diff options
| author | 2010-06-05 19:41:27 +0000 | |
|---|---|---|
| committer | 2010-06-05 19:41:27 +0000 | |
| commit | 7ca4c4a9f5ecd885a9340958b4f4851685db810f (patch) | |
| tree | 02d4f99edc6fed9df3815b9e7672449cf7ba6c87 | |
| parent | 5803cb7b405b47cfdbcab829c57212375dec95e7 (diff) | |
pcat_nit.c update [Mariusz Wojcieszek]
- added VGA emulation from MESS
- added INS8250 emulation from MESS
- added format decimal support to Microtouch
- added rom banking and inputs to pcat_nit games
- streetg(2) now boot properly
| -rw-r--r-- | .gitattributes | 6 | ||||
| -rw-r--r-- | src/emu/emu.mak | 3 | ||||
| -rw-r--r-- | src/emu/machine/ins8250.c | 704 | ||||
| -rw-r--r-- | src/emu/machine/ins8250.h | 91 | ||||
| -rw-r--r-- | src/emu/machine/microtch.c | 64 | ||||
| -rw-r--r-- | src/emu/video/pc_vga.c | 1625 | ||||
| -rw-r--r-- | src/emu/video/pc_vga.h | 120 | ||||
| -rw-r--r-- | src/emu/video/pc_video.c | 124 | ||||
| -rw-r--r-- | src/emu/video/pc_video.h | 24 | ||||
| -rw-r--r-- | src/mame/drivers/pcat_nit.c | 420 |
10 files changed, 2894 insertions, 287 deletions
diff --git a/.gitattributes b/.gitattributes index 58780bf751a..3c384522c41 100644 --- a/.gitattributes +++ b/.gitattributes @@ -685,6 +685,8 @@ src/emu/machine/idectrl.c svneol=native#text/plain src/emu/machine/idectrl.h svneol=native#text/plain src/emu/machine/ins8154.c svneol=native#text/plain src/emu/machine/ins8154.h svneol=native#text/plain +src/emu/machine/ins8250.c svneol=native#text/plain +src/emu/machine/ins8250.h svneol=native#text/plain src/emu/machine/intelfsh.c svneol=native#text/plain src/emu/machine/intelfsh.h svneol=native#text/plain src/emu/machine/k033906.c svneol=native#text/plain @@ -1041,6 +1043,10 @@ src/emu/video/hd63484.c svneol=native#text/plain src/emu/video/hd63484.h svneol=native#text/plain src/emu/video/mc6845.c svneol=native#text/plain src/emu/video/mc6845.h svneol=native#text/plain +src/emu/video/pc_vga.c svneol=native#text/plain +src/emu/video/pc_vga.h svneol=native#text/plain +src/emu/video/pc_video.c svneol=native#text/plain +src/emu/video/pc_video.h svneol=native#text/plain src/emu/video/poly.c svneol=native#text/plain src/emu/video/poly.h svneol=native#text/plain src/emu/video/resnet.c svneol=native#text/plain diff --git a/src/emu/emu.mak b/src/emu/emu.mak index e813da0a4b8..db4b257b64f 100644 --- a/src/emu/emu.mak +++ b/src/emu/emu.mak @@ -143,6 +143,7 @@ EMUMACHINEOBJS = \ $(EMUMACHINE)/i2cmemdev.o \ $(EMUMACHINE)/idectrl.o \ $(EMUMACHINE)/ins8154.o \ + $(EMUMACHINE)/ins8250.o \ $(EMUMACHINE)/intelfsh.o \ $(EMUMACHINE)/k033906.o \ $(EMUMACHINE)/k056230.o \ @@ -190,6 +191,8 @@ EMUVIDEOOBJS = \ $(EMUVIDEO)/generic.o \ $(EMUVIDEO)/hd63484.o \ $(EMUVIDEO)/mc6845.o \ + $(EMUVIDEO)/pc_vga.o \ + $(EMUVIDEO)/pc_video.o \ $(EMUVIDEO)/poly.o \ $(EMUVIDEO)/resnet.o \ $(EMUVIDEO)/rgbutil.o \ diff --git a/src/emu/machine/ins8250.c b/src/emu/machine/ins8250.c new file mode 100644 index 00000000000..22e8fcb279b --- /dev/null +++ b/src/emu/machine/ins8250.c @@ -0,0 +1,704 @@ +/********************************************************************** + + National Semiconductor 8250 UART interface and emulation + + More information on the different models can be found in + section 1.6 at this location: + http://www.freebsd.org/doc/en_US.ISO8859-1/articles/serial-uart/ + +Model overview (from page above): + +INS8250 +This part was used in the original IBM PC and IBM PC/XT. The original name +for this part was the INS8250 ACE (Asynchronous Communications Element) and +it is made from NMOS technology. + +The 8250 uses eight I/O ports and has a one-byte send and a one-byte receive +buffer. This original UART has several race conditions and other flaws. The +original IBM BIOS includes code to work around these flaws, but this made +the BIOS dependent on the flaws being present, so subsequent parts like the +8250A, 16450 or 16550 could not be used in the original IBM PC or IBM PC/XT. + +INS8250-B +This is the slower speed of the INS8250 made from NMOS technology. It contains +the same problems as the original INS8250. + +INS8250A +An improved version of the INS8250 using XMOS technology with various functional +flaws corrected. The INS8250A was used initially in PC clone computers by vendors +who used "clean" BIOS designs. Because of the corrections in the chip, this part +could not be used with a BIOS compatible with the INS8250 or INS8250B. + +INS82C50A +This is a CMOS version (low power consumption) of the INS8250A and has similar +functional characteristics. + +NS16450 +Same as NS8250A with improvements so it can be used with faster CPU bus designs. +IBM used this part in the IBM AT and updated the IBM BIOS to no longer rely on +the bugs in the INS8250. + +NS16C450 +This is a CMOS version (low power consumption) of the NS16450. + +NS16550 +Same as NS16450 with a 16-byte send and receive buffer but the buffer design +was flawed and could not be reliably be used. + +NS16550A +Same as NS16550 with the buffer flaws corrected. The 16550A and its successors +have become the most popular UART design in the PC industry, mainly due to +its ability to reliably handle higher data rates on operating systems with +sluggish interrupt response times. + +NS16C552 +This component consists of two NS16C550A CMOS UARTs in a single package. + +PC16550D +Same as NS16550A with subtle flaws corrected. This is revision D of the +16550 family and is the latest design available from National Semiconductor. + + +Known issues: +- MESS does currently not handle all these model specific features. + + +History: + KT - 14-Jun-2000 - Improved Interrupt setting/clearing + KT - moved into seperate file so it can be used in Super I/O emulation and + any other system which uses a PC type COM port + KT - 24-Jun-2000 - removed pc specific input port tests. More compatible + with PCW16 and PCW16 doesn't requre the PC input port definitions + which are not required by the PCW16 hardware + +**********************************************************************/ + +#include "emu.h" +#include "machine/ins8250.h" + + +#define LOG(LEVEL,N,M,A) \ + do { \ + if( M ) \ + logerror("%-24s",(char*)M ); \ + logerror A; \ + } while (0) + + +/* device types */ +enum { + TYPE_INS8250 = 0, + TYPE_INS8250A, + TYPE_NS16450, + TYPE_NS16550, + TYPE_NS16550A, + TYPE_PC16550D, + + NUM_TYPES +}; + + +/* device tags */ +static const char * const device_tags[NUM_TYPES] = { "ins8250", "ins8250a", "ns16450", "ns16550", "ns16550a", "pc16550d" }; + + +#define VERBOSE_COM 0 +#define COM_LOG(n,m,a) LOG(VERBOSE_COM,n,m,a) + +typedef struct { + const ins8250_interface *interface; + int device_type; + + UINT8 thr; /* 0 -W transmitter holding register */ + UINT8 rbr; /* 0 R- receiver buffer register */ + UINT8 ier; /* 1 RW interrupt enable register */ + UINT8 dll; /* 0 RW divisor latch lsb (if DLAB = 1) */ + UINT8 dlm; /* 1 RW divisor latch msb (if DLAB = 1) */ + UINT8 iir; /* 2 R- interrupt identification register */ + UINT8 lcr; /* 3 RW line control register (bit 7: DLAB) */ + UINT8 mcr; /* 4 RW modem control register */ + UINT8 lsr; /* 5 R- line status register */ + UINT8 msr; /* 6 R- modem status register */ + UINT8 scr; /* 7 RW scratch register */ + +/* holds int pending state for com */ + UINT8 int_pending; + + // sending circuit + struct { + int active; + UINT8 data; + double time; + } send; +} ins8250_t; + +/* int's pending */ +#define COM_INT_PENDING_RECEIVED_DATA_AVAILABLE 0x0001 +#define COM_INT_PENDING_TRANSMITTER_HOLDING_REGISTER_EMPTY 0x0002 +#define COM_INT_PENDING_RECEIVER_LINE_STATUS 0x0004 +#define COM_INT_PENDING_MODEM_STATUS_REGISTER 0x0008 + + +INLINE ins8250_t *get_safe_token(running_device *device) +{ + assert( device != NULL ); + assert( device->token != NULL ); + assert( ( device->type == DEVICE_GET_INFO_NAME(ins8250) ) || + ( device->type == DEVICE_GET_INFO_NAME(ins8250a) ) || + ( device->type == DEVICE_GET_INFO_NAME(ns16450) ) || + ( device->type == DEVICE_GET_INFO_NAME(ns16550) ) || + ( device->type == DEVICE_GET_INFO_NAME(ns16550a) ) || + ( device->type == DEVICE_GET_INFO_NAME(pc16550d) ) ); + return ( ins8250_t *) device->token; +} + + +/* setup iir with the priority id */ +static void ins8250_setup_iir(running_device *device) +{ + ins8250_t *ins8250 = get_safe_token(device); + + ins8250->iir &= ~(0x04|0x02); + + /* highest to lowest */ + if (ins8250->ier & ins8250->int_pending & COM_INT_PENDING_RECEIVER_LINE_STATUS) + { + ins8250->iir |=0x04|0x02; + return; + } + + if (ins8250->ier & ins8250->int_pending & COM_INT_PENDING_RECEIVED_DATA_AVAILABLE) + { + ins8250->iir |=0x04; + return; + } + + if (ins8250->ier & ins8250->int_pending & COM_INT_PENDING_TRANSMITTER_HOLDING_REGISTER_EMPTY) + { + ins8250->iir |=0x02; + return; + } + + /* modem status has both bits clear */ +} + + +/* ints will continue to be set for as long as there are ints pending */ +static void ins8250_update_interrupt(running_device *device) +{ + ins8250_t *ins8250 = get_safe_token(device); + int state; + + /* if any bits are set and are enabled */ + if (((ins8250->int_pending&ins8250->ier) & 0x0f) != 0) + { + /* trigger next highest priority int */ + + /* set int */ + state = 1; + ins8250_setup_iir(device); + + /* int pending */ + ins8250->iir &= ~0x01; + } + else + { + /* clear int */ + state = 0; + + /* no ints pending */ + ins8250->iir |= 0x01; + /* priority level */ + ins8250->iir &= ~(0x04|0x02); + } + + /* set or clear the int */ + if (ins8250->interface->interrupt) + ins8250->interface->interrupt(device, state); +} + + + +/* set pending bit and trigger int */ +static void ins8250_trigger_int(running_device *device, int flag) +{ + ins8250_t *ins8250 = get_safe_token(device); + + ins8250->int_pending |= flag; + ins8250_update_interrupt(device); +} + + + +/* clear pending bit, if any ints are pending, then int will be triggered, otherwise it +will be cleared */ +static void ins8250_clear_int(running_device *device, int flag) +{ + ins8250_t *ins8250 = get_safe_token(device); + + ins8250->int_pending &= ~flag; + ins8250_update_interrupt(device); +} + + +WRITE8_DEVICE_HANDLER( ins8250_w ) +{ + static const char P[] = "NONENHNL"; /* names for parity select */ + ins8250_t *ins8250 = get_safe_token(device); + int tmp; + + switch (offset) + { + case 0: + if (ins8250->lcr & 0x80) + { + ins8250->dll = data; + tmp = ins8250->dlm * 256 + ins8250->dll; + COM_LOG(1,"COM_dll_w",("COM \"%s\" $%02x: [$%04x = %d baud]\n", device->tag(), + data, tmp, (tmp)?(int)(ins8250->interface->clockin/16/tmp):0)); + } + else + { + ins8250->thr = data; + COM_LOG(2,"COM_thr_w",("COM $%02x\n", data)); + + if ( ins8250->mcr & 0x10 ) + { + ins8250->lsr |= 1; + ins8250->rbr = data; + ins8250_trigger_int( device, COM_INT_PENDING_RECEIVED_DATA_AVAILABLE ); + } + + if ( ins8250->interface->transmit ) + ins8250->interface->transmit(device, ins8250->thr); + + /* writing to thr will clear the int */ + ins8250_clear_int(device, COM_INT_PENDING_TRANSMITTER_HOLDING_REGISTER_EMPTY); + } + break; + case 1: + if (ins8250->lcr & 0x80) + { + ins8250->dlm = data; + tmp = ins8250->dlm * 256 + ins8250->dll; + COM_LOG(1,"COM_dlm_w",("COM \"%s\" $%02x: [$%04x = %d baud]\n", device->tag(), + data, tmp, (tmp)?(int)(ins8250->interface->clockin/16/tmp):0)); + } + else + { + ins8250->ier = data; + COM_LOG(2,"COM_ier_w",("COM \"%s\" $%02x: enable int on RX %d, THRE %d, RLS %d, MS %d\n", device->tag(), + data, data&1, (data>>1)&1, (data>>2)&1, (data>>3)&1)); + COM_LOG(2,"COM_ier_w",("COM \"%s\" lsr = $%02x, int_pending = $%02x\n", device->tag(), ins8250->lsr, ins8250->int_pending )); + ins8250_update_interrupt(device); + } + break; + case 2: + COM_LOG(1,"COM_fcr_w",("COM \"%s\" $%02x (16550 only)\n", device->tag(), data)); + break; + case 3: + ins8250->lcr = data; + COM_LOG(1,"COM_lcr_w",("COM \"%s\" $%02x word length %d, stop bits %d, parity %c, break %d, DLAB %d\n", device->tag(), + data, 5+(data&3), 1+((data>>2)&1), P[(data>>3)&7], (data>>6)&1, (data>>7)&1)); + break; + case 4: + if ( ( ins8250->mcr & 0x1f ) != ( data & 0x1f ) ) + { + ins8250->mcr = data & 0x1f; + COM_LOG(1,"COM_mcr_w",("COM \"%s\" $%02x DTR %d, RTS %d, OUT1 %d, OUT2 %d, loopback %d\n", device->tag(), + data, data&1, (data>>1)&1, (data>>2)&1, (data>>3)&1, (data>>4)&1)); + if (ins8250->interface->handshake_out) + ins8250->interface->handshake_out(device,data); + + if ( ins8250->mcr & 0x10 ) /* loopback test */ + { + data = ( ( ins8250->mcr & 0x0c ) << 4 ) | ( ( ins8250->mcr & 0x01 ) << 5 ) | ( ( ins8250->mcr & 0x02 ) << 3 ); + if ( ( ins8250->msr & 0x20 ) != ( data & 0x20 ) ) + { + data |= 0x02; + } + if ( ( ins8250->msr & 0x10 ) != ( data & 0x10 ) ) + { + data |= 0x01; + } + if ( ( ins8250->msr & 0x40 ) && ! ( data & 0x40 ) ) + { + data |= 0x04; + } + if ( ( ins8250->msr & 0x80 ) != ( data & 0x80 ) ) + { + data |= 0x08; + } + ins8250->msr = data; + } + } + break; + case 5: + /* + This register can be written, but if you write a 1 bit into any of + bits 5 - 0, you could cause an interrupt if the appropriate IER bit + is set. + */ + COM_LOG(1,"COM_lsr_w",("COM \"%s\" $%02x\n", device->tag(), data )); + + ins8250->lsr = data; + + tmp = 0; + tmp |= ( ins8250->lsr & 0x01 ) ? COM_INT_PENDING_RECEIVED_DATA_AVAILABLE : 0; + tmp |= ( ins8250->lsr & 0x1e ) ? COM_INT_PENDING_RECEIVER_LINE_STATUS : 0; + tmp |= ( ins8250->lsr & 0x20 ) ? COM_INT_PENDING_TRANSMITTER_HOLDING_REGISTER_EMPTY : 0; + ins8250_trigger_int( device, tmp ); + + break; + case 6: + /* + This register can be written, but if you write a 1 bit into any of + bits 3 - 0, you could cause an interrupt if the appropriate IER bit + is set. + */ + COM_LOG(1,"COM_msr_w",("COM \"%s\" $%02x\n", device->tag(), data )); + + ins8250->msr = data; + + if ( ins8250->msr & 0x0f ) + { + ins8250_trigger_int( device, COM_INT_PENDING_MODEM_STATUS_REGISTER ); + } + break; + case 7: + ins8250->scr = data; + COM_LOG(2,"COM_scr_w",("COM \"%s\" $%02x\n", device->tag(), data)); + break; + } + + if (ins8250->interface->refresh_connected) + ins8250->interface->refresh_connected(device); +} + + + +READ8_DEVICE_HANDLER( ins8250_r ) +{ + ins8250_t *ins8250 = get_safe_token(device); + int data = 0x0ff; + + switch (offset) + { + case 0: + if (ins8250->lcr & 0x80) + { + data = ins8250->dll; + COM_LOG(1,"COM_dll_r",("COM \"%s\" $%02x\n", device->tag(), data)); + } + else + { + data = ins8250->rbr; + if( ins8250->lsr & 0x01 ) + { + ins8250->lsr &= ~0x01; /* clear data ready status */ + COM_LOG(2,"COM_rbr_r",("COM \"%s\" $%02x\n", device->tag(), data)); + } + + ins8250_clear_int(device, COM_INT_PENDING_RECEIVED_DATA_AVAILABLE); + } + break; + case 1: + if (ins8250->lcr & 0x80) + { + data = ins8250->dlm; + COM_LOG(1,"COM_dlm_r",("COM \"%s\" $%02x\n", device->tag(), data)); + } + else + { + data = ins8250->ier & 0x0f; + COM_LOG(2,"COM_ier_r",("COM \"%s\" $%02x\n", device->tag(), data)); + } + break; + case 2: + data = ins8250->iir; + COM_LOG(2,"COM_iir_r",("COM \"%s\" $%02x\n", device->tag(), data)); + /* The documentation says that reading this register will + clear the int if this is the source of the int */ + if ( ins8250->ier & COM_INT_PENDING_TRANSMITTER_HOLDING_REGISTER_EMPTY ) + { + ins8250_clear_int(device, COM_INT_PENDING_TRANSMITTER_HOLDING_REGISTER_EMPTY); + } + break; + case 3: + data = ins8250->lcr; + COM_LOG(2,"COM_lcr_r",("COM \"%s\" $%02x\n", device->tag(), data)); + break; + case 4: + data = ins8250->mcr; + COM_LOG(2,"COM_mcr_r",("COM \"%s\" $%02x\n", device->tag(), data)); + break; + case 5: + +#if 0 + if (ins8250->send.active && (timer_get_time(machine)-ins8250->send.time>uart_byte_time(n))) + { + // currently polling is enough for pc1512 + ins8250->lsr |= 0x40; /* set TSRE */ + ins8250->send.active = 0; + if ( ins8250->mcr & 0x10 ) + { + ins8250->lsr |= 1; + ins8250->rbr = ins8250->send.data; + } + } +#endif + ins8250->lsr |= 0x20; /* set THRE */ + data = ins8250->lsr; + if( ins8250->lsr & 0x1f ) + { + ins8250->lsr &= 0xe1; /* clear FE, PE and OE and BREAK bits */ + COM_LOG(2,"COM_lsr_r",("COM \"%s\" $%02x, DR %d, OE %d, PE %d, FE %d, BREAK %d, THRE %d, TSRE %d\n", device->tag(), + data, data&1, (data>>1)&1, (data>>2)&1, (data>>3)&1, (data>>4)&1, (data>>5)&1, (data>>6)&1)); + } + + /* reading line status register clears int */ + ins8250_clear_int(device, COM_INT_PENDING_RECEIVER_LINE_STATUS); + break; + case 6: + data = ins8250->msr; + ins8250->msr &= 0xf0; /* reset delta values */ + COM_LOG(2,"COM_msr_r",("COM \"%s\" $%02x\n", device->tag(), data)); + + /* reading msr clears int */ + ins8250_clear_int(device, COM_INT_PENDING_MODEM_STATUS_REGISTER); + + break; + case 7: + data = ins8250->scr; + COM_LOG(2,"COM_scr_r",("COM \"%s\" $%02x\n", device->tag(), data)); + break; + } + + if (ins8250->interface->refresh_connected) + ins8250->interface->refresh_connected(device); + + return data; +} + + + +void ins8250_receive(running_device *device, int data) +{ + ins8250_t *ins8250 = get_safe_token(device); + + /* check if data rate 1200 baud is set */ + if( ins8250->dlm != 0x00 || ins8250->dll != 0x60 ) + ins8250->lsr |= 0x08; /* set framing error */ + + /* if data not yet serviced */ + if( ins8250->lsr & 0x01 ) + ins8250->lsr |= 0x02; /* set overrun error */ + + /* put data into receiver buffer register */ + ins8250->rbr = data; + + /* set data ready status */ + ins8250->lsr |= 0x01; + + /* set pending state for this interrupt. */ + ins8250_trigger_int(device, COM_INT_PENDING_RECEIVED_DATA_AVAILABLE); + + +// /* OUT2 + received line data avail interrupt enabled? */ +// if( (COM_mcr[n] & 0x08) && (COM_ier[n] & 0x01) ) +// { +// if (com_interface.interrupt) +// com_interface.interrupt(4-(n&1), 1); +// +// } +} + +/************************************************************************** + * change the modem status register + **************************************************************************/ +void ins8250_handshake_in(running_device *device, int new_msr) +{ + ins8250_t *ins8250 = get_safe_token(device); + + /* no change in modem status bits? */ + if( ((ins8250->msr ^ new_msr) & 0xf0) == 0 ) + return; + + /* set delta status bits 0..3 and new modem status bits 4..7 */ + ins8250->msr = (((ins8250->msr ^ new_msr) >> 4) & 0x0f) | (new_msr & 0xf0); + + ins8250_trigger_int(device, COM_INT_PENDING_MODEM_STATUS_REGISTER); + +// /* set up interrupt information register */ + // COM_iir[n] &= ~(0x06 | 0x01); + +// /* OUT2 + modem status interrupt enabled? */ +// if( (COM_mcr[n] & 0x08) && (COM_ier[n] & 0x08) ) +// { +// if (com_interface.interrupt) +// com_interface.interrupt(4-(n&1), 1); +// } +} + + +static void common_start( running_device *device, int device_type ) +{ + ins8250_t *ins8250 = get_safe_token(device); + + ins8250->interface = (const ins8250_interface*)device->baseconfig().static_config; + ins8250->device_type = device_type; +} + + +static DEVICE_START( ins8250 ) +{ + common_start( device, TYPE_INS8250 ); +} + + +static DEVICE_START( ins8250a ) +{ + common_start( device, TYPE_INS8250A ); +} + + +static DEVICE_START( ns16450 ) +{ + common_start( device, TYPE_NS16450 ); +} + + +static DEVICE_START( ns16550 ) +{ + common_start( device, TYPE_NS16550 ); +} + + +static DEVICE_START( ns16550a ) +{ + common_start( device, TYPE_NS16550A ); +} + + +static DEVICE_START( pc16550d ) +{ + common_start( device, TYPE_PC16550D ); +} + + +static DEVICE_RESET( ins8250 ) +{ + ins8250_t *ins8250 = get_safe_token(device); + + ins8250->ier = 0; + ins8250->iir = 1; + ins8250->lcr = 0; + ins8250->mcr = 0; + ins8250->lsr = (1<<5) | (1<<6); + + ins8250->send.active=0; + + /* refresh with reset state of register */ + if (ins8250->interface->refresh_connected) + ins8250->interface->refresh_connected(device); +} + + +DEVICE_GET_INFO( ins8250 ) +{ + switch ( state ) + { + /* --- the following bits of info are returned as 64-bit signed integers --- */ + case DEVINFO_INT_TOKEN_BYTES: info->i = sizeof(ins8250_t); break; + case DEVINFO_INT_INLINE_CONFIG_BYTES: info->i = 0; break; + case DEVINFO_INT_CLASS: info->i = DEVICE_CLASS_PERIPHERAL; break; + + /* --- the following bits of info are returned as pointers to data or functions --- */ + case DEVINFO_FCT_START: info->start = DEVICE_START_NAME(ins8250); break; + case DEVINFO_FCT_STOP: /* nothing */ break; + case DEVINFO_FCT_RESET: info->reset = DEVICE_RESET_NAME(ins8250); break; + + /* --- the following bits of info are returned as NULL-terminated strings --- */ + case DEVINFO_STR_NAME: strcpy(info->s, "National Semiconductor INS8250/INS8250B"); break; + case DEVINFO_STR_FAMILY: strcpy(info->s, "INS8250"); break; + case DEVINFO_STR_VERSION: strcpy(info->s, "1.00"); break; + case DEVINFO_STR_SOURCE_FILE: strcpy(info->s, __FILE__); break; + case DEVINFO_STR_CREDITS: strcpy(info->s, "Copyright the MESS Team"); break; + } +} + + +DEVICE_GET_INFO( ins8250a ) +{ + switch ( state ) + { + /* --- the following bits of info are returned as 64-bit signed integers --- */ + case DEVINFO_STR_NAME: strcpy(info->s, "National Semiconductor INS8250A/INS82C50A"); break; + + /* --- the following bits of info are returned as pointers to data or functions --- */ + case DEVINFO_FCT_START: info->start = DEVICE_START_NAME(ins8250a); break; + + default: DEVICE_GET_INFO_CALL(ins8250); break; + } +} + + +DEVICE_GET_INFO( ns16450 ) +{ + switch ( state ) + { + /* --- the following bits of info are returned as 64-bit signed integers --- */ + case DEVINFO_STR_NAME: strcpy(info->s, "National Semiconductor NS16450/PC16450"); break; + + /* --- the following bits of info are returned as pointers to data or functions --- */ + case DEVINFO_FCT_START: info->start = DEVICE_START_NAME(ns16450); break; + + default: DEVICE_GET_INFO_CALL(ins8250); break; + } +} + + +DEVICE_GET_INFO( ns16550 ) +{ + switch ( state ) + { + /* --- the following bits of info are returned as 64-bit signed integers --- */ + case DEVINFO_STR_NAME: strcpy(info->s, "National Semiconductor NS16550/PC16550"); break; + + /* --- the following bits of info are returned as pointers to data or functions --- */ + case DEVINFO_FCT_START: info->start = DEVICE_START_NAME(ns16550); break; + + default: DEVICE_GET_INFO_CALL(ins8250); break; + } +} + + +DEVICE_GET_INFO( ns16550a ) +{ + switch ( state ) + { + /* --- the following bits of info are returned as 64-bit signed integers --- */ + case DEVINFO_STR_NAME: strcpy(info->s, "National Semiconductor NS16550A/PC16550A"); break; + + /* --- the following bits of info are returned as pointers to data or functions --- */ + case DEVINFO_FCT_START: info->start = DEVICE_START_NAME(ns16550a); break; + + default: DEVICE_GET_INFO_CALL(ins8250); break; + } +} + + +DEVICE_GET_INFO( pc16550d ) +{ + switch ( state ) + { + /* --- the following bits of info are returned as 64-bit signed integers --- */ + case DEVINFO_STR_NAME: strcpy(info->s, "National Semiconductor PC16550D"); break; + + /* --- the following bits of info are returned as pointers to data or functions --- */ + case DEVINFO_FCT_START: info->start = DEVICE_START_NAME(pc16550d); break; + + default: DEVICE_GET_INFO_CALL(ins8250); break; + } +} + diff --git a/src/emu/machine/ins8250.h b/src/emu/machine/ins8250.h new file mode 100644 index 00000000000..d5570ecd775 --- /dev/null +++ b/src/emu/machine/ins8250.h @@ -0,0 +1,91 @@ +/********************************************************************** + + 8250 UART interface and emulation + +**********************************************************************/ + +#ifndef __INS8250_H_ +#define __INS8250_H_ + +#define INS8250 DEVICE_GET_INFO_NAME(ins8250) +#define INS8250A DEVICE_GET_INFO_NAME(ins8250a) +#define NS16450 DEVICE_GET_INFO_NAME(ns16450) +#define NS16550 DEVICE_GET_INFO_NAME(ns16550) +#define NS16550A DEVICE_GET_INFO_NAME(ns16550a) +#define PC16550D DEVICE_GET_INFO_NAME(pc16550d) + +#define UART8250_HANDSHAKE_OUT_DTR 0x01 +#define UART8250_HANDSHAKE_OUT_RTS 0x02 + +#define UART8250_HANDSHAKE_IN_DSR 0x020 +#define UART8250_HANDSHAKE_IN_CTS 0x010 +#define UART8250_INPUTS_RING_INDICATOR 0x0040 +#define UART8250_INPUTS_DATA_CARRIER_DETECT 0x0080 + + +/*************************************************************************** + TYPE DEFINITIONS +***************************************************************************/ + +typedef void (*ins8250_interrupt_func)(running_device *device, int state); +typedef void (*ins8250_transmit_func)(running_device *device, int data); +typedef void (*ins8250_handshake_out_func)(running_device *device, int data); +typedef void (*ins8250_refresh_connect_func)(running_device *device); + +#define INS8250_INTERRUPT(name) void name(running_device *device, int state) +#define INS8250_TRANSMIT(name) void name(running_device *device, int data) +#define INS8250_HANDSHAKE_OUT(name) void name(running_device *device, int data) +#define INS8250_REFRESH_CONNECT(name) void name(running_device *device) + +typedef struct +{ + long clockin; + ins8250_interrupt_func interrupt; + + ins8250_transmit_func transmit; + ins8250_handshake_out_func handshake_out; + + // refresh object connected to this port + ins8250_refresh_connect_func refresh_connected; +} ins8250_interface; + + +/*************************************************************************** + DEVICE CONFIGURATION MACROS +***************************************************************************/ + +#define MDRV_INS8250_ADD(_tag, _intrf) \ + MDRV_DEVICE_ADD(_tag, INS8250, 0) \ + MDRV_DEVICE_CONFIG(_intrf) + + +#define MDRV_NS16450_ADD(_tag, _intrf) \ + MDRV_DEVICE_ADD(_tag, NS16450, 0) \ + MDRV_DEVICE_CONFIG(_intrf) + + +#define MDRV_NS16550_ADD(_tag, _intrf) \ + MDRV_DEVICE_ADD(_tag, NS16550, 0) \ + MDRV_DEVICE_CONFIG(_intrf) + + +/*************************************************************************** + FUNCTION PROTOTYPES +***************************************************************************/ + +void ins8250_receive(running_device *device, int data); +void ins8250_handshake_in(running_device *device, int new_msr); + +READ8_DEVICE_HANDLER( ins8250_r ); +WRITE8_DEVICE_HANDLER( ins8250_w ); + +/* device interface */ +DEVICE_GET_INFO( ins8250 ); +DEVICE_GET_INFO( ins8250a ); +DEVICE_GET_INFO( ns16450 ); +DEVICE_GET_INFO( ns16550 ); +DEVICE_GET_INFO( ns16550a ); +DEVICE_GET_INFO( pc16550d ); + + +#endif /* __INS8250_H_ */ diff --git a/src/emu/machine/microtch.c b/src/emu/machine/microtch.c index 6e502054dc8..c82d827fc69 100644 --- a/src/emu/machine/microtch.c +++ b/src/emu/machine/microtch.c @@ -5,13 +5,15 @@ Notes/ToDo: - calibration mode (command CX) - - only tablet format is supported for returning touch screen state + - only tablet format and decimal format are supported for returning touch screen state */ #include "emu.h" #include "microtch.h" +#define LOG 0 + static struct { UINT8 rx_buffer[16]; @@ -22,6 +24,7 @@ static struct UINT8 tx_buffer_ptr; int reset_done; int format_tablet; + int format_decimal; int mode_inactive; int mode_stream; int last_touch_state; @@ -60,6 +63,33 @@ static void microtouch_send_format_table_packet(UINT8 flag, int x, int y) microtouch.tx_buffer[microtouch.tx_buffer_num++] = (y >> 7) & 0x7f; }; +static void microtouch_send_format_decimal_packet(int x, int y) +{ + int decx, decy; + + decx = x / 16; + if ( decx > 999 ) + decx = 999; + decy = y / 16; + if ( decy > 999 ) + decy = 999; + + // header byte + microtouch.tx_buffer[microtouch.tx_buffer_num++] = 0x01; + // x coordinate in decimal mode + microtouch.tx_buffer[microtouch.tx_buffer_num++] = (decx / 100) + '0'; + microtouch.tx_buffer[microtouch.tx_buffer_num++] = ((decx / 10) % 10) + '0'; + microtouch.tx_buffer[microtouch.tx_buffer_num++] = (decx % 10) + '0'; + // comma (separator) + microtouch.tx_buffer[microtouch.tx_buffer_num++] = ','; + // y coordinate in decimal mode + microtouch.tx_buffer[microtouch.tx_buffer_num++] = (decy / 100) + '0'; + microtouch.tx_buffer[microtouch.tx_buffer_num++] = ((decy / 10) % 10) + '0'; + microtouch.tx_buffer[microtouch.tx_buffer_num++] = (decy % 10) + '0'; + // terminator + microtouch.tx_buffer[microtouch.tx_buffer_num++] = 0x0d; +} + static TIMER_CALLBACK(microtouch_timer_callback) { if ( microtouch.tx_buffer_ptr < microtouch.tx_buffer_num ) @@ -73,7 +103,7 @@ static TIMER_CALLBACK(microtouch_timer_callback) } if ( (microtouch.reset_done == 0) || - (microtouch.format_tablet == 0) || + ((microtouch.format_tablet == 0) && (microtouch.format_decimal == 0)) || (microtouch.mode_inactive == 1) || (microtouch.mode_stream == 0) ) { @@ -91,7 +121,14 @@ static TIMER_CALLBACK(microtouch_timer_callback) { ty = 0x4000 - ty; - microtouch_send_format_table_packet(0xc8, tx, ty); + if ( microtouch.format_tablet ) + { + microtouch_send_format_table_packet(0xc8, tx, ty); + } + else if ( microtouch.format_decimal ) + { + microtouch_send_format_decimal_packet(tx, ty); + } microtouch.last_touch_state = 1; microtouch.last_x = tx; microtouch.last_y = ty; @@ -102,7 +139,14 @@ static TIMER_CALLBACK(microtouch_timer_callback) if ( microtouch.last_touch_state == 1 ) { microtouch.last_touch_state = 0; - microtouch_send_format_table_packet(0x88, microtouch.last_x, microtouch.last_y); + if ( microtouch.format_tablet ) + { + microtouch_send_format_table_packet(0x88, microtouch.last_x, microtouch.last_y); + } + else if ( microtouch.format_decimal ) + { + microtouch_send_format_decimal_packet(microtouch.last_x, microtouch.last_y); + } } } }; @@ -130,6 +174,7 @@ void microtouch_init(running_machine *machine, microtouch_tx_func tx_cb, microto state_save_register_item_array(machine, "microtouch", NULL, 0, microtouch.tx_buffer); state_save_register_item(machine, "microtouch", NULL, 0, microtouch.tx_buffer_num); state_save_register_item(machine, "microtouch", NULL, 0, microtouch.tx_buffer_ptr); + state_save_register_item(machine, "microtouch", NULL, 0, microtouch.format_decimal); }; @@ -146,6 +191,13 @@ void microtouch_rx(int count, UINT8* data) if (microtouch.rx_buffer_ptr > 0 && (microtouch.rx_buffer[microtouch.rx_buffer_ptr-1] == 0x0d)) { + if (LOG) + { + char command[16]; + memset(command, 0, sizeof(command)); + strncpy( command, (const char*)microtouch.rx_buffer + 1, microtouch.rx_buffer_ptr - 2 ); + logerror("Microtouch: received command %s\n", command); + } // check command if ( microtouch_check_command( "MS", microtouch.rx_buffer_ptr, microtouch.rx_buffer ) ) { @@ -165,6 +217,10 @@ void microtouch_rx(int count, UINT8* data) { microtouch.format_tablet = 1; } + else if ( microtouch_check_command( "FD", microtouch.rx_buffer_ptr, microtouch.rx_buffer ) ) + { + microtouch.format_decimal = 1; + } // send response microtouch.tx_buffer[microtouch.tx_buffer_num++] = 0x01; microtouch.tx_buffer[microtouch.tx_buffer_num++] = 0x30; diff --git a/src/emu/video/pc_vga.c b/src/emu/video/pc_vga.c new file mode 100644 index 00000000000..f9e92bd3d0f --- /dev/null +++ b/src/emu/video/pc_vga.c @@ -0,0 +1,1625 @@ +/*************************************************************************** + + Video Graphics Adapter (VGA) section + + Nathan Woods npwoods@mess.org + Peter Trauner PeT mess@utanet.at + + This code takes care of installing the various VGA memory and port + handlers + + The VGA standard is compatible with MDA, CGA, Hercules, EGA + (mda, cga, hercules not real register compatible) + several vga cards drive also mda, cga, ega monitors + some vga cards have register compatible mda, cga, hercules modes + + ega/vga + 64k (early ega 16k) words of 32 bit memory + + + ROM declarations: + + (oti 037 chip) + ROM_LOAD("oakvga.bin", 0xc0000, 0x8000, 0x318c5f43) + (tseng labs famous et4000 isa vga card (oem)) + ROM_LOAD("et4000b.bin", 0xc0000, 0x8000, 0xa903540d) + (tseng labs famous et4000 isa vga card) + ROM_LOAD("et4000.bin", 0xc0000, 0x8000, 0xf01e4be0) + +***************************************************************************/ + +#include "emu.h" +#include "pc_vga.h" +#include "pc_video.h" + +#include "memconv.h" + +/*************************************************************************** + + Static declarations + +***************************************************************************/ + +#define LOG_ACCESSES 0 +#define LOG_REGISTERS 0 + +static const char* vga_crtc_reg_names[] = +{ + "Horizontal Total Register", + "End Horizontal Display Register", + "Start Horizontal Blanking Register", + "End Horizontal Blanking Register", + "Start Horizontal Retrace Register", + "End Horizontal Retrace Register", + "Vertical Total Register", + "Overflow Register", + "Preset Row Scan Register", + "Maximum Scan Line Register", + "Cursor Start Register", + "Cursor End Register", + "Start Address High Register", + "Start Address Low Register", + "Cursor Location High Register", + "Cursor Location Low Register", + "Vertical Retrace Start Register", + "Vertical Retrace End Register", + "Vertical Display End Register", + "Offset Register", + "Underline Location Register", + "Start Vertical Blanking Register", + "End Vertical Blanking", + "CRTC Mode Control Register", + "Line Compare Register" +}; + + +static PALETTE_INIT( ega ); +static PALETTE_INIT( vga ); +static VIDEO_START( ega ); +static VIDEO_START( vga ); +static VIDEO_RESET( ega ); +static VIDEO_RESET( vga ); + +static pc_video_update_proc pc_vga_choosevideomode(running_machine *machine, int *width, int *height); +static pc_video_update_proc pc_ega_choosevideomode(running_machine *machine, int *width, int *height); + +/*************************************************************************** + + MachineDriver stuff + +***************************************************************************/ + +/* grabbed from dac inited by et4000 bios */ +static const unsigned char ega_palette[] = +{ + 0x00, 0x00, 0x00, + 0x00, 0x00, 0xa8, + 0x00, 0xa8, 0x00, + 0x00, 0xa8, 0xa8, + 0xa8, 0x00, 0x00, + 0xa8, 0x00, 0xa8, + 0xa8, 0x54, 0x00, + 0xa8, 0xa8, 0xa8, + 0x00, 0x00, 0x00, + 0x00, 0x00, 0xa8, + 0x00, 0xa8, 0x00, + 0x00, 0xa8, 0xa8, + 0xa8, 0x00, 0x00, + 0xa8, 0x00, 0xa8, + 0xa8, 0x54, 0x00, + 0xa8, 0xa8, 0xa8, + 0x54, 0x54, 0x54, + 0x54, 0x54, 0xfc, + 0x54, 0xfc, 0x54, + 0x54, 0xfc, 0xfc, + 0xfc, 0x54, 0x54, + 0xfc, 0x54, 0xfc, + 0xfc, 0xfc, 0x54, + 0xfc, 0xfc, 0xfc, + 0x54, 0x54, 0x54, + 0x54, 0x54, 0xfc, + 0x54, 0xfc, 0x54, + 0x54, 0xfc, 0xfc, + 0xfc, 0x54, 0x54, + 0xfc, 0x54, 0xfc, + 0xfc, 0xfc, 0x54, + 0xfc, 0xfc, 0xfc, + 0x00, 0x00, 0x00, + 0x00, 0x00, 0xa8, + 0x00, 0xa8, 0x00, + 0x00, 0xa8, 0xa8, + 0xa8, 0x00, 0x00, + 0xa8, 0x00, 0xa8, + 0xa8, 0x54, 0x00, + 0xa8, 0xa8, 0xa8, + 0x00, 0x00, 0x00, + 0x00, 0x00, 0xa8, + 0x00, 0xa8, 0x00, + 0x00, 0xa8, 0xa8, + 0xa8, 0x00, 0x00, + 0xa8, 0x00, 0xa8, + 0xa8, 0x54, 0x00, + 0xa8, 0xa8, 0xa8, + 0x54, 0x54, 0x54, + 0x54, 0x54, 0xfc, + 0x54, 0xfc, 0x54, + 0x54, 0xfc, 0xfc, + 0xfc, 0x54, 0x54, + 0xfc, 0x54, 0xfc, + 0xfc, 0xfc, 0x54, + 0xfc, 0xfc, 0xfc, + 0x54, 0x54, 0x54, + 0x54, 0x54, 0xfc, + 0x54, 0xfc, 0x54, + 0x54, 0xfc, 0xfc, + 0xfc, 0x54, 0x54, + 0xfc, 0x54, 0xfc, + 0xfc, 0xfc, 0x54, + 0xfc, 0xfc, 0xfc +}; + +static const unsigned short vga_colortable[] = +{ + 0, 0, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 8, 0, 9, 0,10, 0,11, 0,12, 0,13, 0,14, 0,15, + 1, 0, 1, 1, 1, 2, 1, 3, 1, 4, 1, 5, 1, 6, 1, 7, 1, 8, 1, 9, 1,10, 1,11, 1,12, 1,13, 1,14, 1,15, + 2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 2, 5, 2, 6, 2, 7, 2, 8, 2, 9, 2,10, 2,11, 2,12, 2,13, 2,14, 2,15, + 3, 0, 3, 1, 3, 2, 3, 3, 3, 4, 3, 5, 3, 6, 3, 7, 3, 8, 3, 9, 3,10, 3,11, 3,12, 3,13, 3,14, 3,15, + 4, 0, 4, 1, 4, 2, 4, 3, 4, 4, 4, 5, 4, 6, 4, 7, 4, 8, 4, 9, 4,10, 4,11, 4,12, 4,13, 4,14, 4,15, + 5, 0, 5, 1, 5, 2, 5, 3, 5, 4, 5, 5, 5, 6, 5, 7, 5, 8, 5, 9, 5,10, 5,11, 5,12, 5,13, 5,14, 5,15, + 6, 0, 6, 1, 6, 2, 6, 3, 6, 4, 6, 5, 6, 6, 6, 7, 6, 8, 6, 9, 6,10, 6,11, 6,12, 6,13, 6,14, 6,15, + 7, 0, 7, 1, 7, 2, 7, 3, 7, 4, 7, 5, 7, 6, 7, 7, 7, 8, 7, 9, 7,10, 7,11, 7,12, 7,13, 7,14, 7,15, +/* flashing is done by dirtying the videoram buffer positions with attr bit #7 set */ + 8, 0, 8, 1, 8, 2, 8, 3, 8, 4, 8, 5, 8, 6, 8, 7, 8, 8, 8, 9, 8,10, 8,11, 8,12, 8,13, 8,14, 8,15, + 9, 0, 9, 1, 9, 2, 9, 3, 9, 4, 9, 5, 9, 6, 9, 7, 9, 8, 9, 9, 9,10, 9,11, 9,12, 9,13, 9,14, 9,15, + 10, 0,10, 1,10, 2,10, 3,10, 4,10, 5,10, 6,10, 7,10, 8,10, 9,10,10,10,11,10,12,10,13,10,14,10,15, + 11, 0,11, 1,11, 2,11, 3,11, 4,11, 5,11, 6,11, 7,11, 8,11, 9,11,10,11,11,11,12,11,13,11,14,11,15, + 12, 0,12, 1,12, 2,12, 3,12, 4,12, 5,12, 6,12, 7,12, 8,12, 9,12,10,12,11,12,12,12,13,12,14,12,15, + 13, 0,13, 1,13, 2,13, 3,13, 4,13, 5,13, 6,13, 7,13, 8,13, 9,13,10,13,11,13,12,13,13,13,14,13,15, + 14, 0,14, 1,14, 2,14, 3,14, 4,14, 5,14, 6,14, 7,14, 8,14, 9,14,10,14,11,14,12,14,13,14,14,14,15, + 15, 0,15, 1,15, 2,15, 3,15, 4,15, 5,15, 6,15, 7,15, 8,15, 9,15,10,15,11,15,12,15,13,15,14,15,15 +}; + +MACHINE_DRIVER_START( pcvideo_vga ) + MDRV_SCREEN_ADD("screen", RASTER) + MDRV_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16) + MDRV_SCREEN_SIZE(720, 480) + MDRV_SCREEN_VISIBLE_AREA(0,720-1, 0,480-1) + MDRV_PALETTE_LENGTH(0x100) + MDRV_PALETTE_INIT(vga) + + MDRV_VIDEO_START(vga) + MDRV_VIDEO_RESET(vga) + MDRV_VIDEO_UPDATE(pc_video) +MACHINE_DRIVER_END + +MACHINE_DRIVER_START( pcvideo_pc1640 ) + MDRV_SCREEN_ADD("screen", RASTER) + MDRV_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16) + MDRV_SCREEN_SIZE(720, 350) + MDRV_SCREEN_VISIBLE_AREA(0,720-1, 0,350-1) + MDRV_PALETTE_LENGTH(sizeof(ega_palette) / 3) + MDRV_PALETTE_INIT(ega) + + MDRV_VIDEO_START(ega) + MDRV_VIDEO_RESET(ega) + MDRV_VIDEO_UPDATE(pc_video) +MACHINE_DRIVER_END + +/***************************************************************************/ + +static PALETTE_INIT( ega ) +{ + int i; + + for ( i = 0; i < sizeof(ega_palette) / 3; i++ ) { + palette_set_color_rgb(machine, i, ega_palette[i*3], ega_palette[i*3+1], ega_palette[i*3+2]); + } +} + +static PALETTE_INIT( vga ) +{ + int i; + for (i = 0; i < 0x100; i++) + palette_set_color_rgb(machine, i, 0, 0, 0); +} + +static UINT8 color_bitplane_to_packed[4/*plane*/][8/*pixel*/][256]; + +static struct +{ + struct pc_vga_interface vga_intf; + struct pc_svga_interface svga_intf; + + UINT8 *memory; + UINT8 *fontdirty; + UINT16 pens[16]; /* the current 16 pens */ + + UINT8 miscellaneous_output; + UINT8 feature_control; + UINT16 line_compare; // for split-screen use. + + struct + { + UINT8 index; + UINT8 *data; + } sequencer; + struct + { + UINT8 index; + UINT8 *data; + } crtc; + struct + { + UINT8 index; + UINT8 *data; + UINT8 latch[4]; + } gc; + struct { UINT8 index, data[0x15]; int state; } attribute; + + + struct { + UINT8 read_index, write_index, mask; + int read; + int state; + struct { UINT8 red, green, blue; } color[0x100]; + int dirty; + } dac; + + struct { + int time; + int visible; + } cursor; + + struct { + int (*get_clock)(void); + + int (*get_lines)(void); + int (*get_sync_lines)(void); + + int (*get_columns)(void); + int (*get_sync_columns)(void); + + attotime start_time; + int retrace; + } monitor; + + /* oak vga */ + struct { UINT8 reg; } oak; + + int log; +} vga; + + +// to use the mscrtc6845 macros +#define REG(x) vga.crtc.data[x] + +#define DOUBLESCAN ((vga.crtc.data[9]&0x80)||((vga.crtc.data[9]&0x1f)!=0) ) +#define CRTC_PORT_ADDR ((vga.miscellaneous_output&1)?0x3d0:0x3b0) + +#define CRTC_ON (vga.crtc.data[0x17]&0x80) + +#define LINES_HELPER ( (vga.crtc.data[0x12] \ + |((vga.crtc.data[7]&2)<<7) \ + |((vga.crtc.data[7]&0x40)<<3))+1 ) +//#define TEXT_LINES (LINES_HELPER) +#define LINES (DOUBLESCAN?LINES_HELPER>>1:LINES_HELPER) +#define TEXT_LINES (LINES_HELPER >> ((vga.crtc.data[9]&0x80) ? 1 : 0)) + +#define GRAPHIC_MODE (vga.gc.data[6]&1) /* else textmodus */ + +#define EGA_COLUMNS (vga.crtc.data[1]+1) +#define EGA_START_ADDRESS ((vga.crtc.data[0xd]|(vga.crtc.data[0xc]<<8))<<2) +#define EGA_LINE_LENGTH (vga.crtc.data[0x13]<<3) + +#define VGA_COLUMNS (EGA_COLUMNS>>1) +#define VGA_START_ADDRESS (EGA_START_ADDRESS) +#define VGA_LINE_LENGTH (EGA_LINE_LENGTH<<2) + +#define CHAR_WIDTH ((vga.sequencer.data[1]&1)?8:9) +//#define CHAR_HEIGHT ((vga.crtc.data[9]&0x1f)+1) + +#define TEXT_COLUMNS (vga.crtc.data[1]+1) +#define TEXT_START_ADDRESS (EGA_START_ADDRESS) +#define TEXT_LINE_LENGTH (EGA_LINE_LENGTH>>2) + +#define TEXT_COPY_9COLUMN(ch) ( (ch>=192)&&(ch<=223)&&(vga.attribute.data[0x10]&4)) + +//#define CURSOR_ON (!(vga.crtc.data[0xa]&0x20)) +//#define CURSOR_STARTLINE (vga.crtc.data[0xa]&0x1f) +//#define CURSOR_ENDLINE (vga.crtc.data[0xb]&0x1f) +//#define CURSOR_POS (vga.crtc.data[0xf]|(vga.crtc.data[0xe]<<8)) + +#define FONT1 ( ((vga.sequencer.data[3]&3)|((vga.sequencer.data[3]&0x10)<<2))*0x2000) +#define FONT2 ((((vga.sequencer.data[3]&c)>>2)|((vga.sequencer.data[3]&0x20)<<3))*0x2000) + +#define CRTC6845_COLUMNS (REG(0)+1) +#define CRTC6845_CHAR_COLUMNS (REG(1)) +#define CRTC6845_LINES (REG(4)*CRTC6845_CHAR_HEIGHT+REG(5)) +#define CRTC6845_CHAR_LINES REG(6) +#define CRTC6845_CHAR_HEIGHT ((REG(9)&0x1f)+1) +#define CRTC6845_VIDEO_START ((REG(0xc)<<8)|REG(0xd)) +#define CRTC6845_INTERLACE_MODE (REG(8)&3) +#define CRTC6845_INTERLACE_SIGNAL 1 +#define CRTC6845_INTERLACE 3 +#define CRTC6845_CURSOR_MODE (REG(0xa)&0x60) +#define CRTC6845_CURSOR_OFF 0x20 +#define CRTC6845_CURSOR_16FRAMES 0x40 +#define CRTC6845_CURSOR_32FRAMES 0x60 +#define CRTC6845_SKEW (REG(8)&15) +#define CRTC6845_CURSOR_POS ((REG(0xe)<<8)|REG(0xf)) +#define CRTC6845_CURSOR_TOP (REG(0xa)&0x1f) +#define CRTC6845_CURSOR_BOTTOM REG(0xb) + +INLINE UINT8 rotate_right(UINT8 val, UINT8 rot) +{ + return (val >> rot) | (val << (8 - rot)); +} + + + +static int ega_get_clock(void) +{ + int clck=0; + switch(vga.miscellaneous_output&0xc) { + case 0: clck=14000000;break; + case 4: clck=16000000;break; + /* case 8: external */ + /* case 0xc: reserved */ + } + if (vga.sequencer.data[1]&8) clck/=2; + return clck; +} + +static int vga_get_clock(void) +{ + int clck=0; + switch(vga.miscellaneous_output&0xc) { + case 0: clck=25000000;break; + case 4: clck=28000000;break; + /* case 8: external */ + /* case 0xc: reserved */ + } + if (vga.sequencer.data[1]&8) clck/=2; + return clck; +} + +static int ega_get_crtc_columns(void) /* in clocks! */ +{ + int columns=vga.crtc.data[0]+2; + if (!GRAPHIC_MODE) { + columns*=CHAR_WIDTH; + } else { + columns*=8; + } + return columns; +} + +static int ega_get_crtc_lines(void) +{ + int lines=vga.crtc.data[6]|((vga.crtc.data[7]&1)); + + return lines; +} + +static int vga_get_crtc_columns(void) /* in clocks! */ +{ + int columns=vga.crtc.data[0]+5; + + if (!GRAPHIC_MODE) + columns *= CHAR_WIDTH; + else if (vga.gc.data[5]&0x40) + columns *= 4; + else + columns *= 8; + + return columns; +} + +static int vga_get_crtc_lines(void) +{ + int lines=(vga.crtc.data[6] + |((vga.crtc.data[7]&1)<<8) + |((vga.crtc.data[7]&0x20)<<(8-4)))+2; + + return lines; +} + +static int vga_get_crtc_sync_lines(void) +{ + return 10; +} + +static int vga_get_crtc_sync_columns(void) +{ + return 40; +} + +INLINE WRITE8_HANDLER(vga_dirty_w) +{ + vga.memory[offset] = data; +} + +INLINE WRITE8_HANDLER(vga_dirty_font_w) +{ + if (vga.memory[offset] != data) + { + vga.memory[offset] = data; + if ((offset&3)==2) + vga.fontdirty[offset>>7]=1; + } +} + +static READ8_HANDLER(vga_text_r) +{ + int data; + data=vga.memory[((offset&~1)<<1)|(offset&1)]; + + return data; +} + +static WRITE8_HANDLER(vga_text_w) +{ + vga_dirty_w(space, ((offset&~1)<<1)|(offset&1),data); +} + +INLINE UINT8 ega_bitplane_to_packed(UINT8 *latch, int number) +{ + return color_bitplane_to_packed[0][number][latch[0]] + |color_bitplane_to_packed[1][number][latch[1]] + |color_bitplane_to_packed[2][number][latch[2]] + |color_bitplane_to_packed[3][number][latch[3]]; +} + +static READ8_HANDLER(vga_ega_r) +{ + int data; + vga.gc.latch[0]=vga.memory[(offset<<2)]; + vga.gc.latch[1]=vga.memory[(offset<<2)+1]; + vga.gc.latch[2]=vga.memory[(offset<<2)+2]; + vga.gc.latch[3]=vga.memory[(offset<<2)+3]; + if (vga.gc.data[5]&8) { + data=0; + if (!(ega_bitplane_to_packed(vga.gc.latch, 0)^(vga.gc.data[2]&0xf&~vga.gc.data[7]))) data|=1; + if (!(ega_bitplane_to_packed(vga.gc.latch, 1)^(vga.gc.data[2]&0xf&~vga.gc.data[7]))) data|=2; + if (!(ega_bitplane_to_packed(vga.gc.latch, 2)^(vga.gc.data[2]&0xf&~vga.gc.data[7]))) data|=4; + if (!(ega_bitplane_to_packed(vga.gc.latch, 3)^(vga.gc.data[2]&0xf&~vga.gc.data[7]))) data|=8; + if (!(ega_bitplane_to_packed(vga.gc.latch, 4)^(vga.gc.data[2]&0xf&~vga.gc.data[7]))) data|=0x10; + if (!(ega_bitplane_to_packed(vga.gc.latch, 5)^(vga.gc.data[2]&0xf&~vga.gc.data[7]))) data|=0x20; + if (!(ega_bitplane_to_packed(vga.gc.latch, 6)^(vga.gc.data[2]&0xf&~vga.gc.data[7]))) data|=0x40; + if (!(ega_bitplane_to_packed(vga.gc.latch, 7)^(vga.gc.data[2]&0xf&~vga.gc.data[7]))) data|=0x80; + } else { + data=vga.gc.latch[vga.gc.data[4]&3]; + } + + return data; +} + +INLINE UINT8 vga_latch_helper(UINT8 cpu, UINT8 latch, UINT8 mask) +{ + switch (vga.gc.data[3] & 0x18) + { + case 0x00: + return rotate_right((cpu&mask)|(latch&~mask), vga.gc.data[3] & 0x07); + case 0x08: + return rotate_right(((cpu&latch)&mask)|(latch&~mask), vga.gc.data[3] & 0x07); + case 0x10: + return rotate_right(((cpu|latch)&mask)|(latch&~mask), vga.gc.data[3] & 0x07); + case 0x18: + return rotate_right(((cpu^latch)&mask)|(latch&~mask), vga.gc.data[3] & 0x07); + } + return 0; /* must not be reached, suppress compiler warning */ +} + +INLINE UINT8 vga_latch_write(int offs, UINT8 data) +{ + switch (vga.gc.data[5]&3) { + case 0: + if (vga.gc.data[1]&(1<<offs)) { + return vga_latch_helper( (vga.gc.data[0]&(1<<offs))?vga.gc.data[8]:0, + vga.gc.latch[offs],vga.gc.data[8] ); + } else { + return vga_latch_helper(data, vga.gc.latch[offs], vga.gc.data[8]); + } + break; + case 1: + return vga.gc.latch[offs]; + case 2: + if (data&(1<<offs)) { + return vga_latch_helper(0xff, vga.gc.latch[offs], vga.gc.data[8]); + } else { + return vga_latch_helper(0, vga.gc.latch[offs], vga.gc.data[8]); + } + break; + case 3: + if (vga.gc.data[0]&(1<<offs)) { + return vga_latch_helper(0xff, vga.gc.latch[offs], data&vga.gc.data[8]); + } else { + return vga_latch_helper(0, vga.gc.latch[offs], data&vga.gc.data[8]); + } + break; + } + return 0; /* must not be reached, suppress compiler warning */ +} + +static WRITE8_HANDLER(vga_ega_w) +{ + if (vga.sequencer.data[2]&1) + vga_dirty_w(space, offset<<2, vga_latch_write(0,data)); + if (vga.sequencer.data[2]&2) + vga_dirty_w(space, (offset<<2)+1, vga_latch_write(1,data)); + if (vga.sequencer.data[2]&4) + vga_dirty_font_w(space, (offset<<2)+2, vga_latch_write(2,data)); + if (vga.sequencer.data[2]&8) + vga_dirty_w(space, (offset<<2)+3, vga_latch_write(3,data)); + if ((offset==0xffff)&&(data==0)) vga.log=1; +} + +static READ8_HANDLER(vga_vga_r) +{ + int data; + data=vga.memory[((offset&~3)<<2)|(offset&3)]; + + return data; +} + +static WRITE8_HANDLER(vga_vga_w) +{ + vga_dirty_font_w(space, ((offset&~3)<<2)|(offset&3),data); +} + +/* 16 bit */ +static READ16_HANDLER( vga_text16_r ) { return read16le_with_read8_handler(vga_text_r, space, offset, mem_mask); } +static READ16_HANDLER( vga_vga16_r ) { return read16le_with_read8_handler(vga_vga_r, space, offset, mem_mask); } +static WRITE16_HANDLER( vga_text16_w ) { write16le_with_write8_handler(vga_text_w, space, offset, data, mem_mask); } +static WRITE16_HANDLER( vga_vga16_w ) { write16le_with_write8_handler(vga_vga_w, space, offset, data, mem_mask); } + +static READ16_HANDLER( vga_ega16_r ) { return read16le_with_read8_handler(vga_ega_r, space, offset, mem_mask); } +static WRITE16_HANDLER( vga_ega16_w ) { write16le_with_write8_handler(vga_ega_w, space, offset, data, mem_mask); } + +/* 32 bit */ +static READ32_HANDLER( vga_text32_r ) { return read32le_with_read8_handler(vga_text_r, space, offset, mem_mask); } +static READ32_HANDLER( vga_vga32_r ) { return read32le_with_read8_handler(vga_vga_r, space, offset, mem_mask); } +static WRITE32_HANDLER( vga_text32_w ) { write32le_with_write8_handler(vga_text_w, space, offset, data, mem_mask); } +static WRITE32_HANDLER( vga_vga32_w ) { write32le_with_write8_handler(vga_vga_w, space, offset, data, mem_mask); } + +static READ32_HANDLER( vga_ega32_r ) { return read32le_with_read8_handler(vga_ega_r, space, offset, mem_mask); } +static WRITE32_HANDLER( vga_ega32_w ) { write32le_with_write8_handler(vga_ega_w, space, offset, data, mem_mask); } + +/* 64 bit */ +static READ64_HANDLER( vga_text64_r ) { return read64be_with_read8_handler(vga_text_r, space, offset, mem_mask); } +static READ64_HANDLER( vga_vga64_r ) { return read64be_with_read8_handler(vga_vga_r, space, offset, mem_mask); } +static WRITE64_HANDLER( vga_text64_w ) { write64be_with_write8_handler(vga_text_w, space, offset, data, mem_mask); } +static WRITE64_HANDLER( vga_vga64_w ) { write64be_with_write8_handler(vga_vga_w, space, offset, data, mem_mask); } + +static READ64_HANDLER( vga_ega64_r ) { return read64be_with_read8_handler(vga_ega_r, space, offset, mem_mask); } +static WRITE64_HANDLER( vga_ega64_w ) { write64be_with_write8_handler(vga_ega_w, space, offset, data, mem_mask); } + +static void vga_cpu_interface(running_machine *machine) +{ + const address_space *space = cpu_get_address_space(machine->firstcpu, ADDRESS_SPACE_PROGRAM); + static int sequencer, gc; + read8_space_func read_handler; + write8_space_func write_handler; + read16_space_func read_handler16; + write16_space_func write_handler16; + read32_space_func read_handler32; + write32_space_func write_handler32; + read64_space_func read_handler64; + write64_space_func write_handler64; + UINT8 sel; + int buswidth; + + if ((gc==vga.gc.data[6])&&(sequencer==vga.sequencer.data[4])) return; + + gc=vga.gc.data[6]; + sequencer=vga.sequencer.data[4]; + + if (vga.sequencer.data[4]&8) + { + read_handler = vga_vga_r; + write_handler = vga_vga_w; + read_handler16 = vga_vga16_r; + write_handler16 = vga_vga16_w; + read_handler32 = vga_vga32_r; + write_handler32 = vga_vga32_w; + read_handler64 = vga_vga64_r; + write_handler64 = vga_vga64_w; + } + else if (vga.sequencer.data[4] & 4) + { + read_handler = vga_ega_r; + write_handler = vga_ega_w; + read_handler16 = vga_ega16_r; + write_handler16 = vga_ega16_w; + read_handler32 = vga_ega32_r; + write_handler32 = vga_ega32_w; + read_handler64 = vga_ega64_r; + write_handler64 = vga_ega64_w; + } + else + { + read_handler = vga_text_r; + write_handler = vga_text_w; + read_handler16 = vga_text16_r; + write_handler16 = vga_text16_w; + read_handler32 = vga_text32_r; + write_handler32 = vga_text32_w; + read_handler64 = vga_text64_r; + write_handler64 = vga_text64_w; + } + + /* remap the VGA memory */ + + if (vga.vga_intf.map_vga_memory) + { + sel = vga.gc.data[6] & 0x0c; + switch(sel) + { + case 0x00: + if (vga.vga_intf.vga_memory_bank != NULL) + { + vga.vga_intf.map_vga_memory(machine, 0xA0000, 0xBFFFF, read_handler, write_handler); + memory_set_bankptr(machine, vga.vga_intf.vga_memory_bank, vga.memory); + } + break; + case 0x04: + vga.vga_intf.map_vga_memory(machine, 0xA0000, 0xAFFFF, read_handler, write_handler); + break; + case 0x08: + vga.vga_intf.map_vga_memory(machine, 0xB0000, 0xB7FFF, read_handler, write_handler); + break; + case 0x0C: + vga.vga_intf.map_vga_memory(machine, 0xB8000, 0xBFFFF, read_handler, write_handler); + break; + } + } + else + { + buswidth = machine->firstcpu->databus_width(AS_PROGRAM); + switch(buswidth) + { + case 8: + sel = vga.gc.data[6] & 0x0c; + if (sel) + { + if (sel == 0x04) memory_install_read8_handler(space, 0xa0000, 0xaffff, 0, 0, read_handler ); else memory_nop_read(space, 0xa0000, 0xaffff, 0, 0); + if (sel == 0x08) memory_install_read8_handler(space, 0xb0000, 0xb7fff, 0, 0, read_handler ); else memory_nop_read(space, 0xb0000, 0xb7fff, 0, 0); + if (sel == 0x0C) memory_install_read8_handler(space, 0xb8000, 0xbffff, 0, 0, read_handler ); else memory_nop_read(space, 0xb8000, 0xbffff, 0, 0); + if (sel == 0x04) memory_install_write8_handler(space, 0xa0000, 0xaffff, 0, 0, write_handler); else memory_nop_write(space, 0xa0000, 0xaffff, 0, 0); + if (sel == 0x08) memory_install_write8_handler(space, 0xb0000, 0xb7fff, 0, 0, write_handler); else memory_nop_write(space, 0xb0000, 0xb7fff, 0, 0); + if (sel == 0x0C) memory_install_write8_handler(space, 0xb8000, 0xbffff, 0, 0, write_handler); else memory_nop_write(space, 0xb8000, 0xbffff, 0, 0); + } + else + { + memory_install_read_bank(space, 0xa0000, 0xbffff, 0, 0, "vgabank" ); + memory_install_write_bank(space, 0xa0000, 0xbffff, 0, 0, "vgabank" ); + memory_set_bankptr(machine,"vgabank", vga.memory); + } + break; + + case 16: + sel = vga.gc.data[6] & 0x0c; + if (sel) + { + if (sel == 0x04) memory_install_read16_handler(space, 0xa0000, 0xaffff, 0, 0, read_handler16 ); else memory_nop_read(space, 0xa0000, 0xaffff, 0, 0); + if (sel == 0x08) memory_install_read16_handler(space, 0xb0000, 0xb7fff, 0, 0, read_handler16 ); else memory_nop_read(space, 0xb0000, 0xb7fff, 0, 0); + if (sel == 0x0C) memory_install_read16_handler(space, 0xb8000, 0xbffff, 0, 0, read_handler16 ); else memory_nop_read(space, 0xb8000, 0xbffff, 0, 0); + if (sel == 0x04) memory_install_write16_handler(space, 0xa0000, 0xaffff, 0, 0, write_handler16); else memory_nop_write(space, 0xa0000, 0xaffff, 0, 0); + if (sel == 0x08) memory_install_write16_handler(space, 0xb0000, 0xb7fff, 0, 0, write_handler16); else memory_nop_write(space, 0xb0000, 0xb7fff, 0, 0); + if (sel == 0x0C) memory_install_write16_handler(space, 0xb8000, 0xbffff, 0, 0, write_handler16); else memory_nop_write(space, 0xb8000, 0xbffff, 0, 0); + } + else + { + memory_install_read_bank(space, 0xa0000, 0xbffff, 0, 0, "vgabank" ); + memory_install_write_bank(space, 0xa0000, 0xbffff, 0, 0, "vgabank" ); + memory_set_bankptr(machine,"vgabank", vga.memory); + } + break; + + case 32: + sel = vga.gc.data[6] & 0x0c; + if (sel) + { + if (sel == 0x04) memory_install_read32_handler(space, 0xa0000, 0xaffff, 0, 0, read_handler32 ); else memory_nop_read(space, 0xa0000, 0xaffff, 0, 0); + if (sel == 0x08) memory_install_read32_handler(space, 0xb0000, 0xb7fff, 0, 0, read_handler32 ); else memory_nop_read(space, 0xb0000, 0xb7fff, 0, 0); + if (sel == 0x0C) memory_install_read32_handler(space, 0xb8000, 0xbffff, 0, 0, read_handler32 ); else memory_nop_read(space, 0xb8000, 0xbffff, 0, 0); + if (sel == 0x04) memory_install_write32_handler(space, 0xa0000, 0xaffff, 0, 0, write_handler32); else memory_nop_write(space, 0xa0000, 0xaffff, 0, 0); + if (sel == 0x08) memory_install_write32_handler(space, 0xb0000, 0xb7fff, 0, 0, write_handler32); else memory_nop_write(space, 0xb0000, 0xb7fff, 0, 0); + if (sel == 0x0C) memory_install_write32_handler(space, 0xb8000, 0xbffff, 0, 0, write_handler32); else memory_nop_write(space, 0xb8000, 0xbffff, 0, 0); + } + else + { + memory_install_read_bank(space, 0xa0000, 0xbffff, 0, 0, "vgabank" ); + memory_install_write_bank(space, 0xa0000, 0xbffff, 0, 0, "vgabank" ); + memory_set_bankptr(machine,"vgabank", vga.memory); + } + break; + + case 64: + sel = vga.gc.data[6] & 0x0c; + if (sel) + { + if (sel == 0x04) memory_install_read64_handler(space, 0xa0000, 0xaffff, 0, 0, read_handler64 ); else memory_nop_read(space, 0xa0000, 0xaffff, 0, 0); + if (sel == 0x08) memory_install_read64_handler(space, 0xb0000, 0xb7fff, 0, 0, read_handler64 ); else memory_nop_read(space, 0xb0000, 0xb7fff, 0, 0); + if (sel == 0x0C) memory_install_read64_handler(space, 0xb8000, 0xbffff, 0, 0, read_handler64 ); else memory_nop_read(space, 0xb8000, 0xbffff, 0, 0); + if (sel == 0x04) memory_install_write64_handler(space, 0xa0000, 0xaffff, 0, 0, write_handler64); else memory_nop_write(space, 0xa0000, 0xaffff, 0, 0); + if (sel == 0x08) memory_install_write64_handler(space, 0xb0000, 0xb7fff, 0, 0, write_handler64); else memory_nop_write(space, 0xb0000, 0xb7fff, 0, 0); + if (sel == 0x0C) memory_install_write64_handler(space, 0xb8000, 0xbffff, 0, 0, write_handler64); else memory_nop_write(space, 0xb8000, 0xbffff, 0, 0); + } + else + { + memory_install_read_bank(space, 0xa0000, 0xbffff, 0, 0, "vgabank" ); + memory_install_write_bank(space, 0xa0000, 0xbffff, 0, 0, "vgabank" ); + memory_set_bankptr(machine,"vgabank", vga.memory); + } + break; + + default: + fatalerror("VGA: Bus width %d not supported\n", buswidth); + break; + } + } +} + +static READ8_HANDLER(vga_crtc_r) +{ + UINT8 data = 0xff; + + switch (offset) { + case 4: + data = vga.crtc.index; + break; + case 5: + if (vga.crtc.index < vga.svga_intf.crtc_regcount) + data = vga.crtc.data[vga.crtc.index]; + break; + case 0xa: + vga.attribute.state = 0; + data = 0;/*4; */ +#if 0 /* slow */ + { + int clock=vga.monitor.get_clock(); + int lines=vga.monitor.get_lines(); + int columns=vga.monitor.get_columns(); + int diff = (attotime_mul(attotime_sub(timer_get_time(space->machine), vga.monitor.start_time), clock).seconds) + %(lines*columns); + if (diff<columns*vga.monitor.get_sync_lines()) data|=8; + diff=diff/lines; + if (diff%columns<vga.monitor.get_sync_columns()) data|=1; + } +#elif 1 + if (vga.monitor.retrace) + { + data |= 1; + if (attotime_compare(attotime_sub(timer_get_time(space->machine), vga.monitor.start_time), ATTOTIME_IN_USEC(300)) > 0) + { + data |= 8; + vga.monitor.retrace=0; + } + } + else + { + if (attotime_compare(attotime_sub(timer_get_time(space->machine), vga.monitor.start_time), ATTOTIME_IN_MSEC(15)) > 0) + vga.monitor.retrace=1; + vga.monitor.start_time=timer_get_time(space->machine); + } +#else + // not working with ps2m30 + if (vga.monitor.retrace) data|=9; + vga.monitor.retrace=0; +#endif + /* ega diagnostic readback enough for oak bios */ + switch (vga.attribute.data[0x12]&0x30) { + case 0: + if (vga.attribute.data[0x11]&1) data|=0x10; + if (vga.attribute.data[0x11]&4) data|=0x20; + break; + case 0x10: + data|=(vga.attribute.data[0x11]&0x30); + break; + case 0x20: + if (vga.attribute.data[0x11]&2) data|=0x10; + if (vga.attribute.data[0x11]&8) data|=0x20; + break; + case 0x30: + data|=(vga.attribute.data[0x11]&0xc0)>>2; + break; + } + break; + case 0xf: + /* oak test */ + data=0; + /* pega bios on/off */ + data=0x80; + break; + } + return data; +} + +static WRITE8_HANDLER(vga_crtc_w) +{ + switch (offset) + { + case 0xa: + vga.feature_control = data; + break; + + case 4: + vga.crtc.index = data; + break; + + case 5: + if (LOG_REGISTERS) + { + logerror("vga_crtc_w(): CRTC[0x%02X %s] = 0x%02X\n", + vga.crtc.index, + (vga.crtc.index < vga.svga_intf.crtc_regcount) ? vga_crtc_reg_names[vga.crtc.index] : "?", + data); + } + if(vga.crtc.index == 0x18 || vga.crtc.index == 0x07 || vga.crtc.index == 0x19 ) // Line compare + vga.line_compare = (((vga.crtc.data[0x09] & 0x40) << 3) | ((vga.crtc.data[0x07] & 0x10) << 4) | vga.crtc.data[0x18])/2; + if (vga.crtc.index < vga.svga_intf.crtc_regcount) + vga.crtc.data[vga.crtc.index] = data; + break; + } +} + + + +READ8_HANDLER( vga_port_03b0_r ) +{ + UINT8 data = 0xff; + if (CRTC_PORT_ADDR==0x3b0) + data=vga_crtc_r(space, offset); + return data; +} + + + +READ8_HANDLER( ega_port_03c0_r) +{ + UINT8 data = 0xff; + switch (offset) { + case 2: data=0xff;/*!*/break; + } + return data; +} + +READ8_HANDLER( vga_port_03c0_r ) +{ + UINT8 data = 0xff; + + switch (offset) + { + case 1: + if (vga.attribute.state==0) + { + data = vga.attribute.index; + } + else + { + if ((vga.attribute.index&0x1f)<sizeof(vga.attribute.data)) + data=vga.attribute.data[vga.attribute.index&0x1f]; + } + break; + + case 2: + data = 0; + switch ((vga.miscellaneous_output>>2)&3) + { + case 3: + if (vga.vga_intf.read_dipswitch && vga.vga_intf.read_dipswitch(space, 0) & 0x01) + data |= 0x10; + break; + case 2: + if (vga.vga_intf.read_dipswitch && vga.vga_intf.read_dipswitch(space, 0) & 0x02) + data |= 0x10; + break; + case 1: + if (vga.vga_intf.read_dipswitch && vga.vga_intf.read_dipswitch(space, 0) & 0x04) + data |= 0x10; + break; + case 0: + if (vga.vga_intf.read_dipswitch && vga.vga_intf.read_dipswitch(space, 0) & 0x08) + data |= 0x10; + break; + } + break; + + case 3: + data = vga.oak.reg; + break; + + case 4: + data = vga.sequencer.index; + break; + + case 5: + if (vga.sequencer.index < vga.svga_intf.seq_regcount) + data = vga.sequencer.data[vga.sequencer.index]; + break; + + case 6: + data = vga.dac.mask; + break; + + case 7: + if (vga.dac.read) + data = 0; + else + data = 3; + break; + + case 8: + data = vga.dac.write_index; + break; + + case 9: + if (vga.dac.read) + { + switch (vga.dac.state++) + { + case 0: + data = vga.dac.color[vga.dac.read_index].red; + break; + case 1: + data = vga.dac.color[vga.dac.read_index].green; + break; + case 2: + data = vga.dac.color[vga.dac.read_index].blue; + break; + } + + if (vga.dac.state==3) + { + vga.dac.state = 0; + vga.dac.read_index++; + } + } + break; + + case 0xa: + data = vga.feature_control; + break; + + case 0xc: + data = vga.miscellaneous_output; + break; + + case 0xe: + data = vga.gc.index; + break; + + case 0xf: + if (vga.gc.index < vga.svga_intf.gc_regcount) + data = vga.gc.data[vga.gc.index]; + break; + } + return data; +} + +READ8_HANDLER(vga_port_03d0_r) +{ + UINT8 data = 0xff; + if (CRTC_PORT_ADDR == 0x3d0) + data = vga_crtc_r(space, offset); + return data; +} + +WRITE8_HANDLER( vga_port_03b0_w ) +{ + if (LOG_ACCESSES) + logerror("vga_port_03b0_w(): port=0x%04x data=0x%02x\n", offset + 0x3b0, data); + + if (CRTC_PORT_ADDR == 0x3b0) + vga_crtc_w(space, offset, data); +} + +WRITE8_HANDLER(vga_port_03c0_w) +{ + if (LOG_ACCESSES) + logerror("vga_port_03c0_w(): port=0x%04x data=0x%02x\n", offset + 0x3c0, data); + + switch (offset) { + case 0: + if (vga.attribute.state==0) + { + vga.attribute.index=data; + } + else + { + if ((vga.attribute.index&0x1f)<sizeof(vga.attribute.data)) + vga.attribute.data[vga.attribute.index&0x1f]=data; + } + vga.attribute.state=!vga.attribute.state; + break; + case 2: + vga.miscellaneous_output=data; + break; + case 3: + vga.oak.reg = data; + break; + case 4: + vga.sequencer.index = data; + break; + case 5: + if (LOG_REGISTERS) + { + logerror("vga_port_03c0_w(): SEQ[0x%02X%s] = 0x%02X\n", + vga.sequencer.index, + (vga.sequencer.index < vga.svga_intf.seq_regcount) ? "" : "?", + data); + } + if (vga.sequencer.index < vga.svga_intf.seq_regcount) + { + vga.sequencer.data[vga.sequencer.index] = data; + vga_cpu_interface(space->machine); + + if (vga.sequencer.index == 0) + vga.monitor.start_time = timer_get_time(space->machine); + } + break; + case 6: + vga.dac.mask=data; + break; + case 7: + vga.dac.read_index=data; + vga.dac.state=0; + vga.dac.read=1; + break; + case 8: + vga.dac.write_index=data; + vga.dac.state=0; + vga.dac.read=0; + break; + case 9: + if (!vga.dac.read) + { + switch (vga.dac.state++) { + case 0: + vga.dac.color[vga.dac.write_index].red=data; + break; + case 1: + vga.dac.color[vga.dac.write_index].green=data; + break; + case 2: + vga.dac.color[vga.dac.write_index].blue=data; + break; + } + vga.dac.dirty=1; + if (vga.dac.state==3) { + vga.dac.state=0; vga.dac.write_index++; +#if 0 + if (vga.dac.write_index==64) { + int i; + mame_printf_debug("start palette\n"); + for (i=0;i<64;i++) { + mame_printf_debug(" 0x%.2x, 0x%.2x, 0x%.2x,\n", + vga.dac.color[i].red*4, + vga.dac.color[i].green*4, + vga.dac.color[i].blue*4); + } + } +#endif + } + } + break; + case 0xe: + vga.gc.index=data; + break; + case 0xf: + if (LOG_REGISTERS) + { + logerror("vga_port_03c0_w(): GC[0x%02X%s] = 0x%02X\n", + vga.gc.index, + (vga.gc.index < vga.svga_intf.gc_regcount) ? "" : "?", + data); + } + if (vga.gc.index < vga.svga_intf.gc_regcount) + { + vga.gc.data[vga.gc.index] = data; + vga_cpu_interface(space->machine); + } + break; + } +} + + + +WRITE8_HANDLER(vga_port_03d0_w) +{ + if (LOG_ACCESSES) + logerror("vga_port_03d0_w(): port=0x%04x data=0x%02x\n", offset + 0x3d0, data); + + if (CRTC_PORT_ADDR == 0x3d0) + vga_crtc_w(space, offset, data); +} + + + +READ8_HANDLER( paradise_ega_03c0_r ) +{ + UINT8 data = vga_port_03c0_r(space, offset); + + if (offset == 2) + { + if ( (vga.feature_control&3)==2 ) { + data=(data&~0x60)|((vga.vga_intf.read_dipswitch(space, 0)&0xc0)>>1); + } else if ((vga.feature_control&3)==1 ) { + data=(data&~0x60)|((vga.vga_intf.read_dipswitch(space, 0)&0x30)<<1); + } + } + return data; +} + + + +void pc_vga_reset(running_machine *machine) +{ + /* clear out the VGA structure */ + memset(vga.pens, 0, sizeof(vga.pens)); + vga.miscellaneous_output = 1; + vga.feature_control = 0; + vga.sequencer.index = 0; + memset(vga.sequencer.data, 0, vga.svga_intf.seq_regcount * sizeof(*vga.sequencer.data)); + vga.crtc.index = 0; + memset(vga.crtc.data, 0, vga.svga_intf.crtc_regcount * sizeof(*vga.crtc.data)); + vga.gc.index = 0; + memset(vga.gc.data, 0, vga.svga_intf.gc_regcount * sizeof(*vga.gc.data)); + memset(vga.gc.latch, 0, sizeof(vga.gc.latch)); + memset(&vga.attribute, 0, sizeof(vga.attribute)); + memset(&vga.dac, 0, sizeof(vga.dac)); + memset(&vga.cursor, 0, sizeof(vga.cursor)); + memset(&vga.monitor, 0, sizeof(vga.monitor)); + memset(&vga.oak, 0, sizeof(vga.oak)); + vga.log = 0; + + vga.gc.data[6] = 0xc; /* prevent xtbios excepting vga ram as system ram */ +/* amstrad pc1640 bios relies on the position of + the video memory area, + so I introduced the reset to switch to b8000 area */ + vga.sequencer.data[4] = 0; + vga_cpu_interface(machine); + + vga.line_compare = 0x3ff; + // set CRTC register to match the line compare value + vga.crtc.data[0x18] = vga.line_compare & 0xff; + if(vga.line_compare & 0x100) + vga.crtc.data[0x07] |= 0x10; + if(vga.line_compare & 0x200) + vga.crtc.data[0x09] |= 0x40; +} + +/* 16 bit */ +READ16_HANDLER( vga_port16le_03b0_r ) { return read16le_with_read8_handler(vga_port_03b0_r, space, offset, mem_mask); } +READ16_HANDLER( vga_port16le_03c0_r ) { return read16le_with_read8_handler(vga_port_03c0_r, space, offset, mem_mask); } +READ16_HANDLER( vga_port16le_03d0_r ) { return read16le_with_read8_handler(vga_port_03d0_r, space, offset, mem_mask); } + +WRITE16_HANDLER( vga_port16le_03b0_w ) { write16le_with_write8_handler(vga_port_03b0_w, space, offset, data, mem_mask); } +WRITE16_HANDLER( vga_port16le_03c0_w ) { write16le_with_write8_handler(vga_port_03c0_w, space, offset, data, mem_mask); } +WRITE16_HANDLER( vga_port16le_03d0_w ) { write16le_with_write8_handler(vga_port_03d0_w, space, offset, data, mem_mask); } + +/* 32 bit */ +static READ32_HANDLER( vga_port32le_03b0_r ) { return read32le_with_read8_handler(vga_port_03b0_r, space, offset, mem_mask); } +static READ32_HANDLER( vga_port32le_03c0_r ) { return read32le_with_read8_handler(vga_port_03c0_r, space, offset, mem_mask); } +static READ32_HANDLER( vga_port32le_03d0_r ) { return read32le_with_read8_handler(vga_port_03d0_r, space, offset, mem_mask); } + +static WRITE32_HANDLER( vga_port32le_03b0_w ) { write32le_with_write8_handler(vga_port_03b0_w, space, offset, data, mem_mask); } +static WRITE32_HANDLER( vga_port32le_03c0_w ) { write32le_with_write8_handler(vga_port_03c0_w, space, offset, data, mem_mask); } +static WRITE32_HANDLER( vga_port32le_03d0_w ) { write32le_with_write8_handler(vga_port_03d0_w, space, offset, data, mem_mask); } + +/* 64 bit */ +static READ64_HANDLER( vga_port64be_03b0_r ) { return read64be_with_read8_handler(vga_port_03b0_r, space, offset, mem_mask); } +static READ64_HANDLER( vga_port64be_03c0_r ) { return read64be_with_read8_handler(vga_port_03c0_r, space, offset, mem_mask); } +static READ64_HANDLER( vga_port64be_03d0_r ) { return read64be_with_read8_handler(vga_port_03d0_r, space, offset, mem_mask); } + +static WRITE64_HANDLER( vga_port64be_03b0_w ) { write64be_with_write8_handler(vga_port_03b0_w, space, offset, data, mem_mask); } +static WRITE64_HANDLER( vga_port64be_03c0_w ) { write64be_with_write8_handler(vga_port_03c0_w, space, offset, data, mem_mask); } +static WRITE64_HANDLER( vga_port64be_03d0_w ) { write64be_with_write8_handler(vga_port_03d0_w, space, offset, data, mem_mask); } + +void pc_vga_init(running_machine *machine, const struct pc_vga_interface *vga_intf, const struct pc_svga_interface *svga_intf) +{ + int i, j, k, mask, buswidth; + const address_space *spacevga; + + memset(&vga, 0, sizeof(vga)); + + for (k=0;k<4;k++) + { + for (mask=0x80, j=0; j<8; j++, mask>>=1) + { + for (i=0; i<256; i++) + color_bitplane_to_packed[k][j][i]=(i&mask)?(1<<k):0; + } + } + + /* copy over interfaces */ + vga.vga_intf = *vga_intf; + if (svga_intf) + { + vga.svga_intf = *svga_intf; + + if (vga.svga_intf.seq_regcount < 0x05) + fatalerror("Invalid SVGA sequencer register count"); + if (vga.svga_intf.gc_regcount < 0x09) + fatalerror("Invalid SVGA GC register count"); + if (vga.svga_intf.crtc_regcount < 0x19) + fatalerror("Invalid SVGA CRTC register count"); + } + else + { + vga.svga_intf.vram_size = 0x40000; + vga.svga_intf.seq_regcount = 0x05; + vga.svga_intf.gc_regcount = 0x09; + vga.svga_intf.crtc_regcount = 0x19; + } + + vga.memory = auto_alloc_array(machine, UINT8, vga.svga_intf.vram_size); + vga.fontdirty = auto_alloc_array(machine, UINT8, 0x800); + vga.sequencer.data = auto_alloc_array(machine, UINT8, vga.svga_intf.seq_regcount); + vga.crtc.data = auto_alloc_array(machine, UINT8, vga.svga_intf.crtc_regcount); + vga.gc.data = auto_alloc_array(machine, UINT8, vga.svga_intf.gc_regcount); + memset(vga.memory, '\0', vga.svga_intf.vram_size); + memset(vga.fontdirty, '\0', 0x800); + memset(vga.sequencer.data, '\0', vga.svga_intf.seq_regcount); + memset(vga.crtc.data, '\0', vga.svga_intf.crtc_regcount); + memset(vga.gc.data, '\0', vga.svga_intf.gc_regcount); + + buswidth = machine->firstcpu->databus_width(AS_PROGRAM); + spacevga =cpu_get_address_space(machine->firstcpu,vga.vga_intf.port_addressspace); + switch(buswidth) + { + case 8: + memory_install_read8_handler(spacevga, vga.vga_intf.port_offset + 0x3b0, vga.vga_intf.port_offset + 0x3bf, 0, 0, vga_port_03b0_r ); + memory_install_read8_handler(spacevga, vga.vga_intf.port_offset + 0x3c0, vga.vga_intf.port_offset + 0x3cf, 0, 0, vga_port_03c0_r ); + memory_install_read8_handler(spacevga, vga.vga_intf.port_offset + 0x3d0, vga.vga_intf.port_offset + 0x3df, 0, 0, vga_port_03d0_r ); + + memory_install_write8_handler(spacevga, vga.vga_intf.port_offset + 0x3b0, vga.vga_intf.port_offset + 0x3bf, 0, 0, vga_port_03b0_w ); + memory_install_write8_handler(spacevga, vga.vga_intf.port_offset + 0x3c0, vga.vga_intf.port_offset + 0x3cf, 0, 0, vga_port_03c0_w ); + memory_install_write8_handler(spacevga, vga.vga_intf.port_offset + 0x3d0, vga.vga_intf.port_offset + 0x3df, 0, 0, vga_port_03d0_w ); + break; + + case 16: + memory_install_read16_handler(spacevga, vga.vga_intf.port_offset + 0x3b0, vga.vga_intf.port_offset + 0x3bf, 0, 0, vga_port16le_03b0_r ); + memory_install_read16_handler(spacevga, vga.vga_intf.port_offset + 0x3c0, vga.vga_intf.port_offset + 0x3cf, 0, 0, vga_port16le_03c0_r ); + memory_install_read16_handler(spacevga, vga.vga_intf.port_offset + 0x3d0, vga.vga_intf.port_offset + 0x3df, 0, 0, vga_port16le_03d0_r ); + + memory_install_write16_handler(spacevga, vga.vga_intf.port_offset + 0x3b0, vga.vga_intf.port_offset + 0x3bf, 0, 0, vga_port16le_03b0_w ); + memory_install_write16_handler(spacevga, vga.vga_intf.port_offset + 0x3c0, vga.vga_intf.port_offset + 0x3cf, 0, 0, vga_port16le_03c0_w ); + memory_install_write16_handler(spacevga, vga.vga_intf.port_offset + 0x3d0, vga.vga_intf.port_offset + 0x3df, 0, 0, vga_port16le_03d0_w ); + break; + + case 32: + memory_install_read32_handler(spacevga, vga.vga_intf.port_offset + 0x3b0, vga.vga_intf.port_offset + 0x3bf, 0, 0, vga_port32le_03b0_r ); + memory_install_read32_handler(spacevga, vga.vga_intf.port_offset + 0x3c0, vga.vga_intf.port_offset + 0x3cf, 0, 0, vga_port32le_03c0_r ); + memory_install_read32_handler(spacevga, vga.vga_intf.port_offset + 0x3d0, vga.vga_intf.port_offset + 0x3df, 0, 0, vga_port32le_03d0_r ); + + memory_install_write32_handler(spacevga, vga.vga_intf.port_offset + 0x3b0, vga.vga_intf.port_offset + 0x3bf, 0, 0, vga_port32le_03b0_w ); + memory_install_write32_handler(spacevga, vga.vga_intf.port_offset + 0x3c0, vga.vga_intf.port_offset + 0x3cf, 0, 0, vga_port32le_03c0_w ); + memory_install_write32_handler(spacevga, vga.vga_intf.port_offset + 0x3d0, vga.vga_intf.port_offset + 0x3df, 0, 0, vga_port32le_03d0_w ); + break; + + case 64: + memory_install_read64_handler(spacevga, vga.vga_intf.port_offset + 0x3b0, vga.vga_intf.port_offset + 0x3bf, 0, 0, vga_port64be_03b0_r ); + memory_install_read64_handler(spacevga, vga.vga_intf.port_offset + 0x3c0, vga.vga_intf.port_offset + 0x3cf, 0, 0, vga_port64be_03c0_r ); + memory_install_read64_handler(spacevga, vga.vga_intf.port_offset + 0x3d0, vga.vga_intf.port_offset + 0x3df, 0, 0, vga_port64be_03d0_r ); + + memory_install_write64_handler(spacevga, vga.vga_intf.port_offset + 0x3b0, vga.vga_intf.port_offset + 0x3bf, 0, 0, vga_port64be_03b0_w ); + memory_install_write64_handler(spacevga, vga.vga_intf.port_offset + 0x3c0, vga.vga_intf.port_offset + 0x3cf, 0, 0, vga_port64be_03c0_w ); + memory_install_write64_handler(spacevga, vga.vga_intf.port_offset + 0x3d0, vga.vga_intf.port_offset + 0x3df, 0, 0, vga_port64be_03d0_w ); + break; + } + + pc_vga_reset(machine); +} + +static TIMER_CALLBACK(vga_timer) +{ + vga.monitor.retrace=1; +} + +static VIDEO_START( ega ) +{ + vga.monitor.get_clock = ega_get_clock; + vga.monitor.get_lines = ega_get_crtc_lines; + vga.monitor.get_columns = ega_get_crtc_columns; + vga.monitor.get_sync_lines = vga_get_crtc_sync_lines; + vga.monitor.get_sync_columns = vga_get_crtc_sync_columns; + timer_pulse(machine, ATTOTIME_IN_HZ(60), NULL, 0, vga_timer); + pc_video_start(machine, pc_ega_choosevideomode, 0); +} + +static VIDEO_RESET( ega ) +{ +} + +static VIDEO_START( vga ) +{ + vga.monitor.get_clock=vga_get_clock; + vga.monitor.get_lines=vga_get_crtc_lines; + vga.monitor.get_columns=vga_get_crtc_columns; + vga.monitor.get_sync_lines=vga_get_crtc_sync_lines; + vga.monitor.get_sync_columns=vga_get_crtc_sync_columns; + timer_pulse(machine, ATTOTIME_IN_HZ(60), NULL, 0, vga_timer); + pc_video_start(machine, pc_vga_choosevideomode, 0); +} + +static VIDEO_RESET( vga ) +{ + pc_vga_reset(machine); +} + +static void vga_vh_text(bitmap_t *bitmap) +{ + UINT8 ch, attr; + UINT8 bits; + UINT8 *font; + UINT16 *bitmapline; + int width=CHAR_WIDTH, height=CRTC6845_CHAR_HEIGHT; + int pos, line, column, mask, w, h, addr; + pen_t pen; + + if (CRTC6845_CURSOR_MODE!=CRTC6845_CURSOR_OFF) + { + if (++vga.cursor.time>=0x10) + { + vga.cursor.visible^=1; + vga.cursor.time=0; + } + } + + for (addr = TEXT_START_ADDRESS, line = -CRTC6845_SKEW; line < TEXT_LINES; + line += height, addr += TEXT_LINE_LENGTH) + { + for (pos = addr, column=0; column<TEXT_COLUMNS; column++, pos++) + { + ch = vga.memory[(pos<<2) + 0]; + attr = vga.memory[(pos<<2) + 1]; + font = vga.memory+2+(ch<<(5+2))+FONT1; + + for (h = MAX(-line, 0); (h < height) && (line+h < MIN(TEXT_LINES, bitmap->height)); h++) + { + bitmapline = BITMAP_ADDR16(bitmap, line+h, 0); + bits = font[h<<2]; + + assert(bitmapline); + + for (mask=0x80, w=0; (w<width)&&(w<8); w++, mask>>=1) + { + if (bits&mask) + pen = vga.pens[attr & 0x0f]; + else + pen = vga.pens[attr >> 4]; + bitmapline[column*width+w] = pen; + } + if (w<width) + { + /* 9 column */ + if (TEXT_COPY_9COLUMN(ch)&&(bits&1)) + pen = vga.pens[attr & 0x0f]; + else + pen = vga.pens[attr >> 4]; + bitmapline[column*width+w] = pen; + } + } + if ((CRTC6845_CURSOR_MODE!=CRTC6845_CURSOR_OFF) + &&vga.cursor.visible&&(pos==CRTC6845_CURSOR_POS)) + { + for (h=CRTC6845_CURSOR_TOP; + (h<=CRTC6845_CURSOR_BOTTOM)&&(h<height)&&(line+h<TEXT_LINES); + h++) + { + plot_box(bitmap, column*width, line+h, width, 1, vga.pens[attr&0xf]); + } + } + } + } +} + +static void vga_vh_ega(bitmap_t *bitmap) +{ + int pos, line, column, c, addr, i; + int height = CRTC6845_CHAR_HEIGHT; + UINT16 *bitmapline; + UINT16 *newbitmapline; + pen_t pen; + + for (addr=EGA_START_ADDRESS, pos=0, line=0; line<LINES; + line += height, addr=(addr+EGA_LINE_LENGTH)&0x3ffff) + { + bitmapline = BITMAP_ADDR16(bitmap, line, 0); + + for (pos=addr, c=0, column=0; column<EGA_COLUMNS; column++, c+=8, pos=(pos+4)&0x3ffff) + { + int data[4]; + + data[0]=vga.memory[pos]; + data[1]=vga.memory[pos+1]<<1; + data[2]=vga.memory[pos+2]<<2; + data[3]=vga.memory[pos+3]<<3; + + for (i = 7; i >= 0; i--) + { + pen = vga.pens[(data[0]&1) | (data[1]&2) | (data[2]&4) | (data[3]&8)]; + bitmapline[c+i] = pen; + + data[0]>>=1; + data[1]>>=1; + data[2]>>=1; + data[3]>>=1; + } + } + + for (i = 1; i < height; i++) + { + if (line + i >= LINES) + break; + + newbitmapline = BITMAP_ADDR16(bitmap, line+i, 0); + memcpy(newbitmapline, bitmapline, EGA_COLUMNS * 8 * sizeof(UINT16)); + } + } +} + +static void vga_vh_vga(bitmap_t *bitmap) +{ + int pos, line, column, c, addr, curr_addr; + UINT16 *bitmapline; + + curr_addr = 0; + if(vga.sequencer.data[4] & 0x08) + { + for (addr = VGA_START_ADDRESS, line=0; line<LINES; line++, addr+=VGA_LINE_LENGTH, curr_addr+=VGA_LINE_LENGTH) + { + if(line < (vga.line_compare & 0xff)) + curr_addr = addr; + if(line == (vga.line_compare & 0xff)) + curr_addr = 0; + bitmapline = BITMAP_ADDR16(bitmap, line, 0); + addr %= vga.svga_intf.vram_size; + for (pos=curr_addr, c=0, column=0; column<VGA_COLUMNS; column++, c+=8, pos+=0x20) + { + if(pos + 0x20 > vga.svga_intf.vram_size) + return; + bitmapline[c+0] = vga.memory[pos+0]; + bitmapline[c+1] = vga.memory[pos+1]; + bitmapline[c+2] = vga.memory[pos+2]; + bitmapline[c+3] = vga.memory[pos+3]; + bitmapline[c+4] = vga.memory[pos+0x10]; + bitmapline[c+5] = vga.memory[pos+0x11]; + bitmapline[c+6] = vga.memory[pos+0x12]; + bitmapline[c+7] = vga.memory[pos+0x13]; + } + } + } + else + { + for (addr = VGA_START_ADDRESS, line=0; line<LINES; line++, addr+=VGA_LINE_LENGTH/4, curr_addr+=VGA_LINE_LENGTH/4) + { + if(line < (vga.line_compare & 0xff)) + curr_addr = addr; + if(line == (vga.line_compare & 0xff)) + curr_addr = 0; + bitmapline = BITMAP_ADDR16(bitmap, line, 0); + addr %= vga.svga_intf.vram_size; + for (pos=curr_addr, c=0, column=0; column<VGA_COLUMNS; column++, c+=8, pos+=0x08) + { + if(pos + 0x08 > vga.svga_intf.vram_size) + return; + bitmapline[c+0] = vga.memory[pos+0]; + bitmapline[c+1] = vga.memory[pos+1]; + bitmapline[c+2] = vga.memory[pos+2]; + bitmapline[c+3] = vga.memory[pos+3]; + bitmapline[c+4] = vga.memory[pos+4]; + bitmapline[c+5] = vga.memory[pos+5]; + bitmapline[c+6] = vga.memory[pos+6]; + bitmapline[c+7] = vga.memory[pos+7]; + } + } + } +} + +static pc_video_update_proc pc_ega_choosevideomode(running_machine *machine, int *width, int *height) +{ + pc_video_update_proc proc = NULL; + int i; + + //if (CRTC_ON) + { + for (i = 0; i < 16; i++) + vga.pens[i]=machine->pens[i/*vga.attribute.data[i]&0x3f*/]; + + if (!GRAPHIC_MODE) + { + proc = vga_vh_text; + *height = TEXT_LINES; + *width = TEXT_COLUMNS*CHAR_WIDTH; + } + else + { + proc = vga_vh_ega; + *height = LINES; + *width = EGA_COLUMNS*8; + } + } + return proc; +} + +static pc_video_update_proc pc_vga_choosevideomode(running_machine *machine, int *width, int *height) +{ + pc_video_update_proc proc = NULL; + int i; + + //if (CRTC_ON) + { + if (vga.dac.dirty) + { + for (i=0; i<256;i++) + { + palette_set_color_rgb(machine, i,(vga.dac.color[i].red & 0x3f) << 2, + (vga.dac.color[i].green & 0x3f) << 2, + (vga.dac.color[i].blue & 0x3f) << 2); + } + vga.dac.dirty = 0; + } + + if (vga.attribute.data[0x10] & 0x80) + { + for (i=0; i<16;i++) + { + vga.pens[i] = machine->pens[(vga.attribute.data[i]&0x0f) + |((vga.attribute.data[0x14]&0xf)<<4)]; + } + } + else + { + for (i=0; i<16;i++) + { + vga.pens[i]=machine->pens[(vga.attribute.data[i]&0x3f) + |((vga.attribute.data[0x14]&0xc)<<4)]; + } + } + + if (vga.svga_intf.choosevideomode) + proc = vga.svga_intf.choosevideomode(vga.sequencer.data, vga.crtc.data, vga.gc.data, width, height); + + if (!proc) + { + if (!GRAPHIC_MODE) + { + proc = vga_vh_text; + *height = TEXT_LINES; + *width = TEXT_COLUMNS * CHAR_WIDTH; + } + else if (vga.gc.data[5]&0x40) + { + proc = vga_vh_vga; + *height = LINES; + *width = VGA_COLUMNS * 8; + } + else + { + proc = vga_vh_ega; + *height = LINES; + *width = EGA_COLUMNS * 8; + } + } + } + return proc; +} + + + +void *pc_vga_memory(void) +{ + return vga.memory; +} + + + +size_t pc_vga_memory_size(void) +{ + return vga.svga_intf.vram_size; +} + +READ16_HANDLER( paradise_ega16le_03c0_r ) { return read16le_with_read8_handler(paradise_ega_03c0_r, space, offset, mem_mask); } diff --git a/src/emu/video/pc_vga.h b/src/emu/video/pc_vga.h new file mode 100644 index 00000000000..fc06b3333c8 --- /dev/null +++ b/src/emu/video/pc_vga.h @@ -0,0 +1,120 @@ +/*************************************************************************** + + pc_vga.h + + PC standard VGA adaptor + +***************************************************************************/ + +#ifndef PC_VGA_H +#define PC_VGA_H + +#include "osdepend.h" +#include "pc_video.h" + +MACHINE_DRIVER_EXTERN( pcvideo_vga ); +MACHINE_DRIVER_EXTERN( pcvideo_pc1640 ); + +struct pc_vga_interface +{ + /* VGA memory mapper */ + const char *vga_memory_bank; + void (*map_vga_memory)(running_machine *machine, offs_t begin, offs_t end, read8_space_func rh, write8_space_func wh); + + /* VGA dipswitch (???) */ + read8_space_func read_dipswitch; + + /* where the ports go */ + int port_addressspace; + offs_t port_offset; +}; + +struct pc_svga_interface +{ + size_t vram_size; + int seq_regcount; + int gc_regcount; + int crtc_regcount; + pc_video_update_proc (*choosevideomode)(const UINT8 *sequencer, const UINT8 *crtc, const UINT8 *gc, int *width, int *height); +}; + +void pc_vga_init(running_machine *machine, const struct pc_vga_interface *vga_intf, const struct pc_svga_interface *svga_intf); +void pc_vga_reset(running_machine *machine); +void *pc_vga_memory(void); +size_t pc_vga_memory_size(void); + +READ8_HANDLER( ega_port_03c0_r ); + +READ8_HANDLER( paradise_ega_03c0_r ); +READ16_HANDLER( paradise_ega16le_03c0_r ); + +READ8_HANDLER( vga_port_03b0_r ); +READ8_HANDLER( vga_port_03c0_r ); +READ8_HANDLER( vga_port_03d0_r ); +WRITE8_HANDLER( vga_port_03b0_w ); +WRITE8_HANDLER( vga_port_03c0_w ); +WRITE8_HANDLER( vga_port_03d0_w ); + +READ16_HANDLER( vga_port16le_03b0_r ); +READ16_HANDLER( vga_port16le_03c0_r ); +READ16_HANDLER( vga_port16le_03d0_r ); +WRITE16_HANDLER( vga_port16le_03b0_w ); +WRITE16_HANDLER( vga_port16le_03c0_w ); +WRITE16_HANDLER( vga_port16le_03d0_w ); + +/* + pega notes (paradise) + build in amstrad pc1640 + + ROM_LOAD("40100", 0xc0000, 0x8000, CRC(d2d1f1ae)) + + 4 additional dipswitches + seems to have emulation modes at register level + (mda/hgc lines bit 8 not identical to ega/vga) + + standard ega/vga dipswitches + 00000000 320x200 + 00000001 640x200 hanging + 00000010 640x200 hanging + 00000011 640x200 hanging + + 00000100 640x350 hanging + 00000101 640x350 hanging EGA mono + 00000110 320x200 + 00000111 640x200 + + 00001000 640x200 + 00001001 640x200 + 00001010 720x350 partial visible + 00001011 720x350 partial visible + + 00001100 320x200 + 00001101 320x200 + 00001110 320x200 + 00001111 320x200 + +*/ + +/* + oak vga (oti 037 chip) + (below bios patch needed for running) + + ROM_LOAD("oakvga.bin", 0xc0000, 0x8000, CRC(318c5f43)) +*/ +#if 0 + int i; + UINT8 *memory=memory_region(machine, "maincpu")+0xc0000; + UINT8 chksum; + + /* oak vga */ + /* plausibility check of retrace signals goes wrong */ + memory[0x00f5]=memory[0x00f6]=memory[0x00f7]=0x90; + memory[0x00f8]=memory[0x00f9]=memory[0x00fa]=0x90; + for (chksum=0, i=0;i<0x7fff;i++) { + chksum+=memory[i]; + } + memory[i]=0x100-chksum; +#endif + +#endif /* PC_VGA_H */ + diff --git a/src/emu/video/pc_video.c b/src/emu/video/pc_video.c new file mode 100644 index 00000000000..a6a870c61b5 --- /dev/null +++ b/src/emu/video/pc_video.c @@ -0,0 +1,124 @@ +/********************************************************************* + + pc_video.c + + PC Video code + +*********************************************************************/ + +#include "emu.h" +#include "memconv.h" +//#include "includes/crtc6845.h" +#include "video/pc_video.h" + + + +/*************************************************************************** + + Local variables + +***************************************************************************/ + +static pc_video_update_proc (*pc_choosevideomode)(running_machine *machine, int *width, int *height); +static int pc_anythingdirty; +static int pc_current_height; +static int pc_current_width; +static const UINT16 dummy_palette[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; + + + +/**************************************************************************/ + +static STATE_POSTLOAD( pc_video_postload ) +{ + pc_anythingdirty = 1; + pc_current_height = -1; + pc_current_width = -1; +} + + + +void pc_video_start(running_machine *machine, + pc_video_update_proc (*choosevideomode)(running_machine *machine, int *width, int *height), + size_t vramsize) +{ + pc_choosevideomode = choosevideomode; + pc_anythingdirty = 1; + pc_current_height = -1; + pc_current_width = -1; + machine->generic.tmpbitmap = NULL; + + machine->generic.videoram_size = vramsize; + + if (machine->generic.videoram_size) + { + video_start_generic_bitmapped(machine); + } + + state_save_register_postload(machine, pc_video_postload, NULL); +} + + + +VIDEO_UPDATE( pc_video ) +{ + UINT32 rc = 0; + int w = 0, h = 0; + pc_video_update_proc video_update; + + video_update = pc_choosevideomode(screen->machine, &w, &h); + + if (video_update) + { + if ((pc_current_width != w) || (pc_current_height != h)) + { + int width = video_screen_get_width(screen); + int height = video_screen_get_height(screen); + + pc_current_width = w; + pc_current_height = h; + pc_anythingdirty = 1; + + if (pc_current_width > width) + pc_current_width = width; + if (pc_current_height > height) + pc_current_height = height; + + if ((pc_current_width > 100) && (pc_current_height > 100)) + video_screen_set_visarea(screen, 0, pc_current_width-1, 0, pc_current_height-1); + + bitmap_fill(bitmap, cliprect, 0); + } + + video_update(screen->machine->generic.tmpbitmap ? screen->machine->generic.tmpbitmap : bitmap); + + if (screen->machine->generic.tmpbitmap) + { + copybitmap(bitmap, screen->machine->generic.tmpbitmap, 0, 0, 0, 0, cliprect); + if (!pc_anythingdirty) + rc = UPDATE_HAS_NOT_CHANGED; + pc_anythingdirty = 0; + } + } + return rc; +} + + + +WRITE8_HANDLER ( pc_video_videoram_w ) +{ + if (space->machine->generic.videoram.u8 && space->machine->generic.videoram.u8[offset] != data) + { + space->machine->generic.videoram.u8[offset] = data; + pc_anythingdirty = 1; + } +} + + +WRITE16_HANDLER( pc_video_videoram16le_w ) { write16le_with_write8_handler(pc_video_videoram_w, space, offset, data, mem_mask); } + +WRITE32_HANDLER( pc_video_videoram32_w ) +{ + COMBINE_DATA(space->machine->generic.videoram.u32 + offset); + pc_anythingdirty = 1; +} diff --git a/src/emu/video/pc_video.h b/src/emu/video/pc_video.h new file mode 100644 index 00000000000..08212e09681 --- /dev/null +++ b/src/emu/video/pc_video.h @@ -0,0 +1,24 @@ +/********************************************************************* + + pc_video.h + + Refactoring of code common to PC video implementations + +*********************************************************************/ + +#ifndef PC_VIDEO_H +#define PC_VIDEO_H + +typedef void (*pc_video_update_proc)(bitmap_t *bitmap); + +void pc_video_start(running_machine *machine, + pc_video_update_proc (*choosevideomode)(running_machine *machine, int *width, int *height), + size_t vramsize); + +VIDEO_UPDATE( pc_video ); + +WRITE8_HANDLER( pc_video_videoram_w ); +WRITE16_HANDLER( pc_video_videoram16le_w ); +WRITE32_HANDLER( pc_video_videoram32_w ); + +#endif /* PC_VIDEO_H */ diff --git a/src/mame/drivers/pcat_nit.c b/src/mame/drivers/pcat_nit.c index af53c4a6a61..36cd3b5fc8a 100644 --- a/src/mame/drivers/pcat_nit.c +++ b/src/mame/drivers/pcat_nit.c @@ -4,7 +4,7 @@ Street Games (c) 1993 New Image Technologies A modified 386 PC-AT HW -preliminary driver by Angelo Salese +preliminary driver by Angelo Salese and Mariusz Wojcieszek ===================================================================================================================== @@ -80,6 +80,7 @@ Smitdogg ********************************************************************************************************************/ + #include "emu.h" #include "cpu/i386/i386.h" #include "memconv.h" @@ -93,91 +94,52 @@ Smitdogg #include "machine/8042kbdc.h" #include "machine/pckeybrd.h" #include "machine/idectrl.h" +#include "machine/ins8250.h" +#include "machine/microtch.h" +#include "video/pc_vga.h" +#include "video/pc_video.h" -static UINT32 *vga_vram; -static UINT8 vga_regs[0x19]; +static struct { + running_device *pit8253; + running_device *pic8259_1; + running_device *pic8259_2; + running_device *dma8237_1; + running_device *dma8237_2; + running_device *com0; +} streetg2_devices; -#define SET_VISIBLE_AREA(_x_,_y_) \ - { \ - rectangle visarea = *video_screen_get_visible_area(machine->primary_screen); \ - visarea.min_x = 0; \ - visarea.max_x = _x_-1; \ - visarea.min_y = 0; \ - visarea.max_y = _y_-1; \ - video_screen_configure(machine->primary_screen, _x_, _y_, &visarea, video_screen_get_frame_period(machine->primary_screen).attoseconds ); \ - } \ +/************************************* + * + * Microtouch <-> ins8250 interface + * + *************************************/ -#define RES_320x200 0 -#define RES_640x200 1 +static void pcat_nit_microtouch_tx_callback(running_machine *machine, UINT8 data) +{ + ins8250_receive(streetg2_devices.com0, data); +}; -static VIDEO_START(streetg2) +static INS8250_TRANSMIT( pcat_nit_com_transmit ) { + UINT8 data8 = data; + microtouch_rx(1, &data8); } - - -static void cga_alphanumeric_tilemap(running_machine *machine, bitmap_t *bitmap,const rectangle *cliprect,UINT16 size,UINT32 map_offs,UINT8 gfx_num) +static INS8250_INTERRUPT( at_com_interrupt_1 ) { - static UINT32 offs,x,y,max_x,max_y; - int tile,color; - - /*define the visible area*/ - switch(size) - { - case RES_320x200: - SET_VISIBLE_AREA(320,200); - max_x = 40; - max_y = 25; - break; - case RES_640x200: - SET_VISIBLE_AREA(640,200); - max_x = 80; - max_y = 25; - break; - } - - offs = map_offs; - - for(y=0;y<max_y;y++) - for(x=0;x<max_x;x+=2) - { - tile = (vga_vram[offs] & 0x00ff0000)>>16; - color = (vga_vram[offs] & 0xff000000)>>24; - - drawgfx_opaque(bitmap,cliprect,machine->gfx[gfx_num], - tile, - color, - 0,0, - (x+1)*8,y*8); - - - tile = (vga_vram[offs] & 0x000000ff); - color = (vga_vram[offs] & 0x0000ff00)>>8; - - drawgfx_opaque(bitmap,cliprect,machine->gfx[gfx_num], - tile, - color, - 0,0, - (x+0)*8,y*8); - - offs++; - } + pic8259_ir4_w(streetg2_devices.pic8259_1, state); } -static VIDEO_UPDATE(streetg2) +static const ins8250_interface pcat_nit_com0_interface = { - cga_alphanumeric_tilemap(screen->machine,bitmap,cliprect,RES_640x200,0x18000/4,0); - - return 0; -} + 1843200, + at_com_interrupt_1, + pcat_nit_com_transmit, + NULL, + NULL +}; -static struct { - running_device *pit8253; - running_device *pic8259_1; - running_device *pic8259_2; - running_device *dma8237_1; - running_device *dma8237_2; -} streetg2_devices; +static UINT32 *main_ram; /****************** DMA8237 Controller @@ -354,76 +316,61 @@ static const struct pit8253_config at_pit8254_config = } }; -//ce9b8 -/* TODO: understand the proper ROM loading.*/ -static ADDRESS_MAP_START( pcat_map, ADDRESS_SPACE_PROGRAM, 32 ) - AM_RANGE(0x00000000, 0x0009ffff) AM_RAM - AM_RANGE(0x000a0000, 0x000bffff) AM_RAM AM_BASE(&vga_vram) - AM_RANGE(0x000c0000, 0x000c7fff) AM_RAM - AM_RANGE(0x000c8000, 0x000cffff) AM_RAM AM_REGION("video_bios", 0) - AM_RANGE(0x000d0000, 0x000d7fff) AM_RAM AM_REGION("disk_bios", 0) - AM_RANGE(0x000d8000, 0x000dffff) AM_RAM AM_REGION("disk_bios", 0) - AM_RANGE(0x000e0000, 0x000effff) AM_ROM AM_REGION("game_prg", 0) - AM_RANGE(0x000f0000, 0x000fffff) AM_ROM AM_REGION("bios", 0 ) - AM_RANGE(0x00100000, 0x0027ffff) AM_ROM AM_REGION("game_prg", 0) - AM_RANGE(0xffff0000, 0xffffffff) AM_ROM AM_REGION("bios", 0 ) -ADDRESS_MAP_END - - -static READ32_HANDLER( kludge_r ) -{ - return mame_rand(space->machine); -} - -/* 3c8-3c9 -> ramdac*/ -static WRITE32_HANDLER( vga_ramdac_w ) +static WRITE8_HANDLER(nit_rombank_w) { - static int pal_offs,r,g,b,internal_pal_offs; - - if (ACCESSING_BITS_0_7) - { - //printf("%02x X\n",data); - pal_offs = internal_pal_offs = data; - } - if (ACCESSING_BITS_8_15) + logerror( "rom bank #%02x at PC=%08X\n", data, cpu_get_pc(space->cpu) ); + if ( data & 0x40 ) { - //printf("%02x\n",data); - data>>=8; - switch(internal_pal_offs) + // rom bank + memory_install_read_bank(space, 0x000d8000, 0x000dffff, 0, 0, "rombank" ); + memory_unmap_write(space, 0x000d8000, 0x000dffff, 0, 0); + + if ( data & 0x80 ) + { + memory_set_bank(space->machine, "rombank", (data & 0x3f) | 0x40 ); + } + else { - case 0: - r = ((data & 0x3f) << 2) | ((data & 0x30) >> 4); - internal_pal_offs++; - break; - case 1: - g = ((data & 0x3f) << 2) | ((data & 0x30) >> 4); - internal_pal_offs++; - break; - case 2: - b = ((data & 0x3f) << 2) | ((data & 0x30) >> 4); - palette_set_color(space->machine, 0x200+pal_offs, MAKE_RGB(r, g, b)); - internal_pal_offs = 0; - pal_offs++; - break; + memory_set_bank(space->machine, "rombank", data & 0x3f ); } } + else + { + // nvram bank + memory_unmap_read(space, 0x000d8000, 0x000dffff, 0, 0); + memory_unmap_write(space, 0x000d8000, 0x000dffff, 0, 0); + + memory_install_read_bank(space, 0x000d8000, 0x000d9fff, 0, 0, "nvrambank" ); + memory_install_write_bank(space, 0x000d8000, 0x000d9fff, 0, 0, "nvrambank" ); + + memory_set_bankptr(space->machine, "nvrambank", space->machine->generic.nvram.u8); + + } } -static WRITE32_HANDLER( vga_regs_w ) -{ - static UINT8 vga_address; +static ADDRESS_MAP_START( pcat_map, ADDRESS_SPACE_PROGRAM, 32 ) + AM_RANGE(0x00000000, 0x0009ffff) AM_RAM + AM_RANGE(0x000a0000, 0x000bffff) AM_RAM + AM_RANGE(0x000c0000, 0x000c7fff) AM_ROM AM_REGION("video_bios", 0) + AM_RANGE(0x000d0000, 0x000d3fff) AM_RAM AM_REGION("disk_bios", 0) + AM_RANGE(0x000d7000, 0x000d7003) AM_WRITE8(nit_rombank_w, 0xff) + AM_RANGE(0x000d8000, 0x000dffff) AM_ROMBANK("rombank") + AM_RANGE(0x000f0000, 0x000fffff) AM_RAM AM_REGION("bios", 0 ) + AM_RANGE(0xffff0000, 0xffffffff) AM_ROM AM_REGION("bios", 0 ) +ADDRESS_MAP_END - if (ACCESSING_BITS_0_7) - vga_address = data; - if (ACCESSING_BITS_8_15) +static READ8_HANDLER(pc_nit_io_r) +{ + switch(offset) { - if(vga_address < 0x19) - { - vga_regs[vga_address] = data>>8; - logerror("VGA reg %02x with data %02x\n",vga_address,vga_regs[vga_address]); - } - else - logerror("Warning: used undefined VGA reg %02x with data %02x\n",vga_address,data>>8); + case 0: /* 278 */ + return 0xff; + case 1: /* 279 */ + return input_port_read(space->machine, "IN0"); + case 7: /* 27f dips */ + return 0xff; + default: + return 0; } } @@ -431,147 +378,58 @@ static ADDRESS_MAP_START( pcat_io, ADDRESS_SPACE_IO, 32 ) AM_RANGE(0x0000, 0x001f) AM_DEVREADWRITE8("dma8237_1", i8237_r, i8237_w, 0xffffffff) AM_RANGE(0x0020, 0x003f) AM_DEVREADWRITE8("pic8259_1", pic8259_r, pic8259_w, 0xffffffff) AM_RANGE(0x0040, 0x005f) AM_DEVREADWRITE8("pit8254", pit8253_r, pit8253_w, 0xffffffff) - AM_RANGE(0x0060, 0x006f) AM_READWRITE(kbdc8042_32le_r, kbdc8042_32le_w) + AM_RANGE(0x0060, 0x006f) AM_READWRITE8(kbdc8042_8_r, kbdc8042_8_w, 0xffffffff) AM_RANGE(0x0070, 0x007f) AM_RAM//READWRITE(mc146818_port32le_r, mc146818_port32le_w) AM_RANGE(0x0080, 0x009f) AM_READWRITE8(dma_page_select_r,dma_page_select_w, 0xffffffff)//TODO AM_RANGE(0x00a0, 0x00bf) AM_DEVREADWRITE8("pic8259_2", pic8259_r, pic8259_w, 0xffffffff) AM_RANGE(0x00c0, 0x00df) AM_DEVREADWRITE8("dma8237_2", i8237_r, i8237_w, 0xffff) - AM_RANGE(0x0278, 0x027f) AM_RAM //parallel port 2 - AM_RANGE(0x0378, 0x037f) AM_RAM //parallel port - AM_RANGE(0x03c0, 0x03c3) AM_RAM - AM_RANGE(0x03cc, 0x03cf) AM_RAM - AM_RANGE(0x03b4, 0x03b7) AM_WRITE(vga_regs_w) - AM_RANGE(0x03c4, 0x03c7) AM_RAM //vga regs - AM_RANGE(0x03c8, 0x03cb) AM_WRITE(vga_ramdac_w) - AM_RANGE(0x03b8, 0x03bb) AM_READ(kludge_r) //hv_retrace - AM_RANGE(0x03c8, 0x03cb) AM_READ(kludge_r) //hv_retrace - AM_RANGE(0x03d4, 0x03d7) AM_WRITE(vga_regs_w) - AM_RANGE(0x03d8, 0x03db) AM_RAM - AM_RANGE(0x03bc, 0x03bf) AM_RAM //parallel port 3 + AM_RANGE(0x0278, 0x027f) AM_READ8(pc_nit_io_r, 0xffffffff) AM_WRITENOP + AM_RANGE(0x03f8, 0x03ff) AM_DEVREADWRITE8("ns16450_0", ins8250_r, ins8250_w, 0xffffffff) ADDRESS_MAP_END -#define AT_KEYB_HELPER(bit, text, key1) \ - PORT_BIT( bit, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME(text) PORT_CODE(key1) - static INPUT_PORTS_START( pcat_nit ) - PORT_START("pc_keyboard_0") - PORT_BIT ( 0x0001, 0x0000, IPT_UNUSED ) /* unused scancode 0 */ - AT_KEYB_HELPER( 0x0002, "Esc", KEYCODE_Q ) /* Esc 01 81 */ - - PORT_START("pc_keyboard_1") - AT_KEYB_HELPER( 0x0020, "Y", KEYCODE_Y ) /* Y 15 95 */ - AT_KEYB_HELPER( 0x1000, "Enter", KEYCODE_ENTER ) /* Enter 1C 9C */ - - PORT_START("pc_keyboard_2") - - PORT_START("pc_keyboard_3") - AT_KEYB_HELPER( 0x0002, "N", KEYCODE_N ) /* N 31 B1 */ - AT_KEYB_HELPER( 0x0800, "F1", KEYCODE_S ) /* F1 3B BB */ - - PORT_START("pc_keyboard_4") - - PORT_START("pc_keyboard_5") - - PORT_START("pc_keyboard_6") - AT_KEYB_HELPER( 0x0040, "(MF2)Cursor Up", KEYCODE_UP ) /* Up 67 e7 */ - AT_KEYB_HELPER( 0x0080, "(MF2)Page Up", KEYCODE_PGUP ) /* Page Up 68 e8 */ - AT_KEYB_HELPER( 0x0100, "(MF2)Cursor Left", KEYCODE_LEFT ) /* Left 69 e9 */ - AT_KEYB_HELPER( 0x0200, "(MF2)Cursor Right", KEYCODE_RIGHT ) /* Right 6a ea */ - AT_KEYB_HELPER( 0x0800, "(MF2)Cursor Down", KEYCODE_DOWN ) /* Down 6c ec */ - AT_KEYB_HELPER( 0x1000, "(MF2)Page Down", KEYCODE_PGDN ) /* Page Down 6d ed */ - AT_KEYB_HELPER( 0x4000, "Del", KEYCODE_A ) /* Delete 6f ef */ - - PORT_START("pc_keyboard_7") + PORT_INCLUDE(microtouch) + + PORT_START("IN0") + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Clear") PORT_CODE(KEYCODE_C) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_SERVICE) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_COIN1) PORT_IMPULSE(1) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_COIN2) PORT_IMPULSE(1) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_COIN3) PORT_IMPULSE(1) INPUT_PORTS_END -static const rgb_t defcolors[]= -{ - MAKE_RGB(0x00,0x00,0x00), - MAKE_RGB(0x00,0x00,0xaa), - MAKE_RGB(0x00,0xaa,0x00), - MAKE_RGB(0x00,0xaa,0xaa), - MAKE_RGB(0xaa,0x00,0x00), - MAKE_RGB(0xaa,0x00,0xaa), - MAKE_RGB(0xaa,0xaa,0x00), - MAKE_RGB(0xaa,0xaa,0xaa), - MAKE_RGB(0x55,0x55,0x55), - MAKE_RGB(0x55,0x55,0xff), - MAKE_RGB(0x55,0xff,0x55), - MAKE_RGB(0x55,0xff,0xff), - MAKE_RGB(0xff,0x55,0x55), - MAKE_RGB(0xff,0x55,0xff), - MAKE_RGB(0xff,0xff,0x55), - MAKE_RGB(0xff,0xff,0xff) -}; - -static PALETTE_INIT(pcat_286) -{ - /*Note:palette colors are 6bpp... - xxxx xx-- - */ - int ix,iy; - - for(ix=0;ix<0x300;ix++) - palette_set_color(machine, ix,MAKE_RGB(0x00,0x00,0x00)); - - //regular colors - for(iy=0;iy<0x10;iy++) - { - for(ix=0;ix<0x10;ix++) - { - palette_set_color(machine,(ix*2)+1+(iy*0x20),defcolors[ix]); - palette_set_color(machine,(ix*2)+0+(iy*0x20),defcolors[iy]); - } - } - - //bitmap mode - for(ix=0;ix<0x10;ix++) - palette_set_color(machine, 0x200+ix,defcolors[ix]); - //todo: 256 colors -} - static void streetg2_set_keyb_int(running_machine *machine, int state) { pic8259_ir1_w(streetg2_devices.pic8259_1, state); } +static const struct pc_vga_interface vga_interface = +{ + NULL, + NULL, + NULL, + ADDRESS_SPACE_IO, + 0x0000 +}; static MACHINE_START( streetg2 ) { -// bank = -1; -// lastvalue = -1; -// hv_blank = 0; cpu_set_irq_callback(devtag_get_device(machine, "maincpu"), irq_callback); streetg2_devices.pit8253 = devtag_get_device( machine, "pit8254" ); streetg2_devices.pic8259_1 = devtag_get_device( machine, "pic8259_1" ); streetg2_devices.pic8259_2 = devtag_get_device( machine, "pic8259_2" ); streetg2_devices.dma8237_1 = devtag_get_device( machine, "dma8237_1" ); streetg2_devices.dma8237_2 = devtag_get_device( machine, "dma8237_2" ); + streetg2_devices.com0 = devtag_get_device( machine, "ns16450_0" ); init_pc_common(machine, PCCOMMON_KEYBOARD_AT, streetg2_set_keyb_int); mc146818_init(machine, MC146818_STANDARD); -} -static const gfx_layout CGA_charlayout = -{ - 8,8, - 256, - 1, - { 0 }, - { 0,1,2,3,4,5,6,7 }, - { 0*8,1*8,2*8,3*8,4*8,5*8,6*8,7*8 }, - 8*8 -}; - -static GFXDECODE_START( streetg2 ) - GFXDECODE_ENTRY( "video_bios", 0x2da2, CGA_charlayout, 0, 256 ) - //there's also a 8x16 entry (just after the 8x8) -GFXDECODE_END + memory_configure_bank(machine, "rombank", 0, 0x80, memory_region(machine, "game_prg"), 0x8000 ); + memory_set_bank(machine, "rombank", 0); -static GFXDECODE_START( bonanza ) - GFXDECODE_ENTRY( "video_bios", 0x56f3, CGA_charlayout, 0, 256 ) - //there's also a 8x16 entry (just after the 8x8) -GFXDECODE_END + microtouch_init(machine, pcat_nit_microtouch_tx_callback, NULL); +} static MACHINE_DRIVER_START( pcat_nit ) /* basic machine hardware */ @@ -580,13 +438,11 @@ static MACHINE_DRIVER_START( pcat_nit ) MDRV_CPU_IO_MAP(pcat_io) /* video hardware */ - MDRV_SCREEN_ADD("screen", RASTER) - MDRV_SCREEN_FORMAT(BITMAP_FORMAT_RGB32) + MDRV_IMPORT_FROM( pcvideo_vga ) + + MDRV_SCREEN_MODIFY("screen") MDRV_SCREEN_REFRESH_RATE(60) - MDRV_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0)) - MDRV_SCREEN_SIZE(64*8, 32*8) - MDRV_SCREEN_VISIBLE_AREA(0*8, 64*8-1, 0*8, 32*8-1) - MDRV_GFXDECODE( streetg2 ) + MDRV_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */ MDRV_MACHINE_START(streetg2) MDRV_NVRAM_HANDLER( mc146818 ) @@ -597,18 +453,8 @@ static MACHINE_DRIVER_START( pcat_nit ) MDRV_I8237_ADD( "dma8237_1", XTAL_14_31818MHz/3, dma8237_1_config ) MDRV_I8237_ADD( "dma8237_2", XTAL_14_31818MHz/3, dma8237_2_config ) MDRV_PIT8254_ADD( "pit8254", at_pit8254_config ) + MDRV_NS16450_ADD( "ns16450_0", pcat_nit_com0_interface ) - MDRV_PALETTE_INIT(pcat_286) - - MDRV_PALETTE_LENGTH(0x300) - - MDRV_VIDEO_START(streetg2) - MDRV_VIDEO_UPDATE(streetg2) -MACHINE_DRIVER_END - -static MACHINE_DRIVER_START( pcat_nitB ) - MDRV_IMPORT_FROM( pcat_nit ) - MDRV_GFXDECODE( bonanza ) MACHINE_DRIVER_END /*************************************** @@ -625,7 +471,7 @@ ROM_START(streetg) ROM_LOAD16_BYTE("vga1-bios-ver-b-1.00-07.u8", 0x00000, 0x04000, CRC(a40551d6) SHA1(db38190f06e4af2c2d59ae310e65883bb16cd3d6)) ROM_CONTINUE( 0x00001, 0x04000 ) - ROM_REGION(0x180000, "game_prg", 0) /* proper game */ + ROM_REGION(0x400000, "game_prg", 0) /* proper game */ ROM_LOAD("10-0003-04.u11", 0x000000,0x80000, CRC(1471a728) SHA1(5e12a9230f8130282a1be9a10118a3556bafbc37) ) ROM_LOAD("10-0003-04.u12", 0x080000,0x80000, CRC(5a50f519) SHA1(c07a583b4220d4d5506824def91774fede760e65) ) ROM_LOAD("10-0003-04.u13", 0x100000,0x80000, CRC(8a609145) SHA1(18fcb58b461aa9149a163b85dd8267dec90da3cd) ) @@ -645,7 +491,7 @@ ROM_START(streetgr3) ROM_LOAD16_BYTE("vga1-bios-ver-b-1.00-07.u8", 0x00000, 0x04000, CRC(a40551d6) SHA1(db38190f06e4af2c2d59ae310e65883bb16cd3d6)) ROM_CONTINUE( 0x00001, 0x04000 ) - ROM_REGION(0x180000, "game_prg", 0) /* proper game */ + ROM_REGION(0x400000, "game_prg", 0) /* proper game */ ROM_LOAD("10-00003-03.u11", 0x000000,0x80000, CRC(2fbcb12b) SHA1(f6413565fc1289ba32b411de877cdf6526f1fa9d) ) ROM_LOAD("10-00003-03.u12", 0x080000,0x80000, CRC(b37c7dff) SHA1(cf6318bfeca0bd272734f45c7589a0224863b0f1) ) ROM_LOAD("10-00003-03.u13", 0x100000,0x80000, CRC(6a9d0771) SHA1(6cd9a56a2413416d0928e5cf9340c94bc0c87c46) ) @@ -665,13 +511,13 @@ ROM_START(bonanza) ROM_LOAD16_BYTE("techyosd-isa-bios-v1.2.u8", 0x00000, 0x04000, CRC(6adf7e71) SHA1(2b07d964cc7c2c0aa560625b7c12f38d4537d652) ) ROM_CONTINUE( 0x00001, 0x04000 ) - ROM_REGION(0x300000, "game_prg", 0) /* proper game */ + ROM_REGION(0x400000, "game_prg", 0) /* proper game */ ROM_LOAD("10-0018-03-090894.u11", 0x000000,0x80000, CRC(32b6c8bc) SHA1(7f4097990dca268915842d4253d4257654de2cfc) ) ROM_LOAD("10-0018-03-090894.u12", 0x080000,0x80000, CRC(d7cb191d) SHA1(2047f3668b0e41ad5347107f4e3446c0374c5bb7) ) ROM_LOAD("10-0018-03-090894.u13", 0x100000,0x80000, CRC(1d3ddeaa) SHA1(8e73fe535882f6d634668733e550281e727fbdbc) ) - ROM_LOAD("10-0018-03-090894.u15", 0x180000,0x80000, CRC(b9b3f442) SHA1(6ea5ce3eb007b95ad3350fdb634625b151ae7bdb) ) - ROM_LOAD("10-0018-03-090894.u16", 0x200000,0x80000, CRC(5b0dd6f5) SHA1(8172118185179ecb7d3f958480186bf9c906785f) ) - ROM_LOAD("10-0018-03-090894.u17", 0x280000,0x80000, CRC(b637eb58) SHA1(7c4615f58118d9b82575d816ef916fccbb1be0f9) ) + ROM_LOAD("10-0018-03-090894.u15", 0x200000,0x80000, CRC(b9b3f442) SHA1(6ea5ce3eb007b95ad3350fdb634625b151ae7bdb) ) + ROM_LOAD("10-0018-03-090894.u16", 0x280000,0x80000, CRC(5b0dd6f5) SHA1(8172118185179ecb7d3f958480186bf9c906785f) ) + ROM_LOAD("10-0018-03-090894.u17", 0x300000,0x80000, CRC(b637eb58) SHA1(7c4615f58118d9b82575d816ef916fccbb1be0f9) ) ROM_REGION(0x08000, "disk_bios", 0) ROM_LOAD("disk-bios-10-0001-04.u10", 0x00000, 0x08000, CRC(1b4ce068) SHA1(8570b36acf3eb29f1c59e56a4dad6d38c218748f) ) @@ -688,13 +534,13 @@ ROM_START(bonanzar2) ROM_LOAD16_BYTE("techyosd-isa-bios-v1.2.u8", 0x00000, 0x04000, CRC(6adf7e71) SHA1(2b07d964cc7c2c0aa560625b7c12f38d4537d652) ) ROM_CONTINUE( 0x00001, 0x04000 ) - ROM_REGION(0x300000, "game_prg", 0) /* proper game */ + ROM_REGION(0x400000, "game_prg", 0) /* proper game */ ROM_LOAD("10-0018-02-081794.u11", 0x000000,0x80000, CRC(f87fa935) SHA1(b06144496406231aa63149ae12a048ffab8f77d0) ) ROM_LOAD("10-0018-02-081794.u12", 0x080000,0x80000, CRC(bd892e3e) SHA1(1b9174fe2a6eaa7687b543798099b86b9039c049) ) ROM_LOAD("10-0018-02-081794.u13", 0x100000,0x80000, CRC(626d999e) SHA1(5c27e3b064b0235c0d6e0be8d8f78538a11647a2) ) - ROM_LOAD("10-0018-02-081794.u15", 0x180000,0x80000, CRC(3b28f582) SHA1(3da61fbd92e6cc60e00eaa21d8fb04aa78cce663) ) - ROM_LOAD("10-0018-02-081794.u16", 0x200000,0x80000, CRC(fe29ad76) SHA1(64aaae639f024c50c09fe920bc92e6d45ced5648) ) - ROM_LOAD("10-0018-02-081794.u17", 0x280000,0x80000, CRC(066108fe) SHA1(ef837422a2a81f5ac3375b6ed68f20143ac6caec) ) + ROM_LOAD("10-0018-02-081794.u15", 0x200000,0x80000, CRC(3b28f582) SHA1(3da61fbd92e6cc60e00eaa21d8fb04aa78cce663) ) + ROM_LOAD("10-0018-02-081794.u16", 0x280000,0x80000, CRC(fe29ad76) SHA1(64aaae639f024c50c09fe920bc92e6d45ced5648) ) + ROM_LOAD("10-0018-02-081794.u17", 0x300000,0x80000, CRC(066108fe) SHA1(ef837422a2a81f5ac3375b6ed68f20143ac6caec) ) ROM_REGION(0x08000, "disk_bios", 0) ROM_LOAD("disk-bios-10-0001-04.u10", 0x00000, 0x08000, CRC(1b4ce068) SHA1(8570b36acf3eb29f1c59e56a4dad6d38c218748f) ) @@ -711,7 +557,7 @@ ROM_START(streetg2) ROM_LOAD16_BYTE("vga1-bios-ver-b-1.00-07.u8", 0x00000, 0x04000, CRC(a40551d6) SHA1(db38190f06e4af2c2d59ae310e65883bb16cd3d6)) ROM_CONTINUE( 0x00001, 0x04000 ) - ROM_REGION(0x180000, "game_prg", 0) /* proper game */ + ROM_REGION(0x400000, "game_prg", 0) /* proper game */ ROM_LOAD("10-0007-07c_083194_rom4.u11", 0x000000,0x80000, CRC(244c2bfa) SHA1(4f2f0fb6923b4e3f1ab4e607e29a27fb15b39fac) ) ROM_LOAD("10-0007-07c_083194_rom5.u12", 0x080000,0x80000, CRC(c89d5dca) SHA1(212bcbf7a39243f4524b4a855fbedabd387d17f2) ) ROM_LOAD("10-0007-07c_083194_rom6.u13", 0x100000,0x80000, CRC(6264f65f) SHA1(919a8e5d9861dc642ac0f0885faed544bbafa321) ) @@ -731,7 +577,7 @@ ROM_START(streetg2r5) ROM_LOAD16_BYTE("vga1-bios-ver-b-1.00-07.u8", 0x00000, 0x04000, CRC(a40551d6) SHA1(db38190f06e4af2c2d59ae310e65883bb16cd3d6)) ROM_CONTINUE( 0x00001, 0x04000 ) - ROM_REGION(0x180000, "game_prg", 0) /* proper game */ + ROM_REGION(0x400000, "game_prg", 0) /* proper game */ ROM_LOAD("10-00007-05-032194.u15", 0x000000,0x80000, CRC(cefa230f) SHA1(91fd30a3def381974fae0edb4d42d452acda19bb) ) ROM_LOAD("10-00007-05-032194.u16", 0x080000,0x80000, CRC(0be5dd19) SHA1(d0474ff5156e1fa8b4edb502c49b7e1a2b3f6169) ) ROM_LOAD("10-00007-05-032194.u17", 0x100000,0x80000, CRC(f6c996b9) SHA1(871a8d093b856511a0e2b03334ef5c66a2482622) ) @@ -743,9 +589,17 @@ ROM_START(streetg2r5) ROM_LOAD("8k_nvram.u9", 0x00000, 0x02000, CRC(44be0b89) SHA1(81666dd369d1d85269833293136d61ffe80e940a)) ROM_END -GAME( 1993, bonanza, 0, pcat_nitB, pcat_nit, 0, ROT0, "New Image Technologies", "Bonanza (Revision 3)", GAME_NOT_WORKING|GAME_NO_SOUND ) -GAME( 1993, bonanzar2, bonanza, pcat_nitB, pcat_nit, 0, ROT0, "New Image Technologies", "Bonanza (Revision 2)", GAME_NOT_WORKING|GAME_NO_SOUND ) -GAME( 1993, streetg, 0, pcat_nit, pcat_nit, 0, ROT0, "New Image Technologies", "Street Games (Revision 4)", GAME_NOT_WORKING|GAME_NO_SOUND ) -GAME( 1993, streetgr3, streetg, pcat_nit, pcat_nit, 0, ROT0, "New Image Technologies", "Street Games (Revision 3)", GAME_NOT_WORKING|GAME_NO_SOUND ) -GAME( 1993, streetg2, 0, pcat_nit, pcat_nit, 0, ROT0, "New Image Technologies", "Street Games II (Revision 7C)", GAME_NOT_WORKING|GAME_NO_SOUND ) -GAME( 1993, streetg2r5, streetg2, pcat_nit, pcat_nit, 0, ROT0, "New Image Technologies", "Street Games II (Revision 5)", GAME_NOT_WORKING|GAME_NO_SOUND ) +static DRIVER_INIT(pcat_nit) +{ + machine->generic.nvram_size = 0x2000; + machine->generic.nvram.u8 = auto_alloc_array(machine, UINT8, machine->generic.nvram_size); + + pc_vga_init(machine, &vga_interface, NULL); +} + +GAME( 1993, bonanza, 0, pcat_nit, pcat_nit, pcat_nit, ROT0, "New Image Technologies", "Bonanza (Revision 3)", GAME_NOT_WORKING|GAME_NO_SOUND ) +GAME( 1993, bonanzar2, bonanza, pcat_nit, pcat_nit, pcat_nit, ROT0, "New Image Technologies", "Bonanza (Revision 2)", GAME_NOT_WORKING|GAME_NO_SOUND ) +GAME( 1993, streetg, 0, pcat_nit, pcat_nit, pcat_nit, ROT0, "New Image Technologies", "Street Games (Revision 4)", GAME_NOT_WORKING|GAME_NO_SOUND ) +GAME( 1993, streetgr3, streetg, pcat_nit, pcat_nit, pcat_nit, ROT0, "New Image Technologies", "Street Games (Revision 3)", GAME_NOT_WORKING|GAME_NO_SOUND ) +GAME( 1993, streetg2, 0, pcat_nit, pcat_nit, pcat_nit, ROT0, "New Image Technologies", "Street Games II (Revision 7C)", GAME_NOT_WORKING|GAME_NO_SOUND ) +GAME( 1993, streetg2r5, streetg2, pcat_nit, pcat_nit, pcat_nit, ROT0, "New Image Technologies", "Street Games II (Revision 5)", GAME_NOT_WORKING|GAME_NO_SOUND ) |
