Added emulation of Packard Bell PB410A, along with the built-in Headland HT216-32 video.
This commit is contained in:
parent
cc4118fca0
commit
35962551dd
18 changed files with 1178 additions and 13 deletions
|
|
@ -23,7 +23,7 @@ wx-resources.cpp : pc.xrc
|
|||
-wxrc -c pc.xrc -o wx-resources.cpp
|
||||
|
||||
# PCem
|
||||
pcem_SOURCES = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.c acc2036.c acer386sx.c ali1429.c amstrad.c cbm_io.c cdrom-image.cc cdrom-null.c \
|
||||
pcem_SOURCES = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.c acc2036.c acc2036.c acc2168.c acer386sx.c ali1429.c amstrad.c cbm_io.c cdrom-image.cc cdrom-null.c \
|
||||
cmd640.c codegen.c codegen_ops.c codegen_timing_486.c codegen_timing_686.c codegen_timing_common.c codegen_timing_pentium.c codegen_timing_winchip.c compaq.c config.c cpu.c \
|
||||
dells200.c device.c disc.c disc_fdi.c disc_img.c disc_sector.c dma.c esdi_at.c fdc.c fdc37c665.c fdd.c fdi2raw.c gameport.c \
|
||||
hdd.c hdd_esdi.c hdd_file.c headland.c i430hx.c i430lx.c i430fx.c i430vx.c ide.c ide_atapi.c intel.c intel_flash.c io.c jim.c joystick_ch_flightstick_pro.c joystick_standard.c joystick_sw_pad.c \
|
||||
|
|
@ -36,7 +36,7 @@ sound_speaker.c sound_ssi2001.c sound_wss.c sound_ym7128.c soundopenal.c tandy_e
|
|||
t1000.c t3100e.c \
|
||||
timer.c um8669f.c um8881f.c vid_ati_eeprom.c vid_ati_mach64.c vid_ati18800.c vid_ati28800.c \
|
||||
vid_ati68860_ramdac.c vid_cga.c vid_cl5429.c vid_colorplus.c vid_compaq_cga.c vid_ega.c vid_et4000.c vid_et4000w32.c vid_genius.c vid_hercules.c \
|
||||
vid_icd2061.c vid_ics2595.c vid_incolor.c vid_mda.c vid_olivetti_m24.c vid_oti037.c vid_oti067.c vid_paradise.c vid_pc200.c \
|
||||
vid_ht216.c vid_icd2061.c vid_ics2595.c vid_incolor.c vid_mda.c vid_olivetti_m24.c vid_oti037.c vid_oti067.c vid_paradise.c vid_pc200.c \
|
||||
vid_pc1512.c vid_pc1640.c vid_pcjr.c vid_ps1_svga.c vid_s3.c vid_s3_virge.c vid_sdac_ramdac.c vid_sigma.c \
|
||||
vid_stg_ramdac.c vid_svga.c vid_svga_render.c vid_t1000.c vid_t3100e.c vid_tandy.c vid_tandysl.c vid_tgui9440.c \
|
||||
vid_tkd8001_ramdac.c vid_tvga.c vid_unk_ramdac.c vid_vga.c vid_voodoo.c video.c wd76c10.c vid_wy700.c \
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ CC = gcc
|
|||
WXRC = wxrc
|
||||
CFLAGS = -O3 -fomit-frame-pointer -msse2 -m32 $(shell wx-config --cxxflags) $(shell sdl2-config --cflags)
|
||||
CXXFLAGS = $(CFLAGS)
|
||||
OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acer386sx.o ali1429.o amstrad.o cbm_io.o cdrom-ioctl-linux.o cdrom-image.o cdrom-null.o \
|
||||
OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acc2036.o acc2168.o acer386sx.o ali1429.o amstrad.o cbm_io.o cdrom-ioctl-linux.o cdrom-image.o cdrom-null.o \
|
||||
cmd640.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.c compaq.o config.o cpu.o \
|
||||
dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \
|
||||
hdd.o hdd_esdi.o hdd_file.o headland.o i430hx.o i430lx.o i430fx.o i430vx.o ide.o ide_atapi.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.o joystick_standard.o joystick_sw_pad.o \
|
||||
|
|
@ -16,7 +16,7 @@ sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.o sound_sb.
|
|||
sound_speaker.o sound_ssi2001.o sound_wss.o sound_ym7128.o soundopenal.o t1000.o t3100e.o tandy_eeprom.o tandy_rom.o \
|
||||
timer.o um8669f.o um8881f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o vid_ati28800.o \
|
||||
vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_compaq_cga.o vid_ega.o vid_et4000.o vid_et4000w32.o vid_genius.o vid_hercules.o \
|
||||
vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o vid_olivetti_m24.o vid_oti037.c vid_oti067.o vid_paradise.o vid_pc200.o \
|
||||
vid_ht216.o vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o vid_olivetti_m24.o vid_oti037.c vid_oti067.o vid_paradise.o vid_pc200.o \
|
||||
vid_pc1512.o vid_pc1640.o vid_pcjr.o vid_ps1_svga.o vid_s3.o vid_s3_virge.o vid_sdac_ramdac.o vid_sigma.o \
|
||||
vid_stg_ramdac.o vid_svga.o vid_svga_render.o vid_t1000.o vid_t3100e.o vid_tandy.o vid_tandysl.o vid_tgui9440.o \
|
||||
vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o vid_vga.o vid_voodoo.o vid_wy700.o video.o wd76c10.o \
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ CC = gcc
|
|||
WXRC = wxrc
|
||||
CFLAGS = -O3 -fomit-frame-pointer -msse2 -m64 $(shell wx-config --cxxflags) $(shell sdl2-config --cflags)
|
||||
CXXFLAGS = $(CFLAGS)
|
||||
OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acer386sx.o ali1429.o amstrad.o cbm_io.o cdrom-ioctl-linux.o cdrom-image.o cdrom-null.o \
|
||||
OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acc2036.o acc2168.o acer386sx.o ali1429.o amstrad.o cbm_io.o cdrom-ioctl-linux.o cdrom-image.o cdrom-null.o \
|
||||
cmd640.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86-64.c compaq.o config.o cpu.o \
|
||||
dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \
|
||||
hdd.o hdd_esdi.o hdd_file.o headland.o i430hx.o i430lx.o i430fx.o i430vx.o ide.o ide_atapi.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.o joystick_standard.o joystick_sw_pad.o \
|
||||
|
|
@ -16,7 +16,7 @@ sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.o sound_sb.
|
|||
sound_speaker.o sound_ssi2001.o sound_wss.o sound_ym7128.o soundopenal.o t1000.o t3100e.o tandy_eeprom.o tandy_rom.o \
|
||||
timer.o um8669f.o um8881f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o vid_ati28800.o \
|
||||
vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_compaq_cga.o vid_ega.o vid_et4000.o vid_et4000w32.o vid_genius.o vid_hercules.o \
|
||||
vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o vid_olivetti_m24.o vid_oti037.c vid_oti067.o vid_paradise.o vid_pc200.o \
|
||||
vid_ht216.o vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o vid_olivetti_m24.o vid_oti037.c vid_oti067.o vid_paradise.o vid_pc200.o \
|
||||
vid_pc1512.o vid_pc1640.o vid_pcjr.o vid_ps1_svga.o vid_s3.o vid_s3_virge.o vid_sdac_ramdac.o vid_sigma.o \
|
||||
vid_stg_ramdac.o vid_svga.o vid_svga_render.o vid_t1000.o vid_t3100e.o vid_tandy.o vid_tandysl.o vid_tgui9440.o \
|
||||
vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o vid_vga.o vid_voodoo.o vid_wy700.o video.o wd76c10.o \
|
||||
|
|
|
|||
|
|
@ -3,10 +3,10 @@ CPP = g++
|
|||
CC = gcc
|
||||
WINDRES = windres.exe
|
||||
WXVERSION = 31
|
||||
WXINCLUDE = C:/MinGW/include/wx/
|
||||
WXINCLUDE = e:/MinGWget/include/wx/
|
||||
CFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign -Werror -fno-strict-aliasing
|
||||
CXXFLAGS = $(CFLAGS)
|
||||
OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acer386sx.o ali1429.o amstrad.o cbm_io.o cdrom-ioctl.o cdrom-image.o \
|
||||
OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acc2168.o acc3221.o acer386sx.o ali1429.o amstrad.o cbm_io.o cdrom-ioctl.o cdrom-image.o \
|
||||
cmd640.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.o compaq.o config.o cpu.o \
|
||||
device.o dells200.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430hx.o i430lx.o i430fx.o \
|
||||
i430vx.o ide.o ide_atapi.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.o joystick_standard.o joystick_sw_pad.o joystick_tm_fcs.o keyboard.o keyboard_amstrad.o keyboard_at.o \
|
||||
|
|
@ -17,7 +17,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acer386sx.o ali1429
|
|||
sound_sb.o sound_sb_dsp.o sound_sn76489.o sound_speaker.o sound_ssi2001.o sound_wss.o \
|
||||
sound_ym7128.o soundopenal.o t1000.o t3100e.o tandy_eeprom.o tandy_rom.o timer.o um8881f.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \
|
||||
vid_ati28800.o vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_compaq_cga.o vid_ega.o vid_et4000.o \
|
||||
vid_et4000w32.o vid_et4000w32i.o vid_genius.o vid_hercules.o vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o \
|
||||
vid_et4000w32.o vid_et4000w32i.o vid_genius.o vid_hercules.o vid_ht216.o vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o \
|
||||
vid_olivetti_m24.o vid_oti037.c vid_oti067.o vid_paradise.o vid_pc1512.o vid_pc1640.o vid_pc200.o \
|
||||
vid_pcjr.o vid_ps1_svga.o vid_s3.o vid_s3_virge.o vid_sdac_ramdac.o vid_sigma.o vid_stg_ramdac.o vid_svga.o \
|
||||
vid_svga_render.o vid_t1000.o vid_t3100e.o vid_tandy.o vid_tandysl.o vid_tgui9440.o vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o \
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ WXVERSION = 31
|
|||
WXINCLUDE = e:/mingwget/include/wx/
|
||||
CFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign -Werror -fno-strict-aliasing -DUSE_NETWORKING
|
||||
CXXFLAGS = $(CFLAGS)
|
||||
OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acer386sx.o ali1429.o amstrad.o cbm_io.o cdrom-ioctl.o cdrom-image.o \
|
||||
OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acc2036.o acc2168.o acer386sx.o ali1429.o amstrad.o cbm_io.o cdrom-ioctl.o cdrom-image.o \
|
||||
cmd640.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.o compaq.o config.o cpu.o \
|
||||
device.o dells200.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430hx.o i430lx.o i430fx.o \
|
||||
i430vx.o ide.o ide_atapi.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.o joystick_standard.o joystick_sw_pad.o joystick_tm_fcs.o keyboard.o keyboard_amstrad.o keyboard_at.o \
|
||||
|
|
@ -17,7 +17,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acer386sx.o ali1429
|
|||
sound_sb.o sound_sb_dsp.o sound_sn76489.o sound_speaker.o sound_ssi2001.o sound_wss.o \
|
||||
sound_ym7128.o soundopenal.o t1000.o t3100e.o tandy_eeprom.o tandy_rom.o timer.o um8881f.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \
|
||||
vid_ati28800.o vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_compaq_cga.o vid_ega.o vid_et4000.o \
|
||||
vid_et4000w32.o vid_et4000w32i.o vid_genius.o vid_hercules.o vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o \
|
||||
vid_et4000w32.o vid_et4000w32i.o vid_genius.o vid_hercules.o vid_ht216.o vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o \
|
||||
vid_olivetti_m24.o vid_oti037.c vid_oti067.o vid_paradise.o vid_pc1512.o vid_pc1640.o vid_pc200.o \
|
||||
vid_pcjr.o vid_ps1_svga.o vid_s3.o vid_s3_virge.o vid_sdac_ramdac.o vid_sigma.o vid_stg_ramdac.o vid_svga.o \
|
||||
vid_svga_render.o vid_t1000.o vid_t3100e.o vid_tandy.o vid_tandysl.o vid_tgui9440.o vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o \
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ CPP = g++
|
|||
CC = gcc
|
||||
WXRC = wxrc
|
||||
CFLAGS = -D__unix=1 -DPCEM_RENDER_WITH_TIMER -DPCEM_RENDER_TIMER_LOOP -Dfopen64=fopen -Dfseeko64=fseeko -Dftello64=ftello -Doff64_t=off_t -O3 -fomit-frame-pointer -msse2 -m64 $(shell wx-config --cxxflags) $(shell sdl2-config --cflags) -I/usr/local/opt/openal-soft/include -I/usr/local/include
|
||||
OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acer386sx.o ali1429.o amstrad.o cbm_io.o cdrom-ioctl-osx.o cdrom-image.o cdrom-null.o \
|
||||
OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acc2036.o acc2168.o acer386sx.o ali1429.o amstrad.o cbm_io.o cdrom-ioctl-osx.o cdrom-image.o cdrom-null.o \
|
||||
cmd640.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86-64.c compaq.o config.o cpu.o \
|
||||
device.o dells200.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \
|
||||
hdd.o hdd_esdi.o hdd_file.o headland.o i430hx.o i430lx.o i430fx.o i430vx.o ide.o ide_atapi.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.o joystick_standard.o joystick_sw_pad.o \
|
||||
|
|
@ -15,7 +15,7 @@ sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.o sound_sb.
|
|||
sound_speaker.o sound_ssi2001.o sound_wss.o sound_ym7128.o soundopenal.o t1000.o t3100e.o tandy_eeprom.o tandy_rom.o \
|
||||
timer.o um8669f.o um8881f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o vid_ati28800.o \
|
||||
vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_compaq_cga.o vid_ega.o vid_et4000.o vid_et4000w32.o vid_genius.o vid_hercules.o \
|
||||
vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o vid_olivetti_m24.o vid_oti037.c vid_oti067.o vid_paradise.o vid_pc200.o \
|
||||
vid_ht216.o vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o vid_olivetti_m24.o vid_oti037.c vid_oti067.o vid_paradise.o vid_pc200.o \
|
||||
vid_pc1512.o vid_pc1640.o vid_pcjr.o vid_ps1_svga.o vid_s3.o vid_s3_virge.o vid_sdac_ramdac.o vid_sigma.o \
|
||||
vid_stg_ramdac.o vid_svga.o vid_svga_render.o vid_t1000.o vid_t3100e.o vid_tandy.o vid_tandysl.o vid_tgui9440.o \
|
||||
vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o vid_vga.o vid_voodoo.o vid_wy700.o video.o wd76c10.o \
|
||||
|
|
|
|||
|
|
@ -88,6 +88,9 @@ static uint8_t acc2036_read(uint16_t addr, void *p)
|
|||
{
|
||||
if (!(addr & 1))
|
||||
return acc2036.reg_idx;
|
||||
|
||||
if (acc2036.reg_idx >= 0xbc)
|
||||
return 0xff;
|
||||
|
||||
return acc2036.regs[acc2036.reg_idx];
|
||||
}
|
||||
|
|
|
|||
119
src/acc2168.c
Normal file
119
src/acc2168.c
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
#include "ibm.h"
|
||||
#include "acc2168.h"
|
||||
#include "cpu.h"
|
||||
#include "io.h"
|
||||
#include "mem.h"
|
||||
#include "x86.h"
|
||||
|
||||
static struct
|
||||
{
|
||||
int reg_idx;
|
||||
uint8_t regs[256];
|
||||
uint8_t port_62;
|
||||
} acc2168;
|
||||
|
||||
static void acc2168_shadow_recalc()
|
||||
{
|
||||
if (acc2168.regs[0x02] & 8)
|
||||
{
|
||||
switch (acc2168.regs[0x02] & 0x30)
|
||||
{
|
||||
case 0x00:
|
||||
mem_set_mem_state(0xf0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL);
|
||||
break;
|
||||
case 0x10:
|
||||
mem_set_mem_state(0xf0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
break;
|
||||
case 0x20:
|
||||
mem_set_mem_state(0xf0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
|
||||
break;
|
||||
case 0x30:
|
||||
mem_set_mem_state(0xf0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
mem_set_mem_state(0xf0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
|
||||
|
||||
if (acc2168.regs[0x02] & 4)
|
||||
{
|
||||
switch (acc2168.regs[0x02] & 0x30)
|
||||
{
|
||||
case 0x00:
|
||||
mem_set_mem_state(0xe0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL);
|
||||
break;
|
||||
case 0x10:
|
||||
mem_set_mem_state(0xe0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
break;
|
||||
case 0x20:
|
||||
mem_set_mem_state(0xe0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
|
||||
break;
|
||||
case 0x30:
|
||||
mem_set_mem_state(0xe0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
mem_set_mem_state(0xe0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
|
||||
}
|
||||
|
||||
static void acc2168_write(uint16_t addr, uint8_t val, void *p)
|
||||
{
|
||||
// pclog("acc2168_write: addr=%04x val=%02x\n", addr, val);
|
||||
if (!(addr & 1))
|
||||
acc2168.reg_idx = val;
|
||||
else
|
||||
{
|
||||
acc2168.regs[acc2168.reg_idx] = val;
|
||||
// pclog("acc2168_write: idx=%02x val=%02x %04x:%04x\n", acc2168.reg_idx, val, CS,cpu_state.pc);
|
||||
|
||||
switch (acc2168.reg_idx)
|
||||
{
|
||||
case 0x02:
|
||||
acc2168_shadow_recalc();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t acc2168_read(uint16_t addr, void *p)
|
||||
{
|
||||
if (!(addr & 1))
|
||||
return acc2168.reg_idx;
|
||||
|
||||
// pclog("acc2168_read: idx=%02x val=%02x\n", acc2168.reg_idx, acc2168.regs[acc2168.reg_idx]);
|
||||
return acc2168.regs[acc2168.reg_idx];
|
||||
}
|
||||
|
||||
static uint8_t port78_read(uint16_t addr, void *p)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint8_t port92_read(uint16_t addr, void *p)
|
||||
{
|
||||
return acc2168.port_62 | 0xfc;
|
||||
}
|
||||
|
||||
static void port92_write(uint16_t addr, uint8_t val, void *p)
|
||||
{
|
||||
if ((mem_a20_alt ^ val) & 2)
|
||||
{
|
||||
mem_a20_alt = val & 2;
|
||||
mem_a20_recalc();
|
||||
}
|
||||
if ((~acc2168.port_62 & val) & 1)
|
||||
{
|
||||
softresetx86();
|
||||
cpu_set_edx();
|
||||
}
|
||||
acc2168.port_62 = val | 0xfC;
|
||||
}
|
||||
|
||||
void acc2168_init()
|
||||
{
|
||||
memset(&acc2168, 0, sizeof(acc2168));
|
||||
io_sethandler(0x00f2, 0x0002, acc2168_read, NULL, NULL, acc2168_write, NULL, NULL, NULL);
|
||||
io_sethandler(0x0078, 0x0001, port78_read, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
io_sethandler(0x0092, 0x0001, port92_read, NULL, NULL, port92_write, NULL, NULL, NULL);
|
||||
}
|
||||
1
src/acc2168.h
Normal file
1
src/acc2168.h
Normal file
|
|
@ -0,0 +1 @@
|
|||
void acc2168_init();
|
||||
122
src/acc3221.c
Normal file
122
src/acc3221.c
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
#include "ibm.h"
|
||||
#include "acc3221.h"
|
||||
#include "fdc.h"
|
||||
#include "ide.h"
|
||||
#include "io.h"
|
||||
#include "lpt.h"
|
||||
#include "serial.h"
|
||||
|
||||
static struct
|
||||
{
|
||||
int reg_idx;
|
||||
uint8_t regs[256];
|
||||
} acc3221;
|
||||
|
||||
#define REG_BE_LPT1_DISABLE (1 << 4)
|
||||
|
||||
#define REG_DB_SERIAL1_DISABLE (1 << 4)
|
||||
#define REG_DB_SERIAL2_DISABLE (1 << 1)
|
||||
|
||||
#define REG_DE_SIRQ3_SOURCE (3 << 6)
|
||||
#define REG_DE_SIRQ3_SERIAL1 (1 << 6)
|
||||
#define REG_DE_SIRQ3_SERIAL2 (3 << 6)
|
||||
|
||||
#define REG_DE_SIRQ4_SOURCE (3 << 4)
|
||||
#define REG_DE_SIRQ4_SERIAL1 (1 << 4)
|
||||
#define REG_DE_SIRQ4_SERIAL2 (3 << 4)
|
||||
|
||||
#define REG_FB_FDC_DISABLE (1 << 1)
|
||||
|
||||
#define REG_FE_IDE_DISABLE (1 << 1)
|
||||
|
||||
static void acc3221_write(uint16_t addr, uint8_t val, void *p)
|
||||
{
|
||||
if (!(addr & 1))
|
||||
acc3221.reg_idx = val;
|
||||
else
|
||||
{
|
||||
acc3221.regs[acc3221.reg_idx] = val;
|
||||
// pclog("Write ACC2036 R%02x %02x %04x:%04x %i\n", acc2036.reg_idx, val, CS,cpu_state.pc, ins);
|
||||
|
||||
if (acc3221.reg_idx >= 0xbc)
|
||||
{
|
||||
// pclog("Write ACC3221 R%02x %02x %04x:%04x %i\n", acc3221.reg_idx, val, CS,cpu_state.pc, ins);
|
||||
fdc_remove();
|
||||
if (!(acc3221.regs[0xfb] & REG_FB_FDC_DISABLE))
|
||||
fdc_add();
|
||||
|
||||
serial1_remove();
|
||||
if (!(acc3221.regs[0xdb] & REG_DB_SERIAL1_DISABLE))
|
||||
{
|
||||
uint16_t addr = (acc3221.regs[0xdc] & 0x7f) << 2;
|
||||
|
||||
if ((acc3221.regs[0xde] & REG_DE_SIRQ3_SOURCE) == REG_DE_SIRQ3_SERIAL1)
|
||||
{
|
||||
// pclog("COM1 addr %03x IRQ 3\n", addr);
|
||||
serial1_set(addr, 3);
|
||||
}
|
||||
else if ((acc3221.regs[0xde] & REG_DE_SIRQ4_SOURCE) == REG_DE_SIRQ3_SERIAL1)
|
||||
{
|
||||
// pclog("COM1 addr %03x IRQ 4\n", addr);
|
||||
serial1_set(addr, 4);
|
||||
}
|
||||
// else
|
||||
// pclog("COM1 addr %03x no IRQ\n", addr);
|
||||
}
|
||||
// else
|
||||
// pclog("COM1 disabled\n");
|
||||
|
||||
serial2_remove();
|
||||
if (!(acc3221.regs[0xdb] & REG_DB_SERIAL2_DISABLE))
|
||||
{
|
||||
uint16_t addr = (acc3221.regs[0xdd] & 0x7f) << 2;
|
||||
|
||||
if ((acc3221.regs[0xde] & REG_DE_SIRQ3_SOURCE) == REG_DE_SIRQ3_SERIAL2)
|
||||
{
|
||||
// pclog("COM2 addr %03x IRQ 3\n", addr);
|
||||
serial2_set(addr, 3);
|
||||
}
|
||||
else if ((acc3221.regs[0xde] & REG_DE_SIRQ4_SOURCE) == REG_DE_SIRQ3_SERIAL2)
|
||||
{
|
||||
// pclog("COM2 addr %03x IRQ 4\n", addr);
|
||||
serial2_set(addr, 4);
|
||||
}
|
||||
// else
|
||||
// pclog("COM2 addr %03x no IRQ\n", addr);
|
||||
}
|
||||
// else
|
||||
// pclog("COM2 disabled\n");
|
||||
|
||||
lpt1_remove();
|
||||
lpt2_remove();
|
||||
if (!(acc3221.regs[0xbe] & REG_BE_LPT1_DISABLE))
|
||||
{
|
||||
// pclog("LPT1 addr %03x\n", acc3221.regs[0xbf] << 2);
|
||||
lpt1_init(acc3221.regs[0xbf] << 2);
|
||||
}
|
||||
// else
|
||||
// pclog("LPT1 disabled\n");
|
||||
|
||||
ide_pri_disable();
|
||||
if (!(acc3221.regs[0xfe] & REG_FE_IDE_DISABLE))
|
||||
ide_pri_enable();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t acc3221_read(uint16_t addr, void *p)
|
||||
{
|
||||
if (!(addr & 1))
|
||||
return acc3221.reg_idx;
|
||||
|
||||
if (acc3221.reg_idx < 0xbc)
|
||||
return 0xff;
|
||||
|
||||
return acc3221.regs[acc3221.reg_idx];
|
||||
}
|
||||
|
||||
void acc3221_init()
|
||||
{
|
||||
memset(&acc3221, 0, sizeof(acc3221));
|
||||
io_sethandler(0x00f2, 0x0002, acc3221_read, NULL, NULL, acc3221_write, NULL, NULL, NULL);
|
||||
}
|
||||
1
src/acc3221.h
Normal file
1
src/acc3221.h
Normal file
|
|
@ -0,0 +1 @@
|
|||
void acc3221_init();
|
||||
|
|
@ -467,6 +467,7 @@ enum
|
|||
ROM_IBMPS2_M70_TYPE4,
|
||||
ROM_TULIP_TC7,
|
||||
ROM_ZD_SUPERS, /* [8088] Zenith Data Systems SupersPort */
|
||||
ROM_PB410A,
|
||||
|
||||
ROM_MAX
|
||||
};
|
||||
|
|
|
|||
|
|
@ -965,6 +965,14 @@ int loadbios()
|
|||
fclose(f);
|
||||
biosmask = 0x7fff;
|
||||
return 1;
|
||||
|
||||
case ROM_PB410A:
|
||||
f = romfopen("pb410a/PB410A.080337.4ABF.U25.bin","rb");
|
||||
if (!f) break;
|
||||
romfread(rom, 0x20000, 1, f);
|
||||
fclose(f);
|
||||
biosmask = 0x1ffff;
|
||||
return 1;
|
||||
}
|
||||
printf("Failed to load ROM!\n");
|
||||
if (f) fclose(f);
|
||||
|
|
|
|||
12
src/model.c
12
src/model.c
|
|
@ -5,6 +5,8 @@
|
|||
#include "mouse.h"
|
||||
|
||||
#include "acc2036.h"
|
||||
#include "acc2168.h"
|
||||
#include "acc3221.h"
|
||||
#include "acer386sx.h"
|
||||
#include "ali1429.h"
|
||||
#include "amstrad.h"
|
||||
|
|
@ -107,6 +109,7 @@ void xt_t1000_init();
|
|||
void xt_t1200_init();
|
||||
void at_sl82c460_init();
|
||||
void at_zappa_init();
|
||||
void at_pb410a_init();
|
||||
void at_pb520r_init();
|
||||
void at_pb570_init();
|
||||
void compaq_pip_init();
|
||||
|
|
@ -189,6 +192,7 @@ MODEL models[] =
|
|||
{"[486] Award SiS 496/497", ROM_SIS496, "sis496", { {"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_HAS_IDE, 1, 256, 1, at_sis496_init, NULL},
|
||||
{"[486] Elonex PC-425X", ROM_ELX_PC425X, "elx_pc425x", { {"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}}, MODEL_GFX_FIXED|MODEL_AT|MODEL_HAS_IDE, 1, 256, 1, at_sl82c460_init, NULL},
|
||||
{"[486] IBM PS/2 Model 70 (type 4)", ROM_IBMPS2_M70_TYPE4, "ibmps2_m70_type4", { {"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}}, MODEL_GFX_FIXED|MODEL_AT|MODEL_PS2|MODEL_MCA, 2, 16, 2, ps2_model_70_init, NULL},
|
||||
{"[486] Packard Bell PB410A", ROM_PB410A, "pb410a", { {"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}}, MODEL_GFX_DISABLE_SW|MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 1, 64, 1, at_pb410a_init, NULL},
|
||||
|
||||
{"[Socket 4] Intel Premiere/PCI", ROM_REVENGE, "revenge", { {"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 128, 1, at_batman_init, NULL},
|
||||
{"[Socket 4] Packard Bell PB520R",ROM_PB520R, "pb520r", { {"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}}, MODEL_GFX_DISABLE_SW|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 128, 1, at_pb520r_init, NULL},
|
||||
|
|
@ -591,6 +595,14 @@ void pb_l300sx_init()
|
|||
acc2036_init();
|
||||
}
|
||||
|
||||
void at_pb410a_init()
|
||||
{
|
||||
at_init();
|
||||
acc2168_init();
|
||||
acc3221_init();
|
||||
}
|
||||
|
||||
|
||||
void at_sis496_init()
|
||||
{
|
||||
at_init();
|
||||
|
|
|
|||
|
|
@ -314,6 +314,7 @@ void loadnvr()
|
|||
case ROM_IBMPS2_M70_TYPE3: f = nvrfopen("ibmps2_m70_type3.nvr","rb"); break;
|
||||
case ROM_IBMPS2_M70_TYPE4: f = nvrfopen("ibmps2_m70_type4.nvr","rb"); break;
|
||||
case ROM_TULIP_TC7: f = nvrfopen("tulip_tc7.nvr", "rb"); break;
|
||||
case ROM_PB410A: f = nvrfopen("pb410a.nvr", "rb"); nvrmask = 127; break;
|
||||
|
||||
default: return;
|
||||
}
|
||||
|
|
@ -410,6 +411,7 @@ void savenvr()
|
|||
case ROM_IBMPS2_M70_TYPE3: f = nvrfopen("ibmps2_m70_type3.nvr","wb"); break;
|
||||
case ROM_IBMPS2_M70_TYPE4: f = nvrfopen("ibmps2_m70_type4.nvr","wb"); break;
|
||||
case ROM_TULIP_TC7: f = nvrfopen("tulip_tc7.nvr", "wb"); break;
|
||||
case ROM_PB410A: f = nvrfopen("pb410a.nvr", "wb"); break;
|
||||
|
||||
default: return;
|
||||
}
|
||||
|
|
|
|||
873
src/vid_ht216.c
Normal file
873
src/vid_ht216.c
Normal file
|
|
@ -0,0 +1,873 @@
|
|||
#include <stdlib.h>
|
||||
#include "ibm.h"
|
||||
#include "device.h"
|
||||
#include "io.h"
|
||||
#include "mem.h"
|
||||
#include "rom.h"
|
||||
#include "video.h"
|
||||
#include "vid_ht216.h"
|
||||
#include "vid_svga.h"
|
||||
#include "vid_svga_render.h"
|
||||
#include "vid_unk_ramdac.h"
|
||||
|
||||
typedef struct ht216_t
|
||||
{
|
||||
svga_t svga;
|
||||
|
||||
mem_mapping_t linear_mapping;
|
||||
|
||||
rom_t bios_rom;
|
||||
|
||||
uint32_t vram_mask;
|
||||
|
||||
int ext_reg_enable;
|
||||
int clk_sel;
|
||||
|
||||
uint8_t read_bank_reg[2], write_bank_reg[2];
|
||||
uint32_t read_bank[2], write_bank[2];
|
||||
uint8_t misc;
|
||||
|
||||
uint8_t bg_latch[8];
|
||||
|
||||
uint8_t ht_regs[256];
|
||||
} ht216_t;
|
||||
|
||||
#define HT_MISC_PAGE_SEL (1 << 5)
|
||||
|
||||
/*Shifts CPU VRAM read address by 3 bits, for use with fat pixel colour expansion*/
|
||||
#define HT_REG_C8_MOVSB (1 << 0)
|
||||
#define HT_REG_C8_E256 (1 << 4)
|
||||
#define HT_REG_C8_XLAM (1 << 6)
|
||||
|
||||
#define HT_REG_CD_FP8PCEXP (1 << 1)
|
||||
#define HT_REG_CD_BMSKSL (3 << 2)
|
||||
#define HT_REG_CD_RMWMDE (1 << 5)
|
||||
/*Use GDC data rotate as offset when reading VRAM data into latches*/
|
||||
#define HT_REG_CD_ASTODE (1 << 6)
|
||||
#define HT_REG_CD_EXALU (1 << 7)
|
||||
|
||||
#define HT_REG_E0_SBAE (1 << 7)
|
||||
|
||||
#define HT_REG_F9_XPSEL (1 << 0)
|
||||
|
||||
/*Enables A[14:15] of VRAM address in chain-4 modes*/
|
||||
#define HT_REG_FC_ECOLRE (1 << 2)
|
||||
|
||||
#define HT_REG_FE_FBRC (1 << 1)
|
||||
#define HT_REG_FE_FBMC (3 << 2)
|
||||
#define HT_REG_FE_FBRSL (3 << 4)
|
||||
|
||||
void ht216_remap(ht216_t *ht216);
|
||||
|
||||
void ht216_out(uint16_t addr, uint8_t val, void *p);
|
||||
uint8_t ht216_in(uint16_t addr, void *p);
|
||||
|
||||
void ht216_out(uint16_t addr, uint8_t val, void *p)
|
||||
{
|
||||
ht216_t *ht216 = (ht216_t *)p;
|
||||
svga_t *svga = &ht216->svga;
|
||||
uint8_t old;
|
||||
|
||||
// pclog("ht216 %i out %04X %02X %04X:%04X\n", svga->miscout & 1, addr, val, CS, cpu_state.pc);
|
||||
|
||||
if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1))
|
||||
addr ^= 0x60;
|
||||
|
||||
switch (addr)
|
||||
{
|
||||
case 0x3c2:
|
||||
ht216->clk_sel = (ht216->clk_sel & ~3) | ((val & 0x0c) >> 2);
|
||||
ht216->misc = val;
|
||||
ht216_remap(ht216);
|
||||
svga_recalctimings(&ht216->svga);
|
||||
break;
|
||||
|
||||
case 0x3c5:
|
||||
if (svga->seqaddr == 4)
|
||||
{
|
||||
svga->chain4 = val & 8;
|
||||
ht216_remap(ht216);
|
||||
}
|
||||
else if (svga->seqaddr == 6)
|
||||
{
|
||||
if (val == 0xea)
|
||||
ht216->ext_reg_enable = 1;
|
||||
else if (val == 0xae)
|
||||
ht216->ext_reg_enable = 0;
|
||||
}
|
||||
else if (svga->seqaddr >= 0x80 && ht216->ext_reg_enable)
|
||||
{
|
||||
ht216->ht_regs[svga->seqaddr & 0xff] = val;
|
||||
// pclog("HT[%02x]=%02x %04x(%08x):%08x\n", svga->seqaddr, val, CS,cs,cpu_state.pc);
|
||||
switch (svga->seqaddr & 0xff)
|
||||
{
|
||||
case 0x83:
|
||||
svga->attraddr = val & 0x1f;
|
||||
svga->attrff = (val & 0x80) ? 1 : 0;
|
||||
break;
|
||||
|
||||
case 0x94:
|
||||
svga->hwcursor.addr = ((val << 6) | (3 << 14) | ((ht216->ht_regs[0xff] & 0x60) << 11)) << 2;
|
||||
//pclog("cursor_addr = %05x\n", svga->hwcursor.addr);
|
||||
break;
|
||||
case 0x9c: case 0x9d:
|
||||
svga->hwcursor.x = ht216->ht_regs[0x9d] | ((ht216->ht_regs[0x9c] & 7) << 8);
|
||||
break;
|
||||
case 0x9e: case 0x9f:
|
||||
svga->hwcursor.y = ht216->ht_regs[0x9f] | ((ht216->ht_regs[0x9e] & 3) << 8);
|
||||
break;
|
||||
case 0xa0:
|
||||
svga->la = val;
|
||||
break;
|
||||
case 0xa1:
|
||||
svga->lb = val;
|
||||
break;
|
||||
case 0xa2:
|
||||
svga->lc = val;
|
||||
break;
|
||||
case 0xa3:
|
||||
svga->ld = val;
|
||||
break;
|
||||
case 0xa4:
|
||||
ht216->clk_sel = (val >> 2) & 0xf;
|
||||
svga->miscout = (svga->miscout & ~0xc) | ((ht216->clk_sel & 3) << 2);
|
||||
break;
|
||||
case 0xa5:
|
||||
svga->hwcursor.ena = val & 0x80;
|
||||
break;
|
||||
case 0xe8:
|
||||
ht216->read_bank_reg[0] = val;
|
||||
ht216->write_bank_reg[0] = val;
|
||||
break;
|
||||
case 0xe9:
|
||||
ht216->read_bank_reg[1] = val;
|
||||
ht216->write_bank_reg[1] = val;
|
||||
break;
|
||||
case 0xf6:
|
||||
svga->vram_display_mask = (val & 0x40) ? ht216->vram_mask : 0x3ffff;
|
||||
break;
|
||||
case 0xff:
|
||||
svga->hwcursor.addr = ((ht216->ht_regs[0x94] << 6) | (3 << 14) | ((val & 0x60) << 11)) << 2;
|
||||
//pclog("cursor_addr = %05x\n", svga->hwcursor.addr);
|
||||
break;
|
||||
}
|
||||
switch (svga->seqaddr & 0xff)
|
||||
{
|
||||
case 0xa4: case 0xf6: case 0xfc:
|
||||
svga->fullchange = changeframecount;
|
||||
svga_recalctimings(&ht216->svga);
|
||||
break;
|
||||
}
|
||||
switch (svga->seqaddr & 0xff)
|
||||
{
|
||||
case 0xc8: case 0xc9: case 0xcf:
|
||||
case 0xe0: case 0xe8: case 0xe9:
|
||||
case 0xf6: case 0xf9:
|
||||
ht216_remap(ht216);
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x3cf:
|
||||
if (svga->gdcaddr == 6)
|
||||
{
|
||||
if (val & 8)
|
||||
svga->banked_mask = 0x7fff;
|
||||
else
|
||||
svga->banked_mask = 0xffff;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x3D4:
|
||||
svga->crtcreg = val & 0x3f;
|
||||
return;
|
||||
case 0x3D5:
|
||||
if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80))
|
||||
return;
|
||||
if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80))
|
||||
val = (svga->crtc[7] & ~0x10) | (val & 0x10);
|
||||
|
||||
// if (svga->crtcreg == 0xc)
|
||||
// pclog("CRTC[C]=%02x %08x\n", val, svga->vram_display_mask);
|
||||
old = svga->crtc[svga->crtcreg];
|
||||
svga->crtc[svga->crtcreg] = val;
|
||||
|
||||
if (old != val)
|
||||
{
|
||||
if (svga->crtcreg < 0xe || svga->crtcreg > 0x10)
|
||||
{
|
||||
svga->fullchange = changeframecount;
|
||||
svga_recalctimings(&ht216->svga);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x46e8:
|
||||
io_removehandler(0x03c0, 0x0020, ht216_in, NULL, NULL, ht216_out, NULL, NULL, ht216);
|
||||
mem_mapping_disable(&ht216->svga.mapping);
|
||||
mem_mapping_disable(&ht216->linear_mapping);
|
||||
if (val & 8)
|
||||
{
|
||||
io_sethandler(0x03c0, 0x0020, ht216_in, NULL, NULL, ht216_out, NULL, NULL, ht216);
|
||||
mem_mapping_enable(&ht216->svga.mapping);
|
||||
ht216_remap(ht216);
|
||||
}
|
||||
break;
|
||||
}
|
||||
svga_out(addr, val, svga);
|
||||
}
|
||||
|
||||
uint8_t ht216_in(uint16_t addr, void *p)
|
||||
{
|
||||
ht216_t *ht216 = (ht216_t *)p;
|
||||
svga_t *svga = &ht216->svga;
|
||||
|
||||
// if (addr != 0x3ba && addr != 0x3da) pclog("ht216 %i in %04X\n", svga->miscout & 1, addr);
|
||||
|
||||
if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1))
|
||||
addr ^= 0x60;
|
||||
|
||||
switch (addr)
|
||||
{
|
||||
case 0x3c2:
|
||||
// pclog("3C2 read\n");
|
||||
break;
|
||||
// return 0x10;
|
||||
|
||||
case 0x3c5:
|
||||
if (svga->seqaddr == 6)
|
||||
return ht216->ext_reg_enable;
|
||||
if (svga->seqaddr >= 0x80)
|
||||
{
|
||||
if (ht216->ext_reg_enable)
|
||||
{
|
||||
// pclog("Read HT[%02x]=%02x\n", svga->seqaddr & 0xff, ht216->ht_regs[svga->seqaddr & 0xff]);
|
||||
switch (svga->seqaddr & 0xff)
|
||||
{
|
||||
case 0x83:
|
||||
if (svga->attrff)
|
||||
return svga->attraddr | 0x80;
|
||||
return svga->attraddr;
|
||||
|
||||
case 0x8e: return 0x61; /*HT216-32*/
|
||||
case 0x8f: return 0x78;
|
||||
|
||||
case 0xa0:
|
||||
return svga->la;
|
||||
case 0xa1:
|
||||
return svga->lb;
|
||||
case 0xa2:
|
||||
return svga->lc;
|
||||
case 0xa3:
|
||||
return svga->ld;
|
||||
}
|
||||
return ht216->ht_regs[svga->seqaddr & 0xff];
|
||||
}
|
||||
else
|
||||
return 0xff;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x3D4:
|
||||
return svga->crtcreg;
|
||||
case 0x3D5:
|
||||
if (svga->crtcreg == 0x1f)
|
||||
return svga->crtc[0xc] ^ 0xea;
|
||||
return svga->crtc[svga->crtcreg];
|
||||
}
|
||||
return svga_in(addr, svga);
|
||||
}
|
||||
|
||||
void ht216_remap(ht216_t *ht216)
|
||||
{
|
||||
svga_t *svga = &ht216->svga;
|
||||
|
||||
mem_mapping_disable(&ht216->linear_mapping);
|
||||
if (ht216->ht_regs[0xc8] & HT_REG_C8_XLAM)
|
||||
{
|
||||
uint32_t linear_base = ((ht216->ht_regs[0xc9] & 0xf) << 20) | (ht216->ht_regs[0xcf] << 24);
|
||||
|
||||
pclog("Linear base %08x\n", linear_base);
|
||||
mem_mapping_set_addr(&ht216->linear_mapping, linear_base, 0x100000);
|
||||
|
||||
/*Linear mapping enabled*/
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t read_offset = (ht216->ht_regs[0xf6] & 0xc) << 16;
|
||||
uint32_t write_offset = (ht216->ht_regs[0xf6] & 0x3) << 18;
|
||||
|
||||
if (svga->chain4 && (ht216->ht_regs[0xfc] & HT_REG_FC_ECOLRE))
|
||||
{
|
||||
if (ht216->misc & HT_MISC_PAGE_SEL)
|
||||
{
|
||||
read_offset |= (1 << 17);
|
||||
write_offset |= (1 << 17);
|
||||
}
|
||||
if (ht216->ht_regs[0xf9] & HT_REG_F9_XPSEL)
|
||||
{
|
||||
read_offset |= (1 << 16);
|
||||
write_offset |= (1 << 16);
|
||||
}
|
||||
}
|
||||
ht216->read_bank[0] = read_offset + (ht216->read_bank_reg[0] << 12);
|
||||
ht216->write_bank[0] = write_offset + (ht216->write_bank_reg[0] << 12);
|
||||
if (ht216->ht_regs[0xe0] & HT_REG_E0_SBAE)
|
||||
{
|
||||
/*Split bank*/
|
||||
ht216->read_bank[1] = read_offset + (ht216->read_bank_reg[1] << 12);
|
||||
ht216->write_bank[1] = write_offset + (ht216->write_bank_reg[1] << 12);
|
||||
}
|
||||
else
|
||||
{
|
||||
ht216->read_bank[1] = ht216->read_bank[0] + (svga->chain4 ? 0x8000 : 0x20000);
|
||||
ht216->write_bank[1] = ht216->write_bank[0] + (svga->chain4 ? 0x8000 : 0x20000);
|
||||
}
|
||||
|
||||
if (!svga->chain4)
|
||||
{
|
||||
ht216->read_bank[0] >>= 2;
|
||||
ht216->read_bank[1] >>= 2;
|
||||
ht216->write_bank[0] >>= 2;
|
||||
ht216->write_bank[1] >>= 2;
|
||||
}
|
||||
}
|
||||
// pclog("Remap - chain4=%i gdc[6]=%02x read[0]=%05X write[0]=%05X read[1]=%05X write[1]=%05X\n", svga->chain4, svga->gdcreg[6], ht216->read_bank[0], ht216->write_bank[0], ht216->read_bank[1], ht216->write_bank[1]);
|
||||
}
|
||||
|
||||
void ht216_recalctimings(svga_t *svga)
|
||||
{
|
||||
ht216_t *ht216 = (ht216_t *)svga->p;
|
||||
|
||||
// pclog("clk_sel = %i\n", ht216->clk_sel);
|
||||
switch (ht216->clk_sel)
|
||||
{
|
||||
case 5: svga->clock = cpuclock / 65000000.0; break;
|
||||
case 6: svga->clock = cpuclock / 40000000.0; break;
|
||||
case 10: svga->clock = cpuclock / 80000000.0; break;
|
||||
}
|
||||
svga->lowres = !(ht216->ht_regs[0xc8] & HT_REG_C8_E256);
|
||||
svga->ma_latch |= ((ht216->ht_regs[0xf6] & 0x30) << 12);
|
||||
svga->interlace = ht216->ht_regs[0xe0] & 1;
|
||||
|
||||
if (svga->bpp == 8 && !svga->lowres)
|
||||
svga->render = svga_render_8bpp_highres;
|
||||
}
|
||||
|
||||
static void ht216_hwcursor_draw(svga_t *svga, int displine)
|
||||
{
|
||||
// ht216_t *ht216 = (ht216_t *)svga->p;
|
||||
int x;
|
||||
uint32_t dat[2];
|
||||
int offset = svga->hwcursor_latch.x + 32;
|
||||
|
||||
if (svga->interlace && svga->hwcursor_oddeven)
|
||||
svga->hwcursor_latch.addr += 4;
|
||||
|
||||
dat[0] = (svga->vram[svga->hwcursor_latch.addr] << 24) |
|
||||
(svga->vram[svga->hwcursor_latch.addr+1] << 16) |
|
||||
(svga->vram[svga->hwcursor_latch.addr+2] << 8) |
|
||||
svga->vram[svga->hwcursor_latch.addr+3];
|
||||
dat[1] = (svga->vram[svga->hwcursor_latch.addr+128] << 24) |
|
||||
(svga->vram[svga->hwcursor_latch.addr+128+1] << 16) |
|
||||
(svga->vram[svga->hwcursor_latch.addr+128+2] << 8) |
|
||||
svga->vram[svga->hwcursor_latch.addr+128+3];
|
||||
|
||||
for (x = 0; x < 32; x++)
|
||||
{
|
||||
if (!(dat[0] & 0x80000000))
|
||||
((uint32_t *)buffer32->line[displine])[offset + x] = 0;
|
||||
if (dat[1] & 0x80000000)
|
||||
((uint32_t *)buffer32->line[displine])[offset + x] ^= 0xffffff;
|
||||
|
||||
dat[0] <<= 1;
|
||||
dat[1] <<= 1;
|
||||
}
|
||||
|
||||
svga->hwcursor_latch.addr += 4;
|
||||
if (svga->interlace && !svga->hwcursor_oddeven)
|
||||
svga->hwcursor_latch.addr += 4;
|
||||
}
|
||||
|
||||
static inline uint8_t extalu(int op, uint8_t input_a, uint8_t input_b)
|
||||
{
|
||||
uint8_t val;
|
||||
|
||||
switch (op)
|
||||
{
|
||||
case 0x0: val = 0; break;
|
||||
case 0x1: val = ~(input_a | input_b); break;
|
||||
case 0x2: val = input_a & ~input_b; break;
|
||||
case 0x3: val = ~input_b; break;
|
||||
case 0x4: val = ~input_a & input_b; break;
|
||||
case 0x5: val = ~input_a; break;
|
||||
case 0x6: val = input_a ^ input_b; break;
|
||||
case 0x7: val = ~(input_a & input_b); break;
|
||||
case 0x8: val = input_a & input_b; break;
|
||||
case 0x9: val = ~(input_a ^ input_b); break;
|
||||
case 0xa: val = input_a; break;
|
||||
case 0xb: val = input_a | ~input_b; break;
|
||||
case 0xc: val = input_b; break;
|
||||
case 0xd: val = ~input_a | input_b; break;
|
||||
case 0xe: val = input_a | input_b; break;
|
||||
case 0xf: default: val = 0xff; break;
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
static void ht216_dm_extalu_write(ht216_t *ht216, uint32_t addr, uint8_t cpu_dat, uint8_t bit_mask, uint8_t cpu_dat_unexpanded, uint8_t rop_select)
|
||||
{
|
||||
/*Input B = CD.5
|
||||
Input A = FE[3:2]
|
||||
00 = Set/Reset output mode
|
||||
output = CPU-side ALU input
|
||||
01 = Solid fg/bg mode (3C4:FA/FB)
|
||||
Bit mask = 3CF.F5 or CPU byte
|
||||
10 = Dithered fg (3CF:EC-EF)
|
||||
11 = RMW (dest data) (set if CD.5 = 1)
|
||||
F/B ROP select = FE[5:4]
|
||||
00 = CPU byte
|
||||
01 = Bit mask (3CF:8)
|
||||
1x = (3C4:F5)*/
|
||||
svga_t *svga = &ht216->svga;
|
||||
uint8_t input_a = 0, input_b = 0;
|
||||
uint8_t fg, bg;
|
||||
uint8_t output;
|
||||
|
||||
if (ht216->ht_regs[0xcd] & HT_REG_CD_RMWMDE) /*RMW*/
|
||||
input_b = svga->vram[addr];
|
||||
else
|
||||
input_b = ht216->bg_latch[addr & 7];
|
||||
|
||||
switch (ht216->ht_regs[0xfe] & HT_REG_FE_FBMC)
|
||||
{
|
||||
case 0x00:
|
||||
input_a = cpu_dat;
|
||||
break;
|
||||
case 0x04:
|
||||
if (ht216->ht_regs[0xfe] & HT_REG_FE_FBRC)
|
||||
input_a = (cpu_dat_unexpanded & (1 << ((addr & 7) ^ 7))) ? ht216->ht_regs[0xfa] : ht216->ht_regs[0xfb];
|
||||
else
|
||||
input_a = (ht216->ht_regs[0xf5] & (1 << ((addr & 7) ^ 7))) ? ht216->ht_regs[0xfa] : ht216->ht_regs[0xfb];
|
||||
break;
|
||||
case 0x08:
|
||||
input_a = ht216->ht_regs[0xec + (addr & 3)];
|
||||
break;
|
||||
case 0x0c:
|
||||
input_a = ht216->bg_latch[addr & 7];
|
||||
break;
|
||||
}
|
||||
|
||||
fg = extalu(ht216->ht_regs[0xce] >> 4, input_a, input_b);
|
||||
bg = extalu(ht216->ht_regs[0xce] & 0xf, input_a, input_b);
|
||||
// svga->vram[addr]
|
||||
output = (fg & rop_select) | (bg & ~rop_select);
|
||||
svga->vram[addr] = (svga->vram[addr] & ~bit_mask) | (output & bit_mask);
|
||||
// pclog(" A=%02x B=%02x R=%02x FG=%02x BG=%02x ops=%02x val=%02x addr=%05x\n", input_a, input_b, rop_select, fg, bg, ht216->ht_regs[0xce], svga->vram[addr], addr);
|
||||
svga->changedvram[addr >> 12] = changeframecount;
|
||||
}
|
||||
|
||||
static void ht216_write_common(ht216_t *ht216, uint32_t addr, uint8_t val)
|
||||
{
|
||||
/*Input B = CD.5
|
||||
Input A = FE[3:2]
|
||||
00 = Set/Reset output mode
|
||||
output = CPU-side ALU input
|
||||
01 = Solid fg/bg mode (3C4:FA/FB)
|
||||
Bit mask = 3CF.F5 or CPU byte
|
||||
10 = Dithered fg (3CF:EC-EF)
|
||||
11 = RMW (dest data) (set if CD.5 = 1)
|
||||
F/B ROP select = FE[5:4]
|
||||
00 = CPU byte
|
||||
01 = Bit mask (3CF:8)
|
||||
1x = (3C4:F5)
|
||||
*/
|
||||
uint8_t bit_mask = 0, rop_select = 0;
|
||||
svga_t *svga = &ht216->svga;
|
||||
|
||||
addr &= 0xfffff;
|
||||
|
||||
// pclog("%08X %02x %08x\n", addr, svga->gdcreg[6], svga->banked_mask);
|
||||
|
||||
val = svga_rotate[svga->gdcreg[3] & 7][val];
|
||||
|
||||
switch (ht216->ht_regs[0xcd] & HT_REG_CD_BMSKSL)
|
||||
{
|
||||
case 0x00:
|
||||
bit_mask = svga->gdcreg[8];
|
||||
break;
|
||||
case 0x04:
|
||||
bit_mask = val;
|
||||
break;
|
||||
case 0x08: case 0x0c:
|
||||
bit_mask = ht216->ht_regs[0xf5];
|
||||
break;
|
||||
}
|
||||
switch (ht216->ht_regs[0xfe] & HT_REG_FE_FBRSL)
|
||||
{
|
||||
case 0x00:
|
||||
rop_select = val;
|
||||
break;
|
||||
case 0x10:
|
||||
rop_select = svga->gdcreg[8];
|
||||
break;
|
||||
case 0x20: case 0x30:
|
||||
rop_select = ht216->ht_regs[0xf5];
|
||||
break;
|
||||
}
|
||||
|
||||
if (ht216->ht_regs[0xcd] & HT_REG_CD_EXALU) /*Extended ALU*/
|
||||
{
|
||||
if (ht216->ht_regs[0xcd] & HT_REG_CD_FP8PCEXP) /*1->8 bit expansion*/
|
||||
{
|
||||
addr = (addr << 3) & 0xfffff;
|
||||
ht216_dm_extalu_write(ht216, addr, (val & 0x80) ? 0xff : 0, (bit_mask & 0x80) ? 0xff : 0, val, (rop_select & 0x80) ? 0xff : 0);
|
||||
ht216_dm_extalu_write(ht216, addr + 1, (val & 0x40) ? 0xff : 0, (bit_mask & 0x40) ? 0xff : 0, val, (rop_select & 0x40) ? 0xff : 0);
|
||||
ht216_dm_extalu_write(ht216, addr + 2, (val & 0x20) ? 0xff : 0, (bit_mask & 0x20) ? 0xff : 0, val, (rop_select & 0x20) ? 0xff : 0);
|
||||
ht216_dm_extalu_write(ht216, addr + 3, (val & 0x10) ? 0xff : 0, (bit_mask & 0x10) ? 0xff : 0, val, (rop_select & 0x10) ? 0xff : 0);
|
||||
ht216_dm_extalu_write(ht216, addr + 4, (val & 0x08) ? 0xff : 0, (bit_mask & 0x08) ? 0xff : 0, val, (rop_select & 0x08) ? 0xff : 0);
|
||||
ht216_dm_extalu_write(ht216, addr + 5, (val & 0x04) ? 0xff : 0, (bit_mask & 0x04) ? 0xff : 0, val, (rop_select & 0x04) ? 0xff : 0);
|
||||
ht216_dm_extalu_write(ht216, addr + 6, (val & 0x02) ? 0xff : 0, (bit_mask & 0x02) ? 0xff : 0, val, (rop_select & 0x02) ? 0xff : 0);
|
||||
ht216_dm_extalu_write(ht216, addr + 7, (val & 0x01) ? 0xff : 0, (bit_mask & 0x01) ? 0xff : 0, val, (rop_select & 0x01) ? 0xff : 0);
|
||||
}
|
||||
else
|
||||
ht216_dm_extalu_write(ht216, addr, val, bit_mask, val, rop_select);
|
||||
}
|
||||
}
|
||||
|
||||
static void ht216_write(uint32_t addr, uint8_t val, void *p)
|
||||
{
|
||||
ht216_t *ht216 = (ht216_t *)p;
|
||||
svga_t *svga = &ht216->svga;
|
||||
|
||||
/* if (ht216->ht_regs[0xcd])
|
||||
pclog("ht216_write: [CD]=%02x [FE]=%02x %08x %02x ", ht216->ht_regs[0xcd], ht216->ht_regs[0xfe], addr, val);
|
||||
pclog("ht216_write : %05X %02X ", addr, val);*/
|
||||
addr &= svga->banked_mask;
|
||||
addr = (addr & 0x7fff) + ht216->write_bank[(addr >> 15) & 1];
|
||||
// pclog("phys_addr=%05x\n", addr);
|
||||
if (!ht216->ht_regs[0xcd])
|
||||
svga_write_linear(addr, val, &ht216->svga);
|
||||
else
|
||||
ht216_write_common(ht216, addr, val);
|
||||
}
|
||||
static void ht216_writew(uint32_t addr, uint16_t val, void *p)
|
||||
{
|
||||
ht216_t *ht216 = (ht216_t *)p;
|
||||
svga_t *svga = &ht216->svga;
|
||||
|
||||
addr &= svga->banked_mask;
|
||||
addr = (addr & 0x7fff) + ht216->write_bank[(addr >> 15) & 1];
|
||||
if (!ht216->ht_regs[0xcd])
|
||||
svga_writew_linear(addr, val, &ht216->svga);
|
||||
else
|
||||
{
|
||||
ht216_write_common(ht216, addr, val);
|
||||
ht216_write_common(ht216, addr+1, val >> 8);
|
||||
}
|
||||
}
|
||||
static void ht216_writel(uint32_t addr, uint32_t val, void *p)
|
||||
{
|
||||
ht216_t *ht216 = (ht216_t *)p;
|
||||
svga_t *svga = &ht216->svga;
|
||||
|
||||
addr &= svga->banked_mask;
|
||||
addr = (addr & 0x7fff) + ht216->write_bank[(addr >> 15) & 1];
|
||||
if (!ht216->ht_regs[0xcd])
|
||||
svga_writel_linear(addr, val, &ht216->svga);
|
||||
else
|
||||
{
|
||||
ht216_write_common(ht216, addr, val);
|
||||
ht216_write_common(ht216, addr+1, val >> 8);
|
||||
ht216_write_common(ht216, addr+2, val >> 16);
|
||||
ht216_write_common(ht216, addr+3, val >> 24);
|
||||
}
|
||||
}
|
||||
|
||||
static void ht216_write_linear(uint32_t addr, uint8_t val, void *p)
|
||||
{
|
||||
ht216_t *ht216 = (ht216_t *)p;
|
||||
svga_t *svga = &ht216->svga;
|
||||
|
||||
if (!svga->chain4) /*Bits 16 and 17 of linear address seem to be unused in planar modes*/
|
||||
addr = (addr & 0xffff) | ((addr & 0xc0000) >> 2);
|
||||
|
||||
if (!ht216->ht_regs[0xcd])
|
||||
svga_write_linear(addr, val, &ht216->svga);
|
||||
else
|
||||
ht216_write_common(ht216, addr, val);
|
||||
}
|
||||
static void ht216_writew_linear(uint32_t addr, uint16_t val, void *p)
|
||||
{
|
||||
ht216_t *ht216 = (ht216_t *)p;
|
||||
svga_t *svga = &ht216->svga;
|
||||
|
||||
if (!svga->chain4)
|
||||
addr = (addr & 0xffff) | ((addr & 0xc0000) >> 2);
|
||||
|
||||
if (!ht216->ht_regs[0xcd])
|
||||
svga_writew_linear(addr, val, &ht216->svga);
|
||||
else
|
||||
{
|
||||
ht216_write_common(ht216, addr, val);
|
||||
ht216_write_common(ht216, addr+1, val >> 8);
|
||||
}
|
||||
}
|
||||
static void ht216_writel_linear(uint32_t addr, uint32_t val, void *p)
|
||||
{
|
||||
ht216_t *ht216 = (ht216_t *)p;
|
||||
svga_t *svga = &ht216->svga;
|
||||
|
||||
if (!svga->chain4)
|
||||
addr = (addr & 0xffff) | ((addr & 0xc0000) >> 2);
|
||||
|
||||
if (!ht216->ht_regs[0xcd])
|
||||
svga_writel_linear(addr, val, &ht216->svga);
|
||||
else
|
||||
{
|
||||
ht216_write_common(ht216, addr, val);
|
||||
ht216_write_common(ht216, addr+1, val >> 8);
|
||||
ht216_write_common(ht216, addr+2, val >> 16);
|
||||
ht216_write_common(ht216, addr+3, val >> 24);
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t ht216_read_common(ht216_t *ht216, uint32_t addr)
|
||||
{
|
||||
svga_t *svga = &ht216->svga;
|
||||
uint8_t temp, temp2, temp3, temp4;
|
||||
int readplane = svga->readplane;
|
||||
uint32_t latch_addr;
|
||||
|
||||
if (ht216->ht_regs[0xc8] & HT_REG_C8_MOVSB)
|
||||
addr <<= 3;
|
||||
// pclog("%08X\n", addr);
|
||||
|
||||
addr &= 0xfffff;
|
||||
|
||||
cycles -= video_timing_read_b;
|
||||
cycles_lost += video_timing_read_b;
|
||||
|
||||
egareads++;
|
||||
|
||||
if (svga->chain4 || svga->fb_only)
|
||||
{
|
||||
// if (ht216->ht_regs[0xcd])
|
||||
// pclog(" addr=%08x decode_mask=%08x vram_max=%08x\n", addr, svga->decode_mask, svga->vram_max);
|
||||
addr &= svga->decode_mask;
|
||||
if (addr >= svga->vram_max)
|
||||
return 0xff;
|
||||
|
||||
latch_addr = (addr & svga->vram_mask) & ~7;
|
||||
if (ht216->ht_regs[0xcd] & HT_REG_CD_ASTODE)
|
||||
latch_addr += (svga->gdcreg[3] & 7);
|
||||
ht216->bg_latch[0] = svga->vram[latch_addr];
|
||||
ht216->bg_latch[1] = svga->vram[latch_addr + 1];
|
||||
ht216->bg_latch[2] = svga->vram[latch_addr + 2];
|
||||
ht216->bg_latch[3] = svga->vram[latch_addr + 3];
|
||||
ht216->bg_latch[4] = svga->vram[latch_addr + 4];
|
||||
ht216->bg_latch[5] = svga->vram[latch_addr + 5];
|
||||
ht216->bg_latch[6] = svga->vram[latch_addr + 6];
|
||||
ht216->bg_latch[7] = svga->vram[latch_addr + 7];
|
||||
|
||||
/*pclog(" Read %08x %02x %02x %02x %02x %02x %02x %02x %02x\n", addr,
|
||||
ht216->bg_latch[0],ht216->bg_latch[1],ht216->bg_latch[2],ht216->bg_latch[3],
|
||||
ht216->bg_latch[4],ht216->bg_latch[5],ht216->bg_latch[6],ht216->bg_latch[7]);*/
|
||||
|
||||
return svga->vram[addr & svga->vram_mask];
|
||||
}
|
||||
else if (svga->chain2_read)
|
||||
{
|
||||
readplane = (readplane & 2) | (addr & 1);
|
||||
addr &= ~1;
|
||||
addr <<= 2;
|
||||
}
|
||||
else
|
||||
addr<<=2;
|
||||
|
||||
addr &= svga->decode_mask;
|
||||
|
||||
if (addr >= svga->vram_max)
|
||||
return 0xff;
|
||||
|
||||
addr &= svga->vram_mask;
|
||||
|
||||
latch_addr = addr & ~7;
|
||||
if (ht216->ht_regs[0xcd] & HT_REG_CD_ASTODE)
|
||||
{
|
||||
int offset = addr & 7;
|
||||
|
||||
ht216->bg_latch[0] = svga->vram[latch_addr | offset];
|
||||
ht216->bg_latch[1] = svga->vram[latch_addr | ((offset + 1) & 7)];
|
||||
ht216->bg_latch[2] = svga->vram[latch_addr | ((offset + 2) & 7)];
|
||||
ht216->bg_latch[3] = svga->vram[latch_addr | ((offset + 3) & 7)];
|
||||
ht216->bg_latch[4] = svga->vram[latch_addr | ((offset + 4) & 7)];
|
||||
ht216->bg_latch[5] = svga->vram[latch_addr | ((offset + 5) & 7)];
|
||||
ht216->bg_latch[6] = svga->vram[latch_addr | ((offset + 6) & 7)];
|
||||
ht216->bg_latch[7] = svga->vram[latch_addr | ((offset + 7) & 7)];
|
||||
}
|
||||
else
|
||||
{
|
||||
ht216->bg_latch[0] = svga->vram[latch_addr];
|
||||
ht216->bg_latch[1] = svga->vram[latch_addr | 1];
|
||||
ht216->bg_latch[2] = svga->vram[latch_addr | 2];
|
||||
ht216->bg_latch[3] = svga->vram[latch_addr | 3];
|
||||
ht216->bg_latch[4] = svga->vram[latch_addr | 4];
|
||||
ht216->bg_latch[5] = svga->vram[latch_addr | 5];
|
||||
ht216->bg_latch[6] = svga->vram[latch_addr | 6];
|
||||
ht216->bg_latch[7] = svga->vram[latch_addr | 7];
|
||||
}
|
||||
/*pclog(" Read %02x %02x %02x %02x %02x %02x %02x %02x\n",
|
||||
ht216->bg_latch[0],ht216->bg_latch[1],ht216->bg_latch[2],ht216->bg_latch[3],
|
||||
ht216->bg_latch[4],ht216->bg_latch[5],ht216->bg_latch[6],ht216->bg_latch[7]);*/
|
||||
if (addr & 4)
|
||||
{
|
||||
svga->la = ht216->bg_latch[4];
|
||||
svga->lb = ht216->bg_latch[5];
|
||||
svga->lc = ht216->bg_latch[6];
|
||||
svga->ld = ht216->bg_latch[7];
|
||||
}
|
||||
else
|
||||
{
|
||||
svga->la = ht216->bg_latch[0];
|
||||
svga->lb = ht216->bg_latch[1];
|
||||
svga->lc = ht216->bg_latch[2];
|
||||
svga->ld = ht216->bg_latch[3];
|
||||
}
|
||||
if (svga->readmode)
|
||||
{
|
||||
temp = svga->la;
|
||||
temp ^= (svga->colourcompare & 1) ? 0xff : 0;
|
||||
temp &= (svga->colournocare & 1) ? 0xff : 0;
|
||||
temp2 = svga->lb;
|
||||
temp2 ^= (svga->colourcompare & 2) ? 0xff : 0;
|
||||
temp2 &= (svga->colournocare & 2) ? 0xff : 0;
|
||||
temp3 = svga->lc;
|
||||
temp3 ^= (svga->colourcompare & 4) ? 0xff : 0;
|
||||
temp3 &= (svga->colournocare & 4) ? 0xff : 0;
|
||||
temp4 = svga->ld;
|
||||
temp4 ^= (svga->colourcompare & 8) ? 0xff : 0;
|
||||
temp4 &= (svga->colournocare & 8) ? 0xff : 0;
|
||||
return ~(temp | temp2 | temp3 | temp4);
|
||||
}
|
||||
//printf("Read %02X %04X %04X\n",vram[addr|svga->readplane],addr,svga->readplane);
|
||||
return svga->vram[addr | readplane];
|
||||
|
||||
// return svga_read_linear(addr, &ht216->svga);
|
||||
}
|
||||
static uint8_t ht216_read(uint32_t addr, void *p)
|
||||
{
|
||||
ht216_t *ht216 = (ht216_t *)p;
|
||||
svga_t *svga = &ht216->svga;
|
||||
|
||||
// if (ht216->ht_regs[0xcd])
|
||||
// pclog("ht216_read: [CD]=%02x [FC]=%02x %08x\n", ht216->ht_regs[0xcd], ht216->ht_regs[0xfc], addr);
|
||||
// pclog("ht216_read : %05X ", addr);
|
||||
addr &= svga->banked_mask;
|
||||
addr = (addr & 0x7fff) + ht216->read_bank[(addr >> 15) & 1];
|
||||
|
||||
return ht216_read_common(ht216, addr);
|
||||
}
|
||||
|
||||
/*static uint16_t ht216_readw(uint32_t addr, void *p)
|
||||
{
|
||||
ht216_t *ht216 = (ht216_t *)p;
|
||||
svga_t *svga = &ht216->svga;
|
||||
|
||||
addr &= svga->banked_mask;
|
||||
addr = (addr & 0x7fff) + ht216->write_bank[(addr >> 15) & 1];
|
||||
return svga_readw_linear(addr, &ht216->svga);
|
||||
}*/
|
||||
|
||||
static uint8_t ht216_read_linear(uint32_t addr, void *p)
|
||||
{
|
||||
ht216_t *ht216 = (ht216_t *)p;
|
||||
svga_t *svga = &ht216->svga;
|
||||
|
||||
if (svga->chain4)
|
||||
return ht216_read_common(ht216, addr);
|
||||
else
|
||||
return ht216_read_common(ht216, (addr & 0xffff) | ((addr & 0xc0000) >> 2));
|
||||
}
|
||||
|
||||
void *ht216_init()
|
||||
{
|
||||
ht216_t *ht216 = malloc(sizeof(ht216_t));
|
||||
svga_t *svga = &ht216->svga;
|
||||
memset(ht216, 0, sizeof(ht216_t));
|
||||
|
||||
io_sethandler(0x03c0, 0x0020, ht216_in, NULL, NULL, ht216_out, NULL, NULL, ht216);
|
||||
io_sethandler(0x46e8, 0x0001, ht216_in, NULL, NULL, ht216_out, NULL, NULL, ht216);
|
||||
|
||||
svga_init(&ht216->svga, ht216, 1 << 20, /*1MB*/
|
||||
ht216_recalctimings,
|
||||
ht216_in, ht216_out,
|
||||
ht216_hwcursor_draw,
|
||||
NULL);
|
||||
svga->hwcursor.ysize = 32;
|
||||
ht216->vram_mask = 0xfffff;
|
||||
svga->decode_mask = 0xfffff;
|
||||
|
||||
mem_mapping_set_handler(&ht216->svga.mapping, ht216_read, NULL/*ht216_readw*/, NULL, ht216_write, ht216_writew, ht216_writel);
|
||||
mem_mapping_set_p(&ht216->svga.mapping, ht216);
|
||||
mem_mapping_add(&ht216->linear_mapping, 0, 0, ht216_read_linear, NULL, NULL, ht216_write_linear, ht216_writew_linear, ht216_writel_linear, NULL, 0, &ht216->svga);
|
||||
|
||||
svga->bpp = 8;
|
||||
svga->miscout = 1;
|
||||
|
||||
ht216->ht_regs[0xb4] = 0x08; /*32-bit DRAM bus*/
|
||||
|
||||
return ht216;
|
||||
}
|
||||
|
||||
static void *ht216_pb410a_init()
|
||||
{
|
||||
ht216_t *ht216 = ht216_init();
|
||||
|
||||
return ht216;
|
||||
}
|
||||
|
||||
void ht216_close(void *p)
|
||||
{
|
||||
ht216_t *ht216 = (ht216_t *)p;
|
||||
|
||||
svga_close(&ht216->svga);
|
||||
|
||||
free(ht216);
|
||||
}
|
||||
|
||||
void ht216_speed_changed(void *p)
|
||||
{
|
||||
ht216_t *ht216 = (ht216_t *)p;
|
||||
|
||||
svga_recalctimings(&ht216->svga);
|
||||
}
|
||||
|
||||
void ht216_force_redraw(void *p)
|
||||
{
|
||||
ht216_t *ht216 = (ht216_t *)p;
|
||||
|
||||
ht216->svga.fullchange = changeframecount;
|
||||
}
|
||||
|
||||
void ht216_add_status_info(char *s, int max_len, void *p)
|
||||
{
|
||||
ht216_t *ht216 = (ht216_t *)p;
|
||||
|
||||
svga_add_status_info(s, max_len, &ht216->svga);
|
||||
}
|
||||
|
||||
device_t ht216_32_pb410a_device =
|
||||
{
|
||||
"Headland HT216-32 (Packard Bell PB410A)",
|
||||
0,
|
||||
ht216_pb410a_init,
|
||||
ht216_close,
|
||||
NULL,
|
||||
ht216_speed_changed,
|
||||
ht216_force_redraw,
|
||||
ht216_add_status_info
|
||||
};
|
||||
1
src/vid_ht216.h
Normal file
1
src/vid_ht216.h
Normal file
|
|
@ -0,0 +1 @@
|
|||
extern device_t ht216_32_pb410a_device;
|
||||
22
src/video.c
22
src/video.c
|
|
@ -23,6 +23,7 @@
|
|||
#include "vid_et4000w32.h"
|
||||
#include "vid_genius.h"
|
||||
#include "vid_hercules.h"
|
||||
#include "vid_ht216.h"
|
||||
#include "vid_incolor.h"
|
||||
#include "vid_colorplus.h"
|
||||
#include "vid_mda.h"
|
||||
|
|
@ -128,6 +129,7 @@ static video_timings_t timing_ps1_svga = {VIDEO_ISA, 6, 8,16, 6, 8,16};
|
|||
static video_timings_t timing_t3100e = {VIDEO_ISA, 8,16,32, 8,16,32};
|
||||
static video_timings_t timing_t1000 = {VIDEO_ISA, 8,16,32, 8,16,32};
|
||||
static video_timings_t timing_pc425x = {VIDEO_BUS, 5, 5, 9, 20,20,30};
|
||||
static video_timings_t timing_pb410a = {VIDEO_BUS, 5, 5, 9, 20,20,30};
|
||||
static video_timings_t timing_pb570 = {VIDEO_BUS, 4, 4, 8, 10,10,20};
|
||||
static video_timings_t timing_pb520r = {VIDEO_BUS, 4, 4, 8, 10,10,20};
|
||||
|
||||
|
|
@ -220,6 +222,9 @@ device_t *video_card_getdevice(int card)
|
|||
case ROM_ELX_PC425X:
|
||||
return &tgui9400cxi_elx_device;
|
||||
|
||||
case ROM_PB410A:
|
||||
return &ht216_32_pb410a_device;
|
||||
|
||||
case ROM_PB570:
|
||||
return &gd5430_pb570_device;
|
||||
|
||||
|
|
@ -332,6 +337,7 @@ int video_is_mda()
|
|||
case ROM_T3100E:
|
||||
case ROM_T1000:
|
||||
case ROM_ELX_PC425X:
|
||||
case ROM_PB410A:
|
||||
case ROM_PB570:
|
||||
case ROM_PB520R:
|
||||
return 0;
|
||||
|
|
@ -371,6 +377,7 @@ int video_is_cga()
|
|||
case ROM_IBMPS2_M80:
|
||||
case ROM_IBMPS1_2121:
|
||||
case ROM_ELX_PC425X:
|
||||
case ROM_PB410A:
|
||||
case ROM_PB570:
|
||||
case ROM_PB520R:
|
||||
return 0;
|
||||
|
|
@ -407,6 +414,7 @@ int video_is_ega_vga()
|
|||
case ROM_IBMPS2_M80:
|
||||
case ROM_IBMPS1_2121:
|
||||
case ROM_ELX_PC425X:
|
||||
case ROM_PB410A:
|
||||
case ROM_PB570:
|
||||
case ROM_PB520R:
|
||||
return 1;
|
||||
|
|
@ -561,6 +569,11 @@ void video_updatetiming()
|
|||
timing = &timing_pc425x;
|
||||
break;
|
||||
|
||||
case ROM_PB410A:
|
||||
if (gfxcard == GFX_BUILTIN)
|
||||
timing = &timing_pb410a;
|
||||
break;
|
||||
|
||||
case ROM_PB570:
|
||||
timing = &timing_pb570;
|
||||
break;
|
||||
|
|
@ -733,6 +746,15 @@ void video_init()
|
|||
device_add(&tgui9400cxi_elx_device);
|
||||
return;
|
||||
|
||||
case ROM_PB410A:
|
||||
device_add(&ht216_32_pb410a_device);
|
||||
if (gfxcard != GFX_BUILTIN)
|
||||
{
|
||||
svga_set_override(svga_get_pri(), 1);
|
||||
break;
|
||||
}
|
||||
return;
|
||||
|
||||
case ROM_PB570:
|
||||
device_add(&gd5430_pb570_device);
|
||||
if (gfxcard != GFX_BUILTIN)
|
||||
|
|
|
|||
Loading…
Reference in a new issue