Some more 64bitness fixes for warnings.
Applied relevant upstream patches. Added Sigma Color 400 video card.
This commit is contained in:
@@ -9,7 +9,7 @@
|
||||
* Implementation of the generic device interface to handle
|
||||
* all devices attached to the emulator.
|
||||
*
|
||||
* Version: @(#)device.c 1.0.16 2018/10/14
|
||||
* Version: @(#)device.c 1.0.17 2018/10/25
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -168,6 +168,10 @@ device_add(const device_t *d)
|
||||
old = device_current;
|
||||
device_current = (device_t *)d;
|
||||
|
||||
/*
|
||||
* Do this so that a chained device_add will not identify the
|
||||
* same ID its master device is already trying to assign.
|
||||
*/
|
||||
devices[c] = (device_t *)d;
|
||||
|
||||
if (d->init != NULL) {
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
* Implementation of the Iomega ZIP drive with SCSI(-like)
|
||||
* commands, for both ATAPI and SCSI usage.
|
||||
*
|
||||
* Version: @(#)zip.c 1.0.21 2018/10/21
|
||||
* Version: @(#)zip.c 1.0.22 2018/10/25
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -1364,6 +1364,7 @@ zip_reset(void *p)
|
||||
dev->status = 0;
|
||||
dev->callback = 0LL;
|
||||
zip_set_callback(dev);
|
||||
zip_set_signature(dev);
|
||||
dev->packet_status = 0xff;
|
||||
dev->unit_attention = 0;
|
||||
}
|
||||
@@ -1968,13 +1969,8 @@ zip_command(void *p, uint8_t *cdb)
|
||||
else
|
||||
zipbufferb[0] = 0x00; /*Hard disk*/
|
||||
zipbufferb[1] = 0x80; /*Removable*/
|
||||
if (dev->drv->is_250) {
|
||||
zipbufferb[2] = (dev->drv->bus_type == ZIP_BUS_SCSI) ? 0x02 : 0x00; /*SCSI-2 compliant*/
|
||||
zipbufferb[3] = (dev->drv->bus_type == ZIP_BUS_SCSI) ? 0x02 : 0x21;
|
||||
} else {
|
||||
zipbufferb[2] = (dev->drv->bus_type == ZIP_BUS_SCSI) ? 0x02 : 0x00; /*SCSI-2 compliant*/
|
||||
zipbufferb[3] = (dev->drv->bus_type == ZIP_BUS_SCSI) ? 0x02 : 0x21;
|
||||
}
|
||||
zipbufferb[2] = (dev->drv->bus_type == ZIP_BUS_SCSI) ? 0x02 : 0x00; /*SCSI-2 compliant*/
|
||||
zipbufferb[3] = (dev->drv->bus_type == ZIP_BUS_SCSI) ? 0x02 : 0x21;
|
||||
zipbufferb[4] = 31;
|
||||
if (dev->drv->bus_type == ZIP_BUS_SCSI) {
|
||||
zipbufferb[6] = 1; /* 16-bit transfers supported */
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Implementation of the Teledisk floppy image format.
|
||||
*
|
||||
* Version: @(#)fdd_td0.c 1.0.9 2018/10/05
|
||||
* Version: @(#)fdd_td0.c 1.0.10 2018/10/24
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -365,9 +365,14 @@ state_reconst(td0dsk_t *state)
|
||||
k++;
|
||||
l = (j - k) * 2;
|
||||
|
||||
memcpy(&state->freq[k + 1], &state->freq[k], l);
|
||||
/*
|
||||
* NOTE: these *HAVE* to be memmove's as destination and
|
||||
* source can overlap, which memcpy can't handle.
|
||||
*/
|
||||
memmove(&state->freq[k + 1], &state->freq[k], l);
|
||||
|
||||
state->freq[k] = f;
|
||||
memcpy(&state->son[k + 1], &state->son[k], l);
|
||||
memmove(&state->son[k + 1], &state->son[k], l);
|
||||
state->son[k] = i;
|
||||
}
|
||||
|
||||
@@ -736,7 +741,7 @@ td0_initialize(int drive)
|
||||
offset += 3;
|
||||
switch (hs[8]) {
|
||||
default:
|
||||
ERRLOG("TD0: image uses an unsupported sector data encoding\n");
|
||||
ERRLOG("TD0: image uses an unsupported sector data encoding: %i\n", (int)hs[8]);
|
||||
return(0);
|
||||
|
||||
case 0:
|
||||
@@ -1114,6 +1119,24 @@ td0_init(void)
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
td0_abort(int drive)
|
||||
{
|
||||
td0_t *dev = td0[drive];
|
||||
|
||||
if (dev->imagebuf)
|
||||
free(dev->imagebuf);
|
||||
if (dev->processed_buf)
|
||||
free(dev->processed_buf);
|
||||
if (dev->f)
|
||||
fclose(dev->f);
|
||||
|
||||
free(dev);
|
||||
|
||||
td0[drive] = NULL;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
td0_load(int drive, const wchar_t *fn)
|
||||
{
|
||||
@@ -1137,8 +1160,7 @@ td0_load(int drive, const wchar_t *fn)
|
||||
|
||||
if (! dsk_identify(drive)) {
|
||||
ERRLOG("TD0: not a valid Teledisk image\n");
|
||||
fclose(dev->f);
|
||||
dev->f = NULL;
|
||||
td0_abort(drive);
|
||||
return(0);
|
||||
} else {
|
||||
DEBUG("TD0: valid Teledisk image\n");
|
||||
@@ -1153,9 +1175,7 @@ td0_load(int drive, const wchar_t *fn)
|
||||
|
||||
if (! td0_initialize(drive)) {
|
||||
ERRLOG("TD0: failed to initialize\n");
|
||||
fclose(dev->f);
|
||||
free(dev->imagebuf);
|
||||
free(dev->processed_buf);
|
||||
td0_abort(drive);
|
||||
return(0);
|
||||
}
|
||||
|
||||
@@ -1193,8 +1213,10 @@ td0_close(int drive)
|
||||
|
||||
d86f_unregister(drive);
|
||||
|
||||
free(dev->imagebuf);
|
||||
free(dev->processed_buf);
|
||||
if (dev->imagebuf)
|
||||
free(dev->imagebuf);
|
||||
if (dev->processed_buf)
|
||||
free(dev->processed_buf);
|
||||
|
||||
for (i = 0; i < 256; i++) {
|
||||
for (j = 0; j < 2; j++) {
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Emulation of SCSI (and ATAPI) CD-ROM drives.
|
||||
*
|
||||
* Version: @(#)scsi_cdrom.c 1.0.7 2018/10/22
|
||||
* Version: @(#)scsi_cdrom.c 1.0.8 2018/10/25
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -1445,6 +1445,8 @@ scsi_cdrom_reset(void *p)
|
||||
|
||||
set_callback(dev);
|
||||
|
||||
set_signature(dev);
|
||||
|
||||
dev->packet_status = 0xff;
|
||||
dev->unit_attention = 0xff;
|
||||
}
|
||||
|
||||
@@ -63,15 +63,15 @@
|
||||
* reducing the height of characters so they fit in an 8x12 cell
|
||||
* if necessary.
|
||||
*
|
||||
* Version: @(#)vid_genius.c 1.0.7 2018/09/22
|
||||
* Version: @(#)vid_genius.c 1.0.8 2018/10/24
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
* Sarah Walker, <tommowalker@tommowalker.co.uk>
|
||||
* John Elliott, <jce@seasip.info>
|
||||
*
|
||||
* Copyright 2017,2018 Fred N. van Kempen.
|
||||
* Copyright 2016-2018 Miran Grca.
|
||||
* Copyright 2008-2018 Sarah Walker.
|
||||
* Copyright 2016-2018 John Elliott.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
||||
963
src/devices/video/vid_sigma.c
Normal file
963
src/devices/video/vid_sigma.c
Normal file
@@ -0,0 +1,963 @@
|
||||
/*
|
||||
* VARCem Virtual ARchaeological Computer EMulator.
|
||||
* An emulator of (mostly) x86-based PC systems and devices,
|
||||
* using the ISA,EISA,VLB,MCA and PCI system buses, roughly
|
||||
* spanning the era between 1981 and 1995.
|
||||
*
|
||||
* This file is part of the VARCem Project.
|
||||
*
|
||||
* Emulation of the Sigma Color 400 video card.
|
||||
*
|
||||
* The Sigma Designs Color 400 is a video card from 1985,
|
||||
* presumably intended as an EGA competitor.
|
||||
*
|
||||
* The hardware seems to have gone through various iterations;
|
||||
* I've seen pictures of full-length and half-length versions.
|
||||
* TH99 describes the jumpers / switches:
|
||||
*
|
||||
* <http://arvutimuuseum.ee/th99/v/S-T/52579.htm>
|
||||
*
|
||||
* The card is CGA-compatible at BIOS level, but to improve
|
||||
* compatibility attempts to write to the CGA I/O ports at
|
||||
* 0x3D0-0x3DF trigger an NMI. The card's BIOS handles the NMI
|
||||
* and translates the CGA writes into commands to its own
|
||||
* hardware at 0x2D0-0x2DF. (DIP switches on the card allow the
|
||||
* base address to be changed, but since the BIOS dump I have
|
||||
* doesn't support this I haven't emulated it. Likewise the
|
||||
* BIOS ROM address can be changed, but I'm going with the
|
||||
* default of 0xC0000).
|
||||
*
|
||||
* The BIOS still functions if the NMI system isn't operational.
|
||||
* There doesn't seem to be a jumper or DIP switch to lock it
|
||||
* out, but at startup the BIOS tests for its presence and
|
||||
* configures itself to work or not as required. I've therefore
|
||||
* added a configuration option to handle this.
|
||||
*
|
||||
* The card's real CRTC at 0x2D0/0x2D1 appears to be a 6845.
|
||||
* One oddity is that all its horizontal counts are halved
|
||||
* compared to what a real CGA uses; 40-column modes have a width
|
||||
* of 20, and 80-column modes have a width of 40. This means that
|
||||
* the CRTC cursor position (registers 14/15) can only address
|
||||
* even-numbered columns, so the top bit of the control register
|
||||
* at 0x2D9 is used to adjust the position.
|
||||
*
|
||||
* Version: @(#)vid_sigma.c 1.0.1 2018/10/24
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
* John Elliott, <jce@seasip.info>
|
||||
*
|
||||
* Copyright 2018 Fred N. van Kempen.
|
||||
* Copyright 2018 Miran Grca.
|
||||
* Copyright 2018 John Elliott.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the:
|
||||
*
|
||||
* Free Software Foundation, Inc.
|
||||
* 59 Temple Place - Suite 330
|
||||
* Boston, MA 02111-1307
|
||||
* USA.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <wchar.h>
|
||||
#include "../../emu.h"
|
||||
#include "../../cpu/cpu.h"
|
||||
#include "../../io.h"
|
||||
#include "../../mem.h"
|
||||
#include "../../rom.h"
|
||||
#include "../../timer.h"
|
||||
#include "../../device.h"
|
||||
#include "../../plat.h"
|
||||
#include "../system/nmi.h"
|
||||
#include "../system/pit.h"
|
||||
#include "video.h"
|
||||
#include "vid_cga.h"
|
||||
|
||||
|
||||
#define FONT_ROM_PATH L"video/sigma/sigma400_font.rom"
|
||||
#define BIOS_ROM_PATH L"video/sigma/sigma400_bios.rom"
|
||||
|
||||
|
||||
/* 0x2D8: Mode register. Values written by the card BIOS are:
|
||||
* Text 40x25: 0xA8
|
||||
* Text 80x25: 0xB9
|
||||
* Text 80x30: 0xB9
|
||||
* Text 80x50: 0x79
|
||||
* Graphics 320x200: 0x0F
|
||||
* Graphics 640x200: 0x1F
|
||||
* Graphics 640x400: 0x7F
|
||||
*
|
||||
* I have assumed this is a bitmap with the following meaning:
|
||||
*/
|
||||
#define MODE_80COLS 0x01 /* For text modes, 80 columns across */
|
||||
#define MODE_GRAPHICS 0x02 /* Graphics mode */
|
||||
#define MODE_NOBLINK 0x04 /* Disable blink? */
|
||||
#define MODE_ENABLE 0x08 /* Enable display */
|
||||
#define MODE_HRGFX 0x10 /* For graphics modes, 640 pixels across */
|
||||
#define MODE_640x400 0x40 /* 400-line graphics mode */
|
||||
#define MODE_FONT16 0x80 /* Use 16-pixel high font */
|
||||
|
||||
/*
|
||||
* 0x2D9: Control register, with the following bits:
|
||||
*/
|
||||
#define CTL_CURSOR 0x80 /* Low bit of cursor position */
|
||||
#define CTL_NMI 0x20 /* Writes to 0x3D0-0x3DF trigger NMI */
|
||||
#define CTL_CLEAR_LPEN 0x08 /* Strobe 0 to clear lightpen latch */
|
||||
#define CTL_SET_LPEN 0x04 /* Strobe 0 to set lightpen latch */
|
||||
#define CTL_PALETTE 0x01 /* 0x2DE writes to palette (1) or plane (0) */
|
||||
|
||||
/*
|
||||
* The card BIOS seems to support two variants of the hardware: One where
|
||||
* bits 2 and 3 are normally 1 and are set to 0 to set/clear the latch, and
|
||||
* one where they are normally 0 and are set to 1. Behaviour is selected by
|
||||
* whether the byte at C000:17FFh is greater than 2Fh.
|
||||
*
|
||||
* 0x2DA: Status register.
|
||||
*/
|
||||
#define STATUS_CURSOR 0x80 /* Last value written to bit 7 of 0x2D9 */
|
||||
#define STATUS_NMI 0x20 /* Last value written to bit 5 of 0x2D9 */
|
||||
#define STATUS_RETR_V 0x10 /* Vertical retrace */
|
||||
#define STATUS_LPEN_T 0x04 /* Lightpen switch is off */
|
||||
#define STATUS_LPEN_A 0x02 /* Edge from lightpen has set trigger */
|
||||
#define STATUS_RETR_H 0x01 /* Horizontal retrace */
|
||||
|
||||
/*
|
||||
* 0x2DB: On read: Byte written to the card that triggered NMI
|
||||
* 0x2DB: On write: Resets the 'card raised NMI' flag.
|
||||
* 0x2DC: On read: Bit 7 set if the card raised NMI. If so, bits 0-3
|
||||
* give the low 4 bits of the I/O port address.
|
||||
* 0x2DC: On write: Resets the NMI.
|
||||
* 0x2DD: Memory paging. The memory from 0xC1800 to 0xC1FFF can be either:
|
||||
*
|
||||
* > ROM: A 128 character 8x16 font for use in graphics modes
|
||||
* > RAM: Use by the video BIOS to hold its settings.
|
||||
*
|
||||
* Reading port 2DD switches to ROM. Bit 7 of the value read gives the
|
||||
* previous paging state: bit 7 set if ROM was paged, clear if RAM was
|
||||
* paged.
|
||||
*
|
||||
* Writing port 2DD switches to RAM.
|
||||
*
|
||||
* 0x2DE: Meaning depends on bottom bit of value written to port 0x2D9.
|
||||
* Bit 0 set: Write to palette. High 4 bits of value = register,
|
||||
* low 4 bits = RGBI values (active low)
|
||||
* Bit 0 clear: Write to plane select. Low 2 bits of value select
|
||||
* plane 0-3
|
||||
*/
|
||||
|
||||
|
||||
#define COMPOSITE_OLD 0
|
||||
#define COMPOSITE_NEW 1
|
||||
|
||||
|
||||
typedef struct {
|
||||
mem_map_t mapping,
|
||||
bios_ram;
|
||||
|
||||
rom_t bios_rom;
|
||||
|
||||
uint8_t crtc[32]; /* CRTC: Real values */
|
||||
|
||||
uint8_t lastport; /* Last I/O port written */
|
||||
uint8_t lastwrite; /* Value written to that port */
|
||||
uint8_t sigma_ctl; /* Controls register:
|
||||
* Bit 7 is low bit of cursor position
|
||||
* Bit 5 set if writes to CGA ports trigger NMI
|
||||
* Bit 3 clears lightpen latch
|
||||
* Bit 2 sets lightpen latch
|
||||
* Bit 1 controls meaning of port 2DE
|
||||
*/
|
||||
uint8_t enable_nmi; /* Enable the NMI mechanism for CGA emulation?*/
|
||||
uint8_t rom_paged; /* Is ROM paged in at 0xC1800? */
|
||||
|
||||
uint8_t crtc_value; /* Value to return from a CRTC register read */
|
||||
|
||||
uint8_t sigmastat; /* Status register [0x2DA] */
|
||||
|
||||
uint8_t sigmamode; /* Mode control register [0x2D8] */
|
||||
|
||||
uint16_t ma, maback;
|
||||
|
||||
int crtcreg; /* CRTC: Real selected register */
|
||||
|
||||
int linepos, displine;
|
||||
int sc, vc;
|
||||
int cgadispon;
|
||||
int con, coff, cursoron, cgablink;
|
||||
int vsynctime, vadj;
|
||||
int oddeven;
|
||||
|
||||
int64_t dispontime, dispofftime;
|
||||
|
||||
int firstline, lastline;
|
||||
|
||||
int drawcursor;
|
||||
|
||||
int plane;
|
||||
int revision;
|
||||
|
||||
int64_t vidtime;
|
||||
|
||||
uint8_t *vram;
|
||||
uint8_t bram[2048];
|
||||
uint8_t palette[16];
|
||||
} sigma_t;
|
||||
|
||||
|
||||
static const uint8_t crtcmask[32] = {
|
||||
0xff, 0xff, 0xff, 0xff, 0x7f, 0x1f, 0x7f, 0x7f,
|
||||
0xf3, 0x1f, 0x7f, 0x1f, 0x3f, 0xff, 0x3f, 0xff,
|
||||
0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
static const video_timings_t sigma_timing = {VID_ISA,8,16,32,8,16,32};
|
||||
|
||||
|
||||
static void
|
||||
recalc_timings(sigma_t *dev)
|
||||
{
|
||||
double disptime;
|
||||
double _dispontime, _dispofftime;
|
||||
|
||||
if (dev->sigmamode & MODE_80COLS) {
|
||||
disptime = (dev->crtc[0] + 1) << 1;
|
||||
_dispontime = (dev->crtc[1]) << 1;
|
||||
} else {
|
||||
disptime = (dev->crtc[0] + 1) << 2;
|
||||
_dispontime = dev->crtc[1] << 2;
|
||||
}
|
||||
|
||||
_dispofftime = disptime - _dispontime;
|
||||
_dispontime *= CGACONST;
|
||||
_dispofftime *= CGACONST;
|
||||
|
||||
dev->dispontime = (int)(_dispontime * (1 << TIMER_SHIFT));
|
||||
dev->dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT));
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sigma_out(uint16_t port, uint8_t val, void *priv)
|
||||
{
|
||||
sigma_t *dev = (sigma_t *)priv;
|
||||
uint8_t old;
|
||||
|
||||
if (port >= 0x3d0 && port < 0x3e0) {
|
||||
dev->lastport = port & 0x0f;
|
||||
dev->lastwrite = val;
|
||||
|
||||
/* If set to NMI on video I/O... */
|
||||
if (dev->enable_nmi && (dev->sigma_ctl & CTL_NMI)) {
|
||||
dev->lastport |= 0x80; /* Card raised NMI */
|
||||
nmi = 1;
|
||||
}
|
||||
|
||||
/* For CRTC emulation, the card BIOS sets the value to be
|
||||
* read from port 0x3D1 like this */
|
||||
if (port == 0x3d1)
|
||||
dev->crtc_value = val;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
switch (port) {
|
||||
case 0x2d0:
|
||||
case 0x2d2:
|
||||
case 0x2d4:
|
||||
case 0x2d6:
|
||||
dev->crtcreg = val & 31;
|
||||
break;
|
||||
|
||||
case 0x2d1:
|
||||
case 0x2d3:
|
||||
case 0x2d5:
|
||||
case 0x2d7:
|
||||
old = dev->crtc[dev->crtcreg];
|
||||
dev->crtc[dev->crtcreg] = val & crtcmask[dev->crtcreg];
|
||||
if (old != val) {
|
||||
if (dev->crtcreg < 0xe || dev->crtcreg > 0x10) {
|
||||
fullchange = changeframecount;
|
||||
recalc_timings(dev);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x2d8:
|
||||
dev->sigmamode = val;
|
||||
break;
|
||||
|
||||
case 0x2d9:
|
||||
dev->sigma_ctl = val;
|
||||
break;
|
||||
|
||||
case 0x2db:
|
||||
dev->lastport &= 0x7F;
|
||||
break;
|
||||
|
||||
case 0x2dc: /* Reset NMI */
|
||||
nmi = 0;
|
||||
dev->lastport &= 0x7F;
|
||||
break;
|
||||
|
||||
case 0x2dd: /* Page in RAM at 0xC1800 */
|
||||
if (dev->rom_paged != 0)
|
||||
mmu_invalidate(0xc0000);
|
||||
dev->rom_paged = 0;
|
||||
break;
|
||||
|
||||
case 0x2de:
|
||||
if (dev->sigma_ctl & CTL_PALETTE)
|
||||
dev->palette[val >> 4] = (val & 0x0f) ^ 0x0f;
|
||||
else
|
||||
dev->plane = val & 3;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
sigma_in(uint16_t port, void *priv)
|
||||
{
|
||||
sigma_t *dev = (sigma_t *)priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
switch (port) {
|
||||
case 0x2d0:
|
||||
case 0x2d2:
|
||||
case 0x2d4:
|
||||
case 0x2d6:
|
||||
ret = dev->crtcreg;
|
||||
break;
|
||||
|
||||
case 0x2d1:
|
||||
case 0x2d3:
|
||||
case 0x2d5:
|
||||
case 0x2d7:
|
||||
ret = dev->crtc[dev->crtcreg & 0x1f];
|
||||
break;
|
||||
|
||||
case 0x2da:
|
||||
ret = (dev->sigma_ctl & 0xe0) | (dev->sigmastat & 0x1f);
|
||||
break;
|
||||
|
||||
case 0x2db:
|
||||
ret = dev->lastwrite; /* Value that triggered NMI */
|
||||
break;
|
||||
|
||||
case 0x2dc:
|
||||
ret = dev->lastport; /* Port that triggered NMI */
|
||||
break;
|
||||
|
||||
case 0x2dd: /* Page in ROM at 0xC1800 */
|
||||
ret = (dev->rom_paged ? 0x80 : 0);
|
||||
if (dev->rom_paged != 0x80)
|
||||
mmu_invalidate(0xc0000);
|
||||
dev->rom_paged = 0x80;
|
||||
break;
|
||||
|
||||
case 0x3d1:
|
||||
case 0x3d3:
|
||||
case 0x3d5:
|
||||
case 0x3d7:
|
||||
ret = dev->crtc_value;
|
||||
break;
|
||||
|
||||
/*
|
||||
* For CGA compatibility we have to return something palatable
|
||||
* on this port. On a real card this functionality can be turned
|
||||
* on or off with SW1/6.
|
||||
*/
|
||||
case 0x3da:
|
||||
ret = dev->sigmastat & 7;
|
||||
if (dev->sigmastat & STATUS_RETR_V) ret |= 8;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sigma_write(uint32_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
sigma_t *dev = (sigma_t *)priv;
|
||||
|
||||
cycles -= 4;
|
||||
|
||||
dev->vram[dev->plane * 0x8000 + (addr & 0x7fff)] = val;
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
sigma_read(uint32_t addr, void *priv)
|
||||
{
|
||||
sigma_t *dev = (sigma_t *)priv;
|
||||
|
||||
cycles -= 4;
|
||||
|
||||
return dev->vram[dev->plane * 0x8000 + (addr & 0x7fff)];
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sigma_bwrite(uint32_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
sigma_t *dev = (sigma_t *)priv;
|
||||
|
||||
addr &= 0x3fff;
|
||||
#if 0
|
||||
if ((addr >= 0x1800) && !dev->rom_paged && (addr < 0x2000))
|
||||
#endif
|
||||
if ((addr < 0x1800) || dev->rom_paged || (addr >= 0x2000))
|
||||
;
|
||||
else
|
||||
dev->bram[addr & 0x7ff] = val;
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
sigma_bread(uint32_t addr, void *priv)
|
||||
{
|
||||
sigma_t *dev = (sigma_t *)priv;
|
||||
uint8_t ret;
|
||||
|
||||
addr &= 0x3fff;
|
||||
if (addr >= 0x2000)
|
||||
return 0xff;
|
||||
|
||||
if (addr < 0x1800 || dev->rom_paged)
|
||||
ret = dev->bios_rom.rom[addr & 0x1fff];
|
||||
else
|
||||
ret = dev->bram[addr & 0x7ff];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* Render a line in 80-column text mode */
|
||||
static void
|
||||
sigma_text80(sigma_t *dev)
|
||||
{
|
||||
uint16_t ca = (dev->crtc[15] | (dev->crtc[14] << 8));
|
||||
uint16_t ma = ((dev->ma & 0x3fff) << 1);
|
||||
uint8_t *vram = dev->vram + (ma << 1);
|
||||
int drawcursor, x, c;
|
||||
uint8_t chr, attr;
|
||||
uint32_t cols[4];
|
||||
|
||||
ca = ca << 1;
|
||||
if (dev->sigma_ctl & CTL_CURSOR)
|
||||
++ca;
|
||||
ca &= 0x3fff;
|
||||
|
||||
/* The Sigma 400 seems to use screen widths stated in words
|
||||
(40 for 80-column, 20 for 40-column) */
|
||||
for (x = 0; x < (dev->crtc[1] << 1); x++) {
|
||||
chr = vram[x << 1];
|
||||
attr = vram[(x << 1) + 1];
|
||||
drawcursor = ((ma == ca) && dev->con && dev->cursoron);
|
||||
|
||||
if (! (dev->sigmamode & MODE_NOBLINK)) {
|
||||
cols[1] = (attr & 15) | 16;
|
||||
cols[0] = ((attr >> 4) & 7) | 16;
|
||||
if ((dev->cgablink & 8) && (attr & 0x80) && !dev->drawcursor)
|
||||
cols[1] = cols[0];
|
||||
} else { /* No blink */
|
||||
cols[1] = (attr & 15) | 16;
|
||||
cols[0] = (attr >> 4) | 16;
|
||||
}
|
||||
|
||||
if (drawcursor && !(x & 1)) {
|
||||
for (c = 0; c < 8; c++) {
|
||||
if (dev->sigmamode & MODE_FONT16)
|
||||
buffer->line[dev->displine][(x << 3) + c + 8] = cols[(fontdatm[chr][dev->sc & 15] & (1 << (c ^ 7))) ? 1 : 0] ^ 0x0f;
|
||||
else
|
||||
buffer->line[dev->displine][(x << 3) + c + 8] = cols[(fontdat[chr][dev->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 0x0f;
|
||||
}
|
||||
} else {
|
||||
for (c = 0; c < 8; c++) {
|
||||
if (dev->sigmamode & MODE_FONT16)
|
||||
buffer->line[dev->displine][(x << 3) + c + 8] = cols[(fontdatm[chr][dev->sc & 15] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
else
|
||||
buffer->line[dev->displine][(x << 3) + c + 8] = cols[(fontdat[chr][dev->sc & 7] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
}
|
||||
}
|
||||
++ma;
|
||||
}
|
||||
|
||||
dev->ma += dev->crtc[1];
|
||||
}
|
||||
|
||||
|
||||
/* Render a line in 40-column text mode */
|
||||
static void
|
||||
sigma_text40(sigma_t *dev)
|
||||
{
|
||||
uint16_t ca = (dev->crtc[15] | (dev->crtc[14] << 8));
|
||||
uint16_t ma = ((dev->ma & 0x3FFF) << 1);
|
||||
uint8_t *vram = dev->vram + ((ma << 1) & 0x3FFF);
|
||||
int drawcursor, x, c;
|
||||
uint8_t chr, attr;
|
||||
uint32_t cols[4];
|
||||
|
||||
ca = ca << 1;
|
||||
if (dev->sigma_ctl & CTL_CURSOR)
|
||||
++ca;
|
||||
ca &= 0x3fff;
|
||||
|
||||
/* The Sigma 400 seems to use screen widths stated in words
|
||||
(40 for 80-column, 20 for 40-column) */
|
||||
for (x = 0; x < (dev->crtc[1] << 1); x++) {
|
||||
chr = vram[x << 1];
|
||||
attr = vram[(x << 1) + 1];
|
||||
drawcursor = ((ma == ca) && dev->con && dev->cursoron);
|
||||
|
||||
if (!(dev->sigmamode & MODE_NOBLINK)) {
|
||||
cols[1] = (attr & 15) | 16;
|
||||
cols[0] = ((attr >> 4) & 7) | 16;
|
||||
if ((dev->cgablink & 8) && (attr & 0x80) && !dev->drawcursor)
|
||||
cols[1] = cols[0];
|
||||
} else { /* No blink */
|
||||
cols[1] = (attr & 15) | 16;
|
||||
cols[0] = (attr >> 4) | 16;
|
||||
}
|
||||
|
||||
if (drawcursor) {
|
||||
for (c = 0; c < 8; c++) {
|
||||
buffer->line[dev->displine][(x << 4) + 2*c + 8] =
|
||||
buffer->line[dev->displine][(x << 4) + 2*c + 9] = cols[(fontdatm[chr][dev->sc & 15] & (1 << (c ^ 7))) ? 1 : 0] ^ 0x0f;
|
||||
}
|
||||
} else {
|
||||
for (c = 0; c < 8; c++) {
|
||||
buffer->line[dev->displine][(x << 4) + 2*c + 8] =
|
||||
buffer->line[dev->displine][(x << 4) + 2*c + 9] = cols[(fontdatm[chr][dev->sc & 15] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
}
|
||||
}
|
||||
ma++;
|
||||
}
|
||||
|
||||
dev->ma += dev->crtc[1];
|
||||
}
|
||||
|
||||
|
||||
/* Draw a line in the 640x400 graphics mode */
|
||||
static void
|
||||
sigma_gfx400(sigma_t *dev)
|
||||
{
|
||||
uint8_t *vram = &dev->vram[((dev->ma << 1) & 0x1fff) + (dev->sc & 3) * 0x2000];
|
||||
uint8_t mask, col, c;
|
||||
uint8_t plane[4];
|
||||
int x;
|
||||
|
||||
for (x = 0; x < (dev->crtc[1] << 1); x++) {
|
||||
plane[0] = vram[x];
|
||||
plane[1] = vram[0x8000 + x];
|
||||
plane[2] = vram[0x10000 + x];
|
||||
plane[3] = vram[0x18000 + x];
|
||||
|
||||
for (c = 0, mask = 0x80; c < 8; c++, mask >>= 1) {
|
||||
col = ((plane[3] & mask) ? 8 : 0) |
|
||||
((plane[2] & mask) ? 4 : 0) |
|
||||
((plane[1] & mask) ? 2 : 0) |
|
||||
((plane[0] & mask) ? 1 : 0);
|
||||
col |= 16;
|
||||
buffer->line[dev->displine][(x << 3) + c + 8] = col;
|
||||
}
|
||||
|
||||
if (x & 1) dev->ma++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Draw a line in the 640x200 graphics mode.
|
||||
* This is actually a 640x200x16 mode; on startup, the BIOS selects plane 2,
|
||||
* blanks the other planes, and sets palette ink 4 to white. Pixels plotted
|
||||
* in plane 2 come out in white, others black; but by programming the palette
|
||||
* and plane registers manually you can get the full resolution. */
|
||||
static void
|
||||
sigma_gfx200(sigma_t *dev)
|
||||
{
|
||||
uint8_t *vram = &dev->vram[((dev->ma << 1) & 0x1fff) + (dev->sc & 2) * 0x1000];
|
||||
uint8_t mask, col, c;
|
||||
uint8_t plane[4];
|
||||
int x;
|
||||
|
||||
for (x = 0; x < (dev->crtc[1] << 1); x++) {
|
||||
plane[0] = vram[x];
|
||||
plane[1] = vram[0x8000 + x];
|
||||
plane[2] = vram[0x10000 + x];
|
||||
plane[3] = vram[0x18000 + x];
|
||||
|
||||
for (c = 0, mask = 0x80; c < 8; c++, mask >>= 1) {
|
||||
col = ((plane[3] & mask) ? 8 : 0) |
|
||||
((plane[2] & mask) ? 4 : 0) |
|
||||
((plane[1] & mask) ? 2 : 0) |
|
||||
((plane[0] & mask) ? 1 : 0);
|
||||
col |= 16;
|
||||
buffer->line[dev->displine][(x << 3) + c + 8] = col;
|
||||
}
|
||||
|
||||
if (x & 1) dev->ma++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Draw a line in the 320x200 graphics mode */
|
||||
static void
|
||||
sigma_gfx4col(sigma_t *dev)
|
||||
{
|
||||
uint8_t *vram = &dev->vram[((dev->ma << 1) & 0x1fff) + (dev->sc & 2) * 0x1000];
|
||||
uint8_t mask, col, c;
|
||||
uint8_t plane[4];
|
||||
int x;
|
||||
|
||||
for (x = 0; x < (dev->crtc[1] << 1); x++) {
|
||||
plane[0] = vram[x];
|
||||
plane[1] = vram[0x8000 + x];
|
||||
plane[2] = vram[0x10000 + x];
|
||||
plane[3] = vram[0x18000 + x];
|
||||
|
||||
mask = 0x80;
|
||||
for (c = 0; c < 4; c++) {
|
||||
col = ((plane[3] & mask) ? 2 : 0) |
|
||||
((plane[2] & mask) ? 1 : 0);
|
||||
mask = mask >> 1;
|
||||
col |= ((plane[3] & mask) ? 8 : 0) |
|
||||
((plane[2] & mask) ? 4 : 0);
|
||||
col |= 16;
|
||||
mask = mask >> 1;
|
||||
|
||||
buffer->line[dev->displine][(x << 3) + (c << 1) + 8] =
|
||||
buffer->line[dev->displine][(x << 3) + (c << 1) + 9] = col;
|
||||
}
|
||||
|
||||
if (x & 1) dev->ma++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sigma_poll(void *priv)
|
||||
{
|
||||
sigma_t *dev = (sigma_t *)priv;
|
||||
uint32_t cols[4];
|
||||
int oldsc, oldvc;
|
||||
int x, c;
|
||||
|
||||
if (! dev->linepos) {
|
||||
dev->vidtime += dev->dispofftime;
|
||||
dev->sigmastat |= STATUS_RETR_H;
|
||||
dev->linepos = 1;
|
||||
oldsc = dev->sc;
|
||||
if ((dev->crtc[8] & 3) == 3)
|
||||
dev->sc = ((dev->sc << 1) + dev->oddeven) & 7;
|
||||
if (dev->cgadispon) {
|
||||
if (dev->displine < dev->firstline) {
|
||||
dev->firstline = dev->displine;
|
||||
video_wait_for_buffer();
|
||||
}
|
||||
dev->lastline = dev->displine;
|
||||
|
||||
cols[0] = 16;
|
||||
|
||||
/* Left overscan */
|
||||
for (c = 0; c < 8; c++) {
|
||||
buffer->line[dev->displine][c] = cols[0];
|
||||
if (dev->sigmamode & MODE_80COLS)
|
||||
buffer->line[dev->displine][c + (dev->crtc[1] << 4) + 8] = cols[0];
|
||||
else
|
||||
buffer->line[dev->displine][c + (dev->crtc[1] << 5) + 8] = cols[0];
|
||||
}
|
||||
|
||||
if (dev->sigmamode & MODE_GRAPHICS) {
|
||||
if (dev->sigmamode & MODE_640x400)
|
||||
sigma_gfx400(dev);
|
||||
else if (dev->sigmamode & MODE_HRGFX)
|
||||
sigma_gfx200(dev);
|
||||
else
|
||||
sigma_gfx4col(dev);
|
||||
} else { /* Text modes */
|
||||
if (dev->sigmamode & MODE_80COLS)
|
||||
sigma_text80(dev);
|
||||
else
|
||||
sigma_text40(dev);
|
||||
}
|
||||
} else {
|
||||
cols[0] = 16;
|
||||
if (dev->sigmamode & MODE_80COLS)
|
||||
cga_hline(buffer, 0, dev->displine, (dev->crtc[1] << 4) + 16, cols[0]);
|
||||
else
|
||||
cga_hline(buffer, 0, dev->displine, (dev->crtc[1] << 5) + 16, cols[0]);
|
||||
}
|
||||
|
||||
if (dev->sigmamode & MODE_80COLS)
|
||||
x = (dev->crtc[1] << 4) + 16;
|
||||
else
|
||||
x = (dev->crtc[1] << 5) + 16;
|
||||
|
||||
for (c = 0; c < x; c++)
|
||||
buffer->line[dev->displine][c] = dev->palette[buffer->line[dev->displine][c] & 0xf] | 16;
|
||||
|
||||
dev->sc = oldsc;
|
||||
if (dev->vc == dev->crtc[7] && !dev->sc)
|
||||
dev->sigmastat |= STATUS_RETR_V;
|
||||
dev->displine++;
|
||||
if (dev->displine >= 560)
|
||||
dev->displine = 0;
|
||||
} else {
|
||||
dev->vidtime += dev->dispontime;
|
||||
dev->linepos = 0;
|
||||
if (dev->vsynctime) {
|
||||
dev->vsynctime--;
|
||||
if (!dev->vsynctime)
|
||||
dev->sigmastat &= ~STATUS_RETR_V;
|
||||
}
|
||||
if (dev->sc == (dev->crtc[11] & 31) ||
|
||||
((dev->crtc[8] & 3) == 3 && dev->sc == ((dev->crtc[11] & 31) >> 1))) {
|
||||
dev->con = 0;
|
||||
dev->coff = 1;
|
||||
}
|
||||
if ((dev->crtc[8] & 3) == 3 && dev->sc == (dev->crtc[9] >> 1))
|
||||
dev->maback = dev->ma;
|
||||
if (dev->vadj) {
|
||||
dev->sc++;
|
||||
dev->sc &= 31;
|
||||
dev->ma = dev->maback;
|
||||
dev->vadj--;
|
||||
if (!dev->vadj) {
|
||||
dev->cgadispon = 1;
|
||||
dev->ma = dev->maback = (dev->crtc[13] | (dev->crtc[12] << 8)) & 0x3fff;
|
||||
dev->sc = 0;
|
||||
}
|
||||
} else if (dev->sc == dev->crtc[9]) {
|
||||
dev->maback = dev->ma;
|
||||
dev->sc = 0;
|
||||
oldvc = dev->vc;
|
||||
dev->vc++;
|
||||
dev->vc &= 127;
|
||||
|
||||
if (dev->vc == dev->crtc[6])
|
||||
dev->cgadispon = 0;
|
||||
|
||||
if (oldvc == dev->crtc[4]) {
|
||||
dev->vc = 0;
|
||||
dev->vadj = dev->crtc[5];
|
||||
if (!dev->vadj) dev->cgadispon = 1;
|
||||
if (!dev->vadj) dev->ma = dev->maback = (dev->crtc[13] | (dev->crtc[12] << 8)) & 0x3fff;
|
||||
if ((dev->crtc[10] & 0x60) == 0x20)
|
||||
dev->cursoron = 0;
|
||||
else
|
||||
dev->cursoron = dev->cgablink & 8;
|
||||
}
|
||||
|
||||
if (dev->vc == dev->crtc[7]) {
|
||||
dev->cgadispon = 0;
|
||||
dev->displine = 0;
|
||||
dev->vsynctime = 16;
|
||||
if (dev->crtc[7]) {
|
||||
if (dev->sigmamode & MODE_80COLS)
|
||||
x = (dev->crtc[1] << 4) + 16;
|
||||
else
|
||||
x = (dev->crtc[1] << 5) + 16;
|
||||
dev->lastline++;
|
||||
if ((x != xsize) || ((dev->lastline - dev->firstline) != ysize) ||
|
||||
video_force_resize_get()) {
|
||||
xsize = x;
|
||||
ysize = dev->lastline - dev->firstline;
|
||||
if (xsize < 64)
|
||||
xsize = 656;
|
||||
if (ysize < 32)
|
||||
ysize = 200;
|
||||
|
||||
if (ysize <= 250)
|
||||
set_screen_size(xsize, (ysize << 1) + 16);
|
||||
else
|
||||
set_screen_size(xsize, ysize + 8);
|
||||
|
||||
if (video_force_resize_get())
|
||||
video_force_resize_set(0);
|
||||
}
|
||||
|
||||
video_blit_memtoscreen_8(0, dev->firstline - 4, 0, (dev->lastline - dev->firstline) + 8, xsize, (dev->lastline - dev->firstline) + 8);
|
||||
frames++;
|
||||
|
||||
video_res_x = xsize - 16;
|
||||
video_res_y = ysize;
|
||||
if (dev->sigmamode & MODE_GRAPHICS) {
|
||||
if (dev->sigmamode & (MODE_HRGFX | MODE_640x400))
|
||||
video_bpp = 1;
|
||||
else {
|
||||
video_res_x /= 2;
|
||||
video_bpp = 2;
|
||||
}
|
||||
} else if (dev->sigmamode & MODE_80COLS) {
|
||||
/* 80-column text */
|
||||
video_res_x /= 8;
|
||||
video_res_y /= dev->crtc[9] + 1;
|
||||
video_bpp = 0;
|
||||
} else {
|
||||
/* 40-column text */
|
||||
video_res_x /= 16;
|
||||
video_res_y /= dev->crtc[9] + 1;
|
||||
video_bpp = 0;
|
||||
}
|
||||
}
|
||||
dev->firstline = 1000;
|
||||
dev->lastline = 0;
|
||||
dev->cgablink++;
|
||||
dev->oddeven ^= 1;
|
||||
}
|
||||
} else {
|
||||
dev->sc++;
|
||||
dev->sc &= 31;
|
||||
dev->ma = dev->maback;
|
||||
}
|
||||
if (dev->cgadispon)
|
||||
dev->sigmastat &= ~STATUS_RETR_H;
|
||||
if ((dev->sc == (dev->crtc[10] & 31) ||
|
||||
((dev->crtc[8] & 3) == 3 && dev->sc == ((dev->crtc[10] & 31) >> 1))))
|
||||
dev->con = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
sigma_init(const device_t *info)
|
||||
{
|
||||
sigma_t *dev = malloc(sizeof(sigma_t));
|
||||
memset(dev, 0, sizeof(sigma_t));
|
||||
|
||||
dev->enable_nmi = device_get_config_int("enable_nmi");
|
||||
|
||||
cga_palette = device_get_config_int("rgb_type") << 1;
|
||||
if (cga_palette > 6)
|
||||
cga_palette = 0;
|
||||
cgapal_rebuild();
|
||||
|
||||
dev->vram = malloc(0x8000 * 4);
|
||||
|
||||
mem_map_add(&dev->mapping, 0xb8000, 0x08000,
|
||||
sigma_read,NULL,NULL, sigma_write,NULL,NULL,
|
||||
NULL, MEM_MAPPING_EXTERNAL, dev);
|
||||
|
||||
video_load_font(FONT_ROM_PATH, 7);
|
||||
|
||||
rom_init(&dev->bios_rom, BIOS_ROM_PATH,
|
||||
0xc0000, 0x2000, 0x1fff, 0, MEM_MAPPING_EXTERNAL);
|
||||
|
||||
/*
|
||||
* The BIOS ROM is overlaid by RAM, so remove its default
|
||||
* mapping and access it through sigma_bread/sigma_bwrite.
|
||||
*/
|
||||
mem_map_disable(&dev->bios_rom.mapping);
|
||||
memcpy(dev->bram, &dev->bios_rom.rom[0x1800], 0x0800);
|
||||
|
||||
mem_map_add(&dev->bios_ram, 0xc1800, 0x0800,
|
||||
sigma_bread,NULL,NULL, sigma_bwrite,NULL,NULL,
|
||||
dev->bios_rom.rom, MEM_MAPPING_EXTERNAL, dev);
|
||||
|
||||
io_sethandler(0x03d0, 16,
|
||||
sigma_in,NULL,NULL, sigma_out,NULL,NULL, dev);
|
||||
io_sethandler(0x02d0, 16,
|
||||
sigma_in,NULL,NULL, sigma_out,NULL,NULL, dev);
|
||||
|
||||
timer_add(sigma_poll, &dev->vidtime, TIMER_ALWAYS_ENABLED, dev);
|
||||
|
||||
/* Start with ROM paged in, BIOS RAM paged out */
|
||||
dev->rom_paged = 0x80;
|
||||
|
||||
if (dev->enable_nmi)
|
||||
dev->sigmastat = STATUS_LPEN_T;
|
||||
|
||||
video_inform(VID_TYPE_CGA, &sigma_timing);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sigma_close(void *priv)
|
||||
{
|
||||
sigma_t *dev = (sigma_t *)priv;
|
||||
|
||||
free(dev->vram);
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
speed_changed(void *priv)
|
||||
{
|
||||
sigma_t *dev = (sigma_t *)priv;
|
||||
|
||||
recalc_timings(dev);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
sigma_available(void)
|
||||
{
|
||||
return((rom_present(FONT_ROM_PATH) && rom_present(BIOS_ROM_PATH)));
|
||||
}
|
||||
|
||||
|
||||
static const device_config_t sigma_config[] = {
|
||||
{
|
||||
"rgb_type", "RGB type", CONFIG_SELECTION, "", 0,
|
||||
{
|
||||
{
|
||||
"Color", 0
|
||||
},
|
||||
{
|
||||
"Green Monochrome", 1
|
||||
},
|
||||
{
|
||||
"Amber Monochrome", 2
|
||||
},
|
||||
{
|
||||
"Gray Monochrome", 3
|
||||
},
|
||||
{
|
||||
"Color (no brown)", 4
|
||||
},
|
||||
{
|
||||
""
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"enable_nmi", "Enable NMI for CGA emulation", CONFIG_BINARY, "", 1
|
||||
},
|
||||
{
|
||||
"", "", -1
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
const device_t sigma_device = {
|
||||
"Sigma Color 400",
|
||||
DEVICE_ISA,
|
||||
0,
|
||||
sigma_init, sigma_close, NULL,
|
||||
sigma_available,
|
||||
speed_changed,
|
||||
NULL,
|
||||
NULL,
|
||||
sigma_config
|
||||
};
|
||||
@@ -40,7 +40,7 @@
|
||||
* W = 3 bus clocks
|
||||
* L = 4 bus clocks
|
||||
*
|
||||
* Version: @(#)video.c 1.0.20 2018/10/20
|
||||
* Version: @(#)video.c 1.0.21 2018/10/24
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -893,18 +893,18 @@ video_load_font(const wchar_t *s, int format)
|
||||
case 5: /* Toshiba 3100e */
|
||||
for (d = 0; d < 2048; d += 512) { /* Four languages... */
|
||||
for (c = d; c < d+256; c++)
|
||||
fread(&fontdatm[c][8], 1, 8, fp);
|
||||
(void)fread(&fontdatm[c][8], 1, 8, fp);
|
||||
for (c = d+256; c < d+512; c++)
|
||||
fread(&fontdatm[c][8], 1, 8, fp);
|
||||
(void)fread(&fontdatm[c][8], 1, 8, fp);
|
||||
for (c = d; c < d+256; c++)
|
||||
fread(&fontdatm[c][0], 1, 8, fp);
|
||||
(void)fread(&fontdatm[c][0], 1, 8, fp);
|
||||
for (c = d+256; c < d+512; c++)
|
||||
fread(&fontdatm[c][0], 1, 8, fp);
|
||||
fseek(fp, 4096, SEEK_CUR); /* Skip blank section */
|
||||
(void)fread(&fontdatm[c][0], 1, 8, fp);
|
||||
(void)fseek(fp, 4096, SEEK_CUR); /* Skip blank section */
|
||||
for (c = d; c < d+256; c++)
|
||||
fread(&fontdat[c][0], 1, 8, fp);
|
||||
(void)fread(&fontdat[c][0], 1, 8, fp);
|
||||
for (c = d+256; c < d+512; c++)
|
||||
fread(&fontdat[c][0], 1, 8, fp);
|
||||
(void)fread(&fontdat[c][0], 1, 8, fp);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -920,6 +920,18 @@ video_load_font(const wchar_t *s, int format)
|
||||
fontdatksc5601[c].chr[d] = fgetc(fp);
|
||||
}
|
||||
break;
|
||||
|
||||
case 7: /* Sigma Color 400 */
|
||||
/* The first 4K of the character ROM holds an 8x8 font. */
|
||||
for (c = 0; c < 256; c++) {
|
||||
(void)fread(&fontdat[c][0], 1, 8, fp);
|
||||
(void)fseek(fp, 8, SEEK_CUR);
|
||||
}
|
||||
|
||||
/* The second 4K holds an 8x16 font. */
|
||||
for (c = 0; c < 256; c++)
|
||||
(void)fread(&fontdatm[c][0], 1, 16, fp);
|
||||
break;
|
||||
}
|
||||
|
||||
(void)fclose(fp);
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Definitions for the video controller module.
|
||||
*
|
||||
* Version: @(#)video.h 1.0.20 2018/10/22
|
||||
* Version: @(#)video.h 1.0.21 2018/10/24
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -272,6 +272,9 @@ extern const device_t s3_virge_375_pci_device;
|
||||
extern const device_t s3_virge_375_4_vlb_device;
|
||||
extern const device_t s3_virge_375_4_pci_device;
|
||||
|
||||
/* Sigma Designs cards. */
|
||||
extern const device_t sigma_device;
|
||||
|
||||
/* Trident 8900 series cards. */
|
||||
extern const device_t tvga8900d_device;
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
* "extern" reference to its device into the video.h file,
|
||||
* and add an entry for it into the table here.
|
||||
*
|
||||
* Version: @(#)video_dev.c 1.0.26 2018/10/22
|
||||
* Version: @(#)video_dev.c 1.0.27 2018/10/24
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -101,6 +101,7 @@ static const struct {
|
||||
{ "oti067", &oti067_device },
|
||||
{ "oti077", &oti077_device },
|
||||
{ "pvga1a", ¶dise_pvga1a_device },
|
||||
{ "sigma400", &sigma_device },
|
||||
{ "wd90c11", ¶dise_wd90c11_device },
|
||||
{ "wd90c30", ¶dise_wd90c30_device },
|
||||
{ "plantronics", &colorplus_device },
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* String definitions for "Norwegian (Norway)" language.
|
||||
*
|
||||
* Version: @(#)VARCem-NO.str 1.0.5 2018/10/18
|
||||
* Version: @(#)VARCem-NO.str 1.0.6 2018/10/25
|
||||
*
|
||||
* Author: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Tore Sinding Bekkedal, <toresbe@gmail.com<
|
||||
@@ -47,7 +47,7 @@
|
||||
*/
|
||||
|
||||
/* Main application strings (2000) - DO NOT TRANSLATE! */
|
||||
#define STR_VERSION 1,0,5
|
||||
#define STR_VERSION 1,0,6
|
||||
#define STR_AUTHOR "Tore Sinding Bekkedal"
|
||||
#define STR_EMAIL "toresbe@gmail.com"
|
||||
#define STR_NAME "VARCem"
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#
|
||||
# Makefile for Windows systems using the MinGW32 environment.
|
||||
#
|
||||
# Version: @(#)Makefile.mingw 1.0.63 2018/10/18
|
||||
# Version: @(#)Makefile.mingw 1.0.64 2018/10/24
|
||||
#
|
||||
# Author: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
#
|
||||
@@ -705,6 +705,7 @@ VIDOBJ := video.o \
|
||||
vid_hercules.o vid_herculesplus.o vid_incolor.o \
|
||||
vid_colorplus.o \
|
||||
vid_genius.o \
|
||||
vid_sigma.o \
|
||||
vid_wy700.o \
|
||||
vid_ega.o vid_ega_render.o \
|
||||
vid_svga.o vid_svga_render.o \
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#
|
||||
# Makefile for Windows using Visual Studio 2015.
|
||||
#
|
||||
# Version: @(#)Makefile.VC 1.0.50 2018/10/24
|
||||
# Version: @(#)Makefile.VC 1.0.51 2018/10/24
|
||||
#
|
||||
# Author: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
#
|
||||
@@ -279,8 +279,8 @@ CXXOPTS := -EHsc
|
||||
DOPTS :=
|
||||
ifeq ($(X64), y)
|
||||
LOPTS := -MACHINE:$(ARCH) -LIBPATH:win\msvc\Lib\$(ARCH)
|
||||
#LOPTS_C := -SUBSYSTEM:CONSOLE
|
||||
#LOPTS_W := -SUBSYSTEM:WINDOWS
|
||||
LOPTS_C := -SUBSYSTEM:CONSOLE
|
||||
LOPTS_W := -SUBSYSTEM:WINDOWS
|
||||
else
|
||||
LOPTS := -MACHINE:$(ARCH) -LIBPATH:win\msvc\Lib\$(ARCH)
|
||||
LOPTS_C := -SUBSYSTEM:CONSOLE,5.01
|
||||
@@ -680,6 +680,7 @@ VIDOBJ := video.obj \
|
||||
vid_hercules.obj vid_herculesplus.obj vid_incolor.obj \
|
||||
vid_colorplus.obj \
|
||||
vid_genius.obj \
|
||||
vid_sigma.obj \
|
||||
vid_wy700.obj \
|
||||
vid_ega.obj vid_ega_render.obj \
|
||||
vid_svga.obj vid_svga_render.obj \
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
* only things used globally within the Windows platform; the
|
||||
* generic platform defintions are in the plat.h file.
|
||||
*
|
||||
* Version: @(#)win.h 1.0.22 2018/10/24
|
||||
* Version: @(#)win.h 1.0.23 2018/10/25
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -69,6 +69,9 @@
|
||||
#define WM_HARD_RESET WM_USER+5
|
||||
#define WM_SHUTDOWN WM_USER+6
|
||||
#define WM_CTRLALTDEL WM_USER+7
|
||||
#define WM_SEND_HWND WM_USER+8 /* send main window handle */
|
||||
#define WM_SEND_STATUS WM_USER+9 /* pause/resume status in WPARAM */
|
||||
#define WM_SEND_SSTATUS WM_USER+10 /* settings status: WPARAM 1=open */
|
||||
|
||||
|
||||
/* Status bar definitions. */
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
* 24bit image would be preferred, but we cant use LoadImage
|
||||
* for those (and keep transparency...)
|
||||
*
|
||||
* Version: @(#)win_about.c 1.0.11 2018/10/24
|
||||
* Version: @(#)win_about.c 1.0.12 2018/10/25
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -256,12 +256,12 @@ about_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
void
|
||||
dlg_about(void)
|
||||
{
|
||||
DialogBox(plat_lang_dll(), (LPCTSTR)DLG_ABOUT, hwndMain, about_proc);
|
||||
DialogBox(plat_lang_dll(), (LPCWSTR)DLG_ABOUT, hwndMain, about_proc);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
dlg_localize(void)
|
||||
{
|
||||
DialogBox(plat_lang_dll(), (LPCTSTR)DLG_LOCALIZE, hwndMain, localize_proc);
|
||||
DialogBox(plat_lang_dll(), (LPCWSTR)DLG_LOCALIZE, hwndMain, localize_proc);
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Implementation of the New Floppy/ZIP Image dialog.
|
||||
*
|
||||
* Version: @(#)win_new_image.c 1.0.21 2018/10/24
|
||||
* Version: @(#)win_new_image.c 1.0.22 2018/10/25
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -268,5 +268,5 @@ dlg_new_image(int drive, int part, int zip)
|
||||
drive_id = drive;
|
||||
sb_part = part;
|
||||
|
||||
DialogBox(plat_lang_dll(), (LPCTSTR)DLG_NEW_FLOPPY, hwndMain, dlg_proc);
|
||||
DialogBox(plat_lang_dll(), (LPCWSTR)DLG_NEW_FLOPPY, hwndMain, dlg_proc);
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Implementation of the Settings dialog.
|
||||
*
|
||||
* Version: @(#)win_settings.c 1.0.37 2018/10/24
|
||||
* Version: @(#)win_settings.c 1.0.37 2018/10/25
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -559,7 +559,12 @@ image_list_init(HWND hwndList)
|
||||
|
||||
|
||||
for (i = 0; i < PAGE_MAX; i++) {
|
||||
hiconItem = LoadIcon(hInstance, (LPCWSTR)icons[i]);
|
||||
#if (defined(_MSC_VER) && defined(_M_X64)) || \
|
||||
(defined(__GNUC__) && defined(__amd64__))
|
||||
hiconItem = LoadIcon(hInstance, (LPCWSTR)((uint64_t)icons[i]));
|
||||
#else
|
||||
hiconItem = LoadIcon(hInstance, (LPCWSTR)((uint32_t)icons[i]));
|
||||
#endif
|
||||
ImageList_AddIcon(hSmall, hiconItem);
|
||||
DestroyIcon(hiconItem);
|
||||
}
|
||||
@@ -592,6 +597,49 @@ insert_categories(HWND hwndList)
|
||||
}
|
||||
|
||||
|
||||
#ifdef USE_MANAGER
|
||||
static void
|
||||
communicate_closure(void)
|
||||
{
|
||||
if (source_hwnd)
|
||||
PostMessage((HWND)(uintptr_t)source_hwnd,
|
||||
WM_SEND_SSTATUS, (WPARAM)0, (LPARAM)hwndMain);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static WIN_RESULT CALLBACK
|
||||
settings_confirm(HWND hdlg, int button)
|
||||
{
|
||||
int i;
|
||||
|
||||
SendMessage(hwndChildDialog, WM_SAVE_CFG, 0, 0);
|
||||
|
||||
if (ask_sure) {
|
||||
i = msgbox_reset();
|
||||
if (i == 0) {
|
||||
/* CANCEL, just kidding! */
|
||||
return(FALSE);
|
||||
}
|
||||
} else
|
||||
i = 2;
|
||||
|
||||
if (i == 2) {
|
||||
/* YES, reset system. */
|
||||
settings_save();
|
||||
}
|
||||
|
||||
DestroyWindow(hwndChildDialog);
|
||||
EndDialog(hdlg, i);
|
||||
|
||||
#ifdef USE_MANAGER
|
||||
communicate_closure();
|
||||
#endif
|
||||
|
||||
return button ? FALSE : TRUE;
|
||||
}
|
||||
|
||||
|
||||
static WIN_RESULT CALLBACK
|
||||
dlg_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
@@ -630,33 +678,21 @@ dlg_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_CLOSE:
|
||||
return settings_confirm(hdlg, 0);
|
||||
|
||||
case WM_COMMAND:
|
||||
switch (LOWORD(wParam)) {
|
||||
case IDOK:
|
||||
SendMessage(hwndChildDialog, WM_SAVE_CFG, 0, 0);
|
||||
if (ask_sure) {
|
||||
i = msgbox_reset();
|
||||
if (i == 0) {
|
||||
/* CANCEL, just kidding! */
|
||||
return(FALSE);
|
||||
}
|
||||
} else {
|
||||
i = 2;
|
||||
}
|
||||
|
||||
if (i == 2) {
|
||||
/* YES, reset system. */
|
||||
settings_save();
|
||||
}
|
||||
|
||||
DestroyWindow(hwndChildDialog);
|
||||
EndDialog(hdlg, i);
|
||||
return(TRUE);
|
||||
return settings_confirm(hdlg, 1);
|
||||
|
||||
case IDCANCEL:
|
||||
/* CANCEL, just kidding! */
|
||||
DestroyWindow(hwndChildDialog);
|
||||
EndDialog(hdlg, 0);
|
||||
#ifdef USE_MANAGER
|
||||
communicate_closure();
|
||||
#endif
|
||||
return(TRUE);
|
||||
}
|
||||
break;
|
||||
@@ -718,6 +754,12 @@ dlg_settings(int ask)
|
||||
{
|
||||
int i;
|
||||
|
||||
#ifdef USE_MANAGER
|
||||
if (source_hwnd)
|
||||
PostMessage((HWND) (uintptr_t) source_hwnd,
|
||||
WM_SEND_SSTATUS, (WPARAM)1, (LPARAM)hwndMain;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This looks weird here, but we have to do it
|
||||
* before we open up the Settings dialog, else
|
||||
@@ -736,7 +778,8 @@ dlg_settings(int ask)
|
||||
INFO("A total of %i machines are available.\n", i);
|
||||
|
||||
ask_sure = ask;
|
||||
i = DialogBox(plat_lang_dll(), (LPCWSTR)DLG_CONFIG, hwndMain, dlg_proc);
|
||||
i = (int)DialogBox(plat_lang_dll(),
|
||||
(LPCWSTR)DLG_CONFIG, hwndMain, dlg_proc);
|
||||
|
||||
return(i);
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Implementation of the Settings dialog.
|
||||
*
|
||||
* Version: @(#)win_settings_floppy.h 1.0.9 2018/10/24
|
||||
* Version: @(#)win_settings_floppy.h 1.0.10 2018/10/25
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -59,7 +59,12 @@ floppy_image_list_init(HWND hwndList)
|
||||
ILC_MASK | ILC_COLOR32, 1, 1);
|
||||
|
||||
for (i = 0; i < 14; i++) {
|
||||
hIconItem = LoadIcon(hInstance, (LPCWSTR)ui_fdd_icon(i));
|
||||
#if (defined(_MSC_VER) && defined(_M_X64)) || \
|
||||
(defined(__GNUC__) && defined(__amd64__))
|
||||
hIconItem = LoadIcon(hInstance, (LPCWSTR)((uint64_t)ui_fdd_icon(i)));
|
||||
#else
|
||||
hIconItem = LoadIcon(hInstance, (LPCWSTR)((uint32_t)ui_fdd_icon(i)));
|
||||
#endif
|
||||
ImageList_AddIcon(hSmall, hIconItem);
|
||||
DestroyIcon(hIconItem);
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Implementation of the Sound Gain dialog.
|
||||
*
|
||||
* Version: @(#)win_snd_gain.c 1.0.9 2018/10/24
|
||||
* Version: @(#)win_snd_gain.c 1.0.10 2018/10/25
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -105,5 +105,5 @@ dlg_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
void
|
||||
dlg_sound_gain(void)
|
||||
{
|
||||
DialogBox(plat_lang_dll(), (LPCTSTR)DLG_SND_GAIN, hwndMain, dlg_proc);
|
||||
DialogBox(plat_lang_dll(), (LPCWSTR)DLG_SND_GAIN, hwndMain, dlg_proc);
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Implement the user Interface module.
|
||||
*
|
||||
* Version: @(#)win_ui.c 1.0.31 2018/10/24
|
||||
* Version: @(#)win_ui.c 1.0.32 2018/10/25
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -840,6 +840,18 @@ again:
|
||||
/* Set the PAUSE mode depending on the renderer. */
|
||||
pc_pause(0);
|
||||
|
||||
#ifdef USE_MANAGER
|
||||
/*
|
||||
* If so requested via the command line, inform the
|
||||
* application that started us of our HWND, using the
|
||||
* the hWnd and unique ID the application has given
|
||||
* us.
|
||||
*/
|
||||
if (source_hwnd)
|
||||
PostMessage((HWND) (uintptr_t) source_hwnd,
|
||||
WM_SEND_HWND, (WPARAM)unique_id, (LPARAM)hwndMain);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Everything has been configured, and all seems to work,
|
||||
* so now it is time to start the main thread to do some
|
||||
@@ -982,6 +994,19 @@ plat_fullscreen(int on)
|
||||
}
|
||||
|
||||
|
||||
/* Platform support for the PAUSE action. */
|
||||
void
|
||||
plat_pause(int paused)
|
||||
{
|
||||
#ifdef USE_MANAGER
|
||||
/* Send the WM to a manager if needed. */
|
||||
if (source_hwnd)
|
||||
PostMessage((HWND) (uintptr_t) source_hwnd,
|
||||
WM_SENDSTATUS, (WPARAM)paused, (LPARAM)hwndMain);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* Grab the current keyboard state. */
|
||||
int
|
||||
plat_kbd_state(void)
|
||||
|
||||
Reference in New Issue
Block a user