Added Toshiba T1000 emulation. Patch from John Elliott.

This commit is contained in:
SarahW 2018-01-10 20:44:31 +00:00
commit c40a421700
25 changed files with 1746 additions and 32 deletions

View file

@ -19,16 +19,16 @@ dells200.c device.c disc.c disc_fdi.c disc_img.c disc_sector.c dma.c esdi_at.c f
hdd.c hdd_esdi.c hdd_file.c headland.c i430lx.c i430fx.c i430vx.c ide.c intel.c intel_flash.c io.c jim.c joystick_ch_flightstick_pro.c joystick_standard.c joystick_sw_pad.c \
joystick_tm_fcs.c keyboard.c keyboard_amstrad.c keyboard_at.c keyboard_olim24.c keyboard_pcjr.c keyboard_xt.c \
laserxt.c lpt.c lpt_dac.c lpt_dss.c mca.c mcr.c mem.c mfm_at.c mfm_xebec.c model.c mouse.c mouse_msystems.c mouse_ps2.c mouse_serial.c neat.c nmi.c nvr.c olivetti_m24.c \
opti495.c paths.c pc.c pci.c pic.c piix.c pit.c ppi.c ps1.c ps2.c ps2_mca.c ps2_nvr.c rom.c rtc.c scat.c scsi.c scsi_53c400.c scsi_aha1540.c scsi_cd.c scsi_hd.c \
opti495.c paths.c pc.c pci.c pic.c piix.c pit.c ppi.c ps1.c ps2.c ps2_mca.c ps2_nvr.c nvr_tc8521.c rom.c rtc.c rtc_tc8521.c scat.c scsi.c scsi_53c400.c scsi_aha1540.c scsi_cd.c scsi_hd.c \
serial.c sio.c sis496.c sound.c sound_ad1848.c sound_adlib.c sound_adlibgold.c sound_audiopci.c sound_cms.c sound_emu8k.c sound_gus.c \
sound_mpu401_uart.c sound_opl.c sound_pas16.c sound_ps1.c sound_pssj.c sound_sb.c sound_sb_dsp.c sound_sn76489.c \
sound_speaker.c sound_ssi2001.c sound_wss.c sound_ym7128.c soundopenal.c tandy_eeprom.c tandy_rom.c \
t3100e.c \
t1000.c t3100e.c \
timer.c um8669f.c um8881f.c vid_ati_eeprom.c vid_ati_mach64.c vid_ati18800.c vid_ati28800.c \
vid_ati68860_ramdac.c vid_cga.c vid_cl5429.c vid_colorplus.c vid_ega.c vid_et4000.c vid_et4000w32.c vid_genius.c vid_hercules.c \
vid_icd2061.c vid_ics2595.c vid_incolor.c vid_mda.c vid_olivetti_m24.c vid_oti067.c vid_paradise.c vid_pc200.c \
vid_pc1512.c vid_pc1640.c vid_pcjr.c vid_ps1_svga.c vid_s3.c vid_s3_virge.c vid_sdac_ramdac.c \
vid_stg_ramdac.c vid_svga.c vid_svga_render.c vid_t3100e.c vid_tandy.c vid_tandysl.c vid_tgui9440.c \
vid_stg_ramdac.c vid_svga.c vid_svga_render.c vid_t1000.c vid_t3100e.c vid_tandy.c vid_tandysl.c vid_tgui9440.c \
vid_tkd8001_ramdac.c vid_tvga.c vid_unk_ramdac.c vid_vga.c vid_voodoo.c video.c wd76c10.c vid_wy700.c \
x86seg.c x87.c xtide.c sound_dbopl.cc sound_resid.cc dosbox/cdrom_image.cpp dosbox/dbopl.cpp \
dosbox/nukedopl.cpp dosbox/vid_cga_comp.c resid-fp/convolve.cc resid-fp/convolve-sse.cc resid-fp/envelope.cc \

View file

@ -9,16 +9,16 @@ codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing
dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \
hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.o ide.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.o joystick_standard.o joystick_sw_pad.o \
joystick_tm_fcs.o keyboard.o keyboard_amstrad.o keyboard_at.o keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o \
laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \
opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o \
laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o \
opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o rtc_tc8521.o scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o \
serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.o sound_cms.o sound_emu8k.o sound_gus.o \
sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.o sound_sb.o sound_sb_dsp.o sound_sn76489.o \
sound_speaker.o sound_ssi2001.o sound_wss.o sound_ym7128.o soundopenal.o t3100e.o tandy_eeprom.o tandy_rom.o \
sound_speaker.o sound_ssi2001.o sound_wss.o sound_ym7128.o soundopenal.o t1000.o t3100e.o tandy_eeprom.o tandy_rom.o \
timer.o um8669f.o um8881f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o vid_ati28800.o \
vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_ega.o vid_et4000.o vid_et4000w32.o vid_genius.o vid_hercules.o \
vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o vid_olivetti_m24.o vid_oti067.o vid_paradise.o vid_pc200.o \
vid_pc1512.o vid_pc1640.o vid_pcjr.o vid_ps1_svga.o vid_s3.o vid_s3_virge.o vid_sdac_ramdac.o \
vid_stg_ramdac.o vid_svga.o vid_svga_render.o vid_t3100e.o vid_tandy.o vid_tandysl.o vid_tgui9440.o \
vid_stg_ramdac.o vid_svga.o vid_svga_render.o vid_t1000.o vid_t3100e.o vid_tandy.o vid_tandysl.o vid_tgui9440.o \
vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o vid_vga.o vid_voodoo.o vid_wy700.o video.o wd76c10.o \
x86seg.o x87.o xtide.o sound_dbopl.o sound_resid.o \
wx-main.o wx-config_sel.o wx-dialogbox.o wx-utils.o wx-app.o wx-sdl2-joystick.o wx-sdl2-mouse.o wx-sdl2-keyboard.o wx-sdl2-video.o wx-sdl2-midi.o \

View file

@ -9,16 +9,16 @@ codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing
dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \
hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.o ide.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.o joystick_standard.o joystick_sw_pad.o \
joystick_tm_fcs.o keyboard.o keyboard_amstrad.o keyboard_at.o keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o \
laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \
opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o \
laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o \
opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o rtc_tc8521.o scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o \
serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.o sound_cms.o sound_emu8k.o sound_gus.o \
sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.o sound_sb.o sound_sb_dsp.o sound_sn76489.o \
sound_speaker.o sound_ssi2001.o sound_wss.o sound_ym7128.o soundopenal.o t3100e.o tandy_eeprom.o tandy_rom.o \
sound_speaker.o sound_ssi2001.o sound_wss.o sound_ym7128.o soundopenal.o t1000.o t3100e.o tandy_eeprom.o tandy_rom.o \
timer.o um8669f.o um8881f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o vid_ati28800.o \
vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_ega.o vid_et4000.o vid_et4000w32.o vid_genius.o vid_hercules.o \
vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o vid_olivetti_m24.o vid_oti067.o vid_paradise.o vid_pc200.o \
vid_pc1512.o vid_pc1640.o vid_pcjr.o vid_ps1_svga.o vid_s3.o vid_s3_virge.o vid_sdac_ramdac.o \
vid_stg_ramdac.o vid_svga.o vid_svga_render.o vid_t3100e.o vid_tandy.o vid_tandysl.o vid_tgui9440.o \
vid_stg_ramdac.o vid_svga.o vid_svga_render.o vid_t1000.o vid_t3100e.o vid_tandy.o vid_tandysl.o vid_tgui9440.o \
vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o vid_vga.o vid_voodoo.o vid_wy700.o video.o wd76c10.o \
x86seg.o x87.o xtide.o sound_dbopl.o sound_resid.o \
wx-main.o wx-config_sel.o wx-dialogbox.o wx-utils.o wx-app.o wx-sdl2-joystick.o wx-sdl2-mouse.o wx-sdl2-keyboard.o wx-sdl2-video.o wx-sdl2-midi.o \

View file

@ -8,16 +8,16 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad
dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o \
i430vx.o ide.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.o joystick_standard.o joystick_sw_pad.o joystick_tm_fcs.o keyboard.o keyboard_amstrad.o keyboard_at.o \
keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o \
mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o \
mouse_serial.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o rtc_tc8521.o \
scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.o sound_cms.o sound_dbopl.o \
sound_emu8k.o sound_gus.o sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.o sound_resid.o \
sound_sb.o sound_sb_dsp.o sound_sn76489.o sound_speaker.o sound_ssi2001.o sound_wss.o \
sound_ym7128.o soundopenal.o t3100e.o tandy_eeprom.o tandy_rom.o timer.o um8881f.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \
sound_ym7128.o soundopenal.o t1000.o t3100e.o tandy_eeprom.o tandy_rom.o timer.o um8881f.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \
vid_ati28800.o vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_ega.o vid_et4000.o \
vid_et4000w32.o vid_et4000w32i.o vid_genius.o vid_hercules.o vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o \
vid_olivetti_m24.o vid_oti067.o vid_paradise.o vid_pc1512.o vid_pc1640.o vid_pc200.o \
vid_pcjr.o vid_ps1_svga.o vid_s3.o vid_s3_virge.o vid_sdac_ramdac.o vid_stg_ramdac.o vid_svga.o \
vid_svga_render.o vid_t3100e.o vid_tandy.o vid_tandysl.o vid_tgui9440.o vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o \
vid_svga_render.o vid_t1000.o vid_t3100e.o vid_tandy.o vid_tandysl.o vid_tgui9440.o vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o \
vid_vga.o vid_voodoo.o vid_wy700.o video.o wd76c10.o win.o win-config.o win-config_sel.o win-d3d.o win-d3d-fs.o win-ddraw.o \
win-ddraw-fs.o win-deviceconfig.o win-hdconf.o win-joystick.o win-joystickconfig.o win-keyboard.o win-midi.o win-mouse.o \
win-status.o win-video.o x86seg.o x87.o xtide.o pc.res

View file

@ -9,16 +9,16 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad
dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o \
i430vx.o ide.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.o joystick_standard.o joystick_sw_pad.o joystick_tm_fcs.o keyboard.o keyboard_amstrad.o keyboard_at.o \
keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o \
mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o \
mouse_serial.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o rtc_tc8521.o \
scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.o sound_cms.o sound_dbopl.o \
sound_emu8k.o sound_gus.o sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.o sound_resid.o \
sound_sb.o sound_sb_dsp.o sound_sn76489.o sound_speaker.o sound_ssi2001.o sound_wss.o \
sound_ym7128.o soundopenal.o t3100e.o tandy_eeprom.o tandy_rom.o timer.o um8881f.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \
sound_ym7128.o soundopenal.o t1000.o t3100e.o tandy_eeprom.o tandy_rom.o timer.o um8881f.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \
vid_ati28800.o vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_ega.o vid_et4000.o \
vid_et4000w32.o vid_et4000w32i.o vid_genius.o vid_hercules.o vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o \
vid_olivetti_m24.o vid_oti067.o vid_paradise.o vid_pc1512.o vid_pc1640.o vid_pc200.o \
vid_pcjr.o vid_ps1_svga.o vid_s3.o vid_s3_virge.o vid_sdac_ramdac.o vid_stg_ramdac.o vid_svga.o \
vid_svga_render.o vid_t3100e.o vid_tandy.o vid_tandysl.o vid_tgui9440.o vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o \
vid_svga_render.o vid_t1000.o vid_t3100e.o vid_tandy.o vid_tandysl.o vid_tgui9440.o vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o \
vid_vga.o vid_voodoo.o vid_wy700.o video.o wd76c10.o win.o win-config.o win-config_sel.o win-d3d.o win-d3d-fs.o win-ddraw.o \
win-ddraw-fs.o win-deviceconfig.o win-hdconf.o win-joystick.o win-joystickconfig.o win-keyboard.o win-midi.o win-mouse.o \
win-networkconfig.o win-status.o win-video.o x86seg.o x87.o xtide.o pc.res

View file

@ -11,16 +11,16 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad
device.o dells200.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o \
i430vx.o ide.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.o joystick_standard.o joystick_sw_pad.o joystick_tm_fcs.o keyboard.o keyboard_amstrad.o keyboard_at.o \
keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o \
mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o \
mouse_serial.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o rtc_tc8521.o \
scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.o sound_cms.o sound_dbopl.o \
sound_emu8k.o sound_gus.o sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.o sound_resid.o \
sound_sb.o sound_sb_dsp.o sound_sn76489.o sound_speaker.o sound_ssi2001.o sound_wss.o \
sound_ym7128.o soundopenal.o t3100e.o tandy_eeprom.o tandy_rom.o timer.o um8881f.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \
sound_ym7128.o soundopenal.o t1000.o t3100e.o tandy_eeprom.o tandy_rom.o timer.o um8881f.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \
vid_ati28800.o vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_ega.o vid_et4000.o \
vid_et4000w32.o vid_et4000w32i.o vid_genius.o vid_hercules.o vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o \
vid_olivetti_m24.o vid_oti067.o vid_paradise.o vid_pc1512.o vid_pc1640.o vid_pc200.o \
vid_pcjr.o vid_ps1_svga.o vid_s3.o vid_s3_virge.o vid_sdac_ramdac.o vid_stg_ramdac.o vid_svga.o \
vid_svga_render.o vid_t3100e.o vid_tandy.o vid_tandysl.o vid_tgui9440.o vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o \
vid_svga_render.o vid_t1000.o vid_t3100e.o vid_tandy.o vid_tandysl.o vid_tgui9440.o vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o \
vid_vga.o vid_voodoo.o vid_wy700.o video.o wd76c10.o x86seg.o x87.o xtide.o win-midi.o \
wx-main.o wx-config_sel.o wx-dialogbox.o wx-utils.o wx-app.o wx-sdl2-joystick.o wx-sdl2-mouse.o wx-sdl2-keyboard.o wx-sdl2-video.o \
wx-sdl2.o wx-config.o wx-deviceconfig.o wx-status.o wx-sdl2-status.o wx-resources.o wx-thread.o wx-common.o wx-sdl2-display-win.o \

View file

@ -11,16 +11,16 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad
device.o dells200.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o \
i430vx.o ide.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.o joystick_standard.o joystick_sw_pad.o joystick_tm_fcs.o keyboard.o keyboard_amstrad.o keyboard_at.o \
keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o \
mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o \
mouse_serial.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o rtc_tc8521.o \
scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.o sound_cms.o sound_dbopl.o \
sound_emu8k.o sound_gus.o sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.o sound_resid.o \
sound_sb.o sound_sb_dsp.o sound_sn76489.o sound_speaker.o sound_ssi2001.o sound_wss.o \
sound_ym7128.o soundopenal.o t3100e.o tandy_eeprom.o tandy_rom.o timer.o um8881f.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \
sound_ym7128.o soundopenal.o t1000.o t3100e.o tandy_eeprom.o tandy_rom.o timer.o um8881f.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \
vid_ati28800.o vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_ega.o vid_et4000.o \
vid_et4000w32.o vid_et4000w32i.o vid_genius.o vid_hercules.o vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o \
vid_olivetti_m24.o vid_oti067.o vid_paradise.o vid_pc1512.o vid_pc1640.o vid_pc200.o \
vid_pcjr.o vid_ps1_svga.o vid_s3.o vid_s3_virge.o vid_sdac_ramdac.o vid_stg_ramdac.o vid_svga.o \
vid_svga_render.o vid_t3100e.o vid_tandy.o vid_tandysl.o vid_tgui9440.o vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o \
vid_svga_render.o vid_t1000.o vid_t3100e.o vid_tandy.o vid_tandysl.o vid_tgui9440.o vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o \
vid_vga.o vid_voodoo.o vid_wy700.o video.o wd76c10.o x86seg.o x87.o xtide.o win-midi.o \
wx-main.o wx-config_sel.o wx-dialogbox.o wx-utils.o wx-app.o wx-sdl2-joystick.o wx-sdl2-mouse.o wx-sdl2-keyboard.o wx-sdl2-video.o \
wx-sdl2.o wx-config.o wx-deviceconfig.o wx-hostconfig.o wx-status.o wx-sdl2-status.o wx-resources.o wx-thread.o wx-common.o wx-sdl2-display-win.o \

View file

@ -8,16 +8,16 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad
dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o \
i430vx.o ide.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.o joystick_standard.o joystick_sw_pad.o joystick_tm_fcs.o keyboard.o keyboard_amstrad.o keyboard_at.o \
keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o \
mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o \
mouse_serial.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o rtc_tc8521.o \
scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.o sound_cms.o sound_dbopl.o \
sound_emu8k.o sound_gus.o sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.o sound_resid.o \
sound_sb.o sound_sb_dsp.o sound_sn76489.o sound_speaker.o sound_ssi2001.o sound_wss.o sound_ym7128.o \
soundopenal.o t3100e.o tandy_eeprom.o tandy_rom.o timer.o um8881f.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \
soundopenal.o t1000.o t3100e.o tandy_eeprom.o tandy_rom.o timer.o um8881f.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \
vid_ati28800.o vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_ega.o vid_et4000.o \
vid_et4000w32.o vid_et4000w32i.o vid_genius.o vid_hercules.o vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o \
vid_olivetti_m24.o vid_oti067.o vid_paradise.o vid_pc1512.o vid_pc1640.o vid_pc200.o \
vid_pcjr.o vid_ps1_svga.o vid_s3.o vid_s3_virge.o vid_sdac_ramdac.o vid_stg_ramdac.o vid_svga.o \
vid_svga_render.o vid_t3100e.o vid_tandy.o vid_tandysl.o vid_tgui9440.o vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o \
vid_svga_render.o vid_t1000.o vid_t3100e.o vid_tandy.o vid_tandysl.o vid_tgui9440.o vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o \
vid_vga.o vid_voodoo.o vid_wy700.o video.o wd76c10.o win.o win-config.o win-config_sel.o win-d3d.o win-d3d-fs.o win-ddraw.o \
win-ddraw-fs.o win-deviceconfig.o win-hdconf.o win-joystick.o win-joystickconfig.o win-keyboard.o win-midi.o win-mouse.o \
win-status.o win-video.o x86seg.o x87.o xtide.o pc.res

View file

@ -8,16 +8,16 @@ codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing
device.o dells200.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \
hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.o ide.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.o joystick_standard.o joystick_sw_pad.o \
joystick_tm_fcs.o keyboard.o keyboard_amstrad.o keyboard_at.o keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o \
laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \
opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o \
laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o \
opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o rtc_tc8521.o scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o \
serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.o sound_cms.o sound_emu8k.o sound_gus.o \
sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.o sound_sb.o sound_sb_dsp.o sound_sn76489.o \
sound_speaker.o sound_ssi2001.o sound_wss.o sound_ym7128.o soundopenal.o t3100e.o tandy_eeprom.o tandy_rom.o \
sound_speaker.o sound_ssi2001.o sound_wss.o sound_ym7128.o soundopenal.o t1000.o t3100e.o tandy_eeprom.o tandy_rom.o \
timer.o um8669f.o um8881f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o vid_ati28800.o \
vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_ega.o vid_et4000.o vid_et4000w32.o vid_genius.o vid_hercules.o \
vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o vid_olivetti_m24.o vid_oti067.o vid_paradise.o vid_pc200.o \
vid_pc1512.o vid_pc1640.o vid_pcjr.o vid_ps1_svga.o vid_s3.o vid_s3_virge.o vid_sdac_ramdac.o \
vid_stg_ramdac.o vid_svga.o vid_svga_render.o vid_t3100e.o vid_tandy.o vid_tandysl.o vid_tgui9440.o \
vid_stg_ramdac.o vid_svga.o vid_svga_render.o vid_t1000.o vid_t3100e.o vid_tandy.o vid_tandysl.o vid_tgui9440.o \
vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o vid_vga.o vid_voodoo.o vid_wy700.o video.o wd76c10.o \
x86seg.o x87.o xtide.o sound_dbopl.o sound_resid.o \
wx-main.o wx-config_sel.o wx-dialogbox.o wx-utils.o wx-app.o wx-sdl2-joystick.o wx-sdl2-mouse.o wx-sdl2-keyboard.o wx-sdl2-video.o wx-sdl2-midi.o \

View file

@ -11,6 +11,7 @@ void fdc_set_dskchg_activelow();
void fdc_3f1_enable(int enable);
void fdc_set_ps1();
int fdc_get_bitcell_period();
uint8_t fdc_read(uint16_t addr, void *priv);
/* A few functions to communicate between Super I/O chips and the FDC. */
void fdc_update_is_nsc(int is_nsc);

View file

@ -378,7 +378,7 @@ char discfns[2][256];
int driveempty[2];
#define MDA ((gfxcard==GFX_MDA || gfxcard==GFX_HERCULES || gfxcard==GFX_INCOLOR || gfxcard==GFX_GENIUS) && (romset<ROM_TANDY || romset>=ROM_IBMAT))
#define VGA ((gfxcard>=GFX_TVGA || romset==ROM_ACER386) && gfxcard!=GFX_COLORPLUS && gfxcard!=GFX_INCOLOR && gfxcard!=GFX_WY700 && gfxcard!=GFX_GENIUS && romset!=ROM_PC1640 && romset!=ROM_PC1512 && romset!=ROM_TANDY && romset!=ROM_PC200 && romset != ROM_T3100E)
#define VGA ((gfxcard>=GFX_TVGA || romset==ROM_ACER386) && gfxcard!=GFX_COLORPLUS && gfxcard!=GFX_INCOLOR && gfxcard!=GFX_WY700 && gfxcard!=GFX_GENIUS && romset!=ROM_PC1640 && romset!=ROM_PC1512 && romset!=ROM_TANDY && romset!=ROM_PC200 && romset != ROM_T3100E && romset != ROM_T1000)
#define PCJR (romset == ROM_IBMPCJR)
#define AMIBIOS (romset==ROM_AMI386SX || romset==ROM_AMI486 || romset == ROM_WIN486)
@ -445,6 +445,7 @@ enum
ROM_EPSON_PCAX2E,
ROM_EPSON_PCAX3,
ROM_T3100E,
ROM_T1000,
ROM_MAX
};

View file

@ -8,6 +8,7 @@
#include "sound_speaker.h"
#include "tandy_eeprom.h"
#include "timer.h"
#include "t1000.h"
#include "keyboard.h"
#include "keyboard_xt.h"
@ -56,6 +57,36 @@ void keyboard_xt_poll()
void keyboard_xt_adddata(uint8_t val)
{
/* Test for T1000 'Fn' key (Right Alt / Right Ctrl) */
if (romset == ROM_T1000)
{
if (pcem_key[0xb8] || pcem_key[0x9D]) /* 'Fn' pressed */
{
t1000_syskey(0x00, 0x04, 0x00); /* Set 'Fn' indicator */
switch (val)
{
case 0x45: /* Num Lock => toggle numpad */
t1000_syskey(0x00, 0x00, 0x10); break;
case 0x47: /* Home => internal display */
t1000_syskey(0x40, 0x00, 0x00); break;
case 0x49: /* PgDn => turbo on */
t1000_syskey(0x80, 0x00, 0x00); break;
case 0x4D: /* Right => toggle LCD font */
t1000_syskey(0x00, 0x00, 0x20); break;
case 0x4F: /* End => external display */
t1000_syskey(0x00, 0x40, 0x00); break;
case 0x51: /* PgDn => turbo off */
t1000_syskey(0x00, 0x80, 0x00); break;
case 0x54: /* SysRQ => toggle window */
t1000_syskey(0x00, 0x00, 0x08); break;
}
}
else
{
t1000_syskey(0x04, 0x00, 0x00); /* Reset 'Fn' indicator */
}
}
key_queue[key_queue_end] = val;
pclog("keyboard_xt : %02X added to key queue at %i\n", val, key_queue_end);
key_queue_end = (key_queue_end + 1) & 0xf;

View file

@ -762,6 +762,16 @@ int loadbios()
fread(rom,65536,1,f);
fclose(f);
return 1;
case ROM_T1000:
loadfont("t1000/t1000font.rom", 2);
f=romfopen("t1000/t1000.rom","rb");
if (!f) break;
fread(rom, 0x8000,1,f);
memcpy(rom + 0x8000, rom, 0x8000);
biosmask = 0x7fff;
fclose(f);
return 1;
}
printf("Failed to load ROM!\n");
if (f) fclose(f);

View file

@ -56,6 +56,7 @@
#include "um8669f.h"
#include "vid_pcjr.h"
#include "vid_tandy.h"
#include "vid_t1000.h"
#include "wd76c10.h"
void xt_init();
@ -90,6 +91,7 @@ void at_batman_init();
void at_endeavor_init();
void xt_laserxt_init();
void at_t3100e_init();
void xt_t1000_init();
int model;
int AMSTRAD, AT, PCI, TANDY;
@ -108,6 +110,7 @@ MODEL models[] =
{"[8088] Schneider EuroPC", ROM_EUROPC, "europc", { {"", cpus_europc}, {"", NULL}, {"", NULL}}, 0, 0, 512, 640, 128, europc_init, NULL},
{"[8088] Tandy 1000", ROM_TANDY, "tandy", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, 1, 0, 128, 640, 128, tandy1k_init, &tandy1000_device},
{"[8088] Tandy 1000 HX", ROM_TANDY1000HX, "tandy1000hx", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, 1, 0, 256, 640, 128, tandy1k_init, &tandy1000hx_device},
{"[8088] Toshiba 1000", ROM_T1000, "t1000", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, 1, 0, 512,1280, 768, xt_t1000_init, &t1000_device},
{"[8088] VTech Laser Turbo XT", ROM_LTXT, "ltxt", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, 0, 0, 64,1152, 64, xt_laserxt_init, NULL},
{"[8086] Amstrad PC1512", ROM_PC1512, "pc1512", { {"", cpus_pc1512}, {"", NULL}, {"", NULL}}, 1, MODEL_AMSTRAD, 512, 640, 128, ams_init, NULL},

View file

@ -2,6 +2,7 @@
#include "ibm.h"
#include "io.h"
#include "nvr.h"
#include "nvr_tc8521.h"
#include "pic.h"
#include "timer.h"
#include "rtc.h"
@ -9,6 +10,7 @@
#include "config.h"
#include "model.h"
#include "nmi.h"
#include "t1000.h"
int oldromset;
int nvrmask=63;
@ -286,6 +288,10 @@ void loadnvr()
case ROM_EPSON_PCAX2E: f = nvrfopen("epson_pcax2e.nvr", "rb"); nvrmask = 127; break;
case ROM_EPSON_PCAX3: f = nvrfopen("epson_pcax3.nvr", "rb"); nvrmask = 127; break;
case ROM_T3100E: f = nvrfopen("t3100e.nvr", "rb"); break;
case ROM_T1000: tc8521_loadnvr();
t1000_configsys_loadnvr();
t1000_emsboard_loadnvr();
return;
default: return;
}
@ -359,6 +365,10 @@ void savenvr()
case ROM_EPSON_PCAX2E: f = nvrfopen("epson_pcax2e.nvr", "wb"); break;
case ROM_EPSON_PCAX3: f = nvrfopen("epson_pcax3.nvr", "wb"); break;
case ROM_T3100E: f = nvrfopen("t3100e.nvr", "wb"); break;
case ROM_T1000: tc8521_savenvr();
t1000_configsys_savenvr();
t1000_emsboard_savenvr();
return;
default: return;
}
fwrite(nvrram,128,1,f);

View file

@ -10,3 +10,7 @@ void savenvr();
void nvr_recalc();
FILE *nvrfopen(char *fn, char *mode);
extern uint8_t nvrram[128];
extern int nvrmask;
extern int oldromset;

98
src/nvr_tc8521.c Normal file
View file

@ -0,0 +1,98 @@
#include <stdio.h>
#include "ibm.h"
#include "io.h"
#include "nvr.h"
#include "nvr_tc8521.h"
#include "rtc_tc8521.h"
#include "pic.h"
#include "timer.h"
#include "rtc.h"
#include "paths.h"
#include "config.h"
#include "nmi.h"
static int nvr_onesec_time = 0, nvr_onesec_cnt = 0;
static void tc8521_onesec(void *p)
{
nvr_onesec_cnt++;
if (nvr_onesec_cnt >= 100)
{
tc8521_tick();
nvr_onesec_cnt = 0;
}
nvr_onesec_time += (int)(10000 * TIMER_USEC);
}
void write_tc8521(uint16_t addr, uint8_t val, void *priv)
{
uint8_t page = nvrram[0x0D] & 3;
addr &= 0x0F;
if (addr < 0x0D) addr += 16 * page;
if (addr >= 0x10 && nvrram[addr] != val)
nvr_dosave = 1;
nvrram[addr] = val;
}
uint8_t read_tc8521(uint16_t addr, void *priv)
{
uint8_t page = nvrram[0x0D] & 3;
addr &= 0x0F;
if (addr < 0x0D) addr += 16 * page;
return nvrram[addr];
}
void tc8521_loadnvr()
{
FILE *f;
nvrmask=63;
oldromset=romset;
switch (romset)
{
case ROM_T1000: f = nvrfopen("t1000.nvr", "rb"); break;
default: return;
}
if (!f)
{
memset(nvrram,0xFF,64);
nvrram[0x0E] = 0; /* Test register */
if (!enable_sync)
{
memset(nvrram, 0, 16);
}
return;
}
fread(nvrram,64,1,f);
if (enable_sync)
tc8521_internal_sync(nvrram);
else
tc8521_internal_set_nvrram(nvrram); /* Update the internal clock state based on the NVR registers. */
fclose(f);
}
void tc8521_savenvr()
{
FILE *f;
switch (oldromset)
{
case ROM_T1000: f = nvrfopen("t1000.nvr", "wb"); break;
default: return;
}
fwrite(nvrram,64,1,f);
fclose(f);
}
void nvr_tc8521_init()
{
io_sethandler(0x2C0, 0x10, read_tc8521, NULL, NULL, write_tc8521, NULL, NULL, NULL);
timer_add(tc8521_onesec, &nvr_onesec_time, TIMER_ALWAYS_ENABLED, NULL);
}

12
src/nvr_tc8521.h Normal file
View file

@ -0,0 +1,12 @@
void nvr_tc8521_init();
extern int enable_sync;
extern int nvr_dosave;
void tc8521_loadnvr();
void tc8521_savenvr();
void tc8521_nvr_recalc();
FILE *nvrfopen(char *fn, char *mode);

221
src/rtc_tc8521.c Normal file
View file

@ -0,0 +1,221 @@
/* Emulation of:
Toshiba TC8521 Real Time Clock */
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "nvr.h"
#include "rtc_tc8521.h"
#define peek2(a) (nvrram[(a##1)] + 10 * nvrram[(a##10)])
struct
{
int sec;
int min;
int hour;
int mday;
int mon;
int year;
} internal_clock;
/* Table for days in each month */
static int rtc_days_in_month[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
/* Called to determine whether the year is leap or not */
static int rtc_is_leap(int org_year)
{
if (org_year % 400 == 0) return 1;
if (org_year % 100 == 0) return 0;
if (org_year % 4 == 0) return 1;
return 0;
}
/* Called to determine the days in the current month */
static int rtc_get_days(int org_month, int org_year)
{
if (org_month != 2)
return rtc_days_in_month[org_month];
else
return rtc_is_leap(org_year) ? 29 : 28;
}
/* Called when the internal clock gets updated */
static void tc8521_recalc()
{
if (internal_clock.sec == 60)
{
internal_clock.sec = 0;
internal_clock.min++;
}
if (internal_clock.min == 60)
{
internal_clock.min = 0;
internal_clock.hour++;
}
if (internal_clock.hour == 24)
{
internal_clock.hour = 0;
internal_clock.mday++;
}
if (internal_clock.mday == (rtc_get_days(internal_clock.mon, internal_clock.year) + 1))
{
internal_clock.mday = 1;
internal_clock.mon++;
}
if (internal_clock.mon == 13)
{
internal_clock.mon = 1;
internal_clock.year++;
}
}
/* Called when ticking the second */
void tc8521_tick()
{
internal_clock.sec++;
tc8521_recalc();
}
/* Called when modifying the NVR registers */
void tc8521_update(uint8_t *nvrram, int reg)
{
int temp;
switch(reg)
{
case TC8521_SECOND1:
case TC8521_SECOND10:
internal_clock.sec = peek2(TC8521_SECOND);
break;
case TC8521_MINUTE1:
case TC8521_MINUTE10:
internal_clock.min = peek2(TC8521_MINUTE);
break;
case TC8521_HOUR1:
case TC8521_HOUR10:
temp = peek2(TC8521_HOUR);
if (nvrram[TC8521_24HR] & 1)
internal_clock.hour = temp;
else
internal_clock.hour = ((temp & ~0x20) % 12) + ((temp & 0x20) ? 12 : 0);
break;
case TC8521_DAY1:
case TC8521_DAY10:
internal_clock.mday = peek2(TC8521_DAY);
break;
case TC8521_MONTH1:
case TC8521_MONTH10:
internal_clock.mon = peek2(TC8521_MONTH);
break;
case TC8521_YEAR1:
case TC8521_YEAR10:
internal_clock.year = 1980 + peek2(TC8521_YEAR);
break;
}
}
/* Called to obtain the current day of the week based on the internal clock */
static int time_week_day()
{
int day_of_month = internal_clock.mday;
int month2 = internal_clock.mon;
int year2 = internal_clock.year % 100;
int century = ((internal_clock.year - year2) / 100) % 4;
int sum = day_of_month + month2 + year2 + century;
/* (Sum mod 7) gives 0 for Saturday, we need it for Sunday, so +6 for Saturday to get 6 and Sunday 0 */
int raw_wd = ((sum + 6) % 7);
return raw_wd;
}
/* Called to get time into the internal clock */
static void tc8521_internal_get(struct tm *time_var)
{
time_var->tm_sec = internal_clock.sec;
time_var->tm_min = internal_clock.min;
time_var->tm_hour = internal_clock.hour;
time_var->tm_wday = time_week_day();
time_var->tm_mday = internal_clock.mday;
time_var->tm_mon = internal_clock.mon - 1;
time_var->tm_year = internal_clock.year - 1900;
}
static void tc8521_internal_set(struct tm *time_var)
{
internal_clock.sec = time_var->tm_sec;
internal_clock.min = time_var->tm_min;
internal_clock.hour = time_var->tm_hour;
internal_clock.mday = time_var->tm_mday;
internal_clock.mon = time_var->tm_mon + 1;
internal_clock.year = time_var->tm_year + 1900;
}
static void tc8521_set_nvrram(uint8_t *nvrram, struct tm *cur_time_tm)
{
nvrram[TC8521_SECOND1] = cur_time_tm->tm_sec % 10;
nvrram[TC8521_SECOND10] = cur_time_tm->tm_sec / 10;
nvrram[TC8521_MINUTE1] = cur_time_tm->tm_min % 10;
nvrram[TC8521_MINUTE10] = cur_time_tm->tm_min / 10;
if (nvrram[TC8521_24HR] & 1)
{
nvrram[TC8521_HOUR1] = cur_time_tm->tm_hour % 10;
nvrram[TC8521_HOUR10] = cur_time_tm->tm_hour / 10;
}
else
{
nvrram[TC8521_HOUR1] = (cur_time_tm->tm_hour % 12) % 10;
nvrram[TC8521_HOUR10] = ((cur_time_tm->tm_hour % 12) / 10)
| (cur_time_tm->tm_hour >= 12) ? 2 : 0;
}
nvrram[TC8521_WEEKDAY] = cur_time_tm->tm_wday;
nvrram[TC8521_DAY1] = cur_time_tm->tm_mday % 10;
nvrram[TC8521_DAY10] = cur_time_tm->tm_mday / 10;
nvrram[TC8521_MONTH1] = (cur_time_tm->tm_mon + 1) / 10;
nvrram[TC8521_MONTH10] = (cur_time_tm->tm_mon + 1) % 10;
nvrram[TC8521_YEAR1] = (cur_time_tm->tm_year - 80) % 10;
nvrram[TC8521_YEAR10] = ((cur_time_tm->tm_year - 80) % 100) / 10;
}
void tc8521_internal_set_nvrram(uint8_t *nvrram)
{
/* Load the entire internal clock state from the NVR. */
internal_clock.sec = peek2(TC8521_SECOND);
internal_clock.min = peek2(TC8521_MINUTE);
if (nvrram[TC8521_24HR] & 1)
{
internal_clock.hour = peek2(TC8521_HOUR);
}
else
{
internal_clock.hour = (peek2(TC8521_HOUR) % 12)
+ (nvrram[TC8521_HOUR10] & 2) ? 12 : 0;
}
internal_clock.mday = peek2(TC8521_DAY);
internal_clock.mon = peek2(TC8521_MONTH);
internal_clock.year = 1980 + peek2(TC8521_YEAR);
}
void tc8521_internal_sync(uint8_t *nvrram)
{
struct tm *cur_time_tm;
time_t cur_time;
time(&cur_time);
cur_time_tm = localtime(&cur_time);
tc8521_internal_set(cur_time_tm);
tc8521_set_nvrram(nvrram, cur_time_tm);
}
void tc8521_get(uint8_t *nvrram)
{
struct tm cur_time_tm;
tc8521_internal_get(&cur_time_tm);
tc8521_set_nvrram(nvrram, &cur_time_tm);
}

33
src/rtc_tc8521.h Normal file
View file

@ -0,0 +1,33 @@
/* The TC8521 is a 4-bit RTC, so each memory location can only hold a single
* BCD digit. Hence everything has 'ones' and 'tens' digits. */
enum TC8521_ADDR
{
/* Page 0 registers */
TC8521_SECOND1,
TC8521_SECOND10,
TC8521_MINUTE1,
TC8521_MINUTE10,
TC8521_HOUR1,
TC8521_HOUR10,
TC8521_WEEKDAY,
TC8521_DAY1,
TC8521_DAY10,
TC8521_MONTH1,
TC8521_MONTH10,
TC8521_YEAR1,
TC8521_YEAR10,
TC8521_PAGE, /* PAGE register */
TC8521_TEST, /* TEST register */
TC8521_RESET, /* RESET register */
/* Page 1 registers */
TC8521_24HR = 0x1A,
TC8521_LEAPYEAR = 0x1B
};
void tc8521_tick();
void tc8521_update(uint8_t *nvrram, int reg);
void tc8521_get(uint8_t *nvrram);
void tc8521_internal_set_nvrram(uint8_t *nvrram);
void tc8521_internal_sync(uint8_t *nvrram);

579
src/t1000.c Normal file
View file

@ -0,0 +1,579 @@
#include <stdlib.h>
#include "ibm.h"
#include "cpu.h"
#include "model.h"
#include "io.h"
#include "fdc.h"
#include "fdd.h"
#include "mouse.h"
#include "mem.h"
#include "nmi.h"
#include "nvr.h"
#include "nvr_tc8521.h"
#include "pit.h"
#include "device.h"
#include "keyboard_xt.h"
#include "vid_t1000.h"
/* The T1000 is the T3100e's little brother -- a real laptop with a
* rechargeable battery.
*
* Features: 80C88 at 4.77MHz
* 512k system RAM
* 640x200 monochrome LCD
* 82-key keyboard
* Real-time clock. Not the normal 146818, but a TC8521, which
* is a 4-bit chip.
* A ROM drive (128k, 256k or 512k) which acts as a mini hard
* drive and contains a copy of DOS 2.11.
* 160 bytes of non-volatile RAM for the CONFIG.SYS used when
* booting from the ROM drive.
*
* An optional memory expansion board can be fitted. This adds 768k of RAM,
* which can be used for up to three purposes:
* > Conventional memory -- 128k between 512k and 640k
* > HardRAM -- a battery-backed RAM drive.
* > EMS
*
* This means that there are up to three different implementations of
* non-volatile RAM in the same computer (52 nibbles in the TC8521, 160
* bytes of CONFIG.SYS, and up to 768k of HardRAM).
*
*/
void common_init();
uint8_t config_sys[160];
static struct t1000_system
{
/* ROM drive */
uint8_t *romdrive;
uint8_t rom_ctl;
uint32_t rom_offset;
mem_mapping_t rom_mapping;
/* System control registers */
uint8_t sys_ctl[16];
uint8_t syskeys;
/* NVRAM control */
uint8_t nvr_c0;
uint8_t nvr_tick;
int nvr_addr;
uint8_t nvr_active;
/* EMS data */
uint8_t ems_reg[4];
mem_mapping_t mapping[4];
uint32_t page_exec[4];
uint8_t ems_port_index;
uint16_t ems_port;
uint8_t is_640k;
uint32_t ems_base;
int32_t ems_pages;
} t1000;
#define T1000_ROMSIZE (512 * 1024) /* Maximum ROM drive size is 512k */
/* The CONFIG.SYS storage (160 bytes) and battery-backed EMS (all RAM
* above 512k) are implemented as NVR devices */
void t1000_configsys_loadnvr()
{
FILE *f;
memset(config_sys, 0x1A, sizeof(config_sys));
f = nvrfopen("t1000_config.nvr", "rb");
if (f)
{
fread(config_sys, sizeof(config_sys), 1, f);
fclose(f);
}
}
/* All RAM beyond 512k is non-volatile */
void t1000_emsboard_loadnvr()
{
FILE *f;
if (mem_size > 512)
{
f = nvrfopen("t1000_ems.nvr", "rb");
if (f)
{
fread(&ram[512 * 1024],
1024, (mem_size - 512), f);
fclose(f);
}
}
}
void t1000_configsys_savenvr()
{
FILE *f;
f = nvrfopen("t1000_config.nvr", "wb");
if (f)
{
fwrite(config_sys, sizeof(config_sys), 1, f);
fclose(f);
}
}
void t1000_emsboard_savenvr()
{
FILE *f;
if (mem_size > 512)
{
f = nvrfopen("t1000_ems.nvr", "wb");
if (f)
{
fwrite(&ram[512 * 1024],
1024, (mem_size - 512), f);
fclose(f);
}
}
}
/* Given an EMS page ID, return its physical address in RAM. */
uint32_t ems_execaddr(struct t1000_system *sys, int pg, uint16_t val)
{
if (!(val & 0x80)) return 0; /* Bit 7 reset => not mapped */
if (!sys->ems_pages) return 0; /* No EMS available: all used by
* HardRAM or conventional RAM */
val &= 0x7F;
/* pclog("Select EMS page: %d of %d\n", val, sys->ems_pages); */
if (val < sys->ems_pages)
{
/* EMS is any memory above 512k, with ems_base giving the start address */
return (512 * 1024) + (sys->ems_base * 0x10000) + (0x4000 * val);
}
return 0;
}
static uint8_t ems_in(uint16_t addr, void *priv)
{
struct t1000_system *sys = (struct t1000_system *)priv;
/* pclog("ems_in(%04x)=%02x\n", addr, sys->ems_reg[(addr >> 14) & 3]); */
return sys->ems_reg[(addr >> 14) & 3];
}
static void ems_out(uint16_t addr, uint8_t val, void *priv)
{
struct t1000_system *sys = (struct t1000_system *)priv;
int pg = (addr >> 14) & 3;
/* pclog("ems_out(%04x, %02x) pg=%d\n", addr, val, pg); */
sys->ems_reg[pg] = val;
sys->page_exec[pg] = ems_execaddr(sys, pg, val);
if (sys->page_exec[pg]) /* Page present */
{
mem_mapping_enable(&sys->mapping[pg]);
mem_mapping_set_exec(&sys->mapping[pg], ram + sys->page_exec[pg]);
}
else
{
mem_mapping_disable(&sys->mapping[pg]);
}
}
/* Hardram size is in 64k units */
static void ems_set_hardram(struct t1000_system *sys, uint8_t val)
{
int n;
val &= 0x1F; /* Mask off pageframe address */
if (val && mem_size > 512)
{
sys->ems_base = val;
}
else
{
sys->ems_base = 0;
}
/* pclog("EMS base set to %02x\n", val); */
sys->ems_pages = 48 - 4 * sys->ems_base;
if (sys->ems_pages < 0) sys->ems_pages = 0;
/* Recalculate EMS mappings */
for (n = 0; n < 4; n++)
{
ems_out(n << 14, sys->ems_reg[n], sys);
}
}
static void ems_set_640k(struct t1000_system *sys, uint8_t val)
{
if (val && mem_size >= 640)
{
mem_mapping_set_addr(&ram_low_mapping, 0, 640 * 1024);
sys->is_640k = 1;
}
else
{
mem_mapping_set_addr(&ram_low_mapping, 0, 512 * 1024);
sys->is_640k = 0;
}
}
static void ems_set_port(struct t1000_system *sys, uint8_t val)
{
int n;
/* pclog("ems_set_port(%d)", val & 0x0F); */
if (sys->ems_port)
{
for (n = 0; n <= 0xC000; n += 0x4000)
{
io_removehandler(sys->ems_port + n, 0x01,
ems_in, NULL, NULL, ems_out, NULL, NULL, sys);
}
sys->ems_port = 0;
}
val &= 0x0F;
sys->ems_port_index = val;
if (val == 7) /* No EMS */
{
sys->ems_port = 0;
}
else
{
sys->ems_port = 0x208 | (val << 4);
for (n = 0; n <= 0xC000; n += 0x4000)
{
io_sethandler(sys->ems_port + n, 0x01,
ems_in, NULL, NULL, ems_out, NULL, NULL, sys);
}
sys->ems_port = 0;
}
/* pclog(" -> %04x\n", sys->ems_port); */
}
static int addr_to_page(uint32_t addr)
{
return (addr - 0xD0000) / 0x4000;
}
/* Read RAM in the EMS page frame */
static uint8_t ems_read_ram(uint32_t addr, void *priv)
{
struct t1000_system *sys = (struct t1000_system *)priv;
int pg = addr_to_page(addr);
if (pg < 0) return 0xFF;
addr = sys->page_exec[pg] + (addr & 0x3FFF);
return ram[addr];
}
static uint16_t ems_read_ramw(uint32_t addr, void *priv)
{
struct t1000_system *sys = (struct t1000_system *)priv;
int pg = addr_to_page(addr);
if (pg < 0) return 0xFF;
/* pclog("ems_read_ramw addr=%05x ", addr); */
addr = sys->page_exec[pg] + (addr & 0x3FFF);
/* pclog("-> %06x val=%04x\n", addr, *(uint16_t *)&ram[addr]); */
return *(uint16_t *)&ram[addr];
}
static uint32_t ems_read_raml(uint32_t addr, void *priv)
{
struct t1000_system *sys = (struct t1000_system *)priv;
int pg = addr_to_page(addr);
if (pg < 0) return 0xFF;
addr = sys->page_exec[pg] + (addr & 0x3FFF);
return *(uint32_t *)&ram[addr];
}
/* Write RAM in the EMS page frame */
static void ems_write_ram(uint32_t addr, uint8_t val, void *priv)
{
struct t1000_system *sys = (struct t1000_system *)priv;
int pg = addr_to_page(addr);
if (pg < 0) return;
addr = sys->page_exec[pg] + (addr & 0x3FFF);
if (ram[addr] != val) nvr_dosave = 1;
ram[addr] = val;
}
static void ems_write_ramw(uint32_t addr, uint16_t val, void *priv)
{
struct t1000_system *sys = (struct t1000_system *)priv;
int pg = addr_to_page(addr);
if (pg < 0) return;
/* pclog("ems_write_ramw addr=%05x ", addr); */
addr = sys->page_exec[pg] + (addr & 0x3FFF);
/* pclog("-> %06x val=%04x\n", addr, val); */
if (*(uint16_t *)&ram[addr] != val) nvr_dosave = 1;
*(uint16_t *)&ram[addr] = val;
}
static void ems_write_raml(uint32_t addr, uint32_t val, void *priv)
{
struct t1000_system *sys = (struct t1000_system *)priv;
int pg = addr_to_page(addr);
if (pg < 0) return;
addr = sys->page_exec[pg] + (addr & 0x3FFF);
if (*(uint32_t *)&ram[addr] != val) nvr_dosave = 1;
*(uint32_t *)&ram[addr] = val;
}
void t1000_syskey(uint8_t andmask, uint8_t ormask, uint8_t xormask)
{
t1000.syskeys &= ~andmask;
t1000.syskeys |= ormask;
t1000.syskeys ^= xormask;
}
static uint8_t read_t1000_ctl(uint16_t addr, void *priv)
{
struct t1000_system *sys = (struct t1000_system *)priv;
switch (addr & 0x0F)
{
case 1: return sys->syskeys;
/* Detect EMS board */
case 0x0F: switch (sys->sys_ctl[0x0E])
{
case 0x50: if (mem_size <= 512)
return 0xFF;
return 0x90 | sys->ems_port_index;
/* 0x60 is the page frame address: (0xD000 - 0xC400) / 0x20 */
case 0x51: return sys->ems_base | 0x60;
case 0x52: return sys->is_640k ? 0x80 : 0;
}
return 0xFF;
default: return sys->sys_ctl[addr & 0x0F];
}
}
static void write_t1000_ctl(uint16_t addr, uint8_t val, void *priv)
{
struct t1000_system *sys = (struct t1000_system *)priv;
sys->sys_ctl[addr & 0x0F] = val;
switch (addr & 0x0F)
{
/* Video control */
case 4: if (sys->sys_ctl[3] == 0x5A)
{
t1000_video_options_set((val & 0x20) ? 1 : 0);
t1000_display_set((val & 0x40) ? 0 : 1);
}
break;
/* EMS control*/
case 0x0F:
switch (sys->sys_ctl[0x0E])
{
case 0x50: ems_set_port(sys, val); break;
case 0x51: ems_set_hardram(sys, val); break;
case 0x52: ems_set_640k(sys, val); break;
}
break;
}
}
/* Ports 0xC0 to 0xC3 appear to have two purposes:
*
* > Access to the 160 bytes of non-volatile RAM containing CONFIG.SYS
* > Reading the floppy changeline. I don't know why the Toshiba doesn't
* use the normal port 0x3F7 for this, but it doesn't.
*
*/
static uint8_t read_t1000_nvram(uint16_t addr, void *priv)
{
struct t1000_system *sys = (struct t1000_system *)priv;
uint8_t tmp;
switch (addr)
{
case 0xC2: /* Read next byte from NVRAM */
tmp = 0xFF;
if (sys->nvr_addr >= 0 && sys->nvr_addr < 160)
tmp = config_sys[sys->nvr_addr];
++sys->nvr_addr;
return tmp;
case 0xC3: /* Read floppy changeline and NVRAM ready state */
tmp = fdc_read(0x3F7, NULL);
tmp = (tmp & 0x80) >> 3; /* Bit 4 is changeline */
tmp |= (sys->nvr_active & 0xC0);/* Bits 6,7 are r/w mode */
tmp |= 0x2E; /* Bits 5,3,2,1 always 1 */
tmp |= (sys->nvr_active & 0x40) >> 6; /* Ready state */
return tmp;
}
return 0xFF;
}
static void write_t1000_nvram(uint16_t addr, uint8_t val, void *priv)
{
struct t1000_system *sys = (struct t1000_system *)priv;
switch (addr)
{
/* On the real T1000, port 0xC1 is only usable as the high byte of a 16-bit
* write to port 0xC0, with 0x5A in the low byte. */
case 0xC0: sys->nvr_c0 = val;
break;
/* Write next byte to NVRAM */
case 0xC1: if (sys->nvr_addr >= 0 && sys->nvr_addr < 160)
{
if (config_sys[sys->nvr_addr] != val)
nvr_dosave = 1;
config_sys[sys->nvr_addr] = val;
}
++sys->nvr_addr;
break;
case 0xC2: break;
/* At start of NVRAM read / write, 0x80 is written to port 0xC3. This seems
* to reset the NVRAM address counter. A single byte is then written (0xFF
* for write, 0x00 for read) which appears to be ignored. Simulate that by
* starting the address counter off at -1 */
case 0xC3: sys->nvr_active = val;
if (val == 0x80) sys->nvr_addr = -1;
break;
}
}
/* Port 0xC8 controls the ROM drive */
static uint8_t read_t1000_rom_ctl(uint16_t addr, void *priv)
{
struct t1000_system *sys = (struct t1000_system *)priv;
return sys->rom_ctl;
}
static void write_t1000_rom_ctl(uint16_t addr, uint8_t val, void *priv)
{
struct t1000_system *sys = (struct t1000_system *)priv;
sys->rom_ctl = val;
if (sys->romdrive && (val & 0x80)) /* Enable */
{
sys->rom_offset = ((val & 0x7F) * 0x10000) % T1000_ROMSIZE;
mem_mapping_set_addr(&sys->rom_mapping, 0xA0000, 0x10000);
mem_mapping_set_exec(&sys->rom_mapping, sys->romdrive +
sys->rom_offset);
mem_mapping_enable(&sys->rom_mapping);
}
else
{
mem_mapping_disable(&sys->rom_mapping);
}
}
/* Read the ROM drive */
static uint8_t t1000_read_rom(uint32_t addr, void *priv)
{
struct t1000_system *sys = (struct t1000_system *)priv;
if (!sys->romdrive) return 0xFF;
return sys->romdrive[sys->rom_offset + (addr & 0xFFFF)];
}
static uint16_t t1000_read_romw(uint32_t addr, void *priv)
{
struct t1000_system *sys = (struct t1000_system *)priv;
if (!sys->romdrive) return 0xFFFF;
return *(uint16_t *)(&sys->romdrive[sys->rom_offset + (addr & 0xFFFF)]);
}
static uint32_t t1000_read_roml(uint32_t addr, void *priv)
{
struct t1000_system *sys = (struct t1000_system *)priv;
if (!sys->romdrive) return 0xFFFFFFFF;
return *(uint32_t *)(&sys->romdrive[sys->rom_offset + (addr & 0xFFFF)]);
}
void xt_t1000_init()
{
FILE *f;
int pg;
memset(&t1000, 0, sizeof(t1000));
t1000.ems_port_index = 7; /* EMS disabled */
/* The ROM drive is optional. If the file is missing, continue to boot; the
* BIOS will complain 'No ROM drive' but boot normally from floppy. */
f = romfopen("t1000/t1000dos.rom", "rb");
if (f)
{
t1000.romdrive = malloc(T1000_ROMSIZE);
if (t1000.romdrive)
{
memset(t1000.romdrive, 0xFF, T1000_ROMSIZE);
fread(t1000.romdrive, T1000_ROMSIZE, 1, f);
}
fclose(f);
}
mem_mapping_add(&t1000.rom_mapping, 0xA0000, 0x10000,
t1000_read_rom, t1000_read_romw, t1000_read_roml,
NULL, NULL, NULL, NULL, MEM_MAPPING_INTERNAL, &t1000);
mem_mapping_disable(&t1000.rom_mapping);
/* Map the EMS page frame */
for (pg = 0; pg < 4; pg++)
{
mem_mapping_add(&t1000.mapping[pg],
0xD0000 + (0x4000 * pg), 16384,
ems_read_ram, ems_read_ramw, ems_read_raml,
ems_write_ram, ems_write_ramw, ems_write_raml,
NULL, MEM_MAPPING_EXTERNAL,
&t1000);
/* Start them all off disabled */
mem_mapping_disable(&t1000.mapping[pg]);
}
/* Non-volatile RAM for CONFIG.SYS */
io_sethandler(0xC0, 4, read_t1000_nvram, NULL, NULL,
write_t1000_nvram, NULL, NULL, &t1000);
/* ROM drive */
io_sethandler(0xC8, 1, read_t1000_rom_ctl, NULL, NULL,
write_t1000_rom_ctl, NULL, NULL, &t1000);
/* System control functions, and add-on memory board */
io_sethandler(0xE0, 0x10, read_t1000_ctl, NULL, NULL,
write_t1000_ctl, NULL, NULL, &t1000);
common_init();
mem_add_bios();
pit_set_out_func(&pit, 1, pit_refresh_timer_xt);
keyboard_xt_init();
nmi_init();
nvr_tc8521_init();
/* No gameport, and no provision to fit one device_add(&gameport_device); */
}

7
src/t1000.h Normal file
View file

@ -0,0 +1,7 @@
void t1000_syskey(uint8_t andmask, uint8_t ormask, uint8_t xormask);
void t1000_configsys_loadnvr();
void t1000_emsboard_loadnvr();
void t1000_configsys_savenvr();
void t1000_emsboard_savenvr();

695
src/vid_t1000.c Normal file
View file

@ -0,0 +1,695 @@
/* Emulate the Toshiba 1000 plasma display. This display has a fixed 640x200
* resolution. */
#include <stdlib.h>
#include "ibm.h"
#include "device.h"
#include "io.h"
#include "mem.h"
#include "timer.h"
#include "video.h"
#include "vid_cga.h"
#include "vid_t1000.h"
#define T1000_XSIZE 640
#define T1000_YSIZE 200
/* Mapping of attributes to colours */
static uint32_t blue, grey;
static uint8_t boldcols[256]; /* Which attributes use the bold font */
static uint32_t blinkcols[256][2];
static uint32_t normcols[256][2];
/* Video options set by the motherboard; they will be picked up by the card
* on the next poll.
*
* Bit 1: Danish
* Bit 0: Thin font
*/
static uint8_t st_video_options;
static uint8_t st_display_internal = -1;
void t1000_video_options_set(uint8_t options)
{
st_video_options = options & 1;
st_video_options |= device_get_config_int("display_language") ? 2 : 0;
}
void t1000_display_set(uint8_t internal)
{
st_display_internal = internal;
}
uint8_t t1000_display_get()
{
return st_display_internal;
}
typedef struct t1000_t
{
mem_mapping_t mapping;
cga_t cga; /* The CGA is used for the external
* display; most of its registers are
* ignored by the plasma display. */
int font; /* Current font, 0-3 */
int enabled; /* Hardware enabled, 0 or 1 */
int internal; /* Using internal display? */
uint8_t attrmap; /* Attribute mapping register */
int dispontime, dispofftime;
int linepos, displine;
int vc;
int dispon;
int vsynctime;
uint8_t video_options;
uint8_t *vram;
} t1000_t;
static void t1000_recalctimings(t1000_t *t1000);
static void t1000_write(uint32_t addr, uint8_t val, void *p);
static uint8_t t1000_read(uint32_t addr, void *p);
static void t1000_recalcattrs(t1000_t *t1000);
static void t1000_out(uint16_t addr, uint8_t val, void *p)
{
t1000_t *t1000 = (t1000_t *)p;
switch (addr)
{
/* Emulated CRTC, register select */
case 0x3d0: case 0x3d2: case 0x3d4: case 0x3d6:
cga_out(addr, val, &t1000->cga);
break;
/* Emulated CRTC, value */
case 0x3d1: case 0x3d3: case 0x3d5: case 0x3d7:
/* Register 0x12 controls the attribute mappings for the
* LCD screen. */
if (t1000->cga.crtcreg == 0x12)
{
t1000->attrmap = val;
t1000_recalcattrs(t1000);
return;
}
cga_out(addr, val, &t1000->cga);
t1000_recalctimings(t1000);
return;
/* CGA control register */
case 0x3D8:
cga_out(addr, val, &t1000->cga);
return;
/* CGA colour register */
case 0x3D9:
cga_out(addr, val, &t1000->cga);
return;
}
}
static uint8_t t1000_in(uint16_t addr, void *p)
{
t1000_t *t1000 = (t1000_t *)p;
uint8_t val;
switch (addr)
{
case 0x3d1: case 0x3d3: case 0x3d5: case 0x3d7:
if (t1000->cga.crtcreg == 0x12)
{
val = t1000->attrmap & 0x0F;
if (t1000->internal) val |= 0x20; /* LCD / CRT */
return val;
}
}
return cga_in(addr, &t1000->cga);
}
static void t1000_write(uint32_t addr, uint8_t val, void *p)
{
t1000_t *t1000 = (t1000_t *)p;
egawrites++;
// pclog("CGA_WRITE %04X %02X\n", addr, val);
t1000->vram[addr & 0x3fff] = val;
cycles -= 4;
}
static uint8_t t1000_read(uint32_t addr, void *p)
{
t1000_t *t1000 = (t1000_t *)p;
egareads++;
cycles -= 4;
// pclog("CGA_READ %04X\n", addr);
return t1000->vram[addr & 0x3fff];
}
static void t1000_recalctimings(t1000_t *t1000)
{
double disptime;
double _dispontime, _dispofftime;
if (!t1000->internal)
{
cga_recalctimings(&t1000->cga);
return;
}
disptime = 651;
_dispontime = 640;
_dispofftime = disptime - _dispontime;
t1000->dispontime = (int)(_dispontime * (1 << TIMER_SHIFT));
t1000->dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT));
}
/* Draw a row of text in 80-column mode */
static void t1000_text_row80(t1000_t *t1000)
{
uint32_t cols[2];
int x, c;
uint8_t chr, attr;
int drawcursor;
int cursorline;
int bold;
int blink;
uint16_t addr;
uint8_t sc;
uint16_t ma = (t1000->cga.crtc[13] | (t1000->cga.crtc[12] << 8)) & 0x3fff;
uint16_t ca = (t1000->cga.crtc[15] | (t1000->cga.crtc[14] << 8)) & 0x3fff;
sc = (t1000->displine) & 7;
addr = ((ma & ~1) + (t1000->displine >> 3) * 80) * 2;
ma += (t1000->displine >> 3) * 80;
if ((t1000->cga.crtc[10] & 0x60) == 0x20)
{
cursorline = 0;
}
else
{
cursorline = ((t1000->cga.crtc[10] & 0x0F) <= sc) &&
((t1000->cga.crtc[11] & 0x0F) >= sc);
}
for (x = 0; x < 80; x++)
{
chr = t1000->vram[(addr + 2 * x) & 0x3FFF];
attr = t1000->vram[(addr + 2 * x + 1) & 0x3FFF];
drawcursor = ((ma == ca) && cursorline &&
(t1000->cga.cgamode & 8) && (t1000->cga.cgablink & 16));
blink = ((t1000->cga.cgablink & 16) && (t1000->cga.cgamode & 0x20) &&
(attr & 0x80) && !drawcursor);
if (t1000->video_options & 1)
bold = boldcols[attr] ? chr : chr + 256;
else
bold = boldcols[attr] ? chr + 256 : chr;
if (t1000->video_options & 2)
bold += 512;
if (t1000->cga.cgamode & 0x20) /* Blink */
{
cols[1] = blinkcols[attr][1];
cols[0] = blinkcols[attr][0];
if (blink) cols[1] = cols[0];
}
else
{
cols[1] = normcols[attr][1];
cols[0] = normcols[attr][0];
}
if (drawcursor)
{
for (c = 0; c < 8; c++)
{
((uint32_t *)buffer32->line[t1000->displine])[(x << 3) + c] = cols[(fontdat[bold][sc] & (1 << (c ^ 7))) ? 1 : 0] ^ (blue ^ grey);
}
}
else
{
for (c = 0; c < 8; c++)
((uint32_t *)buffer32->line[t1000->displine])[(x << 3) + c] = cols[(fontdat[bold][sc] & (1 << (c ^ 7))) ? 1 : 0];
}
++ma;
}
}
/* Draw a row of text in 40-column mode */
static void t1000_text_row40(t1000_t *t1000)
{
uint32_t cols[2];
int x, c;
uint8_t chr, attr;
int drawcursor;
int cursorline;
int bold;
int blink;
uint16_t addr;
uint8_t sc;
uint16_t ma = (t1000->cga.crtc[13] | (t1000->cga.crtc[12] << 8)) & 0x3fff;
uint16_t ca = (t1000->cga.crtc[15] | (t1000->cga.crtc[14] << 8)) & 0x3fff;
sc = (t1000->displine) & 7;
addr = ((ma & ~1) + (t1000->displine >> 3) * 40) * 2;
ma += (t1000->displine >> 3) * 40;
if ((t1000->cga.crtc[10] & 0x60) == 0x20)
{
cursorline = 0;
}
else
{
cursorline = ((t1000->cga.crtc[10] & 0x0F) <= sc) &&
((t1000->cga.crtc[11] & 0x0F) >= sc);
}
for (x = 0; x < 40; x++)
{
chr = t1000->vram[(addr + 2 * x) & 0x3FFF];
attr = t1000->vram[(addr + 2 * x + 1) & 0x3FFF];
drawcursor = ((ma == ca) && cursorline &&
(t1000->cga.cgamode & 8) && (t1000->cga.cgablink & 16));
blink = ((t1000->cga.cgablink & 16) && (t1000->cga.cgamode & 0x20) &&
(attr & 0x80) && !drawcursor);
if (t1000->video_options & 1)
bold = boldcols[attr] ? chr : chr + 256;
else
bold = boldcols[attr] ? chr + 256 : chr;
if (t1000->video_options & 2)
bold += 512;
if (t1000->cga.cgamode & 0x20) /* Blink */
{
cols[1] = blinkcols[attr][1];
cols[0] = blinkcols[attr][0];
if (blink) cols[1] = cols[0];
}
else
{
cols[1] = normcols[attr][1];
cols[0] = normcols[attr][0];
}
if (drawcursor)
{
for (c = 0; c < 8; c++)
{
((uint32_t *)buffer32->line[t1000->displine])[(x << 4) + c*2] =
((uint32_t *)buffer32->line[t1000->displine])[(x << 4) + c*2 + 1] = cols[(fontdat[bold][sc] & (1 << (c ^ 7))) ? 1 : 0] ^ (blue ^ grey);
}
}
else
{
for (c = 0; c < 8; c++)
{
((uint32_t *)buffer32->line[t1000->displine])[(x << 4) + c*2] =
((uint32_t *)buffer32->line[t1000->displine])[(x << 4) + c*2+1] = cols[(fontdat[bold][sc] & (1 << (c ^ 7))) ? 1 : 0];
}
}
++ma;
}
}
/* Draw a line in CGA 640x200 mode */
static void t1000_cgaline6(t1000_t *t1000)
{
int x, c;
uint8_t dat;
uint32_t ink = 0;
uint16_t addr;
uint32_t fg = (t1000->cga.cgacol & 0x0F) ? blue : grey;
uint32_t bg = grey;
uint16_t ma = (t1000->cga.crtc[13] | (t1000->cga.crtc[12] << 8)) & 0x3fff;
addr = ((t1000->displine) & 1) * 0x2000 +
(t1000->displine >> 1) * 80 +
((ma & ~1) << 1);
for (x = 0; x < 80; x++)
{
dat = t1000->vram[addr & 0x3FFF];
addr++;
for (c = 0; c < 8; c++)
{
ink = (dat & 0x80) ? fg : bg;
if (!(t1000->cga.cgamode & 8))
ink = grey;
((uint32_t *)buffer32->line[t1000->displine])[x*8+c] = ink;
dat = dat << 1;
}
}
}
/* Draw a line in CGA 320x200 mode. Here the CGA colours are converted to
* dither patterns: colour 1 to 25% grey, colour 2 to 50% grey */
static void t1000_cgaline4(t1000_t *t1000)
{
int x, c;
uint8_t dat, pattern;
uint32_t ink0, ink1;
uint16_t addr;
uint16_t ma = (t1000->cga.crtc[13] | (t1000->cga.crtc[12] << 8)) & 0x3fff;
addr = ((t1000->displine) & 1) * 0x2000 +
(t1000->displine >> 1) * 80 +
((ma & ~1) << 1);
for (x = 0; x < 80; x++)
{
dat = t1000->vram[addr & 0x3FFF];
addr++;
for (c = 0; c < 4; c++)
{
pattern = (dat & 0xC0) >> 6;
if (!(t1000->cga.cgamode & 8)) pattern = 0;
switch (pattern & 3)
{
case 0: ink0 = ink1 = grey; break;
case 1: if (t1000->displine & 1)
{
ink0 = grey; ink1 = grey;
}
else
{
ink0 = blue; ink1 = grey;
}
break;
case 2: if (t1000->displine & 1)
{
ink0 = grey; ink1 = blue;
}
else
{
ink0 = blue; ink1 = grey;
}
break;
case 3: ink0 = ink1 = blue; break;
}
((uint32_t *)buffer32->line[t1000->displine])[x*8+2*c] = ink0;
((uint32_t *)buffer32->line[t1000->displine])[x*8+2*c+1] = ink1;
dat = dat << 2;
}
}
}
static void t1000_poll(void *p)
{
t1000_t *t1000 = (t1000_t *)p;
if (t1000->video_options != st_video_options)
{
t1000->video_options = st_video_options;
/* Set the font used for the external display */
t1000->cga.fontbase = ((t1000->video_options & 3) * 256);
}
/* Switch between internal plasma and external CRT display. */
if (st_display_internal != -1 && st_display_internal != t1000->internal)
{
t1000->internal = st_display_internal;
t1000_recalctimings(t1000);
}
if (!t1000->internal)
{
cga_poll(&t1000->cga);
return;
}
if (!t1000->linepos)
{
t1000->cga.vidtime += t1000->dispofftime;
t1000->cga.cgastat |= 1;
t1000->linepos = 1;
if (t1000->dispon)
{
if (t1000->displine == 0)
{
video_wait_for_buffer();
}
/* Graphics */
if (t1000->cga.cgamode & 0x02)
{
if (t1000->cga.cgamode & 0x10)
t1000_cgaline6(t1000);
else t1000_cgaline4(t1000);
}
else
if (t1000->cga.cgamode & 0x01) /* High-res text */
{
t1000_text_row80(t1000);
}
else
{
t1000_text_row40(t1000);
}
}
t1000->displine++;
/* Hardcode a fixed refresh rate and VSYNC timing */
if (t1000->displine == 200) /* Start of VSYNC */
{
t1000->cga.cgastat |= 8;
t1000->dispon = 0;
}
if (t1000->displine == 216) /* End of VSYNC */
{
t1000->displine = 0;
t1000->cga.cgastat &= ~8;
t1000->dispon = 1;
}
}
else
{
if (t1000->dispon)
{
t1000->cga.cgastat &= ~1;
}
t1000->cga.vidtime += t1000->dispontime;
t1000->linepos = 0;
if (t1000->displine == 200)
{
/* Hardcode 640x200 window size */
if (T1000_XSIZE != xsize || T1000_YSIZE != ysize)
{
xsize = T1000_XSIZE;
ysize = T1000_YSIZE;
if (xsize < 64) xsize = 656;
if (ysize < 32) ysize = 200;
updatewindowsize(xsize, ysize);
}
video_blit_memtoscreen(0, 0, 0, ysize, xsize, ysize);
frames++;
/* Fixed 640x200 resolution */
video_res_x = T1000_XSIZE;
video_res_y = T1000_YSIZE;
if (t1000->cga.cgamode & 0x02)
{
if (t1000->cga.cgamode & 0x10)
video_bpp = 1;
else video_bpp = 2;
}
else video_bpp = 0;
t1000->cga.cgablink++;
}
}
}
static void t1000_recalcattrs(t1000_t *t1000)
{
int n;
/* val behaves as follows:
* Bit 0: Attributes 01-06, 08-0E are inverse video
* Bit 1: Attributes 01-06, 08-0E are bold
* Bit 2: Attributes 11-16, 18-1F, 21-26, 28-2F ... F1-F6, F8-FF
* are inverse video
* Bit 3: Attributes 11-16, 18-1F, 21-26, 28-2F ... F1-F6, F8-FF
* are bold */
/* Set up colours */
blue = makecol(0x2D, 0x39, 0x5A);
grey = makecol(0x85, 0xa0, 0xD6);
/* Initialise the attribute mapping. Start by defaulting everything
* to grey on blue, and with bold set by bit 3 */
for (n = 0; n < 256; n++)
{
boldcols[n] = (n & 8) != 0;
blinkcols[n][0] = normcols[n][0] = blue;
blinkcols[n][1] = normcols[n][1] = grey;
}
/* Colours 0x11-0xFF are controlled by bits 2 and 3 of the
* passed value. Exclude x0 and x8, which are always grey on
* blue. */
for (n = 0x11; n <= 0xFF; n++)
{
if ((n & 7) == 0) continue;
if (t1000->attrmap & 4) /* Inverse */
{
blinkcols[n][0] = normcols[n][0] = blue;
blinkcols[n][1] = normcols[n][1] = grey;
}
else /* Normal */
{
blinkcols[n][0] = normcols[n][0] = grey;
blinkcols[n][1] = normcols[n][1] = blue;
}
if (t1000->attrmap & 8) boldcols[n] = 1; /* Bold */
}
/* Set up the 01-0E range, controlled by bits 0 and 1 of the
* passed value. When blinking is enabled this also affects 81-8E. */
for (n = 0x01; n <= 0x0E; n++)
{
if (n == 7) continue;
if (t1000->attrmap & 1)
{
blinkcols[n][0] = normcols[n][0] = blue;
blinkcols[n][1] = normcols[n][1] = grey;
blinkcols[n+128][0] = blue;
blinkcols[n+128][1] = grey;
}
else
{
blinkcols[n][0] = normcols[n][0] = grey;
blinkcols[n][1] = normcols[n][1] = blue;
blinkcols[n+128][0] = grey;
blinkcols[n+128][1] = blue;
}
if (t1000->attrmap & 2) boldcols[n] = 1;
}
/* Colours 07 and 0F are always blue on grey. If blinking is
* enabled so are 87 and 8F. */
for (n = 0x07; n <= 0x0F; n += 8)
{
blinkcols[n][0] = normcols[n][0] = grey;
blinkcols[n][1] = normcols[n][1] = blue;
blinkcols[n+128][0] = grey;
blinkcols[n+128][1] = blue;
}
/* When not blinking, colours 81-8F are always blue on grey. */
for (n = 0x81; n <= 0x8F; n ++)
{
normcols[n][0] = grey;
normcols[n][1] = blue;
boldcols[n] = (n & 0x08) != 0;
}
/* Finally do the ones which are solid grey. These differ between
* the normal and blinking mappings */
for (n = 0; n <= 0xFF; n += 0x11)
{
normcols[n][0] = normcols[n][1] = grey;
}
/* In the blinking range, 00 11 22 .. 77 and 80 91 A2 .. F7 are grey */
for (n = 0; n <= 0x77; n += 0x11)
{
blinkcols[n][0] = blinkcols[n][1] = grey;
blinkcols[n+128][0] = blinkcols[n+128][1] = grey;
}
}
static void *t1000_init()
{
t1000_t *t1000 = malloc(sizeof(t1000_t));
memset(t1000, 0, sizeof(t1000_t));
cga_init(&t1000->cga);
t1000->internal = 1;
/* 16k video RAM */
t1000->vram = malloc(0x4000);
timer_add(t1000_poll, &t1000->cga.vidtime, TIMER_ALWAYS_ENABLED, t1000);
/* Occupy memory between 0xB8000 and 0xBFFFF */
mem_mapping_add(&t1000->mapping, 0xb8000, 0x8000, t1000_read, NULL, NULL, t1000_write, NULL, NULL, NULL, 0, t1000);
/* Respond to CGA I/O ports */
io_sethandler(0x03d0, 0x000c, t1000_in, NULL, NULL, t1000_out, NULL, NULL, t1000);
/* Default attribute mapping is 4 */
t1000->attrmap = 4;
t1000_recalcattrs(t1000);
/* Start off in 80x25 text mode */
t1000->cga.cgastat = 0xF4;
t1000->cga.vram = t1000->vram;
t1000->enabled = 1;
t1000->video_options = 0x01;
return t1000;
}
static void t1000_close(void *p)
{
t1000_t *t1000 = (t1000_t *)p;
free(t1000->vram);
free(t1000);
}
static void t1000_speed_changed(void *p)
{
t1000_t *t1000 = (t1000_t *)p;
t1000_recalctimings(t1000);
}
static device_config_t t1000_config[] =
{
{
.name = "display_language",
.description = "Language",
.type = CONFIG_SELECTION,
.selection =
{
{
.description = "USA",
.value = 0
},
{
.description = "Danish",
.value = 1
}
},
.default_int = 0
},
{
.type = -1
}
};
device_t t1000_device =
{
"Toshiba T1000",
0,
t1000_init,
t1000_close,
NULL,
t1000_speed_changed,
NULL,
NULL,
t1000_config
};

4
src/vid_t1000.h Normal file
View file

@ -0,0 +1,4 @@
extern device_t t1000_device;
void t1000_video_options_set(uint8_t options);
void t1000_display_set(uint8_t internal);

View file

@ -42,6 +42,7 @@
#include "vid_vga.h"
#include "vid_wy700.h"
#include "vid_t3100e.h"
#include "vid_t1000.h"
typedef struct
{
@ -316,6 +317,10 @@ void video_init()
case ROM_T3100E:
device_add(&t3100e_device);
return;
case ROM_T1000:
device_add(&t1000_device);
return;
}
device_add(video_cards[video_old_to_new(gfxcard)].device);
}
@ -393,7 +398,7 @@ void loadfont(char *s, int format)
break;
default:
case 2: /* CGA */
for (c=0;c<256;c++)
for (c=0;c<2048;c++) /* Allow up to 2048 chars */
{
for (d=0;d<8;d++)
{