1
0
mirror of https://github.com/simh/simh.git synced 2026-02-11 02:31:35 +00:00

Merge of Bob's simh-v3.9-0-rc3

This commit is contained in:
Mark Pizzolato
2012-04-23 11:50:43 -07:00
parent 19ae16ac6e
commit db9bf32112
62 changed files with 5342 additions and 3796 deletions

231
swtp6800/common/bootrom.c Normal file
View File

@@ -0,0 +1,231 @@
/* bootrom.c: Boot ROM simulator for Motorola processors
Copyright (c) 2010-2011, William A. Beech
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
WILLIAM A. BEECH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of William A. Beech shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from William A. Beech.
These functions support a single simulated 2704 to 2764 EPROM device on
an 8-bit computer system.. This device allows the the device buffer to
be loaded from a binary file containing the emulated EPROM code.
These functions support a simulated 2704, 2708, 2716, 2732 or 2764 EPROM
device on a CPU board. The byte get and put routines use an offset into
the boot EPROM image to locate the proper byte. This allows another device
to set the base address for the boot EPROM. The device type is stored as
a binary number in the first three unit flag bits.
This device uses a dynamically allocated buffer to hold the EPROM image.
A call to BOOTROM_config will free the current buffer. A call to
BOOTROM_reset will allocate a new buffer of BOOTROM_unit.capac bytes. A
call to BOOTROM_attach will load the buffer with the EPROM image.
*/
#include <stdio.h>
#include "swtp_defs.h"
#define UNIT_V_MSIZE (UNIT_V_UF) /* ROM Size */
#define UNIT_MSIZE (0x7 << UNIT_V_MSIZE)
#define UNIT_NONE (0 << UNIT_V_MSIZE) /* No EPROM */
#define UNIT_2704 (1 << UNIT_V_MSIZE) /* 2704 mode */
#define UNIT_2708 (2 << UNIT_V_MSIZE) /* 2708 mode */
#define UNIT_2716 (3 << UNIT_V_MSIZE) /* 2716 mode */
#define UNIT_2732 (4 << UNIT_V_MSIZE) /* 2732 mode */
#define UNIT_2764 (5 << UNIT_V_MSIZE) /* 2764 mode */
/* function prototypes */
t_stat BOOTROM_svc (UNIT *uptr);
t_stat BOOTROM_config (UNIT *uptr, int32 val, char *cptr, void *desc);
t_stat BOOTROM_attach (UNIT *uptr, char *cptr);
t_stat BOOTROM_reset (DEVICE *dptr);
int32 BOOTROM_get_mbyte(int32 offset);
/* SIMH Standard I/O Data Structures */
UNIT BOOTROM_unit = { UDATA (NULL,
UNIT_ATTABLE+UNIT_BINK+UNIT_ROABLE+UNIT_RO, 0),
KBD_POLL_WAIT };
MTAB BOOTROM_mod[] = {
{ UNIT_MSIZE, UNIT_NONE, "None", "NONE", &BOOTROM_config },
{ UNIT_MSIZE, UNIT_2704, "2704", "2704", &BOOTROM_config },
{ UNIT_MSIZE, UNIT_2708, "2708", "2708", &BOOTROM_config },
{ UNIT_MSIZE, UNIT_2716, "2716", "2716", &BOOTROM_config },
{ UNIT_MSIZE, UNIT_2732, "2732", "2732", &BOOTROM_config },
{ UNIT_MSIZE, UNIT_2764, "2764", "2764", &BOOTROM_config },
{ 0 }
};
DEBTAB BOOTROM_debug[] = {
{ "ALL", DEBUG_all },
{ "FLOW", DEBUG_flow },
{ "READ", DEBUG_read },
{ "WRITE", DEBUG_write },
{ "LEV1", DEBUG_level1 },
{ "LEV2", DEBUG_level2 },
{ NULL }
};
DEVICE BOOTROM_dev = {
"BOOTROM", /* name */
&BOOTROM_unit, /* units */
NULL, /* registers */
BOOTROM_mod, /* modifiers */
1, /* numunits */
16, /* aradix */
32, /* awidth */
1, /* aincr */
16, /* dradix */
8, /* dwidth */
NULL, /* examine */
NULL, /* deposit */
&BOOTROM_reset, /* reset */
NULL, /* boot */
&BOOTROM_attach, /* attach */
NULL, /* detach */
NULL, /* ctxt */
DEV_DEBUG, /* flags */
0, /* dctrl */
BOOTROM_debug, /* debflags */
NULL, /* msize */
NULL /* lname */
};
/* global variables */
/* BOOTROM_attach - attach file to EPROM unit */
t_stat BOOTROM_attach (UNIT *uptr, char *cptr)
{
t_stat r;
if (BOOTROM_dev.dctrl & DEBUG_flow)
printf("BOOTROM_attach: cptr=%s\n", cptr);
if ((r = attach_unit (uptr, cptr)) != SCPE_OK) {
if (BOOTROM_dev.dctrl & DEBUG_flow)
printf("BOOTROM_attach: Error\n");
return r;
}
if (BOOTROM_dev.dctrl & DEBUG_flow)
printf("BOOTROM_attach: Done\n");
return (BOOTROM_reset (NULL));
}
/* BOOTROM_config = None, 2704, 2708, 2716, 2732 or 2764 */
t_stat BOOTROM_config (UNIT *uptr, int32 val, char *cptr, void *desc)
{
if (BOOTROM_dev.dctrl & DEBUG_flow) /* entry message */
printf("BOOTROM_config: val=%d\n", val);
if ((val < UNIT_NONE) || (val > UNIT_2764)) { /* valid param? */
if (BOOTROM_dev.dctrl & DEBUG_flow) /* No */
printf("BOOTROM_config: Parameter error\n");
return SCPE_ARG;
}
if (val == UNIT_NONE)
BOOTROM_unit.capac = 0; /* set EPROM size */
else
BOOTROM_unit.capac = 0x200 << ((val >> UNIT_V_MSIZE) - 1); /* set EPROM size */
if (BOOTROM_unit.filebuf) { /* free buffer */
free (BOOTROM_unit.filebuf);
BOOTROM_unit.filebuf = NULL;
}
if (BOOTROM_dev.dctrl & DEBUG_flow) /* status message */
printf("BOOTROM_config: BOOTROM_unit.capac=%d\n",
BOOTROM_unit.capac);
if (BOOTROM_dev.dctrl & DEBUG_flow) /* exit message */
printf("BOOTROM_config: Done\n");
return SCPE_OK;
}
/* EPROM reset */
t_stat BOOTROM_reset (DEVICE *dptr)
{
t_addr j;
int c;
FILE *fp;
if (BOOTROM_dev.dctrl & DEBUG_flow)
printf("BOOTROM_reset: \n");
if ((BOOTROM_unit.flags & UNIT_MSIZE) == 0) { /* if none selected */
// printf(" EPROM: Defaulted to None\n");
// printf(" \"set eprom NONE | 2704 | 2708 | 2716 | 2732 | 2764\"\n");
// printf(" \"att eprom <filename>\"\n");
BOOTROM_unit.capac = 0; /* set EPROM size to 0 */
if (BOOTROM_dev.dctrl & DEBUG_flow)
printf("BOOTROM_reset: Done1\n");
return SCPE_OK;
} /* if attached */
// printf(" EPROM: Initializing [%04X-%04XH]\n",
// 0xE000, 0xE000 + BOOTROM_unit.capac - 1);
if (BOOTROM_unit.filebuf == NULL) { /* no buffer allocated */
BOOTROM_unit.filebuf = malloc(BOOTROM_unit.capac); /* allocate EPROM buffer */
if (BOOTROM_unit.filebuf == NULL) {
if (BOOTROM_dev.dctrl & DEBUG_flow)
printf("BOOTROM_reset: Malloc error\n");
return SCPE_MEM;
}
}
fp = fopen(BOOTROM_unit.filename, "rb"); /* open EPROM file */
if (fp == NULL) {
printf("\tUnable to open ROM file %s\n",BOOTROM_unit.filename);
printf("\tNo ROM image loaded!!!\n");
return SCPE_OK;
}
j = 0; /* load EPROM file */
c = fgetc(fp);
while (c != EOF) {
*((uint8 *)(BOOTROM_unit.filebuf) + j++) = c & 0xFF;
c = fgetc(fp);
if (j > BOOTROM_unit.capac) {
printf("\tImage is too large - Load truncated!!!\n");
break;
}
}
fclose(fp);
// printf("\t%d bytes of ROM image %s loaded\n", j, BOOTROM_unit.filename);
if (BOOTROM_dev.dctrl & DEBUG_flow)
printf("BOOTROM_reset: Done2\n");
return SCPE_OK;
}
/* get a byte from memory - byte offset of image */
int32 BOOTROM_get_mbyte(int32 offset)
{
int32 val;
if (BOOTROM_unit.filebuf == NULL) {
if (BOOTROM_dev.dctrl & DEBUG_read)
printf("BOOTROM_get_mbyte: EPROM not configured\n");
return 0xFF;
}
if (BOOTROM_dev.dctrl & DEBUG_read)
printf("BOOTROM_get_mbyte: offset=%04X\n", offset);
val = *((uint8 *)(BOOTROM_unit.filebuf) + offset) & 0xFF;
if (BOOTROM_dev.dctrl & DEBUG_read)
printf("BOOTROM_get_mbyte: Normal val=%02X\n", val);
return val;
}
/* end of bootrom.c */

570
swtp6800/common/dc-4.c Normal file
View File

@@ -0,0 +1,570 @@
/* dc4.c: SWTP DC-4 FDC Simulator
Copyright (c) 2005-2011, William A. Beech
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
WILLIAM A BEECH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of William A. Beech shall not
be used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from William A. Beech.
The DC-4 is a 5-inch floppy controller which can control up
to 4 daisy-chained 5-inch floppy drives. The controller is based on
the Western Digital 1797 Floppy Disk Controller (FDC) chip. This
file only emulates the minimum DC-4 functionality to interface with
the virtual disk file.
The floppy controller is interfaced to the CPU by use of 5 memory
addreses. These are SS-30 slot numbers 5 and 6 (0x8014-0x801B).
Address Mode Function
------- ---- --------
0x8014 Read Returns FDC interrupt status
0x8014 Write Selects the drive/head/motor control
0x8018 Read Returns status of FDC
0x8018 Write FDC command register
0x8019 Read Returns FDC track register
0x8019 Write Set FDC track register
0x801A Read Returns FDC sector register
0x801A Write Set FDC sector register
0x801B Read Read data
0x801B Write Write data
Drive Select Read (0x8014):
+---+---+---+---+---+---+---+---+
| I | D | X | X | X | X | X | X |
+---+---+---+---+---+---+---+---+
I = Set indicates an interrupt request from the FDC pending.
D = DRQ pending - same as bit 1 of FDC status register.
Drive Select Write (0x8014):
+---+---+---+---+---+---+---+---+
| M | S | X | X | X | X | Device|
+---+---+---+---+---+---+---+---+
M = If this bit is 1, the one-shot is triggered/retriggered to
start/keep the motors on.
S = Side select. If set, side one is selected otherwise side zero
is selected.
X = not used
Device = value 0 thru 3, selects drive 0-3 to be controlled.
Drive Status Read (0x8018):
+---+---+---+---+---+---+---+---+
| R | P | H | S | C | L | D | B |
+---+---+---+---+---+---+---+---+
B - When 1, the controller is busy.
D - When 1, index mark detected (type I) or data request - read data
ready/write data empty (type II or III).
H - When 1, track 0 (type I) or lost data (type II or III).
C - When 1, crc error detected.
S - When 1, seek (type I) or RNF (type II or III) error.
H - When 1, head is currently loaded (type I) or record type/
write fault (type II or III).
P - When 1, indicates that diskette is write-protected.
R - When 1, drive is not ready.
Drive Control Write (0x8018) for type I commands:
+---+---+---+---+---+---+---+---+
| 0 | S2| S1| S0| H | V | R1| R0|
+---+---+---+---+---+---+---+---+
R0/R1 - Selects the step rate.
V - When 1, verify on destination track.
H - When 1, loads head to drive surface.
S0/S1/S2 = 000 - home.
001 - seek track in data register.
010 - step without updating track register.
011 - step and update track register.
100 - step in without updating track register.
101 - step in and update track register.
110 - step out without updating track register.
111 - step out and update track register.
Drive Control Write (0x8018) for type II commands:
+---+---+---+---+---+---+---+---+
| 1 | 0 | T | M | S | E | B | A |
+---+---+---+---+---+---+---+---+
A - Zero for read, 1 on write deleted data mark else data mark.
B - When 1, shifts sector length field definitions one place.
E - When, delay operation 15 ms, 0 no delay.
S - When 1, select side 1, 0 select side 0.
M - When 1, multiple records, 0 for single record.
T - When 1, write command, 0 for read.
Drive Control Write (0x8018) for type III commands:
+---+---+---+---+---+---+---+---+
| 1 | 1 | T0| T1| 0 | E | 0 | 0 |
+---+---+---+---+---+---+---+---+
E - When, delay operation 15 ms, 0 no delay.
T0/T1 - 00 - read address command.
10 - read track command.
11 - write track command.
Tracks are numbered from 0 up to one minus the last track in the 1797!
Track Register Read (0x8019):
+---+---+---+---+---+---+---+---+
| Track Number |
+---+---+---+---+---+---+---+---+
Reads the current 8-bit value from the track position.
Track Register Write (0x8019):
+---+---+---+---+---+---+---+---+
| Track Number |
+---+---+---+---+---+---+---+---+
Writes the 8-bit value to the track register.
Sectors are numbers from 1 up to the last sector in the 1797!
Sector Register Read (0x801A):
+---+---+---+---+---+---+---+---+
| Sector Number |
+---+---+---+---+---+---+---+---+
Reads the current 8-bit value from the sector position.
Sector Register Write (0x801A):
+---+---+---+---+---+---+---+---+
| Sector Number |
+---+---+---+---+---+---+---+---+
Writes the 8-bit value to the sector register.
Data Register Read (0x801B):
+---+---+---+---+---+---+---+---+
| Data |
+---+---+---+---+---+---+---+---+
Reads the current 8-bit value from the data register.
Data Register Write (0x801B):
+---+---+---+---+---+---+---+---+
| Data |
+---+---+---+---+---+---+---+---+
Writes the 8-bit value to the data register.
A FLEX disk is defined as follows:
Track Sector Use
0 1 Boot sector
0 2 Boot sector (cont)
0 3 Unused
0 4 System Identity Record (explained below)
0 5 Unused
0 6-last Directory - 10 entries/sector (explained below)
1 1 First available data sector
last-1 last Last available data sector
System Identity Record
Byte Use
0x00 Two bytes of zeroes (Clears forward link)
0x10 Volume name in ASCII(11 bytes)
0x1B Volume number in binary (2 bytes)
0x1D Address of first free data sector (Track-Sector) (2 bytes)
0x1F Address of last free data sector (Track-Sector) (2 bytes)
0x21 Total number of data sectors in binary (2 bytes)
0x23 Current date (Month-Day-Year) in binary
0x26 Highest track number on disk in binary (byte)
0x27 Highest sector number on a track in binary (byte)
The following unit registers are used by this controller emulation:
dsk_unit[cur_drv].u3 unit current flags
dsk_unit[cur_drv].u4 unit current track
dsk_unit[cur_drv].u5 unit current sector
dsk_unit[cur_drv].pos unit current sector byte index into buffer
dsk_unit[cur_drv].filebuf unit current sector buffer
dsk_unit[cur_drv].fileref unit current attached file reference
*/
#include <stdio.h>
#include "swtp_defs.h"
#define DEBUG 0
#define UNIT_V_ENABLE (UNIT_V_UF + 0) /* Write Enable */
#define UNIT_ENABLE (1 << UNIT_V_ENABLE)
/* emulate a SS FLEX disk with 72 sectors and 80 tracks */
#define NUM_DISK 4 /* standard 1797 maximum */
#define SECT_SIZE 256 /* standard FLEX sector */
#define NUM_SECT 72 /* sectors/track */
#define TRAK_SIZE (SECT_SIZE * NUM_SECT) /* trk size (bytes) */
#define HEADS 1 /* handle as SS with twice the sectors */
#define NUM_CYL 80 /* maximum tracks */
#define DSK_SIZE (NUM_SECT * HEADS * NUM_CYL * SECT_SIZE) /* dsk size (bytes) */
#define SECSIZ 256 /* standard FLEX sector */
/* SIR offsets */
#define MAXCYL 0x26 /* last cylinder # */
#define MAXSEC 0x27 /* last sector # */
/* 1797 status bits */
#define BUSY 0x01
#define DRQ 0x02
#define WRPROT 0x40
#define NOTRDY 0x80
/* function prototypes */
t_stat dsk_reset (DEVICE *dptr);
/* SS-50 I/O address space functions */
int32 fdcdrv(int32 io, int32 data);
int32 fdccmd(int32 io, int32 data);
int32 fdctrk(int32 io, int32 data);
int32 fdcsec(int32 io, int32 data);
int32 fdcdata(int32 io, int32 data);
/* Local Variables */
int32 fdcbyte;
int32 intrq = 0; /* interrupt request flag */
int32 cur_dsk; /* Currently selected drive */
int32 wrt_flag = 0; /* FDC write flag */
int32 spt; /* sectors/track */
int32 trksiz; /* trk size (bytes) */
int32 heds; /* number of heads */
int32 cpd; /* cylinders/disk */
int32 dsksiz; /* dsk size (bytes) */
/* Floppy Disk Controller data structures
dsk_dev Mother Board device descriptor
dsk_unit Mother Board unit descriptor
dsk_reg Mother Board register list
dsk_mod Mother Board modifiers list
*/
UNIT dsk_unit[] = {
{ UDATA (NULL, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE, 0) },
{ UDATA (NULL, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE, 0) },
{ UDATA (NULL, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE, 0) },
{ UDATA (NULL, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE, 0) }
};
REG dsk_reg[] = {
{ HRDATA (DISK, cur_dsk, 4) },
{ NULL }
};
MTAB dsk_mod[] = {
{ UNIT_ENABLE, UNIT_ENABLE, "RW", "RW", NULL },
{ UNIT_ENABLE, 0, "RO", "RO", NULL },
{ 0 }
};
DEBTAB dsk_debug[] = {
{ "ALL", DEBUG_all },
{ "FLOW", DEBUG_flow },
{ "READ", DEBUG_read },
{ "WRITE", DEBUG_write },
{ "LEV1", DEBUG_level1 },
{ "LEV2", DEBUG_level2 },
{ NULL }
};
DEVICE dsk_dev = {
"DC-4", //name
dsk_unit, //units
dsk_reg, //registers
dsk_mod, //modifiers
4, //numunits
16, //aradix
16, //awidth
1, //aincr
16, //dradix
8, //dwidth
NULL, //examine
NULL, //deposit
&dsk_reset, //reset
NULL, //boot
NULL, //attach
NULL, //detach
NULL, //ctxt
DEV_DEBUG, //flags
0, //dctrl
dsk_debug, /* debflags */
NULL, //msize
NULL //lname
};
/* Reset routine */
t_stat dsk_reset (DEVICE *dptr)
{
int i;
cur_dsk = 5; /* force initial SIR read */
for (i=0; i<NUM_DISK; i++) {
dsk_unit[i].u3 = 0; /* clear current flags */
dsk_unit[i].u4 = 0; /* clear current cylinder # */
dsk_unit[i].u5 = 0; /* clear current sector # */
dsk_unit[i].pos = 0; /* clear current byte ptr */
if (dsk_unit[i].filebuf == NULL) {
dsk_unit[i].filebuf = malloc(256); /* allocate buffer */
if (dsk_unit[i].filebuf == NULL) {
printf("dc-4_reset: Malloc error\n");
return SCPE_MEM;
}
}
}
spt = 0;
trksiz = 0;
heds = 0;
cpd = 0;
dsksiz = 0;
return SCPE_OK;
}
/* I/O instruction handlers, called from the MP-B2 module when a
read or write occur to addresses 0x8004-0x8007. */
/* DC-4 drive select register routine - this register is not part of the 1797
*/
int32 fdcdrv(int32 io, int32 data)
{
static long pos;
if (io) { /* write to DC-4 drive register */
if (dsk_dev.dctrl & DEBUG_write)
printf("\nfdcdrv: Drive selected %d cur_dsk=%d", data & 0x03, cur_dsk);
if (cur_dsk == (data & 0x03))
return 0; /* already selected */
cur_dsk = data & 0x03; /* only 2 drive select bits */
if (dsk_dev.dctrl & DEBUG_write)
printf("\nfdcdrv: Drive set to %d", cur_dsk);
if ((dsk_unit[cur_dsk].flags & UNIT_ENABLE) == 0) {
dsk_unit[cur_dsk].u3 |= WRPROT; /* set 1797 WPROT */
if (dsk_dev.dctrl & DEBUG_write)
printf("\nfdcdrv: Drive write protected");
} else {
dsk_unit[cur_dsk].u3 &= ~WRPROT; /* set 1797 not WPROT */
if (dsk_dev.dctrl & DEBUG_write)
printf("\nfdcdrv: Drive NOT write protected");
}
pos = 0x200; /* Read in SIR */
if (dsk_dev.dctrl & DEBUG_read)
printf("\nfdcdrv: Read pos = %ld ($%04X)", pos, (unsigned int) pos);
sim_fseek(dsk_unit[cur_dsk].fileref, pos, 0); /* seek to offset */
sim_fread(dsk_unit[cur_dsk].filebuf, SECSIZ, 1, dsk_unit[cur_dsk].fileref); /* read in buffer */
dsk_unit[cur_dsk].u3 |= BUSY | DRQ; /* set DRQ & BUSY */
dsk_unit[cur_dsk].pos = 0; /* clear counter */
spt = *((uint8 *)(dsk_unit[cur_dsk].filebuf) + MAXSEC) & 0xFF;
heds = 0;
cpd = *((uint8 *)(dsk_unit[cur_dsk].filebuf) + MAXCYL) & 0xFF;
trksiz = spt * SECSIZ;
dsksiz = trksiz * cpd;
if (dsk_dev.dctrl & DEBUG_read)
printf("\nfdcdrv: spt=%d heds=%d cpd=%d trksiz=%d dsksiz=%d flags=%08X u3=%08X",
spt, heds, cpd, trksiz, dsksiz, dsk_unit[cur_dsk].flags, dsk_unit[cur_dsk].u3);
return 0;
} else { /* read from DC-4 drive register */
if (dsk_dev.dctrl & DEBUG_read)
printf("\nfdcdrv: Drive read as %02X", intrq);
return intrq;
}
}
/* WD 1797 FDC command register routine */
int32 fdccmd(int32 io, int32 data)
{
static int32 val = 0, val1 = NOTRDY;
static long pos;
if ((dsk_unit[cur_dsk].flags & UNIT_ATT) == 0) { /* not attached */
dsk_unit[cur_dsk].u3 |= NOTRDY; /* set not ready flag */
if (dsk_dev.dctrl & DEBUG_flow)
printf("\nfdccmd: Drive %d is not attached", cur_dsk);
return 0;
} else {
dsk_unit[cur_dsk].u3 &= ~NOTRDY; /* clear not ready flag */
}
if (io) { /* write command to fdc */
switch(data) {
case 0x8C: /* read command */
case 0x9C:
if (dsk_dev.dctrl & DEBUG_read)
printf("\nfdccmd: Read of disk %d, track %d, sector %d",
cur_dsk, dsk_unit[cur_dsk].u4, dsk_unit[cur_dsk].u5);
pos = trksiz * dsk_unit[cur_dsk].u4; /* calculate file offset */
pos += SECSIZ * (dsk_unit[cur_dsk].u5 - 1);
if (dsk_dev.dctrl & DEBUG_read)
printf("\nfdccmd: Read pos = %ld ($%08X)", pos, (unsigned int) pos);
sim_fseek(dsk_unit[cur_dsk].fileref, pos, 0); /* seek to offset */
sim_fread(dsk_unit[cur_dsk].filebuf, SECSIZ, 1, dsk_unit[cur_dsk].fileref); /* read in buffer */
dsk_unit[cur_dsk].u3 |= BUSY | DRQ; /* set DRQ & BUSY */
dsk_unit[cur_dsk].pos = 0; /* clear counter */
break;
case 0xAC: /* write command */
if (dsk_dev.dctrl & DEBUG_write)
printf("\nfdccmd: Write of disk %d, track %d, sector %d",
cur_dsk, dsk_unit[cur_dsk].u4, dsk_unit[cur_dsk].u5);
if (dsk_unit[cur_dsk].u3 & WRPROT) {
printf("\nfdccmd: Drive %d is write-protected", cur_dsk);
} else {
pos = trksiz * dsk_unit[cur_dsk].u4; /* calculate file offset */
pos += SECSIZ * (dsk_unit[cur_dsk].u5 - 1);
if (dsk_dev.dctrl & DEBUG_write)
printf("\nfdccmd: Write pos = %ld ($%08X)", pos, (unsigned int) pos);
sim_fseek(dsk_unit[cur_dsk].fileref, pos, 0); /* seek to offset */
wrt_flag = 1; /* set write flag */
dsk_unit[cur_dsk].u3 |= BUSY | DRQ;/* set DRQ & BUSY */
dsk_unit[cur_dsk].pos = 0; /* clear counter */
}
break;
case 0x18: /* seek command */
case 0x1B:
dsk_unit[cur_dsk].u4 = fdcbyte; /* set track */
dsk_unit[cur_dsk].u3 &= ~(BUSY | DRQ); /* clear flags */
if (dsk_dev.dctrl & DEBUG_flow)
printf("\nfdccmd: Seek of disk %d, track %d", cur_dsk, fdcbyte);
break;
case 0x0B: /* restore command */
dsk_unit[cur_dsk].u4 = 0; /* home the drive */
dsk_unit[cur_dsk].u3 &= ~(BUSY | DRQ); /* clear flags */
if (dsk_dev.dctrl & DEBUG_flow)
printf("\nfdccmd: Drive %d homed", cur_dsk);
break;
case 0xF0: /* write track command */
if (dsk_dev.dctrl & DEBUG_write)
printf("\nfdccmd: Write track command for drive %d", cur_dsk);
break;
default:
printf("Unknown FDC command %02XH\n\r", data);
}
} else { /* read status from fdc */
val = dsk_unit[cur_dsk].u3; /* set return value */
/* either print below will force the val to 0x43 forever. timing problem in
the 6800 disk driver software? */
// if (dsk_dev.dctrl & DEBUG_flow)
// printf("\nfdccmd: Exit Drive %d status=%02X", cur_dsk, val);
// printf("\n%02X", val); //even this short fails it!
if (val1 == 0 && ((val & (BUSY + DRQ)) == (BUSY + DRQ))) /* delay BUSY going high */
val &= ~BUSY;
if (val != val1) /* now allow BUSY after one read */
val1 = val;
if (dsk_dev.dctrl & DEBUG_flow)
printf("\nfdccmd: Exit Drive %d status=%02X", cur_dsk, val);
}
return val;
}
/* WD 1797 FDC track register routine */
int32 fdctrk(int32 io, int32 data)
{
if (io) {
dsk_unit[cur_dsk].u4 = data & 0xFF;
if (dsk_dev.dctrl & DEBUG_read)
printf("\nfdctrk: Drive %d track set to %d", cur_dsk, dsk_unit[cur_dsk].u4);
} else
;
if (dsk_dev.dctrl & DEBUG_write)
printf("\nfdctrk: Drive %d track read as %d", cur_dsk, dsk_unit[cur_dsk].u4);
return dsk_unit[cur_dsk].u4;
}
/* WD 1797 FDC sector register routine */
int32 fdcsec(int32 io, int32 data)
{
if (io) {
dsk_unit[cur_dsk].u5 = data & 0xFF;
if (dsk_unit[cur_dsk].u5 == 0) /* fix for swtp boot! */
dsk_unit[cur_dsk].u5 = 1;
if (dsk_dev.dctrl & DEBUG_write)
printf("\nfdcsec: Drive %d sector set to %d", cur_dsk, dsk_unit[cur_dsk].u5);
} else
;
if (dsk_dev.dctrl & DEBUG_read)
printf("\nfdcsec: Drive %d sector read as %d", cur_dsk, dsk_unit[cur_dsk].u5);
return dsk_unit[cur_dsk].u5;
}
/* WD 1797 FDC data register routine */
int32 fdcdata(int32 io, int32 data)
{
int32 val;
if (io) { /* write byte to fdc */
fdcbyte = data; /* save for seek */
if (dsk_unit[cur_dsk].pos < SECSIZ) { /* copy bytes to buffer */
if (dsk_dev.dctrl & DEBUG_write)
printf("\nfdcdata: Writing byte %d of %02X", dsk_unit[cur_dsk].pos, data);
*((uint8 *)(dsk_unit[cur_dsk].filebuf) + dsk_unit[cur_dsk].pos) = data; /* byte into buffer */
dsk_unit[cur_dsk].pos++; /* step counter */
if (dsk_unit[cur_dsk].pos == SECSIZ) {
dsk_unit[cur_dsk].u3 &= ~(BUSY | DRQ);
if (wrt_flag) { /* if initiated by FDC write command */
sim_fwrite(dsk_unit[cur_dsk].filebuf, SECSIZ, 1, dsk_unit[cur_dsk].fileref); /* write it */
wrt_flag = 0; /* clear write flag */
}
if (dsk_dev.dctrl & DEBUG_write)
printf("\nfdcdata: Sector write complete");
}
}
return 0;
} else { /* read byte from fdc */
if (dsk_unit[cur_dsk].pos < SECSIZ) { /* copy bytes from buffer */
if (dsk_dev.dctrl & DEBUG_read)
printf("\nfdcdata: Reading byte %d u3=%02X", dsk_unit[cur_dsk].pos, dsk_unit[cur_dsk].u3);
val = *((uint8 *)(dsk_unit[cur_dsk].filebuf) + dsk_unit[cur_dsk].pos) & 0xFF;
dsk_unit[cur_dsk].pos++; /* step counter */
if (dsk_unit[cur_dsk].pos == SECSIZ) { /* done? */
dsk_unit[cur_dsk].u3 &= ~(BUSY | DRQ); /* clear flags */
if (dsk_dev.dctrl & DEBUG_write)
printf("\nfdcdata: Sector read complete");
}
return val;
} else
return 0;
}
}
/* end of dc-4.c */

221
swtp6800/common/i2716.c Normal file
View File

@@ -0,0 +1,221 @@
/* i2716.c: Intel 2716 EPROM simulator for 8-bit processors
Copyright (c) 2011, William A. Beech
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
WILLIAM A. BEECH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of William A. Beech shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from William A. Beech.
These functions support a simulated 2704 to 2764 EPROMs device on an 8-bit
computer system. This device allows the attachment of the device to a binary file
containing the EPROM code.
These functions support emulation of 0 to 4 2716 EPROM devices on a CPU board.
The byte get and put routines use an offset into the boot EPROM image to locate
the proper byte. This allows another device to set the base address for each
EPROM.
This device uses a dynamically allocated buffer to hold each EPROM image.
A call to BOOTROM_config will free the current buffer. A call to
i2716_reset will allocate a new buffer of 2048 bytes. A
call to BOOTROM_attach will load the buffer with the EPROM image.
*/
#include <stdio.h>
#include "swtp_defs.h"
#define I2716_NUM 4 /* number of 2716 EPROMS */
extern int32 get_base(void);
/* function prototypes */
t_stat i2716_attach (UNIT *uptr, char *cptr);
t_stat i2716_reset (DEVICE *dptr);
int32 i2716_get_mbyte(int32 offset);
/* SIMH EPROM Standard I/O Data Structures */
UNIT i2716_unit[] = {
{ UDATA (NULL,UNIT_ATTABLE+UNIT_ROABLE+UNIT_RO, 0), 0 },
{ UDATA (NULL,UNIT_ATTABLE+UNIT_ROABLE+UNIT_RO, 0), 0 },
{ UDATA (NULL,UNIT_ATTABLE+UNIT_ROABLE+UNIT_RO, 0), 0 },
{ UDATA (NULL,UNIT_ATTABLE+UNIT_ROABLE+UNIT_RO, 0), 0 }
};
MTAB i2716_mod[] = {
{ 0 }
};
DEBTAB i2716_debug[] = {
{ "ALL", DEBUG_all },
{ "FLOW", DEBUG_flow },
{ "READ", DEBUG_read },
{ "WRITE", DEBUG_write },
{ "LEV1", DEBUG_level1 },
{ "LEV2", DEBUG_level2 },
{ NULL }
};
DEVICE i2716_dev = {
"I2716", /* name */
i2716_unit, /* units */
NULL, /* registers */
i2716_mod, /* modifiers */
I2716_NUM, /* numunits */
16, /* aradix */
32, /* awidth */
1, /* aincr */
16, /* dradix */
8, /* dwidth */
NULL, /* examine */
NULL, /* deposit */
&i2716_reset, /* reset */
NULL, /* boot */
&i2716_attach, /* attach */
NULL, /* detach */
NULL, /* ctxt */
DEV_DEBUG, /* flags */
0, /* dctrl */
i2716_debug, /* debflags */
NULL, /* msize */
NULL /* lname */
};
/* global variables */
/* i2716_attach - attach file to EPROM unit
force EPROM reset at completion */
t_stat i2716_attach (UNIT *uptr, char *cptr)
{
int32 j, c;
t_stat r;
FILE *fp;
if (i2716_dev.dctrl & DEBUG_flow)
printf("i2716_attach: cptr=%s\n", cptr);
if ((r = attach_unit (uptr, cptr)) != SCPE_OK) {
if (i2716_dev.dctrl & DEBUG_flow)
printf("i2716_attach: Error\n");
return r;
}
if (i2716_dev.dctrl & DEBUG_read)
printf("\tOpen file\n");
fp = fopen(uptr->filename, "rb"); /* open EPROM file */
if (fp == NULL) {
printf("i2716%d: Unable to open ROM file %s\n", (int)(uptr - i2716_dev.units), uptr->filename);
printf("\tNo ROM image loaded!!!\n");
return SCPE_OK;
}
if (i2716_dev.dctrl & DEBUG_read)
printf("\tRead file\n");
j = 0; /* load EPROM file */
c = fgetc(fp);
while (c != EOF) {
*((uint8 *)(uptr->filebuf) + j++) = c & 0xFF;
c = fgetc(fp);
if (j > 2048) {
printf("\tImage is too large - Load truncated!!!\n");
break;
}
}
if (i2716_dev.dctrl & DEBUG_read)
printf("\tClose file\n");
fclose(fp);
// printf("i2716%d: %d bytes of ROM image %s loaded\n",uptr - i2716_dev.units, j, uptr->filename);
if (i2716_dev.dctrl & DEBUG_flow)
printf("i2716_attach: Done\n");
return SCPE_OK;
}
/* EPROM reset */
t_stat i2716_reset (DEVICE *dptr)
{
int32 i, base;
UNIT *uptr;
if (i2716_dev.dctrl & DEBUG_flow)
printf("i2716_reset: \n");
for (i = 0; i < I2716_NUM; i++) { /* init all units */
uptr = i2716_dev.units + i;
if (i2716_dev.dctrl & DEBUG_flow)
printf("i2716 %d unit.flags=%08X\n", i, uptr->flags);
uptr->capac = 2048;
uptr->u3 = 2048 * i;
base = get_base();
if (uptr->filebuf == NULL) { /* no buffer allocated */
uptr->filebuf = malloc(2048); /* allocate EPROM buffer */
if (uptr->filebuf == NULL) {
if (i2716_dev.dctrl & DEBUG_flow)
printf("i2716_reset: Malloc error\n");
return SCPE_MEM;
}
}
if (base == 0) {
// printf("i2716%d: Not enabled on MP-A2\n", i);
continue;
}
// printf("i2716%d: Initializing [%04X-%04XH]\n",
// i, base+uptr->u3, base+uptr->u3 + uptr->capac);
// if ((uptr->flags & UNIT_ATT) == 0) {
// printf("i2716%d: No file attached\n", i);
// }
}
if (i2716_dev.dctrl & DEBUG_flow)
printf("i2716_reset: Done\n");
return SCPE_OK;
}
/* I/O instruction handlers, called from the CPU module when an
EPROM memory read or write is issued.
*/
/* get a byte from memory */
int32 i2716_get_mbyte(int32 offset)
{
int32 i, val, org, len;
UNIT *uptr;
for (i = 0; i < I2716_NUM; i++) { /* find addressed unit */
uptr = i2716_dev.units + i;
org = uptr->u3;
len = uptr->capac - 1;
if ((offset >= org) && (offset < (org + len))) {
if (uptr->filebuf == NULL) {
if (i2716_dev.dctrl & DEBUG_read)
printf("i2716_get_mbyte: EPROM not configured\n");
return 0xFF;
} else {
val = *((uint8 *)(uptr->filebuf) + (offset - org));
if (i2716_dev.dctrl & DEBUG_read)
printf(" val=%04X\n", val);
return (val & 0xFF);
}
}
}
if (i2716_dev.dctrl & DEBUG_read)
printf("i2716_get_mbyte: Out of range\n");
return 0xFF;
}
/* end of i2716.c */

2018
swtp6800/common/m6800.c Normal file

File diff suppressed because it is too large Load Diff

146
swtp6800/common/m6810.c Normal file
View File

@@ -0,0 +1,146 @@
/* m6810.c: Motorola m6810 RAM emulator
Copyright (c) 2011, William A. Beech
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
WILLIAM A. BEECH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of William A. Beech shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from William A. Beech.
These functions support a simulated m6810 RAM device on a CPU board. The
byte get and put routines use an offset into the RAM image to locate the
proper byte. This allows another device to set the base address for the
M6810.
*/
#include <stdio.h>
#include "swtp_defs.h"
/* function prototypes */
t_stat m6810_reset (DEVICE *dptr);
int32 m6810_get_mbyte(int32 offset);
void m6810_put_mbyte(int32 offset, int32 val);
/* SIMH RAM Standard I/O Data Structures */
UNIT m6810_unit = { UDATA (NULL, UNIT_BINK, 128),
0 };
MTAB m6810_mod[] = {
{ 0 }
};
DEBTAB m6810_debug[] = {
{ "ALL", DEBUG_all },
{ "FLOW", DEBUG_flow },
{ "READ", DEBUG_read },
{ "WRITE", DEBUG_write },
{ "LEV1", DEBUG_level1 },
{ "LEV2", DEBUG_level2 },
{ NULL }
};
DEVICE m6810_dev = {
"M6810", //name
&m6810_unit, //units
NULL, //registers
m6810_mod, //modifiers
1, //numunits
16, //aradix
32, //awidth
1, //aincr
16, //dradix
8, //dwidth
NULL, //examine
NULL, //deposit
&m6810_reset, //reset
NULL, //boot
NULL, //attach
NULL, //detach
NULL, //ctxt
DEV_DEBUG, //flags
0, //dctrl
m6810_debug, //debflags
NULL, //msize
NULL //lname
};
/* global variables */
/* m6810_reset */
t_stat m6810_reset (DEVICE *dptr)
{
if (m6810_dev.dctrl & DEBUG_flow)
printf("m6810_reset: \n");
if (m6810_unit.filebuf == NULL) {
m6810_unit.filebuf = malloc(128);
if (m6810_unit.filebuf == NULL) {
printf("m6810_reset: Malloc error\n");
return SCPE_MEM;
}
m6810_unit.capac = 128;
}
if (m6810_dev.dctrl & DEBUG_flow)
printf("m6810_reset: Done\n");
return SCPE_OK;
}
/* I/O instruction handlers, called from the CPU module when an
RAM memory read or write is issued.
*/
/* get a byte from memory - from offset from start of RAM*/
int32 m6810_get_mbyte(int32 offset)
{
int32 val;
if (m6810_dev.dctrl & DEBUG_read)
printf("m6810_get_mbyte: offset=%04X\n", offset);
if (((t_addr)offset) < m6810_unit.capac) {
val = *((uint8 *)(m6810_unit.filebuf) + offset) & 0xFF;
if (m6810_dev.dctrl & DEBUG_read)
printf("val=%04X\n", val);
return val;
} else {
if (m6810_dev.dctrl & DEBUG_read)
printf("m6810_get_mbyte: out of range\n");
return 0xFF;
}
}
/* put a byte to memory */
void m6810_put_mbyte(int32 offset, int32 val)
{
if (m6810_dev.dctrl & DEBUG_write)
printf("m6810_put_mbyte: offset=%04X, val=%02X\n", offset, val);
if ((t_addr)offset < m6810_unit.capac) {
*((uint8 *)(m6810_unit.filebuf) + offset) = val & 0xFF;
return;
} else {
if (m6810_dev.dctrl & DEBUG_write)
printf("m6810_put_mbyte: out of range\n");
return;
}
}
/* end of m6810.c */

209
swtp6800/common/mp-8m.c Normal file
View File

@@ -0,0 +1,209 @@
/* mp-8m.c: SWTP 8K Byte Memory Card emulator
Copyright (c) 2011, William A. Beech
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
WILLIAM A. BEECH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of William A. Beech shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from William A. Beech.
These functions support 6 simulated MP-8M memory cards on an SS-50 system.
Each unit uses a dynamically allocated 8192 byte buffer to hold the data.
Each unit contains the base address in mp_8m_unit.u3. The unit capacity is
held in mp_8m_unit.capac. Each unit can be enabled or disabled to reconfigure
the RAM for the system.
*/
#include <stdio.h>
#include "swtp_defs.h"
#define MP_8M_NUM 6 /* number of MP-*m boards */
/* prototypes */
t_stat mp_8m_reset (DEVICE *dptr);
int32 mp_8m_get_mbyte(int32 addr);
int32 mp_8m_get_mword(int32 addr);
void mp_8m_put_mbyte(int32 addr, int32 val);
void mp_8m_put_mword(int32 addr, int32 val);
/* isbc064 Standard I/O Data Structures */
UNIT mp_8m_unit[] = {
{ UDATA (NULL, UNIT_FIX+UNIT_BINK+UNIT_DISABLE, 0),0 },
{ UDATA (NULL, UNIT_FIX+UNIT_BINK+UNIT_DISABLE, 0),0 },
{ UDATA (NULL, UNIT_FIX+UNIT_BINK+UNIT_DISABLE, 0),0 },
{ UDATA (NULL, UNIT_FIX+UNIT_BINK+UNIT_DISABLE, 0),0 },
{ UDATA (NULL, UNIT_FIX+UNIT_BINK+UNIT_DISABLE, 0),0 },
{ UDATA (NULL, UNIT_FIX+UNIT_BINK+UNIT_DISABLE, 0),0 }
};
MTAB mp_8m_mod[] = {
{ 0 }
};
DEBTAB mp_8m_debug[] = {
{ "ALL", DEBUG_all },
{ "FLOW", DEBUG_flow },
{ "READ", DEBUG_read },
{ "WRITE", DEBUG_write },
{ "LEV1", DEBUG_level1 },
{ "LEV2", DEBUG_level2 },
{ NULL }
};
DEVICE mp_8m_dev = {
"MP-8M", //name
mp_8m_unit, //units
NULL, //registers
mp_8m_mod, //modifiers
MP_8M_NUM, //numunits
16, //aradix
8, //awidth
1, //aincr
16, //dradix
8, //dwidth
NULL, //examine
NULL, //deposite
&mp_8m_reset, //reset
NULL, //boot
NULL, //attach
NULL, //detach
NULL, //ctxt
DEV_DEBUG, //flags
0, //dctrl
mp_8m_debug, //debflags
NULL, //msize
NULL //lname
};
/* Reset routine */
t_stat mp_8m_reset (DEVICE *dptr)
{
int32 i, j, val;
UNIT *uptr;
if (mp_8m_dev.dctrl & DEBUG_flow)
printf("mp_8m_reset: \n");
for (i = 0; i < MP_8M_NUM; i++) { /* init all units */
uptr = mp_8m_dev.units + i;
if (mp_8m_dev.dctrl & DEBUG_flow)
printf("MP-8M %d unit.flags=%08X\n", i, uptr->flags);
uptr->capac = 0x2000;
if (i < 4)
uptr->u3 = 0x2000 * i;
else
uptr->u3 = 0x2000 * (i + 1);
if (uptr->filebuf == NULL) {
uptr->filebuf = malloc(0x2000);
if (uptr->filebuf == NULL) {
printf("mp_8m_reset: Malloc error\n");
return SCPE_MEM;
}
for (j=0; j<8192; j++) { /* fill pattern for testing */
val = (0xA0 | i);
*((uint8 *)(uptr->filebuf) + j) = val & 0xFF;
}
}
if (mp_8m_dev.dctrl & DEBUG_flow)
printf("MP-8M %d initialized at [%04X-%04XH]\n", i, uptr->u3,
uptr->u3 + uptr->capac - 1);
}
if (mp_8m_dev.dctrl & DEBUG_flow)
printf("mp_8m_reset: Done\n");
return SCPE_OK;
}
/* I/O instruction handlers, called from the mp-b2 module when an
external memory read or write is issued.
*/
/* get a byte from memory */
int32 mp_8m_get_mbyte(int32 addr)
{
int32 val, org, len;
int32 i;
UNIT *uptr;
if (mp_8m_dev.dctrl & DEBUG_read)
printf("mp_8m_get_mbyte: addr=%04X", addr);
for (i = 0; i < MP_8M_NUM; i++) { /* find addressed unit */
uptr = mp_8m_dev.units + i;
org = uptr->u3;
len = uptr->capac - 1;
if ((addr >= org) && (addr <= org + len)) {
val = *((uint8 *)(uptr->filebuf) + (addr - org));
if (mp_8m_dev.dctrl & DEBUG_read)
printf(" val=%04X\n", val);
return (val & 0xFF);
}
}
if (mp_8m_dev.dctrl & DEBUG_read)
printf("mp_8m_get_mbyte: Out of range\n");
return 0xFF; /* multibus has active high pullups */
}
/* get a word from memory */
int32 mp_8m_get_mword(int32 addr)
{
int32 val;
val = (mp_8m_get_mbyte(addr) << 8);
val |= mp_8m_get_mbyte(addr+1);
return val;
}
/* put a byte into memory */
void mp_8m_put_mbyte(int32 addr, int32 val)
{
int32 org, len;
int32 i;
UNIT *uptr;
if (mp_8m_dev.dctrl & DEBUG_write)
printf("mp_8m_put_mbyte: addr=%04X, val=%02X", addr, val);
for (i = 0; i < MP_8M_NUM; i++) { /* find addressed unit */
uptr = mp_8m_dev.units + i;
org = uptr->u3;
len = uptr->capac - 1;
if ((addr >= org) && (addr < org + len)) {
*((uint8 *)(uptr->filebuf) + (addr - org)) = val & 0xFF;
if (mp_8m_dev.dctrl & DEBUG_write)
printf("\n");
return;
}
}
if (mp_8m_dev.dctrl & DEBUG_write)
printf("mp_8m_put_mbyte: Out of range\n");
}
/* put a word into memory */
void mp_8m_put_mword(int32 addr, int32 val)
{
mp_8m_put_mbyte(addr, val >> 8);
mp_8m_put_mbyte(addr+1, val);
}
/* end of mp-8m.c */

211
swtp6800/common/mp-a.c Normal file
View File

@@ -0,0 +1,211 @@
/* mp-a.c: SWTP MP-A M6800 CPU simulator
Copyright (c) 2011, William Beech
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
WILLIAM A. BEECH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of William A. Beech shall not
be used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from William A. Beech.
The MP-A CPU Board contains the following devices [mp-a.c]:
M6800 processor [m6800.c].
M6810 128 byte RAM at 0xA000 [m6810.c].
M6830, SWTBUG, or custom boot ROM at 0xE000 [bootrom.c].
Interface to the SS-50 bus and the MP-B2 Mother Board for I/O
and memory boards [mp-b2.c].
Note: The file names of the emulator source programs for each device are
contained in "[]".
*/
#include <stdio.h>
#include "swtp_defs.h"
#define UNIT_V_SWT (UNIT_V_UF) /* on SWTBUG, off MIKBUG */
#define UNIT_SWT (1 << UNIT_V_SWT)
#define UNIT_V_RAM (UNIT_V_UF+1) /* off disables 6810 RAM */
#define UNIT_RAM (1 << UNIT_V_RAM)
/* local global variables */
/* function prototypes */
int32 CPU_BD_get_mbyte(int32 addr);
int32 CPU_BD_get_mword(int32 addr);
void CPU_BD_put_mbyte(int32 addr, int32 val);
void CPU_BD_put_mword(int32 addr, int32 val);
/* external routines */
/* MP-B2 bus routines */
extern int32 MB_get_mbyte(int32 addr);
extern int32 MB_get_mword(int32 addr);
extern void MB_put_mbyte(int32 addr, int32 val);
extern void MB_put_mword(int32 addr, int32 val);
/* M6810 bus routines */
extern int32 m6810_get_mbyte(int32 addr);
extern void m6810_put_mbyte(int32 addr, int32 val);
/* BOOTROM bus routines */
extern UNIT BOOTROM_unit;
extern int32 BOOTROM_get_mbyte(int32 offset);
/* MP-A data structures
CPU_BD_dev MP-A2 device descriptor
CPU_BD_unit MP-A2 unit descriptor
CPU_BD_reg MP-A2 register list
CPU_BD_mod MP-A2 modifiers list */
UNIT CPU_BD_unit = { UDATA (NULL, 0, 0) };
REG CPU_BD_reg[] = {
{ NULL }
};
MTAB CPU_BD_mod[] = {
{ UNIT_SWT, UNIT_SWT, "SWT", "SWT", NULL },
{ UNIT_SWT, 0, "NOSWT", "NOSWT", NULL },
{ UNIT_RAM, UNIT_RAM, "RAM", "RAM", NULL },
{ UNIT_RAM, 0, "NORAM", "NORAM", NULL },
{ 0 }
};
DEBTAB CPU_BD_debug[] = {
{ "ALL", DEBUG_all },
{ "FLOW", DEBUG_flow },
{ "READ", DEBUG_read },
{ "WRITE", DEBUG_write },
{ "LEV1", DEBUG_level1 },
{ "LEV2", DEBUG_level2 },
{ NULL }
};
DEVICE CPU_BD_dev = {
"MP-A", //name
&CPU_BD_unit, //units
CPU_BD_reg, //registers
CPU_BD_mod, //modifiers
1, //numunits
16, //aradix
16, //awidth
1, //aincr
16, //dradix
8, //dwidth
NULL, //examine
NULL, //deposit
NULL, //reset
NULL, //boot
NULL, //attach
NULL, //detach
NULL, //ctxt
DEV_DEBUG, //flags
0, //dctrl
CPU_BD_debug, /* debflags */
NULL, //msize
NULL //lname
};
/* get a byte from memory */
int32 CPU_BD_get_mbyte(int32 addr)
{
int32 val;
if (CPU_BD_dev.dctrl & DEBUG_read)
printf("CPU_BD_get_mbyte: addr=%04X\n", addr);
switch(addr & 0xF000) {
case 0xA000:
if (CPU_BD_unit.flags & UNIT_RAM) {
val = m6810_get_mbyte(addr - 0xA000) & 0xFF;
if (CPU_BD_dev.dctrl & DEBUG_read)
printf("CPU_BD_get_mbyte: m6810 val=%02X\n", val);
return val;
} else {
val = MB_get_mbyte(addr) & 0xFF;
if (CPU_BD_dev.dctrl & DEBUG_read)
printf("CPU_BD_get_mbyte: m6810 val=%02X\n", val);
return val;
}
case 0xE000:
val = BOOTROM_get_mbyte(addr - 0xE000) & 0xFF;
if (CPU_BD_dev.dctrl & DEBUG_read)
printf("CPU_BD_get_mbyte: EPROM=%02X\n", val);
return val;
case 0xF000:
val = BOOTROM_get_mbyte(addr - (0x10000 - BOOTROM_unit.capac)) & 0xFF;
if (CPU_BD_dev.dctrl & DEBUG_read)
printf("CPU_BD_get_mbyte: EPROM=%02X\n", val);
return val;
default:
val = MB_get_mbyte(addr) & 0xFF;
if (CPU_BD_dev.dctrl & DEBUG_read)
printf("CPU_BD_get_mbyte: mp_b2 val=%02X\n", val);
return val;
}
}
/* get a word from memory */
int32 CPU_BD_get_mword(int32 addr)
{
int32 val;
if (CPU_BD_dev.dctrl & DEBUG_read)
printf("CPU_BD_get_mword: addr=%04X\n", addr);
val = (CPU_BD_get_mbyte(addr) << 8);
val |= CPU_BD_get_mbyte(addr+1);
val &= 0xFFFF;
if (CPU_BD_dev.dctrl & DEBUG_read)
printf("CPU_BD_get_mword: val=%04X\n", val);
return val;
}
/* put a byte to memory */
void CPU_BD_put_mbyte(int32 addr, int32 val)
{
if (CPU_BD_dev.dctrl & DEBUG_write)
printf("CPU_BD_put_mbyte: addr=%04X, val=%02X\n", addr, val);
switch(addr & 0xF000) {
case 0xA000:
if (CPU_BD_unit.flags & UNIT_RAM) {
m6810_put_mbyte(addr - 0xA000, val);
return;
} else {
MB_put_mbyte(addr, val);
return;
}
default:
MB_put_mbyte(addr, val);
return;
}
}
/* put a word to memory */
void CPU_BD_put_mword(int32 addr, int32 val)
{
if (CPU_BD_dev.dctrl & DEBUG_write)
printf("CPU_BD_put_mword: addr=%04X, val=%04X\n", addr, val);
CPU_BD_put_mbyte(addr, val >> 8);
CPU_BD_put_mbyte(addr+1, val);
}
/* end of mp-a.c */

263
swtp6800/common/mp-a2.c Normal file
View File

@@ -0,0 +1,263 @@
/* mp-a2.c: SWTP MP-A2 M6800 CPU simulator
Copyright (c) 2011, William Beech
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
WILLIAM A. BEECH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of William A. Beech shall not
be used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from William A. Beech.
The MP-A2 CPU Board contains the following devices [mp-a2.c]:
M6800 processor [m6800.c].
M6810 128 byte RAM at 0xA000 [m6810.c].
M6830, SWTBUG, or custom boot ROM at 0xE000 [bootrom.c].
4 ea 2716 EPROMs at either 0xC000, 0xC800, 0xD000 and 0xD800 (LO_PROM)or
0xE000, 0xE800, 0xF000 and 0xF800 (HI_PROM) [eprom.c].
Interface to the SS-50 bus and the MP-B2 Mother Board for I/O
and memory boards [mp-b2.c].
Note: The file names of the emulator source programs for each device are
contained in "[]".
*/
#include <stdio.h>
#include "swtp_defs.h"
#define UNIT_V_USER_D (UNIT_V_UF) /* user defined switch */
#define UNIT_USER_D (1 << UNIT_V_USER_D)
#define UNIT_V_4K_8K (UNIT_V_UF+1) /* off if HI_PROM and only 2K EPROM */
#define UNIT_4K_8K (1 << UNIT_V_4K_8K)
#define UNIT_V_SWT (UNIT_V_UF+2) /* on SWTBUG, off MIKBUG */
#define UNIT_SWT (1 << UNIT_V_SWT)
#define UNIT_V_8K (UNIT_V_UF+3) /* off if HI_PROM and only 2K or 4k EPROM */
#define UNIT_8K (1 << UNIT_V_8K)
#define UNIT_V_RAM (UNIT_V_UF+4) /* off disables 6810 RAM */
#define UNIT_RAM (1 << UNIT_V_RAM)
#define UNIT_V_LO_PROM (UNIT_V_UF+5) /* on EPROMS @ C000-CFFFH, off no EPROMS */
#define UNIT_LO_PROM (1 << UNIT_V_LO_PROM)
#define UNIT_V_HI_PROM (UNIT_V_UF+6) /* on EPROMS @ F000-FFFFH, off fo LO_PROM, MON, or no EPROMS */
#define UNIT_HI_PROM (1 << UNIT_V_HI_PROM)
#define UNIT_V_MON (UNIT_V_UF+7) /* on for monitor vectors in high memory */
#define UNIT_MON (1 << UNIT_V_MON)
/* local global variables */
/* function prototypes */
int32 get_base(void);
int32 CPU_BD_get_mbyte(int32 addr);
int32 CPU_BD_get_mword(int32 addr);
void CPU_BD_put_mbyte(int32 addr, int32 val);
void CPU_BD_put_mword(int32 addr, int32 val);
/* external routines */
/* MP-B2 bus routines */
extern int32 MB_get_mbyte(int32 addr);
extern int32 MB_get_mword(int32 addr);
extern void MB_put_mbyte(int32 addr, int32 val);
extern void MB_put_mword(int32 addr, int32 val);
/* M6810 bus routines */
extern int32 m6810_get_mbyte(int32 addr);
extern void m6810_put_mbyte(int32 addr, int32 val);
/* BOOTROM bus routines */
extern UNIT BOOTROM_unit;
extern int32 BOOTROM_get_mbyte(int32 offset);
/* I2716 bus routines */
extern int32 i2716_get_mbyte(int32 offset);
/* MP-A2 data structures
CPU_BD_dev MP-A2 device descriptor
CPU_BD_unit MP-A2 unit descriptor
CPU_BD_reg MP-A2 register list
CPU_BD_mod MP-A2 modifiers list */
UNIT CPU_BD_unit = { UDATA (NULL, 0, 0) };
REG CPU_BD_reg[] = {
{ NULL }
};
MTAB CPU_BD_mod[] = {
{ UNIT_USER_D, UNIT_USER_D, "USER_D", "USER_D", NULL },
{ UNIT_USER_D, 0, "NOUSER_D", "NOUSER_D", NULL },
{ UNIT_4K_8K, UNIT_4K_8K, "4K_8K", "4K_8K", NULL },
{ UNIT_4K_8K, 0, "NO4K_8K", "NO4K_8K", NULL },
{ UNIT_SWT, UNIT_SWT, "SWT", "SWT", NULL },
{ UNIT_SWT, 0, "NOSWT", "NOSWT", NULL },
{ UNIT_8K, UNIT_8K, "8K", "8K", NULL },
{ UNIT_8K, 0, "NO8K", "NO8K", NULL },
{ UNIT_RAM, UNIT_RAM, "RAM", "RAM", NULL },
{ UNIT_RAM, 0, "NORAM", "NORAM", NULL },
{ UNIT_LO_PROM, UNIT_LO_PROM, "LO_PROM", "LO_PROM", NULL },
{ UNIT_LO_PROM, 0, "NOLO_PROM", "NOLO_PROM", NULL },
{ UNIT_HI_PROM, UNIT_HI_PROM, "HI_PROM", "HI_PROM", NULL },
{ UNIT_HI_PROM, 0, "NOHI_PROM", "NOHI_PROM", NULL },
{ UNIT_MON, UNIT_MON, "MON", "MON", NULL },
{ UNIT_MON, 0, "NOMON", "NOMON", NULL },
{ 0 }
};
DEBTAB CPU_BD_debug[] = {
{ "ALL", DEBUG_all },
{ "FLOW", DEBUG_flow },
{ "READ", DEBUG_read },
{ "WRITE", DEBUG_write },
{ "LEV1", DEBUG_level1 },
{ "LEV2", DEBUG_level2 },
{ NULL }
};
DEVICE CPU_BD_dev = {
"MP-A2", //name
&CPU_BD_unit, //units
CPU_BD_reg, //registers
CPU_BD_mod, //modifiers
1, //numunits
16, //aradix
16, //awidth
1, //aincr
16, //dradix
8, //dwidth
NULL, //examine
NULL, //deposit
NULL, //reset
NULL, //boot
NULL, //attach
NULL, //detach
NULL, //ctxt
DEV_DEBUG, //flags
0, //dctrl
CPU_BD_debug, /* debflags */
NULL, //msize
NULL //lname
};
/* get base address of 2716's */
int32 get_base(void)
{
if (CPU_BD_unit.flags & UNIT_LO_PROM)
return 0xC000;
else if (CPU_BD_unit.flags & UNIT_HI_PROM)
return 0xF000;
return 0;
}
/* get a byte from memory */
int32 CPU_BD_get_mbyte(int32 addr)
{
int32 val;
if (CPU_BD_dev.dctrl & DEBUG_read)
printf("CPU_BD_get_mbyte: addr=%04X\n", addr);
switch(addr & 0xF000) {
case 0xA000:
if (CPU_BD_unit.flags & UNIT_RAM) {
val = m6810_get_mbyte(addr - 0xA000) & 0xFF;
if (CPU_BD_dev.dctrl & DEBUG_read)
printf("CPU_BD_get_mbyte: m6810 val=%02X\n", val);
return val;
} else {
val = MB_get_mbyte(addr) & 0xFF;
if (CPU_BD_dev.dctrl & DEBUG_read)
printf("CPU_BD_get_mbyte: m6810 val=%02X\n", val);
return val;
}
case 0xC000:
if (CPU_BD_unit.flags & UNIT_LO_PROM) {
val = i2716_get_mbyte(addr - 0xC000) & 0xFF;
if (CPU_BD_dev.dctrl & DEBUG_read)
printf("CPU_BD_get_mbyte: 2716=%02X\n", val);
return val;
} else
return 0xFF;
break;
case 0xE000:
val = BOOTROM_get_mbyte(addr - 0xE000) & 0xFF;
if (CPU_BD_dev.dctrl & DEBUG_read)
printf("CPU_BD_get_mbyte: EPROM=%02X\n", val);
return val;
case 0xF000:
if (CPU_BD_unit.flags & UNIT_MON) {
val = BOOTROM_get_mbyte(addr - (0x10000 - BOOTROM_unit.capac)) & 0xFF;
if (CPU_BD_dev.dctrl & DEBUG_read)
printf("CPU_BD_get_mbyte: EPROM=%02X\n", val);
return val;
}
default:
val = MB_get_mbyte(addr) & 0xFF;
if (CPU_BD_dev.dctrl & DEBUG_read)
printf("CPU_BD_get_mbyte: mp_b2 val=%02X\n", val);
return val;
}
}
/* get a word from memory */
int32 CPU_BD_get_mword(int32 addr)
{
int32 val;
if (CPU_BD_dev.dctrl & DEBUG_read)
printf("CPU_BD_get_mword: addr=%04X\n", addr);
val = (CPU_BD_get_mbyte(addr) << 8);
val |= CPU_BD_get_mbyte(addr+1);
val &= 0xFFFF;
if (CPU_BD_dev.dctrl & DEBUG_read)
printf("CPU_BD_get_mword: val=%04X\n", val);
return val;
}
/* put a byte to memory */
void CPU_BD_put_mbyte(int32 addr, int32 val)
{
if (CPU_BD_dev.dctrl & DEBUG_write)
printf("CPU_BD_put_mbyte: addr=%04X, val=%02X\n", addr, val);
switch(addr & 0xF000) {
case 0xA000:
if (CPU_BD_unit.flags & UNIT_RAM) {
m6810_put_mbyte(addr - 0xA000, val);
return;
} else {
MB_put_mbyte(addr, val);
return;
}
default:
MB_put_mbyte(addr, val);
return;
}
}
/* put a word to memory */
void CPU_BD_put_mword(int32 addr, int32 val)
{
if (CPU_BD_dev.dctrl & DEBUG_write)
printf("CPU_BD_put_mword: addr=%04X, val=%04X\n", addr, val);
CPU_BD_put_mbyte(addr, val >> 8);
CPU_BD_put_mbyte(addr+1, val);
}
/* end of mp-a2.c */

322
swtp6800/common/mp-b2.c Normal file
View File

@@ -0,0 +1,322 @@
/* mp-b2.c: SWTP SS-50/SS-30 MP-B2 Mother Board
Copyright (c) 2011, William A. Beech
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
WILLIAM A. BEECH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of William A. Beech shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from William A. Beech.
*/
#include <stdio.h>
#include "swtp_defs.h"
#define UNIT_V_RAM_0000 (UNIT_V_UF) /* MP-8M board 0 enable */
#define UNIT_RAM_0000 (1 << UNIT_V_RAM_0000)
#define UNIT_V_RAM_2000 (UNIT_V_UF+1) /* MP-8M board 1 enable */
#define UNIT_RAM_2000 (1 << UNIT_V_RAM_2000)
#define UNIT_V_RAM_4000 (UNIT_V_UF+2) /* MP-8M board 2 enable */
#define UNIT_RAM_4000 (1 << UNIT_V_RAM_4000)
#define UNIT_V_RAM_6000 (UNIT_V_UF+3) /* MP-8M board 3 enable */
#define UNIT_RAM_6000 (1 << UNIT_V_RAM_6000)
#define UNIT_V_RAM_A000 (UNIT_V_UF+4) /* MP-8M board 4 enable */
#define UNIT_RAM_A000 (1 << UNIT_V_RAM_A000)
#define UNIT_V_RAM_C000 (UNIT_V_UF+5) /* MP-8M board 5 enable */
#define UNIT_RAM_C000 (1 << UNIT_V_RAM_C000)
/* function prototypes */
/* empty I/O device routine */
int32 nulldev(int32 io, int32 data);
/* SS-50 bus routines */
int32 MB_get_mbyte(int32 addr);
int32 MB_get_mword(int32 addr);
void MB_put_mbyte(int32 addr, int32 val);
void MB_put_mword(int32 addr, int32 val);
/* MP-8M bus routines */
extern int32 mp_8m_get_mbyte(int32 addr);
extern void mp_8m_put_mbyte(int32 addr, int32 val);
/* SS-50 I/O address space functions */
/* MP-S serial I/O routines */
extern int32 sio0s(int32 io, int32 data);
extern int32 sio0d(int32 io, int32 data);
extern int32 sio1s(int32 io, int32 data);
extern int32 sio1d(int32 io, int32 data);
/* DC-4 FDC I/O routines */
extern int32 fdcdrv(int32 io, int32 data);
extern int32 fdccmd(int32 io, int32 data);
extern int32 fdctrk(int32 io, int32 data);
extern int32 fdcsec(int32 io, int32 data);
extern int32 fdcdata(int32 io, int32 data);
/* This is the I/O configuration table. There are 32 possible
device addresses, if a device is plugged into a port it's routine
address is here, 'nulldev' means no device is available
*/
struct idev {
int32 (*routine)();
};
struct idev dev_table[32] = {
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /*Port 0 8000-8003 */
{&sio0s}, {&sio0d}, {&sio1s}, {&sio1d}, /*Port 1 8004-8007 */
/* sio1x routines just return the last value read on the matching
sio0x routine. SWTBUG tests for the MP-C with most port reads! */
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /*Port 2 8008-800B*/
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /*Port 3 800C-800F*/
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /*Port 4 8010-8013*/
{&fdcdrv}, {&nulldev}, {&nulldev}, {&nulldev}, /*Port 5 8014-8017*/
{&fdccmd}, {&fdctrk}, {&fdcsec}, {&fdcdata}, /*Port 6 8018-801B*/
{&nulldev}, {&nulldev}, {&nulldev}, {&nulldev} /*Port 7 801C-801F*/
};
/* dummy i/o device */
int32 nulldev(int32 io, int32 data)
{
if (io == 0)
return (0xFF);
return 0;
}
/* Mother Board data structures
MB_dev Mother Board device descriptor
MB_unit Mother Board unit descriptor
MB_reg Mother Board register list
MB_mod Mother Board modifiers list
*/
UNIT MB_unit = {
UDATA (NULL, 0, 0)
};
REG MB_reg[] = {
{ NULL }
};
MTAB MB_mod[] = {
{ UNIT_RAM_0000, UNIT_RAM_0000, "BD0 On", "BD0", NULL },
{ UNIT_RAM_0000, 0, "BD0 Off", "NOBD0", NULL },
{ UNIT_RAM_2000, UNIT_RAM_2000, "BD1 On", "BD1", NULL },
{ UNIT_RAM_2000, 0, "BD1 Off", "NOBD1", NULL },
{ UNIT_RAM_4000, UNIT_RAM_4000, "BD2 On", "BD2", NULL },
{ UNIT_RAM_4000, 0, "BD2 Off", "NOBD2", NULL },
{ UNIT_RAM_6000, UNIT_RAM_6000, "BD3 On", "BD3", NULL },
{ UNIT_RAM_6000, 0, "BD3 Off", "NOBD3", NULL },
{ UNIT_RAM_A000, UNIT_RAM_A000, "BD4 On", "BD4", NULL },
{ UNIT_RAM_A000, 0, "BD4 Off", "NOBD4", NULL },
{ UNIT_RAM_C000, UNIT_RAM_C000, "BD5 On", "BD5", NULL },
{ UNIT_RAM_C000, 0, "BD5 Off", "NOBD5", NULL },
{ 0 }
};
DEBTAB MB_debug[] = {
{ "ALL", DEBUG_all },
{ "FLOW", DEBUG_flow },
{ "READ", DEBUG_read },
{ "WRITE", DEBUG_write },
{ "LEV1", DEBUG_level1 },
{ "LEV2", DEBUG_level2 },
{ NULL }
};
DEVICE MB_dev = {
"MP-B2", //name
&MB_unit, //units
MB_reg, //registers
MB_mod, //modifiers
1, //numunits
16, //aradix
16, //awidth
1, //aincr
16, //dradix
8, //dwidth
NULL, //examine
NULL, //deposit
NULL, //reset
NULL, //boot
NULL, //attach
NULL, //detach
NULL, //ctxt
DEV_DEBUG, //flags
0, //dctrl
MB_debug, /* debflags */
NULL, //msize
NULL //lname
};
/* get a byte from memory */
int32 MB_get_mbyte(int32 addr)
{
int32 val;
if (MB_dev.dctrl & DEBUG_read)
printf("MB_get_mbyte: addr=%04X\n", addr);
switch(addr & 0xF000) {
case 0x0000:
case 0x1000:
if (MB_unit.flags & UNIT_RAM_0000) {
val = mp_8m_get_mbyte(addr) & 0xFF;
if (MB_dev.dctrl & DEBUG_read)
printf("MB_get_mbyte: mp_8m val=%02X\n", val);
return val;
} else
return 0xFF;
case 0x2000:
case 0x3000:
if (MB_unit.flags & UNIT_RAM_2000) {
val = mp_8m_get_mbyte(addr) & 0xFF;
if (MB_dev.dctrl & DEBUG_read)
printf("MB_get_mbyte: mp_8m val=%02X\n", val);
return val;
} else
return 0xFF;
case 0x4000:
case 0x5000:
if (MB_unit.flags & UNIT_RAM_4000) {
val = mp_8m_get_mbyte(addr) & 0xFF;
if (MB_dev.dctrl & DEBUG_read)
printf("MB_get_mbyte: mp_8m val=%02X\n", val);
return val;
} else
return 0xFF;
case 0x6000:
case 0x7000:
if (MB_unit.flags & UNIT_RAM_6000) {
val = mp_8m_get_mbyte(addr) & 0xFF;
if (MB_dev.dctrl & DEBUG_read)
printf("MB_get_mbyte: mp_8m val=%02X\n", val);
return val;
} else
return 0xFF;
case 0x8000:
val = (dev_table[addr - 0x8000].routine(0, 0)) & 0xFF;
if (MB_dev.dctrl & DEBUG_read)
printf("MB_get_mbyte: I/O addr=%04X val=%02X\n", addr, val);
return val;
case 0xA000:
case 0xB000:
if (MB_unit.flags & UNIT_RAM_A000) {
val = mp_8m_get_mbyte(addr) & 0xFF;
if (MB_dev.dctrl & DEBUG_read)
printf("MB_get_mbyte: mp_8m val=%02X\n", val);
return val;
} else
return 0xFF;
case 0xC000:
case 0xD000:
if (MB_unit.flags & UNIT_RAM_C000) {
val = mp_8m_get_mbyte(addr) & 0xFF;
if (MB_dev.dctrl & DEBUG_read)
printf("MB_get_mbyte: mp_8m val=%02X\n", val);
return val;
} else
return 0xFF;
default:
return 0xFF;
}
}
/* get a word from memory */
int32 MB_get_mword(int32 addr)
{
int32 val;
if (MB_dev.dctrl & DEBUG_read)
printf("MB_get_mword: addr=%04X\n", addr);
val = (MB_get_mbyte(addr) << 8);
val |= MB_get_mbyte(addr+1);
val &= 0xFFFF;
if (MB_dev.dctrl & DEBUG_read)
printf("MB_get_mword: val=%04X\n", val);
return val;
}
/* put a byte to memory */
void MB_put_mbyte(int32 addr, int32 val)
{
if (MB_dev.dctrl & DEBUG_write)
printf("MB_put_mbyte: addr=%04X, val=%02X\n", addr, val);
switch(addr & 0xF000) {
case 0x0000:
case 0x1000:
if (MB_unit.flags & UNIT_RAM_0000) {
mp_8m_put_mbyte(addr, val);
return;
}
case 0x2000:
case 0x3000:
if (MB_unit.flags & UNIT_RAM_2000) {
mp_8m_put_mbyte(addr, val);
return;
}
case 0x4000:
case 0x5000:
if (MB_unit.flags & UNIT_RAM_4000) {
mp_8m_put_mbyte(addr, val);
return;
}
case 0x6000:
case 0x7000:
if (MB_unit.flags & UNIT_RAM_6000) {
mp_8m_put_mbyte(addr, val);
return;
}
case 0x8000:
dev_table[addr - 0x8000].routine(1, val);
return;
case 0xA000:
case 0xB000:
if (MB_unit.flags & UNIT_RAM_A000) {
mp_8m_put_mbyte(addr, val);
return;
}
case 0xC000:
case 0xD000:
if (MB_unit.flags & UNIT_RAM_C000) {
mp_8m_put_mbyte(addr, val);
return;
}
default:
return;
}
}
/* put a word to memory */
void MB_put_mword(int32 addr, int32 val)
{
if (MB_dev.dctrl & DEBUG_write)
printf("MB_ptt_mword: addr=%04X, val=%04X\n", addr, val);
MB_put_mbyte(addr, val >> 8);
MB_put_mbyte(addr+1, val);
}
/* end of mp-b2.c */

330
swtp6800/common/mp-s.c Normal file
View File

@@ -0,0 +1,330 @@
/* mp-s.c: SWTP MP-S serial I/O card emulator
Copyright (c) 2005-2011, William Beech
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
Willaim Beech BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of William A. Beech shall not
be used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from William A. Beech.
These functions support a simulated SWTP MP-S interface card.
The card contains one M6850 ACIA. The ACIA implements one complete
serial port. It provides 7 or 8-bit ASCII RS-232 interface to Terminals
or 20 mA current loop interface to a model 33 or 37 Teletype. It is not
compatible with baudot Teletypes. Baud rates from 110 to 1200 are
switch selectable from S! on the MP-S. The ACIA ports appear at all
4 addresses. This fact is used by SWTBUG to determine the presence of the
MP-S vice MP-C serial card. The ACIA interrupt request line can be connected
to the IRQ or NMI interrupt lines by a jumper on the MP-S.
All I/O is via either programmed I/O or interrupt controlled I/O.
It has a status port and a data port. A write to the status port
can select some options for the device (0x03 will reset the port).
A read of the status port gets the port status:
+---+---+---+---+---+---+---+---+
| I | P | O | F |CTS|DCD|TXE|RXF|
+---+---+---+---+---+---+---+---+
RXF - A 1 in this bit position means a character has been received
on the data port and is ready to be read.
TXE - A 1 in this bit means the port is ready to receive a character
on the data port and transmit it out over the serial line.
A read to the data port gets the buffered character, a write
to the data port writes the character to the device.
*/
#include <stdio.h>
#include <ctype.h>
#include "swtp_defs.h"
#define UNIT_V_TTY (UNIT_V_UF) // TTY or ANSI mode
#define UNIT_TTY (1 << UNIT_V_TTY)
/* local global variables */
int32 ptr_stopioe = 0; // stop on error
int32 ptp_stopioe = 0; // stop on error
int32 odata;
int32 status;
int32 ptp_flag = 0;
int32 ptr_flag = 0;
/* function prototypes */
t_stat sio_svc (UNIT *uptr);
t_stat ptr_svc (UNIT *uptr);
t_stat ptp_svc (UNIT *uptr);
t_stat sio_reset (DEVICE *dptr);
t_stat ptr_reset (DEVICE *dptr);
t_stat ptp_reset (DEVICE *dptr);
int32 sio0s(int32 io, int32 data);
int32 sio0d(int32 io, int32 data);
int32 sio1s(int32 io, int32 data);
int32 sio1d(int32 io, int32 data);
/* sio data structures
sio_dev SIO device descriptor
sio_unit SIO unit descriptor
sio_reg SIO register list
sio_mod SIO modifiers list */
UNIT sio_unit = { UDATA (&sio_svc, 0, 0), KBD_POLL_WAIT
};
REG sio_reg[] = {
{ ORDATA (DATA, sio_unit.buf, 8) },
{ ORDATA (STAT, sio_unit.u3, 8) },
{ NULL }
};
MTAB sio_mod[] = {
{ UNIT_TTY, UNIT_TTY, "TTY", "TTY", NULL },
{ UNIT_TTY, 0, "ANSI", "ANSI", NULL },
{ 0 }
};
DEVICE sio_dev = {
"MP-S", &sio_unit, sio_reg, sio_mod,
1, 10, 31, 1, 8, 8,
NULL, NULL, &sio_reset,
NULL, NULL, NULL
};
/* paper tape reader data structures
ptr_dev PTR device descriptor
ptr_unit PTR unit descriptor
ptr_reg PTR register list
ptr_mod PTR modifiers list */
UNIT ptr_unit = { UDATA (&ptr_svc, UNIT_SEQ + UNIT_ATTABLE, 0), KBD_POLL_WAIT
};
DEVICE ptr_dev = {
"PTR", &ptr_unit, NULL, NULL,
1, 10, 31, 1, 8, 8,
NULL, NULL, &ptr_reset,
NULL, NULL, NULL
};
/* paper tape punch data structures
ptp_dev PTP device descriptor
ptp_unit PTP unit descriptor
ptp_reg PTP register list
ptp_mod PTP modifiers list */
UNIT ptp_unit = { UDATA (&ptp_svc, UNIT_SEQ + UNIT_ATTABLE, 0), KBD_POLL_WAIT
};
DEVICE ptp_dev = {
"PTP", &ptp_unit, NULL, NULL,
1, 10, 31, 1, 8, 8,
NULL, NULL, &ptp_reset,
NULL, NULL, NULL
};
/* console input service routine */
int32 sio_svc (UNIT *uptr)
{
int32 temp;
sim_activate (&sio_unit, sio_unit.wait); // continue poll
if ((temp = sim_poll_kbd ()) < SCPE_KFLAG)
return temp; // no char or error?
sio_unit.buf = temp & 0xFF; // Save char
sio_unit.u3 |= 0x01; // Set RXF flag
/* Do any special character handling here */
sio_unit.pos++; // step character count
return SCPE_OK;
}
/* paper tape reader input service routine */
int32 ptr_svc (UNIT *uptr)
{
int32 temp;
sim_activate (&ptr_unit, ptr_unit.wait); // continue poll
if ((temp = sim_poll_kbd ()) < SCPE_KFLAG)
return temp; // no char or error?
ptr_unit.buf = temp & 0xFF; // Save char
ptr_unit.u3 |= 0x01; // Set RXF flag
/* Do any special character handling here */
ptr_unit.pos++; // step character count
return SCPE_OK;
}
/* paper tape punch output service routine */
int32 ptp_svc (UNIT *uptr)
{
return SCPE_OK;
}
/* Reset console */
int32 sio_reset (DEVICE *dptr)
{
sio_unit.buf = 0; // Data buffer
sio_unit.u3 = 0x02; // Status buffer
sim_activate (&sio_unit, sio_unit.wait); // activate unit
return SCPE_OK;
}
/* Reset paper tape reader */
int32 ptr_reset (DEVICE *dptr)
{
ptr_unit.buf = 0;
ptr_unit.u3 = 0x02;
sim_activate (&ptr_unit, ptr_unit.wait); // activate unit
// sim_cancel (&ptr_unit); // deactivate unit
return SCPE_OK;
}
/* Reset paper tape punch */
int32 ptp_reset (DEVICE *dptr)
{
ptp_unit.buf = 0;
ptp_unit.u3 = 0x02;
sim_activate (&ptp_unit, ptp_unit.wait); // activate unit
// sim_cancel (&ptp_unit); // deactivate unit
return SCPE_OK;
}
/* I/O instruction handlers, called from the MP-B2 module when a
read or write occur to addresses 0x8004-0x8007. */
int32 sio0s(int32 io, int32 data)
{
if (io == 0) { // control register read
if (ptr_flag) { // reader enabled?
if ((ptr_unit.flags & UNIT_ATT) == 0) { // attached?
ptr_unit.u3 &= 0xFE; // no, clear RXF flag
ptr_flag = 0; // clear reader flag
printf("Reader not attached to file\n");
} else { // attached
if (feof(ptr_unit.fileref)) { // EOF
ptr_unit.u3 &= 0xFE; // clear RXF flag
ptr_flag = 0; // clear reader flag
} else // not EOF
ptr_unit.u3 |= 0x01; // set ready
}
return (status = ptr_unit.u3); // return ptr status
} else {
return (status = sio_unit.u3); // return console status
}
} else { // control register write
if (data == 0x03) { // reset port!
sio_unit.u3 = 0x02; // reset console
sio_unit.buf = 0;
sio_unit.pos = 0;
ptr_unit.u3 = 0x02; // reset reader
ptr_unit.buf = 0;
ptr_unit.pos = 0;
ptp_unit.u3 = 0x02; // reset punch
ptp_unit.buf = 0;
ptp_unit.pos = 0;
}
return (status = 0); // invalid io
}
}
int32 sio0d(int32 io, int32 data)
{
if (io == 0) { // data register read
if (ptr_flag) { // RDR enabled?
if ((ptr_unit.flags & UNIT_ATT) == 0) // attached?
return 0; // no, done
// printf("ptr_unit.u3=%02X\n", ptr_unit.u3);
if ((ptr_unit.u3 & 0x01) == 0) { // yes, more data?
// printf("Returning old %02X\n", odata); // no, return previous byte
return (odata & 0xFF);
}
if ((odata = getc(ptr_unit.fileref)) == EOF) { // end of file?
// printf("Got EOF\n");
ptr_unit.u3 &= 0xFE; // clear RXF flag
return (odata = 0); // no data
}
// printf("Returning new %02X\n", odata);
ptr_unit.pos++; // step character count
ptr_unit.u3 &= 0xFE; // clear RXF flag
return (odata & 0xFF); // return character
} else {
sio_unit.u3 &= 0xFE; // clear RXF flag
return (odata = sio_unit.buf); // return next char
}
} else { // data register write
if (isprint(data) || data == '\r' || data == '\n') { // printable?
sim_putchar(data); // print character on console
if (ptp_flag && ptp_unit.flags & UNIT_ATT) { // PTP enabled & attached?
putc(data, ptp_unit.fileref);
ptp_unit.pos++; // step character counter
}
} else { // DC1-DC4 control Reader/Punch
switch (data) {
case 0x11: // PTR on
ptr_flag = 1;
ptr_unit.u3 |= 0x01;
// printf("Reader on\n");
break;
case 0x12: // PTP on
ptp_flag = 1;
ptp_unit.u3 |= 0x02;
// printf("Punch on\n");
break;
case 0x13: // PTR off
ptr_flag = 0;
// printf("Reader off-%d bytes read\n", ptr_unit.pos);
break;
case 0x14: // PTP off
ptp_flag = 0;
// printf("Punch off-%d bytes written\n", ptp_unit.pos);
break;
default: // ignore all other characters
break;
}
}
}
return (odata = 0);
}
/* because each port appears at 2 addresses and this fact is used
to determine if it is a MP-C or MP-S repeatedly in the SWTBUG
monitor, this code assures that reads of the high ports return
the same data as was read the last time on the low ports.
*/
int32 sio1s(int32 io, int32 data)
{
return status;
}
int32 sio1d(int32 io, int32 data)
{
return odata;
}
/* end of mp-s.c */

View File

@@ -0,0 +1,87 @@
/* mp-a_sys.c: SWTP 6800 system interface
Copyright (c) 2005, William Beech
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
WILLIAM A BEECH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of William A. Beech shall not
be used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from William A. Beech.
*/
#include <ctype.h>
#include <string.h>
#include "swtp_defs.h"
/* externals */
extern DEVICE CPU_BD_dev;
extern DEVICE m6800_dev;
extern REG m6800_reg[];
extern DEVICE BOOTROM_dev;
extern DEVICE m6810_dev;
extern DEVICE i2716_dev;
extern DEVICE MB_dev;
extern DEVICE sio_dev;
extern DEVICE ptr_dev;
extern DEVICE ptp_dev;
extern DEVICE mp_8m_dev;
extern DEVICE dsk_dev;
/* SCP data structures
sim_name simulator name string
sim_PC pointer to saved PC register descriptor
sim_emax number of words needed for examine
sim_devices array of pointers to simulated devices
sim_stop_messages array of pointers to stop messages
sim_load binary loader
*/
char sim_name[] = "SWTP 6800, V2, MP-A2 CPU Board";
REG *sim_PC = &m6800_reg[0];
int32 sim_emax = 4;
DEVICE *sim_devices[] = {
&CPU_BD_dev,
&m6800_dev,
&BOOTROM_dev,
&m6810_dev,
&i2716_dev,
&MB_dev,
&sio_dev,
&ptr_dev,
&ptp_dev,
&mp_8m_dev,
&dsk_dev,
NULL
};
const char *sim_stop_messages[] = {
"Unknown error",
"Unknown I/O Instruction",
"HALT instruction",
"Breakpoint",
"Invalid Opcode",
"Invalid Memory"
};
/* end of mp-a_sys.c */

View File

@@ -0,0 +1,85 @@
/* mp-a_sys.c: SWTP 6800 system interface
Copyright (c) 2005, William Beech
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
WILLIAM A BEECH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of William A. Beech shall not
be used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from William A. Beech.
*/
#include <ctype.h>
#include <string.h>
#include "swtp_defs.h"
/* externals */
extern DEVICE CPU_BD_dev;
extern DEVICE m6800_dev;
extern REG m6800_reg[];
extern DEVICE BOOTROM_dev;
extern DEVICE m6810_dev;
extern DEVICE MB_dev;
extern DEVICE sio_dev;
extern DEVICE ptr_dev;
extern DEVICE ptp_dev;
extern DEVICE mp_8m_dev;
extern DEVICE dsk_dev;
/* SCP data structures
sim_name simulator name string
sim_PC pointer to saved PC register descriptor
sim_emax number of words needed for examine
sim_devices array of pointers to simulated devices
sim_stop_messages array of pointers to stop messages
sim_load binary loader
*/
char sim_name[] = "SWTP 6800, V2, MP-A CPU Board";
REG *sim_PC = &m6800_reg[0];
int32 sim_emax = 4;
DEVICE *sim_devices[] = {
&CPU_BD_dev,
&m6800_dev,
&BOOTROM_dev,
&m6810_dev,
&MB_dev,
&sio_dev,
&ptr_dev,
&ptp_dev,
&mp_8m_dev,
&dsk_dev,
NULL
};
const char *sim_stop_messages[] = {
"Unknown error",
"Unknown I/O Instruction",
"HALT instruction",
"Breakpoint",
"Invalid Opcode",
"Invalid Memory"
};
/* end of mp-a_sys.c */

Binary file not shown.

View File

@@ -0,0 +1,8 @@
set bootrom 2708
attach bootrom swtbug.bin
set cpu hex
set cpu itrap
set cpu mtrap
reset
set mp-b2 bd0, bd1, bd2, bd3, bd4, bd5
g

View File

@@ -0,0 +1,9 @@
set bootrom 2708
attach bootrom swtbug.bin
set mp-a2 mon, lo_prom
set cpu hex
set cpu itrap
set cpu mtrap
reset
set mp-b2 bd0, bd1, bd2, bd3, bd4, bd5
g

View File

@@ -0,0 +1,55 @@
/* swtp_defs.h: SWTP 6800 simulator definitions
Copyright (c) 2005-2012, William Beech
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
WILLIAM A BEECH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of William A Beech shall not
be used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from William A Beech.
*/
#include <ctype.h>
#include "sim_defs.h" // simulator defs
/* Memory */
#define MAXMEMSIZE 65536 // max memory size
#define MEMSIZE (m6800_unit.capac) // actual memory size
#define ADDRMASK (MAXMEMSIZE - 1) // address mask
#define MEM_ADDR_OK(x) (((uint32) (x)) < MEMSIZE)
/* debug definitions */
#define DEBUG_flow 0x0001
#define DEBUG_read 0x0002
#define DEBUG_write 0x0004
#define DEBUG_level1 0x0008
#define DEBUG_level2 0x0010
#define DEBUG_reg 0x0020
#define DEBUG_asm 0x0040
#define DEBUG_all 0xFFFF
/* Simulator stop codes */
#define STOP_RSRV 1 // must be 1
#define STOP_HALT 2 // HALT-really WAI
#define STOP_IBKPT 3 // breakpoint
#define STOP_OPCODE 4 // invalid opcode
#define STOP_MEMORY 5 // invalid memory address