diff -u -r -N pce-0.1.7/src/arch/ibmpc/ibmpc.c pce-new/src/arch/ibmpc/ibmpc.c --- pce-0.1.7/src/arch/ibmpc/ibmpc.c 2006-07-03 07:48:47.000000000 +0100 +++ pce-new/src/arch/ibmpc/ibmpc.c 2008-10-14 23:06:25.000000000 +0100 @@ -5,8 +5,9 @@ /***************************************************************************** * File name: src/arch/ibmpc/ibmpc.c * * Created: 1999-04-16 by Hampa Hug * - * Last modified: 2006-07-03 by Hampa Hug * + * Last modified: 2008-10-13 by John Elliott * * Copyright: (C) 1999-2006 Hampa Hug * + * (C) 2008 John Elliott * *****************************************************************************/ /***************************************************************************** @@ -386,6 +387,42 @@ } static +int pc_setup_plantronics (ibmpc_t *pc, ini_sct_t *sct) +{ + pc->video = plantronics_new (pc->trm, sct); + if (pc->video == NULL) { + return (1); + } + + mem_add_blk (pc->mem, pce_video_get_mem (pc->video), 0); + mem_add_blk (pc->prt, pce_video_get_reg (pc->video), 0); + + pc->ppi_port_a[0] &= ~0x30; + pc->ppi_port_a[0] |= 0x20; + + return (0); +} + + +static +int pc_setup_wy700 (ibmpc_t *pc, ini_sct_t *sct) +{ + pc->video = wy700_new (pc->trm, sct); + if (pc->video == NULL) { + return (1); + } + + mem_add_blk (pc->mem, pce_video_get_mem (pc->video), 0); + mem_add_blk (pc->prt, pce_video_get_reg (pc->video), 0); + + pc->ppi_port_a[0] &= ~0x30; + pc->ppi_port_a[0] |= 0x20; + + return (0); +} + + +static int pc_setup_cga (ibmpc_t *pc, ini_sct_t *sct) { pc->video = cga_new (pc->trm, sct); @@ -469,6 +506,12 @@ else if (strcmp (dev, "cga") == 0) { pc_setup_cga (pc, sct); } + else if (strcmp (dev, "plantronics") == 0) { + pc_setup_plantronics (pc, sct); + } + else if (strcmp (dev, "wyse") == 0 || strcmp (dev, "wy700") == 0) { + pc_setup_wy700 (pc, sct); + } else if (strcmp (dev, "hgc") == 0) { pc_setup_hgc (pc, sct); } diff -u -r -N pce-0.1.7/src/arch/ibmpc/main.h pce-new/src/arch/ibmpc/main.h --- pce-0.1.7/src/arch/ibmpc/main.h 2006-06-19 08:56:15.000000000 +0100 +++ pce-new/src/arch/ibmpc/main.h 2008-10-14 23:01:18.000000000 +0100 @@ -5,8 +5,9 @@ /***************************************************************************** * File name: src/arch/ibmpc/main.h * * Created: 2001-05-01 by Hampa Hug * - * Last modified: 2006-06-19 by Hampa Hug * + * Last modified: 2008-10-13 by John Elliott * * Copyright: (C) 1996-2006 Hampa Hug * + * (C) 2008 John Elliott * *****************************************************************************/ /***************************************************************************** @@ -111,6 +112,8 @@ #include #include #include +#include +#include #include #include diff -u -r -N pce-0.1.7/src/arch/ibmpc/Makefile.in pce-new/src/arch/ibmpc/Makefile.in --- pce-0.1.7/src/arch/ibmpc/Makefile.in 2006-06-19 08:56:15.000000000 +0100 +++ pce-new/src/arch/ibmpc/Makefile.in 2008-10-14 23:04:34.000000000 +0100 @@ -28,6 +28,8 @@ $(pcedst)/cpu/e8086/e8086.a \ $(pcedst)/chipset/82xx/chipset.a \ $(pcedst)/devices/video/cga.o \ + $(pcedst)/devices/video/plantronics.o \ + $(pcedst)/devices/video/wy700.o \ $(pcedst)/devices/video/vga.o \ $(pcedst)/devices/video/ega.o \ $(pcedst)/devices/video/hgc.o \ diff -u -r -N pce-0.1.7/src/devices/video/cga.c pce-new/src/devices/video/cga.c --- pce-0.1.7/src/devices/video/cga.c 2005-12-28 21:42:53.000000000 +0000 +++ pce-new/src/devices/video/cga.c 2008-10-14 21:57:00.000000000 +0100 @@ -5,8 +5,9 @@ /***************************************************************************** * File name: src/devices/video/cga.c * * Created: 2003-04-18 by Hampa Hug * - * Last modified: 2005-04-20 by Hampa Hug * + * Last modified: 2008-10-13 by John Elliott * * Copyright: (C) 2003-2005 Hampa Hug * + * (C) 2008 John Elliott * *****************************************************************************/ /***************************************************************************** @@ -130,6 +131,8 @@ cga->palette[1] = 11; cga->palette[2] = 13; cga->palette[3] = 15; + cga->modereg = 0; + cga->colreg = 0; cga->mode = 0; trm_set_mode (trm, TERM_MODE_TEXT, 80, 25); @@ -472,11 +475,12 @@ int cga_mode2_screenshot (cga_t *cga, FILE *fp) { unsigned x, y, i; - unsigned val; + unsigned val, col; unsigned char *mem; - fputs ("P5\n640 200\n255 ", fp); + fputs ("P6\n640 200\n255 ", fp); + col = cga->palette[0]; for (y = 0; y < 200; y++) { mem = cga->mem->data + 80 * (y / 2); @@ -489,10 +493,14 @@ for (i = 0; i < 8; i++) { if (val & (0x80 >> i)) { - fputc (0xff, fp); + fputc (cga_col[col].r >> 8, fp); + fputc (cga_col[col].g >> 8, fp); + fputc (cga_col[col].b >> 8, fp); } else { fputc (0x00, fp); + fputc (0x00, fp); + fputc (0x00, fp); } } } @@ -517,10 +525,10 @@ val1 = mem1[x]; for (i = 0; i < 8; i++) { - trm_set_col (cga->trm, (val0 & 0x80) ? 15 : 0, 0); + trm_set_col (cga->trm, (val0 & 0x80) ? cga->palette[0] : 0, 0); trm_set_pxl (cga->trm, 8 * x + i, 2 * y); - trm_set_col (cga->trm, (val1 & 0x80) ? 15 : 0, 0); + trm_set_col (cga->trm, (val1 & 0x80) ? cga->palette[0] : 0, 0); trm_set_pxl (cga->trm, 8 * x + i, 2 * y + 1); val0 <<= 1; @@ -561,7 +569,7 @@ if ((old ^ val) & 0x80) { col = (val >> 7) & 0x01; - trm_set_col (cga->trm, col ? 15 : 0, 0); + trm_set_col (cga->trm, col ? cga->palette[0] : 0, 0); trm_set_pxl (cga->trm, x + i, y); } @@ -654,38 +662,73 @@ } } -void cga_set_palette (cga_t *cga, unsigned pal, unsigned char bg) +void cga_set_palette (cga_t *cga) { - pal &= 1; + unsigned pal, bg; + + pal = ((cga->colreg >> 4) & 3) | (cga->modereg & 4); + bg = cga->colreg & 0x0F; - if (pal == cga->pal) { + if (pal == cga->pal && bg == cga->palette[0]) { return; } cga->pal = pal; - switch (pal & 1) { + switch (pal) { case 0: cga->palette[0] = bg; - cga->palette[1] = 8; + cga->palette[1] = 3; + cga->palette[2] = 5; + cga->palette[3] = 7; + break; + + case 1: + cga->palette[0] = bg; + cga->palette[1] = 11; cga->palette[2] = 13; cga->palette[3] = 15; break; - case 1: + case 2: + cga->palette[0] = bg; + cga->palette[1] = 2; + cga->palette[2] = 4; + cga->palette[3] = 6; + break; + + case 3: cga->palette[0] = bg; cga->palette[1] = 10; cga->palette[2] = 12; cga->palette[3] = 14; break; + + case 4: + case 6: + cga->palette[0] = bg; + cga->palette[1] = 3; + cga->palette[2] = 4; + cga->palette[3] = 7; + break; + + case 5: + case 7: + cga->palette[0] = bg; + cga->palette[1] = 11; + cga->palette[2] = 12; + cga->palette[3] = 15; + break; } cga_update (cga); } -void cga_set_mode (cga_t *cga, unsigned char mode) +void cga_set_mode (cga_t *cga) { - unsigned newmode; + unsigned newmode, mode; + + mode = cga->modereg; if ((mode & 0x02) == 0) { newmode = 0; @@ -723,6 +766,9 @@ cga_update (cga); } + + + void cga_mem_set_uint8 (cga_t *cga, unsigned long addr, unsigned char val) { switch (cga->mode) { @@ -810,11 +856,15 @@ break; case 0x04: - cga_set_mode (cga, val); + cga->modereg = val; + cga_set_mode (cga); +/* Mode register can affect palette */ + cga_set_palette (cga); break; case 0x05: - cga_set_palette (cga, (val >> 5) ^ 1, val & 0x0f); + cga->colreg = val; + cga_set_palette (cga); break; } } diff -u -r -N pce-0.1.7/src/devices/video/cga.h pce-new/src/devices/video/cga.h --- pce-0.1.7/src/devices/video/cga.h 2005-12-28 21:42:53.000000000 +0000 +++ pce-new/src/devices/video/cga.h 2008-10-14 21:53:59.000000000 +0100 @@ -5,8 +5,9 @@ /***************************************************************************** * File name: src/devices/video/cga.h * * Created: 2003-04-18 by Hampa Hug * - * Last modified: 2005-04-18 by Hampa Hug * + * Last modified: 2008-10-13 by John Elliott * * Copyright: (C) 2003-2005 Hampa Hug * + * (C) 2008 John Elliott * *****************************************************************************/ /***************************************************************************** @@ -55,6 +56,9 @@ unsigned char pal; unsigned char palette[4]; + unsigned char modereg; + unsigned char colreg; + int crs_on; unsigned mode; diff -u -r -N pce-0.1.7/src/devices/video/Makefile.in pce-new/src/devices/video/Makefile.in --- pce-0.1.7/src/devices/video/Makefile.in 2005-04-18 10:43:52.000000000 +0100 +++ pce-new/src/devices/video/Makefile.in 2008-10-14 22:55:30.000000000 +0100 @@ -10,7 +10,7 @@ include $(reldir)/config.inc -FILES := cga ega hgc mda vga video +FILES := cga ega hgc mda vga plantronics wy700 video SRC := $(foreach f,$(FILES),$(f).c) OBJ := $(foreach f,$(FILES),$(f).o) @@ -27,6 +27,18 @@ all: $(BIN) $(OBJ) +plantronics.o: plantronics.c plantronics.h video.h devices/memory.h \ + libini/libini.h \ + terminal/terminal.h \ + lib/log.h \ + lib/hexdump.h $(SDP) + +wy700.o: wy700.c wy700.h video.h devices/memory.h \ + libini/libini.h \ + terminal/terminal.h \ + lib/log.h \ + lib/hexdump.h $(SDP) + cga.o: cga.c cga.h video.h devices/memory.h \ libini/libini.h \ terminal/terminal.h \ diff -u -r -N pce-0.1.7/src/devices/video/plantronics.c pce-new/src/devices/video/plantronics.c --- pce-0.1.7/src/devices/video/plantronics.c 1970-01-01 01:00:00.000000000 +0100 +++ pce-new/src/devices/video/plantronics.c 2008-10-14 21:57:33.000000000 +0100 @@ -0,0 +1,1309 @@ +/***************************************************************************** + * pce * + *****************************************************************************/ + +/***************************************************************************** + * File name: src/devices/video/plantronics.c * + * Created: 2003-04-18 by Hampa Hug * + * Last modified: 2008-10-13 by John Elliott * + * Copyright: (C) 2003-2005 Hampa Hug * + * (C) 2008 John Elliott * + *****************************************************************************/ + +/***************************************************************************** + * This program is free software. You can redistribute it and / or modify it * + * under the terms of the GNU General Public License version 2 as published * + * by the Free Software Foundation. * + * * + * This program is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY, without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * + * Public License for more details. * + *****************************************************************************/ + +/* $Id: plantronics.c 619 2005-12-28 21:42:53Z hampa $ */ + + +#include + +#include +#include + +#include "plantronics.h" + + +static +struct { unsigned short r, g, b; } plantronics_col[16] = { + { 0x0000, 0x0000, 0x0000 }, + { 0x0a0a, 0x0a0a, 0xb9b9 }, + { 0x0a0a, 0xc3c3, 0x0a0a }, + { 0x1414, 0xa0a0, 0xa0a0 }, + { 0xa7a7, 0x0a0a, 0x0a0a }, + { 0xa7a7, 0x0000, 0xa7a7 }, + { 0xa5a5, 0xa5a5, 0x2828 }, + { 0xc5c5, 0xc5c5, 0xc5c5 }, + { 0x6464, 0x6464, 0x6464 }, + { 0x0a0a, 0x0a0a, 0xffff }, + { 0x0a0a, 0xffff, 0x0a0a }, + { 0x0a0a, 0xffff, 0xffff }, + { 0xffff, 0x0a0a, 0x0a0a }, + { 0xffff, 0x0a0a, 0xffff }, + { 0xffff, 0xffff, 0x0000 }, + { 0xffff, 0xffff, 0xffff } +}; + + +video_t *plantronics_new (terminal_t *trm, ini_sct_t *sct) +{ + unsigned i; + unsigned long iobase, membase, memsize; + unsigned w, h; + plantronics_t *plantronics; + + plantronics = (plantronics_t *) malloc (sizeof (plantronics_t)); + if (plantronics == NULL) { + return (NULL); + } + + pce_video_init (&plantronics->vid); + + plantronics->vid.ext = plantronics; + plantronics->vid.del = (pce_video_del_f) plantronics_del; + plantronics->vid.get_mem = (pce_video_get_mem_f) plantronics_get_mem; + plantronics->vid.get_reg = (pce_video_get_reg_f) plantronics_get_reg; + plantronics->vid.prt_state = (pce_video_prt_state_f) plantronics_prt_state; + plantronics->vid.update = (pce_video_update_f) plantronics_update; + plantronics->vid.dump = (pce_video_dump_f) plantronics_dump; + plantronics->vid.screenshot = (pce_video_screenshot_f) plantronics_screenshot; + plantronics->vid.clock = (pce_video_clock_f) plantronics_clock; + + for (i = 0; i < 16; i++) { + plantronics->crtc_reg[i] = 0; + } + + w = ini_get_lng_def (sct, "w", 640); + h = ini_get_lng_def (sct, "h", 400); + + plantronics->mode_80x25_w = ini_get_lng_def (sct, "mode_80x25_w", w); + plantronics->mode_80x25_h = ini_get_lng_def (sct, "mode_80x25_h", h); + plantronics->mode_320x200_w = ini_get_lng_def (sct, "mode_320x200_w", w); + plantronics->mode_320x200_h = ini_get_lng_def (sct, "mode_320x200_h", h); + plantronics->mode_640x200_w = ini_get_lng_def (sct, "mode_640x200_w", w); + plantronics->mode_640x200_h = ini_get_lng_def (sct, "mode_640x200_h", h); + iobase = ini_get_lng_def (sct, "io", 0x3d4L); + membase = ini_get_lng_def (sct, "membase", 0xb8000L); + memsize = ini_get_lng_def (sct, "memsize", 32768L); + + if (memsize < 32768) { + memsize = 32768; + } + + pce_log (MSG_INF, "video:\tPlantronics io=0x%04lx membase=0x%05lx memsize=0x%05lx\n", + iobase, membase, memsize + ); + + plantronics->mem = mem_blk_new (membase, memsize, 1); + plantronics->mem->ext = plantronics; + plantronics->mem->set_uint8 = (mem_set_uint8_f) &plantronics_mem_set_uint8; + plantronics->mem->set_uint16 = (mem_set_uint16_f) &plantronics_mem_set_uint16; + mem_blk_clear (plantronics->mem, 0x00); + + plantronics->reg = mem_blk_new (iobase, 16, 1); + plantronics->reg->ext = plantronics; + plantronics->reg->set_uint8 = (mem_set_uint8_f) &plantronics_reg_set_uint8; + plantronics->reg->set_uint16 = (mem_set_uint16_f) &plantronics_reg_set_uint16; + plantronics->reg->get_uint8 = (mem_get_uint8_f) &plantronics_reg_get_uint8; + plantronics->reg->get_uint16 = (mem_get_uint16_f) &plantronics_reg_get_uint16; + mem_blk_clear (plantronics->reg, 0x00); + + plantronics->trm = trm; + + plantronics->crtc_pos = 0; + plantronics->crtc_ofs = 0; + + plantronics->clkcnt = 0; + + plantronics->crs_on = 1; + + plantronics->pal = 0; + plantronics->palette[0] = 0; + plantronics->palette[1] = 11; + plantronics->palette[2] = 13; + plantronics->palette[3] = 15; + plantronics->special = 0; + plantronics->modereg = 0; + plantronics->colreg = 0; + + plantronics->mode = 0; + trm_set_mode (trm, TERM_MODE_TEXT, 80, 25); + trm_set_size (trm, plantronics->mode_80x25_w, plantronics->mode_80x25_h); + + return (&plantronics->vid); +} + +void plantronics_del (plantronics_t *plantronics) +{ + if (plantronics != NULL) { + mem_blk_del (plantronics->mem); + mem_blk_del (plantronics->reg); + free (plantronics); + } +} + +void plantronics_clock (plantronics_t *plantronics, unsigned long cnt) +{ + plantronics->clkcnt += cnt; +} + +void plantronics_prt_state (plantronics_t *plantronics, FILE *fp) +{ + unsigned i; + unsigned x, y; + + if (plantronics->crtc_pos < plantronics->crtc_ofs) { + x = 0; + y = 0; + } + else { + x = (plantronics->crtc_pos - plantronics->crtc_ofs) % 80; + y = (plantronics->crtc_pos - plantronics->crtc_ofs) / 80; + } + + fprintf (fp, "Plantronics: MODE=%u OFS=%04X POS=%04X[%u/%u] CRS=%s BG=%02X PAL=%u\n", + plantronics->mode, plantronics->crtc_ofs, plantronics->crtc_pos, x, y, + (plantronics->crs_on) ? "ON" : "OFF", + plantronics->reg->data[5] & 0x0f, (plantronics->reg->data[5] >> 5) & 1 + ); + + fprintf (fp, "REG: 3D8=%02X 3D9=%02X 3DA=%02X 3DD=%02X PAL=%u:[%02X %02X %02X %02X]\n", + plantronics->reg->data[4], plantronics->reg->data[5], plantronics->reg->data[6], plantronics->reg->data[9], + plantronics->pal, plantronics->palette[0], plantronics->palette[1], plantronics->palette[2], plantronics->palette[3] + ); + + fprintf (fp, "CRTC=[%02X", plantronics->crtc_reg[0]); + for (i = 1; i < 18; i++) { + if ((i & 7) == 0) { + fputs ("-", fp); + } + else { + fputs (" ", fp); + } + fprintf (fp, "%02X", plantronics->crtc_reg[i]); + } + fputs ("]\n", fp); + + fflush (fp); +} + +int plantronics_dump (plantronics_t *plantronics, FILE *fp) +{ + fprintf (fp, "# Plantronics dump\n"); + + fprintf (fp, "\n# REGS:\n"); + pce_dump_hex (fp, + mem_blk_get_data (plantronics->reg), + mem_blk_get_size (plantronics->reg), + mem_blk_get_addr (plantronics->reg), + 16, "# ", 0 + ); + + fprintf (fp, "\n# CRTC:\n"); + pce_dump_hex (fp, plantronics->crtc_reg, 18, 0, 16, "# ", 0); + + fputs ("\n\n# RAM:\n", fp); + pce_dump_hex (fp, + mem_blk_get_data (plantronics->mem), + mem_blk_get_size (plantronics->mem), + mem_blk_get_addr (plantronics->mem), + 16, "", 1 + ); + + return (0); +} + +mem_blk_t *plantronics_get_mem (plantronics_t *plantronics) +{ + return (plantronics->mem); +} + +mem_blk_t *plantronics_get_reg (plantronics_t *plantronics) +{ + return (plantronics->reg); +} + + +/***************************************************************************** + * mode 0 (text 80 * 25) + *****************************************************************************/ + +static +int plantronics_mode0_screenshot (plantronics_t *plantronics, FILE *fp) +{ + unsigned i; + unsigned x, y; + + i = (plantronics->crtc_ofs << 1) & 0x3fff; + + for (y = 0; y < 25; y++) { + for (x = 0; x < 80; x++) { + fputc (plantronics->mem->data[i], fp); + i = (i + 2) & 0x7fff; + } + + fputs ("\n", fp); + } + + return (0); +} + +static +void plantronics_mode0_update (plantronics_t *plantronics) +{ + unsigned i; + unsigned x, y; + unsigned fg, bg; + + i = (plantronics->crtc_ofs << 1) & 0x3fff; + + for (y = 0; y < 25; y++) { + for (x = 0; x < 80; x++) { + fg = plantronics->mem->data[i + 1] & 0x0f; + bg = (plantronics->mem->data[i + 1] & 0xf0) >> 4; + + trm_set_col (plantronics->trm, fg, bg); + trm_set_chr (plantronics->trm, x, y, plantronics->mem->data[i]); + + i = (i + 2) & 0x3fff; + } + } +} + +void plantronics_mode0_set_uint8 (plantronics_t *plantronics, unsigned long addr, unsigned char val) +{ + unsigned x, y; + unsigned char c, a; + + if (plantronics->mem->data[addr] == val) { + return; + } + + plantronics->mem->data[addr] = val; + + if (addr & 1) { + c = plantronics->mem->data[addr - 1]; + a = val; + } + else { + c = val; + a = plantronics->mem->data[addr + 1]; + } + + if (addr < (plantronics->crtc_ofs << 1)) { + return; + } + + addr -= (plantronics->crtc_ofs << 1); + + if (addr >= 4000) { + return; + } + + x = (addr >> 1) % 80; + y = (addr >> 1) / 80; + + trm_set_col (plantronics->trm, a & 0x0f, (a & 0xf0) >> 4); + trm_set_chr (plantronics->trm, x, y, c); +} + +void plantronics_mode0_set_uint16 (plantronics_t *plantronics, unsigned long addr, unsigned short val) +{ + unsigned x, y; + unsigned char c, a; + + if (addr & 1) { + plantronics_mem_set_uint8 (plantronics, addr, val & 0xff); + plantronics_mem_set_uint8 (plantronics, addr + 1, (val >> 8) & 0xff); + return; + } + + c = val & 0xff; + a = (val >> 8) & 0xff; + + if ((plantronics->mem->data[addr] == c) && (plantronics->mem->data[addr + 1] == a)) { + return; + } + + plantronics->mem->data[addr] = c; + plantronics->mem->data[addr + 1] = a; + + if (addr < (plantronics->crtc_ofs << 1)) { + return; + } + + addr -= (plantronics->crtc_ofs << 1); + + if (addr >= 4000) { + return; + } + + x = (addr >> 1) % 80; + y = (addr >> 1) / 80; + + trm_set_col (plantronics->trm, a & 0x0f, (a & 0xf0) >> 4); + trm_set_chr (plantronics->trm, x, y, c); +} + + +/***************************************************************************** + * mode 1 (graphics 320 * 200 * 4) + *****************************************************************************/ + +static +int plantronics_mode1_screenshot (plantronics_t *plantronics, FILE *fp) +{ + unsigned x, y, i; + unsigned val, idx; + unsigned char *mem; + + fputs ("P6\n320 200\n255 ", fp); + + for (y = 0; y < 200; y++) { + mem = plantronics->mem->data + 80 * (y / 2); + + if (y & 1) { + mem += 8192; + } + + for (x = 0; x < 80; x++) { + val = mem[x]; + + for (i = 0; i < 4; i++) { + idx = (val >> 6) & 0x03; + idx = plantronics->palette[idx]; + fputc (plantronics_col[idx].r >> 8, fp); + fputc (plantronics_col[idx].g >> 8, fp); + fputc (plantronics_col[idx].b >> 8, fp); + + val <<= 2; + } + } + } + + return (0); +} + +static +void plantronics_mode1_update (plantronics_t *plantronics) +{ + unsigned x, y, i; + unsigned val0, val1; + unsigned char *mem0, *mem1; + + mem0 = plantronics->mem->data; + mem1 = plantronics->mem->data + 8192; + + for (y = 0; y < 100; y++) { + for (x = 0; x < 80; x++) { + val0 = mem0[x]; + val1 = mem1[x]; + + for (i = 0; i < 4; i++) { + trm_set_col (plantronics->trm, plantronics->palette[(val0 >> 6) & 0x03], 0); + trm_set_pxl (plantronics->trm, 4 * x + i, 2 * y); + + trm_set_col (plantronics->trm, plantronics->palette[(val1 >> 6) & 0x03], 0); + trm_set_pxl (plantronics->trm, 4 * x + i, 2 * y + 1); + + val0 <<= 2; + val1 <<= 2; + } + } + + mem0 += 80; + mem1 += 80; + } +} + +void plantronics_mode1_set_uint8 (plantronics_t *plantronics, unsigned long addr, unsigned char val) +{ + unsigned i; + unsigned x, y; + unsigned char old; + + old = plantronics->mem->data[addr]; + + if (old == val) { + return; + } + + plantronics->mem->data[addr] = val; + + if (addr < 8192) { + x = 4 * (addr % 80); + y = 2 * (addr / 80); + } + else { + x = 4 * ((addr - 8192) % 80); + y = 2 * ((addr - 8192) / 80) + 1; + } + + if (y >= 200) { + return; + } + + for (i = 0; i < 4; i++) { + unsigned col; + + if ((old ^ val) & 0xc0) { + col = (val >> 6) & 0x03; + trm_set_col (plantronics->trm, plantronics->palette[col], 0); + + trm_set_pxl (plantronics->trm, x + i, y); + } + + old <<= 2; + val <<= 2; + } +} + + +/***************************************************************************** + * mode 2 (graphics 620 * 200 * 2) + *****************************************************************************/ + +static +int plantronics_mode2_screenshot (plantronics_t *plantronics, FILE *fp) +{ + unsigned x, y, i; + unsigned val, col; + unsigned char *mem; + + fputs ("P6\n640 200\n255 ", fp); + + col = plantronics->palette[0]; + for (y = 0; y < 200; y++) { + mem = plantronics->mem->data + 80 * (y / 2); + + if (y & 1) { + mem += 8192; + } + + for (x = 0; x < 80; x++) { + val = mem[x]; + + for (i = 0; i < 8; i++) { + if (val & (0x80 >> i)) { + fputc (plantronics_col[col].r >> 8, fp); + fputc (plantronics_col[col].g >> 8, fp); + fputc (plantronics_col[col].b >> 8, fp); + } + else { + fputc (0x00, fp); + fputc (0x00, fp); + fputc (0x00, fp); + } + } + } + } + + return (0); +} + +static +void plantronics_mode2_update (plantronics_t *plantronics) +{ + unsigned x, y, i; + unsigned val0, val1; + unsigned char *mem0, *mem1; + + mem0 = plantronics->mem->data; + mem1 = plantronics->mem->data + 8192; + + for (y = 0; y < 100; y++) { + for (x = 0; x < 80; x++) { + val0 = mem0[x]; + val1 = mem1[x]; + + for (i = 0; i < 8; i++) { + trm_set_col (plantronics->trm, (val0 & 0x80) ? plantronics->palette[0] : 0, 0); + trm_set_pxl (plantronics->trm, 8 * x + i, 2 * y); + + trm_set_col (plantronics->trm, (val1 & 0x80) ? plantronics->palette[0] : 0, 0); + trm_set_pxl (plantronics->trm, 8 * x + i, 2 * y + 1); + + val0 <<= 1; + val1 <<= 1; + } + } + + mem0 += 80; + mem1 += 80; + } +} + +void plantronics_mode2_set_uint8 (plantronics_t *plantronics, unsigned long addr, unsigned char val) +{ + unsigned i; + unsigned x, y; + unsigned char old; + + old = plantronics->mem->data[addr]; + + if (old == val) { + return; + } + + plantronics->mem->data[addr] = val; + + if (addr < 8192) { + x = 8 * (addr % 80); + y = 2 * (addr / 80); + } + else { + x = 8 * ((addr - 8192) % 80); + y = 2 * ((addr - 8192) / 80) + 1; + } + + for (i = 0; i < 8; i++) { + unsigned col; + + if ((old ^ val) & 0x80) { + col = (val >> 7) & 0x01; + trm_set_col (plantronics->trm, col ? plantronics->palette[0] : 0, 0); + trm_set_pxl (plantronics->trm, x + i, y); + } + + old <<= 1; + val <<= 1; + } +} + + + +/***************************************************************************** + * mode 3 (graphics 320 * 200 * 16) + *****************************************************************************/ + +static +int plantronics_mode3_screenshot (plantronics_t *plantronics, FILE *fp) +{ + unsigned x, y, i; + unsigned val0, val1, idx; + unsigned char *mem0, *mem1, *plane0, *plane1; + + fputs ("P6\n320 200\n255 ", fp); + + if (plantronics->special & 0x40) { + plane0 = plantronics->mem->data; + plane1 = plantronics->mem->data + 0x4000; + } else { + plane0 = plantronics->mem->data + 0x4000; + plane1 = plantronics->mem->data; + } + + for (y = 0; y < 200; y++) { + mem0 = plane0 + 80 * (y / 2); + mem1 = plane1 + 80 * (y / 2); + + if (y & 1) { + mem0 += 8192; + mem1 += 8192; + } + + for (x = 0; x < 80; x++) { + val0 = mem0[x]; + val1 = mem1[x]; + + for (i = 0; i < 4; i++) { + idx = (( val0 >> 6) & 3) | + (((val1 >> 6) & 3) << 2); + fputc (plantronics_col[idx].r >> 8, fp); + fputc (plantronics_col[idx].g >> 8, fp); + fputc (plantronics_col[idx].b >> 8, fp); + + val0 <<= 2; + val1 <<= 2; + } + } + } + + return (0); +} + +static +void plantronics_mode3_update (plantronics_t *plantronics) +{ + unsigned x, y, i, col; + unsigned val0, val1, val2, val3; + unsigned char *mem0, *mem1, *mem2, *mem3, *plane0, *plane1; + + if (plantronics->special & 0x40) { + plane0 = plantronics->mem->data; + plane1 = plantronics->mem->data + 0x4000; + } else { + plane0 = plantronics->mem->data + 0x4000; + plane1 = plantronics->mem->data; + } + + mem0 = plane0; + mem1 = plane0 + 8192; + mem2 = plane1; + mem3 = plane1 + 8192; + + for (y = 0; y < 100; y++) { + for (x = 0; x < 80; x++) { + val0 = mem0[x]; + val1 = mem1[x]; + val2 = mem2[x]; + val3 = mem3[x]; + + for (i = 0; i < 4; i++) { + col = ((val0 >> 6) & 3) | ((val2 >> 4) & 0x0c); + trm_set_col (plantronics->trm, col, 0); + trm_set_pxl (plantronics->trm, 4 * x + i, 2 * y); + + col = ((val1 >> 6) & 3) | ((val3 >> 4) & 0x0c); + trm_set_col (plantronics->trm, col, 0); + trm_set_pxl (plantronics->trm, 4 * x + i, 2 * y + 1); + + val0 <<= 2; + val1 <<= 2; + val2 <<= 2; + val3 <<= 2; + } + } + + mem0 += 80; + mem1 += 80; + mem2 += 80; + mem3 += 80; + } +} + +void plantronics_mode3_set_uint8 (plantronics_t *plantronics, unsigned long addr, unsigned char val) +{ + unsigned i; + unsigned x, y; + unsigned char old, *plane0, *plane1, val0, val1; + unsigned offset; + + old = plantronics->mem->data[addr]; + + if (old == val) { + return; + } + + plantronics->mem->data[addr] = val; + + offset = addr & 0x3FFF; + if (offset < 8192) { + x = 4 * (offset % 80); + y = 2 * (offset / 80); + } + else { + x = 4 * ((offset - 8192) % 80); + y = 2 * ((offset - 8192) / 80) + 1; + } + if (plantronics->special & 0x40) { + plane0 = plantronics->mem->data; + plane1 = plantronics->mem->data + 0x4000; + } else { + plane0 = plantronics->mem->data + 0x4000; + plane1 = plantronics->mem->data; + } + + val0 = plane0[offset]; + val1 = plane1[offset]; + for (i = 0; i < 4; i++) { + unsigned col; + + col = ((val0 >> 6) & 3) | ((val1 >> 4) & 0x0c); + if ((old ^ val) & 0xC0) { + trm_set_col (plantronics->trm, col, 0); + trm_set_pxl (plantronics->trm, x + i, y); + } + + old <<= 2; + val <<= 2; + val0 <<= 2; + val1 <<= 2; + } +} + + +/***************************************************************************** + * mode 4 (graphics 620 * 200 * 4) + *****************************************************************************/ + +static +int plantronics_mode4_screenshot (plantronics_t *plantronics, FILE *fp) +{ + unsigned x, y, i; + unsigned val0, val1, idx; + unsigned char *mem0, *mem1, *plane0, *plane1; + + fputs ("P6\n640 200\n255 ", fp); + + if (plantronics->special & 0x40) { + plane0 = plantronics->mem->data; + plane1 = plantronics->mem->data + 0x4000; + } else { + plane0 = plantronics->mem->data + 0x4000; + plane1 = plantronics->mem->data; + } + + for (y = 0; y < 200; y++) { + mem0 = plane0 + 80 * (y / 2); + mem1 = plane1 + 80 * (y / 2); + + if (y & 1) { + mem0 += 8192; + mem1 += 8192; + } + + for (x = 0; x < 80; x++) { + val0 = mem0[x]; + val1 = mem1[x]; + + for (i = 0; i < 8; i++) { + idx = (( val0 >> 7) & 1) | + (((val1 >> 7) & 1) << 1); + idx = plantronics->palette[idx]; + fputc (plantronics_col[idx].r >> 8, fp); + fputc (plantronics_col[idx].g >> 8, fp); + fputc (plantronics_col[idx].b >> 8, fp); + + val0 <<= 1; + val1 <<= 1; + } + } + } + + return (0); +} + +static +void plantronics_mode4_update (plantronics_t *plantronics) +{ + unsigned x, y, i, col; + unsigned val0, val1, val2, val3; + unsigned char *mem0, *mem1, *mem2, *mem3, *plane0, *plane1; + + if (plantronics->special & 0x40) { + plane0 = plantronics->mem->data; + plane1 = plantronics->mem->data + 0x4000; + } else { + plane0 = plantronics->mem->data + 0x4000; + plane1 = plantronics->mem->data; + } + + mem0 = plane0; + mem1 = plane0 + 8192; + mem2 = plane1; + mem3 = plane1 + 8192; + + for (y = 0; y < 100; y++) { + for (x = 0; x < 80; x++) { + val0 = mem0[x]; + val1 = mem1[x]; + val2 = mem2[x]; + val3 = mem3[x]; + + for (i = 0; i < 8; i++) { + col = ((val0 >> 7) & 1) | ((val2 >> 6) & 2); + trm_set_col (plantronics->trm, plantronics->palette[col], 0); + trm_set_pxl (plantronics->trm, 8 * x + i, 2 * y); + + col = ((val1 >> 7) & 1) | ((val3 >> 6) & 2); + trm_set_col (plantronics->trm, plantronics->palette[col], 0); + trm_set_pxl (plantronics->trm, 8 * x + i, 2 * y + 1); + + val0 <<= 1; + val1 <<= 1; + val2 <<= 1; + val3 <<= 1; + } + } + + mem0 += 80; + mem1 += 80; + mem2 += 80; + mem3 += 80; + } +} + +void plantronics_mode4_set_uint8 (plantronics_t *plantronics, unsigned long addr, unsigned char val) +{ + unsigned i; + unsigned x, y; + unsigned char old, *plane0, *plane1, val0, val1; + unsigned offset; + + old = plantronics->mem->data[addr]; + + if (old == val) { + return; + } + + plantronics->mem->data[addr] = val; + + offset = addr & 0x3FFF; + if (offset < 8192) { + x = 8 * (offset % 80); + y = 2 * (offset / 80); + } + else { + x = 8 * ((offset - 8192) % 80); + y = 2 * ((offset - 8192) / 80) + 1; + } + if (plantronics->special & 0x40) { + plane0 = plantronics->mem->data; + plane1 = plantronics->mem->data + 0x4000; + } else { + plane0 = plantronics->mem->data + 0x4000; + plane1 = plantronics->mem->data; + } + + val0 = plane0[offset]; + val1 = plane1[offset]; + for (i = 0; i < 8; i++) { + unsigned col; + + col = ((val0 >> 7) & 1) | ((val1 >> 6) & 2); + if ((old ^ val) & 0x80) { + trm_set_col (plantronics->trm, plantronics->palette[col], 0); + trm_set_pxl (plantronics->trm, x + i, y); + } + + old <<= 1; + val <<= 1; + val0 <<= 1; + val1 <<= 1; + } +} + + +int plantronics_screenshot (plantronics_t *plantronics, FILE *fp, unsigned mode) +{ + if ((plantronics->mode == 0) && ((mode == 1) || (mode == 0))) { + return (plantronics_mode0_screenshot (plantronics, fp)); + } + else if ((plantronics->mode == 1) && ((mode == 2) || (mode == 0))) { + return (plantronics_mode1_screenshot (plantronics, fp)); + } + else if ((plantronics->mode == 2) && ((mode == 2) || (mode == 0))) { + return (plantronics_mode2_screenshot (plantronics, fp)); + } + else if ((plantronics->mode == 3) && ((mode == 2) || (mode == 0))) { + return (plantronics_mode3_screenshot (plantronics, fp)); + } + else if ((plantronics->mode == 4) && ((mode == 2) || (mode == 0))) { + return (plantronics_mode4_screenshot (plantronics, fp)); + } + + return (1); +} + + + +void plantronics_update (plantronics_t *plantronics) +{ + switch (plantronics->mode) { + case 0: + plantronics_mode0_update (plantronics); + break; + + case 1: + plantronics_mode1_update (plantronics); + break; + + case 2: + plantronics_mode2_update (plantronics); + break; + + case 3: + plantronics_mode3_update (plantronics); + break; + + case 4: + plantronics_mode4_update (plantronics); + break; + } +} + +void plantronics_set_pos (plantronics_t *plantronics, unsigned pos) +{ + plantronics->crtc_pos = pos; + + if (plantronics->mode == 0) { + if (pos < plantronics->crtc_ofs) { + return; + } + + pos -= plantronics->crtc_ofs; + + if (pos >= 2000) { + return; + } + + trm_set_pos (plantronics->trm, pos % 80, pos / 80); + } +} + +void plantronics_set_crs (plantronics_t *plantronics, unsigned y1, unsigned y2) +{ + if (plantronics->mode == 0) { + if (y1 > 7) { + trm_set_crs (plantronics->trm, 0, 0, 0); + return; + } + + if ((y2 < y1) || (y2 > 7)) { + y2 = 7; + } + + y1 = (y1 << 5) | (y1 << 2) | (y1 >> 1); + y2 = (y2 << 5) | (y2 << 2) | (y2 >> 1); + + trm_set_crs (plantronics->trm, y1, y2, 1); + } +} + +void plantronics_set_page_ofs (plantronics_t *plantronics, unsigned ofs) +{ + if (plantronics->crtc_ofs == ofs) { + return; + } + + plantronics->crtc_ofs = ofs; + + if (plantronics->mode == 0) { + plantronics_update (plantronics); + } +} + +void plantronics_set_palette (plantronics_t *plantronics) +{ + unsigned pal, bg; + + pal = ((plantronics->colreg >> 4) & 3) | (plantronics->modereg & 4); + bg = plantronics->colreg & 0x0F; + + if (pal == plantronics->pal && bg == plantronics->palette[0]) { + return; + } + + plantronics->pal = pal; + + switch (pal) { + case 0: + plantronics->palette[0] = bg; + plantronics->palette[1] = 3; + plantronics->palette[2] = 5; + plantronics->palette[3] = 7; + break; + + case 1: + plantronics->palette[0] = bg; + plantronics->palette[1] = 11; + plantronics->palette[2] = 13; + plantronics->palette[3] = 15; + break; + + case 2: + plantronics->palette[0] = bg; + plantronics->palette[1] = 2; + plantronics->palette[2] = 4; + plantronics->palette[3] = 6; + break; + + case 3: + plantronics->palette[0] = bg; + plantronics->palette[1] = 10; + plantronics->palette[2] = 12; + plantronics->palette[3] = 14; + break; + + case 4: + case 6: + plantronics->palette[0] = bg; + plantronics->palette[1] = 3; + plantronics->palette[2] = 4; + plantronics->palette[3] = 7; + break; + + case 5: + case 7: + plantronics->palette[0] = bg; + plantronics->palette[1] = 11; + plantronics->palette[2] = 12; + plantronics->palette[3] = 15; + break; + } + + plantronics_update (plantronics); +} + + + +void plantronics_set_mode (plantronics_t *plantronics) +{ + unsigned newmode, mode; + + mode = plantronics->modereg; + + if ((mode & 0x02) == 0) { + newmode = 0; + } + else if ((mode & 0x10) == 0) { + newmode = 1; + } + else { + newmode = 2; + } + if (newmode != 0 && (plantronics->special & 0x30)) { + if (plantronics->special & 0x10) { + newmode = 3; + } + else { + newmode = 4; + } + } + + if (newmode == plantronics->mode) { + return; + } + + plantronics->mode = newmode; + + switch (newmode) { + case 0: + trm_set_mode (plantronics->trm, TERM_MODE_TEXT, 80, 25); + trm_set_size (plantronics->trm, plantronics->mode_80x25_w, plantronics->mode_80x25_h); + break; + + case 1: + case 3: + trm_set_mode (plantronics->trm, TERM_MODE_GRAPH, 320, 200); + trm_set_size (plantronics->trm, plantronics->mode_320x200_w, plantronics->mode_320x200_h); + break; + + case 2: + case 4: + trm_set_mode (plantronics->trm, TERM_MODE_GRAPH, 640, 200); + trm_set_size (plantronics->trm, plantronics->mode_640x200_w, plantronics->mode_640x200_h); + break; + } + + plantronics_update (plantronics); +} + + + +void plantronics_set_special (plantronics_t *plantronics, unsigned char spl) +{ + if (plantronics->special == spl) { + return; + } +/* Depending on what bits change, this may force a mode change */ + if ((plantronics->special ^ spl) & 0x30) { + plantronics->special = spl; + plantronics_set_mode(plantronics); + } +/* Or a screen repaint */ + else if ((plantronics->special ^ spl) & 0x40) { + plantronics->special = spl; + plantronics_update(plantronics); + } +/* Or nothing */ + else { + plantronics->special = spl; + } +} + + + + +void plantronics_mem_set_uint8 (plantronics_t *plantronics, unsigned long addr, unsigned char val) +{ + switch (plantronics->mode) { + case 0: + plantronics_mode0_set_uint8 (plantronics, addr, val); + break; + + case 1: + plantronics_mode1_set_uint8 (plantronics, addr, val); + break; + + case 2: + plantronics_mode2_set_uint8 (plantronics, addr, val); + break; + + case 3: + plantronics_mode3_set_uint8 (plantronics, addr, val); + break; + + case 4: + plantronics_mode4_set_uint8 (plantronics, addr, val); + break; + } +} + +void plantronics_mem_set_uint16 (plantronics_t *plantronics, unsigned long addr, unsigned short val) +{ + switch (plantronics->mode) { + case 0: + plantronics_mode0_set_uint16 (plantronics, addr, val); + break; + + case 1: + plantronics_mode1_set_uint8 (plantronics, addr, val); + plantronics_mode1_set_uint8 (plantronics, addr + 1, val >> 8); + break; + + case 2: + plantronics_mode2_set_uint8 (plantronics, addr, val); + plantronics_mode2_set_uint8 (plantronics, addr + 1, val >> 8); + break; + + case 3: + plantronics_mode3_set_uint8 (plantronics, addr, val); + plantronics_mode3_set_uint8 (plantronics, addr + 1, val >> 8); + break; + + case 4: + plantronics_mode4_set_uint8 (plantronics, addr, val); + plantronics_mode4_set_uint8 (plantronics, addr + 1, val >> 8); + break; + } +} + +void plantronics_crtc_set_reg (plantronics_t *plantronics, unsigned reg, unsigned char val) +{ + if (reg > 17) { + return; + } + + plantronics->crtc_reg[reg] = val; + + switch (reg) { + case 0x0a: + case 0x0b: + plantronics_set_crs (plantronics, plantronics->crtc_reg[0x0a], plantronics->crtc_reg[0x0b]); + break; + + case 0x0c: + plantronics_set_page_ofs (plantronics, (plantronics->crtc_reg[0x0c] << 8) | val); + break; + + case 0x0d: + plantronics_set_page_ofs (plantronics, (plantronics->crtc_reg[0x0c] << 8) | val); + break; + + case 0x0e: +/* plantronics_set_pos (plantronics, (val << 8) | (plantronics->crtc_reg[0x0f] & 0xff)); */ + break; + + case 0x0f: + plantronics_set_pos (plantronics, (plantronics->crtc_reg[0x0e] << 8) | val); + break; + } +} + +unsigned char plantronics_crtc_get_reg (plantronics_t *plantronics, unsigned reg) +{ + if (reg > 15) { + return (0xff); + } + + return (plantronics->crtc_reg[reg]); +} + +void plantronics_reg_set_uint8 (plantronics_t *plantronics, unsigned long addr, unsigned char val) +{ + plantronics->reg->data[addr] = val; + + switch (addr) { + case 0x01: + plantronics_crtc_set_reg (plantronics, plantronics->reg->data[0], val); + break; + + case 0x04: + plantronics->modereg = val; + plantronics_set_mode (plantronics); +/* Mode register can affect palette */ + plantronics_set_palette (plantronics); + break; + + case 0x05: + plantronics->colreg = val; + plantronics_set_palette (plantronics); + break; + + case 0x09: + plantronics_set_special (plantronics, val); + break; + } +} + +void plantronics_reg_set_uint16 (plantronics_t *plantronics, unsigned long addr, unsigned short val) +{ + plantronics_reg_set_uint8 (plantronics, addr, val & 0xff); + + if ((addr + 1) < plantronics->reg->size) { + plantronics_reg_set_uint8 (plantronics, addr + 1, val >> 8); + } +} + +unsigned char plantronics_reg_get_uint8 (plantronics_t *plantronics, unsigned long addr) +{ + switch (addr) { + case 0x00: + return (plantronics->reg->data[0]); + + case 0x01: + return (plantronics_crtc_get_reg (plantronics, plantronics->reg->data[0])); + + case 0x06: + /* p freq: 14.31818 MHz + h freq: 15.750 KHz + v freq: 60 Hz + 912 / 14.31818e6 * 1e6 = 63.6952 + 640 / 14.31818e6 * 1e6 = 44.6984 + 262 / 15.75e3 * 1e6 = 16634.9206 + 200 / 15.75e3 * 1e6 = 12698.4127 + */ + if ((plantronics->clkcnt % 16635) < 12699) { + plantronics->reg->data[6] &= ~0x08; + + if ((plantronics->clkcnt % 64) < 45) { + plantronics->reg->data[6] |= 0x01; + } + else { + plantronics->reg->data[6] &= ~0x01; + } + } + else { + plantronics->reg->data[6] |= 0x08; + plantronics->reg->data[6] |= 0x01; + } + + return (plantronics->reg->data[6]); + + default: + return (0xff); + } +} + +unsigned short plantronics_reg_get_uint16 (plantronics_t *plantronics, unsigned long addr) +{ + unsigned short ret; + + ret = plantronics_reg_get_uint8 (plantronics, addr); + + if ((addr + 1) < plantronics->reg->size) { + ret |= plantronics_reg_get_uint8 (plantronics, addr + 1) << 8; + } + + return (ret); +} diff -u -r -N pce-0.1.7/src/devices/video/plantronics.h pce-new/src/devices/video/plantronics.h --- pce-0.1.7/src/devices/video/plantronics.h 1970-01-01 01:00:00.000000000 +0100 +++ pce-new/src/devices/video/plantronics.h 2008-10-14 21:06:47.000000000 +0100 @@ -0,0 +1,99 @@ +/***************************************************************************** + * pce * + *****************************************************************************/ + +/***************************************************************************** + * File name: src/devices/video/platronics.h * + * Created: 2003-04-18 by Hampa Hug * + * Last modified: 2008-10-12 by John Elliott * + * Copyright: (C) 2003-2005 Hampa Hug * + * (C) 2008 John Elliott * + *****************************************************************************/ + +/***************************************************************************** + * This program is free software. You can redistribute it and / or modify it * + * under the terms of the GNU General Public License version 2 as published * + * by the Free Software Foundation. * + * * + * This program is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY, without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * + * Public License for more details. * + *****************************************************************************/ + +/* $Id: plantronics.h 619 2005-12-28 21:42:53Z hampa $ */ + + +#ifndef PCE_PLANTRONICS_H +#define PCE_PLANTRONICS_H 1 + + +#include +#include +#include + + +typedef struct { + video_t vid; + + mem_blk_t *mem; + mem_blk_t *reg; + + unsigned mode_80x25_w; + unsigned mode_80x25_h; + unsigned mode_320x200_w; + unsigned mode_320x200_h; + unsigned mode_640x200_w; + unsigned mode_640x200_h; + + unsigned char crtc_reg[18]; + + unsigned crtc_pos; + unsigned crtc_ofs; + + unsigned long clkcnt; + + unsigned char pal; + unsigned char palette[4]; + + unsigned char modereg; + unsigned char colreg; + unsigned char special; + + int crs_on; + + unsigned mode; + + terminal_t *trm; +} plantronics_t; + + +video_t *plantronics_new (terminal_t *trm, ini_sct_t *sct); + +void plantronics_del (plantronics_t *plantronics); + +void plantronics_clock (plantronics_t *plantronics, unsigned long cnt); + +void plantronics_prt_state (plantronics_t *plantronics, FILE *fp); + +int plantronics_dump (plantronics_t *plantronics, FILE *fp); + +mem_blk_t *plantronics_get_mem (plantronics_t *plantronics); +mem_blk_t *plantronics_get_reg (plantronics_t *plantronics); + +int plantronics_screenshot (plantronics_t *plantronics, FILE *fp, unsigned mode); + +void plantronics_update (plantronics_t *plantronics); + +void plantronics_set_pos (plantronics_t *plantronics, unsigned pos); + +void plantronics_mem_set_uint8 (plantronics_t *plantronics, unsigned long addr, unsigned char val); +void plantronics_mem_set_uint16 (plantronics_t *plantronics, unsigned long addr, unsigned short val); + +void plantronics_reg_set_uint8 (plantronics_t *plantronics, unsigned long addr, unsigned char val); +void plantronics_reg_set_uint16 (plantronics_t *plantronics, unsigned long addr, unsigned short val); +unsigned char plantronics_reg_get_uint8 (plantronics_t *plantronics, unsigned long addr); +unsigned short plantronics_reg_get_uint16 (plantronics_t *plantronics, unsigned long addr); + + +#endif diff -u -r -N pce-0.1.7/src/devices/video/video.h pce-new/src/devices/video/video.h --- pce-0.1.7/src/devices/video/video.h 2005-12-28 21:42:53.000000000 +0000 +++ pce-new/src/devices/video/video.h 2008-10-14 21:48:38.000000000 +0100 @@ -6,7 +6,9 @@ * File name: src/devices/video.h * * Created: 2003-08-30 by Hampa Hug * * Last modified: 2004-08-01 by Hampa Hug * + * Last modified: 2008-10-13 by John Elliott * * Copyright: (C) 2003-2004 Hampa Hug * + * (C) 2008 John Elliott * *****************************************************************************/ /***************************************************************************** @@ -37,6 +39,7 @@ #define PCE_VIDEO_CGA 2 #define PCE_VIDEO_HGC 3 #define PCE_VIDEO_EGA 4 +#define PCE_VIDEO_PLANTRONICS 5 typedef void (*pce_video_del_f) (void *ext); diff -u -r -N pce-0.1.7/src/devices/video/wy700.c pce-new/src/devices/video/wy700.c --- pce-0.1.7/src/devices/video/wy700.c 1970-01-01 01:00:00.000000000 +0100 +++ pce-new/src/devices/video/wy700.c 2008-10-15 19:12:44.000000000 +0100 @@ -0,0 +1,1118 @@ +/***************************************************************************** + * pce * + *****************************************************************************/ + +/***************************************************************************** + * File name: src/devices/video/wy700.c * + * Created: 2003-04-18 by Hampa Hug * + * Last modified: 2008-10-13 by John Elliott * + * Copyright: (C) 2003-2005 Hampa Hug * + * (C) 2008 John Elliott * + *****************************************************************************/ + +/***************************************************************************** + * This program is free software. You can redistribute it and / or modify it * + * under the terms of the GNU General Public License version 2 as published * + * by the Free Software Foundation. * + * * + * This program is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY, without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * + * Public License for more details. * + *****************************************************************************/ + +/* $Id: wy700.c 619 2005-12-28 21:42:53Z hampa $ */ + + +#include + +#include +#include + +#include "wy700.h" + + +static +struct { unsigned short r, g, b; } wy700_col[16] = { + { 0x0000, 0x0000, 0x0000 }, + { 0x0a0a, 0x0a0a, 0xb9b9 }, + { 0x0a0a, 0xc3c3, 0x0a0a }, + { 0x1414, 0xa0a0, 0xa0a0 }, + { 0xa7a7, 0x0a0a, 0x0a0a }, + { 0xa7a7, 0x0000, 0xa7a7 }, + { 0xa5a5, 0xa5a5, 0x2828 }, + { 0xc5c5, 0xc5c5, 0xc5c5 }, + { 0x6464, 0x6464, 0x6464 }, + { 0x0a0a, 0x0a0a, 0xffff }, + { 0x0a0a, 0xffff, 0x0a0a }, + { 0x0a0a, 0xffff, 0xffff }, + { 0xffff, 0x0a0a, 0x0a0a }, + { 0xffff, 0x0a0a, 0xffff }, + { 0xffff, 0xffff, 0x0000 }, + { 0xffff, 0xffff, 0xffff } +}; + + +video_t *wy700_new (terminal_t *trm, ini_sct_t *sct) +{ + unsigned i; + unsigned long iobase, membase, memsize; + unsigned w, h; + wy700_t *wy700; + + wy700 = (wy700_t *) malloc (sizeof (wy700_t)); + if (wy700 == NULL) { + return (NULL); + } + + pce_video_init (&wy700->vid); + + wy700->vid.ext = wy700; + wy700->vid.del = (pce_video_del_f) wy700_del; + wy700->vid.get_mem = (pce_video_get_mem_f) wy700_get_mem; + wy700->vid.get_reg = (pce_video_get_reg_f) wy700_get_reg; + wy700->vid.prt_state = (pce_video_prt_state_f) wy700_prt_state; + wy700->vid.update = (pce_video_update_f) wy700_update; + wy700->vid.dump = (pce_video_dump_f) wy700_dump; + wy700->vid.screenshot = (pce_video_screenshot_f) wy700_screenshot; + wy700->vid.clock = (pce_video_clock_f) wy700_clock; + + for (i = 0; i < 16; i++) { + wy700->crtc_reg[i] = 0; + } + + w = ini_get_lng_def (sct, "w", 1280); + h = ini_get_lng_def (sct, "h", 800); + + wy700->mode_80x25_w = ini_get_lng_def (sct, "mode_80x25_w", w); + wy700->mode_80x25_h = ini_get_lng_def (sct, "mode_80x25_h", h); + wy700->mode_320x200_w = ini_get_lng_def (sct, "mode_320x200_w", w); + wy700->mode_320x200_h = ini_get_lng_def (sct, "mode_320x200_h", h); + wy700->mode_640x200_w = ini_get_lng_def (sct, "mode_640x200_w", w); + wy700->mode_640x200_h = ini_get_lng_def (sct, "mode_640x200_h", h); + wy700->mode_1280x800_w = ini_get_lng_def (sct, "mode_1280x800_w", w); + wy700->mode_1280x800_h = ini_get_lng_def (sct, "mode_1280x800_h", h); + + iobase = ini_get_lng_def (sct, "io", 0x3d4L); + membase = ini_get_lng_def (sct, "membase", 0xa0000L); + memsize = ini_get_lng_def (sct, "memsize", 131072L); + + if (memsize < 131072) { + memsize = 131072; + } + + pce_log (MSG_INF, "video:\tWY700 io=0x%04lx membase=0x%05lx memsize=0x%05lx\n", + iobase, membase, memsize + ); + + wy700->mem = mem_blk_new (membase, memsize, 1); + wy700->mem->ext = wy700; + wy700->mem->set_uint8 = (mem_set_uint8_f) &wy700_mem_set_uint8; + wy700->mem->set_uint16 = (mem_set_uint16_f) &wy700_mem_set_uint16; + wy700->mem->get_uint8 = (mem_get_uint8_f) &wy700_mem_get_uint8; + wy700->mem->get_uint16 = (mem_get_uint16_f) &wy700_mem_get_uint16; + mem_blk_clear (wy700->mem, 0x00); + + wy700->reg = mem_blk_new (iobase, 16, 1); + wy700->reg->ext = wy700; + wy700->reg->set_uint8 = (mem_set_uint8_f) &wy700_reg_set_uint8; + wy700->reg->set_uint16 = (mem_set_uint16_f) &wy700_reg_set_uint16; + wy700->reg->get_uint8 = (mem_get_uint8_f) &wy700_reg_get_uint8; + wy700->reg->get_uint16 = (mem_get_uint16_f) &wy700_reg_get_uint16; + mem_blk_clear (wy700->reg, 0x00); + + wy700->trm = trm; + + wy700->crtc_pos = 0; + wy700->crtc_ofs = 0; + + wy700->clkcnt = 0; + + wy700->crs_on = 1; + + wy700->pal = 0; + wy700->palette[0] = 0; + wy700->palette[1] = 11; + wy700->palette[2] = 13; + wy700->palette[3] = 15; + wy700->modereg = 0; + wy700->colreg = 0; + wy700->control = 0; + + wy700->mode = 0; + trm_set_mode (trm, TERM_MODE_TEXT, 80, 25); + trm_set_size (trm, wy700->mode_80x25_w, wy700->mode_80x25_h); + + return (&wy700->vid); +} + +void wy700_del (wy700_t *wy700) +{ + if (wy700 != NULL) { + mem_blk_del (wy700->mem); + mem_blk_del (wy700->reg); + free (wy700); + } +} + +void wy700_clock (wy700_t *wy700, unsigned long cnt) +{ + wy700->clkcnt += cnt; +} + +void wy700_prt_state (wy700_t *wy700, FILE *fp) +{ + unsigned i; + unsigned x, y; + + if (wy700->crtc_pos < wy700->crtc_ofs) { + x = 0; + y = 0; + } + else { + x = (wy700->crtc_pos - wy700->crtc_ofs) % 80; + y = (wy700->crtc_pos - wy700->crtc_ofs) / 80; + } + + fprintf (fp, "WY700: MODE=%u OFS=%04X POS=%04X[%u/%u] CRS=%s BG=%02X PAL=%u\n", + wy700->mode, wy700->crtc_ofs, wy700->crtc_pos, x, y, + (wy700->crs_on) ? "ON" : "OFF", + wy700->reg->data[5] & 0x0f, (wy700->reg->data[5] >> 5) & 1 + ); + + fprintf (fp, "REG: 3D8=%02X 3D9=%02X 3DA=%02X PAL=%u:[%02X %02X %02X %02X]\n", + wy700->reg->data[4], wy700->reg->data[5], wy700->reg->data[6], + wy700->pal, wy700->palette[0], wy700->palette[1], wy700->palette[2], wy700->palette[3] + ); + + fprintf (fp, "CRTC=[%02X", wy700->crtc_reg[0]); + for (i = 1; i < 18; i++) { + if ((i & 7) == 0) { + fputs ("-", fp); + } + else { + fputs (" ", fp); + } + fprintf (fp, "%02X", wy700->crtc_reg[i]); + } + fputs ("]\n", fp); + + fflush (fp); +} + +int wy700_dump (wy700_t *wy700, FILE *fp) +{ + fprintf (fp, "# WY700 dump\n"); + + fprintf (fp, "\n# REGS:\n"); + pce_dump_hex (fp, + mem_blk_get_data (wy700->reg), + mem_blk_get_size (wy700->reg), + mem_blk_get_addr (wy700->reg), + 16, "# ", 0 + ); + + fprintf (fp, "\n# CRTC:\n"); + pce_dump_hex (fp, wy700->crtc_reg, 18, 0, 16, "# ", 0); + + fputs ("\n\n# RAM:\n", fp); + pce_dump_hex (fp, + mem_blk_get_data (wy700->mem), + mem_blk_get_size (wy700->mem), + mem_blk_get_addr (wy700->mem), + 16, "", 1 + ); + + return (0); +} + +mem_blk_t *wy700_get_mem (wy700_t *wy700) +{ + return (wy700->mem); +} + +mem_blk_t *wy700_get_reg (wy700_t *wy700) +{ + return (wy700->reg); +} + + +/***************************************************************************** + * mode 0 (text 80 * 25) + *****************************************************************************/ + +static +int wy700_mode0_screenshot (wy700_t *wy700, FILE *fp) +{ + unsigned i; + unsigned x, y; + + i = (wy700->crtc_ofs << 1) & 0x3fff; + + for (y = 0; y < 25; y++) { + for (x = 0; x < 80; x++) { + fputc (wy700->mem->data[i], fp); + i = (i + 2) & 0x7fff; + } + + fputs ("\n", fp); + } + + return (0); +} + +static +void wy700_mode0_update (wy700_t *wy700) +{ + unsigned i; + unsigned x, y; + unsigned fg, bg; + + i = (wy700->crtc_ofs << 1) & 0x3fff; + + for (y = 0; y < 25; y++) { + for (x = 0; x < 80; x++) { + fg = wy700->mem->data[i + 1] & 0x0f; + bg = (wy700->mem->data[i + 1] & 0xf0) >> 4; + + trm_set_col (wy700->trm, fg, bg); + trm_set_chr (wy700->trm, x, y, wy700->mem->data[i]); + + i = (i + 2) & 0x3fff; + } + } +} + +void wy700_mode0_set_uint8 (wy700_t *wy700, unsigned long addr, unsigned char val) +{ + unsigned x, y; + unsigned char c, a; + + if (wy700->mem->data[addr] == val) { + return; + } + + wy700->mem->data[addr] = val; + + if (addr & 1) { + c = wy700->mem->data[addr - 1]; + a = val; + } + else { + c = val; + a = wy700->mem->data[addr + 1]; + } + + if (addr < (wy700->crtc_ofs << 1)) { + return; + } + + addr -= (wy700->crtc_ofs << 1); + + if (addr >= 4000) { + return; + } + + x = (addr >> 1) % 80; + y = (addr >> 1) / 80; + + trm_set_col (wy700->trm, a & 0x0f, (a & 0xf0) >> 4); + trm_set_chr (wy700->trm, x, y, c); +} + +void wy700_mode0_set_uint16 (wy700_t *wy700, unsigned long addr, unsigned short val) +{ + unsigned x, y; + unsigned char c, a; + + if (addr & 1) { + wy700_mem_set_uint8 (wy700, addr, val & 0xff); + wy700_mem_set_uint8 (wy700, addr + 1, (val >> 8) & 0xff); + return; + } + + c = val & 0xff; + a = (val >> 8) & 0xff; + + if ((wy700->mem->data[addr] == c) && (wy700->mem->data[addr + 1] == a)) { + return; + } + + wy700->mem->data[addr] = c; + wy700->mem->data[addr + 1] = a; + + if (addr < (wy700->crtc_ofs << 1)) { + return; + } + + addr -= (wy700->crtc_ofs << 1); + + if (addr >= 4000) { + return; + } + + x = (addr >> 1) % 80; + y = (addr >> 1) / 80; + + trm_set_col (wy700->trm, a & 0x0f, (a & 0xf0) >> 4); + trm_set_chr (wy700->trm, x, y, c); +} + + +/***************************************************************************** + * mode 1 (graphics 320 * 200 * 4) + *****************************************************************************/ + +static +int wy700_mode1_screenshot (wy700_t *wy700, FILE *fp) +{ + unsigned x, y, i; + unsigned val, idx; + unsigned char *mem; + + fputs ("P6\n320 200\n255 ", fp); + + for (y = 0; y < 200; y++) { + mem = wy700->mem->data + 80 * (y / 2); + + if (y & 1) { + mem += 8192; + } + + for (x = 0; x < 80; x++) { + val = mem[x]; + + for (i = 0; i < 4; i++) { + idx = (val >> 6) & 0x03; + idx = wy700->palette[idx]; + fputc (wy700_col[idx].r >> 8, fp); + fputc (wy700_col[idx].g >> 8, fp); + fputc (wy700_col[idx].b >> 8, fp); + + val <<= 2; + } + } + } + + return (0); +} + +static +void wy700_mode1_update (wy700_t *wy700) +{ + unsigned x, y, i; + unsigned val0, val1; + unsigned char *mem0, *mem1; + + mem0 = wy700->mem->data; + mem1 = wy700->mem->data + 8192; + + for (y = 0; y < 100; y++) { + for (x = 0; x < 80; x++) { + val0 = mem0[x]; + val1 = mem1[x]; + + for (i = 0; i < 4; i++) { + trm_set_col (wy700->trm, wy700->palette[(val0 >> 6) & 0x03], 0); + trm_set_pxl (wy700->trm, 4 * x + i, 2 * y); + + trm_set_col (wy700->trm, wy700->palette[(val1 >> 6) & 0x03], 0); + trm_set_pxl (wy700->trm, 4 * x + i, 2 * y + 1); + + val0 <<= 2; + val1 <<= 2; + } + } + + mem0 += 80; + mem1 += 80; + } +} + +void wy700_mode1_set_uint8 (wy700_t *wy700, unsigned long addr, unsigned char val) +{ + unsigned i; + unsigned x, y; + unsigned char old; + + old = wy700->mem->data[addr]; + + if (old == val) { + return; + } + + wy700->mem->data[addr] = val; + + if (addr < 8192) { + x = 4 * (addr % 80); + y = 2 * (addr / 80); + } + else { + x = 4 * ((addr - 8192) % 80); + y = 2 * ((addr - 8192) / 80) + 1; + } + + if (y >= 200) { + return; + } + + for (i = 0; i < 4; i++) { + unsigned col; + + if ((old ^ val) & 0xc0) { + col = (val >> 6) & 0x03; + trm_set_col (wy700->trm, wy700->palette[col], 0); + + trm_set_pxl (wy700->trm, x + i, y); + } + + old <<= 2; + val <<= 2; + } +} + + +/***************************************************************************** + * mode 2 (graphics 620 * 200 * 2) + *****************************************************************************/ + +static +int wy700_mode2_screenshot (wy700_t *wy700, FILE *fp) +{ + unsigned x, y, i; + unsigned val, col; + unsigned char *mem; + + fputs ("P6\n640 200\n255 ", fp); + + col = wy700->palette[0]; + for (y = 0; y < 200; y++) { + mem = wy700->mem->data + 80 * (y / 2); + + if (y & 1) { + mem += 8192; + } + + for (x = 0; x < 80; x++) { + val = mem[x]; + + for (i = 0; i < 8; i++) { + if (val & (0x80 >> i)) { + fputc (wy700_col[col].r >> 8, fp); + fputc (wy700_col[col].g >> 8, fp); + fputc (wy700_col[col].b >> 8, fp); + } + else { + fputc (0x00, fp); + fputc (0x00, fp); + fputc (0x00, fp); + } + } + } + } + + return (0); +} + +static +void wy700_mode2_update (wy700_t *wy700) +{ + unsigned x, y, i; + unsigned val0, val1; + unsigned char *mem0, *mem1; + + mem0 = wy700->mem->data; + mem1 = wy700->mem->data + 8192; + + for (y = 0; y < 100; y++) { + for (x = 0; x < 80; x++) { + val0 = mem0[x]; + val1 = mem1[x]; + + for (i = 0; i < 8; i++) { + trm_set_col (wy700->trm, (val0 & 0x80) ? wy700->palette[0] : 0, 0); + trm_set_pxl (wy700->trm, 8 * x + i, 2 * y); + + trm_set_col (wy700->trm, (val1 & 0x80) ? wy700->palette[0] : 0, 0); + trm_set_pxl (wy700->trm, 8 * x + i, 2 * y + 1); + + val0 <<= 1; + val1 <<= 1; + } + } + + mem0 += 80; + mem1 += 80; + } +} + +void wy700_mode2_set_uint8 (wy700_t *wy700, unsigned long addr, unsigned char val) +{ + unsigned i; + unsigned x, y; + unsigned char old; + + old = wy700->mem->data[addr]; + + if (old == val) { + return; + } + + wy700->mem->data[addr] = val; + + if (addr < 8192) { + x = 8 * (addr % 80); + y = 2 * (addr / 80); + } + else { + x = 8 * ((addr - 8192) % 80); + y = 2 * ((addr - 8192) / 80) + 1; + } + + for (i = 0; i < 8; i++) { + unsigned col; + + if ((old ^ val) & 0x80) { + col = (val >> 7) & 0x01; + trm_set_col (wy700->trm, col ? wy700->palette[0] : 0, 0); + trm_set_pxl (wy700->trm, x + i, y); + } + + old <<= 1; + val <<= 1; + } +} + +/***************************************************************************** + * mode 3 (graphics 1280 * 800 * 2) + *****************************************************************************/ + +static +int wy700_mode3_screenshot (wy700_t *wy700, FILE *fp) +{ + unsigned x, y, i; + unsigned val, col; + unsigned char *mem; + + fputs ("P6\n1280 800\n255 ", fp); + + col = 15; //wy700->palette[0]; + for (y = 0; y < 800; y++) { + mem = wy700->mem->data + 160 * (y / 2); + + if (y & 1) { + mem += 0x10000L; + } + + for (x = 0; x < 160; x++) { + val = mem[x]; + + for (i = 0; i < 8; i++) { + if (val & (0x80 >> i)) { + fputc (wy700_col[col].r >> 8, fp); + fputc (wy700_col[col].g >> 8, fp); + fputc (wy700_col[col].b >> 8, fp); + } + else { + fputc (0x00, fp); + fputc (0x00, fp); + fputc (0x00, fp); + } + } + } + } + + return (0); +} + +static +void wy700_mode3_update (wy700_t *wy700) +{ + unsigned x, y, i; + unsigned val0, val1; + unsigned char *mem0, *mem1; + + mem0 = wy700->mem->data; + mem1 = wy700->mem->data + 0x10000L; + + for (y = 0; y < 400; y++) { + for (x = 0; x < 160; x++) { + val0 = mem0[x]; + val1 = mem1[x]; + + for (i = 0; i < 8; i++) { + trm_set_col (wy700->trm, (val0 & 0x80) ? 15/*wy700->palette[0]*/ : 0, 0); + trm_set_pxl (wy700->trm, 8 * x + i, 2 * y); + + trm_set_col (wy700->trm, (val1 & 0x80) ? 15/*wy700->palette[0]*/ : 0, 0); + trm_set_pxl (wy700->trm, 8 * x + i, 2 * y + 1); + + val0 <<= 1; + val1 <<= 1; + } + } + + mem0 += 160; + mem1 += 160; + } +} + +/* XXX The mapping of read/write like this is sheer guesswork. */ +unsigned char wy700_mode3_get_uint8(wy700_t *wy700, unsigned long addr) +{ + addr &= 0xFFFF; + if (wy700->control & 1) { + addr += 0x10000L; + } + + return wy700->mem->data[addr]; +} + +void wy700_mode3_set_uint8 (wy700_t *wy700, unsigned long addr, unsigned char val) +{ + unsigned i; + unsigned x, y; + unsigned char old; + + addr &= 0xFFFF; + if (wy700->control & 2) { + addr += 0x10000L; + } + + old = wy700->mem->data[addr]; + + if (old == val) { + return; + } + + wy700->mem->data[addr] = val; + + if (addr < 0x10000L) { + x = 8 * (addr % 160); + y = 2 * (addr / 160); + } + else { + x = 8 * ((addr - 0x10000L) % 160); + y = 2 * ((addr - 0x10000L) / 160) + 1; + } + + for (i = 0; i < 8; i++) { + unsigned col; + + if ((old ^ val) & 0x80) { + col = (val >> 7) & 0x01; + trm_set_col (wy700->trm, col ? 15 /*wy700->palette[0]*/ : 0, 0); + trm_set_pxl (wy700->trm, x + i, y); + } + + old <<= 1; + val <<= 1; + } +} + + + + +int wy700_screenshot (wy700_t *wy700, FILE *fp, unsigned mode) +{ + if ((wy700->mode == 0) && ((mode == 1) || (mode == 0))) { + return (wy700_mode0_screenshot (wy700, fp)); + } + else if ((wy700->mode == 1) && ((mode == 2) || (mode == 0))) { + return (wy700_mode1_screenshot (wy700, fp)); + } + else if ((wy700->mode == 2) && ((mode == 2) || (mode == 0))) { + return (wy700_mode2_screenshot (wy700, fp)); + } + else if ((wy700->mode == 3) && ((mode == 2) || (mode == 0))) { + return (wy700_mode3_screenshot (wy700, fp)); + } + + return (1); +} + +void wy700_update (wy700_t *wy700) +{ + switch (wy700->mode) { + case 0: + wy700_mode0_update (wy700); + break; + + case 1: + wy700_mode1_update (wy700); + break; + + case 2: + wy700_mode2_update (wy700); + break; + + case 3: + wy700_mode3_update (wy700); + break; + } +} + +void wy700_set_pos (wy700_t *wy700, unsigned pos) +{ + wy700->crtc_pos = pos; + + if (wy700->mode == 0) { + if (pos < wy700->crtc_ofs) { + return; + } + + pos -= wy700->crtc_ofs; + + if (pos >= 2000) { + return; + } + + trm_set_pos (wy700->trm, pos % 80, pos / 80); + } +} + +void wy700_set_crs (wy700_t *wy700, unsigned y1, unsigned y2) +{ + if (wy700->mode == 0) { + if (y1 > 7) { + trm_set_crs (wy700->trm, 0, 0, 0); + return; + } + + if ((y2 < y1) || (y2 > 7)) { + y2 = 7; + } + + y1 = (y1 << 5) | (y1 << 2) | (y1 >> 1); + y2 = (y2 << 5) | (y2 << 2) | (y2 >> 1); + + trm_set_crs (wy700->trm, y1, y2, 1); + } +} + +void wy700_set_page_ofs (wy700_t *wy700, unsigned ofs) +{ + if (wy700->crtc_ofs == ofs) { + return; + } + + wy700->crtc_ofs = ofs; + + if (wy700->mode == 0) { + wy700_update (wy700); + } +} + +void wy700_set_palette (wy700_t *wy700) +{ + unsigned pal, bg; + + pal = ((wy700->colreg >> 4) & 3) | (wy700->modereg & 4); + bg = wy700->colreg & 0x0F; + + if (pal == wy700->pal && bg == wy700->palette[0]) { + return; + } + + wy700->pal = pal; + + switch (pal) { + case 0: + wy700->palette[0] = bg; + wy700->palette[1] = 3; + wy700->palette[2] = 5; + wy700->palette[3] = 7; + break; + + case 1: + wy700->palette[0] = bg; + wy700->palette[1] = 11; + wy700->palette[2] = 13; + wy700->palette[3] = 15; + break; + + case 2: + wy700->palette[0] = bg; + wy700->palette[1] = 2; + wy700->palette[2] = 4; + wy700->palette[3] = 6; + break; + + case 3: + wy700->palette[0] = bg; + wy700->palette[1] = 10; + wy700->palette[2] = 12; + wy700->palette[3] = 14; + break; + + case 4: + case 6: + wy700->palette[0] = bg; + wy700->palette[1] = 3; + wy700->palette[2] = 4; + wy700->palette[3] = 7; + break; + + case 5: + case 7: + wy700->palette[0] = bg; + wy700->palette[1] = 11; + wy700->palette[2] = 12; + wy700->palette[3] = 15; + break; + } + + wy700_update (wy700); +} + +void wy700_set_mode (wy700_t *wy700) +{ + unsigned newmode, mode; + + mode = wy700->modereg; + + if ((mode & 0x02) == 0) { + newmode = 0; + } + else if ((mode & 0x10) == 0) { + newmode = 1; + } + else { + newmode = 2; + } + if (wy700->control & 8) + { + newmode = 3; /* 1280x800 mode */ + } + + if (newmode == wy700->mode) { + return; + } + + wy700->mode = newmode; + + switch (newmode) { + case 0: + trm_set_mode (wy700->trm, TERM_MODE_TEXT, 80, 25); + trm_set_size (wy700->trm, wy700->mode_80x25_w, wy700->mode_80x25_h); + break; + + case 1: + trm_set_mode (wy700->trm, TERM_MODE_GRAPH, 320, 200); + trm_set_size (wy700->trm, wy700->mode_320x200_w, wy700->mode_320x200_h); + break; + + case 2: + trm_set_mode (wy700->trm, TERM_MODE_GRAPH, 640, 200); + trm_set_size (wy700->trm, wy700->mode_640x200_w, wy700->mode_640x200_h); + break; + + case 3: + trm_set_mode (wy700->trm, TERM_MODE_GRAPH, 1280, 800); + trm_set_size (wy700->trm, wy700->mode_1280x800_w, wy700->mode_1280x800_h); + break; + } + + wy700_update (wy700); +} + + +unsigned char wy700_mem_get_uint8 (wy700_t *wy700, unsigned long addr) +{ + switch (wy700->mode) { + case 0: + case 1: + case 2: + return wy700->mem->data[addr & 0x3FFF]; + case 3: + return wy700_mode3_get_uint8 (wy700, addr & 0xFFFF); + } +} + +unsigned short wy700_mem_get_uint16 (wy700_t *wy700, unsigned long addr) +{ + unsigned short l = wy700_mem_get_uint8(wy700, addr); + unsigned short h = wy700_mem_get_uint8(wy700, addr + 1); + return (h << 8) | l; +} + +void wy700_mem_set_uint8 (wy700_t *wy700, unsigned long addr, unsigned char val) +{ + switch (wy700->mode) { + case 0: + wy700_mode0_set_uint8 (wy700, addr & 0x3FFF, val); + break; + + case 1: + wy700_mode1_set_uint8 (wy700, addr & 0x3FFF, val); + break; + + case 2: + wy700_mode2_set_uint8 (wy700, addr & 0x3FFF, val); + break; + + case 3: + wy700_mode3_set_uint8 (wy700, addr & 0xFFFF, val); + break; + } +} + +void wy700_mem_set_uint16 (wy700_t *wy700, unsigned long addr, unsigned short val) +{ + switch (wy700->mode) { + case 0: + wy700_mode0_set_uint16 (wy700, addr & 0x3FFF, val); + break; + + case 1: + wy700_mode1_set_uint8 (wy700, addr & 0x3FFF, val); + wy700_mode1_set_uint8 (wy700, (addr + 1) & 0x3FFF, val >> 8); + break; + + case 2: + wy700_mode2_set_uint8 (wy700, addr & 0x3FFF, val); + wy700_mode2_set_uint8 (wy700, (addr + 1) & 0x3FFF, val >> 8); + break; + + case 3: + wy700_mode3_set_uint8 (wy700, addr & 0xFFFF, val); + wy700_mode3_set_uint8 (wy700, (addr + 1) & 0xFFFF, val >> 8); + break; + } +} + +void wy700_crtc_set_reg (wy700_t *wy700, unsigned reg, unsigned char val) +{ + if (reg > 17) { + return; + } + + wy700->crtc_reg[reg] = val; + + switch (reg) { + case 0x0a: + case 0x0b: + wy700_set_crs (wy700, wy700->crtc_reg[0x0a], wy700->crtc_reg[0x0b]); + break; + + case 0x0c: + wy700_set_page_ofs (wy700, (wy700->crtc_reg[0x0c] << 8) | val); + break; + + case 0x0d: + wy700_set_page_ofs (wy700, (wy700->crtc_reg[0x0c] << 8) | val); + break; + + case 0x0e: +/* wy700_set_pos (wy700, (val << 8) | (wy700->crtc_reg[0x0f] & 0xff)); */ + break; + + case 0x0f: + wy700_set_pos (wy700, (wy700->crtc_reg[0x0e] << 8) | val); + break; + } +} + +unsigned char wy700_crtc_get_reg (wy700_t *wy700, unsigned reg) +{ + if (reg > 15) { + return (0xff); + } + + return (wy700->crtc_reg[reg]); +} + +void wy700_reg_set_uint8 (wy700_t *wy700, unsigned long addr, unsigned char val) +{ + wy700->reg->data[addr] = val; + + switch (addr) { + case 0x01: + wy700_crtc_set_reg (wy700, wy700->reg->data[0], val); + break; + + case 0x04: +/* HACK If the video mode is changed, take us out of 1280x800 */ + if (wy700->modereg != val) + { + wy700->control = 0; + } + wy700->modereg = val; + wy700_set_mode (wy700); +/* Mode register can affect palette */ + wy700_set_palette (wy700); + break; + + case 0x05: + wy700->colreg = val; + wy700_set_palette (wy700); + break; + + case 0x0B: + wy700->control = val; + wy700_set_mode (wy700); + break; + } +} + +void wy700_reg_set_uint16 (wy700_t *wy700, unsigned long addr, unsigned short val) +{ + wy700_reg_set_uint8 (wy700, addr, val & 0xff); + + if ((addr + 1) < wy700->reg->size) { + wy700_reg_set_uint8 (wy700, addr + 1, val >> 8); + } +} + +unsigned char wy700_reg_get_uint8 (wy700_t *wy700, unsigned long addr) +{ + switch (addr) { + case 0x00: + return (wy700->reg->data[0]); + + case 0x01: + return (wy700_crtc_get_reg (wy700, wy700->reg->data[0])); + + case 0x06: + /* p freq: 14.31818 MHz + h freq: 15.750 KHz + v freq: 60 Hz + 912 / 14.31818e6 * 1e6 = 63.6952 + 640 / 14.31818e6 * 1e6 = 44.6984 + 262 / 15.75e3 * 1e6 = 16634.9206 + 200 / 15.75e3 * 1e6 = 12698.4127 + */ + if ((wy700->clkcnt % 16635) < 12699) { + wy700->reg->data[6] &= ~0x08; + + if ((wy700->clkcnt % 64) < 45) { + wy700->reg->data[6] |= 0x01; + } + else { + wy700->reg->data[6] &= ~0x01; + } + } + else { + wy700->reg->data[6] |= 0x08; + wy700->reg->data[6] |= 0x01; + } + + return (wy700->reg->data[6]); + + default: + return (0xff); + } +} + +unsigned short wy700_reg_get_uint16 (wy700_t *wy700, unsigned long addr) +{ + unsigned short ret; + + ret = wy700_reg_get_uint8 (wy700, addr); + + if ((addr + 1) < wy700->reg->size) { + ret |= wy700_reg_get_uint8 (wy700, addr + 1) << 8; + } + + return (ret); +} diff -u -r -N pce-0.1.7/src/devices/video/wy700.h pce-new/src/devices/video/wy700.h --- pce-0.1.7/src/devices/video/wy700.h 1970-01-01 01:00:00.000000000 +0100 +++ pce-new/src/devices/video/wy700.h 2008-10-14 23:12:55.000000000 +0100 @@ -0,0 +1,103 @@ +/***************************************************************************** + * pce * + *****************************************************************************/ + +/***************************************************************************** + * File name: src/devices/video/wy700.h * + * Created: 2003-04-18 by Hampa Hug * + * Last modified: 2008-10-13 by John Elliott * + * Copyright: (C) 2003-2005 Hampa Hug * + * (C) 2008 John Elliott * + *****************************************************************************/ + +/***************************************************************************** + * This program is free software. You can redistribute it and / or modify it * + * under the terms of the GNU General Public License version 2 as published * + * by the Free Software Foundation. * + * * + * This program is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY, without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * + * Public License for more details. * + *****************************************************************************/ + +/* $Id: wy700.h 619 2005-12-28 21:42:53Z hampa $ */ + + +#ifndef PCE_WY700_H +#define PCE_WY700_H 1 + + +#include +#include +#include + + +typedef struct { + video_t vid; + + mem_blk_t *mem; + mem_blk_t *reg; + + unsigned mode_80x25_w; + unsigned mode_80x25_h; + unsigned mode_320x200_w; + unsigned mode_320x200_h; + unsigned mode_640x200_w; + unsigned mode_640x200_h; + unsigned mode_1280x800_w; + unsigned mode_1280x800_h; + + unsigned char crtc_reg[18]; + + unsigned crtc_pos; + unsigned crtc_ofs; + + unsigned long clkcnt; + + unsigned char pal; + unsigned char palette[4]; + + unsigned char modereg; + unsigned char colreg; + unsigned control; + + int crs_on; + + unsigned mode; + + terminal_t *trm; +} wy700_t; + + +video_t *wy700_new (terminal_t *trm, ini_sct_t *sct); + +void wy700_del (wy700_t *wy700); + +void wy700_clock (wy700_t *wy700, unsigned long cnt); + +void wy700_prt_state (wy700_t *wy700, FILE *fp); + +int wy700_dump (wy700_t *wy700, FILE *fp); + +mem_blk_t *wy700_get_mem (wy700_t *wy700); +mem_blk_t *wy700_get_reg (wy700_t *wy700); + +int wy700_screenshot (wy700_t *wy700, FILE *fp, unsigned mode); + +void wy700_update (wy700_t *wy700); + +void wy700_set_pos (wy700_t *wy700, unsigned pos); + +void wy700_mem_set_uint8 (wy700_t *wy700, unsigned long addr, unsigned char val); +void wy700_mem_set_uint16 (wy700_t *wy700, unsigned long addr, unsigned short val); +unsigned char wy700_mem_get_uint8 (wy700_t *wy700, unsigned long addr); +unsigned short wy700_mem_get_uint16 (wy700_t *wy700, unsigned long addr); + +void wy700_reg_set_uint8 (wy700_t *wy700, unsigned long addr, unsigned char val); +void wy700_reg_set_uint16 (wy700_t *wy700, unsigned long addr, unsigned short val); +unsigned char wy700_reg_get_uint8 (wy700_t *wy700, unsigned long addr); +unsigned short wy700_reg_get_uint16 (wy700_t *wy700, unsigned long addr); + + +#endif