1
0
mirror of https://github.com/simh/simh.git synced 2026-01-25 19:56:25 +00:00

Notes For V3.5-0

The source set has been extensively overhauled.  For correct
viewing, set Visual C++ or Emacs to have tab stops every 4
characters.

1. New Features in 3.4-1

1.1 All Ethernet devices

- Added Windows user-defined adapter names (from Timothe Litt)

1.2 Interdata, SDS, HP, PDP-8, PDP-18b terminal multiplexors

- Added support for SET <unit>n DISCONNECT

1.3 VAX

- Added latent QDSS support
- Revised autoconfigure to handle QDSS

1.4 PDP-11

- Revised autoconfigure to handle more casees

2. Bugs Fixed in 3.4-1

2.1 SCP and libraries

- Trim trailing spaces on all input (for example, attach file names)
- Fixed sim_sock spurious SIGPIPE error in Unix/Linux
- Fixed sim_tape misallocation of TPC map array for 64b simulators

2.2 1401

- Fixed bug, CPU reset was clearing SSB through SSG

2.3 PDP-11

- Fixed bug in VH vector display routine
- Fixed XU runt packet processing (found by Tim Chapman)

2.4 Interdata

- Fixed bug in SHOW PAS CONN/STATS
- Fixed potential integer overflow exception in divide

2.5 SDS

- Fixed bug in SHOW MUX CONN/STATS

2.6 HP

- Fixed bug in SHOW MUX CONN/STATS

2.7 PDP-8

- Fixed bug in SHOW TTIX CONN/STATS
- Fixed bug in SET/SHOW TTOXn LOG

2.8 PDP-18b

- Fixed bug in SHOW TTIX CONN/STATS
- Fixed bug in SET/SHOW TTOXn LOG

2.9 Nova, Eclipse

- Fixed potential integer overflow exception in divide
This commit is contained in:
Bob Supnik
2005-09-09 18:09:00 -07:00
committed by Mark Pizzolato
parent ec60bbf329
commit b7c1eae41f
257 changed files with 107140 additions and 97195 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
/* altair_defs.h: MITS Altair simulator definitions
Copyright (c) 1997-2003, Charles E. Owen
Copyright (c) 1997-2005, Charles E. Owen
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
@@ -19,24 +19,24 @@
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 Charles E. Owen shall not
be used in advertising or otherwise to promote the sale, use or other dealings
Except as contained in this notice, the name of Charles E. Owen shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Charles E. Owen.
*/
#include "sim_defs.h" /* simulator defns */
#include "sim_defs.h" /* simulator defns */
/* Memory */
#define MAXMEMSIZE 65536 /* max memory size */
#define MEMSIZE (cpu_unit.capac) /* actual memory size */
#define ADDRMASK (MAXMEMSIZE - 1) /* address mask */
#define MAXMEMSIZE 65536 /* max memory size */
#define MEMSIZE (cpu_unit.capac) /* actual memory size */
#define ADDRMASK (MAXMEMSIZE - 1) /* address mask */
#define MEM_ADDR_OK(x) (((uint32) (x)) < MEMSIZE)
/* Simulator stop codes */
#define STOP_RSRV 1 /* must be 1 */
#define STOP_HALT 2 /* HALT */
#define STOP_IBKPT 3 /* breakpoint */
#define STOP_RSRV 1 /* must be 1 */
#define STOP_HALT 2 /* HALT */
#define STOP_IBKPT 3 /* breakpoint */
#define STOP_OPCODE 4

View File

@@ -1,6 +1,6 @@
/* altair_dsk.c: MITS Altair 88-DISK Simulator
Copyright (c) 1997-2003, Charles E. Owen
Copyright (c) 1997-2005, Charles E. Owen
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
@@ -19,11 +19,11 @@
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 Charles E. Owen shall not
be used in advertising or otherwise to promote the sale, use or other dealings
Except as contained in this notice, the name of Charles E. Owen shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Charles E. Owen.
The 88_DISK is a 8-inch floppy controller which can control up
The 88_DISK is a 8-inch floppy controller which can control up
to 16 daisy-chained Pertec FD-400 hard-sectored floppy drives.
Each diskette has physically 77 tracks of 32 137-byte sectors
each.
@@ -31,15 +31,15 @@
The controller is interfaced to the CPU by use of 3 I/O addreses,
standardly, these are device numbers 10, 11, and 12 (octal).
Address Mode Function
------- ---- --------
Address Mode Function
------- ---- --------
10 Out Selects and enables Controller and Drive
10 In Indicates status of Drive and Controller
11 Out Controls Disk Function
11 In Indicates current sector position of disk
12 Out Write data
12 In Read data
10 Out Selects and enables Controller and Drive
10 In Indicates status of Drive and Controller
11 Out Controls Disk Function
11 In Indicates current sector position of disk
12 Out Write data
12 In Read data
Drive Select Out (Device 10 OUT):
@@ -48,7 +48,7 @@
+---+---+---+---+---+---+---+---+
C = If this bit is 1, the disk controller selected by 'device' is
cleared. If the bit is zero, 'device' is selected as the
cleared. If the bit is zero, 'device' is selected as the
device being controlled by subsequent I/O operations.
X = not used
Device = value zero thru 15, selects drive to be controlled.
@@ -80,8 +80,8 @@
E - Enables interrupts (ignored this simulator)
D - Disables interrupts (ignored this simulator)
C - When 1 lowers head current (ignored this simulator)
W - When 1, starts Write Enable sequence: W bit on device 10
(see above) will go 1 and data will be read from port 12
W - When 1, starts Write Enable sequence: W bit on device 10
(see above) will go 1 and data will be read from port 12
until 137 bytes have been read by the controller from
that port. The W bit will go off then, and the sector data
will be written to disk. Before you do this, you must have
@@ -100,9 +100,9 @@
X = Not used
Sector number = binary of the sector number currently under the
head, 0-31.
head, 0-31.
T = Sector True, is a 1 when the sector is positioned to read or
write.
write.
*/
@@ -110,8 +110,8 @@
#include "altair_defs.h"
#define UNIT_V_ENABLE (UNIT_V_UF + 0) /* Write Enable */
#define UNIT_ENABLE (1 << UNIT_V_ENABLE)
#define UNIT_V_ENABLE (UNIT_V_UF + 0) /* Write Enable */
#define UNIT_ENABLE (1 << UNIT_V_ENABLE)
#define DSK_SECTSIZE 137
#define DSK_SECT 32
@@ -128,41 +128,43 @@ extern int32 PCX;
/* Global data on status */
int32 cur_disk = 8; /* Currently selected drive */
int32 cur_disk = 8; /* Currently selected drive */
int32 cur_track[9] = {0, 0, 0, 0, 0, 0, 0, 0, 377};
int32 cur_sect[9] = {0, 0, 0, 0, 0, 0, 0, 0, 377};
int32 cur_byte[9] = {0, 0, 0, 0, 0, 0, 0, 0, 377};
int32 cur_flags[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
char dskbuf[137]; /* Data Buffer */
int32 dirty = 0; /* 1 when buffer has unwritten data in it */
UNIT *dptr; /* fileref to write dirty buffer to */
char dskbuf[137]; /* Data Buffer */
int32 dirty = 0; /* 1 when buffer has unwritten data in it */
UNIT *dptr; /* fileref to write dirty buffer to */
int32 dsk_rwait = 100; /* rotate latency */
int32 dsk_rwait = 100; /* rotate latency */
/* 88DSK Standard I/O Data Structures */
UNIT dsk_unit[] = {
{ UDATA (&dsk_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE, DSK_SIZE) },
{ UDATA (&dsk_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE, DSK_SIZE) },
{ UDATA (&dsk_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE, DSK_SIZE) },
{ UDATA (&dsk_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE, DSK_SIZE) },
{ UDATA (&dsk_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE, DSK_SIZE) },
{ UDATA (&dsk_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE, DSK_SIZE) },
{ UDATA (&dsk_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE, DSK_SIZE) },
{ UDATA (&dsk_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE, DSK_SIZE) }
};
{ UDATA (&dsk_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE, DSK_SIZE) },
{ UDATA (&dsk_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE, DSK_SIZE) },
{ UDATA (&dsk_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE, DSK_SIZE) },
{ UDATA (&dsk_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE, DSK_SIZE) },
{ UDATA (&dsk_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE, DSK_SIZE) },
{ UDATA (&dsk_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE, DSK_SIZE) },
{ UDATA (&dsk_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE, DSK_SIZE) },
{ UDATA (&dsk_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE, DSK_SIZE) }
};
REG dsk_reg[] = {
{ ORDATA (DISK, cur_disk, 4) },
{ NULL } };
{ ORDATA (DISK, cur_disk, 4) },
{ NULL }
};
DEVICE dsk_dev = {
"DSK", dsk_unit, dsk_reg, NULL,
8, 10, 31, 1, 8, 8,
NULL, NULL, &dsk_reset,
NULL, NULL, NULL };
"DSK", dsk_unit, dsk_reg, NULL,
8, 10, 31, 1, 8, 8,
NULL, NULL, &dsk_reset,
NULL, NULL, NULL
};
/* Service routines to handle simlulator functions */
@@ -181,19 +183,19 @@ cur_disk = 0;
return SCPE_OK;
}
/* I/O instruction handlers, called from the CPU module when an
IN or OUT instruction is issued.
/* I/O instruction handlers, called from the CPU module when an
IN or OUT instruction is issued.
Each function is passed an 'io' flag, where 0 means a read from
the port, and 1 means a write to the port. On input, the actual
Each function is passed an 'io' flag, where 0 means a read from
the port, and 1 means a write to the port. On input, the actual
input is passed as the return value, on output, 'data' is written
to the device.
*/
/* Disk Controller Status/Select */
/* IMPORTANT: The status flags read by port 8 IN instruction are
INVERTED, that is, 0 is true and 1 is false. To handle this, the
/* IMPORTANT: The status flags read by port 8 IN instruction are
INVERTED, that is, 0 is true and 1 is false. To handle this, the
simulator keeps it's own status flags as 0=false, 1=true; and
returns the COMPLEMENT of the status flags when read. This makes
setting/testing of the flag bits more logical, yet meets the
@@ -203,28 +205,28 @@ return SCPE_OK;
int32 dsk10(int32 io, int32 data)
{
if (io == 0) { /* IN: return flags */
return ((~cur_flags[cur_disk]) & 0xFF); /* Return the COMPLEMENT! */
if (io == 0) { /* IN: return flags */
return ((~cur_flags[cur_disk]) & 0xFF); /* Return the COMPLEMENT! */
}
/* OUT: Controller set/reset/enable/disable */
if (dirty == 1)
writebuf();
writebuf();
/*printf("\n[%o] OUT 10: %x", PCX, data);*/
cur_disk = data & 0x0F;
if (data & 0x80) {
cur_flags[cur_disk] = 0; /* Disable drive */
cur_flags[cur_disk] = 0; /* Disable drive */
cur_sect[cur_disk = 0377];
cur_byte[cur_disk = 0377];
return (0);
}
cur_flags[cur_disk] = 0x1A; /* Enable: head move true */
cur_sect[cur_disk] = 0377; /* reset internal counters */
cur_flags[cur_disk] = 0x1A; /* Enable: head move true */
cur_sect[cur_disk] = 0377; /* reset internal counters */
cur_byte[cur_disk] = 0377;
if (cur_track[cur_disk] == 0)
cur_flags[cur_disk] |= 0x40; /* track 0 if there */
cur_flags[cur_disk] |= 0x40; /* track 0 if there */
return (0);
}
@@ -232,74 +234,74 @@ int32 dsk10(int32 io, int32 data)
int32 dsk11(int32 io, int32 data)
{
int32 stat;
int32 stat;
if (io == 0) { /* Read sector position */
/*printf("\n[%o] IN 11", PCX);*/
if (dirty == 1)
writebuf();
if (cur_flags[cur_disk] & 0x04) { /* head loaded? */
if (io == 0) { /* Read sector position */
/*printf("\n[%o] IN 11", PCX);*/
if (dirty == 1)
writebuf();
if (cur_flags[cur_disk] & 0x04) { /* head loaded? */
cur_sect[cur_disk]++;
if (cur_sect[cur_disk] > 31)
cur_sect[cur_disk] = 0;
cur_sect[cur_disk] = 0;
cur_byte[cur_disk] = 0377;
stat = cur_sect[cur_disk] << 1;
stat &= 0x3E; /* return 'sector true' bit = 0 (true) */
stat |= 0xC0; /* set on 'unused' bits */
stat = cur_sect[cur_disk] << 1;
stat &= 0x3E; /* return 'sector true' bit = 0 (true) */
stat |= 0xC0; /* set on 'unused' bits */
return (stat);
} else {
return (0); /* head not loaded - return 0 */
return (0); /* head not loaded - return 0 */
}
}
/* Drive functions */
if (cur_disk > 7)
return (0); /* no drive selected - can do nothin */
return (0); /* no drive selected - can do nothin */
/*printf("\n[%o] OUT 11: %x", PCX, data);*/
if (data & 0x01) { /* Step head in */
cur_track[cur_disk]++;
if (data & 0x01) { /* Step head in */
cur_track[cur_disk]++;
if (cur_track[cur_disk] > 76 )
cur_track[cur_disk] = 76;
if (dirty == 1)
writebuf();
cur_track[cur_disk] = 76;
if (dirty == 1)
writebuf();
cur_sect[cur_disk] = 0377;
cur_byte[cur_disk] = 0377;
}
if (data & 0x02) { /* Step head out */
cur_track[cur_disk]--;
if (data & 0x02) { /* Step head out */
cur_track[cur_disk]--;
if (cur_track[cur_disk] < 0) {
cur_track[cur_disk] = 0;
cur_flags[cur_disk] |= 0x40; /* track 0 if there */
cur_track[cur_disk] = 0;
cur_flags[cur_disk] |= 0x40; /* track 0 if there */
}
if (dirty == 1)
writebuf();
if (dirty == 1)
writebuf();
cur_sect[cur_disk] = 0377;
cur_byte[cur_disk] = 0377;
}
if (dirty == 1)
writebuf();
writebuf();
if (data & 0x04) { /* Head load */
cur_flags[cur_disk] |= 0x04; /* turn on head loaded bit */
cur_flags[cur_disk] |= 0x80; /* turn on 'read data available */
if (data & 0x04) { /* Head load */
cur_flags[cur_disk] |= 0x04; /* turn on head loaded bit */
cur_flags[cur_disk] |= 0x80; /* turn on 'read data available */
}
if (data & 0x08) { /* Head Unload */
cur_flags[cur_disk] &= 0xFB; /* off on 'head loaded' */
cur_flags[cur_disk] &= 0x7F; /* off on 'read data avail */
if (data & 0x08) { /* Head Unload */
cur_flags[cur_disk] &= 0xFB; /* off on 'head loaded' */
cur_flags[cur_disk] &= 0x7F; /* off on 'read data avail */
cur_sect[cur_disk] = 0377;
cur_byte[cur_disk] = 0377;
}
/* Interrupts & head current are ignored */
if (data & 0x80) { /* write sequence start */
if (data & 0x80) { /* write sequence start */
cur_byte[cur_disk] = 0;
cur_flags[cur_disk] |= 0x01; /* enter new write data on */
cur_flags[cur_disk] |= 0x01; /* enter new write data on */
}
return 0;
}
@@ -308,19 +310,19 @@ int32 dsk11(int32 io, int32 data)
int32 dsk12(int32 io, int32 data)
{
static int32 rtn, i;
static int32 rtn, i;
static long pos;
UNIT *uptr;
uptr = dsk_dev.units + cur_disk;
if (io == 0) {
if ((i = cur_byte[cur_disk]) < 138) { /* just get from buffer */
cur_byte[cur_disk]++;
return (dskbuf[i] & 0xFF);
if ((i = cur_byte[cur_disk]) < 138) { /* just get from buffer */
cur_byte[cur_disk]++;
return (dskbuf[i] & 0xFF);
}
/* physically read the sector */
/*printf("\n[%o] IN 12 (READ) T%d S%d", PCX, cur_track[cur_disk],
cur_sect[cur_disk]);*/
cur_sect[cur_disk]);*/
pos = DSK_TRACSIZE * cur_track[cur_disk];
pos += DSK_SECTSIZE * cur_sect[cur_disk];
rtn = fseek(uptr -> fileref, pos, 0);
@@ -328,9 +330,9 @@ int32 dsk12(int32 io, int32 data)
cur_byte[cur_disk] = 1;
return (dskbuf[0] & 0xFF);
} else {
if (cur_byte[cur_disk] > 136) {
i = cur_byte[cur_disk];
dskbuf[i] = data & 0xFF;
if (cur_byte[cur_disk] > 136) {
i = cur_byte[cur_disk];
dskbuf[i] = data & 0xFF;
writebuf();
return (0);
}
@@ -345,21 +347,21 @@ int32 dsk12(int32 io, int32 data)
void writebuf()
{
long pos;
long pos;
int32 rtn, i;
i = cur_byte[cur_disk]; /* null-fill rest of sector if any */
i = cur_byte[cur_disk]; /* null-fill rest of sector if any */
while (i < 138) {
dskbuf[i] = 0;
dskbuf[i] = 0;
i++;
}
/*printf("\n[%o] OUT 12 (WRITE) T%d S%d", PCX, cur_track[cur_disk],
cur_sect[cur_disk]); i = getch(); */
pos = DSK_TRACSIZE * cur_track[cur_disk]; /* calc file pos */
cur_sect[cur_disk]); i = getch(); */
pos = DSK_TRACSIZE * cur_track[cur_disk]; /* calc file pos */
pos += DSK_SECTSIZE * cur_sect[cur_disk];
rtn = fseek(dptr -> fileref, pos, 0);
rtn = fwrite(dskbuf, 137, 1, dptr -> fileref);
cur_flags[cur_disk] &= 0xFE; /* ENWD off */
cur_flags[cur_disk] &= 0xFE; /* ENWD off */
cur_byte[cur_disk] = 0377;
dirty = 0;
return;

View File

@@ -1,6 +1,6 @@
/* altair_sio: MITS Altair serial I/O card
Copyright (c) 1997-2003, Charles E. Owen
Copyright (c) 1997-2005, Charles E. Owen
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
@@ -19,11 +19,11 @@
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 Charles E. Owen shall not
be used in advertising or otherwise to promote the sale, use or other dealings
Except as contained in this notice, the name of Charles E. Owen shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Charles E. Owen.
These functions support a simulated MITS 2SIO interface card.
These functions support a simulated MITS 2SIO interface card.
The card had two physical I/O ports which could be connected
to any serial I/O device that would connect to a current loop,
RS232, or TTY interface. Available baud rates were jumper
@@ -35,13 +35,13 @@
A read of the status port gets the port status:
+---+---+---+---+---+---+---+---+
| X X X X X X O I |
| X X X X X X O I |
+---+---+---+---+---+---+---+---+
I - A 1 in this bit position means a character has been received
on the data port and is ready to be read.
I - A 1 in this bit position means a character has been received
on the data port and is ready to be read.
O - 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.
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.
@@ -51,8 +51,8 @@
#include "altair_defs.h"
#define UNIT_V_ANSI (UNIT_V_UF + 0) /* ANSI mode */
#define UNIT_ANSI (1 << UNIT_V_ANSI)
#define UNIT_V_ANSI (UNIT_V_UF + 0) /* ANSI mode */
#define UNIT_ANSI (1 << UNIT_V_ANSI)
t_stat sio_svc (UNIT *uptr);
t_stat sio_reset (DEVICE *dptr);
@@ -61,77 +61,81 @@ t_stat ptr_reset (DEVICE *dptr);
t_stat ptp_svc (UNIT *uptr);
t_stat ptp_reset (DEVICE *dptr);
int32 ptr_stopioe = 0, ptp_stopioe = 0; /* stop on error */
int32 ptr_stopioe = 0, ptp_stopioe = 0; /* stop on error */
/* 2SIO Standard I/O Data Structures */
UNIT sio_unit = { UDATA (&sio_svc, 0, 0),
KBD_POLL_WAIT };
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 } };
{ ORDATA (DATA, sio_unit.buf, 8) },
{ ORDATA (STAT, sio_unit.u3, 8) },
{ NULL }
};
MTAB sio_mod[] = {
{ UNIT_ANSI, 0, "TTY", "TTY", NULL },
{ UNIT_ANSI, UNIT_ANSI, "ANSI", "ANSI", NULL },
{ 0 } };
{ UNIT_ANSI, 0, "TTY", "TTY", NULL },
{ UNIT_ANSI, UNIT_ANSI, "ANSI", "ANSI", NULL },
{ 0 }
};
DEVICE sio_dev = {
"2SIO", &sio_unit, sio_reg, sio_mod,
1, 10, 31, 1, 8, 8,
NULL, NULL, &sio_reset,
NULL, NULL, NULL };
"2SIO", &sio_unit, sio_reg, sio_mod,
1, 10, 31, 1, 8, 8,
NULL, NULL, &sio_reset,
NULL, NULL, NULL
};
UNIT ptr_unit = { UDATA (&ptr_svc, UNIT_SEQ + UNIT_ATTABLE, 0),
KBD_POLL_WAIT };
UNIT ptr_unit = { UDATA (&ptr_svc, UNIT_SEQ + UNIT_ATTABLE, 0), KBD_POLL_WAIT };
REG ptr_reg[] = {
{ ORDATA (DATA, ptr_unit.buf, 8) },
{ ORDATA (STAT, ptr_unit.u3, 8) },
{ ORDATA (POS, ptr_unit.pos, T_ADDR_W) },
{ NULL } };
{ ORDATA (DATA, ptr_unit.buf, 8) },
{ ORDATA (STAT, ptr_unit.u3, 8) },
{ ORDATA (POS, ptr_unit.pos, T_ADDR_W) },
{ NULL }
};
DEVICE ptr_dev = {
"PTR", &ptr_unit, ptr_reg, NULL,
1, 10, 31, 1, 8, 8,
NULL, NULL, &ptr_reset,
NULL, NULL, NULL };
"PTR", &ptr_unit, ptr_reg, NULL,
1, 10, 31, 1, 8, 8,
NULL, NULL, &ptr_reset,
NULL, NULL, NULL
};
UNIT ptp_unit = { UDATA (&ptp_svc, UNIT_SEQ + UNIT_ATTABLE, 0),
KBD_POLL_WAIT };
UNIT ptp_unit = { UDATA (&ptp_svc, UNIT_SEQ + UNIT_ATTABLE, 0), KBD_POLL_WAIT };
REG ptp_reg[] = {
{ ORDATA (DATA, ptp_unit.buf, 8) },
{ ORDATA (STAT, ptp_unit.u3, 8) },
{ ORDATA (POS, ptp_unit.pos, T_ADDR_W) },
{ NULL } };
{ ORDATA (DATA, ptp_unit.buf, 8) },
{ ORDATA (STAT, ptp_unit.u3, 8) },
{ ORDATA (POS, ptp_unit.pos, T_ADDR_W) },
{ NULL }
};
DEVICE ptp_dev = {
"PTP", &ptp_unit, ptp_reg, NULL,
1, 10, 31, 1, 8, 8,
NULL, NULL, &ptp_reset,
NULL, NULL, NULL };
"PTP", &ptp_unit, ptp_reg, NULL,
1, 10, 31, 1, 8, 8,
NULL, NULL, &ptp_reset,
NULL, NULL, NULL
};
/* Service routines to handle simulator functions */
/* Service routines to handle simulator functions */
/* service routine - actually gets char & places in buffer */
int32 sio_svc (UNIT *uptr)
{
int32 temp;
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 & 0377; /* Save char */
sio_unit.u3 |= 0x01; /* Set status */
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 & 0377; /* Save char */
sio_unit.u3 |= 0x01; /* Set status */
/* Do any special character handling here */
/* Do any special character handling here */
sio_unit.pos++;
return SCPE_OK;
sio_unit.pos++;
return SCPE_OK;
}
@@ -142,7 +146,7 @@ int32 ptr_svc (UNIT *uptr)
int32 ptp_svc (UNIT *uptr)
{
return SCPE_OK;
return SCPE_OK;
}
@@ -150,60 +154,60 @@ int32 ptp_svc (UNIT *uptr)
int32 sio_reset (DEVICE *dptr)
{
sio_unit.buf = 0; /* Data */
sio_unit.u3 = 0x02; /* Status */
sim_activate (&sio_unit, sio_unit.wait); /* activate unit */
return SCPE_OK;
sio_unit.buf = 0; /* Data */
sio_unit.u3 = 0x02; /* Status */
sim_activate (&sio_unit, sio_unit.wait); /* activate unit */
return SCPE_OK;
}
int32 ptr_reset (DEVICE *dptr)
{
ptr_unit.buf = 0;
ptr_unit.u3 = 0x02;
sim_cancel (&ptr_unit); /* deactivate unit */
return SCPE_OK;
ptr_unit.buf = 0;
ptr_unit.u3 = 0x02;
sim_cancel (&ptr_unit); /* deactivate unit */
return SCPE_OK;
}
int32 ptp_reset (DEVICE *dptr)
{
ptp_unit.buf = 0;
ptp_unit.u3 = 0x02;
sim_cancel (&ptp_unit); /* deactivate unit */
return SCPE_OK;
ptp_unit.buf = 0;
ptp_unit.u3 = 0x02;
sim_cancel (&ptp_unit); /* deactivate unit */
return SCPE_OK;
}
/* I/O instruction handlers, called from the CPU module when an
IN or OUT instruction is issued.
/* I/O instruction handlers, called from the CPU module when an
IN or OUT instruction is issued.
Each function is passed an 'io' flag, where 0 means a read from
the port, and 1 means a write to the port. On input, the actual
Each function is passed an 'io' flag, where 0 means a read from
the port, and 1 means a write to the port. On input, the actual
input is passed as the return value, on output, 'data' is written
to the device.
*/
int32 sio0s(int32 io, int32 data)
{
if (io == 0) {
if (io == 0) {
return (sio_unit.u3);
} else {
if (data == 0x03) { /* reset port! */
sio_unit.u3 = 0x02;
if (data == 0x03) { /* reset port! */
sio_unit.u3 = 0x02;
sio_unit.buf = 0;
sio_unit.pos = 0;
}
return (0);
return (0);
}
}
int32 sio0d(int32 io, int32 data)
{
if (io == 0) {
if (io == 0) {
sio_unit.u3 = sio_unit.u3 & 0xFE;
return (sio_unit.buf);
} else {
sim_putchar(data);
sim_putchar(data);
}
return 0;
}
@@ -212,46 +216,46 @@ int32 sio0d(int32 io, int32 data)
int32 sio1s(int32 io, int32 data)
{
if (io == 0) {
if ((ptr_unit.flags & UNIT_ATT) == 0) /* attached? */
return 0x02;
if (ptr_unit.u3 != 0) /* No more data? */
return 0x02;
return (0x03); /* ready to read/write */
if (io == 0) {
if ((ptr_unit.flags & UNIT_ATT) == 0) /* attached? */
return 0x02;
if (ptr_unit.u3 != 0) /* No more data? */
return 0x02;
return (0x03); /* ready to read/write */
} else {
if (data == 0x03) {
ptr_unit.u3 = 0;
if (data == 0x03) {
ptr_unit.u3 = 0;
ptr_unit.buf = 0;
ptr_unit.pos = 0;
ptp_unit.u3 = 0;
ptp_unit.u3 = 0;
ptp_unit.buf = 0;
ptp_unit.pos = 0;
}
return (0);
return (0);
}
}
int32 sio1d(int32 io, int32 data)
{
int32 temp;
int32 temp;
UNIT *uptr;
if (io == 0) {
if ((ptr_unit.flags & UNIT_ATT) == 0) /* attached? */
if (io == 0) {
if ((ptr_unit.flags & UNIT_ATT) == 0) /* attached? */
return 0;
if (ptr_unit.u3 != 0)
return 0;
return 0;
uptr = ptr_dev.units;
if ((temp = getc(uptr -> fileref)) == EOF) { /* end of file? */
if ((temp = getc(uptr -> fileref)) == EOF) { /* end of file? */
ptr_unit.u3 = 0x01;
return 0;
}
ptr_unit.pos++;
ptr_unit.pos++;
return (temp & 0xFF);
} else {
uptr = ptp_dev.units;
putc(data, uptr -> fileref);
ptp_unit.pos++;
uptr = ptp_dev.units;
putc(data, uptr -> fileref);
ptp_unit.pos++;
}
return 0;
}

View File

@@ -1,6 +1,6 @@
/* altair_sys.c: MITS Altair system interface
Copyright (c) 1997-2003, Charles E. Owen
Copyright (c) 1997-2005, Charles E. Owen
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
@@ -19,8 +19,8 @@
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 Charles E. Owen shall not
be used in advertising or otherwise to promote the sale, use or other dealings
Except as contained in this notice, the name of Charles E. Owen shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Charles E. Owen.
*/
@@ -40,12 +40,12 @@ extern int32 saved_PC;
/* 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
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[] = "Altair 8800";
@@ -54,81 +54,88 @@ REG *sim_PC = &cpu_reg[0];
int32 sim_emax = 4;
DEVICE *sim_devices[] = { &cpu_dev, &sio_dev, &ptr_dev,
&ptp_dev, &dsk_dev, NULL };
DEVICE *sim_devices[] = {
&cpu_dev,
&sio_dev,
&ptr_dev,
&ptp_dev,
&dsk_dev,
NULL
};
const char *sim_stop_messages[] = {
"Unknown error",
"Unknown error",
"Unknown I/O Instruction",
"HALT instruction",
"HALT instruction",
"Breakpoint",
"Invalid Opcode" };
"Invalid Opcode"
};
static const char *opcode[] = {
"NOP", "LXI B", "STAX B", "INX B", /* 000-003 */
"INR B", "DCR B", "MVI B", "RLC", /* 004-007 */
"???", "DAD B", "LDAX B", "DCX B", /* 010-013 */
"INR C", "DCR C", "MVI C", "RRC", /* 014-017 */
"???", "LXI D", "STAX D", "INX D", /* 020-023 */
"INR D", "DCR D", "MVI D", "RAL", /* 024-027 */
"???", "DAD D", "LDAX D", "DCX D", /* 030-033 */
"INR E", "DCR E", "MVI E", "RAR", /* 034-037 */
"???", "LXI H", "SHLD", "INX H", /* 040-043 */
"INR H", "DCR H", "MVI H", "DAA", /* 044-047 */
"???", "DAD H", "LHLD", "DCX H", /* 050-053 */
"INR L", "DCR L", "MVI L", "CMA", /* 054-057 */
"???", "LXI SP", "STA", "INX SP", /* 060-063 */
"INR M", "DCR M", "MVI M", "STC", /* 064-067 */
"???", "DAD SP", "LDA", "DCX SP", /* 070-073 */
"INR A", "DCR A", "MVI A", "CMC", /* 074-077 */
"MOV B,B", "MOV B,C", "MOV B,D", "MOV B,E", /* 100-103 */
"MOV B,H", "MOV B,L", "MOV B,M", "MOV B,A", /* 104-107 */
"MOV C,B", "MOV C,C", "MOV C,D", "MOV C,E", /* 110-113 */
"MOV C,H", "MOV C,L", "MOV C,M", "MOV C,A", /* 114-117 */
"MOV D,B", "MOV D,C", "MOV D,D", "MOV D,E", /* 120-123 */
"MOV D,H", "MOV D,L", "MOV D,M", "MOV D,A", /* 124-127 */
"MOV E,B", "MOV E,C", "MOV E,D", "MOV E,E", /* 130-133 */
"MOV E,H", "MOV E,L", "MOV E,M", "MOV E,A", /* 134-137 */
"MOV H,B", "MOV H,C", "MOV H,D", "MOV H,E", /* 140-143 */
"MOV H,H", "MOV H,L", "MOV H,M", "MOV H,A", /* 144-147 */
"MOV L,B", "MOV L,C", "MOV L,D", "MOV L,E", /* 150-153 */
"MOV L,H", "MOV L,L", "MOV L,M", "MOV L,A", /* 154-157 */
"MOV M,B", "MOV M,C", "MOV M,D", "MOV M,E", /* 160-163 */
"MOV M,H", "MOV M,L", "HLT", "MOV M,A", /* 164-167 */
"MOV A,B", "MOV A,C", "MOV A,D", "MOV A,E", /* 170-173 */
"MOV A,H", "MOV A,L", "MOV A,M", "MOV A,A", /* 174-177 */
"ADD B", "ADD C", "ADD D", "ADD E", /* 200-203 */
"ADD H", "ADD L", "ADD M", "ADD A", /* 204-207 */
"ADC B", "ADC C", "ADC D", "ADC E", /* 210-213 */
"ADC H", "ADC L", "ADC M", "ADC A", /* 214-217 */
"SUB B", "SUB C", "SUB D", "SUB E", /* 220-223 */
"SUB H", "SUB L", "SUB M", "SUB A", /* 224-227 */
"SBB B", "SBB C", "SBB D", "SBB E", /* 230-233 */
"SBB H", "SBB L", "SBB M", "SBB A", /* 234-237 */
"ANA B", "ANA C", "ANA D", "ANA E", /* 240-243 */
"ANA H", "ANA L", "ANA M", "ANA A", /* 244-247 */
"XRA B", "XRA C", "XRA D", "XRA E", /* 250-253 */
"XRA H", "XRA L", "XRA M", "XRA A", /* 254-257 */
"ORA B", "ORA C", "ORA D", "ORA E", /* 260-263 */
"ORA H", "ORA L", "ORA M", "ORA A", /* 264-267 */
"CMP B", "CMP C", "CMP D", "CMP E", /* 270-273 */
"CMP H", "CMP L", "CMP M", "CMP A", /* 274-277 */
"RNZ", "POP B", "JNZ", "JMP", /* 300-303 */
"CNZ", "PUSH B", "ADI", "RST 0", /* 304-307 */
"RZ", "RET", "JZ", "???", /* 310-313 */
"CZ", "CALL", "ACI", "RST 1", /* 314-317 */
"RNC", "POP D", "JNC", "OUT", /* 320-323 */
"CNC", "PUSH D", "SUI", "RST 2", /* 324-327 */
"RC", "???", "JC", "IN", /* 330-333 */
"CC", "???", "SBI", "RST 3", /* 334-337 */
"RPO", "POP H", "JPO", "XTHL", /* 340-343 */
"CPO", "PUSH H", "ANI", "RST 4", /* 344-347 */
"RPE", "PCHL", "JPE", "XCHG", /* 350-353 */
"CPE", "???", "XRI", "RST 5", /* 354-357 */
"RP", "POP PSW", "JP", "DI", /* 360-363 */
"CP", "PUSH PSW", "ORI", "RST 6", /* 364-367 */
"RM", "SPHL", "JM", "EI", /* 370-373 */
"CM", "???", "CPI", "RST 7", /* 374-377 */
"NOP", "LXI B", "STAX B", "INX B", /* 000-003 */
"INR B", "DCR B", "MVI B", "RLC", /* 004-007 */
"???", "DAD B", "LDAX B", "DCX B", /* 010-013 */
"INR C", "DCR C", "MVI C", "RRC", /* 014-017 */
"???", "LXI D", "STAX D", "INX D", /* 020-023 */
"INR D", "DCR D", "MVI D", "RAL", /* 024-027 */
"???", "DAD D", "LDAX D", "DCX D", /* 030-033 */
"INR E", "DCR E", "MVI E", "RAR", /* 034-037 */
"???", "LXI H", "SHLD", "INX H", /* 040-043 */
"INR H", "DCR H", "MVI H", "DAA", /* 044-047 */
"???", "DAD H", "LHLD", "DCX H", /* 050-053 */
"INR L", "DCR L", "MVI L", "CMA", /* 054-057 */
"???", "LXI SP", "STA", "INX SP", /* 060-063 */
"INR M", "DCR M", "MVI M", "STC", /* 064-067 */
"???", "DAD SP", "LDA", "DCX SP", /* 070-073 */
"INR A", "DCR A", "MVI A", "CMC", /* 074-077 */
"MOV B,B", "MOV B,C", "MOV B,D", "MOV B,E", /* 100-103 */
"MOV B,H", "MOV B,L", "MOV B,M", "MOV B,A", /* 104-107 */
"MOV C,B", "MOV C,C", "MOV C,D", "MOV C,E", /* 110-113 */
"MOV C,H", "MOV C,L", "MOV C,M", "MOV C,A", /* 114-117 */
"MOV D,B", "MOV D,C", "MOV D,D", "MOV D,E", /* 120-123 */
"MOV D,H", "MOV D,L", "MOV D,M", "MOV D,A", /* 124-127 */
"MOV E,B", "MOV E,C", "MOV E,D", "MOV E,E", /* 130-133 */
"MOV E,H", "MOV E,L", "MOV E,M", "MOV E,A", /* 134-137 */
"MOV H,B", "MOV H,C", "MOV H,D", "MOV H,E", /* 140-143 */
"MOV H,H", "MOV H,L", "MOV H,M", "MOV H,A", /* 144-147 */
"MOV L,B", "MOV L,C", "MOV L,D", "MOV L,E", /* 150-153 */
"MOV L,H", "MOV L,L", "MOV L,M", "MOV L,A", /* 154-157 */
"MOV M,B", "MOV M,C", "MOV M,D", "MOV M,E", /* 160-163 */
"MOV M,H", "MOV M,L", "HLT", "MOV M,A", /* 164-167 */
"MOV A,B", "MOV A,C", "MOV A,D", "MOV A,E", /* 170-173 */
"MOV A,H", "MOV A,L", "MOV A,M", "MOV A,A", /* 174-177 */
"ADD B", "ADD C", "ADD D", "ADD E", /* 200-203 */
"ADD H", "ADD L", "ADD M", "ADD A", /* 204-207 */
"ADC B", "ADC C", "ADC D", "ADC E", /* 210-213 */
"ADC H", "ADC L", "ADC M", "ADC A", /* 214-217 */
"SUB B", "SUB C", "SUB D", "SUB E", /* 220-223 */
"SUB H", "SUB L", "SUB M", "SUB A", /* 224-227 */
"SBB B", "SBB C", "SBB D", "SBB E", /* 230-233 */
"SBB H", "SBB L", "SBB M", "SBB A", /* 234-237 */
"ANA B", "ANA C", "ANA D", "ANA E", /* 240-243 */
"ANA H", "ANA L", "ANA M", "ANA A", /* 244-247 */
"XRA B", "XRA C", "XRA D", "XRA E", /* 250-253 */
"XRA H", "XRA L", "XRA M", "XRA A", /* 254-257 */
"ORA B", "ORA C", "ORA D", "ORA E", /* 260-263 */
"ORA H", "ORA L", "ORA M", "ORA A", /* 264-267 */
"CMP B", "CMP C", "CMP D", "CMP E", /* 270-273 */
"CMP H", "CMP L", "CMP M", "CMP A", /* 274-277 */
"RNZ", "POP B", "JNZ", "JMP", /* 300-303 */
"CNZ", "PUSH B", "ADI", "RST 0", /* 304-307 */
"RZ", "RET", "JZ", "???", /* 310-313 */
"CZ", "CALL", "ACI", "RST 1", /* 314-317 */
"RNC", "POP D", "JNC", "OUT", /* 320-323 */
"CNC", "PUSH D", "SUI", "RST 2", /* 324-327 */
"RC", "???", "JC", "IN", /* 330-333 */
"CC", "???", "SBI", "RST 3", /* 334-337 */
"RPO", "POP H", "JPO", "XTHL", /* 340-343 */
"CPO", "PUSH H", "ANI", "RST 4", /* 344-347 */
"RPE", "PCHL", "JPE", "XCHG", /* 350-353 */
"CPE", "???", "XRI", "RST 5", /* 354-357 */
"RP", "POP PSW", "JP", "DI", /* 360-363 */
"CP", "PUSH PSW", "ORI", "RST 6", /* 364-367 */
"RM", "SPHL", "JM", "EI", /* 370-373 */
"CM", "???", "CPI", "RST 7", /* 374-377 */
};
int32 oplen[256] = {
@@ -140,7 +147,7 @@ int32 oplen[256] = {
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,3,3,3,1,2,1,1,1,3,0,3,3,2,1,1,1,3,2,3,1,2,1,1,0,3,2,3,0,2,1,
1,1,3,1,3,1,2,1,1,1,3,1,3,0,2,1,1,1,3,1,3,1,2,1,1,1,3,1,3,0,2,1 };
/* This is the binary loader. The input file is considered to be
a string of literal bytes with no format special format. The
load starts at the current value of the PC.
@@ -153,28 +160,28 @@ int32 i, addr = 0, cnt = 0;
if ((*cptr != 0) || (flag != 0)) return SCPE_ARG;
addr = saved_PC;
while ((i = getc (fileref)) != EOF) {
M[addr] = i;
addr++;
cnt++;
} /* end while */
M[addr] = i;
addr++;
cnt++;
} /* end while */
printf ("%d Bytes loaded.\n", cnt);
return (SCPE_OK);
}
/* Symbolic output
Inputs:
*of = output stream
addr = current PC
*val = pointer to values
*uptr = pointer to unit
sw = switches
*of = output stream
addr = current PC
*val = pointer to values
*uptr = pointer to unit
sw = switches
Outputs:
status = error code
status = error code
*/
int32 fprint_sym (FILE *of, int32 addr, uint32 *val,
UNIT *uptr, int32 sw)
UNIT *uptr, int32 sw)
{
int32 cflag, c1, c2, inst, adr;
@@ -182,42 +189,44 @@ cflag = (uptr == NULL) || (uptr == &cpu_unit);
c1 = (val[0] >> 8) & 0177;
c2 = val[0] & 0177;
if (sw & SWMASK ('A')) {
fprintf (of, (c2 < 040)? "<%03o>": "%c", c2);
return SCPE_OK; }
fprintf (of, (c2 < 040)? "<%03o>": "%c", c2);
return SCPE_OK;
}
if (sw & SWMASK ('C')) {
fprintf (of, (c1 < 040)? "<%03o>": "%c", c1);
fprintf (of, (c2 < 040)? "<%03o>": "%c", c2);
return SCPE_OK; }
fprintf (of, (c1 < 040)? "<%03o>": "%c", c1);
fprintf (of, (c2 < 040)? "<%03o>": "%c", c2);
return SCPE_OK;
}
if (!(sw & SWMASK ('M'))) return SCPE_ARG;
inst = val[0];
fprintf (of, "%s", opcode[inst]);
if (oplen[inst] == 2) {
if (strchr(opcode[inst], ' ') != NULL)
fprintf (of, ",");
else fprintf (of, " ");
fprintf (of, "%o", val[1]);
if (strchr(opcode[inst], ' ') != NULL)
fprintf (of, ",");
else fprintf (of, " ");
fprintf (of, "%o", val[1]);
}
if (oplen[inst] == 3) {
adr = val[1] & 0xFF;
adr |= (val[2] << 8) & 0xff00;
if (strchr(opcode[inst], ' ') != NULL)
fprintf (of, ",");
else fprintf (of, " ");
if (strchr(opcode[inst], ' ') != NULL)
fprintf (of, ",");
else fprintf (of, " ");
fprintf (of, "%o", adr);
}
return -(oplen[inst] - 1);
}
/* Symbolic input
Inputs:
*cptr = pointer to input string
addr = current PC
*uptr = pointer to unit
*val = pointer to output values
sw = switches
*cptr = pointer to input string
addr = current PC
*uptr = pointer to unit
*val = pointer to output values
sw = switches
Outputs:
status = error status
status = error status
*/
int32 parse_sym (char *cptr, int32 addr, UNIT *uptr, uint32 *val, int32 sw)
@@ -226,25 +235,27 @@ int32 cflag, i = 0, j, r;
char gbuf[CBUFSIZE];
cflag = (uptr == NULL) || (uptr == &cpu_unit);
while (isspace (*cptr)) cptr++; /* absorb spaces */
while (isspace (*cptr)) cptr++; /* absorb spaces */
if ((sw & SWMASK ('A')) || ((*cptr == '\'') && cptr++)) { /* ASCII char? */
if (cptr[0] == 0) return SCPE_ARG; /* must have 1 char */
val[0] = (uint32) cptr[0];
return SCPE_OK; }
if (cptr[0] == 0) return SCPE_ARG; /* must have 1 char */
val[0] = (uint32) cptr[0];
return SCPE_OK;
}
if ((sw & SWMASK ('C')) || ((*cptr == '"') && cptr++)) { /* ASCII string? */
if (cptr[0] == 0) return SCPE_ARG; /* must have 1 char */
val[0] = ((uint32) cptr[0] << 8) + (uint32) cptr[1];
return SCPE_OK; }
if (cptr[0] == 0) return SCPE_ARG; /* must have 1 char */
val[0] = ((uint32) cptr[0] << 8) + (uint32) cptr[1];
return SCPE_OK;
}
/* An instruction: get opcode (all characters until null, comma,
or numeric (including spaces).
*/
while (1) {
if (*cptr == ',' || *cptr == '\0' ||
isdigit(*cptr))
break;
gbuf[i] = toupper(*cptr);
if (*cptr == ',' || *cptr == '\0' ||
isdigit(*cptr))
break;
gbuf[i] = toupper(*cptr);
cptr++;
i++;
}
@@ -252,9 +263,9 @@ while (1) {
/* Allow for RST which has numeric as part of opcode */
if (toupper(gbuf[0]) == 'R' &&
toupper(gbuf[1]) == 'S' &&
toupper(gbuf[1]) == 'S' &&
toupper(gbuf[2]) == 'T') {
gbuf[i] = toupper(*cptr);
gbuf[i] = toupper(*cptr);
cptr++;
i++;
}
@@ -262,9 +273,9 @@ if (toupper(gbuf[0]) == 'R' &&
/* Allow for 'MOV' which is only opcode that has comma in it. */
if (toupper(gbuf[0]) == 'M' &&
toupper(gbuf[1]) == 'O' &&
toupper(gbuf[1]) == 'O' &&
toupper(gbuf[2]) == 'V') {
gbuf[i] = toupper(*cptr);
gbuf[i] = toupper(*cptr);
cptr++;
i++;
gbuf[i] = toupper(*cptr);
@@ -275,25 +286,25 @@ if (toupper(gbuf[0]) == 'M' &&
/* kill trailing spaces if any */
gbuf[i] = '\0';
for (j = i - 1; gbuf[j] == ' '; j--) {
gbuf[j] = '\0';
gbuf[j] = '\0';
}
/* find opcode in table */
for (j = 0; j < 256; j++) {
if (strcmp(gbuf, opcode[j]) == 0)
break;
if (strcmp(gbuf, opcode[j]) == 0)
break;
}
if (j > 255) /* not found */
return SCPE_ARG;
if (j > 255) /* not found */
return SCPE_ARG;
val[0] = j; /* store opcode */
if (oplen[j] < 2) /* if 1-byter we are done */
return SCPE_OK;
val[0] = j; /* store opcode */
if (oplen[j] < 2) /* if 1-byter we are done */
return SCPE_OK;
if (*cptr == ',') cptr++;
cptr = get_glyph(cptr, gbuf, 0); /* get address */
cptr = get_glyph(cptr, gbuf, 0); /* get address */
sscanf(gbuf, "%o", &r);
if (oplen[j] == 2) {
val[1] = r & 0xFF;
val[1] = r & 0xFF;
return (-1);
}
val[1] = r & 0xFF;