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:
231
swtp6800/common/bootrom.c
Normal file
231
swtp6800/common/bootrom.c
Normal 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
570
swtp6800/common/dc-4.c
Normal 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
221
swtp6800/common/i2716.c
Normal 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
2018
swtp6800/common/m6800.c
Normal file
File diff suppressed because it is too large
Load Diff
146
swtp6800/common/m6810.c
Normal file
146
swtp6800/common/m6810.c
Normal 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
209
swtp6800/common/mp-8m.c
Normal 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
211
swtp6800/common/mp-a.c
Normal 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
263
swtp6800/common/mp-a2.c
Normal 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
322
swtp6800/common/mp-b2.c
Normal 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
330
swtp6800/common/mp-s.c
Normal 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 */
|
||||
87
swtp6800/swtp6800/mp-a2_sys.c
Normal file
87
swtp6800/swtp6800/mp-a2_sys.c
Normal 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 */
|
||||
85
swtp6800/swtp6800/mp-a_sys.c
Normal file
85
swtp6800/swtp6800/mp-a_sys.c
Normal 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 */
|
||||
BIN
swtp6800/swtp6800/swtbug.bin
Normal file
BIN
swtp6800/swtp6800/swtbug.bin
Normal file
Binary file not shown.
8
swtp6800/swtp6800/swtp6800mp-a.ini
Normal file
8
swtp6800/swtp6800/swtp6800mp-a.ini
Normal 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
|
||||
9
swtp6800/swtp6800/swtp6800mp-a2.ini
Normal file
9
swtp6800/swtp6800/swtp6800mp-a2.ini
Normal 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
|
||||
55
swtp6800/swtp6800/swtp_defs.h
Normal file
55
swtp6800/swtp6800/swtp_defs.h
Normal 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
|
||||
|
||||
Reference in New Issue
Block a user