Merge from trunk
This commit is contained in:
commit
f23dc883fc
22 changed files with 5195 additions and 36 deletions
31
Readme-BSD.txt
Normal file
31
Readme-BSD.txt
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
PCem v14 BSD supplement
|
||||
|
||||
|
||||
You will need the following libraries :
|
||||
|
||||
SDL2
|
||||
wxWidgets 3.x
|
||||
OpenAL
|
||||
|
||||
and their dependencies.
|
||||
|
||||
Open a terminal window, navigate to the PCem directory then enter
|
||||
|
||||
./configure --enable-release-build
|
||||
gmake
|
||||
|
||||
then ./pcem to run.
|
||||
|
||||
The BSD version stores BIOS ROM images, configuration files, and other data in ~/.pcem
|
||||
|
||||
configure options are :
|
||||
--enable-release-build : Generate release build. Recommended for regular use.
|
||||
--enable-debug : Compile with debugging enabled.
|
||||
--enable-networking : Build with networking support.
|
||||
--enable-alsa : Build with support for MIDI output through ALSA. Requires libasound.
|
||||
|
||||
|
||||
The menu is a pop-up menu in the BSD port. Right-click on the main window when mouse is not
|
||||
captured.
|
||||
|
||||
CD-ROM support currently only accesses /dev/cdrom. It has not been heavily tested.
|
||||
12
configure.ac
12
configure.ac
|
|
@ -160,6 +160,18 @@ case "$host" in
|
|||
exit -1])
|
||||
build_linux="yes"
|
||||
;;
|
||||
*-*-freebsd*)
|
||||
CFLAGS="$CFLAGS -I/usr/local/include"
|
||||
CXXFLAGS="$CXXFLAGS -I/usr/local/include"
|
||||
LDFLAGS="$LDFLAGS -L/usr/local/lib"
|
||||
AC_CHECK_LIB([GL], [glGetError], [], \
|
||||
[echo "You need to install the OpenGL library."
|
||||
exit -1])
|
||||
AC_CHECK_LIB([openal], [alGetError], [], \
|
||||
[echo "You need to install the OpenAL library."
|
||||
exit -1])
|
||||
build_other="yes"
|
||||
;;
|
||||
*)
|
||||
AC_CHECK_LIB([GL], [glGetError], [], \
|
||||
[echo "You need to install the OpenGL library."
|
||||
|
|
|
|||
0
install-sh
Normal file → Executable file
0
install-sh
Normal file → Executable file
|
|
@ -37,8 +37,8 @@ sound_speaker.c sound_ssi2001.c sound_wss.c sound_ym7128.c soundopenal.c sst39sf
|
|||
t1000.c t3100e.c \
|
||||
timer.c um8669f.c um8881f.c vid_ati_eeprom.c vid_ati_mach64.c vid_ati18800.c vid_ati28800.c \
|
||||
vid_ati68860_ramdac.c vid_cga.c vid_cl5429.c vid_colorplus.c vid_compaq_cga.c vid_ega.c vid_et4000.c vid_et4000w32.c vid_genius.c vid_hercules.c \
|
||||
vid_ht216.c vid_icd2061.c vid_ics2595.c vid_incolor.c vid_mda.c vid_olivetti_m24.c vid_oti037.c vid_oti067.c vid_paradise.c vid_pc200.c \
|
||||
vid_pc1512.c vid_pc1640.c vid_pcjr.c vid_ps1_svga.c vid_s3.c vid_s3_virge.c vid_sdac_ramdac.c vid_sigma.c \
|
||||
vid_ht216.c vid_icd2061.c vid_ics2595.c vid_im1024.c vid_incolor.c vid_mda.c vid_olivetti_m24.c vid_oti037.c vid_oti067.c vid_paradise.c vid_pc200.c \
|
||||
vid_pc1512.c vid_pc1640.c vid_pcjr.c vid_pgc.c vid_ps1_svga.c vid_s3.c vid_s3_virge.c vid_sdac_ramdac.c vid_sigma.c \
|
||||
vid_stg_ramdac.c vid_svga.c vid_svga_render.c vid_t1000.c vid_t3100e.c vid_tandy.c vid_tandysl.c vid_tgui9440.c \
|
||||
vid_tkd8001_ramdac.c vid_tvga.c vid_unk_ramdac.c vid_vga.c vid_voodoo.c video.c wd76c10.c vid_wy700.c vt82c586b.c \
|
||||
w83877tf.c x86seg.c x87.c xi8088.c xtide.c sound_dbopl.cc sound_resid.cc \
|
||||
|
|
|
|||
|
|
@ -16,8 +16,8 @@ sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.o sound_sb.
|
|||
sound_speaker.o sound_ssi2001.o sound_wss.o sound_ym7128.o soundopenal.o t1000.o t3100e.o tandy_eeprom.o tandy_rom.o \
|
||||
timer.o um8669f.o um8881f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o vid_ati28800.o \
|
||||
vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_compaq_cga.o vid_ega.o vid_et4000.o vid_et4000w32.o vid_genius.o vid_hercules.o \
|
||||
vid_ht216.o vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o vid_olivetti_m24.o vid_oti037.c vid_oti067.o vid_paradise.o vid_pc200.o \
|
||||
vid_pc1512.o vid_pc1640.o vid_pcjr.o vid_ps1_svga.o vid_s3.o vid_s3_virge.o vid_sdac_ramdac.o vid_sigma.o \
|
||||
vid_ht216.o vid_icd2061.o vid_ics2595.o vid_im1024.o vid_incolor.o vid_mda.o vid_olivetti_m24.o vid_oti037.c vid_oti067.o vid_paradise.o vid_pc200.o \
|
||||
vid_pc1512.o vid_pc1640.o vid_pcjr.o vid_pgc.o vid_ps1_svga.o vid_s3.o vid_s3_virge.o vid_sdac_ramdac.o vid_sigma.o \
|
||||
vid_stg_ramdac.o vid_svga.o vid_svga_render.o vid_t1000.o vid_t3100e.o vid_tandy.o vid_tandysl.o vid_tgui9440.o \
|
||||
vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o vid_vga.o vid_voodoo.o vid_wy700.o video.o wd76c10.o \
|
||||
x86seg.o x87.o xi8088.c xtide.o zenith.o sound_dbopl.o sound_resid.o \
|
||||
|
|
|
|||
|
|
@ -16,8 +16,8 @@ sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.o sound_sb.
|
|||
sound_speaker.o sound_ssi2001.o sound_wss.o sound_ym7128.o soundopenal.o t1000.o t3100e.o tandy_eeprom.o tandy_rom.o \
|
||||
timer.o um8669f.o um8881f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o vid_ati28800.o \
|
||||
vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_compaq_cga.o vid_ega.o vid_et4000.o vid_et4000w32.o vid_genius.o vid_hercules.o \
|
||||
vid_ht216.o vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o vid_olivetti_m24.o vid_oti037.c vid_oti067.o vid_paradise.o vid_pc200.o \
|
||||
vid_pc1512.o vid_pc1640.o vid_pcjr.o vid_ps1_svga.o vid_s3.o vid_s3_virge.o vid_sdac_ramdac.o vid_sigma.o \
|
||||
vid_ht216.o vid_icd2061.o vid_ics2595.o vid_im1024.o vid_incolor.o vid_mda.o vid_olivetti_m24.o vid_oti037.c vid_oti067.o vid_paradise.o vid_pc200.o \
|
||||
vid_pc1512.o vid_pc1640.o vid_pcjr.o vid_pgc.o vid_ps1_svga.o vid_s3.o vid_s3_virge.o vid_sdac_ramdac.o vid_sigma.o \
|
||||
vid_stg_ramdac.o vid_svga.o vid_svga_render.o vid_t1000.o vid_t3100e.o vid_tandy.o vid_tandysl.o vid_tgui9440.o \
|
||||
vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o vid_vga.o vid_voodoo.o vid_wy700.o video.o wd76c10.o \
|
||||
x86seg.o x87.o xi8088.c xtide.o zenith.o sound_dbopl.o sound_resid.o \
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ OBJ = 386.o 386_common.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acer38
|
|||
vid_cl5429.o vid_colorplus.o vid_compaq_cga.o vid_ega.o vid_et4000.o vid_et4000w32.o \
|
||||
vid_et4000w32i.o vid_genius.o vid_hercules.o vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o \
|
||||
vid_olivetti_m24.o vid_oti037.c vid_oti067.o vid_paradise.o vid_pc1512.o vid_pc1640.o vid_pc200.o \
|
||||
vid_pcjr.o vid_ps1_svga.o vid_s3.o vid_s3_virge.o vid_sdac_ramdac.o vid_sigma.o vid_stg_ramdac.o vid_svga.o \
|
||||
vid_pcjr.o vid_pgc.o vid_ps1_svga.o vid_s3.o vid_s3_virge.o vid_sdac_ramdac.o vid_sigma.o vid_stg_ramdac.o vid_svga.o \
|
||||
vid_svga_render.o vid_t1000.o vid_t3100e.o vid_tandy.o vid_tandysl.o vid_tgui9440.o \
|
||||
vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o vid_vga.o vid_voodoo.o vid_wy700.o video.o \
|
||||
vt82c586b.o w83877tf.o wd76c10.o x86seg.o x87.o xi8088.c xtide.o win-midi.o wx-main.o \
|
||||
|
|
|
|||
|
|
@ -17,9 +17,9 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acc2168.o acc3221.o
|
|||
sound_sb.o sound_sb_dsp.o sound_sn76489.o sound_speaker.o sound_ssi2001.o sound_wss.o \
|
||||
sound_ym7128.o soundopenal.o t1000.o t3100e.o tandy_eeprom.o tandy_rom.o timer.o um8881f.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \
|
||||
vid_ati28800.o vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_compaq_cga.o vid_ega.o vid_et4000.o \
|
||||
vid_et4000w32.o vid_et4000w32i.o vid_genius.o vid_hercules.o vid_ht216.o vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o \
|
||||
vid_et4000w32.o vid_et4000w32i.o vid_genius.o vid_hercules.o vid_ht216.o vid_icd2061.o vid_ics2595.o vid_im1024.o vid_incolor.o vid_mda.o \
|
||||
vid_olivetti_m24.o vid_oti037.c vid_oti067.o vid_paradise.o vid_pc1512.o vid_pc1640.o vid_pc200.o \
|
||||
vid_pcjr.o vid_ps1_svga.o vid_s3.o vid_s3_virge.o vid_sdac_ramdac.o vid_sigma.o vid_stg_ramdac.o vid_svga.o \
|
||||
vid_pcjr.o vid_pgc.o vid_ps1_svga.o vid_s3.o vid_s3_virge.o vid_sdac_ramdac.o vid_sigma.o vid_stg_ramdac.o vid_svga.o \
|
||||
vid_svga_render.o vid_t1000.o vid_t3100e.o vid_tandy.o vid_tandysl.o vid_tgui9440.o vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o \
|
||||
vid_vga.o vid_voodoo.o vid_wy700.o video.o wd76c10.o x86seg.o x87.o xi8088.c xtide.o zenith.o win-midi.o \
|
||||
wx-main.o wx-config_sel.o wx-dialogbox.o wx-utils.o wx-app.o wx-sdl2-joystick.o wx-sdl2-mouse.o wx-sdl2-keyboard.o wx-sdl2-video.o \
|
||||
|
|
|
|||
|
|
@ -15,8 +15,8 @@ sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.o sound_sb.
|
|||
sound_speaker.o sound_ssi2001.o sound_wss.o sound_ym7128.o soundopenal.o t1000.o t3100e.o tandy_eeprom.o tandy_rom.o \
|
||||
timer.o um8669f.o um8881f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o vid_ati28800.o \
|
||||
vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_compaq_cga.o vid_ega.o vid_et4000.o vid_et4000w32.o vid_genius.o vid_hercules.o \
|
||||
vid_ht216.o vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o vid_olivetti_m24.o vid_oti037.c vid_oti067.o vid_paradise.o vid_pc200.o \
|
||||
vid_pc1512.o vid_pc1640.o vid_pcjr.o vid_ps1_svga.o vid_s3.o vid_s3_virge.o vid_sdac_ramdac.o vid_sigma.o \
|
||||
vid_ht216.o vid_icd2061.o vid_ics2595.o vid_im1024.o vid_incolor.o vid_mda.o vid_olivetti_m24.o vid_oti037.c vid_oti067.o vid_paradise.o vid_pc200.o \
|
||||
vid_pc1512.o vid_pc1640.o vid_pcjr.o vid_pgc.o vid_ps1_svga.o vid_s3.o vid_s3_virge.o vid_sdac_ramdac.o vid_sigma.o \
|
||||
vid_stg_ramdac.o vid_svga.o vid_svga_render.o vid_t1000.o vid_t3100e.o vid_tandy.o vid_tandysl.o vid_tgui9440.o \
|
||||
vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o vid_vga.o vid_voodoo.o vid_wy700.o video.o wd76c10.o \
|
||||
x86seg.o x87.o xi8088.c xtide.o zenith.o sound_dbopl.o sound_resid.o \
|
||||
|
|
|
|||
|
|
@ -250,6 +250,7 @@ enum
|
|||
ROM_ZD_SUPERS, /* [8088] Zenith Data Systems SupersPort */
|
||||
ROM_PB410A,
|
||||
ROM_PPC512,
|
||||
ROM_BULL_MICRAL_45,
|
||||
ROM_FIC_VA503P,
|
||||
|
||||
ROM_MAX
|
||||
|
|
@ -297,6 +298,8 @@ enum
|
|||
GFX_OTI037, /*Oak OTI-037*/
|
||||
GFX_COMPAQ_CGA, /*Compaq CGA*/
|
||||
GFX_SIGMA400, /*Sigma Designs Color 400 */
|
||||
GFX_PGC, /*Professional Graphics Controller */
|
||||
GFX_IM1024, /*Vermont Microsystems IM1024 */
|
||||
GFX_MAX
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@ int loadbios()
|
|||
loadfont("mda.rom", FONT_MDA);
|
||||
loadfont("wy700.rom", FONT_WY700);
|
||||
loadfont("8x12.bin", FONT_MDSI);
|
||||
loadfont("im1024font.bin", FONT_IM1024);
|
||||
|
||||
biosmask = 0xffff;
|
||||
|
||||
|
|
@ -986,6 +987,19 @@ int loadbios()
|
|||
fclose(f);
|
||||
biosmask = 0x1ffff;
|
||||
return 1;
|
||||
|
||||
case ROM_BULL_MICRAL_45:
|
||||
f = romfopen("bull_micral_45/even.fil", "rb");
|
||||
ff = romfopen("bull_micral_45/odd.fil", "rb");
|
||||
if (!f || !ff) break;
|
||||
for (c = 0x0000; c < 0x10000; c += 2)
|
||||
{
|
||||
rom[c] = getc(f);
|
||||
rom[c+1] = getc(ff);
|
||||
}
|
||||
fclose(ff);
|
||||
fclose(f);
|
||||
return 1;
|
||||
|
||||
case ROM_FIC_VA503P:
|
||||
f = romfopen("fic_va503p/je4333.bin","rb");
|
||||
|
|
|
|||
|
|
@ -160,6 +160,7 @@ MODEL models[] =
|
|||
|
||||
{"[286] AMI 286 clone", ROM_AMI286, "ami286", { {"", cpus_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE|MODEL_AT|MODEL_HAS_IDE, 512,16384, 128, at_neat_init, NULL},
|
||||
{"[286] Award 286 clone", ROM_AWARD286, "award286", { {"", cpus_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE|MODEL_AT|MODEL_HAS_IDE, 512,16384, 128, at_scat_init, NULL},
|
||||
{"[286] Bull Micral 45", ROM_BULL_MICRAL_45, "bull_micral_45", { {"", cpus_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE|MODEL_AT|MODEL_HAS_IDE, 1024, 6144, 128, ibm_at_init, NULL},
|
||||
{"[286] Commodore PC 30 III", ROM_CMDPC30, "cmdpc30", { {"", cpus_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE|MODEL_AT|MODEL_HAS_IDE, 640,16384, 128, at_cbm_init, NULL},
|
||||
{"[286] Compaq Portable II", ROM_COMPAQ_PII, "compaq_pii", { {"", cpus_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE|MODEL_AT|MODEL_HAS_IDE, 256,15872, 128, ibm_at_init, NULL},
|
||||
{"[286] DELL System 200", ROM_DELL200, "dells200", { {"", cpus_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE|MODEL_AT, 640,16384, 128, dells200_init, NULL},
|
||||
|
|
|
|||
|
|
@ -322,6 +322,7 @@ void loadnvr()
|
|||
case ROM_IBMPS2_M70_TYPE4: f = nvrfopen("ibmps2_m70_type4.nvr","rb"); break;
|
||||
case ROM_TULIP_TC7: f = nvrfopen("tulip_tc7.nvr", "rb"); break;
|
||||
case ROM_PB410A: f = nvrfopen("pb410a.nvr", "rb"); nvrmask = 127; break;
|
||||
case ROM_BULL_MICRAL_45: f = nvrfopen("bull_micral_45.nvr", "rb"); break;
|
||||
case ROM_FIC_VA503P: f = nvrfopen("fic_va503p.nvr", "rb"); nvrmask = 127; break;
|
||||
|
||||
default: return;
|
||||
|
|
@ -421,6 +422,7 @@ void savenvr()
|
|||
case ROM_IBMPS2_M70_TYPE4: f = nvrfopen("ibmps2_m70_type4.nvr","wb"); break;
|
||||
case ROM_TULIP_TC7: f = nvrfopen("tulip_tc7.nvr", "wb"); break;
|
||||
case ROM_PB410A: f = nvrfopen("pb410a.nvr", "wb"); break;
|
||||
case ROM_BULL_MICRAL_45: f = nvrfopen("bull_micral_45.nvr", "wb"); break;
|
||||
case ROM_FIC_VA503P: f = nvrfopen("fic_va503p.nvr", "wb"); break;
|
||||
|
||||
default: return;
|
||||
|
|
|
|||
1554
src/pgc_palettes.h
Normal file
1554
src/pgc_palettes.h
Normal file
File diff suppressed because it is too large
Load diff
906
src/vid_im1024.c
Normal file
906
src/vid_im1024.c
Normal file
|
|
@ -0,0 +1,906 @@
|
|||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <ctype.h>
|
||||
#include "ibm.h"
|
||||
#include "device.h"
|
||||
#include "io.h"
|
||||
#include "mem.h"
|
||||
#include "thread.h"
|
||||
#include "video.h"
|
||||
#include "vid_pgc.h"
|
||||
#include "vid_im1024.h"
|
||||
|
||||
/* This implements just enough of the Vermont Microsystems IM-1024 to
|
||||
* support the Windows 1.03 driver. Functions are partially implemented
|
||||
* or hardwired to the behaviour expected by the Windows driver.
|
||||
*
|
||||
* One major difference seems to be that in hex mode, coordinates are
|
||||
* passed as 2-byte integer words rather than 4-byte fixed-point fractions.
|
||||
* I don't know what triggers this, so for now it's always on.
|
||||
*/
|
||||
|
||||
extern uint8_t fontdat12x18[256][36];
|
||||
|
||||
typedef struct im1024_t
|
||||
{
|
||||
pgc_core_t pgc;
|
||||
unsigned char fontx[256];
|
||||
unsigned char fonty[256];
|
||||
unsigned char font[256][128];
|
||||
|
||||
unsigned char *fifo;
|
||||
unsigned fifo_len, fifo_wrptr, fifo_rdptr;
|
||||
} im1024_t;
|
||||
|
||||
/* As well as the usual PGC ring buffer at 0xC6000, the IM1024 appears to
|
||||
* have an alternate method of passing commands. This is enabled by setting
|
||||
* 0xC6330 to 1, and then:
|
||||
*
|
||||
* CX = count to write
|
||||
* SI -> bytes to write
|
||||
*
|
||||
* Set pending bytes to 0
|
||||
* Read [C6331]. This gives number of bytes that can be written:
|
||||
* 0xFF => 0, 0xFE => 1, 0xFD => 2 etc.
|
||||
* Write that number of bytes to C6000.
|
||||
* If there are more to come, go back to reading [C6331].
|
||||
* As far as I can see, at least one byte is always written; there's no
|
||||
* provision to pause if the queue is full.
|
||||
*
|
||||
* I am implementing this by holding a FIFO of unlimited depth in the
|
||||
* IM1024 to receive the data.
|
||||
*
|
||||
*/
|
||||
|
||||
static void fifo_write(im1024_t *im1024, unsigned char val)
|
||||
{
|
||||
/* PGCLOG(("fifo_write: %02x [rd=%04x wr=%04x]\n", val,
|
||||
im1024->fifo_rdptr, im1024->fifo_wrptr)); */
|
||||
if (((im1024->fifo_wrptr + 1) % im1024->fifo_len) == im1024->fifo_rdptr)
|
||||
{
|
||||
/* FIFO is full. Double its size. */
|
||||
unsigned char *buf;
|
||||
|
||||
PGCLOG(("fifo_resize: %d to %d\n",
|
||||
im1024->fifo_len, 2 * im1024->fifo_len));
|
||||
|
||||
buf = realloc(im1024->fifo, 2 * im1024->fifo_len);
|
||||
if (!buf) return;
|
||||
/* Move the [0..wrptr] range to the newly-allocated area [len..len+wrptr] */
|
||||
memmove(buf + im1024->fifo_len, buf, im1024->fifo_wrptr);
|
||||
im1024->fifo = buf;
|
||||
im1024->fifo_wrptr += im1024->fifo_len;
|
||||
im1024->fifo_len *= 2;
|
||||
}
|
||||
/* Append to the queue */
|
||||
im1024->fifo[im1024->fifo_wrptr] = val;
|
||||
++im1024->fifo_wrptr;
|
||||
|
||||
/* Wrap if end of buffer reached */
|
||||
if (im1024->fifo_wrptr >= im1024->fifo_len)
|
||||
{
|
||||
im1024->fifo_wrptr = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int fifo_read(im1024_t *im1024)
|
||||
{
|
||||
uint8_t result;
|
||||
|
||||
if (im1024->fifo_wrptr == im1024->fifo_rdptr)
|
||||
{
|
||||
return -1; /* FIFO empty */
|
||||
}
|
||||
result = im1024->fifo[im1024->fifo_rdptr];
|
||||
++im1024->fifo_rdptr;
|
||||
if (im1024->fifo_rdptr >= im1024->fifo_len)
|
||||
{
|
||||
im1024->fifo_rdptr = 0;
|
||||
}
|
||||
/*
|
||||
PGCLOG(("fifo_read: %02x\n", result));
|
||||
*/
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
/* Where a normal PGC would just read from the ring buffer at 0xC6300, the
|
||||
* IM-1024 can read either from this or from its internal FIFO. The internal
|
||||
* FIFO has priority. */
|
||||
int im1024_input_byte(pgc_core_t *pgc, uint8_t *result)
|
||||
{
|
||||
im1024_t *im1024 = (im1024_t *)pgc;
|
||||
|
||||
/* If input buffer empty, wait for it to fill */
|
||||
while ((im1024->fifo_wrptr == im1024->fifo_rdptr) &&
|
||||
(pgc->mapram[0x300] == pgc->mapram[0x301]))
|
||||
{
|
||||
pgc->waiting_input_fifo = 1;
|
||||
pgc_sleep(pgc);
|
||||
}
|
||||
if (pgc->mapram[0x3FF]) /* Reset triggered */
|
||||
{
|
||||
pgc_reset(pgc);
|
||||
return 0;
|
||||
}
|
||||
if (im1024->fifo_wrptr == im1024->fifo_rdptr)
|
||||
{
|
||||
*result = pgc->mapram[pgc->mapram[0x301]];
|
||||
++pgc->mapram[0x301];
|
||||
}
|
||||
else
|
||||
{
|
||||
*result = fifo_read(im1024);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Macros to disable clipping and save clip state */
|
||||
#define PUSHCLIP { \
|
||||
uint16_t vp_x1, vp_x2, vp_y1, vp_y2; \
|
||||
vp_x1 = pgc->vp_x1; \
|
||||
vp_y1 = pgc->vp_y1; \
|
||||
vp_x2 = pgc->vp_x2; \
|
||||
vp_y2 = pgc->vp_y2; \
|
||||
pgc->vp_x1 = 0; \
|
||||
pgc->vp_y1 = 0; \
|
||||
pgc->vp_x2 = pgc->maxw - 1; \
|
||||
pgc->vp_y2 = pgc->maxh - 1; \
|
||||
|
||||
/* And to restore clip state */
|
||||
#define POPCLIP \
|
||||
pgc->vp_x1 = vp_x1; \
|
||||
pgc->vp_y1 = vp_y1; \
|
||||
pgc->vp_x2 = vp_x2; \
|
||||
pgc->vp_y2 = vp_y2; \
|
||||
}
|
||||
|
||||
|
||||
/* Override memory read to return FIFO space */
|
||||
uint8_t im1024_read(uint32_t addr, void *p)
|
||||
{
|
||||
im1024_t *im1024 = (im1024_t *)p;
|
||||
|
||||
if (addr == 0xC6331 && im1024->pgc.mapram[0x330] == 1)
|
||||
{
|
||||
return 0x80; /* Hardcode that there are 128 bytes
|
||||
* free */
|
||||
}
|
||||
return pgc_read(addr, &im1024->pgc);
|
||||
}
|
||||
|
||||
/* Override memory write to handle writes to the FIFO */
|
||||
void im1024_write(uint32_t addr, uint8_t val, void *p)
|
||||
{
|
||||
im1024_t *im1024 = (im1024_t *)p;
|
||||
|
||||
/* If we are in 'fast' input mode, send all writes to the internal
|
||||
* FIFO */
|
||||
if (addr >= 0xC6000 && addr < 0xC6100 && im1024->pgc.mapram[0x330] == 1)
|
||||
{
|
||||
fifo_write(im1024, val);
|
||||
/*
|
||||
PGCLOG(("im1024_write(%02x)\n", val));
|
||||
*/
|
||||
if (im1024->pgc.waiting_input_fifo)
|
||||
{
|
||||
im1024->pgc.waiting_input_fifo = 0;
|
||||
pgc_wake(&im1024->pgc);
|
||||
}
|
||||
return;
|
||||
}
|
||||
pgc_write(addr, val, &im1024->pgc);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* I don't know what the IMGSIZ command does, only that the Windows driver
|
||||
* issues it. So just parse and ignore it */
|
||||
void hndl_imgsiz(pgc_core_t *pgc)
|
||||
{
|
||||
int16_t w,h;
|
||||
uint8_t a,b;
|
||||
// im1024_t *im1024 = (im1024_t *)pgc;
|
||||
|
||||
if (!pgc_param_word(pgc, &w)) return;
|
||||
if (!pgc_param_word(pgc, &h)) return;
|
||||
if (!pgc_param_byte(pgc, &a)) return;
|
||||
if (!pgc_param_byte(pgc, &b)) return;
|
||||
|
||||
PGCLOG(("IMGSIZ %d,%d,%d,%d\n", w,h,a,b));
|
||||
}
|
||||
|
||||
|
||||
/* I don't know what the IPREC command does, only that the Windows driver
|
||||
* issues it. So just parse and ignore it */
|
||||
void hndl_iprec(pgc_core_t *pgc)
|
||||
{
|
||||
uint8_t param;
|
||||
// im1024_t *im1024 = (im1024_t *)pgc;
|
||||
|
||||
if (!pgc_param_byte(pgc, ¶m)) return;
|
||||
|
||||
PGCLOG(("IPREC %d\n", param));
|
||||
}
|
||||
|
||||
/* I think PAN controls which part of the 1024x1024 framebuffer is displayed
|
||||
* in the 1024x800 visible screen. */
|
||||
void hndl_pan(pgc_core_t *pgc)
|
||||
{
|
||||
int16_t x,y;
|
||||
|
||||
if (!pgc_param_word(pgc, &x)) return;
|
||||
if (!pgc_param_word(pgc, &y)) return;
|
||||
|
||||
PGCLOG(("PAN %d,%d\n", x, y));
|
||||
|
||||
pgc->pan_x = x;
|
||||
pgc->pan_y = y;
|
||||
}
|
||||
|
||||
/* PLINE draws a non-filled polyline at a fixed position */
|
||||
void hndl_pline(pgc_core_t *pgc)
|
||||
{
|
||||
int16_t x[257];
|
||||
int16_t y[257];
|
||||
uint8_t count;
|
||||
unsigned n;
|
||||
uint16_t linemask = pgc->line_pattern;
|
||||
|
||||
if (!pgc_param_byte(pgc, &count)) return;
|
||||
|
||||
PGCLOG(("PLINE<IM1024> (%d) ", count));
|
||||
for (n = 0; n < count; n++)
|
||||
{
|
||||
if (!pgc_param_word(pgc, &x[n])) return;
|
||||
if (!pgc_param_word(pgc, &y[n])) return;
|
||||
PGCLOG((" (%d,%d)\n", x[n], y[n]));
|
||||
}
|
||||
for (n = 1; n < count; n++)
|
||||
{
|
||||
linemask = pgc_draw_line(pgc, x[n - 1] << 16, y[n - 1] << 16,
|
||||
x[n] << 16, y[n] << 16, linemask);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Blit a single row of pixels from one location to another. To avoid
|
||||
* difficulties if the two overlap, read both rows into memory, process them
|
||||
* there, and write the result back. */
|
||||
void blkmov_row(pgc_core_t *pgc, int16_t x0, int16_t x1, int16_t x2,
|
||||
int16_t sy, int16_t ty)
|
||||
{
|
||||
int16_t x;
|
||||
uint8_t src[1024];
|
||||
uint8_t dst[1024];
|
||||
|
||||
for (x = x0; x <= x1; x++)
|
||||
{
|
||||
src[x - x0] = pgc_read_pixel(pgc, x, sy);
|
||||
dst[x - x0] = pgc_read_pixel(pgc, x - x0 + x2, ty);
|
||||
}
|
||||
for (x = x0; x <= x1; x++)
|
||||
{
|
||||
switch (pgc->draw_mode)
|
||||
{
|
||||
default:
|
||||
case 0: pgc_write_pixel(pgc, (x - x0 + x2), ty, src[x - x0]); break;
|
||||
case 1: pgc_write_pixel(pgc, (x - x0 + x2), ty, dst[x - x0] ^ 0xFF); break;
|
||||
case 2: pgc_write_pixel(pgc, (x - x0 + x2), ty, src[x - x0] ^ dst[x - x0]); break;
|
||||
case 3: pgc_write_pixel(pgc, (x - x0 + x2), ty, src[x - x0] & dst[x - x0]); break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* BLKMOV blits a rectangular area from one location to another, with no
|
||||
* clipping. */
|
||||
void hndl_blkmov(pgc_core_t *pgc)
|
||||
{
|
||||
int16_t x0,y0;
|
||||
int16_t x1,y1;
|
||||
int16_t x2,y2;
|
||||
int16_t y;
|
||||
// im1024_t *im1024 = (im1024_t *)pgc;
|
||||
|
||||
if (!pgc_param_word(pgc, &x0)) return;
|
||||
if (!pgc_param_word(pgc, &y0)) return;
|
||||
if (!pgc_param_word(pgc, &x1)) return;
|
||||
if (!pgc_param_word(pgc, &y1)) return;
|
||||
if (!pgc_param_word(pgc, &x2)) return;
|
||||
if (!pgc_param_word(pgc, &y2)) return;
|
||||
|
||||
PGCLOG(("BLKMOV %d,%d,%d,%d,%d,%d\n", x0,y0,x1,y1,x2,y2));
|
||||
|
||||
/* Disable clipping */
|
||||
PUSHCLIP
|
||||
|
||||
/* Either go down from the top, or up from the bottom, depending
|
||||
* whether areas might overlap */
|
||||
if (y2 <= y0)
|
||||
{
|
||||
for (y = y0; y <= y1; y++)
|
||||
{
|
||||
blkmov_row(pgc, x0, x1, x2, y, y - y0 + y2);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (y = y1; y >= y0; y--)
|
||||
{
|
||||
blkmov_row(pgc, x0, x1, x2, y, y - y0 + y2);
|
||||
}
|
||||
}
|
||||
/* Restore clipping */
|
||||
POPCLIP
|
||||
}
|
||||
|
||||
|
||||
/* This overrides the PGC ELIPSE command to parse its parameters as words
|
||||
* rather than coordinates */
|
||||
static void hndl_ellipse(pgc_core_t *pgc)
|
||||
{
|
||||
int16_t x, y;
|
||||
|
||||
if (!pgc_param_word(pgc, &x)) return;
|
||||
if (!pgc_param_word(pgc, &y)) return;
|
||||
|
||||
PGCLOG(("ELLIPSE<IM1024> %d,%d @ %d,%d\n", x,y,
|
||||
pgc->x >> 16, pgc->y >> 16));
|
||||
pgc_draw_ellipse(pgc, x << 16, y << 16);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* This overrides the PGC MOVE command to parse its parameters as words
|
||||
* rather than coordinates */
|
||||
static void hndl_move(pgc_core_t *pgc)
|
||||
{
|
||||
int16_t x, y;
|
||||
|
||||
if (!pgc_param_word(pgc, &x)) return;
|
||||
if (!pgc_param_word(pgc, &y)) return;
|
||||
|
||||
pgc->x = x << 16;
|
||||
pgc->y = y << 16;
|
||||
PGCLOG(("MOVE<IM1024> %d,%d\n", x,y));
|
||||
}
|
||||
|
||||
/* This overrides the PGC DRAW command to parse its parameters as words
|
||||
* rather than coordinates */
|
||||
static void hndl_draw(pgc_core_t *pgc)
|
||||
{
|
||||
int16_t x, y;
|
||||
|
||||
if (!pgc_param_word(pgc, &x)) return;
|
||||
if (!pgc_param_word(pgc, &y)) return;
|
||||
|
||||
PGCLOG(("DRAW<IM1024> %d,%d to %d,%d\n",
|
||||
pgc->x >> 16, pgc->y >> 16, x, y));
|
||||
pgc_draw_line(pgc, pgc->x, pgc->y, x << 16, y << 16, pgc->line_pattern);
|
||||
pgc->x = x << 16;
|
||||
pgc->y = y << 16;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* This overrides the PGC POLY command to parse its parameters as words
|
||||
* rather than coordinates */
|
||||
static void hndl_poly(pgc_core_t *pgc)
|
||||
{
|
||||
int32_t *x, *y;
|
||||
int32_t n;
|
||||
int16_t xw, yw, mask;
|
||||
unsigned realcount = 0;
|
||||
int parsing = 1;
|
||||
int as = 256;
|
||||
|
||||
x = malloc(as * sizeof(int32_t));
|
||||
y = malloc(as * sizeof(int32_t));
|
||||
|
||||
if (!x || !y)
|
||||
{
|
||||
PGCLOG(("hndl_poly: malloc failed\n"));
|
||||
return;
|
||||
}
|
||||
while (parsing)
|
||||
{
|
||||
uint8_t count;
|
||||
if (!pgc_param_byte(pgc, &count)) return;
|
||||
|
||||
if (count + realcount >= as)
|
||||
{
|
||||
int32_t *nx, *ny;
|
||||
|
||||
nx = realloc(x, 2 * as * sizeof(int32_t));
|
||||
ny = realloc(y, 2 * as * sizeof(int32_t));
|
||||
if (!x || !y)
|
||||
{
|
||||
PGCLOG(("hndl_poly: realloc failed\n"));
|
||||
break;
|
||||
}
|
||||
x = nx;
|
||||
y = ny;
|
||||
as *= 2;
|
||||
}
|
||||
|
||||
for (n = 0; n < count; n++)
|
||||
{
|
||||
if (!pgc_param_word(pgc, &xw)) return;
|
||||
if (!pgc_param_word(pgc, &yw)) return;
|
||||
|
||||
/* Skip degenerate line segments */
|
||||
if (realcount > 0 &&
|
||||
(xw << 16) == x[realcount - 1] &&
|
||||
(yw << 16) == y[realcount - 1])
|
||||
{
|
||||
continue;
|
||||
}
|
||||
x[realcount] = xw << 16;
|
||||
y[realcount] = yw << 16;
|
||||
++realcount;
|
||||
}
|
||||
/* If we're in a command list, peek ahead to see if the next command is
|
||||
* also POLY. If so, that's a continuation of this polygon! */
|
||||
parsing = 0;
|
||||
if (pgc->clcur && (pgc->clcur->rdptr+1) < pgc->clcur->wrptr &&
|
||||
pgc->clcur->list[pgc->clcur->rdptr] == 0x30)
|
||||
{
|
||||
PGCLOG(("hndl_poly: POLY continues!\n"));
|
||||
parsing = 1;
|
||||
/* Swallow the POLY */
|
||||
++pgc->clcur->rdptr;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
PGCLOG(("POLY<IM1024> (%d) fill_mode=%d\n", realcount, pgc->fill_mode));
|
||||
for (n = 0; n < realcount; n++)
|
||||
{
|
||||
PGCLOG((" (%d,%d)\n", x[n] >> 16, y[n] >> 16));
|
||||
}
|
||||
if (pgc->fill_mode)
|
||||
{
|
||||
pgc_fill_polygon(pgc, realcount, x, y);
|
||||
}
|
||||
/* Now draw borders */
|
||||
mask = pgc->line_pattern;
|
||||
for (n = 1; n < realcount; n++)
|
||||
{
|
||||
mask = pgc_draw_line(pgc, x[n - 1], y[n - 1], x[n], y[n], mask);
|
||||
}
|
||||
pgc_draw_line(pgc, x[realcount - 1], y[realcount - 1], x[0], y[0], mask);
|
||||
free(y);
|
||||
free(x);
|
||||
}
|
||||
|
||||
|
||||
static int parse_poly(pgc_core_t *pgc, pgc_commandlist_t *cl, int c)
|
||||
{
|
||||
uint8_t count;
|
||||
|
||||
PGCLOG(("parse_poly<IM1024>\n"));
|
||||
if (!pgc_param_byte(pgc, &count)) return 0;
|
||||
|
||||
PGCLOG(("parse_poly<IM1024>: count=%02x\n", count));
|
||||
if (!pgc_commandlist_append(cl, count))
|
||||
{
|
||||
pgc_error(pgc, PGC_ERROR_OVERFLOW);
|
||||
return 0;
|
||||
}
|
||||
PGCLOG(("parse_poly<IM1024>: parse %d words\n", 2 * count));
|
||||
return pgc_parse_words(pgc, cl, count * 2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* This overrides the PGC RECT command to parse its parameters as words
|
||||
* rather than coordinates */
|
||||
static void hndl_rect(pgc_core_t *pgc)
|
||||
{
|
||||
int16_t x0, y0, x1, y1, p, q;
|
||||
|
||||
x0 = pgc->x >> 16;
|
||||
y0 = pgc->y >> 16;
|
||||
|
||||
if (!pgc_param_word(pgc, &x1)) return;
|
||||
if (!pgc_param_word(pgc, &y1)) return;
|
||||
|
||||
/* Convert to raster coords */
|
||||
pgc_sto_raster(pgc, &x0, &y0);
|
||||
pgc_sto_raster(pgc, &x1, &y1);
|
||||
|
||||
if (x0 > x1) { p = x0; x0 = x1; x1 = p; }
|
||||
if (y0 > y1) { q = y0; y0 = y1; y1 = q; }
|
||||
|
||||
PGCLOG(("RECT<IM1024> (%d,%d) -> (%d,%d)\n", x0, y0, x1, y1));
|
||||
|
||||
if (pgc->fill_mode)
|
||||
{
|
||||
for (p = y0; p <= y1; p++)
|
||||
{
|
||||
pgc_fill_line_r(pgc, x0, x1, p);
|
||||
}
|
||||
}
|
||||
else /* Outline: 4 lines */
|
||||
{
|
||||
p = pgc->line_pattern;
|
||||
p = pgc_draw_line_r(pgc, x0, y0, x1, y0, p);
|
||||
p = pgc_draw_line_r(pgc, x1, y0, x1, y1, p);
|
||||
p = pgc_draw_line_r(pgc, x1, y1, x0, y1, p);
|
||||
p = pgc_draw_line_r(pgc, x0, y1, x0, y0, p);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* TODO: Text drawing should probably be implemented in vid_pgc.c rather
|
||||
* than vid_im1024.c */
|
||||
static void hndl_tdefin(pgc_core_t *pgc)
|
||||
{
|
||||
unsigned char ch, bt;
|
||||
unsigned char rows, cols;
|
||||
unsigned len, n;
|
||||
// unsigned x = 0;
|
||||
im1024_t * im1024 = (im1024_t *)pgc;
|
||||
|
||||
if (!pgc_param_byte(pgc, &ch)) return;
|
||||
if (!pgc_param_byte(pgc, &cols)) return;
|
||||
if (!pgc_param_byte(pgc, &rows)) return;
|
||||
|
||||
PGCLOG(("TDEFIN<IM1024> (%d,%d,%d) 0x%02x 0x%02x\n", ch, rows, cols,
|
||||
pgc->mapram[0x300], pgc->mapram[0x301]));
|
||||
|
||||
len = ((cols + 7) / 8) * rows;
|
||||
for (n = 0; n < len; n++)
|
||||
{
|
||||
// char buf[10];
|
||||
// unsigned char mask;
|
||||
|
||||
if (!pgc_param_byte(pgc, &bt)) return;
|
||||
|
||||
// buf[0] = 0;
|
||||
// for (mask = 0x80; mask != 0; mask >>= 1)
|
||||
// {
|
||||
// if (bt & mask) strcat(buf, "#");
|
||||
// else strcat(buf, "-");
|
||||
// ++x;
|
||||
// if (x == cols) { strcat(buf, "\n"); x = 0; }
|
||||
// }
|
||||
// PGCLOG((buf));
|
||||
|
||||
if (n < sizeof(im1024->font[ch])) im1024->font[ch][n] = bt;
|
||||
}
|
||||
im1024->fontx[ch] = cols;
|
||||
im1024->fonty[ch] = rows;
|
||||
}
|
||||
|
||||
static void hndl_tsize(pgc_core_t *pgc)
|
||||
{
|
||||
int16_t size;
|
||||
|
||||
if (!pgc_param_word(pgc, &size)) return;
|
||||
PGCLOG(("TSIZE<IM1024>(%d)\n", size));
|
||||
|
||||
pgc->tsize = size << 16;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void hndl_twrite(pgc_core_t *pgc)
|
||||
{
|
||||
unsigned char count;
|
||||
unsigned char mask;
|
||||
unsigned char *row;
|
||||
int x, y, wb, n;
|
||||
im1024_t * im1024 = (im1024_t *)pgc;
|
||||
int16_t x0 = pgc->x >> 16;
|
||||
int16_t y0 = pgc->y >> 16;
|
||||
unsigned char buf[256];
|
||||
/* unsigned char rbuf[256];*/
|
||||
|
||||
if (!pgc_param_byte(pgc, &count)) return;
|
||||
|
||||
for (n = 0; n < count; n++)
|
||||
{
|
||||
if (!pgc_param_byte(pgc, &buf[n])) return;
|
||||
}
|
||||
buf[count] = 0;
|
||||
/* for (n = 0; n <= count; n++)
|
||||
{
|
||||
if (isprint(buf[n]) || 0 == buf[n])
|
||||
{
|
||||
rbuf[n] = buf[n];
|
||||
}
|
||||
else rbuf[n] = '?';
|
||||
}*/
|
||||
pgc_sto_raster(pgc, &x0, &y0);
|
||||
PGCLOG(("TWRITE<IM1024> (%d,%-*.*s) x0=%d y0=%d\n", count, count, count, rbuf, x0, y0));
|
||||
|
||||
for (n = 0; n < count; n++)
|
||||
{
|
||||
wb = (im1024->fontx[buf[n]] + 7) / 8;
|
||||
PGCLOG(("ch=0x%02x w=%d h=%d wb=%d\n",
|
||||
buf[n], im1024->fontx[buf[n]],
|
||||
im1024->fonty[buf[n]], wb));
|
||||
for (y = 0; y < im1024->fonty[buf[n]]; y++)
|
||||
{
|
||||
mask = 0x80;
|
||||
row = &im1024->font[buf[n]][y * wb];
|
||||
for (x = 0; x < im1024->fontx[buf[n]]; x++)
|
||||
{
|
||||
/* rbuf[x] = (row[0] & mask) ? '#' : '-';*/
|
||||
if (row[0] & mask) pgc_plot(pgc, x + x0, y0 - y);
|
||||
mask = mask >> 1;
|
||||
if (mask == 0) { mask = 0x80; ++row; }
|
||||
}
|
||||
/* rbuf[x++] = '\n';
|
||||
rbuf[x++] = 0;*/
|
||||
// PGCLOG((rbuf);
|
||||
}
|
||||
x0 += im1024->fontx[buf[n]];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void hndl_txt88(pgc_core_t *pgc)
|
||||
{
|
||||
unsigned char count;
|
||||
unsigned char mask;
|
||||
unsigned char *row;
|
||||
int x, y, /*wb, */n;
|
||||
int16_t x0 = pgc->x >> 16;
|
||||
int16_t y0 = pgc->y >> 16;
|
||||
unsigned char buf[256];
|
||||
/* unsigned char rbuf[256];*/
|
||||
|
||||
if (!pgc_param_byte(pgc, &count)) return;
|
||||
|
||||
for (n = 0; n < count; n++)
|
||||
{
|
||||
if (!pgc_param_byte(pgc, &buf[n])) return;
|
||||
}
|
||||
buf[count] = 0;
|
||||
/* for (n = 0; n <= count; n++)
|
||||
{
|
||||
if (isprint(buf[n]) || 0 == buf[n])
|
||||
{
|
||||
rbuf[n] = buf[n];
|
||||
}
|
||||
else rbuf[n] = '?';
|
||||
}*/
|
||||
pgc_sto_raster(pgc, &x0, &y0);
|
||||
PGCLOG(("TXT88<IM1024> (%d,%-*.*s) x0=%d y0=%d\n", count, count, count, rbuf, x0, y0));
|
||||
|
||||
for (n = 0; n < count; n++)
|
||||
{
|
||||
/* wb = 2;*/
|
||||
PGCLOG(("ch=0x%02x w=%d h=%d wb=%d\n", buf[n], 12, 18, wb));
|
||||
for (y = 0; y < 18; y++)
|
||||
{
|
||||
mask = 0x80;
|
||||
row = &fontdat12x18[buf[n]][y * 2];
|
||||
for (x = 0; x < 12; x++)
|
||||
{
|
||||
/* rbuf[x] = (row[0] & mask) ? '#' : '-';*/
|
||||
if (row[0] & mask) pgc_plot(pgc, x + x0, y0 - y);
|
||||
mask = mask >> 1;
|
||||
if (mask == 0) { mask = 0x80; ++row; }
|
||||
}
|
||||
/* rbuf[x++] = '\n';
|
||||
rbuf[x++] = 0;*/
|
||||
// PGCLOG((rbuf);
|
||||
}
|
||||
x0 += 12;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static void hndl_imagew(pgc_core_t *pgc)
|
||||
{
|
||||
int16_t row1, col1, col2;
|
||||
uint8_t v1, v2;
|
||||
int16_t vp_x1, vp_y1, vp_x2, vp_y2;
|
||||
|
||||
if (!pgc_param_word(pgc, &row1)) return;
|
||||
if (!pgc_param_word(pgc, &col1)) return;
|
||||
if (!pgc_param_word(pgc, &col2)) return;
|
||||
|
||||
/* IMAGEW already uses raster coordinates so there is no need to
|
||||
* convert it */
|
||||
PGCLOG(("IMAGEW<IM1024> (row=%d,col1=%d,col2=%d)\n", row1, col1, col2));
|
||||
|
||||
vp_x1 = pgc->vp_x1;
|
||||
vp_y1 = pgc->vp_y1;
|
||||
vp_x2 = pgc->vp_x2;
|
||||
vp_y2 = pgc->vp_y2;
|
||||
/* Disable clipping */
|
||||
pgc->vp_x1 = 0;
|
||||
pgc->vp_y1 = 0;
|
||||
pgc->vp_x2 = pgc->maxw - 1;
|
||||
pgc->vp_y2 = pgc->maxh - 1;
|
||||
|
||||
/* In ASCII mode, what is written is a stream of bytes */
|
||||
if (pgc->ascii_mode)
|
||||
{
|
||||
while (col1 <= col2)
|
||||
{
|
||||
if (!pgc_param_byte(pgc, &v1)) return;
|
||||
pgc_write_pixel(pgc, col1, row1, v1);
|
||||
++col1;
|
||||
}
|
||||
return;
|
||||
}
|
||||
else /* In hex mode, it's RLE compressed */
|
||||
{
|
||||
while (col1 <= col2)
|
||||
{
|
||||
if (!pgc_param_byte(pgc, &v1)) return;
|
||||
|
||||
if (v1 & 0x80) /* Literal run */
|
||||
{
|
||||
v1 -= 0x7F;
|
||||
while (col1 <= col2 && v1 != 0)
|
||||
{
|
||||
if (!pgc_param_byte(pgc, &v2)) return;
|
||||
pgc_write_pixel(pgc, col1, row1, v2);
|
||||
++col1;
|
||||
--v1;
|
||||
}
|
||||
}
|
||||
else /* Repeated run */
|
||||
{
|
||||
if (!pgc_param_byte(pgc, &v2)) return;
|
||||
|
||||
++v1;
|
||||
while (col1 <= col2 && v1 != 0)
|
||||
{
|
||||
pgc_write_pixel(pgc, col1, row1, v2);
|
||||
++col1;
|
||||
--v1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Restore clipping */
|
||||
pgc->vp_x1 = vp_x1;
|
||||
pgc->vp_y1 = vp_y1;
|
||||
pgc->vp_x2 = vp_x2;
|
||||
pgc->vp_y2 = vp_y2;
|
||||
}
|
||||
|
||||
/* I have called this command DOT - I don't know its proper name. Draws a
|
||||
* single pixel at the current location */
|
||||
static void hndl_dot(pgc_core_t *pgc)
|
||||
{
|
||||
int16_t x = pgc->x >> 16, y = pgc->y >> 16;
|
||||
|
||||
pgc_sto_raster(pgc, &x, &y);
|
||||
|
||||
PGCLOG(("Dot @ %d,%d ink=%d mode=%d\n", x, y, pgc->colour, pgc->draw_mode));
|
||||
pgc_plot(pgc, x, y);
|
||||
}
|
||||
|
||||
/* This command (which I have called IMAGEX, since I don't know its real
|
||||
* name) is a screen-to-memory blit. It reads a rectangle of bytes, rather
|
||||
* than the single row read by IMAGER, and does not attempt to compress
|
||||
* the result */
|
||||
static void hndl_imagex(pgc_core_t *pgc)
|
||||
{
|
||||
int16_t x0, x1, y0, y1;
|
||||
int16_t p,q;
|
||||
|
||||
if (!pgc_param_word(pgc, &x0)) return;
|
||||
if (!pgc_param_word(pgc, &y0)) return;
|
||||
if (!pgc_param_word(pgc, &x1)) return;
|
||||
if (!pgc_param_word(pgc, &y1)) return;
|
||||
|
||||
/* IMAGEX already uses raster coordinates so don't convert */
|
||||
PGCLOG(("IMAGEX<IM1024> (%d,%d,%d,%d)\n", x0,y0,x1,y1));
|
||||
|
||||
for (p = y0; p <= y1; p++)
|
||||
{
|
||||
for (q = x0; q <= x1; q++)
|
||||
{
|
||||
if (!pgc_result_byte(pgc, pgc_read_pixel(pgc, q, p)))
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Commands implemented by the IM-1024.
|
||||
*
|
||||
* TODO: A lot of commands need commandlist parsers.
|
||||
* TODO: The IM-1024 has a lot more commands that are not included here
|
||||
* (BLINK, BUTRD, COPROC, RBAND etc) because the Windows 1.03 driver
|
||||
* does not use them.
|
||||
*/
|
||||
static const pgc_command_t im1024_commands[] =
|
||||
{
|
||||
{ "BLKMOV", 0xDF, hndl_blkmov, pgc_parse_words, 6 },
|
||||
{ "DRAW", 0x28, hndl_draw, pgc_parse_words, 2 },
|
||||
{ "D", 0x28, hndl_draw, pgc_parse_words, 2 },
|
||||
{ "DOT", 0x08, hndl_dot },
|
||||
{ "ELIPSE", 0x39, hndl_ellipse, pgc_parse_words, 2 },
|
||||
{ "EL", 0x39, hndl_ellipse, pgc_parse_words, 2 },
|
||||
{ "IMAGEW", 0xD9, hndl_imagew },
|
||||
{ "IW", 0xD9, hndl_imagew },
|
||||
{ "IMAGEX", 0xDA, hndl_imagex },
|
||||
{ "TXT88", 0x88, hndl_txt88 },
|
||||
{ "TWRITE", 0x8B, hndl_twrite },
|
||||
{ "TDEFIN", 0x84, hndl_tdefin },
|
||||
{ "TD", 0x84, hndl_tdefin },
|
||||
{ "TSIZE", 0x81, hndl_tsize },
|
||||
{ "TS", 0x81, hndl_tsize },
|
||||
{ "IPREC", 0xE4, hndl_iprec },
|
||||
{ "IMGSIZ", 0x4E, hndl_imgsiz },
|
||||
{ "LUT8", 0xE6, pgc_hndl_lut8 },
|
||||
{ "L8", 0xE6, pgc_hndl_lut8 },
|
||||
{ "LUT8RD", 0x53, pgc_hndl_lut8rd },
|
||||
{ "L8RD", 0x53, pgc_hndl_lut8rd },
|
||||
{ "PAN", 0xB7, hndl_pan },
|
||||
{ "POLY", 0x30, hndl_poly, parse_poly },
|
||||
{ "P", 0x30, hndl_poly, parse_poly },
|
||||
{ "PLINE", 0x36, hndl_pline },
|
||||
{ "PL", 0x37, hndl_pline },
|
||||
{ "MOVE", 0x10, hndl_move, pgc_parse_words, 2 },
|
||||
{ "M", 0x10, hndl_move, pgc_parse_words, 2 },
|
||||
{ "RECT", 0x34, hndl_rect },
|
||||
{ "R", 0x34, hndl_rect },
|
||||
{ "******", 0x00, NULL }
|
||||
};
|
||||
|
||||
|
||||
void *im1024_init()
|
||||
{
|
||||
im1024_t *im1024 = malloc(sizeof(im1024_t));
|
||||
memset(im1024, 0, sizeof(im1024_t));
|
||||
|
||||
im1024->fifo = malloc(4096);
|
||||
im1024->fifo_len = 4096;
|
||||
im1024->fifo_wrptr = 0;
|
||||
im1024->fifo_rdptr = 0;
|
||||
|
||||
/* 1024x1024 framebuffer with 1024x800 visible
|
||||
Pixel clock is a guess */
|
||||
pgc_core_init(&im1024->pgc, 1024, 1024, 1024, 800, im1024_input_byte, 65000000.0);
|
||||
|
||||
mem_mapping_set_handler(&im1024->pgc.mapping,
|
||||
im1024_read, NULL, NULL,
|
||||
im1024_write, NULL, NULL);
|
||||
|
||||
im1024->pgc.pgc_commands = im1024_commands;
|
||||
return im1024;
|
||||
}
|
||||
|
||||
void im1024_close(void *p)
|
||||
{
|
||||
im1024_t *im1024 = (im1024_t *)p;
|
||||
|
||||
pgc_close(&im1024->pgc);
|
||||
}
|
||||
|
||||
void im1024_speed_changed(void *p)
|
||||
{
|
||||
im1024_t *im1024 = (im1024_t *)p;
|
||||
|
||||
pgc_speed_changed(&im1024->pgc);
|
||||
}
|
||||
|
||||
device_t im1024_device =
|
||||
{
|
||||
"Image Manager 1024",
|
||||
0,
|
||||
im1024_init,
|
||||
im1024_close,
|
||||
NULL,
|
||||
im1024_speed_changed,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
1
src/vid_im1024.h
Normal file
1
src/vid_im1024.h
Normal file
|
|
@ -0,0 +1 @@
|
|||
extern device_t im1024_device;
|
||||
2477
src/vid_pgc.c
Normal file
2477
src/vid_pgc.c
Normal file
File diff suppressed because it is too large
Load diff
164
src/vid_pgc.h
Normal file
164
src/vid_pgc.h
Normal file
|
|
@ -0,0 +1,164 @@
|
|||
#include "timer.h"
|
||||
|
||||
struct pgc_core_t;
|
||||
|
||||
typedef struct pgc_commandlist_t
|
||||
{
|
||||
uint8_t *list;
|
||||
uint32_t listmax;
|
||||
uint32_t wrptr;
|
||||
uint32_t rdptr;
|
||||
uint32_t repeat;
|
||||
struct pgc_commandlist_t *chain;
|
||||
} pgc_commandlist_t;
|
||||
|
||||
int pgc_commandlist_append(pgc_commandlist_t *list, uint8_t v);
|
||||
|
||||
typedef struct pgc_command_t
|
||||
{
|
||||
char ascii[6];
|
||||
uint8_t hex;
|
||||
void (*handler)(struct pgc_core_t *pgc);
|
||||
int (*parser) (struct pgc_core_t *pgc, pgc_commandlist_t *cl,
|
||||
int p);
|
||||
int p;
|
||||
} pgc_command_t;
|
||||
|
||||
|
||||
typedef struct pgc_core_t
|
||||
{
|
||||
mem_mapping_t mapping;
|
||||
mem_mapping_t cga_mapping;
|
||||
|
||||
pgc_commandlist_t *clist;
|
||||
pgc_commandlist_t *clcur;
|
||||
uint8_t mapram[2048]; /* Host <--> PGC communication buffer */
|
||||
uint8_t *cga_vram;
|
||||
uint8_t *vram;
|
||||
char asc_command[7];
|
||||
uint8_t hex_command;
|
||||
uint32_t palette[256];
|
||||
uint32_t userpal[256];
|
||||
uint32_t maxw, maxh; /* Maximum framebuffer size */
|
||||
uint32_t visw, vish; /* Maximum screen size */
|
||||
uint32_t screenw, screenh;
|
||||
int16_t pan_x, pan_y;
|
||||
uint16_t win_x1, win_x2, win_y1, win_y2;
|
||||
uint16_t vp_x1, vp_x2, vp_y1, vp_y2;
|
||||
int16_t fill_pattern[16];
|
||||
int16_t line_pattern;
|
||||
uint8_t draw_mode;
|
||||
uint8_t fill_mode;
|
||||
uint8_t colour;
|
||||
uint8_t tjust_h; /* Horizontal alignment 1=left 2=centre 3=right*/
|
||||
uint8_t tjust_v; /* Vertical alignment 1=bottom 2=centre 3=top*/
|
||||
int32_t tsize; /* Horizontal spacing */
|
||||
|
||||
int32_t x, y, z;/* Drawing position */
|
||||
|
||||
const pgc_command_t *pgc_commands;
|
||||
thread_t *pgc_thread;
|
||||
event_t *pgc_wake_thread;
|
||||
pc_timer_t wake_timer;
|
||||
// int wake_timer;
|
||||
|
||||
int waiting_input_fifo;
|
||||
int waiting_output_fifo;
|
||||
int waiting_error_fifo;
|
||||
int cga_enabled;
|
||||
int cga_selected;
|
||||
int ascii_mode;
|
||||
int result_count;
|
||||
|
||||
int fontbase;
|
||||
int linepos, displine;
|
||||
int vc;
|
||||
int cgadispon;
|
||||
int con, coff, cursoron, cgablink;
|
||||
int vsynctime, vadj;
|
||||
uint16_t ma, maback;
|
||||
int oddeven;
|
||||
|
||||
uint64_t dispontime, dispofftime;
|
||||
pc_timer_t timer;
|
||||
// int vidtime;
|
||||
double native_pixel_clock;
|
||||
|
||||
int drawcursor;
|
||||
|
||||
int (*inputbyte)(struct pgc_core_t *pgc, uint8_t *result);
|
||||
|
||||
} pgc_core_t;
|
||||
|
||||
void pgc_init(pgc_core_t *pgc);
|
||||
void pgc_out(uint16_t addr, uint8_t val, void *p);
|
||||
uint8_t pgc_in(uint16_t addr, void *p);
|
||||
void pgc_write(uint32_t addr, uint8_t val, void *p);
|
||||
uint8_t pgc_read(uint32_t addr, void *p);
|
||||
void pgc_recalctimings(pgc_core_t *pgc);
|
||||
void pgc_poll(void *p);
|
||||
void pgc_reset(pgc_core_t *pgc);
|
||||
void pgc_wake(pgc_core_t *pgc);
|
||||
/* Plot a pixel (raster coordinates, current ink) */
|
||||
void pgc_plot(pgc_core_t *pgc, uint16_t x, uint16_t y);
|
||||
void pgc_write_pixel(pgc_core_t *pgc, uint16_t x, uint16_t y, uint8_t ink);
|
||||
uint8_t pgc_read_pixel(pgc_core_t *pgc, uint16_t x, uint16_t y);
|
||||
uint8_t *pgc_vram_addr(pgc_core_t *pgc, int16_t x, int16_t y);
|
||||
/* Draw line (window coordinates) */
|
||||
uint16_t pgc_draw_line(pgc_core_t *pgc, int32_t x1, int32_t y1, int32_t x2, int32_t y2, uint16_t linemask);
|
||||
/* Draw line (raster coordinates) */
|
||||
uint16_t pgc_draw_line_r(pgc_core_t *pgc, int32_t x1, int32_t y1, int32_t x2, int32_t y2, uint16_t linemask);
|
||||
void pgc_draw_ellipse(pgc_core_t *pgc, int32_t x, int32_t y);
|
||||
void pgc_fill_polygon(pgc_core_t *pgc, unsigned corners, int32_t *x, int32_t *y);
|
||||
/* Horizontal line in fill pattern (raster coordinates) */
|
||||
void pgc_fill_line_r(pgc_core_t *pgc, int32_t x0, int32_t x1, int32_t y);
|
||||
|
||||
/* Convert to raster coordinates */
|
||||
void pgc_sto_raster(pgc_core_t *pgc, int16_t *x, int16_t *y);
|
||||
void pgc_ito_raster(pgc_core_t *pgc, int32_t *x, int32_t *y);
|
||||
void pgc_dto_raster(pgc_core_t *pgc, double *x, double *y);
|
||||
|
||||
/* Read/write to the PGC's FIFOs */
|
||||
int pgc_input_byte(pgc_core_t *pgc, uint8_t *val);
|
||||
int pgc_output_byte(pgc_core_t *pgc, uint8_t val);
|
||||
int pgc_output_string(pgc_core_t *pgc, const char *val);
|
||||
int pgc_error_byte(pgc_core_t *pgc, uint8_t val);
|
||||
int pgc_error_string(pgc_core_t *pgc, const char *val);
|
||||
|
||||
int pgc_param_byte(pgc_core_t *pgc, uint8_t *val);
|
||||
int pgc_param_word(pgc_core_t *pgc, int16_t *val);
|
||||
int pgc_param_coord(pgc_core_t *pgc, int32_t *val);
|
||||
int pgc_result_byte(pgc_core_t *pgc, uint8_t val);
|
||||
int pgc_result_word(pgc_core_t *pgc, int16_t val);
|
||||
int pgc_result_coord(pgc_core_t *pgc, int32_t val);
|
||||
|
||||
void pgc_sleep(pgc_core_t *pgc);
|
||||
int pgc_error(pgc_core_t *pgc, int err);
|
||||
void pgc_core_init(pgc_core_t *pgc, int maxw, int maxh, int visw, int vish,
|
||||
int (*inpbyte)(struct pgc_core_t *pgc, uint8_t *result), double native_pixel_clock);
|
||||
void pgc_speed_changed(void *p);
|
||||
void pgc_close(void *p);
|
||||
|
||||
void pgc_hndl_lut8(pgc_core_t *pgc);
|
||||
void pgc_hndl_lut8rd(pgc_core_t *pgc);
|
||||
|
||||
int pgc_parse_bytes(pgc_core_t *pgc, pgc_commandlist_t *cl, int p);
|
||||
int pgc_parse_words(pgc_core_t *pgc, pgc_commandlist_t *cl, int p);
|
||||
int pgc_parse_coords(pgc_core_t *pgc, pgc_commandlist_t *cl, int p);
|
||||
|
||||
extern device_t pgc_device;
|
||||
|
||||
#define PGC_ERROR_RANGE 0x01
|
||||
#define PGC_ERROR_INTEGER 0x02
|
||||
#define PGC_ERROR_MEMORY 0x03
|
||||
#define PGC_ERROR_OVERFLOW 0x04
|
||||
#define PGC_ERROR_DIGIT 0x05
|
||||
#define PGC_ERROR_OPCODE 0x06
|
||||
#define PGC_ERROR_RUNNING 0x07
|
||||
#define PGC_ERROR_STACK 0x08
|
||||
#define PGC_ERROR_TOOLONG 0x09
|
||||
#define PGC_ERROR_AREA 0x0A
|
||||
#define PGC_ERROR_MISSING 0x0B
|
||||
|
||||
/* #define PGCLOG(x) pclog x */
|
||||
#define PGCLOG(x)
|
||||
|
|
@ -3354,17 +3354,7 @@ static void voodoo_codegen_init(voodoo_t *voodoo)
|
|||
#if WIN64
|
||||
voodoo->codegen_data = VirtualAlloc(NULL, sizeof(voodoo_x86_data_t) * BLOCK_NUM * 2, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
|
||||
#else
|
||||
voodoo->codegen_data = malloc(sizeof(voodoo_x86_data_t) * BLOCK_NUM * 2);
|
||||
#endif
|
||||
|
||||
#if defined(__linux__) || defined(__APPLE__)
|
||||
start = (void *)((long)voodoo->codegen_data & pagemask);
|
||||
len = ((sizeof(voodoo_x86_data_t) * BLOCK_NUM * 2) + pagesize) & pagemask;
|
||||
if (mprotect(start, len, PROT_READ | PROT_WRITE | PROT_EXEC) != 0)
|
||||
{
|
||||
perror("mprotect");
|
||||
exit(-1);
|
||||
}
|
||||
voodoo->codegen_data = mmap(0, sizeof(voodoo_x86_data_t) * BLOCK_NUM*2, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANON|MAP_PRIVATE, 0, 0);
|
||||
#endif
|
||||
|
||||
for (c = 0; c < 256; c++)
|
||||
|
|
@ -3394,7 +3384,7 @@ static void voodoo_codegen_close(voodoo_t *voodoo)
|
|||
#if WIN64
|
||||
VirtualFree(voodoo->codegen_data, 0, MEM_RELEASE);
|
||||
#else
|
||||
free(voodoo->codegen_data);
|
||||
munmap(voodoo->codegen_data, sizeof(voodoo_x86_data_t) * BLOCK_NUM*2);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3292,17 +3292,7 @@ static void voodoo_codegen_init(voodoo_t *voodoo)
|
|||
#if defined WIN32 || defined _WIN32 || defined _WIN32
|
||||
voodoo->codegen_data = VirtualAlloc(NULL, sizeof(voodoo_x86_data_t) * BLOCK_NUM*2, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
|
||||
#else
|
||||
voodoo->codegen_data = malloc(sizeof(voodoo_x86_data_t) * BLOCK_NUM*2);
|
||||
#endif
|
||||
|
||||
#if defined(__linux__) || defined(__APPLE__)
|
||||
start = (void *)((long)voodoo->codegen_data & pagemask);
|
||||
len = ((sizeof(voodoo_x86_data_t) * BLOCK_NUM*2) + pagesize) & pagemask;
|
||||
if (mprotect(start, len, PROT_READ | PROT_WRITE | PROT_EXEC) != 0)
|
||||
{
|
||||
perror("mprotect");
|
||||
exit(-1);
|
||||
}
|
||||
voodoo->codegen_data = mmap(0, sizeof(voodoo_x86_data_t) * BLOCK_NUM*2, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANON|MAP_PRIVATE, 0, 0);
|
||||
#endif
|
||||
|
||||
for (c = 0; c < 256; c++)
|
||||
|
|
@ -3332,6 +3322,6 @@ static void voodoo_codegen_close(voodoo_t *voodoo)
|
|||
#if defined WIN32 || defined _WIN32 || defined _WIN32
|
||||
VirtualFree(voodoo->codegen_data, 0, MEM_RELEASE);
|
||||
#else
|
||||
free(voodoo->codegen_data);
|
||||
munmap(voodoo->codegen_data, sizeof(voodoo_x86_data_t) * BLOCK_NUM*2);
|
||||
#endif
|
||||
}
|
||||
|
|
|
|||
14
src/video.c
14
src/video.c
|
|
@ -24,6 +24,7 @@
|
|||
#include "vid_genius.h"
|
||||
#include "vid_hercules.h"
|
||||
#include "vid_ht216.h"
|
||||
#include "vid_im1024.h"
|
||||
#include "vid_incolor.h"
|
||||
#include "vid_colorplus.h"
|
||||
#include "vid_mda.h"
|
||||
|
|
@ -35,6 +36,7 @@
|
|||
#include "vid_pc1640.h"
|
||||
#include "vid_pc200.h"
|
||||
#include "vid_pcjr.h"
|
||||
#include "vid_pgc.h"
|
||||
#include "vid_ps1_svga.h"
|
||||
#include "vid_s3.h"
|
||||
#include "vid_s3_virge.h"
|
||||
|
|
@ -94,6 +96,7 @@ static VIDEO_CARD video_cards[] =
|
|||
{"EGA", "ega", &ega_device, GFX_EGA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}},
|
||||
{"Hercules", "hercules", &hercules_device, GFX_HERCULES, VIDEO_FLAG_TYPE_MDA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}},
|
||||
{"Hercules InColor", "incolor", &incolor_device, GFX_INCOLOR, VIDEO_FLAG_TYPE_MDA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}},
|
||||
{"Image Manager 1024", "im1024", &im1024_device, GFX_IM1024, VIDEO_FLAG_TYPE_CGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}},
|
||||
{"MDA", "mda", &mda_device, GFX_MDA, VIDEO_FLAG_TYPE_MDA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}},
|
||||
{"MDSI Genius", "genius", &genius_device, GFX_GENIUS, VIDEO_FLAG_TYPE_CGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}},
|
||||
{"Number Nine 9FX (S3 Trio64)", "n9_9fx", &s3_9fx_device, GFX_N9_9FX, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 3, 2, 4, 25, 25, 40}},
|
||||
|
|
@ -101,6 +104,9 @@ static VIDEO_CARD video_cards[] =
|
|||
{"OAK OTI-067", "oti067", &oti067_device, GFX_OTI067, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 6, 8, 16, 6, 8, 16}},
|
||||
{"Olivetti GO481 (Paradise PVGA1A)", "olivetti_go481", ¶dise_pvga1a_oli_go481_device, GFX_OLIVETTI_GO481, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 6, 8, 16, 6, 8, 16}},
|
||||
{"Paradise Bahamas 64 (S3 Vision864)", "bahamas64", &s3_bahamas64_device, GFX_BAHAMAS64, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 5, 20, 20, 35}},
|
||||
/* Not offered as the emulation is very incomplete
|
||||
{"Professional Graphics Controller", "pgc", &pgc_device, GFX_PGC, VIDEO_FLAG_TYPE_CGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}},
|
||||
*/
|
||||
{"Phoenix S3 Trio32", "px_trio32", &s3_phoenix_trio32_device, GFX_PHOENIX_TRIO32, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 3, 2, 4, 25, 25, 40}},
|
||||
{"Phoenix S3 Trio64", "px_trio64", &s3_phoenix_trio64_device, GFX_PHOENIX_TRIO64, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 3, 2, 4, 25, 25, 40}},
|
||||
{"Plantronics ColorPlus", "plantronics", &colorplus_device, GFX_COLORPLUS, VIDEO_FLAG_TYPE_CGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}},
|
||||
|
|
@ -817,6 +823,7 @@ uint8_t fontdat[2048][8];
|
|||
uint8_t fontdatm[2048][16];
|
||||
uint8_t fontdatw[512][32]; /* Wyse700 font */
|
||||
uint8_t fontdat8x12[256][16]; /* MDSI Genius font */
|
||||
uint8_t fontdat12x18[256][36]; /* IM1024 font */
|
||||
uint8_t fontdatksc5601[16384][32]; /* Korean KSC-5601 font */
|
||||
uint8_t fontdatksc5601_user[192][32]; /* Korean KSC-5601 user defined font */
|
||||
|
||||
|
|
@ -952,6 +959,13 @@ void loadfont(char *s, fontformat_t format)
|
|||
fread(&fontdatm[c][0], 1, 16, f);
|
||||
}
|
||||
break;
|
||||
case FONT_IM1024: /* Image Manager 1024 native font */
|
||||
for (c=0;c<256;c++)
|
||||
{
|
||||
fread(&fontdat12x18[c][0], 1, 36, f);
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
fclose(f);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@ typedef enum
|
|||
FONT_T3100E, /* Toshiba T3100e, four fonts */
|
||||
FONT_KSC5601, /* Korean KSC-5601 */
|
||||
FONT_SIGMA400, /* Sigma Color 400, 8x8 and 8x16 */
|
||||
|
||||
FONT_IM1024, /* Image Manager 1024 */
|
||||
} fontformat_t;
|
||||
|
||||
void loadfont(char *s, fontformat_t format);
|
||||
|
|
|
|||
Loading…
Reference in a new issue