Merge branch 'master' of ssh://github.com/OBattler/PCem-Unofficial into port-forward-config

This commit is contained in:
RichardG867
2016-07-10 21:58:11 -03:00
34 changed files with 950 additions and 989 deletions

View File

@@ -1,2 +1,7 @@
# PCem-Experimental # PCem Unofficial [![Build Status](http://polar.rol.im:8080/job/PCem-Unofficial/badge/icon)](http://polar.rol.im:8080/job/PCem-Unofficial)
Unofficial experimental branchof the PCem emulator. 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)

View File

@@ -297,7 +297,10 @@ int rep386(int fv)
that high frequency timers still work okay. This amount is different that high frequency timers still work okay. This amount is different
for interpreter and recompiler*/ for interpreter and recompiler*/
int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); 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++; cpu_reps++;
flags_rebuild(); flags_rebuild();

View File

@@ -2,36 +2,34 @@ VPATH = . dosbox resid-fp slirp
CPP = g++.exe CPP = g++.exe
CC = gcc.exe CC = gcc.exe
WINDRES = windres.exe WINDRES = windres.exe
KFLAGS = -O2 -flto -ffast-math -msse -msse2 -mfpmath=387 -mstackrealign 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
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
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 \ 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 \ 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 \ 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 \ 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 \ 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 \ 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_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 \ sound_sb.o sound_sb_dsp.o sound_sn76489.o sound_speaker.o sound_ssi2001.o sound_wss.o sound_ym7128.o \
soundopenal.o tandy_eeprom.o tandy_rom.o timer.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \ soundopenal.o tandy_eeprom.o tandy_rom.o timer.o um8669f.o 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_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_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_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_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 \ 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-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 win-status.o win-video.o x86seg.o x87.o xtide.o pc.res
FMOBJ = dbopl.o 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 SIDOBJ = convolve.o convolve-sse.o envelope.o extfilt.o filter.o pot.o sid.o voice.o wave6581__ST.o wave6581_P_T.o wave6581_PS_.o wave6581_PST.o wave8580__ST.o wave8580_P_T.o wave8580_PS_.o wave8580_PST.o wave.o
SLIRPOBJ = bootp.o ip_icmp.o misc.o socket.o tcp_timer.o cksum.o ip_input.o queue.o tcp_input.o tftp.o debug.o ip_output.o sbuf.o tcp_output.o udp.o if.o mbuf.o slirp.o tcp_subr.o SLIRPOBJ = bootp.o ip_icmp.o misc.o socket.o tcp_timer.o cksum.o ip_input.o queue.o tcp_input.o tftp.o debug.o ip_output.o sbuf.o tcp_output.o udp.o if.o mbuf.o slirp.o tcp_subr.o
LIBS = -mwindows -lwinmm -lopenal.dll -lopenal -lddraw -ldinput8 -ldxguid -ld3d9 -ld3dx9 -lwsock32 -liphlpapi -lstdc++ -static-libstdc++ -static-libgcc -static LIBS = -mwindows -lwinmm -lopenal.dll -lopenal -lddraw -ldinput8 -ldxguid -ld3d9 -ld3dx9 -lwsock32 -liphlpapi -lstdc++ -static-libstdc++ -static-libgcc -static
PCem.exe: $(OBJ) $(FMOBJ) $(SIDOBJ) $(SLIRPOBJ) PCem.exe: $(OBJ) $(DBOBJ) $(SIDOBJ) $(SLIRPOBJ)
$(CC) $(OBJ) $(FMOBJ) $(SIDOBJ) $(SLIRPOBJ) -o "PCem.exe" $(LIBS) $(CC) $(OBJ) $(DBOBJ) $(SIDOBJ) $(SLIRPOBJ) -o "PCem.exe" $(LIBS)
strip "PCem.exe" strip "PCem.exe"
all : PCem.exe all : PCem.exe

View File

@@ -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 \ 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 \ 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 \ 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 \ 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_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 \ sound_sb.o sound_sb_dsp.o sound_sn76489.o sound_speaker.o sound_ssi2001.o sound_wss.o sound_ym7128.o \
soundopenal.o tandy_eeprom.o tandy_rom.o timer.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \ soundopenal.o tandy_eeprom.o tandy_rom.o timer.o um8669f.o 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_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_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_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_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 \ 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-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 win-status.o win-video.o x86seg.o x87.o xtide.o pc.res
FMOBJ = dbopl.o 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 SIDOBJ = convolve.o convolve-sse.o envelope.o extfilt.o filter.o pot.o sid.o voice.o wave6581__ST.o wave6581_P_T.o wave6581_PS_.o wave6581_PST.o wave8580__ST.o wave8580_P_T.o wave8580_PS_.o wave8580_PST.o wave.o
SLIRPOBJ = bootp.o ip_icmp.o misc.o socket.o tcp_timer.o cksum.o ip_input.o queue.o tcp_input.o tftp.o debug.o ip_output.o sbuf.o tcp_output.o udp.o if.o mbuf.o slirp.o tcp_subr.o SLIRPOBJ = bootp.o ip_icmp.o misc.o socket.o tcp_timer.o cksum.o ip_input.o queue.o tcp_input.o tftp.o debug.o ip_output.o sbuf.o tcp_output.o udp.o if.o mbuf.o slirp.o tcp_subr.o
LIBS = -mwindows -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) PCem64.exe: $(OBJ) $(DBOBJ) $(SIDOBJ) $(SLIRPOBJ)
$(CC) $(OBJ) $(FMOBJ) $(SIDOBJ) $(SLIRPOBJ) -o "PCem64.exe" $(LIBS) $(CC) $(OBJ) $(DBOBJ) $(SIDOBJ) $(SLIRPOBJ) -o "PCem64.exe" $(LIBS)
strip "PCem64.exe" strip "PCem64.exe"
all : PCem64.exe all : PCem64.exe

View File

@@ -2,35 +2,34 @@ VPATH = . dosbox resid-fp slirp
CPP = g++.exe CPP = g++.exe
CC = gcc.exe CC = gcc.exe
WINDRES = windres.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 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
BFLAGS = -DRELEASE_BUILD
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 \ 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 \ 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 \ 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 \ 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 \ 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 \ 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_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 \ sound_sb.o sound_sb_dsp.o sound_sn76489.o sound_speaker.o sound_ssi2001.o sound_wss.o sound_ym7128.o \
soundopenal.o tandy_eeprom.o tandy_rom.o timer.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \ soundopenal.o tandy_eeprom.o tandy_rom.o timer.o um8669f.o 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_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_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_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_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 \ 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-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 win-status.o win-video.o x86seg.o x87.o xtide.o pc.res
FMOBJ = dbopl.o 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 SIDOBJ = convolve.o convolve-sse.o envelope.o extfilt.o filter.o pot.o sid.o voice.o wave6581__ST.o wave6581_P_T.o wave6581_PS_.o wave6581_PST.o wave8580__ST.o wave8580_P_T.o wave8580_PS_.o wave8580_PST.o wave.o
SLIRPOBJ = bootp.o ip_icmp.o misc.o socket.o tcp_timer.o cksum.o ip_input.o queue.o tcp_input.o tftp.o debug.o ip_output.o sbuf.o tcp_output.o udp.o if.o mbuf.o slirp.o tcp_subr.o SLIRPOBJ = bootp.o ip_icmp.o misc.o socket.o tcp_timer.o cksum.o ip_input.o queue.o tcp_input.o tftp.o debug.o ip_output.o sbuf.o tcp_output.o udp.o if.o mbuf.o slirp.o tcp_subr.o
LIBS = -mwindows -lwinmm -lopenal.dll -lopenal -lddraw -ldinput8 -ldxguid -ld3d9 -ld3dx9 -lwsock32 -liphlpapi -lstdc++ -static-libstdc++ -static-libgcc -static LIBS = -mwindows -lwinmm -lopenal.dll -lopenal -lddraw -ldinput8 -ldxguid -ld3d9 -ld3dx9 -lwsock32 -liphlpapi -lstdc++ -static-libstdc++ -static-libgcc -static
PCem.exe: $(OBJ) $(FMOBJ) $(SIDOBJ) $(SLIRPOBJ) PCem.exe: $(OBJ) $(DBOBJ) $(SIDOBJ) $(SLIRPOBJ)
$(CC) $(OBJ) $(FMOBJ) $(SIDOBJ) $(SLIRPOBJ) -o "PCem.exe" $(LIBS) $(CC) $(OBJ) $(DBOBJ) $(SIDOBJ) $(SLIRPOBJ) -o "PCem.exe" $(LIBS)
strip "PCem.exe" strip "PCem.exe"
all : PCem.exe all : PCem.exe

View File

@@ -75,6 +75,7 @@ int cpu_use_dynarec;
uint64_t cpu_CR4_mask; uint64_t cpu_CR4_mask;
int is286, is386; int is286, is386;
int israpidcad;
uint64_t tsc = 0; uint64_t tsc = 0;
@@ -228,9 +229,9 @@ CPU cpus_i386[] =
{"i386DX/25", CPU_386DX, 2, 25000000, 1, 0, 0x0308, 0, 0, 0}, {"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/33", CPU_386DX, 3, 33333333, 1, 0, 0x0308, 0, 0, 0},
{"i386DX/40", CPU_386DX, 4, 40000000, 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/25", CPU_RAPIDCAD, 2, 25000000, 1, 0, 0x404, 0, 0, 0},
{"RapidCAD/33", CPU_i486DX, 3, 33333333, 1, 0, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC}, {"RapidCAD/33", CPU_RAPIDCAD, 3, 33333333, 1, 0, 0x404, 0, 0, 0},
{"RapidCAD/40", CPU_i486DX, 4, 40000000, 1, 0, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC}, {"RapidCAD/40", CPU_RAPIDCAD, 4, 40000000, 1, 0, 0x404, 0, 0, 0},
{"", -1, 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*/ {"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/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}, {"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} {"", -1, 0, 0, 0}
}; };
@@ -582,7 +582,8 @@ void cpu_set()
is8086 = (cpu_s->cpu_type > CPU_8088); is8086 = (cpu_s->cpu_type > CPU_8088);
is286 = (cpu_s->cpu_type >= CPU_286); is286 = (cpu_s->cpu_type >= CPU_286);
is386 = (cpu_s->cpu_type >= CPU_386SX); 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); 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_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); 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; timing_jmp_pm_gate = 45;
break; 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: case CPU_486SLC:
x86_setopcodes(ops_386, ops_486_0f, dynarec_ops_386, dynarec_ops_486_0f); x86_setopcodes(ops_386, ops_486_0f, dynarec_ops_386, dynarec_ops_486_0f);
timing_rr = 1; /*register dest - register src*/ timing_rr = 1; /*register dest - register src*/

View File

@@ -13,34 +13,35 @@ extern int cpu, cpu_manufacturer;
/*386 class CPUs*/ /*386 class CPUs*/
#define CPU_386SX 3 #define CPU_386SX 3
#define CPU_386DX 4 #define CPU_386DX 4
#define CPU_486SLC 5 #define CPU_RAPIDCAD 5
#define CPU_486DLC 6 #define CPU_486SLC 6
#define CPU_486DLC 7
/*486 class CPUs*/ /*486 class CPUs*/
#define CPU_i486SX 7 #define CPU_i486SX 8
#define CPU_Am486SX 8 #define CPU_Am486SX 9
#define CPU_Cx486S 9 #define CPU_Cx486S 10
#define CPU_i486DX 10 #define CPU_i486DX 11
#define CPU_Am486DX 11 #define CPU_Am486DX 12
#define CPU_Cx486DX 12 #define CPU_Cx486DX 13
#define CPU_Cx5x86 13 #define CPU_Cx5x86 14
/*586 class CPUs*/ /*586 class CPUs*/
#define CPU_WINCHIP 14 #define CPU_WINCHIP 15
#define CPU_PENTIUM 15 #define CPU_PENTIUM 16
#define CPU_PENTIUMMMX 16 #define CPU_PENTIUMMMX 17
#define CPU_Cx6x86 17 #define CPU_Cx6x86 18
#define CPU_Cx6x86MX 18 #define CPU_Cx6x86MX 19
#define CPU_Cx6x86L 19 #define CPU_Cx6x86L 20
#define CPU_CxGX1 20 #define CPU_CxGX1 21
#define CPU_K5 21 #define CPU_K5 22
#define CPU_5K86 22 #define CPU_5K86 23
#define CPU_K6 23 #define CPU_K6 24
/*686 class CPUs*/ /*686 class CPUs*/
#define CPU_PENTIUMPRO 24 #define CPU_PENTIUMPRO 25
#define CPU_PENTIUM2 25 #define CPU_PENTIUM2 26
#define CPU_PENTIUM2D 26 #define CPU_PENTIUM2D 27
#define MANU_INTEL 0 #define MANU_INTEL 0
#define MANU_AMD 1 #define MANU_AMD 1

View File

@@ -5,13 +5,10 @@
#include <stdint.h> #include <stdint.h>
#include <math.h> #include <math.h>
#include "ibm.h" #include "../ibm.h"
#include "device.h" #include "../device.h"
#include "io.h" #include "../mem.h"
#include "mem.h" #include "../vid_cga.h"
#include "timer.h"
#include "video.h"
#include "vid_cga.h"
#include "vid_cga_comp.h" #include "vid_cga_comp.h"
int CGA_Composite_Table[1024]; 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_bi = (int) (bi*iq_adjust_i + bq*iq_adjust_q);
video_bq = (int) (-bi*iq_adjust_q + bq*iq_adjust_i); video_bq = (int) (-bi*iq_adjust_q + bq*iq_adjust_i);
video_sharpness = (int) (sharpness*256/100); 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) { static Bit8u byte_clamp(int v) {
v >>= 13; v >>= 13;
return v < 0 ? 0 : (v > 255 ? 255 : v); 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) for (x = 0; x < 5; ++x)
OUT(b[x&3]); OUT(b[x&3]);
if ((cga->cgamode & 4) != 0 || !cga_color_burst) { if ((cga->cgamode & 4) != 0) {
// Decode // Decode
int* i = temp + 5; int* i = temp + 5;
Bit32u* srgb = (Bit32u *)TempLine; Bit32u* srgb = (Bit32u *)TempLine;
@@ -256,18 +237,6 @@ Bit8u * Composite_Process(cga_t *cga, Bit8u border, Bit32u blocks/*, bool double
#undef COMPOSITE_CONVERT #undef COMPOSITE_CONVERT
#undef OUT #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; return TempLine;
} }
@@ -343,7 +312,7 @@ void DecreaseSharpness(cga_t *cga)
void cga_comp_init(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. */ /* Making sure this gets reset after reset. */
brightness = 0; brightness = 0;
@@ -353,4 +322,4 @@ void cga_comp_init(cga_t *cga)
hue_offset = 0; hue_offset = 0;
update_cga16_color(cga); update_cga16_color(cga);
} }

View File

@@ -99,13 +99,11 @@ void fdc_reset()
fdc_set_skip_pulses(1, 0); fdc_set_skip_pulses(1, 0);
fdd_stepping_motor_on[0] = fdd_stepping_motor_on[1] = 0; fdd_stepping_motor_on[0] = fdd_stepping_motor_on[1] = 0;
fdd_track_diff[0] = fdd_track_diff[1] = 0; fdd_track_diff[0] = fdd_track_diff[1] = 0;
#if 0
if (!AT) if (!AT)
{ {
fdc.rate = 2; fdc.rate = 2;
// fdc_update_rate(); // fdc_update_rate();
} }
#endif
fdc_state = FDC_STATE_NORMAL; fdc_state = FDC_STATE_NORMAL;
// pclog("Reset FDC\n"); // pclog("Reset FDC\n");
} }

View File

@@ -194,6 +194,7 @@ uint32_t dr[8];
//#define IOPLV86 ((!(msw&1)) || (CPL<=IOPL)) //#define IOPLV86 ((!(msw&1)) || (CPL<=IOPL))
extern int cycles; extern int cycles;
extern int cycles_lost; extern int cycles_lost;
extern int israpidcad;
extern int is486; extern int is486;
extern uint8_t opcode; extern uint8_t opcode;
extern int insc; extern int insc;
@@ -286,7 +287,7 @@ char discfns[2][256];
int driveempty[2]; int driveempty[2];
#define MDA ((gfxcard==GFX_MDA || gfxcard==GFX_HERCULES || gfxcard==GFX_INCOLOR) && (romset<ROM_TANDY || romset>=ROM_IBMAT)) #define MDA ((gfxcard==GFX_MDA || gfxcard==GFX_HERCULES || gfxcard==GFX_INCOLOR) && (romset<ROM_TANDY || 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 PCJR (romset == ROM_IBMPCJR)
#define AMIBIOS (romset==ROM_AMI386 || romset==ROM_AMI486 || romset == ROM_WIN486) #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_TRIO32, /*S3 732/Trio32 (Phoenix)*/
GFX_PHOENIX_TRIO64, /*S3 764/Trio64 (Phoenix)*/ GFX_PHOENIX_TRIO64, /*S3 764/Trio64 (Phoenix)*/
GFX_INCOLOR, /* Hercules InColor */ GFX_INCOLOR, /* Hercules InColor */
GFX_NEW_CGA,
GFX_ET4000W32C, /*Tseng ET4000/W32p (Cardex) */ GFX_ET4000W32C, /*Tseng ET4000/W32p (Cardex) */
GFX_COMPAQ_EGA, /*Compaq EGA*/ GFX_COMPAQ_EGA, /*Compaq EGA*/
GFX_SUPER_EGA, /*Using Chips & Technologies SuperEGA BIOS*/ GFX_SUPER_EGA, /*Using Chips & Technologies SuperEGA BIOS*/
@@ -393,7 +393,7 @@ enum
GFX_MIRO_VISION964, /*S3 Vision964 (Miro Crystal)*/ GFX_MIRO_VISION964, /*S3 Vision964 (Miro Crystal)*/
GFX_CL_GD5446, /*Cirrus Logic CL-GD5446*/ GFX_CL_GD5446, /*Cirrus Logic CL-GD5446*/
GFX_VGAWONDERXL, /*Compaq ATI VGA Wonder XL (28800-5)*/ GFX_VGAWONDERXL, /*Compaq ATI VGA Wonder XL (28800-5)*/
GFX_WD90C11, /*Paradise WD90C11*/ GFX_WD90C11, /*Paradise WD90C11 Standalone*/
GFX_OTI077, /*Oak OTI-077*/ GFX_OTI077, /*Oak OTI-077*/
GFX_MAX GFX_MAX
}; };

View File

@@ -3,6 +3,14 @@
#include "device.h" #include "device.h"
#include "mem.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 enum
{ {
CMD_READ_ARRAY = 0xff, CMD_READ_ARRAY = 0xff,
@@ -18,99 +26,86 @@ enum
typedef struct flash_t typedef struct flash_t
{ {
uint32_t command, status; uint32_t command, status;
uint32_t data_addr1, data_addr2, data_start, boot_start; uint32_t flash_id;
uint32_t main_start[2], main_end[2], main_len[2]; uint8_t type; /* 0 = BXT, 1 = BXB */
uint32_t flash_id, invert_high_pin; uint8_t invert_high_pin; /* 0 = no, 1 = yes */
mem_mapping_t read_mapping, write_mapping; mem_mapping_t mapping[8], mapping_h[8];
mem_mapping_t read_mapping_h, write_mapping_h; uint32_t block_start[4], block_end[4], block_len[4];
uint8_t array[131072];
} flash_t; } flash_t;
static flash_t flash; static flash_t flash;
char flash_path[1024]; 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) static uint8_t flash_read(uint32_t addr, void *p)
{ {
flash_t *flash = (flash_t *)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) switch (flash->command)
{ {
case CMD_READ_ARRAY:
default:
return flash->array[addr];
case CMD_IID: case CMD_IID:
if (addr & 1) if (addr & 1)
return flash->flash_id; return flash->flash_id;
return 0x89; return 0x89;
default: case CMD_READ_STATUS:
return flash->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) static void flash_write(uint32_t addr, uint8_t val, void *p)
{ {
flash_t *flash = (flash_t *)p; flash_t *flash = (flash_t *)p;
int i; 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) switch (flash->command)
{ {
case CMD_ERASE_SETUP: case CMD_ERASE_SETUP:
if (val == CMD_ERASE_CONFIRM) 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) for (i = 0; i < 3; i++)
memset(&rom[flash->data_addr1], 0xff, 0x1000); {
if ((addr & 0x1f000) == flash->data_addr2) if ((addr >= flash->block_start[i]) && (addr <= flash->block_end[i]))
memset(&rom[flash->data_addr2], 0xff, 0x1000); memset(&(flash->array[flash->block_start[i]]), 0xff, flash->block_len[i]);
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]);
flash->status = 0x80; flash->status = 0x80;
} }
@@ -118,9 +113,9 @@ static void flash_write(uint32_t addr, uint8_t val, void *p)
break; break;
case CMD_PROGRAM_SETUP: case CMD_PROGRAM_SETUP:
// pclog("flash_write: program %05x %02x\n", addr & 0x1ffff, val); pclog("flash_write: program %05x %02x\n", addr, val);
if ((addr & 0x1e000) != (flash->boot_start & 0x1e000)) if ((addr & 0x1e000) != (flash->block_start[3] & 0x1e000))
rom[addr & 0x1ffff] = val; flash->array[addr] = val;
flash->command = CMD_READ_STATUS; flash->command = CMD_READ_STATUS;
flash->status = 0x80; flash->status = 0x80;
break; break;
@@ -131,46 +126,42 @@ static void flash_write(uint32_t addr, uint8_t val, void *p)
{ {
case CMD_CLEAR_STATUS: case CMD_CLEAR_STATUS:
flash->status = 0; flash->status = 0;
break; 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;
} }
} }
} }
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; FILE *f;
flash_t *flash = malloc(sizeof(flash_t)); flash_t *flash = malloc(sizeof(flash_t));
char fpath[1024]; 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); // 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); // 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->block_start[0] = 0x04000; /* MAIN BLOCK */
flash->data_addr1 = 0xc000; flash->block_end[0] = 0x1ffff;
flash->data_addr2 = 0xd000; flash->block_start[1] = 0x03000; /* DMI BLOCK */
flash->data_start = 0xc000; flash->block_end[1] = 0x03fff;
flash->boot_start = 0xe000; flash->block_start[2] = 0x04000; /* ESCD BLOCK */
flash->main_start[0] = 0x0000; flash->block_end[2] = 0x04fff;
flash->main_end[0] = 0xbfff; flash->block_start[3] = 0x00000; /* BOOT BLOCK */
flash->main_len[0] = 0xc000; flash->block_end[3] = 0x01fff;
flash->main_start[1] = 0x10000; }
flash->main_end[1] = 0x1ffff; else /* 28F001BX-T */
flash->main_len[1] = 0x10000; {
break; flash->block_start[0] = 0x00000; /* MAIN BLOCK */
case 1: flash->block_end[0] = 0x1bfff;
flash->data_addr1 = 0x1c000; flash->block_start[1] = 0x1c000; /* DMI BLOCK */
flash->data_addr2 = 0x1d000; flash->block_end[1] = 0x1cfff;
flash->data_start = 0x1c000; flash->block_start[2] = 0x1d000; /* ESCD BLOCK */
flash->boot_start = 0x1e000; flash->block_end[2] = 0x1dfff;
flash->main_start[0] = 0x00000; flash->block_start[3] = 0x1e000; /* BOOT BLOCK */
flash->main_end[0] = 0x1bfff; flash->block_end[3] = 0x1ffff;
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->flash_id = (type != 2) ? 0x94 : 0x95; for (i = 0; i < 8; i++)
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)
{ {
mem_mapping_add(&flash->read_mapping_h, mem_mapping_disable(&bios_mapping[i]);
0xfffe0000, mem_mapping_disable(&bios_high_mapping[i]);
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);
} }
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 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); intel_flash_add_mappings_inverted(flash);
strcpy(fpath, flash_path);
strcat(fpath, "dmi.bin");
f = romfopen(fpath, "rb");
if (f)
{
fread(&rom[flash->data_addr1], 0x1000, 1, f);
fclose(f);
}
} }
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); memset(fpath, 0, 1024);
strcpy(fpath, flash_path); strcpy(fpath, flash_path);
strcat(fpath, "escd.bin"); strcat(fpath, "escd.bin");
f = romfopen(fpath, "rb"); f = romfopen(fpath, "rb");
if (f) 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); fclose(f);
} }
#if 0
flash_add_null_mapping();
#endif
return flash; return flash;
} }
/* For AMI BIOS'es - Intel 28F001BXT with high address pin inverted. */ /* For AMI BIOS'es - Intel 28F001BXT with high address pin inverted. */
void *intel_flash_bxt_ami_init() 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. */ /* For Award BIOS'es - Intel 28F001BXT with high address pin not inverted. */
void *intel_flash_bxt_init() 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() void *intel_flash_bxb_init()
{ {
return intel_flash_init(2); return intel_flash_init(FLASH_IS_BXB);
} }
void intel_flash_close(void *p) 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); // pclog("Flash close: Path is: %s\n", flash_path);
if ((romset != ROM_586MC1) && (romset != ROM_MB500N)) /* Save the main block. */
{ memset(fpath, 0, 1024);
memset(fpath, 0, 1024); strcpy(fpath, flash_path);
strcpy(fpath, flash_path); strcat(fpath, "main.bin");
strcat(fpath, "dmi.bin"); f = romfopen(fpath, "wb");
f = romfopen(fpath, "wb"); fwrite(&(flash->array[flash->block_start[BLOCK_MAIN]]), flash->block_len[BLOCK_MAIN], 1, f);
fwrite(&rom[flash->data_addr1], 0x1000, 1, f); fclose(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); memset(fpath, 0, 1024);
strcpy(fpath, flash_path); strcpy(fpath, flash_path);
strcat(fpath, "escd.bin"); strcat(fpath, "escd.bin");
f = romfopen(fpath, "wb"); 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); fclose(f);
free(flash); free(flash);

View File

@@ -1,48 +0,0 @@
#include <sys/time.h>
#include <time.h>
#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;
}

View File

@@ -1647,7 +1647,7 @@ void mem_write_nulll(uint32_t addr, uint32_t val, void *p)
void mem_updatecache() void mem_updatecache()
{ {
flushmmucache(); flushmmucache();
if (!is386) if (!is386 || israpidcad)
{ {
cachesize=256; cachesize=256;
memwaitstate=0; memwaitstate=0;

View File

@@ -441,6 +441,7 @@ void at_batman_init()
sio_init(1); sio_init(1);
fdc37c665_init(); fdc37c665_init();
intel_batman_init(); intel_batman_init();
device_add(&intel_flash_bxt_ami_device);
if (cdrom_channel >= 4) ide_ter_init(); if (cdrom_channel >= 4) ide_ter_init();
} }
@@ -466,7 +467,7 @@ void at_plato_init()
fdc37c665_init(); fdc37c665_init();
/* It seems it uses the same interface as Batman. */ /* It seems it uses the same interface as Batman. */
intel_batman_init(); intel_batman_init();
// device_add(&intel_flash_bxt_ami_device); device_add(&intel_flash_bxt_ami_device);
if (cdrom_channel >= 4) ide_ter_init(); if (cdrom_channel >= 4) ide_ter_init();
} }

390
src/nvr.c
View File

@@ -4,6 +4,7 @@
#include "nvr.h" #include "nvr.h"
#include "pic.h" #include "pic.h"
#include "timer.h" #include "timer.h"
#include "rtc.h"
int oldromset; int oldromset;
int nvrmask=63; int nvrmask=63;
@@ -14,230 +15,16 @@ int nvr_dosave = 0;
static int nvr_onesec_time = 0, nvr_onesec_cnt = 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() void getnvrtime()
{ {
if (enable_sync) time_get(nvrram);
{
/* 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();
}
} }
void nvr_recalc() void nvr_recalc()
{ {
int c; int c;
int newrtctime; int newrtctime;
c=1<<((nvrram[0xA]&0xF)-1); c=1<<((nvrram[RTCREGA]&(RTCRS0|RTCRS1|RTCRS2|RTCRS3))-1);
newrtctime=(int)(RTCCONST * c * (1 << TIMER_SHIFT)); newrtctime=(int)(RTCCONST * c * (1 << TIMER_SHIFT));
if (rtctime>newrtctime) rtctime=newrtctime; if (rtctime>newrtctime) rtctime=newrtctime;
} }
@@ -245,42 +32,80 @@ void nvr_recalc()
void nvr_rtc(void *p) void nvr_rtc(void *p)
{ {
int c; int c;
if (!(nvrram[0xA]&0xF)) if (!(nvrram[RTCREGA]&(RTCRS0|RTCRS1|RTCRS2|RTCRS3)))
{ {
rtctime=0x7fffffff; rtctime=0x7fffffff;
return; return;
} }
c=1<<((nvrram[0xA]&0xF)-1); c=1<<((nvrram[RTCREGA]&(RTCRS0|RTCRS1|RTCRS2|RTCRS3))-1);
rtctime += (int)(RTCCONST * c * (1 << TIMER_SHIFT)); rtctime += (int)(RTCCONST * c * (1 << TIMER_SHIFT));
// pclog("RTCtime now %f\n",rtctime); // pclog("RTCtime now %f\n",rtctime);
nvrram[0xC] |= 0x40; nvrram[RTCREGC] |= RTCPF;
if (nvrram[0xB]&0x40) if (nvrram[RTCREGB]&RTCPIE)
{ {
nvrram[0xC]|=0x80; nvrram[RTCREGC]|=RTCIRQF;
if (AMSTRAD) picint(2); if (AMSTRAD) picint(2);
else picint(0x100); else picint(0x100);
// pclog("RTC int\n"); // 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) void nvr_onesec(void *p)
{ {
nvr_onesec_cnt++; nvr_onesec_cnt++;
if (nvr_onesec_cnt >= 100) if (nvr_onesec_cnt >= 32768)
{ {
nvr_onesec_cnt = 0; nvr_onesec_cnt = 0;
/* If sync is disabled, move internal clock ahead by 1 second. */
if (!enable_sync) nvr_update_internal_clock(); /* If sync is disabled, move internal clock ahead by 1 second. */
nvrram[0xC] |= 0x10; if (!(nvrram[RTCREGB] & RTCSET))
if (nvrram[0xB] & 0x10)
{ {
nvrram[0xC] |= 0x80; nvr_update_status = RTCUIP;
if (AMSTRAD) picint(2); if (!enable_sync) rtc_tick();
else picint(0x100); 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) 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); // printf("Write NVR %03X %02X %02X %04X:%04X %i\n",addr,nvraddr,val,cs>>4,pc,ins);
if (addr&1) 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); // if (nvraddr == 0x33) pclog("NVRWRITE33 %02X %04X:%04X %i\n",val,CS,pc,ins);
old = nvrram[nvraddr]; if (nvraddr > RTCREGD && nvrram[nvraddr] != val)
if (nvraddr >= 0xe && nvrram[nvraddr] != val)
nvr_dosave = 1; 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 (nvraddr==RTCREGA)
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)
{ {
// pclog("NVR rate %i\n",val&0xF); // 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)); rtctime += (int)(RTCCONST * c * (1 << TIMER_SHIFT));
} }
else else
rtctime = 0x7fffffff; 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; 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); // printf("Read NVR %03X %02X %02X %04X:%04X\n",addr,nvraddr,nvrram[nvraddr],cs>>4,pc);
if (addr&1) if (addr&1)
{ {
if (nvraddr<=0xA) getnvrtime(); if (nvraddr==RTCREGA) return ((nvrram[RTCREGA] & 0x7F) | nvr_update_status);
if (nvraddr==0xD) nvrram[0xD]|=0x80; if (nvraddr==RTCREGD) nvrram[RTCREGD]|=RTCVRT;
if (nvraddr==0xA) if (nvraddr==RTCREGC)
{
temp=nvrram[0xA];
nvrram[0xA]&=~0x80;
return temp;
}
if (nvraddr==0xC)
{ {
if (AMSTRAD) picintc(2); if (AMSTRAD) picintc(2);
else picintc(0x100); else picintc(0x100);
temp=nvrram[0xC]; temp=nvrram[RTCREGC];
nvrram[0xC]=0; nvrram[RTCREGC]=0; /* All flags in register C are unused (always 0) or cleared on read */
return temp; return temp;
} }
// if (AMIBIOS && nvraddr==0x36) return 0; // 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_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_CMDPC30: f = romfopen("nvr/cmdpc30.nvr", "rb"); nvrmask = 127; break;
case ROM_AMI286: f = romfopen("nvr/ami286.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_DELL200: f = romfopen("nvr/dell200.nvr", "rb"); nvrmask = 127; break;
case ROM_IBMAT386: f = romfopen("nvr/at386.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_DESKPRO_386: f = romfopen("nvr/deskpro386.nvr", "rb"); break;
@@ -413,19 +235,22 @@ void loadnvr()
if (!f) if (!f)
{ {
memset(nvrram,0xFF,128); 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; return;
} }
fread(nvrram,128,1,f); fread(nvrram,128,1,f);
if (!(feof(f))) if (!enable_sync) time_update(nvrram, 0xFF); /* Update the internal clock state based on the NVR registers. */
fread(internal_time,6,4,f);
else
{
if (!enable_sync) get_registers();
}
fclose(f); fclose(f);
nvrram[0xA]=6; nvrram[RTCREGA]=(RTCRS1|RTCRS2);
nvrram[0xB]=0; nvrram[RTCREGB]=RTC2412;
c=1<<((6&0xF)-1); c=1<<((nvrram[RTCREGA]&(RTCRS0|RTCRS1|RTCRS2|RTCRS3))-1);
rtctime += (int)(RTCCONST * c * (1 << TIMER_SHIFT)); rtctime += (int)(RTCCONST * c * (1 << TIMER_SHIFT));
} }
void savenvr() void savenvr()
@@ -443,7 +268,7 @@ void savenvr()
case ROM_IBMPS1_2121: f = romfopen("nvr/ibmps1_2121.nvr", "wb"); break; case ROM_IBMPS1_2121: f = romfopen("nvr/ibmps1_2121.nvr", "wb"); break;
case ROM_CMDPC30: f = romfopen("nvr/cmdpc30.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_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_DELL200: f = romfopen("nvr/dell200.nvr", "wb"); break;
case ROM_IBMAT386: f = romfopen("nvr/at386.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_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; case ROM_KN97: f = romfopen("nvr/kn97.nvr", "wb"); break;
default: return; default: return;
} }
/* If sync is disabled, save internal clock to registers. */
if (!enable_sync) set_registers();
fwrite(nvrram,128,1,f); fwrite(nvrram,128,1,f);
fwrite(internal_time,6,4,f);
fclose(f); fclose(f);
} }

View File

@@ -1,11 +1,8 @@
void nvr_init(); void nvr_init();
extern int nvr_dosave;
extern int enable_sync; extern int enable_sync;
void time_sleep(int count); extern int nvr_dosave;
void time_get(char *nvrram); void time_get(char *nvrram);
void nvr_add_10sec();
void update_sync();

View File

@@ -511,7 +511,7 @@ void runpc()
if (win_title_update) if (win_title_update)
{ {
win_title_update=0; 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); set_window_title(s);
} }
done++; done++;
@@ -673,11 +673,9 @@ void loadconfig(char *fn)
force_43 = config_get_int(NULL, "force_43", 0); force_43 = config_get_int(NULL, "force_43", 0);
enable_overscan = config_get_int(NULL, "enable_overscan", 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_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); mouse_always_serial = config_get_int(NULL, "mouse_always_serial", 0);
window_w = config_get_int(NULL, "window_w", 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, "force_43", force_43);
config_set_int(NULL, "enable_overscan", enable_overscan); 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_flash", enable_flash);
config_set_int(NULL, "enable_sync", enable_sync); config_set_int(NULL, "enable_sync", enable_sync);

View File

@@ -57,13 +57,13 @@ BEGIN
END END
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 STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Configure PCem" CAPTION "Configure PCem"
FONT 9, "Segoe UI" FONT 9, "Segoe UI"
BEGIN BEGIN
DEFPUSHBUTTON "OK",IDOK,64,300,50,14, WS_TABSTOP DEFPUSHBUTTON "OK",IDOK,64,284,50,14, WS_TABSTOP
PUSHBUTTON "Cancel",IDCANCEL,128,300,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_COMBO1,62,16,157,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
COMBOBOX IDC_COMBOVID,62,36,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 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 "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 "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 "EGA/(S)VGA overscan",IDC_CHECKOVERSCAN,"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 "Disk activity flash",IDC_CHECKFLASH,"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 "Ser.mouse inst.of PS/2",IDC_CHECKSERIAL,"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 "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 LTEXT "Joystick :",IDC_STATIC,15,252,40,10
PUSHBUTTON "Configure", IDC_CONFIGUREVOODOO, 224, 252, 40, 14, WS_TABSTOP COMBOBOX IDC_COMBOJOY,62,252,157,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
DEFPUSHBUTTON "Joystick 1...",IDC_JOY1,16,268,50,14, WS_TABSTOP
LTEXT "Joystick :",IDC_STATIC,15,268,40,10 PUSHBUTTON "Joystick 2...",IDC_JOY2,80,268,50,14, WS_TABSTOP
COMBOBOX IDC_COMBOJOY,62,268,157,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP DEFPUSHBUTTON "Joystick 3...",IDC_JOY3,144,268,50,14, WS_TABSTOP
DEFPUSHBUTTON "Joystick 1...",IDC_JOY1,16,284,50,14, WS_TABSTOP PUSHBUTTON "Joystick 4...",IDC_JOY4,208,268,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 "Machine :",IDC_STATIC,15,16,40,10 LTEXT "Machine :",IDC_STATIC,15,16,40,10
LTEXT "Video :",IDC_STATIC,15,36,34,10 LTEXT "Video :",IDC_STATIC,15,36,34,10

View File

@@ -51,11 +51,9 @@
#define IDC_STATIC 1020 #define IDC_STATIC 1020
#define IDC_CHECKFORCE43 1021 #define IDC_CHECKFORCE43 1021
#define IDC_CHECKOVERSCAN 1022 #define IDC_CHECKOVERSCAN 1022
#define IDC_CHECKCBURST 1023 #define IDC_CHECKFLASH 1023
#define IDC_CHECKBROWN 1024 #define IDC_CHECKSYNC 1024
#define IDC_CHECKFLASH 1025 #define IDC_CHECKSERIAL 1025
#define IDC_CHECKSYNC 1026
#define IDC_CHECKSERIAL 1027
#define IDC_EDIT1 1030 #define IDC_EDIT1 1030
#define IDC_EDIT2 1031 #define IDC_EDIT2 1031
#define IDC_EDIT3 1032 #define IDC_EDIT3 1032

261
src/rtc.c Normal file
View File

@@ -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 <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#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;
}
}
}
}

186
src/rtc.h Normal file
View File

@@ -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, /*!<RS1*/
RTCRS2 = 0b100, /*!<RS2*/
RTCRS3 = 0b1000, /*!<RS3*/
/* DV0
These three bits are used to turn the oscillator on or off and to reset the countdown chain.
A pattern of 010 is the only combination of bits that turn the oscillator on and allow the RTC to keep time.
A pattern of 11x enables the oscillator but holds the countdown chain in reset.
The next update occurs at 500ms after a pattern of 010 is written to DV0, DV1, and DV2. */
RTCDV0 = 0b10000,
RTCDV1 = 0b100000, /*!<DV1*/
RTCDV2 = 0b1000000, /*!<DV2*/
/* Update-In-Progress (UIP)
This bit is a status flag that can be monitored. When the UIP bit is a 1, the update transfer occurs soon.
When UIP is a 0, the update transfer does not occur for at least 244us.
The time, calendar, and alarm information in RAM is fully available for access when the UIP bit is 0.
The UIP bit is read-only and is not affected by !RESET.
Writing the SET bit in Register B to a 1 inhibits any update transfer and clears the UIP status bit. */
RTCUIP = 0b10000000
};
/* Register B bitflags */
enum RTCRBBITS
{
/* Daylight Saving Enable (DSE)
This bit is a read/write bit that enables two daylight saving adjustments when DSE is set to 1.
On the first Sunday in April (or the last Sunday in April in the MC146818A), the time increments from 1:59:59 AM to 3:00:00 AM.
On the last Sunday in October when the time first reaches 1:59:59 AM, it changes to 1:00:00 AM.
When DSE is enabled, the internal logic test for the first/last Sunday condition at midnight.
If the DSE bit is not set when the test occurs, the daylight saving function does not operate correctly.
These adjustments do not occur when the DSE bit is 0. This bit is not affected by internal functions or !RESET. */
RTCDSE = 0b1,
/* 24/12
The 24/12 control bit establishes the format of the hours byte. A 1 indicates the 24-hour mode and a 0 indicates the 12-hour mode.
This bit is read/write and is not affected by internal functions or !RESET. */
RTC2412 = 0b10,
/* Data Mode (DM)
This bit indicates whether time and calendar information is in binary or BCD format.
The DM bit is set by the program to the appropriate format and can be read as required.
This bit is not modified by internal functions or !RESET. A 1 in DM signifies binary data, while a 0 in DM specifies BCD data. */
RTCDM = 0b100,
/* Square-Wave Enable (SQWE)
When this bit is set to 1, a square-wave signal at the frequency set by the rate-selection bits RS3-RS0 is driven out on the SQW pin.
When the SQWE bit is set to 0, the SQW pin is held low. SQWE is a read/write bit and is cleared by !RESET.
SQWE is low if disabled, and is high impedance when VCC is below VPF. SQWE is cleared to 0 on !RESET. */
RTCSQWE = 0b1000,
/* Update-Ended Interrupt Enable (UIE)
This bit is a read/write bit that enables the update-end flag (UF) bit in Register C to assert !IRQ.
The !RESET pin going low or the SET bit going high clears the UIE bit.
The internal functions of the device do not affect the UIE bit, but is cleared to 0 on !RESET. */
RTCUIE = 0b10000,
/* Alarm Interrupt Enable (AIE)
This bit is a read/write bit that, when set to 1, permits the alarm flag (AF) bit in Register C to assert !IRQ.
An alarm interrupt occurs for each second that the three time bytes equal the three alarm bytes, including a don't-care alarm code of binary 11XXXXXX.
The AF bit does not initiate the !IRQ signal when the AIE bit is set to 0.
The internal functions of the device do not affect the AIE bit, but is cleared to 0 on !RESET. */
RTCAIE = 0b100000,
/* Periodic Interrupt Enable (PIE)
The PIE bit is a read/write bit that allows the periodic interrupt flag (PF) bit in Register C to drive the !IRQ pin low.
When the PIE bit is set to 1, periodic interrupts are generated by driving the !IRQ pin low at a rate specified by the RS3-RS0 bits of Register A.
A 0 in the PIE bit blocks the !IRQ output from being driven by a periodic interrupt, but the PF bit is still set at the periodic rate.
PIE is not modified by any internal device functions, but is cleared to 0 on !RESET. */
RTCPIE = 0b1000000,
/* SET
When the SET bit is 0, the update transfer functions normally by advancing the counts once per second.
When the SET bit is written to 1, any update transfer is inhibited, and the program can initialize the time and calendar bytes without an update
occurring in the midst of initializing. Read cycles can be executed in a similar manner. SET is a read/write bit and is not affected by !RESET or
internal functions of the device. */
RTCSET = 0b10000000
};
/* Register C bitflags */
enum RTCRCBITS
{
/* Unused
These bits are unused in Register C. These bits always read 0 and cannot be written. */
RTCRC0 = 0b1,
RTCRC1 = 0b10, /*!<Unused*/
RTCRC2 = 0b100, /*!<Unused*/
RTCRC3 = 0b1000, /*!<Unused*/
/* Update-Ended Interrupt Flag (UF)
This bit is set after each update cycle. When the UIE bit is set to 1, the 1 in UF causes the IRQF bit to be a 1, which asserts the !IRQ pin.
This bit can be cleared by reading Register C or with a !RESET. */
RTCUF = 0b10000,
/* Alarm Interrupt Flag (AF)
A 1 in the AF bit indicates that the current time has matched the alarm time.
If the AIE bit is also 1, the !IRQ pin goes low and a 1 appears in the IRQF bit. This bit can be cleared by reading Register C or with a !RESET. */
RTCAF = 0b100000,
/* Periodic Interrupt Flag (PF)
This bit is read-only and is set to 1 when an edge is detected on the selected tap of the divider chain.
The RS3 through RS0 bits establish the periodic rate. PF is set to 1 independent of the state of the PIE bit.
When both PF and PIE are 1s, the !IRQ signal is active and sets the IRQF bit. This bit can be cleared by reading Register C or with a !RESET. */
RTCPF = 0b1000000,
/* Interrupt Request Flag (IRQF)
The interrupt request flag (IRQF) is set to a 1 when one or more of the following are true:
- PF == PIE == 1
- AF == AIE == 1
- UF == UIE == 1
Any time the IRQF bit is a 1, the !IRQ pin is driven low.
All flag bits are cleared after Register C is read by the program or when the !RESET pin is low. */
RTCIRQF = 0b10000000
};
/* Register D bitflags */
enum RTCRDBITS
{
/* Unused
The remaining bits of Register D are not usable. They cannot be written and they always read 0. */
RTCRD0 = 0b1,
RTCRD1 = 0b10, /*!<Unused*/
RTCRD2 = 0b100, /*!<Unused*/
RTCRD3 = 0b1000, /*!<Unused*/
RTCRD4 = 0b10000, /*!<Unused*/
RTCRD5 = 0b100000, /*!<Unused*/
RTCRD6 = 0b1000000, /*!<Unused*/
/* Valid RAM and Time (VRT)
This bit indicates the condition of the battery connected to the VBAT pin. This bit is not writeable and should always be 1 when read.
If a 0 is ever present, an exhausted internal lithium energy source is indicated and both the contents of the RTC data and RAM data are questionable.
This bit is unaffected by !RESET. */
RTCVRT = 0b10000000
};
void rtc_tick();
void time_update(char *nvrram, int reg);
void time_get(char *nvrram);

View File

@@ -8,14 +8,13 @@
#include "timer.h" #include "timer.h"
#include "video.h" #include "video.h"
#include "vid_cga.h" #include "vid_cga.h"
#include "vid_cga_comp.h" #include "dosbox/vid_cga_comp.h"
static int i_filt[8],q_filt[8]; #define CGA_RGB 0
#define CGA_COMPOSITE 1
static uint8_t tarray[65536]; #define COMPOSITE_OLD 0
#define COMPOSITE_NEW 1
int cga_brown;
int cga_color_burst;
static uint8_t crtcmask[32] = static uint8_t crtcmask[32] =
{ {
@@ -48,7 +47,8 @@ void cga_out(uint16_t addr, uint8_t val, void *p)
} }
return; return;
case 0x3D8: case 0x3D8:
if (((cga->cgamode ^ val) & 5) != 0) { if (((cga->cgamode ^ val) & 5) != 0)
{
cga->cgamode = val; cga->cgamode = val;
update_cga16_color(cga); 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; cga_t *cga = (cga_t *)p;
// pclog("CGA_WRITE %04X %02X\n", addr, val); // 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->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] = val;
cga->charbuffer[(((int)(((cga->dispontime - cga->vidtime) * 2) / CGACONST)) & 0xfc) | 1] = 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)); 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) void cga_poll(void *p)
{ {
cga_t *cga = (cga_t *)p; cga_t *cga = (cga_t *)p;
@@ -149,11 +134,7 @@ void cga_poll(void *p)
int cols[4]; int cols[4];
int col; int col;
int oldsc; 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) if (!cga->linepos)
{ {
cga->vidtime += cga->dispofftime; cga->vidtime += cga->dispofftime;
@@ -307,21 +288,12 @@ void cga_poll(void *p)
if (cga->cgamode & 1) x = (cga->crtc[1] << 3) + 16; if (cga->cgamode & 1) x = (cga->crtc[1] << 3) + 16;
else x = (cga->crtc[1] << 4) + 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++) Composite_Process(cga, 0, x >> 2, buffer32->line[cga->displine]);
{
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];
}
} }
cga->sc = oldsc; cga->sc = oldsc;
@@ -386,8 +358,7 @@ void cga_poll(void *p)
{ {
cga->cgadispon = 0; cga->cgadispon = 0;
cga->displine = 0; cga->displine = 0;
// cga->vsynctime = (cga->crtc[3] >> 4) + 1; cga->vsynctime = 16;
cga->vsynctime = 16;
if (cga->crtc[7]) if (cga->crtc[7])
{ {
if (cga->cgamode & 1) x = (cga->crtc[1] << 3) + 16; if (cga->cgamode & 1) x = (cga->crtc[1] << 3) + 16;
@@ -403,7 +374,7 @@ void cga_poll(void *p)
} }
startblit(); 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); video_blit_memtoscreen(0, cga->firstline - 4, 0, (cga->lastline - cga->firstline) + 8, xsize, (cga->lastline - cga->firstline) + 8);
else else
video_blit_memtoscreen_8(0, cga->firstline - 4, xsize, (cga->lastline - cga->firstline) + 8); video_blit_memtoscreen_8(0, cga->firstline - 4, xsize, (cga->lastline - cga->firstline) + 8);
@@ -445,7 +416,8 @@ endblit();
cga->sc &= 31; cga->sc &= 31;
cga->ma = cga->maback; 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)))) if ((cga->sc == (cga->crtc[10] & 31) || ((cga->crtc[8] & 3) == 3 && cga->sc == ((cga->crtc[10] & 31) >> 1))))
cga->con = 1; cga->con = 1;
if (cga->cgadispon && (cga->cgamode & 1)) if (cga->cgadispon && (cga->cgamode & 1))
@@ -458,28 +430,27 @@ endblit();
void cga_init(cga_t *cga) void cga_init(cga_t *cga)
{ {
cga->composite = 0;
} }
void *cga_standalone_init() void *cga_standalone_init()
{ {
int c; int display_type;
int cga_tint = -2;
cga_t *cga = malloc(sizeof(cga_t)); cga_t *cga = malloc(sizeof(cga_t));
memset(cga, 0, 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->vram = malloc(0x4000);
cga_comp_init(cga); cga_comp_init(cga);
timer_add(cga_poll, &cga->vidtime, TIMER_ALWAYS_ENABLED, 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); 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); 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; return cga;
} }
@@ -499,26 +470,62 @@ void cga_speed_changed(void *p)
cga_recalctimings(cga); cga_recalctimings(cga);
} }
device_t cga_device = static device_config_t cga_config[] =
{ {
"CGA (Old)", {
0, .name = "display_type",
cga_standalone_init, .description = "Display type",
cga_close, .type = CONFIG_SELECTION,
NULL, .selection =
cga_speed_changed, {
NULL, {
NULL .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, 0,
cga_standalone_init, cga_standalone_init,
cga_close, cga_close,
NULL, NULL,
cga_speed_changed, cga_speed_changed,
NULL, NULL,
NULL NULL,
cga_config
}; };

View File

@@ -27,6 +27,9 @@ typedef struct cga_t
uint8_t *vram; uint8_t *vram;
uint8_t charbuffer[256]; uint8_t charbuffer[256];
int revision;
int composite;
} cga_t; } cga_t;
void cga_init(cga_t *cga); 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_recalctimings(cga_t *cga);
void cga_poll(void *p); void cga_poll(void *p);
extern device_t cga_new_device;
extern device_t cga_device; extern device_t cga_device;

View File

@@ -51,8 +51,7 @@ static VIDEO_CARD video_cards[] =
{"ATI VGA Charger (ATI-28800)", &ati28800_device, GFX_VGACHARGER}, {"ATI VGA Charger (ATI-28800)", &ati28800_device, GFX_VGACHARGER},
{"ATI VGA Edge-16 (ATI-18800)", &ati18800_device, GFX_VGAEDGE16}, {"ATI VGA Edge-16 (ATI-18800)", &ati18800_device, GFX_VGAEDGE16},
{"Cardex Tseng ET4000/w32p", &et4000w32pc_device, GFX_ET4000W32C}, {"Cardex Tseng ET4000/w32p", &et4000w32pc_device, GFX_ET4000W32C},
{"CGA (New)", &cga_new_device, GFX_NEW_CGA}, {"CGA", &cga_device, GFX_CGA},
{"CGA (Old)", &cga_device, GFX_CGA},
{"Cirrus Logic CL-GD5429", &gd5429_device, GFX_CL_GD5429}, {"Cirrus Logic CL-GD5429", &gd5429_device, GFX_CL_GD5429},
{"Diamond Stealth 32 (Tseng ET4000/w32p)", &et4000w32p_device, GFX_ET4000W32}, {"Diamond Stealth 32 (Tseng ET4000/w32p)", &et4000w32p_device, GFX_ET4000W32},
{"Diamond Stealth 3D 2000 (S3 ViRGE)", &s3_virge_device, GFX_VIRGE}, {"Diamond Stealth 3D 2000 (S3 ViRGE)", &s3_virge_device, GFX_VIRGE},

View File

@@ -75,10 +75,6 @@ extern int enable_overscan;
extern int overscan_x, overscan_y; extern int overscan_x, overscan_y;
/* Forcibly stretch emulated video output to 4:3 or not. */ /* Forcibly stretch emulated video output to 4:3 or not. */
extern int force_43; 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. */ /* Enable disk activity flash. */
extern int enable_flash; extern int enable_flash;

View File

@@ -172,12 +172,6 @@ static BOOL CALLBACK config_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPAR
h=GetDlgItem(hdlg, IDC_CHECK4); h=GetDlgItem(hdlg, IDC_CHECK4);
SendMessage(h, BM_SETCHECK, cga_comp, 0); 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); h=GetDlgItem(hdlg, IDC_CHECKFORCE43);
SendMessage(h, BM_SETCHECK, force_43, 0); 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); h = GetDlgItem(hdlg, IDC_CHECKOVERSCAN);
enable_overscan = SendMessage(h, BM_GETCHECK, 0, 0); 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); h = GetDlgItem(hdlg, IDC_CHECKFLASH);
enable_flash=SendMessage(h, BM_GETCHECK, 0, 0); enable_flash=SendMessage(h, BM_GETCHECK, 0, 0);
h = GetDlgItem(hdlg, IDC_CHECKSYNC); h = GetDlgItem(hdlg, IDC_CHECKSYNC);
enable_sync = SendMessage(h, BM_GETCHECK, 0, 0); enable_sync = SendMessage(h, BM_GETCHECK, 0, 0);
update_sync();
h = GetDlgItem(hdlg, IDC_CHECKSERIAL); h = GetDlgItem(hdlg, IDC_CHECKSERIAL);
temp_always_serial = SendMessage(h, BM_GETCHECK, 0, 0); temp_always_serial = SendMessage(h, BM_GETCHECK, 0, 0);

View File

@@ -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++) for (xx = 0; xx < w; xx++)
{ {
p[xx] = pal_lookup[buffer->line[y + yy][x + 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);
} }
} }
} }

View File

@@ -252,8 +252,6 @@ static void ddraw_blit_memtoscreen_8(int x, int y, int w, int h)
for (xx = 0; xx < w; xx++) for (xx = 0; xx < w; xx++)
{ {
p[xx] = pal_lookup[buffer->line[y + yy][x + 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);
} }
} }
} }

View File

@@ -1,48 +0,0 @@
#include <windows.h>
#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;
}

View File

@@ -555,7 +555,7 @@ int WINAPI WinMain (HINSTANCE hThisInstance,
hwnd = CreateWindowEx ( hwnd = CreateWindowEx (
0, /* Extended possibilites for variation */ 0, /* Extended possibilites for variation */
szClassName, /* Classname */ szClassName, /* Classname */
"PCem v11 [Experimental]", /* Title Text */ "PCem v11 [Unofficial]", /* Title Text */
WS_OVERLAPPEDWINDOW&~WS_SIZEBOX, /* default window */ WS_OVERLAPPEDWINDOW&~WS_SIZEBOX, /* default window */
CW_USEDEFAULT, /* Windows decides the position */ CW_USEDEFAULT, /* Windows decides the position */
CW_USEDEFAULT, /* where the window ends up on the screen */ CW_USEDEFAULT, /* where the window ends up on the screen */

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -723,6 +723,16 @@ static int opLOADALL386(uint32_t fetchdat)
{ {
uint32_t la_addr = es + EDI; 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); cr0 = readmeml(0, la_addr);
flags = readmemw(0, la_addr + 4); flags = readmemw(0, la_addr + 4);
eflags = readmemw(0, la_addr + 6); eflags = readmemw(0, la_addr + 6);