Removed files in MESS that are not used anymore and cleaned mess.mak of duplicated files (nw)
This commit is contained in:
parent
81763bddf4
commit
005eef1e03
15
.gitattributes
vendored
15
.gitattributes
vendored
@ -5468,8 +5468,6 @@ src/mess/audio/special.c svneol=native#text/plain
|
||||
src/mess/audio/svision.c svneol=native#text/plain
|
||||
src/mess/audio/t6721.c svneol=native#text/plain
|
||||
src/mess/audio/t6721.h svneol=native#text/plain
|
||||
src/mess/audio/ted7360.c svneol=native#text/plain
|
||||
src/mess/audio/ted7360.h svneol=native#text/plain
|
||||
src/mess/audio/tvc.c svneol=native#text/plain
|
||||
src/mess/audio/upd1771.c svneol=native#text/plain
|
||||
src/mess/audio/upd1771.h svneol=native#text/plain
|
||||
@ -5479,14 +5477,10 @@ src/mess/audio/vc4000.c svneol=native#text/plain
|
||||
src/mess/audio/wswan.c svneol=native#text/plain
|
||||
src/mess/devices/appldriv.c svneol=native#text/plain
|
||||
src/mess/devices/appldriv.h svneol=native#text/plain
|
||||
src/mess/devices/kermit.c svneol=native#text/plain
|
||||
src/mess/devices/kermit.h svneol=native#text/plain
|
||||
src/mess/devices/microdrv.c svneol=native#text/plain
|
||||
src/mess/devices/microdrv.h svneol=native#text/plain
|
||||
src/mess/devices/sonydriv.c svneol=native#text/plain
|
||||
src/mess/devices/sonydriv.h svneol=native#text/plain
|
||||
src/mess/devices/xmodem.c svneol=native#text/plain
|
||||
src/mess/devices/xmodem.h svneol=native#text/plain
|
||||
src/mess/drivers/4004clk.c svneol=native#text/plain
|
||||
src/mess/drivers/68ksbc.c svneol=native#text/plain
|
||||
src/mess/drivers/a2600.c svneol=native#text/plain
|
||||
@ -5561,7 +5555,6 @@ src/mess/drivers/bw12.c svneol=native#text/plain
|
||||
src/mess/drivers/bw2.c svneol=native#text/plain
|
||||
src/mess/drivers/c10.c svneol=native#text/plain
|
||||
src/mess/drivers/c128.c svneol=native#text/plain
|
||||
src/mess/drivers/c16.c svneol=native#text/plain
|
||||
src/mess/drivers/c64.c svneol=native#text/plain
|
||||
src/mess/drivers/c64dtv.c svneol=native#text/plain
|
||||
src/mess/drivers/c65.c svneol=native#text/plain
|
||||
@ -6425,10 +6418,6 @@ src/mess/machine/amigakbd.c svneol=native#text/plain
|
||||
src/mess/machine/amigakbd.h svneol=native#text/plain
|
||||
src/mess/machine/amstr_pc.c svneol=native#text/plain
|
||||
src/mess/machine/amstrad.c svneol=native#text/plain
|
||||
src/mess/machine/ap2_lang.c svneol=native#text/plain
|
||||
src/mess/machine/ap2_lang.h svneol=native#text/plain
|
||||
src/mess/machine/ap2_slot.c svneol=native#text/plain
|
||||
src/mess/machine/ap2_slot.h svneol=native#text/plain
|
||||
src/mess/machine/apollo.c svneol=native#text/plain
|
||||
src/mess/machine/apollo_dbg.c svneol=native#text/plain
|
||||
src/mess/machine/apollo_eth.c svneol=native#text/plain
|
||||
@ -6475,7 +6464,6 @@ src/mess/machine/c1571.c svneol=native#text/plain
|
||||
src/mess/machine/c1571.h svneol=native#text/plain
|
||||
src/mess/machine/c1581.c svneol=native#text/plain
|
||||
src/mess/machine/c1581.h svneol=native#text/plain
|
||||
src/mess/machine/c16.c svneol=native#text/plain
|
||||
src/mess/machine/c2031.c svneol=native#text/plain
|
||||
src/mess/machine/c2031.h svneol=native#text/plain
|
||||
src/mess/machine/c2040.c svneol=native#text/plain
|
||||
@ -6770,7 +6758,6 @@ src/mess/machine/isa_sblaster.c svneol=native#text/plain
|
||||
src/mess/machine/isa_sblaster.h svneol=native#text/plain
|
||||
src/mess/machine/isa_wdxt_gen.c svneol=native#text/plain
|
||||
src/mess/machine/isa_wdxt_gen.h svneol=native#text/plain
|
||||
src/mess/machine/jupiter.c svneol=native#text/plain
|
||||
src/mess/machine/k7659kb.c svneol=native#text/plain
|
||||
src/mess/machine/k7659kb.h svneol=native#text/plain
|
||||
src/mess/machine/kay_kbd.c svneol=native#text/plain
|
||||
@ -7009,8 +6996,6 @@ src/mess/machine/thomflop.c svneol=native#text/plain
|
||||
src/mess/machine/thomflop.h svneol=native#text/plain
|
||||
src/mess/machine/thomson.c svneol=native#text/plain
|
||||
src/mess/machine/ti85.c svneol=native#text/plain
|
||||
src/mess/machine/ti85_ser.c svneol=native#text/plain
|
||||
src/mess/machine/ti85_ser.h svneol=native#text/plain
|
||||
src/mess/machine/ti99/bwg.c svneol=native#text/plain
|
||||
src/mess/machine/ti99/bwg.h svneol=native#text/plain
|
||||
src/mess/machine/ti99/datamux.c svneol=native#text/plain
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,92 +0,0 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* audio/ted7360.h
|
||||
*
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __TED7360_H__
|
||||
#define __TED7360_H__
|
||||
|
||||
#include "devcb.h"
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
TYPE DEFINITIONS
|
||||
***************************************************************************/
|
||||
|
||||
typedef int (*ted7360_dma_read)(running_machine &machine, int);
|
||||
typedef int (*ted7360_dma_read_rom)(running_machine &machine, int);
|
||||
typedef void (*ted7360_irq) (running_machine &, int);
|
||||
typedef UINT8 (*ted7360_key_cb) (running_machine &, int);
|
||||
|
||||
typedef enum
|
||||
{
|
||||
TED7360_NTSC,
|
||||
TED7360_PAL
|
||||
} ted_type;
|
||||
|
||||
typedef struct _ted7360_interface ted7360_interface;
|
||||
struct _ted7360_interface
|
||||
{
|
||||
const char *screen;
|
||||
|
||||
ted_type type;
|
||||
|
||||
ted7360_dma_read dma_read;
|
||||
ted7360_dma_read_rom dma_read_rom;
|
||||
|
||||
ted7360_irq irq;
|
||||
|
||||
ted7360_key_cb keyb_cb;
|
||||
};
|
||||
|
||||
/***************************************************************************
|
||||
CONSTANTS
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#define TED7360NTSC_VRETRACERATE 60
|
||||
#define TED7360PAL_VRETRACERATE 50
|
||||
#define TED7360_HRETRACERATE 15625
|
||||
|
||||
/* the following values depend on the VIC clock,
|
||||
* but to achieve TV-frequency the clock must have a fix frequency */
|
||||
#define TED7360_HSIZE 320
|
||||
#define TED7360_VSIZE 200
|
||||
|
||||
/* of course you clock select an other clock, but for accurate */
|
||||
/* video timing (these are used in c16/c116/plus4) */
|
||||
#define TED7360NTSC_CLOCK (14318180/4)
|
||||
#define TED7360PAL_CLOCK (17734470/5)
|
||||
|
||||
/* pal 50 Hz vertical screen refresh, screen consists of 312 lines
|
||||
* ntsc 60 Hz vertical screen refresh, screen consists of 262 lines */
|
||||
#define TED7360NTSC_LINES 261
|
||||
#define TED7360PAL_LINES 312
|
||||
|
||||
/***************************************************************************
|
||||
DEVICE CONFIGURATION MACROS
|
||||
***************************************************************************/
|
||||
|
||||
DECLARE_LEGACY_SOUND_DEVICE(TED7360, ted7360);
|
||||
|
||||
#define MCFG_TED7360_ADD(_tag, _interface) \
|
||||
MCFG_SOUND_ADD(_tag, TED7360, 0) \
|
||||
MCFG_DEVICE_CONFIG(_interface)
|
||||
|
||||
|
||||
/*----------- defined in audio/ted7360.c -----------*/
|
||||
|
||||
WRITE8_DEVICE_HANDLER( ted7360_port_w );
|
||||
READ8_DEVICE_HANDLER( ted7360_port_r );
|
||||
|
||||
WRITE_LINE_DEVICE_HANDLER( ted7360_rom_switch_w );
|
||||
READ_LINE_DEVICE_HANDLER( ted7360_rom_switch_r );
|
||||
|
||||
void ted7360_frame_interrupt_gen(device_t *device);
|
||||
void ted7360_raster_interrupt_gen(device_t *device);
|
||||
UINT32 ted7360_video_update(device_t *device, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
|
||||
|
||||
#endif /* __TED7360_H__ */
|
@ -1,710 +0,0 @@
|
||||
/* Kermit protocol implementation.
|
||||
|
||||
Transfer between an emulated machine and an image using the kermit protocol.
|
||||
|
||||
Used in the HP48 S/SX/G/GX emulation.
|
||||
|
||||
Based on the 'KERMIT PROTOCOL MANUAL', Sixth Edition, by Frank da Cruz,
|
||||
Columbia University Center for Computing Activities, New York, June 1986.
|
||||
Available at: http://www-vs.informatik.uni-ulm.de/teach/ws05/rn1/Kermit%20Protocol.pdf
|
||||
|
||||
Used in the HP48 S/SX/G/GX emulation.
|
||||
For HP48 specific kermit notes, see http://www.columbia.edu/kermit/hp48.html
|
||||
|
||||
Only the basic protocol is implemented.
|
||||
The following features are NOT supported:
|
||||
- 8-bit quoting (QBIN)
|
||||
- 2- or 3-byte checksums (only 1-byte supported)
|
||||
- repeat count
|
||||
- file attribute packets
|
||||
- sliding window
|
||||
- extended length packets
|
||||
- server mode
|
||||
|
||||
Author: Antoine Mine'
|
||||
Date: 29/03/2008
|
||||
*/
|
||||
|
||||
|
||||
#include "emu.h"
|
||||
#include "kermit.h"
|
||||
|
||||
|
||||
/* debugging */
|
||||
#define VERBOSE 0
|
||||
|
||||
#define LOG(x) do { if (VERBOSE) logerror x; } while (0)
|
||||
|
||||
/* protocol bytes */
|
||||
#define KERMIT_SOH 0x01 /* (default) start of header */
|
||||
|
||||
/* packet types */
|
||||
#define KERMIT_DATA 'D' /* data packet */
|
||||
#define KERMIT_ACK 'Y' /* acknowledge */
|
||||
#define KERMIT_NAK 'N' /* negative acknowledge */
|
||||
#define KERMIT_SEND 'S' /* send initiate (exchange parameters) */
|
||||
#define KERMIT_EOT 'B' /* break transmission */
|
||||
#define KERMIT_FILE 'F' /* file header */
|
||||
#define KERMIT_EOF 'Z' /* end of file */
|
||||
#define KERMIT_ERR 'E' /* error */
|
||||
|
||||
#define KERMIT_QCTL '#' /* default escape character */
|
||||
#define KERMIT_EOL 15 /* default terminator: carriage-return */
|
||||
#define KERMIT_MAXL 80 /* default maximum packet length */
|
||||
|
||||
/* protocol state, to drive action */
|
||||
#define KERMIT_IDLE 0 /* nothing to do */
|
||||
#define KERMIT_RESET 1 /* reset after sending the last packet */
|
||||
#define KERMIT_RECEIVE 2 /* receiving */
|
||||
#define KERMIT_SEND_DATA 3 /* sending data */
|
||||
#define KERMIT_SEND_EOF 4 /* sending EOF */
|
||||
#define KERMIT_SEND_EOT 5 /* sendinf EOT */
|
||||
|
||||
/* packet retry parameters */
|
||||
#define KERMIT_MAX_RETRIES 5
|
||||
#define KERMIT_RETRY_DELAY attotime::from_seconds( 10 )
|
||||
|
||||
|
||||
/* packet format is:
|
||||
|
||||
<mark> <len> <seq> <type> <data0> ... <datan> <check>
|
||||
|
||||
- <mark> KERMIT_SOH
|
||||
- <len> number of bytes after <len> (max=94), plus 32
|
||||
- <seq> sequence number, modulo 63, plus 32
|
||||
- <type> one of KERMIT_ packet types
|
||||
- <data> payload, with control characters escaped with KERMIT_QCTL
|
||||
- <check> checksum, from <len> to <datan>, excluding <mark>
|
||||
|
||||
the packet may be followed by arbitrary (non KERMIT_SOH) data, not counted
|
||||
in <len>, <check>, and not interpreted
|
||||
there is generally at least one KERMIT_EOL
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
|
||||
UINT8 pin[1024]; /* packet received */
|
||||
UINT8 pout[1024]; /* packet sent */
|
||||
UINT32 seq; /* sequence number, starting at 0 */
|
||||
UINT16 posin; /* position in pin */
|
||||
UINT16 posout; /* position in pout */
|
||||
UINT16 nbout; /* size of pout */
|
||||
|
||||
UINT8 state; /* current protocol state */
|
||||
UINT8 retries; /* packet retries remaining */
|
||||
|
||||
/* (relevant) configuration information, sent in S and D packet */
|
||||
UINT8 maxl; /* max packet length (value of <len>) */
|
||||
UINT8 npad; /* number of padding characters before packet */
|
||||
UINT8 padc; /* padding character */
|
||||
UINT8 eol; /* character to add after packet */
|
||||
UINT8 qctl; /* escape character */
|
||||
|
||||
emu_timer* resend; /* auto-resend packet */
|
||||
|
||||
device_image_interface* image; /* underlying image */
|
||||
|
||||
running_machine *machine;
|
||||
kermit_config* conf;
|
||||
|
||||
} kermit;
|
||||
|
||||
|
||||
INLINE kermit *get_safe_token(device_t *device)
|
||||
{
|
||||
assert(device != NULL);
|
||||
assert(device->type() == KERMIT);
|
||||
|
||||
return (kermit*)downcast<legacy_device_base *>(device)->token();
|
||||
}
|
||||
|
||||
static int kermit_is_char( UINT8 data )
|
||||
{
|
||||
return data >= 32 && data <= 126;
|
||||
}
|
||||
|
||||
|
||||
static UINT8 kermit_tochar( UINT8 data )
|
||||
{
|
||||
if ( data > 94 )
|
||||
{
|
||||
logerror( "kermit: tochar: %i not in the range 0-94\n", data );
|
||||
}
|
||||
return data + 32;
|
||||
}
|
||||
|
||||
static UINT8 kermit_unchar( UINT8 data )
|
||||
{
|
||||
if ( data < 32 || data > 126 )
|
||||
{
|
||||
logerror( "kermit: unchar: %i not in the range 32-126\n", data );
|
||||
}
|
||||
return data - 32;
|
||||
}
|
||||
|
||||
#define kermit_ctl(x) ((x) ^ 0x40)
|
||||
|
||||
static int kermit_is_ctl( UINT8 x )
|
||||
{
|
||||
x &= 0x7f;
|
||||
return (x < 32) || (x == 127);
|
||||
}
|
||||
|
||||
static UINT8 kermit_checksum( UINT8* packet )
|
||||
{
|
||||
int i, len = kermit_unchar( packet[1] );
|
||||
UINT8 sum = 0;
|
||||
for ( i = 0; i < len; i++ )
|
||||
sum += packet[ i + 1 ];
|
||||
sum = kermit_tochar( (sum + (sum >> 6)) & 63 );
|
||||
return sum;
|
||||
}
|
||||
|
||||
/* starts sending a new packet */
|
||||
static void kermit_start_sending( kermit* state )
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=1;i<state->nbout;i++)
|
||||
if (kermit_is_ctl(state->pout[i]))
|
||||
logerror( "send: not char %i at pos %i\n", state->pout[i], i );
|
||||
|
||||
if ( state->nbout <= 0 ) return;
|
||||
|
||||
/* prepend padding and append eol */
|
||||
if ( state->npad > 0 )
|
||||
{
|
||||
memmove( state->pout + state->npad, state->pout, state->nbout );
|
||||
memset( state->pout, state->padc, state->npad );
|
||||
state->nbout += state->npad;
|
||||
}
|
||||
state->pout[ state->nbout ] = state->eol;
|
||||
state->nbout++;
|
||||
|
||||
if ( state->conf && state->conf->send )
|
||||
{
|
||||
state->conf->send( *state->machine, state->pout[ 0 ] );
|
||||
}
|
||||
state->posout = 1;
|
||||
|
||||
state->retries = KERMIT_MAX_RETRIES;
|
||||
state->resend->adjust( KERMIT_RETRY_DELAY, 0, KERMIT_RETRY_DELAY );
|
||||
}
|
||||
|
||||
static void kermit_reset( kermit* state );
|
||||
|
||||
static void kermit_resend( kermit* state )
|
||||
{
|
||||
if ( state->conf && state->conf->send )
|
||||
{
|
||||
/* retry */
|
||||
if ( state->nbout == 0 ) return;
|
||||
if ( state->retries <= 0 )
|
||||
{
|
||||
kermit_reset( state );
|
||||
return;
|
||||
}
|
||||
|
||||
state->conf->send( *state->machine, state->pout[ 0 ] );
|
||||
|
||||
state->posout = 1;
|
||||
state->retries--;
|
||||
LOG(( "kermit: resend packet (%i tries left)\n", state->retries ));
|
||||
}
|
||||
}
|
||||
|
||||
/* resend packet periodically */
|
||||
static TIMER_CALLBACK( kermit_resend_cb )
|
||||
{
|
||||
kermit* state = (kermit*) ptr;
|
||||
if ( state->posout >= state->nbout)
|
||||
{
|
||||
kermit_resend( state );
|
||||
}
|
||||
}
|
||||
|
||||
/* fetches image data and wrap it into a kermit data packet */
|
||||
static void kermit_send_data_packet( kermit* state )
|
||||
{
|
||||
int len;
|
||||
LOG(( "kermit: send data packet\n" ));
|
||||
for ( len = 2; len < state->maxl-2; len++ )
|
||||
{
|
||||
UINT8 c;
|
||||
if ( state->image->image_feof() ) break;
|
||||
c = state->image->fgetc();
|
||||
if ( kermit_is_ctl( c ) )
|
||||
{
|
||||
/* escape control char */
|
||||
state->pout[ 2 + len ] = state->qctl;
|
||||
len++;
|
||||
state->pout[ 2 + len ] = kermit_ctl( c );
|
||||
}
|
||||
else if ( (c & 0x7f) == state->qctl )
|
||||
{
|
||||
/* escape escape char */
|
||||
state->pout[ 2 + len ] = state->qctl;
|
||||
len++;
|
||||
state->pout[ 2 + len ] = c;
|
||||
}
|
||||
else
|
||||
{
|
||||
state->pout[ 2 + len ] = c;
|
||||
}
|
||||
}
|
||||
state->pout[ 0 ] = KERMIT_SOH;
|
||||
state->pout[ 1 ] = kermit_tochar( len + 1 );
|
||||
state->pout[ 2 ] = kermit_tochar( state->seq & 63 );
|
||||
state->pout[ 3 ] = KERMIT_DATA;
|
||||
state->pout[ 2 + len ] = kermit_checksum( state->pout );
|
||||
state->nbout = len + 3;
|
||||
kermit_start_sending( state );
|
||||
}
|
||||
|
||||
/* write data from packet to the image */
|
||||
static void kermit_write_data_packet( kermit* state )
|
||||
{
|
||||
int i, len = kermit_unchar( state->pin[1] );
|
||||
LOG(( "kermit: received data pack, len=%i\n", len ));
|
||||
for ( i = 4; i <= len; i++ )
|
||||
{
|
||||
UINT8 c = state->pin[i];
|
||||
if ( (c /*& 0x7f*/) == state->qctl )
|
||||
{
|
||||
/* unescape */
|
||||
i++;
|
||||
c = state->pin[i];
|
||||
if ( kermit_is_ctl( kermit_ctl( c ) ) )
|
||||
{
|
||||
c = kermit_ctl( c );
|
||||
}
|
||||
}
|
||||
state->image->fwrite(&c, 1 );
|
||||
}
|
||||
}
|
||||
|
||||
/* validate received packet and acquire seq number, <0 if error */
|
||||
static int kermit_validate_packet( kermit* state )
|
||||
{
|
||||
int len;
|
||||
if ( state->pin[ 0 ] != KERMIT_SOH ) return -1;
|
||||
if ( !kermit_is_char( state->pin[1] ) ) return -1;
|
||||
if ( !kermit_is_char( state->pin[2] ) ) return -1;
|
||||
len = kermit_unchar( state->pin[1] );
|
||||
if ( state->pin[ 1 + len ] != kermit_checksum( state->pin ) ) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* interpret configuration packet, <0 if error */
|
||||
static int kermit_get_conf( kermit* state )
|
||||
{
|
||||
int len = kermit_unchar( state->pin[1] );
|
||||
if ( len >= 4 ) state->maxl = kermit_unchar( state->pin[ 4 ] );
|
||||
if ( len >= 6 ) state->npad = kermit_unchar( state->pin[ 6 ] );
|
||||
if ( len >= 7 ) state->padc = kermit_ctl( state->pin[ 7 ] );
|
||||
if ( len >= 8 ) state->eol = kermit_unchar( state->pin[ 8 ] );
|
||||
if ( len >= 9 ) state->qctl = state->pin[ 9 ];
|
||||
|
||||
LOG(( "kermit: get conf: len=%i, maxl=%i, npad=%i, padc=%i, eol=%i, qctl=%i\n",
|
||||
len, state->maxl, state->npad, state->padc, state->eol, state->qctl ));
|
||||
|
||||
/* validation */
|
||||
if ( state->maxl < 10 || state->maxl > 94 ) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* create a configuration packet, with header h */
|
||||
static void kermit_send_conf_packet( kermit* state, UINT8 h )
|
||||
{
|
||||
LOG(( "kermit: send conf packet of type %c\n", h ));
|
||||
state->seq = 0;
|
||||
state->pout[ 0 ] = KERMIT_SOH;
|
||||
state->pout[ 1 ] = kermit_tochar( 13 );
|
||||
state->pout[ 2 ] = kermit_tochar( state->seq & 63 );
|
||||
state->pout[ 3 ] = h;
|
||||
state->pout[ 4 ] = kermit_tochar( state->maxl ); /* maxl */
|
||||
state->pout[ 5 ] = kermit_tochar( 1 ); /* time: 1 sec */
|
||||
state->pout[ 6 ] = kermit_tochar( state->npad ); /* npad */
|
||||
state->pout[ 7 ] = kermit_ctl( state->padc ); /* padc */
|
||||
state->pout[ 8 ] = kermit_tochar( state->eol ); /* eol */
|
||||
state->pout[ 9 ] = state->qctl; /* qtcl */
|
||||
state->pout[ 10 ] = 'N'; /* qbin: no 8-bit quoting */
|
||||
state->pout[ 11 ] = '1'; /* chkt: single character checksum */
|
||||
state->pout[ 12 ] = ' '; /* rept: no repeat count */
|
||||
state->pout[ 13 ] = kermit_tochar( 0 ); /* capas: no capabilities */
|
||||
state->pout[ 14 ] = kermit_checksum( state->pout );
|
||||
state->nbout = 15;
|
||||
kermit_start_sending( state );
|
||||
}
|
||||
|
||||
/* sends a packet with no data */
|
||||
static void kermit_send_simple_packet( kermit* state, UINT8 h )
|
||||
{
|
||||
LOG(( "kermit: send empty packet of type %c, seq=%i\n", h, state->seq & 63 ));
|
||||
state->pout[ 0 ] = KERMIT_SOH;
|
||||
state->pout[ 1 ] = kermit_tochar( 3 );
|
||||
state->pout[ 2 ] = kermit_tochar( state->seq & 63 );
|
||||
state->pout[ 3 ] = h;
|
||||
state->pout[ 4 ] = kermit_checksum( state->pout );
|
||||
state->nbout = 5;
|
||||
kermit_start_sending( state );
|
||||
}
|
||||
|
||||
/* sends a packet with string data */
|
||||
static void kermit_send_string_packet( kermit* state, UINT8 h, const char* data )
|
||||
{
|
||||
int i, len;
|
||||
LOG(( "kermit: send string packet of type %c, data=%s, seq=%i\n", h, data, state->seq & 63 ));
|
||||
for ( len = i = 0; (len < state->maxl - 5) && data[i]; i++ )
|
||||
{
|
||||
char c = data[i];
|
||||
if ( kermit_is_char( c ) && ( c != '_' ) && ( c != ' ' ) )
|
||||
{
|
||||
state->pout[ 4 + len ] = c;
|
||||
len++;
|
||||
}
|
||||
}
|
||||
state->pout[ 0 ] = KERMIT_SOH;
|
||||
state->pout[ 1 ] = kermit_tochar( len + 3 );
|
||||
state->pout[ 2 ] = kermit_tochar( state->seq & 63 );
|
||||
state->pout[ 3 ] = h;
|
||||
state->pout[ 4 + len ] = kermit_checksum( state->pout );
|
||||
state->nbout = len + 5;
|
||||
kermit_start_sending( state );
|
||||
}
|
||||
|
||||
/* extract the string contained in received packet */
|
||||
static char* kermit_string_in_packet( kermit* state )
|
||||
{
|
||||
int len = kermit_unchar( state->pin[1] );
|
||||
state->pin[ len + 1 ] = 0;
|
||||
return (char*) state->pin + 4;
|
||||
}
|
||||
|
||||
static void kermit_reset( kermit* state )
|
||||
{
|
||||
/* default config */
|
||||
state->maxl = KERMIT_MAXL;
|
||||
state->npad = 0;
|
||||
state->padc = 0;
|
||||
state->eol = KERMIT_EOL;
|
||||
state->qctl = KERMIT_QCTL;
|
||||
|
||||
state->retries = KERMIT_MAX_RETRIES;
|
||||
state->posin = 0;
|
||||
state->posout = 0;
|
||||
state->nbout = 0;
|
||||
state->state = KERMIT_IDLE;
|
||||
state->seq = 0;
|
||||
|
||||
if ( state->image )
|
||||
{
|
||||
state->image->fseek( SEEK_SET, 0 );
|
||||
}
|
||||
|
||||
state->resend->adjust( attotime::never, 0, attotime::never );
|
||||
}
|
||||
|
||||
|
||||
/* emulated machine sends a byte to the outside (us) */
|
||||
void kermit_receive_byte( device_t *device, UINT8 data )
|
||||
{
|
||||
kermit* state = get_safe_token(device);
|
||||
|
||||
LOG(( "get %i %2x %c (%i)\n", data, data, data, state->posin ));
|
||||
|
||||
/* get SOH */
|
||||
if ( (data == KERMIT_SOH) && (state->posin <= 1) )
|
||||
{
|
||||
state->pin[ 0 ] = data;
|
||||
state->posin = 1;
|
||||
}
|
||||
|
||||
/* get packet contents */
|
||||
else if ( state->posin > 0 )
|
||||
{
|
||||
if ( state->posin >= sizeof( state->pout ) )
|
||||
{
|
||||
LOG(( "kermit: too many bytes received\n" ));
|
||||
state->posin = 0;
|
||||
kermit_send_simple_packet( state, KERMIT_NAK );
|
||||
return;
|
||||
}
|
||||
|
||||
if (kermit_is_ctl(data))
|
||||
logerror( "received: not char %i at pos %i\n", data, state->posin );
|
||||
|
||||
state->pin[ state->posin ] = data;
|
||||
state->posin++;
|
||||
|
||||
if ( state->posin > 5 )
|
||||
{
|
||||
int len, seq, typ;
|
||||
if ( !kermit_is_char( state->pin[1] ) ||
|
||||
(kermit_unchar( state->pin[1] ) < 3) ||
|
||||
(kermit_unchar( state->pin[1] ) > state->maxl) )
|
||||
{
|
||||
LOG(( "kermit: invalid packet size %i-32, not in 3-%i\n", state->pin[1], state->maxl ));
|
||||
kermit_resend( state );
|
||||
return;
|
||||
}
|
||||
|
||||
len = kermit_unchar( state->pin[1] );
|
||||
|
||||
if ( state->posin >= len + 2 )
|
||||
{
|
||||
/* got packet! */
|
||||
state->posin = 0;
|
||||
if ( kermit_validate_packet( state ) )
|
||||
{
|
||||
LOG(( "kermit: invalid packet\n" ));
|
||||
kermit_resend( state );
|
||||
return;
|
||||
}
|
||||
|
||||
typ = state->pin[3];
|
||||
seq = kermit_unchar( state->pin[2] );
|
||||
|
||||
LOG(( "kermit: received packet type=%c, seq=%i, len=%i\n", typ, seq, len ));
|
||||
|
||||
if ( !state->image )
|
||||
{
|
||||
kermit_send_string_packet( state, KERMIT_ERR, "NO IMAGE" );
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
switch ( typ )
|
||||
{
|
||||
|
||||
/* receiving */
|
||||
|
||||
case KERMIT_SEND:
|
||||
kermit_get_conf( state );
|
||||
if ( state->maxl >= KERMIT_MAXL )
|
||||
{
|
||||
state->maxl = KERMIT_MAXL;
|
||||
}
|
||||
kermit_send_conf_packet( state, KERMIT_ACK );
|
||||
state->state = KERMIT_RECEIVE;
|
||||
break;
|
||||
|
||||
case KERMIT_FILE:
|
||||
LOG(( "kermit: got file name '%s'\n", kermit_string_in_packet( state ) ));
|
||||
state->seq = seq;
|
||||
kermit_send_simple_packet( state, KERMIT_ACK );
|
||||
break;
|
||||
|
||||
case KERMIT_DATA:
|
||||
case KERMIT_EOF:
|
||||
if ( seq == ((state->seq + 1) & 63) )
|
||||
{
|
||||
/* next packet */
|
||||
if ( typ == KERMIT_DATA )
|
||||
{
|
||||
kermit_write_data_packet( state );
|
||||
}
|
||||
state->seq = seq;
|
||||
kermit_send_simple_packet( state, KERMIT_ACK );
|
||||
}
|
||||
else if ( seq == (state->seq & 63) )
|
||||
{
|
||||
/* same packet */
|
||||
kermit_send_simple_packet( state, KERMIT_ACK );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* unexpected sequence number */
|
||||
LOG(( "kermit: got seq=%i, expected %i\n", seq, (state->seq + 1) & 63 ));
|
||||
state->seq++;
|
||||
kermit_send_simple_packet( state, KERMIT_NAK );
|
||||
state->seq--;
|
||||
}
|
||||
break;
|
||||
|
||||
case KERMIT_EOT:
|
||||
/* send ack and reset */
|
||||
state->seq = seq;
|
||||
kermit_send_simple_packet( state, KERMIT_ACK );
|
||||
state->state = KERMIT_RESET;
|
||||
break;
|
||||
|
||||
|
||||
/* sending */
|
||||
|
||||
case KERMIT_NAK:
|
||||
case KERMIT_ACK:
|
||||
|
||||
if ( (typ == KERMIT_NAK) && (seq == 0) && (state->state == KERMIT_IDLE) )
|
||||
{
|
||||
/* transfer start */
|
||||
kermit_send_conf_packet( state, KERMIT_SEND );
|
||||
break;
|
||||
}
|
||||
|
||||
if ( ((seq == (state->seq & 63)) && (typ == KERMIT_ACK)) ||
|
||||
((seq == ((state->seq + 1) & 63)) && (typ == KERMIT_NAK)) )
|
||||
{
|
||||
/* send next packet */
|
||||
|
||||
state->seq = state->seq + 1;
|
||||
|
||||
switch ( state->state )
|
||||
{
|
||||
case KERMIT_IDLE:
|
||||
/* get conf & send file name */
|
||||
kermit_get_conf( state );
|
||||
kermit_send_string_packet( state, KERMIT_FILE, state->image->basename() );
|
||||
state->state = KERMIT_SEND_DATA;
|
||||
break;
|
||||
|
||||
case KERMIT_SEND_DATA:
|
||||
/* send next data packet or EOF */
|
||||
if ( state->image->image_feof() )
|
||||
{
|
||||
kermit_send_simple_packet( state, KERMIT_EOF );
|
||||
state->state = KERMIT_SEND_EOF;
|
||||
}
|
||||
else
|
||||
{
|
||||
kermit_send_data_packet( state );
|
||||
}
|
||||
break;
|
||||
|
||||
case KERMIT_SEND_EOF:
|
||||
/* send EOT */
|
||||
kermit_send_simple_packet( state, KERMIT_EOT );
|
||||
state->state = KERMIT_SEND_EOT;
|
||||
break;
|
||||
|
||||
case KERMIT_SEND_EOT:
|
||||
/* reset */
|
||||
kermit_reset( state );
|
||||
state->state = KERMIT_RESET;
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
else if ( (seq == (state->seq & 63)) && (typ == KERMIT_NAK) )
|
||||
{
|
||||
/* resend last packet */
|
||||
kermit_resend( state );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* bad */
|
||||
LOG(( "kermit: expected to send %i, got seq=%i\n", (state->seq + 1) & 63, seq ));
|
||||
kermit_reset( state );
|
||||
}
|
||||
break;
|
||||
|
||||
/* errors */
|
||||
|
||||
case KERMIT_ERR:
|
||||
LOG(( "kermit: got error '%s'\n", kermit_string_in_packet( state ) ));
|
||||
state->seq = seq;
|
||||
kermit_reset( state );
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG(( "kermit: ignoring packet type %c\n", state->pin[ 3 ] ));
|
||||
/* no abort, just ignoring */
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void kermit_byte_transmitted( device_t *device )
|
||||
{
|
||||
kermit* state = get_safe_token(device);
|
||||
|
||||
LOG(( "transmitted %i %2x %c, %i / %i\n", state->pout[ state->posout-1 ], state->pout[ state->posout-1 ], state->pout[ state->posout-1 ], state->posout - 1, state->nbout - 1 ));
|
||||
|
||||
/* at end of packet */
|
||||
if ( state->posout >= state->nbout )
|
||||
{
|
||||
if ( state->state == KERMIT_RESET )
|
||||
{
|
||||
kermit_reset( state );
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if ( state->conf && state->conf->send )
|
||||
{
|
||||
state->conf->send(*state->machine, state->pout[ state->posout ] );
|
||||
}
|
||||
state->posout++;
|
||||
}
|
||||
|
||||
static DEVICE_START( kermit )
|
||||
{
|
||||
kermit* state = get_safe_token(device);
|
||||
LOG(( "kermit: start\n" ));
|
||||
state->image = NULL;
|
||||
state->conf = (kermit_config*) device->static_config();
|
||||
state->machine = &device->machine();
|
||||
state->resend = device->machine().scheduler().timer_alloc(FUNC(kermit_resend_cb), state );
|
||||
kermit_reset( state );
|
||||
}
|
||||
|
||||
static DEVICE_RESET( kermit )
|
||||
{
|
||||
kermit* state = get_safe_token(device);
|
||||
LOG(( "kermit: reset\n" ));
|
||||
kermit_reset( state );
|
||||
}
|
||||
|
||||
static DEVICE_IMAGE_LOAD( kermit )
|
||||
{
|
||||
kermit* state = get_safe_token(&image.device());
|
||||
LOG(( "kermit: image load\n" ));
|
||||
state->image = ℑ
|
||||
kermit_reset( state );
|
||||
return IMAGE_INIT_PASS;
|
||||
}
|
||||
|
||||
static DEVICE_IMAGE_CREATE( kermit )
|
||||
{
|
||||
kermit* state = get_safe_token(&image.device());
|
||||
LOG(( "kermit: image create\n" ));
|
||||
state->image = ℑ
|
||||
kermit_reset( state );
|
||||
return IMAGE_INIT_PASS;
|
||||
}
|
||||
|
||||
static DEVICE_IMAGE_UNLOAD( kermit )
|
||||
{
|
||||
kermit* state = get_safe_token(&image.device());
|
||||
LOG(( "kermit: image unload\n" ));
|
||||
state->image = NULL;
|
||||
kermit_reset( state );
|
||||
}
|
||||
|
||||
DEVICE_GET_INFO( kermit )
|
||||
|
||||
{
|
||||
switch ( state ) {
|
||||
case DEVINFO_INT_TOKEN_BYTES: info->i = sizeof( kermit ); break;
|
||||
case DEVINFO_INT_INLINE_CONFIG_BYTES: info->i = 0; break;
|
||||
case DEVINFO_INT_IMAGE_TYPE: info->i = IO_SERIAL; break;
|
||||
case DEVINFO_INT_IMAGE_READABLE: info->i = 1; break;
|
||||
case DEVINFO_INT_IMAGE_WRITEABLE: info->i = 1; break;
|
||||
case DEVINFO_INT_IMAGE_CREATABLE: info->i = 1; break;
|
||||
case DEVINFO_FCT_START: info->start = DEVICE_START_NAME( kermit ); break;
|
||||
case DEVINFO_FCT_RESET: info->reset = DEVICE_RESET_NAME( kermit ); break;
|
||||
case DEVINFO_FCT_IMAGE_LOAD: info->f = (genf *) DEVICE_IMAGE_LOAD_NAME( kermit ); break;
|
||||
case DEVINFO_FCT_IMAGE_UNLOAD: info->f = (genf *) DEVICE_IMAGE_UNLOAD_NAME( kermit ); break;
|
||||
case DEVINFO_FCT_IMAGE_CREATE: info->f = (genf *) DEVICE_IMAGE_CREATE_NAME( kermit ); break;
|
||||
case DEVINFO_STR_IMAGE_BRIEF_INSTANCE_NAME: strcpy(info->s, "k"); break;
|
||||
case DEVINFO_STR_IMAGE_INSTANCE_NAME:
|
||||
case DEVINFO_STR_NAME: strcpy(info->s, "Kermit"); break;
|
||||
case DEVINFO_STR_FAMILY: strcpy(info->s, "Serial protocol"); break;
|
||||
case DEVINFO_STR_SOURCE_FILE: strcpy(info->s, __FILE__); break;
|
||||
case DEVINFO_STR_IMAGE_FILE_EXTENSIONS: strcpy(info->s, ""); break;
|
||||
}
|
||||
}
|
||||
|
||||
DEFINE_LEGACY_IMAGE_DEVICE(KERMIT, kermit);
|
@ -1,36 +0,0 @@
|
||||
/* Kermit protocol implementation.
|
||||
|
||||
Transfer between an emulated machine and an image using the kermit protocol.
|
||||
|
||||
Used in the HP48 S/SX/G/GX emulation.
|
||||
|
||||
Author: Antoine Mine'
|
||||
Date: 29/03/2008
|
||||
*/
|
||||
|
||||
#include "timer.h"
|
||||
#include "image.h"
|
||||
|
||||
|
||||
DECLARE_LEGACY_IMAGE_DEVICE(KERMIT, kermit);
|
||||
|
||||
|
||||
typedef struct {
|
||||
|
||||
/* called by Kermit when it wants to send a byte to the emulated machine */
|
||||
void (*send)( running_machine &machine, UINT8 data );
|
||||
|
||||
} kermit_config;
|
||||
|
||||
|
||||
#define MCFG_KERMIT_ADD(_tag, _intrf) \
|
||||
MCFG_DEVICE_ADD(_tag, KERMIT, 0) \
|
||||
MCFG_DEVICE_CONFIG(_intrf)
|
||||
|
||||
|
||||
/* call this when the emulated machine has read the last byte sent by
|
||||
Kermit through the send call-back */
|
||||
extern void kermit_byte_transmitted( device_t *device );
|
||||
|
||||
/* call this when the emulated machine sends a byte to Kermit */
|
||||
extern void kermit_receive_byte( device_t *device, UINT8 data );
|
@ -1,368 +0,0 @@
|
||||
/* XMODEM protocol implementation.
|
||||
|
||||
Transfer between an emulated machine and an image using the XMODEM protocol.
|
||||
|
||||
Used in the HP48 G/GX emulation.
|
||||
|
||||
Based on the "Xmodem protol specification" by Ward Christensen.
|
||||
|
||||
Does not support any extension (such as 16-bit CRC, 1K packet size,
|
||||
batchs, YMODEM, ZMODEM).
|
||||
|
||||
Author: Antoine Mine'
|
||||
Date: 29/03/2008
|
||||
*/
|
||||
|
||||
#include "emu.h"
|
||||
#include "xmodem.h"
|
||||
|
||||
|
||||
/* debugging */
|
||||
#define VERBOSE 0
|
||||
|
||||
#define LOG(x) do { if (VERBOSE) logerror x; } while (0)
|
||||
|
||||
|
||||
/* XMODEM protocol bytes */
|
||||
#define XMODEM_SOH 0x01 /* data packet header */
|
||||
#define XMODEM_EOT 0x04 /* end of transmission */
|
||||
#define XMODEM_ACK 0x06 /* acknowledge (packet received) */
|
||||
#define XMODEM_NAK 0x15 /* not-acknowledge (10-second timeout) */
|
||||
#define XMODEM_CAN 0x18 /* cancel */
|
||||
|
||||
/* XMODEM protocol is:
|
||||
|
||||
sender receiver
|
||||
|
||||
<-- <NAK>
|
||||
packet -->
|
||||
<-- <ACK>
|
||||
...
|
||||
packet -->
|
||||
<-- <ACK>
|
||||
<EOT> -->
|
||||
<-- <ACK>
|
||||
|
||||
and packet is: <SOH> <id> <0xff-id> <data0> ... <data127> <checksum>
|
||||
|
||||
<id> is 1 for the first packet, 2 for the 2d, etc...
|
||||
<checksum> is the sum of <data0> to <data127> modulo 256
|
||||
|
||||
there are always 128 bytes of data in a packet, so, any file transfered is
|
||||
rounded to a multiple of 128 bytes, using 0-filler
|
||||
*/
|
||||
|
||||
|
||||
/* our state */
|
||||
#define XMODEM_NOIMAGE 0
|
||||
#define XMODEM_IDLE 1
|
||||
#define XMODEM_SENDING 2 /* image to emulated machine */
|
||||
#define XMODEM_RECEIVING 3 /* emulated machine to image */
|
||||
|
||||
typedef struct {
|
||||
|
||||
UINT8 m_block[132]; /* 3-byte header + 128-byte block + checksum */
|
||||
UINT32 m_id; /* block id, starting at 1 */
|
||||
UINT16 m_pos; /* position in block, including header */
|
||||
UINT8 m_state; /* one of XMODEM_ */
|
||||
|
||||
device_image_interface* m_image; /* underlying image */
|
||||
|
||||
emu_timer* m_timer; /* used to send periodic NAKs */
|
||||
|
||||
running_machine *m_machine;
|
||||
|
||||
xmodem_config* m_conf;
|
||||
|
||||
} xmodem;
|
||||
|
||||
INLINE xmodem *get_safe_token(device_t *device)
|
||||
{
|
||||
assert(device != NULL);
|
||||
assert(device->type() == XMODEM);
|
||||
|
||||
return (xmodem*)downcast<legacy_device_base *>(device)->token();
|
||||
}
|
||||
|
||||
/* compute checksum of the data part of the packet, i.e., sum modulo 256 */
|
||||
static UINT8 xmodem_chksum( xmodem* state )
|
||||
{
|
||||
UINT8 sum = 0;
|
||||
int i;
|
||||
for ( i = 0; i < 128; i++ ) sum += state->m_block[ i + 3 ];
|
||||
return sum;
|
||||
}
|
||||
|
||||
/* fills state->m_block with the data for packet number state->m_id
|
||||
returns != 0 if fail or end of file
|
||||
*/
|
||||
static int xmodem_make_send_block( xmodem* state )
|
||||
{
|
||||
if ( ! state->m_image ) return -1;
|
||||
memset( state->m_block + 3, 0, 128 );
|
||||
if ( state->m_image->fseek( (state->m_id - 1) * 128, SEEK_SET ) ) return -1;
|
||||
if ( state->m_image->fread( state->m_block + 3, 128 ) <= 0 ) return -1;
|
||||
state->m_block[0] = XMODEM_SOH;
|
||||
state->m_block[1] = state->m_id & 0xff;
|
||||
state->m_block[2] = 0xff - state->m_block[1];
|
||||
state->m_block[131] = xmodem_chksum( state );
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* checks the received state->m_block packet and stores the data in the image
|
||||
returns != 0 if fail (bad packet or bad image)
|
||||
*/
|
||||
static int xmodem_get_receive_block( xmodem* state )
|
||||
{
|
||||
int next_id = state->m_id + 1;
|
||||
if ( ! state->m_image ) return -1;
|
||||
if ( state->m_image->is_readonly() ) return -1;
|
||||
if ( state->m_block[0] != XMODEM_SOH ) return -1;
|
||||
if ( state->m_block[1] != 0xff - state->m_block[2] ) return -1;
|
||||
if ( state->m_block[131] != xmodem_chksum( state ) ) return -1;
|
||||
if ( state->m_block[1] != (next_id & 0xff) ) return -1;
|
||||
if ( state->m_image->fseek( (next_id - 1) * 128, SEEK_SET ) ) return -1;
|
||||
if ( state->m_image->fwrite( state->m_block + 3, 128 ) != 128 ) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* the outside (us) sends a byte to the emulated machine */
|
||||
static void xmodem_send_byte( xmodem* state, UINT8 data )
|
||||
{
|
||||
if ( state->m_conf && state->m_conf->send )
|
||||
{
|
||||
state->m_conf->send(*state->m_machine, data );
|
||||
}
|
||||
}
|
||||
|
||||
static void xmodem_send_packet_byte( xmodem* state )
|
||||
{
|
||||
assert( state->m_pos < 132 );
|
||||
xmodem_send_byte( state, state->m_block[ state->m_pos ] );
|
||||
state->m_pos++;
|
||||
}
|
||||
|
||||
|
||||
static TIMER_CALLBACK( xmodem_nak_cb )
|
||||
{
|
||||
xmodem* state = (xmodem*) ptr;
|
||||
if ( state->m_state != XMODEM_IDLE ) return;
|
||||
LOG(( "xmodem: sending NAK keep-alive\n" ));
|
||||
xmodem_send_byte( state, XMODEM_NAK );
|
||||
}
|
||||
|
||||
static void xmodem_make_idle( xmodem* state )
|
||||
{
|
||||
LOG(( "xmodem: entering idle state\n" ));
|
||||
state->m_state = XMODEM_IDLE;
|
||||
state->m_id = 0;
|
||||
state->m_pos = 0;
|
||||
/* When idle, we send NAK periodically to tell the emulated machine that we are
|
||||
always ready to receive.
|
||||
The 2 sec start time is here so that the machine does not get NAK instead of
|
||||
ACK or EOT as the last byte of a transfer.
|
||||
*/
|
||||
state->m_timer->adjust( attotime::from_seconds( 2 ), 0, attotime::from_seconds( 2 ) );
|
||||
}
|
||||
|
||||
/* emulated machine has read the last byte we sent */
|
||||
void xmodem_byte_transmitted( device_t *device )
|
||||
{
|
||||
xmodem* state = get_safe_token(device);
|
||||
if ( (state->m_state == XMODEM_SENDING) && (state->m_pos < 132) )
|
||||
{
|
||||
/* send next byte */
|
||||
xmodem_send_packet_byte( state );
|
||||
}
|
||||
}
|
||||
|
||||
/* emulated machine sends a byte to the outside (us) */
|
||||
void xmodem_receive_byte( device_t *device, UINT8 data )
|
||||
{
|
||||
xmodem* state = get_safe_token(device);
|
||||
switch ( state->m_state )
|
||||
{
|
||||
|
||||
case XMODEM_NOIMAGE:
|
||||
break;
|
||||
|
||||
case XMODEM_IDLE:
|
||||
if ( data == XMODEM_NAK )
|
||||
{
|
||||
/* start sending */
|
||||
LOG(( "xmodem: got NAK, start sending\n" ));
|
||||
state->m_id = 1;
|
||||
if ( xmodem_make_send_block( state ) )
|
||||
{
|
||||
/* error */
|
||||
LOG(( "xmodem: nothing to send, sending NAK\n" ));
|
||||
xmodem_send_byte( state, XMODEM_NAK );
|
||||
xmodem_make_idle( state );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* send first packet */
|
||||
state->m_state = XMODEM_SENDING;
|
||||
state->m_pos = 0;
|
||||
xmodem_send_packet_byte( state );
|
||||
}
|
||||
break;
|
||||
}
|
||||
else if ( data == XMODEM_SOH )
|
||||
{
|
||||
/* start receiving */
|
||||
LOG(( "xmodem: got SOH, start receiving\n" ));
|
||||
state->m_state = XMODEM_RECEIVING;
|
||||
state->m_block[ 0 ] = data;
|
||||
state->m_pos = 1;
|
||||
state->m_id = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(( "xmodem: ignored data %02x while idle\n", data ));
|
||||
}
|
||||
break;
|
||||
|
||||
case XMODEM_SENDING:
|
||||
if ( (data != XMODEM_NAK) && (data != XMODEM_ACK) )
|
||||
{
|
||||
/* error */
|
||||
LOG(( "xmodem: invalid date %02x while sending, sending CAN\n", data ));
|
||||
xmodem_send_byte( state, XMODEM_CAN );
|
||||
xmodem_make_idle( state );
|
||||
break;
|
||||
}
|
||||
if ( data == XMODEM_ACK )
|
||||
{
|
||||
/* send next packet */
|
||||
state->m_id++;
|
||||
LOG(( "xmodem: got ACK, sending next packet (%i)\n", state->m_id ));
|
||||
if ( xmodem_make_send_block( state ) )
|
||||
{
|
||||
/* end of file */
|
||||
LOG(( "xmodem: no more packet, sending EOT\n" ));
|
||||
xmodem_send_byte( state, XMODEM_EOT );
|
||||
xmodem_make_idle( state );
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
/* empty - resend last packet */
|
||||
LOG(( "xmodem: got NAK, resending packet %i\n", state->m_id ));
|
||||
}
|
||||
state->m_pos = 0;
|
||||
xmodem_send_packet_byte( state );
|
||||
break;
|
||||
|
||||
|
||||
case XMODEM_RECEIVING:
|
||||
assert( state->m_pos < 132 );
|
||||
state->m_block[ state->m_pos ] = data;
|
||||
state->m_pos++;
|
||||
if ( state->m_pos == 1 )
|
||||
{
|
||||
/* header byte */
|
||||
if ( data == XMODEM_EOT )
|
||||
{
|
||||
/* end of file */
|
||||
LOG(( "xmodem: got EOT, stop receiving\n" ));
|
||||
xmodem_send_byte( state, XMODEM_ACK );
|
||||
xmodem_make_idle( state );
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if ( state->m_pos == 132 )
|
||||
{
|
||||
LOG(( "xmodem: received packet %i\n", state->m_id ));
|
||||
/* end of block */
|
||||
if ( xmodem_get_receive_block( state ) )
|
||||
{
|
||||
/* error */
|
||||
LOG(( "xmodem: packet is invalid, sending NAK\n" ));
|
||||
xmodem_send_byte( state, XMODEM_NAK );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* ok */
|
||||
LOG(( "xmodem: packet is valid, sending ACK\n" ));
|
||||
xmodem_send_byte( state, XMODEM_ACK );
|
||||
state->m_id++;
|
||||
}
|
||||
state->m_pos = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static DEVICE_START( xmodem )
|
||||
{
|
||||
xmodem* state = get_safe_token(device);
|
||||
LOG(( "xmodem: start\n" ));
|
||||
state->m_state = XMODEM_NOIMAGE;
|
||||
state->m_image = NULL;
|
||||
state->m_conf = (xmodem_config*) device->static_config();
|
||||
state->m_machine = &device->machine();
|
||||
state->m_timer = device->machine().scheduler().timer_alloc(FUNC(xmodem_nak_cb), state );
|
||||
}
|
||||
|
||||
static DEVICE_RESET( xmodem )
|
||||
{
|
||||
xmodem* state = get_safe_token(device);
|
||||
LOG(( "xmodem: reset\n" ));
|
||||
if ( state->m_state != XMODEM_NOIMAGE ) xmodem_make_idle( state );
|
||||
}
|
||||
|
||||
static DEVICE_IMAGE_LOAD( xmodem )
|
||||
{
|
||||
xmodem* state = get_safe_token(&image.device());
|
||||
LOG(( "xmodem: image load\n" ));
|
||||
state->m_image = ℑ
|
||||
xmodem_make_idle( state );
|
||||
return IMAGE_INIT_PASS;
|
||||
}
|
||||
|
||||
static DEVICE_IMAGE_CREATE( xmodem )
|
||||
{
|
||||
xmodem* state = get_safe_token(&image.device());
|
||||
LOG(( "xmodem: image create\n" ));
|
||||
state->m_image = ℑ
|
||||
xmodem_make_idle( state );
|
||||
return IMAGE_INIT_PASS;
|
||||
}
|
||||
|
||||
static DEVICE_IMAGE_UNLOAD( xmodem )
|
||||
{
|
||||
xmodem* state = get_safe_token(&image.device());
|
||||
LOG(( "xmodem: image unload\n" ));
|
||||
state->m_state = XMODEM_NOIMAGE;
|
||||
state->m_image = NULL;
|
||||
}
|
||||
|
||||
DEVICE_GET_INFO( xmodem )
|
||||
|
||||
{
|
||||
switch ( state ) {
|
||||
case DEVINFO_INT_TOKEN_BYTES: info->i = sizeof( xmodem ); break;
|
||||
case DEVINFO_INT_INLINE_CONFIG_BYTES: info->i = 0; break;
|
||||
case DEVINFO_INT_IMAGE_TYPE: info->i = IO_SERIAL; break;
|
||||
case DEVINFO_INT_IMAGE_READABLE: info->i = 1; break;
|
||||
case DEVINFO_INT_IMAGE_WRITEABLE: info->i = 1; break;
|
||||
case DEVINFO_INT_IMAGE_CREATABLE: info->i = 1; break;
|
||||
case DEVINFO_FCT_START: info->start = DEVICE_START_NAME( xmodem ); break;
|
||||
case DEVINFO_FCT_RESET: info->reset = DEVICE_RESET_NAME( xmodem ); break;
|
||||
case DEVINFO_FCT_IMAGE_LOAD: info->f = (genf *) DEVICE_IMAGE_LOAD_NAME( xmodem ); break;
|
||||
case DEVINFO_FCT_IMAGE_UNLOAD: info->f = (genf *) DEVICE_IMAGE_UNLOAD_NAME( xmodem ); break;
|
||||
case DEVINFO_FCT_IMAGE_CREATE: info->f = (genf *) DEVICE_IMAGE_CREATE_NAME( xmodem ); break;
|
||||
case DEVINFO_STR_IMAGE_BRIEF_INSTANCE_NAME: strcpy(info->s, "x"); break;
|
||||
case DEVINFO_STR_IMAGE_INSTANCE_NAME:
|
||||
case DEVINFO_STR_NAME: strcpy(info->s, "Xmodem"); break;
|
||||
case DEVINFO_STR_FAMILY: strcpy(info->s, "Serial protocol"); break;
|
||||
case DEVINFO_STR_SOURCE_FILE: strcpy(info->s, __FILE__); break;
|
||||
case DEVINFO_STR_IMAGE_FILE_EXTENSIONS: strcpy(info->s, ""); break;
|
||||
}
|
||||
}
|
||||
|
||||
DEFINE_LEGACY_IMAGE_DEVICE(XMODEM, xmodem);
|
@ -1,37 +0,0 @@
|
||||
/* XMODEM protocol implementation.
|
||||
|
||||
Transfer between an emulated machine and an image using the XMODEM protocol.
|
||||
|
||||
Used in the HP48 G/GX emulation.
|
||||
|
||||
Author: Antoine Mine'
|
||||
Date: 29/03/2008
|
||||
*/
|
||||
|
||||
#include "timer.h"
|
||||
#include "image.h"
|
||||
|
||||
|
||||
DECLARE_LEGACY_IMAGE_DEVICE(XMODEM, xmodem);
|
||||
|
||||
|
||||
typedef struct {
|
||||
|
||||
/* called by XMODEM when it wants to send a byte to the emulated machine */
|
||||
void (*send)( running_machine &machine, UINT8 data );
|
||||
|
||||
} xmodem_config;
|
||||
|
||||
|
||||
#define MCFG_XMODEM_ADD(_tag, _intrf) \
|
||||
MCFG_DEVICE_ADD(_tag, XMODEM, 0) \
|
||||
MCFG_DEVICE_CONFIG(_intrf)
|
||||
|
||||
|
||||
|
||||
/* call when the emulated machine has read the last byte sent by
|
||||
XMODEM through the send call-back */
|
||||
extern void xmodem_byte_transmitted( device_t *device );
|
||||
|
||||
/* call when the emulated machine sends a byte to XMODEM */
|
||||
extern void xmodem_receive_byte( device_t *device, UINT8 data );
|
@ -1,668 +0,0 @@
|
||||
/***************************************************************************
|
||||
commodore c16 home computer
|
||||
|
||||
PeT mess@utanet.at
|
||||
|
||||
documentation
|
||||
www.funet.fi
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
/*
|
||||
|
||||
2008 - Driver Updates
|
||||
---------------------
|
||||
|
||||
(most of the informations are taken from http://www.zimmers.net/cbmpics/ )
|
||||
|
||||
|
||||
[CBM systems which belong to this driver]
|
||||
|
||||
* Commodore 116 (1984, Europe only)
|
||||
|
||||
Entry level computer of the Commodore 264 family, it was marketed only
|
||||
in Europe. It was impressive for the small size of its case, but it didn't
|
||||
meet commercial success
|
||||
|
||||
CPU: MOS Technology 7501 (variable clock rate, with max 1.76 MHz)
|
||||
RAM: 16 kilobytes (expandable to 64k internally)
|
||||
ROM: 32 kilobytes
|
||||
Video: MOS Technology 7360 "TED" (5 Video modes; Max. Resolution 320x200;
|
||||
40 columns text; Palette of 16 colors in 8 shades, for 128 colors)
|
||||
Sound: MOS Technology 7360 "TED" (2 voice tone-generating sound capabilities)
|
||||
Ports: MOS 7360 (2 Joystick/Mouse ports; CBM Serial port; 'TED' port; "TV"
|
||||
Port and switch; CBM Monitor port; Power and reset switches; Power
|
||||
connector)
|
||||
Keyboard: QWERTY 62 key "membrane" (8 programmable function keys; 4 direction
|
||||
cursor-pad)
|
||||
|
||||
|
||||
* Commodore 16 (1984)
|
||||
|
||||
Redesigned version of the C116, with a different case and a different
|
||||
keyboard.
|
||||
|
||||
CPU: MOS Technology 7501 (variable clock rate, with max 1.76 MHz)
|
||||
RAM: 16 kilobytes (expandable to 64k internally)
|
||||
ROM: 32 kilobytes
|
||||
Video: MOS Technology 7360 "TED" (5 Video modes; Max. Resolution 320x200;
|
||||
40 columns text; Palette of 16 colors in 8 shades, for 128 colors)
|
||||
Sound: MOS Technology 7360 "TED" (2 voice tone-generating sound capabilities)
|
||||
Ports: MOS 7360 (2 Joystick/Mouse ports; CBM Serial port; 'TED' port; "TV"
|
||||
Port and switch; CBM Monitor port; Power and reset switches; Power
|
||||
connector)
|
||||
Keyboard: QWERTY 66 key typewriter style (8 programmable function keys;
|
||||
4 direction cursor-pad)
|
||||
|
||||
|
||||
* Commodore Plus/4 (1984)
|
||||
|
||||
This system became the middle tier of the Commodore 264 family, replacing
|
||||
the original Commodore 264. The Plus/4 is basically the same as the C264,
|
||||
but the name refers to the four built-in programs which came with the
|
||||
machine: Word Processing, Spreadsheet, Database software, Graphing package.
|
||||
|
||||
CPU: MOS Technology 7501 (variable clock rate, with max 1.76 MHz)
|
||||
RAM: 64 kilobytes (expandable to 64k internally)
|
||||
ROM: 64 kilobytes
|
||||
Video: MOS Technology 7360 "TED" (5 Video modes; Max. Resolution 320x200;
|
||||
40 columns text; Palette of 16 colors in 8 shades, for 128 colors)
|
||||
Sound: MOS Technology 7360 "TED" (2 voice tone-generating sound capabilities)
|
||||
Ports: MOS 7360 (2 Joystick/Mouse ports; CBM Serial port; 'TED' port; "TV"
|
||||
Port and switch; CBM Monitor port; Power and reset switches; Power
|
||||
connector)
|
||||
Keyboard: Full-sized QWERTY 67 key (8 programmable function keys;
|
||||
4 direction cursor-pad)
|
||||
|
||||
|
||||
* Commodore 232 (1984, Prototype)
|
||||
|
||||
This system never reached the production and only few units exist. It is
|
||||
in between the C16 and the C264, with its 32 kilobytes of RAM.
|
||||
|
||||
|
||||
* Commodore 264 (1984, Prototype)
|
||||
|
||||
Basically the same of a Plus/4 but without the built-in programs.
|
||||
|
||||
|
||||
* Commodore V364 (1984, Prototype)
|
||||
|
||||
This system was supposed to become the high-end system of the family,
|
||||
featuring 64 kilobytes of RAM, the same technology of the Plus/4, a
|
||||
keyboard with numeric keypad and built in voice synthesis capabilities.
|
||||
|
||||
[TO DO]
|
||||
|
||||
* Supported Systems:
|
||||
|
||||
- Once we can add / remove devices, we shall only support c16, c116 and plus/4,
|
||||
removing the separated drivers for different floppy drives
|
||||
|
||||
* Other Peripherals:
|
||||
|
||||
- Lightpen support is unfinished
|
||||
- Missing support for (it might or might not be added eventually):
|
||||
printers and other devices; most expansion modules; userport; rs232/v.24 interface.
|
||||
|
||||
* System Specific
|
||||
|
||||
- V364 lacks speech hardware emulation
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#include "emu.h"
|
||||
#include "audio/ted7360.h"
|
||||
#include "audio/t6721.h"
|
||||
#include "cpu/m6502/m6502.h"
|
||||
#include "machine/ram.h"
|
||||
#include "formats/cbm_snqk.h"
|
||||
#include "includes/cbm.h"
|
||||
#include "includes/c16.h"
|
||||
#include "machine/c1551.h"
|
||||
#include "machine/cbmiec.h"
|
||||
#include "machine/cbmipt.h"
|
||||
#include "sound/sid6581.h"
|
||||
#include "machine/plus4exp.h"
|
||||
#include "machine/plus4user.h"
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Main CPU memory handlers
|
||||
*
|
||||
*************************************/
|
||||
|
||||
|
||||
/*
|
||||
* commodore c16/c116/plus 4
|
||||
* 16 KByte (C16/C116) or 32 KByte or 64 KByte (plus4) RAM
|
||||
* 32 KByte Rom (C16/C116) 64 KByte Rom (plus4)
|
||||
* availability to append additional 64 KByte Rom
|
||||
*
|
||||
* ports 0xfd00 till 0xff3f are always read/writeable for the cpu
|
||||
* for the video interface chip it seams to read from
|
||||
* ram or from rom in this area
|
||||
*
|
||||
* writes go always to ram
|
||||
* only 16 KByte Ram mapped to 0x4000,0x8000,0xc000
|
||||
* only 32 KByte Ram mapped to 0x8000
|
||||
*
|
||||
* rom bank at 0x8000: 16K Byte(low bank)
|
||||
* first: basic
|
||||
* second(plus 4 only): plus4 rom low
|
||||
* third: expansion slot
|
||||
* fourth: expansion slot
|
||||
* rom bank at 0xc000: 16K Byte(high bank)
|
||||
* first: kernal
|
||||
* second(plus 4 only): plus4 rom high
|
||||
* third: expansion slot
|
||||
* fourth: expansion slot
|
||||
* writes to 0xfddx select rom banks:
|
||||
* address line 0 and 1: rom bank low
|
||||
* address line 2 and 3: rom bank high
|
||||
*
|
||||
* writes to 0xff3e switches to roms (0x8000 till 0xfd00, 0xff40 till 0xffff)
|
||||
* writes to 0xff3f switches to rams
|
||||
*
|
||||
* at 0xfc00 till 0xfcff is ram or rom kernal readable
|
||||
*/
|
||||
|
||||
static ADDRESS_MAP_START(c16_map, AS_PROGRAM, 8, c16_state )
|
||||
AM_RANGE(0x0000, 0x3fff) AM_RAMBANK("bank9")
|
||||
AM_RANGE(0x4000, 0x7fff) AM_READ_BANK("bank1") AM_WRITE_BANK("bank5") /* only ram memory configuration */
|
||||
AM_RANGE(0x8000, 0xbfff) AM_READ_BANK("bank2") AM_WRITE_BANK("bank6")
|
||||
AM_RANGE(0xc000, 0xfbff) AM_READ_BANK("bank3")
|
||||
AM_RANGE(0xfc00, 0xfcff) AM_READ_BANK("bank4")
|
||||
AM_RANGE(0xc000, 0xfcff) AM_WRITE_BANK("bank7")
|
||||
AM_RANGE(0xfd10, 0xfd1f) AM_READ_LEGACY(c16_fd1x_r)
|
||||
AM_RANGE(0xfd30, 0xfd3f) AM_READWRITE_LEGACY(c16_6529_port_r, c16_6529_port_w) /* 6529 keyboard matrix */
|
||||
AM_RANGE(0xfdd0, 0xfddf) AM_WRITE_LEGACY(c16_select_roms) /* rom chips selection */
|
||||
AM_RANGE(0xff00, 0xff1f) AM_DEVREADWRITE_LEGACY("ted7360", ted7360_port_r, ted7360_port_w)
|
||||
AM_RANGE(0xff20, 0xffff) AM_READ_BANK("bank8")
|
||||
AM_RANGE(0xff3e, 0xff3e) AM_WRITE_LEGACY(c16_switch_to_rom)
|
||||
AM_RANGE(0xff3f, 0xff3f) AM_WRITE_LEGACY(c16_switch_to_ram)
|
||||
ADDRESS_MAP_END
|
||||
|
||||
static ADDRESS_MAP_START(plus4_map, AS_PROGRAM, 8, c16_state )
|
||||
AM_RANGE(0x0000, 0x7fff) AM_READ_BANK("bank9")
|
||||
AM_RANGE(0x8000, 0xbfff) AM_READ_BANK("bank2")
|
||||
AM_RANGE(0xc000, 0xfbff) AM_READ_BANK("bank3")
|
||||
AM_RANGE(0xfc00, 0xfcff) AM_READ_BANK("bank4")
|
||||
AM_RANGE(0x0000, 0xfcff) AM_WRITE_BANK("bank9")
|
||||
AM_RANGE(0xfd00, 0xfd0f) AM_READWRITE_LEGACY(c16_6551_port_r, c16_6551_port_w)
|
||||
AM_RANGE(0xfd10, 0xfd1f) AM_READWRITE_LEGACY(plus4_6529_port_r, plus4_6529_port_w)
|
||||
AM_RANGE(0xfd30, 0xfd3f) AM_READWRITE_LEGACY(c16_6529_port_r, c16_6529_port_w) /* 6529 keyboard matrix */
|
||||
AM_RANGE(0xfdd0, 0xfddf) AM_WRITE_LEGACY(c16_select_roms) /* rom chips selection */
|
||||
AM_RANGE(0xff00, 0xff1f) AM_DEVREADWRITE_LEGACY("ted7360", ted7360_port_r, ted7360_port_w)
|
||||
AM_RANGE(0xff20, 0xffff) AM_READ_BANK("bank8")
|
||||
AM_RANGE(0xff20, 0xff3d) AM_WRITEONLY
|
||||
AM_RANGE(0xff3e, 0xff3e) AM_WRITE_LEGACY(c16_switch_to_rom)
|
||||
AM_RANGE(0xff3f, 0xff3f) AM_WRITE_LEGACY(c16_switch_to_ram)
|
||||
AM_RANGE(0xff40, 0xffff) AM_WRITEONLY
|
||||
ADDRESS_MAP_END
|
||||
|
||||
static ADDRESS_MAP_START(c364_map , AS_PROGRAM, 8, c16_state )
|
||||
AM_RANGE(0x0000, 0x7fff) AM_READ_BANK("bank9")
|
||||
AM_RANGE(0x8000, 0xbfff) AM_READ_BANK("bank2")
|
||||
AM_RANGE(0xc000, 0xfbff) AM_READ_BANK("bank3")
|
||||
AM_RANGE(0xfc00, 0xfcff) AM_READ_BANK("bank4")
|
||||
AM_RANGE(0x0000, 0xfcff) AM_WRITE_BANK("bank9")
|
||||
AM_RANGE(0xfd00, 0xfd0f) AM_READWRITE_LEGACY(c16_6551_port_r, c16_6551_port_w)
|
||||
AM_RANGE(0xfd10, 0xfd1f) AM_READWRITE_LEGACY(plus4_6529_port_r, plus4_6529_port_w)
|
||||
AM_RANGE(0xfd20, 0xfd2f) AM_DEVREADWRITE_LEGACY("t6721", t6721_speech_r, t6721_speech_w)
|
||||
AM_RANGE(0xfd30, 0xfd3f) AM_READWRITE_LEGACY(c16_6529_port_r, c16_6529_port_w) /* 6529 keyboard matrix */
|
||||
AM_RANGE(0xfdd0, 0xfddf) AM_WRITE_LEGACY(c16_select_roms) /* rom chips selection */
|
||||
AM_RANGE(0xff00, 0xff1f) AM_DEVREADWRITE_LEGACY("ted7360", ted7360_port_r, ted7360_port_w)
|
||||
AM_RANGE(0xff20, 0xffff) AM_READ_BANK("bank8")
|
||||
AM_RANGE(0xff20, 0xff3d) AM_WRITEONLY
|
||||
AM_RANGE(0xff3e, 0xff3e) AM_WRITE_LEGACY(c16_switch_to_rom)
|
||||
AM_RANGE(0xff3f, 0xff3f) AM_WRITE_LEGACY(c16_switch_to_ram)
|
||||
AM_RANGE(0xff40, 0xffff) AM_WRITEONLY
|
||||
ADDRESS_MAP_END
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Input Ports
|
||||
*
|
||||
*************************************/
|
||||
|
||||
static INPUT_PORTS_START( c16 )
|
||||
PORT_INCLUDE( common_cbm_keyboard ) /* ROW0 -> ROW7 */
|
||||
|
||||
PORT_MODIFY("ROW0")
|
||||
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("@") PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('@')
|
||||
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F3) PORT_CHAR(UCHAR_MAMEKEY(F3)) PORT_CHAR(UCHAR_MAMEKEY(F6))
|
||||
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F2) PORT_CHAR(UCHAR_MAMEKEY(F2)) PORT_CHAR(UCHAR_MAMEKEY(F5))
|
||||
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F1) PORT_CHAR(UCHAR_MAMEKEY(F1)) PORT_CHAR(UCHAR_MAMEKEY(F4))
|
||||
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("HELP f7") PORT_CODE(KEYCODE_F4) PORT_CHAR(UCHAR_MAMEKEY(F8)) PORT_CHAR(UCHAR_MAMEKEY(F7))
|
||||
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_INSERT) PORT_CHAR(0xA3)
|
||||
|
||||
PORT_MODIFY("ROW1")
|
||||
/* Both Shift keys were mapped to the same bit */
|
||||
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Shift (Left & Right)") PORT_CODE(KEYCODE_LSHIFT) PORT_CODE(KEYCODE_RSHIFT)
|
||||
|
||||
PORT_MODIFY("ROW4")
|
||||
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("0 \xE2\x86\x91") PORT_CODE(KEYCODE_0) PORT_CHAR('0') PORT_CHAR(0x2191)
|
||||
|
||||
PORT_MODIFY("ROW5")
|
||||
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("-") PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-')
|
||||
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_BACKSLASH2) PORT_CHAR(UCHAR_MAMEKEY(UP))
|
||||
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_PGUP) PORT_CHAR(UCHAR_MAMEKEY(DOWN))
|
||||
|
||||
PORT_MODIFY("ROW6")
|
||||
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR('+')
|
||||
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("= Pi \xE2\x86\x90") PORT_CODE(KEYCODE_PGDN) PORT_CHAR('=') PORT_CHAR(0x03C0) PORT_CHAR(0x2190)
|
||||
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_ESC) PORT_CHAR(UCHAR_MAMEKEY(ESC))
|
||||
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_EQUALS) PORT_CHAR(UCHAR_MAMEKEY(RIGHT))
|
||||
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR('*')
|
||||
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_MINUS) PORT_CHAR(UCHAR_MAMEKEY(LEFT))
|
||||
|
||||
PORT_MODIFY("ROW7")
|
||||
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Home Clear") PORT_CODE(KEYCODE_DEL) PORT_CHAR(UCHAR_MAMEKEY(HOME))
|
||||
|
||||
PORT_INCLUDE( c16_special ) /* SPECIAL */
|
||||
|
||||
PORT_INCLUDE( c16_controls ) /* CTRLSEL, JOY0, JOY1 */
|
||||
INPUT_PORTS_END
|
||||
|
||||
|
||||
static INPUT_PORTS_START( plus4 )
|
||||
PORT_INCLUDE( c16 )
|
||||
|
||||
PORT_MODIFY( "ROW0" )
|
||||
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR(0xA3)
|
||||
PORT_MODIFY( "ROW5" )
|
||||
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('-')
|
||||
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_UP) PORT_CHAR(UCHAR_MAMEKEY(UP))
|
||||
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_DOWN) PORT_CHAR(UCHAR_MAMEKEY(DOWN))
|
||||
PORT_MODIFY( "ROW6" )
|
||||
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('+')
|
||||
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("= Pi \xE2\x86\x90") PORT_CODE(KEYCODE_BACKSLASH2) PORT_CHAR('=') PORT_CHAR(0x03C0) PORT_CHAR(0x2190)
|
||||
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_RIGHT) PORT_CHAR(UCHAR_MAMEKEY(RIGHT))
|
||||
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_INSERT) PORT_CHAR('*')
|
||||
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_LEFT) PORT_CHAR(UCHAR_MAMEKEY(LEFT))
|
||||
INPUT_PORTS_END
|
||||
|
||||
static INPUT_PORTS_START( c16sid )
|
||||
PORT_INCLUDE( c16 )
|
||||
|
||||
PORT_START("SID")
|
||||
PORT_CONFNAME( 0x01, 0x00, "SID Card Address")
|
||||
PORT_CONFSETTING( 0x00, "0xfd40" )
|
||||
PORT_CONFSETTING( 0x01, "0xfe80" )
|
||||
#if 0
|
||||
PORT_CONFNAME( 0x02, 0x00, "Enable SID writes to 0xd400")
|
||||
PORT_CONFSETTING( 0x00, DEF_STR( No ) )
|
||||
PORT_CONFSETTING( 0x02, DEF_STR( Yes ) )
|
||||
#endif
|
||||
INPUT_PORTS_END
|
||||
|
||||
|
||||
static INPUT_PORTS_START( plus4sid )
|
||||
PORT_INCLUDE( plus4 )
|
||||
|
||||
PORT_START("SID")
|
||||
PORT_CONFNAME( 0x01, 0x00, "SID Card Address")
|
||||
PORT_CONFSETTING( 0x00, "0xfd40" )
|
||||
PORT_CONFSETTING( 0x01, "0xfe80" )
|
||||
#if 0
|
||||
PORT_CONFNAME( 0x02, 0x00, "Enable SID writes to 0xd400")
|
||||
PORT_CONFSETTING( 0x00, DEF_STR( No ) )
|
||||
PORT_CONFSETTING( 0x02, DEF_STR( Yes ) )
|
||||
#endif
|
||||
INPUT_PORTS_END
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Graphics definitions
|
||||
*
|
||||
*************************************/
|
||||
|
||||
static const unsigned char ted7360_palette[] =
|
||||
{
|
||||
/* black, white, red, cyan */
|
||||
/* purple, green, blue, yellow */
|
||||
/* orange, light orange, pink, light cyan, */
|
||||
/* light violett, light green, light blue, light yellow */
|
||||
/* these 16 colors are 8 times here in different luminance (dark..light) */
|
||||
/* taken from digitized tv screenshot */
|
||||
0x06, 0x01, 0x03, 0x2b, 0x2b, 0x2b, 0x67, 0x0e, 0x0f, 0x00, 0x3f, 0x42,
|
||||
0x57, 0x00, 0x6d, 0x00, 0x4e, 0x00, 0x19, 0x1c, 0x94, 0x38, 0x38, 0x00,
|
||||
0x56, 0x20, 0x00, 0x4b, 0x28, 0x00, 0x16, 0x48, 0x00, 0x69, 0x07, 0x2f,
|
||||
0x00, 0x46, 0x26, 0x06, 0x2a, 0x80, 0x2a, 0x14, 0x9b, 0x0b, 0x49, 0x00,
|
||||
|
||||
0x00, 0x03, 0x02, 0x3d, 0x3d, 0x3d, 0x75, 0x1e, 0x20, 0x00, 0x50, 0x4f,
|
||||
0x6a, 0x10, 0x78, 0x04, 0x5c, 0x00, 0x2a, 0x2a, 0xa3, 0x4c, 0x47, 0x00,
|
||||
0x69, 0x2f, 0x00, 0x59, 0x38, 0x00, 0x26, 0x56, 0x00, 0x75, 0x15, 0x41,
|
||||
0x00, 0x58, 0x3d, 0x15, 0x3d, 0x8f, 0x39, 0x22, 0xae, 0x19, 0x59, 0x00,
|
||||
|
||||
0x00, 0x03, 0x04, 0x42, 0x42, 0x42, 0x7b, 0x28, 0x20, 0x02, 0x56, 0x59,
|
||||
0x6f, 0x1a, 0x82, 0x0a, 0x65, 0x09, 0x30, 0x34, 0xa7, 0x50, 0x51, 0x00,
|
||||
0x6e, 0x36, 0x00, 0x65, 0x40, 0x00, 0x2c, 0x5c, 0x00, 0x7d, 0x1e, 0x45,
|
||||
0x01, 0x61, 0x45, 0x1c, 0x45, 0x99, 0x42, 0x2d, 0xad, 0x1d, 0x62, 0x00,
|
||||
|
||||
0x05, 0x00, 0x02, 0x56, 0x55, 0x5a, 0x90, 0x3c, 0x3b, 0x17, 0x6d, 0x72,
|
||||
0x87, 0x2d, 0x99, 0x1f, 0x7b, 0x15, 0x46, 0x49, 0xc1, 0x66, 0x63, 0x00,
|
||||
0x84, 0x4c, 0x0d, 0x73, 0x55, 0x00, 0x40, 0x72, 0x00, 0x91, 0x33, 0x5e,
|
||||
0x19, 0x74, 0x5c, 0x32, 0x59, 0xae, 0x59, 0x3f, 0xc3, 0x32, 0x76, 0x00,
|
||||
|
||||
0x02, 0x01, 0x06, 0x84, 0x7e, 0x85, 0xbb, 0x67, 0x68, 0x45, 0x96, 0x96,
|
||||
0xaf, 0x58, 0xc3, 0x4a, 0xa7, 0x3e, 0x73, 0x73, 0xec, 0x92, 0x8d, 0x11,
|
||||
0xaf, 0x78, 0x32, 0xa1, 0x80, 0x20, 0x6c, 0x9e, 0x12, 0xba, 0x5f, 0x89,
|
||||
0x46, 0x9f, 0x83, 0x61, 0x85, 0xdd, 0x84, 0x6c, 0xef, 0x5d, 0xa3, 0x29,
|
||||
|
||||
0x02, 0x00, 0x0a, 0xb2, 0xac, 0xb3, 0xe9, 0x92, 0x92, 0x6c, 0xc3, 0xc1,
|
||||
0xd9, 0x86, 0xf0, 0x79, 0xd1, 0x76, 0x9d, 0xa1, 0xff, 0xbd, 0xbe, 0x40,
|
||||
0xdc, 0xa2, 0x61, 0xd1, 0xa9, 0x4c, 0x93, 0xc8, 0x3d, 0xe9, 0x8a, 0xb1,
|
||||
0x6f, 0xcd, 0xab, 0x8a, 0xb4, 0xff, 0xb2, 0x9a, 0xff, 0x88, 0xcb, 0x59,
|
||||
|
||||
0x02, 0x00, 0x0a, 0xc7, 0xca, 0xc9, 0xff, 0xac, 0xac, 0x85, 0xd8, 0xe0,
|
||||
0xf3, 0x9c, 0xff, 0x92, 0xea, 0x8a, 0xb7, 0xba, 0xff, 0xd6, 0xd3, 0x5b,
|
||||
0xf3, 0xbe, 0x79, 0xe6, 0xc5, 0x65, 0xb0, 0xe0, 0x57, 0xff, 0xa4, 0xcf,
|
||||
0x89, 0xe5, 0xc8, 0xa4, 0xca, 0xff, 0xca, 0xb3, 0xff, 0xa2, 0xe5, 0x7a,
|
||||
|
||||
0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0xf6, 0xf2, 0xd1, 0xff, 0xff,
|
||||
0xff, 0xe9, 0xff, 0xdb, 0xff, 0xd3, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xa3,
|
||||
0xff, 0xff, 0xc1, 0xff, 0xff, 0xb2, 0xfc, 0xff, 0xa2, 0xff, 0xee, 0xff,
|
||||
0xd1, 0xff, 0xff, 0xeb, 0xff, 0xff, 0xff, 0xf8, 0xff, 0xed, 0xff, 0xbc
|
||||
};
|
||||
|
||||
static PALETTE_INIT( c16 )
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < sizeof(ted7360_palette) / 3; i++)
|
||||
palette_set_color_rgb(machine, i, ted7360_palette[i * 3], ted7360_palette[i * 3 + 1], ted7360_palette[i * 3 + 2]);
|
||||
}
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* TED7360 interfaces
|
||||
*
|
||||
*************************************/
|
||||
|
||||
static const ted7360_interface c16_ted7360_intf = {
|
||||
"screen",
|
||||
TED7360_PAL,
|
||||
c16_dma_read,
|
||||
c16_dma_read_rom,
|
||||
c16_interrupt,
|
||||
c16_read_keyboard
|
||||
};
|
||||
|
||||
static const ted7360_interface plus4_ted7360_intf = {
|
||||
"screen",
|
||||
TED7360_NTSC,
|
||||
c16_dma_read,
|
||||
c16_dma_read_rom,
|
||||
c16_interrupt,
|
||||
c16_read_keyboard
|
||||
};
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Machine driver
|
||||
*
|
||||
*************************************/
|
||||
|
||||
static const m6502_interface c16_m7501_interface =
|
||||
{
|
||||
NULL, /* read_indexed_func */
|
||||
NULL, /* write_indexed_func */
|
||||
DEVCB_HANDLER(c16_m7501_port_read), /* port_read_func */
|
||||
DEVCB_HANDLER(c16_m7501_port_write) /* port_write_func */
|
||||
};
|
||||
|
||||
static CBM_IEC_INTERFACE( cbm_iec_intf )
|
||||
{
|
||||
DEVCB_NULL,
|
||||
DEVCB_NULL,
|
||||
DEVCB_NULL,
|
||||
DEVCB_NULL,
|
||||
DEVCB_NULL
|
||||
};
|
||||
|
||||
static PLUS4_EXPANSION_INTERFACE( expansion_intf )
|
||||
{
|
||||
DEVCB_NULL,
|
||||
DEVCB_NULL,
|
||||
DEVCB_NULL,
|
||||
DEVCB_NULL,
|
||||
DEVCB_NULL
|
||||
};
|
||||
|
||||
static PLUS4_USER_PORT_INTERFACE( user_intf )
|
||||
{
|
||||
DEVCB_NULL
|
||||
};
|
||||
|
||||
static SCREEN_UPDATE_IND16( c16 )
|
||||
{
|
||||
c16_state *state = screen.machine().driver_data<c16_state>();
|
||||
ted7360_video_update(state->m_ted7360, bitmap, cliprect);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static INTERRUPT_GEN( c16_raster_interrupt )
|
||||
{
|
||||
c16_state *state = device->machine().driver_data<c16_state>();
|
||||
ted7360_raster_interrupt_gen(state->m_ted7360);
|
||||
}
|
||||
|
||||
|
||||
static MACHINE_START( c16 )
|
||||
{
|
||||
c16_state *state = machine.driver_data<c16_state>();
|
||||
|
||||
state->m_maincpu = machine.device<legacy_cpu_device>("maincpu");
|
||||
state->m_ted7360 = machine.device("ted7360");
|
||||
state->m_cassette = machine.device<cassette_image_device>(CASSETTE_TAG);
|
||||
state->m_messram = machine.device<ram_device>(RAM_TAG);
|
||||
state->m_sid = machine.device("sid");
|
||||
|
||||
state->save_item(NAME(state->m_old_level));
|
||||
state->save_item(NAME(state->m_lowrom));
|
||||
state->save_item(NAME(state->m_highrom));
|
||||
state->save_item(NAME(state->m_port6529));
|
||||
state->save_item(NAME(state->m_keyline));
|
||||
}
|
||||
|
||||
static MACHINE_CONFIG_START( c16, c16_state )
|
||||
/* basic machine hardware */
|
||||
MCFG_CPU_ADD("maincpu", M7501, XTAL_17_73447MHz/20)
|
||||
MCFG_CPU_PROGRAM_MAP(c16_map)
|
||||
MCFG_CPU_CONFIG( c16_m7501_interface )
|
||||
MCFG_CPU_VBLANK_INT("screen", c16_frame_interrupt)
|
||||
MCFG_CPU_PERIODIC_INT(c16_raster_interrupt, TED7360_HRETRACERATE)
|
||||
MCFG_QUANTUM_TIME(attotime::from_hz(60))
|
||||
|
||||
MCFG_MACHINE_START( c16 )
|
||||
MCFG_MACHINE_RESET( c16 )
|
||||
|
||||
/* video hardware */
|
||||
MCFG_SCREEN_ADD("screen", RASTER)
|
||||
MCFG_SCREEN_REFRESH_RATE(TED7360PAL_VRETRACERATE)
|
||||
MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */
|
||||
MCFG_SCREEN_SIZE(336, 216)
|
||||
MCFG_SCREEN_VISIBLE_AREA(0, 336 - 1, 0, 216 - 1)
|
||||
MCFG_SCREEN_UPDATE_STATIC( c16 )
|
||||
|
||||
MCFG_PALETTE_LENGTH(ARRAY_LENGTH(ted7360_palette) / 3)
|
||||
MCFG_PALETTE_INIT(c16)
|
||||
|
||||
/* sound hardware */
|
||||
MCFG_SPEAKER_STANDARD_MONO("mono")
|
||||
MCFG_TED7360_ADD("ted7360", c16_ted7360_intf)
|
||||
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25)
|
||||
|
||||
/* devices */
|
||||
MCFG_QUICKLOAD_ADD("quickload", cbm_c16, "p00,prg", CBM_QUICKLOAD_DELAY_SECONDS)
|
||||
|
||||
/* cassette */
|
||||
MCFG_CASSETTE_ADD( CASSETTE_TAG, cbm_cassette_interface )
|
||||
|
||||
MCFG_FRAGMENT_ADD(c16_cartslot)
|
||||
|
||||
MCFG_C1551_ADD(C1551_TAG, 8)
|
||||
MCFG_SOFTWARE_LIST_ADD("disk_list", "plus4_flop")
|
||||
|
||||
/* IEC serial bus */
|
||||
MCFG_CBM_IEC_ADD(cbm_iec_intf, NULL)
|
||||
|
||||
MCFG_PLUS4_EXPANSION_SLOT_ADD(PLUS4_EXPANSION_SLOT_TAG, XTAL_17_73447MHz/20, expansion_intf, plus4_expansion_cards, NULL, NULL)
|
||||
MCFG_PLUS4_USER_PORT_ADD(PLUS4_USER_PORT_TAG, user_intf, plus4_user_port_cards, NULL, NULL)
|
||||
|
||||
/* internal ram */
|
||||
MCFG_RAM_ADD(RAM_TAG)
|
||||
MCFG_RAM_DEFAULT_SIZE("64K")
|
||||
MCFG_RAM_EXTRA_OPTIONS("16K,32K")
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
static MACHINE_CONFIG_DERIVED( plus4, c16 )
|
||||
MCFG_CPU_MODIFY( "maincpu" )
|
||||
MCFG_CPU_CLOCK( XTAL_14_31818MHz/16 )
|
||||
MCFG_CPU_PROGRAM_MAP(plus4_map)
|
||||
MCFG_CPU_CONFIG( c16_m7501_interface )
|
||||
|
||||
MCFG_SCREEN_MODIFY("screen")
|
||||
MCFG_SCREEN_REFRESH_RATE(TED7360NTSC_VRETRACERATE)
|
||||
|
||||
MCFG_DEVICE_REMOVE("ted7360")
|
||||
MCFG_TED7360_ADD("ted7360", plus4_ted7360_intf)
|
||||
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25)
|
||||
|
||||
/* internal ram */
|
||||
MCFG_RAM_MODIFY(RAM_TAG)
|
||||
MCFG_RAM_DEFAULT_SIZE("64K")
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
static MACHINE_CONFIG_DERIVED( c364, plus4 )
|
||||
MCFG_SCREEN_MODIFY("screen")
|
||||
MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */
|
||||
MCFG_CPU_MODIFY( "maincpu" )
|
||||
MCFG_CPU_PROGRAM_MAP(c364_map)
|
||||
|
||||
MCFG_T6721_ADD("t6721")
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
static MACHINE_CONFIG_DERIVED( c264, c16 )
|
||||
/* internal ram */
|
||||
MCFG_RAM_MODIFY(RAM_TAG)
|
||||
MCFG_RAM_DEFAULT_SIZE("64K")
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
static MACHINE_CONFIG_DERIVED( c16sid, c16 )
|
||||
|
||||
MCFG_SOUND_ADD("sid", SID8580, TED7360PAL_CLOCK/4)
|
||||
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25)
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
static MACHINE_CONFIG_DERIVED( plus4sid, plus4 )
|
||||
|
||||
MCFG_SOUND_ADD("sid", SID8580, TED7360NTSC_CLOCK/4)
|
||||
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25)
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* ROM definition(s)
|
||||
*
|
||||
*************************************/
|
||||
ROM_START( c232 )
|
||||
ROM_REGION( 0x40000, "maincpu", 0 )
|
||||
ROM_LOAD( "318006-01.bin", 0x10000, 0x4000, CRC(74eaae87) SHA1(161c96b4ad20f3a4f2321808e37a5ded26a135dd) )
|
||||
ROM_LOAD( "318004-01.bin", 0x14000, 0x4000, CRC(dbdc3319) SHA1(3c77caf72914c1c0a0875b3a7f6935cd30c54201) )
|
||||
ROM_END
|
||||
|
||||
ROM_START( c264 )
|
||||
ROM_REGION( 0x40000, "maincpu", 0 )
|
||||
ROM_LOAD( "basic-264.bin", 0x10000, 0x4000, CRC(6a2fc8e3) SHA1(473fce23afa07000cdca899fbcffd6961b36a8a0) )
|
||||
ROM_LOAD( "kernal-264.bin", 0x14000, 0x4000, CRC(8f32abe7) SHA1(d481faf5fcbb331878dc7851c642d04f26a32873) )
|
||||
ROM_END
|
||||
|
||||
ROM_START( c364 )
|
||||
ROM_REGION( 0x40000, "maincpu", 0 )
|
||||
ROM_LOAD( "318006.01", 0x10000, 0x4000, CRC(74eaae87) SHA1(161c96b4ad20f3a4f2321808e37a5ded26a135dd) )
|
||||
ROM_LOAD( "kern364p.bin", 0x14000, 0x4000, CRC(84fd4f7a) SHA1(b9a5b5dacd57ca117ef0b3af29e91998bf4d7e5f) )
|
||||
ROM_LOAD( "317053-01.bin", 0x18000, 0x4000, CRC(4fd1d8cb) SHA1(3b69f6e7cb4c18bb08e203fb18b7dabfa853390f) )
|
||||
ROM_LOAD( "317054-01.bin", 0x1c000, 0x4000, CRC(109de2fc) SHA1(0ad7ac2db7da692d972e586ca0dfd747d82c7693) )
|
||||
/* at address 0x20000 not so good */
|
||||
ROM_LOAD( "spk3cc4.bin", 0x28000, 0x4000, CRC(5227c2ee) SHA1(59af401cbb2194f689898271c6e8aafa28a7af11) )
|
||||
ROM_END
|
||||
|
||||
|
||||
ROM_START( c16 )
|
||||
ROM_REGION( 0x40000, "maincpu", 0 )
|
||||
ROM_DEFAULT_BIOS("r5")
|
||||
ROM_LOAD( "318006-01.u3", 0x10000, 0x4000, CRC(74eaae87) SHA1(161c96b4ad20f3a4f2321808e37a5ded26a135dd) )
|
||||
|
||||
ROM_SYSTEM_BIOS( 0, "r3", "rev. 3" )
|
||||
ROMX_LOAD( "318004-03.u4", 0x14000, 0x4000, CRC(77bab934) SHA1(97814dab9d757fe5a3a61d357a9a81da588a9783), ROM_BIOS(1) )
|
||||
ROM_SYSTEM_BIOS( 1, "r4", "rev. 4" )
|
||||
ROMX_LOAD( "318004-04.u4", 0x14000, 0x4000, CRC(be54ed79) SHA1(514ad3c29d01a2c0a3b143d9c1d4143b1912b793), ROM_BIOS(2) )
|
||||
ROM_SYSTEM_BIOS( 2, "r5", "rev. 5" )
|
||||
ROMX_LOAD( "318004-05.u4", 0x14000, 0x4000, CRC(71c07bd4) SHA1(7c7e07f016391174a557e790c4ef1cbe33512cdb), ROM_BIOS(3) )
|
||||
ROM_END
|
||||
|
||||
#define rom_c16c rom_c16
|
||||
#define rom_c16v rom_c16
|
||||
|
||||
#define rom_c116 rom_c16
|
||||
#define rom_c116c rom_c16c
|
||||
#define rom_c116v rom_c16v
|
||||
|
||||
ROM_START( c16hun )
|
||||
ROM_REGION( 0x40000, "maincpu", 0 )
|
||||
ROM_LOAD( "318006-01.u3", 0x10000, 0x4000, CRC(74eaae87) SHA1(161c96b4ad20f3a4f2321808e37a5ded26a135dd) )
|
||||
ROM_LOAD( "hungary.u4", 0x14000, 0x4000, CRC(775f60c5) SHA1(20cf3c4bf6c54ef09799af41887218933f2e27ee) )
|
||||
ROM_END
|
||||
|
||||
ROM_START( plus4 )
|
||||
ROM_REGION( 0x40000, "maincpu", 0 )
|
||||
ROM_DEFAULT_BIOS("r5")
|
||||
ROM_SYSTEM_BIOS( 0, "r4", "rev. 4" )
|
||||
ROMX_LOAD( "318005-04.u24", 0x14000, 0x4000, CRC(799a633d) SHA1(5df52c693387c0e2b5d682613a3b5a65477311cf), ROM_BIOS(1) )
|
||||
ROM_SYSTEM_BIOS( 1, "r5", "rev. 5" )
|
||||
ROMX_LOAD( "318005-05.u24", 0x14000, 0x4000, CRC(70295038) SHA1(a3d9e5be091b98de39a046ab167fb7632d053682), ROM_BIOS(2) )
|
||||
ROM_SYSTEM_BIOS( 2, "jiffydos", "JiffyDOS v6.01" )
|
||||
ROMX_LOAD( "jiffydos plus4.u24", 0x10000, 0x8000, CRC(818d3f45) SHA1(9bc1b1c3da9ca642deae717905f990d8e36e6c3b), ROM_BIOS(3) )
|
||||
|
||||
ROM_LOAD( "318006-01.u23", 0x10000, 0x4000, CRC(74eaae87) SHA1(161c96b4ad20f3a4f2321808e37a5ded26a135dd) )
|
||||
|
||||
ROM_LOAD( "317053-01.u25", 0x18000, 0x4000, CRC(4fd1d8cb) SHA1(3b69f6e7cb4c18bb08e203fb18b7dabfa853390f) )
|
||||
ROM_LOAD( "317054-01.26", 0x1c000, 0x4000, CRC(109de2fc) SHA1(0ad7ac2db7da692d972e586ca0dfd747d82c7693) )
|
||||
ROM_END
|
||||
|
||||
#define rom_plus4c rom_plus4
|
||||
#define rom_plus4v rom_plus4
|
||||
|
||||
#define rom_c16sid rom_c16
|
||||
#define rom_plus4sid rom_plus4
|
||||
|
||||
/***************************************************************************
|
||||
|
||||
Game driver(s)
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
/* YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME FLAGS */
|
||||
|
||||
COMP( 1984, c16, 0, 0, c16, c16, c16_state, c16, "Commodore Business Machines", "Commodore 16 (PAL)", 0)
|
||||
COMP( 1984, c16hun, c16, 0, c16, c16, c16_state, c16, "Commodore Business Machines", "Commodore 16 Novotrade (PAL, Hungary)", 0)
|
||||
|
||||
COMP( 1984, c116, c16, 0, c16, c16, c16_state, c16, "Commodore Business Machines", "Commodore 116 (PAL)", 0)
|
||||
|
||||
COMP( 1984, plus4, c16, 0, plus4, plus4, c16_state, plus4, "Commodore Business Machines", "Commodore Plus/4 (NTSC)", 0)
|
||||
|
||||
COMP( 1984, c232, c16, 0, c16, c16, c16_state, c16, "Commodore Business Machines", "Commodore 232 (Prototype)", 0)
|
||||
COMP( 1984, c264, c16, 0, c264, plus4, c16_state, plus4, "Commodore Business Machines", "Commodore 264 (Prototype)", 0)
|
||||
COMP( 1984, c364, c16, 0, c364, plus4, c16_state, plus4, "Commodore Business Machines", "Commodore V364 (Prototype)", GAME_IMPERFECT_SOUND)
|
||||
|
||||
COMP( 1984, c16sid, c16, 0, c16sid, c16sid, c16_state, c16sid, "Commodore Business Machines", "Commodore 16 (PAL, SID Card)", GAME_UNOFFICIAL | GAME_IMPERFECT_SOUND)
|
||||
COMP( 1984, plus4sid, c16, 0, plus4sid, plus4sid, c16_state, plus4sid, "Commodore Business Machines", "Commodore Plus/4 (NTSC, SID Card)", GAME_UNOFFICIAL | GAME_IMPERFECT_SOUND)
|
@ -1,122 +0,0 @@
|
||||
/*********************************************************************
|
||||
|
||||
ap2_lang.c
|
||||
|
||||
Implementation of the Apple II Language Card
|
||||
|
||||
*********************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "includes/apple2.h"
|
||||
#include "ap2_lang.h"
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
PARAMETERS
|
||||
***************************************************************************/
|
||||
|
||||
#define LOG_LANGCARD 0
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
CORE IMPLEMENTATION
|
||||
***************************************************************************/
|
||||
|
||||
/*-------------------------------------------------
|
||||
apple2_langcard_touch - device read callback
|
||||
-------------------------------------------------*/
|
||||
|
||||
static void apple2_langcard_touch(device_t *device, offs_t offset)
|
||||
{
|
||||
UINT32 val, mask;
|
||||
|
||||
if (LOG_LANGCARD)
|
||||
logerror("language card bankswitch read, offset: $c08%0x\n", offset);
|
||||
|
||||
/* determine which flags to change */
|
||||
mask = VAR_LCWRITE | VAR_LCRAM | VAR_LCRAM2;
|
||||
val = 0;
|
||||
|
||||
if (offset & 0x01)
|
||||
val |= VAR_LCWRITE;
|
||||
|
||||
switch(offset & 0x03)
|
||||
{
|
||||
case 0x03:
|
||||
case 0x00:
|
||||
val |= VAR_LCRAM;
|
||||
break;
|
||||
}
|
||||
|
||||
if ((offset & 0x08) == 0)
|
||||
val |= VAR_LCRAM2;
|
||||
|
||||
/* change the flags */
|
||||
apple2_setvar(device->machine(), val, mask);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
apple2_langcard_r - device read callback
|
||||
-------------------------------------------------*/
|
||||
|
||||
READ8_DEVICE_HANDLER(apple2_langcard_r)
|
||||
{
|
||||
apple2_langcard_touch(device, offset);
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
apple2_langcard_w - device read callback
|
||||
-------------------------------------------------*/
|
||||
|
||||
WRITE8_DEVICE_HANDLER(apple2_langcard_w)
|
||||
{
|
||||
apple2_langcard_touch(device, offset);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
DEVICE_START(apple2_langcard) - device start
|
||||
function
|
||||
-------------------------------------------------*/
|
||||
|
||||
static DEVICE_START(apple2_langcard)
|
||||
{
|
||||
/* nothing to do */
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
DEVICE_GET_INFO(apple2_langcard) - device get info
|
||||
function
|
||||
-------------------------------------------------*/
|
||||
|
||||
DEVICE_GET_INFO(apple2_langcard)
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
/* --- the following bits of info are returned as 64-bit signed integers --- */
|
||||
case DEVINFO_INT_TOKEN_BYTES: info->i = 1; break;
|
||||
case DEVINFO_INT_INLINE_CONFIG_BYTES: info->i = 0; break;
|
||||
|
||||
/* --- the following bits of info are returned as pointers to data or functions --- */
|
||||
case DEVINFO_FCT_START: info->start = DEVICE_START_NAME(apple2_langcard); break;
|
||||
case DEVINFO_FCT_STOP: /* Nothing */ break;
|
||||
case DEVINFO_FCT_RESET: /* Nothing */ break;
|
||||
|
||||
/* --- the following bits of info are returned as NULL-terminated strings --- */
|
||||
case DEVINFO_STR_NAME: strcpy(info->s, "Apple II Language Card"); break;
|
||||
case DEVINFO_STR_FAMILY: strcpy(info->s, "Apple II Language Card"); break;
|
||||
case DEVINFO_STR_VERSION: strcpy(info->s, "1.0"); break;
|
||||
case DEVINFO_STR_SOURCE_FILE: strcpy(info->s, __FILE__); break;
|
||||
}
|
||||
}
|
||||
|
||||
DEFINE_LEGACY_DEVICE(APPLE2_LANGCARD, apple2_langcard);
|
@ -1,35 +0,0 @@
|
||||
/*********************************************************************
|
||||
|
||||
ap2_lang.h
|
||||
|
||||
Implementation of the Apple II Language Card
|
||||
|
||||
*********************************************************************/
|
||||
|
||||
#ifndef __AP2_LANG__
|
||||
#define __AP2_LANG__
|
||||
|
||||
#include "emu.h"
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
CONSTANTS
|
||||
***************************************************************************/
|
||||
|
||||
DECLARE_LEGACY_DEVICE(APPLE2_LANGCARD, apple2_langcard);
|
||||
|
||||
#define MCFG_APPLE2_LANGCARD_ADD(_tag) \
|
||||
MCFG_DEVICE_ADD((_tag), APPLE2_LANGCARD, 0)
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
FUNCTION PROTOTYPES
|
||||
***************************************************************************/
|
||||
/* slot read function */
|
||||
READ8_DEVICE_HANDLER(apple2_langcard_r);
|
||||
|
||||
/* slot write function */
|
||||
WRITE8_DEVICE_HANDLER(apple2_langcard_w);
|
||||
|
||||
#endif /* __AP2_LANG__ */
|
@ -1,233 +0,0 @@
|
||||
/*********************************************************************
|
||||
|
||||
ap2_slot.c
|
||||
|
||||
Implementation of Apple II device slots
|
||||
|
||||
*********************************************************************/
|
||||
|
||||
#include "ap2_slot.h"
|
||||
#include "includes/apple2.h"
|
||||
|
||||
/***************************************************************************
|
||||
TYPE DEFINITIONS
|
||||
***************************************************************************/
|
||||
|
||||
typedef struct _apple2_slot_token apple2_slot_token;
|
||||
struct _apple2_slot_token
|
||||
{
|
||||
device_t *slot_device;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
INLINE FUNCTIONS
|
||||
***************************************************************************/
|
||||
|
||||
INLINE void assert_valid(device_t *device)
|
||||
{
|
||||
assert(device != NULL);
|
||||
assert(device->type() == APPLE2_SLOT);
|
||||
}
|
||||
|
||||
|
||||
|
||||
INLINE const apple2_slot_config *get_config(device_t *device)
|
||||
{
|
||||
assert_valid(device);
|
||||
return (const apple2_slot_config *) downcast<const legacy_device_base *>(device)->inline_config();
|
||||
}
|
||||
|
||||
|
||||
|
||||
INLINE apple2_slot_token *get_token(device_t *device)
|
||||
{
|
||||
assert_valid(device);
|
||||
return (apple2_slot_token *) downcast<legacy_device_base *>(device)->token();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
CORE IMPLEMENTATION
|
||||
***************************************************************************/
|
||||
|
||||
/*-------------------------------------------------
|
||||
apple2_slot - looks up a slot
|
||||
-------------------------------------------------*/
|
||||
|
||||
device_t *apple2_slot(running_machine &machine, int slotnum)
|
||||
{
|
||||
char buffer[7];
|
||||
|
||||
assert((slotnum >= 0) && (slotnum <= 7));
|
||||
snprintf(buffer, ARRAY_LENGTH(buffer), "slot_%d", slotnum);
|
||||
|
||||
return machine.device(buffer);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
DEVICE_START(apple2_slot) - device start
|
||||
function
|
||||
-------------------------------------------------*/
|
||||
|
||||
static DEVICE_START(apple2_slot)
|
||||
{
|
||||
const apple2_slot_config *config = get_config(device);
|
||||
apple2_slot_token *token = get_token(device);
|
||||
|
||||
if (config->tag != NULL)
|
||||
{
|
||||
/* locate the device */
|
||||
token->slot_device = device->machine().device(config->tag);
|
||||
|
||||
assert(token->slot_device != NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
token->slot_device = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
apple2_slot_r - slot read function
|
||||
-------------------------------------------------*/
|
||||
|
||||
READ8_DEVICE_HANDLER(apple2_slot_r)
|
||||
{
|
||||
UINT8 result = 0x00;
|
||||
const apple2_slot_config *config = get_config(device);
|
||||
apple2_slot_token *token = get_token(device);
|
||||
|
||||
/* do we actually have a device, and can we read? */
|
||||
if ((token->slot_device != NULL) && (config->rh != NULL))
|
||||
{
|
||||
result = (*config->rh)(token->slot_device, offset);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
apple2_slot_w - slot write function
|
||||
-------------------------------------------------*/
|
||||
|
||||
WRITE8_DEVICE_HANDLER(apple2_slot_w)
|
||||
{
|
||||
const apple2_slot_config *config = get_config(device);
|
||||
apple2_slot_token *token = get_token(device);
|
||||
|
||||
/* do we actually have a device, and can we read? */
|
||||
if ((token->slot_device != NULL) && (config->wh != NULL))
|
||||
{
|
||||
(*config->wh)(token->slot_device, offset, data);
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
apple2_c800_slot_r - slot read function
|
||||
-------------------------------------------------*/
|
||||
|
||||
READ8_DEVICE_HANDLER(apple2_c800_slot_r)
|
||||
{
|
||||
UINT8 result = 0x00;
|
||||
const apple2_slot_config *config = get_config(device);
|
||||
apple2_slot_token *token = get_token(device);
|
||||
|
||||
/* do we actually have a device, and can we read? */
|
||||
if ((token->slot_device != NULL) && (config->rhc800 != NULL))
|
||||
{
|
||||
result = (*config->rhc800)(token->slot_device, offset);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
apple2_c800_slot_w - slot write function
|
||||
-------------------------------------------------*/
|
||||
|
||||
WRITE8_DEVICE_HANDLER(apple2_c800_slot_w)
|
||||
{
|
||||
const apple2_slot_config *config = get_config(device);
|
||||
apple2_slot_token *token = get_token(device);
|
||||
|
||||
/* do we actually have a device, and can we read? */
|
||||
if ((token->slot_device != NULL) && (config->whc800 != NULL))
|
||||
{
|
||||
(*config->whc800)(token->slot_device, offset, data);
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
apple2_slot_ROM_w - slot ROM read function
|
||||
-------------------------------------------------*/
|
||||
READ8_DEVICE_HANDLER(apple2_slot_ROM_r)
|
||||
{
|
||||
const apple2_slot_config *config = get_config(device);
|
||||
apple2_slot_token *token = get_token(device);
|
||||
|
||||
/* do we actually have a device, and can we read? */
|
||||
if ((token->slot_device != NULL) && (config->rhcnxx != NULL))
|
||||
{
|
||||
return (*config->rhcnxx)(token->slot_device, offset);
|
||||
}
|
||||
|
||||
if (config->slotnum > 0)
|
||||
{
|
||||
return apple2_slotram_r(device->machine(), config->slotnum, offset + ((config->slotnum-1)<<8));
|
||||
}
|
||||
|
||||
return apple2_getfloatingbusvalue(device->machine());
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
apple2_slot_ROM_w - slot ROM write function
|
||||
-------------------------------------------------*/
|
||||
|
||||
WRITE8_DEVICE_HANDLER(apple2_slot_ROM_w)
|
||||
{
|
||||
const apple2_slot_config *config = get_config(device);
|
||||
apple2_slot_token *token = get_token(device);
|
||||
|
||||
/* do we actually have a device, and can we write? */
|
||||
if ((token->slot_device != NULL) && (config->whcnxx != NULL))
|
||||
{
|
||||
(*config->whcnxx)(token->slot_device, offset, data);
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
DEVICE_GET_INFO(apple2_slot) - device get info
|
||||
function
|
||||
-------------------------------------------------*/
|
||||
|
||||
DEVICE_GET_INFO(apple2_slot)
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
/* --- the following bits of info are returned as 64-bit signed integers --- */
|
||||
case DEVINFO_INT_TOKEN_BYTES: info->i = sizeof(apple2_slot_token); break;
|
||||
case DEVINFO_INT_INLINE_CONFIG_BYTES: info->i = sizeof(apple2_slot_config); break;
|
||||
|
||||
/* --- the following bits of info are returned as pointers to data or functions --- */
|
||||
case DEVINFO_FCT_START: info->start = DEVICE_START_NAME(apple2_slot); break;
|
||||
case DEVINFO_FCT_STOP: /* Nothing */ break;
|
||||
case DEVINFO_FCT_RESET: /* Nothing */ break;
|
||||
|
||||
/* --- the following bits of info are returned as NULL-terminated strings --- */
|
||||
case DEVINFO_STR_NAME: strcpy(info->s, "Apple II Slot"); break;
|
||||
case DEVINFO_STR_FAMILY: strcpy(info->s, "Apple II Slot"); break;
|
||||
case DEVINFO_STR_VERSION: strcpy(info->s, "1.0"); break;
|
||||
case DEVINFO_STR_SOURCE_FILE: strcpy(info->s, __FILE__); break;
|
||||
}
|
||||
}
|
||||
|
||||
DEFINE_LEGACY_DEVICE(APPLE2_SLOT, apple2_slot);
|
@ -1,85 +0,0 @@
|
||||
/*********************************************************************
|
||||
|
||||
ap2_slot.h
|
||||
|
||||
Implementation of Apple II device slots
|
||||
|
||||
*********************************************************************/
|
||||
|
||||
#ifndef __AP2_SLOT__
|
||||
#define __AP2_SLOT__
|
||||
|
||||
#include "emu.h"
|
||||
|
||||
/***************************************************************************
|
||||
CONSTANTS
|
||||
***************************************************************************/
|
||||
|
||||
DECLARE_LEGACY_DEVICE(APPLE2_SLOT, apple2_slot);
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
TYPE DEFINITIONS
|
||||
***************************************************************************/
|
||||
|
||||
typedef struct _apple2_slot_config apple2_slot_config;
|
||||
struct _apple2_slot_config
|
||||
{
|
||||
const char *tag;
|
||||
int slotnum; // slot number
|
||||
|
||||
read8_device_func rh; // C0nX I/O space (DEVSEL)
|
||||
write8_device_func wh;
|
||||
|
||||
read8_device_func rhcnxx; // CnXX ROM space (IOSEL)
|
||||
write8_device_func whcnxx;
|
||||
|
||||
read8_device_func rhc800; // C800 ROM extension space (IOSTB)
|
||||
write8_device_func whc800;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
DEVICE CONFIGURATION MACROS
|
||||
***************************************************************************/
|
||||
|
||||
#define MCFG_APPLE2_SLOT_ADD(_slot_number, _slot_device_tag, _rh, _wh, _rhc800, _whc800, _rhcnxx, _whcnxx) \
|
||||
MCFG_DEVICE_ADD("slot_" #_slot_number, APPLE2_SLOT, 0) \
|
||||
MCFG_DEVICE_CONFIG_DATAPTR(apple2_slot_config, tag, _slot_device_tag) \
|
||||
MCFG_DEVICE_CONFIG_DATA32(apple2_slot_config, slotnum, _slot_number) \
|
||||
MCFG_DEVICE_CONFIG_DATAPTR(apple2_slot_config, rh, _rh) \
|
||||
MCFG_DEVICE_CONFIG_DATAPTR(apple2_slot_config, wh, _wh) \
|
||||
MCFG_DEVICE_CONFIG_DATAPTR(apple2_slot_config, rhc800, _rhc800) \
|
||||
MCFG_DEVICE_CONFIG_DATAPTR(apple2_slot_config, whc800, _whc800) \
|
||||
MCFG_DEVICE_CONFIG_DATAPTR(apple2_slot_config, rhcnxx, _rhcnxx) \
|
||||
MCFG_DEVICE_CONFIG_DATAPTR(apple2_slot_config, whcnxx, _whcnxx) \
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
FUNCTION PROTOTYPES
|
||||
***************************************************************************/
|
||||
/* slot read function */
|
||||
READ8_DEVICE_HANDLER(apple2_slot_r);
|
||||
|
||||
/* slot write function */
|
||||
WRITE8_DEVICE_HANDLER(apple2_slot_w);
|
||||
|
||||
/* slot ROM read function */
|
||||
READ8_DEVICE_HANDLER(apple2_slot_ROM_r);
|
||||
|
||||
/* slot ROM write function */
|
||||
WRITE8_DEVICE_HANDLER(apple2_slot_ROM_w);
|
||||
|
||||
/* slot extended ROM read function */
|
||||
READ8_DEVICE_HANDLER(apple2_c800_slot_r);
|
||||
|
||||
/* slot extended ROM write function */
|
||||
WRITE8_DEVICE_HANDLER(apple2_c800_slot_w);
|
||||
|
||||
/* slot device lookup */
|
||||
device_t *apple2_slot(running_machine &machine, int slotnum);
|
||||
|
||||
#endif /* __AP2_SLOT__ */
|
@ -1,715 +0,0 @@
|
||||
/***************************************************************************
|
||||
|
||||
commodore c16 home computer
|
||||
|
||||
peter.trauner@jk.uni-linz.ac.at
|
||||
documentation
|
||||
www.funet.fi
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "audio/ted7360.h"
|
||||
#include "cpu/m6502/m6502.h"
|
||||
#include "imagedev/cassette.h"
|
||||
#include "imagedev/cartslot.h"
|
||||
#include "machine/ram.h"
|
||||
#include "includes/c16.h"
|
||||
#include "machine/cbmiec.h"
|
||||
#include "sound/sid6581.h"
|
||||
|
||||
#define VERBOSE_LEVEL 0
|
||||
#define DBG_LOG( MACHINE, N, M, A ) \
|
||||
do { \
|
||||
if(VERBOSE_LEVEL >= N) \
|
||||
{ \
|
||||
if( M ) \
|
||||
logerror("%11.6f: %-24s", MACHINE.time().as_double(), (char*) M ); \
|
||||
logerror A; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
/*
|
||||
* tia6523
|
||||
*
|
||||
* connector to floppy c1551 (delivered with c1551 as c16 expansion)
|
||||
* port a for data read/write
|
||||
* port b
|
||||
* 0 status 0
|
||||
* 1 status 1
|
||||
* port c
|
||||
* 6 dav output edge data on port a available
|
||||
* 7 ack input edge ready for next datum
|
||||
*/
|
||||
|
||||
/*
|
||||
ddr bit 1 port line is output
|
||||
port bit 1 port line is high
|
||||
|
||||
serial bus
|
||||
1 serial srq in (ignored)
|
||||
2 gnd
|
||||
3 atn out (pull up)
|
||||
4 clock in/out (pull up)
|
||||
5 data in/out (pull up)
|
||||
6 /reset (pull up) hardware
|
||||
|
||||
|
||||
p0 negated serial bus pin 5 /data out
|
||||
p1 negated serial bus pin 4 /clock out, cassette write
|
||||
p2 negated serial bus pin 3 /atn out
|
||||
p3 cassette motor out
|
||||
|
||||
p4 cassette read
|
||||
p5 not connected (or not available on MOS7501?)
|
||||
p6 serial clock in
|
||||
p7 serial data in, serial bus 5
|
||||
*/
|
||||
|
||||
WRITE8_DEVICE_HANDLER(c16_m7501_port_write)
|
||||
{
|
||||
c16_state *state = device->machine().driver_data<c16_state>();
|
||||
|
||||
/* bit zero then output 0 */
|
||||
state->m_iec->atn_w(!BIT(data, 2));
|
||||
state->m_iec->clk_w(!BIT(data, 1));
|
||||
state->m_iec->data_w(!BIT(data, 0));
|
||||
|
||||
state->m_cassette->output(!BIT(data, 1) ? -(0x5a9e >> 1) : +(0x5a9e >> 1));
|
||||
|
||||
state->m_cassette->change_state(BIT(data, 7) ? CASSETTE_MOTOR_DISABLED : CASSETTE_MOTOR_ENABLED, CASSETTE_MASK_MOTOR);
|
||||
}
|
||||
|
||||
READ8_DEVICE_HANDLER(c16_m7501_port_read)
|
||||
{
|
||||
c16_state *state = device->machine().driver_data<c16_state>();
|
||||
UINT8 data = 0xff;
|
||||
UINT8 c16_port7501 = m6510_get_port(state->m_maincpu);
|
||||
|
||||
if (BIT(c16_port7501, 0) || !state->m_iec->data_r())
|
||||
data &= ~0x80;
|
||||
|
||||
if (BIT(c16_port7501, 1) || !state->m_iec->clk_r())
|
||||
data &= ~0x40;
|
||||
|
||||
// data &= ~0x20; // port bit not in pinout
|
||||
|
||||
if (state->m_cassette->input() > +0.0)
|
||||
data |= 0x10;
|
||||
else
|
||||
data &= ~0x10;
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
static void c16_bankswitch( running_machine &machine )
|
||||
{
|
||||
c16_state *state = machine.driver_data<c16_state>();
|
||||
UINT8 *rom = state->memregion("maincpu")->base();
|
||||
state->membank("bank9")->set_base(state->m_messram->pointer());
|
||||
|
||||
switch (state->m_lowrom)
|
||||
{
|
||||
case 0:
|
||||
state->membank("bank2")->set_base(rom + 0x10000);
|
||||
break;
|
||||
case 1:
|
||||
state->membank("bank2")->set_base(rom + 0x18000);
|
||||
break;
|
||||
case 2:
|
||||
state->membank("bank2")->set_base(rom + 0x20000);
|
||||
break;
|
||||
case 3:
|
||||
state->membank("bank2")->set_base(rom + 0x28000);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (state->m_highrom)
|
||||
{
|
||||
case 0:
|
||||
state->membank("bank3")->set_base(rom + 0x14000);
|
||||
state->membank("bank8")->set_base(rom + 0x17f20);
|
||||
break;
|
||||
case 1:
|
||||
state->membank("bank3")->set_base(rom + 0x1c000);
|
||||
state->membank("bank8")->set_base(rom + 0x1ff20);
|
||||
break;
|
||||
case 2:
|
||||
state->membank("bank3")->set_base(rom + 0x24000);
|
||||
state->membank("bank8")->set_base(rom + 0x27f20);
|
||||
break;
|
||||
case 3:
|
||||
state->membank("bank3")->set_base(rom + 0x2c000);
|
||||
state->membank("bank8")->set_base(rom + 0x2ff20);
|
||||
break;
|
||||
}
|
||||
state->membank("bank4")->set_base(rom + 0x17c00);
|
||||
}
|
||||
|
||||
WRITE8_HANDLER( c16_switch_to_rom )
|
||||
{
|
||||
c16_state *state = space->machine().driver_data<c16_state>();
|
||||
|
||||
ted7360_rom_switch_w(state->m_ted7360, 1);
|
||||
c16_bankswitch(space->machine());
|
||||
}
|
||||
|
||||
/* write access to fddX load data flipflop
|
||||
* and selects roms
|
||||
* a0 a1
|
||||
* 0 0 basic
|
||||
* 0 1 plus4 low
|
||||
* 1 0 c1 low
|
||||
* 1 1 c2 low
|
||||
*
|
||||
* a2 a3
|
||||
* 0 0 kernal
|
||||
* 0 1 plus4 hi
|
||||
* 1 0 c1 high
|
||||
* 1 1 c2 high */
|
||||
WRITE8_HANDLER( c16_select_roms )
|
||||
{
|
||||
c16_state *state = space->machine().driver_data<c16_state>();
|
||||
|
||||
state->m_lowrom = offset & 0x03;
|
||||
state->m_highrom = (offset & 0x0c) >> 2;
|
||||
if (ted7360_rom_switch_r(state->m_ted7360))
|
||||
c16_bankswitch(space->machine());
|
||||
}
|
||||
|
||||
WRITE8_HANDLER( c16_switch_to_ram )
|
||||
{
|
||||
c16_state *state = space->machine().driver_data<c16_state>();
|
||||
UINT8 *ram = state->m_messram->pointer();
|
||||
UINT32 ram_size = state->m_messram->size();
|
||||
|
||||
ted7360_rom_switch_w(state->m_ted7360, 0);
|
||||
|
||||
state->membank("bank2")->set_base(ram + (0x8000 % ram_size));
|
||||
state->membank("bank3")->set_base(ram + (0xc000 % ram_size));
|
||||
state->membank("bank4")->set_base(ram + (0xfc00 % ram_size));
|
||||
state->membank("bank8")->set_base(ram + (0xff20 % ram_size));
|
||||
}
|
||||
|
||||
UINT8 c16_read_keyboard( running_machine &machine, int databus )
|
||||
{
|
||||
c16_state *state = machine.driver_data<c16_state>();
|
||||
UINT8 value = 0xff;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
if (!BIT(state->m_port6529, i))
|
||||
value &= state->m_keyline[i];
|
||||
}
|
||||
|
||||
/* looks like joy 0 needs dataline2 low
|
||||
* and joy 1 needs dataline1 low
|
||||
* write to 0xff08 (value on databus) reloads latches */
|
||||
if (!BIT(databus, 2))
|
||||
value &= state->m_keyline[8];
|
||||
|
||||
if (!BIT(databus, 1))
|
||||
value &= state->m_keyline[9];
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/*
|
||||
* mos 6529
|
||||
* simple 1 port 8bit input output
|
||||
* output with pull up resistors, 0 means low
|
||||
* input, 0 means low
|
||||
*/
|
||||
/*
|
||||
* ic used as output,
|
||||
* output low means keyboard line selected
|
||||
* keyboard line is then read into the ted7360 latch
|
||||
*/
|
||||
WRITE8_HANDLER( c16_6529_port_w )
|
||||
{
|
||||
c16_state *state = space->machine().driver_data<c16_state>();
|
||||
state->m_port6529 = data;
|
||||
}
|
||||
|
||||
READ8_HANDLER( c16_6529_port_r )
|
||||
{
|
||||
c16_state *state = space->machine().driver_data<c16_state>();
|
||||
return state->m_port6529 & (c16_read_keyboard (space->machine(), 0xff /*databus */ ) | (state->m_port6529 ^ 0xff));
|
||||
}
|
||||
|
||||
/*
|
||||
* p0 Userport b
|
||||
* p1 Userport k
|
||||
* p2 Userport 4, cassette sense
|
||||
* p3 Userport 5
|
||||
* p4 Userport 6
|
||||
* p5 Userport 7
|
||||
* p6 Userport j
|
||||
* p7 Userport f
|
||||
*/
|
||||
WRITE8_HANDLER( plus4_6529_port_w )
|
||||
{
|
||||
}
|
||||
|
||||
READ8_HANDLER( plus4_6529_port_r )
|
||||
{
|
||||
c16_state *state = space->machine().driver_data<c16_state>();
|
||||
int data = 0x00;
|
||||
|
||||
if ((state->m_cassette->get_state() & CASSETTE_MASK_UISTATE) != CASSETTE_STOPPED)
|
||||
data &= ~0x04;
|
||||
else
|
||||
data |= 0x04;
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
READ8_HANDLER( c16_fd1x_r )
|
||||
{
|
||||
c16_state *state = space->machine().driver_data<c16_state>();
|
||||
int data = 0x00;
|
||||
|
||||
if ((state->m_cassette->get_state() & CASSETTE_MASK_UISTATE) != CASSETTE_STOPPED)
|
||||
data &= ~0x04;
|
||||
else
|
||||
data |= 0x04;
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
0 write: transmit data
|
||||
0 read: receiver data
|
||||
1 write: programmed rest (data is dont care)
|
||||
1 read: status register
|
||||
2 command register
|
||||
3 control register
|
||||
control register (offset 3)
|
||||
cleared by hardware reset, not changed by programmed reset
|
||||
7: 2 stop bits (0 1 stop bit)
|
||||
6,5: data word length
|
||||
00 8 bits
|
||||
01 7
|
||||
10 6
|
||||
11 5
|
||||
4: ?? clock source
|
||||
0 external receiver clock
|
||||
1 baud rate generator
|
||||
3-0: baud rate generator
|
||||
0000 use external clock
|
||||
0001 60
|
||||
0010 75
|
||||
0011
|
||||
0100
|
||||
0101
|
||||
0110 300
|
||||
0111 600
|
||||
1000 1200
|
||||
1001
|
||||
1010 2400
|
||||
1011 3600
|
||||
1100 4800
|
||||
1101 7200
|
||||
1110 9600
|
||||
1111 19200
|
||||
control register
|
||||
*/
|
||||
WRITE8_HANDLER( c16_6551_port_w )
|
||||
{
|
||||
c16_state *state = space->machine().driver_data<c16_state>();
|
||||
|
||||
offset &= 0x03;
|
||||
DBG_LOG(space->machine(), 3, "6551", ("port write %.2x %.2x\n", offset, data));
|
||||
state->m_port6529 = data;
|
||||
}
|
||||
|
||||
READ8_HANDLER( c16_6551_port_r )
|
||||
{
|
||||
int data = 0x00;
|
||||
|
||||
offset &= 0x03;
|
||||
DBG_LOG(space->machine(), 3, "6551", ("port read %.2x %.2x\n", offset, data));
|
||||
return data;
|
||||
}
|
||||
|
||||
int c16_dma_read( running_machine &machine, int offset )
|
||||
{
|
||||
c16_state *state = machine.driver_data<c16_state>();
|
||||
return state->m_messram->pointer()[offset % state->m_messram->size()];
|
||||
}
|
||||
|
||||
int c16_dma_read_rom( running_machine &machine, int offset )
|
||||
{
|
||||
c16_state *state = machine.driver_data<c16_state>();
|
||||
|
||||
/* should read real c16 system bus from 0xfd00 -ff1f */
|
||||
if (offset >= 0xc000)
|
||||
{ /* rom address in rom */
|
||||
if ((offset >= 0xfc00) && (offset < 0xfd00))
|
||||
return state->m_mem10000[offset];
|
||||
|
||||
switch (state->m_highrom)
|
||||
{
|
||||
case 0:
|
||||
return state->m_mem10000[offset & 0x7fff];
|
||||
case 1:
|
||||
return state->m_mem18000[offset & 0x7fff];
|
||||
case 2:
|
||||
return state->m_mem20000[offset & 0x7fff];
|
||||
case 3:
|
||||
return state->m_mem28000[offset & 0x7fff];
|
||||
}
|
||||
}
|
||||
|
||||
if (offset >= 0x8000)
|
||||
{ /* rom address in rom */
|
||||
switch (state->m_lowrom)
|
||||
{
|
||||
case 0:
|
||||
return state->m_mem10000[offset & 0x7fff];
|
||||
case 1:
|
||||
return state->m_mem18000[offset & 0x7fff];
|
||||
case 2:
|
||||
return state->m_mem20000[offset & 0x7fff];
|
||||
case 3:
|
||||
return state->m_mem28000[offset & 0x7fff];
|
||||
}
|
||||
}
|
||||
|
||||
return state->m_messram->pointer()[offset % state->m_messram->size()];
|
||||
}
|
||||
|
||||
void c16_interrupt( running_machine &machine, int level )
|
||||
{
|
||||
c16_state *state = machine.driver_data<c16_state>();
|
||||
|
||||
if (level != state->m_old_level)
|
||||
{
|
||||
DBG_LOG(machine, 3, "mos7501", ("irq %s\n", level ? "start" : "end"));
|
||||
device_set_input_line(state->m_maincpu, M6510_IRQ_LINE, level);
|
||||
state->m_old_level = level;
|
||||
}
|
||||
}
|
||||
|
||||
static void c16_common_driver_init( running_machine &machine )
|
||||
{
|
||||
c16_state *state = machine.driver_data<c16_state>();
|
||||
UINT8 *rom = state->memregion("maincpu")->base();
|
||||
|
||||
/* initial bankswitch (notice that TED7360 is init to ROM) */
|
||||
state->membank("bank2")->set_base(rom + 0x10000);
|
||||
state->membank("bank3")->set_base(rom + 0x14000);
|
||||
state->membank("bank4")->set_base(rom + 0x17c00);
|
||||
state->membank("bank8")->set_base(rom + 0x17f20);
|
||||
|
||||
state->m_mem10000 = rom + 0x10000;
|
||||
state->m_mem14000 = rom + 0x14000;
|
||||
state->m_mem18000 = rom + 0x18000;
|
||||
state->m_mem1c000 = rom + 0x1c000;
|
||||
state->m_mem20000 = rom + 0x20000;
|
||||
state->m_mem24000 = rom + 0x24000;
|
||||
state->m_mem28000 = rom + 0x28000;
|
||||
state->m_mem2c000 = rom + 0x2c000;
|
||||
}
|
||||
|
||||
DRIVER_INIT_MEMBER(c16_state,c16)
|
||||
{
|
||||
c16_common_driver_init(machine());
|
||||
|
||||
m_sidcard = 0;
|
||||
m_pal = 1;
|
||||
}
|
||||
|
||||
DRIVER_INIT_MEMBER(c16_state,plus4)
|
||||
{
|
||||
c16_common_driver_init(machine());
|
||||
|
||||
m_sidcard = 0;
|
||||
m_pal = 0;
|
||||
}
|
||||
|
||||
DRIVER_INIT_MEMBER(c16_state,c16sid)
|
||||
{
|
||||
c16_common_driver_init(machine());
|
||||
|
||||
m_sidcard = 1;
|
||||
m_pal = 1;
|
||||
}
|
||||
|
||||
DRIVER_INIT_MEMBER(c16_state,plus4sid)
|
||||
{
|
||||
c16_common_driver_init(machine());
|
||||
|
||||
m_sidcard = 1;
|
||||
m_pal = 0;
|
||||
}
|
||||
|
||||
MACHINE_RESET( c16 )
|
||||
{
|
||||
address_space *space = machine.device("maincpu")->memory().space(AS_PROGRAM);
|
||||
c16_state *state = machine.driver_data<c16_state>();
|
||||
UINT8 *ram = state->m_messram->pointer();
|
||||
UINT32 ram_size = state->m_messram->size();
|
||||
|
||||
memset(state->m_keyline, 0xff, ARRAY_LENGTH(state->m_keyline));
|
||||
|
||||
state->m_lowrom = 0;
|
||||
state->m_highrom = 0;
|
||||
state->m_old_level = 0;
|
||||
state->m_port6529 = 0;
|
||||
|
||||
if (state->m_pal)
|
||||
{
|
||||
state->membank("bank1")->set_base(ram + (0x4000 % ram_size));
|
||||
|
||||
state->membank("bank5")->set_base(ram + (0x4000 % ram_size));
|
||||
state->membank("bank6")->set_base(ram + (0x8000 % ram_size));
|
||||
state->membank("bank7")->set_base(ram + (0xc000 % ram_size));
|
||||
|
||||
space->install_write_bank(0xff20, 0xff3d,"bank10");
|
||||
space->install_write_bank(0xff40, 0xffff, "bank11");
|
||||
state->membank("bank10")->set_base(ram + (0xff20 % ram_size));
|
||||
state->membank("bank11")->set_base(ram + (0xff40 % ram_size));
|
||||
}
|
||||
else
|
||||
{
|
||||
space->install_write_bank(0x4000, 0xfcff, "bank10");
|
||||
state->membank("bank10")->set_base(ram + (0x4000 % ram_size));
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
// FIXME
|
||||
// in very old MESS versions, we had these handlers to enable SID writes to 0xd400.
|
||||
// would a real SID Card allow for this? If not, this should be removed completely
|
||||
static WRITE8_HANDLER( c16_sidcart_16k )
|
||||
{
|
||||
c16_state *state = space->machine().driver_data<c16_state>();
|
||||
UINT8 *ram = state->m_messram->pointer();
|
||||
|
||||
ram[0x1400 + offset] = data;
|
||||
ram[0x5400 + offset] = data;
|
||||
ram[0x9400 + offset] = data;
|
||||
ram[0xd400 + offset] = data;
|
||||
|
||||
sid6581_w(state->m_sid, offset, data);
|
||||
}
|
||||
|
||||
static WRITE8_HANDLER( c16_sidcart_64k )
|
||||
{
|
||||
c16_state *state = space->machine().driver_data<c16_state>();
|
||||
|
||||
state->m_messram->pointer()[0xd400 + offset] = data;
|
||||
|
||||
sid6581_w(state->m_sid, offset, data);
|
||||
}
|
||||
|
||||
static TIMER_CALLBACK( c16_sidhack_tick )
|
||||
{
|
||||
address_space *space = machine.device("maincpu")->memory().space(AS_PROGRAM);
|
||||
c16_state *state = space->machine().driver_data<c16_state>();
|
||||
|
||||
if (machine.root_device().ioport("SID")->read_safe(0x00) & 0x02)
|
||||
{
|
||||
if (state->m_pal)
|
||||
space->install_legacy_write_handler(0xd400, 0xd41f, FUNC(c16_sidcart_16k));
|
||||
else
|
||||
space->install_legacy_write_handler(0xd400, 0xd41f, FUNC(c16_sidcart_64k));
|
||||
}
|
||||
else
|
||||
{
|
||||
space->unmap_write(0xd400, 0xd41f);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static TIMER_CALLBACK( c16_sidcard_tick )
|
||||
{
|
||||
c16_state *state = machine.driver_data<c16_state>();
|
||||
address_space *space = state->m_maincpu->memory().space(AS_PROGRAM);
|
||||
|
||||
if (machine.root_device().ioport("SID")->read_safe(0x00) & 0x01)
|
||||
space->install_legacy_readwrite_handler(*state->m_sid, 0xfe80, 0xfe9f, FUNC(sid6581_r), FUNC(sid6581_w));
|
||||
else
|
||||
space->install_legacy_readwrite_handler(*state->m_sid, 0xfd40, 0xfd5f, FUNC(sid6581_r), FUNC(sid6581_w));
|
||||
}
|
||||
|
||||
INTERRUPT_GEN( c16_frame_interrupt )
|
||||
{
|
||||
c16_state *state = device->machine().driver_data<c16_state>();
|
||||
int value, i;
|
||||
static const char *const c16ports[] = { "ROW0", "ROW1", "ROW2", "ROW3", "ROW4", "ROW5", "ROW6", "ROW7" };
|
||||
|
||||
/* Lines 0-7 : common keyboard */
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
value = 0xff;
|
||||
value &= ~device->machine().root_device().ioport(c16ports[i])->read();
|
||||
|
||||
/* Shift Lock is mapped on Left/Right Shift */
|
||||
if ((i == 1) && (device->machine().root_device().ioport("SPECIAL")->read() & 0x80))
|
||||
value &= ~0x80;
|
||||
|
||||
state->m_keyline[i] = value;
|
||||
}
|
||||
|
||||
if (device->machine().root_device().ioport("CTRLSEL")->read() & 0x01)
|
||||
{
|
||||
value = 0xff;
|
||||
if (device->machine().root_device().ioport("JOY0")->read() & 0x10) /* Joypad1_Button */
|
||||
{
|
||||
if (device->machine().root_device().ioport("SPECIAL")->read() & 0x40)
|
||||
value &= ~0x80;
|
||||
else
|
||||
value &= ~0x40;
|
||||
}
|
||||
|
||||
value &= ~(device->machine().root_device().ioport("JOY0")->read() & 0x0f); /* Other Inputs Joypad1 */
|
||||
|
||||
if (device->machine().root_device().ioport("SPECIAL")->read() & 0x40)
|
||||
state->m_keyline[9] = value;
|
||||
else
|
||||
state->m_keyline[8] = value;
|
||||
}
|
||||
|
||||
if (device->machine().root_device().ioport("CTRLSEL")->read() & 0x10)
|
||||
{
|
||||
value = 0xff;
|
||||
if (device->machine().root_device().ioport("JOY1")->read() & 0x10) /* Joypad2_Button */
|
||||
{
|
||||
if (device->machine().root_device().ioport("SPECIAL")->read() & 0x40)
|
||||
value &= ~0x40;
|
||||
else
|
||||
value &= ~0x80;
|
||||
}
|
||||
|
||||
value &= ~(device->machine().root_device().ioport("JOY1")->read() & 0x0f); /* Other Inputs Joypad2 */
|
||||
|
||||
if (device->machine().root_device().ioport("SPECIAL")->read() & 0x40)
|
||||
state->m_keyline[8] = value;
|
||||
else
|
||||
state->m_keyline[9] = value;
|
||||
}
|
||||
|
||||
ted7360_frame_interrupt_gen(state->m_ted7360);
|
||||
|
||||
if (state->m_sidcard)
|
||||
{
|
||||
/* if we are emulating the SID card, check which memory area should be accessed */
|
||||
device->machine().scheduler().timer_set(attotime::zero, FUNC(c16_sidcard_tick));
|
||||
#if 0
|
||||
/* if we are emulating the SID card, check if writes to 0xd400 have been enabled */
|
||||
device->machine().scheduler().timer_set(attotime::zero, FUNC(c16_sidhack_tick));
|
||||
#endif
|
||||
}
|
||||
|
||||
set_led_status(device->machine(), 1, device->machine().root_device().ioport("SPECIAL")->read() & 0x80 ? 1 : 0); /* Shift Lock */
|
||||
set_led_status(device->machine(), 0, device->machine().root_device().ioport("SPECIAL")->read() & 0x40 ? 1 : 0); /* Joystick Swap */
|
||||
}
|
||||
|
||||
|
||||
/***********************************************
|
||||
|
||||
C16 Cartridges
|
||||
|
||||
***********************************************/
|
||||
|
||||
static void plus4_software_list_cartridge_load(device_image_interface &image)
|
||||
{
|
||||
UINT8 *mem = image.device().machine().root_device().memregion("maincpu")->base();
|
||||
|
||||
size_t size = image.get_software_region_length("c1l");
|
||||
if (size)
|
||||
memcpy(mem + 0x20000, image.get_software_region("c1l"), size);
|
||||
|
||||
size = image.get_software_region_length("c1h");
|
||||
if (size)
|
||||
memcpy(mem + 0x24000, image.get_software_region("c1h"), size);
|
||||
|
||||
size = image.get_software_region_length("c2l");
|
||||
if (size)
|
||||
memcpy(mem + 0x28000, image.get_software_region("c2l"), size);
|
||||
|
||||
size = image.get_software_region_length("c2h");
|
||||
if (size)
|
||||
memcpy(mem + 0x2c000, image.get_software_region("c2h"), size);
|
||||
}
|
||||
|
||||
static int plus4_crt_load( device_image_interface &image )
|
||||
{
|
||||
UINT8 *mem = image.device().machine().root_device().memregion("maincpu")->base();
|
||||
int size = image.length(), test;
|
||||
const char *filetype;
|
||||
int address = 0;
|
||||
|
||||
/* magic lowrom at offset 7: $43 $42 $4d */
|
||||
/* if at offset 6 stands 1 it will immediatly jumped to offset 0 (0x8000) */
|
||||
static const unsigned char magic[] = {0x43, 0x42, 0x4d};
|
||||
unsigned char buffer[sizeof (magic)];
|
||||
|
||||
image.fseek(7, SEEK_SET);
|
||||
image.fread( buffer, sizeof (magic));
|
||||
image.fseek(0, SEEK_SET);
|
||||
|
||||
/* Check if our cart has the magic string, and set its loading address */
|
||||
if (!memcmp(buffer, magic, sizeof (magic)))
|
||||
address = 0x20000;
|
||||
|
||||
/* Give a loading address to non .bin / non .rom carts as well */
|
||||
filetype = image.filetype();
|
||||
|
||||
/* We would support .hi and .lo files, but currently I'm not sure where to load them.
|
||||
We simply load them at 0x20000 at this stage, even if it's probably wrong!
|
||||
It could also well be that they both need to be loaded at the same time, but this
|
||||
is now impossible since I reduced to 1 the number of cart slots.
|
||||
More investigations are in order if any .hi, .lo dump would surface! */
|
||||
if (!mame_stricmp(filetype, "hi"))
|
||||
address = 0x20000; /* FIX ME! */
|
||||
|
||||
else if (!mame_stricmp(filetype, "lo"))
|
||||
address = 0x20000; /* FIX ME! */
|
||||
|
||||
/* As a last try, give a reasonable loading address also to .bin/.rom without the magic string */
|
||||
else if (!address)
|
||||
{
|
||||
logerror("Cart %s does not contain the magic string: it may be loaded at the wrong memory address!\n", image.filename());
|
||||
address = 0x20000;
|
||||
}
|
||||
|
||||
logerror("Loading cart %s at %.5x size:%.4x\n", image.filename(), address, size);
|
||||
|
||||
/* Finally load the cart */
|
||||
test = image.fread( mem + address, size);
|
||||
|
||||
if (test != size)
|
||||
return IMAGE_INIT_FAIL;
|
||||
|
||||
return IMAGE_INIT_PASS;
|
||||
}
|
||||
|
||||
static DEVICE_IMAGE_LOAD( c16_cart )
|
||||
{
|
||||
int result = IMAGE_INIT_PASS;
|
||||
|
||||
if (image.software_entry() != NULL)
|
||||
{
|
||||
plus4_software_list_cartridge_load(image);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = plus4_crt_load(image);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
MACHINE_CONFIG_FRAGMENT( c16_cartslot )
|
||||
MCFG_CARTSLOT_ADD("cart")
|
||||
MCFG_CARTSLOT_EXTENSION_LIST("bin,rom,hi,lo")
|
||||
MCFG_CARTSLOT_NOT_MANDATORY
|
||||
MCFG_CARTSLOT_INTERFACE("plus4_cart")
|
||||
MCFG_CARTSLOT_LOAD(c16_cart)
|
||||
MCFG_SOFTWARE_LIST_ADD("cart_list", "plus4_cart")
|
||||
MACHINE_CONFIG_END
|
@ -1,119 +0,0 @@
|
||||
/***************************************************************************
|
||||
|
||||
machine.c
|
||||
|
||||
Functions to emulate general aspects of the machine (RAM, ROM, interrupts,
|
||||
I/O ports)
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "cpu/z80/z80.h"
|
||||
#include "imagedev/snapquik.h"
|
||||
#include "includes/jupiter.h"
|
||||
|
||||
|
||||
|
||||
/* Load in .ace files. These are memory images of 0x2000 to 0x7fff
|
||||
and compressed as follows:
|
||||
|
||||
ED 00 : End marker
|
||||
ED <cnt> <byt> : repeat <byt> count <cnt:1-240> times
|
||||
<byt> : <byt>
|
||||
*/
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
Snapshot Handling
|
||||
******************************************************************************/
|
||||
|
||||
SNAPSHOT_LOAD(jupiter)
|
||||
{
|
||||
UINT8 *RAM = image.device().machine().root_device().memregion("maincpu")->base();
|
||||
device_t *cpu = image.device().machine().device("maincpu");
|
||||
address_space *space = image.device().machine().device("maincpu")->memory().space(AS_PROGRAM);
|
||||
unsigned char jupiter_repeat, jupiter_byte, loop;
|
||||
int done=0, jupiter_index=0x2000;
|
||||
|
||||
if (space->machine().root_device().ioport("CFG")->read()==0)
|
||||
{
|
||||
image.seterror(IMAGE_ERROR_INVALIDIMAGE, "At least 16KB RAM expansion required");
|
||||
image.message("At least 16KB RAM expansion required");
|
||||
return IMAGE_INIT_FAIL;
|
||||
}
|
||||
|
||||
logerror("Loading file %s.\r\n", image.filename());
|
||||
while (!done && (jupiter_index < 0x8001))
|
||||
{
|
||||
image.fread( &jupiter_byte, 1);
|
||||
if (jupiter_byte == 0xed)
|
||||
{
|
||||
image.fread(&jupiter_byte, 1);
|
||||
switch (jupiter_byte)
|
||||
{
|
||||
case 0x00:
|
||||
logerror("File loaded!\r\n");
|
||||
done = 1;
|
||||
break;
|
||||
case 0x01:
|
||||
image.fread(&jupiter_byte, 1);
|
||||
RAM[jupiter_index++] = jupiter_byte;
|
||||
break;
|
||||
default:
|
||||
image.fread(&jupiter_repeat, 1);
|
||||
for (loop = 0; loop < jupiter_byte; loop++)
|
||||
RAM[jupiter_index++] = jupiter_repeat;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
RAM[jupiter_index++] = jupiter_byte;
|
||||
}
|
||||
|
||||
logerror("Decoded %X bytes.\r\n", jupiter_index-0x2000);
|
||||
|
||||
if (!done)
|
||||
{
|
||||
image.seterror(IMAGE_ERROR_INVALIDIMAGE, "EOF marker not found");
|
||||
image.message("EOF marker not found");
|
||||
return IMAGE_INIT_FAIL;
|
||||
}
|
||||
|
||||
// patch CPU registers
|
||||
// Some games do not follow the standard, and have rubbish in the CPU area. So,
|
||||
// we check that some other bytes are correct.
|
||||
// 2080 = memory size of original machine, should be 0000 or 8000 or C000.
|
||||
// 2118 = new stack pointer, do not use if between 8000 and FF00.
|
||||
|
||||
jupiter_index = RAM[0x2080] | (RAM[0x2081] << 8);
|
||||
|
||||
if ((jupiter_index & 0x3FFF)==0)
|
||||
{
|
||||
cpu_set_reg(cpu, Z80_AF, RAM[0x2100] | (RAM[0x2101] << 8));
|
||||
cpu_set_reg(cpu, Z80_BC, RAM[0x2104] | (RAM[0x2105] << 8));
|
||||
cpu_set_reg(cpu, Z80_DE, RAM[0x2108] | (RAM[0x2109] << 8));
|
||||
cpu_set_reg(cpu, Z80_HL, RAM[0x210c] | (RAM[0x210d] << 8));
|
||||
cpu_set_reg(cpu, Z80_IX, RAM[0x2110] | (RAM[0x2111] << 8));
|
||||
cpu_set_reg(cpu, Z80_IY, RAM[0x2114] | (RAM[0x2115] << 8));
|
||||
cpu_set_reg(cpu, STATE_GENPC, RAM[0x211c] | (RAM[0x211d] << 8));
|
||||
cpu_set_reg(cpu, Z80_AF2, RAM[0x2120] | (RAM[0x2121] << 8));
|
||||
cpu_set_reg(cpu, Z80_BC2, RAM[0x2124] | (RAM[0x2125] << 8));
|
||||
cpu_set_reg(cpu, Z80_DE2, RAM[0x2128] | (RAM[0x2129] << 8));
|
||||
cpu_set_reg(cpu, Z80_HL2, RAM[0x212c] | (RAM[0x212d] << 8));
|
||||
cpu_set_reg(cpu, Z80_IM, RAM[0x2130]);
|
||||
cpu_set_reg(cpu, Z80_IFF1, RAM[0x2134]);
|
||||
cpu_set_reg(cpu, Z80_IFF2, RAM[0x2138]);
|
||||
cpu_set_reg(cpu, Z80_I, RAM[0x213c]);
|
||||
cpu_set_reg(cpu, Z80_R, RAM[0x2140]);
|
||||
|
||||
if ((RAM[0x2119] < 0x80) || !jupiter_index)
|
||||
cpu_set_reg(cpu, STATE_GENSP, RAM[0x2118] | (RAM[0x2119] << 8));
|
||||
}
|
||||
|
||||
/* Copy data to the address space */
|
||||
for (jupiter_index = 0x2000; jupiter_index < 0x8000; jupiter_index++)
|
||||
space->write_byte(jupiter_index, RAM[jupiter_index]);
|
||||
|
||||
return IMAGE_INIT_PASS;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,34 +0,0 @@
|
||||
|
||||
#ifndef __TI85SERIAL_H_
|
||||
#define __TI85SERIAL_H_
|
||||
|
||||
|
||||
DECLARE_LEGACY_IMAGE_DEVICE(TI85SERIAL, ti85serial);
|
||||
DECLARE_LEGACY_IMAGE_DEVICE(TI73SERIAL, ti73serial);
|
||||
DECLARE_LEGACY_IMAGE_DEVICE(TI82SERIAL, ti82serial);
|
||||
DECLARE_LEGACY_IMAGE_DEVICE(TI83PSERIAL, ti83pserial);
|
||||
DECLARE_LEGACY_IMAGE_DEVICE(TI86SERIAL, ti86serial);
|
||||
|
||||
extern void ti85_update_serial(device_t *device);
|
||||
|
||||
#define MCFG_TI85SERIAL_ADD( _tag ) \
|
||||
MCFG_DEVICE_ADD( _tag, TI85SERIAL, 0 )
|
||||
|
||||
#define MCFG_TI73SERIAL_ADD( _tag ) \
|
||||
MCFG_DEVICE_ADD( _tag, TI73SERIAL, 0 )
|
||||
|
||||
#define MCFG_TI82SERIAL_ADD( _tag ) \
|
||||
MCFG_DEVICE_ADD( _tag, TI82SERIAL, 0 )
|
||||
|
||||
#define MCFG_TI83PSERIAL_ADD( _tag ) \
|
||||
MCFG_DEVICE_ADD( _tag, TI83PSERIAL, 0 )
|
||||
|
||||
#define MCFG_TI86SERIAL_ADD( _tag ) \
|
||||
MCFG_DEVICE_ADD( _tag, TI86SERIAL, 0 )
|
||||
|
||||
WRITE8_DEVICE_HANDLER( ti85serial_red_out );
|
||||
WRITE8_DEVICE_HANDLER( ti85serial_white_out );
|
||||
READ8_DEVICE_HANDLER( ti85serial_red_in );
|
||||
READ8_DEVICE_HANDLER( ti85serial_white_in );
|
||||
|
||||
#endif
|
@ -303,7 +303,6 @@ DRVLIBS += \
|
||||
$(MESSOBJ)/hp.a \
|
||||
$(MESSOBJ)/intel.a \
|
||||
$(MESSOBJ)/intelgnt.a \
|
||||
$(MESSOBJ)/interact.a \
|
||||
$(MESSOBJ)/interton.a \
|
||||
$(MESSOBJ)/intv.a \
|
||||
$(MESSOBJ)/kaypro.a \
|
||||
@ -1177,11 +1176,7 @@ $(MESSOBJ)/hec2hrp.a: \
|
||||
$(MESS_VIDEO)/hec2video.o \
|
||||
$(MESS_MACHINE)/hecdisk2.o \
|
||||
$(MESS_MACHINE)/hec2hrp.o \
|
||||
|
||||
$(MESSOBJ)/interact.a: \
|
||||
$(MESS_DRIVERS)/interact.o \
|
||||
$(MESS_VIDEO)/hec2video.o \
|
||||
$(MESS_MACHINE)/hec2hrp.o \
|
||||
|
||||
$(MESSOBJ)/intel.a: \
|
||||
$(MESS_DRIVERS)/basic52.o \
|
||||
@ -1556,7 +1551,6 @@ $(MESSOBJ)/sega.a: \
|
||||
$(MESS_MACHINE)/dccons.o \
|
||||
$(MESS_MACHINE)/sms.o \
|
||||
$(MESS_DRIVERS)/sms.o \
|
||||
$(MESS_DRIVERS)/sg1000.o \
|
||||
|
||||
$(MESSOBJ)/sgi.a: \
|
||||
$(MESS_MACHINE)/sgi.o \
|
||||
|
Loading…
Reference in New Issue
Block a user