simh-testsetgenerator/B5500/b5500_sys.c
Richard Cornwell 0a33758e47 B5500: Initial checking of simulator for current simh
The B5500 simulator supports the following peripherals.

Two CPUs with between 4K and 32K of memory. The second CPU can be
enabled with "set cpu1 enable". "set cpu1 disable" disables the
second CPU.

Up to 4 floating IO channels. Individual channels can be enabled with
"set io# enable", or "set io# disable".

There are two card readers. The second reader is disabled by default.

There is one Card Punch.

The Card reader and Card Punch support the following options:
  set cr format=

     auto   - will automatically determine the format based on the
              text it recieves.
     text     Text based cards. Tabs are converted to the correct
              number of spaces. A record of
              ~raw octal will enter a binary card.
              ~eor will enter a 7/8/9 punch in column 1.
              ~eof will enter a 6/7/9 punch in column 1.
              ~eoi will enter a 6/7/8/9 punch in column 1.
              ~~ will enter a ~ as the first character.

     bin      Binary Card format:
              Each record 160 characters.
              First characters 6789----
              Second character 21012345
                               111
              Top 4 bits of second character are 0.
              It is unlikely that any other format could
              look like this.

     bcd      BCD Format:
              Each record variable length (80 chars or less).
              Record mark has bit 7 set.
              Bit 6 is even parity.
              Bits 5-0 are character.

    cbn       CBN Format:
              Each record 160 charaters.
              First char has bit 7 set. Rest set to 0.
              Bit 6 is odd parity.
              Bit 5-0 of first character are top 6 bits
                      of card.
              Bit 5-0 of second character are lower 6 bits
                      of card.

    For punch format of auto if the card can't be converted to text it is
    output as a raw record.

 There are two line printers, the second one is disabled by default. The LP
 supports the option "set lp# linesperpage=#" which determines when the
 printer will force out a page break.

 There are up to 16 mag tape drives, the format is controlled by the standard
 simh format control for tapes. These are 6 bit tapes, 1 character per record
 with parity. Units 8-16 are disabled by default.

 There are up to two drum units DR0 and DR1. These can either be attached
 to a file or set to AUXMEM. Setting to AUXMEM causes them to exist only
 during the given simh run. Setting back to DRUM will clear whatever was
 stored on the drum. To enable use of DRUM on XV the following options should
 be turned on "DRA,DRB,CODEOLAY,DATAOLAY". MCP will then use the drum as a
 overlay device instead of the disk system.

 Disks can be attached to the various ESU's, ESU0-9 are on DKA by default,
 ESU10-19 are on DKB. If "set dk1 dfx" is set, then ESU10-19 are not used and
 the disks are shared by both DKA and DKB. To use more then 10 ESU's in a non
 shared mode, a new version of MCP must be created. MCP must be compiled with
 DFX option set to false. For MCP XV DKBNODFX must also be set to true.  ESU units
 can be set to MODI or MODIB. MODIB will double the size of the drive.

 The DTC can be attached to a telnet port with "attach dtc #" to enable dialup
 access to the sim.

The loader card for the card reader is:
~raw0104441100204231524012004000004444550211002041317700000000000024045303040243
00050000006501004131011041310055005500000062005042310000006600304231000000720010
42310000007675610165001002310010413100040107202500440106202533554061256520252265
20251765202514655355536117650000004401062025155522610165225572610465044101160500
4131

  This card should be all in one line.
2016-02-06 15:51:04 -05:00

541 lines
22 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* b5500_sys.c: Burroughs 5500 Simulator system interface.
Copyright (c) 2016, Richard Cornwell
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
RICHARD CORNWELL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "sim_defs.h"
#include "b5500_defs.h"
#include "sim_card.h"
#include <ctype.h>
t_stat parse_sym(char *cptr, t_addr addr, UNIT * uptr, t_value * val, int32 sw);
/* SCP data structures and interface routines
sim_name simulator name string
sim_PC pointer to saved PC register descriptor
sim_emax number of words for examine
sim_devices array of pointers to simulated devices
sim_stop_messages array of pointers to stop messages
sim_load binary loader
*/
char sim_name[] = "B5500";
REG *sim_PC = &cpu_reg[0];
int32 sim_emax = 1;
DEVICE *sim_devices[] = {
&cpu_dev,
&chan_dev,
#if NUM_DEVS_CDR > 0
&cdr_dev,
#endif
#if NUM_DEVS_CDP > 0
&cdp_dev,
#endif
#if NUM_DEVS_LPR > 0
&lpr_dev,
#endif
#if NUM_DEVS_CON > 0
&con_dev,
#endif
#if NUM_DEVS_MT > 0
&mt_dev,
#endif
#if NUM_DEVS_DR > 0
&drm_dev,
#endif
#if NUM_DEVS_DSK > 0
&esu_dev,
&dsk_dev,
#endif
#if NUM_DEVS_DTC > 0
&dtc_dev,
#endif
NULL
};
/* Simulator stop codes */
const char *sim_stop_messages[] = {
0,
};
/* Simulator debug controls */
DEBTAB dev_debug[] = {
{"CMD", DEBUG_CMD, "Show command execution to devices"},
{"DATA", DEBUG_DATA, "Show data transfers"},
{"DETAIL", DEBUG_DETAIL, "Show details about device"},
{"EXP", DEBUG_EXP, "Show exception information"},
{0, 0}
};
uint8 parity_table[64] = {
/* 0 1 2 3 4 5 6 7 */
0000, 0100, 0100, 0000, 0100, 0000, 0000, 0100,
0100, 0000, 0000, 0100, 0000, 0100, 0100, 0000,
0100, 0000, 0000, 0100, 0000, 0100, 0100, 0000,
0000, 0100, 0100, 0000, 0100, 0000, 0000, 0100,
0100, 0000, 0000, 0100, 0000, 0100, 0100, 0000,
0000, 0100, 0100, 0000, 0100, 0000, 0000, 0100,
0000, 0100, 0100, 0000, 0100, 0000, 0000, 0100,
0100, 0000, 0000, 0100, 0000, 0100, 0100, 0000
};
uint8 mem_to_ascii[64] = {
/* x0 x1 x2 x3 x4 x5 x6 x7 */
'0', '1', '2', '3', '4', '5', '6', '7', /* 0x */
'8', '9', '#', '@', '?', ':', '>', '}', /* 1x */
'+', 'A', 'B', 'C', 'D', 'E', 'F', 'G', /* 2x */
'H', 'I', '.', '[', '&', '(', '<', '~', /* 3x */
'|', 'J', 'K', 'L', 'M', 'N', 'O', 'P', /* 4x */
'Q', 'R', '$', '*', '-', ')', ';', '{', /* 5x */
' ', '/', 'S', 'T', 'U', 'V', 'W', 'X', /* 6x */
'Y', 'Z', ',', '%', '!', '=', ']', '"' /* 7x */
};
const char con_to_ascii[64] = {
'?', '1', '2', '3', '4', '5', '6', '7',
'8', '9', '0', '#', '@', ':', '>', '}', /* 17 = box */
' ', '/', 'S', 'T', 'U', 'V', 'W', 'X',
'Y', 'Z', '!', ',', '%', '=', ']', '"',
'-', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
'Q', 'R', '|', '$', '*', ')', ';', '{', /* 57 = triangle */
'&', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
'H', 'I', '+', '.', '[', '(', '<', '~', /* 37 = stop code */
}; /* 72 = rec mark */
/* 75 = squiggle, 77 = del */
const char ascii_to_con[128] = {
/* Control */
-1, -1, -1, -1, -1, -1, -1, -1, /* 0 - 37 */
/* Control */
-1, -1, -1, -1, -1, -1, -1, -1,
/* Control */
-1, -1, -1, -1, -1, -1, -1, -1,
/* Control */
-1, -1, -1, -1, -1, -1, -1, -1,
/*sp ! " # $ % & ' */
020, 032, 037, 013, 053, 017, 060, 014, /* 40 - 77 */
/* ( ) * + , - . / */
075, 055, 054, 072, 033, 040, 073, 021,
/* 0 1 2 3 4 5 6 7 */
012, 001, 002, 003, 004, 005, 006, 007,
/* 8 9 : ; < = > ? */
010, 011, 015, 056, 076, 035, 016, 000,
/* @ A B C D E F G */
014, 061, 062, 063, 064, 065, 066, 067, /* 100 - 137 */
/* H I J K L M N O */
070, 071, 041, 042, 043, 044, 045, 046,
/* P Q R S T U V W */
047, 050, 051, 022, 023, 024, 025, 026,
/* X Y Z [ \ ] ^ _ */
027, 030, 031, 075, 036, 055, 057, 000,
/* ` a b c d e f g */
035, 061, 062, 063, 064, 065, 066, 067, /* 140 - 177 */
/* h i j k l m n o */
070, 071, 041, 042, 043, 044, 045, 046,
/* p q r s t u v w */
047, 050, 051, 022, 023, 024, 025, 026,
/* x y z { | } ~ del*/
027, 030, 031, 057, 077, 017, -1, -1
};
/* Load a card image file into memory. */
t_stat
sim_load(FILE * fileref, char *cptr, char *fnam, int flag)
{
/* Currently not implimented until I know format of load files */
return SCPE_NOFNC;
}
#define TYPE_A 1 /* Full 12 bit opcode */
#define TYPE_B 2 /* 6 Bit Opcode with 6 bit field */
#define TYPE_C 3 /* 8 Bit opcode with 4 bit field */
#define TYPE_D 4 /* 2 bit opcode, 10 bit field */
/* Opcodes */
t_opcode word_ops[] = {
/* Word mode opcodes */
WMOP_LITC, TYPE_D, "LITC", /* Load literal */
WMOP_OPDC, TYPE_D, "OPDC", /* Load operand */
WMOP_DESC, TYPE_D, "DESC", /* Load Descriptor */
WMOP_DEL, TYPE_A, "DEL", /* Delete top of stack */
WMOP_NOP, TYPE_A, "NOP", /* Nop operation */
WMOP_XRT, TYPE_A, "XRT", /* Set Variant */
WMOP_ADD, TYPE_A, "ADD", /* Add */
WMOP_DLA, TYPE_A, "DLA", /* Double Precision Add */
WMOP_PRL, TYPE_A, "PRL", /* Program Release */
WMOP_LNG, TYPE_A, "LNG", /* Logical Negate */
WMOP_CID, TYPE_A, "CID", /* Conditional Integer Store Destructive */
WMOP_GEQ, TYPE_A, "GEQ", /* B greater than or equal to A */
WMOP_BBC, TYPE_A, "BBC", /* Branch Backward Conditional */
WMOP_BRT, TYPE_A, "BRT", /* Branch Return */
WMOP_INX, TYPE_A, "INX", /* Index */
WMOP_ITI, TYPE_A, "ITI", /* Interrogate interrupt */
WMOP_LOR, TYPE_A, "LOR", /* Logical Or */
WMOP_CIN, TYPE_A, "CIN", /* Conditional Integer Store non-destructive */
WMOP_GTR, TYPE_A, "GTR", /* B Greater than A */
WMOP_BFC, TYPE_A, "BFC", /* Branch Forward Conditional */
WMOP_RTN, TYPE_A, "RTN", /* Return normal */
WMOP_COC, TYPE_A, "COC", /* Construct Operand Call */
WMOP_SUB, TYPE_A, "SUB", /* Subtract */
WMOP_DLS, TYPE_A, "DLS", /* Double Precision Subtract */
WMOP_MUL, TYPE_A, "MUL", /* Multiply */
WMOP_DLM, TYPE_A, "DLM", /* Double Precision Multiply */
WMOP_RTR, TYPE_A, "RTR", /* Read Timer */
WMOP_LND, TYPE_A, "LND", /* Logical And */
WMOP_STD, TYPE_A, "STD", /* B Store Destructive */
WMOP_NEQ, TYPE_A, "NEQ", /* B Not equal to A */
WMOP_SSN, TYPE_A, "SSN", /* Set Sign Bit */
WMOP_XIT, TYPE_A, "XIT", /* Exit */
WMOP_MKS, TYPE_A, "MKS", /* Mark Stack */
WMOP_DIV, TYPE_A, "DIV", /* Divide */
WMOP_DLD, TYPE_A, "DLD", /* Double Precision Divide */
WMOP_COM, TYPE_A, "COM", /* Communication operator */
WMOP_LQV, TYPE_A, "LQV", /* Logical Equivalence */
WMOP_SND, TYPE_A, "SND", /* B Store Non-destructive */
WMOP_XCH, TYPE_A, "XCH", /* Exchange */
WMOP_CHS, TYPE_A, "CHS", /* Change sign bit */
WMOP_RTS, TYPE_A, "RTS", /* Return Special */
WMOP_CDC, TYPE_A, "CDC", /* Construct descriptor call */
WMOP_FTC, TYPE_A, "FTC", /* Transfer F Field to Core Field */
WMOP_MOP, TYPE_A, "MOP", /* Reset Flag bit */
WMOP_LOD, TYPE_A, "LOD", /* Load */
WMOP_DUP, TYPE_A, "DUP", /* Duplicate */
WMOP_TOP, TYPE_A, "TOP", /* Test Flag Bit */
WMOP_IOR, TYPE_A, "IOR", /* I/O Release */
WMOP_LBC, TYPE_A, "LBC", /* Word Branch Backward Conditional */
WMOP_SSF, TYPE_A, "SSF", /* Set or Store S or F registers */
WMOP_HP2, TYPE_A, "HP2", /* Halt P2 */
WMOP_LFC, TYPE_A, "LFC", /* Word Branch Forward Conditional */
WMOP_ZP1, TYPE_A, "ZP1", /* Conditional Halt */
WMOP_TUS, TYPE_A, "TUS", /* Interrogate Peripheral Status */
WMOP_LLL, TYPE_A, "LLL", /* Link List Look-up */
WMOP_IDV, TYPE_A, "IDV", /* Integer Divide Integer */
WMOP_SFI, TYPE_A, "SFI", /* Store for Interrupt */
WMOP_SFT, TYPE_A, "SFT", /* Store for Test */
WMOP_FTF, TYPE_A, "FTF", /* Transfer F Field to F Field */
WMOP_MDS, TYPE_A, "MDS", /* Set Flag Bit */
WMOP_IP1, TYPE_A, "IP1", /* Initiate P1 */
WMOP_ISD, TYPE_A, "ISD", /* Interger Store Destructive */
WMOP_LEQ, TYPE_A, "LEQ", /* B Less Than or Equal to A */
WMOP_BBW, TYPE_A, "BBW", /* Banch Backward Conditional */
WMOP_IP2, TYPE_A, "IP2", /* Initiate P2 */
WMOP_ISN, TYPE_A, "ISN", /* Integer Store Non-Destructive */
WMOP_LSS, TYPE_A, "LSS", /* B Less Than A */
WMOP_BFW, TYPE_A, "BFW", /* Branch Forward Unconditional */
WMOP_IIO, TYPE_A, "IIO", /* Initiate I/O */
WMOP_EQL, TYPE_A, "EQL", /* B Equal A */
WMOP_SSP, TYPE_A, "SSP", /* Reset Sign Bit */
WMOP_CMN, TYPE_A, "CMN", /* Enter Character Mode In Line */
WMOP_IFT, TYPE_A, "IFT", /* Test Initiate */
WMOP_CTC, TYPE_A, "CTC", /* Transfer Core Field to Core Field */
WMOP_LBU, TYPE_A, "LBU", /* Word Branch Backward Unconditional */
WMOP_LFU, TYPE_A, "LFU", /* Word Branch Forward Unconditional */
WMOP_TIO, TYPE_A, "TIO", /* Interrogate I/O Channels */
WMOP_RDV, TYPE_A, "RDV", /* Remainder Divide */
WMOP_FBS, TYPE_A, "FBS", /* Flag Bit Search */
WMOP_CTF, TYPE_A, "CTF", /* Transfer Core Field to F Field */
WMOP_ISO, TYPE_B, "ISO", /* Variable Field Isolate XX */
WMOP_CBD, TYPE_C, "CBD", /* Non-Zero Field Branch Backward Destructive Xy */
WMOP_CBN, TYPE_C, "CBN", /* Non-Zero Field Branch Backward Non-Destructive Xy */
WMOP_CFD, TYPE_C, "CFD", /* Non-Zero Field Branch Forward Destructive Xy */
WMOP_CFN, TYPE_B, "CFN", /* Non-Zero Field Branch Forward Non-Destructive Xy */
WMOP_DIA, TYPE_B, "DIA", /* Dial A XX */
WMOP_DIB, TYPE_B, "DIB", /* Dial B XX Upper 6 not Zero */
WMOP_TRB, TYPE_B, "TRB", /* Transfer Bits XX */
WMOP_FCL, TYPE_B, "FCL", /* Compare Field Low XX */
WMOP_FCE, TYPE_B, "FCE", /* Compare Field Equal XX */
{0, 0, NULL},
};
t_opcode char_ops[] = {
/* Character Mode */
CMOP_EXC, TYPE_A, "EXC", /* Exit Character Mode */
CMOP_CMX, TYPE_A, "CMX", /* Exit Character Mode In Line */
CMOP_BSD, TYPE_B, "BSD", /* Skip Bit Destiniation */
CMOP_BSS, TYPE_B, "BSS", /* SKip Bit Source */
CMOP_RDA, TYPE_B, "RDA", /* Recall Destination Address */
CMOP_TRW, TYPE_B, "TRW", /* Transfer Words */
CMOP_SED, TYPE_B, "SED", /* Set Destination Address */
CMOP_TDA, TYPE_B, "TDA", /* Transfer Destination Address */
CMOP_TBN, TYPE_B, "TBN", /* Transfer Blanks for Non-Numerics */
WMOP_ITI, TYPE_A, "ITI", /* Interrogate interrupt */
WMOP_SFI, TYPE_A, "SFI", /* Store for Interrupt */
WMOP_SFT, TYPE_A, "SFT", /* Store for Test */
WMOP_ZP1, TYPE_A, "ZP1", /* Conditional Halt */
WMOP_HP2, TYPE_A, "HP2", /* Halt P2 */
CMOP_SDA, TYPE_B, "SDA", /* Store Destination Address */
CMOP_SSA, TYPE_B, "SSA", /* Store Source Address */
CMOP_SFD, TYPE_B, "SFD", /* Skip Forward Destination */
CMOP_SRD, TYPE_B, "SRD", /* Skip Reverse Destination */
CMOP_SES, TYPE_B, "SES", /* Set Source Address */
CMOP_TEQ, TYPE_B, "TEQ", /* Test for Equal */
CMOP_TNE, TYPE_B, "TNE", /* Test for Not-Equal */
CMOP_TEG, TYPE_B, "TEG", /* Test for Greater Or Equal */
CMOP_TGR, TYPE_B, "TGR", /* Test For Greater */
CMOP_SRS, TYPE_B, "SRS", /* Skip Reverse Source */
CMOP_SFS, TYPE_B, "SFS", /* Skip Forward Source */
CMOP_TEL, TYPE_B, "TEL", /* Test For Equal or Less */
CMOP_TLS, TYPE_B, "TLS", /* Test For Less */
CMOP_TAN, TYPE_B, "TAN", /* Test for Alphanumeric */
CMOP_BIT, TYPE_B, "BIT", /* Test Bit */
CMOP_INC, TYPE_B, "INC", /* Increase Tally */
CMOP_STC, TYPE_B, "STC", /* Store Tally */
CMOP_SEC, TYPE_B, "SEC", /* Set Tally */
CMOP_CRF, TYPE_B, "CRF", /* Call repeat Field */
CMOP_JNC, TYPE_B, "JNC", /* Jump Out Of Loop Conditional */
CMOP_JFC, TYPE_B, "JFC", /* Jump Forward Conditional */
CMOP_JNS, TYPE_B, "JNS", /* Jump out of loop unconditional */
CMOP_JFW, TYPE_B, "JFW", /* Jump Forward Unconditional */
CMOP_RCA, TYPE_B, "RCA", /* Recall Control Address */
CMOP_ENS, TYPE_B, "ENS", /* End Loop */
CMOP_BNS, TYPE_B, "BNS", /* Begin Loop */
CMOP_RSA, TYPE_B, "RSA", /* Recall Source Address */
CMOP_SCA, TYPE_B, "SCA", /* Store Control Address */
CMOP_JRC, TYPE_B, "JRC", /* Jump Reverse Conditional */
CMOP_TSA, TYPE_B, "TSA", /* Transfer Source Address */
CMOP_JRV, TYPE_B, "JRV", /* Jump Reverse Unconditional */
CMOP_CEQ, TYPE_B, "CEQ", /* Compare Equal */
CMOP_CNE, TYPE_B, "CNE", /* COmpare for Not Equal */
CMOP_CEG, TYPE_B, "CEG", /* Compare For Greater Or Equal */
CMOP_CGR, TYPE_B, "CGR", /* Compare For Greater */
CMOP_BIS, TYPE_B, "BIS", /* Set Bit */
CMOP_BIR, TYPE_B, "BIR", /* Reet Bit */
CMOP_OCV, TYPE_B, "OCV", /* Output Convert */
CMOP_ICV, TYPE_B, "ICV", /* Input Convert */
CMOP_CEL, TYPE_B, "CEL", /* Compare For Equal or Less */
CMOP_CLS, TYPE_B, "CLS", /* Compare for Less */
CMOP_FSU, TYPE_B, "FSU", /* Field Subtract */
CMOP_FAD, TYPE_B, "FAD", /* Field Add */
CMOP_TRP, TYPE_B, "TRP", /* Transfer Program Characters */
CMOP_TRN, TYPE_B, "TRN", /* Transfer Numeric */
CMOP_TRZ, TYPE_B, "TRZ", /* Transfer Zones */
CMOP_TRS, TYPE_B, "TRS", /* Transfer Source Characters */
{0, 0, NULL},
};
/* Print out an instruction */
void
print_opcode(FILE * of, t_value val, t_opcode * tab)
{
uint16 op;
op = val;
while (tab->name != NULL) {
switch(tab->type) {
case TYPE_A:
if (op != tab->op)
break;
fputs(tab->name, of);
fputs(" ",of);
return;
case TYPE_B:
if ((op & 077) != tab->op)
break;
fputs(tab->name, of);
fputc(' ',of);
fputc(' ',of);
fprint_val(of, (val >> 6), 8, 6, 0);
fputs(" ",of);
return;
case TYPE_C:
if ((op & 0377) != tab->op)
break;
fputs(tab->name, of);
fputc(' ',of);
fprint_val(of, (val >> 8), 8, 4, 0);
fputs(" ",of);
return;
case TYPE_D:
if ((op & 03) != tab->op)
break;
fputs(tab->name, of);
fputc(' ',of);
fprint_val(of, (val >> 2), 8, 10, 0);
fputc(' ',of);
return;
}
tab++;
}
fprintf(of, "*%04o uuo ", op);
}
/* Symbolic decode
Inputs:
*of = output stream
addr = current PC
*val = pointer to values
*uptr = pointer to unit
sw = switches
Outputs:
return = status code
*/
t_stat
fprint_sym(FILE * of, t_addr addr, t_value * val, UNIT * uptr, int32 sw)
{
t_value inst = *val;
int i;
fputc(' ', of);
fprint_val(of, inst, 8, 48, PV_RZRO);
if (sw & SWMASK('W')) { /* Word mode opcodes */
fputs(" ", of);
for (i = 36; i >= 0; i-=12) {
int op = (int)(inst >> i) & 07777;
print_opcode(of, op, word_ops);
}
}
if (sw & SWMASK('C')) { /* Char mode opcodes */
fputs(" ", of);
for (i = 36; i >= 0; i-=12) {
int op = (int)(inst >> i) & 07777;
print_opcode(of, op, char_ops);
}
}
if (sw & SWMASK('B')) { /* BCD mode */
fputs(" '", of);
for (i = 42; i >= 0; i-=6) {
int ch;
ch = (int)(inst >> i) & 077;
fputc(mem_to_ascii[ch], of);
}
fputc('\'', of);
}
if (sw & SWMASK('F')) { /* Floating point/Descriptor */
}
return SCPE_OK;
}
t_opcode *
find_opcode(char *op, t_opcode * tab)
{
while (tab->name != NULL) {
if (*tab->name != '\0' && strcmp(op, tab->name) == 0)
return tab;
tab++;
}
return NULL;
}
/* Symbolic input
Inputs:
*cptr = pointer to input string
addr = current PC
uptr = pointer to unit
*val = pointer to output values
sw = switches
Outputs:
status = error status
*/
t_stat
parse_sym(char *cptr, t_addr addr, UNIT * uptr, t_value * val, int32 sw)
{
int i;
t_value d;
int opr;
char opcode[100];
while (isspace(*cptr))
cptr++;
d = 0;
if (sw & (SWMASK('W')|SWMASK('C'))) {
t_opcode *op;
/* Grab opcode */
cptr = get_glyph(cptr, opcode, 0);
op = 0;
opr = -1;
if((op = find_opcode(opcode,
(SWMASK('W') ? word_ops : char_ops))) == 0) {
return SCPE_UNK;
}
while (*cptr == ' ' || *cptr == '\t')
cptr++;
/* Collect first argument if there is one */
while (*cptr >= '0' && *cptr <= '7')
opr = (opr << 3) + (*cptr++ - '0');
/* Skip blanks */
while (*cptr == ' ' || *cptr == '\t')
cptr++;
switch (op->type) {
case TYPE_A:
if (opr >= 0)
return SCPE_2MARG;
*val = op->op;
return SCPE_OK;
case TYPE_B:
if (opr < 0 || opr > 64)
return SCPE_ARG;
*val = (opr << 6) | op->op;
return SCPE_OK;
case TYPE_C:
if (opr < 0 || opr > 16)
return SCPE_ARG;
*val = (opr << 8) | op->op;
return SCPE_OK;
case TYPE_D:
if (opr < 0 || opr > 1024)
return SCPE_ARG;
*val = (opr << 2) | op->op;
return SCPE_OK;
}
} else if (sw & SWMASK('B')) {
i = 0;
while (*cptr != '\0' && i < 8) {
d <<= 6;
d |= (int)sim_ascii_to_six[0177 & *cptr];
cptr++;
i++;
}
d <<= 6 * (8 - i);
} else {
while (*cptr >= '0' && *cptr <= '7') {
d <<= 3;
d |= *cptr++ - '0';
}
}
*val = d;
return SCPE_OK;
/* Symbolic input, continued */
if (*cptr != 0)
return SCPE_ARG; /* junk at end? */
return SCPE_OK;
}