1
0
mirror of https://github.com/simh/simh.git synced 2026-04-13 23:44:44 +00:00

Notes For V3.5-0

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

1. New Features in 3.4-1

1.1 All Ethernet devices

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

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

- Added support for SET <unit>n DISCONNECT

1.3 VAX

- Added latent QDSS support
- Revised autoconfigure to handle QDSS

1.4 PDP-11

- Revised autoconfigure to handle more casees

2. Bugs Fixed in 3.4-1

2.1 SCP and libraries

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

2.2 1401

- Fixed bug, CPU reset was clearing SSB through SSG

2.3 PDP-11

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

2.4 Interdata

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

2.5 SDS

- Fixed bug in SHOW MUX CONN/STATS

2.6 HP

- Fixed bug in SHOW MUX CONN/STATS

2.7 PDP-8

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

2.8 PDP-18b

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

2.9 Nova, Eclipse

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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,7 @@
To: Users
From: Bob Supnik
Subj: VAX Simulator Usage
Date: 15-Nov-2004
Date: 01-Jul-2005
COPYRIGHT NOTICE
@@ -27,8 +27,8 @@ The following copyright notice applies to both the SIMH source and binary:
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of Robert M Supnik shall not
be used in advertising or otherwise to promote the sale, use or other dealings
Except as contained in this notice, the name of Robert M Supnik shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik.
This memorandum documents the VAX simulator.
@@ -869,7 +869,7 @@ DISCONNECT command, or a DETACH DZ command.
The SHOW DZ CONNECTIONS command displays the current connections to the DZ.
The SHOW DZ STATISTICS command displays statistics for active connections.
The SET DZ DISCONNECT=linenumber disconnects the specified line.
The SET DZ DISCONNECT=linenumber command disconnects the specified line.
The DZV11 implements these registers:
@@ -953,7 +953,7 @@ a SET VH DISCONNECT command, or a DETACH VH command.
The SHOW VH CONNECTIONS command displays the current connections to the VH.
The SHOW VH STATISTICS command displays statistics for active connections.
The SET VH DISCONNECT=linenumber disconnects the specified line.
The SET VH DISCONNECT=linenumber command disconnects the specified line.
The DHQ11 implements these registers, though not all can be examined
from SCP:

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
/* vax_mm.c - VAX memory management
/* vax_mmu.c - VAX memory management
Copyright (c) 1998-2004, Robert M Supnik
Copyright (c) 1998-2005, Robert M Supnik
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
@@ -19,39 +19,37 @@
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of Robert M Supnik shall not
be used in advertising or otherwise to promote the sale, use or other dealings
Except as contained in this notice, the name of Robert M Supnik shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik.
30-Sep-04 RMS Comment and formating changes
19-Sep-03 RMS Fixed upper/lower case linkage problems on VMS
01-Jun-03 RMS Fixed compilation problem with USE_ADDR64
30-Sep-04 RMS Comment and formating changes
19-Sep-03 RMS Fixed upper/lower case linkage problems on VMS
01-Jun-03 RMS Fixed compilation problem with USE_ADDR64
This module contains the instruction simulators for
Read - read virtual
Write - write virtual
ReadL(P) - read aligned physical longword (physical context)
WriteL(P) - write aligned physical longword (physical context)
ReadB(W) - read aligned physical byte (word)
WriteB(W) - write aligned physical byte (word)
Test - test acccess
Read - read virtual
Write - write virtual
ReadL(P) - read aligned physical longword (physical context)
WriteL(P) - write aligned physical longword (physical context)
ReadB(W) - read aligned physical byte (word)
WriteB(W) - write aligned physical byte (word)
Test - test acccess
zap_tb - clear TB
zap_tb_ent - clear TB entry
chk_tb_ent - check TB entry
set_map_reg - set up working map registers
zap_tb - clear TB
zap_tb_ent - clear TB entry
chk_tb_ent - check TB entry
set_map_reg - set up working map registers
*/
#include "vax_defs.h"
#include <setjmp.h>
struct tlbent {
int32 tag; /* tag */
int32 pte; /* pte */
};
typedef struct tlbent TLBENT;
typedef struct {
int32 tag; /* tag */
int32 pte; /* pte */
} TLBENT;
extern uint32 *M;
extern uint32 align[4];
@@ -65,35 +63,36 @@ extern int32 SISR;
extern jmp_buf save_env;
extern UNIT cpu_unit;
int32 d_p0br, d_p0lr; /* dynamic copies */
int32 d_p1br, d_p1lr; /* altered per ucode */
int32 d_p0br, d_p0lr; /* dynamic copies */
int32 d_p1br, d_p1lr; /* altered per ucode */
int32 d_sbr, d_slr;
extern int32 mchk_va, mchk_ref; /* for mcheck */
extern int32 mchk_va, mchk_ref; /* for mcheck */
TLBENT stlb[VA_TBSIZE], ptlb[VA_TBSIZE];
static const int32 insert[4] = {
0x00000000, 0x000000FF, 0x0000FFFF, 0x00FFFFFF };
0x00000000, 0x000000FF, 0x0000FFFF, 0x00FFFFFF
};
static const int32 cvtacc[16] = { 0, 0,
TLB_ACCW (KERN)+TLB_ACCR (KERN),
TLB_ACCR (KERN),
TLB_ACCW (KERN)+TLB_ACCW (EXEC)+TLB_ACCW (SUPV)+TLB_ACCW (USER)+
TLB_ACCR (KERN)+TLB_ACCR (EXEC)+TLB_ACCR (SUPV)+TLB_ACCR (USER),
TLB_ACCW (KERN)+TLB_ACCW (EXEC)+TLB_ACCR (KERN)+TLB_ACCR (EXEC),
TLB_ACCW (KERN)+TLB_ACCR (KERN)+TLB_ACCR (EXEC),
TLB_ACCR (KERN)+TLB_ACCR (EXEC),
TLB_ACCW (KERN)+TLB_ACCW (EXEC)+TLB_ACCW (SUPV)+
TLB_ACCR (KERN)+TLB_ACCR (EXEC)+TLB_ACCR (SUPV),
TLB_ACCW (KERN)+TLB_ACCW (EXEC)+
TLB_ACCR (KERN)+TLB_ACCR (EXEC)+TLB_ACCR (SUPV),
TLB_ACCW (KERN)+TLB_ACCR (KERN)+TLB_ACCR (EXEC)+TLB_ACCR (SUPV),
TLB_ACCR (KERN)+TLB_ACCR (EXEC)+TLB_ACCR (SUPV),
TLB_ACCW (KERN)+TLB_ACCW (EXEC)+TLB_ACCW (SUPV)+
TLB_ACCR (KERN)+TLB_ACCR (EXEC)+TLB_ACCR (SUPV)+TLB_ACCR (USER),
TLB_ACCW (KERN)+TLB_ACCW (EXEC)+
TLB_ACCR (KERN)+TLB_ACCR (EXEC)+TLB_ACCR (SUPV)+TLB_ACCR (USER),
TLB_ACCW (KERN)+
TLB_ACCR (KERN)+TLB_ACCR (EXEC)+TLB_ACCR (SUPV)+TLB_ACCR (USER),
TLB_ACCR (KERN)+TLB_ACCR (EXEC)+TLB_ACCR (SUPV)+TLB_ACCR (USER)
};
TLB_ACCW (KERN)+TLB_ACCR (KERN),
TLB_ACCR (KERN),
TLB_ACCW (KERN)+TLB_ACCW (EXEC)+TLB_ACCW (SUPV)+TLB_ACCW (USER)+
TLB_ACCR (KERN)+TLB_ACCR (EXEC)+TLB_ACCR (SUPV)+TLB_ACCR (USER),
TLB_ACCW (KERN)+TLB_ACCW (EXEC)+TLB_ACCR (KERN)+TLB_ACCR (EXEC),
TLB_ACCW (KERN)+TLB_ACCR (KERN)+TLB_ACCR (EXEC),
TLB_ACCR (KERN)+TLB_ACCR (EXEC),
TLB_ACCW (KERN)+TLB_ACCW (EXEC)+TLB_ACCW (SUPV)+
TLB_ACCR (KERN)+TLB_ACCR (EXEC)+TLB_ACCR (SUPV),
TLB_ACCW (KERN)+TLB_ACCW (EXEC)+
TLB_ACCR (KERN)+TLB_ACCR (EXEC)+TLB_ACCR (SUPV),
TLB_ACCW (KERN)+TLB_ACCR (KERN)+TLB_ACCR (EXEC)+TLB_ACCR (SUPV),
TLB_ACCR (KERN)+TLB_ACCR (EXEC)+TLB_ACCR (SUPV),
TLB_ACCW (KERN)+TLB_ACCW (EXEC)+TLB_ACCW (SUPV)+
TLB_ACCR (KERN)+TLB_ACCR (EXEC)+TLB_ACCR (SUPV)+TLB_ACCR (USER),
TLB_ACCW (KERN)+TLB_ACCW (EXEC)+
TLB_ACCR (KERN)+TLB_ACCR (EXEC)+TLB_ACCR (SUPV)+TLB_ACCR (USER),
TLB_ACCW (KERN)+
TLB_ACCR (KERN)+TLB_ACCR (EXEC)+TLB_ACCR (SUPV)+TLB_ACCR (USER),
TLB_ACCR (KERN)+TLB_ACCR (EXEC)+TLB_ACCR (SUPV)+TLB_ACCR (USER)
};
t_stat tlb_ex (t_value *vptr, t_addr addr, UNIT *uptr, int32 sw);
t_stat tlb_dep (t_value val, t_addr addr, UNIT *uptr, int32 sw);
@@ -112,52 +111,55 @@ extern int32 ReadIO (uint32 pa, int32 lnt);
extern void WriteIO (uint32 pa, int32 val, int32 lnt);
extern int32 ReadReg (uint32 pa, int32 lnt);
extern void WriteReg (uint32 pa, int32 val, int32 lnt);
/* TLB data structures
tlb_dev pager device descriptor
tlb_unit pager units
pager_reg pager register list
tlb_dev pager device descriptor
tlb_unit pager units
pager_reg pager register list
*/
UNIT tlb_unit[] = {
{ UDATA (NULL, UNIT_FIX, VA_TBSIZE * 2) },
{ UDATA (NULL, UNIT_FIX, VA_TBSIZE * 2) } };
{ UDATA (NULL, UNIT_FIX, VA_TBSIZE * 2) },
{ UDATA (NULL, UNIT_FIX, VA_TBSIZE * 2) }
};
REG tlb_reg[] = {
{ NULL } };
{ NULL }
};
DEVICE tlb_dev = {
"TLB", tlb_unit, tlb_reg, NULL,
2, 16, VA_N_TBI * 2, 1, 16, 32,
&tlb_ex, &tlb_dep, &tlb_reset,
NULL, NULL, NULL };
"TLB", tlb_unit, tlb_reg, NULL,
2, 16, VA_N_TBI * 2, 1, 16, 32,
&tlb_ex, &tlb_dep, &tlb_reset,
NULL, NULL, NULL
};
/* Read and write virtual
These routines logically fall into three phases:
1. Look up the virtual address in the translation buffer, calling
the fill routine on a tag mismatch or access mismatch (invalid
tlb entries have access = 0 and thus always mismatch). The
fill routine handles all errors. If the resulting physical
address is aligned, do an aligned physical read or write.
2. Test for unaligned across page boundaries. If cross page, look
up the physical address of the second page. If not cross page,
the second physical address is the same as the first.
3. Using the two physical addresses, do an unaligned read or
write, with three cases: unaligned long, unaligned word within
a longword, unaligned word crossing a longword boundary.
1. Look up the virtual address in the translation buffer, calling
the fill routine on a tag mismatch or access mismatch (invalid
tlb entries have access = 0 and thus always mismatch). The
fill routine handles all errors. If the resulting physical
address is aligned, do an aligned physical read or write.
2. Test for unaligned across page boundaries. If cross page, look
up the physical address of the second page. If not cross page,
the second physical address is the same as the first.
3. Using the two physical addresses, do an unaligned read or
write, with three cases: unaligned long, unaligned word within
a longword, unaligned word crossing a longword boundary.
*/
/* Read virtual
Inputs:
va = virtual address
lnt = length code (BWLQ)
acc = access code (KESU)
va = virtual address
lnt = length code (BWLQ)
acc = access code (KESU)
Output:
returned data, right justified in 32b longword
returned data, right justified in 32b longword
*/
int32 Read (uint32 va, int32 lnt, int32 acc)
@@ -167,50 +169,56 @@ int32 pa1, bo, sc, wl, wh;
TLBENT xpte;
mchk_va = va;
if (mapen) { /* mapping on? */
vpn = VA_GETVPN (va); /* get vpn, offset */
off = VA_GETOFF (va);
tbi = VA_GETTBI (vpn);
xpte = (va & VA_S0)? stlb[tbi]: ptlb[tbi]; /* access tlb */
if (((xpte.pte & acc) == 0) || (xpte.tag != vpn) ||
((acc & TLB_WACC) && ((xpte.pte & TLB_M) == 0)))
xpte = fill (va, lnt, acc, NULL); /* fill if needed */
pa = (xpte.pte & TLB_PFN) | off; } /* get phys addr */
if (mapen) { /* mapping on? */
vpn = VA_GETVPN (va); /* get vpn, offset */
off = VA_GETOFF (va);
tbi = VA_GETTBI (vpn);
xpte = (va & VA_S0)? stlb[tbi]: ptlb[tbi]; /* access tlb */
if (((xpte.pte & acc) == 0) || (xpte.tag != vpn) ||
((acc & TLB_WACC) && ((xpte.pte & TLB_M) == 0)))
xpte = fill (va, lnt, acc, NULL); /* fill if needed */
pa = (xpte.pte & TLB_PFN) | off; /* get phys addr */
}
else pa = va & PAMASK;
if ((pa & (lnt - 1)) == 0) { /* aligned? */
if (lnt >= L_LONG) return ReadL (pa); /* long, quad? */
if (lnt == L_WORD) return ReadW (pa); /* word? */
return ReadB (pa); } /* byte */
if (mapen && ((off + lnt) > VA_PAGSIZE)) { /* cross page? */
vpn = VA_GETVPN (va + lnt); /* vpn 2nd page */
tbi = VA_GETTBI (vpn);
xpte = (va & VA_S0)? stlb[tbi]: ptlb[tbi]; /* access tlb */
if (((xpte.pte & acc) == 0) || (xpte.tag != vpn) ||
((acc & TLB_WACC) && ((xpte.pte & TLB_M) == 0)))
xpte = fill (va + lnt, lnt, acc, NULL); /* fill if needed */
pa1 = (xpte.pte & TLB_PFN) | VA_GETOFF (va + 4); }
else pa1 = (pa + 4) & PAMASK; /* not cross page */
if ((pa & (lnt - 1)) == 0) { /* aligned? */
if (lnt >= L_LONG) return ReadL (pa); /* long, quad? */
if (lnt == L_WORD) return ReadW (pa); /* word? */
return ReadB (pa); /* byte */
}
if (mapen && ((off + lnt) > VA_PAGSIZE)) { /* cross page? */
vpn = VA_GETVPN (va + lnt); /* vpn 2nd page */
tbi = VA_GETTBI (vpn);
xpte = (va & VA_S0)? stlb[tbi]: ptlb[tbi]; /* access tlb */
if (((xpte.pte & acc) == 0) || (xpte.tag != vpn) ||
((acc & TLB_WACC) && ((xpte.pte & TLB_M) == 0)))
xpte = fill (va + lnt, lnt, acc, NULL); /* fill if needed */
pa1 = (xpte.pte & TLB_PFN) | VA_GETOFF (va + 4);
}
else pa1 = (pa + 4) & PAMASK; /* not cross page */
bo = pa & 3;
if (lnt >= L_LONG) { /* lw unaligned? */
sc = bo << 3;
wl = ReadL (pa); /* read both lw */
wh = ReadL (pa1); /* extract */
return ((((wl >> sc) & align[bo]) | (wh << (32 - sc))) & LMASK); }
if (lnt >= L_LONG) { /* lw unaligned? */
sc = bo << 3;
wl = ReadL (pa); /* read both lw */
wh = ReadL (pa1); /* extract */
return ((((wl >> sc) & align[bo]) | (wh << (32 - sc))) & LMASK);
}
else if (bo == 1) return ((ReadL (pa) >> 8) & WMASK);
else { wl = ReadL (pa); /* word cross lw */
wh = ReadL (pa1); /* read, extract */
return (((wl >> 24) & 0xFF) | ((wh & 0xFF) << 8)); }
else {
wl = ReadL (pa); /* word cross lw */
wh = ReadL (pa1); /* read, extract */
return (((wl >> 24) & 0xFF) | ((wh & 0xFF) << 8));
}
}
/* Write virtual
Inputs:
va = virtual address
val = data to be written, right justified in 32b lw
lnt = length code (BWLQ)
acc = access code (KESU)
va = virtual address
val = data to be written, right justified in 32b lw
lnt = length code (BWLQ)
acc = access code (KESU)
Output:
none
none
*/
void Write (uint32 va, int32 val, int32 lnt, int32 acc)
@@ -221,49 +229,56 @@ TLBENT xpte;
mchk_va = va;
if (mapen) {
vpn = VA_GETVPN (va);
off = VA_GETOFF (va);
tbi = VA_GETTBI (vpn);
xpte = (va & VA_S0)? stlb[tbi]: ptlb[tbi]; /* access tlb */
if (((xpte.pte & acc) == 0) || (xpte.tag != vpn) ||
((xpte.pte & TLB_M) == 0))
xpte = fill (va, lnt, acc, NULL);
pa = (xpte.pte & TLB_PFN) | off; }
vpn = VA_GETVPN (va);
off = VA_GETOFF (va);
tbi = VA_GETTBI (vpn);
xpte = (va & VA_S0)? stlb[tbi]: ptlb[tbi]; /* access tlb */
if (((xpte.pte & acc) == 0) || (xpte.tag != vpn) ||
((xpte.pte & TLB_M) == 0))
xpte = fill (va, lnt, acc, NULL);
pa = (xpte.pte & TLB_PFN) | off;
}
else pa = va & PAMASK;
if ((pa & (lnt - 1)) == 0) { /* aligned? */
if (lnt >= L_LONG) WriteL (pa, val); /* long, quad? */
else if (lnt == L_WORD) WriteW (pa, val); /* word? */
else WriteB (pa, val); /* byte */
return; }
if ((pa & (lnt - 1)) == 0) { /* aligned? */
if (lnt >= L_LONG) WriteL (pa, val); /* long, quad? */
else if (lnt == L_WORD) WriteW (pa, val); /* word? */
else WriteB (pa, val); /* byte */
return;
}
if (mapen && ((off + lnt) > VA_PAGSIZE)) {
vpn = VA_GETVPN (va + 4);
tbi = VA_GETTBI (vpn);
xpte = (va & VA_S0)? stlb[tbi]: ptlb[tbi]; /* access tlb */
if (((xpte.pte & acc) == 0) || (xpte.tag != vpn) ||
((xpte.pte & TLB_M) == 0))
xpte = fill (va + lnt, lnt, acc, NULL);
pa1 = (xpte.pte & TLB_PFN) | VA_GETOFF (va + 4); }
vpn = VA_GETVPN (va + 4);
tbi = VA_GETTBI (vpn);
xpte = (va & VA_S0)? stlb[tbi]: ptlb[tbi]; /* access tlb */
if (((xpte.pte & acc) == 0) || (xpte.tag != vpn) ||
((xpte.pte & TLB_M) == 0))
xpte = fill (va + lnt, lnt, acc, NULL);
pa1 = (xpte.pte & TLB_PFN) | VA_GETOFF (va + 4);
}
else pa1 = (pa + 4) & PAMASK;
bo = pa & 3;
wl = ReadL (pa);
if (lnt >= L_LONG) {
sc = bo << 3;
wh = ReadL (pa1);
wl = (wl & insert[bo]) | ((val << sc) & LMASK);
wh = (wh & ~insert[bo]) | ((val >> (32 - sc)) & insert[bo]);
WriteL (pa, wl);
WriteL (pa1, wh); }
sc = bo << 3;
wh = ReadL (pa1);
wl = (wl & insert[bo]) | ((val << sc) & LMASK);
wh = (wh & ~insert[bo]) | ((val >> (32 - sc)) & insert[bo]);
WriteL (pa, wl);
WriteL (pa1, wh);
}
else if (bo == 1) {
wl = (wl & 0xFF0000FF) | (val << 8);
WriteL (pa, wl); }
else { wh = ReadL (pa1);
wl = (wl & 0x00FFFFFF) | ((val & 0xFF) << 24);
wh = (wh & 0xFFFFFF00) | ((val >> 8) & 0xFF);
WriteL (pa, wl);
WriteL (pa1, wh); }
wl = (wl & 0xFF0000FF) | (val << 8);
WriteL (pa, wl);
}
else {
wh = ReadL (pa1);
wl = (wl & 0x00FFFFFF) | ((val & 0xFF) << 24);
wh = (wh & 0xFFFFFF00) | ((val >> 8) & 0xFF);
WriteL (pa, wl);
WriteL (pa1, wh);
}
return;
}
/* Test access to a byte (VAX PROBEx) */
int32 Test (int32 va, int32 acc, int32 *status)
@@ -271,26 +286,27 @@ int32 Test (int32 va, int32 acc, int32 *status)
int32 vpn, off, tbi;
TLBENT xpte;
*status = PR_OK; /* assume ok */
if (mapen) { /* mapping on? */
vpn = VA_GETVPN (va); /* get vpn, off */
off = VA_GETOFF (va);
tbi = VA_GETTBI (vpn);
xpte = (va & VA_S0)? stlb[tbi]: ptlb[tbi]; /* access tlb */
if ((xpte.pte & acc) && (xpte.tag == vpn)) /* TB hit, acc ok? */
return (xpte.pte & TLB_PFN) | off;
xpte = fill (va, L_BYTE, acc, status); /* fill TB */
if (*status == PR_OK) return (xpte.pte & TLB_PFN) | off;
else return -1; }
return va & PAMASK; /* ret phys addr */
*status = PR_OK; /* assume ok */
if (mapen) { /* mapping on? */
vpn = VA_GETVPN (va); /* get vpn, off */
off = VA_GETOFF (va);
tbi = VA_GETTBI (vpn);
xpte = (va & VA_S0)? stlb[tbi]: ptlb[tbi]; /* access tlb */
if ((xpte.pte & acc) && (xpte.tag == vpn)) /* TB hit, acc ok? */
return (xpte.pte & TLB_PFN) | off;
xpte = fill (va, L_BYTE, acc, status); /* fill TB */
if (*status == PR_OK) return (xpte.pte & TLB_PFN) | off;
else return -1;
}
return va & PAMASK; /* ret phys addr */
}
/* Read aligned physical (in virtual context, unless indicated)
Inputs:
pa = physical address, naturally aligned
pa = physical address, naturally aligned
Output:
returned data, right justified in 32b longword
returned data, right justified in 32b longword
*/
int32 ReadB (uint32 pa)
@@ -298,9 +314,11 @@ int32 ReadB (uint32 pa)
int32 dat;
if (ADDR_IS_MEM (pa)) dat = M[pa >> 2];
else { mchk_ref = REF_V;
if (ADDR_IS_IO (pa)) dat = ReadIO (pa, L_BYTE);
else dat = ReadReg (pa, L_BYTE); }
else {
mchk_ref = REF_V;
if (ADDR_IS_IO (pa)) dat = ReadIO (pa, L_BYTE);
else dat = ReadReg (pa, L_BYTE);
}
return ((dat >> ((pa & 3) << 3)) & BMASK);
}
@@ -309,9 +327,11 @@ int32 ReadW (uint32 pa)
int32 dat;
if (ADDR_IS_MEM (pa)) dat = M[pa >> 2];
else { mchk_ref = REF_V;
if (ADDR_IS_IO (pa)) dat = ReadIO (pa, L_WORD);
else dat = ReadReg (pa, L_WORD); }
else {
mchk_ref = REF_V;
if (ADDR_IS_IO (pa)) dat = ReadIO (pa, L_WORD);
else dat = ReadReg (pa, L_WORD);
}
return ((dat >> ((pa & 2)? 16: 0)) & WMASK);
}
@@ -335,56 +355,66 @@ return ReadReg (pa, L_LONG);
/* Write aligned physical (in virtual context, unless indicated)
Inputs:
pa = physical address, naturally aligned
val = data to be written, right justified in 32b longword
pa = physical address, naturally aligned
val = data to be written, right justified in 32b longword
Output:
none
none
*/
void WriteB (uint32 pa, int32 val)
{
if (ADDR_IS_MEM (pa)) {
int32 id = pa >> 2;
int32 sc = (pa & 3) << 3;
int32 mask = 0xFF << sc;
M[id] = (M[id] & ~mask) | (val << sc); }
else { mchk_ref = REF_V;
if (ADDR_IS_IO (pa)) WriteIO (pa, val, L_BYTE);
else WriteReg (pa, val, L_BYTE); }
int32 id = pa >> 2;
int32 sc = (pa & 3) << 3;
int32 mask = 0xFF << sc;
M[id] = (M[id] & ~mask) | (val << sc);
}
else {
mchk_ref = REF_V;
if (ADDR_IS_IO (pa)) WriteIO (pa, val, L_BYTE);
else WriteReg (pa, val, L_BYTE);
}
return;
}
void WriteW (uint32 pa, int32 val)
{
if (ADDR_IS_MEM (pa)) {
int32 id = pa >> 2;
M[id] = (pa & 2)? (M[id] & 0xFFFF) | (val << 16):
(M[id] & ~0xFFFF) | val; }
else { mchk_ref = REF_V;
if (ADDR_IS_IO (pa)) WriteIO (pa, val, L_WORD);
else WriteReg (pa, val, L_WORD); }
int32 id = pa >> 2;
M[id] = (pa & 2)? (M[id] & 0xFFFF) | (val << 16):
(M[id] & ~0xFFFF) | val;
}
else {
mchk_ref = REF_V;
if (ADDR_IS_IO (pa)) WriteIO (pa, val, L_WORD);
else WriteReg (pa, val, L_WORD);
}
return;
}
void WriteL (uint32 pa, int32 val)
{
if (ADDR_IS_MEM (pa)) M[pa >> 2] = val;
else { mchk_ref = REF_V;
if (ADDR_IS_IO (pa)) WriteIO (pa, val, L_LONG);
else WriteReg (pa, val, L_LONG); }
else {
mchk_ref = REF_V;
if (ADDR_IS_IO (pa)) WriteIO (pa, val, L_LONG);
else WriteReg (pa, val, L_LONG);
}
return;
}
void WriteLP (uint32 pa, int32 val)
{
if (ADDR_IS_MEM (pa)) M[pa >> 2] = val;
else { mchk_va = pa;
mchk_ref = REF_P;
if (ADDR_IS_IO (pa)) WriteIO (pa, val, L_LONG);
else WriteReg (pa, val, L_LONG); }
else {
mchk_va = pa;
mchk_ref = REF_P;
if (ADDR_IS_IO (pa)) WriteIO (pa, val, L_LONG);
else WriteReg (pa, val, L_LONG);
}
return;
}
/* TLB fill
This routine fills the TLB after a tag or access mismatch, or
@@ -397,10 +427,10 @@ return;
*/
#define MM_ERR(param) { \
if (stat) { *stat = param; return zero_pte; } \
p1 = MM_PARAM (acc & TLB_WACC, param); \
p2 = va; \
ABORT ((param & PR_TNV)? ABORT_TNV: ABORT_ACV); }
if (stat) { *stat = param; return zero_pte; } \
p1 = MM_PARAM (acc & TLB_WACC, param); \
p2 = va; \
ABORT ((param & PR_TNV)? ABORT_TNV: ABORT_ACV); }
TLBENT fill (uint32 va, int32 lnt, int32 acc, int32 *stat)
{
@@ -408,58 +438,65 @@ int32 ptidx = (((uint32) va) >> 7) & ~03;
int32 tlbpte, ptead, pte, tbi, vpn;
static TLBENT zero_pte = { 0, 0 };
if (va & VA_S0) { /* system space? */
if (ptidx >= d_slr) MM_ERR (PR_LNV); /* system */
ptead = d_sbr + ptidx; }
else { if (va & VA_P1) { /* P1? */
if (ptidx < d_p1lr) MM_ERR (PR_LNV);
ptead = d_p1br + ptidx; }
else { /* P0 */
if (ptidx >= d_p0lr)
MM_ERR (PR_LNV);
ptead = d_p0br + ptidx; }
if ((ptead & VA_S0) == 0)
ABORT (STOP_PPTE); /* ppte must be sys */
vpn = VA_GETVPN (ptead); /* get vpn, tbi */
tbi = VA_GETTBI (vpn);
if (stlb[tbi].tag != vpn) { /* in sys tlb? */
ptidx = ((uint32) ptead) >> 7; /* xlate like sys */
if (ptidx >= d_slr) MM_ERR (PR_PLNV);
pte = ReadLP (d_sbr + ptidx); /* get system pte */
if ((pte & PTE_V) == 0) MM_ERR (PR_PTNV); /* spte TNV? */
stlb[tbi].tag = vpn; /* set stlb tag */
stlb[tbi].pte = cvtacc[PTE_GETACC (pte)] |
((pte << VA_N_OFF) & TLB_PFN); } /* set stlb data */
ptead = (stlb[tbi].pte & TLB_PFN) | VA_GETOFF (ptead); }
pte = ReadL (ptead); /* read pte */
tlbpte = cvtacc[PTE_GETACC (pte)] | /* cvt access */
((pte << VA_N_OFF) & TLB_PFN); /* set addr */
if ((tlbpte & acc) == 0) MM_ERR (PR_ACV); /* chk access */
if ((pte & PTE_V) == 0) MM_ERR (PR_TNV); /* check valid */
if (acc & TLB_WACC) { /* write? */
if ((pte & PTE_M) == 0) WriteL (ptead, pte | PTE_M);
tlbpte = tlbpte | TLB_M; } /* set M */
if (va & VA_S0) { /* system space? */
if (ptidx >= d_slr) MM_ERR (PR_LNV); /* system */
ptead = d_sbr + ptidx;
}
else {
if (va & VA_P1) { /* P1? */
if (ptidx < d_p1lr) MM_ERR (PR_LNV);
ptead = d_p1br + ptidx;
}
else { /* P0 */
if (ptidx >= d_p0lr) MM_ERR (PR_LNV);
ptead = d_p0br + ptidx;
}
if ((ptead & VA_S0) == 0)
ABORT (STOP_PPTE); /* ppte must be sys */
vpn = VA_GETVPN (ptead); /* get vpn, tbi */
tbi = VA_GETTBI (vpn);
if (stlb[tbi].tag != vpn) { /* in sys tlb? */
ptidx = ((uint32) ptead) >> 7; /* xlate like sys */
if (ptidx >= d_slr) MM_ERR (PR_PLNV);
pte = ReadLP (d_sbr + ptidx); /* get system pte */
if ((pte & PTE_V) == 0) MM_ERR (PR_PTNV); /* spte TNV? */
stlb[tbi].tag = vpn; /* set stlb tag */
stlb[tbi].pte = cvtacc[PTE_GETACC (pte)] |
((pte << VA_N_OFF) & TLB_PFN); /* set stlb data */
}
ptead = (stlb[tbi].pte & TLB_PFN) | VA_GETOFF (ptead);
}
pte = ReadL (ptead); /* read pte */
tlbpte = cvtacc[PTE_GETACC (pte)] | /* cvt access */
((pte << VA_N_OFF) & TLB_PFN); /* set addr */
if ((tlbpte & acc) == 0) MM_ERR (PR_ACV); /* chk access */
if ((pte & PTE_V) == 0) MM_ERR (PR_TNV); /* check valid */
if (acc & TLB_WACC) { /* write? */
if ((pte & PTE_M) == 0) WriteL (ptead, pte | PTE_M);
tlbpte = tlbpte | TLB_M; /* set M */
}
vpn = VA_GETVPN (va);
tbi = VA_GETTBI (vpn);
if ((va & VA_S0) == 0) { /* process space? */
ptlb[tbi].tag = vpn; /* store tlb ent */
ptlb[tbi].pte = tlbpte;
return ptlb[tbi]; }
stlb[tbi].tag = vpn; /* system space */
stlb[tbi].pte = tlbpte; /* store tlb ent */
if ((va & VA_S0) == 0) { /* process space? */
ptlb[tbi].tag = vpn; /* store tlb ent */
ptlb[tbi].pte = tlbpte;
return ptlb[tbi];
}
stlb[tbi].tag = vpn; /* system space */
stlb[tbi].pte = tlbpte; /* store tlb ent */
return stlb[tbi];
}
/* Utility routines */
extern void set_map_reg (void)
{
d_p0br = P0BR & ~03;
d_p1br = (P1BR - 0x800000) & ~03; /* VA<30> >> 7 */
d_sbr = (SBR - 0x1000000) & ~03; /* VA<31> >> 7 */
d_p1br = (P1BR - 0x800000) & ~03; /* VA<30> >> 7 */
d_sbr = (SBR - 0x1000000) & ~03; /* VA<31> >> 7 */
d_p0lr = (P0LR << 2);
d_p1lr = (P1LR << 2) + 0x800000; /* VA<30> >> 7 */
d_slr = (SLR << 2) + 0x1000000; /* VA<31> >> 7 */
d_p1lr = (P1LR << 2) + 0x800000; /* VA<30> >> 7 */
d_slr = (SLR << 2) + 0x1000000; /* VA<31> >> 7 */
return;
}
@@ -470,8 +507,9 @@ void zap_tb (int stb)
int32 i;
for (i = 0; i < VA_TBSIZE; i++) {
ptlb[i].tag = ptlb[i].pte = -1;
if (stb) stlb[i].tag = stlb[i].pte = -1; }
ptlb[i].tag = ptlb[i].pte = -1;
if (stb) stlb[i].tag = stlb[i].pte = -1;
}
return;
}
@@ -498,7 +536,7 @@ xpte = (va & VA_S0)? stlb[tbi]: ptlb[tbi];
if (xpte.tag == vpn) return TRUE;
return FALSE;
}
/* TLB examine */
t_stat tlb_ex (t_value *vptr, t_addr addr, UNIT *uptr, int32 sw)
@@ -521,10 +559,13 @@ int32 idx = (uint32) addr >> 1;
if (idx >= VA_TBSIZE) return SCPE_NXM;
if (addr & 1) {
if (tlbn) stlb[idx].pte = (int32) val;
else ptlb[idx].pte = (int32) val; }
else { if (tlbn) stlb[idx].tag = (int32) val;
else ptlb[idx].tag = (int32) val; }
if (tlbn) stlb[idx].pte = (int32) val;
else ptlb[idx].pte = (int32) val;
}
else {
if (tlbn) stlb[idx].tag = (int32) val;
else ptlb[idx].tag = (int32) val;
}
return SCPE_OK;
}
@@ -535,6 +576,6 @@ t_stat tlb_reset (DEVICE *dptr)
int32 i;
for (i = 0; i < VA_TBSIZE; i++)
stlb[i].tag = ptlb[i].tag = stlb[i].pte = ptlb[i].pte = -1;
stlb[i].tag = ptlb[i].tag = stlb[i].pte = ptlb[i].pte = -1;
return SCPE_OK;
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
/* vax_stddev.c: VAX 3900 standard I/O devices
Copyright (c) 1998-2004, Robert M Supnik
Copyright (c) 1998-2005, Robert M Supnik
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
@@ -19,57 +19,57 @@
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of Robert M Supnik shall not
be used in advertising or otherwise to promote the sale, use or other dealings
Except as contained in this notice, the name of Robert M Supnik shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik.
tti terminal input
tto terminal output
clk 100Hz and TODR clock
tti terminal input
tto terminal output
clk 100Hz and TODR clock
09-Sep-04 RMS Integrated powerup into RESET (with -p)
28-May-04 RMS Removed SET TTI CTRL-C
29-Dec-03 RMS Added console backpressure support
25-Apr-03 RMS Revised for extended file support
02-Mar-02 RMS Added SET TTI CTRL-C
22-Dec-02 RMS Added console halt capability
01-Nov-02 RMS Added 7B/8B capability to terminal
12-Sep-02 RMS Removed paper tape, added variable vector support
30-May-02 RMS Widened POS to 32b
30-Apr-02 RMS Automatically set TODR to VMS-correct value during boot
09-Sep-04 RMS Integrated powerup into RESET (with -p)
28-May-04 RMS Removed SET TTI CTRL-C
29-Dec-03 RMS Added console backpressure support
25-Apr-03 RMS Revised for extended file support
02-Mar-02 RMS Added SET TTI CTRL-C
22-Dec-02 RMS Added console halt capability
01-Nov-02 RMS Added 7B/8B capability to terminal
12-Sep-02 RMS Removed paper tape, added variable vector support
30-May-02 RMS Widened POS to 32b
30-Apr-02 RMS Automatically set TODR to VMS-correct value during boot
*/
#include "vax_defs.h"
#include <time.h>
#define TTICSR_IMP (CSR_DONE + CSR_IE) /* terminal input */
#define TTICSR_RW (CSR_IE)
#define TTIBUF_ERR 0x8000 /* error */
#define TTIBUF_OVR 0x4000 /* overrun */
#define TTIBUF_FRM 0x2000 /* framing error */
#define TTIBUF_RBR 0x0400 /* receive break */
#define TTOCSR_IMP (CSR_DONE + CSR_IE) /* terminal output */
#define TTOCSR_RW (CSR_IE)
#define CLKCSR_IMP (CSR_IE) /* real-time clock */
#define CLKCSR_RW (CSR_IE)
#define CLK_DELAY 5000 /* 100 Hz */
#define TMXR_MULT 2 /* 50 Hz */
#define TTICSR_IMP (CSR_DONE + CSR_IE) /* terminal input */
#define TTICSR_RW (CSR_IE)
#define TTIBUF_ERR 0x8000 /* error */
#define TTIBUF_OVR 0x4000 /* overrun */
#define TTIBUF_FRM 0x2000 /* framing error */
#define TTIBUF_RBR 0x0400 /* receive break */
#define TTOCSR_IMP (CSR_DONE + CSR_IE) /* terminal output */
#define TTOCSR_RW (CSR_IE)
#define CLKCSR_IMP (CSR_IE) /* real-time clock */
#define CLKCSR_RW (CSR_IE)
#define CLK_DELAY 5000 /* 100 Hz */
#define TMXR_MULT 2 /* 50 Hz */
#define UNIT_V_8B (UNIT_V_UF + 0) /* 8B mode */
#define UNIT_8B (1 << UNIT_V_8B)
#define UNIT_V_8B (UNIT_V_UF + 0) /* 8B mode */
#define UNIT_8B (1 << UNIT_V_8B)
extern int32 int_req[IPL_HLVL];
extern int32 hlt_pin;
extern int32 sim_switches;
int32 tti_csr = 0; /* control/status */
int32 tto_csr = 0; /* control/status */
int32 clk_csr = 0; /* control/status */
int32 clk_tps = 100; /* ticks/second */
int32 todr_reg = 0; /* TODR register */
int32 todr_blow = 1; /* TODR battery low */
int32 tmxr_poll = CLK_DELAY * TMXR_MULT; /* term mux poll */
int32 tmr_poll = CLK_DELAY; /* pgm timer poll */
int32 tti_csr = 0; /* control/status */
int32 tto_csr = 0; /* control/status */
int32 clk_csr = 0; /* control/status */
int32 clk_tps = 100; /* ticks/second */
int32 todr_reg = 0; /* TODR register */
int32 todr_blow = 1; /* TODR battery low */
int32 tmxr_poll = CLK_DELAY * TMXR_MULT; /* term mux poll */
int32 tmr_poll = CLK_DELAY; /* pgm timer poll */
t_stat tti_svc (UNIT *uptr);
t_stat tto_svc (UNIT *uptr);
@@ -79,12 +79,12 @@ t_stat tto_reset (DEVICE *dptr);
t_stat clk_reset (DEVICE *dptr);
extern int32 sysd_hlt_enb (void);
/* TTI data structures
tti_dev TTI device descriptor
tti_unit TTI unit descriptor
tti_reg TTI register list
tti_dev TTI device descriptor
tti_unit TTI unit descriptor
tti_reg TTI register list
*/
DIB tti_dib = { 0, 0, NULL, NULL, 1, IVCL (TTI), SCB_TTI, { NULL } };
@@ -92,34 +92,37 @@ DIB tti_dib = { 0, 0, NULL, NULL, 1, IVCL (TTI), SCB_TTI, { NULL } };
UNIT tti_unit = { UDATA (&tti_svc, UNIT_8B, 0), KBD_POLL_WAIT };
REG tti_reg[] = {
{ HRDATA (BUF, tti_unit.buf, 16) },
{ HRDATA (CSR, tti_csr, 16) },
{ FLDATA (INT, int_req[IPL_TTI], INT_V_TTI) },
{ FLDATA (DONE, tti_csr, CSR_V_DONE) },
{ FLDATA (IE, tti_csr, CSR_V_IE) },
{ DRDATA (POS, tti_unit.pos, T_ADDR_W), PV_LEFT },
{ DRDATA (TIME, tti_unit.wait, 24), REG_NZ + PV_LEFT },
{ NULL } };
{ HRDATA (BUF, tti_unit.buf, 16) },
{ HRDATA (CSR, tti_csr, 16) },
{ FLDATA (INT, int_req[IPL_TTI], INT_V_TTI) },
{ FLDATA (DONE, tti_csr, CSR_V_DONE) },
{ FLDATA (IE, tti_csr, CSR_V_IE) },
{ DRDATA (POS, tti_unit.pos, T_ADDR_W), PV_LEFT },
{ DRDATA (TIME, tti_unit.wait, 24), REG_NZ + PV_LEFT },
{ NULL }
};
MTAB tti_mod[] = {
{ UNIT_8B, UNIT_8B, "8b", "8B", NULL },
{ UNIT_8B, 0 , "7b", "7B", NULL },
{ MTAB_XTD|MTAB_VDV, 0, "VECTOR", NULL,
NULL, &show_vec, NULL },
{ 0 } };
{ UNIT_8B, UNIT_8B, "8b", "8B", NULL },
{ UNIT_8B, 0 , "7b", "7B", NULL },
{ MTAB_XTD|MTAB_VDV, 0, "VECTOR", NULL,
NULL, &show_vec, NULL },
{ 0 }
};
DEVICE tti_dev = {
"TTI", &tti_unit, tti_reg, tti_mod,
1, 10, 31, 1, 16, 8,
NULL, NULL, &tti_reset,
NULL, NULL, NULL,
&tti_dib, 0 };
"TTI", &tti_unit, tti_reg, tti_mod,
1, 10, 31, 1, 16, 8,
NULL, NULL, &tti_reset,
NULL, NULL, NULL,
&tti_dib, 0
};
/* TTO data structures
tto_dev TTO device descriptor
tto_unit TTO unit descriptor
tto_reg TTO register list
tto_dev TTO device descriptor
tto_unit TTO unit descriptor
tto_reg TTO register list
*/
DIB tto_dib = { 0, 0, NULL, NULL, 1, IVCL (TTO), SCB_TTO, { NULL } };
@@ -127,33 +130,36 @@ DIB tto_dib = { 0, 0, NULL, NULL, 1, IVCL (TTO), SCB_TTO, { NULL } };
UNIT tto_unit = { UDATA (&tto_svc, UNIT_8B, 0), SERIAL_OUT_WAIT };
REG tto_reg[] = {
{ HRDATA (BUF, tto_unit.buf, 8) },
{ HRDATA (CSR, tto_csr, 16) },
{ FLDATA (INT, int_req[IPL_TTO], INT_V_TTO) },
{ FLDATA (DONE, tto_csr, CSR_V_DONE) },
{ FLDATA (IE, tto_csr, CSR_V_IE) },
{ DRDATA (POS, tto_unit.pos, T_ADDR_W), PV_LEFT },
{ DRDATA (TIME, tto_unit.wait, 24), PV_LEFT },
{ NULL } };
{ HRDATA (BUF, tto_unit.buf, 8) },
{ HRDATA (CSR, tto_csr, 16) },
{ FLDATA (INT, int_req[IPL_TTO], INT_V_TTO) },
{ FLDATA (DONE, tto_csr, CSR_V_DONE) },
{ FLDATA (IE, tto_csr, CSR_V_IE) },
{ DRDATA (POS, tto_unit.pos, T_ADDR_W), PV_LEFT },
{ DRDATA (TIME, tto_unit.wait, 24), PV_LEFT },
{ NULL }
};
MTAB tto_mod[] = {
{ UNIT_8B, UNIT_8B, "8b", "8B", NULL },
{ UNIT_8B, 0 , "7b", "7B", NULL },
{ MTAB_XTD|MTAB_VDV, 0, "VECTOR", NULL, NULL, &show_vec },
{ 0 } };
{ UNIT_8B, UNIT_8B, "8b", "8B", NULL },
{ UNIT_8B, 0 , "7b", "7B", NULL },
{ MTAB_XTD|MTAB_VDV, 0, "VECTOR", NULL, NULL, &show_vec },
{ 0 }
};
DEVICE tto_dev = {
"TTO", &tto_unit, tto_reg, tto_mod,
1, 10, 31, 1, 16, 8,
NULL, NULL, &tto_reset,
NULL, NULL, NULL,
&tto_dib, 0 };
"TTO", &tto_unit, tto_reg, tto_mod,
1, 10, 31, 1, 16, 8,
NULL, NULL, &tto_reset,
NULL, NULL, NULL,
&tto_dib, 0
};
/* CLK data structures
clk_dev CLK device descriptor
clk_unit CLK unit descriptor
clk_reg CLK register list
clk_dev CLK device descriptor
clk_unit CLK unit descriptor
clk_reg CLK register list
*/
DIB clk_dib = { 0, 0, NULL, NULL, 1, IVCL (CLK), SCB_INTTIM, { NULL } };
@@ -161,34 +167,37 @@ DIB clk_dib = { 0, 0, NULL, NULL, 1, IVCL (CLK), SCB_INTTIM, { NULL } };
UNIT clk_unit = { UDATA (&clk_svc, 0, 0), CLK_DELAY };
REG clk_reg[] = {
{ HRDATA (CSR, clk_csr, 16) },
{ FLDATA (INT, int_req[IPL_CLK], INT_V_CLK) },
{ FLDATA (IE, clk_csr, CSR_V_IE) },
{ DRDATA (TODR, todr_reg, 32), PV_LEFT },
{ FLDATA (BLOW, todr_blow, 0) },
{ DRDATA (TIME, clk_unit.wait, 24), REG_NZ + PV_LEFT },
{ DRDATA (TPS, clk_tps, 8), REG_NZ + PV_LEFT },
{ NULL } };
{ HRDATA (CSR, clk_csr, 16) },
{ FLDATA (INT, int_req[IPL_CLK], INT_V_CLK) },
{ FLDATA (IE, clk_csr, CSR_V_IE) },
{ DRDATA (TODR, todr_reg, 32), PV_LEFT },
{ FLDATA (BLOW, todr_blow, 0) },
{ DRDATA (TIME, clk_unit.wait, 24), REG_NZ + PV_LEFT },
{ DRDATA (TPS, clk_tps, 8), REG_NZ + PV_LEFT },
{ NULL }
};
MTAB clk_mod[] = {
{ MTAB_XTD|MTAB_VDV, 0, "VECTOR", NULL, NULL, &show_vec },
{ 0 } };
{ MTAB_XTD|MTAB_VDV, 0, "VECTOR", NULL, NULL, &show_vec },
{ 0 }
};
DEVICE clk_dev = {
"CLK", &clk_unit, clk_reg, clk_mod,
1, 0, 0, 0, 0, 0,
NULL, NULL, &clk_reset,
NULL, NULL, NULL,
&clk_dib, 0 };
"CLK", &clk_unit, clk_reg, clk_mod,
1, 0, 0, 0, 0, 0,
NULL, NULL, &clk_reset,
NULL, NULL, NULL,
&clk_dib, 0
};
/* Clock and terminal MxPR routines
iccs_rd/wr interval timer
todr_rd/wr time of year clock
rxcs_rd/wr input control/status
rxdb_rd input buffer
txcs_rd/wr output control/status
txdb_wr output buffer
iccs_rd/wr interval timer
todr_rd/wr time of year clock
rxcs_rd/wr input control/status
rxdb_rd input buffer
txcs_rd/wr output control/status
txdb_wr output buffer
*/
int32 iccs_rd (void)
@@ -208,10 +217,10 @@ return (tti_csr & TTICSR_IMP);
int32 rxdb_rd (void)
{
int32 t = tti_unit.buf; /* char + error */
int32 t = tti_unit.buf; /* char + error */
tti_csr = tti_csr & ~CSR_DONE; /* clr done */
tti_unit.buf = tti_unit.buf & 0377; /* clr errors */
tti_csr = tti_csr & ~CSR_DONE; /* clr done */
tti_unit.buf = tti_unit.buf & 0377; /* clr errors */
CLR_INT (TTI);
return t;
}
@@ -239,7 +248,7 @@ void rxcs_wr (int32 data)
{
if ((data & CSR_IE) == 0) CLR_INT (TTI);
else if ((tti_csr & (CSR_DONE + CSR_IE)) == CSR_DONE)
SET_INT (TTI);
SET_INT (TTI);
tti_csr = (tti_csr & ~TTICSR_RW) | (data & TTICSR_RW);
return;
}
@@ -248,7 +257,7 @@ void txcs_wr (int32 data)
{
if ((data & CSR_IE) == 0) CLR_INT (TTO);
else if ((tto_csr & (CSR_DONE + CSR_IE)) == CSR_DONE)
SET_INT (TTO);
SET_INT (TTO);
tto_csr = (tto_csr & ~TTOCSR_RW) | (data & TTOCSR_RW);
return;
}
@@ -261,22 +270,23 @@ CLR_INT (TTO);
sim_activate (&tto_unit, tto_unit.wait);
return;
}
/* Terminal input routines
tti_svc process event (character ready)
tti_reset process reset
tti_svc process event (character ready)
tti_reset process reset
*/
t_stat tti_svc (UNIT *uptr)
{
int32 c;
sim_activate (&tti_unit, tti_unit.wait); /* continue poll */
if ((c = sim_poll_kbd ()) < SCPE_KFLAG) return c; /* no char or error? */
if (c & SCPE_BREAK) { /* break? */
if (sysd_hlt_enb ()) hlt_pin = 1; /* if enabled, halt */
tti_unit.buf = TTIBUF_ERR | TTIBUF_FRM | TTIBUF_RBR; }
sim_activate (&tti_unit, tti_unit.wait); /* continue poll */
if ((c = sim_poll_kbd ()) < SCPE_KFLAG) return c; /* no char or error? */
if (c & SCPE_BREAK) { /* break? */
if (sysd_hlt_enb ()) hlt_pin = 1; /* if enabled, halt */
tti_unit.buf = TTIBUF_ERR | TTIBUF_FRM | TTIBUF_RBR;
}
else tti_unit.buf = c & ((tti_unit.flags & UNIT_8B)? 0377: 0177);
tti_unit.pos = tti_unit.pos + 1;
tti_csr = tti_csr | CSR_DONE;
@@ -289,14 +299,14 @@ t_stat tti_reset (DEVICE *dptr)
tti_unit.buf = 0;
tti_csr = 0;
CLR_INT (TTI);
sim_activate (&tti_unit, tti_unit.wait); /* activate unit */
sim_activate (&tti_unit, tti_unit.wait); /* activate unit */
return SCPE_OK;
}
/* Terminal output routines
tto_svc process event (character typed)
tto_reset process reset
tto_svc process event (character typed)
tto_reset process reset
*/
t_stat tto_svc (UNIT *uptr)
@@ -305,9 +315,10 @@ int32 c;
t_stat r;
c = tto_unit.buf & ((tto_unit.flags & UNIT_8B)? 0377: 0177);
if ((r = sim_putchar_s (c)) != SCPE_OK) { /* output; error? */
sim_activate (uptr, uptr->wait); /* retry */
return ((r == SCPE_STALL)? SCPE_OK: r); } /* !stall? report */
if ((r = sim_putchar_s (c)) != SCPE_OK) { /* output; error? */
sim_activate (uptr, uptr->wait); /* retry */
return ((r == SCPE_STALL)? SCPE_OK: r); /* !stall? report */
}
tto_csr = tto_csr | CSR_DONE;
if (tto_csr & CSR_IE) SET_INT (TTO);
tto_unit.pos = tto_unit.pos + 1;
@@ -319,15 +330,15 @@ t_stat tto_reset (DEVICE *dptr)
tto_unit.buf = 0;
tto_csr = CSR_DONE;
CLR_INT (TTO);
sim_cancel (&tto_unit); /* deactivate unit */
sim_cancel (&tto_unit); /* deactivate unit */
return SCPE_OK;
}
/* Clock routines
clk_svc process event (clock tick)
clk_reset process reset
todr_powerup powerup for TODR (get date from system)
clk_svc process event (clock tick)
clk_reset process reset
todr_powerup powerup for TODR (get date from system)
*/
t_stat clk_svc (UNIT *uptr)
@@ -335,11 +346,11 @@ t_stat clk_svc (UNIT *uptr)
int32 t;
if (clk_csr & CSR_IE) SET_INT (CLK);
t = sim_rtcn_calb (clk_tps, TMR_CLK); /* calibrate clock */
sim_activate (&clk_unit, t); /* reactivate unit */
tmr_poll = t; /* set tmr poll */
tmxr_poll = t * TMXR_MULT; /* set mux poll */
if (!todr_blow) todr_reg = todr_reg + 1; /* incr TODR */
t = sim_rtcn_calb (clk_tps, TMR_CLK); /* calibrate clock */
sim_activate (&clk_unit, t); /* reactivate unit */
tmr_poll = t; /* set tmr poll */
tmxr_poll = t * TMXR_MULT; /* set mux poll */
if (!todr_blow) todr_reg = todr_reg + 1; /* incr TODR */
return SCPE_OK;
}
@@ -349,15 +360,15 @@ uint32 base;
time_t curr;
struct tm *ctm;
curr = time (NULL); /* get curr time */
if (curr == (time_t) -1) return SCPE_NOFNC; /* error? */
ctm = localtime (&curr); /* decompose */
if (ctm == NULL) return SCPE_NOFNC; /* error? */
base = (((((ctm->tm_yday * 24) + /* sec since 1-Jan */
ctm->tm_hour) * 60) +
ctm->tm_min) * 60) +
ctm->tm_sec;
todr_reg = (base * 100) + 0x10000000; /* cvt to VAX form */
curr = time (NULL); /* get curr time */
if (curr == (time_t) -1) return SCPE_NOFNC; /* error? */
ctm = localtime (&curr); /* decompose */
if (ctm == NULL) return SCPE_NOFNC; /* error? */
base = (((((ctm->tm_yday * 24) + /* sec since 1-Jan */
ctm->tm_hour) * 60) +
ctm->tm_min) * 60) +
ctm->tm_sec;
todr_reg = (base * 100) + 0x10000000; /* cvt to VAX form */
todr_blow = 0;
return SCPE_OK;
}
@@ -366,13 +377,13 @@ t_stat clk_reset (DEVICE *dptr)
{
int32 t;
if (sim_switches & SWMASK ('P')) todr_powerup (); /* powerup? */
if (sim_switches & SWMASK ('P')) todr_powerup (); /* powerup? */
clk_csr = 0;
CLR_INT (CLK);
t = sim_rtcn_init (clk_unit.wait, TMR_CLK); /* init timer */
sim_activate (&clk_unit, t); /* activate unit */
tmr_poll = t; /* set tmr poll */
tmxr_poll = t * TMXR_MULT; /* set mux poll */
t = sim_rtcn_init (clk_unit.wait, TMR_CLK); /* init timer */
sim_activate (&clk_unit, t); /* activate unit */
tmr_poll = t; /* set tmr poll */
tmxr_poll = t * TMXR_MULT; /* set mux poll */
return SCPE_OK;
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
/* vax_syscm.c: PDP-11 compatibility mode symbolic decode and parse
Copyright (c) 1993-2004, Robert M Supnik
Copyright (c) 1993-2005, Robert M Supnik
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
@@ -19,11 +19,11 @@
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of Robert M Supnik shall not
be used in advertising or otherwise to promote the sale, use or other dealings
Except as contained in this notice, the name of Robert M Supnik shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik.
15-Sep-04 RMS Cloned from pdp11_sys.c
15-Sep-04 RMS Cloned from pdp11_sys.c
*/
#include "vax_defs.h"
@@ -34,37 +34,38 @@ extern UNIT cpu_unit;
/* Symbol tables */
/* Warning: for literals, the class number MUST equal the field width!! */
#define I_V_CL 18 /* class bits */
#define I_M_CL 017 /* class mask */
#define I_V_NPN 0 /* no operands */
#define I_V_REG 1 /* reg */
#define I_V_SOP 2 /* operand */
#define I_V_3B 3 /* 3b literal */
#define I_V_RSOP 4 /* reg, operand */
#define I_V_BR 5 /* cond branch */
#define I_V_6B 6 /* 6b literal */
#define I_V_SOB 7 /* reg, disp */
#define I_V_8B 8 /* 8b literal */
#define I_V_DOP 9 /* double operand */
#define I_V_CCC 10 /* CC clear */
#define I_V_CCS 11 /* CC set */
#define I_NPN (I_V_NPN << I_V_CL)
#define I_REG (I_V_REG << I_V_CL)
#define I_SOP (I_V_SOP << I_V_CL)
#define I_3B (I_V_3B << I_V_CL)
#define I_6B (I_V_6B << I_V_CL)
#define I_BR (I_V_BR << I_V_CL)
#define I_8B (I_V_8B << I_V_CL)
#define I_RSOP (I_V_RSOP << I_V_CL)
#define I_SOB (I_V_SOB << I_V_CL)
#define I_DOP (I_V_DOP << I_V_CL)
#define I_CCC (I_V_CCC << I_V_CL)
#define I_CCS (I_V_CCS << I_V_CL)
#define I_V_CL 18 /* class bits */
#define I_M_CL 017 /* class mask */
#define I_V_NPN 0 /* no operands */
#define I_V_REG 1 /* reg */
#define I_V_SOP 2 /* operand */
#define I_V_3B 3 /* 3b literal */
#define I_V_RSOP 4 /* reg, operand */
#define I_V_BR 5 /* cond branch */
#define I_V_6B 6 /* 6b literal */
#define I_V_SOB 7 /* reg, disp */
#define I_V_8B 8 /* 8b literal */
#define I_V_DOP 9 /* double operand */
#define I_V_CCC 10 /* CC clear */
#define I_V_CCS 11 /* CC set */
#define I_NPN (I_V_NPN << I_V_CL)
#define I_REG (I_V_REG << I_V_CL)
#define I_SOP (I_V_SOP << I_V_CL)
#define I_3B (I_V_3B << I_V_CL)
#define I_6B (I_V_6B << I_V_CL)
#define I_BR (I_V_BR << I_V_CL)
#define I_8B (I_V_8B << I_V_CL)
#define I_RSOP (I_V_RSOP << I_V_CL)
#define I_SOB (I_V_SOB << I_V_CL)
#define I_DOP (I_V_DOP << I_V_CL)
#define I_CCC (I_V_CCC << I_V_CL)
#define I_CCS (I_V_CCS << I_V_CL)
static const int32 masks[] = {
0177777, 0177770, 0177700, 0177770,
0177000, 0177400, 0177700, 0177000,
0177400, 0170000, 0177777, 0177777 };
0177777, 0177770, 0177700, 0177770,
0177000, 0177400, 0177700, 0177000,
0177400, 0170000, 0177777, 0177777
};
static const char *opcode[] = {
"HALT","WAIT","RTI","BPT",
@@ -110,7 +111,7 @@ static const char *opcode[] = {
"SOB",
"BPL","BMI","BHI","BLOS",
"BVC","BVS","BCC","BCS",
"BHIS","BLO", /* encode only */
"BHIS","BLO", /* encode only */
"EMT","TRAP",
"CLRB","COMB","INCB","DECB",
"NEGB","ADCB","SBCB","TSTB",
@@ -118,7 +119,8 @@ static const char *opcode[] = {
"MTPS","MFPD","MTPD","MFPS",
"MOVB","CMPB","BITB","BICB",
"BISB","SUB",
NULL };
NULL
};
static const int32 opc_val[] = {
0000000+I_NPN, 0000001+I_NPN, 0000002+I_NPN, 0000003+I_NPN,
@@ -172,24 +174,26 @@ static const int32 opc_val[] = {
0106400+I_SOP, 0106500+I_SOP, 0106600+I_SOP, 0106700+I_SOP,
0110000+I_DOP, 0120000+I_DOP, 0130000+I_DOP, 0140000+I_DOP,
0150000+I_DOP, 0160000+I_DOP,
-1 };
-1
};
static const char *rname [] =
{ "R0", "R1", "R2", "R3", "R4", "R5", "SP", "PC" };
static const char *rname [] = {
"R0", "R1", "R2", "R3", "R4", "R5", "SP", "PC"
};
static const char r50_to_asc[] = " ABCDEFGHIJKLMNOPQRSTUVWXYZ$._0123456789";
/* Specifier decode
Inputs:
*of = output stream
addr = current PC
spec = specifier
nval = next word
flag = TRUE if decoding for CPU
iflag = TRUE if decoding integer instruction
*of = output stream
addr = current PC
spec = specifier
nval = next word
flag = TRUE if decoding for CPU
iflag = TRUE if decoding integer instruction
Outputs:
count = -number of extra words retired
count = -number of extra words retired
*/
int32 fprint_spec (FILE *of, t_addr addr, int32 spec, int32 nval)
@@ -201,48 +205,58 @@ static const int32 pcwd[8] = { 0, 0, -1, -1, 0, 0, -1, -1 };
reg = spec & 07;
mode = ((spec >> 3) & 07);
switch (mode) {
case 0:
fprintf (of, "%s", rname[reg]);
break;
case 1:
fprintf (of, "(%s)", rname[reg]);
break;
case 2:
if (reg != 7) fprintf (of, "(%s)+", rname[reg]);
else fprintf (of, "#%-X", nval);
break;
case 3:
if (reg != 7) fprintf (of, "@(%s)+", rname[reg]);
else fprintf (of, "@#%-X", nval);
break;
case 4:
fprintf (of, "-(%s)", rname[reg]);
break;
case 5:
fprintf (of, "@-(%s)", rname[reg]);
break;
case 6:
if (reg != 7) fprintf (of, "%-X(%s)", nval, rname[reg]);
else fprintf (of, "%-X", (nval + addr + 4) & 0177777);
break;
case 7:
if (reg != 7) fprintf (of, "@%-X(%s)", nval, rname[reg]);
else fprintf (of, "@%-X", (nval + addr + 4) & 0177777);
break; } /* end case */
case 0:
fprintf (of, "%s", rname[reg]);
break;
case 1:
fprintf (of, "(%s)", rname[reg]);
break;
case 2:
if (reg != 7) fprintf (of, "(%s)+", rname[reg]);
else fprintf (of, "#%-X", nval);
break;
case 3:
if (reg != 7) fprintf (of, "@(%s)+", rname[reg]);
else fprintf (of, "@#%-X", nval);
break;
case 4:
fprintf (of, "-(%s)", rname[reg]);
break;
case 5:
fprintf (of, "@-(%s)", rname[reg]);
break;
case 6:
if (reg != 7) fprintf (of, "%-X(%s)", nval, rname[reg]);
else fprintf (of, "%-X", (nval + addr + 4) & 0177777);
break;
case 7:
if (reg != 7) fprintf (of, "@%-X(%s)", nval, rname[reg]);
else fprintf (of, "@%-X", (nval + addr + 4) & 0177777);
break;
} /* end case */
return ((reg == 07)? pcwd[mode]: rgwd[mode]);
}
/* Symbolic decode
Inputs:
*of = output stream
addr = current PC
*val = values to decode
*uptr = pointer to unit
sw = switches
*of = output stream
addr = current PC
*val = values to decode
*uptr = pointer to unit
sw = switches
Outputs:
return = if >= 0, error code
if < 0, number of extra words retired
return = if >= 0, error code
if < 0, number of extra words retired
*/
t_stat fprint_sym_cm (FILE *of, t_addr addr, t_value *bytes, int32 sw)
@@ -250,99 +264,107 @@ t_stat fprint_sym_cm (FILE *of, t_addr addr, t_value *bytes, int32 sw)
int32 i, j, c1, c2, c3, inst, srcm, srcr, dstm, dstr;
int32 l8b, brdisp, wd1;
uint32 val[3];
extern int32 FPS;
for (i = j = 0; i < 3; i++, j = j + 2)
val[i] = (int32) (bytes[j] | (bytes[j + 1] << 8));
if (sw & SWMASK ('R')) { /* radix 50? */
if (val[0] > 0174777) return SCPE_ARG; /* max value */
c3 = val[0] % 050;
c2 = (val[0] / 050) % 050;
c1 = val[0] / (050 * 050);
fprintf (of, "%c%c%c", r50_to_asc[c1],
r50_to_asc[c2], r50_to_asc[c3]);
return -1; }
val[i] = (int32) (bytes[j] | (bytes[j + 1] << 8));
if (sw & SWMASK ('R')) { /* radix 50? */
if (val[0] > 0174777) return SCPE_ARG; /* max value */
c3 = val[0] % 050;
c2 = (val[0] / 050) % 050;
c1 = val[0] / (050 * 050);
fprintf (of, "%c%c%c", r50_to_asc[c1],
r50_to_asc[c2], r50_to_asc[c3]);
return -1;
}
if (!(sw & SWMASK ('P')) || (addr & 1) || (addr > WMASK))
return SCPE_ARG;
return SCPE_ARG;
inst = val[0]; /* inst */
inst = val[0]; /* inst */
wd1 = 0;
for (i = 0; opc_val[i] >= 0; i++) { /* loop thru ops */
j = (opc_val[i] >> I_V_CL) & I_M_CL; /* get class */
if ((opc_val[i] & 0177777) == (inst & masks[j])) { /* match? */
srcm = (inst >> 6) & 077; /* opr fields */
srcr = srcm & 07;
dstm = inst & 077;
dstr = dstm & 07;
l8b = inst & 0377;
/* Instruction decode */
for (i = 0; opc_val[i] >= 0; i++) { /* loop thru ops */
j = (opc_val[i] >> I_V_CL) & I_M_CL; /* get class */
if ((opc_val[i] & 0177777) == (inst & masks[j])) { /* match? */
srcm = (inst >> 6) & 077; /* opr fields */
srcr = srcm & 07;
dstm = inst & 077;
dstr = dstm & 07;
l8b = inst & 0377;
switch (j) { /* case on class */
switch (j) { /* case on class */
case I_V_NPN: case I_V_CCC: case I_V_CCS: /* no operands */
fprintf (of, "%s", opcode[i]);
break;
case I_V_REG: /* reg */
fprintf (of, "%s %-s", opcode[i], rname[dstr]);
break;
case I_V_SOP: /* sop */
fprintf (of, "%s ", opcode[i]);
wd1 = fprint_spec (of, addr, dstm, val[1]);
break;
case I_V_3B: /* 3b */
fprintf (of, "%s %-X", opcode[i], dstr);
break;
case I_V_6B: /* 6b */
fprintf (of, "%s %-X", opcode[i], dstm);
break;
case I_V_BR: /* cond branch */
fprintf (of, "%s ", opcode[i]);
brdisp = (l8b + l8b + ((l8b & 0200)? 0177002: 2)) & 0177777;
fprintf (of, "%-X", (addr + brdisp) & 0177777);
break;
case I_V_8B: /* 8b */
fprintf (of, "%s %-X", opcode[i], l8b);
break;
case I_V_SOB: /* sob */
fprintf (of, "%s %s,", opcode[i], rname[srcr]);
brdisp = (dstm * 2) - 2;
fprintf (of, "%-X", (addr - brdisp) & 0177777);
break;
case I_V_RSOP: /* rsop */
fprintf (of, "%s %s,", opcode[i], rname[srcr]);
wd1 = fprint_spec (of, addr, dstm, val[1]);
break;
case I_V_DOP: /* dop */
fprintf (of, "%s ", opcode[i]);
wd1 = fprint_spec (of, addr, srcm, val[1]);
fprintf (of, ",");
wd1 += fprint_spec (of, addr - wd1 - wd1, dstm,
val[1 - wd1]);
break;
} /* end case */
return ((wd1 * 2) - 1);
} /* end if */
} /* end for */
return SCPE_ARG; /* no match */
case I_V_NPN: case I_V_CCC: case I_V_CCS: /* no operands */
fprintf (of, "%s", opcode[i]);
break;
case I_V_REG: /* reg */
fprintf (of, "%s %-s", opcode[i], rname[dstr]);
break;
case I_V_SOP: /* sop */
fprintf (of, "%s ", opcode[i]);
wd1 = fprint_spec (of, addr, dstm, val[1]);
break;
case I_V_3B: /* 3b */
fprintf (of, "%s %-X", opcode[i], dstr);
break;
case I_V_6B: /* 6b */
fprintf (of, "%s %-X", opcode[i], dstm);
break;
case I_V_BR: /* cond branch */
fprintf (of, "%s ", opcode[i]);
brdisp = (l8b + l8b + ((l8b & 0200)? 0177002: 2)) & 0177777;
fprintf (of, "%-X", (addr + brdisp) & 0177777);
break;
case I_V_8B: /* 8b */
fprintf (of, "%s %-X", opcode[i], l8b);
break;
case I_V_SOB: /* sob */
fprintf (of, "%s %s,", opcode[i], rname[srcr]);
brdisp = (dstm * 2) - 2;
fprintf (of, "%-X", (addr - brdisp) & 0177777);
break;
case I_V_RSOP: /* rsop */
fprintf (of, "%s %s,", opcode[i], rname[srcr]);
wd1 = fprint_spec (of, addr, dstm, val[1]);
break;
case I_V_DOP: /* dop */
fprintf (of, "%s ", opcode[i]);
wd1 = fprint_spec (of, addr, srcm, val[1]);
fprintf (of, ",");
wd1 += fprint_spec (of, addr - wd1 - wd1, dstm,
val[1 - wd1]);
break;
} /* end case */
return ((wd1 * 2) - 1);
} /* end if */
} /* end for */
return SCPE_ARG; /* no match */
}
#define A_PND 100 /* # seen */
#define A_MIN 040 /* -( seen */
#define A_PAR 020 /* (Rn) seen */
#define A_REG 010 /* Rn seen */
#define A_PLS 004 /* + seen */
#define A_NUM 002 /* number seen */
#define A_REL 001 /* relative addr seen */
#define A_PND 100 /* # seen */
#define A_MIN 040 /* -( seen */
#define A_PAR 020 /* (Rn) seen */
#define A_REG 010 /* Rn seen */
#define A_PLS 004 /* + seen */
#define A_NUM 002 /* number seen */
#define A_REL 001 /* relative addr seen */
/* Register number
Inputs:
*cptr = pointer to input string
mchar = character to match after register name
*cptr = pointer to input string
mchar = character to match after register name
Outputs:
rnum = 0..7 if a legitimate register
< 0 if error
rnum = 0..7 if a legitimate register
< 0 if error
*/
int32 get_reg (char *cptr, char mchar)
@@ -351,19 +373,20 @@ int32 i;
if (*(cptr + 2) != mchar) return -1;
for (i = 0; i < 8; i++) {
if (strncmp (cptr, rname[i], 2) == 0) return i; }
if (strncmp (cptr, rname[i], 2) == 0) return i;
}
return -1;
}
/* Number or memory address
Inputs:
*cptr = pointer to input string
*dptr = pointer to output displacement
*pflag = pointer to accumulating flags
*cptr = pointer to input string
*dptr = pointer to output displacement
*pflag = pointer to accumulating flags
Outputs:
cptr = pointer to next character in input string
NULL if parsing error
cptr = pointer to next character in input string
NULL if parsing error
Flags: 0 (no result), A_NUM (number), A_REL (relative)
*/
@@ -375,124 +398,143 @@ char *tptr;
minus = 0;
if (*cptr == '.') { /* relative? */
*pflag = *pflag | A_REL;
cptr++; }
if (*cptr == '+') { /* +? */
*pflag = *pflag | A_NUM;
cptr++; }
if (*cptr == '-') { /* -? */
*pflag = *pflag | A_NUM;
minus = 1;
cptr++; }
if (*cptr == '.') { /* relative? */
*pflag = *pflag | A_REL;
cptr++;
}
if (*cptr == '+') { /* +? */
*pflag = *pflag | A_NUM;
cptr++;
}
if (*cptr == '-') { /* -? */
*pflag = *pflag | A_NUM;
minus = 1;
cptr++;
}
errno = 0;
val = strtoul (cptr, &tptr, 16);
if (cptr == tptr) { /* no number? */
if (*pflag == (A_REL + A_NUM)) return NULL; /* .+, .-? */
*dptr = 0;
return cptr; }
if (errno || (*pflag == A_REL)) return NULL; /* .n? */
if (cptr == tptr) { /* no number? */
if (*pflag == (A_REL + A_NUM)) return NULL; /* .+, .-? */
*dptr = 0;
return cptr;
}
if (errno || (*pflag == A_REL)) return NULL; /* .n? */
*dptr = (minus? -val: val) & 0177777;
*pflag = *pflag | A_NUM;
return tptr;
}
/* Specifier decode
Inputs:
*cptr = pointer to input string
addr = current PC
n1 = 0 if no extra word used
-1 if extra word used in prior decode
*sptr = pointer to output specifier
*dptr = pointer to output displacement
*cptr = pointer to input string
addr = current PC
n1 = 0 if no extra word used
-1 if extra word used in prior decode
*sptr = pointer to output specifier
*dptr = pointer to output displacement
Outputs:
status = = -1 extra word decoded
= 0 ok
= +1 error
status = = -1 extra word decoded
= 0 ok
= +1 error
*/
t_stat get_spec (char *cptr, t_addr addr, int32 n1, int32 *sptr, int32 *dptr)
{
int32 reg, indir, pflag, disp;
indir = 0; /* no indirect */
indir = 0; /* no indirect */
pflag = 0;
if (*cptr == '@') { /* indirect? */
indir = 010;
cptr++; }
if (*cptr == '#') { /* literal? */
pflag = pflag | A_PND;
cptr++; }
if (strncmp (cptr, "-(", 2) == 0) { /* autodecrement? */
pflag = pflag | A_MIN;
cptr++; }
if (*cptr == '@') { /* indirect? */
indir = 010;
cptr++;
}
if (*cptr == '#') { /* literal? */
pflag = pflag | A_PND;
cptr++;
}
if (strncmp (cptr, "-(", 2) == 0) { /* autodecrement? */
pflag = pflag | A_MIN;
cptr++;
}
else if ((cptr = get_addr (cptr, &disp, &pflag)) == NULL) return 1;
if (*cptr == '(') { /* register index? */
pflag = pflag | A_PAR;
if ((reg = get_reg (cptr + 1, ')')) < 0) return 1;
cptr = cptr + 4;
if (*cptr == '+') { /* autoincrement? */
pflag = pflag | A_PLS;
cptr++; } }
if (*cptr == '(') { /* register index? */
pflag = pflag | A_PAR;
if ((reg = get_reg (cptr + 1, ')')) < 0) return 1;
cptr = cptr + 4;
if (*cptr == '+') { /* autoincrement? */
pflag = pflag | A_PLS;
cptr++;
}
}
else if ((reg = get_reg (cptr, 0)) >= 0) {
pflag = pflag | A_REG;
cptr = cptr + 2; }
if (*cptr != 0) return 1; /* all done? */
/* Specifier decode, continued */
pflag = pflag | A_REG;
cptr = cptr + 2;
}
if (*cptr != 0) return 1; /* all done? */
switch (pflag) { /* case on syntax */
case A_REG: /* Rn, @Rn */
*sptr = indir + reg;
return 0;
case A_PAR: /* (Rn), @(Rn) */
if (indir) { /* @(Rn) = @0(Rn) */
*sptr = 070 + reg;
*dptr = 0;
return -1; }
else *sptr = 010 + reg;
return 0;
case A_PAR+A_PLS: /* (Rn)+, @(Rn)+ */
*sptr = 020 + indir + reg;
return 0;
case A_MIN+A_PAR: /* -(Rn), @-(Rn) */
*sptr = 040 + indir + reg;
return 0;
case A_NUM+A_PAR: /* d(Rn), @d(Rn) */
*sptr = 060 + indir + reg;
*dptr = disp;
return -1;
case A_PND+A_REL: case A_PND+A_REL+A_NUM: /* #.+n, @#.+n */
disp = (disp + addr) & 0177777; /* fall through */
case A_PND+A_NUM: /* #n, @#n */
*sptr = 027 + indir;
*dptr = disp;
return -1;
case A_REL: case A_REL+A_NUM: /* .+n, @.+n */
*sptr = 067 + indir;
*dptr = (disp - 4 + (2 * n1)) & 0177777;
return -1;
case A_NUM: /* n, @n */
*sptr = 067 + indir;
*dptr = (disp - addr - 4 + (2 * n1)) & 0177777;
return -1;
default:
return 1; } /* end case */
switch (pflag) { /* case on syntax */
case A_REG: /* Rn, @Rn */
*sptr = indir + reg;
return 0;
case A_PAR: /* (Rn), @(Rn) */
if (indir) { /* @(Rn) = @0(Rn) */
*sptr = 070 + reg;
*dptr = 0;
return -1;
}
else *sptr = 010 + reg;
return 0;
case A_PAR+A_PLS: /* (Rn)+, @(Rn)+ */
*sptr = 020 + indir + reg;
return 0;
case A_MIN+A_PAR: /* -(Rn), @-(Rn) */
*sptr = 040 + indir + reg;
return 0;
case A_NUM+A_PAR: /* d(Rn), @d(Rn) */
*sptr = 060 + indir + reg;
*dptr = disp;
return -1;
case A_PND+A_REL: case A_PND+A_REL+A_NUM: /* #.+n, @#.+n */
disp = (disp + addr) & 0177777; /* fall through */
case A_PND+A_NUM: /* #n, @#n */
*sptr = 027 + indir;
*dptr = disp;
return -1;
case A_REL: case A_REL+A_NUM: /* .+n, @.+n */
*sptr = 067 + indir;
*dptr = (disp - 4 + (2 * n1)) & 0177777;
return -1;
case A_NUM: /* n, @n */
*sptr = 067 + indir;
*dptr = (disp - addr - 4 + (2 * n1)) & 0177777;
return -1;
default:
return 1;
} /* end case */
}
/* Symbolic input
Inputs:
*cptr = pointer to input string
addr = current PC
*uptr = pointer to unit
*val = pointer to output values
sw = switches
*cptr = pointer to input string
addr = current PC
*uptr = pointer to unit
*val = pointer to output values
sw = switches
Outputs:
status = > 0 error code
<= 0 -number of extra words
status = > 0 error code
<= 0 -number of extra words
*/
t_stat parse_sym_cm (char *cptr, t_addr addr, t_value *bytes, int32 sw)
@@ -502,86 +544,99 @@ int32 val[3];
t_stat r;
char *tptr, gbuf[CBUFSIZE];
if (sw & SWMASK ('R')) return SCPE_ARG; /* radix 50 */
if (sw & SWMASK ('R')) return SCPE_ARG; /* radix 50 */
if (!(sw & SWMASK ('P')) || (addr & 1) || (addr > WMASK))
return SCPE_ARG;
return SCPE_ARG;
cptr = get_glyph (cptr, gbuf, 0); /* get opcode */
cptr = get_glyph (cptr, gbuf, 0); /* get opcode */
n1 = n2 = pflag = 0;
for (i = 0; (opcode[i] != NULL) && (strcmp (opcode[i], gbuf) != 0) ; i++) ;
if (opcode[i] == NULL) return SCPE_ARG;
val[0] = opc_val[i] & 0177777; /* get value */
j = (opc_val[i] >> I_V_CL) & I_M_CL; /* get class */
val[0] = opc_val[i] & 0177777; /* get value */
j = (opc_val[i] >> I_V_CL) & I_M_CL; /* get class */
switch (j) { /* case on class */
case I_V_NPN: /* no operand */
break;
case I_V_REG: /* register */
cptr = get_glyph (cptr, gbuf, 0); /* get glyph */
if ((reg = get_reg (gbuf, 0)) < 0) return SCPE_ARG;
val[0] = val[0] | reg;
break;
case I_V_3B: case I_V_6B: case I_V_8B: /* xb literal */
cptr = get_glyph (cptr, gbuf, 0); /* get literal */
d = (int32) get_uint (gbuf, 16, (1 << j) - 1, &r);
if (r != SCPE_OK) return SCPE_ARG;
val[0] = val[0] | d; /* put in place */
break;
case I_V_BR: /* cond br */
cptr = get_glyph (cptr, gbuf, 0); /* get address */
tptr = get_addr (gbuf, &disp, &pflag); /* parse */
if ((tptr == NULL) || (*tptr != 0)) return SCPE_ARG;
if ((pflag & A_REL) == 0)
disp = (disp - addr) & 0177777;
if ((disp & 1) || (disp > 0400) && (disp < 0177402)) return SCPE_ARG;
val[0] = val[0] | (((disp - 2) >> 1) & 0377);
break;
case I_V_SOB: /* sob */
cptr = get_glyph (cptr, gbuf, ','); /* get glyph */
if ((reg = get_reg (gbuf, 0)) < 0) return SCPE_ARG;
val[0] = val[0] | (reg << 6);
cptr = get_glyph (cptr, gbuf, 0); /* get address */
tptr = get_addr (gbuf, &disp, &pflag); /* parse */
if ((tptr == NULL) || (*tptr != 0)) return SCPE_ARG;
if ((pflag & A_REL) == 0)
disp = (disp - addr) & 0177777;
if ((disp & 1) || ((disp > 2) && (disp < 0177604))) return SCPE_ARG;
val[0] = val[0] | (((2 - disp) >> 1) & 077);
break;
case I_V_RSOP: /* reg, sop */
cptr = get_glyph (cptr, gbuf, ','); /* get glyph */
if ((reg = get_reg (gbuf, 0)) < 0) return SCPE_ARG;
val[0] = val[0] | (reg << 6); /* fall through */
case I_V_SOP: /* sop */
cptr = get_glyph (cptr, gbuf, 0); /* get glyph */
if ((n1 = get_spec (gbuf, addr, 0, &spec, &val[1])) > 0)
return SCPE_ARG;
val[0] = val[0] | spec;
break;
case I_V_DOP: /* double op */
cptr = get_glyph (cptr, gbuf, ','); /* get glyph */
if ((n1 = get_spec (gbuf, addr, 0, &spec, &val[1])) > 0)
return SCPE_ARG;
val[0] = val[0] | (spec << 6);
cptr = get_glyph (cptr, gbuf, 0); /* get glyph */
if ((n2 = get_spec (gbuf, addr, n1, &spec, &val[1 - n1])) > 0)
return SCPE_ARG;
val[0] = val[0] | spec;
break;
case I_V_CCC: case I_V_CCS: /* cond code oper */
for (cptr = get_glyph (cptr, gbuf, 0); gbuf[0] != 0;
cptr = get_glyph (cptr, gbuf, 0)) {
for (i = 0; (opcode[i] != NULL) &&
(strcmp (opcode[i], gbuf) != 0) ; i++) ;
if ((((opc_val[i] >> I_V_CL) & I_M_CL) != j) ||
(opcode[i] == NULL)) return SCPE_ARG;
val[0] = val[0] | (opc_val[i] & 0177777); }
break;
default:
return SCPE_ARG; }
if (*cptr != 0) return SCPE_ARG; /* junk at end? */
switch (j) { /* case on class */
case I_V_NPN: /* no operand */
break;
case I_V_REG: /* register */
cptr = get_glyph (cptr, gbuf, 0); /* get glyph */
if ((reg = get_reg (gbuf, 0)) < 0) return SCPE_ARG;
val[0] = val[0] | reg;
break;
case I_V_3B: case I_V_6B: case I_V_8B: /* xb literal */
cptr = get_glyph (cptr, gbuf, 0); /* get literal */
d = (int32) get_uint (gbuf, 16, (1 << j) - 1, &r);
if (r != SCPE_OK) return SCPE_ARG;
val[0] = val[0] | d; /* put in place */
break;
case I_V_BR: /* cond br */
cptr = get_glyph (cptr, gbuf, 0); /* get address */
tptr = get_addr (gbuf, &disp, &pflag); /* parse */
if ((tptr == NULL) || (*tptr != 0)) return SCPE_ARG;
if ((pflag & A_REL) == 0)
disp = (disp - addr) & 0177777;
if ((disp & 1) || (disp > 0400) && (disp < 0177402)) return SCPE_ARG;
val[0] = val[0] | (((disp - 2) >> 1) & 0377);
break;
case I_V_SOB: /* sob */
cptr = get_glyph (cptr, gbuf, ','); /* get glyph */
if ((reg = get_reg (gbuf, 0)) < 0) return SCPE_ARG;
val[0] = val[0] | (reg << 6);
cptr = get_glyph (cptr, gbuf, 0); /* get address */
tptr = get_addr (gbuf, &disp, &pflag); /* parse */
if ((tptr == NULL) || (*tptr != 0)) return SCPE_ARG;
if ((pflag & A_REL) == 0)
disp = (disp - addr) & 0177777;
if ((disp & 1) || ((disp > 2) && (disp < 0177604))) return SCPE_ARG;
val[0] = val[0] | (((2 - disp) >> 1) & 077);
break;
case I_V_RSOP: /* reg, sop */
cptr = get_glyph (cptr, gbuf, ','); /* get glyph */
if ((reg = get_reg (gbuf, 0)) < 0) return SCPE_ARG;
val[0] = val[0] | (reg << 6); /* fall through */
case I_V_SOP: /* sop */
cptr = get_glyph (cptr, gbuf, 0); /* get glyph */
if ((n1 = get_spec (gbuf, addr, 0, &spec, &val[1])) > 0)
return SCPE_ARG;
val[0] = val[0] | spec;
break;
case I_V_DOP: /* double op */
cptr = get_glyph (cptr, gbuf, ','); /* get glyph */
if ((n1 = get_spec (gbuf, addr, 0, &spec, &val[1])) > 0)
return SCPE_ARG;
val[0] = val[0] | (spec << 6);
cptr = get_glyph (cptr, gbuf, 0); /* get glyph */
if ((n2 = get_spec (gbuf, addr, n1, &spec, &val[1 - n1])) > 0)
return SCPE_ARG;
val[0] = val[0] | spec;
break;
case I_V_CCC: case I_V_CCS: /* cond code oper */
for (cptr = get_glyph (cptr, gbuf, 0); gbuf[0] != 0;
cptr = get_glyph (cptr, gbuf, 0)) {
for (i = 0; (opcode[i] != NULL) &&
(strcmp (opcode[i], gbuf) != 0) ; i++) ;
if ((((opc_val[i] >> I_V_CL) & I_M_CL) != j) ||
(opcode[i] == NULL)) return SCPE_ARG;
val[0] = val[0] | (opc_val[i] & 0177777);
}
break;
default:
return SCPE_ARG;
}
if (*cptr != 0) return SCPE_ARG; /* junk at end? */
for (i = j = 0; i < 3; i++, j = j + 2) {
bytes[j] = val[i] & BMASK;
bytes[j + 1] = (val[i] >> 8) & BMASK; }
bytes[j] = val[i] & BMASK;
bytes[j + 1] = (val[i] >> 8) & BMASK;
}
return ((2 * (n1 + n2)) - 1);
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
/* vax_sys.c: VAX simulator interface
Copyright (c) 1998-2004, Robert M Supnik
Copyright (c) 1998-2005, Robert M Supnik
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
@@ -19,11 +19,11 @@
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of Robert M Supnik shall not
be used in advertising or otherwise to promote the sale, use or other dealings
Except as contained in this notice, the name of Robert M Supnik shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik.
01-Oct-2004 RMS Cloned from vax_sys.c
01-Oct-2004 RMS Cloned from vax_sys.c
*/
#include "vax_defs.h"
@@ -55,41 +55,42 @@ extern void rom_wr_B (int32 pa, int32 val);
extern UNIT cpu_unit;
DEVICE *sim_devices[] = {
&cpu_dev,
&tlb_dev,
&rom_dev,
&nvr_dev,
&sysd_dev,
&qba_dev,
&tti_dev,
&tto_dev,
&csi_dev,
&cso_dev,
&clk_dev,
&dz_dev,
&vh_dev,
&lpt_dev,
&rl_dev,
&rq_dev,
&rqb_dev,
&rqc_dev,
&rqd_dev,
&ry_dev,
&ts_dev,
&tq_dev,
&xq_dev,
&xqb_dev,
NULL };
&cpu_dev,
&tlb_dev,
&rom_dev,
&nvr_dev,
&sysd_dev,
&qba_dev,
&tti_dev,
&tto_dev,
&csi_dev,
&cso_dev,
&clk_dev,
&dz_dev,
&vh_dev,
&lpt_dev,
&rl_dev,
&rq_dev,
&rqb_dev,
&rqc_dev,
&rqd_dev,
&ry_dev,
&ts_dev,
&tq_dev,
&xq_dev,
&xqb_dev,
NULL
};
/* Binary loader
The binary loader handles absolute system images, that is, system
images linked /SYSTEM. These are simply a byte stream, with no
origin or relocation information.
-r load ROM
-n load NVR
-o for memory, specify origin
-r load ROM
-n load NVR
-o for memory, specify origin
*/
t_stat sim_load (FILE *fileref, char *cptr, char *fnam, int flag)
@@ -98,27 +99,33 @@ t_stat r;
int32 i;
uint32 origin, limit;
extern int32 ssc_cnf;
#define SSCCNF_BLO 0x80000000
#define SSCCNF_BLO 0x80000000
if (flag) return SCPE_ARG; /* dump? */
if (sim_switches & SWMASK ('R')) { /* ROM? */
origin = ROMBASE;
limit = ROMBASE + ROMSIZE; }
else if (sim_switches & SWMASK ('N')) { /* NVR? */
origin = NVRBASE;
limit = NVRBASE + NVRSIZE;
ssc_cnf = ssc_cnf & ~SSCCNF_BLO; }
else { origin = 0; /* memory */
limit = (uint32) cpu_unit.capac;
if (sim_switches & SWMASK ('O')) { /* origin? */
origin = (int32) get_uint (cptr, 16, 0xFFFFFFFF, &r);
if (r != SCPE_OK) return SCPE_ARG; } }
while ((i = getc (fileref)) != EOF) { /* read byte stream */
if (origin >= limit) return SCPE_NXM; /* NXM? */
if (sim_switches & SWMASK ('R')) /* ROM? */
rom_wr_B (origin, i); /* not writeable */
else WriteB (origin, i); /* store byte */
origin = origin + 1; }
if (flag) return SCPE_ARG; /* dump? */
if (sim_switches & SWMASK ('R')) { /* ROM? */
origin = ROMBASE;
limit = ROMBASE + ROMSIZE;
}
else if (sim_switches & SWMASK ('N')) { /* NVR? */
origin = NVRBASE;
limit = NVRBASE + NVRSIZE;
ssc_cnf = ssc_cnf & ~SSCCNF_BLO;
}
else {
origin = 0; /* memory */
limit = (uint32) cpu_unit.capac;
if (sim_switches & SWMASK ('O')) { /* origin? */
origin = (int32) get_uint (cptr, 16, 0xFFFFFFFF, &r);
if (r != SCPE_OK) return SCPE_ARG;
}
}
while ((i = getc (fileref)) != EOF) { /* read byte stream */
if (origin >= limit) return SCPE_NXM; /* NXM? */
if (sim_switches & SWMASK ('R')) /* ROM? */
rom_wr_B (origin, i); /* not writeable */
else WriteB (origin, i); /* store byte */
origin = origin + 1;
}
return SCPE_OK;
}

View File

@@ -1,6 +1,6 @@
/* vaxmod_defs.h: VAX model-specific definitions file
Copyright (c) 1998-2004, Robert M Supnik
Copyright (c) 1998-2005, Robert M Supnik
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
@@ -19,23 +19,24 @@
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of Robert M Supnik shall not
be used in advertising or otherwise to promote the sale, use or other dealings
Except as contained in this notice, the name of Robert M Supnik shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik.
12-Sep-04 RMS Removed map_address prototype
16-Jun-04 RMS Added DHQ11 support
21-Mar-04 RMS Added RXV21 support
25-Jan-04 RMS Removed local debug logging support
RMS,MP Added "KA655X" support
29-Dec-03 RMS Added Q18 definition for PDP11 compatibility
22-Dec-02 RMS Added BDR halt enable definition
11-Nov-02 RMS Added log bits for XQ
10-Oct-02 RMS Added DEQNA/DELQA, multiple RQ, autoconfigure support
29-Sep-02 RMS Revamped bus support macros
06-Sep-02 RMS Added TMSCP support
14-Jul-02 RMS Added additional console halt codes
28-Apr-02 RMS Fixed DZV vector base and number of lines
15-Jun-05 RMS Added QDSS support
12-Sep-04 RMS Removed map_address prototype
16-Jun-04 RMS Added DHQ11 support
21-Mar-04 RMS Added RXV21 support
25-Jan-04 RMS Removed local debug logging support
RMS,MP Added "KA655X" support
29-Dec-03 RMS Added Q18 definition for PDP11 compatibility
22-Dec-02 RMS Added BDR halt enable definition
11-Nov-02 RMS Added log bits for XQ
10-Oct-02 RMS Added DEQNA/DELQA, multiple RQ, autoconfigure support
29-Sep-02 RMS Revamped bus support macros
06-Sep-02 RMS Added TMSCP support
14-Jul-02 RMS Added additional console halt codes
28-Apr-02 RMS Fixed DZV vector base and number of lines
This file covers the KA65x ("Mayfair") series of CVAX-based Qbus systems.
The simulator defines an extended physical memory variant of the KA655,
@@ -43,258 +44,258 @@
System memory map
0000 0000 - 03FF FFFF main memory (KA655)
0400 0000 - 0FFF FFFF reserved (KA655), main memory (KA655X)
1000 0000 - 13FF FFFF cache diagnostic space (KA655), main memory (KA655X)
1400 0000 - 1FFF FFFF reserved (KA655), main memory (KA655X)
0000 0000 - 03FF FFFF main memory (KA655)
0400 0000 - 0FFF FFFF reserved (KA655), main memory (KA655X)
1000 0000 - 13FF FFFF cache diagnostic space (KA655), main memory (KA655X)
1400 0000 - 1FFF FFFF reserved (KA655), main memory (KA655X)
2000 0000 - 2000 1FFF Qbus I/O page
2000 2000 - 2003 FFFF reserved
2004 0000 - 2005 FFFF ROM space, halt protected
2006 0000 - 2007 FFFF ROM space, halt unprotected
2008 0000 - 201F FFFF Local register space
2020 0000 - 2FFF FFFF reserved
3000 0000 - 303F FFFF Qbus memory space
3400 0000 - 3FFF FFFF reserved
2000 0000 - 2000 1FFF Qbus I/O page
2000 2000 - 2003 FFFF reserved
2004 0000 - 2005 FFFF ROM space, halt protected
2006 0000 - 2007 FFFF ROM space, halt unprotected
2008 0000 - 201F FFFF Local register space
2020 0000 - 2FFF FFFF reserved
3000 0000 - 303F FFFF Qbus memory space
3400 0000 - 3FFF FFFF reserved
*/
#ifdef FULL_VAX /* subset VAX */
#ifdef FULL_VAX /* subset VAX */
#undef FULL_VAX
#endif
#ifndef _VAXMOD_DEFS_H_
#define _VAXMOD_DEFS_H_ 1
#define _VAXMOD_DEFS_H_ 1
/* Microcode constructs */
#define CVAX_SID (10 << 24) /* system ID */
#define CVAX_UREV 6 /* ucode revision */
#define CON_HLTPIN 0x0200 /* external CPU halt */
#define CON_PWRUP 0x0300 /* powerup code */
#define CON_HLTINS 0x0600 /* HALT instruction */
#define CON_BADPSL 0x4000 /* invalid PSL flag */
#define CON_MAPON 0x8000 /* mapping on flag */
#define MCHK_TBM_P0 0x05 /* PPTE in P0 */
#define MCHK_TBM_P1 0x06 /* PPTE in P1 */
#define MCHK_M0_P0 0x07 /* PPTE in P0 */
#define MCHK_M0_P1 0x08 /* PPTE in P1 */
#define MCHK_INTIPL 0x09 /* invalid ireq */
#define MCHK_READ 0x80 /* read check */
#define MCHK_WRITE 0x82 /* write check */
#define CVAX_SID (10 << 24) /* system ID */
#define CVAX_UREV 6 /* ucode revision */
#define CON_HLTPIN 0x0200 /* external CPU halt */
#define CON_PWRUP 0x0300 /* powerup code */
#define CON_HLTINS 0x0600 /* HALT instruction */
#define CON_BADPSL 0x4000 /* invalid PSL flag */
#define CON_MAPON 0x8000 /* mapping on flag */
#define MCHK_TBM_P0 0x05 /* PPTE in P0 */
#define MCHK_TBM_P1 0x06 /* PPTE in P1 */
#define MCHK_M0_P0 0x07 /* PPTE in P0 */
#define MCHK_M0_P1 0x08 /* PPTE in P1 */
#define MCHK_INTIPL 0x09 /* invalid ireq */
#define MCHK_READ 0x80 /* read check */
#define MCHK_WRITE 0x82 /* write check */
/* Machine specific IPRs */
#define MT_CADR 37
#define MT_MSER 39
#define MT_CONPC 42
#define MT_CONPSL 43
#define MT_IORESET 55
#define MT_CADR 37
#define MT_MSER 39
#define MT_CONPC 42
#define MT_CONPSL 43
#define MT_IORESET 55
/* Memory system error register */
#define MSER_HM 0x80 /* hit/miss */
#define MSER_CPE 0x40 /* CDAL par err */
#define MSER_CPM 0x20 /* CDAL mchk */
#define MSER_HM 0x80 /* hit/miss */
#define MSER_CPE 0x40 /* CDAL par err */
#define MSER_CPM 0x20 /* CDAL mchk */
/* Cache disable register */
#define CADR_RW 0xF3
#define CADR_MBO 0x0C
#define CADR_RW 0xF3
#define CADR_MBO 0x0C
/* Memory */
#define MAXMEMWIDTH 26 /* max mem, std KA655 */
#define MAXMEMSIZE (1 << MAXMEMWIDTH) /* max mem size */
#define MAXMEMWIDTH_X 29 /* max mem, KA655X */
#define MAXMEMSIZE_X (1 << MAXMEMWIDTH_X)
#define INITMEMSIZE (1 << 24) /* initial memory size */
#define MEMSIZE (cpu_unit.capac)
#define ADDR_IS_MEM(x) (((uint32) (x)) < MEMSIZE)
#define MAXMEMWIDTH 26 /* max mem, std KA655 */
#define MAXMEMSIZE (1 << MAXMEMWIDTH) /* max mem size */
#define MAXMEMWIDTH_X 29 /* max mem, KA655X */
#define MAXMEMSIZE_X (1 << MAXMEMWIDTH_X)
#define INITMEMSIZE (1 << 24) /* initial memory size */
#define MEMSIZE (cpu_unit.capac)
#define ADDR_IS_MEM(x) (((uint32) (x)) < MEMSIZE)
/* Cache diagnostic space */
#define CDAAWIDTH 16 /* cache dat addr width */
#define CDASIZE (1u << CDAAWIDTH) /* cache dat length */
#define CDAMASK (CDASIZE - 1) /* cache dat mask */
#define CTGAWIDTH 10 /* cache tag addr width */
#define CTGSIZE (1u << CTGAWIDTH) /* cache tag length */
#define CTGMASK (CTGSIZE - 1) /* cache tag mask */
#define CDGSIZE (CDASIZE * CTGSIZE) /* diag addr length */
#define CDGBASE 0x10000000 /* diag addr base */
#define CDG_GETROW(x) (((x) & CDAMASK) >> 2)
#define CDG_GETTAG(x) (((x) >> CDAAWIDTH) & CTGMASK)
#define CTG_V (1u << (CTGAWIDTH + 0)) /* tag valid */
#define CTG_WP (1u << (CTGAWIDTH + 1)) /* wrong parity */
#define ADDR_IS_CDG(x) ((((uint32) (x)) >= CDGBASE) && \
(((uint32) (x)) < (CDGBASE + CDGSIZE)))
#define CDAAWIDTH 16 /* cache dat addr width */
#define CDASIZE (1u << CDAAWIDTH) /* cache dat length */
#define CDAMASK (CDASIZE - 1) /* cache dat mask */
#define CTGAWIDTH 10 /* cache tag addr width */
#define CTGSIZE (1u << CTGAWIDTH) /* cache tag length */
#define CTGMASK (CTGSIZE - 1) /* cache tag mask */
#define CDGSIZE (CDASIZE * CTGSIZE) /* diag addr length */
#define CDGBASE 0x10000000 /* diag addr base */
#define CDG_GETROW(x) (((x) & CDAMASK) >> 2)
#define CDG_GETTAG(x) (((x) >> CDAAWIDTH) & CTGMASK)
#define CTG_V (1u << (CTGAWIDTH + 0)) /* tag valid */
#define CTG_WP (1u << (CTGAWIDTH + 1)) /* wrong parity */
#define ADDR_IS_CDG(x) ((((uint32) (x)) >= CDGBASE) && \
(((uint32) (x)) < (CDGBASE + CDGSIZE)))
/* Qbus I/O registers */
#define IOPAGEAWIDTH 13 /* IO addr width */
#define IOPAGESIZE (1u << IOPAGEAWIDTH) /* IO page length */
#define IOPAGEMASK (IOPAGESIZE - 1) /* IO addr mask */
#define IOPAGEBASE 0x20000000 /* IO page base */
#define ADDR_IS_IO(x) ((((uint32) (x)) >= IOPAGEBASE) && \
(((uint32) (x)) < (IOPAGEBASE + IOPAGESIZE)))
#define IOPAGEAWIDTH 13 /* IO addr width */
#define IOPAGESIZE (1u << IOPAGEAWIDTH) /* IO page length */
#define IOPAGEMASK (IOPAGESIZE - 1) /* IO addr mask */
#define IOPAGEBASE 0x20000000 /* IO page base */
#define ADDR_IS_IO(x) ((((uint32) (x)) >= IOPAGEBASE) && \
(((uint32) (x)) < (IOPAGEBASE + IOPAGESIZE)))
/* Read only memory - appears twice */
#define ROMAWIDTH 17 /* ROM addr width */
#define ROMSIZE (1u << ROMAWIDTH) /* ROM length */
#define ROMAMASK (ROMSIZE - 1) /* ROM addr mask */
#define ROMBASE 0x20040000 /* ROM base */
#define ADDR_IS_ROM(x) ((((uint32) (x)) >= ROMBASE) && \
(((uint32) (x)) < (ROMBASE + ROMSIZE + ROMSIZE)))
#define ROMAWIDTH 17 /* ROM addr width */
#define ROMSIZE (1u << ROMAWIDTH) /* ROM length */
#define ROMAMASK (ROMSIZE - 1) /* ROM addr mask */
#define ROMBASE 0x20040000 /* ROM base */
#define ADDR_IS_ROM(x) ((((uint32) (x)) >= ROMBASE) && \
(((uint32) (x)) < (ROMBASE + ROMSIZE + ROMSIZE)))
/* Local register space */
#define REGAWIDTH 19 /* REG addr width */
#define REGSIZE (1u << REGAWIDTH) /* REG length */
#define REGBASE 0x20080000 /* REG addr base */
#define REGAWIDTH 19 /* REG addr width */
#define REGSIZE (1u << REGAWIDTH) /* REG length */
#define REGBASE 0x20080000 /* REG addr base */
/* KA655 board registers */
#define KAAWIDTH 3 /* KA reg width */
#define KASIZE (1u << KAAWIDTH) /* KA reg length */
#define KABASE (REGBASE + 0x4000) /* KA650 addr base */
#define KAAWIDTH 3 /* KA reg width */
#define KASIZE (1u << KAAWIDTH) /* KA reg length */
#define KABASE (REGBASE + 0x4000) /* KA650 addr base */
/* CQBIC registers */
#define CQBICSIZE (5 << 2) /* 5 registers */
#define CQBICBASE (REGBASE) /* CQBIC addr base */
#define CQMAPASIZE 15 /* map addr width */
#define CQMAPSIZE (1u << CQMAPASIZE) /* map length */
#define CQMAPAMASK (CQMAPSIZE - 1) /* map addr mask */
#define CQMAPBASE (REGBASE + 0x8000) /* map addr base */
#define CQIPCSIZE 2 /* 2 bytes only */
#define CQIPCBASE (REGBASE + 0x1F40) /* ipc reg addr */
#define CQBICSIZE (5 << 2) /* 5 registers */
#define CQBICBASE (REGBASE) /* CQBIC addr base */
#define CQMAPASIZE 15 /* map addr width */
#define CQMAPSIZE (1u << CQMAPASIZE) /* map length */
#define CQMAPAMASK (CQMAPSIZE - 1) /* map addr mask */
#define CQMAPBASE (REGBASE + 0x8000) /* map addr base */
#define CQIPCSIZE 2 /* 2 bytes only */
#define CQIPCBASE (REGBASE + 0x1F40) /* ipc reg addr */
/* CMCTL registers */
/* #define CMCTLSIZE (18 << 2) /* 18 registers */
#define CMCTLSIZE (19 << 2) /* KA655X extra reg */
#define CMCTLBASE (REGBASE + 0x100) /* CMCTL addr base */
/* #define CMCTLSIZE (18 << 2) /* 18 registers */
#define CMCTLSIZE (19 << 2) /* KA655X extra reg */
#define CMCTLBASE (REGBASE + 0x100) /* CMCTL addr base */
/* SSC registers */
#define SSCSIZE 0x150 /* SSC size */
#define SSCBASE 0x20140000 /* SSC base */
#define SSCSIZE 0x150 /* SSC size */
#define SSCBASE 0x20140000 /* SSC base */
/* Non-volatile RAM - 1KB long */
#define NVRAWIDTH 10 /* NVR addr width */
#define NVRSIZE (1u << NVRAWIDTH) /* NVR length */
#define NVRAMASK (NVRSIZE - 1) /* NVR addr mask */
#define NVRBASE 0x20140400 /* NVR base */
#define ADDR_IS_NVR(x) ((((uint32) (x)) >= NVRBASE) && \
(((uint32) (x)) < (NVRBASE + NVRSIZE)))
#define NVRAWIDTH 10 /* NVR addr width */
#define NVRSIZE (1u << NVRAWIDTH) /* NVR length */
#define NVRAMASK (NVRSIZE - 1) /* NVR addr mask */
#define NVRBASE 0x20140400 /* NVR base */
#define ADDR_IS_NVR(x) ((((uint32) (x)) >= NVRBASE) && \
(((uint32) (x)) < (NVRBASE + NVRSIZE)))
/* CQBIC Qbus memory space (seen from CVAX) */
#define CQMAWIDTH 22 /* Qmem addr width */
#define CQMSIZE (1u << CQMAWIDTH) /* Qmem length */
#define CQMAMASK (CQMSIZE - 1) /* Qmem addr mask */
#define CQMBASE 0x30000000 /* Qmem base */
#define CQMAWIDTH 22 /* Qmem addr width */
#define CQMSIZE (1u << CQMAWIDTH) /* Qmem length */
#define CQMAMASK (CQMSIZE - 1) /* Qmem addr mask */
#define CQMBASE 0x30000000 /* Qmem base */
/* Qbus I/O modes */
#define READ 0 /* PDP-11 compatibility */
#define WRITE (L_WORD)
#define WRITEB (L_BYTE)
#define READ 0 /* PDP-11 compatibility */
#define WRITE (L_WORD)
#define WRITEB (L_BYTE)
/* Common CSI flags */
#define CSR_V_GO 0 /* go */
#define CSR_V_IE 6 /* interrupt enable */
#define CSR_V_DONE 7 /* done */
#define CSR_V_BUSY 11 /* busy */
#define CSR_V_ERR 15 /* error */
#define CSR_GO (1u << CSR_V_GO)
#define CSR_IE (1u << CSR_V_IE)
#define CSR_DONE (1u << CSR_V_DONE)
#define CSR_BUSY (1u << CSR_V_BUSY)
#define CSR_ERR (1u << CSR_V_ERR)
#define CSR_V_GO 0 /* go */
#define CSR_V_IE 6 /* interrupt enable */
#define CSR_V_DONE 7 /* done */
#define CSR_V_BUSY 11 /* busy */
#define CSR_V_ERR 15 /* error */
#define CSR_GO (1u << CSR_V_GO)
#define CSR_IE (1u << CSR_V_IE)
#define CSR_DONE (1u << CSR_V_DONE)
#define CSR_BUSY (1u << CSR_V_BUSY)
#define CSR_ERR (1u << CSR_V_ERR)
/* Timers */
#define TMR_CLK 0 /* 100Hz clock */
#define TMR_CLK 0 /* 100Hz clock */
/* I/O system definitions */
#define DZ_MUXES 4 /* max # of DZV muxes */
#define DZ_LINES 4 /* lines per DZV mux */
#define VH_MUXES 4 /* max # of DHQ muxes */
#define MT_MAXFR (1 << 16) /* magtape max rec */
#define AUTO_LNT 34 /* autoconfig ranks */
#define DZ_MUXES 4 /* max # of DZV muxes */
#define DZ_LINES 4 /* lines per DZV mux */
#define VH_MUXES 4 /* max # of DHQ muxes */
#define MT_MAXFR (1 << 16) /* magtape max rec */
#define AUTO_LNT 34 /* autoconfig ranks */
#define DEV_V_UBUS (DEV_V_UF + 0) /* Unibus */
#define DEV_V_QBUS (DEV_V_UF + 1) /* Qbus */
#define DEV_V_Q18 (DEV_V_UF + 2) /* Qbus, mem <= 256KB */
#define DEV_V_FLTA (DEV_V_UF + 3) /* flt addr */
#define DEV_UBUS (1u << DEV_V_UBUS)
#define DEV_QBUS (1u << DEV_V_QBUS)
#define DEV_Q18 (1u << DEV_V_Q18)
#define DEV_FLTA (1u << DEV_V_FLTA)
#define DEV_V_UBUS (DEV_V_UF + 0) /* Unibus */
#define DEV_V_QBUS (DEV_V_UF + 1) /* Qbus */
#define DEV_V_Q18 (DEV_V_UF + 2) /* Qbus, mem <= 256KB */
#define DEV_V_FLTA (DEV_V_UF + 3) /* flt addr */
#define DEV_UBUS (1u << DEV_V_UBUS)
#define DEV_QBUS (1u << DEV_V_QBUS)
#define DEV_Q18 (1u << DEV_V_Q18)
#define DEV_FLTA (1u << DEV_V_FLTA)
#define UNIBUS FALSE /* 22b only */
#define UNIBUS FALSE /* 22b only */
#define DEV_RDX 16 /* default device radix */
#define DEV_RDX 16 /* default device radix */
/* Device information block */
#define VEC_DEVMAX 4 /* max device vec */
#define VEC_DEVMAX 4 /* max device vec */
struct pdp_dib {
uint32 ba; /* base addr */
uint32 lnt; /* length */
t_stat (*rd)(int32 *dat, int32 ad, int32 md);
t_stat (*wr)(int32 dat, int32 ad, int32 md);
int32 vnum; /* vectors: number */
int32 vloc; /* locator */
int32 vec; /* value */
int32 (*ack[VEC_DEVMAX])(void); /* ack routine */
};
typedef struct pdp_dib DIB;
typedef struct {
uint32 ba; /* base addr */
uint32 lnt; /* length */
t_stat (*rd)(int32 *dat, int32 ad, int32 md);
t_stat (*wr)(int32 dat, int32 ad, int32 md);
int32 vnum; /* vectors: number */
int32 vloc; /* locator */
int32 vec; /* value */
int32 (*ack[VEC_DEVMAX])(void); /* ack routine */
} DIB;
/* I/O page layout - RQB,RQC,RQD float based on number of DZ's */
#define IOBA_DZ (IOPAGEBASE + 000100) /* DZ11 */
#define IOLN_DZ 010
#define IOBA_RQB (IOPAGEBASE + 000334 + (020 * (DZ_MUXES / 2)))
#define IOLN_RQB 004
#define IOBA_RQC (IOPAGEBASE + IOBA_RQB + IOLN_RQB)
#define IOLN_RQC 004
#define IOBA_RQD (IOPAGEBASE + IOBA_RQC + IOLN_RQC)
#define IOLN_RQD 004
#define IOBA_VH (IOPAGEBASE + 000440) /* DHQ11 */
#define IOLN_VH 020
#define IOBA_RQ (IOPAGEBASE + 012150) /* RQDX3 */
#define IOLN_RQ 004
#define IOBA_TS (IOPAGEBASE + 012520) /* TS11 */
#define IOLN_TS 004
#define IOBA_RL (IOPAGEBASE + 014400) /* RL11 */
#define IOLN_RL 012
#define IOBA_XQ (IOPAGEBASE + 014440) /* DEQNA/DELQA */
#define IOLN_XQ 020
#define IOBA_XQB (IOPAGEBASE + 014460) /* 2nd DEQNA/DELQA */
#define IOLN_XQB 020
#define IOBA_TQ (IOPAGEBASE + 014500) /* TMSCP */
#define IOLN_TQ 004
#define IOBA_RP (IOPAGEBASE + 016700) /* RP/RM */
#define IOLN_RP 054
#define IOBA_RX (IOPAGEBASE + 017170) /* RXV11 */
#define IOLN_RX 004
#define IOBA_RY (IOPAGEBASE + 017170) /* RXV21 */
#define IOLN_RY 004
#define IOBA_DBL (IOPAGEBASE + 017500) /* doorbell */
#define IOLN_DBL 002
#define IOBA_LPT (IOPAGEBASE + 017514) /* LP11 */
#define IOLN_LPT 004
#define IOBA_PTR (IOPAGEBASE + 017550) /* PC11 reader */
#define IOLN_PTR 004
#define IOBA_PTP (IOPAGEBASE + 017554) /* PC11 punch */
#define IOLN_PTP 004
#define IOBA_DZ (IOPAGEBASE + 000100) /* DZ11 */
#define IOLN_DZ 010
#define IOBA_RQB (IOPAGEBASE + 000334 + (020 * (DZ_MUXES / 2)))
#define IOLN_RQB 004
#define IOBA_RQC (IOPAGEBASE + IOBA_RQB + IOLN_RQB)
#define IOLN_RQC 004
#define IOBA_RQD (IOPAGEBASE + IOBA_RQC + IOLN_RQC)
#define IOLN_RQD 004
#define IOBA_VH (IOPAGEBASE + 000440) /* DHQ11 */
#define IOLN_VH 020
#define IOBA_RQ (IOPAGEBASE + 012150) /* RQDX3 */
#define IOLN_RQ 004
#define IOBA_TS (IOPAGEBASE + 012520) /* TS11 */
#define IOLN_TS 004
#define IOBA_RL (IOPAGEBASE + 014400) /* RL11 */
#define IOLN_RL 012
#define IOBA_XQ (IOPAGEBASE + 014440) /* DEQNA/DELQA */
#define IOLN_XQ 020
#define IOBA_XQB (IOPAGEBASE + 014460) /* 2nd DEQNA/DELQA */
#define IOLN_XQB 020
#define IOBA_TQ (IOPAGEBASE + 014500) /* TMSCP */
#define IOLN_TQ 004
#define IOBA_RP (IOPAGEBASE + 016700) /* RP/RM */
#define IOLN_RP 054
#define IOBA_RX (IOPAGEBASE + 017170) /* RXV11 */
#define IOLN_RX 004
#define IOBA_RY (IOPAGEBASE + 017170) /* RXV21 */
#define IOLN_RY 004
#define IOBA_QDSS (IOPAGEBASE + 017400) /* QDSS */
#define IOLN_QDSS 002
#define IOBA_DBL (IOPAGEBASE + 017500) /* doorbell */
#define IOLN_DBL 002
#define IOBA_LPT (IOPAGEBASE + 017514) /* LP11 */
#define IOLN_LPT 004
#define IOBA_PTR (IOPAGEBASE + 017550) /* PC11 reader */
#define IOLN_PTR 004
#define IOBA_PTP (IOPAGEBASE + 017554) /* PC11 punch */
#define IOLN_PTP 004
/* The KA65x maintains 4 separate hardware IPL levels, IPL 17 to IPL 14
Within each IPL, priority is right to left
@@ -304,123 +305,118 @@ typedef struct pdp_dib DIB;
/* IPL 16 */
#define INT_V_CLK 0 /* clock */
#define INT_V_CLK 0 /* clock */
/* IPL 15 */
#define INT_V_RQ 0 /* RQDX3 */
#define INT_V_RL 1 /* RLV12/RL02 */
#define INT_V_DZRX 2 /* DZ11 */
#define INT_V_DZTX 3
#define INT_V_RP 4 /* RP,RM drives */
#define INT_V_TS 5 /* TS11/TSV05 */
#define INT_V_TQ 6 /* TMSCP */
#define INT_V_XQ 7 /* DEQNA/DELQA */
#define INT_V_RY 8 /* RXV21 */
#define INT_V_RQ 0 /* RQDX3 */
#define INT_V_RL 1 /* RLV12/RL02 */
#define INT_V_DZRX 2 /* DZ11 */
#define INT_V_DZTX 3
#define INT_V_RP 4 /* RP,RM drives */
#define INT_V_TS 5 /* TS11/TSV05 */
#define INT_V_TQ 6 /* TMSCP */
#define INT_V_XQ 7 /* DEQNA/DELQA */
#define INT_V_RY 8 /* RXV21 */
/* IPL 14 */
#define INT_V_TTI 0 /* console */
#define INT_V_TTO 1
#define INT_V_PTR 2 /* PC11 */
#define INT_V_PTP 3
#define INT_V_LPT 4 /* LP11 */
#define INT_V_CSI 5 /* SSC cons UART */
#define INT_V_CSO 6
#define INT_V_TMR0 7 /* SSC timers */
#define INT_V_TMR1 8
#define INT_V_VHRX 9 /* DHQ11 */
#define INT_V_VHTX 10
#define INT_V_TTI 0 /* console */
#define INT_V_TTO 1
#define INT_V_PTR 2 /* PC11 */
#define INT_V_PTP 3
#define INT_V_LPT 4 /* LP11 */
#define INT_V_CSI 5 /* SSC cons UART */
#define INT_V_CSO 6
#define INT_V_TMR0 7 /* SSC timers */
#define INT_V_TMR1 8
#define INT_V_VHRX 9 /* DHQ11 */
#define INT_V_VHTX 10
#define INT_V_QDSS 11 /* QDSS */
#define INT_CLK (1u << INT_V_CLK)
#define INT_RQ (1u << INT_V_RQ)
#define INT_RL (1u << INT_V_RL)
#define INT_DZRX (1u << INT_V_DZRX)
#define INT_DZTX (1u << INT_V_DZTX)
#define INT_RP (1u << INT_V_RP)
#define INT_TS (1u << INT_V_TS)
#define INT_TQ (1u << INT_V_TQ)
#define INT_XQ (1u << INT_V_XQ)
#define INT_RY (1u << INT_V_RY)
#define INT_TTI (1u << INT_V_TTI)
#define INT_TTO (1u << INT_V_TTO)
#define INT_PTR (1u << INT_V_PTR)
#define INT_PTP (1u << INT_V_PTP)
#define INT_LPT (1u << INT_V_LPT)
#define INT_CSI (1u << INT_V_CSI)
#define INT_CSO (1u << INT_V_CSO)
#define INT_TMR0 (1u << INT_V_TMR0)
#define INT_TMR1 (1u << INT_V_TMR1)
#define INT_VHRX (1u << INT_V_VHRX)
#define INT_VHTX (1u << INT_V_VHTX)
#define INT_CLK (1u << INT_V_CLK)
#define INT_RQ (1u << INT_V_RQ)
#define INT_RL (1u << INT_V_RL)
#define INT_DZRX (1u << INT_V_DZRX)
#define INT_DZTX (1u << INT_V_DZTX)
#define INT_RP (1u << INT_V_RP)
#define INT_TS (1u << INT_V_TS)
#define INT_TQ (1u << INT_V_TQ)
#define INT_XQ (1u << INT_V_XQ)
#define INT_RY (1u << INT_V_RY)
#define INT_TTI (1u << INT_V_TTI)
#define INT_TTO (1u << INT_V_TTO)
#define INT_PTR (1u << INT_V_PTR)
#define INT_PTP (1u << INT_V_PTP)
#define INT_LPT (1u << INT_V_LPT)
#define INT_CSI (1u << INT_V_CSI)
#define INT_CSO (1u << INT_V_CSO)
#define INT_TMR0 (1u << INT_V_TMR0)
#define INT_TMR1 (1u << INT_V_TMR1)
#define INT_VHRX (1u << INT_V_VHRX)
#define INT_VHTX (1u << INT_V_VHTX)
#define INT_QDSS (1u << INT_V_QDSS)
#define IPL_CLK (0x16 - IPL_HMIN) /* relative IPL */
#define IPL_RQ (0x15 - IPL_HMIN)
#define IPL_RL (0x15 - IPL_HMIN)
#define IPL_DZRX (0x15 - IPL_HMIN)
#define IPL_DZTX (0x15 - IPL_HMIN)
#define IPL_RP (0x15 - IPL_HMIN)
#define IPL_TS (0x15 - IPL_HMIN)
#define IPL_TQ (0x15 - IPL_HMIN)
#define IPL_XQ (0x15 - IPL_HMIN)
#define IPL_RY (0x15 - IPL_HMIN)
#define IPL_TTI (0x14 - IPL_HMIN)
#define IPL_TTO (0x14 - IPL_HMIN)
#define IPL_PTR (0x14 - IPL_HMIN)
#define IPL_PTP (0x14 - IPL_HMIN)
#define IPL_LPT (0x14 - IPL_HMIN)
#define IPL_CSI (0x14 - IPL_HMIN)
#define IPL_CSO (0x14 - IPL_HMIN)
#define IPL_TMR0 (0x14 - IPL_HMIN)
#define IPL_TMR1 (0x14 - IPL_HMIN)
#define IPL_VHRX (0x14 - IPL_HMIN)
#define IPL_VHTX (0x14 - IPL_HMIN)
#define IPL_CLK (0x16 - IPL_HMIN) /* relative IPL */
#define IPL_RQ (0x15 - IPL_HMIN)
#define IPL_RL (0x15 - IPL_HMIN)
#define IPL_DZRX (0x15 - IPL_HMIN)
#define IPL_DZTX (0x15 - IPL_HMIN)
#define IPL_RP (0x15 - IPL_HMIN)
#define IPL_TS (0x15 - IPL_HMIN)
#define IPL_TQ (0x15 - IPL_HMIN)
#define IPL_XQ (0x15 - IPL_HMIN)
#define IPL_RY (0x15 - IPL_HMIN)
#define IPL_TTI (0x14 - IPL_HMIN)
#define IPL_TTO (0x14 - IPL_HMIN)
#define IPL_PTR (0x14 - IPL_HMIN)
#define IPL_PTP (0x14 - IPL_HMIN)
#define IPL_LPT (0x14 - IPL_HMIN)
#define IPL_CSI (0x14 - IPL_HMIN)
#define IPL_CSO (0x14 - IPL_HMIN)
#define IPL_TMR0 (0x14 - IPL_HMIN)
#define IPL_TMR1 (0x14 - IPL_HMIN)
#define IPL_VHRX (0x14 - IPL_HMIN)
#define IPL_VHTX (0x14 - IPL_HMIN)
#define IPL_QDSS (0x14 - IPL_HMIN)
#define IPL_HMAX 0x17 /* highest hwre level */
#define IPL_HMIN 0x14 /* lowest hwre level */
#define IPL_HLVL (IPL_HMAX - IPL_HMIN + 1) /* # hardware levels */
#define IPL_SMAX 0xF /* highest swre level */
#define IPL_HMAX 0x17 /* highest hwre level */
#define IPL_HMIN 0x14 /* lowest hwre level */
#define IPL_HLVL (IPL_HMAX - IPL_HMIN + 1) /* # hardware levels */
#define IPL_SMAX 0xF /* highest swre level */
/* Device vectors */
#define VEC_Q 0x200 /* Qbus vector offset */
#define VEC_PTR (VEC_Q + 0070)
#define VEC_PTP (VEC_Q + 0074)
#define VEC_XQ (VEC_Q + 0120)
#define VEC_RQ (VEC_Q + 0154)
#define VEC_RL (VEC_Q + 0160)
#define VEC_LPT (VEC_Q + 0200)
#define VEC_TS (VEC_Q + 0224)
#define VEC_RP (VEC_Q + 0254)
#define VEC_TQ (VEC_Q + 0260)
#define VEC_RY (VEC_Q + 0264)
#define VEC_DZRX (VEC_Q + 0300)
#define VEC_DZTX (VEC_Q + 0304)
#define VEC_VHRX (VEC_Q + 0310)
#define VEC_VHTX (VEC_Q + 0314)
/* Autoconfigure ranks */
#define RANK_DZ 8
#define RANK_RL 14
#define RANK_RX 18
#define RANK_RQ 26
#define RANK_TQ 30
#define RANK_VH 32
#define VEC_Q 0x200 /* Qbus vector offset */
#define VEC_PTR (VEC_Q + 0070)
#define VEC_PTP (VEC_Q + 0074)
#define VEC_XQ (VEC_Q + 0120)
#define VEC_RQ (VEC_Q + 0154)
#define VEC_RL (VEC_Q + 0160)
#define VEC_LPT (VEC_Q + 0200)
#define VEC_TS (VEC_Q + 0224)
#define VEC_RP (VEC_Q + 0254)
#define VEC_TQ (VEC_Q + 0260)
#define VEC_RX (VEC_Q + 0264)
#define VEC_RY (VEC_Q + 0264)
#define VEC_DZRX (VEC_Q + 0300)
#define VEC_DZTX (VEC_Q + 0304)
#define VEC_VHRX (VEC_Q + 0310)
#define VEC_VHTX (VEC_Q + 0314)
/* Interrupt macros */
#define IVCL(dv) ((IPL_##dv * 32) + INT_V_##dv)
#define IREQ(dv) int_req[IPL_##dv]
#define SET_INT(dv) int_req[IPL_##dv] = int_req[IPL_##dv] | (INT_##dv)
#define CLR_INT(dv) int_req[IPL_##dv] = int_req[IPL_##dv] & ~(INT_##dv)
#define IORETURN(f,v) ((f)? (v): SCPE_OK) /* cond error return */
#define IVCL(dv) ((IPL_##dv * 32) + INT_V_##dv)
#define IREQ(dv) int_req[IPL_##dv]
#define SET_INT(dv) int_req[IPL_##dv] = int_req[IPL_##dv] | (INT_##dv)
#define CLR_INT(dv) int_req[IPL_##dv] = int_req[IPL_##dv] & ~(INT_##dv)
#define IORETURN(f,v) ((f)? (v): SCPE_OK) /* cond error return */
/* Logging */
#define LOG_CPU_I 0x1 /* intexc */
#define LOG_CPU_R 0x2 /* REI */
#define LOG_CPU_P 0x4 /* context */
#define LOG_CPU_I 0x1 /* intexc */
#define LOG_CPU_R 0x2 /* REI */
#define LOG_CPU_P 0x4 /* context */
/* Function prototypes for I/O */
@@ -434,6 +430,6 @@ t_stat show_addr (FILE *st, UNIT *uptr, int32 val, void *desc);
t_stat set_addr_flt (UNIT *uptr, int32 val, char *cptr, void *desc);
t_stat set_vec (UNIT *uptr, int32 val, char *cptr, void *desc);
t_stat show_vec (FILE *st, UNIT *uptr, int32 val, void *desc);
t_stat auto_config (uint32 rank, uint32 num);
t_stat auto_config (char *name, int32 num);
#endif