ALPHA, ALTAIR, AltairZ80, I7094, NOVA, PDP1, PDP10, PDP11, PDP18B, PDP8, SAGE, sigma, swtp6800, TX-0, VAX: Change tabs to spaces which had crept in over time
This commit is contained in:
parent
1d3ac294c4
commit
66dba79418
87 changed files with 8311 additions and 8311 deletions
|
@ -24,19 +24,19 @@
|
|||
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 MEM_ADDR_OK(x) (((uint32) (x)) < MEMSIZE)
|
||||
#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_OPCODE 4
|
||||
#define STOP_RSRV 1 /* must be 1 */
|
||||
#define STOP_HALT 2 /* HALT */
|
||||
#define STOP_IBKPT 3 /* breakpoint */
|
||||
#define STOP_OPCODE 4
|
||||
|
||||
|
|
|
@ -106,28 +106,28 @@
|
|||
T = Sector True, is a 0 when the sector is positioned to read or
|
||||
write.
|
||||
|
||||
----------------------------------------------------------
|
||||
----------------------------------------------------------
|
||||
|
||||
5/22/2014 - Updated by Mike Douglas to support the Altair Minidisk.
|
||||
This disk uses 35 (vs 70) tracks of 16 (vs 32) sectors
|
||||
of 137 bytes each.
|
||||
5/22/2014 - Updated by Mike Douglas to support the Altair Minidisk.
|
||||
This disk uses 35 (vs 70) tracks of 16 (vs 32) sectors
|
||||
of 137 bytes each.
|
||||
|
||||
6/30/2014 - When the disk is an Altair Minidisk, load the head as
|
||||
soon as the disk is enabled, and ignore the head
|
||||
unload command (both like the real hardware).
|
||||
6/30/2014 - When the disk is an Altair Minidisk, load the head as
|
||||
soon as the disk is enabled, and ignore the head
|
||||
unload command (both like the real hardware).
|
||||
|
||||
7/13/2014 - This code previously returned zero when the sector position
|
||||
register was read with the head not loaded. This zero looks
|
||||
like an asserted "Sector True" flag for sector zero. The real
|
||||
hardware returns 0xff in this case. The same problem occurs
|
||||
when the drive is deselected - the sector position register
|
||||
returned zero instead of 0xff. These have been corrected.
|
||||
7/13/2014 - This code previously returned zero when the sector position
|
||||
register was read with the head not loaded. This zero looks
|
||||
like an asserted "Sector True" flag for sector zero. The real
|
||||
hardware returns 0xff in this case. The same problem occurs
|
||||
when the drive is deselected - the sector position register
|
||||
returned zero instead of 0xff. These have been corrected.
|
||||
|
||||
7/13/2014 Some software for the Altair skips a sector by verifying
|
||||
that "Sector True" goes false. Previously, this code
|
||||
returned "Sector True" every time the sector register
|
||||
was read. Now the flag alternates true and false on
|
||||
subsequent reads of the sector register.
|
||||
7/13/2014 Some software for the Altair skips a sector by verifying
|
||||
that "Sector True" goes false. Previously, this code
|
||||
returned "Sector True" every time the sector register
|
||||
was read. Now the flag alternates true and false on
|
||||
subsequent reads of the sector register.
|
||||
*/
|
||||
|
||||
#include "altairz80_defs.h"
|
||||
|
@ -153,9 +153,9 @@
|
|||
#define NUM_OF_DSK_MASK (NUM_OF_DSK - 1)
|
||||
#define BOOTROM_SIZE_DSK 256 /* size of boot rom */
|
||||
|
||||
#define MINI_DISK_SECT 16 /* mini disk sectors per track */
|
||||
#define MINI_DISK_TRACKS 35 /* number of tracks on mini disk */
|
||||
#define MINI_DISK_SIZE (MINI_DISK_TRACKS * MINI_DISK_SECT * DSK_SECTSIZE)
|
||||
#define MINI_DISK_SECT 16 /* mini disk sectors per track */
|
||||
#define MINI_DISK_TRACKS 35 /* number of tracks on mini disk */
|
||||
#define MINI_DISK_SIZE (MINI_DISK_TRACKS * MINI_DISK_SECT * DSK_SECTSIZE)
|
||||
#define MINI_DISK_DELTA 4096 /* threshold for detecting mini disks */
|
||||
|
||||
int32 dsk10(const int32 port, const int32 io, const int32 data);
|
||||
|
@ -183,7 +183,7 @@ static int32 current_track [NUM_OF_DSK] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|||
static int32 current_sector [NUM_OF_DSK] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
static int32 current_byte [NUM_OF_DSK] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
static int32 current_flag [NUM_OF_DSK] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
static int32 sectors_per_track [NUM_OF_DSK] = { DSK_SECT, DSK_SECT, DSK_SECT, DSK_SECT,
|
||||
static int32 sectors_per_track [NUM_OF_DSK] = { DSK_SECT, DSK_SECT, DSK_SECT, DSK_SECT,
|
||||
DSK_SECT, DSK_SECT, DSK_SECT, DSK_SECT,
|
||||
DSK_SECT, DSK_SECT, DSK_SECT, DSK_SECT,
|
||||
DSK_SECT, DSK_SECT, DSK_SECT, DSK_SECT };
|
||||
|
@ -201,7 +201,7 @@ static int32 warnDSK10 = 0;
|
|||
static int32 warnDSK11 = 0;
|
||||
static int32 warnDSK12 = 0;
|
||||
static int8 dskbuf[DSK_SECTSIZE]; /* data Buffer */
|
||||
static int32 sector_true = 0; /* sector true flag for sector register read */
|
||||
static int32 sector_true = 0; /* sector true flag for sector register read */
|
||||
|
||||
const static int32 alt_bootrom_dsk[BOOTROM_SIZE_DSK] = { // boot ROM for mini disk support
|
||||
0x21, 0x13, 0xff, 0x11, 0x00, 0x4c, 0x0e, 0xe3, /* ff00-ff07 */
|
||||
|
@ -396,7 +396,7 @@ static t_stat dsk_reset(DEVICE *dptr) {
|
|||
|
||||
static t_stat dsk_attach(UNIT *uptr, char *cptr) {
|
||||
int32 thisUnitIndex;
|
||||
int32 imageSize;
|
||||
int32 imageSize;
|
||||
const t_stat r = attach_unit(uptr, cptr); /* attach unit */
|
||||
if (r != SCPE_OK) /* error? */
|
||||
return r;
|
||||
|
@ -408,7 +408,7 @@ static t_stat dsk_attach(UNIT *uptr, char *cptr) {
|
|||
/* If the file size is close to the mini-disk image size, set the number of
|
||||
tracks to 16, otherwise, 32 sectors per track. */
|
||||
|
||||
imageSize = sim_fsize(uptr -> fileref);
|
||||
imageSize = sim_fsize(uptr -> fileref);
|
||||
sectors_per_track[thisUnitIndex] = (((MINI_DISK_SIZE - MINI_DISK_DELTA < imageSize) &&
|
||||
(imageSize < MINI_DISK_SIZE + MINI_DISK_DELTA)) ?
|
||||
MINI_DISK_SECT : DSK_SECT);
|
||||
|
@ -547,15 +547,15 @@ int32 dsk10(const int32 port, const int32 io, const int32 data) {
|
|||
else {
|
||||
current_sector[current_disk] = 0xff; /* reset internal counters */
|
||||
current_byte[current_disk] = 0xff;
|
||||
if (data & 0x80) /* disable drive? */
|
||||
current_flag[current_disk] = 0; /* yes, clear all flags */
|
||||
else { /* enable drive */
|
||||
current_flag[current_disk] = 0x1a; /* move head true */
|
||||
if (current_track[current_disk] == 0) /* track 0? */
|
||||
current_flag[current_disk] |= 0x40; /* yes, set track 0 true as well */
|
||||
if (sectors_per_track[current_disk] == MINI_DISK_SECT) /* drive enable loads head for Minidisk */
|
||||
current_flag[current_disk] |= 0x84;
|
||||
}
|
||||
if (data & 0x80) /* disable drive? */
|
||||
current_flag[current_disk] = 0; /* yes, clear all flags */
|
||||
else { /* enable drive */
|
||||
current_flag[current_disk] = 0x1a; /* move head true */
|
||||
if (current_track[current_disk] == 0) /* track 0? */
|
||||
current_flag[current_disk] |= 0x40; /* yes, set track 0 true as well */
|
||||
if (sectors_per_track[current_disk] == MINI_DISK_SECT) /* drive enable loads head for Minidisk */
|
||||
current_flag[current_disk] |= 0x84;
|
||||
}
|
||||
}
|
||||
return 0; /* ignored since OUT */
|
||||
}
|
||||
|
@ -587,13 +587,13 @@ int32 dsk11(const int32 port, const int32 io, const int32 data) {
|
|||
if (dirty) /* implies that current_disk < NUM_OF_DSK */
|
||||
writebuf();
|
||||
if (current_flag[current_disk] & 0x04) { /* head loaded? */
|
||||
sector_true ^= 1; /* return sector true every other entry */
|
||||
if (sector_true == 0) { /* true when zero */
|
||||
sector_true ^= 1; /* return sector true every other entry */
|
||||
if (sector_true == 0) { /* true when zero */
|
||||
current_sector[current_disk]++;
|
||||
if (current_sector[current_disk] >= sectors_per_track[current_disk])
|
||||
current_sector[current_disk] = 0;
|
||||
current_byte[current_disk] = 0xff;
|
||||
}
|
||||
}
|
||||
return (((current_sector[current_disk] << 1) & 0x3e) /* return sector number and...) */
|
||||
| 0xc0 | sector_true); /* sector true, and set 'unused' bits */
|
||||
} else
|
||||
|
@ -611,7 +611,7 @@ int32 dsk11(const int32 port, const int32 io, const int32 data) {
|
|||
current_disk, PCX);
|
||||
}
|
||||
current_track[current_disk]++;
|
||||
current_flag[current_disk] &= 0xbf; /* mwd 1/29/13: track zero now false */
|
||||
current_flag[current_disk] &= 0xbf; /* mwd 1/29/13: track zero now false */
|
||||
if (current_track[current_disk] > (tracks[current_disk] - 1))
|
||||
current_track[current_disk] = (tracks[current_disk] - 1);
|
||||
if (dirty) /* implies that current_disk < NUM_OF_DSK */
|
||||
|
|
|
@ -6425,10 +6425,10 @@ void m68k_op_bfffo_32_d(void)
|
|||
width = ((width-1) & 31) + 1;
|
||||
|
||||
data = ROL_32(data, offset);
|
||||
FLAG_N = (uint)(NFLAG_32(data));
|
||||
FLAG_N = (uint)(NFLAG_32(data));
|
||||
data >>= 32 - width;
|
||||
|
||||
FLAG_Z = (uint)data;
|
||||
FLAG_Z = (uint)data;
|
||||
FLAG_V = VFLAG_CLEAR;
|
||||
FLAG_C = CFLAG_CLEAR;
|
||||
|
||||
|
@ -6833,8 +6833,8 @@ void m68k_op_bfins_32_d(void)
|
|||
mask = ROR_32(mask, offset);
|
||||
|
||||
insert = MASK_OUT_ABOVE_32(insert << (32 - width));
|
||||
FLAG_N = (uint)(NFLAG_32(insert));
|
||||
FLAG_Z = (uint)insert;
|
||||
FLAG_N = (uint)(NFLAG_32(insert));
|
||||
FLAG_Z = (uint)insert;
|
||||
insert = ROR_32(insert, offset);
|
||||
|
||||
FLAG_V = VFLAG_CLEAR;
|
||||
|
|
|
@ -1139,11 +1139,11 @@ void m68k_op_divl_32_d(void)
|
|||
}
|
||||
}
|
||||
|
||||
REG_D[word2 & 7] = (uint)remainder;
|
||||
REG_D[(word2 >> 12) & 7] = (uint)quotient;
|
||||
REG_D[word2 & 7] = (uint)remainder;
|
||||
REG_D[(word2 >> 12) & 7] = (uint)quotient;
|
||||
|
||||
FLAG_N = (uint)(NFLAG_32(quotient));
|
||||
FLAG_Z = (uint)quotient;
|
||||
FLAG_N = (uint)(NFLAG_32(quotient));
|
||||
FLAG_Z = (uint)quotient;
|
||||
FLAG_V = VFLAG_CLEAR;
|
||||
FLAG_C = CFLAG_CLEAR;
|
||||
return;
|
||||
|
@ -1350,11 +1350,11 @@ void m68k_op_divl_32_ai(void)
|
|||
}
|
||||
}
|
||||
|
||||
REG_D[word2 & 7] = (uint)remainder;
|
||||
REG_D[(word2 >> 12) & 7] = (uint)quotient;
|
||||
REG_D[word2 & 7] = (uint)remainder;
|
||||
REG_D[(word2 >> 12) & 7] = (uint)quotient;
|
||||
|
||||
FLAG_N = (uint)NFLAG_32(quotient);
|
||||
FLAG_Z = (uint)quotient;
|
||||
FLAG_N = (uint)NFLAG_32(quotient);
|
||||
FLAG_Z = (uint)quotient;
|
||||
FLAG_V = VFLAG_CLEAR;
|
||||
FLAG_C = CFLAG_CLEAR;
|
||||
return;
|
||||
|
@ -1561,11 +1561,11 @@ void m68k_op_divl_32_pi(void)
|
|||
}
|
||||
}
|
||||
|
||||
REG_D[word2 & 7] = (uint)remainder;
|
||||
REG_D[(word2 >> 12) & 7] = (uint)quotient;
|
||||
REG_D[word2 & 7] = (uint)remainder;
|
||||
REG_D[(word2 >> 12) & 7] = (uint)quotient;
|
||||
|
||||
FLAG_N = (uint)NFLAG_32(quotient);
|
||||
FLAG_Z = (uint)quotient;
|
||||
FLAG_N = (uint)NFLAG_32(quotient);
|
||||
FLAG_Z = (uint)quotient;
|
||||
FLAG_V = VFLAG_CLEAR;
|
||||
FLAG_C = CFLAG_CLEAR;
|
||||
return;
|
||||
|
@ -1772,11 +1772,11 @@ void m68k_op_divl_32_pd(void)
|
|||
}
|
||||
}
|
||||
|
||||
REG_D[word2 & 7] = (uint)remainder;
|
||||
REG_D[(word2 >> 12) & 7] = (uint)quotient;
|
||||
REG_D[word2 & 7] = (uint)remainder;
|
||||
REG_D[(word2 >> 12) & 7] = (uint)quotient;
|
||||
|
||||
FLAG_N = (uint)NFLAG_32(quotient);
|
||||
FLAG_Z = (uint)quotient;
|
||||
FLAG_N = (uint)NFLAG_32(quotient);
|
||||
FLAG_Z = (uint)quotient;
|
||||
FLAG_V = VFLAG_CLEAR;
|
||||
FLAG_C = CFLAG_CLEAR;
|
||||
return;
|
||||
|
@ -1983,11 +1983,11 @@ void m68k_op_divl_32_di(void)
|
|||
}
|
||||
}
|
||||
|
||||
REG_D[word2 & 7] = (uint)remainder;
|
||||
REG_D[(word2 >> 12) & 7] = (uint)quotient;
|
||||
REG_D[word2 & 7] = (uint)remainder;
|
||||
REG_D[(word2 >> 12) & 7] = (uint)quotient;
|
||||
|
||||
FLAG_N = (uint)NFLAG_32(quotient);
|
||||
FLAG_Z = (uint)quotient;
|
||||
FLAG_N = (uint)NFLAG_32(quotient);
|
||||
FLAG_Z = (uint)quotient;
|
||||
FLAG_V = VFLAG_CLEAR;
|
||||
FLAG_C = CFLAG_CLEAR;
|
||||
return;
|
||||
|
@ -2194,11 +2194,11 @@ void m68k_op_divl_32_ix(void)
|
|||
}
|
||||
}
|
||||
|
||||
REG_D[word2 & 7] = (uint)remainder;
|
||||
REG_D[(word2 >> 12) & 7] = (uint)quotient;
|
||||
REG_D[word2 & 7] = (uint)remainder;
|
||||
REG_D[(word2 >> 12) & 7] = (uint)quotient;
|
||||
|
||||
FLAG_N = (uint)NFLAG_32(quotient);
|
||||
FLAG_Z = (uint)quotient;
|
||||
FLAG_N = (uint)NFLAG_32(quotient);
|
||||
FLAG_Z = (uint)quotient;
|
||||
FLAG_V = VFLAG_CLEAR;
|
||||
FLAG_C = CFLAG_CLEAR;
|
||||
return;
|
||||
|
@ -2405,11 +2405,11 @@ void m68k_op_divl_32_aw(void)
|
|||
}
|
||||
}
|
||||
|
||||
REG_D[word2 & 7] = (uint)remainder;
|
||||
REG_D[(word2 >> 12) & 7] = (uint)quotient;
|
||||
REG_D[word2 & 7] = (uint)remainder;
|
||||
REG_D[(word2 >> 12) & 7] = (uint)quotient;
|
||||
|
||||
FLAG_N = (uint)(NFLAG_32(quotient));
|
||||
FLAG_Z = (uint)quotient;
|
||||
FLAG_N = (uint)(NFLAG_32(quotient));
|
||||
FLAG_Z = (uint)quotient;
|
||||
FLAG_V = VFLAG_CLEAR;
|
||||
FLAG_C = CFLAG_CLEAR;
|
||||
return;
|
||||
|
@ -2616,11 +2616,11 @@ void m68k_op_divl_32_al(void)
|
|||
}
|
||||
}
|
||||
|
||||
REG_D[word2 & 7] = (uint)remainder;
|
||||
REG_D[(word2 >> 12) & 7] = (uint)quotient;
|
||||
REG_D[word2 & 7] = (uint)remainder;
|
||||
REG_D[(word2 >> 12) & 7] = (uint)quotient;
|
||||
|
||||
FLAG_N = (uint)(NFLAG_32(quotient));
|
||||
FLAG_Z = (uint)quotient;
|
||||
FLAG_N = (uint)(NFLAG_32(quotient));
|
||||
FLAG_Z = (uint)quotient;
|
||||
FLAG_V = VFLAG_CLEAR;
|
||||
FLAG_C = CFLAG_CLEAR;
|
||||
return;
|
||||
|
@ -2827,11 +2827,11 @@ void m68k_op_divl_32_pcdi(void)
|
|||
}
|
||||
}
|
||||
|
||||
REG_D[word2 & 7] = (uint)remainder;
|
||||
REG_D[(word2 >> 12) & 7] = (uint)quotient;
|
||||
REG_D[word2 & 7] = (uint)remainder;
|
||||
REG_D[(word2 >> 12) & 7] = (uint)quotient;
|
||||
|
||||
FLAG_N = (uint)(NFLAG_32(quotient));
|
||||
FLAG_Z = (uint)quotient;
|
||||
FLAG_N = (uint)(NFLAG_32(quotient));
|
||||
FLAG_Z = (uint)quotient;
|
||||
FLAG_V = VFLAG_CLEAR;
|
||||
FLAG_C = CFLAG_CLEAR;
|
||||
return;
|
||||
|
@ -3038,11 +3038,11 @@ void m68k_op_divl_32_pcix(void)
|
|||
}
|
||||
}
|
||||
|
||||
REG_D[word2 & 7] = (uint)remainder;
|
||||
REG_D[(word2 >> 12) & 7] = (uint)quotient;
|
||||
REG_D[word2 & 7] = (uint)remainder;
|
||||
REG_D[(word2 >> 12) & 7] = (uint)quotient;
|
||||
|
||||
FLAG_N = (uint)(NFLAG_32(quotient));
|
||||
FLAG_Z = (uint)quotient;
|
||||
FLAG_N = (uint)(NFLAG_32(quotient));
|
||||
FLAG_Z = (uint)quotient;
|
||||
FLAG_V = VFLAG_CLEAR;
|
||||
FLAG_C = CFLAG_CLEAR;
|
||||
return;
|
||||
|
@ -3249,11 +3249,11 @@ void m68k_op_divl_32_i(void)
|
|||
}
|
||||
}
|
||||
|
||||
REG_D[word2 & 7] = (uint)remainder;
|
||||
REG_D[(word2 >> 12) & 7] = (uint)quotient;
|
||||
REG_D[word2 & 7] = (uint)remainder;
|
||||
REG_D[(word2 >> 12) & 7] = (uint)quotient;
|
||||
|
||||
FLAG_N = (uint)(NFLAG_32(quotient));
|
||||
FLAG_Z = (uint)quotient;
|
||||
FLAG_N = (uint)(NFLAG_32(quotient));
|
||||
FLAG_Z = (uint)quotient;
|
||||
FLAG_V = VFLAG_CLEAR;
|
||||
FLAG_C = CFLAG_CLEAR;
|
||||
return;
|
||||
|
@ -11869,7 +11869,7 @@ void m68k_op_mull_32_d(void)
|
|||
if(!BIT_A(word2))
|
||||
{
|
||||
FLAG_Z = MASK_OUT_ABOVE_32(res);
|
||||
FLAG_N = (uint)(NFLAG_32(res));
|
||||
FLAG_N = (uint)(NFLAG_32(res));
|
||||
FLAG_V = ((sint64)res != (sint32)res)<<7;
|
||||
REG_D[(word2 >> 12) & 7] = FLAG_Z;
|
||||
return;
|
||||
|
@ -11886,7 +11886,7 @@ void m68k_op_mull_32_d(void)
|
|||
if(!BIT_A(word2))
|
||||
{
|
||||
FLAG_Z = MASK_OUT_ABOVE_32(res);
|
||||
FLAG_N = (uint)(NFLAG_32(res));
|
||||
FLAG_N = (uint)(NFLAG_32(res));
|
||||
FLAG_V = (res > 0xffffffff)<<7;
|
||||
REG_D[(word2 >> 12) & 7] = FLAG_Z;
|
||||
return;
|
||||
|
@ -11993,7 +11993,7 @@ void m68k_op_mull_32_ai(void)
|
|||
if(!BIT_A(word2))
|
||||
{
|
||||
FLAG_Z = MASK_OUT_ABOVE_32(res);
|
||||
FLAG_N = (uint)(NFLAG_32(res));
|
||||
FLAG_N = (uint)(NFLAG_32(res));
|
||||
FLAG_V = ((sint64)res != (sint32)res)<<7;
|
||||
REG_D[(word2 >> 12) & 7] = FLAG_Z;
|
||||
return;
|
||||
|
@ -12010,7 +12010,7 @@ void m68k_op_mull_32_ai(void)
|
|||
if(!BIT_A(word2))
|
||||
{
|
||||
FLAG_Z = MASK_OUT_ABOVE_32(res);
|
||||
FLAG_N = (uint)(NFLAG_32(res));
|
||||
FLAG_N = (uint)(NFLAG_32(res));
|
||||
FLAG_V = (res > 0xffffffff)<<7;
|
||||
REG_D[(word2 >> 12) & 7] = FLAG_Z;
|
||||
return;
|
||||
|
@ -12117,7 +12117,7 @@ void m68k_op_mull_32_pi(void)
|
|||
if(!BIT_A(word2))
|
||||
{
|
||||
FLAG_Z = MASK_OUT_ABOVE_32(res);
|
||||
FLAG_N = (uint)(NFLAG_32(res));
|
||||
FLAG_N = (uint)(NFLAG_32(res));
|
||||
FLAG_V = ((sint64)res != (sint32)res)<<7;
|
||||
REG_D[(word2 >> 12) & 7] = FLAG_Z;
|
||||
return;
|
||||
|
@ -12134,7 +12134,7 @@ void m68k_op_mull_32_pi(void)
|
|||
if(!BIT_A(word2))
|
||||
{
|
||||
FLAG_Z = MASK_OUT_ABOVE_32(res);
|
||||
FLAG_N = (uint)(NFLAG_32(res));
|
||||
FLAG_N = (uint)(NFLAG_32(res));
|
||||
FLAG_V = (res > 0xffffffff)<<7;
|
||||
REG_D[(word2 >> 12) & 7] = FLAG_Z;
|
||||
return;
|
||||
|
@ -12241,7 +12241,7 @@ void m68k_op_mull_32_pd(void)
|
|||
if(!BIT_A(word2))
|
||||
{
|
||||
FLAG_Z = MASK_OUT_ABOVE_32(res);
|
||||
FLAG_N = (uint)(NFLAG_32(res));
|
||||
FLAG_N = (uint)(NFLAG_32(res));
|
||||
FLAG_V = ((sint64)res != (sint32)res)<<7;
|
||||
REG_D[(word2 >> 12) & 7] = FLAG_Z;
|
||||
return;
|
||||
|
@ -12258,7 +12258,7 @@ void m68k_op_mull_32_pd(void)
|
|||
if(!BIT_A(word2))
|
||||
{
|
||||
FLAG_Z = MASK_OUT_ABOVE_32(res);
|
||||
FLAG_N = (uint)(NFLAG_32(res));
|
||||
FLAG_N = (uint)(NFLAG_32(res));
|
||||
FLAG_V = (res > 0xffffffff)<<7;
|
||||
REG_D[(word2 >> 12) & 7] = FLAG_Z;
|
||||
return;
|
||||
|
@ -12365,7 +12365,7 @@ void m68k_op_mull_32_di(void)
|
|||
if(!BIT_A(word2))
|
||||
{
|
||||
FLAG_Z = MASK_OUT_ABOVE_32(res);
|
||||
FLAG_N = (uint)(NFLAG_32(res));
|
||||
FLAG_N = (uint)(NFLAG_32(res));
|
||||
FLAG_V = ((sint64)res != (sint32)res)<<7;
|
||||
REG_D[(word2 >> 12) & 7] = FLAG_Z;
|
||||
return;
|
||||
|
@ -12382,7 +12382,7 @@ void m68k_op_mull_32_di(void)
|
|||
if(!BIT_A(word2))
|
||||
{
|
||||
FLAG_Z = MASK_OUT_ABOVE_32(res);
|
||||
FLAG_N = (uint)(NFLAG_32(res));
|
||||
FLAG_N = (uint)(NFLAG_32(res));
|
||||
FLAG_V = (res > 0xffffffff)<<7;
|
||||
REG_D[(word2 >> 12) & 7] = FLAG_Z;
|
||||
return;
|
||||
|
@ -12489,7 +12489,7 @@ void m68k_op_mull_32_ix(void)
|
|||
if(!BIT_A(word2))
|
||||
{
|
||||
FLAG_Z = MASK_OUT_ABOVE_32(res);
|
||||
FLAG_N = (uint)(NFLAG_32(res));
|
||||
FLAG_N = (uint)(NFLAG_32(res));
|
||||
FLAG_V = ((sint64)res != (sint32)res)<<7;
|
||||
REG_D[(word2 >> 12) & 7] = FLAG_Z;
|
||||
return;
|
||||
|
@ -12506,7 +12506,7 @@ void m68k_op_mull_32_ix(void)
|
|||
if(!BIT_A(word2))
|
||||
{
|
||||
FLAG_Z = MASK_OUT_ABOVE_32(res);
|
||||
FLAG_N = (uint)(NFLAG_32(res));
|
||||
FLAG_N = (uint)(NFLAG_32(res));
|
||||
FLAG_V = (res > 0xffffffff)<<7;
|
||||
REG_D[(word2 >> 12) & 7] = FLAG_Z;
|
||||
return;
|
||||
|
@ -12613,7 +12613,7 @@ void m68k_op_mull_32_aw(void)
|
|||
if(!BIT_A(word2))
|
||||
{
|
||||
FLAG_Z = MASK_OUT_ABOVE_32(res);
|
||||
FLAG_N = (uint)(NFLAG_32(res));
|
||||
FLAG_N = (uint)(NFLAG_32(res));
|
||||
FLAG_V = ((sint64)res != (sint32)res)<<7;
|
||||
REG_D[(word2 >> 12) & 7] = FLAG_Z;
|
||||
return;
|
||||
|
@ -12630,7 +12630,7 @@ void m68k_op_mull_32_aw(void)
|
|||
if(!BIT_A(word2))
|
||||
{
|
||||
FLAG_Z = MASK_OUT_ABOVE_32(res);
|
||||
FLAG_N = (uint)(NFLAG_32(res));
|
||||
FLAG_N = (uint)(NFLAG_32(res));
|
||||
FLAG_V = (res > 0xffffffff)<<7;
|
||||
REG_D[(word2 >> 12) & 7] = FLAG_Z;
|
||||
return;
|
||||
|
@ -12737,7 +12737,7 @@ void m68k_op_mull_32_al(void)
|
|||
if(!BIT_A(word2))
|
||||
{
|
||||
FLAG_Z = MASK_OUT_ABOVE_32(res);
|
||||
FLAG_N = (uint)(NFLAG_32(res));
|
||||
FLAG_N = (uint)(NFLAG_32(res));
|
||||
FLAG_V = ((sint64)res != (sint32)res)<<7;
|
||||
REG_D[(word2 >> 12) & 7] = FLAG_Z;
|
||||
return;
|
||||
|
@ -12754,7 +12754,7 @@ void m68k_op_mull_32_al(void)
|
|||
if(!BIT_A(word2))
|
||||
{
|
||||
FLAG_Z = MASK_OUT_ABOVE_32(res);
|
||||
FLAG_N = (uint)(NFLAG_32(res));
|
||||
FLAG_N = (uint)(NFLAG_32(res));
|
||||
FLAG_V = (res > 0xffffffff)<<7;
|
||||
REG_D[(word2 >> 12) & 7] = FLAG_Z;
|
||||
return;
|
||||
|
@ -12861,7 +12861,7 @@ void m68k_op_mull_32_pcdi(void)
|
|||
if(!BIT_A(word2))
|
||||
{
|
||||
FLAG_Z = MASK_OUT_ABOVE_32(res);
|
||||
FLAG_N = (uint)(NFLAG_32(res));
|
||||
FLAG_N = (uint)(NFLAG_32(res));
|
||||
FLAG_V = ((sint64)res != (sint32)res)<<7;
|
||||
REG_D[(word2 >> 12) & 7] = FLAG_Z;
|
||||
return;
|
||||
|
@ -12878,7 +12878,7 @@ void m68k_op_mull_32_pcdi(void)
|
|||
if(!BIT_A(word2))
|
||||
{
|
||||
FLAG_Z = MASK_OUT_ABOVE_32(res);
|
||||
FLAG_N = (uint)(NFLAG_32(res));
|
||||
FLAG_N = (uint)(NFLAG_32(res));
|
||||
FLAG_V = (res > 0xffffffff)<<7;
|
||||
REG_D[(word2 >> 12) & 7] = FLAG_Z;
|
||||
return;
|
||||
|
@ -12985,7 +12985,7 @@ void m68k_op_mull_32_pcix(void)
|
|||
if(!BIT_A(word2))
|
||||
{
|
||||
FLAG_Z = MASK_OUT_ABOVE_32(res);
|
||||
FLAG_N = (uint)(NFLAG_32(res));
|
||||
FLAG_N = (uint)(NFLAG_32(res));
|
||||
FLAG_V = ((sint64)res != (sint32)res)<<7;
|
||||
REG_D[(word2 >> 12) & 7] = FLAG_Z;
|
||||
return;
|
||||
|
@ -13002,7 +13002,7 @@ void m68k_op_mull_32_pcix(void)
|
|||
if(!BIT_A(word2))
|
||||
{
|
||||
FLAG_Z = MASK_OUT_ABOVE_32(res);
|
||||
FLAG_N = (uint)(NFLAG_32(res));
|
||||
FLAG_N = (uint)(NFLAG_32(res));
|
||||
FLAG_V = (res > 0xffffffff)<<7;
|
||||
REG_D[(word2 >> 12) & 7] = FLAG_Z;
|
||||
return;
|
||||
|
@ -13109,7 +13109,7 @@ void m68k_op_mull_32_i(void)
|
|||
if(!BIT_A(word2))
|
||||
{
|
||||
FLAG_Z = MASK_OUT_ABOVE_32(res);
|
||||
FLAG_N = (uint)(NFLAG_32(res));
|
||||
FLAG_N = (uint)(NFLAG_32(res));
|
||||
FLAG_V = ((sint64)res != (sint32)res)<<7;
|
||||
REG_D[(word2 >> 12) & 7] = FLAG_Z;
|
||||
return;
|
||||
|
@ -13126,7 +13126,7 @@ void m68k_op_mull_32_i(void)
|
|||
if(!BIT_A(word2))
|
||||
{
|
||||
FLAG_Z = MASK_OUT_ABOVE_32(res);
|
||||
FLAG_N = (uint)(NFLAG_32(res));
|
||||
FLAG_N = (uint)(NFLAG_32(res));
|
||||
FLAG_V = (res > 0xffffffff)<<7;
|
||||
REG_D[(word2 >> 12) & 7] = FLAG_Z;
|
||||
return;
|
||||
|
|
|
@ -2777,7 +2777,7 @@ void m68k_op_ror_32_s(void)
|
|||
|
||||
FLAG_N = NFLAG_32(res);
|
||||
FLAG_Z = res;
|
||||
FLAG_C = (uint)(src << (9 - shift));
|
||||
FLAG_C = (uint)(src << (9 - shift));
|
||||
FLAG_V = VFLAG_CLEAR;
|
||||
}
|
||||
|
||||
|
@ -2849,7 +2849,7 @@ void m68k_op_ror_32_r(void)
|
|||
USE_CYCLES(orig_shift<<CYC_SHIFT);
|
||||
|
||||
*r_dst = res;
|
||||
FLAG_C = (uint)((src >> ((shift - 1) & 31)) << 8);
|
||||
FLAG_C = (uint)((src >> ((shift - 1) & 31)) << 8);
|
||||
FLAG_N = NFLAG_32(res);
|
||||
FLAG_Z = res;
|
||||
FLAG_V = VFLAG_CLEAR;
|
||||
|
@ -2857,8 +2857,8 @@ void m68k_op_ror_32_r(void)
|
|||
}
|
||||
|
||||
FLAG_C = CFLAG_CLEAR;
|
||||
FLAG_N = (uint)(NFLAG_32(src));
|
||||
FLAG_Z = (uint)src;
|
||||
FLAG_N = (uint)(NFLAG_32(src));
|
||||
FLAG_Z = (uint)src;
|
||||
FLAG_V = VFLAG_CLEAR;
|
||||
}
|
||||
|
||||
|
@ -3012,7 +3012,7 @@ void m68k_op_rol_32_s(void)
|
|||
|
||||
FLAG_N = NFLAG_32(res);
|
||||
FLAG_Z = res;
|
||||
FLAG_C = (uint)(src >> (24 - shift));
|
||||
FLAG_C = (uint)(src >> (24 - shift));
|
||||
FLAG_V = VFLAG_CLEAR;
|
||||
}
|
||||
|
||||
|
@ -3101,7 +3101,7 @@ void m68k_op_rol_32_r(void)
|
|||
|
||||
*r_dst = res;
|
||||
|
||||
FLAG_C = (uint)((src >> (32 - shift)) << 8);
|
||||
FLAG_C = (uint)((src >> (32 - shift)) << 8);
|
||||
FLAG_N = NFLAG_32(res);
|
||||
FLAG_Z = res;
|
||||
FLAG_V = VFLAG_CLEAR;
|
||||
|
@ -3109,8 +3109,8 @@ void m68k_op_rol_32_r(void)
|
|||
}
|
||||
|
||||
FLAG_C = CFLAG_CLEAR;
|
||||
FLAG_N = (uint)(NFLAG_32(src));
|
||||
FLAG_Z = (uint)src;
|
||||
FLAG_N = (uint)(NFLAG_32(src));
|
||||
FLAG_Z = (uint)src;
|
||||
FLAG_V = VFLAG_CLEAR;
|
||||
}
|
||||
|
||||
|
@ -3267,13 +3267,13 @@ void m68k_op_roxr_32_s(void)
|
|||
|
||||
res = ROR_33_64(res, shift);
|
||||
|
||||
FLAG_C = FLAG_X = (uint)(res >> 24);
|
||||
FLAG_C = FLAG_X = (uint)(res >> 24);
|
||||
res = MASK_OUT_ABOVE_32(res);
|
||||
|
||||
*r_dst = (uint)res;
|
||||
*r_dst = (uint)res;
|
||||
|
||||
FLAG_N = (uint)(NFLAG_32(res));
|
||||
FLAG_Z = (uint)res;
|
||||
FLAG_N = (uint)(NFLAG_32(res));
|
||||
FLAG_Z = (uint)res;
|
||||
FLAG_V = VFLAG_CLEAR;
|
||||
|
||||
#else
|
||||
|
@ -3372,12 +3372,12 @@ void m68k_op_roxr_32_r(void)
|
|||
|
||||
USE_CYCLES(orig_shift<<CYC_SHIFT);
|
||||
|
||||
FLAG_C = FLAG_X = (uint)(res >> 24);
|
||||
FLAG_C = FLAG_X = (uint)(res >> 24);
|
||||
res = MASK_OUT_ABOVE_32(res);
|
||||
|
||||
*r_dst = (uint)res;
|
||||
FLAG_N = (uint)(NFLAG_32(res));
|
||||
FLAG_Z = (uint)res;
|
||||
*r_dst = (uint)res;
|
||||
FLAG_N = (uint)(NFLAG_32(res));
|
||||
FLAG_Z = (uint)res;
|
||||
FLAG_V = VFLAG_CLEAR;
|
||||
return;
|
||||
}
|
||||
|
@ -3581,13 +3581,13 @@ void m68k_op_roxl_32_s(void)
|
|||
|
||||
res = ROL_33_64(res, shift);
|
||||
|
||||
FLAG_C = FLAG_X = (uint)(res >> 24);
|
||||
FLAG_C = FLAG_X = (uint)(res >> 24);
|
||||
res = MASK_OUT_ABOVE_32(res);
|
||||
|
||||
*r_dst = (uint)res;
|
||||
*r_dst = (uint)res;
|
||||
|
||||
FLAG_N = (uint)(NFLAG_32(res));
|
||||
FLAG_Z = (uint)res;
|
||||
FLAG_N = (uint)(NFLAG_32(res));
|
||||
FLAG_Z = (uint)res;
|
||||
FLAG_V = VFLAG_CLEAR;
|
||||
|
||||
#else
|
||||
|
@ -3687,12 +3687,12 @@ void m68k_op_roxl_32_r(void)
|
|||
|
||||
USE_CYCLES(orig_shift<<CYC_SHIFT);
|
||||
|
||||
FLAG_C = FLAG_X = (uint)(res >> 24);
|
||||
FLAG_C = FLAG_X = (uint)(res >> 24);
|
||||
res = MASK_OUT_ABOVE_32(res);
|
||||
|
||||
*r_dst = (uint)res;
|
||||
FLAG_N = (uint)(NFLAG_32(res));
|
||||
FLAG_Z = (uint)res;
|
||||
*r_dst = (uint)res;
|
||||
FLAG_N = (uint)(NFLAG_32(res));
|
||||
FLAG_Z = (uint)res;
|
||||
FLAG_V = VFLAG_CLEAR;
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1189,7 +1189,7 @@ for (a = 0, ctss = TRUE; a < dsk_tab[dtyp].accpm; a++) {
|
|||
fprintf (st, "Invalid record length %d, unit = %d, access = %d, track = %d, record = %d\n",
|
||||
rlnt, u, a, t, rec);
|
||||
return SCPE_OK;
|
||||
}
|
||||
}
|
||||
if (rlnt > maxrsz)
|
||||
maxrsz = rlnt;
|
||||
if (rlnt < minrsz)
|
||||
|
|
|
@ -256,12 +256,12 @@
|
|||
#define UNIT_V_MDV (UNIT_V_UF + 0) /* MDV present */
|
||||
#define UNIT_V_STK (UNIT_V_UF + 1) /* stack instr */
|
||||
#define UNIT_V_BYT (UNIT_V_UF + 2) /* byte instr */
|
||||
#define UNIT_V_64KW (UNIT_V_UF + 3) /* 64KW mem support */
|
||||
#define UNIT_V_64KW (UNIT_V_UF + 3) /* 64KW mem support */
|
||||
#define UNIT_V_MSIZE (UNIT_V_UF + 4) /* dummy mask */
|
||||
#define UNIT_MDV (1 << UNIT_V_MDV)
|
||||
#define UNIT_STK (1 << UNIT_V_STK)
|
||||
#define UNIT_BYT (1 << UNIT_V_BYT)
|
||||
#define UNIT_64KW (1 << UNIT_V_64KW)
|
||||
#define UNIT_64KW (1 << UNIT_V_64KW)
|
||||
#define UNIT_MSIZE (1 << UNIT_V_MSIZE)
|
||||
#define UNIT_IOPT (UNIT_MDV | UNIT_STK | UNIT_BYT | UNIT_64KW)
|
||||
#define UNIT_NOVA3 (UNIT_MDV | UNIT_STK)
|
||||
|
@ -476,7 +476,7 @@ while (reason == 0) { /* loop until halted */
|
|||
IR = M[PC]; /* fetch instr */
|
||||
if ( hist_cnt )
|
||||
{
|
||||
hist_save( PC, IR ) ; /* PC, int_req unchanged */
|
||||
hist_save( PC, IR ) ; /* PC, int_req unchanged */
|
||||
}
|
||||
|
||||
INCREMENT_PC ;
|
||||
|
@ -1202,11 +1202,11 @@ return SCPE_OK;
|
|||
* - The Binary Loader was in turn used to load tapes in the usual DG 'absolute binary' format.
|
||||
*/
|
||||
|
||||
#define BOOT_START 00000
|
||||
#define BOOT_LEN (sizeof(boot_rom) / sizeof(int32))
|
||||
#define BOOT_START 00000
|
||||
#define BOOT_LEN (sizeof(boot_rom) / sizeof(int32))
|
||||
|
||||
static const int32 boot_rom[] = {
|
||||
0062677, /* IORST ;reset all I/O */
|
||||
0062677, /* IORST ;reset all I/O */
|
||||
0060477, /* READS 0 ;read SR into AC0 */
|
||||
0024026, /* LDA 1,C77 ;get dev mask */
|
||||
0107400, /* AND 0,1 ;isolate dev code */
|
||||
|
@ -1352,7 +1352,7 @@ if ( (r != SCPE_OK) || (lnt && (lnt < HIST_MIN)) )
|
|||
}
|
||||
hist_p = 0;
|
||||
if ( hist_cnt )
|
||||
{
|
||||
{
|
||||
free( hist ) ;
|
||||
hist_cnt = 0 ;
|
||||
hist = NULL ;
|
||||
|
|
|
@ -56,7 +56,7 @@
|
|||
#endif
|
||||
|
||||
/* Simulator stop codes */
|
||||
|
||||
|
||||
#define STOP_RSRV 1 /* must be 1 */
|
||||
#define STOP_HALT 2 /* HALT */
|
||||
#define STOP_IBKPT 3 /* breakpoint */
|
||||
|
@ -284,7 +284,7 @@ typedef struct {
|
|||
#define INT_ION (1 << INT_V_ION)
|
||||
#define INT_DEV ((1 << INT_V_STK) - 1) /* device ints */
|
||||
#define INT_PENDING INT_ION+INT_NO_ION_PENDING
|
||||
#define INT_TRAP (1 << INT_V_TRAP)
|
||||
#define INT_TRAP (1 << INT_V_TRAP)
|
||||
|
||||
/* PI disable bits */
|
||||
|
||||
|
|
|
@ -139,22 +139,22 @@
|
|||
#define STA_PEM 0000001 /* *PE mode */
|
||||
|
||||
#define STA_EFLGS1 (STA_DLT | STA_ILL | STA_DAE | STA_EOT | \
|
||||
STA_EOF | STA_BOT | STA_BAT | STA_ODD)
|
||||
STA_EOF | STA_BOT | STA_BAT | STA_ODD)
|
||||
#define STA_EFLGS2 (STA_FGP | STA_CDL | STA_BDS | STA_OVS | \
|
||||
STA_CRC | STA_FPR | STA_FPR) /* set error 2 */
|
||||
STA_CRC | STA_FPR | STA_FPR) /* set error 2 */
|
||||
#define STA_CLR ((020 << 16) | 0010000) /* always clear */
|
||||
#define STA_SET (STA_HDN | STA_9TK) /* always set */
|
||||
#define STA_DYN (STA_REW | STA_EOT | STA_EOF | STA_BOT | \
|
||||
STA_WLK | STA_RDY | STA_PEM) /* kept in USTAT */
|
||||
STA_WLK | STA_RDY | STA_PEM) /* kept in USTAT */
|
||||
#define STA_MON (STA_REW | STA_BOT | STA_WLK | STA_RDY | \
|
||||
STA_PEM) /* set status chg */
|
||||
STA_PEM) /* set status chg */
|
||||
|
||||
extern uint16 M[];
|
||||
extern UNIT cpu_unit;
|
||||
extern int32 int_req, dev_busy, dev_done, dev_disable;
|
||||
extern int32 SR, AMASK;
|
||||
extern uint16 M[];
|
||||
extern UNIT cpu_unit;
|
||||
extern int32 int_req, dev_busy, dev_done, dev_disable;
|
||||
extern int32 SR, AMASK;
|
||||
|
||||
extern t_stat cpu_boot(int32 unitno, DEVICE * dptr ) ;
|
||||
extern t_stat cpu_boot(int32 unitno, DEVICE * dptr ) ;
|
||||
|
||||
|
||||
int32 mta_ma = 0; /* memory address */
|
||||
|
@ -363,9 +363,9 @@ if ((uptr->flags & UNIT_ATT) == 0) { /* not attached? */
|
|||
}
|
||||
else switch (c) { /* case on command */
|
||||
|
||||
case CU_CMODE: /* controller mode */
|
||||
mta_ep = mta_cu & CU_EP;
|
||||
break;
|
||||
case CU_CMODE: /* controller mode */
|
||||
mta_ep = mta_cu & CU_EP;
|
||||
break;
|
||||
|
||||
case CU_DMODE: /* drive mode */
|
||||
if (!sim_tape_bot (uptr)) /* must be BOT */
|
||||
|
@ -577,9 +577,9 @@ for (u = 0; u < MTA_NUMDR; u++) { /* loop thru units */
|
|||
sim_tape_reset (uptr); /* clear pos flag */
|
||||
sim_cancel (uptr); /* cancel activity */
|
||||
if (uptr->flags & UNIT_ATT) uptr->USTAT = STA_RDY |
|
||||
(uptr->USTAT & STA_PEM) |
|
||||
(sim_tape_wrp (uptr)? STA_WLK: 0) |
|
||||
(sim_tape_bot (uptr)? STA_BOT: 0);
|
||||
(uptr->USTAT & STA_PEM) |
|
||||
(sim_tape_wrp (uptr)? STA_WLK: 0) |
|
||||
(sim_tape_bot (uptr)? STA_BOT: 0);
|
||||
else uptr->USTAT = 0;
|
||||
}
|
||||
mta_updcsta (&mta_unit[0]); /* update status */
|
||||
|
@ -629,17 +629,17 @@ return SCPE_OK;
|
|||
/* Boot routine */
|
||||
|
||||
t_stat mta_boot (int32 unitno, DEVICE *dptr)
|
||||
{
|
||||
sim_tape_rewind( &mta_unit[unitno] ) ;
|
||||
/*
|
||||
use common rewind/reset code
|
||||
device reset
|
||||
rewind 'tape' file
|
||||
device
|
||||
unit
|
||||
controller
|
||||
*/
|
||||
cpu_boot( unitno, dptr ) ;
|
||||
SR = 0100000 + DEV_MTA ;
|
||||
return ( SCPE_OK );
|
||||
} /* end of 'mta_boot' */
|
||||
{
|
||||
sim_tape_rewind( &mta_unit[unitno] ) ;
|
||||
/*
|
||||
use common rewind/reset code
|
||||
device reset
|
||||
rewind 'tape' file
|
||||
device
|
||||
unit
|
||||
controller
|
||||
*/
|
||||
cpu_boot( unitno, dptr ) ;
|
||||
SR = 0100000 + DEV_MTA ;
|
||||
return ( SCPE_OK );
|
||||
} /* end of 'mta_boot' */
|
||||
|
|
|
@ -54,7 +54,7 @@ t_stat plt_svc (UNIT *uptr);
|
|||
t_stat plt_reset (DEVICE *dptr);
|
||||
|
||||
|
||||
/* 7 or 8 bit data mask support for either device */
|
||||
/* 7 or 8 bit data mask support for either device */
|
||||
|
||||
#define UNIT_V_8B (UNIT_V_UF + 0) /* 8b output */
|
||||
#define UNIT_8B (1 << UNIT_V_8B)
|
||||
|
|
|
@ -45,10 +45,10 @@ Notes:
|
|||
|
||||
#include "nova_defs.h"
|
||||
|
||||
extern int32 int_req, dev_busy, dev_done, dev_disable ;
|
||||
extern int32 SR ;
|
||||
extern int32 int_req, dev_busy, dev_done, dev_disable ;
|
||||
extern int32 SR ;
|
||||
|
||||
extern t_stat cpu_boot(int32 unitno, DEVICE * dptr ) ;
|
||||
extern t_stat cpu_boot(int32 unitno, DEVICE * dptr ) ;
|
||||
|
||||
|
||||
int32 ptr_stopioe = 0, ptp_stopioe = 0; /* stop on error */
|
||||
|
@ -62,7 +62,7 @@ t_stat ptp_reset (DEVICE *dptr);
|
|||
t_stat ptr_boot (int32 unitno, DEVICE *dptr);
|
||||
|
||||
|
||||
/* 7 or 8 bit data mask support for either device */
|
||||
/* 7 or 8 bit data mask support for either device */
|
||||
|
||||
#define UNIT_V_8B (UNIT_V_UF + 0) /* 8b output */
|
||||
#define UNIT_8B (1 << UNIT_V_8B)
|
||||
|
|
|
@ -176,11 +176,11 @@ internal state machine:
|
|||
|
||||
t_stat sim_load (FILE *fileref, char *cptr, char *fnam, int flag)
|
||||
{
|
||||
int32 data, csum, count, state, i;
|
||||
int32 origin;
|
||||
int pos ;
|
||||
int block_start ;
|
||||
int done ;
|
||||
int32 data, csum, count, state, i;
|
||||
int32 origin;
|
||||
int pos ;
|
||||
int block_start ;
|
||||
int done ;
|
||||
|
||||
if ((*cptr != 0) || (flag != 0))
|
||||
return ( SCPE_ARG ) ;
|
||||
|
@ -223,8 +223,8 @@ for ( pos = 0 ; (! done) && ((i=getc(fileref)) != EOF) ; ++pos )
|
|||
/* do any auto-start check or inhibit check */
|
||||
saved_PC = (origin & 077777) ; /* 0B0 = auto-start program */
|
||||
/* 1B0 = do not auto start */
|
||||
state = 0 ; /* indicate okay state */
|
||||
done = 1 ; /* we're done! */
|
||||
state = 0 ; /* indicate okay state */
|
||||
done = 1 ; /* we're done! */
|
||||
if ( ! (origin & 0x8000) )
|
||||
{
|
||||
printf( "auto start @ %05o \n", (origin & 0x7FFF) ) ;
|
||||
|
|
|
@ -296,7 +296,7 @@ for (i = 0; i < DRM_NUMWDS; i++, da++) { /* do transfer */
|
|||
if ((drm_wlk >> (drm_da >> 4)) & 1)
|
||||
drm_err = 1;
|
||||
else { /* not locked */
|
||||
fbuf[da] = M[drm_ma]; /* write word */
|
||||
fbuf[da] = M[drm_ma]; /* write word */
|
||||
if (da >= uptr->hwmark)
|
||||
uptr->hwmark = da + 1;
|
||||
}
|
||||
|
|
|
@ -374,7 +374,7 @@ if (pulse == 003) { /* MSE */
|
|||
dt_deselect (dtsa);
|
||||
dtsa = (dtsa & ~DTA_UNIT) | (dat & DTA_UNIT);
|
||||
dtsb = dtsb & ~(DTB_DTF | DTB_BEF | DTB_ERF | DTB_ALLERR);
|
||||
}
|
||||
}
|
||||
if (pulse == 004) { /* MLC */
|
||||
dtsa = (dtsa & ~DTA_RW) | (dat & DTA_RW); /* load dtsa */
|
||||
dtsb = dtsb & ~(DTB_DTF | DTB_BEF | DTB_ERF | DTB_ALLERR);
|
||||
|
@ -616,7 +616,7 @@ switch (fnc) { /* case function */
|
|||
if ((fnc == FNC_WRIT) || (fnc == FNC_WALL)) { /* write function? */
|
||||
dtsb = dtsb | DTB_DTF; /* set data flag */
|
||||
DT_UPDINT;
|
||||
}
|
||||
}
|
||||
sim_activate (uptr, ABS (newpos - ((int32) uptr->pos)) * dt_ltime);
|
||||
return;
|
||||
}
|
||||
|
@ -678,13 +678,13 @@ if (mot & DTS_DIR) /* update pos */
|
|||
else uptr->pos = uptr->pos + delta;
|
||||
if (((int32) uptr->pos < 0) ||
|
||||
((int32) uptr->pos > (DTU_FWDEZ (uptr) + DT_EZLIN))) {
|
||||
detach_unit (uptr); /* off reel? */
|
||||
uptr->STATE = uptr->pos = 0;
|
||||
unum = (int32) (uptr - dt_dev.units);
|
||||
if (unum == DTA_GETUNIT (dtsa)) /* if selected, */
|
||||
dt_seterr (uptr, DTB_SEL); /* error */
|
||||
return TRUE;
|
||||
}
|
||||
detach_unit (uptr); /* off reel? */
|
||||
uptr->STATE = uptr->pos = 0;
|
||||
unum = (int32) (uptr - dt_dev.units);
|
||||
if (unum == DTA_GETUNIT (dtsa)) /* if selected, */
|
||||
dt_seterr (uptr, DTB_SEL); /* error */
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -1078,7 +1078,7 @@ if (sim_is_active (uptr)) {
|
|||
if ((u == DTA_GETUNIT (dtsa)) && (dtsa & DTA_STSTP)) {
|
||||
dtsb = dtsb | DTB_ERF | DTB_SEL | DTB_DTF;
|
||||
DT_UPDINT;
|
||||
}
|
||||
}
|
||||
uptr->STATE = uptr->pos = 0;
|
||||
}
|
||||
fbuf = (uint32 *) uptr->filebuf; /* file buffer */
|
||||
|
|
|
@ -115,7 +115,7 @@ if ((inst & 07000) == 01000) { /* fill buf */
|
|||
lpt_buf[i] = lpt_trans[(dat >> 12) & 077];
|
||||
lpt_buf[i + 1] = lpt_trans[(dat >> 6) & 077];
|
||||
lpt_buf[i + 2] = lpt_trans[dat & 077];
|
||||
}
|
||||
}
|
||||
lpt_bptr = (lpt_bptr + 1) & BPTR_MASK;
|
||||
return dat;
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -121,45 +121,45 @@ DEVICE fe_dev = {
|
|||
*/
|
||||
|
||||
/* Here is the definition of the communications area:
|
||||
XPP RLWORD,31 ;RELOAD WORD [FE_KEEPA]
|
||||
KSRLD==1B4 ;RELOAD REQUEST (8080 will reload -10 if this is set)
|
||||
KPACT==1B5 ;KEEP ALIVE ACTIVE (8080 reloads -10 if KPALIV doesn't change)
|
||||
KLACT==1B6 ;KLINIK ACTIVE (Remote diagnosis line enabled)
|
||||
PAREN==1B7 ;PARITY ERROR DETECT ENABLED
|
||||
CRMPAR==1B8 ;CRAM PAR ERR DETECT ENABLED
|
||||
DRMPAR==1B9 ;DRAM PAR ERR DETECT ENABLED
|
||||
CASHEN==1B10 ;CACHE ENABLED
|
||||
MILSEN==1B11 ;1MSEC ENABLED
|
||||
TRPENA==1B12 ;TRAPS ENABLED
|
||||
MFGMOD==1B13 ;MANUFACTURING MODE
|
||||
KPALIV==377B27 ;KEEP ALIVE WORD CHECKED EVERY 1 SEC, AFTER 15, FAIL
|
||||
XPP RLWORD,31 ;RELOAD WORD [FE_KEEPA]
|
||||
KSRLD==1B4 ;RELOAD REQUEST (8080 will reload -10 if this is set)
|
||||
KPACT==1B5 ;KEEP ALIVE ACTIVE (8080 reloads -10 if KPALIV doesn't change)
|
||||
KLACT==1B6 ;KLINIK ACTIVE (Remote diagnosis line enabled)
|
||||
PAREN==1B7 ;PARITY ERROR DETECT ENABLED
|
||||
CRMPAR==1B8 ;CRAM PAR ERR DETECT ENABLED
|
||||
DRMPAR==1B9 ;DRAM PAR ERR DETECT ENABLED
|
||||
CASHEN==1B10 ;CACHE ENABLED
|
||||
MILSEN==1B11 ;1MSEC ENABLED
|
||||
TRPENA==1B12 ;TRAPS ENABLED
|
||||
MFGMOD==1B13 ;MANUFACTURING MODE
|
||||
KPALIV==377B27 ;KEEP ALIVE WORD CHECKED EVERY 1 SEC, AFTER 15, FAIL
|
||||
; Why reload (8080->10)
|
||||
AUTOBT==1B32 ;BOOT SWITCH OR POWER UP CONDITION
|
||||
PWRFAL==1B33 ;POWER FAIL restart (Start at 70)
|
||||
FORREL==1B34 ;FORCED RELOAD
|
||||
KEPFAL==1B35 ;KEEP ALIVE FAILURE (XCT exec 71)
|
||||
AUTOBT==1B32 ;BOOT SWITCH OR POWER UP CONDITION
|
||||
PWRFAL==1B33 ;POWER FAIL restart (Start at 70)
|
||||
FORREL==1B34 ;FORCED RELOAD
|
||||
KEPFAL==1B35 ;KEEP ALIVE FAILURE (XCT exec 71)
|
||||
|
||||
XPP CTYIWD,32 ;CTY INPUT WORD [FE_CTYIN]
|
||||
CTYICH==377B35 ;CTY INPUT CHARACTER
|
||||
CTYIVL==1B27 ;INPUT VALID BIT (Actually, this is an 8-bit function code)
|
||||
XPP CTYIWD,32 ;CTY INPUT WORD [FE_CTYIN]
|
||||
CTYICH==377B35 ;CTY INPUT CHARACTER
|
||||
CTYIVL==1B27 ;INPUT VALID BIT (Actually, this is an 8-bit function code)
|
||||
|
||||
XPP CTYOWD,33 ;CTY OUTPUT WORD [FE_CTYOUT]
|
||||
CTYOCH==377B35 ;CTY OUTPUT CHARACTER
|
||||
CTYOVL==1B27 ;OUTPUT VALID FLAG
|
||||
XPP CTYOWD,33 ;CTY OUTPUT WORD [FE_CTYOUT]
|
||||
CTYOCH==377B35 ;CTY OUTPUT CHARACTER
|
||||
CTYOVL==1B27 ;OUTPUT VALID FLAG
|
||||
|
||||
XPP KLIIWD,34 ;KLINIK INPUT WORD [FE_KLININ]
|
||||
KLIICH==377B35 ;KLINIK INPUT CHARACTER
|
||||
KLIIVL==1B27 ;KLINIK INPUT VALID (Historical)
|
||||
KLICHR==1B27 ;KLINIK CHARACTER
|
||||
KLIINI==2B27 ;KLINIK INITED
|
||||
KLICAR==3B27 ;CARRIER LOST
|
||||
XPP KLIIWD,34 ;KLINIK INPUT WORD [FE_KLININ]
|
||||
KLIICH==377B35 ;KLINIK INPUT CHARACTER
|
||||
KLIIVL==1B27 ;KLINIK INPUT VALID (Historical)
|
||||
KLICHR==1B27 ;KLINIK CHARACTER
|
||||
KLIINI==2B27 ;KLINIK INITED
|
||||
KLICAR==3B27 ;CARRIER LOST
|
||||
|
||||
|
||||
XPP KLIOWD,35 ;KLINIK OUTPUT WORD [FE_KLINOUT]
|
||||
KLIOCH==377B35 ;KLINIK OUTPUT CHARACTER
|
||||
KLIOVL==1B27 ;KLINIK OUTPUT VALID (Historical)
|
||||
KLOCHR==1B27 ;KLINIK CHARACTER AVAILABLE
|
||||
KLIHUP==2B27 ;KLINIK HANGUP REQUEST
|
||||
XPP KLIOWD,35 ;KLINIK OUTPUT WORD [FE_KLINOUT]
|
||||
KLIOCH==377B35 ;KLINIK OUTPUT CHARACTER
|
||||
KLIOVL==1B27 ;KLINIK OUTPUT VALID (Historical)
|
||||
KLOCHR==1B27 ;KLINIK CHARACTER AVAILABLE
|
||||
KLIHUP==2B27 ;KLINIK HANGUP REQUEST
|
||||
*/
|
||||
|
||||
void fe_intr (void)
|
||||
|
|
|
@ -718,14 +718,14 @@ if (sw & SWMASK ('C')) { /* character? */
|
|||
for (i = 30; i >= 0; i = i - 6) {
|
||||
c = (int32) ((inst >> i) & 077);
|
||||
fprintf (of, "%c", SIXTOASC (c));
|
||||
}
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
if (sw & SWMASK ('P')) { /* packed? */
|
||||
for (i = 29; i >= 0; i = i - 7) {
|
||||
c = (int32) ((inst >> i) & 0177);
|
||||
fprintf (of, FMTASC (c));
|
||||
}
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
if (!(sw & SWMASK ('M')))
|
||||
|
|
|
@ -628,8 +628,8 @@ typedef struct pdp_dib DIB;
|
|||
/* VT simulation is sequential, so only
|
||||
one interrupt is posted at a time. */
|
||||
#define INT_V_VTLP 13 /* XXX - Manual says VTLP, VTST have opposite */
|
||||
#define INT_V_VTST 14 /* XXX precedence, but that breaks LUNAR! */
|
||||
/* XXX How this happens is an utter mystery. */
|
||||
#define INT_V_VTST 14 /* XXX precedence, but that breaks LUNAR! */
|
||||
/* XXX How this happens is an utter mystery. */
|
||||
#define INT_V_VTCH 15
|
||||
#define INT_V_VTNM 16
|
||||
#define INT_V_LK 17
|
||||
|
|
|
@ -967,9 +967,9 @@ if (fnc_rdy[fnc] && sim_is_active (uptr)) /* need inactive? */
|
|||
if (fnc_cyl[fnc] && /* need valid cyl */
|
||||
((GET_CY (hkdc) >= HK_CYL (uptr)) || /* bad cylinder */
|
||||
(GET_SF (hkda) >= HK_NUMSF))) { /* bad surface */
|
||||
hk_err (CS1_ERR|CS1_DONE, 0, ER_SKI|ER_IAE, drv); /* set err, no op */
|
||||
return;
|
||||
}
|
||||
hk_err (CS1_ERR|CS1_DONE, 0, ER_SKI|ER_IAE, drv); /* set err, no op */
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
hkcs1 = (hkcs1 | CS1_GO) & ~CS1_DONE; /* set go, clear done */
|
||||
|
|
|
@ -844,7 +844,7 @@ static t_stat kmc_writeCsr (int32 data, int32 PA, int32 access) {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (changed & SEL0_RUN) { /* Changing the run bit? */
|
||||
if (changed & SEL0_RUN) { /* Changing the run bit? */
|
||||
if (sel0 & SEL0_RUN) {
|
||||
kmc_startUcode (k);
|
||||
} else {
|
||||
|
@ -858,7 +858,7 @@ static t_stat kmc_writeCsr (int32 data, int32 PA, int32 access) {
|
|||
if ((sel0 & SEL0_RQI) && !(sel2 & SEL2_RDO))
|
||||
sel2 = (sel2 & 0xFF00) | SEL2_RDI; /* Clear command bits too */
|
||||
kmc_updints(k);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 01: /* SEL2 */
|
||||
if (access == WRITEB) {
|
||||
|
@ -921,23 +921,23 @@ static t_stat kmc_writeCsr (int32 data, int32 PA, int32 access) {
|
|||
static void kmc_doMicroinstruction (int32 k, uint16 instr) {
|
||||
switch (instr) {
|
||||
case 0041222: /* MOVE <MEM><BSEL2> */
|
||||
sel2 = (sel2 & ~0xFF) | (dram[mar%KMC_DRAMSIZE] & 0xFF);
|
||||
break;
|
||||
sel2 = (sel2 & ~0xFF) | (dram[mar%KMC_DRAMSIZE] & 0xFF);
|
||||
break;
|
||||
case 0055222: /* MOVE <MRM><BSEL2><MARINC> */
|
||||
sel2 = (sel2 & ~0xFF) | (dram[mar%KMC_DRAMSIZE] & 0xFF);
|
||||
mar = (mar +1)%KMC_DRAMSIZE;
|
||||
break;
|
||||
sel2 = (sel2 & ~0xFF) | (dram[mar%KMC_DRAMSIZE] & 0xFF);
|
||||
mar = (mar +1)%KMC_DRAMSIZE;
|
||||
break;
|
||||
case 0122440: /* MOVE <BSEL2><MEM> */
|
||||
dram[mar%KMC_DRAMSIZE] = sel2 & 0xFF;
|
||||
break;
|
||||
break;
|
||||
case 0136440: /* MOVE <BSEL2><MEM><MARINC> */
|
||||
dram[mar%KMC_DRAMSIZE] = sel2 & 0xFF;
|
||||
mar = (mar +1)%KMC_DRAMSIZE;
|
||||
break;
|
||||
mar = (mar +1)%KMC_DRAMSIZE;
|
||||
break;
|
||||
case 0121202: /* MOVE <NPR><BSEL2> */
|
||||
case 0021002: /* MOVE <IBUS 0><BSEL2> */
|
||||
sel2 = (sel2 & ~0xFF) | 0;
|
||||
break;
|
||||
sel2 = (sel2 & ~0xFF) | 0;
|
||||
break;
|
||||
default:
|
||||
if ((instr & 0160000) == 0000000) { /* MVI */
|
||||
switch (instr & 0174000) {
|
||||
|
@ -1707,19 +1707,19 @@ static void kmc_dispatchInputCmd(int32 k) {
|
|||
cmdsel2, sel4, sel6, ba);
|
||||
|
||||
switch (cmdsel2 & (SEL2_IOT | SEL2_CMD)) {
|
||||
case CMD_BUFFIN: /* TX BUFFER IN */
|
||||
case CMD_BUFFIN: /* TX BUFFER IN */
|
||||
kmc_txBufferIn(d, ba, sel6);
|
||||
break;
|
||||
case CMD_CTRLIN: /* CONTROL IN. */
|
||||
case CMD_CTRLIN: /* CONTROL IN. */
|
||||
case SEL2_IOT | CMD_CTRLIN:
|
||||
kmc_ctrlIn (k, d, line);
|
||||
break;
|
||||
|
||||
case CMD_BASEIN: /* BASE IN. */
|
||||
case CMD_BASEIN: /* BASE IN. */
|
||||
kmc_baseIn (k, d, cmdsel2, line);
|
||||
break;
|
||||
|
||||
case (SEL2_IOT | CMD_BUFFIN): /* Buffer in, receive buffer for us... */
|
||||
case (SEL2_IOT | CMD_BUFFIN): /* Buffer in, receive buffer for us... */
|
||||
kmc_rxBufferIn(d, ba ,sel6);
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -60,7 +60,7 @@
|
|||
|
||||
#define UNIT_V_DTYPE (UNIT_V_UF + 0) /* disk type */
|
||||
#define RS03_DTYPE (0)
|
||||
#define RS04_DTYPE (1)
|
||||
#define RS04_DTYPE (1)
|
||||
#define UNIT_V_AUTO (UNIT_V_UF + 1) /* autosize */
|
||||
#define UNIT_V_WLK (UNIT_V_UF + 2) /* write lock */
|
||||
#define UNIT_DTYPE (1 << UNIT_V_DTYPE)
|
||||
|
|
|
@ -1,49 +1,49 @@
|
|||
#include <stdio.h>
|
||||
|
||||
#define ERROR 00404
|
||||
#define ERROR 00404
|
||||
#include "pdp11_cr_dat.h"
|
||||
|
||||
static int colStart = 1; /* starting column */
|
||||
static int colEnd = 80; /* ending column */
|
||||
static int colStart = 1; /* starting column */
|
||||
static int colEnd = 80; /* ending column */
|
||||
|
||||
main ()
|
||||
{
|
||||
int col, c;
|
||||
int col, c;
|
||||
|
||||
while (1) {
|
||||
for (col = colStart; col <= colEnd; ) {
|
||||
switch (c = fgetc (stdin)) {
|
||||
case EOF:
|
||||
/* fall through */
|
||||
case '\n':
|
||||
while (col <= colEnd) {
|
||||
fputc (o29_code[' '] & 077, stdout);
|
||||
fputc ((o29_code[' '] >> 6) & 077, stdout);
|
||||
col++;
|
||||
}
|
||||
break;
|
||||
case '\t':
|
||||
do {
|
||||
fputc (o29_code[' '] & 077, stdout);
|
||||
fputc ((o29_code[' '] >> 6) & 077, stdout);
|
||||
col++;
|
||||
} while (((col & 07) != 1) && (col <= colEnd));
|
||||
break;
|
||||
default:
|
||||
fputc (o29_code[c] & 077, stdout);
|
||||
fputc ((o29_code[c] >> 6) & 077, stdout);
|
||||
col++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* flush long lines, or flag over-length card */
|
||||
if (c != '\n' && c != EOF) {
|
||||
printf ("overlength line\n");
|
||||
do c = fgetc (stdin);
|
||||
while ((c != EOF) && (c != '\n'));
|
||||
}
|
||||
if (c == EOF)
|
||||
break;
|
||||
}
|
||||
exit (1);
|
||||
while (1) {
|
||||
for (col = colStart; col <= colEnd; ) {
|
||||
switch (c = fgetc (stdin)) {
|
||||
case EOF:
|
||||
/* fall through */
|
||||
case '\n':
|
||||
while (col <= colEnd) {
|
||||
fputc (o29_code[' '] & 077, stdout);
|
||||
fputc ((o29_code[' '] >> 6) & 077, stdout);
|
||||
col++;
|
||||
}
|
||||
break;
|
||||
case '\t':
|
||||
do {
|
||||
fputc (o29_code[' '] & 077, stdout);
|
||||
fputc ((o29_code[' '] >> 6) & 077, stdout);
|
||||
col++;
|
||||
} while (((col & 07) != 1) && (col <= colEnd));
|
||||
break;
|
||||
default:
|
||||
fputc (o29_code[c] & 077, stdout);
|
||||
fputc ((o29_code[c] >> 6) & 077, stdout);
|
||||
col++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* flush long lines, or flag over-length card */
|
||||
if (c != '\n' && c != EOF) {
|
||||
printf ("overlength line\n");
|
||||
do c = fgetc (stdin);
|
||||
while ((c != EOF) && (c != '\n'));
|
||||
}
|
||||
if (c == EOF)
|
||||
break;
|
||||
}
|
||||
exit (1);
|
||||
}
|
||||
|
|
|
@ -727,7 +727,7 @@ while (reason == 0) { /* loop until halted */
|
|||
if (sim_brk_summ && sim_brk_test (PC, SWMASK ('E'))) { /* breakpoint? */
|
||||
reason = STOP_IBKPT; /* stop simulation */
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!usmd_defer) /* no IOT? load usmd */
|
||||
usmd = usmd_buf;
|
||||
else usmd_defer = 0; /* cancel defer */
|
||||
|
@ -2051,15 +2051,15 @@ if (MMR & MM_RDIS) /* reloc disabled? */
|
|||
else if ((MMR & MM_SH) && /* shared enabled and */
|
||||
(ma >= g_base[gmode]) && /* >= shared base and */
|
||||
(ma < (g_base[gmode] + slr_lnt[slr]))) { /* < shared end? */
|
||||
if (ma & 017400) { /* ESAS? */
|
||||
if ((rc == REL_W) && (MMR & MM_WP)) { /* write and protected? */
|
||||
prvn = trap_pending = 1; /* set flag, trap */
|
||||
return -1;
|
||||
}
|
||||
pa = (((MMR & MM_SBR_MASK) << 8) + ma) & DMASK; /* ESAS reloc */
|
||||
}
|
||||
else pa = RR + (ma & 0377); /* no, ISAS reloc */
|
||||
}
|
||||
if (ma & 017400) { /* ESAS? */
|
||||
if ((rc == REL_W) && (MMR & MM_WP)) { /* write and protected? */
|
||||
prvn = trap_pending = 1; /* set flag, trap */
|
||||
return -1;
|
||||
}
|
||||
pa = (((MMR & MM_SBR_MASK) << 8) + ma) & DMASK; /* ESAS reloc */
|
||||
}
|
||||
else pa = RR + (ma & 0377); /* no, ISAS reloc */
|
||||
}
|
||||
else {
|
||||
if (ma > (BR | 0377)) { /* normal reloc, viol? */
|
||||
if (rc != REL_C) /* set flag, trap */
|
||||
|
@ -2248,7 +2248,7 @@ static const uint8 std_dev[] =
|
|||
for (i = 0; i < DEV_MAX; i++) { /* clr tables */
|
||||
dev_tab[i] = NULL;
|
||||
dev_iors[i] = NULL;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < ((uint32) sizeof (std_dev)); i++) /* std entries */
|
||||
dev_tab[std_dev[i]] = &bad_dev;
|
||||
for (i = p = 0; (dptr = sim_devices[i]) != NULL; i++) { /* add devices */
|
||||
|
|
|
@ -241,7 +241,7 @@ static const int32 boot_rom[] = {
|
|||
0706101, /* DRSF ; wait for done */
|
||||
0602003, /* JMP .-1 */
|
||||
0600000 /* JMP 0 ; enter boot */
|
||||
};
|
||||
};
|
||||
|
||||
t_stat drm_boot (int32 unitno, DEVICE *dptr)
|
||||
{
|
||||
|
|
|
@ -27,8 +27,8 @@
|
|||
(PDP-9) TC02/TU55 DECtape
|
||||
(PDP-15) TC15/TU56 DECtape
|
||||
|
||||
23-Jun-06 RMS Fixed switch conflict in ATTACH
|
||||
Revised Type 550 header based on DECTOG formatter
|
||||
23-Jun-06 RMS Fixed switch conflict in ATTACH
|
||||
Revised Type 550 header based on DECTOG formatter
|
||||
13-Jun-06 RMS Fixed checksum calculation bug in Type 550
|
||||
16-Aug-05 RMS Fixed C++ declaration and cast problems
|
||||
25-Jan-04 RMS Revised for device debug support
|
||||
|
@ -557,7 +557,7 @@ else if ((pulse & 044) == 004) { /* MMLC */
|
|||
((fnc == FNC_WALL) && (uptr->flags & UNIT_WLK)))
|
||||
dt_seterr (uptr, DTB_SEL); /* select err */
|
||||
else dt_newsa (dtsa);
|
||||
}
|
||||
}
|
||||
DT_UPDINT;
|
||||
return dat;
|
||||
}
|
||||
|
@ -858,13 +858,13 @@ if (mot & DTS_DIR) /* update pos */
|
|||
else uptr->pos = uptr->pos + delta;
|
||||
if (((int32) uptr->pos < 0) ||
|
||||
((int32) uptr->pos > (DTU_FWDEZ (uptr) + DT_EZLIN))) {
|
||||
detach_unit (uptr); /* off reel? */
|
||||
uptr->STATE = uptr->pos = 0;
|
||||
unum = (int32) (uptr - dt_dev.units);
|
||||
if (unum == DTA_GETUNIT (dtsa)) /* if selected, */
|
||||
dt_seterr (uptr, DTB_SEL); /* error */
|
||||
return TRUE;
|
||||
}
|
||||
detach_unit (uptr); /* off reel? */
|
||||
uptr->STATE = uptr->pos = 0;
|
||||
unum = (int32) (uptr - dt_dev.units);
|
||||
if (unum == DTA_GETUNIT (dtsa)) /* if selected, */
|
||||
dt_seterr (uptr, DTB_SEL); /* error */
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -1038,7 +1038,7 @@ switch (fnc) { /* at speed, check fnc *
|
|||
if (dtsb & DTB_DTF) { /* DTF set? */
|
||||
dt_seterr (uptr, DTB_TIM); /* timing error */
|
||||
return SCPE_OK;
|
||||
}
|
||||
}
|
||||
if (DEBUG_PRI (dt_dev, LOG_RW) ||
|
||||
(DEBUG_PRI (dt_dev, LOG_BL) && (blk == dt_logblk)))
|
||||
fprintf (sim_deb, ">>DT%d: writing block %d %s%s\n", unum, blk,
|
||||
|
@ -1460,7 +1460,7 @@ if (uptr->flags & UNIT_8FMT) { /* 12b? */
|
|||
}
|
||||
} /* end file loop */
|
||||
uptr->hwmark = ba;
|
||||
} /* end if */
|
||||
} /* end if */
|
||||
else if (uptr->flags & UNIT_11FMT) { /* 16b? */
|
||||
for (ba = 0; ba < uptr->capac; ) { /* loop thru file */
|
||||
k = fxread (pdp11b, sizeof (uint16), D18_BSIZE, uptr->fileref);
|
||||
|
@ -1508,7 +1508,7 @@ if (uptr->WRITTEN && uptr->hwmark && ((uptr->flags & UNIT_RO)== 0)) { /* any
|
|||
((fbuf[ba + 1] >> 12) & 077);
|
||||
pdp8b[k + 2] = fbuf[ba + 1] & 07777;
|
||||
ba = ba + 2;
|
||||
} /* end loop blk */
|
||||
} /* end loop blk */
|
||||
fxwrite (pdp8b, sizeof (uint16), D8_NBSIZE, uptr->fileref);
|
||||
if (ferror (uptr->fileref))
|
||||
break;
|
||||
|
@ -1544,7 +1544,7 @@ if (sim_is_active (uptr)) {
|
|||
if ((u == DTA_GETUNIT (dtsa)) && (dtsa & DTA_STSTP)) {
|
||||
dtsb = dtsb | DTB_ERF | DTB_SEL | DTB_DTF;
|
||||
DT_UPDINT;
|
||||
}
|
||||
}
|
||||
uptr->STATE = uptr->pos = 0;
|
||||
}
|
||||
if (uptr->hwmark && ((uptr->flags & UNIT_RO) == 0)) { /* any data? */
|
||||
|
|
|
@ -204,9 +204,9 @@ int32 s = rb_set_bcd (bcd_s); /* bin sector */
|
|||
|
||||
if ((t >= RB_NUMTR) || (t < 0) || /* invalid? */
|
||||
(s >= RB_NUMSC) || (s < 0)) {
|
||||
rb_updsta (RBS_ILA); /* error */
|
||||
return old_da; /* don't change */
|
||||
}
|
||||
rb_updsta (RBS_ILA); /* error */
|
||||
return old_da; /* don't change */
|
||||
}
|
||||
else return (((t * RB_NUMSC) + s) * RB_NUMWD); /* new da */
|
||||
}
|
||||
|
||||
|
|
|
@ -101,11 +101,11 @@
|
|||
|
||||
#define RFS_CLR 0000170 /* always clear */
|
||||
#define RFS_EFLGS (RFS_HDW | RFS_APE | RFS_MXF | RFS_WCE | \
|
||||
RFS_DPE | RFS_WLO | RFS_NED ) /* error flags */
|
||||
RFS_DPE | RFS_WLO | RFS_NED ) /* error flags */
|
||||
#define RFS_FR (RFS_FNC|RFS_IE)
|
||||
#define GET_FNC(x) (((x) >> RFS_V_FNC) & RFS_M_FNC)
|
||||
#define GET_POS(x) ((int) fmod (sim_gtime () / ((double) (x)), \
|
||||
((double) RF_NUMWD)))
|
||||
((double) RF_NUMWD)))
|
||||
#define RF_BUSY (sim_is_active (&rf_unit))
|
||||
|
||||
extern int32 M[];
|
||||
|
@ -295,7 +295,7 @@ do {
|
|||
break;
|
||||
}
|
||||
else { /* not locked */
|
||||
fbuf[rf_da] = M[pa]; /* write word */
|
||||
fbuf[rf_da] = M[pa]; /* write word */
|
||||
if (((uint32) rf_da) >= uptr->hwmark)
|
||||
uptr->hwmark = rf_da + 1;
|
||||
}
|
||||
|
|
|
@ -90,7 +90,7 @@
|
|||
|
||||
#define STA_RW 0777000 /* read/write */
|
||||
#define STA_EFLGS (STA_WPE | STA_NXC | STA_NXF | STA_NXS | \
|
||||
STA_HNF | STA_SUSI) /* error flags */
|
||||
STA_HNF | STA_SUSI) /* error flags */
|
||||
#define STA_DYN (STA_SUWP | STA_SUSI) /* per unit status */
|
||||
#define GET_UNIT(x) (((x) >> STA_V_UNIT) & STA_M_UNIT)
|
||||
#define GET_FUNC(x) (((x) >> STA_V_FUNC) & STA_M_FUNC)
|
||||
|
@ -111,7 +111,7 @@
|
|||
#define STB_SUNR 0000001 /* sel unit not rdy */
|
||||
|
||||
#define STB_EFLGS (STB_SUFU | STB_PGE | STB_EOP | STB_TME | STB_FME | \
|
||||
STB_WCE | STB_WPE | STB_LON ) /* error flags */
|
||||
STB_WCE | STB_WPE | STB_LON ) /* error flags */
|
||||
#define STB_DYN (STB_SUFU | STB_SUSU | STB_SUNR) /* per unit */
|
||||
|
||||
/* Disk address */
|
||||
|
|
|
@ -259,7 +259,7 @@ if (ttix_done) {
|
|||
}
|
||||
else {
|
||||
CLR_INT (TTI1);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -438,7 +438,7 @@ if (newln < ttx_lines) {
|
|||
if (ttx_ldsc[i].conn) {
|
||||
tmxr_linemsg (&ttx_ldsc[i], "\r\nOperator disconnected line\r\n");
|
||||
tmxr_reset_ln (&ttx_ldsc[i]); /* reset line */
|
||||
}
|
||||
}
|
||||
ttox_unit[i].flags = ttox_unit[i].flags | UNIT_DIS;
|
||||
ttx_reset_ln (i);
|
||||
}
|
||||
|
|
|
@ -357,7 +357,7 @@ while (reason == 0) { /* loop until halted */
|
|||
sim_brk_test (MA, (1u << SIM_BKPT_V_SPC) | SWMASK ('E'))) { /* breakpoint? */
|
||||
reason = STOP_IBKPT; /* stop simulation */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
IR = M[MA]; /* fetch instruction */
|
||||
if (sim_brk_summ &&
|
||||
|
|
|
@ -131,7 +131,7 @@ DIB df_dib = { DEV_DF, 3, { &df60, &df61, &df62 } };
|
|||
|
||||
UNIT df_unit = {
|
||||
UDATA (&df_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_BUFABLE+UNIT_MUSTBUF,
|
||||
DF_DKSIZE)
|
||||
DF_DKSIZE)
|
||||
};
|
||||
|
||||
REG df_reg[] = {
|
||||
|
@ -266,7 +266,7 @@ do {
|
|||
if (da >= uptr->capac) { /* nx disk addr? */
|
||||
df_sta = df_sta | DFS_NXD;
|
||||
break;
|
||||
}
|
||||
}
|
||||
M[DF_WC] = (M[DF_WC] + 1) & 07777; /* incr word count */
|
||||
M[DF_MA] = (M[DF_MA] + 1) & 07777; /* incr mem addr */
|
||||
pa = mex | M[DF_MA]; /* add extension */
|
||||
|
@ -278,7 +278,7 @@ do {
|
|||
if ((df_wlk >> t) & 1) /* locked? set err */
|
||||
df_sta = df_sta | DFS_WLS;
|
||||
else { /* not locked */
|
||||
fbuf[da] = M[pa]; /* write word */
|
||||
fbuf[da] = M[pa]; /* write word */
|
||||
if (da >= uptr->hwmark) uptr->hwmark = da + 1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -682,13 +682,13 @@ if (mot & DTS_DIR) /* update pos */
|
|||
else uptr->pos = uptr->pos + delta;
|
||||
if (((int32) uptr->pos < 0) ||
|
||||
((int32) uptr->pos > (DTU_FWDEZ (uptr) + DT_EZLIN))) {
|
||||
detach_unit (uptr); /* off reel? */
|
||||
uptr->STATE = uptr->pos = 0;
|
||||
unum = (int32) (uptr - dt_dev.units);
|
||||
if (unum == DTA_GETUNIT (dtsa)) /* if selected, */
|
||||
dt_seterr (uptr, DTB_SEL); /* error */
|
||||
return TRUE;
|
||||
}
|
||||
detach_unit (uptr); /* off reel? */
|
||||
uptr->STATE = uptr->pos = 0;
|
||||
unum = (int32) (uptr - dt_dev.units);
|
||||
if (unum == DTA_GETUNIT (dtsa)) /* if selected, */
|
||||
dt_seterr (uptr, DTB_SEL); /* error */
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -796,7 +796,7 @@ switch (fnc) { /* at speed, check fnc *
|
|||
if (dtsb & DTB_DTF) { /* DTF set? */
|
||||
dt_seterr (uptr, DTB_TIM); /* timing error */
|
||||
return SCPE_OK;
|
||||
}
|
||||
}
|
||||
if (DEBUG_PRI (dt_dev, LOG_RW) ||
|
||||
(DEBUG_PRI (dt_dev, LOG_BL) && (blk == dt_logblk)))
|
||||
fprintf (sim_deb, ">>DT%d: reading block %d %s%s\n",
|
||||
|
@ -950,7 +950,7 @@ switch (fnc) { /* at speed, check fnc *
|
|||
if (dtsb & DTB_DTF) { /* DTF set? */
|
||||
dt_seterr (uptr, DTB_TIM); /* timing error */
|
||||
return SCPE_OK;
|
||||
}
|
||||
}
|
||||
relpos = DT_LIN2OF (uptr->pos, uptr); /* cur pos in blk */
|
||||
M[DT_WC] = (M[DT_WC] + 1) & 07777; /* incr WC, CA */
|
||||
M[DT_CA] = (M[DT_CA] + 1) & 07777;
|
||||
|
@ -965,7 +965,7 @@ switch (fnc) { /* at speed, check fnc *
|
|||
fbuf[ba] = dat; /* write word */
|
||||
if (ba >= uptr->hwmark)
|
||||
uptr->hwmark = ba + 1;
|
||||
}
|
||||
}
|
||||
/* ignore hdr */
|
||||
sim_activate (uptr, DT_WSIZE * dt_ltime);
|
||||
if (M[DT_WC] == 0)
|
||||
|
|
|
@ -128,7 +128,7 @@
|
|||
|
||||
#define STA_CLR (FN_RMASK | 00020) /* always clear */
|
||||
#define STA_DYN (STA_REW | STA_BOT | STA_REM | STA_EOF | \
|
||||
STA_EOT | STA_WLK) /* kept in USTAT */
|
||||
STA_EOT | STA_WLK) /* kept in USTAT */
|
||||
|
||||
extern uint16 M[];
|
||||
extern int32 int_req, stop_inst;
|
||||
|
|
|
@ -217,9 +217,9 @@ switch (IR & 07) { /* decode IR<9:11> */
|
|||
sim_activate (&ptp_unit, ptp_unit.wait); /* activate unit */
|
||||
return AC;
|
||||
|
||||
default:
|
||||
return (stop_inst << IOT_V_REASON) + AC;
|
||||
} /* end switch */
|
||||
default:
|
||||
return (stop_inst << IOT_V_REASON) + AC;
|
||||
} /* end switch */
|
||||
}
|
||||
|
||||
/* Unit service */
|
||||
|
|
|
@ -332,7 +332,7 @@ do {
|
|||
if ((rf_wlk >> t) & 1) /* write locked? */
|
||||
rf_sta = rf_sta | RFS_WLS;
|
||||
else { /* not locked */
|
||||
fbuf[rf_da] = M[pa]; /* write word */
|
||||
fbuf[rf_da] = M[pa]; /* write word */
|
||||
if (((uint32) rf_da) >= uptr->hwmark)
|
||||
uptr->hwmark = rf_da + 1;
|
||||
}
|
||||
|
|
|
@ -375,16 +375,16 @@ if (new_mving && !prev_mving) { /* start from stop? */
|
|||
|
||||
if ((prev_mving && !new_mving) || /* stop from moving? */
|
||||
(prev_dir != new_dir)) { /* dir chg while moving? */
|
||||
if (uptr->STATE >= STA_ACC) { /* not stopping? */
|
||||
if (td_setpos (uptr)) /* update pos */
|
||||
if (uptr->STATE >= STA_ACC) { /* not stopping? */
|
||||
if (td_setpos (uptr)) /* update pos */
|
||||
return TRUE;
|
||||
sim_cancel (uptr); /* stop current */
|
||||
sim_activate (uptr, td_dctime); /* schedule decel */
|
||||
uptr->STATE = STA_DEC | prev_dir; /* set status */
|
||||
td_slf = td_qlf = td_qlctr = 0; /* clear state */
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
sim_cancel (uptr); /* stop current */
|
||||
sim_activate (uptr, td_dctime); /* schedule decel */
|
||||
uptr->STATE = STA_DEC | prev_dir; /* set status */
|
||||
td_slf = td_qlf = td_qlctr = 0; /* clear state */
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -445,10 +445,10 @@ if (uptr->STATE & STA_DIR) /* update pos */
|
|||
else uptr->pos = uptr->pos + delta;
|
||||
if (((int32) uptr->pos < 0) ||
|
||||
((int32) uptr->pos > (DTU_FWDEZ (uptr) + DT_EZLIN))) {
|
||||
detach_unit (uptr); /* off reel */
|
||||
sim_cancel (uptr); /* no timing pulses */
|
||||
return TRUE;
|
||||
}
|
||||
detach_unit (uptr); /* off reel */
|
||||
sim_cancel (uptr); /* no timing pulses */
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
|
352
SAGE/chip_defs.h
352
SAGE/chip_defs.h
|
@ -55,7 +55,7 @@
|
|||
/* generic debug tracing support */
|
||||
#if DBG_MSG==1
|
||||
|
||||
#define ADDRESS_FORMAT "[0x%08x]"
|
||||
#define ADDRESS_FORMAT "[0x%08x]"
|
||||
#if UNIX_PLATFORM
|
||||
#define NLP "\r\n"
|
||||
#else
|
||||
|
@ -63,21 +63,21 @@
|
|||
#endif
|
||||
|
||||
#define TRACE_PRINT(level,args)\
|
||||
if(sim_deb && chip->dev->dctrl & level) { \
|
||||
fprintf(sim_deb,"%-4s: " ADDRESS_FORMAT " ", chip->dev->name, PCX); \
|
||||
fprintf args; fputs(NLP,sim_deb); }
|
||||
if(sim_deb && chip->dev->dctrl & level) { \
|
||||
fprintf(sim_deb,"%-4s: " ADDRESS_FORMAT " ", chip->dev->name, PCX); \
|
||||
fprintf args; fputs(NLP,sim_deb); }
|
||||
#define TRACE_PRINT0(level,fmt)\
|
||||
if(sim_deb && chip->dev->dctrl & level) { \
|
||||
fprintf(sim_deb,"%-4s: " ADDRESS_FORMAT " ", chip->dev->name, PCX); \
|
||||
fprintf(sim_deb,fmt NLP); }
|
||||
if(sim_deb && chip->dev->dctrl & level) { \
|
||||
fprintf(sim_deb,"%-4s: " ADDRESS_FORMAT " ", chip->dev->name, PCX); \
|
||||
fprintf(sim_deb,fmt NLP); }
|
||||
#define TRACE_PRINT1(level,fmt,arg1)\
|
||||
if(sim_deb && chip->dev->dctrl & level) { \
|
||||
fprintf(sim_deb,"%-4s: " ADDRESS_FORMAT " ", chip->dev->name, PCX); \
|
||||
fprintf(sim_deb,fmt NLP,arg1); }
|
||||
if(sim_deb && chip->dev->dctrl & level) { \
|
||||
fprintf(sim_deb,"%-4s: " ADDRESS_FORMAT " ", chip->dev->name, PCX); \
|
||||
fprintf(sim_deb,fmt NLP,arg1); }
|
||||
#define TRACE_PRINT2(level,fmt,arg1,arg2)\
|
||||
if(sim_deb && chip->dev->dctrl & level) { \
|
||||
fprintf(sim_deb,"%-4s: " ADDRESS_FORMAT " ", chip->dev->name, PCX); \
|
||||
fprintf(sim_deb,fmt NLP,arg1,arg2); }
|
||||
if(sim_deb && chip->dev->dctrl & level) { \
|
||||
fprintf(sim_deb,"%-4s: " ADDRESS_FORMAT " ", chip->dev->name, PCX); \
|
||||
fprintf(sim_deb,fmt NLP,arg1,arg2); }
|
||||
#else
|
||||
#define TRACE_PRINT(level,args)
|
||||
#define TRACE_PRINT0(level,fmt)
|
||||
|
@ -90,12 +90,12 @@
|
|||
*****************************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
int pfirst;
|
||||
int prate;
|
||||
TMLN ldsc;
|
||||
TMXR desc;
|
||||
UNIT* term;
|
||||
UNIT* poll;
|
||||
int pfirst;
|
||||
int prate;
|
||||
TMLN ldsc;
|
||||
TMXR desc;
|
||||
UNIT* term;
|
||||
UNIT* poll;
|
||||
} SERMUX;
|
||||
t_stat mux_attach(UNIT*,char*,SERMUX*);
|
||||
t_stat mux_detach(UNIT*,SERMUX*);
|
||||
|
@ -103,44 +103,44 @@ t_stat mux_detach(UNIT*,SERMUX*);
|
|||
/*****************************************************************************************
|
||||
* 8259 PIC
|
||||
*****************************************************************************************/
|
||||
#define I8259_ICW1 0x10
|
||||
#define I8259_ICW1_A765 0xe0
|
||||
#define I8259_ICW1_LTIM 0x08
|
||||
#define I8259_ICW1_ADI 0x04
|
||||
#define I8259_ICW1_SNGL 0x02
|
||||
#define I8259_ICW1_IC4 0x01
|
||||
#define I8259_ICW4_SFNM 0x10
|
||||
#define I8259_ICW4_BUF 0x08
|
||||
#define I8259_ICW4_MS 0x04
|
||||
#define I8259_ICW4_AEOI 0x02
|
||||
#define I8259_ICW4_UPM 0x01
|
||||
#define I8259_OCW2_MODE 0xe0
|
||||
#define I8259_OCW2_LEVEL 0x07
|
||||
#define I8259_OCW3_ESMM 0x40
|
||||
#define I8259_OCW3_SMM 0x20
|
||||
#define I8259_OCW3 0x08
|
||||
#define I8259_OCW3_POLL 0x04
|
||||
#define I8259_OCW3_RR 0x02
|
||||
#define I8259_OCW3_RIS 0x01
|
||||
#define I8259_ICW1 0x10
|
||||
#define I8259_ICW1_A765 0xe0
|
||||
#define I8259_ICW1_LTIM 0x08
|
||||
#define I8259_ICW1_ADI 0x04
|
||||
#define I8259_ICW1_SNGL 0x02
|
||||
#define I8259_ICW1_IC4 0x01
|
||||
#define I8259_ICW4_SFNM 0x10
|
||||
#define I8259_ICW4_BUF 0x08
|
||||
#define I8259_ICW4_MS 0x04
|
||||
#define I8259_ICW4_AEOI 0x02
|
||||
#define I8259_ICW4_UPM 0x01
|
||||
#define I8259_OCW2_MODE 0xe0
|
||||
#define I8259_OCW2_LEVEL 0x07
|
||||
#define I8259_OCW3_ESMM 0x40
|
||||
#define I8259_OCW3_SMM 0x20
|
||||
#define I8259_OCW3 0x08
|
||||
#define I8259_OCW3_POLL 0x04
|
||||
#define I8259_OCW3_RR 0x02
|
||||
#define I8259_OCW3_RIS 0x01
|
||||
|
||||
typedef struct i8259 {
|
||||
PNP_INFO pnp;
|
||||
DEVICE* dev; /* backlink to device */
|
||||
t_stat (*write)(struct i8259* chip,int port,uint32 value);
|
||||
t_stat (*read)(struct i8259* chip,int port,uint32* value);
|
||||
t_stat (*reset)(struct i8259* chip);
|
||||
int state;
|
||||
int rmode;
|
||||
int32 imr;
|
||||
int32 isr;
|
||||
int32 irr;
|
||||
int32 icw1;
|
||||
int32 icw2;
|
||||
int32 icw4;
|
||||
int32 prio; /* which IR* has prio 7? */
|
||||
t_bool autoint;
|
||||
int intlevel;
|
||||
int intvector;
|
||||
PNP_INFO pnp;
|
||||
DEVICE* dev; /* backlink to device */
|
||||
t_stat (*write)(struct i8259* chip,int port,uint32 value);
|
||||
t_stat (*read)(struct i8259* chip,int port,uint32* value);
|
||||
t_stat (*reset)(struct i8259* chip);
|
||||
int state;
|
||||
int rmode;
|
||||
int32 imr;
|
||||
int32 isr;
|
||||
int32 irr;
|
||||
int32 icw1;
|
||||
int32 icw2;
|
||||
int32 icw4;
|
||||
int32 prio; /* which IR* has prio 7? */
|
||||
t_bool autoint;
|
||||
int intlevel;
|
||||
int intvector;
|
||||
} I8259;
|
||||
|
||||
extern t_stat i8259_io(IOHANDLER* ioh,uint32* value,uint32 rw,uint32 mask);
|
||||
|
@ -159,63 +159,63 @@ extern DEBTAB i8259_dt[];
|
|||
/*****************************************************************************************
|
||||
* 8251 USART
|
||||
*****************************************************************************************/
|
||||
#define I8251_AMODE_STOP 0xc0
|
||||
#define I8251_AMODE_S1 0x40
|
||||
#define I8251_AMODE_S15 0x80
|
||||
#define I8251_AMODE_S2 0xc0
|
||||
#define I8251_MODE_EP 0x20
|
||||
#define I8251_MODE_PEN 0x10
|
||||
#define I8251_AMODE_BITS 0x0c
|
||||
#define I8251_AMODE_BITS5 0x00
|
||||
#define I8251_AMODE_BITS6 0x04
|
||||
#define I8251_AMODE_BITS7 0x08
|
||||
#define I8251_AMODE_BITS8 0x0c
|
||||
#define I8251_MODE_BAUD 0x03
|
||||
#define I8251_MODE_SYNC 0x00
|
||||
#define I8251_AMODE_BAUD1 0x01
|
||||
#define I8251_AMODE_BAUD16 0x02
|
||||
#define I8251_AMODE_BAUD64 0x03
|
||||
#define I8251_SMODE_ESD 0x40
|
||||
#define I8251_SMODE_SCS 0x80
|
||||
#define I8251_CMD_EH 0x80
|
||||
#define I8251_CMD_IR 0x40
|
||||
#define I8251_CMD_RTS 0x20
|
||||
#define I8251_CMD_ER 0x10
|
||||
#define I8251_CMD_SBRK 0x08
|
||||
#define I8251_CMD_RXE 0x04
|
||||
#define I8251_CMD_DTR 0x02
|
||||
#define I8251_CMD_TXEN 0x01
|
||||
#define I8251_ST_DSR 0x80
|
||||
#define I8251_ST_SYNBRK 0x40
|
||||
#define I8251_ST_FE 0x20
|
||||
#define I8251_ST_OE 0x10
|
||||
#define I8251_ST_PE 0x08
|
||||
#define I8251_ST_TXEMPTY 0x04
|
||||
#define I8251_ST_RXRDY 0x02
|
||||
#define I8251_ST_TXRDY 0x01
|
||||
#define I8251_AMODE_STOP 0xc0
|
||||
#define I8251_AMODE_S1 0x40
|
||||
#define I8251_AMODE_S15 0x80
|
||||
#define I8251_AMODE_S2 0xc0
|
||||
#define I8251_MODE_EP 0x20
|
||||
#define I8251_MODE_PEN 0x10
|
||||
#define I8251_AMODE_BITS 0x0c
|
||||
#define I8251_AMODE_BITS5 0x00
|
||||
#define I8251_AMODE_BITS6 0x04
|
||||
#define I8251_AMODE_BITS7 0x08
|
||||
#define I8251_AMODE_BITS8 0x0c
|
||||
#define I8251_MODE_BAUD 0x03
|
||||
#define I8251_MODE_SYNC 0x00
|
||||
#define I8251_AMODE_BAUD1 0x01
|
||||
#define I8251_AMODE_BAUD16 0x02
|
||||
#define I8251_AMODE_BAUD64 0x03
|
||||
#define I8251_SMODE_ESD 0x40
|
||||
#define I8251_SMODE_SCS 0x80
|
||||
#define I8251_CMD_EH 0x80
|
||||
#define I8251_CMD_IR 0x40
|
||||
#define I8251_CMD_RTS 0x20
|
||||
#define I8251_CMD_ER 0x10
|
||||
#define I8251_CMD_SBRK 0x08
|
||||
#define I8251_CMD_RXE 0x04
|
||||
#define I8251_CMD_DTR 0x02
|
||||
#define I8251_CMD_TXEN 0x01
|
||||
#define I8251_ST_DSR 0x80
|
||||
#define I8251_ST_SYNBRK 0x40
|
||||
#define I8251_ST_FE 0x20
|
||||
#define I8251_ST_OE 0x10
|
||||
#define I8251_ST_PE 0x08
|
||||
#define I8251_ST_TXEMPTY 0x04
|
||||
#define I8251_ST_RXRDY 0x02
|
||||
#define I8251_ST_TXRDY 0x01
|
||||
|
||||
typedef struct i8251 {
|
||||
PNP_INFO pnp;
|
||||
DEVICE* dev; /* backlink to device */
|
||||
t_stat (*write)(struct i8251* chip,int port,uint32 value);
|
||||
t_stat (*read)(struct i8251* chip,int port,uint32* value);
|
||||
t_stat (*reset)(struct i8251* chip);
|
||||
t_stat (*txint)(struct i8251* chip);
|
||||
t_stat (*rxint)(struct i8251* chip);
|
||||
UNIT* in;
|
||||
UNIT* out;
|
||||
SERMUX* mux;
|
||||
int init;
|
||||
int mode;
|
||||
int sync1;
|
||||
int sync2;
|
||||
int cmd;
|
||||
int ibuf;
|
||||
int obuf;
|
||||
int status;
|
||||
int bitmask;
|
||||
t_bool oob; /* out-of-band=1 will allow a console to receive CTRL-E even when receiver is disabled */
|
||||
int crlf; /* CRLF state machine to suppress NUL bytes */
|
||||
PNP_INFO pnp;
|
||||
DEVICE* dev; /* backlink to device */
|
||||
t_stat (*write)(struct i8251* chip,int port,uint32 value);
|
||||
t_stat (*read)(struct i8251* chip,int port,uint32* value);
|
||||
t_stat (*reset)(struct i8251* chip);
|
||||
t_stat (*txint)(struct i8251* chip);
|
||||
t_stat (*rxint)(struct i8251* chip);
|
||||
UNIT* in;
|
||||
UNIT* out;
|
||||
SERMUX* mux;
|
||||
int init;
|
||||
int mode;
|
||||
int sync1;
|
||||
int sync2;
|
||||
int cmd;
|
||||
int ibuf;
|
||||
int obuf;
|
||||
int status;
|
||||
int bitmask;
|
||||
t_bool oob; /* out-of-band=1 will allow a console to receive CTRL-E even when receiver is disabled */
|
||||
int crlf; /* CRLF state machine to suppress NUL bytes */
|
||||
} I8251;
|
||||
|
||||
/* default handlers */
|
||||
|
@ -236,48 +236,48 @@ extern DEBTAB i8251_dt[];
|
|||
*****************************************************************************************/
|
||||
/*forward*/ struct i8253;
|
||||
typedef struct {
|
||||
t_stat (*call)(struct i8253* chip,int rw,uint32* src);
|
||||
int state; /* the current output state (latching, MSB/LSB out */
|
||||
int mode; /* programmed mode */
|
||||
int32 latch; /* the latched value of count */
|
||||
int32 divider; /* programmed divider value */
|
||||
int32 count; /* the real count value as calculated by rcall callback */
|
||||
t_stat (*call)(struct i8253* chip,int rw,uint32* src);
|
||||
int state; /* the current output state (latching, MSB/LSB out */
|
||||
int mode; /* programmed mode */
|
||||
int32 latch; /* the latched value of count */
|
||||
int32 divider; /* programmed divider value */
|
||||
int32 count; /* the real count value as calculated by rcall callback */
|
||||
} I8253CNTR;
|
||||
|
||||
typedef struct i8253 {
|
||||
PNP_INFO pnp;
|
||||
DEVICE* dev; /* backlink to device */
|
||||
UNIT* unit; /* backlink to unit */
|
||||
t_stat (*reset)(struct i8253* chip);
|
||||
t_stat (*ckmode)(struct i8253* chip, uint32 value);
|
||||
I8253CNTR cntr[3];
|
||||
int init;
|
||||
PNP_INFO pnp;
|
||||
DEVICE* dev; /* backlink to device */
|
||||
UNIT* unit; /* backlink to unit */
|
||||
t_stat (*reset)(struct i8253* chip);
|
||||
t_stat (*ckmode)(struct i8253* chip, uint32 value);
|
||||
I8253CNTR cntr[3];
|
||||
int init;
|
||||
} I8253;
|
||||
|
||||
#define I8253_SCMASK 0xc0
|
||||
#define I8253_SC0 0x00
|
||||
#define I8253_SC1 0x40
|
||||
#define I8253_SC2 0x80
|
||||
#define I8253_RLMASK 0x30
|
||||
#define I8253_LATCH 0x00
|
||||
#define I8253_LSB 0x10
|
||||
#define I8253_MSB 0x20
|
||||
#define I8253_BOTH 0x30
|
||||
#define I8253_MODEMASK 0xe0
|
||||
#define I8253_MODE0 0x00
|
||||
#define I8253_MODE1 0x02
|
||||
#define I8253_MODE2 0x04
|
||||
#define I8253_MODE2a 0x0c
|
||||
#define I8253_MODE3 0x06
|
||||
#define I8253_MODE3a 0x0e
|
||||
#define I8253_MODE4 0x08
|
||||
#define I8253_MODE5 0x0a
|
||||
#define I8253_MODEBIN 0x00
|
||||
#define I8253_MODEBCD 0x01
|
||||
#define I8253_SCMASK 0xc0
|
||||
#define I8253_SC0 0x00
|
||||
#define I8253_SC1 0x40
|
||||
#define I8253_SC2 0x80
|
||||
#define I8253_RLMASK 0x30
|
||||
#define I8253_LATCH 0x00
|
||||
#define I8253_LSB 0x10
|
||||
#define I8253_MSB 0x20
|
||||
#define I8253_BOTH 0x30
|
||||
#define I8253_MODEMASK 0xe0
|
||||
#define I8253_MODE0 0x00
|
||||
#define I8253_MODE1 0x02
|
||||
#define I8253_MODE2 0x04
|
||||
#define I8253_MODE2a 0x0c
|
||||
#define I8253_MODE3 0x06
|
||||
#define I8253_MODE3a 0x0e
|
||||
#define I8253_MODE4 0x08
|
||||
#define I8253_MODE5 0x0a
|
||||
#define I8253_MODEBIN 0x00
|
||||
#define I8253_MODEBCD 0x01
|
||||
|
||||
#define I8253_ST_LSBNEXT 0x01
|
||||
#define I8253_ST_MSBNEXT 0x02
|
||||
#define I8253_ST_LATCH 0x08
|
||||
#define I8253_ST_LSBNEXT 0x01
|
||||
#define I8253_ST_MSBNEXT 0x02
|
||||
#define I8253_ST_LATCH 0x08
|
||||
|
||||
/* default handlers */
|
||||
extern t_stat i8253_io(IOHANDLER* ioh,uint32* value,uint32 rw,uint32 mask);
|
||||
|
@ -311,20 +311,20 @@ typedef struct {
|
|||
} I8272_DRIVE_INFO;
|
||||
|
||||
typedef enum i8272state {
|
||||
S_CMD=1, S_CMDREAD, S_EXEC, S_DATAWRITE, S_SECWRITE, S_SECREAD, S_DATAREAD, S_RESULT
|
||||
S_CMD=1, S_CMDREAD, S_EXEC, S_DATAWRITE, S_SECWRITE, S_SECREAD, S_DATAREAD, S_RESULT
|
||||
} I8272_STATE;
|
||||
|
||||
typedef struct i8272 {
|
||||
PNP_INFO pnp; /* Plug-n-Play Information */
|
||||
DEVICE* dev; /* backlink to device */
|
||||
t_stat (*write)(struct i8272* chip,int port,uint32 data);
|
||||
t_stat (*read)(struct i8272* chip,int port,uint32* data);
|
||||
t_stat (*reset)(struct i8272* chip);
|
||||
void (*seldrv)(struct i8272* chip,int seldrv);
|
||||
void (*irq)(struct i8272* chip,int delay);
|
||||
|
||||
I8272_STATE fdc_state; /* internal state machine */
|
||||
uint32 fdc_dma_addr;/* DMA Transfer Address */
|
||||
PNP_INFO pnp; /* Plug-n-Play Information */
|
||||
DEVICE* dev; /* backlink to device */
|
||||
t_stat (*write)(struct i8272* chip,int port,uint32 data);
|
||||
t_stat (*read)(struct i8272* chip,int port,uint32* data);
|
||||
t_stat (*reset)(struct i8272* chip);
|
||||
void (*seldrv)(struct i8272* chip,int seldrv);
|
||||
void (*irq)(struct i8272* chip,int delay);
|
||||
|
||||
I8272_STATE fdc_state; /* internal state machine */
|
||||
uint32 fdc_dma_addr;/* DMA Transfer Address */
|
||||
uint8 fdc_msr; /* 8272 Main Status Register */
|
||||
uint8 fdc_nd; /* Non-DMA Mode 1=Non-DMA, 0=DMA */
|
||||
uint8 fdc_head; /* H Head Number */
|
||||
|
@ -340,9 +340,9 @@ typedef struct i8272 {
|
|||
uint8 fdc_seek_end; /* Seek was executed successfully */
|
||||
int fdc_secsz; /* N Sector Length in bytes: 2^(7 + fdc_sec_len), fdc_sec_len <= I8272_MAX_N */
|
||||
int fdc_nd_cnt; /* read/write count in non-DMA mode, -1 if start read */
|
||||
uint8 fdc_sdata[I8272_MAX_SECTOR_SZ]; /* sector buffer */
|
||||
uint8 fdc_fault; /* error code passed from some commands to sense_int */
|
||||
|
||||
uint8 fdc_sdata[I8272_MAX_SECTOR_SZ]; /* sector buffer */
|
||||
uint8 fdc_fault; /* error code passed from some commands to sense_int */
|
||||
|
||||
uint8 cmd_cnt; /* command read count */
|
||||
uint8 cmd[10]; /* Storage for current command */
|
||||
uint8 cmd_len; /* FDC Command Length */
|
||||
|
@ -397,22 +397,22 @@ extern DEVICE* i8272_dev;
|
|||
* 8255 PARPORT
|
||||
*****************************************************************************************/
|
||||
typedef struct i8255 {
|
||||
PNP_INFO pnp;
|
||||
DEVICE* dev; /* backlink to device */
|
||||
t_stat (*write)(struct i8255* chip,int port,uint32 data);
|
||||
t_stat (*read)(struct i8255* chip,int port,uint32* data);
|
||||
t_stat (*reset)(struct i8255* chip);
|
||||
t_stat (*calla)(struct i8255* chip,int rw);
|
||||
t_stat (*callb)(struct i8255* chip,int rw);
|
||||
t_stat (*callc)(struct i8255* chip,int rw);
|
||||
t_stat (*ckmode)(struct i8255* chip,uint32 data);
|
||||
uint32 porta;
|
||||
uint32 last_porta; /* for edge detection */
|
||||
uint32 portb;
|
||||
uint32 last_portb; /* for edge detection */
|
||||
uint32 portc;
|
||||
uint32 last_portc; /* for edge detection */
|
||||
uint32 ctrl;
|
||||
PNP_INFO pnp;
|
||||
DEVICE* dev; /* backlink to device */
|
||||
t_stat (*write)(struct i8255* chip,int port,uint32 data);
|
||||
t_stat (*read)(struct i8255* chip,int port,uint32* data);
|
||||
t_stat (*reset)(struct i8255* chip);
|
||||
t_stat (*calla)(struct i8255* chip,int rw);
|
||||
t_stat (*callb)(struct i8255* chip,int rw);
|
||||
t_stat (*callc)(struct i8255* chip,int rw);
|
||||
t_stat (*ckmode)(struct i8255* chip,uint32 data);
|
||||
uint32 porta;
|
||||
uint32 last_porta; /* for edge detection */
|
||||
uint32 portb;
|
||||
uint32 last_portb; /* for edge detection */
|
||||
uint32 portc;
|
||||
uint32 last_portc; /* for edge detection */
|
||||
uint32 ctrl;
|
||||
} I8255;
|
||||
extern t_stat i8255_io(IOHANDLER* ioh,uint32* value,uint32 rw,uint32 mask);
|
||||
extern t_stat i8255_read(I8255* chip,int port,uint32* data);
|
||||
|
|
182
SAGE/i8251.c
182
SAGE/i8251.c
|
@ -34,112 +34,112 @@ static int i8251_bitmask[] = { 0x1f, 0x3f, 0x7f, 0xff };
|
|||
|
||||
/* Debug Flags */
|
||||
DEBTAB i8251_dt[] = {
|
||||
{ "READ", DBG_UART_RD },
|
||||
{ "WRITE", DBG_UART_WR },
|
||||
{ "IRQ", DBG_UART_IRQ },
|
||||
{ NULL, 0 }
|
||||
{ "READ", DBG_UART_RD },
|
||||
{ "WRITE", DBG_UART_WR },
|
||||
{ "IRQ", DBG_UART_IRQ },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
t_stat i8251_io(IOHANDLER* ioh,uint32* value,uint32 rw,uint32 mask)
|
||||
{
|
||||
int port = ioh->offset;
|
||||
I8251* chip = (I8251*)ioh->ctxt;
|
||||
if (rw==MEM_WRITE) {
|
||||
return chip->write ? chip->write(chip,port,*value) : i8251_write(chip,port,*value);
|
||||
} else {
|
||||
return chip->read ? chip->read(chip,port,value) : i8251_read(chip,port,value);
|
||||
}
|
||||
int port = ioh->offset;
|
||||
I8251* chip = (I8251*)ioh->ctxt;
|
||||
if (rw==MEM_WRITE) {
|
||||
return chip->write ? chip->write(chip,port,*value) : i8251_write(chip,port,*value);
|
||||
} else {
|
||||
return chip->read ? chip->read(chip,port,value) : i8251_read(chip,port,value);
|
||||
}
|
||||
}
|
||||
|
||||
t_stat i8251_write(I8251* chip,int port,uint32 value)
|
||||
{
|
||||
int bits;
|
||||
int bits;
|
||||
|
||||
if (port==0) { /* data port */
|
||||
chip->obuf = value & chip->bitmask;
|
||||
TRACE_PRINT1(DBG_UART_WR,"WR DATA = 0x%02x",chip->obuf);
|
||||
if (chip->init==3) { /* is fully initialized */
|
||||
if ((chip->mode & I8251_MODE_BAUD)==I8251_MODE_SYNC) {
|
||||
sim_printf("i8251: sync mode not implemented\n");
|
||||
return STOP_IMPL;
|
||||
}
|
||||
if (chip->cmd & I8251_CMD_TXEN) {
|
||||
/* transmit data */
|
||||
chip->status &= ~(I8251_ST_TXEMPTY|I8251_ST_TXRDY);
|
||||
sim_activate(chip->out,chip->out->wait);
|
||||
}
|
||||
}
|
||||
return SCPE_OK;
|
||||
} else { /* control port */
|
||||
switch (chip->init) {
|
||||
case 0: /* expect mode word */
|
||||
chip->mode = value;
|
||||
TRACE_PRINT1(DBG_UART_WR,"WR MODE = 0x%02x",value);
|
||||
chip->init = (value & I8251_MODE_BAUD)==I8251_MODE_SYNC ? 1 : 3;
|
||||
bits = (chip->mode & I8251_AMODE_BITS) >> 2;
|
||||
chip->bitmask = i8251_bitmask[bits];
|
||||
break;
|
||||
case 1: /* expect sync1 */
|
||||
chip->sync1 = value;
|
||||
TRACE_PRINT1(DBG_UART_WR,"WR SYNC1 = 0x%02x",value);
|
||||
chip->init = 2;
|
||||
break;
|
||||
case 2: /* expect sync2 */
|
||||
chip->sync2 = value;
|
||||
TRACE_PRINT1(DBG_UART_WR,"WR SYNC2 = 0x%02x",value);
|
||||
chip->init = 3;
|
||||
break;
|
||||
case 3: /* expect cmd word */
|
||||
chip->cmd = value;
|
||||
TRACE_PRINT1(DBG_UART_WR,"WR CMD = 0x%02x",value);
|
||||
if (value & I8251_CMD_EH) {
|
||||
sim_printf("i8251: hunt mode not implemented\n");
|
||||
return STOP_IMPL;
|
||||
}
|
||||
if (value & I8251_CMD_IR)
|
||||
chip->init = 0;
|
||||
if (value & I8251_CMD_ER)
|
||||
chip->status &= ~(I8251_ST_FE|I8251_ST_OE|I8251_ST_PE);
|
||||
if (value & I8251_CMD_SBRK)
|
||||
sim_printf("i8251: BREAK sent\n");
|
||||
if (value & I8251_CMD_RXE) {
|
||||
sim_activate(chip->in,chip->in->wait);
|
||||
} else {
|
||||
if (!chip->oob) sim_cancel(chip->in);
|
||||
}
|
||||
if (value & I8251_CMD_TXEN) {
|
||||
if (!(chip->status & I8251_ST_TXEMPTY))
|
||||
sim_activate(chip->out,chip->out->wait);
|
||||
else {
|
||||
chip->status |= I8251_ST_TXRDY;
|
||||
if (chip->txint) chip->txint(chip);
|
||||
}
|
||||
} else {
|
||||
chip->status &= ~I8251_ST_TXRDY;
|
||||
sim_cancel(chip->out);
|
||||
}
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
if (port==0) { /* data port */
|
||||
chip->obuf = value & chip->bitmask;
|
||||
TRACE_PRINT1(DBG_UART_WR,"WR DATA = 0x%02x",chip->obuf);
|
||||
if (chip->init==3) { /* is fully initialized */
|
||||
if ((chip->mode & I8251_MODE_BAUD)==I8251_MODE_SYNC) {
|
||||
sim_printf("i8251: sync mode not implemented\n");
|
||||
return STOP_IMPL;
|
||||
}
|
||||
if (chip->cmd & I8251_CMD_TXEN) {
|
||||
/* transmit data */
|
||||
chip->status &= ~(I8251_ST_TXEMPTY|I8251_ST_TXRDY);
|
||||
sim_activate(chip->out,chip->out->wait);
|
||||
}
|
||||
}
|
||||
return SCPE_OK;
|
||||
} else { /* control port */
|
||||
switch (chip->init) {
|
||||
case 0: /* expect mode word */
|
||||
chip->mode = value;
|
||||
TRACE_PRINT1(DBG_UART_WR,"WR MODE = 0x%02x",value);
|
||||
chip->init = (value & I8251_MODE_BAUD)==I8251_MODE_SYNC ? 1 : 3;
|
||||
bits = (chip->mode & I8251_AMODE_BITS) >> 2;
|
||||
chip->bitmask = i8251_bitmask[bits];
|
||||
break;
|
||||
case 1: /* expect sync1 */
|
||||
chip->sync1 = value;
|
||||
TRACE_PRINT1(DBG_UART_WR,"WR SYNC1 = 0x%02x",value);
|
||||
chip->init = 2;
|
||||
break;
|
||||
case 2: /* expect sync2 */
|
||||
chip->sync2 = value;
|
||||
TRACE_PRINT1(DBG_UART_WR,"WR SYNC2 = 0x%02x",value);
|
||||
chip->init = 3;
|
||||
break;
|
||||
case 3: /* expect cmd word */
|
||||
chip->cmd = value;
|
||||
TRACE_PRINT1(DBG_UART_WR,"WR CMD = 0x%02x",value);
|
||||
if (value & I8251_CMD_EH) {
|
||||
sim_printf("i8251: hunt mode not implemented\n");
|
||||
return STOP_IMPL;
|
||||
}
|
||||
if (value & I8251_CMD_IR)
|
||||
chip->init = 0;
|
||||
if (value & I8251_CMD_ER)
|
||||
chip->status &= ~(I8251_ST_FE|I8251_ST_OE|I8251_ST_PE);
|
||||
if (value & I8251_CMD_SBRK)
|
||||
sim_printf("i8251: BREAK sent\n");
|
||||
if (value & I8251_CMD_RXE) {
|
||||
sim_activate(chip->in,chip->in->wait);
|
||||
} else {
|
||||
if (!chip->oob) sim_cancel(chip->in);
|
||||
}
|
||||
if (value & I8251_CMD_TXEN) {
|
||||
if (!(chip->status & I8251_ST_TXEMPTY))
|
||||
sim_activate(chip->out,chip->out->wait);
|
||||
else {
|
||||
chip->status |= I8251_ST_TXRDY;
|
||||
if (chip->txint) chip->txint(chip);
|
||||
}
|
||||
} else {
|
||||
chip->status &= ~I8251_ST_TXRDY;
|
||||
sim_cancel(chip->out);
|
||||
}
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
}
|
||||
|
||||
t_stat i8251_read(I8251* chip,int port,uint32* value)
|
||||
{
|
||||
if (port==0) { /* data read */
|
||||
*value = chip->ibuf;
|
||||
chip->status &= ~I8251_ST_RXRDY; /* mark read buffer as empty */
|
||||
TRACE_PRINT1(DBG_UART_RD,"RD DATA = 0x%02x",*value);
|
||||
} else { /* status read */
|
||||
*value = chip->status & 0xff;
|
||||
TRACE_PRINT1(DBG_UART_RD,"RD STATUS = 0x%02x",*value);
|
||||
}
|
||||
return SCPE_OK;
|
||||
if (port==0) { /* data read */
|
||||
*value = chip->ibuf;
|
||||
chip->status &= ~I8251_ST_RXRDY; /* mark read buffer as empty */
|
||||
TRACE_PRINT1(DBG_UART_RD,"RD DATA = 0x%02x",*value);
|
||||
} else { /* status read */
|
||||
*value = chip->status & 0xff;
|
||||
TRACE_PRINT1(DBG_UART_RD,"RD STATUS = 0x%02x",*value);
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat i8251_reset(I8251* chip)
|
||||
{
|
||||
chip->init = 0;
|
||||
chip->oob = FALSE;
|
||||
chip->crlf = 0;
|
||||
return SCPE_OK;
|
||||
chip->init = 0;
|
||||
chip->oob = FALSE;
|
||||
chip->crlf = 0;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
|
170
SAGE/i8253.c
170
SAGE/i8253.c
|
@ -41,103 +41,103 @@ static char* rltype[] = { "latch","8bitL","8bitH", "16bit" };
|
|||
|
||||
t_stat i8253_write(I8253* chip, int addr, uint32 value)
|
||||
{
|
||||
I8253CNTR* cntr;
|
||||
t_stat rc;
|
||||
int num;
|
||||
|
||||
if (addr==3) { /* mode reg */
|
||||
TRACE_PRINT(DBG_TMR_WR,(sim_deb,"WR MODE=%x (SC=%d RL=%s MODE=%d BCD=%d)",
|
||||
value,(value>>6)&3,rltype[(value>>4)&3],(value>>1)&7,value&1));
|
||||
if (chip->ckmode && (rc=chip->ckmode(chip,value))!= SCPE_OK) return rc;
|
||||
num = (value & I8253_SCMASK)>>6;
|
||||
cntr = &chip->cntr[num];
|
||||
if ((value & I8253_RLMASK)==I8253_LATCH) {
|
||||
/* calculate current value of count */
|
||||
cntr->latch = cntr->count; /* latch it */
|
||||
cntr->state |= I8253_ST_LATCH;
|
||||
} else {
|
||||
cntr->mode = value;
|
||||
cntr->state = (value & I8253_RLMASK)==I8253_MSB ? I8253_ST_MSBNEXT : I8253_ST_LSBNEXT;
|
||||
}
|
||||
} else { /* write dividers */
|
||||
cntr = &chip->cntr[addr];
|
||||
switch (cntr->mode & I8253_RLMASK) {
|
||||
case I8253_MSB:
|
||||
TRACE_PRINT2(DBG_TMR_WR,"WR CNT=%d DIVMSB=%x",addr,value);
|
||||
cntr->divider = (cntr->divider & 0x00ff) | ((value<<8) | 0xff);
|
||||
cntr->state &= ~I8253_ST_LATCH;
|
||||
cntr->count = cntr->divider;
|
||||
break;
|
||||
case I8253_LSB:
|
||||
TRACE_PRINT2(DBG_TMR_WR,"WR CNT=%d DIVLSB=%x",addr,value);
|
||||
cntr->divider = (cntr->divider & 0xff00) | (value | 0xff);
|
||||
cntr->state &= ~I8253_ST_LATCH;
|
||||
cntr->count = cntr->divider;
|
||||
break;
|
||||
case I8253_BOTH:
|
||||
if (cntr->state & I8253_ST_MSBNEXT) {
|
||||
TRACE_PRINT2(DBG_TMR_WR,"WR CNT=%d DIV16MSB=%x",addr,value);
|
||||
cntr->divider = (cntr->divider & 0x00ff) | ((value & 0xff)<<8);
|
||||
cntr->state = I8253_ST_LSBNEXT; /* reset latch mode and MSB bit */
|
||||
cntr->count = cntr->divider;
|
||||
} else {
|
||||
TRACE_PRINT2(DBG_TMR_WR,"WR CNT=%d DIV16LSB=%x",addr,value);
|
||||
cntr->divider = (cntr->divider & 0xff00) | (value & 0xff);
|
||||
cntr->state = I8253_ST_MSBNEXT; /* reset latch mode and LSB bit */
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
/* execute a registered callback before returning result */
|
||||
if (cntr->call && (rc=(*cntr->call)(chip,1,&value)) != SCPE_OK) return rc;
|
||||
}
|
||||
return SCPE_OK;
|
||||
I8253CNTR* cntr;
|
||||
t_stat rc;
|
||||
int num;
|
||||
|
||||
if (addr==3) { /* mode reg */
|
||||
TRACE_PRINT(DBG_TMR_WR,(sim_deb,"WR MODE=%x (SC=%d RL=%s MODE=%d BCD=%d)",
|
||||
value,(value>>6)&3,rltype[(value>>4)&3],(value>>1)&7,value&1));
|
||||
if (chip->ckmode && (rc=chip->ckmode(chip,value))!= SCPE_OK) return rc;
|
||||
num = (value & I8253_SCMASK)>>6;
|
||||
cntr = &chip->cntr[num];
|
||||
if ((value & I8253_RLMASK)==I8253_LATCH) {
|
||||
/* calculate current value of count */
|
||||
cntr->latch = cntr->count; /* latch it */
|
||||
cntr->state |= I8253_ST_LATCH;
|
||||
} else {
|
||||
cntr->mode = value;
|
||||
cntr->state = (value & I8253_RLMASK)==I8253_MSB ? I8253_ST_MSBNEXT : I8253_ST_LSBNEXT;
|
||||
}
|
||||
} else { /* write dividers */
|
||||
cntr = &chip->cntr[addr];
|
||||
switch (cntr->mode & I8253_RLMASK) {
|
||||
case I8253_MSB:
|
||||
TRACE_PRINT2(DBG_TMR_WR,"WR CNT=%d DIVMSB=%x",addr,value);
|
||||
cntr->divider = (cntr->divider & 0x00ff) | ((value<<8) | 0xff);
|
||||
cntr->state &= ~I8253_ST_LATCH;
|
||||
cntr->count = cntr->divider;
|
||||
break;
|
||||
case I8253_LSB:
|
||||
TRACE_PRINT2(DBG_TMR_WR,"WR CNT=%d DIVLSB=%x",addr,value);
|
||||
cntr->divider = (cntr->divider & 0xff00) | (value | 0xff);
|
||||
cntr->state &= ~I8253_ST_LATCH;
|
||||
cntr->count = cntr->divider;
|
||||
break;
|
||||
case I8253_BOTH:
|
||||
if (cntr->state & I8253_ST_MSBNEXT) {
|
||||
TRACE_PRINT2(DBG_TMR_WR,"WR CNT=%d DIV16MSB=%x",addr,value);
|
||||
cntr->divider = (cntr->divider & 0x00ff) | ((value & 0xff)<<8);
|
||||
cntr->state = I8253_ST_LSBNEXT; /* reset latch mode and MSB bit */
|
||||
cntr->count = cntr->divider;
|
||||
} else {
|
||||
TRACE_PRINT2(DBG_TMR_WR,"WR CNT=%d DIV16LSB=%x",addr,value);
|
||||
cntr->divider = (cntr->divider & 0xff00) | (value & 0xff);
|
||||
cntr->state = I8253_ST_MSBNEXT; /* reset latch mode and LSB bit */
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
/* execute a registered callback before returning result */
|
||||
if (cntr->call && (rc=(*cntr->call)(chip,1,&value)) != SCPE_OK) return rc;
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat i8253_read(I8253* chip,int addr,uint32* value)
|
||||
{
|
||||
t_stat rc;
|
||||
I8253CNTR* cntr = &chip->cntr[addr];
|
||||
int32 src = cntr->state & I8253_ST_LATCH ? cntr->latch : cntr->count;
|
||||
if (cntr->call && (rc=(*cntr->call)(chip,0,(uint32*)&src)) != SCPE_OK) return rc;
|
||||
t_stat rc;
|
||||
I8253CNTR* cntr = &chip->cntr[addr];
|
||||
int32 src = cntr->state & I8253_ST_LATCH ? cntr->latch : cntr->count;
|
||||
if (cntr->call && (rc=(*cntr->call)(chip,0,(uint32*)&src)) != SCPE_OK) return rc;
|
||||
|
||||
switch (cntr->mode & I8253_RLMASK) {
|
||||
case I8253_MSB:
|
||||
src >>= 8;
|
||||
TRACE_PRINT2(DBG_TMR_RD,"RD CNT=%d CNTMSB=%x",addr,src&0xff);
|
||||
cntr->state &= ~I8253_ST_LATCH;
|
||||
break;
|
||||
case I8253_LSB:
|
||||
cntr->state &= ~I8253_ST_LATCH;
|
||||
TRACE_PRINT2(DBG_TMR_RD,"RD CNT=%d CNTLSB=%x",addr,src&0xff);
|
||||
break;
|
||||
case I8253_BOTH:
|
||||
if (cntr->state & I8253_ST_MSBNEXT) {
|
||||
src >>= 8; cntr->state = I8253_ST_LSBNEXT; /* reset latch mode and MSB bit */
|
||||
TRACE_PRINT2(DBG_TMR_RD,"RD CNT=%d CNT16MSB=%x",addr,src&0xff);
|
||||
} else {
|
||||
TRACE_PRINT2(DBG_TMR_RD,"RD CNT=%d CNT16LSB=%x",addr,src&0xff);
|
||||
cntr->state |= I8253_ST_MSBNEXT; /* does not reset latch mode if set */
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return SCPE_OK;
|
||||
}
|
||||
*value = src & 0xff;
|
||||
return SCPE_OK;
|
||||
switch (cntr->mode & I8253_RLMASK) {
|
||||
case I8253_MSB:
|
||||
src >>= 8;
|
||||
TRACE_PRINT2(DBG_TMR_RD,"RD CNT=%d CNTMSB=%x",addr,src&0xff);
|
||||
cntr->state &= ~I8253_ST_LATCH;
|
||||
break;
|
||||
case I8253_LSB:
|
||||
cntr->state &= ~I8253_ST_LATCH;
|
||||
TRACE_PRINT2(DBG_TMR_RD,"RD CNT=%d CNTLSB=%x",addr,src&0xff);
|
||||
break;
|
||||
case I8253_BOTH:
|
||||
if (cntr->state & I8253_ST_MSBNEXT) {
|
||||
src >>= 8; cntr->state = I8253_ST_LSBNEXT; /* reset latch mode and MSB bit */
|
||||
TRACE_PRINT2(DBG_TMR_RD,"RD CNT=%d CNT16MSB=%x",addr,src&0xff);
|
||||
} else {
|
||||
TRACE_PRINT2(DBG_TMR_RD,"RD CNT=%d CNT16LSB=%x",addr,src&0xff);
|
||||
cntr->state |= I8253_ST_MSBNEXT; /* does not reset latch mode if set */
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return SCPE_OK;
|
||||
}
|
||||
*value = src & 0xff;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat i8253_reset(I8253* chip)
|
||||
{
|
||||
int i;
|
||||
for (i=0; i<3; i++) chip->cntr[i].state = 0;
|
||||
return SCPE_OK;
|
||||
int i;
|
||||
for (i=0; i<3; i++) chip->cntr[i].state = 0;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat i8253_io(IOHANDLER* ioh,uint32* value,uint32 rw,uint32 mask)
|
||||
{
|
||||
int port = ioh->offset;
|
||||
I8253* chip = (I8253*)ioh->ctxt;
|
||||
return rw==MEM_WRITE ? i8253_write(chip,port,*value) : i8253_read(chip,port,value);
|
||||
int port = ioh->offset;
|
||||
I8253* chip = (I8253*)ioh->ctxt;
|
||||
return rw==MEM_WRITE ? i8253_write(chip,port,*value) : i8253_read(chip,port,value);
|
||||
}
|
||||
|
||||
|
|
118
SAGE/i8255.c
118
SAGE/i8255.c
|
@ -32,75 +32,75 @@
|
|||
|
||||
static t_stat i8255_error(const char* err)
|
||||
{
|
||||
sim_printf("I8255: Missing method '%s'\n",err);
|
||||
return STOP_IMPL;
|
||||
sim_printf("I8255: Missing method '%s'\n",err);
|
||||
return STOP_IMPL;
|
||||
}
|
||||
|
||||
t_stat i8255_io(IOHANDLER* ioh,uint32* value,uint32 rw,uint32 mask)
|
||||
{
|
||||
int port = ioh->offset;
|
||||
I8255* chip = (I8255*)ioh->ctxt;
|
||||
if (rw==MEM_WRITE) {
|
||||
return chip->write ? chip->write(chip,port,*value) : i8255_error("write");
|
||||
} else {
|
||||
return chip->read ? chip->read(chip,port,value) : i8255_error("read");
|
||||
}
|
||||
int port = ioh->offset;
|
||||
I8255* chip = (I8255*)ioh->ctxt;
|
||||
if (rw==MEM_WRITE) {
|
||||
return chip->write ? chip->write(chip,port,*value) : i8255_error("write");
|
||||
} else {
|
||||
return chip->read ? chip->read(chip,port,value) : i8255_error("read");
|
||||
}
|
||||
}
|
||||
|
||||
t_stat i8255_read(I8255* chip,int port,uint32* data)
|
||||
{
|
||||
t_stat rc;
|
||||
switch (port) {
|
||||
case 0:
|
||||
if (chip->calla && (rc=(*chip->calla)(chip,0)) != SCPE_OK) return rc;
|
||||
*data = chip->porta;
|
||||
return SCPE_OK;
|
||||
case 1:
|
||||
if (chip->callb && (rc=(*chip->callb)(chip,0)) != SCPE_OK) return rc;
|
||||
*data = chip->portb;
|
||||
return SCPE_OK;
|
||||
case 2:
|
||||
if (chip->callc && (rc=(*chip->callc)(chip,0)) != SCPE_OK) return rc;
|
||||
*data = chip->portc;
|
||||
return SCPE_OK;
|
||||
case 3:
|
||||
*data = 0xff; /* undefined */
|
||||
return SCPE_OK;
|
||||
default:
|
||||
return SCPE_IERR;
|
||||
}
|
||||
t_stat rc;
|
||||
switch (port) {
|
||||
case 0:
|
||||
if (chip->calla && (rc=(*chip->calla)(chip,0)) != SCPE_OK) return rc;
|
||||
*data = chip->porta;
|
||||
return SCPE_OK;
|
||||
case 1:
|
||||
if (chip->callb && (rc=(*chip->callb)(chip,0)) != SCPE_OK) return rc;
|
||||
*data = chip->portb;
|
||||
return SCPE_OK;
|
||||
case 2:
|
||||
if (chip->callc && (rc=(*chip->callc)(chip,0)) != SCPE_OK) return rc;
|
||||
*data = chip->portc;
|
||||
return SCPE_OK;
|
||||
case 3:
|
||||
*data = 0xff; /* undefined */
|
||||
return SCPE_OK;
|
||||
default:
|
||||
return SCPE_IERR;
|
||||
}
|
||||
}
|
||||
|
||||
t_stat i8255_write(I8255* chip,int port,uint32 data)
|
||||
{
|
||||
t_stat rc;
|
||||
uint32 bit;
|
||||
switch(port) {
|
||||
case 0: /*port a*/
|
||||
chip->last_porta = chip->porta;
|
||||
chip->porta = data;
|
||||
return chip->calla ? (*chip->calla)(chip,1) : SCPE_OK;
|
||||
case 1: /*port b*/
|
||||
chip->last_portb = chip->portb;
|
||||
return chip->callb ? (*chip->callb)(chip,1) : SCPE_OK;
|
||||
case 2:
|
||||
chip->last_portc = chip->portc;
|
||||
chip->portc = data & 0xff;
|
||||
return chip->callc ? (*chip->callc)(chip,1) : SCPE_OK;
|
||||
case 3:
|
||||
if (data & 0x80) { /* mode set mode */
|
||||
if (chip->ckmode && (rc=chip->ckmode(chip,data))) return rc;
|
||||
chip->ctrl = data & 0x7f;
|
||||
return SCPE_OK;
|
||||
} else { /* bit set mode */
|
||||
chip->last_portc = chip->portc;
|
||||
bit = 1 << ((data & 0x0e)>>1);
|
||||
TRACE_PRINT2(DBG_PP_WRC,"WR PORTC %s bit=%x",data&1 ? "SET": "CLR",bit);
|
||||
if (data & 1) chip->portc |= bit; else chip->portc &= ~bit;
|
||||
chip->portc &= 0xff;
|
||||
return chip->callc ? (*chip->callc)(chip,1) : SCPE_OK;
|
||||
}
|
||||
default:
|
||||
return SCPE_IERR;
|
||||
}
|
||||
t_stat rc;
|
||||
uint32 bit;
|
||||
switch(port) {
|
||||
case 0: /*port a*/
|
||||
chip->last_porta = chip->porta;
|
||||
chip->porta = data;
|
||||
return chip->calla ? (*chip->calla)(chip,1) : SCPE_OK;
|
||||
case 1: /*port b*/
|
||||
chip->last_portb = chip->portb;
|
||||
return chip->callb ? (*chip->callb)(chip,1) : SCPE_OK;
|
||||
case 2:
|
||||
chip->last_portc = chip->portc;
|
||||
chip->portc = data & 0xff;
|
||||
return chip->callc ? (*chip->callc)(chip,1) : SCPE_OK;
|
||||
case 3:
|
||||
if (data & 0x80) { /* mode set mode */
|
||||
if (chip->ckmode && (rc=chip->ckmode(chip,data))) return rc;
|
||||
chip->ctrl = data & 0x7f;
|
||||
return SCPE_OK;
|
||||
} else { /* bit set mode */
|
||||
chip->last_portc = chip->portc;
|
||||
bit = 1 << ((data & 0x0e)>>1);
|
||||
TRACE_PRINT2(DBG_PP_WRC,"WR PORTC %s bit=%x",data&1 ? "SET": "CLR",bit);
|
||||
if (data & 1) chip->portc |= bit; else chip->portc &= ~bit;
|
||||
chip->portc &= 0xff;
|
||||
return chip->callc ? (*chip->callc)(chip,1) : SCPE_OK;
|
||||
}
|
||||
default:
|
||||
return SCPE_IERR;
|
||||
}
|
||||
}
|
||||
|
|
348
SAGE/i8259.c
348
SAGE/i8259.c
|
@ -44,201 +44,201 @@ static int32 priomask[] = { 0x0000,0x4000,0x6000,0x7000,0x7800,0x7c00,0x7e00,0x7
|
|||
|
||||
t_stat i8259_io(IOHANDLER* ioh,uint32* value,uint32 rw,uint32 mask)
|
||||
{
|
||||
int port = ioh->offset;
|
||||
I8259* chip = (I8259*)ioh->ctxt;
|
||||
if (rw==MEM_WRITE) {
|
||||
return chip->write ? chip->write(chip,port,*value) : i8259_write(chip,port,*value);
|
||||
} else {
|
||||
return chip->read ? chip->read(chip,port,value) : i8259_read(chip,port,value);
|
||||
}
|
||||
int port = ioh->offset;
|
||||
I8259* chip = (I8259*)ioh->ctxt;
|
||||
if (rw==MEM_WRITE) {
|
||||
return chip->write ? chip->write(chip,port,*value) : i8259_write(chip,port,*value);
|
||||
} else {
|
||||
return chip->read ? chip->read(chip,port,value) : i8259_read(chip,port,value);
|
||||
}
|
||||
}
|
||||
|
||||
t_stat i8259_write(I8259* chip,int addr,uint32 value)
|
||||
{
|
||||
int i, bit;
|
||||
int i, bit;
|
||||
|
||||
#if 0
|
||||
TRACE_PRINT2(DBG_PIC_WR,"WR addr=%d data=0x%x",addr,value);
|
||||
TRACE_PRINT2(DBG_PIC_WR,"WR addr=%d data=0x%x",addr,value);
|
||||
#endif
|
||||
if (addr==1) {
|
||||
switch (chip->state) {
|
||||
default:
|
||||
case 0: /* after reset */
|
||||
sim_printf("PIC: write addr=1 without initialization\n");
|
||||
return SCPE_IOERR;
|
||||
case 1: /* expect ICW2 */
|
||||
TRACE_PRINT2(DBG_PIC_WR,"WR ICW2: addr=%d data=0x%x",addr,value);
|
||||
chip->icw2 = value;
|
||||
if (chip->icw1 & I8259_ICW1_SNGL) {
|
||||
chip->state = (chip->icw1 & I8259_ICW1_IC4) ? 4 : 5;
|
||||
} else {
|
||||
/* attempt to program cascade mode */
|
||||
sim_printf("PIC: attempt to program chip for cascade mode - not wired for this!\n");
|
||||
chip->state = 0;
|
||||
return SCPE_IOERR;
|
||||
}
|
||||
break;
|
||||
case 4: /* expect ICW4 */
|
||||
TRACE_PRINT2(DBG_PIC_WR,"WR ICW4 addr=%d data=0x%x",addr,value);
|
||||
chip->icw4 = value;
|
||||
if (chip->icw4 & I8259_ICW4_AEOI) {
|
||||
sim_printf("PIC: attempt to program chip for AEOI mode - not wired for this!\n");
|
||||
return SCPE_IOERR;
|
||||
}
|
||||
if (chip->icw4 & I8259_ICW4_BUF) {
|
||||
sim_printf("PIC: attempt to program chip for buffered mode - not wired for this!\n");
|
||||
return SCPE_IOERR;
|
||||
}
|
||||
if (chip->icw4 & I8259_ICW4_SFNM) {
|
||||
sim_printf("PIC: attempt to program chip for spc nested mode - not wired for this!\n");
|
||||
return SCPE_IOERR;
|
||||
}
|
||||
chip->state = 5;
|
||||
break;
|
||||
case 5: /* ready to accept interrupt requests and ocw commands */
|
||||
/* ocw1 */
|
||||
TRACE_PRINT2(DBG_PIC_WR,"WR IMR addr=%d data=0x%x",addr,value);
|
||||
chip->imr = value;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (value & I8259_ICW1) { /* state initialization sequence */
|
||||
TRACE_PRINT2(DBG_PIC_WR,"WR ICW1 addr=%d data=0x%x",addr,value);
|
||||
chip->icw1 = value;
|
||||
chip->state = 1;
|
||||
chip->rmode = 0;
|
||||
chip->prio = 7;
|
||||
if ((chip->icw1 & I8259_ICW1_IC4)==0) chip->icw4 = 0;
|
||||
|
||||
return SCPE_OK;
|
||||
} else { /* ocw2 and ocw3 */
|
||||
if (value & I8259_OCW3) { /* ocw3 */
|
||||
TRACE_PRINT2(DBG_PIC_WR,"WR OCW3 addr=%d data=0x%x",addr,value);
|
||||
if (value & I8259_OCW3_ESMM) {
|
||||
sim_printf("PIC: ESMM not yet supported\n");
|
||||
return STOP_IMPL;
|
||||
}
|
||||
if (value & I8259_OCW3_POLL) {
|
||||
chip->rmode |= 2;
|
||||
return SCPE_OK;
|
||||
}
|
||||
if (value & I8259_OCW3_RR)
|
||||
chip->rmode = (value & I8259_OCW3_RIS) ? 1 /*isr*/ : 0; /* irr */
|
||||
} else { /* ocw2 */
|
||||
TRACE_PRINT2(DBG_PIC_WR,"WR OCW2 addr=%d data=0x%x",addr,value);
|
||||
switch (value & I8259_OCW2_MODE) {
|
||||
case 0xa0: /* rotate on nospecific eoi */
|
||||
case 0x20: /* nonspecific eoi */
|
||||
bit = 1 << (7 - chip->prio);
|
||||
for (i=0; i<7; i++) {
|
||||
if (chip->isr & bit) break;
|
||||
bit = bit << 1; if (bit==0x100) bit = 1;
|
||||
}
|
||||
chip->isr &= ~bit; break;
|
||||
if ((value & I8259_OCW2_MODE) == 0xa0) {
|
||||
chip->prio = 7 - i + chip->prio; if (chip->prio>7) chip->prio -= 8;
|
||||
}
|
||||
break;
|
||||
case 0xe0: /* rotate on specific eoi */
|
||||
chip->prio = 7 - (value & 7) + chip->prio; if (chip->prio>7) chip->prio -= 8;
|
||||
/*fallthru*/
|
||||
case 0x60: /* specific eoi */
|
||||
bit = 1 << (value & 7);
|
||||
chip->isr = chip->isr & ~bit & 0xff;
|
||||
break;
|
||||
case 0x80: /* rotate in autoeoi (set) */
|
||||
case 0x00: /* rotate in autoeoi (clear) */
|
||||
sim_printf("PIC: AEOI not supported\n");
|
||||
return SCPE_IOERR;
|
||||
case 0xc0: /* set prio */
|
||||
chip->prio = value & 7;
|
||||
return SCPE_OK;
|
||||
case 0x40: /* nop */
|
||||
break;
|
||||
default:
|
||||
return SCPE_IERR;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return SCPE_OK;
|
||||
if (addr==1) {
|
||||
switch (chip->state) {
|
||||
default:
|
||||
case 0: /* after reset */
|
||||
sim_printf("PIC: write addr=1 without initialization\n");
|
||||
return SCPE_IOERR;
|
||||
case 1: /* expect ICW2 */
|
||||
TRACE_PRINT2(DBG_PIC_WR,"WR ICW2: addr=%d data=0x%x",addr,value);
|
||||
chip->icw2 = value;
|
||||
if (chip->icw1 & I8259_ICW1_SNGL) {
|
||||
chip->state = (chip->icw1 & I8259_ICW1_IC4) ? 4 : 5;
|
||||
} else {
|
||||
/* attempt to program cascade mode */
|
||||
sim_printf("PIC: attempt to program chip for cascade mode - not wired for this!\n");
|
||||
chip->state = 0;
|
||||
return SCPE_IOERR;
|
||||
}
|
||||
break;
|
||||
case 4: /* expect ICW4 */
|
||||
TRACE_PRINT2(DBG_PIC_WR,"WR ICW4 addr=%d data=0x%x",addr,value);
|
||||
chip->icw4 = value;
|
||||
if (chip->icw4 & I8259_ICW4_AEOI) {
|
||||
sim_printf("PIC: attempt to program chip for AEOI mode - not wired for this!\n");
|
||||
return SCPE_IOERR;
|
||||
}
|
||||
if (chip->icw4 & I8259_ICW4_BUF) {
|
||||
sim_printf("PIC: attempt to program chip for buffered mode - not wired for this!\n");
|
||||
return SCPE_IOERR;
|
||||
}
|
||||
if (chip->icw4 & I8259_ICW4_SFNM) {
|
||||
sim_printf("PIC: attempt to program chip for spc nested mode - not wired for this!\n");
|
||||
return SCPE_IOERR;
|
||||
}
|
||||
chip->state = 5;
|
||||
break;
|
||||
case 5: /* ready to accept interrupt requests and ocw commands */
|
||||
/* ocw1 */
|
||||
TRACE_PRINT2(DBG_PIC_WR,"WR IMR addr=%d data=0x%x",addr,value);
|
||||
chip->imr = value;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (value & I8259_ICW1) { /* state initialization sequence */
|
||||
TRACE_PRINT2(DBG_PIC_WR,"WR ICW1 addr=%d data=0x%x",addr,value);
|
||||
chip->icw1 = value;
|
||||
chip->state = 1;
|
||||
chip->rmode = 0;
|
||||
chip->prio = 7;
|
||||
if ((chip->icw1 & I8259_ICW1_IC4)==0) chip->icw4 = 0;
|
||||
|
||||
return SCPE_OK;
|
||||
} else { /* ocw2 and ocw3 */
|
||||
if (value & I8259_OCW3) { /* ocw3 */
|
||||
TRACE_PRINT2(DBG_PIC_WR,"WR OCW3 addr=%d data=0x%x",addr,value);
|
||||
if (value & I8259_OCW3_ESMM) {
|
||||
sim_printf("PIC: ESMM not yet supported\n");
|
||||
return STOP_IMPL;
|
||||
}
|
||||
if (value & I8259_OCW3_POLL) {
|
||||
chip->rmode |= 2;
|
||||
return SCPE_OK;
|
||||
}
|
||||
if (value & I8259_OCW3_RR)
|
||||
chip->rmode = (value & I8259_OCW3_RIS) ? 1 /*isr*/ : 0; /* irr */
|
||||
} else { /* ocw2 */
|
||||
TRACE_PRINT2(DBG_PIC_WR,"WR OCW2 addr=%d data=0x%x",addr,value);
|
||||
switch (value & I8259_OCW2_MODE) {
|
||||
case 0xa0: /* rotate on nospecific eoi */
|
||||
case 0x20: /* nonspecific eoi */
|
||||
bit = 1 << (7 - chip->prio);
|
||||
for (i=0; i<7; i++) {
|
||||
if (chip->isr & bit) break;
|
||||
bit = bit << 1; if (bit==0x100) bit = 1;
|
||||
}
|
||||
chip->isr &= ~bit; break;
|
||||
if ((value & I8259_OCW2_MODE) == 0xa0) {
|
||||
chip->prio = 7 - i + chip->prio; if (chip->prio>7) chip->prio -= 8;
|
||||
}
|
||||
break;
|
||||
case 0xe0: /* rotate on specific eoi */
|
||||
chip->prio = 7 - (value & 7) + chip->prio; if (chip->prio>7) chip->prio -= 8;
|
||||
/*fallthru*/
|
||||
case 0x60: /* specific eoi */
|
||||
bit = 1 << (value & 7);
|
||||
chip->isr = chip->isr & ~bit & 0xff;
|
||||
break;
|
||||
case 0x80: /* rotate in autoeoi (set) */
|
||||
case 0x00: /* rotate in autoeoi (clear) */
|
||||
sim_printf("PIC: AEOI not supported\n");
|
||||
return SCPE_IOERR;
|
||||
case 0xc0: /* set prio */
|
||||
chip->prio = value & 7;
|
||||
return SCPE_OK;
|
||||
case 0x40: /* nop */
|
||||
break;
|
||||
default:
|
||||
return SCPE_IERR;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat i8259_read(I8259* chip,int addr, uint32* value)
|
||||
{
|
||||
int i, bit, num;
|
||||
int i, bit, num;
|
||||
|
||||
if (addr) {
|
||||
*value = chip->imr;
|
||||
} else {
|
||||
switch (chip->rmode) {
|
||||
case 0:
|
||||
TRACE_PRINT2(DBG_PIC_RD,"Read IRR addr=%d data=0x%x",addr,chip->irr);
|
||||
*value = chip->irr; break;
|
||||
case 1:
|
||||
TRACE_PRINT2(DBG_PIC_RD,"Read ISR addr=%d data=0x%x",addr,chip->irr);
|
||||
*value = chip->isr; break;
|
||||
case 2:
|
||||
case 3:
|
||||
TRACE_PRINT2(DBG_PIC_RD,"Read POLL addr=%d data=0x%x",addr,chip->irr);
|
||||
num = chip->prio;
|
||||
bit = 1 << chip->prio;
|
||||
for (i=0; i<8; i++,num--) {
|
||||
if (chip->isr & bit) {
|
||||
*value = 0x80 | (num & 7);
|
||||
TRACE_PRINT2(DBG_PIC_RD,"Read POLL addr=%d data=0x%x",addr,*value);
|
||||
return SCPE_OK;
|
||||
}
|
||||
bit >>= 1;
|
||||
if (bit==0) { bit = 0x80; num = 7; }
|
||||
}
|
||||
chip->rmode &= ~2;
|
||||
}
|
||||
}
|
||||
if (addr) {
|
||||
*value = chip->imr;
|
||||
} else {
|
||||
switch (chip->rmode) {
|
||||
case 0:
|
||||
TRACE_PRINT2(DBG_PIC_RD,"Read IRR addr=%d data=0x%x",addr,chip->irr);
|
||||
*value = chip->irr; break;
|
||||
case 1:
|
||||
TRACE_PRINT2(DBG_PIC_RD,"Read ISR addr=%d data=0x%x",addr,chip->irr);
|
||||
*value = chip->isr; break;
|
||||
case 2:
|
||||
case 3:
|
||||
TRACE_PRINT2(DBG_PIC_RD,"Read POLL addr=%d data=0x%x",addr,chip->irr);
|
||||
num = chip->prio;
|
||||
bit = 1 << chip->prio;
|
||||
for (i=0; i<8; i++,num--) {
|
||||
if (chip->isr & bit) {
|
||||
*value = 0x80 | (num & 7);
|
||||
TRACE_PRINT2(DBG_PIC_RD,"Read POLL addr=%d data=0x%x",addr,*value);
|
||||
return SCPE_OK;
|
||||
}
|
||||
bit >>= 1;
|
||||
if (bit==0) { bit = 0x80; num = 7; }
|
||||
}
|
||||
chip->rmode &= ~2;
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
TRACE_PRINT2(DBG_PIC_RD,"Read addr=%d data=0x%x",addr,*value);
|
||||
TRACE_PRINT2(DBG_PIC_RD,"Read addr=%d data=0x%x",addr,*value);
|
||||
#endif
|
||||
return SCPE_OK;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat i8259_raiseint(I8259* chip,int level)
|
||||
{
|
||||
int32 bit, isr, myprio;
|
||||
int32 bit, isr, myprio;
|
||||
|
||||
TRACE_PRINT1(DBG_PIC_II,"Request INT level=%d",level);
|
||||
|
||||
if (chip->state != 5) return SCPE_OK; /* not yet initialized, ignore interrupts */
|
||||
bit = 1<<level;
|
||||
if (chip->imr & bit) return SCPE_OK; /* inhibited */
|
||||
chip->isr = (chip->isr | bit) & 0xff; /* request this interrupt level */
|
||||
|
||||
/* bit7=prio7 => bitN = prioN
|
||||
bit7=prio6 => bitN = prioN-1
|
||||
...
|
||||
bit7=prio0 => bitN = prioN-7
|
||||
*/
|
||||
isr = (chip->isr<<8) | chip->isr; /* simple rotation */
|
||||
isr = isr << (7-level); /* shift level bit into bit 15 */
|
||||
myprio = chip->prio - 7 + level; if (myprio < 0) myprio += 8;
|
||||
if (!(isr & priomask[myprio])) { /* higher interrupt is pending */
|
||||
if (chip->autoint) {
|
||||
TRACE_PRINT1(DBG_PIC_IO,"Raise AUTOINT level=%d",chip->intlevel);
|
||||
return m68k_raise_autoint(chip->intlevel);
|
||||
} else {
|
||||
TRACE_PRINT2(DBG_PIC_IO,"Raise VECTORINT level=%d vector=%x",chip->intlevel,chip->intvector);
|
||||
return m68k_raise_vectorint(chip->intlevel,chip->intvector);
|
||||
}
|
||||
}
|
||||
return SCPE_OK;
|
||||
TRACE_PRINT1(DBG_PIC_II,"Request INT level=%d",level);
|
||||
|
||||
if (chip->state != 5) return SCPE_OK; /* not yet initialized, ignore interrupts */
|
||||
bit = 1<<level;
|
||||
if (chip->imr & bit) return SCPE_OK; /* inhibited */
|
||||
chip->isr = (chip->isr | bit) & 0xff; /* request this interrupt level */
|
||||
|
||||
/* bit7=prio7 => bitN = prioN
|
||||
bit7=prio6 => bitN = prioN-1
|
||||
...
|
||||
bit7=prio0 => bitN = prioN-7
|
||||
*/
|
||||
isr = (chip->isr<<8) | chip->isr; /* simple rotation */
|
||||
isr = isr << (7-level); /* shift level bit into bit 15 */
|
||||
myprio = chip->prio - 7 + level; if (myprio < 0) myprio += 8;
|
||||
if (!(isr & priomask[myprio])) { /* higher interrupt is pending */
|
||||
if (chip->autoint) {
|
||||
TRACE_PRINT1(DBG_PIC_IO,"Raise AUTOINT level=%d",chip->intlevel);
|
||||
return m68k_raise_autoint(chip->intlevel);
|
||||
} else {
|
||||
TRACE_PRINT2(DBG_PIC_IO,"Raise VECTORINT level=%d vector=%x",chip->intlevel,chip->intvector);
|
||||
return m68k_raise_vectorint(chip->intlevel,chip->intvector);
|
||||
}
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat i8259_reset(I8259* chip)
|
||||
{
|
||||
chip->autoint = TRUE;
|
||||
chip->intlevel = 1;
|
||||
chip->intvector = 0;
|
||||
chip->state = 0;
|
||||
chip->rmode = 0;
|
||||
chip->imr = 0;
|
||||
return SCPE_OK;
|
||||
chip->autoint = TRUE;
|
||||
chip->intlevel = 1;
|
||||
chip->intvector = 0;
|
||||
chip->state = 0;
|
||||
chip->rmode = 0;
|
||||
chip->imr = 0;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
|
886
SAGE/i8272.c
886
SAGE/i8272.c
File diff suppressed because it is too large
Load diff
5886
SAGE/m68k_cpu.c
5886
SAGE/m68k_cpu.c
File diff suppressed because it is too large
Load diff
192
SAGE/m68k_cpu.h
192
SAGE/m68k_cpu.h
|
@ -46,13 +46,13 @@ extern DEVICE* m68kcpu_dev;
|
|||
extern REG m68kcpu_reg[];
|
||||
|
||||
/* debug flags */
|
||||
#define DBG_CPU_EXC (1 << 0)
|
||||
#define DBG_CPU_PC (1 << 1)
|
||||
#define DBG_CPU_INT (1 << 2)
|
||||
#define DBG_CPU_CTRACE (1 << 3)
|
||||
#define DBG_CPU_BTRACE (1 << 4)
|
||||
#define DBG_CPU_CUSTOM1 (1 << 5) /* reserved for custom debugging */
|
||||
#define DBG_CPU_CUSTOM2 (1 << 6) /* reserved for custom debugging */
|
||||
#define DBG_CPU_EXC (1 << 0)
|
||||
#define DBG_CPU_PC (1 << 1)
|
||||
#define DBG_CPU_INT (1 << 2)
|
||||
#define DBG_CPU_CTRACE (1 << 3)
|
||||
#define DBG_CPU_BTRACE (1 << 4)
|
||||
#define DBG_CPU_CUSTOM1 (1 << 5) /* reserved for custom debugging */
|
||||
#define DBG_CPU_CUSTOM2 (1 << 6) /* reserved for custom debugging */
|
||||
extern DEBTAB m68kcpu_dt[];
|
||||
#if DBG_MSG==1
|
||||
#define IFDEBUG(flag,func) if ((m68kcpu_dev->dctrl & flag) && sim_deb) { (void)(func); fflush(sim_deb); }
|
||||
|
@ -60,60 +60,60 @@ extern DEBTAB m68kcpu_dt[];
|
|||
#define IFDEBUG(flag,func)
|
||||
#endif
|
||||
|
||||
#define SIM_EMAX 16 /* ? */
|
||||
#define MAXMEMORY (256*256*256) /* 2^24 bytes */
|
||||
#define MINMEMORY (256*256) /* reserve 64k by default */
|
||||
#define MEMORYSIZE (m68kcpu_unit->capac) /* actual memory size */
|
||||
#define KB 1024 /* kilobyte */
|
||||
#define SIM_EMAX 16 /* ? */
|
||||
#define MAXMEMORY (256*256*256) /* 2^24 bytes */
|
||||
#define MINMEMORY (256*256) /* reserve 64k by default */
|
||||
#define MEMORYSIZE (m68kcpu_unit->capac) /* actual memory size */
|
||||
#define KB 1024 /* kilobyte */
|
||||
|
||||
/* simulator stop codes */
|
||||
#define STOP_IBKPT 1 /* pc breakpoint */
|
||||
#define STOP_MEM 2 /* memory breakpoint */
|
||||
#define STOP_ERROP 3 /* invalid opcode, normally exception 4 */
|
||||
#define STOP_ERRIO 4 /* invalid I/O address, normally exception 2 */
|
||||
#define STOP_ERRADR 5 /* invalid memory address, normally exception 3 */
|
||||
#define STOP_IMPL 6 /* not yet implemented (should disappear) */
|
||||
#define SIM_ISIO 7 /* internal indicator that I/O dispatch is required */
|
||||
#define SIM_NOMEM 8 /* allows to signal that there is no memory at that location */
|
||||
#define STOP_PCIO 9 /* code error, PC steps on I/O address */
|
||||
#define STOP_PRVIO 10 /* internal indicator: privileged instruction */
|
||||
#define STOP_TRACE 11 /* halt on trace */
|
||||
#define STOP_HALT 12 /* STOP instruction */
|
||||
#define STOP_DBF 13 /* double bus fault */
|
||||
#define STOP_OFFLINE 14 /* printer offline */
|
||||
#define STOP_IBKPT 1 /* pc breakpoint */
|
||||
#define STOP_MEM 2 /* memory breakpoint */
|
||||
#define STOP_ERROP 3 /* invalid opcode, normally exception 4 */
|
||||
#define STOP_ERRIO 4 /* invalid I/O address, normally exception 2 */
|
||||
#define STOP_ERRADR 5 /* invalid memory address, normally exception 3 */
|
||||
#define STOP_IMPL 6 /* not yet implemented (should disappear) */
|
||||
#define SIM_ISIO 7 /* internal indicator that I/O dispatch is required */
|
||||
#define SIM_NOMEM 8 /* allows to signal that there is no memory at that location */
|
||||
#define STOP_PCIO 9 /* code error, PC steps on I/O address */
|
||||
#define STOP_PRVIO 10 /* internal indicator: privileged instruction */
|
||||
#define STOP_TRACE 11 /* halt on trace */
|
||||
#define STOP_HALT 12 /* STOP instruction */
|
||||
#define STOP_DBF 13 /* double bus fault */
|
||||
#define STOP_OFFLINE 14 /* printer offline */
|
||||
|
||||
#define UNIT_CPU_M_TYPE 017
|
||||
#define UNIT_CPU_V_TYPE (UNIT_V_UF+0) /* CPUTYPE */
|
||||
#define UNIT_CPU_TYPE (1 << UNIT_CPU_V_CPU)
|
||||
#define UNIT_CPU_V_EXC (UNIT_V_UF+4) /* halt on exception 2..4 */
|
||||
#define UNIT_CPU_EXC (1 << UNIT_CPU_V_EXC)
|
||||
#define UNIT_CPU_V_STOP (UNIT_V_UF+5) /* halt on STOP instruction */
|
||||
#define UNIT_CPU_STOP (1 << UNIT_CPU_V_STOP)
|
||||
#define UNIT_CPU_V_PRVIO (UNIT_V_UF+6) /* halt on privilege violation */
|
||||
#define UNIT_CPU_PRVIO (1 << UNIT_CPU_V_PRVIO)
|
||||
#define UNIT_CPU_V_TRACE (UNIT_V_UF+7) /* halt on TRACE exception */
|
||||
#define UNIT_CPU_TRACE (1 << UNIT_CPU_V_TRACE)
|
||||
#define UNIT_CPU_V_FPU (UNIT_V_UF+8) /* has FPU */
|
||||
#define UNIT_CPU_FPU (1 << UNIT_CPU_V_FPU)
|
||||
#define UNIT_CPU_V_MMU (UNIT_V_UF+9) /* has MMU */
|
||||
#define UNIT_CPU_MMU (1 << UNIT_CPU_V_MMU)
|
||||
#define UNIT_CPU_V_MSIZE (UNIT_V_UF+10) /* set memsize */
|
||||
#define UNIT_CPU_MSIZE (1 << UNIT_CPU_V_MSIZE)
|
||||
#define UNIT_CPU_M_TYPE 017
|
||||
#define UNIT_CPU_V_TYPE (UNIT_V_UF+0) /* CPUTYPE */
|
||||
#define UNIT_CPU_TYPE (1 << UNIT_CPU_V_CPU)
|
||||
#define UNIT_CPU_V_EXC (UNIT_V_UF+4) /* halt on exception 2..4 */
|
||||
#define UNIT_CPU_EXC (1 << UNIT_CPU_V_EXC)
|
||||
#define UNIT_CPU_V_STOP (UNIT_V_UF+5) /* halt on STOP instruction */
|
||||
#define UNIT_CPU_STOP (1 << UNIT_CPU_V_STOP)
|
||||
#define UNIT_CPU_V_PRVIO (UNIT_V_UF+6) /* halt on privilege violation */
|
||||
#define UNIT_CPU_PRVIO (1 << UNIT_CPU_V_PRVIO)
|
||||
#define UNIT_CPU_V_TRACE (UNIT_V_UF+7) /* halt on TRACE exception */
|
||||
#define UNIT_CPU_TRACE (1 << UNIT_CPU_V_TRACE)
|
||||
#define UNIT_CPU_V_FPU (UNIT_V_UF+8) /* has FPU */
|
||||
#define UNIT_CPU_FPU (1 << UNIT_CPU_V_FPU)
|
||||
#define UNIT_CPU_V_MMU (UNIT_V_UF+9) /* has MMU */
|
||||
#define UNIT_CPU_MMU (1 << UNIT_CPU_V_MMU)
|
||||
#define UNIT_CPU_V_MSIZE (UNIT_V_UF+10) /* set memsize */
|
||||
#define UNIT_CPU_MSIZE (1 << UNIT_CPU_V_MSIZE)
|
||||
|
||||
#define UNIT_CPU_V_FREE (UNIT_V_UF+11) /* next free bit */
|
||||
#define UNIT_CPU_V_FREE (UNIT_V_UF+11) /* next free bit */
|
||||
|
||||
/* the various CPUs */
|
||||
#define UNIT_CPUTYPE_MASK (UNIT_CPU_M_TYPE << UNIT_CPU_V_TYPE)
|
||||
#define CPU_TYPE_68000 (0 << UNIT_CPU_V_TYPE)
|
||||
#define CPU_TYPE_68008 (1 << UNIT_CPU_V_TYPE)
|
||||
#define CPU_TYPE_68010 (2 << UNIT_CPU_V_TYPE) /* not yet! */
|
||||
#define CPU_TYPE_68020 (3 << UNIT_CPU_V_TYPE) /* not yet! */
|
||||
#define CPU_TYPE_68030 (4 << UNIT_CPU_V_TYPE) /* not yet! */
|
||||
#define UNIT_CPUTYPE_MASK (UNIT_CPU_M_TYPE << UNIT_CPU_V_TYPE)
|
||||
#define CPU_TYPE_68000 (0 << UNIT_CPU_V_TYPE)
|
||||
#define CPU_TYPE_68008 (1 << UNIT_CPU_V_TYPE)
|
||||
#define CPU_TYPE_68010 (2 << UNIT_CPU_V_TYPE) /* not yet! */
|
||||
#define CPU_TYPE_68020 (3 << UNIT_CPU_V_TYPE) /* not yet! */
|
||||
#define CPU_TYPE_68030 (4 << UNIT_CPU_V_TYPE) /* not yet! */
|
||||
|
||||
extern uint8 *M;
|
||||
extern int16 cputype;
|
||||
extern uint8 *M;
|
||||
extern int16 cputype;
|
||||
extern t_addr saved_PC;
|
||||
#define PCX saved_PC
|
||||
#define PCX saved_PC
|
||||
|
||||
/* breakpoint space for data accesses (R=read, W=write) */
|
||||
#define E_BKPT_SPC (0)
|
||||
|
@ -121,7 +121,7 @@ extern t_addr saved_PC;
|
|||
#define W_BKPT_SPC (2<<SIM_BKPT_V_SPC)
|
||||
|
||||
/* IR 7-6 bits */
|
||||
#define SZ_BYTE 0
|
||||
#define SZ_BYTE 0
|
||||
#define SZ_WORD 1
|
||||
#define SZ_LONG 2
|
||||
#define SZ_SPEC 3
|
||||
|
@ -131,30 +131,30 @@ extern t_addr saved_PC;
|
|||
* xxxxVx access virtual memory using MMU; if no MMU xxxxVX == xxxxPX
|
||||
* xxxxxB = byte, xxxxxW = 16 bit word, xxxxxL = 32 bit word
|
||||
*/
|
||||
#define BMASK 0x000000ff
|
||||
#define BLMASK BMASK
|
||||
#define BHMASK 0x0000ff00
|
||||
#define BMASK 0x000000ff
|
||||
#define BLMASK BMASK
|
||||
#define BHMASK 0x0000ff00
|
||||
|
||||
#define WMASK 0x0000ffff
|
||||
#define WLMASK WMASK
|
||||
#define WHMASK 0xffff0000
|
||||
#define WMASK 0x0000ffff
|
||||
#define WLMASK WMASK
|
||||
#define WHMASK 0xffff0000
|
||||
|
||||
#define LMASK 0xffffffff
|
||||
#define LMASK 0xffffffff
|
||||
extern t_addr addrmask;
|
||||
|
||||
#define MEM_READ 0
|
||||
#define MEM_WRITE 1
|
||||
|
||||
/* I/O handler block */
|
||||
#define IO_READ 0
|
||||
#define IO_READ 0
|
||||
#define IO_WRITE 1
|
||||
struct _iohandler {
|
||||
void* ctxt;
|
||||
t_addr port;
|
||||
t_addr offset;
|
||||
UNIT* u;
|
||||
t_stat (*io)(struct _iohandler* ioh,uint32* value,uint32 rw,uint32 mask);
|
||||
struct _iohandler* next;
|
||||
void* ctxt;
|
||||
t_addr port;
|
||||
t_addr offset;
|
||||
UNIT* u;
|
||||
t_stat (*io)(struct _iohandler* ioh,uint32* value,uint32 rw,uint32 mask);
|
||||
struct _iohandler* next;
|
||||
};
|
||||
typedef struct _iohandler IOHANDLER;
|
||||
|
||||
|
@ -163,11 +163,11 @@ typedef struct {
|
|||
uint32 mem_size; /* Memory Address space requirement */
|
||||
uint32 io_base; /* I/O Base Address */
|
||||
uint32 io_size; /* I/O Address Space requirement */
|
||||
uint32 io_incr; /* I/O Address increment */
|
||||
uint32 io_incr; /* I/O Address increment */
|
||||
} PNP_INFO;
|
||||
|
||||
extern t_stat add_iohandler(UNIT* u,void* ctxt,
|
||||
t_stat (*io)(IOHANDLER* ioh,uint32* value,uint32 rw,uint32 mask));
|
||||
t_stat (*io)(IOHANDLER* ioh,uint32* value,uint32 rw,uint32 mask));
|
||||
extern t_stat del_iohandler(void* ctxt);
|
||||
extern t_stat set_iobase(UNIT *uptr, int32 val, char *cptr, void *desc);
|
||||
extern t_stat show_iobase(FILE *st, UNIT *uptr, int32 val, void *desc);
|
||||
|
@ -218,34 +218,34 @@ extern void (*m68kcpu_trapcallback)(DEVICE* cpudev,int trapnum);
|
|||
|
||||
/* standard MTAB declarations for most 68K CPUs */
|
||||
#define M68KCPU_STDMOD \
|
||||
{ UNIT_CPUTYPE_MASK, CPU_TYPE_68000, "", "68000", &m68k_set_cpu, &m68k_show_cpu, "68000" },\
|
||||
{ UNIT_CPUTYPE_MASK, CPU_TYPE_68008, "", "68008", &m68k_set_cpu, &m68k_show_cpu, "68008" },\
|
||||
{ UNIT_CPUTYPE_MASK, CPU_TYPE_68010, "", "68010", &m68k_set_cpu, &m68k_show_cpu, "68010" },\
|
||||
{ UNIT_CPU_MSIZE, (1u << 16), NULL, "64K", &m68k_set_size },\
|
||||
{ UNIT_CPU_MSIZE, (1u << 17), NULL, "128K", &m68k_set_size },\
|
||||
{ UNIT_CPU_MSIZE, (1u << 18), NULL, "256K", &m68k_set_size },\
|
||||
{ UNIT_CPU_MSIZE, (1u << 19), NULL, "512K", &m68k_set_size },\
|
||||
{ UNIT_CPU_MSIZE, (1u << 20), NULL, "1M", &m68k_set_size },\
|
||||
{ UNIT_CPU_MSIZE, (1u << 21), NULL, "2M", &m68k_set_size },\
|
||||
{ UNIT_CPU_MSIZE, (1u << 22), NULL, "4M", &m68k_set_size },\
|
||||
{ UNIT_CPU_MSIZE, (1u << 23), NULL, "8M", &m68k_set_size },\
|
||||
{ UNIT_CPU_EXC, UNIT_CPU_EXC, "halt on EXC", "EXC", &m68kcpu_set_flag },\
|
||||
{ UNIT_CPU_EXC, 0, "no EXC", NULL, NULL },\
|
||||
{ MTAB_XTD|MTAB_VDV, UNIT_CPU_EXC, NULL, "NOEXC", &m68kcpu_set_noflag },\
|
||||
{ UNIT_CPU_STOP, UNIT_CPU_STOP, "halt on STOP", "STOP", &m68kcpu_set_flag },\
|
||||
{ UNIT_CPU_STOP, 0, "no STOP", NULL, NULL },\
|
||||
{ MTAB_XTD|MTAB_VDV, UNIT_CPU_STOP, NULL, "NOSTOP", &m68kcpu_set_noflag },\
|
||||
{ UNIT_CPU_PRVIO, UNIT_CPU_PRVIO, "halt on PRVIO", "PRVIO", &m68kcpu_set_flag },\
|
||||
{ UNIT_CPU_PRVIO, 0, "no PRVIO", NULL, NULL },\
|
||||
{ MTAB_XTD|MTAB_VDV, UNIT_CPU_PRVIO, NULL, "NOPRVIO", &m68kcpu_set_noflag },\
|
||||
{ UNIT_CPU_TRACE, UNIT_CPU_TRACE, "halt on TRACE", "TRACE", &m68kcpu_set_flag },\
|
||||
{ UNIT_CPU_TRACE, 0, "no TRACE", NULL, NULL },\
|
||||
{ MTAB_XTD|MTAB_VDV, UNIT_CPU_TRACE, NULL, "NOTRACE", &m68kcpu_set_noflag }
|
||||
{ UNIT_CPUTYPE_MASK, CPU_TYPE_68000, "", "68000", &m68k_set_cpu, &m68k_show_cpu, "68000" },\
|
||||
{ UNIT_CPUTYPE_MASK, CPU_TYPE_68008, "", "68008", &m68k_set_cpu, &m68k_show_cpu, "68008" },\
|
||||
{ UNIT_CPUTYPE_MASK, CPU_TYPE_68010, "", "68010", &m68k_set_cpu, &m68k_show_cpu, "68010" },\
|
||||
{ UNIT_CPU_MSIZE, (1u << 16), NULL, "64K", &m68k_set_size },\
|
||||
{ UNIT_CPU_MSIZE, (1u << 17), NULL, "128K", &m68k_set_size },\
|
||||
{ UNIT_CPU_MSIZE, (1u << 18), NULL, "256K", &m68k_set_size },\
|
||||
{ UNIT_CPU_MSIZE, (1u << 19), NULL, "512K", &m68k_set_size },\
|
||||
{ UNIT_CPU_MSIZE, (1u << 20), NULL, "1M", &m68k_set_size },\
|
||||
{ UNIT_CPU_MSIZE, (1u << 21), NULL, "2M", &m68k_set_size },\
|
||||
{ UNIT_CPU_MSIZE, (1u << 22), NULL, "4M", &m68k_set_size },\
|
||||
{ UNIT_CPU_MSIZE, (1u << 23), NULL, "8M", &m68k_set_size },\
|
||||
{ UNIT_CPU_EXC, UNIT_CPU_EXC, "halt on EXC", "EXC", &m68kcpu_set_flag },\
|
||||
{ UNIT_CPU_EXC, 0, "no EXC", NULL, NULL },\
|
||||
{ MTAB_XTD|MTAB_VDV, UNIT_CPU_EXC, NULL, "NOEXC", &m68kcpu_set_noflag },\
|
||||
{ UNIT_CPU_STOP, UNIT_CPU_STOP, "halt on STOP", "STOP", &m68kcpu_set_flag },\
|
||||
{ UNIT_CPU_STOP, 0, "no STOP", NULL, NULL },\
|
||||
{ MTAB_XTD|MTAB_VDV, UNIT_CPU_STOP, NULL, "NOSTOP", &m68kcpu_set_noflag },\
|
||||
{ UNIT_CPU_PRVIO, UNIT_CPU_PRVIO, "halt on PRVIO", "PRVIO", &m68kcpu_set_flag },\
|
||||
{ UNIT_CPU_PRVIO, 0, "no PRVIO", NULL, NULL },\
|
||||
{ MTAB_XTD|MTAB_VDV, UNIT_CPU_PRVIO, NULL, "NOPRVIO", &m68kcpu_set_noflag },\
|
||||
{ UNIT_CPU_TRACE, UNIT_CPU_TRACE, "halt on TRACE", "TRACE", &m68kcpu_set_flag },\
|
||||
{ UNIT_CPU_TRACE, 0, "no TRACE", NULL, NULL },\
|
||||
{ MTAB_XTD|MTAB_VDV, UNIT_CPU_TRACE, NULL, "NOTRACE", &m68kcpu_set_noflag }
|
||||
|
||||
#if 0
|
||||
,{ UNIT_CPU_FPU, UNIT_CPU_FPU, "FPU", "FPU", &m68k_set_fpu },
|
||||
{ UNIT_CPU_FPU, 0, "no FPU", NULL, NULL },
|
||||
{ MTAB_XTD|MTAB_VDV, UNIT_CPU_FPU, NULL, "NOFPU", &m68k_set_nofpu },
|
||||
,{ UNIT_CPU_FPU, UNIT_CPU_FPU, "FPU", "FPU", &m68k_set_fpu },
|
||||
{ UNIT_CPU_FPU, 0, "no FPU", NULL, NULL },
|
||||
{ MTAB_XTD|MTAB_VDV, UNIT_CPU_FPU, NULL, "NOFPU", &m68k_set_nofpu },
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
502
SAGE/m68k_mem.c
502
SAGE/m68k_mem.c
|
@ -44,7 +44,7 @@ static IOHANDLER** iohash = NULL;
|
|||
/*
|
||||
* memory
|
||||
*/
|
||||
uint8* M = 0;
|
||||
uint8* M = 0;
|
||||
t_addr addrmask = 0xffffffff;
|
||||
int m68k_fcode = 0;
|
||||
int m68k_dma = 0;
|
||||
|
@ -53,20 +53,20 @@ int m68k_dma = 0;
|
|||
/* TODO */
|
||||
t_stat m68k_set_mmu(UNIT *uptr, int32 value, char *cptr, void *desc)
|
||||
{
|
||||
uptr->flags |= value;
|
||||
|
||||
/* TODO initialize the MMU */
|
||||
TranslateAddr = &m68k_translateaddr;
|
||||
return SCPE_OK;
|
||||
uptr->flags |= value;
|
||||
|
||||
/* TODO initialize the MMU */
|
||||
TranslateAddr = &m68k_translateaddr;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat m68k_set_nommu(UNIT *uptr, int32 value, char *cptr, void *desc)
|
||||
{
|
||||
uptr->flags &= ~value;
|
||||
uptr->flags &= ~value;
|
||||
|
||||
/* initialize NO MMU */
|
||||
TranslateAddr = &m68k_translateaddr;
|
||||
return SCPE_OK;
|
||||
/* initialize NO MMU */
|
||||
TranslateAddr = &m68k_translateaddr;
|
||||
return SCPE_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -82,59 +82,59 @@ t_stat m68k_set_nommu(UNIT *uptr, int32 value, char *cptr, void *desc)
|
|||
*/
|
||||
t_stat m68k_ioinit()
|
||||
{
|
||||
if (iohash == NULL) {
|
||||
iohash = (IOHANDLER**)calloc(IOHASHSIZE,sizeof(IOHANDLER*));
|
||||
if (iohash == NULL) return SCPE_MEM;
|
||||
}
|
||||
return SCPE_OK;
|
||||
if (iohash == NULL) {
|
||||
iohash = (IOHANDLER**)calloc(IOHASHSIZE,sizeof(IOHANDLER*));
|
||||
if (iohash == NULL) return SCPE_MEM;
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat add_iohandler(UNIT* u,void* ctxt,
|
||||
t_stat (*io)(struct _iohandler* ioh,uint32* value,uint32 rw,uint32 mask))
|
||||
t_stat (*io)(struct _iohandler* ioh,uint32* value,uint32 rw,uint32 mask))
|
||||
{
|
||||
PNP_INFO* pnp = (PNP_INFO*)ctxt;
|
||||
IOHANDLER* ioh;
|
||||
uint32 i,k;
|
||||
|
||||
if (!pnp) return SCPE_IERR;
|
||||
for (k=i=0; i<pnp->io_size; i+=pnp->io_incr,k++) {
|
||||
t_addr p = (pnp->io_base+i) & addrmask;
|
||||
t_addr idx = MAKEIOHASH(p);
|
||||
ioh = iohash[idx];
|
||||
while (ioh != NULL && ioh->port != p) ioh = ioh->next;
|
||||
if (ioh) continue; /* already registered */
|
||||
|
||||
// printf("Register IO for address %x offset=%d\n",p,k);
|
||||
ioh = (IOHANDLER*)malloc(sizeof(IOHANDLER));
|
||||
if (ioh == NULL) return SCPE_MEM;
|
||||
ioh->ctxt = ctxt;
|
||||
ioh->port = p;
|
||||
ioh->offset = k;
|
||||
ioh->u = u;
|
||||
ioh->io = io;
|
||||
ioh->next = iohash[idx];
|
||||
iohash[idx] = ioh;
|
||||
}
|
||||
return SCPE_OK;
|
||||
PNP_INFO* pnp = (PNP_INFO*)ctxt;
|
||||
IOHANDLER* ioh;
|
||||
uint32 i,k;
|
||||
|
||||
if (!pnp) return SCPE_IERR;
|
||||
for (k=i=0; i<pnp->io_size; i+=pnp->io_incr,k++) {
|
||||
t_addr p = (pnp->io_base+i) & addrmask;
|
||||
t_addr idx = MAKEIOHASH(p);
|
||||
ioh = iohash[idx];
|
||||
while (ioh != NULL && ioh->port != p) ioh = ioh->next;
|
||||
if (ioh) continue; /* already registered */
|
||||
|
||||
// printf("Register IO for address %x offset=%d\n",p,k);
|
||||
ioh = (IOHANDLER*)malloc(sizeof(IOHANDLER));
|
||||
if (ioh == NULL) return SCPE_MEM;
|
||||
ioh->ctxt = ctxt;
|
||||
ioh->port = p;
|
||||
ioh->offset = k;
|
||||
ioh->u = u;
|
||||
ioh->io = io;
|
||||
ioh->next = iohash[idx];
|
||||
iohash[idx] = ioh;
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
t_stat del_iohandler(void* ctxt)
|
||||
{
|
||||
uint32 i;
|
||||
PNP_INFO* pnp = (PNP_INFO*)ctxt;
|
||||
|
||||
if (!pnp) return SCPE_IERR;
|
||||
for (i=0; i<pnp->io_size; i += pnp->io_incr) {
|
||||
t_addr p = (pnp->io_base+i) & addrmask;
|
||||
t_addr idx = MAKEIOHASH(p);
|
||||
IOHANDLER **ioh = &iohash[idx];
|
||||
while (*ioh != NULL && (*ioh)->port != p) ioh = &((*ioh)->next);
|
||||
if (*ioh) {
|
||||
IOHANDLER *e = *ioh;
|
||||
*ioh = (*ioh)->next;
|
||||
free((void*)e);
|
||||
}
|
||||
}
|
||||
return SCPE_OK;
|
||||
uint32 i;
|
||||
PNP_INFO* pnp = (PNP_INFO*)ctxt;
|
||||
|
||||
if (!pnp) return SCPE_IERR;
|
||||
for (i=0; i<pnp->io_size; i += pnp->io_incr) {
|
||||
t_addr p = (pnp->io_base+i) & addrmask;
|
||||
t_addr idx = MAKEIOHASH(p);
|
||||
IOHANDLER **ioh = &iohash[idx];
|
||||
while (*ioh != NULL && (*ioh)->port != p) ioh = &((*ioh)->next);
|
||||
if (*ioh) {
|
||||
IOHANDLER *e = *ioh;
|
||||
*ioh = (*ioh)->next;
|
||||
free((void*)e);
|
||||
}
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/***********************************************************************************************
|
||||
|
@ -156,26 +156,26 @@ t_stat del_iohandler(void* ctxt)
|
|||
/* default handler */
|
||||
t_stat m68k_translateaddr(t_addr in,t_addr* out, IOHANDLER** ioh,int rw,int fc,int dma)
|
||||
{
|
||||
t_addr ma = in & addrmask;
|
||||
t_addr idx = MAKEIOHASH(ma);
|
||||
IOHANDLER* i = iohash[idx];
|
||||
t_addr ma = in & addrmask;
|
||||
t_addr idx = MAKEIOHASH(ma);
|
||||
IOHANDLER* i = iohash[idx];
|
||||
|
||||
*out = ma;
|
||||
*ioh = 0;
|
||||
while (i != NULL && i->port != ma) i = i->next;
|
||||
if (i) {
|
||||
*ioh = i;
|
||||
return SIM_ISIO;
|
||||
} else
|
||||
return SCPE_OK;
|
||||
*out = ma;
|
||||
*ioh = 0;
|
||||
while (i != NULL && i->port != ma) i = i->next;
|
||||
if (i) {
|
||||
*ioh = i;
|
||||
return SIM_ISIO;
|
||||
} else
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* default memory pointer */
|
||||
t_stat m68k_mem(t_addr addr,uint8** mem)
|
||||
{
|
||||
if (addr > MEMORYSIZE) return STOP_ERRADR;
|
||||
*mem = M+addr;
|
||||
return SCPE_OK;
|
||||
if (addr > MEMORYSIZE) return STOP_ERRADR;
|
||||
*mem = M+addr;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat (*TranslateAddr)(t_addr in,t_addr* out,IOHANDLER** ioh,int rw,int fc,int dma) = &m68k_translateaddr;
|
||||
|
@ -193,233 +193,233 @@ t_stat (*Mem)(t_addr addr,uint8** mem) = &m68k_mem;
|
|||
*/
|
||||
t_stat ReadPB(t_addr a, uint32* val)
|
||||
{
|
||||
uint8* mem;
|
||||
uint8* mem;
|
||||
|
||||
t_stat rc = Mem(a & addrmask,&mem);
|
||||
switch (rc) {
|
||||
default:
|
||||
return rc;
|
||||
case SIM_NOMEM:
|
||||
*val = 0xff;
|
||||
return SCPE_OK;
|
||||
case SCPE_OK:
|
||||
*val = *mem & BMASK;
|
||||
return SCPE_OK;
|
||||
}
|
||||
t_stat rc = Mem(a & addrmask,&mem);
|
||||
switch (rc) {
|
||||
default:
|
||||
return rc;
|
||||
case SIM_NOMEM:
|
||||
*val = 0xff;
|
||||
return SCPE_OK;
|
||||
case SCPE_OK:
|
||||
*val = *mem & BMASK;
|
||||
return SCPE_OK;
|
||||
}
|
||||
}
|
||||
|
||||
t_stat ReadPW(t_addr a, uint32* val)
|
||||
{
|
||||
uint8* mem;
|
||||
uint32 dat1,dat2;
|
||||
uint8* mem;
|
||||
uint32 dat1,dat2;
|
||||
|
||||
t_stat rc = Mem((a+1)&addrmask,&mem);
|
||||
switch (rc) {
|
||||
default:
|
||||
return rc;
|
||||
case SIM_NOMEM:
|
||||
*val = 0xffff;
|
||||
return SCPE_OK;
|
||||
case SCPE_OK:
|
||||
/* 68000/08/10 do not like unaligned access */
|
||||
if (cputype < 3 && (a & 1)) return STOP_ERRADR;
|
||||
dat1 = (*(mem-1) & BMASK) << 8;
|
||||
dat2 = *mem & BMASK;
|
||||
*val = (dat1 | dat2) & WMASK;
|
||||
return SCPE_OK;
|
||||
}
|
||||
t_stat rc = Mem((a+1)&addrmask,&mem);
|
||||
switch (rc) {
|
||||
default:
|
||||
return rc;
|
||||
case SIM_NOMEM:
|
||||
*val = 0xffff;
|
||||
return SCPE_OK;
|
||||
case SCPE_OK:
|
||||
/* 68000/08/10 do not like unaligned access */
|
||||
if (cputype < 3 && (a & 1)) return STOP_ERRADR;
|
||||
dat1 = (*(mem-1) & BMASK) << 8;
|
||||
dat2 = *mem & BMASK;
|
||||
*val = (dat1 | dat2) & WMASK;
|
||||
return SCPE_OK;
|
||||
}
|
||||
}
|
||||
|
||||
t_stat ReadPL(t_addr a, uint32* val)
|
||||
{
|
||||
uint8* mem;
|
||||
uint32 dat1,dat2,dat3,dat4;
|
||||
uint8* mem;
|
||||
uint32 dat1,dat2,dat3,dat4;
|
||||
|
||||
t_stat rc = Mem((a+3)&addrmask,&mem);
|
||||
switch (rc) {
|
||||
default:
|
||||
return rc;
|
||||
case SIM_NOMEM:
|
||||
*val = 0xffffffff;
|
||||
return SCPE_OK;
|
||||
case SCPE_OK:
|
||||
/* 68000/08/10 do not like unaligned access */
|
||||
if (cputype < 3 && (a & 1)) return STOP_ERRADR;
|
||||
dat1 = *(mem-3) & BMASK;
|
||||
dat2 = *(mem-2) & BMASK;
|
||||
dat3 = *(mem-1) & BMASK;
|
||||
dat4 = *mem & BMASK;
|
||||
*val = (((((dat1 << 8) | dat2) << 8) | dat3) << 8) | dat4;
|
||||
return SCPE_OK;
|
||||
}
|
||||
t_stat rc = Mem((a+3)&addrmask,&mem);
|
||||
switch (rc) {
|
||||
default:
|
||||
return rc;
|
||||
case SIM_NOMEM:
|
||||
*val = 0xffffffff;
|
||||
return SCPE_OK;
|
||||
case SCPE_OK:
|
||||
/* 68000/08/10 do not like unaligned access */
|
||||
if (cputype < 3 && (a & 1)) return STOP_ERRADR;
|
||||
dat1 = *(mem-3) & BMASK;
|
||||
dat2 = *(mem-2) & BMASK;
|
||||
dat3 = *(mem-1) & BMASK;
|
||||
dat4 = *mem & BMASK;
|
||||
*val = (((((dat1 << 8) | dat2) << 8) | dat3) << 8) | dat4;
|
||||
return SCPE_OK;
|
||||
}
|
||||
}
|
||||
|
||||
t_stat WritePB(t_addr a, uint32 val)
|
||||
{
|
||||
uint8* mem;
|
||||
|
||||
t_stat rc = Mem(a&addrmask,&mem);
|
||||
switch (rc) {
|
||||
default:
|
||||
return rc;
|
||||
case SCPE_OK:
|
||||
*mem = val & BMASK;
|
||||
/*fallthru*/
|
||||
case SIM_NOMEM:
|
||||
return SCPE_OK;
|
||||
}
|
||||
uint8* mem;
|
||||
|
||||
t_stat rc = Mem(a&addrmask,&mem);
|
||||
switch (rc) {
|
||||
default:
|
||||
return rc;
|
||||
case SCPE_OK:
|
||||
*mem = val & BMASK;
|
||||
/*fallthru*/
|
||||
case SIM_NOMEM:
|
||||
return SCPE_OK;
|
||||
}
|
||||
}
|
||||
|
||||
t_stat WritePW(t_addr a, uint32 val)
|
||||
{
|
||||
uint8* mem;
|
||||
t_stat rc = Mem((a+1)&addrmask,&mem);
|
||||
switch (rc) {
|
||||
default:
|
||||
return rc;
|
||||
case SCPE_OK:
|
||||
/* 68000/08/10 do not like unaligned access */
|
||||
if (cputype < 3 && (a & 1)) return STOP_ERRADR;
|
||||
*(mem-1) = (val >> 8) & BMASK;
|
||||
*mem = val & BMASK;
|
||||
/*fallthru*/
|
||||
case SIM_NOMEM:
|
||||
return SCPE_OK;
|
||||
}
|
||||
uint8* mem;
|
||||
t_stat rc = Mem((a+1)&addrmask,&mem);
|
||||
switch (rc) {
|
||||
default:
|
||||
return rc;
|
||||
case SCPE_OK:
|
||||
/* 68000/08/10 do not like unaligned access */
|
||||
if (cputype < 3 && (a & 1)) return STOP_ERRADR;
|
||||
*(mem-1) = (val >> 8) & BMASK;
|
||||
*mem = val & BMASK;
|
||||
/*fallthru*/
|
||||
case SIM_NOMEM:
|
||||
return SCPE_OK;
|
||||
}
|
||||
}
|
||||
|
||||
t_stat WritePL(t_addr a, uint32 val)
|
||||
{
|
||||
uint8* mem;
|
||||
uint8* mem;
|
||||
|
||||
t_stat rc = Mem((a+3)&addrmask,&mem);
|
||||
switch (rc) {
|
||||
default:
|
||||
return rc;
|
||||
case SCPE_OK:
|
||||
/* 68000/08/10 do not like unaligned access */
|
||||
if (cputype < 3 && (a & 1)) return STOP_ERRADR;
|
||||
*(mem-3) = (val >> 24) & BMASK;
|
||||
*(mem-2) = (val >> 16) & BMASK;
|
||||
*(mem-1) = (val >> 8) & BMASK;
|
||||
*mem = val & BMASK;
|
||||
/*fallthru*/
|
||||
case SIM_NOMEM:
|
||||
return SCPE_OK;
|
||||
}
|
||||
t_stat rc = Mem((a+3)&addrmask,&mem);
|
||||
switch (rc) {
|
||||
default:
|
||||
return rc;
|
||||
case SCPE_OK:
|
||||
/* 68000/08/10 do not like unaligned access */
|
||||
if (cputype < 3 && (a & 1)) return STOP_ERRADR;
|
||||
*(mem-3) = (val >> 24) & BMASK;
|
||||
*(mem-2) = (val >> 16) & BMASK;
|
||||
*(mem-1) = (val >> 8) & BMASK;
|
||||
*mem = val & BMASK;
|
||||
/*fallthru*/
|
||||
case SIM_NOMEM:
|
||||
return SCPE_OK;
|
||||
}
|
||||
}
|
||||
|
||||
t_stat ReadVB(t_addr a, uint32* val)
|
||||
{
|
||||
t_addr addr;
|
||||
IOHANDLER* ioh;
|
||||
t_stat rc = TranslateAddr(a,&addr,&ioh,MEM_READ,m68k_fcode,m68k_dma);
|
||||
switch (rc) {
|
||||
case SIM_NOMEM:
|
||||
/* note this is a hack to persuade memory testing code that there is no memory:
|
||||
* writing to such an address is a bit bucket,
|
||||
* and reading from it will return some arbitrary value.
|
||||
*
|
||||
* SIM_NOMEM has to be defined for systems without a strict memory handling that will
|
||||
* result in reading out anything without trapping a memory fault
|
||||
*/
|
||||
*val = 0xff;
|
||||
return SCPE_OK;
|
||||
case SIM_ISIO:
|
||||
return ioh->io(ioh,val,IO_READ,BMASK);
|
||||
case SCPE_OK:
|
||||
return ReadPB(addr,val);
|
||||
default:
|
||||
return rc;
|
||||
}
|
||||
t_addr addr;
|
||||
IOHANDLER* ioh;
|
||||
t_stat rc = TranslateAddr(a,&addr,&ioh,MEM_READ,m68k_fcode,m68k_dma);
|
||||
switch (rc) {
|
||||
case SIM_NOMEM:
|
||||
/* note this is a hack to persuade memory testing code that there is no memory:
|
||||
* writing to such an address is a bit bucket,
|
||||
* and reading from it will return some arbitrary value.
|
||||
*
|
||||
* SIM_NOMEM has to be defined for systems without a strict memory handling that will
|
||||
* result in reading out anything without trapping a memory fault
|
||||
*/
|
||||
*val = 0xff;
|
||||
return SCPE_OK;
|
||||
case SIM_ISIO:
|
||||
return ioh->io(ioh,val,IO_READ,BMASK);
|
||||
case SCPE_OK:
|
||||
return ReadPB(addr,val);
|
||||
default:
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
t_stat ReadVW(t_addr a, uint32* val)
|
||||
{
|
||||
t_addr addr;
|
||||
IOHANDLER* ioh;
|
||||
t_stat rc = TranslateAddr(a,&addr,&ioh,MEM_READ,m68k_fcode,m68k_dma);
|
||||
switch (rc) {
|
||||
case SIM_NOMEM:
|
||||
*val = 0xffff;
|
||||
return SCPE_OK;
|
||||
case SIM_ISIO:
|
||||
return ioh->io(ioh,val,IO_READ,WMASK);
|
||||
case SCPE_OK:
|
||||
return ReadPW(addr,val);
|
||||
default:
|
||||
return rc;
|
||||
}
|
||||
t_addr addr;
|
||||
IOHANDLER* ioh;
|
||||
t_stat rc = TranslateAddr(a,&addr,&ioh,MEM_READ,m68k_fcode,m68k_dma);
|
||||
switch (rc) {
|
||||
case SIM_NOMEM:
|
||||
*val = 0xffff;
|
||||
return SCPE_OK;
|
||||
case SIM_ISIO:
|
||||
return ioh->io(ioh,val,IO_READ,WMASK);
|
||||
case SCPE_OK:
|
||||
return ReadPW(addr,val);
|
||||
default:
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
t_stat ReadVL(t_addr a, uint32* val)
|
||||
{
|
||||
t_addr addr;
|
||||
IOHANDLER* ioh;
|
||||
t_stat rc = TranslateAddr(a,&addr,&ioh,MEM_READ,m68k_fcode,m68k_dma);
|
||||
switch (rc) {
|
||||
case SIM_NOMEM:
|
||||
*val = 0xffffffff;
|
||||
return SCPE_OK;
|
||||
case SIM_ISIO:
|
||||
return ioh->io(ioh,val,IO_READ,LMASK);
|
||||
case SCPE_OK:
|
||||
return ReadPL(addr,val);
|
||||
default:
|
||||
return rc;
|
||||
}
|
||||
t_addr addr;
|
||||
IOHANDLER* ioh;
|
||||
t_stat rc = TranslateAddr(a,&addr,&ioh,MEM_READ,m68k_fcode,m68k_dma);
|
||||
switch (rc) {
|
||||
case SIM_NOMEM:
|
||||
*val = 0xffffffff;
|
||||
return SCPE_OK;
|
||||
case SIM_ISIO:
|
||||
return ioh->io(ioh,val,IO_READ,LMASK);
|
||||
case SCPE_OK:
|
||||
return ReadPL(addr,val);
|
||||
default:
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
t_stat WriteVB(t_addr a, uint32 val)
|
||||
{
|
||||
t_addr addr;
|
||||
IOHANDLER* ioh;
|
||||
t_stat rc = TranslateAddr(a,&addr,&ioh,MEM_WRITE,m68k_fcode,m68k_dma);
|
||||
switch (rc) {
|
||||
case SIM_NOMEM:
|
||||
/* part 2 of hack for less strict memory handling: ignore anything written
|
||||
* to a nonexisting address
|
||||
*/
|
||||
return SCPE_OK;
|
||||
case SIM_ISIO:
|
||||
return ioh->io(ioh,&val,IO_WRITE,BMASK);
|
||||
case SCPE_OK:
|
||||
return WritePB(addr,val);
|
||||
default:
|
||||
return rc;
|
||||
}
|
||||
t_addr addr;
|
||||
IOHANDLER* ioh;
|
||||
t_stat rc = TranslateAddr(a,&addr,&ioh,MEM_WRITE,m68k_fcode,m68k_dma);
|
||||
switch (rc) {
|
||||
case SIM_NOMEM:
|
||||
/* part 2 of hack for less strict memory handling: ignore anything written
|
||||
* to a nonexisting address
|
||||
*/
|
||||
return SCPE_OK;
|
||||
case SIM_ISIO:
|
||||
return ioh->io(ioh,&val,IO_WRITE,BMASK);
|
||||
case SCPE_OK:
|
||||
return WritePB(addr,val);
|
||||
default:
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
t_stat WriteVW(t_addr a, uint32 val)
|
||||
{
|
||||
t_addr addr;
|
||||
IOHANDLER* ioh;
|
||||
t_stat rc = TranslateAddr(a,&addr,&ioh,MEM_WRITE,m68k_fcode,m68k_dma);
|
||||
switch (rc) {
|
||||
case SIM_NOMEM:
|
||||
return SCPE_OK;
|
||||
case SIM_ISIO:
|
||||
return ioh->io(ioh,&val,IO_WRITE,WMASK);
|
||||
case SCPE_OK:
|
||||
return WritePW(addr,val);
|
||||
default:
|
||||
return rc;
|
||||
}
|
||||
t_addr addr;
|
||||
IOHANDLER* ioh;
|
||||
t_stat rc = TranslateAddr(a,&addr,&ioh,MEM_WRITE,m68k_fcode,m68k_dma);
|
||||
switch (rc) {
|
||||
case SIM_NOMEM:
|
||||
return SCPE_OK;
|
||||
case SIM_ISIO:
|
||||
return ioh->io(ioh,&val,IO_WRITE,WMASK);
|
||||
case SCPE_OK:
|
||||
return WritePW(addr,val);
|
||||
default:
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
t_stat WriteVL(t_addr a, uint32 val)
|
||||
{
|
||||
t_addr addr;
|
||||
IOHANDLER* ioh;
|
||||
t_stat rc = TranslateAddr(a,&addr,&ioh,MEM_WRITE,m68k_fcode,m68k_dma);
|
||||
switch (rc) {
|
||||
case SIM_NOMEM:
|
||||
return SCPE_OK;
|
||||
case SIM_ISIO:
|
||||
return ioh->io(ioh,&val,IO_WRITE,LMASK);
|
||||
case SCPE_OK:
|
||||
return WritePL(addr,val);
|
||||
default:
|
||||
return rc;
|
||||
}
|
||||
t_addr addr;
|
||||
IOHANDLER* ioh;
|
||||
t_stat rc = TranslateAddr(a,&addr,&ioh,MEM_WRITE,m68k_fcode,m68k_dma);
|
||||
switch (rc) {
|
||||
case SIM_NOMEM:
|
||||
return SCPE_OK;
|
||||
case SIM_ISIO:
|
||||
return ioh->io(ioh,&val,IO_WRITE,LMASK);
|
||||
case SCPE_OK:
|
||||
return WritePL(addr,val);
|
||||
default:
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -338,19 +338,19 @@
|
|||
typedef union YYSTYPE
|
||||
#line 74 "m68k_parse.y"
|
||||
{
|
||||
int rc;
|
||||
int reg;
|
||||
int wl;
|
||||
int opc;
|
||||
struct _ea ea;
|
||||
t_value num;
|
||||
struct _rea rea;
|
||||
struct _mask mask;
|
||||
struct _brop brop;
|
||||
int rc;
|
||||
int reg;
|
||||
int wl;
|
||||
int opc;
|
||||
struct _ea ea;
|
||||
t_value num;
|
||||
struct _rea rea;
|
||||
struct _mask mask;
|
||||
struct _brop brop;
|
||||
}
|
||||
/* Line 1489 of yacc.c. */
|
||||
#line 353 "m68k_parse.tab.h"
|
||||
YYSTYPE;
|
||||
YYSTYPE;
|
||||
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
|
||||
# define YYSTYPE_IS_DECLARED 1
|
||||
# define YYSTYPE_IS_TRIVIAL 1
|
||||
|
|
382
SAGE/m68k_scp.c
382
SAGE/m68k_scp.c
|
@ -39,30 +39,30 @@ static t_stat symlist_cmd(int32 arg,char* buf);
|
|||
static t_stat symtrace_cmd(int32 arg,char* buf);
|
||||
|
||||
static CTAB m68k_sim_cmds[] = {
|
||||
{"STEP", &run_cmd, RU_STEP,
|
||||
"s{tep} {n} simulate n instructions\n" },
|
||||
{"HEXDUMP", &hdump_cmd, 0,
|
||||
"hex{dump} range dump memory\n" },
|
||||
{"SYMSET", &symset_cmd, 0,
|
||||
"syms{et} name=value define symbolic name for disassembler/tracer\n"},
|
||||
{"SYMCLR",&symclr_cmd, 0,
|
||||
"symc{lr} {-a|name} clear symbolic name / all symbolic names\n"},
|
||||
{"SYMLIST", &symlist_cmd, 0,
|
||||
"syml{ist} [name] list symbol table\n"},
|
||||
{"SYMTRACE", &symtrace_cmd, 1,
|
||||
"symt{race} enable symbolic tracing\n"},
|
||||
{"NOSYMTRACE", &symtrace_cmd, 0,
|
||||
"nosymt{race} disable symbolic tracing\n"},
|
||||
{0,0,0,0}
|
||||
{"STEP", &run_cmd, RU_STEP,
|
||||
"s{tep} {n} simulate n instructions\n" },
|
||||
{"HEXDUMP", &hdump_cmd, 0,
|
||||
"hex{dump} range dump memory\n" },
|
||||
{"SYMSET", &symset_cmd, 0,
|
||||
"syms{et} name=value define symbolic name for disassembler/tracer\n"},
|
||||
{"SYMCLR",&symclr_cmd, 0,
|
||||
"symc{lr} {-a|name} clear symbolic name / all symbolic names\n"},
|
||||
{"SYMLIST", &symlist_cmd, 0,
|
||||
"syml{ist} [name] list symbol table\n"},
|
||||
{"SYMTRACE", &symtrace_cmd, 1,
|
||||
"symt{race} enable symbolic tracing\n"},
|
||||
{"NOSYMTRACE", &symtrace_cmd, 0,
|
||||
"nosymt{race} disable symbolic tracing\n"},
|
||||
{0,0,0,0}
|
||||
};
|
||||
|
||||
void (*sim_vm_init)(void) = &m68k_sim_init;
|
||||
|
||||
typedef struct _symhash {
|
||||
struct _symhash* nnext;
|
||||
struct _symhash* vnext;
|
||||
char* name;
|
||||
t_addr val;
|
||||
struct _symhash* nnext;
|
||||
struct _symhash* vnext;
|
||||
char* name;
|
||||
t_addr val;
|
||||
} SYMHASH;
|
||||
#define SYMHASHSIZE 397
|
||||
|
||||
|
@ -71,237 +71,237 @@ static SYMHASH *symbyval = 0;
|
|||
|
||||
static void sym_clearall(void)
|
||||
{
|
||||
int i;
|
||||
SYMHASH *p,*n;
|
||||
|
||||
if (!symbyname) return;
|
||||
for (i=0; i<SYMHASHSIZE; i++) {
|
||||
p = symbyname[i].nnext;
|
||||
while ((n = p) != 0) {
|
||||
p = p->nnext;
|
||||
free(n->name);
|
||||
free(n);
|
||||
}
|
||||
symbyname[i].nnext = symbyval[i].vnext = 0;
|
||||
}
|
||||
return;
|
||||
int i;
|
||||
SYMHASH *p,*n;
|
||||
|
||||
if (!symbyname) return;
|
||||
for (i=0; i<SYMHASHSIZE; i++) {
|
||||
p = symbyname[i].nnext;
|
||||
while ((n = p) != 0) {
|
||||
p = p->nnext;
|
||||
free(n->name);
|
||||
free(n);
|
||||
}
|
||||
symbyname[i].nnext = symbyval[i].vnext = 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static void m68k_sim_init(void)
|
||||
{
|
||||
int i;
|
||||
sim_vm_cmd = m68k_sim_cmds;
|
||||
int i;
|
||||
sim_vm_cmd = m68k_sim_cmds;
|
||||
|
||||
sym_clearall();
|
||||
symbyname = (SYMHASH*)calloc(sizeof(SYMHASH),SYMHASHSIZE);
|
||||
symbyval = (SYMHASH*)calloc(sizeof(SYMHASH),SYMHASHSIZE);
|
||||
for (i=0; i<SYMHASHSIZE; i++)
|
||||
symbyval[i].vnext = symbyname[i].nnext = 0;
|
||||
sym_clearall();
|
||||
symbyname = (SYMHASH*)calloc(sizeof(SYMHASH),SYMHASHSIZE);
|
||||
symbyval = (SYMHASH*)calloc(sizeof(SYMHASH),SYMHASHSIZE);
|
||||
for (i=0; i<SYMHASHSIZE; i++)
|
||||
symbyval[i].vnext = symbyname[i].nnext = 0;
|
||||
|
||||
symtrace = TRUE;
|
||||
symtrace = TRUE;
|
||||
}
|
||||
|
||||
static int getnhash(const char* name)
|
||||
{
|
||||
int i, nhash = 0;
|
||||
for (i=0; name[i]; i++) {
|
||||
nhash += name[i];
|
||||
}
|
||||
return nhash % SYMHASHSIZE;
|
||||
int i, nhash = 0;
|
||||
for (i=0; name[i]; i++) {
|
||||
nhash += name[i];
|
||||
}
|
||||
return nhash % SYMHASHSIZE;
|
||||
}
|
||||
|
||||
static int getvhash(t_addr val)
|
||||
{
|
||||
return val % SYMHASHSIZE;
|
||||
return val % SYMHASHSIZE;
|
||||
}
|
||||
|
||||
static t_bool sym_lookupname(const char *name,SYMHASH **n)
|
||||
{
|
||||
int hash = getnhash(name);
|
||||
SYMHASH *p = symbyname[hash].nnext;
|
||||
while (p && strcmp(name,p->name)) p = p->nnext;
|
||||
*n = p;
|
||||
return p != 0;
|
||||
int hash = getnhash(name);
|
||||
SYMHASH *p = symbyname[hash].nnext;
|
||||
while (p && strcmp(name,p->name)) p = p->nnext;
|
||||
*n = p;
|
||||
return p != 0;
|
||||
}
|
||||
|
||||
static t_bool sym_lookupval(t_addr val, SYMHASH **v)
|
||||
{
|
||||
int hash = getvhash(val);
|
||||
SYMHASH *p = symbyval[hash].vnext;
|
||||
while (p && p->val != val) p = p->vnext;
|
||||
*v = p;
|
||||
return p != 0;
|
||||
int hash = getvhash(val);
|
||||
SYMHASH *p = symbyval[hash].vnext;
|
||||
while (p && p->val != val) p = p->vnext;
|
||||
*v = p;
|
||||
return p != 0;
|
||||
}
|
||||
|
||||
static t_bool sym_enter(const char* name,t_addr val)
|
||||
{
|
||||
int nhash = getnhash(name);
|
||||
int vhash = getvhash(val);
|
||||
SYMHASH *v, *n, *e;
|
||||
|
||||
if (sym_lookupname(name,&n) || sym_lookupval(val,&v)) return FALSE;
|
||||
n = symbyname[nhash].nnext;
|
||||
v = symbyval[vhash].vnext;
|
||||
e = (SYMHASH*)malloc(sizeof(SYMHASH));
|
||||
e->nnext = n;
|
||||
e->vnext = v;
|
||||
e->name = malloc(strlen(name)+1);
|
||||
strcpy(e->name,name);
|
||||
e->val = val;
|
||||
symbyname[nhash].nnext = symbyval[vhash].vnext = e;
|
||||
return TRUE;
|
||||
int nhash = getnhash(name);
|
||||
int vhash = getvhash(val);
|
||||
SYMHASH *v, *n, *e;
|
||||
|
||||
if (sym_lookupname(name,&n) || sym_lookupval(val,&v)) return FALSE;
|
||||
n = symbyname[nhash].nnext;
|
||||
v = symbyval[vhash].vnext;
|
||||
e = (SYMHASH*)malloc(sizeof(SYMHASH));
|
||||
e->nnext = n;
|
||||
e->vnext = v;
|
||||
e->name = malloc(strlen(name)+1);
|
||||
strcpy(e->name,name);
|
||||
e->val = val;
|
||||
symbyname[nhash].nnext = symbyval[vhash].vnext = e;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static t_bool sym_delete(const char* name)
|
||||
{
|
||||
int hash = getnhash(name);
|
||||
SYMHASH *p, *q, **n, **v;
|
||||
n = &symbyname[hash].nnext;
|
||||
while ((p = *n) != 0) {
|
||||
if (!strcmp(p->name,name)) { /*found*/
|
||||
hash = getvhash(p->val);
|
||||
v = &symbyval[hash].vnext;
|
||||
while ((q = *v) != 0) {
|
||||
if (q->val == p->val) { /*found*/
|
||||
*v = q->vnext;
|
||||
break;
|
||||
}
|
||||
v = &(q->vnext);
|
||||
}
|
||||
*n = p->nnext;
|
||||
free(p->name);
|
||||
free(p);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
int hash = getnhash(name);
|
||||
SYMHASH *p, *q, **n, **v;
|
||||
n = &symbyname[hash].nnext;
|
||||
while ((p = *n) != 0) {
|
||||
if (!strcmp(p->name,name)) { /*found*/
|
||||
hash = getvhash(p->val);
|
||||
v = &symbyval[hash].vnext;
|
||||
while ((q = *v) != 0) {
|
||||
if (q->val == p->val) { /*found*/
|
||||
*v = q->vnext;
|
||||
break;
|
||||
}
|
||||
v = &(q->vnext);
|
||||
}
|
||||
*n = p->nnext;
|
||||
free(p->name);
|
||||
free(p);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static t_stat symset_cmd(int32 arg,char* buf)
|
||||
{
|
||||
char *name,*vstr;
|
||||
t_addr val;
|
||||
char *name,*vstr;
|
||||
t_addr val;
|
||||
|
||||
if ((name = strtok(buf, "= ")) == 0) return SCPE_2FARG;
|
||||
if ((vstr = strtok(NULL, " \t\n")) == 0) return SCPE_2FARG;
|
||||
val = strtol(vstr, 0, 16);
|
||||
if (!sym_enter(name, val))
|
||||
printf("Name or value already exists\n");
|
||||
return SCPE_OK;
|
||||
if ((name = strtok(buf, "= ")) == 0) return SCPE_2FARG;
|
||||
if ((vstr = strtok(NULL, " \t\n")) == 0) return SCPE_2FARG;
|
||||
val = strtol(vstr, 0, 16);
|
||||
if (!sym_enter(name, val))
|
||||
printf("Name or value already exists\n");
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
static t_stat symclr_cmd(int32 arg,char* buf)
|
||||
{
|
||||
char* token;
|
||||
if (buf[0] == '-' && buf[1]=='a') {
|
||||
sym_clearall();
|
||||
return SCPE_OK;
|
||||
} else {
|
||||
token = strtok(buf," \t\n");
|
||||
if (!token) return SCPE_2FARG;
|
||||
return sym_delete(token) ? SCPE_OK : SCPE_ARG;
|
||||
}
|
||||
char* token;
|
||||
if (buf[0] == '-' && buf[1]=='a') {
|
||||
sym_clearall();
|
||||
return SCPE_OK;
|
||||
} else {
|
||||
token = strtok(buf," \t\n");
|
||||
if (!token) return SCPE_2FARG;
|
||||
return sym_delete(token) ? SCPE_OK : SCPE_ARG;
|
||||
}
|
||||
}
|
||||
|
||||
static t_stat symlist_cmd(int32 arg,char* buf)
|
||||
{
|
||||
int i;
|
||||
SYMHASH* n;
|
||||
char *name;
|
||||
t_bool found = FALSE;
|
||||
|
||||
name = strtok(buf," \t\n");
|
||||
if (name) {
|
||||
if (sym_lookupname(name,&n))
|
||||
printf(" %s = 0x%08x\n",n->name,n->val);
|
||||
else
|
||||
printf("Unknown\n");
|
||||
} else {
|
||||
for (i=0; i<SYMHASHSIZE; i++) {
|
||||
n = symbyname[i].nnext;
|
||||
while (n) {
|
||||
printf(" %s = 0x%08x\n",n->name,n->val);
|
||||
n = n->nnext;
|
||||
found = TRUE;
|
||||
}
|
||||
}
|
||||
if (!found) printf("Symbol table is empty\n");
|
||||
}
|
||||
return SCPE_OK;
|
||||
int i;
|
||||
SYMHASH* n;
|
||||
char *name;
|
||||
t_bool found = FALSE;
|
||||
|
||||
name = strtok(buf," \t\n");
|
||||
if (name) {
|
||||
if (sym_lookupname(name,&n))
|
||||
printf(" %s = 0x%08x\n",n->name,n->val);
|
||||
else
|
||||
printf("Unknown\n");
|
||||
} else {
|
||||
for (i=0; i<SYMHASHSIZE; i++) {
|
||||
n = symbyname[i].nnext;
|
||||
while (n) {
|
||||
printf(" %s = 0x%08x\n",n->name,n->val);
|
||||
n = n->nnext;
|
||||
found = TRUE;
|
||||
}
|
||||
}
|
||||
if (!found) printf("Symbol table is empty\n");
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
static t_stat symtrace_cmd(int32 arg,char* buf)
|
||||
{
|
||||
if (!*buf)
|
||||
symtrace = arg ? TRUE : FALSE;
|
||||
if (!*buf)
|
||||
symtrace = arg ? TRUE : FALSE;
|
||||
|
||||
printf("Symbolic tracing %sabled\n",symtrace ? "en" : "dis");
|
||||
return SCPE_OK;
|
||||
printf("Symbolic tracing %sabled\n",symtrace ? "en" : "dis");
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
static void putascii(uint32* buf)
|
||||
{
|
||||
int i;
|
||||
putchar('|');
|
||||
for (i=0; i<16; i++) {
|
||||
if (isprint(buf[i])) putchar(buf[i]);
|
||||
else putchar('.');
|
||||
}
|
||||
putchar('|');
|
||||
int i;
|
||||
putchar('|');
|
||||
for (i=0; i<16; i++) {
|
||||
if (isprint(buf[i])) putchar(buf[i]);
|
||||
else putchar('.');
|
||||
}
|
||||
putchar('|');
|
||||
}
|
||||
|
||||
static t_stat hdump_cmd(int32 arg, char* buf)
|
||||
{
|
||||
int i;
|
||||
t_addr low, high, base, top;
|
||||
char *token;
|
||||
uint32 byte[16];
|
||||
t_bool ascii = FALSE;
|
||||
t_bool first = TRUE;
|
||||
|
||||
if (buf[0]=='-' && buf[1]=='a') {
|
||||
ascii = TRUE;
|
||||
buf += 2;
|
||||
while (*buf && isspace(*buf)) buf++;
|
||||
}
|
||||
memset(byte,0,sizeof(uint32)*16);
|
||||
|
||||
token = strtok(buf,"- \t\n");
|
||||
if (!token) return SCPE_2FARG;
|
||||
low = strtol(token,0,16);
|
||||
token = strtok(NULL,"- \t\n");
|
||||
if (!token) return SCPE_2FARG;
|
||||
high = strtol(token,0,16);
|
||||
|
||||
base = low - (low % 16);
|
||||
top = (high + 15) - ((high+15) % 16);
|
||||
for (; base<top; base++) {
|
||||
if ((base % 16)==0) {
|
||||
if (!first && ascii) putascii(byte);
|
||||
printf("\n%08x: ",base);
|
||||
first = FALSE;
|
||||
}
|
||||
if (base < low) printf(" ");
|
||||
else if (base > high) printf(" ");
|
||||
else {
|
||||
i = base %16;
|
||||
if (ReadPB(base,byte+i) != SCPE_OK) printf("?? ");
|
||||
else printf("%02x ",byte[i] & 0xff);
|
||||
}
|
||||
}
|
||||
if (!first && ascii) putascii(byte);
|
||||
putchar('\n');
|
||||
return SCPE_OK;
|
||||
int i;
|
||||
t_addr low, high, base, top;
|
||||
char *token;
|
||||
uint32 byte[16];
|
||||
t_bool ascii = FALSE;
|
||||
t_bool first = TRUE;
|
||||
|
||||
if (buf[0]=='-' && buf[1]=='a') {
|
||||
ascii = TRUE;
|
||||
buf += 2;
|
||||
while (*buf && isspace(*buf)) buf++;
|
||||
}
|
||||
memset(byte,0,sizeof(uint32)*16);
|
||||
|
||||
token = strtok(buf,"- \t\n");
|
||||
if (!token) return SCPE_2FARG;
|
||||
low = strtol(token,0,16);
|
||||
token = strtok(NULL,"- \t\n");
|
||||
if (!token) return SCPE_2FARG;
|
||||
high = strtol(token,0,16);
|
||||
|
||||
base = low - (low % 16);
|
||||
top = (high + 15) - ((high+15) % 16);
|
||||
for (; base<top; base++) {
|
||||
if ((base % 16)==0) {
|
||||
if (!first && ascii) putascii(byte);
|
||||
printf("\n%08x: ",base);
|
||||
first = FALSE;
|
||||
}
|
||||
if (base < low) printf(" ");
|
||||
else if (base > high) printf(" ");
|
||||
else {
|
||||
i = base %16;
|
||||
if (ReadPB(base,byte+i) != SCPE_OK) printf("?? ");
|
||||
else printf("%02x ",byte[i] & 0xff);
|
||||
}
|
||||
}
|
||||
if (!first && ascii) putascii(byte);
|
||||
putchar('\n');
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
char* m68k_getsym(t_addr val,const char* fmt, char* outbuf)
|
||||
{
|
||||
SYMHASH *v;
|
||||
if (symtrace && sym_lookupval(val,&v))
|
||||
return v->name;
|
||||
else {
|
||||
sprintf(outbuf,fmt,val);
|
||||
return outbuf;
|
||||
}
|
||||
SYMHASH *v;
|
||||
if (symtrace && sym_lookupval(val,&v))
|
||||
return v->name;
|
||||
else {
|
||||
sprintf(outbuf,fmt,val);
|
||||
return outbuf;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
1486
SAGE/m68k_sys.c
1486
SAGE/m68k_sys.c
File diff suppressed because it is too large
Load diff
|
@ -31,32 +31,32 @@
|
|||
static t_stat sageaux_reset(DEVICE* dptr);
|
||||
|
||||
UNIT sageaux_unit[] = {
|
||||
{ UDATA (NULL, UNIT_FIX | UNIT_BINK, 0) },
|
||||
{ UDATA (NULL, UNIT_FIX | UNIT_BINK, 0) },
|
||||
{ UDATA (NULL, UNIT_FIX | UNIT_BINK, 0) },
|
||||
{ UDATA (NULL, UNIT_FIX | UNIT_BINK, 0) }
|
||||
{ UDATA (NULL, UNIT_FIX | UNIT_BINK, 0) },
|
||||
{ UDATA (NULL, UNIT_FIX | UNIT_BINK, 0) },
|
||||
{ UDATA (NULL, UNIT_FIX | UNIT_BINK, 0) },
|
||||
{ UDATA (NULL, UNIT_FIX | UNIT_BINK, 0) }
|
||||
};
|
||||
|
||||
REG sageaux_reg[] = {
|
||||
{ NULL }
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
static MTAB sageaux_mod[] = {
|
||||
{ 0 }
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
DEVICE sageaux_dev = {
|
||||
"AUX", sageaux_unit, sageaux_reg, sageaux_mod,
|
||||
4, 16, 32, 2, 16, 16,
|
||||
NULL, NULL, &sageaux_reset,
|
||||
NULL, NULL, NULL,
|
||||
NULL, DEV_DISABLE|DEV_DIS, 0,
|
||||
NULL, NULL, NULL
|
||||
"AUX", sageaux_unit, sageaux_reg, sageaux_mod,
|
||||
4, 16, 32, 2, 16, 16,
|
||||
NULL, NULL, &sageaux_reset,
|
||||
NULL, NULL, NULL,
|
||||
NULL, DEV_DISABLE|DEV_DIS, 0,
|
||||
NULL, NULL, NULL
|
||||
};
|
||||
|
||||
static t_stat sageaux_reset(DEVICE* dptr)
|
||||
{
|
||||
printf("sageaux_reset\n");
|
||||
return SCPE_OK;
|
||||
printf("sageaux_reset\n");
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
|
|
580
SAGE/sage_cons.c
580
SAGE/sage_cons.c
|
@ -33,13 +33,13 @@
|
|||
#include "sim_sock.h"
|
||||
#include "sim_tmxr.h"
|
||||
|
||||
#define SIOPOLL 0
|
||||
#define SIOTERM 1
|
||||
#define SIOPOLL 0
|
||||
#define SIOTERM 1
|
||||
|
||||
#define SIO_POLL_FIRST 1 /* immediate */
|
||||
#define SIO_POLL_RATE 100 /* sample 100 times /sec */
|
||||
#define SIO_POLL_WAIT 15800 /* about 10ms */
|
||||
#define SIO_OUT_WAIT 200
|
||||
#define SIO_POLL_FIRST 1 /* immediate */
|
||||
#define SIO_POLL_RATE 100 /* sample 100 times /sec */
|
||||
#define SIO_POLL_WAIT 15800 /* about 10ms */
|
||||
#define SIO_OUT_WAIT 200
|
||||
|
||||
static t_stat sio_reset(DEVICE* dptr);
|
||||
static t_stat sioterm_svc(UNIT*);
|
||||
|
@ -51,196 +51,196 @@ static t_stat sio_rxint(I8251* chip);
|
|||
extern DEVICE sagesio_dev;
|
||||
|
||||
UNIT sio_unit[] = {
|
||||
{ UDATA (&siopoll_svc, UNIT_ATTABLE, 0), SIO_POLL_WAIT },
|
||||
{ UDATA (&sioterm_svc, UNIT_IDLE, 0), SIO_OUT_WAIT }
|
||||
{ UDATA (&siopoll_svc, UNIT_ATTABLE, 0), SIO_POLL_WAIT },
|
||||
{ UDATA (&sioterm_svc, UNIT_IDLE, 0), SIO_OUT_WAIT }
|
||||
};
|
||||
|
||||
static SERMUX sio_mux = {
|
||||
SIO_POLL_FIRST, /*pollfirst*/
|
||||
SIO_POLL_RATE, /*pollrate*/
|
||||
{ 0 }, /*ldsc*/
|
||||
{ 1, 0, 0, 0 }, /*desc*/
|
||||
&sio_unit[SIOTERM], /*term_unit*/
|
||||
&sio_unit[SIOPOLL] /*poll unit*/
|
||||
SIO_POLL_FIRST, /*pollfirst*/
|
||||
SIO_POLL_RATE, /*pollrate*/
|
||||
{ 0 }, /*ldsc*/
|
||||
{ 1, 0, 0, 0 }, /*desc*/
|
||||
&sio_unit[SIOTERM], /*term_unit*/
|
||||
&sio_unit[SIOPOLL] /*poll unit*/
|
||||
};
|
||||
|
||||
static I8251 u58 = {
|
||||
{0,0,U58_ADDR,4,2},
|
||||
&sagesio_dev,NULL,NULL,i8251_reset,
|
||||
&sio_txint,&sio_rxint,
|
||||
&sio_unit[SIOPOLL],&sio_unit[SIOTERM],
|
||||
&sio_mux
|
||||
{0,0,U58_ADDR,4,2},
|
||||
&sagesio_dev,NULL,NULL,i8251_reset,
|
||||
&sio_txint,&sio_rxint,
|
||||
&sio_unit[SIOPOLL],&sio_unit[SIOTERM],
|
||||
&sio_mux
|
||||
};
|
||||
|
||||
REG sio_reg[] = {
|
||||
{ DRDATA(INIT, u58.init, 3) },
|
||||
{ HRDATA(MODE, u58.mode, 8) },
|
||||
{ HRDATA(SYNC1, u58.sync1, 8) },
|
||||
{ HRDATA(SYNC2, u58.sync2, 8) },
|
||||
{ HRDATA(CMD, u58.cmd, 8) },
|
||||
{ HRDATA(IBUF, u58.ibuf, 8) },
|
||||
{ HRDATA(OBUF, u58.obuf, 8) },
|
||||
{ HRDATA(STATUS, u58.status, 8) },
|
||||
{ HRDATA(STATUS, u58.bitmask, 8), REG_HRO },
|
||||
{ 0 }
|
||||
{ DRDATA(INIT, u58.init, 3) },
|
||||
{ HRDATA(MODE, u58.mode, 8) },
|
||||
{ HRDATA(SYNC1, u58.sync1, 8) },
|
||||
{ HRDATA(SYNC2, u58.sync2, 8) },
|
||||
{ HRDATA(CMD, u58.cmd, 8) },
|
||||
{ HRDATA(IBUF, u58.ibuf, 8) },
|
||||
{ HRDATA(OBUF, u58.obuf, 8) },
|
||||
{ HRDATA(STATUS, u58.status, 8) },
|
||||
{ HRDATA(STATUS, u58.bitmask, 8), REG_HRO },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static MTAB sio_mod[] = {
|
||||
{ MTAB_XTD|MTAB_VDV, 0, "IO", "IO", &set_iobase, &show_iobase, NULL },
|
||||
{ 0 }
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
DEVICE sagesio_dev = {
|
||||
"SIO", sio_unit, sio_reg, sio_mod,
|
||||
2, 16, 32, 2, 16, 16,
|
||||
NULL, NULL, &sio_reset,
|
||||
NULL, &sio_attach, &sio_detach,
|
||||
&u58, DEV_DEBUG, 0,
|
||||
i8251_dt, NULL, NULL
|
||||
"SIO", sio_unit, sio_reg, sio_mod,
|
||||
2, 16, 32, 2, 16, 16,
|
||||
NULL, NULL, &sio_reset,
|
||||
NULL, &sio_attach, &sio_detach,
|
||||
&u58, DEV_DEBUG, 0,
|
||||
i8251_dt, NULL, NULL
|
||||
};
|
||||
|
||||
static t_stat sioterm_svc(UNIT* uptr)
|
||||
{
|
||||
DEVICE* dptr = find_dev_from_unit(uptr);
|
||||
I8251* chip = (I8251*)dptr->ctxt;
|
||||
SERMUX* mux = chip->mux;
|
||||
t_stat rc;
|
||||
int ch = chip->obuf;
|
||||
|
||||
/* suppress NUL bytes after CR LF */
|
||||
switch (ch) {
|
||||
case 0x0d:
|
||||
chip->crlf = 1; break;
|
||||
case 0x0a:
|
||||
chip->crlf = chip->crlf==1 ? 2 : 0; break;
|
||||
case 0:
|
||||
if (chip->crlf==2) goto set_stat;
|
||||
default:
|
||||
chip->crlf = 0;
|
||||
}
|
||||
|
||||
/* TODO? sim_tt_outcvt */
|
||||
|
||||
/* attached to a telnet port? */
|
||||
if (mux->poll->flags & UNIT_ATT) {
|
||||
if ((rc=tmxr_putc_ln(&mux->ldsc, ch & chip->bitmask)) != SCPE_OK) {
|
||||
sim_activate(uptr, uptr->wait);
|
||||
return SCPE_OK;
|
||||
} else
|
||||
tmxr_poll_tx(&mux->desc);
|
||||
} else {
|
||||
/* no, use normal terminal output */
|
||||
if ((rc=sim_putchar_s(ch & chip->bitmask)) != SCPE_OK) {
|
||||
sim_activate(uptr, uptr->wait);
|
||||
return rc==SCPE_STALL ? SCPE_OK : rc;
|
||||
}
|
||||
}
|
||||
DEVICE* dptr = find_dev_from_unit(uptr);
|
||||
I8251* chip = (I8251*)dptr->ctxt;
|
||||
SERMUX* mux = chip->mux;
|
||||
t_stat rc;
|
||||
int ch = chip->obuf;
|
||||
|
||||
/* suppress NUL bytes after CR LF */
|
||||
switch (ch) {
|
||||
case 0x0d:
|
||||
chip->crlf = 1; break;
|
||||
case 0x0a:
|
||||
chip->crlf = chip->crlf==1 ? 2 : 0; break;
|
||||
case 0:
|
||||
if (chip->crlf==2) goto set_stat;
|
||||
default:
|
||||
chip->crlf = 0;
|
||||
}
|
||||
|
||||
/* TODO? sim_tt_outcvt */
|
||||
|
||||
/* attached to a telnet port? */
|
||||
if (mux->poll->flags & UNIT_ATT) {
|
||||
if ((rc=tmxr_putc_ln(&mux->ldsc, ch & chip->bitmask)) != SCPE_OK) {
|
||||
sim_activate(uptr, uptr->wait);
|
||||
return SCPE_OK;
|
||||
} else
|
||||
tmxr_poll_tx(&mux->desc);
|
||||
} else {
|
||||
/* no, use normal terminal output */
|
||||
if ((rc=sim_putchar_s(ch & chip->bitmask)) != SCPE_OK) {
|
||||
sim_activate(uptr, uptr->wait);
|
||||
return rc==SCPE_STALL ? SCPE_OK : rc;
|
||||
}
|
||||
}
|
||||
set_stat:
|
||||
chip->status |= I8251_ST_TXEMPTY;
|
||||
if (chip->cmd & I8251_CMD_TXEN) {
|
||||
chip->status |= I8251_ST_TXRDY;
|
||||
return sio_txint(chip);
|
||||
}
|
||||
chip->status &= ~I8251_ST_TXRDY;
|
||||
return SCPE_OK;
|
||||
chip->status |= I8251_ST_TXEMPTY;
|
||||
if (chip->cmd & I8251_CMD_TXEN) {
|
||||
chip->status |= I8251_ST_TXRDY;
|
||||
return sio_txint(chip);
|
||||
}
|
||||
chip->status &= ~I8251_ST_TXRDY;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
static t_stat siopoll_svc(UNIT* uptr)
|
||||
{
|
||||
int32 c;
|
||||
DEVICE* dptr = find_dev_from_unit(uptr);
|
||||
I8251* chip = (I8251*)dptr->ctxt;
|
||||
SERMUX* mux = chip->mux;
|
||||
|
||||
sim_activate(uptr, uptr->wait); /* restart it again */
|
||||
|
||||
/* network attached? */
|
||||
if (mux->poll->flags & UNIT_ATT) {
|
||||
if (tmxr_poll_conn(&mux->desc) >= 0) /* new connection? */
|
||||
mux->ldsc.rcve = 1;
|
||||
tmxr_poll_rx(&mux->desc);
|
||||
if (!tmxr_rqln(&mux->ldsc)) return SCPE_OK;
|
||||
/* input ready */
|
||||
c = tmxr_getc_ln(&mux->ldsc);
|
||||
if ((c & TMXR_VALID)==0) return SCPE_OK;
|
||||
c &= 0xff; /* extract character */
|
||||
} else
|
||||
return SCPE_OK;
|
||||
|
||||
if (!(chip->cmd & I8251_CMD_RXE)) { /* ignore data if receiver not enabled */
|
||||
chip->status &= ~I8251_ST_RXRDY;
|
||||
return SCPE_OK;
|
||||
}
|
||||
int32 c;
|
||||
DEVICE* dptr = find_dev_from_unit(uptr);
|
||||
I8251* chip = (I8251*)dptr->ctxt;
|
||||
SERMUX* mux = chip->mux;
|
||||
|
||||
sim_activate(uptr, uptr->wait); /* restart it again */
|
||||
|
||||
/* network attached? */
|
||||
if (mux->poll->flags & UNIT_ATT) {
|
||||
if (tmxr_poll_conn(&mux->desc) >= 0) /* new connection? */
|
||||
mux->ldsc.rcve = 1;
|
||||
tmxr_poll_rx(&mux->desc);
|
||||
if (!tmxr_rqln(&mux->ldsc)) return SCPE_OK;
|
||||
/* input ready */
|
||||
c = tmxr_getc_ln(&mux->ldsc);
|
||||
if ((c & TMXR_VALID)==0) return SCPE_OK;
|
||||
c &= 0xff; /* extract character */
|
||||
} else
|
||||
return SCPE_OK;
|
||||
|
||||
if (!(chip->cmd & I8251_CMD_RXE)) { /* ignore data if receiver not enabled */
|
||||
chip->status &= ~I8251_ST_RXRDY;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* got char */
|
||||
if (c & SCPE_BREAK) { /* a break? */
|
||||
c = 0;
|
||||
chip->status |= I8251_ST_SYNBRK;
|
||||
} else
|
||||
chip->status &= ~I8251_ST_SYNBRK;
|
||||
/* got char */
|
||||
if (c & SCPE_BREAK) { /* a break? */
|
||||
c = 0;
|
||||
chip->status |= I8251_ST_SYNBRK;
|
||||
} else
|
||||
chip->status &= ~I8251_ST_SYNBRK;
|
||||
|
||||
/* TODO? sim_tt_icvt */
|
||||
chip->ibuf = c & chip->bitmask;
|
||||
if (chip->status & I8251_ST_RXRDY)
|
||||
chip->status |= I8251_ST_OE;
|
||||
chip->status |= I8251_ST_RXRDY;
|
||||
return sio_rxint(chip);
|
||||
/* TODO? sim_tt_icvt */
|
||||
chip->ibuf = c & chip->bitmask;
|
||||
if (chip->status & I8251_ST_RXRDY)
|
||||
chip->status |= I8251_ST_OE;
|
||||
chip->status |= I8251_ST_RXRDY;
|
||||
return sio_rxint(chip);
|
||||
}
|
||||
|
||||
static t_stat sio_reset(DEVICE* dptr)
|
||||
{
|
||||
t_stat rc;
|
||||
I8251* chip = (I8251*)dptr->ctxt;
|
||||
SERMUX* mux = chip->mux;
|
||||
|
||||
if ((rc = (dptr->flags & DEV_DIS) ?
|
||||
del_iohandler(chip) :
|
||||
add_iohandler(mux->poll,chip,i8251_io)) != SCPE_OK) return rc;
|
||||
{
|
||||
t_stat rc;
|
||||
I8251* chip = (I8251*)dptr->ctxt;
|
||||
SERMUX* mux = chip->mux;
|
||||
|
||||
if ((rc = (dptr->flags & DEV_DIS) ?
|
||||
del_iohandler(chip) :
|
||||
add_iohandler(mux->poll,chip,i8251_io)) != SCPE_OK) return rc;
|
||||
|
||||
u58.reset(&u58);
|
||||
mux->term->wait = 1000; /* TODO adjust to realistic speed */
|
||||
u58.reset(&u58);
|
||||
mux->term->wait = 1000; /* TODO adjust to realistic speed */
|
||||
|
||||
/* network attached? */
|
||||
if (mux->poll->flags & UNIT_ATT) {
|
||||
mux->poll->wait = mux->pfirst;
|
||||
sim_activate(mux->poll,mux->poll->wait); /* start poll routine */
|
||||
} else
|
||||
sim_cancel(mux->poll);
|
||||
sim_cancel(mux->term);
|
||||
return SCPE_OK;
|
||||
/* network attached? */
|
||||
if (mux->poll->flags & UNIT_ATT) {
|
||||
mux->poll->wait = mux->pfirst;
|
||||
sim_activate(mux->poll,mux->poll->wait); /* start poll routine */
|
||||
} else
|
||||
sim_cancel(mux->poll);
|
||||
sim_cancel(mux->term);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
static t_stat sio_attach(UNIT* uptr, char* cptr)
|
||||
{
|
||||
return mux_attach(uptr,cptr,&sio_mux);
|
||||
return mux_attach(uptr,cptr,&sio_mux);
|
||||
}
|
||||
|
||||
static t_stat sio_detach(UNIT* uptr)
|
||||
{
|
||||
return mux_detach(uptr,&sio_mux);
|
||||
return mux_detach(uptr,&sio_mux);
|
||||
}
|
||||
|
||||
static t_stat sio_txint(I8251* chip)
|
||||
{
|
||||
TRACE_PRINT0(DBG_UART_IRQ,"Raise TX Interrupt");
|
||||
return sage_raiseint(SIOTX_PICINT);
|
||||
TRACE_PRINT0(DBG_UART_IRQ,"Raise TX Interrupt");
|
||||
return sage_raiseint(SIOTX_PICINT);
|
||||
}
|
||||
|
||||
static t_stat sio_rxint(I8251* chip)
|
||||
{
|
||||
TRACE_PRINT0(DBG_UART_IRQ,"Raise RX Interrupt");
|
||||
return sage_raiseint(SIORX_PICINT);
|
||||
TRACE_PRINT0(DBG_UART_IRQ,"Raise RX Interrupt");
|
||||
return sage_raiseint(SIORX_PICINT);
|
||||
}
|
||||
|
||||
/***************************************************************************************************/
|
||||
|
||||
#define CONSPOLL 0
|
||||
#define CONSTERM 1
|
||||
#define CONSPOLL 0
|
||||
#define CONSTERM 1
|
||||
|
||||
#define CONS_POLL_FIRST 1 /* immediate */
|
||||
#define CONS_POLL_RATE 100 /* sample 100 times /sec */
|
||||
#define CONS_POLL_WAIT 15800 /* about 10ms */
|
||||
#define CONS_OUT_WAIT 200
|
||||
#define CONS_POLL_FIRST 1 /* immediate */
|
||||
#define CONS_POLL_RATE 100 /* sample 100 times /sec */
|
||||
#define CONS_POLL_WAIT 15800 /* about 10ms */
|
||||
#define CONS_OUT_WAIT 200
|
||||
|
||||
static t_stat cons_reset(DEVICE* dptr);
|
||||
static t_stat cons_txint(I8251* chip);
|
||||
|
@ -252,213 +252,213 @@ static t_stat cons_detach(UNIT*);
|
|||
extern DEVICE sagecons_dev;
|
||||
|
||||
UNIT cons_unit[] = {
|
||||
{ UDATA (&conspoll_svc, UNIT_ATTABLE, 0), CONS_POLL_WAIT },
|
||||
{ UDATA (&consterm_svc, UNIT_IDLE, 0), CONS_OUT_WAIT }
|
||||
{ UDATA (&conspoll_svc, UNIT_ATTABLE, 0), CONS_POLL_WAIT },
|
||||
{ UDATA (&consterm_svc, UNIT_IDLE, 0), CONS_OUT_WAIT }
|
||||
};
|
||||
|
||||
static SERMUX cons_mux = {
|
||||
CONS_POLL_FIRST,
|
||||
CONS_POLL_RATE,
|
||||
{ 0 },
|
||||
{ 1, 0, 0, 0 },
|
||||
&cons_unit[CONSTERM],
|
||||
&cons_unit[CONSPOLL]
|
||||
CONS_POLL_FIRST,
|
||||
CONS_POLL_RATE,
|
||||
{ 0 },
|
||||
{ 1, 0, 0, 0 },
|
||||
&cons_unit[CONSTERM],
|
||||
&cons_unit[CONSPOLL]
|
||||
};
|
||||
|
||||
static I8251 u57 = {
|
||||
{ 0,0,U57_ADDR,4,2},
|
||||
&sagecons_dev,NULL,NULL,&i8251_reset,
|
||||
&cons_txint,&cons_rxint,
|
||||
&cons_unit[CONSPOLL],&cons_unit[CONSTERM],
|
||||
&cons_mux
|
||||
{ 0,0,U57_ADDR,4,2},
|
||||
&sagecons_dev,NULL,NULL,&i8251_reset,
|
||||
&cons_txint,&cons_rxint,
|
||||
&cons_unit[CONSPOLL],&cons_unit[CONSTERM],
|
||||
&cons_mux
|
||||
};
|
||||
|
||||
REG cons_reg[] = {
|
||||
{ DRDATA(INIT, u57.init, 3) },
|
||||
{ HRDATA(MODE, u57.mode, 8) },
|
||||
{ HRDATA(SYNC1, u57.sync1, 8) },
|
||||
{ HRDATA(SYNC2, u57.sync2, 8) },
|
||||
{ HRDATA(CMD, u57.cmd, 8) },
|
||||
{ HRDATA(IBUF, u57.ibuf, 8) },
|
||||
{ HRDATA(OBUF, u57.obuf, 8) },
|
||||
{ HRDATA(STATUS, u57.status, 8) },
|
||||
{ HRDATA(BITS, u57.bitmask,8), REG_HRO },
|
||||
{ 0 }
|
||||
{ DRDATA(INIT, u57.init, 3) },
|
||||
{ HRDATA(MODE, u57.mode, 8) },
|
||||
{ HRDATA(SYNC1, u57.sync1, 8) },
|
||||
{ HRDATA(SYNC2, u57.sync2, 8) },
|
||||
{ HRDATA(CMD, u57.cmd, 8) },
|
||||
{ HRDATA(IBUF, u57.ibuf, 8) },
|
||||
{ HRDATA(OBUF, u57.obuf, 8) },
|
||||
{ HRDATA(STATUS, u57.status, 8) },
|
||||
{ HRDATA(BITS, u57.bitmask,8), REG_HRO },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static MTAB cons_mod[] = {
|
||||
{ MTAB_XTD|MTAB_VDV, 0, "IO", "IO", &set_iobase, &show_iobase, NULL },
|
||||
{ 0 }
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
DEVICE sagecons_dev = {
|
||||
"CONS", cons_unit, cons_reg, cons_mod,
|
||||
2, 16, 32, 2, 16, 16,
|
||||
NULL, NULL, &cons_reset,
|
||||
NULL, &cons_attach, &cons_detach,
|
||||
&u57, DEV_DEBUG, 0,
|
||||
i8251_dt, NULL, NULL
|
||||
"CONS", cons_unit, cons_reg, cons_mod,
|
||||
2, 16, 32, 2, 16, 16,
|
||||
NULL, NULL, &cons_reset,
|
||||
NULL, &cons_attach, &cons_detach,
|
||||
&u57, DEV_DEBUG, 0,
|
||||
i8251_dt, NULL, NULL
|
||||
};
|
||||
|
||||
static t_stat cons_reset(DEVICE* dptr)
|
||||
{
|
||||
t_stat rc;
|
||||
int32 wait;
|
||||
I8251* chip = (I8251*)dptr->ctxt;
|
||||
SERMUX* mux = chip->mux;
|
||||
|
||||
if ((rc = (dptr->flags & DEV_DIS) ?
|
||||
del_iohandler(chip) :
|
||||
add_iohandler(mux->poll,chip,&i8251_io)) != SCPE_OK) return rc;
|
||||
t_stat rc;
|
||||
int32 wait;
|
||||
I8251* chip = (I8251*)dptr->ctxt;
|
||||
SERMUX* mux = chip->mux;
|
||||
|
||||
if ((rc = (dptr->flags & DEV_DIS) ?
|
||||
del_iohandler(chip) :
|
||||
add_iohandler(mux->poll,chip,&i8251_io)) != SCPE_OK) return rc;
|
||||
|
||||
u57.reset(&u57);
|
||||
|
||||
/* initialize POLL timer */
|
||||
wait = mux->poll->wait = CONS_POLL_WAIT;
|
||||
sim_rtcn_init(wait, TMR_CONS);
|
||||
|
||||
u57.oob = TRUE; /* this is the console */
|
||||
sim_activate(mux->poll, wait);
|
||||
sim_cancel(mux->term);
|
||||
return SCPE_OK;
|
||||
u57.reset(&u57);
|
||||
|
||||
/* initialize POLL timer */
|
||||
wait = mux->poll->wait = CONS_POLL_WAIT;
|
||||
sim_rtcn_init(wait, TMR_CONS);
|
||||
|
||||
u57.oob = TRUE; /* this is the console */
|
||||
sim_activate(mux->poll, wait);
|
||||
sim_cancel(mux->term);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* this service is started when a unit is attached, or characters are available on keyboard */
|
||||
static t_stat conspoll_svc(UNIT* uptr)
|
||||
{
|
||||
int32 c, kbdc;
|
||||
DEVICE* dptr = find_dev_from_unit(uptr);
|
||||
I8251* chip = (I8251*)dptr->ctxt;
|
||||
SERMUX* mux = chip->mux;
|
||||
int32 c, kbdc;
|
||||
DEVICE* dptr = find_dev_from_unit(uptr);
|
||||
I8251* chip = (I8251*)dptr->ctxt;
|
||||
SERMUX* mux = chip->mux;
|
||||
|
||||
uptr->wait = sim_rtcn_calb(mux->prate, TMR_CONS); /* calibrate timer */
|
||||
sim_activate(uptr, uptr->wait); /* restart it again */
|
||||
uptr->wait = sim_rtcn_calb(mux->prate, TMR_CONS); /* calibrate timer */
|
||||
sim_activate(uptr, uptr->wait); /* restart it again */
|
||||
|
||||
kbdc = sim_poll_kbd(); /* check keyboard */
|
||||
if (kbdc==SCPE_STOP) return kbdc; /* handle CTRL-E */
|
||||
kbdc = sim_poll_kbd(); /* check keyboard */
|
||||
if (kbdc==SCPE_STOP) return kbdc; /* handle CTRL-E */
|
||||
|
||||
/* network-redirected input? */
|
||||
if (mux->poll->flags & UNIT_ATT) {
|
||||
if (tmxr_poll_conn(&mux->desc) >= 0) /* incoming connection */
|
||||
mux->ldsc.rcve = 1;
|
||||
/* network-redirected input? */
|
||||
if (mux->poll->flags & UNIT_ATT) {
|
||||
if (tmxr_poll_conn(&mux->desc) >= 0) /* incoming connection */
|
||||
mux->ldsc.rcve = 1;
|
||||
|
||||
tmxr_poll_rx(&mux->desc); /* poll for input */
|
||||
if (!tmxr_rqln(&mux->ldsc)) return SCPE_OK;
|
||||
/* input ready */
|
||||
c = tmxr_getc_ln(&mux->ldsc);
|
||||
if ((c & TMXR_VALID)==0) return SCPE_OK;
|
||||
c &= 0xff; /* extract character */
|
||||
} else {
|
||||
c = kbdc; /* use char polled from keyboard instead */
|
||||
if (c < SCPE_KFLAG) return c; /* ignore data if not valid */
|
||||
}
|
||||
|
||||
if (!(chip->cmd & I8251_CMD_RXE)) { /* ignore data if receiver not enabled */
|
||||
chip->status &= ~I8251_ST_RXRDY;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* got char */
|
||||
if (c & SCPE_BREAK) { /* a break? */
|
||||
c = 0;
|
||||
chip->status |= I8251_ST_SYNBRK;
|
||||
} else
|
||||
chip->status &= ~I8251_ST_SYNBRK;
|
||||
tmxr_poll_rx(&mux->desc); /* poll for input */
|
||||
if (!tmxr_rqln(&mux->ldsc)) return SCPE_OK;
|
||||
/* input ready */
|
||||
c = tmxr_getc_ln(&mux->ldsc);
|
||||
if ((c & TMXR_VALID)==0) return SCPE_OK;
|
||||
c &= 0xff; /* extract character */
|
||||
} else {
|
||||
c = kbdc; /* use char polled from keyboard instead */
|
||||
if (c < SCPE_KFLAG) return c; /* ignore data if not valid */
|
||||
}
|
||||
|
||||
if (!(chip->cmd & I8251_CMD_RXE)) { /* ignore data if receiver not enabled */
|
||||
chip->status &= ~I8251_ST_RXRDY;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* got char */
|
||||
if (c & SCPE_BREAK) { /* a break? */
|
||||
c = 0;
|
||||
chip->status |= I8251_ST_SYNBRK;
|
||||
} else
|
||||
chip->status &= ~I8251_ST_SYNBRK;
|
||||
|
||||
/* TODO? sim_tt_icvt */
|
||||
chip->ibuf = c & chip->bitmask;
|
||||
if (chip->status & I8251_ST_RXRDY)
|
||||
chip->status |= I8251_ST_OE;
|
||||
chip->status |= I8251_ST_RXRDY;
|
||||
return cons_rxint(chip);
|
||||
/* TODO? sim_tt_icvt */
|
||||
chip->ibuf = c & chip->bitmask;
|
||||
if (chip->status & I8251_ST_RXRDY)
|
||||
chip->status |= I8251_ST_OE;
|
||||
chip->status |= I8251_ST_RXRDY;
|
||||
return cons_rxint(chip);
|
||||
}
|
||||
|
||||
static t_stat consterm_svc(UNIT* uptr)
|
||||
{
|
||||
DEVICE* dptr = find_dev_from_unit(uptr);
|
||||
I8251* chip = (I8251*)dptr->ctxt;
|
||||
SERMUX* mux = chip->mux;
|
||||
t_stat rc;
|
||||
DEVICE* dptr = find_dev_from_unit(uptr);
|
||||
I8251* chip = (I8251*)dptr->ctxt;
|
||||
SERMUX* mux = chip->mux;
|
||||
t_stat rc;
|
||||
|
||||
int ch = chip->obuf;
|
||||
|
||||
/* suppress NUL bytes after CR LF */
|
||||
switch (ch) {
|
||||
case 0x0d:
|
||||
chip->crlf = 1; break;
|
||||
case 0x0a:
|
||||
chip->crlf = (chip->crlf==1) ? 2 : 0; break;
|
||||
case 0:
|
||||
if (chip->crlf==2) goto set_stat;
|
||||
default:
|
||||
chip->crlf = 0;
|
||||
}
|
||||
|
||||
/* TODO? sim_tt_outcvt */
|
||||
|
||||
/* attached to a telnet port? */
|
||||
if (mux->poll->flags & UNIT_ATT) {
|
||||
if ((rc=tmxr_putc_ln(&mux->ldsc, ch & chip->bitmask)) != SCPE_OK) {
|
||||
sim_activate(uptr, uptr->wait);
|
||||
return SCPE_OK;
|
||||
} else
|
||||
tmxr_poll_tx(&mux->desc);
|
||||
} else {
|
||||
/* no, use normal terminal output */
|
||||
if ((rc=sim_putchar_s(ch & chip->bitmask)) != SCPE_OK) {
|
||||
sim_activate(uptr, uptr->wait);
|
||||
return rc==SCPE_STALL ? SCPE_OK : rc;
|
||||
}
|
||||
}
|
||||
int ch = chip->obuf;
|
||||
|
||||
/* suppress NUL bytes after CR LF */
|
||||
switch (ch) {
|
||||
case 0x0d:
|
||||
chip->crlf = 1; break;
|
||||
case 0x0a:
|
||||
chip->crlf = (chip->crlf==1) ? 2 : 0; break;
|
||||
case 0:
|
||||
if (chip->crlf==2) goto set_stat;
|
||||
default:
|
||||
chip->crlf = 0;
|
||||
}
|
||||
|
||||
/* TODO? sim_tt_outcvt */
|
||||
|
||||
/* attached to a telnet port? */
|
||||
if (mux->poll->flags & UNIT_ATT) {
|
||||
if ((rc=tmxr_putc_ln(&mux->ldsc, ch & chip->bitmask)) != SCPE_OK) {
|
||||
sim_activate(uptr, uptr->wait);
|
||||
return SCPE_OK;
|
||||
} else
|
||||
tmxr_poll_tx(&mux->desc);
|
||||
} else {
|
||||
/* no, use normal terminal output */
|
||||
if ((rc=sim_putchar_s(ch & chip->bitmask)) != SCPE_OK) {
|
||||
sim_activate(uptr, uptr->wait);
|
||||
return rc==SCPE_STALL ? SCPE_OK : rc;
|
||||
}
|
||||
}
|
||||
set_stat:
|
||||
chip->status |= I8251_ST_TXEMPTY;
|
||||
if (chip->cmd & I8251_CMD_TXEN) {
|
||||
chip->status |= I8251_ST_TXRDY;
|
||||
return cons_txint(chip);
|
||||
}
|
||||
chip->status &= ~I8251_ST_TXRDY;
|
||||
return SCPE_OK;
|
||||
chip->status |= I8251_ST_TXEMPTY;
|
||||
if (chip->cmd & I8251_CMD_TXEN) {
|
||||
chip->status |= I8251_ST_TXRDY;
|
||||
return cons_txint(chip);
|
||||
}
|
||||
chip->status &= ~I8251_ST_TXRDY;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
static t_stat cons_txint(I8251* chip)
|
||||
{
|
||||
TRACE_PRINT0(DBG_UART_IRQ,"Raise TX Interrupt");
|
||||
return sage_raiseint(CONSTX_PICINT);
|
||||
TRACE_PRINT0(DBG_UART_IRQ,"Raise TX Interrupt");
|
||||
return sage_raiseint(CONSTX_PICINT);
|
||||
}
|
||||
|
||||
static t_stat cons_rxint(I8251* chip)
|
||||
{
|
||||
TRACE_PRINT0(DBG_UART_IRQ,"Raise RX Interrupt");
|
||||
return m68k_raise_autoint(CONSRX_AUTOINT);
|
||||
TRACE_PRINT0(DBG_UART_IRQ,"Raise RX Interrupt");
|
||||
return m68k_raise_autoint(CONSRX_AUTOINT);
|
||||
}
|
||||
|
||||
static t_stat cons_attach(UNIT* uptr,char* cptr)
|
||||
{
|
||||
return mux_attach(uptr,cptr,&cons_mux);
|
||||
return mux_attach(uptr,cptr,&cons_mux);
|
||||
}
|
||||
|
||||
static t_stat cons_detach(UNIT* uptr)
|
||||
{
|
||||
return mux_detach(uptr,&cons_mux);
|
||||
return mux_detach(uptr,&cons_mux);
|
||||
}
|
||||
|
||||
t_stat mux_attach(UNIT* uptr, char* cptr, SERMUX* mux)
|
||||
{
|
||||
t_stat rc;
|
||||
t_stat rc;
|
||||
|
||||
mux->desc.ldsc = &mux->ldsc;
|
||||
if ((rc = tmxr_attach(&mux->desc, uptr, cptr)) == SCPE_OK) {
|
||||
mux->poll->wait = mux->pfirst;
|
||||
sim_activate(mux->poll,mux->poll->wait);
|
||||
}
|
||||
return rc;
|
||||
mux->desc.ldsc = &mux->ldsc;
|
||||
if ((rc = tmxr_attach(&mux->desc, uptr, cptr)) == SCPE_OK) {
|
||||
mux->poll->wait = mux->pfirst;
|
||||
sim_activate(mux->poll,mux->poll->wait);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
t_stat mux_detach(UNIT* uptr,SERMUX* mux)
|
||||
{
|
||||
t_stat rc = tmxr_detach(&mux->desc, uptr);
|
||||
mux->ldsc.rcve = 0;
|
||||
sim_cancel(mux->poll);
|
||||
sim_cancel(mux->term);
|
||||
return rc;
|
||||
t_stat rc = tmxr_detach(&mux->desc, uptr);
|
||||
mux->ldsc.rcve = 0;
|
||||
sim_cancel(mux->poll);
|
||||
sim_cancel(mux->term);
|
||||
return rc;
|
||||
}
|
||||
|
|
194
SAGE/sage_cpu.c
194
SAGE/sage_cpu.c
|
@ -40,8 +40,8 @@ static int rom_enable = TRUE; /* LS74 U51 in CPU schematic */
|
|||
extern int32 DR[];
|
||||
extern t_addr AR[];
|
||||
|
||||
#define UNIT_CPU_V_BIOS UNIT_CPU_V_FREE /* has custom BIOS */
|
||||
#define UNIT_CPU_BIOS (1 << UNIT_CPU_V_BIOS)
|
||||
#define UNIT_CPU_V_BIOS UNIT_CPU_V_FREE /* has custom BIOS */
|
||||
#define UNIT_CPU_BIOS (1 << UNIT_CPU_V_BIOS)
|
||||
|
||||
|
||||
#define MAX_ROMSIZE 16384
|
||||
|
@ -52,106 +52,106 @@ char* biosfile = "sage-ii.hex";
|
|||
#endif
|
||||
|
||||
static MTAB sagecpu_mod[] = {
|
||||
{ MTAB_XTD|MTAB_VDV, 0, "BIOS", "BIOS", &sagecpu_set_bios, &sagecpu_show_bios },
|
||||
M68KCPU_STDMOD,
|
||||
{ 0 }
|
||||
{ MTAB_XTD|MTAB_VDV, 0, "BIOS", "BIOS", &sagecpu_set_bios, &sagecpu_show_bios },
|
||||
M68KCPU_STDMOD,
|
||||
{ 0 }
|
||||
};
|
||||
UNIT sagecpu_unit = {
|
||||
UDATA (NULL, UNIT_FIX|UNIT_BINK|CPU_TYPE_68000|UNIT_CPU_EXC|UNIT_CPU_STOP|UNIT_CPU_PRVIO, SAGEMEM)
|
||||
UDATA (NULL, UNIT_FIX|UNIT_BINK|CPU_TYPE_68000|UNIT_CPU_EXC|UNIT_CPU_STOP|UNIT_CPU_PRVIO, SAGEMEM)
|
||||
};
|
||||
|
||||
#define DBG_CPU_OSCPM DBG_CPU_CUSTOM1
|
||||
#define DBG_CPU_OSCPM DBG_CPU_CUSTOM1
|
||||
DEBTAB sagecpu_dt[] = {
|
||||
{ "EXC", DBG_CPU_EXC },
|
||||
{ "PC", DBG_CPU_PC },
|
||||
{ "INT", DBG_CPU_INT },
|
||||
{ "CTRACE", DBG_CPU_CTRACE },
|
||||
{ "BTRACE", DBG_CPU_BTRACE },
|
||||
{ "OSCPM", DBG_CPU_OSCPM },
|
||||
{ NULL, 0 }
|
||||
{ "EXC", DBG_CPU_EXC },
|
||||
{ "PC", DBG_CPU_PC },
|
||||
{ "INT", DBG_CPU_INT },
|
||||
{ "CTRACE", DBG_CPU_CTRACE },
|
||||
{ "BTRACE", DBG_CPU_BTRACE },
|
||||
{ "OSCPM", DBG_CPU_OSCPM },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
DEVICE sagecpu_dev = {
|
||||
"CPU", &sagecpu_unit, m68kcpu_reg, sagecpu_mod,
|
||||
1, 16, 32, 2, 16, 16,
|
||||
&m68kcpu_ex, &m68kcpu_dep, &sagecpu_reset,
|
||||
&sagecpu_boot, NULL, NULL,
|
||||
NULL, DEV_DEBUG, 0,
|
||||
sagecpu_dt, NULL, NULL
|
||||
"CPU", &sagecpu_unit, m68kcpu_reg, sagecpu_mod,
|
||||
1, 16, 32, 2, 16, 16,
|
||||
&m68kcpu_ex, &m68kcpu_dep, &sagecpu_reset,
|
||||
&sagecpu_boot, NULL, NULL,
|
||||
NULL, DEV_DEBUG, 0,
|
||||
sagecpu_dt, NULL, NULL
|
||||
};
|
||||
|
||||
static t_stat sagecpu_set_bios(UNIT *uptr, int32 value, char *cptr, void *desc)
|
||||
{
|
||||
FILE* fp;
|
||||
if (cptr==NULL) return SCPE_ARG;
|
||||
if ((fp=fopen(cptr,"r"))==0) return SCPE_OPENERR;
|
||||
fclose(fp);
|
||||
|
||||
biosfile = malloc(strlen(cptr)+1);
|
||||
strcpy(biosfile,cptr);
|
||||
FILE* fp;
|
||||
if (cptr==NULL) return SCPE_ARG;
|
||||
if ((fp=fopen(cptr,"r"))==0) return SCPE_OPENERR;
|
||||
fclose(fp);
|
||||
|
||||
biosfile = malloc(strlen(cptr)+1);
|
||||
strcpy(biosfile,cptr);
|
||||
|
||||
/* enforce reload of BIOS code on next boot */
|
||||
if (ROM != 0) free(ROM);
|
||||
ROM = 0;
|
||||
return SCPE_OK;
|
||||
/* enforce reload of BIOS code on next boot */
|
||||
if (ROM != 0) free(ROM);
|
||||
ROM = 0;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
static t_stat sagecpu_show_bios(FILE *st, UNIT *uptr, int32 val, void *desc)
|
||||
{
|
||||
fprintf(st, "BIOS=%s", biosfile);
|
||||
return SCPE_OK;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat sagecpu_boot(int32 unitno,DEVICE* dptr)
|
||||
{
|
||||
t_stat rc;
|
||||
t_stat rc;
|
||||
|
||||
if (!ROM) return SCPE_IERR;
|
||||
|
||||
if (*ROM==0) {
|
||||
printf("Loading boot code from %s\n",biosfile);
|
||||
if ((rc = load_cmd(0,biosfile)) != SCPE_OK) return rc;
|
||||
}
|
||||
return m68kcpu_boot(unitno,dptr);
|
||||
if (!ROM) return SCPE_IERR;
|
||||
|
||||
if (*ROM==0) {
|
||||
printf("Loading boot code from %s\n",biosfile);
|
||||
if ((rc = load_cmd(0,biosfile)) != SCPE_OK) return rc;
|
||||
}
|
||||
return m68kcpu_boot(unitno,dptr);
|
||||
}
|
||||
|
||||
/* special logic: capture essential TRAP 8-14 for debugging */
|
||||
static void sage_trapcallback(DEVICE* dptr,int trapnum)
|
||||
{
|
||||
if ((dptr->dctrl & DBG_CPU_OSCPM) && sim_deb) {
|
||||
if (trapnum>=0x08 && trapnum<=0x0e) {
|
||||
fprintf(sim_deb,"SAGE: TRAP #%x: D0=%x A0=%x\n",trapnum,DR[0],AR[0]);
|
||||
}
|
||||
if (trapnum==2) {
|
||||
fprintf(sim_deb,"SAGE: CPM BDOS #%d D1=0x%x D2=0x%x\n",DR[0]&0xff,DR[1],DR[2]);
|
||||
}
|
||||
if (trapnum==3) {
|
||||
fprintf(sim_deb,"SAGE: CPM BIOS #%d D1=0x%x D2=0x%x\n",DR[0]&0xff,DR[1],DR[2]);
|
||||
}
|
||||
}
|
||||
if ((dptr->dctrl & DBG_CPU_OSCPM) && sim_deb) {
|
||||
if (trapnum>=0x08 && trapnum<=0x0e) {
|
||||
fprintf(sim_deb,"SAGE: TRAP #%x: D0=%x A0=%x\n",trapnum,DR[0],AR[0]);
|
||||
}
|
||||
if (trapnum==2) {
|
||||
fprintf(sim_deb,"SAGE: CPM BDOS #%d D1=0x%x D2=0x%x\n",DR[0]&0xff,DR[1],DR[2]);
|
||||
}
|
||||
if (trapnum==3) {
|
||||
fprintf(sim_deb,"SAGE: CPM BIOS #%d D1=0x%x D2=0x%x\n",DR[0]&0xff,DR[1],DR[2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static t_stat sagecpu_reset(DEVICE* dptr)
|
||||
{
|
||||
t_stat rc;
|
||||
t_stat rc;
|
||||
|
||||
/* set CPU pointers */
|
||||
m68kcpu_dev = &sagecpu_dev;
|
||||
m68kcpu_unit = &sagecpu_unit;
|
||||
|
||||
/* redefine memory handlers */
|
||||
TranslateAddr = &sage_translateaddr;
|
||||
Mem = &sage_mem;
|
||||
/* set CPU pointers */
|
||||
m68kcpu_dev = &sagecpu_dev;
|
||||
m68kcpu_unit = &sagecpu_unit;
|
||||
|
||||
if (!ROM) ROM = (uint8*)calloc(MAX_ROMSIZE,1);
|
||||
rom_enable = TRUE;
|
||||
|
||||
if ((rc=m68kcpu_reset(dptr)) != SCPE_OK) return rc;
|
||||
|
||||
/* redirect callbacks */
|
||||
m68kcpu_trapcallback = &sage_trapcallback;
|
||||
|
||||
return SCPE_OK;
|
||||
/* redefine memory handlers */
|
||||
TranslateAddr = &sage_translateaddr;
|
||||
Mem = &sage_mem;
|
||||
|
||||
if (!ROM) ROM = (uint8*)calloc(MAX_ROMSIZE,1);
|
||||
rom_enable = TRUE;
|
||||
|
||||
if ((rc=m68kcpu_reset(dptr)) != SCPE_OK) return rc;
|
||||
|
||||
/* redirect callbacks */
|
||||
m68kcpu_trapcallback = &sage_trapcallback;
|
||||
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
uint8 ioemul[4] = { 0,0,0,0 };
|
||||
|
@ -159,37 +159,37 @@ uint8 ioemul[4] = { 0,0,0,0 };
|
|||
/* sage memory */
|
||||
static t_stat sage_mem(t_addr addr,uint8** mem)
|
||||
{
|
||||
t_addr a;
|
||||
// printf("Try to access %x\n",addr); fflush(stdout);
|
||||
if (rom_enable && (addr < MAX_ROMSIZE)) { /* boot rom mapped to zero page */
|
||||
*mem = ROM+addr;
|
||||
return SCPE_OK;
|
||||
}
|
||||
a = addr - 0xfe0000; /* boot rom at normal ROM page */
|
||||
if (a < MAX_ROMSIZE) {
|
||||
rom_enable = FALSE;
|
||||
*mem = ROM+a;
|
||||
return SCPE_OK;
|
||||
}
|
||||
a = addr - 0xffc0fe;
|
||||
if (a < 2) { /* boot rom diagnostic address: black hole */
|
||||
ioemul[0] = ioemul[1] = 0;
|
||||
*mem = ioemul+a;
|
||||
return SCPE_OK;
|
||||
}
|
||||
a = addr - 0xff0000;
|
||||
if (a < 0x10000) {
|
||||
*mem = ioemul;
|
||||
return SCPE_OK;
|
||||
}
|
||||
if (addr > MEMORYSIZE) return SIM_NOMEM;
|
||||
return m68k_mem(addr,mem);
|
||||
t_addr a;
|
||||
// printf("Try to access %x\n",addr); fflush(stdout);
|
||||
if (rom_enable && (addr < MAX_ROMSIZE)) { /* boot rom mapped to zero page */
|
||||
*mem = ROM+addr;
|
||||
return SCPE_OK;
|
||||
}
|
||||
a = addr - 0xfe0000; /* boot rom at normal ROM page */
|
||||
if (a < MAX_ROMSIZE) {
|
||||
rom_enable = FALSE;
|
||||
*mem = ROM+a;
|
||||
return SCPE_OK;
|
||||
}
|
||||
a = addr - 0xffc0fe;
|
||||
if (a < 2) { /* boot rom diagnostic address: black hole */
|
||||
ioemul[0] = ioemul[1] = 0;
|
||||
*mem = ioemul+a;
|
||||
return SCPE_OK;
|
||||
}
|
||||
a = addr - 0xff0000;
|
||||
if (a < 0x10000) {
|
||||
*mem = ioemul;
|
||||
return SCPE_OK;
|
||||
}
|
||||
if (addr > MEMORYSIZE) return SIM_NOMEM;
|
||||
return m68k_mem(addr,mem);
|
||||
}
|
||||
|
||||
t_stat sage_translateaddr(t_addr in,t_addr* out, IOHANDLER** ioh,int rw,int fc,int dma)
|
||||
{
|
||||
static uint32 bptype[] = { R_BKPT_SPC|SWMASK('R'), W_BKPT_SPC|SWMASK('W') };
|
||||
t_addr ma = in & addrmask;
|
||||
if (sim_brk_summ && sim_brk_test(ma, bptype[rw])) return STOP_IBKPT;
|
||||
return m68k_translateaddr(in,out,ioh,rw,fc,dma);
|
||||
static uint32 bptype[] = { R_BKPT_SPC|SWMASK('R'), W_BKPT_SPC|SWMASK('W') };
|
||||
t_addr ma = in & addrmask;
|
||||
if (sim_brk_summ && sim_brk_test(ma, bptype[rw])) return STOP_IBKPT;
|
||||
return m68k_translateaddr(in,out,ioh,rw,fc,dma);
|
||||
}
|
||||
|
|
146
SAGE/sage_defs.h
146
SAGE/sage_defs.h
|
@ -34,116 +34,116 @@
|
|||
#include "m68k_cpu.h"
|
||||
|
||||
/* don't define this yet, won't work */
|
||||
#undef SAGE_IV
|
||||
#undef SAGE_IV
|
||||
|
||||
#define UNIT_CPU_V_ROM UNIT_CPU_V_FREE /* has switchable ROM */
|
||||
#define UNIT_CPU_ROM (1 << UNIT_CPU_V_ROM)
|
||||
#define UNIT_CPU_V_ROM UNIT_CPU_V_FREE /* has switchable ROM */
|
||||
#define UNIT_CPU_ROM (1 << UNIT_CPU_V_ROM)
|
||||
|
||||
#define SAGEMEM (128*1024)
|
||||
#define SAGEMEM (128*1024)
|
||||
|
||||
#define ROMBASE 0xfe0000 /* base address of ROM */
|
||||
#define ROMBASE 0xfe0000 /* base address of ROM */
|
||||
#ifdef SAGE_IV
|
||||
#define ROMSIZE 0x004000 /* size of ROM (4K words) */
|
||||
#define ROMSIZE 0x004000 /* size of ROM (4K words) */
|
||||
#else
|
||||
#define ROMSIZE 0x002000 /* size of ROM (4K words) */
|
||||
#define ROMSIZE 0x002000 /* size of ROM (4K words) */
|
||||
#endif
|
||||
|
||||
/* simh timers */
|
||||
#define TMR_RTC1 0
|
||||
#define TMR_RTC2 1
|
||||
#define TMR_CONS 2
|
||||
#define TMR_INT 3
|
||||
#define TMR_RTC1 0
|
||||
#define TMR_RTC2 1
|
||||
#define TMR_CONS 2
|
||||
#define TMR_INT 3
|
||||
|
||||
/* definitions for certain chips */
|
||||
#include "chip_defs.h"
|
||||
|
||||
/* PIC base address */
|
||||
#define U73_ADDR 0xffc041
|
||||
extern t_stat sage_raiseint(int level); /* sage specific interrupt handler */
|
||||
#define U73_ADDR 0xffc041
|
||||
extern t_stat sage_raiseint(int level); /* sage specific interrupt handler */
|
||||
|
||||
/* 8255 for dip switches and floppy control */
|
||||
#define U22_ADDR 0xffc021
|
||||
extern uint32 *u22_portc; /* exposed for use by FD device */
|
||||
#define U22C_FRES 0x80
|
||||
#define U22C_PCRMP 0x40
|
||||
#define U22C_MOT 0x20
|
||||
#define U22C_SL1 0x10
|
||||
#define U22C_SL0 0x08
|
||||
#define U22C_FDIE 0x04
|
||||
#define U22C_RDY 0x02
|
||||
#define U22C_TC 0x01
|
||||
#define U22_ADDR 0xffc021
|
||||
extern uint32 *u22_portc; /* exposed for use by FD device */
|
||||
#define U22C_FRES 0x80
|
||||
#define U22C_PCRMP 0x40
|
||||
#define U22C_MOT 0x20
|
||||
#define U22C_SL1 0x10
|
||||
#define U22C_SL0 0x08
|
||||
#define U22C_FDIE 0x04
|
||||
#define U22C_RDY 0x02
|
||||
#define U22C_TC 0x01
|
||||
|
||||
/* 8253 timer units */
|
||||
#define U75_ADDR 0xffc001
|
||||
#define U74_ADDR 0xffc081
|
||||
#define U75_ADDR 0xffc001
|
||||
#define U74_ADDR 0xffc081
|
||||
#define TIMER2C0_PICINT 6
|
||||
#define TIMER2C2_PICINT 0
|
||||
|
||||
/* FDC */
|
||||
#define U21_ADDR 0xffc051
|
||||
#define U21_ADDR 0xffc051
|
||||
extern I8272 u21;
|
||||
#define FDC_AUTOINT 6
|
||||
#define FDC_AUTOINT 6
|
||||
|
||||
/* LP port */
|
||||
#define U39_ADDR 0xffc061
|
||||
#define LP_PICINT 5
|
||||
#define SI_PICINT 7
|
||||
#define U39_ADDR 0xffc061
|
||||
#define LP_PICINT 5
|
||||
#define SI_PICINT 7
|
||||
|
||||
#define U39B_FDI 0x01
|
||||
#define U39B_WP 0x02
|
||||
#define U39B_RG 0x04
|
||||
#define U39B_CD 0x08
|
||||
#define U39B_BUSY 0x10
|
||||
#define U39B_PAPER 0x20
|
||||
#define U39B_SEL 0x40
|
||||
#define U39B_FAULT 0x80
|
||||
#define U39C_PRES 0x01
|
||||
#define U39C_SC 0x02
|
||||
#define U39C_SI 0x04
|
||||
#define U39C_LEDR 0x08
|
||||
#define U39C_STROBE 0x10
|
||||
#define U39C_PRIME 0x20
|
||||
#define U39C_RCNI 0x40
|
||||
#define U39C_RMI 0x80
|
||||
#define U39B_FDI 0x01
|
||||
#define U39B_WP 0x02
|
||||
#define U39B_RG 0x04
|
||||
#define U39B_CD 0x08
|
||||
#define U39B_BUSY 0x10
|
||||
#define U39B_PAPER 0x20
|
||||
#define U39B_SEL 0x40
|
||||
#define U39B_FAULT 0x80
|
||||
#define U39C_PRES 0x01
|
||||
#define U39C_SC 0x02
|
||||
#define U39C_SI 0x04
|
||||
#define U39C_LEDR 0x08
|
||||
#define U39C_STROBE 0x10
|
||||
#define U39C_PRIME 0x20
|
||||
#define U39C_RCNI 0x40
|
||||
#define U39C_RMI 0x80
|
||||
|
||||
|
||||
/* SIO port */
|
||||
#define U58_ADDR 0xffc031
|
||||
#define SIORX_PICINT 1
|
||||
#define SIOTX_PICINT 3
|
||||
#define U58_ADDR 0xffc031
|
||||
#define SIORX_PICINT 1
|
||||
#define SIOTX_PICINT 3
|
||||
|
||||
/* CONS port */
|
||||
#define U57_ADDR 0xffc071
|
||||
#define CONSRX_AUTOINT 5
|
||||
#define CONSTX_PICINT 2
|
||||
#define U57_ADDR 0xffc071
|
||||
#define CONSRX_AUTOINT 5
|
||||
#define CONSTX_PICINT 2
|
||||
|
||||
/* unimplemented */
|
||||
#define IEEEBASE 0xffc011 /* IEEE-488 interface (TMS9914) */
|
||||
#define IEEEBASE 0xffc011 /* IEEE-488 interface (TMS9914) */
|
||||
|
||||
/* winchester board: not yet */
|
||||
#define S2651d 0xffc401 /* aux serial 4 */
|
||||
#define S2651d_DATA (S2651d+0) /* RW data port aux 4 */
|
||||
#define S2651d_STATUS (S2651d+2) /* R status aux 4 */
|
||||
#define S2651d_MODE (S2651d+4) /* W mode aux 4 */
|
||||
#define S2651d_CTRL (S2651d+6) /* W mode aux 4 */
|
||||
#define S2651d 0xffc401 /* aux serial 4 */
|
||||
#define S2651d_DATA (S2651d+0) /* RW data port aux 4 */
|
||||
#define S2651d_STATUS (S2651d+2) /* R status aux 4 */
|
||||
#define S2651d_MODE (S2651d+4) /* W mode aux 4 */
|
||||
#define S2651d_CTRL (S2651d+6) /* W mode aux 4 */
|
||||
|
||||
#define S2651c 0xffc441 /* aux serial 3 */
|
||||
#define S2651c_DATA (S2651c+0) /* RW data port aux 3 */
|
||||
#define S2651c_STATUS (S2651c+2) /* R status aux 3 */
|
||||
#define S2651c_MODE (S2651c+4) /* W mode aux 3 */
|
||||
#define S2651c_CTRL (S2651c+6) /* W mode aux 3 */
|
||||
#define S2651c 0xffc441 /* aux serial 3 */
|
||||
#define S2651c_DATA (S2651c+0) /* RW data port aux 3 */
|
||||
#define S2651c_STATUS (S2651c+2) /* R status aux 3 */
|
||||
#define S2651c_MODE (S2651c+4) /* W mode aux 3 */
|
||||
#define S2651c_CTRL (S2651c+6) /* W mode aux 3 */
|
||||
|
||||
#define S2651b 0xffc481 /* aux serial 2 */
|
||||
#define S2651b_DATA (S2651b+0) /* RW data port aux 2 */
|
||||
#define S2651b_STATUS (S2651b+2) /* R status aux 2 */
|
||||
#define S2651b_MODE (S2651b+4) /* W mode aux 2 */
|
||||
#define S2651b_CTRL (S2651b+6) /* W mode aux 2 */
|
||||
#define S2651b 0xffc481 /* aux serial 2 */
|
||||
#define S2651b_DATA (S2651b+0) /* RW data port aux 2 */
|
||||
#define S2651b_STATUS (S2651b+2) /* R status aux 2 */
|
||||
#define S2651b_MODE (S2651b+4) /* W mode aux 2 */
|
||||
#define S2651b_CTRL (S2651b+6) /* W mode aux 2 */
|
||||
|
||||
#define S2651a 0xff4c1 /* aux serial 1 */
|
||||
#define S2651a_DATA (S2651a+0) /* RW data port aux 1 */
|
||||
#define S2651a_STATUS (S2651a+2) /* R status aux 1 */
|
||||
#define S2651a_MODE (S2651a+4) /* W mode aux 1 */
|
||||
#define S2651a_CTRL (S2651a+6) /* W mode aux 1 */
|
||||
#define S2651a 0xff4c1 /* aux serial 1 */
|
||||
#define S2651a_DATA (S2651a+0) /* RW data port aux 1 */
|
||||
#define S2651a_STATUS (S2651a+2) /* R status aux 1 */
|
||||
#define S2651a_MODE (S2651a+4) /* W mode aux 1 */
|
||||
#define S2651a_CTRL (S2651a+6) /* W mode aux 1 */
|
||||
|
||||
/* must be included at the end */
|
||||
#include "m68k_cpu.h"
|
||||
|
|
|
@ -37,9 +37,9 @@ static t_stat fdcint_svc(UNIT*);
|
|||
|
||||
/* this is the FDC chip */
|
||||
I8272 u21 = {
|
||||
{ 0, 0, U21_ADDR, 4, 2 },
|
||||
&sagefd_dev,
|
||||
NULL, NULL, &i8272_reset, &sagefd_seldrv, &sagefd_interrupt
|
||||
{ 0, 0, U21_ADDR, 4, 2 },
|
||||
&sagefd_dev,
|
||||
NULL, NULL, &i8272_reset, &sagefd_seldrv, &sagefd_interrupt
|
||||
};
|
||||
|
||||
UNIT sagefd_unit[] = {
|
||||
|
@ -48,11 +48,11 @@ UNIT sagefd_unit[] = {
|
|||
};
|
||||
|
||||
REG sagefd_reg[] = {
|
||||
{ NULL }
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
static MTAB sagefd_mod[] = {
|
||||
{ MTAB_XTD|MTAB_VDV, 0, "IO", "IO", &set_iobase, &show_iobase, NULL },
|
||||
{ MTAB_XTD|MTAB_VDV, 0, "IO", "IO", &set_iobase, &show_iobase, NULL },
|
||||
{ UNIT_I8272_WLK, 0, "WRTENB", "WRTENB", NULL },
|
||||
{ UNIT_I8272_WLK, UNIT_I8272_WLK, "WRTLCK", "WRTLCK", NULL },
|
||||
{ UNIT_I8272_VERBOSE, 0, "QUIET", "QUIET", NULL },
|
||||
|
@ -61,71 +61,71 @@ static MTAB sagefd_mod[] = {
|
|||
};
|
||||
|
||||
DEVICE sagefd_dev = {
|
||||
"FD", sagefd_unit, sagefd_reg, sagefd_mod,
|
||||
2, 16, 32, 2, 16, 16,
|
||||
NULL, NULL, &sagefd_reset,
|
||||
&sagefd_boot, &i8272_attach, &i8272_detach,
|
||||
&u21, (DEV_DISABLE|DEV_DEBUG), 0,
|
||||
i8272_dt, NULL, NULL
|
||||
"FD", sagefd_unit, sagefd_reg, sagefd_mod,
|
||||
2, 16, 32, 2, 16, 16,
|
||||
NULL, NULL, &sagefd_reset,
|
||||
&sagefd_boot, &i8272_attach, &i8272_detach,
|
||||
&u21, (DEV_DISABLE|DEV_DEBUG), 0,
|
||||
i8272_dt, NULL, NULL
|
||||
};
|
||||
|
||||
static void sagefd_seldrv(I8272* chip,int drvnum)
|
||||
{
|
||||
/* this routine defeats the standard drive select in i8272.c
|
||||
* which interprets the US0/US1 bits of various commands.
|
||||
* Sage uses 8255 portc bits for that, and always leaves
|
||||
* US0/US1 = 0, despite which drive is selected.
|
||||
* The actual code to select drives is in sage_stddev.c in u22callc()
|
||||
*/
|
||||
return;
|
||||
/* this routine defeats the standard drive select in i8272.c
|
||||
* which interprets the US0/US1 bits of various commands.
|
||||
* Sage uses 8255 portc bits for that, and always leaves
|
||||
* US0/US1 = 0, despite which drive is selected.
|
||||
* The actual code to select drives is in sage_stddev.c in u22callc()
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
static t_stat sagefd_reset(DEVICE* dptr)
|
||||
{
|
||||
t_stat rc;
|
||||
I8272* chip = (I8272*)dptr->ctxt;
|
||||
t_stat rc;
|
||||
I8272* chip = (I8272*)dptr->ctxt;
|
||||
|
||||
/* fixup device link */
|
||||
i8272_dev = dptr;
|
||||
|
||||
/* fixup device link */
|
||||
i8272_dev = dptr;
|
||||
|
||||
rc = (dptr->flags & DEV_DIS) ? /* Disconnect I/O Ports */
|
||||
del_iohandler((void*)chip) :
|
||||
add_iohandler(&sagefd_unit[0],(void*)chip,i8272_io);
|
||||
del_iohandler((void*)chip) :
|
||||
add_iohandler(&sagefd_unit[0],(void*)chip,i8272_io);
|
||||
if (rc != SCPE_OK) return rc;
|
||||
return (*chip->reset)(chip);
|
||||
return (*chip->reset)(chip);
|
||||
}
|
||||
|
||||
static t_stat fdcint_svc(UNIT* unit)
|
||||
{
|
||||
#if DBG_MSG==1
|
||||
I8272* chip;
|
||||
DEVICE* dptr;
|
||||
I8272* chip;
|
||||
DEVICE* dptr;
|
||||
if (!unit) return -1;
|
||||
dptr = find_dev_from_unit(unit);
|
||||
if (!dptr) return -1;
|
||||
chip = (I8272*)dptr->ctxt;
|
||||
if (!dptr) return -1;
|
||||
chip = (I8272*)dptr->ctxt;
|
||||
#endif
|
||||
if (*u22_portc & U22C_FDIE) {
|
||||
TRACE_PRINT0(DBG_FD_IRQ,"FDCINT_SVC: deliver interrupt");
|
||||
m68k_raise_autoint(FDC_AUTOINT);
|
||||
|
||||
} else {
|
||||
TRACE_PRINT0(DBG_FD_IRQ,"FDCINT_SVC: int not granted");
|
||||
}
|
||||
return SCPE_OK;
|
||||
if (*u22_portc & U22C_FDIE) {
|
||||
TRACE_PRINT0(DBG_FD_IRQ,"FDCINT_SVC: deliver interrupt");
|
||||
m68k_raise_autoint(FDC_AUTOINT);
|
||||
|
||||
} else {
|
||||
TRACE_PRINT0(DBG_FD_IRQ,"FDCINT_SVC: int not granted");
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
|
||||
static t_stat sagefd_boot(int32 unit_num,DEVICE* dptr)
|
||||
{
|
||||
printf("sagefd_boot\n");
|
||||
return SCPE_OK;
|
||||
printf("sagefd_boot\n");
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
static void sagefd_interrupt(I8272* chip,int delay)
|
||||
{
|
||||
TRACE_PRINT0(DBG_FD_IRQ,"SAGEFD_INT: request interrupt");
|
||||
sim_activate(&sagefd_unit[0],delay);
|
||||
TRACE_PRINT0(DBG_FD_IRQ,"SAGEFD_INT: request interrupt");
|
||||
sim_activate(&sagefd_unit[0],delay);
|
||||
}
|
||||
|
||||
/* dummy routines for i8272 - sage does not use DMA */
|
||||
|
@ -135,5 +135,5 @@ void PutByteDMA(uint32 addr, uint8 data)
|
|||
|
||||
uint8 GetByteDMA(uint32 addr)
|
||||
{
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -35,50 +35,50 @@ static t_stat sagehd_detach(UNIT* uptr);
|
|||
|
||||
|
||||
UNIT sagehd_unit[] = {
|
||||
{ UDATA (NULL, UNIT_FIX | UNIT_BINK | UNIT_DISABLE | UNIT_ROABLE, 0) },
|
||||
{ UDATA (NULL, UNIT_FIX | UNIT_BINK | UNIT_DISABLE | UNIT_DIS | UNIT_ROABLE, 0) },
|
||||
{ UDATA (NULL, UNIT_FIX | UNIT_BINK | UNIT_DISABLE | UNIT_DIS | UNIT_ROABLE, 0) },
|
||||
{ UDATA (NULL, UNIT_FIX | UNIT_BINK | UNIT_DISABLE | UNIT_DIS | UNIT_ROABLE, 0) }
|
||||
{ UDATA (NULL, UNIT_FIX | UNIT_BINK | UNIT_DISABLE | UNIT_ROABLE, 0) },
|
||||
{ UDATA (NULL, UNIT_FIX | UNIT_BINK | UNIT_DISABLE | UNIT_DIS | UNIT_ROABLE, 0) },
|
||||
{ UDATA (NULL, UNIT_FIX | UNIT_BINK | UNIT_DISABLE | UNIT_DIS | UNIT_ROABLE, 0) },
|
||||
{ UDATA (NULL, UNIT_FIX | UNIT_BINK | UNIT_DISABLE | UNIT_DIS | UNIT_ROABLE, 0) }
|
||||
};
|
||||
|
||||
REG sagehd_reg[] = {
|
||||
{ NULL }
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
/*
|
||||
static MTAB sagehd_mod[] = {
|
||||
{ NULL }
|
||||
{ NULL }
|
||||
};
|
||||
*/
|
||||
DEVICE sagehd_dev = {
|
||||
"HD", sagehd_unit, sagehd_reg, /*sagehd_mod*/NULL,
|
||||
4, 16, 32, 2, 16, 16,
|
||||
NULL, NULL, &sagehd_reset,
|
||||
&sagehd_boot, &sagehd_attach, &sagehd_detach,
|
||||
NULL, DEV_DISABLE|DEV_DIS, 0,
|
||||
NULL, NULL, NULL
|
||||
"HD", sagehd_unit, sagehd_reg, /*sagehd_mod*/NULL,
|
||||
4, 16, 32, 2, 16, 16,
|
||||
NULL, NULL, &sagehd_reset,
|
||||
&sagehd_boot, &sagehd_attach, &sagehd_detach,
|
||||
NULL, DEV_DISABLE|DEV_DIS, 0,
|
||||
NULL, NULL, NULL
|
||||
};
|
||||
|
||||
static t_stat sagehd_reset(DEVICE* dptr)
|
||||
{
|
||||
printf("sagehd_reset\n");
|
||||
return SCPE_OK;
|
||||
printf("sagehd_reset\n");
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
static t_stat sagehd_boot(int32 unit_num,DEVICE* dptr)
|
||||
{
|
||||
printf("sagehd_boot\n");
|
||||
return SCPE_OK;
|
||||
printf("sagehd_boot\n");
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
static t_stat sagehd_attach(UNIT* uptr, char* file)
|
||||
{
|
||||
printf("sagehd_attach\n");
|
||||
return SCPE_OK;
|
||||
printf("sagehd_attach\n");
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
static t_stat sagehd_detach(UNIT* uptr)
|
||||
{
|
||||
printf("sagehd_detach\n");
|
||||
return SCPE_OK;
|
||||
printf("sagehd_detach\n");
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
|
|
@ -33,30 +33,30 @@
|
|||
static t_stat sageieee_reset(DEVICE* dptr);
|
||||
|
||||
UNIT sageieee_unit = {
|
||||
UDATA (NULL, UNIT_FIX | UNIT_BINK, 0)
|
||||
UDATA (NULL, UNIT_FIX | UNIT_BINK, 0)
|
||||
};
|
||||
|
||||
REG sageieee_reg[] = {
|
||||
{ NULL }
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
static MTAB sageieee_mod[] = {
|
||||
{ 0 }
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
DEVICE sageieee_dev = {
|
||||
"IEEE", &sageieee_unit, sageieee_reg, sageieee_mod,
|
||||
1, 16, 32, 2, 16, 16,
|
||||
NULL, NULL, &sageieee_reset,
|
||||
NULL, NULL, NULL,
|
||||
NULL, DEV_DISABLE|DEV_DIS, 0,
|
||||
NULL, NULL, NULL
|
||||
"IEEE", &sageieee_unit, sageieee_reg, sageieee_mod,
|
||||
1, 16, 32, 2, 16, 16,
|
||||
NULL, NULL, &sageieee_reset,
|
||||
NULL, NULL, NULL,
|
||||
NULL, DEV_DISABLE|DEV_DIS, 0,
|
||||
NULL, NULL, NULL
|
||||
};
|
||||
|
||||
static t_stat sageieee_reset(DEVICE* dptr)
|
||||
{
|
||||
printf("sageieee_reset\n");
|
||||
return SCPE_OK;
|
||||
printf("sageieee_reset\n");
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
234
SAGE/sage_lp.c
234
SAGE/sage_lp.c
|
@ -66,58 +66,58 @@ extern DEVICE sagelp_dev;
|
|||
*/
|
||||
|
||||
static I8255 u39 = {
|
||||
{ 0,0,U39_ADDR,8,2},
|
||||
&sagelp_dev,
|
||||
i8255_write,i8255_read,u39_reset,u39_calla,u39_callb,u39_callc,u39_ckmode
|
||||
{ 0,0,U39_ADDR,8,2},
|
||||
&sagelp_dev,
|
||||
i8255_write,i8255_read,u39_reset,u39_calla,u39_callb,u39_callc,u39_ckmode
|
||||
};
|
||||
|
||||
UNIT sagelp_unit = {
|
||||
UDATA (NULL, UNIT_SEQ|UNIT_ATTABLE|UNIT_TEXT, 0), SERIAL_OUT_WAIT
|
||||
UDATA (NULL, UNIT_SEQ|UNIT_ATTABLE|UNIT_TEXT, 0), SERIAL_OUT_WAIT
|
||||
};
|
||||
|
||||
REG sagelp_reg[] = {
|
||||
{ HRDATA(PORTA, u39.porta, 8) },
|
||||
{ HRDATA(PORTB, u39.portb, 8) },
|
||||
{ HRDATA(PORTC, u39.portc, 8) },
|
||||
{ HRDATA(CTRL, u39.ctrl, 8) },
|
||||
{ HRDATA(PORTA, u39.porta, 8) },
|
||||
{ HRDATA(PORTB, u39.portb, 8) },
|
||||
{ HRDATA(PORTC, u39.portc, 8) },
|
||||
{ HRDATA(CTRL, u39.ctrl, 8) },
|
||||
{ GRDATA (BUF, sagelp_unit.buf, 16, 8, 0) },
|
||||
{ DRDATA (POS, sagelp_unit.pos, T_ADDR_W), PV_LEFT },
|
||||
{ NULL }
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
static MTAB sagelp_mod[] = {
|
||||
{ MTAB_XTD|MTAB_VDV, 0, "IO", "IO", &set_iobase, &show_iobase, NULL },
|
||||
{ UNIT_OFFLINE, UNIT_OFFLINE, "offline", "OFFLINE", NULL },
|
||||
{ UNIT_OFFLINE, 0, "online", "ONLINE", NULL },
|
||||
{ 0 }
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
DEBTAB sagelp_dt[] = {
|
||||
{ "WRA", DBG_PP_WRA },
|
||||
{ "RDB", DBG_PP_RDB },
|
||||
{ "RDC", DBG_PP_RDC },
|
||||
{ "WRC", DBG_PP_WRC },
|
||||
{ "WRMODE", DBG_PP_MODE },
|
||||
{ NULL, 0 }
|
||||
{ "WRA", DBG_PP_WRA },
|
||||
{ "RDB", DBG_PP_RDB },
|
||||
{ "RDC", DBG_PP_RDC },
|
||||
{ "WRC", DBG_PP_WRC },
|
||||
{ "WRMODE", DBG_PP_MODE },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
DEVICE sagelp_dev = {
|
||||
"LP", &sagelp_unit, sagelp_reg, sagelp_mod,
|
||||
1, 16, 32, 2, 16, 16,
|
||||
NULL, NULL, &sagelp_reset,
|
||||
NULL, &sagelp_attach, &sagelp_detach,
|
||||
&u39, (DEV_DISABLE|DEV_DEBUG), 0,
|
||||
sagelp_dt, NULL, NULL
|
||||
"LP", &sagelp_unit, sagelp_reg, sagelp_mod,
|
||||
1, 16, 32, 2, 16, 16,
|
||||
NULL, NULL, &sagelp_reset,
|
||||
NULL, &sagelp_attach, &sagelp_detach,
|
||||
&u39, (DEV_DISABLE|DEV_DEBUG), 0,
|
||||
sagelp_dt, NULL, NULL
|
||||
};
|
||||
|
||||
t_stat sagelp_reset(DEVICE* dptr)
|
||||
{
|
||||
t_stat rc;
|
||||
t_stat rc;
|
||||
if ((rc = (dptr->flags & DEV_DIS) ? /* Disconnect I/O Ports */
|
||||
del_iohandler(dptr->ctxt) :
|
||||
add_iohandler(&sagelp_unit,dptr->ctxt,i8255_io)) != SCPE_OK) return rc;
|
||||
|
||||
return u39.reset(&u39);
|
||||
del_iohandler(dptr->ctxt) :
|
||||
add_iohandler(&sagelp_unit,dptr->ctxt,i8255_io)) != SCPE_OK) return rc;
|
||||
|
||||
return u39.reset(&u39);
|
||||
}
|
||||
|
||||
/* we don't accept any mode and combination that a 8255 can do, because
|
||||
|
@ -126,122 +126,122 @@ t_stat sagelp_reset(DEVICE* dptr)
|
|||
|
||||
static t_stat u39_calla(I8255* chip, int rw)
|
||||
{
|
||||
if (rw) {
|
||||
sagelp_unit.buf = chip->porta;
|
||||
TRACE_PRINT1(DBG_PP_WRA,"WR PortA = 0x%x",chip->porta);
|
||||
}
|
||||
return SCPE_OK;
|
||||
if (rw) {
|
||||
sagelp_unit.buf = chip->porta;
|
||||
TRACE_PRINT1(DBG_PP_WRA,"WR PortA = 0x%x",chip->porta);
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
static t_stat u39_callb(I8255* chip, int rw)
|
||||
{
|
||||
if (rw==0) { /* only when reading port */
|
||||
/* propagate FDC Write Protect */
|
||||
int portb = 0;
|
||||
I8272_DRIVE_INFO* dip = &u21.drive[u21.fdc_curdrv];
|
||||
if (dip->uptr && (dip->uptr->flags & UNIT_I8272_WLK)) {
|
||||
portb |= U39B_WP;
|
||||
TRACE_PRINT1(DBG_PP_RDB,"RD PortB: WP+=%d",(portb&U39B_WP)?1:0);
|
||||
}
|
||||
|
||||
/* propagate FDC interrupt */
|
||||
if (u21.irqflag) {
|
||||
portb |= U39B_FDI;
|
||||
TRACE_PRINT0(DBG_PP_RDB,"RD PortB: FDI+=1");
|
||||
} else {
|
||||
TRACE_PRINT0(DBG_PP_RDB,"RD PortB: FDI+=0");
|
||||
}
|
||||
chip->portb = portb;
|
||||
}
|
||||
return SCPE_OK;
|
||||
if (rw==0) { /* only when reading port */
|
||||
/* propagate FDC Write Protect */
|
||||
int portb = 0;
|
||||
I8272_DRIVE_INFO* dip = &u21.drive[u21.fdc_curdrv];
|
||||
if (dip->uptr && (dip->uptr->flags & UNIT_I8272_WLK)) {
|
||||
portb |= U39B_WP;
|
||||
TRACE_PRINT1(DBG_PP_RDB,"RD PortB: WP+=%d",(portb&U39B_WP)?1:0);
|
||||
}
|
||||
|
||||
/* propagate FDC interrupt */
|
||||
if (u21.irqflag) {
|
||||
portb |= U39B_FDI;
|
||||
TRACE_PRINT0(DBG_PP_RDB,"RD PortB: FDI+=1");
|
||||
} else {
|
||||
TRACE_PRINT0(DBG_PP_RDB,"RD PortB: FDI+=0");
|
||||
}
|
||||
chip->portb = portb;
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
static t_stat u39_callc(I8255* chip,int rw)
|
||||
{
|
||||
if (rw==1) {
|
||||
if (I8255_FALLEDGE(portc,U39C_STROBE)) {
|
||||
sagelp_output(&sagelp_unit);
|
||||
TRACE_PRINT1(DBG_PP_RDC,"RD PortC: STROBE-=%d",chip->portc&U39C_STROBE?1:0);
|
||||
}
|
||||
if (I8255_RISEEDGE(portc,U39C_SI)) {
|
||||
/* printf("rising edge on SI: PC=%x!\n",PCX);*/
|
||||
TRACE_PRINT1(DBG_PP_RDC,"RD PortC: SI+=%d",chip->portc&U39C_SI?1:0);
|
||||
sage_raiseint(SI_PICINT);
|
||||
}
|
||||
}
|
||||
return SCPE_OK;
|
||||
if (rw==1) {
|
||||
if (I8255_FALLEDGE(portc,U39C_STROBE)) {
|
||||
sagelp_output(&sagelp_unit);
|
||||
TRACE_PRINT1(DBG_PP_RDC,"RD PortC: STROBE-=%d",chip->portc&U39C_STROBE?1:0);
|
||||
}
|
||||
if (I8255_RISEEDGE(portc,U39C_SI)) {
|
||||
/* printf("rising edge on SI: PC=%x!\n",PCX);*/
|
||||
TRACE_PRINT1(DBG_PP_RDC,"RD PortC: SI+=%d",chip->portc&U39C_SI?1:0);
|
||||
sage_raiseint(SI_PICINT);
|
||||
}
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
static t_stat u39_ckmode(I8255* chip,uint32 data)
|
||||
{
|
||||
TRACE_PRINT1(DBG_PP_MODE,"WR Mode: 0x%x",data);
|
||||
|
||||
/* BIOS initializes port A as input, later LP is initialized to output */
|
||||
if (!(data==0x82 || data==0x92)) {
|
||||
/* hardwired:
|
||||
* d7=1 -- mode set flag
|
||||
* d6=0 -+ group a mode 0: basic I/O
|
||||
* d5=0 -+
|
||||
* d4=0 -- port a = output / input
|
||||
* d3=0 -- port c upper = output
|
||||
* d2=0 -- group b mode 0: basic I/O
|
||||
* d1=1 -- port b = input
|
||||
* d0=0 -- port c lower = output
|
||||
*/
|
||||
printf("u39_ckmode: unsupported ctrl=0x%02x\n",data);
|
||||
return STOP_IMPL;
|
||||
}
|
||||
chip->portc = 0; /* reset port */
|
||||
return SCPE_OK;
|
||||
TRACE_PRINT1(DBG_PP_MODE,"WR Mode: 0x%x",data);
|
||||
|
||||
/* BIOS initializes port A as input, later LP is initialized to output */
|
||||
if (!(data==0x82 || data==0x92)) {
|
||||
/* hardwired:
|
||||
* d7=1 -- mode set flag
|
||||
* d6=0 -+ group a mode 0: basic I/O
|
||||
* d5=0 -+
|
||||
* d4=0 -- port a = output / input
|
||||
* d3=0 -- port c upper = output
|
||||
* d2=0 -- group b mode 0: basic I/O
|
||||
* d1=1 -- port b = input
|
||||
* d0=0 -- port c lower = output
|
||||
*/
|
||||
printf("u39_ckmode: unsupported ctrl=0x%02x\n",data);
|
||||
return STOP_IMPL;
|
||||
}
|
||||
chip->portc = 0; /* reset port */
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
static t_stat u39_reset(I8255* chip)
|
||||
{
|
||||
sagelp_unit.buf = 0;
|
||||
sim_cancel (&sagelp_unit);
|
||||
return SCPE_OK;
|
||||
sagelp_unit.buf = 0;
|
||||
sim_cancel (&sagelp_unit);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
static t_stat sagelp_attach (UNIT *uptr, char *cptr)
|
||||
{
|
||||
t_stat rc;
|
||||
rc = attach_unit(uptr, cptr);
|
||||
if ((sagelp_unit.flags & UNIT_ATT) == 0)
|
||||
u39.portb |= U39B_PAPER; /* no paper */
|
||||
|
||||
return rc;
|
||||
t_stat rc;
|
||||
rc = attach_unit(uptr, cptr);
|
||||
if ((sagelp_unit.flags & UNIT_ATT) == 0)
|
||||
u39.portb |= U39B_PAPER; /* no paper */
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static t_stat sagelp_detach (UNIT *uptr)
|
||||
{
|
||||
u39.portb |= U39B_PAPER; /* no paper */
|
||||
return detach_unit (uptr);
|
||||
u39.portb |= U39B_PAPER; /* no paper */
|
||||
return detach_unit (uptr);
|
||||
}
|
||||
|
||||
static t_stat sagelp_output(UNIT *uptr)
|
||||
{
|
||||
if ((uptr->flags & UNIT_ATT)==0) {
|
||||
u39.portb |= U39B_PAPER; /* unattached means: no paper */
|
||||
return SCPE_UNATT;
|
||||
} else if (uptr->flags & UNIT_OFFLINE) {
|
||||
u39.portb &= ~U39B_SEL; /* offline means: SEL = 0 */
|
||||
return STOP_OFFLINE;
|
||||
}
|
||||
u39.portb &= ~U39B_PAPER; /* has paper */
|
||||
u39.portb |= U39B_SEL; /* is online */
|
||||
u39.portb |= U39B_FAULT; /* no fault */
|
||||
u39.portb &= ~U39B_BUSY; /* not busy */
|
||||
if ((u39.portc & U39C_STROBE)==0) { /* strobe presented */
|
||||
fputc (uptr->buf & 0177, uptr->fileref); /* put out char */
|
||||
if (ferror (uptr->fileref)) {
|
||||
perror ("LP I/O error");
|
||||
clearerr (uptr->fileref);
|
||||
return SCPE_IOERR;
|
||||
}
|
||||
sagelp_unit.pos = ftell(uptr->fileref); /* update pos */
|
||||
u39.portc |= U39C_STROBE; /* XXX reset strobe directly */
|
||||
sage_raiseint(LP_PICINT);
|
||||
return SCPE_OK;
|
||||
}
|
||||
return SCPE_OK;
|
||||
if ((uptr->flags & UNIT_ATT)==0) {
|
||||
u39.portb |= U39B_PAPER; /* unattached means: no paper */
|
||||
return SCPE_UNATT;
|
||||
} else if (uptr->flags & UNIT_OFFLINE) {
|
||||
u39.portb &= ~U39B_SEL; /* offline means: SEL = 0 */
|
||||
return STOP_OFFLINE;
|
||||
}
|
||||
u39.portb &= ~U39B_PAPER; /* has paper */
|
||||
u39.portb |= U39B_SEL; /* is online */
|
||||
u39.portb |= U39B_FAULT; /* no fault */
|
||||
u39.portb &= ~U39B_BUSY; /* not busy */
|
||||
if ((u39.portc & U39C_STROBE)==0) { /* strobe presented */
|
||||
fputc (uptr->buf & 0177, uptr->fileref); /* put out char */
|
||||
if (ferror (uptr->fileref)) {
|
||||
perror ("LP I/O error");
|
||||
clearerr (uptr->fileref);
|
||||
return SCPE_IOERR;
|
||||
}
|
||||
sagelp_unit.pos = ftell(uptr->fileref); /* update pos */
|
||||
u39.portc |= U39C_STROBE; /* XXX reset strobe directly */
|
||||
sage_raiseint(LP_PICINT);
|
||||
return SCPE_OK;
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
|
|
@ -52,8 +52,8 @@
|
|||
* IR7 = Output C2 of U39
|
||||
*
|
||||
* Notes:
|
||||
* INTA- is hardwired to VCC, so vectoring is not possible
|
||||
* SP- is hardwired to VCC, so buffered mode is not possible, and device is a master.
|
||||
* INTA- is hardwired to VCC, so vectoring is not possible
|
||||
* SP- is hardwired to VCC, so buffered mode is not possible, and device is a master.
|
||||
* CAS0-2 lines are open, no need to handle
|
||||
* UCSD bios and boot prom do not program the PIC for rotating priorities,
|
||||
* so effectively prio is always 7.
|
||||
|
@ -62,51 +62,51 @@
|
|||
extern DEVICE sagepic_dev;
|
||||
static t_stat sagepic_reset(DEVICE* dptr);
|
||||
static I8259 u73 = { {0,0,U73_ADDR,4,2},
|
||||
&sagepic_dev,NULL,NULL,i8259_reset
|
||||
&sagepic_dev,NULL,NULL,i8259_reset
|
||||
};
|
||||
|
||||
UNIT sagepic_unit = {
|
||||
UDATA (NULL, UNIT_IDLE, 0)
|
||||
UDATA (NULL, UNIT_IDLE, 0)
|
||||
};
|
||||
|
||||
REG sagepic_reg[] = {
|
||||
{ DRDATA(STATE, u73.state, 8) },
|
||||
{ HRDATA(IRR, u73.irr, 8) },
|
||||
{ HRDATA(IMR, u73.imr, 8) },
|
||||
{ HRDATA(ISR, u73.isr, 8) },
|
||||
{ HRDATA(ICW1, u73.icw1, 8) },
|
||||
{ HRDATA(ICW2, u73.icw2, 8) },
|
||||
{ HRDATA(ICW4, u73.icw4, 8) },
|
||||
{ HRDATA(OCW2, u73.prio, 3) },
|
||||
{ NULL }
|
||||
{ DRDATA(STATE, u73.state, 8) },
|
||||
{ HRDATA(IRR, u73.irr, 8) },
|
||||
{ HRDATA(IMR, u73.imr, 8) },
|
||||
{ HRDATA(ISR, u73.isr, 8) },
|
||||
{ HRDATA(ICW1, u73.icw1, 8) },
|
||||
{ HRDATA(ICW2, u73.icw2, 8) },
|
||||
{ HRDATA(ICW4, u73.icw4, 8) },
|
||||
{ HRDATA(OCW2, u73.prio, 3) },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
static MTAB sagepic_mod[] = {
|
||||
{ MTAB_XTD|MTAB_VDV, 0, "IO", "IO", &set_iobase, &show_iobase, NULL },
|
||||
{ 0 }
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
DEVICE sagepic_dev = {
|
||||
"PIC", &sagepic_unit, sagepic_reg, sagepic_mod,
|
||||
1, 16, 32, 2, 16, 16,
|
||||
NULL, NULL, &sagepic_reset,
|
||||
NULL, NULL, NULL,
|
||||
&u73, DEV_DEBUG, 0,
|
||||
i8259_dt, NULL, NULL
|
||||
"PIC", &sagepic_unit, sagepic_reg, sagepic_mod,
|
||||
1, 16, 32, 2, 16, 16,
|
||||
NULL, NULL, &sagepic_reset,
|
||||
NULL, NULL, NULL,
|
||||
&u73, DEV_DEBUG, 0,
|
||||
i8259_dt, NULL, NULL
|
||||
};
|
||||
|
||||
static t_stat sagepic_reset(DEVICE* dptr)
|
||||
{
|
||||
t_stat rc;
|
||||
if ((rc = (dptr->flags & DEV_DIS) ?
|
||||
del_iohandler(dptr->ctxt) :
|
||||
add_iohandler(&sagepic_unit,dptr->ctxt,i8259_io)) != SCPE_OK) return rc;
|
||||
return u73.reset(&u73);
|
||||
t_stat rc;
|
||||
if ((rc = (dptr->flags & DEV_DIS) ?
|
||||
del_iohandler(dptr->ctxt) :
|
||||
add_iohandler(&sagepic_unit,dptr->ctxt,i8259_io)) != SCPE_OK) return rc;
|
||||
return u73.reset(&u73);
|
||||
}
|
||||
|
||||
t_stat sage_raiseint(int level)
|
||||
{
|
||||
return i8259_raiseint(&u73,level);
|
||||
return i8259_raiseint(&u73,level);
|
||||
}
|
||||
|
||||
/******************************************************************************************************
|
||||
|
@ -152,11 +152,11 @@ t_stat sage_raiseint(int level)
|
|||
*/
|
||||
|
||||
#if defined(SAGE_IV)
|
||||
uint32 groupa = 0xd7; /* used by cons device, 19k2, no parity, boot floppy 0 */
|
||||
uint32 groupb = 0xf8; /* used by ieee device */
|
||||
uint32 groupa = 0xd7; /* used by cons device, 19k2, no parity, boot floppy 0 */
|
||||
uint32 groupb = 0xf8; /* used by ieee device */
|
||||
#else
|
||||
uint32 groupa = 0xe7; /* used by cons device, 19k2, no parity, boot winchester 0 */
|
||||
uint32 groupb = 0xf8; /* used by ieee device */
|
||||
uint32 groupa = 0xe7; /* used by cons device, 19k2, no parity, boot winchester 0 */
|
||||
uint32 groupb = 0xf8; /* used by ieee device */
|
||||
#endif
|
||||
|
||||
static t_stat sagedip_reset(DEVICE* dptr);
|
||||
|
@ -172,194 +172,194 @@ static t_stat u22_ckmode(I8255* chip,uint32 data);
|
|||
|
||||
extern DEVICE sagedip_dev;
|
||||
static I8255 u22 = {
|
||||
{ 0,0,U22_ADDR,8,2 },
|
||||
&sagedip_dev,i8255_write,i8255_read,u22_reset,u22_calla,u22_callb,u22_callc,u22_ckmode
|
||||
{ 0,0,U22_ADDR,8,2 },
|
||||
&sagedip_dev,i8255_write,i8255_read,u22_reset,u22_calla,u22_callb,u22_callc,u22_ckmode
|
||||
};
|
||||
uint32* u22_portc = &u22.portc; /* this is used in the FD device as well, but whole 8255 is handled here */
|
||||
|
||||
UNIT sagedip_unit = {
|
||||
UDATA (NULL, UNIT_IDLE, 0)
|
||||
UDATA (NULL, UNIT_IDLE, 0)
|
||||
};
|
||||
|
||||
REG sagedip_reg[] = {
|
||||
{ HRDATA(PORTA, u22.porta, 8) },
|
||||
{ HRDATA(PORTB, u22.portb, 8) },
|
||||
{ HRDATA(PORTC, u22.portc, 8) },
|
||||
{ HRDATA(CTRL, u22.ctrl, 8) },
|
||||
{ NULL }
|
||||
{ HRDATA(PORTA, u22.porta, 8) },
|
||||
{ HRDATA(PORTB, u22.portb, 8) },
|
||||
{ HRDATA(PORTC, u22.portc, 8) },
|
||||
{ HRDATA(CTRL, u22.ctrl, 8) },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
static MTAB sagedip_mod[] = {
|
||||
{ MTAB_XTD|MTAB_VDV, 0, "IO", "IO", &set_iobase, &show_iobase, NULL },
|
||||
{ MTAB_XTD|MTAB_VDV, 0, "GROUPA", "GROUPA", &set_groupa, &show_groupa, NULL },
|
||||
{ MTAB_XTD|MTAB_VDV, 0, "GROUPB", "GROUPB", &set_groupb, &show_groupb, NULL },
|
||||
{ 0 }
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
/* Debug Flags */
|
||||
DEBTAB sagedip_dt[] = {
|
||||
{ "RDA", DBG_PP_RDA },
|
||||
{ "RDB", DBG_PP_RDB },
|
||||
{ "WRC", DBG_PP_WRC },
|
||||
{ "WRMODE", DBG_PP_MODE },
|
||||
{ NULL, 0 }
|
||||
{ "RDA", DBG_PP_RDA },
|
||||
{ "RDB", DBG_PP_RDB },
|
||||
{ "WRC", DBG_PP_WRC },
|
||||
{ "WRMODE", DBG_PP_MODE },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
DEVICE sagedip_dev = {
|
||||
"DIP", &sagedip_unit, sagedip_reg, sagedip_mod,
|
||||
1, 16, 32, 2, 16, 16,
|
||||
NULL, NULL, &sagedip_reset,
|
||||
NULL, NULL, NULL,
|
||||
&u22, DEV_DEBUG, 0,
|
||||
sagedip_dt, NULL, NULL
|
||||
"DIP", &sagedip_unit, sagedip_reg, sagedip_mod,
|
||||
1, 16, 32, 2, 16, 16,
|
||||
NULL, NULL, &sagedip_reset,
|
||||
NULL, NULL, NULL,
|
||||
&u22, DEV_DEBUG, 0,
|
||||
sagedip_dt, NULL, NULL
|
||||
};
|
||||
|
||||
static t_stat sagedip_reset(DEVICE* dptr)
|
||||
{
|
||||
t_stat rc;
|
||||
|
||||
if ((rc = (dptr->flags & DEV_DIS) ? /* Disconnect I/O Ports */
|
||||
del_iohandler(dptr->ctxt) :
|
||||
add_iohandler(&sagedip_unit,dptr->ctxt,i8255_io)) != SCPE_OK) return rc;
|
||||
|
||||
/* clear 8255 ctrl register */
|
||||
return u22.reset(&u22);
|
||||
t_stat rc;
|
||||
|
||||
if ((rc = (dptr->flags & DEV_DIS) ? /* Disconnect I/O Ports */
|
||||
del_iohandler(dptr->ctxt) :
|
||||
add_iohandler(&sagedip_unit,dptr->ctxt,i8255_io)) != SCPE_OK) return rc;
|
||||
|
||||
/* clear 8255 ctrl register */
|
||||
return u22.reset(&u22);
|
||||
}
|
||||
|
||||
static t_stat set_gr(char* cptr, uint32* sw)
|
||||
{
|
||||
int i;
|
||||
char c;
|
||||
|
||||
if (!cptr) return SCPE_ARG;
|
||||
|
||||
*sw = 0;
|
||||
for (i=0; *cptr && i<8; i++) {
|
||||
c = *cptr++;
|
||||
*sw <<= 1;
|
||||
if (c=='1') *sw |= 1;
|
||||
else if (c=='0') continue;
|
||||
else if (c==0) break;
|
||||
else return SCPE_ARG;
|
||||
}
|
||||
return SCPE_OK;
|
||||
int i;
|
||||
char c;
|
||||
|
||||
if (!cptr) return SCPE_ARG;
|
||||
|
||||
*sw = 0;
|
||||
for (i=0; *cptr && i<8; i++) {
|
||||
c = *cptr++;
|
||||
*sw <<= 1;
|
||||
if (c=='1') *sw |= 1;
|
||||
else if (c=='0') continue;
|
||||
else if (c==0) break;
|
||||
else return SCPE_ARG;
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
static t_stat set_groupa(UNIT *uptr, int32 val, char *cptr, void *desc)
|
||||
{
|
||||
return set_gr(cptr,&groupa);
|
||||
return set_gr(cptr,&groupa);
|
||||
}
|
||||
|
||||
static t_stat set_groupb(UNIT *uptr, int32 val, char *cptr, void *desc)
|
||||
{
|
||||
return set_gr(cptr,&groupb);
|
||||
return set_gr(cptr,&groupb);
|
||||
}
|
||||
|
||||
static t_stat show_gr(FILE* st, char* prefix, uint32 gr)
|
||||
{
|
||||
int i;
|
||||
fputs(prefix, st);
|
||||
for (i = 0x80; i > 0; i = i >> 1)
|
||||
fprintf(st,"%c", gr&i ? '1' : '0');
|
||||
return SCPE_OK;
|
||||
int i;
|
||||
fputs(prefix, st);
|
||||
for (i = 0x80; i > 0; i = i >> 1)
|
||||
fprintf(st,"%c", gr&i ? '1' : '0');
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
static t_stat show_groupa(FILE *st, UNIT *uptr, int32 val, void *desc)
|
||||
{
|
||||
return show_gr(st, "GROUPA=", groupa);
|
||||
return show_gr(st, "GROUPA=", groupa);
|
||||
}
|
||||
|
||||
static t_stat show_groupb(FILE *st, UNIT *uptr, int32 val, void *desc)
|
||||
{
|
||||
return show_gr(st, "GROUPB=", groupb);
|
||||
return show_gr(st, "GROUPB=", groupb);
|
||||
}
|
||||
|
||||
static t_stat u22_reset(I8255* chip)
|
||||
{
|
||||
chip->ctrl = 0;
|
||||
chip->portc = 0;
|
||||
return SCPE_OK;
|
||||
chip->ctrl = 0;
|
||||
chip->portc = 0;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
extern I8272 u21;
|
||||
|
||||
static t_stat u22_calla(I8255* chip,int rw)
|
||||
{
|
||||
if (rw==0) {
|
||||
chip->porta = groupa & 0xff;
|
||||
TRACE_PRINT1(DBG_PP_RDA,"WR PortA: 0x%x",groupa);
|
||||
}
|
||||
return SCPE_OK;
|
||||
if (rw==0) {
|
||||
chip->porta = groupa & 0xff;
|
||||
TRACE_PRINT1(DBG_PP_RDA,"WR PortA: 0x%x",groupa);
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
static t_stat u22_callb(I8255* chip,int rw)
|
||||
{
|
||||
if (rw==0) {
|
||||
chip->portb = groupb & 0xff;
|
||||
TRACE_PRINT1(DBG_PP_RDA,"WR PortB: 0x%x",groupb);
|
||||
}
|
||||
return SCPE_OK;
|
||||
if (rw==0) {
|
||||
chip->portb = groupb & 0xff;
|
||||
TRACE_PRINT1(DBG_PP_RDA,"WR PortB: 0x%x",groupb);
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* callback handler for FDC bits */
|
||||
static t_stat u22_callc(I8255* chip,int rw)
|
||||
{
|
||||
/* bit0: TC+ positive enforce that internal data counter of FDC is reset
|
||||
* bit1: RDY+ positive enable the FDC
|
||||
* bit2: FDIE+ positive enable FDC interrupt (handled directly by reading portc in sage_fd.c)
|
||||
* bit3: SL0- negative select of drive 0
|
||||
* bit4: SL1- negative select of drive 1
|
||||
* bit5: MOT- negative switch on drive motor (ignored)
|
||||
* bit6: PCRMP- negative precompensation (ignored)
|
||||
* bit7: FRES+ positive FDC reset
|
||||
*/
|
||||
/* bit0: TC+ positive enforce that internal data counter of FDC is reset
|
||||
* bit1: RDY+ positive enable the FDC
|
||||
* bit2: FDIE+ positive enable FDC interrupt (handled directly by reading portc in sage_fd.c)
|
||||
* bit3: SL0- negative select of drive 0
|
||||
* bit4: SL1- negative select of drive 1
|
||||
* bit5: MOT- negative switch on drive motor (ignored)
|
||||
* bit6: PCRMP- negative precompensation (ignored)
|
||||
* bit7: FRES+ positive FDC reset
|
||||
*/
|
||||
|
||||
if (I8255_ISSET(portc,U22C_TC)) { /* TC+ */
|
||||
i8272_finish(&u21); /* terminate a read/write in progress */
|
||||
}
|
||||
if (I8255_ISCLR(portc,U22C_RDY)) { /* RDY+ */
|
||||
i8272_abortio(&u21); /* abort current op */
|
||||
}
|
||||
if (I8255_ISCLR(portc,U22C_SL0)) { /* SL0- */
|
||||
u21.fdc_curdrv = 0;
|
||||
} else if (I8255_ISCLR(portc,U22C_SL1)) { /* SL1- */
|
||||
u21.fdc_curdrv = 1;
|
||||
} else if (I8255_ISSET(portc,U22C_SL0|U22C_SL1)) { /* deselect drives */
|
||||
u21.fdc_curdrv = 0;
|
||||
}
|
||||
if (I8255_ISSET(portc,U22C_FRES)) { /* FRES+ */
|
||||
i8272_reset(&u21);
|
||||
}
|
||||
TRACE_PRINT(DBG_PP_WRC,(sim_deb,"PORTC Flags: %s%s%s%s%s%s%s%s",
|
||||
I8255_ISSET(portc,U22C_TC)?"TC ":"",
|
||||
I8255_ISSET(portc,U22C_RDY)?"RDY ":"",
|
||||
I8255_ISSET(portc,U22C_FDIE)?"FDIE ":"",
|
||||
I8255_ISSET(portc,U22C_SL0)?"":"SL0 ",
|
||||
I8255_ISSET(portc,U22C_SL1)?"":"SL1 ",
|
||||
I8255_ISSET(portc,U22C_MOT)?"":"MOT ",
|
||||
I8255_ISSET(portc,U22C_PCRMP)?"":"PCRMP ",
|
||||
I8255_ISSET(portc,U22C_FRES)?"FRES ":""));
|
||||
return SCPE_OK;
|
||||
if (I8255_ISSET(portc,U22C_TC)) { /* TC+ */
|
||||
i8272_finish(&u21); /* terminate a read/write in progress */
|
||||
}
|
||||
if (I8255_ISCLR(portc,U22C_RDY)) { /* RDY+ */
|
||||
i8272_abortio(&u21); /* abort current op */
|
||||
}
|
||||
if (I8255_ISCLR(portc,U22C_SL0)) { /* SL0- */
|
||||
u21.fdc_curdrv = 0;
|
||||
} else if (I8255_ISCLR(portc,U22C_SL1)) { /* SL1- */
|
||||
u21.fdc_curdrv = 1;
|
||||
} else if (I8255_ISSET(portc,U22C_SL0|U22C_SL1)) { /* deselect drives */
|
||||
u21.fdc_curdrv = 0;
|
||||
}
|
||||
if (I8255_ISSET(portc,U22C_FRES)) { /* FRES+ */
|
||||
i8272_reset(&u21);
|
||||
}
|
||||
TRACE_PRINT(DBG_PP_WRC,(sim_deb,"PORTC Flags: %s%s%s%s%s%s%s%s",
|
||||
I8255_ISSET(portc,U22C_TC)?"TC ":"",
|
||||
I8255_ISSET(portc,U22C_RDY)?"RDY ":"",
|
||||
I8255_ISSET(portc,U22C_FDIE)?"FDIE ":"",
|
||||
I8255_ISSET(portc,U22C_SL0)?"":"SL0 ",
|
||||
I8255_ISSET(portc,U22C_SL1)?"":"SL1 ",
|
||||
I8255_ISSET(portc,U22C_MOT)?"":"MOT ",
|
||||
I8255_ISSET(portc,U22C_PCRMP)?"":"PCRMP ",
|
||||
I8255_ISSET(portc,U22C_FRES)?"FRES ":""));
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
static t_stat u22_ckmode(I8255* chip, uint32 data)
|
||||
{
|
||||
/* hardwired:
|
||||
* d7=1 -- mode set flag
|
||||
* d6=0 -+ group a mode 0: basic I/O
|
||||
* d5=0 -+
|
||||
* d4=1 -- porta = input
|
||||
* d3=0 -- portc upper = output
|
||||
* d2=0 -- group b mode 0: basic I/O
|
||||
* d1=1 -- portb = input
|
||||
* d0=0 -- portc lower = output
|
||||
*/
|
||||
TRACE_PRINT1(DBG_PP_MODE,"WR Mode: 0x%x",data);
|
||||
if (data != 0x92) {
|
||||
printf("u22_ckmode: unsupported ctrl=0x%02x\n",data);
|
||||
return STOP_IMPL;
|
||||
}
|
||||
return SCPE_OK;
|
||||
/* hardwired:
|
||||
* d7=1 -- mode set flag
|
||||
* d6=0 -+ group a mode 0: basic I/O
|
||||
* d5=0 -+
|
||||
* d4=1 -- porta = input
|
||||
* d3=0 -- portc upper = output
|
||||
* d2=0 -- group b mode 0: basic I/O
|
||||
* d1=1 -- portb = input
|
||||
* d0=0 -- portc lower = output
|
||||
*/
|
||||
TRACE_PRINT1(DBG_PP_MODE,"WR Mode: 0x%x",data);
|
||||
if (data != 0x92) {
|
||||
printf("u22_ckmode: unsupported ctrl=0x%02x\n",data);
|
||||
return STOP_IMPL;
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/***********************************************************************************
|
||||
|
@ -427,114 +427,114 @@ extern DEVICE sagetimer2_dev;
|
|||
|
||||
/* forward timer 2 */
|
||||
UNIT sagetimer2_unit = {
|
||||
UDATA (&timer2_svc, UNIT_IDLE, 0)
|
||||
UDATA (&timer2_svc, UNIT_IDLE, 0)
|
||||
};
|
||||
|
||||
static I8253 u74 = { {0,0,U74_ADDR,8,2},
|
||||
&sagetimer2_dev,&sagetimer2_unit,i8253_reset,u74_ckmode,
|
||||
{ { 0, }, { u74_call1, }, { 0, } }
|
||||
&sagetimer2_dev,&sagetimer2_unit,i8253_reset,u74_ckmode,
|
||||
{ { 0, }, { u74_call1, }, { 0, } }
|
||||
};
|
||||
|
||||
/* timer 1 */
|
||||
UNIT sagetimer1_unit = {
|
||||
UDATA (&timer1_svc, UNIT_IDLE, 1)
|
||||
UDATA (&timer1_svc, UNIT_IDLE, 1)
|
||||
};
|
||||
|
||||
static I8253 u75 = { {0,0,U75_ADDR,8,2},
|
||||
&sagetimer1_dev,&sagetimer1_unit,i8253_reset,u75_ckmode,
|
||||
{ { u75_call0, }, { 0, }, { 0, } }
|
||||
&sagetimer1_dev,&sagetimer1_unit,i8253_reset,u75_ckmode,
|
||||
{ { u75_call0, }, { 0, }, { 0, } }
|
||||
};
|
||||
|
||||
REG sagetimer1_reg[] = {
|
||||
{ HRDATA(INIT, u75.init, 8), REG_HRO },
|
||||
{ HRDATA(STATE0,u75.cntr[0].state, 8),REG_HRO },
|
||||
{ HRDATA(STATE1,u75.cntr[1].state, 8),REG_HRO },
|
||||
{ HRDATA(STATE2,u75.cntr[2].state, 8),REG_HRO },
|
||||
{ HRDATA(MODE0, u75.cntr[0].mode, 8) },
|
||||
{ HRDATA(MODE1, u75.cntr[1].mode, 8) },
|
||||
{ HRDATA(MODE2, u75.cntr[2].mode, 8) },
|
||||
{ HRDATA(CNT0, u75.cntr[0].count, 16) },
|
||||
{ HRDATA(CNT1, u75.cntr[1].count, 16) },
|
||||
{ HRDATA(CNT2, u75.cntr[2].count, 16) },
|
||||
{ HRDATA(LATCH0,u75.cntr[0].latch, 16) },
|
||||
{ HRDATA(LATCH1,u75.cntr[1].latch, 16) },
|
||||
{ HRDATA(LATCH2,u75.cntr[2].latch, 16) },
|
||||
{ HRDATA(DIV0, u75.cntr[0].divider, 16),REG_HRO },
|
||||
{ HRDATA(DIV1, u75.cntr[1].divider, 16),REG_HRO },
|
||||
{ HRDATA(DIV2, u75.cntr[2].divider, 16),REG_HRO },
|
||||
{ NULL }
|
||||
{ HRDATA(INIT, u75.init, 8), REG_HRO },
|
||||
{ HRDATA(STATE0,u75.cntr[0].state, 8),REG_HRO },
|
||||
{ HRDATA(STATE1,u75.cntr[1].state, 8),REG_HRO },
|
||||
{ HRDATA(STATE2,u75.cntr[2].state, 8),REG_HRO },
|
||||
{ HRDATA(MODE0, u75.cntr[0].mode, 8) },
|
||||
{ HRDATA(MODE1, u75.cntr[1].mode, 8) },
|
||||
{ HRDATA(MODE2, u75.cntr[2].mode, 8) },
|
||||
{ HRDATA(CNT0, u75.cntr[0].count, 16) },
|
||||
{ HRDATA(CNT1, u75.cntr[1].count, 16) },
|
||||
{ HRDATA(CNT2, u75.cntr[2].count, 16) },
|
||||
{ HRDATA(LATCH0,u75.cntr[0].latch, 16) },
|
||||
{ HRDATA(LATCH1,u75.cntr[1].latch, 16) },
|
||||
{ HRDATA(LATCH2,u75.cntr[2].latch, 16) },
|
||||
{ HRDATA(DIV0, u75.cntr[0].divider, 16),REG_HRO },
|
||||
{ HRDATA(DIV1, u75.cntr[1].divider, 16),REG_HRO },
|
||||
{ HRDATA(DIV2, u75.cntr[2].divider, 16),REG_HRO },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
static MTAB sagetimer1_mod[] = {
|
||||
{ MTAB_XTD|MTAB_VDV, 0, "IO", "IO", &set_iobase, &show_iobase, NULL },
|
||||
{ 0 }
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
DEVICE sagetimer1_dev = {
|
||||
"TIMER1", &sagetimer1_unit, sagetimer1_reg, sagetimer1_mod,
|
||||
1, 16, 32, 2, 16, 16,
|
||||
NULL, NULL, &sagetimer1_reset,
|
||||
NULL, NULL, NULL,
|
||||
&u75, DEV_DEBUG, 0,
|
||||
i8253_dt, NULL, NULL
|
||||
"TIMER1", &sagetimer1_unit, sagetimer1_reg, sagetimer1_mod,
|
||||
1, 16, 32, 2, 16, 16,
|
||||
NULL, NULL, &sagetimer1_reset,
|
||||
NULL, NULL, NULL,
|
||||
&u75, DEV_DEBUG, 0,
|
||||
i8253_dt, NULL, NULL
|
||||
};
|
||||
|
||||
static t_stat sagetimer1_reset(DEVICE* dptr)
|
||||
{
|
||||
t_stat rc;
|
||||
if (!(rc = (dptr->flags & DEV_DIS) ?
|
||||
del_iohandler(dptr->ctxt) :
|
||||
add_iohandler(&sagetimer1_unit,dptr->ctxt,i8253_io)) != SCPE_OK) return rc;
|
||||
return u75.reset(&u75);
|
||||
t_stat rc;
|
||||
if (!(rc = (dptr->flags & DEV_DIS) ?
|
||||
del_iohandler(dptr->ctxt) :
|
||||
add_iohandler(&sagetimer1_unit,dptr->ctxt,i8253_io)) != SCPE_OK) return rc;
|
||||
return u75.reset(&u75);
|
||||
}
|
||||
|
||||
static t_stat timer1_svc(UNIT* uptr)
|
||||
{
|
||||
int32 wait;
|
||||
I8253CNTR* t1c0 = &u75.cntr[0];
|
||||
I8253CNTR* t2c0 = &u74.cntr[0];
|
||||
|
||||
// fprintf(sim_deb,"TIMER1: timer1_svc called T1C0=%d T2C0=%d\n",t1c0->count,t2c0->count);
|
||||
/* we call this service 64000 times a second to decrement counter T1C0.
|
||||
* When T1C0 reaches 0, it will decrement T2C0 */
|
||||
t1c0->count--;
|
||||
if (t1c0->count <= 0) {
|
||||
/* reload from divider */
|
||||
t1c0->count = t1c0->divider;
|
||||
/* decrement T2C0 counter and raise interrupt 6 if counter is zero */
|
||||
if (t2c0->count == 0) {
|
||||
sage_raiseint(TIMER2C0_PICINT);
|
||||
// printf("timer1 heartbeat\n");
|
||||
t2c0->count = 65536;
|
||||
}
|
||||
t2c0->count--;
|
||||
}
|
||||
int32 wait;
|
||||
I8253CNTR* t1c0 = &u75.cntr[0];
|
||||
I8253CNTR* t2c0 = &u74.cntr[0];
|
||||
|
||||
// fprintf(sim_deb,"TIMER1: timer1_svc called T1C0=%d T2C0=%d\n",t1c0->count,t2c0->count);
|
||||
/* we call this service 64000 times a second to decrement counter T1C0.
|
||||
* When T1C0 reaches 0, it will decrement T2C0 */
|
||||
t1c0->count--;
|
||||
if (t1c0->count <= 0) {
|
||||
/* reload from divider */
|
||||
t1c0->count = t1c0->divider;
|
||||
/* decrement T2C0 counter and raise interrupt 6 if counter is zero */
|
||||
if (t2c0->count == 0) {
|
||||
sage_raiseint(TIMER2C0_PICINT);
|
||||
// printf("timer1 heartbeat\n");
|
||||
t2c0->count = 65536;
|
||||
}
|
||||
t2c0->count--;
|
||||
}
|
||||
|
||||
/* adjust timing */
|
||||
wait = sim_rtcn_calb(64000,TMR_RTC1);
|
||||
sim_activate(u75.unit,wait); /* 64000 ticks per second */
|
||||
return SCPE_OK;
|
||||
/* adjust timing */
|
||||
wait = sim_rtcn_calb(64000,TMR_RTC1);
|
||||
sim_activate(u75.unit,wait); /* 64000 ticks per second */
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
static t_stat u75_ckmode(I8253* chip,uint32 mode)
|
||||
{
|
||||
/* @TODO check valid modes */
|
||||
return SCPE_OK;
|
||||
/* @TODO check valid modes */
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
static t_stat u75_call0(I8253* chip,int rw,uint32* value)
|
||||
{
|
||||
if (rw==1) {
|
||||
I8253CNTR* cntr = &chip->cntr[0];
|
||||
if ((cntr->mode & I8253_BOTH) && (cntr->state & I8253_ST_MSBNEXT)) {
|
||||
sim_cancel(chip->unit);
|
||||
return SCPE_OK; /* not fully loaded yet */
|
||||
} else {
|
||||
/* start the CK0 clock at 64000Hz */
|
||||
sim_activate(chip->unit,sim_rtcn_init(64000,TMR_RTC1)); /* use timer1 C0 for this clock */
|
||||
}
|
||||
}
|
||||
return SCPE_OK;
|
||||
if (rw==1) {
|
||||
I8253CNTR* cntr = &chip->cntr[0];
|
||||
if ((cntr->mode & I8253_BOTH) && (cntr->state & I8253_ST_MSBNEXT)) {
|
||||
sim_cancel(chip->unit);
|
||||
return SCPE_OK; /* not fully loaded yet */
|
||||
} else {
|
||||
/* start the CK0 clock at 64000Hz */
|
||||
sim_activate(chip->unit,sim_rtcn_init(64000,TMR_RTC1)); /* use timer1 C0 for this clock */
|
||||
}
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
|
||||
|
@ -543,91 +543,91 @@ static t_stat u75_call0(I8253* chip,int rw,uint32* value)
|
|||
***********************************************************************************/
|
||||
|
||||
REG sagetimer2_reg[] = {
|
||||
{ HRDATA(INIT, u74.init, 8), REG_HRO },
|
||||
{ HRDATA(STATE0,u74.cntr[0].state, 8),REG_HRO },
|
||||
{ HRDATA(STATE1,u74.cntr[1].state, 8),REG_HRO },
|
||||
{ HRDATA(STATE2,u74.cntr[2].state, 8),REG_HRO },
|
||||
{ HRDATA(MODE0, u74.cntr[0].mode, 8) },
|
||||
{ HRDATA(MODE1, u74.cntr[1].mode, 8) },
|
||||
{ HRDATA(MODE2, u74.cntr[2].mode, 8) },
|
||||
{ HRDATA(CNT0, u74.cntr[0].count, 16) },
|
||||
{ HRDATA(CNT1, u74.cntr[1].count, 16) },
|
||||
{ HRDATA(CNT2, u74.cntr[2].count, 16) },
|
||||
{ HRDATA(LATCH0,u74.cntr[0].latch, 16) },
|
||||
{ HRDATA(LATCH1,u74.cntr[1].latch, 16) },
|
||||
{ HRDATA(LATCH2,u74.cntr[2].latch, 16) },
|
||||
{ HRDATA(DIV0, u74.cntr[0].divider, 16),REG_HRO },
|
||||
{ HRDATA(DIV1, u74.cntr[1].divider, 16),REG_HRO },
|
||||
{ HRDATA(DIV2, u74.cntr[2].divider, 16),REG_HRO },
|
||||
{ NULL }
|
||||
{ HRDATA(INIT, u74.init, 8), REG_HRO },
|
||||
{ HRDATA(STATE0,u74.cntr[0].state, 8),REG_HRO },
|
||||
{ HRDATA(STATE1,u74.cntr[1].state, 8),REG_HRO },
|
||||
{ HRDATA(STATE2,u74.cntr[2].state, 8),REG_HRO },
|
||||
{ HRDATA(MODE0, u74.cntr[0].mode, 8) },
|
||||
{ HRDATA(MODE1, u74.cntr[1].mode, 8) },
|
||||
{ HRDATA(MODE2, u74.cntr[2].mode, 8) },
|
||||
{ HRDATA(CNT0, u74.cntr[0].count, 16) },
|
||||
{ HRDATA(CNT1, u74.cntr[1].count, 16) },
|
||||
{ HRDATA(CNT2, u74.cntr[2].count, 16) },
|
||||
{ HRDATA(LATCH0,u74.cntr[0].latch, 16) },
|
||||
{ HRDATA(LATCH1,u74.cntr[1].latch, 16) },
|
||||
{ HRDATA(LATCH2,u74.cntr[2].latch, 16) },
|
||||
{ HRDATA(DIV0, u74.cntr[0].divider, 16),REG_HRO },
|
||||
{ HRDATA(DIV1, u74.cntr[1].divider, 16),REG_HRO },
|
||||
{ HRDATA(DIV2, u74.cntr[2].divider, 16),REG_HRO },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
static MTAB sagetimer2_mod[] = {
|
||||
{ MTAB_XTD|MTAB_VDV, 0, "IO", "IO", &set_iobase, &show_iobase, NULL },
|
||||
{ 0 }
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
DEVICE sagetimer2_dev = {
|
||||
"TIMER2", &sagetimer2_unit, sagetimer2_reg, sagetimer2_mod,
|
||||
1, 16, 32, 2, 16, 16,
|
||||
NULL, NULL, &sagetimer2_reset,
|
||||
NULL, NULL, NULL,
|
||||
&u74, DEV_DEBUG, 0,
|
||||
i8253_dt, NULL, NULL
|
||||
"TIMER2", &sagetimer2_unit, sagetimer2_reg, sagetimer2_mod,
|
||||
1, 16, 32, 2, 16, 16,
|
||||
NULL, NULL, &sagetimer2_reset,
|
||||
NULL, NULL, NULL,
|
||||
&u74, DEV_DEBUG, 0,
|
||||
i8253_dt, NULL, NULL
|
||||
};
|
||||
|
||||
static t_stat sagetimer2_reset(DEVICE* dptr)
|
||||
{
|
||||
t_stat rc;
|
||||
if ((rc = (dptr->flags & DEV_DIS) ?
|
||||
del_iohandler(dptr->ctxt) :
|
||||
add_iohandler(&sagetimer2_unit,dptr->ctxt,i8253_io)) != SCPE_OK) return rc;
|
||||
return u74.reset(&u74);
|
||||
t_stat rc;
|
||||
if ((rc = (dptr->flags & DEV_DIS) ?
|
||||
del_iohandler(dptr->ctxt) :
|
||||
add_iohandler(&sagetimer2_unit,dptr->ctxt,i8253_io)) != SCPE_OK) return rc;
|
||||
return u74.reset(&u74);
|
||||
}
|
||||
|
||||
static t_stat u74_ckmode(I8253* chip,uint32 mode)
|
||||
{
|
||||
/* @TODO check valid modes */
|
||||
return SCPE_OK;
|
||||
/* @TODO check valid modes */
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
static t_stat u74_call1(I8253* chip,int rw,uint32* value)
|
||||
{
|
||||
if (rw==1) {
|
||||
I8253CNTR* cntr = &chip->cntr[1];
|
||||
if ((cntr->mode & I8253_BOTH) && (cntr->state & I8253_ST_MSBNEXT)) {
|
||||
sim_cancel(chip->unit);
|
||||
return SCPE_OK; /* not fully loaded yet */
|
||||
} else {
|
||||
/* start the CK0 clock at 64000Hz */
|
||||
sim_activate(chip->unit,sim_rtcn_init(64000,TMR_RTC1)); /* use timer1 C0 for this clock */
|
||||
}
|
||||
}
|
||||
return SCPE_OK;
|
||||
if (rw==1) {
|
||||
I8253CNTR* cntr = &chip->cntr[1];
|
||||
if ((cntr->mode & I8253_BOTH) && (cntr->state & I8253_ST_MSBNEXT)) {
|
||||
sim_cancel(chip->unit);
|
||||
return SCPE_OK; /* not fully loaded yet */
|
||||
} else {
|
||||
/* start the CK0 clock at 64000Hz */
|
||||
sim_activate(chip->unit,sim_rtcn_init(64000,TMR_RTC1)); /* use timer1 C0 for this clock */
|
||||
}
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
static t_stat timer2_svc(UNIT* uptr)
|
||||
{
|
||||
int32 wait;
|
||||
I8253CNTR* t2c1 = &u74.cntr[1];
|
||||
I8253CNTR* t2c2 = &u74.cntr[2];
|
||||
|
||||
/* we call this service 64000 times a second to decrement counter T2C1.
|
||||
* When T2C1 reaches 0, it will decrement T2C2 */
|
||||
t2c1->count--;
|
||||
if (t2c1->count <= 0) {
|
||||
/* reload from divider */
|
||||
t2c1->count = t2c1->divider;
|
||||
/* decrement T2C2 counter and raise interrupt 0 if counter is zero */
|
||||
if (t2c2->count == 0) {
|
||||
// printf("timer2 heartbeat\n");
|
||||
sage_raiseint(TIMER2C2_PICINT);
|
||||
}
|
||||
t2c2->count--;
|
||||
}
|
||||
int32 wait;
|
||||
I8253CNTR* t2c1 = &u74.cntr[1];
|
||||
I8253CNTR* t2c2 = &u74.cntr[2];
|
||||
|
||||
/* adjust timing */
|
||||
wait = sim_rtcn_calb(64000,TMR_RTC1);
|
||||
sim_activate(u74.unit,wait); /* 64000 ticks per second */
|
||||
return SCPE_OK;
|
||||
/* we call this service 64000 times a second to decrement counter T2C1.
|
||||
* When T2C1 reaches 0, it will decrement T2C2 */
|
||||
t2c1->count--;
|
||||
if (t2c1->count <= 0) {
|
||||
/* reload from divider */
|
||||
t2c1->count = t2c1->divider;
|
||||
/* decrement T2C2 counter and raise interrupt 0 if counter is zero */
|
||||
if (t2c2->count == 0) {
|
||||
// printf("timer2 heartbeat\n");
|
||||
sage_raiseint(TIMER2C2_PICINT);
|
||||
}
|
||||
t2c2->count--;
|
||||
}
|
||||
|
||||
/* adjust timing */
|
||||
wait = sim_rtcn_calb(64000,TMR_RTC1);
|
||||
sim_activate(u74.unit,wait); /* 64000 ticks per second */
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
|
|
@ -46,26 +46,26 @@ extern DEVICE sagehd_dev;
|
|||
extern DEVICE sageaux_dev;
|
||||
#endif
|
||||
|
||||
char sim_name[] = "Sage-II/IV 68k";
|
||||
char sim_name[] = "Sage-II/IV 68k";
|
||||
|
||||
REG *sim_PC = &m68kcpu_reg[18];
|
||||
int sim_emax = SIM_EMAX;
|
||||
DEVICE *sim_devices[] = {
|
||||
&sagecpu_dev,
|
||||
&sagepic_dev,
|
||||
&sagetimer1_dev,
|
||||
&sagetimer2_dev,
|
||||
&sagedip_dev,
|
||||
&sagefd_dev,
|
||||
&sagecons_dev,
|
||||
&sagesio_dev,
|
||||
&sagelp_dev,
|
||||
REG *sim_PC = &m68kcpu_reg[18];
|
||||
int sim_emax = SIM_EMAX;
|
||||
DEVICE *sim_devices[] = {
|
||||
&sagecpu_dev,
|
||||
&sagepic_dev,
|
||||
&sagetimer1_dev,
|
||||
&sagetimer2_dev,
|
||||
&sagedip_dev,
|
||||
&sagefd_dev,
|
||||
&sagecons_dev,
|
||||
&sagesio_dev,
|
||||
&sagelp_dev,
|
||||
#if 0
|
||||
&sageieee_dev,
|
||||
&sageieee_dev,
|
||||
#endif
|
||||
#ifdef SAGE_IV
|
||||
&sagehd_dev,
|
||||
&sageaux_dev,
|
||||
&sagehd_dev,
|
||||
&sageaux_dev,
|
||||
#endif
|
||||
NULL
|
||||
NULL
|
||||
};
|
||||
|
|
|
@ -325,7 +325,7 @@ REG cpu_reg[] = {
|
|||
{ ORDATA (MBR, MBR, 18) },
|
||||
{ ORDATA (LR, LR, 18) },
|
||||
{ ORDATA (TAC, TAC, 18) },
|
||||
{ ORDATA (TBR, TBR, 18) },
|
||||
{ ORDATA (TBR, TBR, 18) },
|
||||
{ ORDATA (PF, PF, 18) },
|
||||
{ BRDATA (PCQ, pcq, 8, ASIZE, PCQ_SIZE), REG_RO+REG_CIRC },
|
||||
{ ORDATA (PCQP, pcq_p, 6), REG_HRO },
|
||||
|
@ -703,10 +703,10 @@ t_stat sim_instr (void)
|
|||
break;
|
||||
case 3: /* tix (Transfer and Index) */
|
||||
TRACE_PRINT(TRN_MSG, ("[%06o] TIX: XR=%05o\n", PC-1, XR));
|
||||
if ((XR == 037777) || (XR == 000000)) { /* +/- 0, take next instruction */
|
||||
if ((XR == 037777) || (XR == 000000)) { /* +/- 0, take next instruction */
|
||||
TRACE_PRINT(TRN_MSG, ("+/- 0, transfer not taken.\n"));
|
||||
} else { /* Not +/- 0 */
|
||||
if (XR & 0020000) { /* XR[4] == 1 */
|
||||
if (XR & 0020000) { /* XR[4] == 1 */
|
||||
TRACE_PRINT(TRN_MSG, ("XR is negative, transfer taken,"));
|
||||
XR ++;
|
||||
} else { /* XR[4] = 0 */
|
||||
|
|
|
@ -290,13 +290,13 @@ circuitry. Lines without seventh hole punched are ignored by the PETR.
|
|||
As each line of the tape is read in, the data is stored into an 18-bit BUF
|
||||
register with bits mapped as follows:
|
||||
|
||||
Tape BUF
|
||||
0 0
|
||||
1 3
|
||||
2 6
|
||||
3 9
|
||||
4 12
|
||||
5 15
|
||||
Tape BUF
|
||||
0 0
|
||||
1 3
|
||||
2 6
|
||||
3 9
|
||||
4 12
|
||||
5 15
|
||||
|
||||
Up to three lines of tape may be read into a single the single BUF register.
|
||||
Before subsequent lines are read, the BUF register is cycled one bit right.
|
||||
|
@ -410,18 +410,18 @@ extern UNIT cpu_unit;
|
|||
/* Switches the CPU to READIN mode and starts execution. */
|
||||
t_stat petr_boot (int32 unitno, DEVICE *dptr)
|
||||
{
|
||||
t_stat reason = SCPE_OK;
|
||||
t_stat reason = SCPE_OK;
|
||||
|
||||
#ifdef SANITY_CHECK_TAPE
|
||||
int32 AC, MBR, MAR, IR = 0;
|
||||
int32 blkcnt, chksum = 0, fa, la;
|
||||
int32 addr, tdata;
|
||||
int32 AC, MBR, MAR, IR = 0;
|
||||
int32 blkcnt, chksum = 0, fa, la;
|
||||
int32 addr, tdata;
|
||||
#endif /* SANITY_CHECK_TAPE */
|
||||
|
||||
/* Switch to READIN mode. */
|
||||
cpu_set_mode(&cpu_unit, UNIT_MODE_READIN, NULL, NULL);
|
||||
#ifdef SANITY_CHECK_TAPE
|
||||
for(;(IR != 2) && (IR != 1);) {
|
||||
for(;(IR != 2) && (IR != 1);) {
|
||||
AC = petr(3,0,0); /* Read three chars from tape into AC */
|
||||
MAR = AC & AMASK; /* Set memory address */
|
||||
IR = AC >> 16;
|
||||
|
@ -453,62 +453,62 @@ t_stat petr_boot (int32 unitno, DEVICE *dptr)
|
|||
default:
|
||||
reason = SCPE_IERR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
blkcnt = 0;
|
||||
while (1) {
|
||||
chksum = 0;
|
||||
blkcnt = 0;
|
||||
while (1) {
|
||||
chksum = 0;
|
||||
|
||||
fa = petr(3,0,0); /* Read three characters from tape. */
|
||||
fa = petr(3,0,0); /* Read three characters from tape. */
|
||||
|
||||
if ((fa & 0400000) || (fa & 0200000)) {
|
||||
break;
|
||||
}
|
||||
if ((fa & 0400000) || (fa & 0200000)) {
|
||||
break;
|
||||
}
|
||||
|
||||
chksum += fa;
|
||||
if (chksum > 0777777) {
|
||||
chksum +=1;
|
||||
}
|
||||
chksum &= 0777777;
|
||||
chksum += fa;
|
||||
if (chksum > 0777777) {
|
||||
chksum +=1;
|
||||
}
|
||||
chksum &= 0777777;
|
||||
|
||||
la = petr(3,0,0); /* Read three characters from tape. */
|
||||
la = petr(3,0,0); /* Read three characters from tape. */
|
||||
|
||||
chksum += la;
|
||||
if (chksum > 0777777) {
|
||||
chksum +=1;
|
||||
}
|
||||
chksum &= 0777777;
|
||||
chksum += la;
|
||||
if (chksum > 0777777) {
|
||||
chksum +=1;
|
||||
}
|
||||
chksum &= 0777777;
|
||||
|
||||
la = (~la) & 0177777;
|
||||
la = (~la) & 0177777;
|
||||
|
||||
sim_printf("First Address=%06o, Last Address=%06o\n", fa, la);
|
||||
sim_printf("First Address=%06o, Last Address=%06o\n", fa, la);
|
||||
|
||||
for(addr = fa; addr <= la; addr++) {
|
||||
tdata = petr(3,0,0); /* Read three characters from tape. */
|
||||
chksum += tdata;
|
||||
if (chksum > 0777777) {
|
||||
chksum +=1;
|
||||
}
|
||||
chksum &= 0777777;
|
||||
}
|
||||
for(addr = fa; addr <= la; addr++) {
|
||||
tdata = petr(3,0,0); /* Read three characters from tape. */
|
||||
chksum += tdata;
|
||||
if (chksum > 0777777) {
|
||||
chksum +=1;
|
||||
}
|
||||
chksum &= 0777777;
|
||||
}
|
||||
|
||||
chksum = (~chksum) & 0777777;
|
||||
chksum = (~chksum) & 0777777;
|
||||
|
||||
tdata = petr(3,0,0);
|
||||
tdata = petr(3,0,0);
|
||||
|
||||
if (chksum != tdata) {
|
||||
reason = SCPE_FMT;
|
||||
}
|
||||
if (chksum != tdata) {
|
||||
reason = SCPE_FMT;
|
||||
}
|
||||
|
||||
sim_printf("Block %d: Calculated checksum=%06o, real checksum=%06o, %s\n", blkcnt, chksum, tdata, chksum == tdata ? "OK" : "BAD Checksum!");
|
||||
blkcnt++;
|
||||
}
|
||||
sim_printf("Block %d: Calculated checksum=%06o, real checksum=%06o, %s\n", blkcnt, chksum, tdata, chksum == tdata ? "OK" : "BAD Checksum!");
|
||||
blkcnt++;
|
||||
}
|
||||
|
||||
fseek (petr_dev.units[0].fileref, 0, SEEK_SET);
|
||||
fseek (petr_dev.units[0].fileref, 0, SEEK_SET);
|
||||
#endif /* SANITY_CHECK_TAPE */
|
||||
|
||||
/* Start Execution */
|
||||
/* Start Execution */
|
||||
return (reason);
|
||||
|
||||
}
|
||||
|
|
|
@ -56,7 +56,7 @@
|
|||
#define TXCS_M_TEN 0xF
|
||||
#define TXCS_TEN (TXCS_M_TEN << TXCS_V_TEN)
|
||||
#define TXCS_RD (CSR_DONE + CSR_IE + TXCS_TEN + TXCS_IDC + TXCS_WMN) /* Readable bits */
|
||||
#define TXCS_WR (CSR_IE) /* Writeable bits */
|
||||
#define TXCS_WR (CSR_IE) /* Writeable bits */
|
||||
#define ID_CT 0 /* console terminal */
|
||||
#define ID_RS 1 /* remote services */
|
||||
#define ID_EMM 2 /* environmental monitoring module */
|
||||
|
|
|
@ -1372,7 +1372,7 @@ while (reason == 0) {
|
|||
if (!(arch_mask & AMASK_CIX)) ABORT (EXC_RSVI);
|
||||
for (res = 0; rbv != 0; res++) {
|
||||
rbv = rbv & ~(rbv & NEG_Q (rbv));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x31: /* PERR */
|
||||
|
|
|
@ -164,7 +164,7 @@ REG ev5pal_reg[] = {
|
|||
{ FLDATA (PWRFL, ev5_pwrfl, 0) },
|
||||
{ FLDATA (SLI, ev5_sli, 0) },
|
||||
{ NULL }
|
||||
};
|
||||
};
|
||||
|
||||
DEVICE ev5pal_dev = {
|
||||
"EV5PAL", &ev5pal_unit, ev5pal_reg, NULL,
|
||||
|
@ -172,7 +172,7 @@ DEVICE ev5pal_dev = {
|
|||
NULL, NULL, &pal_proc_reset_hwre,
|
||||
NULL, NULL, NULL,
|
||||
NULL, DEV_DIS
|
||||
};
|
||||
};
|
||||
|
||||
/* EV5 interrupt dispatch - reached from top of instruction loop -
|
||||
dispatch to PALcode */
|
||||
|
@ -675,7 +675,7 @@ switch (fnc) {
|
|||
if (pal_mode && ((val ^ ev5_icsr) & ICSR_SDE)) {
|
||||
if (val & ICSR_SDE) { PAL_USE_SHADOW; }
|
||||
else { PAL_USE_MAIN; }
|
||||
}
|
||||
}
|
||||
ev5_icsr = val & ICSR_RW;
|
||||
itlb_set_spage ((((uint32) val) >> ICSR_V_SPE) & ICSR_M_SPE);
|
||||
fpen = (((uint32) val) >> ICSR_V_FPE) & 1;
|
||||
|
@ -815,12 +815,12 @@ static struct pal_opt ld_st_opt[] = {
|
|||
{ HW_LD_PTE, 'P' },
|
||||
{ HW_LD_LCK, 'L' },
|
||||
{ 0 }
|
||||
};
|
||||
};
|
||||
|
||||
static struct pal_opt rei_opt[] = {
|
||||
{ HW_REI_S, 'S' },
|
||||
{ 0 }
|
||||
};
|
||||
};
|
||||
|
||||
/* Print options for hardware PAL instruction */
|
||||
|
||||
|
|
|
@ -132,8 +132,8 @@ uint32 sign = FPR_GETSIGN (op)? S_SIGN: 0;
|
|||
uint32 frac = ((uint32) (op >> S_V_FRAC)) & M32;
|
||||
uint32 exp = FPR_GETEXP (op);
|
||||
|
||||
if (exp == FPR_NAN) exp = S_NAN; /* inf or NaN? */
|
||||
else if (exp != 0) exp = exp + S_BIAS - T_BIAS; /* non-zero? */
|
||||
if (exp == FPR_NAN) exp = S_NAN; /* inf or NaN? */
|
||||
else if (exp != 0) exp = exp + S_BIAS - T_BIAS; /* non-zero? */
|
||||
exp = (exp & S_M_EXP) << S_V_EXP;
|
||||
return (t_uint64) (sign | exp | (frac & ~(S_SIGN|S_EXP)));
|
||||
}
|
||||
|
@ -631,8 +631,8 @@ static const int32 expmin[2] = { T_BIAS - S_BIAS, 0 };
|
|||
t_uint64 rndadd, rndbits, res;
|
||||
uint32 rndm;
|
||||
|
||||
if (r->frac == 0) /* result 0? */
|
||||
return ((t_uint64) r->sign << FPR_V_SIGN);
|
||||
if (r->frac == 0) /* result 0? */
|
||||
return ((t_uint64) r->sign << FPR_V_SIGN);
|
||||
rndm = I_GETFRND (ir); /* inst round mode */
|
||||
if (rndm == I_FRND_D) rndm = FPCR_GETFRND (fpcr); /* dynamic? use FPCR */
|
||||
rndbits = r->frac & infrnd[dp]; /* isolate round bits */
|
||||
|
|
|
@ -82,7 +82,7 @@ uint32 sign = FPR_GETSIGN (op)? F_SIGN: 0;
|
|||
uint32 frac = (uint32) (op >> F_V_FRAC);
|
||||
uint32 exp = FPR_GETEXP (op);
|
||||
|
||||
if (exp != 0) exp = exp + F_BIAS - G_BIAS; /* zero? */
|
||||
if (exp != 0) exp = exp + F_BIAS - G_BIAS; /* zero? */
|
||||
exp = (exp & F_M_EXP) << F_V_EXP;
|
||||
return (t_uint64) (sign | exp | (SWAP_VAXF (frac) & ~(F_SIGN|F_EXP)));
|
||||
}
|
||||
|
@ -398,7 +398,7 @@ r->frac = r->frac & M64;
|
|||
if (r->frac == 0) { /* if fraction = 0 */
|
||||
r->sign = r->exp = 0; /* result is 0 */
|
||||
return;
|
||||
}
|
||||
}
|
||||
while ((r->frac & UF_NM) == 0) { /* normalized? */
|
||||
for (i = 0; i < 5; i++) { /* find first 1 */
|
||||
if (r->frac & normmask[i]) break;
|
||||
|
|
|
@ -543,7 +543,7 @@ if (sw & SWMASK ('C')) { /* char format? */
|
|||
for (sc = 0; sc < 64; sc = sc + 8) { /* print string */
|
||||
c = (uint32) (val[0] >> sc) & 0x7F;
|
||||
fprintf (of, (c < 0x20)? "<%02X>": "%c", c);
|
||||
}
|
||||
}
|
||||
return -7; /* return # chars */
|
||||
}
|
||||
if (sw & SWMASK ('M')) { /* inst format? */
|
||||
|
|
|
@ -162,7 +162,7 @@ REG unixpal_reg[] = {
|
|||
{ HRDATA (IPL, unix_ipl, 3) },
|
||||
{ HRDATA (CM, unix_cm, 0) },
|
||||
{ NULL }
|
||||
};
|
||||
};
|
||||
|
||||
DEVICE unixpal_dev = {
|
||||
"UNIXPAL", &unixpal_unit, unixpal_reg, NULL,
|
||||
|
@ -170,7 +170,7 @@ DEVICE unixpal_dev = {
|
|||
NULL, NULL, &pal_proc_reset_unix,
|
||||
NULL, NULL, NULL,
|
||||
NULL, DEV_DIS
|
||||
};
|
||||
};
|
||||
|
||||
/* Unix interrupt evaluator - returns IPL of highest priority interrupt */
|
||||
|
||||
|
|
|
@ -211,7 +211,7 @@ REG vmspal_reg[] = {
|
|||
{ HRDATA (ASTSR, vms_astsr, 4) },
|
||||
{ FLDATA (DATFX, vms_datfx, 0) },
|
||||
{ NULL }
|
||||
};
|
||||
};
|
||||
|
||||
DEVICE vmspal_dev = {
|
||||
"VMSPAL", &vmspal_unit, vmspal_reg, NULL,
|
||||
|
@ -219,7 +219,7 @@ DEVICE vmspal_dev = {
|
|||
NULL, NULL, &pal_proc_reset_vms,
|
||||
NULL, NULL, NULL,
|
||||
NULL, 0
|
||||
};
|
||||
};
|
||||
|
||||
/* VMS interrupt evaluator - returns IPL of highest priority interrupt */
|
||||
|
||||
|
@ -1571,7 +1571,7 @@ if ((pa & (lnt - 1)) == 0) { /* aligned? */
|
|||
if (lnt == L_LONG) return ReadPL (pa); /* long? */
|
||||
if (lnt == L_WORD) return ReadPW (pa); /* word? */
|
||||
return ReadPB (pa); /* byte */
|
||||
}
|
||||
}
|
||||
if ((VA_GETOFF (va) + lnt) > VA_PAGSIZE) { /* cross page? */
|
||||
if (exc = Test (va + 8, acc, &pa1)) /* test, translate */
|
||||
ABORT1 (va + 8, exc + EXC_R);
|
||||
|
|
|
@ -139,5 +139,5 @@ extern unsigned char display_tablet;
|
|||
* users of this library are expected to provide these calls.
|
||||
* simulator will set 18 simulated switches.
|
||||
*/
|
||||
extern unsigned long cpu_get_switches(void); /* get current switch state */
|
||||
extern void cpu_set_switches(unsigned long); /* set switches */
|
||||
extern unsigned long cpu_get_switches(void); /* get current switch state */
|
||||
extern void cpu_set_switches(unsigned long); /* set switches */
|
||||
|
|
|
@ -59,17 +59,17 @@
|
|||
|
||||
/* DIO address */
|
||||
|
||||
#define MUXDIO_V_FNC 0 /* function */
|
||||
#define MUXDIO_M_FNC 0xF
|
||||
#define MUXDIO_V_COC 4 /* ctlr num */
|
||||
#define MUXDIO_M_COC 0xF
|
||||
#define MUXDIO_V_FNC 0 /* function */
|
||||
#define MUXDIO_M_FNC 0xF
|
||||
#define MUXDIO_V_COC 4 /* ctlr num */
|
||||
#define MUXDIO_M_COC 0xF
|
||||
#define MUXDIO_GETFNC(x) (((x) >> MUXDIO_V_FNC) & MUXDIO_M_FNC)
|
||||
#define MUXDIO_GETCOC(x) (((x) >> MUXDIO_V_COC) & MUXDIO_M_COC)
|
||||
|
||||
#define MUXDAT_V_LIN 0 /* line num */
|
||||
#define MUXDAT_M_LIN (MUX_LINES - 1)
|
||||
#define MUXDAT_V_CHR 8 /* output char */
|
||||
#define MUXDAT_M_CHR 0xFF
|
||||
#define MUXDAT_V_LIN 0 /* line num */
|
||||
#define MUXDAT_M_LIN (MUX_LINES - 1)
|
||||
#define MUXDAT_V_CHR 8 /* output char */
|
||||
#define MUXDAT_M_CHR 0xFF
|
||||
#define MUXDAT_GETLIN(x) (((x) >> MUXDAT_V_LIN) & MUXDAT_M_LIN)
|
||||
#define MUXDAT_GETCHR(x) (((x) >> MUXDAT_V_CHR) & MUXDAT_M_CHR)
|
||||
|
||||
|
|
|
@ -724,7 +724,7 @@ switch (op) {
|
|||
PSW1 = ((PSW1 & ~PSW1_FPC) | /* set ctrls */
|
||||
((opnd & PSW1_M_FPC) << PSW1_V_FPC)) &
|
||||
~cpu_tab[cpu_model].psw1_mbz; /* clear mbz */
|
||||
break;
|
||||
break;
|
||||
|
||||
case OP_LCF: /* load cc, flt */
|
||||
if ((tr = Ea (IR, &bva, VR, BY)) != 0) /* get eff addr */
|
||||
|
@ -1118,7 +1118,7 @@ switch (op) {
|
|||
res = R[rn] | opnd;
|
||||
CC34_W (res); /* set CC's */
|
||||
R[rn] = res; /* store */
|
||||
break;
|
||||
break;
|
||||
|
||||
case OP_EOR: /* xor */
|
||||
if ((tr = Ea (IR, &bva, VR, WD)) != 0) /* get eff addr */
|
||||
|
@ -1128,7 +1128,7 @@ switch (op) {
|
|||
res = R[rn] ^ opnd;
|
||||
CC34_W (res); /* set CC's */
|
||||
R[rn] = res; /* store */
|
||||
break;
|
||||
break;
|
||||
|
||||
/* Compares */
|
||||
|
||||
|
@ -1137,7 +1137,7 @@ switch (op) {
|
|||
return tr;
|
||||
opnd = SEXT_LIT_W (opnd) & WMASK; /* sext to 32b */
|
||||
CC234_CMP (R[rn], opnd); /* set CC's */
|
||||
break;
|
||||
break;
|
||||
|
||||
case OP_CB: /* compare byte */
|
||||
if ((tr = Ea (IR, &bva, VR, BY)) != 0) /* get eff addr */
|
||||
|
|
|
@ -170,7 +170,7 @@ typedef struct {
|
|||
#define S_V_MCNT 24 /* string mask/count */
|
||||
#define S_M_MCNT 0xFF
|
||||
#define S_MCNT (S_M_MCNT << S_V_MCNT)
|
||||
#define S_GETMCNT(x) (((x) >> S_V_MCNT) & S_M_MCNT)
|
||||
#define S_GETMCNT(x) (((x) >> S_V_MCNT) & S_M_MCNT)
|
||||
#define S_ADDRINC (S_MCNT + 1)
|
||||
|
||||
/* Data types */
|
||||
|
@ -196,7 +196,7 @@ typedef struct {
|
|||
#define FP_NORM 0x00F00000
|
||||
#define FP_M_FRLO 0xFFFFFFFF /* low fraction */
|
||||
#define FP_GETSIGN(x) (((x) >> FP_V_SIGN) & 1)
|
||||
#define FP_GETEXP(x) (((x) >> FP_V_EXP) & FP_M_EXP)
|
||||
#define FP_GETEXP(x) (((x) >> FP_V_EXP) & FP_M_EXP)
|
||||
#define FP_GETFRHI(x) (((x) >> FP_V_FRHI) & FP_M_FRHI)
|
||||
#define FP_GETFRLO(x) ((x) & FP_M_FRLO)
|
||||
|
||||
|
@ -428,7 +428,7 @@ typedef struct {
|
|||
|
||||
#define SEXT_RN_W(x) (((x) & RNSIGN)? ((x) | ~RNMASK): ((x) & RNMASK))
|
||||
#define SEXT_H_W(x) (((x) & HSIGN)? ((x) | ~HMASK): ((x) & HMASK))
|
||||
#define SEXT_LIT_W(x) (((x) & LITSIGN)? ((x) | ~LITMASK): ((x) & LITMASK))
|
||||
#define SEXT_LIT_W(x) (((x) & LITSIGN)? ((x) | ~LITMASK): ((x) & LITMASK))
|
||||
#define NEG_W(x) ((~(x) + 1) & WMASK)
|
||||
#define NEG_D(x,y) do { y = NEG_W(y); x = (~(x) + ((y) == 0)) & WMASK; } while (0)
|
||||
#define CC34_W(x) CC = (((x) & WSIGN)? \
|
||||
|
|
|
@ -50,8 +50,8 @@
|
|||
#define DKA_M_TK 0x1FF
|
||||
#define DKA_V_SC 0 /* sector offset */
|
||||
#define DKA_M_SC 0xF
|
||||
#define DKA_GETTK(x) (((x) >> DKA_V_TK) & DKA_M_TK)
|
||||
#define DKA_GETSC(x) (((x) >> DKA_V_SC) & DKA_M_SC)
|
||||
#define DKA_GETTK(x) (((x) >> DKA_V_TK) & DKA_M_TK)
|
||||
#define DKA_GETSC(x) (((x) >> DKA_V_SC) & DKA_M_SC)
|
||||
|
||||
/* Status byte 3 is current sector */
|
||||
|
||||
|
|
|
@ -65,9 +65,9 @@
|
|||
#define DPA_M_HD 0x1F
|
||||
#define DPA_V_SC 0 /* sector offset */
|
||||
#define DPA_M_SC 0x1F
|
||||
#define DPA_GETCY(x) (((x) >> DPA_V_CY) & DPA_M_CY)
|
||||
#define DPA_GETCY(x) (((x) >> DPA_V_CY) & DPA_M_CY)
|
||||
#define DPA_GETHD(x) (((x) >> DPA_V_HD) & DPA_M_HD)
|
||||
#define DPA_GETSC(x) (((x) >> DPA_V_SC) & DPA_M_SC)
|
||||
#define DPA_GETSC(x) (((x) >> DPA_V_SC) & DPA_M_SC)
|
||||
|
||||
/* Sense order */
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
|
||||
#include "sigma_defs.h"
|
||||
|
||||
#define BVA_REG (RF_NUM << 2)
|
||||
#define BVA_REG (RF_NUM << 2)
|
||||
#define BPAMASK ((cpu_tab[cpu_model].pamask << 2) | 0x3)
|
||||
#define NUM_MUNITS (MAXMEMSIZE / CPU_MUNIT_SIZE)
|
||||
|
||||
|
|
|
@ -489,7 +489,7 @@ switch (st) {
|
|||
uptr->UST |= MTDV_DTE; /* set DTE flag */
|
||||
chan_set_chf (mt_dib.dva, CHF_XMDE);
|
||||
chan_uen (mt_dib.dva); /* force uend */
|
||||
return SCPE_IOERR;
|
||||
return SCPE_IOERR;
|
||||
|
||||
case MTSE_INVRL: /* invalid rec lnt */
|
||||
uptr->UST |= MTDV_DTE; /* set DTE flag */
|
||||
|
|
|
@ -59,8 +59,8 @@
|
|||
#define RADA_M_TK3 0x3FF
|
||||
#define RADA_V_SC3 0
|
||||
#define RADA_M_SC3 0xF
|
||||
#define RADA_GETTK(x) (((x) >> rad_tab[rad_model].tk_v) & rad_tab[rad_model].tk_m)
|
||||
#define RADA_GETSC(x) (((x) >> rad_tab[rad_model].sc_v) & rad_tab[rad_model].sc_m)
|
||||
#define RADA_GETTK(x) (((x) >> rad_tab[rad_model].tk_v) & rad_tab[rad_model].tk_m)
|
||||
#define RADA_GETSC(x) (((x) >> rad_tab[rad_model].sc_v) & rad_tab[rad_model].sc_m)
|
||||
|
||||
/* Address bad flag */
|
||||
|
||||
|
|
|
@ -370,7 +370,7 @@ if (sw & SWMASK ('C')) { /* char format? */
|
|||
if (sw & SWMASK ('A'))
|
||||
fprintf (of, FMTASC (c & 0x7F));
|
||||
else fprint_ebcdic (of, c);
|
||||
}
|
||||
}
|
||||
return 0; /* return # chars */
|
||||
}
|
||||
if (sw & SWMASK ('A')) { /* ASCII? */
|
||||
|
|
48
sim_video.c
48
sim_video.c
|
@ -1149,30 +1149,30 @@ int vid_video_events (void)
|
|||
SDL_Event event;
|
||||
#if SDL_MAJOR_VERSION == 1
|
||||
static char *eventtypes[] = {
|
||||
"NOEVENT", /**< Unused (do not remove) */
|
||||
"ACTIVEEVENT", /**< Application loses/gains visibility */
|
||||
"KEYDOWN", /**< Keys pressed */
|
||||
"KEYUP", /**< Keys released */
|
||||
"MOUSEMOTION", /**< Mouse moved */
|
||||
"MOUSEBUTTONDOWN", /**< Mouse button pressed */
|
||||
"MOUSEBUTTONUP", /**< Mouse button released */
|
||||
"JOYAXISMOTION", /**< Joystick axis motion */
|
||||
"JOYBALLMOTION", /**< Joystick trackball motion */
|
||||
"JOYHATMOTION", /**< Joystick hat position change */
|
||||
"JOYBUTTONDOWN", /**< Joystick button pressed */
|
||||
"JOYBUTTONUP", /**< Joystick button released */
|
||||
"QUIT", /**< User-requested quit */
|
||||
"SYSWMEVENT", /**< System specific event */
|
||||
"EVENT_RESERVEDA", /**< Reserved for future use.. */
|
||||
"EVENT_RESERVEDB", /**< Reserved for future use.. */
|
||||
"VIDEORESIZE", /**< User resized video mode */
|
||||
"VIDEOEXPOSE", /**< Screen needs to be redrawn */
|
||||
"EVENT_RESERVED2", /**< Reserved for future use.. */
|
||||
"EVENT_RESERVED3", /**< Reserved for future use.. */
|
||||
"EVENT_RESERVED4", /**< Reserved for future use.. */
|
||||
"EVENT_RESERVED5", /**< Reserved for future use.. */
|
||||
"EVENT_RESERVED6", /**< Reserved for future use.. */
|
||||
"EVENT_RESERVED7", /**< Reserved for future use.. */
|
||||
"NOEVENT", /**< Unused (do not remove) */
|
||||
"ACTIVEEVENT", /**< Application loses/gains visibility */
|
||||
"KEYDOWN", /**< Keys pressed */
|
||||
"KEYUP", /**< Keys released */
|
||||
"MOUSEMOTION", /**< Mouse moved */
|
||||
"MOUSEBUTTONDOWN", /**< Mouse button pressed */
|
||||
"MOUSEBUTTONUP", /**< Mouse button released */
|
||||
"JOYAXISMOTION", /**< Joystick axis motion */
|
||||
"JOYBALLMOTION", /**< Joystick trackball motion */
|
||||
"JOYHATMOTION", /**< Joystick hat position change */
|
||||
"JOYBUTTONDOWN", /**< Joystick button pressed */
|
||||
"JOYBUTTONUP", /**< Joystick button released */
|
||||
"QUIT", /**< User-requested quit */
|
||||
"SYSWMEVENT", /**< System specific event */
|
||||
"EVENT_RESERVEDA", /**< Reserved for future use.. */
|
||||
"EVENT_RESERVEDB", /**< Reserved for future use.. */
|
||||
"VIDEORESIZE", /**< User resized video mode */
|
||||
"VIDEOEXPOSE", /**< Screen needs to be redrawn */
|
||||
"EVENT_RESERVED2", /**< Reserved for future use.. */
|
||||
"EVENT_RESERVED3", /**< Reserved for future use.. */
|
||||
"EVENT_RESERVED4", /**< Reserved for future use.. */
|
||||
"EVENT_RESERVED5", /**< Reserved for future use.. */
|
||||
"EVENT_RESERVED6", /**< Reserved for future use.. */
|
||||
"EVENT_RESERVED7", /**< Reserved for future use.. */
|
||||
"USEREVENT", /** Events SDL_USEREVENT(24) through SDL_MAXEVENTS-1(31) are for your use */
|
||||
"",
|
||||
"",
|
||||
|
|
|
@ -32,19 +32,19 @@
|
|||
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
|
||||
------- ---- --------
|
||||
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
|
||||
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):
|
||||
|
||||
|
@ -181,28 +181,28 @@
|
|||
|
||||
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
|
||||
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)
|
||||
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:
|
||||
|
||||
|
@ -224,7 +224,7 @@
|
|||
|
||||
/* emulate a SS FLEX disk with 72 sectors and 80 tracks */
|
||||
|
||||
#define NUM_DISK 4 /* standard 1797 maximum */
|
||||
#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) */
|
||||
|
@ -240,10 +240,10 @@
|
|||
|
||||
/* 1797 status bits */
|
||||
|
||||
#define BUSY 0x01
|
||||
#define DRQ 0x02
|
||||
#define WRPROT 0x40
|
||||
#define NOTRDY 0x80
|
||||
#define BUSY 0x01
|
||||
#define DRQ 0x02
|
||||
#define WRPROT 0x40
|
||||
#define NOTRDY 0x80
|
||||
|
||||
/* function prototypes */
|
||||
|
||||
|
@ -444,7 +444,7 @@ int32 fdccmd(int32 io, int32 data)
|
|||
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) {
|
||||
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 */
|
||||
|
|
|
@ -1918,8 +1918,8 @@ t_stat m6800_reset (DEVICE *dptr)
|
|||
|
||||
|
||||
/* This is the dumper/loader. This command uses the -h to signify a
|
||||
hex dump/load vice a binary one. If no address is given to load, it
|
||||
takes the address from the hex record or the current PC for binary.
|
||||
hex dump/load vice a binary one. If no address is given to load, it
|
||||
takes the address from the hex record or the current PC for binary.
|
||||
*/
|
||||
|
||||
t_stat sim_load (FILE *fileref, char *cptr, char *fnam, int flag)
|
||||
|
|
|
@ -43,9 +43,9 @@
|
|||
+---+---+---+---+---+---+---+---+
|
||||
|
||||
RXF - A 1 in this bit position means a character has been received
|
||||
on the data port and is ready to be read.
|
||||
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.
|
||||
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.
|
||||
|
@ -266,12 +266,12 @@ int32 sio0d(int32 io, int32 data)
|
|||
}
|
||||
if ((odata = getc(ptr_unit.fileref)) == EOF) { // end of file?
|
||||
// printf("Got EOF\n");
|
||||
ptr_unit.u3 &= 0xFE; // clear RXF flag
|
||||
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
|
||||
ptr_unit.u3 &= 0xFE; // clear RXF flag
|
||||
return (odata & 0xFF); // return character
|
||||
} else {
|
||||
sio_unit.u3 &= 0xFE; // clear RXF flag
|
||||
|
@ -312,10 +312,10 @@ int32 sio0d(int32 io, int32 data)
|
|||
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.
|
||||
/* 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)
|
||||
|
|
|
@ -46,12 +46,12 @@ 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
|
||||
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";
|
||||
|
|
|
@ -45,12 +45,12 @@ 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
|
||||
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";
|
||||
|
|
|
@ -33,10 +33,10 @@ Copyright (c) 2005-2012, William Beech
|
|||
|
||||
/* 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)
|
||||
#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 */
|
||||
|
||||
|
@ -51,9 +51,9 @@ Copyright (c) 2005-2012, William Beech
|
|||
|
||||
/* 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
|
||||
#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
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue