diff --git a/README.md b/README.md index 5bbf5c586..7fd815522 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,7 @@ -# PCem-Experimental -Unofficial experimental branchof the PCem emulator. +# PCem Unofficial [![Build Status](http://polar.rol.im:8080/job/PCem-Unofficial/badge/icon)](http://polar.rol.im:8080/job/PCem-Unofficial) +PCem Unofficial is an unofficial branch of the PCem emulator, which aims to emulate IBM compatible machines from 1981-2000 period. This branch adds several emulated motherboards. + +--- +Keep in touch with the PCem Unoffical community: + +[![Visit our IRC channel](https://kiwiirc.com/buttons/irc.rol.im/pcem-x.png)](https://kiwiirc.com/client/irc.rol.im/?nick=pcem|?#pcem-x) diff --git a/src/386_dynarec.c b/src/386_dynarec.c index ee9d33f1b..488168286 100644 --- a/src/386_dynarec.c +++ b/src/386_dynarec.c @@ -297,7 +297,10 @@ int rep386(int fv) 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); - + + if (trap) + cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ + cpu_reps++; flags_rebuild(); diff --git a/src/Makefile.mingw b/src/Makefile.mingw index e7411529d..33b1bacc3 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -2,36 +2,34 @@ VPATH = . dosbox resid-fp slirp CPP = g++.exe CC = gcc.exe WINDRES = windres.exe -KFLAGS = -O2 -flto -ffast-math -msse -msse2 -mfpmath=387 -mstackrealign -CFLAGS = -O3 -march=native -mtune=native -flto -fbranch-probabilities -fvpt -funroll-loops -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse -mstackrealign -BFLAGS = -DRELEASE_BUILD +CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -funroll-loops -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse -mstackrealign OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o acerm3a.o ali1429.o amstrad.o cdrom-ioctl.o cdrom-iso.o \ cdrom-null.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.o compaq.o config.o cpu.o dac.o \ device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o fdc.o fdc37c665.o fdc37c932fr.o fdd.o fdi2raw.o gameport.o headland.o i430hx.o i430lx.o i430fx.o \ i430nx.o i430vx.o i440fx.o ide.o intel.o intel_flash.o io.o jim.o joystick_standard.o joystick_sw_pad.o keyboard.o keyboard_amstrad.o keyboard_at.o \ keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o lpt.o mcr.o mem.o memregs.o model.o mouse.o mouse_ps2.o \ - mouse_serial.o ne2000.o neat.o nethandler.o nmi.o nvr.o olivetti_m24.o opti.o pc.o pc87306.o pci.o pic.o piix.o pit.o ppi.o ps1.o rom.o \ + mouse_serial.o ne2000.o neat.o nethandler.o nmi.o nvr.o olivetti_m24.o opti.o pc.o pc87306.o pci.o pic.o piix.o pit.o ppi.o ps1.o rom.o rtc.o \ scat.o serial.o sis496.o sis85c471.o sio.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o \ sound_dbopl.o sound_emu8k.o sound_gus.o sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.o sound_resid.o \ sound_sb.o sound_sb_dsp.o sound_sn76489.o sound_speaker.o sound_ssi2001.o sound_wss.o sound_ym7128.o \ soundopenal.o tandy_eeprom.o tandy_rom.o timer.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \ - vid_ati28800.o vid_ati68860_ramdac.o vid_cga.o vid_cga_comp.o vid_cl5429.o vid_ega.o vid_et4000.o \ + vid_ati28800.o vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_ega.o vid_et4000.o \ vid_et4000w32.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 video.o w83877f.o wd76c10.o win.o win-config.o win-d3d.o win-d3d-fs.o win-ddraw.o \ win-ddraw-fs.o win-ddraw-screenshot.o win-deviceconfig.o win-hdconf.o win-joystick.o win-joystickconfig.o win-keyboard.o win-midi.o win-mouse.o \ - win-status.o win-time.o win-video.o x86seg.o x87.o xtide.o pc.res -FMOBJ = dbopl.o + win-status.o win-video.o x86seg.o x87.o xtide.o pc.res +DBOBJ = 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 SLIRPOBJ = bootp.o ip_icmp.o misc.o socket.o tcp_timer.o cksum.o ip_input.o queue.o tcp_input.o tftp.o debug.o ip_output.o sbuf.o tcp_output.o udp.o if.o mbuf.o slirp.o tcp_subr.o LIBS = -mwindows -lwinmm -lopenal.dll -lopenal -lddraw -ldinput8 -ldxguid -ld3d9 -ld3dx9 -lwsock32 -liphlpapi -lstdc++ -static-libstdc++ -static-libgcc -static -PCem.exe: $(OBJ) $(FMOBJ) $(SIDOBJ) $(SLIRPOBJ) - $(CC) $(OBJ) $(FMOBJ) $(SIDOBJ) $(SLIRPOBJ) -o "PCem.exe" $(LIBS) +PCem.exe: $(OBJ) $(DBOBJ) $(SIDOBJ) $(SLIRPOBJ) + $(CC) $(OBJ) $(DBOBJ) $(SIDOBJ) $(SLIRPOBJ) -o "PCem.exe" $(LIBS) strip "PCem.exe" all : PCem.exe diff --git a/src/Makefile.mingw64 b/src/Makefile.mingw64 index b8a0fc9f9..f395af9f4 100644 --- a/src/Makefile.mingw64 +++ b/src/Makefile.mingw64 @@ -8,28 +8,28 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o acerm3a.o ali1429 device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o fdc.o fdc37c665.o fdc37c932fr.o fdd.o fdi2raw.o gameport.o headland.o i430hx.o i430lx.o i430fx.o \ i430nx.o i430vx.o i440fx.o ide.o intel.o intel_flash.o io.o jim.o joystick_standard.o joystick_sw_pad.o keyboard.o keyboard_amstrad.o keyboard_at.o \ keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o lpt.o mcr.o mem.o memregs.o model.o mouse.o mouse_ps2.o \ - mouse_serial.o ne2000.o neat.o nethandler.o nmi.o nvr.o olivetti_m24.o opti.o pc.o pc87306.o pci.o pic.o piix.o pit.o ppi.o ps1.o rom.o \ + mouse_serial.o ne2000.o neat.o nethandler.o nmi.o nvr.o olivetti_m24.o opti.o pc.o pc87306.o pci.o pic.o piix.o pit.o ppi.o ps1.o rom.o rtc.o \ scat.o serial.o sis496.o sis85c471.o sio.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o \ sound_dbopl.o sound_emu8k.o sound_gus.o sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.o sound_resid.o \ sound_sb.o sound_sb_dsp.o sound_sn76489.o sound_speaker.o sound_ssi2001.o sound_wss.o sound_ym7128.o \ soundopenal.o tandy_eeprom.o tandy_rom.o timer.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \ - vid_ati28800.o vid_ati68860_ramdac.o vid_cga.o vid_cga_comp.o vid_cl5429.o vid_ega.o vid_et4000.o \ + vid_ati28800.o vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_ega.o vid_et4000.o \ vid_et4000w32.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 video.o w83877f.o wd76c10.o win.o win-config.o win-d3d.o win-d3d-fs.o win-ddraw.o \ win-ddraw-fs.o win-ddraw-screenshot.o win-deviceconfig.o win-hdconf.o win-joystick.o win-joystickconfig.o win-keyboard.o win-midi.o win-mouse.o \ - win-status.o win-time.o win-video.o x86seg.o x87.o xtide.o pc.res -FMOBJ = dbopl.o + win-status.o win-video.o x86seg.o x87.o xtide.o pc.res +DBOBJ = 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 SLIRPOBJ = bootp.o ip_icmp.o misc.o socket.o tcp_timer.o cksum.o ip_input.o queue.o tcp_input.o tftp.o debug.o ip_output.o sbuf.o tcp_output.o udp.o if.o mbuf.o slirp.o tcp_subr.o -LIBS = -mwindows -lwinmm -lopenal -lddraw -ldinput8 -ldxguid -ld3d9 -ld3dx9 -lwsock32 -liphlpapi -lstdc++ -static-libstdc++ -static-libgcc -static -lopenal.dll -flto -lgcov -lPacket -lwpcap +LIBS = -mwindows -lwinmm -lopenal -lddraw -ldinput8 -ldxguid -ld3d9 -ld3dx9 -lwsock32 -liphlpapi -lstdc++ -static-libstdc++ -static-libgcc -static -lopenal.dll -lgcov -lPacket -lwpcap -PCem64.exe: $(OBJ) $(FMOBJ) $(SIDOBJ) $(SLIRPOBJ) - $(CC) $(OBJ) $(FMOBJ) $(SIDOBJ) $(SLIRPOBJ) -o "PCem64.exe" $(LIBS) +PCem64.exe: $(OBJ) $(DBOBJ) $(SIDOBJ) $(SLIRPOBJ) + $(CC) $(OBJ) $(DBOBJ) $(SIDOBJ) $(SLIRPOBJ) -o "PCem64.exe" $(LIBS) strip "PCem64.exe" all : PCem64.exe diff --git a/src/Makefile_AMD.mingw b/src/Makefile_AMD.mingw index 3b4661201..76e30062f 100644 --- a/src/Makefile_AMD.mingw +++ b/src/Makefile_AMD.mingw @@ -2,35 +2,34 @@ VPATH = . dosbox resid-fp slirp CPP = g++.exe CC = gcc.exe WINDRES = windres.exe -CFLAGS = -O3 -march=amdfam10 -mtune=amdfam10 -flto -fbranch-probabilities -fvpt -funroll-loops -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mfpmath=sse -mstackrealign -BFLAGS = -DRELEASE_BUILD +CFLAGS = -O3 -march=amdfam10 -mtune=amdfam10 -fbranch-probabilities -fvpt -funroll-loops -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mfpmath=sse -mstackrealign OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o acerm3a.o ali1429.o amstrad.o cdrom-ioctl.o cdrom-iso.o \ cdrom-null.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.o compaq.o config.o cpu.o dac.o \ device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o fdc.o fdc37c665.o fdc37c932fr.o fdd.o fdi2raw.o gameport.o headland.o i430hx.o i430lx.o i430fx.o \ i430nx.o i430vx.o i440fx.o ide.o intel.o intel_flash.o io.o jim.o joystick_standard.o joystick_sw_pad.o keyboard.o keyboard_amstrad.o keyboard_at.o \ keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o lpt.o mcr.o mem.o memregs.o model.o mouse.o mouse_ps2.o \ - mouse_serial.o ne2000.o neat.o nethandler.o nmi.o nvr.o olivetti_m24.o opti.o pc.o pc87306.o pci.o pic.o piix.o pit.o ppi.o ps1.o rom.o \ + mouse_serial.o ne2000.o neat.o nethandler.o nmi.o nvr.o olivetti_m24.o opti.o pc.o pc87306.o pci.o pic.o piix.o pit.o ppi.o ps1.o rom.o rtc.o \ scat.o serial.o sis496.o sis85c471.o sio.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o \ sound_dbopl.o sound_emu8k.o sound_gus.o sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.o sound_resid.o \ sound_sb.o sound_sb_dsp.o sound_sn76489.o sound_speaker.o sound_ssi2001.o sound_wss.o sound_ym7128.o \ soundopenal.o tandy_eeprom.o tandy_rom.o timer.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \ - vid_ati28800.o vid_ati68860_ramdac.o vid_cga.o vid_cga_comp.o vid_cl5429.o vid_ega.o vid_et4000.o \ + vid_ati28800.o vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_ega.o vid_et4000.o \ vid_et4000w32.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 video.o w83877f.o wd76c10.o win.o win-config.o win-d3d.o win-d3d-fs.o win-ddraw.o \ win-ddraw-fs.o win-ddraw-screenshot.o win-deviceconfig.o win-hdconf.o win-joystick.o win-joystickconfig.o win-keyboard.o win-midi.o win-mouse.o \ - win-status.o win-time.o win-video.o x86seg.o x87.o xtide.o pc.res -FMOBJ = dbopl.o + win-status.o win-video.o x86seg.o x87.o xtide.o pc.res +DBOBJ = 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 SLIRPOBJ = bootp.o ip_icmp.o misc.o socket.o tcp_timer.o cksum.o ip_input.o queue.o tcp_input.o tftp.o debug.o ip_output.o sbuf.o tcp_output.o udp.o if.o mbuf.o slirp.o tcp_subr.o LIBS = -mwindows -lwinmm -lopenal.dll -lopenal -lddraw -ldinput8 -ldxguid -ld3d9 -ld3dx9 -lwsock32 -liphlpapi -lstdc++ -static-libstdc++ -static-libgcc -static -PCem.exe: $(OBJ) $(FMOBJ) $(SIDOBJ) $(SLIRPOBJ) - $(CC) $(OBJ) $(FMOBJ) $(SIDOBJ) $(SLIRPOBJ) -o "PCem.exe" $(LIBS) +PCem.exe: $(OBJ) $(DBOBJ) $(SIDOBJ) $(SLIRPOBJ) + $(CC) $(OBJ) $(DBOBJ) $(SIDOBJ) $(SLIRPOBJ) -o "PCem.exe" $(LIBS) strip "PCem.exe" all : PCem.exe diff --git a/src/cpu.c b/src/cpu.c index 5fc2d6fe5..f323c3b9d 100644 --- a/src/cpu.c +++ b/src/cpu.c @@ -75,6 +75,7 @@ int cpu_use_dynarec; uint64_t cpu_CR4_mask; int is286, is386; +int israpidcad; uint64_t tsc = 0; @@ -228,9 +229,9 @@ CPU cpus_i386[] = {"i386DX/25", CPU_386DX, 2, 25000000, 1, 0, 0x0308, 0, 0, 0}, {"i386DX/33", CPU_386DX, 3, 33333333, 1, 0, 0x0308, 0, 0, 0}, {"i386DX/40", CPU_386DX, 4, 40000000, 1, 0, 0x0308, 0, 0, 0}, - {"RapidCAD/25", CPU_i486DX, 2, 25000000, 1, 0, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC}, - {"RapidCAD/33", CPU_i486DX, 3, 33333333, 1, 0, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC}, - {"RapidCAD/40", CPU_i486DX, 4, 40000000, 1, 0, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC}, + {"RapidCAD/25", CPU_RAPIDCAD, 2, 25000000, 1, 0, 0x404, 0, 0, 0}, + {"RapidCAD/33", CPU_RAPIDCAD, 3, 33333333, 1, 0, 0x404, 0, 0, 0}, + {"RapidCAD/40", CPU_RAPIDCAD, 4, 40000000, 1, 0, 0x404, 0, 0, 0}, {"", -1, 0, 0, 0} }; @@ -292,7 +293,6 @@ CPU cpus_i486[] = {"iDX4/100", CPU_i486DX,10, 100000000, 3, 33333333, 0x481, 0x481, 0, CPU_SUPPORTS_DYNAREC}, /*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}, {"Pentium OverDrive/83", CPU_PENTIUM, 8, 83333333, 3, 33333333, 0x1532, 0x1532, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC}, - {"i386DX/33", CPU_386DX, 3, 33333333, 1, 0, 0x0308, 0, 0, 0}, {"", -1, 0, 0, 0} }; @@ -582,7 +582,8 @@ void cpu_set() is8086 = (cpu_s->cpu_type > CPU_8088); is286 = (cpu_s->cpu_type >= CPU_286); 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); + israpidcad = (cpu_s->cpu_type == CPU_RAPIDCAD); + is486 = (cpu_s->cpu_type >= CPU_i486SX) || (cpu_s->cpu_type == CPU_486SLC || cpu_s->cpu_type == CPU_486DLC || cpu_s->cpu_type == CPU_RAPIDCAD); hasfpu = (cpu_s->cpu_type >= CPU_i486DX); 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_386SX || cpu_s->cpu_type == CPU_486SLC); @@ -800,6 +801,37 @@ void cpu_set() timing_jmp_pm_gate = 45; break; + case CPU_RAPIDCAD: + 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 = 3-1; /*branch taken*/ + timing_bnt = 1; /*branch not taken*/ + timing_int = 4; + timing_int_rm = 26; + timing_int_v86 = 82; + timing_int_pm = 44; + timing_int_pm_outer = 71; + timing_iret_rm = 15; + timing_iret_v86 = 36; /*unknown*/ + timing_iret_pm = 20; + timing_iret_pm_outer = 36; + timing_call_rm = 18; + timing_call_pm = 20; + timing_call_pm_gate = 35; + timing_call_pm_gate_inner = 69; + timing_retf_rm = 13; + timing_retf_pm = 17; + timing_retf_pm_outer = 35; + timing_jmp_rm = 17; + timing_jmp_pm = 19; + timing_jmp_pm_gate = 32; + break; + case CPU_486SLC: x86_setopcodes(ops_386, ops_486_0f, dynarec_ops_386, dynarec_ops_486_0f); timing_rr = 1; /*register dest - register src*/ diff --git a/src/cpu.h b/src/cpu.h index a6d20a365..99bcf35ba 100644 --- a/src/cpu.h +++ b/src/cpu.h @@ -13,34 +13,35 @@ extern int cpu, cpu_manufacturer; /*386 class CPUs*/ #define CPU_386SX 3 #define CPU_386DX 4 -#define CPU_486SLC 5 -#define CPU_486DLC 6 +#define CPU_RAPIDCAD 5 +#define CPU_486SLC 6 +#define CPU_486DLC 7 /*486 class CPUs*/ -#define CPU_i486SX 7 -#define CPU_Am486SX 8 -#define CPU_Cx486S 9 -#define CPU_i486DX 10 -#define CPU_Am486DX 11 -#define CPU_Cx486DX 12 -#define CPU_Cx5x86 13 +#define CPU_i486SX 8 +#define CPU_Am486SX 9 +#define CPU_Cx486S 10 +#define CPU_i486DX 11 +#define CPU_Am486DX 12 +#define CPU_Cx486DX 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_K5 21 -#define CPU_5K86 22 -#define CPU_K6 23 +#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_K5 22 +#define CPU_5K86 23 +#define CPU_K6 24 /*686 class CPUs*/ -#define CPU_PENTIUMPRO 24 -#define CPU_PENTIUM2 25 -#define CPU_PENTIUM2D 26 +#define CPU_PENTIUMPRO 25 +#define CPU_PENTIUM2 26 +#define CPU_PENTIUM2D 27 #define MANU_INTEL 0 #define MANU_AMD 1 diff --git a/src/vid_cga_comp.c b/src/dosbox/vid_cga_comp.c similarity index 92% rename from src/vid_cga_comp.c rename to src/dosbox/vid_cga_comp.c index 7cacbedff..cdf79da73 100644 --- a/src/vid_cga_comp.c +++ b/src/dosbox/vid_cga_comp.c @@ -5,13 +5,10 @@ #include #include -#include "ibm.h" -#include "device.h" -#include "io.h" -#include "mem.h" -#include "timer.h" -#include "video.h" -#include "vid_cga.h" +#include "../ibm.h" +#include "../device.h" +#include "../mem.h" +#include "../vid_cga.h" #include "vid_cga_comp.h" int CGA_Composite_Table[1024]; @@ -145,24 +142,8 @@ void update_cga16_color(cga_t *cga) { video_bi = (int) (bi*iq_adjust_i + bq*iq_adjust_q); video_bq = (int) (-bi*iq_adjust_q + bq*iq_adjust_i); video_sharpness = (int) (sharpness*256/100); - -#if 0 - df = fopen("CGA_Composite_Table.dmp", "wb"); - fwrite(CGA_Composite_Table, 1024, sizeof(int), df); - fclose(df); -#endif } -#if 0 -void configure_comp(double h, uint8_t n, uint8_t bw, uint8_t b1) -{ - hue_offset = h; - new_cga = n; - is_bw = bw; - is_bpp1 = b1; -} -#endif - static Bit8u byte_clamp(int v) { v >>= 13; return v < 0 ? 0 : (v > 255 ? 255 : v); @@ -216,7 +197,7 @@ Bit8u * Composite_Process(cga_t *cga, Bit8u border, Bit32u blocks/*, bool double for (x = 0; x < 5; ++x) OUT(b[x&3]); - if ((cga->cgamode & 4) != 0 || !cga_color_burst) { + if ((cga->cgamode & 4) != 0) { // Decode int* i = temp + 5; Bit32u* srgb = (Bit32u *)TempLine; @@ -256,18 +237,6 @@ Bit8u * Composite_Process(cga_t *cga, Bit8u border, Bit32u blocks/*, bool double #undef COMPOSITE_CONVERT #undef OUT -#if 0 - df = fopen("temp.dmp", "ab"); - fwrite(temp, SCALER_MAXWIDTH + 10, sizeof(int), df); - fclose(df); - df = fopen("atemp.dmp", "ab"); - fwrite(atemp, SCALER_MAXWIDTH + 2, sizeof(int), df); - fclose(df); - df = fopen("btemp.dmp", "ab"); - fwrite(btemp, SCALER_MAXWIDTH + 2, sizeof(int), df); - fclose(df); -#endif - return TempLine; } @@ -343,7 +312,7 @@ void DecreaseSharpness(cga_t *cga) void cga_comp_init(cga_t *cga) { - new_cga = (gfxcard == GFX_NEW_CGA); + new_cga = cga->revision; /* Making sure this gets reset after reset. */ brightness = 0; @@ -353,4 +322,4 @@ void cga_comp_init(cga_t *cga) hue_offset = 0; update_cga16_color(cga); -} \ No newline at end of file +} diff --git a/src/vid_cga_comp.h b/src/dosbox/vid_cga_comp.h similarity index 100% rename from src/vid_cga_comp.h rename to src/dosbox/vid_cga_comp.h diff --git a/src/fdc.c b/src/fdc.c index e01dacd45..272416c05 100644 --- a/src/fdc.c +++ b/src/fdc.c @@ -99,13 +99,11 @@ void fdc_reset() fdc_set_skip_pulses(1, 0); fdd_stepping_motor_on[0] = fdd_stepping_motor_on[1] = 0; fdd_track_diff[0] = fdd_track_diff[1] = 0; -#if 0 if (!AT) { fdc.rate = 2; // fdc_update_rate(); } -#endif fdc_state = FDC_STATE_NORMAL; // pclog("Reset FDC\n"); } diff --git a/src/ibm.h b/src/ibm.h index 3693f139c..2c2348635 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -194,6 +194,7 @@ uint32_t dr[8]; //#define IOPLV86 ((!(msw&1)) || (CPL<=IOPL)) extern int cycles; extern int cycles_lost; +extern int israpidcad; extern int is486; extern uint8_t opcode; extern int insc; @@ -286,7 +287,7 @@ char discfns[2][256]; int driveempty[2]; #define MDA ((gfxcard==GFX_MDA || gfxcard==GFX_HERCULES || gfxcard==GFX_INCOLOR) && (romset=ROM_IBMAT)) -#define VGA ((gfxcard>=GFX_TVGA || romset==ROM_ACER386) && gfxcard!=GFX_INCOLOR && gfxcard!=GFX_NEW_CGA && gfxcard!=GFX_COMPAQ_EGA && gfxcard!=GFX_SUPER_EGA && romset!=ROM_PC1640 && romset!=ROM_PC1512 && romset!=ROM_TANDY && romset!=ROM_PC200) +#define VGA ((gfxcard>=GFX_TVGA || romset==ROM_ACER386) && gfxcard!=GFX_INCOLOR && gfxcard!=GFX_COMPAQ_EGA && gfxcard!=GFX_SUPER_EGA && romset!=ROM_PC1640 && romset!=ROM_PC1512 && romset!=ROM_TANDY && romset!=ROM_PC200) #define PCJR (romset == ROM_IBMPCJR) #define AMIBIOS (romset==ROM_AMI386 || romset==ROM_AMI486 || romset == ROM_WIN486) @@ -385,7 +386,6 @@ enum GFX_PHOENIX_TRIO32, /*S3 732/Trio32 (Phoenix)*/ GFX_PHOENIX_TRIO64, /*S3 764/Trio64 (Phoenix)*/ GFX_INCOLOR, /* Hercules InColor */ - GFX_NEW_CGA, GFX_ET4000W32C, /*Tseng ET4000/W32p (Cardex) */ GFX_COMPAQ_EGA, /*Compaq EGA*/ GFX_SUPER_EGA, /*Using Chips & Technologies SuperEGA BIOS*/ @@ -393,7 +393,7 @@ enum GFX_MIRO_VISION964, /*S3 Vision964 (Miro Crystal)*/ GFX_CL_GD5446, /*Cirrus Logic CL-GD5446*/ GFX_VGAWONDERXL, /*Compaq ATI VGA Wonder XL (28800-5)*/ - GFX_WD90C11, /*Paradise WD90C11*/ + GFX_WD90C11, /*Paradise WD90C11 Standalone*/ GFX_OTI077, /*Oak OTI-077*/ GFX_MAX }; diff --git a/src/intel_flash.c b/src/intel_flash.c index e3434ae1c..144dc589f 100644 --- a/src/intel_flash.c +++ b/src/intel_flash.c @@ -3,6 +3,14 @@ #include "device.h" #include "mem.h" +#define FLASH_IS_BXB 2 +#define FLASH_INVERT 1 + +#define BLOCK_MAIN 0 +#define BLOCK_DMI 1 +#define BLOCK_ESCD 2 +#define BLOCK_BOOT 3 + enum { CMD_READ_ARRAY = 0xff, @@ -18,99 +26,86 @@ enum typedef struct flash_t { uint32_t command, status; - uint32_t data_addr1, data_addr2, data_start, boot_start; - uint32_t main_start[2], main_end[2], main_len[2]; - uint32_t flash_id, invert_high_pin; - mem_mapping_t read_mapping, write_mapping; - mem_mapping_t read_mapping_h, write_mapping_h; + uint32_t flash_id; + uint8_t type; /* 0 = BXT, 1 = BXB */ + uint8_t invert_high_pin; /* 0 = no, 1 = yes */ + mem_mapping_t mapping[8], mapping_h[8]; + uint32_t block_start[4], block_end[4], block_len[4]; + uint8_t array[131072]; } flash_t; static flash_t flash; char flash_path[1024]; -#if 0 -mem_mapping_t flash_null_mapping[4]; - -uint8_t flash_read_null(uint32_t addr, void *priv) -{ - return 0xff; -} - -uint16_t flash_read_nullw(uint32_t addr, void *priv) -{ - return 0xffff; -} - -uint32_t flash_read_nulll(uint32_t addr, void *priv) -{ -// pclog("Read BIOS %08X %02X %04X:%04X\n", addr, *(uint32_t *)&rom[addr & biosmask], CS, pc); - return 0xffffffff; -} - -void flash_null_mapping_disable() -{ - mem_mapping_disable(&flash_null_mapping[0]); - mem_mapping_disable(&flash_null_mapping[1]); - mem_mapping_disable(&flash_null_mapping[2]); - mem_mapping_disable(&flash_null_mapping[3]); -} - -void flash_null_mapping_enable() -{ - mem_mapping_enable(&flash_null_mapping[0]); - mem_mapping_enable(&flash_null_mapping[1]); - mem_mapping_enable(&flash_null_mapping[2]); - mem_mapping_enable(&flash_null_mapping[3]); -} - -void flash_add_null_mapping() -{ - mem_mapping_add(&flash_null_mapping[0], 0xe0000, 0x04000, flash_read_null, flash_read_nullw, flash_read_nulll, mem_write_null, mem_write_nullw, mem_write_nulll, NULL, MEM_MAPPING_EXTERNAL, 0); - mem_mapping_add(&flash_null_mapping[1], 0xe4000, 0x04000, flash_read_null, flash_read_nullw, flash_read_nulll, mem_write_null, mem_write_nullw, mem_write_nulll, NULL, MEM_MAPPING_EXTERNAL, 0); - mem_mapping_add(&flash_null_mapping[2], 0xe8000, 0x04000, flash_read_null, flash_read_nullw, flash_read_nulll, mem_write_null, mem_write_nullw, mem_write_nulll, NULL, MEM_MAPPING_EXTERNAL, 0); - mem_mapping_add(&flash_null_mapping[3], 0xec000, 0x04000, flash_read_null, flash_read_nullw, flash_read_nulll, mem_write_null, mem_write_nullw, mem_write_nulll, NULL, MEM_MAPPING_EXTERNAL, 0); - - flash_null_mapping_disable(); -} -#endif - static uint8_t flash_read(uint32_t addr, void *p) { flash_t *flash = (flash_t *)p; - // pclog("flash_read : addr=%08x command=%02x %04x:%08x\n", addr, flash->command, CS, pc); + if (flash->invert_high_pin) + { + // pclog("flash_read : addr=%08x/%08x val=%02x command=%02x %04x:%08x\n", addr, addr ^ 0x10000, flash->array[(addr ^ 0x10000) & 0x1ffff], flash->command, CS, cpu_state.pc); + addr ^= 0x10000; + if (addr & 0xfff00000) return flash->array[addr & 0x1ffff]; + } + // pclog("flash_read : addr=%08x command=%02x %04x:%08x\n", addr, flash->command, CS, cpu_state.pc); + addr &= 0x1ffff; switch (flash->command) { + case CMD_READ_ARRAY: + default: + return flash->array[addr]; + case CMD_IID: if (addr & 1) return flash->flash_id; return 0x89; - - default: - return flash->status; + + case CMD_READ_STATUS: + return flash->status; } } +static uint16_t flash_readw(uint32_t addr, void *p) +{ + flash_t *flash = (flash_t *)p; + addr &= 0x1ffff; + if (flash->invert_high_pin) addr ^= 0x10000; + return *(uint16_t *)&(flash->array[addr]); +} + +static uint32_t flash_readl(uint32_t addr, void *p) +{ + flash_t *flash = (flash_t *)p; + addr &= 0x1ffff; + if (flash->invert_high_pin) addr ^= 0x10000; + return *(uint32_t *)&(flash->array[addr]); +} + 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, 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; + switch (flash->command) { case CMD_ERASE_SETUP: if (val == CMD_ERASE_CONFIRM) { - // pclog("flash_write: erase %05x\n", addr & 0x1ffff); + pclog("flash_write: erase %05x\n", addr); - if ((addr & 0x1f000) == flash->data_addr1) - memset(&rom[flash->data_addr1], 0xff, 0x1000); - if ((addr & 0x1f000) == flash->data_addr2) - memset(&rom[flash->data_addr2], 0xff, 0x1000); - if (((addr & 0x1ffff) >= flash->main_start[0]) && ((addr & 0x1ffff) <= flash->main_end[0]) && flash->main_len[0]) - memset(&rom[flash->main_start[0]], 0xff, flash->main_len[0]); - if (((addr & 0x1ffff) >= flash->main_start[1]) && ((addr & 0x1ffff) <= flash->main_end[1]) && flash->main_len[1]) - memset(&rom[flash->main_start[1]], 0xff, flash->main_len[1]); + for (i = 0; i < 3; i++) + { + if ((addr >= flash->block_start[i]) && (addr <= flash->block_end[i])) + memset(&(flash->array[flash->block_start[i]]), 0xff, flash->block_len[i]); + } flash->status = 0x80; } @@ -118,9 +113,9 @@ static void flash_write(uint32_t addr, uint8_t val, void *p) break; case CMD_PROGRAM_SETUP: - // pclog("flash_write: program %05x %02x\n", addr & 0x1ffff, val); - if ((addr & 0x1e000) != (flash->boot_start & 0x1e000)) - rom[addr & 0x1ffff] = val; + pclog("flash_write: program %05x %02x\n", addr, val); + if ((addr & 0x1e000) != (flash->block_start[3] & 0x1e000)) + flash->array[addr] = val; flash->command = CMD_READ_STATUS; flash->status = 0x80; break; @@ -131,46 +126,42 @@ static void flash_write(uint32_t addr, uint8_t val, void *p) { case CMD_CLEAR_STATUS: flash->status = 0; - break; - - case CMD_IID: - case CMD_READ_STATUS: - for (i = 0; i < 8; i++) - { - mem_mapping_disable((addr & 0x8000000) ? &bios_high_mapping[i] : &bios_mapping[i]); - } - mem_mapping_enable((addr & 0x8000000) ? &flash->read_mapping_h : &flash->read_mapping); - break; - - case CMD_READ_ARRAY: - for (i = 0; i < 8; i++) - { - mem_mapping_enable((addr & 0x8000000) ? &bios_high_mapping[i] : &bios_mapping[i]); - } - mem_mapping_disable((addr & 0x8000000) ? &flash->read_mapping_h : &flash->read_mapping); -#if 0 - if ((romset == ROM_MB500N) || (romset == ROM_430VX) || (romset == ROM_P55VA) || (romset == ROM_P55TVP4) || (romset == ROM_440FX)) - { - for (i = 0; i < 4; i++) - { - mem_mapping_disable(&bios_mapping[i]); - } - - flash_null_mapping_enable(); - } - pclog("; This line needed\n"); -#endif - break; + break; } } } -void *intel_flash_init(int type) +void intel_flash_add_mappings(flash_t *flash) +{ + int i = 0; + + 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); + } +} + +/* 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. */ +void intel_flash_add_mappings_inverted(flash_t *flash) +{ + int i = 0; + + 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); + } +} + +void *intel_flash_init(uint8_t type) { FILE *f; flash_t *flash = malloc(sizeof(flash_t)); char fpath[1024]; - memset(flash, 0, sizeof(flash_t)); + int i; + /* IMPORTANT: Do NOT zero the pointers! */ + memset(flash, 0, sizeof(flash_t) - (6 * sizeof(void *))); // pclog("Initializing Flash (type = %i)\n", type); @@ -223,132 +214,119 @@ void *intel_flash_init(int type) } // pclog("Flash init: Path is: %s\n", flash_path); - switch(type) + flash->type = (type & 2) ? 1 : 0; + flash->flash_id = (!flash->type) ? 0x94 : 0x95; + flash->invert_high_pin = (type & 1); + + /* The block lengths are the same both flash types. */ + flash->block_len[0] = 0x1c000; + flash->block_len[1] = 0x01000; + flash->block_len[2] = 0x01000; + flash->block_len[3] = 0x02000; + + if(flash->type) /* 28F001BX-B */ { - case 0: - flash->data_addr1 = 0xc000; - flash->data_addr2 = 0xd000; - flash->data_start = 0xc000; - flash->boot_start = 0xe000; - flash->main_start[0] = 0x0000; - flash->main_end[0] = 0xbfff; - flash->main_len[0] = 0xc000; - flash->main_start[1] = 0x10000; - flash->main_end[1] = 0x1ffff; - flash->main_len[1] = 0x10000; - break; - case 1: - flash->data_addr1 = 0x1c000; - flash->data_addr2 = 0x1d000; - flash->data_start = 0x1c000; - flash->boot_start = 0x1e000; - flash->main_start[0] = 0x00000; - flash->main_end[0] = 0x1bfff; - flash->main_len[0] = 0x1c000; - flash->main_start[1] = flash->main_end[1] = flash->main_len[1] = 0; - break; - case 2: - flash->data_addr1 = 0x3000; - flash->data_addr2 = 0x2000; - flash->data_start = 0x2000; - flash->boot_start = 0x00000; - flash->main_start[0] = 0x04000; - flash->main_end[0] = 0x1ffff; - flash->main_len[0] = 0x1c000; - flash->main_start[1] = flash->main_end[1] = flash->main_len[1] = 0; - break; + flash->block_start[0] = 0x04000; /* MAIN BLOCK */ + flash->block_end[0] = 0x1ffff; + flash->block_start[1] = 0x03000; /* DMI BLOCK */ + flash->block_end[1] = 0x03fff; + flash->block_start[2] = 0x04000; /* ESCD BLOCK */ + flash->block_end[2] = 0x04fff; + flash->block_start[3] = 0x00000; /* BOOT BLOCK */ + flash->block_end[3] = 0x01fff; + } + else /* 28F001BX-T */ + { + flash->block_start[0] = 0x00000; /* MAIN BLOCK */ + flash->block_end[0] = 0x1bfff; + flash->block_start[1] = 0x1c000; /* DMI BLOCK */ + flash->block_end[1] = 0x1cfff; + flash->block_start[2] = 0x1d000; /* ESCD BLOCK */ + flash->block_end[2] = 0x1dfff; + flash->block_start[3] = 0x1e000; /* BOOT BLOCK */ + flash->block_end[3] = 0x1ffff; } - flash->flash_id = (type != 2) ? 0x94 : 0x95; - flash->invert_high_pin = (type == 0) ? 1 : 0; - - mem_mapping_add(&flash->read_mapping, - 0xe0000, - 0x20000, - flash_read, NULL, NULL, - NULL, NULL, NULL, - NULL, MEM_MAPPING_EXTERNAL, (void *)flash); - mem_mapping_add(&flash->write_mapping, - 0xe0000, - 0x20000, - NULL, NULL, NULL, - flash_write, NULL, NULL, - NULL, MEM_MAPPING_EXTERNAL, (void *)flash); - mem_mapping_disable(&flash->read_mapping); - if (type > 0) + for (i = 0; i < 8; i++) { - mem_mapping_add(&flash->read_mapping_h, - 0xfffe0000, - 0x20000, - flash_read, NULL, NULL, - NULL, NULL, NULL, - NULL, 0, (void *)flash); - mem_mapping_add(&flash->write_mapping_h, - 0xfffe0000, - 0x20000, - NULL, NULL, NULL, - flash_write, NULL, NULL, - NULL, 0, (void *)flash); - mem_mapping_disable(&flash->read_mapping_h); - /* if (romset != ROM_P55TVP4) */ mem_mapping_disable(&flash->write_mapping); + mem_mapping_disable(&bios_mapping[i]); + mem_mapping_disable(&bios_high_mapping[i]); } - flash->command = CMD_READ_ARRAY; - flash->status = 0; - if ((romset == ROM_586MC1) || (romset == ROM_MB500N) || (type == 0)) + if (flash->invert_high_pin) { - memset(&rom[flash->data_addr2], 0xFF, 0x1000); + memcpy(flash->array, rom + 65536, 65536); + memcpy(flash->array + 65536, rom, 65536); } else { - memset(&rom[flash->data_start], 0xFF, 0x2000); + memcpy(flash->array, rom, 131072); } - - if ((romset != ROM_586MC1) && (romset != ROM_MB500N) && (type > 0)) + + if (flash->invert_high_pin) { - memset(fpath, 0, 1024); - strcpy(fpath, flash_path); - strcat(fpath, "dmi.bin"); - f = romfopen(fpath, "rb"); - if (f) - { - fread(&rom[flash->data_addr1], 0x1000, 1, f); - fclose(f); - } + intel_flash_add_mappings_inverted(flash); } + else + { + intel_flash_add_mappings(flash); + } + + flash->command = CMD_READ_ARRAY; + flash->status = 0; + + /* Load the main block. */ + memset(fpath, 0, 1024); + strcpy(fpath, flash_path); + strcat(fpath, "main.bin"); + f = romfopen(fpath, "rb"); + if (f) + { + fread(&(flash->array[flash->block_start[BLOCK_MAIN]]), flash->block_len[BLOCK_MAIN], 1, f); + fclose(f); + } + + /* Load the DMI block. */ + memset(fpath, 0, 1024); + strcpy(fpath, flash_path); + strcat(fpath, "dmi.bin"); + f = romfopen(fpath, "rb"); + if (f) + { + fread(&(flash->array[flash->block_start[BLOCK_DMI]]), flash->block_len[BLOCK_DMI], 1, f); + fclose(f); + } + + /* Load the ESCD block. */ memset(fpath, 0, 1024); strcpy(fpath, flash_path); strcat(fpath, "escd.bin"); f = romfopen(fpath, "rb"); if (f) { - fread(&rom[flash->data_addr2], 0x1000, 1, f); + fread(&(flash->array[flash->block_start[BLOCK_ESCD]]), flash->block_len[BLOCK_ESCD], 1, f); fclose(f); } -#if 0 - flash_add_null_mapping(); -#endif - return flash; } /* For AMI BIOS'es - Intel 28F001BXT with high address pin inverted. */ void *intel_flash_bxt_ami_init() { - return intel_flash_init(0); + return intel_flash_init(FLASH_INVERT); } /* For Award BIOS'es - Intel 28F001BXT with high address pin not inverted. */ void *intel_flash_bxt_init() { - return intel_flash_init(1); + return intel_flash_init(0); } -/* For Acerd BIOS'es - Intel 28F001BXB. */ +/* For Acer BIOS'es - Intel 28F001BXB. */ void *intel_flash_bxb_init() { - return intel_flash_init(2); + return intel_flash_init(FLASH_IS_BXB); } void intel_flash_close(void *p) @@ -360,20 +338,28 @@ void intel_flash_close(void *p) // pclog("Flash close: Path is: %s\n", flash_path); - if ((romset != ROM_586MC1) && (romset != ROM_MB500N)) - { - memset(fpath, 0, 1024); - strcpy(fpath, flash_path); - strcat(fpath, "dmi.bin"); - f = romfopen(fpath, "wb"); - fwrite(&rom[flash->data_addr1], 0x1000, 1, f); - fclose(f); - } + /* Save the main block. */ + memset(fpath, 0, 1024); + strcpy(fpath, flash_path); + strcat(fpath, "main.bin"); + f = romfopen(fpath, "wb"); + fwrite(&(flash->array[flash->block_start[BLOCK_MAIN]]), flash->block_len[BLOCK_MAIN], 1, f); + fclose(f); + + /* Save the DMI block. */ + memset(fpath, 0, 1024); + strcpy(fpath, flash_path); + strcat(fpath, "dmi.bin"); + f = romfopen(fpath, "wb"); + fwrite(&(flash->array[flash->block_start[BLOCK_DMI]]), flash->block_len[BLOCK_DMI], 1, f); + fclose(f); + + /* Save the ESCD block. */ memset(fpath, 0, 1024); strcpy(fpath, flash_path); strcat(fpath, "escd.bin"); f = romfopen(fpath, "wb"); - fwrite(&rom[flash->data_addr2], 0x1000, 1, f); + fwrite(&(flash->array[flash->block_start[BLOCK_ESCD]]), flash->block_len[BLOCK_ESCD], 1, f); fclose(f); free(flash); diff --git a/src/linux-time.c b/src/linux-time.c deleted file mode 100644 index 8b7511d84..000000000 --- a/src/linux-time.c +++ /dev/null @@ -1,48 +0,0 @@ -#include -#include -#include "ibm.h" -#include "nvr.h" - -void time_get(char *nvrram) -{ - int c,d; - uint8_t baknvr[10]; - time_t cur_time; - struct tm cur_time_tm; - - memcpy(baknvr,nvrram,10); - - cur_time = time(NULL); - localtime_r(&cur_time, &cur_time_tm); - - d = cur_time_tm.tm_sec % 10; - c = cur_time_tm.tm_sec / 10; - nvrram[0] = d | (c << 4); - d = cur_time_tm.tm_min % 10; - c = cur_time_tm.tm_min / 10; - nvrram[2] = d | (c << 4); - d = cur_time_tm.tm_hour % 10; - c = cur_time_tm.tm_hour / 10; - nvrram[4] = d | (c << 4); - d = cur_time_tm.tm_wday % 10; - c = cur_time_tm.tm_wday / 10; - nvrram[6] = d | (c << 4); - d = cur_time_tm.tm_mday % 10; - c = cur_time_tm.tm_mday / 10; - nvrram[7] = d | (c << 4); - d = cur_time_tm.tm_mon % 10; - c = cur_time_tm.tm_mon / 10; - nvrram[8] = d | (c << 4); - d = cur_time_tm.tm_year % 10; - c = (cur_time_tm.tm_year / 10) % 10; - nvrram[9] = d | (c << 4); - if (baknvr[0] != nvrram[0] || - baknvr[2] != nvrram[2] || - baknvr[4] != nvrram[4] || - baknvr[6] != nvrram[6] || - baknvr[7] != nvrram[7] || - baknvr[8] != nvrram[8] || - baknvr[9] != nvrram[9]) - nvrram[0xA] |= 0x80; -} - diff --git a/src/mem.c b/src/mem.c index 9a4fb8da7..72faa3f48 100644 --- a/src/mem.c +++ b/src/mem.c @@ -1647,7 +1647,7 @@ void mem_write_nulll(uint32_t addr, uint32_t val, void *p) void mem_updatecache() { flushmmucache(); - if (!is386) + if (!is386 || israpidcad) { cachesize=256; memwaitstate=0; diff --git a/src/model.c b/src/model.c index 9124a1981..6a1a70291 100644 --- a/src/model.c +++ b/src/model.c @@ -441,6 +441,7 @@ void at_batman_init() sio_init(1); fdc37c665_init(); intel_batman_init(); + device_add(&intel_flash_bxt_ami_device); if (cdrom_channel >= 4) ide_ter_init(); } @@ -466,7 +467,7 @@ void at_plato_init() fdc37c665_init(); /* It seems it uses the same interface as Batman. */ intel_batman_init(); - // device_add(&intel_flash_bxt_ami_device); + device_add(&intel_flash_bxt_ami_device); if (cdrom_channel >= 4) ide_ter_init(); } diff --git a/src/nvr.c b/src/nvr.c index 13efe84f4..f9eea38e2 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -4,6 +4,7 @@ #include "nvr.h" #include "pic.h" #include "timer.h" +#include "rtc.h" int oldromset; int nvrmask=63; @@ -14,230 +15,16 @@ int nvr_dosave = 0; static int nvr_onesec_time = 0, nvr_onesec_cnt = 0; -int enable_sync = 0; - -#define second internal_time[0] -#define minute internal_time[1] -#define hour internal_time[2] -#define day internal_time[3] -#define month internal_time[4] -#define year internal_time[5] -int internal_time[6]; -int days_in_month[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; - -static int 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; -} - -static int get_days(int org_month, int org_year) -{ - if (org_month != 2) - { - return days_in_month[org_month]; - } - else - { - return is_leap(org_year) ? 29 : 28; - } -} - -static int convert_to_bcd(int number) -{ - int n1, n2; - n1 = number % 10; - n2 = number - n1; - n2 /= 10; - n2 <<= 4; - return (n2 | n1); -} - -static int convert_from_bcd(int number) -{ - int n1, n2; - n1 = number & 0xF; - n2 = number >> 4; - n2 *= 10; - return (n2 + n1); -} - -static int final_form(int isbcd, int number) -{ - return isbcd ? convert_to_bcd(number) : number; -} - -static int original_form(int isbcd, int number) -{ - return isbcd ? convert_from_bcd(number) : number; -} - -static void nvr_recalc_clock() -{ - if (second == 60) - { - second = 0; - minute++; - } - if (minute == 60) - { - minute = 0; - hour++; - } - if (hour == 24) - { - hour = 0; - day++; - } - if (day == (get_days(month, year) + 1)) - { - day = 1; - month++; - } - if (month == 13) - { - month = 1; - year++; - } - nvr_dosave = 1; -} - -static void nvr_update_internal_clock() -{ - second++; - nvr_recalc_clock(); -} - -void nvr_add_10sec() -{ - time_sleep(10000); - if (!enable_sync) - { - second+=10; - nvr_recalc_clock(); - } -} - -static int to_12_hour(int org_hour) -{ - int hour2 = org_hour; - hour2 %= 12; - if (!hour2) hour2 = 12; - return hour2; -} - -static int from_12_hour(int org_hour) -{ - int hour2 = org_hour & 0x7F; - if (hour2 == 12) hour2 = 0; - if (hour & 0x80) hour2 += 12; - return hour2; -} - -static int week_day() -{ - int day_of_month = day; - int month2 = month; - int year2 = year % 100; - int century = ((year - year2) / 100) % 4; - int sum = day_of_month + month2 + year2 + century; - /* (sum mod 7) gives 0 for Saturday, we need it for Monday, so +5 */ - int raw_wd = ((sum + 5) % 7); - /* +1 so 1 = Monday, 7 = Sunday */ - return raw_wd + 1; -} - -/* Called on every get time. */ -static void set_registers() -{ - int is24hour = (nvrram[0xB] & 2) ? 1 : 0; - int isbcd = (nvrram[0xB] & 4) ? 0 : 1; - - uint8_t baknvr[10]; - - memcpy(baknvr,nvrram,10); - - if (AMSTRAD) - { - is24hour = 1; - isbcd = 1; - } - - nvrram[0] = final_form(isbcd, second); - nvrram[2] = final_form(isbcd, minute); - nvrram[4] = is24hour ? final_form(isbcd, hour) : final_form(isbcd, to_12_hour(hour)); - nvrram[6] = week_day(); - nvrram[7] = final_form(isbcd, day); - nvrram[8] = final_form(isbcd, month); - nvrram[9] = final_form(isbcd, (year % 100)); - - if (baknvr[0] != nvrram[0] || - baknvr[2] != nvrram[2] || - baknvr[4] != nvrram[4] || - baknvr[6] != nvrram[6] || - baknvr[7] != nvrram[7] || - baknvr[8] != nvrram[8] || - baknvr[9] != nvrram[9]) - nvrram[0xA]|=0x80; -} - -/* Called on NVR load and write. */ -static void get_registers() -{ - int is24hour = (nvrram[0xB] & 2) ? 1 : 0; - int isbcd = (nvrram[0xB] & 4) ? 0 : 1; - - int temp_hour = 0; - - if (AMSTRAD) - { - is24hour = 1; - isbcd = 1; - } - - second = original_form(isbcd, nvrram[0]); - minute = original_form(isbcd, nvrram[2]); - hour = is24hour ? original_form(isbcd, nvrram[4]) : from_12_hour(original_form(isbcd, nvrram[4])); - day = original_form(isbcd, nvrram[7]); - month = original_form(isbcd, nvrram[8]); - year = original_form(isbcd, nvrram[9]) + 1900; -} - void getnvrtime() { - if (enable_sync) - { - /* Get time from host. */ - time_get(nvrram); - } - else - { - /* Get time from internal clock. */ - set_registers(); - } -} - -void update_sync() -{ - if (enable_sync) - { - /* Get time from host. */ - time_get(nvrram); - } - else - { - /* Save time to registers but keep it as is. */ - get_registers(); - } + time_get(nvrram); } void nvr_recalc() { int c; int newrtctime; - c=1<<((nvrram[0xA]&0xF)-1); + c=1<<((nvrram[RTCREGA]&(RTCRS0|RTCRS1|RTCRS2|RTCRS3))-1); newrtctime=(int)(RTCCONST * c * (1 << TIMER_SHIFT)); if (rtctime>newrtctime) rtctime=newrtctime; } @@ -245,42 +32,80 @@ void nvr_recalc() void nvr_rtc(void *p) { int c; - if (!(nvrram[0xA]&0xF)) + if (!(nvrram[RTCREGA]&(RTCRS0|RTCRS1|RTCRS2|RTCRS3))) { rtctime=0x7fffffff; return; } - c=1<<((nvrram[0xA]&0xF)-1); + c=1<<((nvrram[RTCREGA]&(RTCRS0|RTCRS1|RTCRS2|RTCRS3))-1); rtctime += (int)(RTCCONST * c * (1 << TIMER_SHIFT)); // pclog("RTCtime now %f\n",rtctime); - nvrram[0xC] |= 0x40; - if (nvrram[0xB]&0x40) + nvrram[RTCREGC] |= RTCPF; + if (nvrram[RTCREGB]&RTCPIE) { - nvrram[0xC]|=0x80; + nvrram[RTCREGC]|=RTCIRQF; if (AMSTRAD) picint(2); else picint(0x100); // pclog("RTC int\n"); } } +int nvr_update_status = 0; + +#define ALARM_DONTCARE 0xc0 + +int nvr_check_alarm(int nvraddr) +{ + return (nvrram[nvraddr + 1] == nvrram[nvraddr] || (nvrram[nvraddr + 1] & ALARM_DONTCARE) == ALARM_DONTCARE); +} + void nvr_onesec(void *p) { nvr_onesec_cnt++; - if (nvr_onesec_cnt >= 100) + if (nvr_onesec_cnt >= 32768) { nvr_onesec_cnt = 0; - /* If sync is disabled, move internal clock ahead by 1 second. */ - if (!enable_sync) nvr_update_internal_clock(); - nvrram[0xC] |= 0x10; - if (nvrram[0xB] & 0x10) + + /* If sync is disabled, move internal clock ahead by 1 second. */ + if (!(nvrram[RTCREGB] & RTCSET)) { - nvrram[0xC] |= 0x80; - if (AMSTRAD) picint(2); - else picint(0x100); + nvr_update_status = RTCUIP; + if (!enable_sync) rtc_tick(); + nvr_dosave = 1; } -// pclog("RTC onesec\n"); } - nvr_onesec_time += (int)(10000 * TIMER_USEC); + else if (nvr_onesec_cnt == 73) /* 73 of our cycles means 244+1984 us = update in progress time per the specification. */ + { + if (!(nvrram[RTCREGB] & RTCSET)) + { + getnvrtime(); + /* Clear update status. */ + nvr_update_status = 0; + + if (nvr_check_alarm(RTCSECONDS) && nvr_check_alarm(RTCMINUTES) && nvr_check_alarm(RTCHOURS)) + { + nvrram[RTCREGC] |= RTCAF; + if (nvrram[RTCREGB] & RTCAIE) + { + nvrram[RTCREGC] |= RTCIRQF; + if (AMSTRAD) picint(2); + else picint(0x100); + } + } + + /* The flag and interrupt should be issued on update ended, not started. */ + nvrram[RTCREGC] |= RTCUF; + if (nvrram[RTCREGB] & RTCUIE) + { + nvrram[RTCREGC] |= RTCIRQF; + if (AMSTRAD) picint(2); + else picint(0x100); + } +// pclog("RTC onesec\n"); + } + } + /* This is correct! The real RTC's one second timer operates at 32768 Hz, not 100 Hz! */ + nvr_onesec_time += (int)((1000000.0 / 32768.0) * TIMER_USEC); } void writenvr(uint16_t addr, uint8_t val, void *priv) @@ -289,45 +114,48 @@ void writenvr(uint16_t addr, uint8_t val, void *priv) // printf("Write NVR %03X %02X %02X %04X:%04X %i\n",addr,nvraddr,val,cs>>4,pc,ins); if (addr&1) { + if (nvraddr==RTCREGC || nvraddr==RTCREGD) return; /* Registers C and D are read-only. There's no reason to continue. */ // if (nvraddr == 0x33) pclog("NVRWRITE33 %02X %04X:%04X %i\n",val,CS,pc,ins); - old = nvrram[nvraddr]; - if (nvraddr >= 0xe && nvrram[nvraddr] != val) + if (nvraddr > RTCREGD && nvrram[nvraddr] != val) nvr_dosave = 1; - // if (nvraddr==0xB) update_reg_0B(val); - if (nvraddr!=0xC && nvraddr!=0xD) nvrram[nvraddr]=val; + + old = nvrram[nvraddr]; + nvrram[nvraddr]=val; - /* If not syncing the time with the host, we need to update our internal clock on write. */ - if (!enable_sync) - { - switch(nvraddr) - { - case 0: - case 2: - case 4: - case 6: - case 7: - case 8: - case 9: - if (old != val) - { - get_registers(); - nvr_dosave = 1; - } - return; - } - } - - if (nvraddr==0xA) + if (nvraddr==RTCREGA) { // pclog("NVR rate %i\n",val&0xF); - if (val&0xF) + if (val&(RTCRS0|RTCRS1|RTCRS2|RTCRS3)) { - c=1<<((val&0xF)-1); + c=1<<((val&(RTCRS0|RTCRS1|RTCRS2|RTCRS3))-1); rtctime += (int)(RTCCONST * c * (1 << TIMER_SHIFT)); } else rtctime = 0x7fffffff; } + else + { + if (nvraddr==RTCREGB) + { + if (((old ^ val) & RTCSET) && (val & RTCSET)) + { + nvrram[RTCREGA] &= ~RTCUIP; /* This has to be done according to the datasheet. */ + nvrram[RTCREGB] &= ~RTCUIE; /* This also has to happen per the specification. */ + } + } + + if ((nvraddr < RTCREGA) || (nvraddr == RTCCENTURY)) + { + if ((nvraddr != 1) && (nvraddr != 3) && (nvraddr != 5)) + { + if ((old != val) && !enable_sync) + { + time_update(nvrram, nvraddr); + nvr_dosave = 1; + } + } + } + } } else nvraddr=val&nvrmask; } @@ -338,20 +166,14 @@ uint8_t readnvr(uint16_t addr, void *priv) // printf("Read NVR %03X %02X %02X %04X:%04X\n",addr,nvraddr,nvrram[nvraddr],cs>>4,pc); if (addr&1) { - if (nvraddr<=0xA) getnvrtime(); - if (nvraddr==0xD) nvrram[0xD]|=0x80; - if (nvraddr==0xA) - { - temp=nvrram[0xA]; - nvrram[0xA]&=~0x80; - return temp; - } - if (nvraddr==0xC) + if (nvraddr==RTCREGA) return ((nvrram[RTCREGA] & 0x7F) | nvr_update_status); + if (nvraddr==RTCREGD) nvrram[RTCREGD]|=RTCVRT; + if (nvraddr==RTCREGC) { if (AMSTRAD) picintc(2); else picintc(0x100); - temp=nvrram[0xC]; - nvrram[0xC]=0; + temp=nvrram[RTCREGC]; + nvrram[RTCREGC]=0; /* All flags in register C are unused (always 0) or cleared on read */ return temp; } // if (AMIBIOS && nvraddr==0x36) return 0; @@ -379,7 +201,7 @@ void loadnvr() case ROM_IBMPS1_2121: f = romfopen("nvr/ibmps1_2121.nvr", "rb"); nvrmask = 127; 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_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; @@ -413,19 +235,22 @@ void loadnvr() if (!f) { memset(nvrram,0xFF,128); + if (!enable_sync) + { + nvrram[RTCSECONDS] = nvrram[RTCMINUTES] = nvrram[RTCHOURS] = 0; + nvrram[RTCDOM] = nvrram[RTCMONTH] = 1; + nvrram[RTCYEAR] = BCD(80); + nvrram[RTCCENTURY] = BCD(19); + nvrram[RTCREGB]=RTC2412; + } return; } fread(nvrram,128,1,f); - if (!(feof(f))) - fread(internal_time,6,4,f); - else - { - if (!enable_sync) get_registers(); - } + if (!enable_sync) time_update(nvrram, 0xFF); /* Update the internal clock state based on the NVR registers. */ fclose(f); - nvrram[0xA]=6; - nvrram[0xB]=0; - c=1<<((6&0xF)-1); + nvrram[RTCREGA]=(RTCRS1|RTCRS2); + nvrram[RTCREGB]=RTC2412; + c=1<<((nvrram[RTCREGA]&(RTCRS0|RTCRS1|RTCRS2|RTCRS3))-1); rtctime += (int)(RTCCONST * c * (1 << TIMER_SHIFT)); } void savenvr() @@ -443,7 +268,7 @@ void savenvr() case ROM_IBMPS1_2121: f = romfopen("nvr/ibmps1_2121.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_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; @@ -474,10 +299,7 @@ void savenvr() case ROM_KN97: f = romfopen("nvr/kn97.nvr", "wb"); break; default: return; } - /* If sync is disabled, save internal clock to registers. */ - if (!enable_sync) set_registers(); fwrite(nvrram,128,1,f); - fwrite(internal_time,6,4,f); fclose(f); } diff --git a/src/nvr.h b/src/nvr.h index fe3c72e1b..a8ecbfe03 100644 --- a/src/nvr.h +++ b/src/nvr.h @@ -1,11 +1,8 @@ void nvr_init(); -extern int nvr_dosave; extern int enable_sync; -void time_sleep(int count); +extern int nvr_dosave; void time_get(char *nvrram); -void nvr_add_10sec(); -void update_sync(); diff --git a/src/pc.c b/src/pc.c index c5a7b9441..61a8f5fb5 100644 --- a/src/pc.c +++ b/src/pc.c @@ -511,7 +511,7 @@ void runpc() if (win_title_update) { win_title_update=0; - sprintf(s, "PCem v11 [Experimental] - %i%% - %s - %s - %s", fps, model_getname(), models[model].cpu[cpu_manufacturer].cpus[cpu].name, (!mousecapture) ? "Click to capture mouse" : "Press F12-F8 or middle button to release mouse"); + sprintf(s, "PCem v11 [Unofficial] - %i%% - %s - %s - %s", fps, model_getname(), models[model].cpu[cpu_manufacturer].cpus[cpu].name, (!mousecapture) ? "Click to capture mouse" : "Press F12-F8 or middle button to release mouse"); set_window_title(s); } done++; @@ -673,11 +673,9 @@ void loadconfig(char *fn) force_43 = config_get_int(NULL, "force_43", 0); enable_overscan = config_get_int(NULL, "enable_overscan", 0); - cga_color_burst = config_get_int(NULL, "cga_color_burst", 1); - cga_brown = config_get_int(NULL, "cga_brown", 1); enable_flash = config_get_int(NULL, "enable_flash", 1); - enable_sync = config_get_int(NULL, "enable_sync", 0); + enable_sync = config_get_int(NULL, "enable_sync", 1); mouse_always_serial = config_get_int(NULL, "mouse_always_serial", 0); window_w = config_get_int(NULL, "window_w", 0); @@ -768,8 +766,6 @@ void saveconfig() config_set_int(NULL, "force_43", force_43); config_set_int(NULL, "enable_overscan", enable_overscan); - config_set_int(NULL, "cga_color_burst", cga_color_burst); - config_set_int(NULL, "cga_brown", cga_brown); config_set_int(NULL, "enable_flash", enable_flash); config_set_int(NULL, "enable_sync", enable_sync); diff --git a/src/pc.rc b/src/pc.rc index a820d6f35..036b76053 100644 --- a/src/pc.rc +++ b/src/pc.rc @@ -57,13 +57,13 @@ BEGIN END END -ConfigureDlg DIALOGEX 0, 0, 248+40, 248+76 +ConfigureDlg DIALOGEX 0, 0, 248+40, 248+60 STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Configure PCem" FONT 9, "Segoe UI" BEGIN - DEFPUSHBUTTON "OK",IDOK,64,300,50,14, WS_TABSTOP - PUSHBUTTON "Cancel",IDCANCEL,128,300,50,14, WS_TABSTOP + DEFPUSHBUTTON "OK",IDOK,64,284,50,14, WS_TABSTOP + PUSHBUTTON "Cancel",IDCANCEL,128,284,50,14, WS_TABSTOP COMBOBOX IDC_COMBO1,62,16,157,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP COMBOBOX IDC_COMBOVID,62,36,157,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP PUSHBUTTON "Configure", IDC_CONFIGUREVID, 224, 36, 40, 14, WS_TABSTOP @@ -84,22 +84,19 @@ BEGIN CONTROL "Enable time sync",IDC_CHECKSYNC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,236,102,10 CONTROL "Force 4:3 display ratio",IDC_CHECKFORCE43,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,118,172,102,10 - CONTROL "Composite CGA color burst",IDC_CHECKCBURST,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,118,188,102,10 - CONTROL "RGB CGA brown circuit",IDC_CHECKBROWN,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,118,204,102,10 - CONTROL "EGA/(S)VGA overscan",IDC_CHECKOVERSCAN,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,118,220,102,10 - CONTROL "Disk activity flash",IDC_CHECKFLASH,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,118,236,102,10 + CONTROL "EGA/(S)VGA overscan",IDC_CHECKOVERSCAN,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,118,188,102,10 + CONTROL "Disk activity flash",IDC_CHECKFLASH,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,118,204,102,10 + CONTROL "Ser.mouse inst.of PS/2",IDC_CHECKSERIAL,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,118,220,102,10 - CONTROL "Ser. mouse instead of PS/2",IDC_CHECKSERIAL,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,252,102,10 + CONTROL "Voodoo Graphics",IDC_CHECKVOODOO,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,118,236,102,10 + PUSHBUTTON "Configure", IDC_CONFIGUREVOODOO, 224, 236, 40, 14, WS_TABSTOP - CONTROL "Voodoo Graphics",IDC_CHECKVOODOO,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,118,252,102,10 - PUSHBUTTON "Configure", IDC_CONFIGUREVOODOO, 224, 252, 40, 14, WS_TABSTOP - - LTEXT "Joystick :",IDC_STATIC,15,268,40,10 - COMBOBOX IDC_COMBOJOY,62,268,157,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP - DEFPUSHBUTTON "Joystick 1...",IDC_JOY1,16,284,50,14, WS_TABSTOP - PUSHBUTTON "Joystick 2...",IDC_JOY2,80,284,50,14, WS_TABSTOP - DEFPUSHBUTTON "Joystick 3...",IDC_JOY3,144,284,50,14, WS_TABSTOP - PUSHBUTTON "Joystick 4...",IDC_JOY4,208,284,50,14, WS_TABSTOP + LTEXT "Joystick :",IDC_STATIC,15,252,40,10 + COMBOBOX IDC_COMBOJOY,62,252,157,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP + DEFPUSHBUTTON "Joystick 1...",IDC_JOY1,16,268,50,14, WS_TABSTOP + PUSHBUTTON "Joystick 2...",IDC_JOY2,80,268,50,14, WS_TABSTOP + DEFPUSHBUTTON "Joystick 3...",IDC_JOY3,144,268,50,14, WS_TABSTOP + PUSHBUTTON "Joystick 4...",IDC_JOY4,208,268,50,14, WS_TABSTOP LTEXT "Machine :",IDC_STATIC,15,16,40,10 LTEXT "Video :",IDC_STATIC,15,36,34,10 diff --git a/src/resources.h b/src/resources.h index b5c9bccc6..9a24149b8 100644 --- a/src/resources.h +++ b/src/resources.h @@ -51,11 +51,9 @@ #define IDC_STATIC 1020 #define IDC_CHECKFORCE43 1021 #define IDC_CHECKOVERSCAN 1022 -#define IDC_CHECKCBURST 1023 -#define IDC_CHECKBROWN 1024 -#define IDC_CHECKFLASH 1025 -#define IDC_CHECKSYNC 1026 -#define IDC_CHECKSERIAL 1027 +#define IDC_CHECKFLASH 1023 +#define IDC_CHECKSYNC 1024 +#define IDC_CHECKSERIAL 1025 #define IDC_EDIT1 1030 #define IDC_EDIT2 1031 #define IDC_EDIT3 1032 diff --git a/src/rtc.c b/src/rtc.c new file mode 100644 index 000000000..203b4eaa4 --- /dev/null +++ b/src/rtc.c @@ -0,0 +1,261 @@ +/* Emulation of: + Dallas Semiconductor DS12C887 Real Time Clock + + http://datasheets.maximintegrated.com/en/ds/DS12885-DS12C887A.pdf + + http://dev-docs.atariforge.org/files/MC146818A_RTC_1984.pdf + */ + +#include +#include +#include +#include +#include +#include "nvr.h" +#include "rtc.h" + +int enable_sync; + +typedef struct +{ + int sec; + int min; + int hour; + int mday; + int mon; + int year; +} +internal_clock_t; + +internal_clock_t internal_clock; + +/* When the RTC was last updated */ +time_t rtc_set_time = 0; + +/* Table for days in each month */ +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 rtc_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++; + } + nvr_dosave = 1; +} + +/* Called when ticking the second */ +void rtc_tick() +{ + internal_clock.sec++; + rtc_recalc(); +} + +/* Called when modifying the NVR registers */ +void time_update(char *nvrram, int reg) +{ + int temp; + + switch(reg) + { + case RTCSECONDS: + internal_clock.sec = (nvrram[RTCREGB] & RTCDM) ? nvrram[RTCSECONDS] : DCB(nvrram[RTCSECONDS]); + break; + case RTCMINUTES: + internal_clock.min = (nvrram[RTCREGB] & RTCDM) ? nvrram[RTCMINUTES] : DCB(nvrram[RTCMINUTES]); + break; + case RTCHOURS: + temp = (nvrram[RTCREGB] & RTCDM) ? nvrram[RTCHOURS] : DCB(nvrram[RTCHOURS]); + + if (nvrram[RTCREGB] & RTC2412) + { + internal_clock.hour = temp; + } + else + { + internal_clock.hour = ((temp & ~RTCAMPM) % 12) + ((temp & RTCAMPM) ? 12 : 0); + } + break; + case RTCDOM: + internal_clock.mday = (nvrram[RTCREGB] & RTCDM) ? nvrram[RTCDOM] : DCB(nvrram[RTCDOM]); + break; + case RTCMONTH: + internal_clock.mon = (nvrram[RTCREGB] & RTCDM) ? nvrram[RTCMONTH] : DCB(nvrram[RTCMONTH]); + break; + case RTCYEAR: + internal_clock.year = (nvrram[RTCREGB] & RTCDM) ? nvrram[RTCYEAR] : DCB(nvrram[RTCYEAR]); + internal_clock.year += (nvrram[RTCREGB] & RTCDM) ? 1900 : (DCB(nvrram[RTCCENTURY]) * 100); + break; + case RTCCENTURY: + if (nvrram[RTCREGB] & RTCDM) return; + internal_clock.year %= 100; + internal_clock.year += (DCB(nvrram[RTCCENTURY]) * 100); + break; + case 0xFF: /* Load the entire internal clock state from the NVR. */ + internal_clock.sec = (nvrram[RTCREGB] & RTCDM) ? nvrram[RTCSECONDS] : DCB(nvrram[RTCSECONDS]); + internal_clock.min = (nvrram[RTCREGB] & RTCDM) ? nvrram[RTCMINUTES] : DCB(nvrram[RTCMINUTES]); + + temp = (nvrram[RTCREGB] & RTCDM) ? nvrram[RTCHOURS] : DCB(nvrram[RTCHOURS]); + + if (nvrram[RTCREGB] & RTC2412) + { + internal_clock.hour = temp; + } + else + { + internal_clock.hour = ((temp & ~RTCAMPM) % 12) + ((temp & RTCAMPM) ? 12 : 0); + } + + internal_clock.mday = (nvrram[RTCREGB] & RTCDM) ? nvrram[RTCDOM] : DCB(nvrram[RTCDOM]); + internal_clock.mon = (nvrram[RTCREGB] & RTCDM) ? nvrram[RTCMONTH] : DCB(nvrram[RTCMONTH]); + internal_clock.year = (nvrram[RTCREGB] & RTCDM) ? nvrram[RTCYEAR] : DCB(nvrram[RTCYEAR]); + internal_clock.year += (nvrram[RTCREGB] & RTCDM) ? 1900 : (DCB(nvrram[RTCCENTURY]) * 100); + 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 time_internal(struct tm **time_var) +{ + if (*time_var == NULL) *time_var = (struct tm *) malloc(sizeof(struct tm)); + + (*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; +} + +/* Periodic RTC update function + See also: nvr_onesec() in nvr.c + */ +void time_get(char *nvrram) +{ + time_t cur_time; + struct tm* cur_time_tm; + int dow, mon, year; + + if (enable_sync) + { + cur_time = time(NULL); + + /* Mingw doesn't support localtime_r */ + #if __MINGW32__ + cur_time_tm = localtime(&cur_time); + #else + #if __MINGW64__ + cur_time_tm = localtime(&cur_time); + #else + localtime_r(&cur_time, &cur_time_tm); + #endif + #endif + } + else + { + time_internal(&cur_time_tm); + } + + if (nvrram[RTCREGB] & RTCDM) + { + nvrram[RTCSECONDS] = cur_time_tm->tm_sec; + nvrram[RTCMINUTES] = cur_time_tm->tm_min; + nvrram[RTCDOW] = cur_time_tm->tm_wday + 1; + nvrram[RTCDOM] = cur_time_tm->tm_mday; + nvrram[RTCMONTH] = cur_time_tm->tm_mon + 1; + nvrram[RTCYEAR] = cur_time_tm->tm_year % 100; + + if (nvrram[RTCREGB] & RTC2412) + { + nvrram[RTCHOURS] = cur_time_tm->tm_hour; + } + else + { + nvrram[RTCHOURS] = (cur_time_tm->tm_hour % 12) ? (cur_time_tm->tm_hour % 12) : 12; + if (cur_time_tm->tm_hour > 11) + { + nvrram[RTCHOURS] |= RTCAMPM; + } + } + } + else + { + nvrram[RTCSECONDS] = BCD(cur_time_tm->tm_sec); + nvrram[RTCMINUTES] = BCD(cur_time_tm->tm_min); + nvrram[RTCDOW] = BCD(cur_time_tm->tm_wday + 1); + nvrram[RTCDOM] = BCD(cur_time_tm->tm_mday); + nvrram[RTCMONTH] = BCD(cur_time_tm->tm_mon + 1); + nvrram[RTCYEAR] = BCD(cur_time_tm->tm_year % 100); + + if (nvrram[RTCREGB] & RTC2412) + { + nvrram[RTCHOURS] = BCD(cur_time_tm->tm_hour); + } + else + { + nvrram[RTCHOURS] = (cur_time_tm->tm_hour % 12) ? BCD(cur_time_tm->tm_hour % 12) : BCD(12); + if (cur_time_tm->tm_hour > 11) + { + nvrram[RTCHOURS] |= RTCAMPM; + } + } + } +} \ No newline at end of file diff --git a/src/rtc.h b/src/rtc.h new file mode 100644 index 000000000..28a254898 --- /dev/null +++ b/src/rtc.h @@ -0,0 +1,186 @@ +#define BCD(X) (((X) % 10) | (((X) / 10) << 4)) +#define DCB(X) ((((X) & 0xF0) >> 4) * 10 + ((X) & 0x0F)) + +enum RTCADDR +{ + RTCSECONDS, + RTCALARMSECONDS, + RTCMINUTES, + RTCALARMMINUTES, + RTCHOURS, + RTCALARMHOURS, + RTCDOW, + RTCDOM, + RTCMONTH, + RTCYEAR, + RTCREGA, + RTCREGB, + RTCREGC, + RTCREGD +}; + +/* The century register at location 32h is a BCD register designed to automatically load the BCD value 20 as the year register changes from 99 to 00. + The MSB of this register is not affected when the load of 20 occurs, and remains at the value written by the user. */ +#define RTCCENTURY 0x32 + +/* When the 12-hour format is selected, the higher-order bit of the hours byte represents PM when it is logic 1. */ +#define RTCAMPM 0b10000000 + +/* Register A bitflags */ +enum RTCRABITS +{ +/* Rate Selector (RS0) + + These four rate-selection bits select one of the 13 taps on the 15-stage divider or disable the divider output. + The tap selected can be used to generate an output square wave (SQW pin) and/or a periodic interrupt. + The user can do one of the following: + - Enable the interrupt with the PIE bit; + - Enable the SQW output pin with the SQWE bit; + - Enable both at the same time and the same rate; or + - Enable neither. + + Table 3 lists the periodic interrupt rates and the square wave frequencies that can be chosen with the RS bits. + These four read/write bits are not affected by !RESET. */ + RTCRS0 = 0b1, + RTCRS1 = 0b10, /*!cgamode ^ val) & 5) != 0) { + if (((cga->cgamode ^ val) & 5) != 0) + { cga->cgamode = val; update_cga16_color(cga); } @@ -80,9 +80,6 @@ void cga_write(uint32_t addr, uint8_t val, void *p) { cga_t *cga = (cga_t *)p; // pclog("CGA_WRITE %04X %02X\n", addr, val); - /* Horrible hack, I know, but it's the only way to fix the 440FX BIOS filling the VRAM with garbage until Tom fixes the memory emulation. */ - if ((cs == 0xE0000) && (cpu_state.pc == 0xBF2F) && (romset == ROM_440FX)) { egawrites++; return; } - if ((cs == 0xE0000) && (cpu_state.pc == 0xBF77) && (romset == ROM_440FX)) { egawrites++; return; } cga->vram[addr & 0x3fff] = val; cga->charbuffer[ ((int)(((cga->dispontime - cga->vidtime) * 2) / CGACONST)) & 0xfc] = val; cga->charbuffer[(((int)(((cga->dispontime - cga->vidtime) * 2) / CGACONST)) & 0xfc) | 1] = val; @@ -125,18 +122,6 @@ void cga_recalctimings(cga_t *cga) cga->dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT)); } -static int ntsc_col[8][8]= -{ - {0,0,0,0,0,0,0,0}, /*Black*/ - {0,0,1,1,1,1,0,0}, /*Blue*/ - {1,0,0,0,0,1,1,1}, /*Green*/ - {0,0,0,0,1,1,1,1}, /*Cyan*/ - {1,1,1,1,0,0,0,0}, /*Red*/ - {0,1,1,1,1,0,0,0}, /*Magenta*/ - {1,1,0,0,0,0,1,1}, /*Yellow*/ - {1,1,1,1,1,1,1,1} /*White*/ -}; - void cga_poll(void *p) { cga_t *cga = (cga_t *)p; @@ -149,11 +134,7 @@ void cga_poll(void *p) int cols[4]; int col; int oldsc; - int y_buf[8] = {0, 0, 0, 0, 0, 0, 0, 0}, y_val, y_tot; - int i_buf[8] = {0, 0, 0, 0, 0, 0, 0, 0}, i_val, i_tot; - int q_buf[8] = {0, 0, 0, 0, 0, 0, 0, 0}, q_val, q_tot; - int r, g, b; - uint8_t *tline; + if (!cga->linepos) { cga->vidtime += cga->dispofftime; @@ -307,21 +288,12 @@ void cga_poll(void *p) if (cga->cgamode & 1) x = (cga->crtc[1] << 3) + 16; else x = (cga->crtc[1] << 4) + 16; - if (cga_comp) + if (cga->composite) { - tline = (uint8_t *) buffer32->line[cga->displine]; + for (c = 0; c < x; c++) + buffer32->line[cga->displine][c] = buffer->line[cga->displine][c] & 0xf; - for (c = 0; c < x; c++) - { - tarray[c] = buffer->line[cga->displine][c] & 0xf; - } - - Composite_Process(cga, 0, x >> 2, tarray); - - for (c = 0; c < x; c++) - { - ((uint32_t *) tline)[c] = ((uint32_t *) tarray)[c]; - } + Composite_Process(cga, 0, x >> 2, buffer32->line[cga->displine]); } cga->sc = oldsc; @@ -386,8 +358,7 @@ void cga_poll(void *p) { cga->cgadispon = 0; cga->displine = 0; - // cga->vsynctime = (cga->crtc[3] >> 4) + 1; - cga->vsynctime = 16; + cga->vsynctime = 16; if (cga->crtc[7]) { if (cga->cgamode & 1) x = (cga->crtc[1] << 3) + 16; @@ -403,7 +374,7 @@ void cga_poll(void *p) } startblit(); - if (cga_comp) + 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); @@ -445,7 +416,8 @@ endblit(); cga->sc &= 31; cga->ma = cga->maback; } - if (cga->cgadispon) cga->cgastat &= ~1; + 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)) @@ -458,28 +430,27 @@ endblit(); void cga_init(cga_t *cga) { + cga->composite = 0; } void *cga_standalone_init() { - int c; - int cga_tint = -2; + int display_type; cga_t *cga = malloc(sizeof(cga_t)); memset(cga, 0, sizeof(cga_t)); + display_type = device_get_config_int("display_type"); + cga->composite = (display_type != CGA_RGB); + cga->revision = device_get_config_int("composite_type"); + cga->vram = malloc(0x4000); - cga_comp_init(cga); + cga_comp_init(cga); 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); io_sethandler(0x03d0, 0x0010, cga_in, NULL, NULL, cga_out, NULL, NULL, cga); - - for (c = 0; c < 8192; c++) - { - ((uint64_t *) tarray)[c] = 0; - } - overscan_x = overscan_y = 16; + overscan_x = overscan_y = 16; return cga; } @@ -499,26 +470,62 @@ void cga_speed_changed(void *p) cga_recalctimings(cga); } -device_t cga_device = +static device_config_t cga_config[] = { - "CGA (Old)", - 0, - cga_standalone_init, - cga_close, - NULL, - cga_speed_changed, - NULL, - NULL + { + .name = "display_type", + .description = "Display type", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "RGB", + .value = CGA_RGB + }, + { + .description = "Composite", + .value = CGA_COMPOSITE + }, + { + .description = "" + } + }, + .default_int = CGA_RGB + }, + { + .name = "composite_type", + .description = "Composite type", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "Old", + .value = COMPOSITE_OLD + }, + { + .description = "New", + .value = COMPOSITE_NEW + }, + { + .description = "" + } + }, + .default_int = COMPOSITE_OLD + }, + { + .type = -1 + } }; -device_t cga_new_device = +device_t cga_device = { - "CGA (New)", + "CGA", 0, cga_standalone_init, cga_close, NULL, cga_speed_changed, NULL, - NULL + NULL, + cga_config }; diff --git a/src/vid_cga.h b/src/vid_cga.h index 534608731..eb2fb8532 100644 --- a/src/vid_cga.h +++ b/src/vid_cga.h @@ -27,6 +27,9 @@ typedef struct cga_t uint8_t *vram; uint8_t charbuffer[256]; + + int revision; + int composite; } cga_t; void cga_init(cga_t *cga); @@ -37,5 +40,4 @@ uint8_t cga_read(uint32_t addr, void *p); void cga_recalctimings(cga_t *cga); void cga_poll(void *p); -extern device_t cga_new_device; extern device_t cga_device; diff --git a/src/video.c b/src/video.c index 40d6540df..ac11f0e1f 100644 --- a/src/video.c +++ b/src/video.c @@ -51,8 +51,7 @@ static VIDEO_CARD video_cards[] = {"ATI VGA Charger (ATI-28800)", &ati28800_device, GFX_VGACHARGER}, {"ATI VGA Edge-16 (ATI-18800)", &ati18800_device, GFX_VGAEDGE16}, {"Cardex Tseng ET4000/w32p", &et4000w32pc_device, GFX_ET4000W32C}, - {"CGA (New)", &cga_new_device, GFX_NEW_CGA}, - {"CGA (Old)", &cga_device, GFX_CGA}, + {"CGA", &cga_device, GFX_CGA}, {"Cirrus Logic CL-GD5429", &gd5429_device, GFX_CL_GD5429}, {"Diamond Stealth 32 (Tseng ET4000/w32p)", &et4000w32p_device, GFX_ET4000W32}, {"Diamond Stealth 3D 2000 (S3 ViRGE)", &s3_virge_device, GFX_VIRGE}, diff --git a/src/video.h b/src/video.h index 6c411cf8e..af6613e67 100644 --- a/src/video.h +++ b/src/video.h @@ -75,10 +75,6 @@ extern int enable_overscan; extern int overscan_x, overscan_y; /* Forcibly stretch emulated video output to 4:3 or not. */ extern int force_43; -/* Enable CGA brown circuitry. */ -extern int cga_brown; -/* Enable CGA color burst. */ -extern int cga_color_burst; /* Enable disk activity flash. */ extern int enable_flash; diff --git a/src/win-config.c b/src/win-config.c index 4291802b2..52e98bbed 100644 --- a/src/win-config.c +++ b/src/win-config.c @@ -172,12 +172,6 @@ static BOOL CALLBACK config_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPAR h=GetDlgItem(hdlg, IDC_CHECK4); SendMessage(h, BM_SETCHECK, cga_comp, 0); - h=GetDlgItem(hdlg, IDC_CHECKCBURST); - SendMessage(h, BM_SETCHECK, cga_color_burst, 0); - - h=GetDlgItem(hdlg, IDC_CHECKBROWN); - SendMessage(h, BM_SETCHECK, cga_brown, 0); - h=GetDlgItem(hdlg, IDC_CHECKFORCE43); SendMessage(h, BM_SETCHECK, force_43, 0); @@ -340,18 +334,11 @@ static BOOL CALLBACK config_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPAR h = GetDlgItem(hdlg, IDC_CHECKOVERSCAN); enable_overscan = SendMessage(h, BM_GETCHECK, 0, 0); - h = GetDlgItem(hdlg, IDC_CHECKCBURST); - cga_color_burst=SendMessage(h, BM_GETCHECK, 0, 0); - - h = GetDlgItem(hdlg, IDC_CHECKBROWN); - cga_brown=SendMessage(h, BM_GETCHECK, 0, 0); - h = GetDlgItem(hdlg, IDC_CHECKFLASH); enable_flash=SendMessage(h, BM_GETCHECK, 0, 0); h = GetDlgItem(hdlg, IDC_CHECKSYNC); enable_sync = SendMessage(h, BM_GETCHECK, 0, 0); - update_sync(); h = GetDlgItem(hdlg, IDC_CHECKSERIAL); temp_always_serial = SendMessage(h, BM_GETCHECK, 0, 0); diff --git a/src/win-ddraw-fs.cc b/src/win-ddraw-fs.cc index b598d0a28..368d8c388 100644 --- a/src/win-ddraw-fs.cc +++ b/src/win-ddraw-fs.cc @@ -286,8 +286,6 @@ static void ddraw_fs_blit_memtoscreen_8(int x, int y, int w, int h) for (xx = 0; xx < w; xx++) { p[xx] = pal_lookup[buffer->line[y + yy][x + xx]]; - /* If brown circuity is disabled, double the green component. */ - if ((buffer->line[y + yy][x + xx] == 0x16) && !cga_brown) p[xx] += (p[xx] & 0xff00); } } } diff --git a/src/win-ddraw.cc b/src/win-ddraw.cc index d449f42fa..2893b15ef 100644 --- a/src/win-ddraw.cc +++ b/src/win-ddraw.cc @@ -252,8 +252,6 @@ static void ddraw_blit_memtoscreen_8(int x, int y, int w, int h) for (xx = 0; xx < w; xx++) { p[xx] = pal_lookup[buffer->line[y + yy][x + xx]]; - /* If brown circuity is disabled, double the green component. */ - if ((buffer->line[y + yy][x + xx] == 0x16) && !cga_brown) p[xx] += (p[xx] & 0xff00); } } } diff --git a/src/win-time.c b/src/win-time.c deleted file mode 100644 index 4075bbf12..000000000 --- a/src/win-time.c +++ /dev/null @@ -1,48 +0,0 @@ -#include -#include "ibm.h" -#include "nvr.h" - -void time_sleep(int count) -{ - Sleep(count); -} - -void time_get(char *nvrram) -{ - SYSTEMTIME systemtime; - int c, d; - uint8_t baknvr[10]; - - memcpy(baknvr,nvrram,10); - GetLocalTime(&systemtime); - - d = systemtime.wSecond % 10; - c = systemtime.wSecond / 10; - nvrram[0] = d | (c << 4); - d = systemtime.wMinute % 10; - c = systemtime.wMinute / 10; - nvrram[2] = d | (c << 4); - d = systemtime.wHour % 10; - c = systemtime.wHour / 10; - nvrram[4] = d | (c << 4); - d = systemtime.wDayOfWeek % 10; - c = systemtime.wDayOfWeek / 10; - nvrram[6] = d | (c << 4); - d = systemtime.wDay % 10; - c = systemtime.wDay / 10; - nvrram[7] = d | (c << 4); - d = systemtime.wMonth % 10; - c = systemtime.wMonth / 10; - nvrram[8] = d | (c << 4); - d = systemtime.wYear % 10; - c = (systemtime.wYear / 10) % 10; - nvrram[9] = d | (c << 4); - if (baknvr[0] != nvrram[0] || - baknvr[2] != nvrram[2] || - baknvr[4] != nvrram[4] || - baknvr[6] != nvrram[6] || - baknvr[7] != nvrram[7] || - baknvr[8] != nvrram[8] || - baknvr[9] != nvrram[9]) - nvrram[0xA]|=0x80; -} diff --git a/src/win.c b/src/win.c index ef370606c..5ce6ed11c 100644 --- a/src/win.c +++ b/src/win.c @@ -555,7 +555,7 @@ int WINAPI WinMain (HINSTANCE hThisInstance, hwnd = CreateWindowEx ( 0, /* Extended possibilites for variation */ szClassName, /* Classname */ - "PCem v11 [Experimental]", /* Title Text */ + "PCem v11 [Unofficial]", /* Title Text */ WS_OVERLAPPEDWINDOW&~WS_SIZEBOX, /* default window */ CW_USEDEFAULT, /* Windows decides the position */ CW_USEDEFAULT, /* where the window ends up on the screen */ diff --git a/src/x86_ops_int - Cópia.h b/src/x86_ops_int - Cópia.h deleted file mode 100644 index 0cfb959dd..000000000 --- a/src/x86_ops_int - Cópia.h +++ /dev/null @@ -1,77 +0,0 @@ -static int opINT3(uint32_t fetchdat) -{ - if ((cr0 & 1) && (eflags & VM_FLAG) && (IOPL != 3)) - { - x86gpf(NULL,0); - return 1; - } - x86_int_sw(3); - CLOCK_CYCLES((is486) ? 44 : 59); - return 1; -} - -static int opINT(uint32_t fetchdat) -{ - uint8_t temp; - - /*if (msw&1) pclog("INT %i %i %i\n",cr0&1,eflags&VM_FLAG,IOPL);*/ - if ((cr0 & 1) && (eflags & VM_FLAG) && (IOPL != 3)) - { - 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; -/* if (pc == 0x8028009A) - output = 3; - if (pc == 0x80282B6F) - { - __times++; - if (__times == 2) - fatal("WRONG\n"); - } - if (pc == 0x802809CE) - fatal("RIGHT\n");*/ -// if (CS == 0x0028 && pc == 0x80037FE9) -// output = 3; -//if (CS == 0x9087 && pc == 0x3763) -// fatal("Here\n"); -//if (CS==0x9087 && pc == 0x0850) -// output = 1; - -/* if (output && pc == 0x80033008) - { - __times++; - if (__times == 2) - fatal("WRONG\n"); - }*/ -/* if (output && pc == 0x80D8) - { - __times++; - if (__times == 2) - fatal("RIGHT\n"); - }*/ - - x86_int_sw(temp); - return 1; -} - -static int opINTO(uint32_t fetchdat) -{ - if ((cr0 & 1) && (eflags & VM_FLAG) && (IOPL != 3)) - { - x86gpf(NULL,0); - return 1; - } - if (VF_SET()) - { - oldpc = pc; - x86_int_sw(4); - return 1; - } - CLOCK_CYCLES(3); - return 0; -} - diff --git a/src/x86_ops_io - Cópia.h b/src/x86_ops_io - Cópia.h deleted file mode 100644 index c7bde30aa..000000000 --- a/src/x86_ops_io - Cópia.h +++ /dev/null @@ -1,112 +0,0 @@ -static int opIN_AL_imm(uint32_t fetchdat) -{ - uint16_t port = (uint16_t)getbytef(); - check_io_perm(port); - AL = inb(port); - CLOCK_CYCLES(12); - return 0; -} -static int opIN_AX_imm(uint32_t fetchdat) -{ - uint16_t port = (uint16_t)getbytef(); - check_io_perm(port); - check_io_perm(port + 1); - AX = inw(port); - CLOCK_CYCLES(12); - return 0; -} -static int opIN_EAX_imm(uint32_t fetchdat) -{ - uint16_t port = (uint16_t)getbytef(); - check_io_perm(port); - check_io_perm(port + 1); - check_io_perm(port + 2); - check_io_perm(port + 3); - EAX = inl(port); - CLOCK_CYCLES(12); - return 0; -} - -static int opOUT_AL_imm(uint32_t fetchdat) -{ - uint16_t port = (uint16_t)getbytef(); - check_io_perm(port); - outb(port, AL); - CLOCK_CYCLES(10); - if (port == 0x64) - return x86_was_reset; - return 0; -} -static int opOUT_AX_imm(uint32_t fetchdat) -{ - uint16_t port = (uint16_t)getbytef(); - check_io_perm(port); - check_io_perm(port + 1); - outw(port, AX); - CLOCK_CYCLES(10); - return 0; -} -static int opOUT_EAX_imm(uint32_t fetchdat) -{ - uint16_t port = (uint16_t)getbytef(); - check_io_perm(port); - check_io_perm(port + 1); - check_io_perm(port + 2); - check_io_perm(port + 3); - outl(port, EAX); - CLOCK_CYCLES(10); - return 0; -} - -static int opIN_AL_DX(uint32_t fetchdat) -{ - check_io_perm(DX); - AL = inb(DX); - CLOCK_CYCLES(12); - return 0; -} -static int opIN_AX_DX(uint32_t fetchdat) -{ - check_io_perm(DX); - check_io_perm(DX + 1); - AX = inw(DX); - CLOCK_CYCLES(12); - return 0; -} -static int opIN_EAX_DX(uint32_t fetchdat) -{ - check_io_perm(DX); - check_io_perm(DX + 1); - check_io_perm(DX + 2); - check_io_perm(DX + 3); - EAX = inl(DX); - CLOCK_CYCLES(12); - return 0; -} - -static int opOUT_AL_DX(uint32_t fetchdat) -{ - check_io_perm(DX); - outb(DX, AL); - CLOCK_CYCLES(11); - return x86_was_reset; -} -static int opOUT_AX_DX(uint32_t fetchdat) -{ - //pclog("OUT_AX_DX %04X %04X\n", DX, AX); - check_io_perm(DX); - check_io_perm(DX + 1); - outw(DX, AX); - CLOCK_CYCLES(11); - return 0; -} -static int opOUT_EAX_DX(uint32_t fetchdat) -{ - check_io_perm(DX); - check_io_perm(DX + 1); - check_io_perm(DX + 2); - check_io_perm(DX + 3); - outl(DX, EAX); - CLOCK_CYCLES(11); - return 0; -} diff --git a/src/x86_ops_misc.h b/src/x86_ops_misc.h index d23421b89..b93d7cc85 100644 --- a/src/x86_ops_misc.h +++ b/src/x86_ops_misc.h @@ -723,6 +723,16 @@ static int opLOADALL386(uint32_t fetchdat) { uint32_t la_addr = es + EDI; + if (is486 || israpidcad) + { + cpu_state.pc = oldpc; + + // fatal("Illegal instruction %08X\n", fetchdat); + pclog("Illegal instruction %08X\n", fetchdat); + x86illegal(); + return 0; + } + cr0 = readmeml(0, la_addr); flags = readmemw(0, la_addr + 4); eflags = readmemw(0, la_addr + 6);