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:
committed by
Mark Pizzolato
parent
ec60bbf329
commit
b7c1eae41f
2083
VAX/vax_cis.c
2083
VAX/vax_cis.c
File diff suppressed because it is too large
Load Diff
1632
VAX/vax_cmode.c
1632
VAX/vax_cmode.c
File diff suppressed because it is too large
Load Diff
4331
VAX/vax_cpu.c
4331
VAX/vax_cpu.c
File diff suppressed because it is too large
Load Diff
1852
VAX/vax_cpu1.c
1852
VAX/vax_cpu1.c
File diff suppressed because it is too large
Load Diff
963
VAX/vax_defs.h
963
VAX/vax_defs.h
File diff suppressed because it is too large
Load Diff
@@ -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:
|
||||
|
||||
1323
VAX/vax_fpa.c
1323
VAX/vax_fpa.c
File diff suppressed because it is too large
Load Diff
1031
VAX/vax_io.c
1031
VAX/vax_io.c
File diff suppressed because it is too large
Load Diff
529
VAX/vax_mmu.c
529
VAX/vax_mmu.c
@@ -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;
|
||||
}
|
||||
|
||||
1237
VAX/vax_octa.c
1237
VAX/vax_octa.c
File diff suppressed because it is too large
Load Diff
311
VAX/vax_stddev.c
311
VAX/vax_stddev.c
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
2074
VAX/vax_sys.c
2074
VAX/vax_sys.c
File diff suppressed because it is too large
Load Diff
725
VAX/vax_syscm.c
725
VAX/vax_syscm.c
@@ -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);
|
||||
}
|
||||
|
||||
1442
VAX/vax_sysdev.c
1442
VAX/vax_sysdev.c
File diff suppressed because it is too large
Load Diff
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user