1
0
mirror of https://github.com/rcornwell/sims.git synced 2026-02-26 16:53:58 +00:00

ICL1900: Initial Commit.

This commit is contained in:
Richard Cornwell
2018-02-04 22:48:35 -05:00
parent b1f234dbc8
commit 08b2a725c0
4 changed files with 3957 additions and 0 deletions

1120
ICL1900/Makefile Executable file

File diff suppressed because it is too large Load Diff

2001
ICL1900/icl1900_cpu.c Normal file

File diff suppressed because it is too large Load Diff

226
ICL1900/icl1900_defs.h Executable file
View File

@@ -0,0 +1,226 @@
/* icl1900_defs.h: ICL1900 simulator definitions
Copyright (c) 2017, 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.
*/
#ifndef _ICL1900_H_
#define _ICL1900_H_
#include "sim_defs.h" /* simulator defns */
/* Definitions for each supported CPU */
#define NUM_DEVS_CDR 0
#define NUM_DEVS_CDP 0
#define NUM_DEVS_LPR 0
#define NUM_DEVS_CON 0
#define NUM_DEVS_MT 0
#define NUM_DEVS_DSK 0
#define NUM_DEVS_DTC 0
#define MAXMEMSIZE (4096 * 1024)
extern uint32 M[]; /* Main Memory */
/* Memory */
#define MEMSIZE (cpu_unit[0].capac) /* actual memory size */
#define MEMMASK (MEMSIZE - 1) /* Memory bits */
/* Debuging controls */
#define DEBUG_CHAN 0x0000001 /* Show channel fetchs */
#define DEBUG_TRAP 0x0000002 /* Show CPU Traps */
#define DEBUG_CMD 0x0000004 /* Show device commands */
#define DEBUG_DATA 0x0000008 /* Show data transfers */
#define DEBUG_DETAIL 0x0000010 /* Show details */
#define DEBUG_EXP 0x0000020 /* Show error conditions */
#define DEBUG_SNS 0x0000040 /* Shows sense data for 7909 devs */
#define DEBUG_CTSS 0x0000080 /* Shows CTSS specail instructions */
#define DEBUG_PROT 0x0000100 /* Protection traps */
extern DEBTAB dev_debug[];
/* Returns from device commands */
#define SCPE_BUSY (1) /* Device is active */
#define SCPE_NODEV (2) /* No device exists */
/* Symbol tables */
typedef struct _opcode
{
const char *name;
uint8 type;
}
t_opcode;
#define OP_LDX 0000 /* Load to X */
#define OP_ADX 0001 /* Add to X */
#define OP_NGX 0002 /* Negative to X */
#define OP_SBX 0003 /* Subtract from X */
#define OP_LDXC 0004 /* Load into X with carry */
#define OP_ADXC 0005 /* Add to X with carry */
#define OP_NGXC 0006 /* Negative to X with carry */
#define OP_SBXC 0007 /* Subtract from X with carry */
#define OP_STO 0010 /* Store contents of X */
#define OP_ADS 0011 /* Add X to store */
#define OP_NGS 0012 /* Negative into Store */
#define OP_SBS 0013 /* Subtract from store */
#define OP_STOC 0014 /* Store contents of X with carry */
#define OP_ADSC 0015 /* Add X to store with carry */
#define OP_NGSC 0016 /* Negative into Store with carry */
#define OP_SBSC 0017 /* Subtract from store with carry */
#define OP_ANDX 0020 /* Logical AND into X */
#define OP_ORX 0021 /* Logical OR into X */
#define OP_ERX 0022 /* Logical XOR into X */
#define OP_OBEY 0023 /* Obey instruction at N */
#define OP_LDCH 0024 /* Load Character to X */
#define OP_LDEX 0025 /* Load Exponent */
#define OP_TXU 0026 /* Test X unequal */
#define OP_TXL 0027 /* Test X Less */
#define OP_ANDS 0030 /* Logical AND into store */
#define OP_ORS 0031 /* Logical OR into store */
#define OP_ERS 0032 /* Logical XOR into store */
#define OP_STOZ 0033 /* Store Zero */
#define OP_DCH 0034 /* Deposit Character to X */
#define OP_DEX 0035 /* Deposit Exponent */
#define OP_DSA 0036 /* Deposit Short Address */
#define OP_DLA 0037 /* Deposit Long Address */
#define OP_MPY 0040 /* Multiply */
#define OP_MPR 0041 /* Multiply and Round */
#define OP_MPA 0042 /* Multiply and Accumulate */
#define OP_CDB 0043 /* Convert Decimal to Binary */
#define OP_DVD 0044 /* Unrounded Double Length Divide */
#define OP_DVR 0045 /* Rounded Double Length Divide */
#define OP_DVS 0046 /* Single Length Divide */
#define OP_CBD 0047 /* Convert Binary to Decimal */
#define OP_BZE 0050 /* Branch if X is Zero */
#define OP_BZE1 0051
#define OP_BNZ 0052 /* Branch if X is not Zero */
#define OP_BNZ1 0053
#define OP_BPZ 0054 /* Branch if X is Positive or zero */
#define OP_BPZ1 0055
#define OP_BNG 0056 /* Branch if X is Positive or zero */
#define OP_BNG1 0057
#define OP_BUX 0060 /* Branch on Unit indexing */
#define OP_BUX1 0061
#define OP_BDX 0062 /* Branch on Double Indexing */
#define OP_BDX1 0063
#define OP_BCHX 0064 /* Branch on Character Indexing */
#define OP_BCHX1 0065
#define OP_BCT 0066 /* Branch on Count - BC */
#define OP_BCT1 0067
#define OP_CALL 0070 /* Call Subroutine */
#define OP_CALL1 0071
#define OP_EXIT 0072 /* Exit Subroutine */
#define OP_EXIT1 0073
#define OP_BRN 0074 /* Branch unconditional */
#define OP_BRN1 0075
#define OP_BFP 0076 /* Branch state of floating point accumulator */
#define OP_BFP1 0077
#define OP_LDN 0100 /* Load direct to X */
#define OP_ADN 0101 /* Add direct to X */
#define OP_NGN 0102 /* Negative direct to X */
#define OP_SBN 0103 /* Subtract direct from X */
#define OP_LDNC 0104 /* Load direct into X with carry */
#define OP_ADNC 0105 /* Add direct to X with carry */
#define OP_NGNC 0106 /* Negative direct to X with carry */
#define OP_SBNC 0107 /* Subtract direct from X with carry */
#define OP_SLL 0110 /* Shift Left */
#define OP_SLD 0111 /* Shift Left Double */
#define OP_SRL 0112 /* Shift Right */
#define OP_SRD 0113 /* Shift Right Double*/
#define OP_NORM 0114 /* Nomarlize Single -2 +FP */
#define OP_NORMD 0115 /* Normalize Double -2 +FP */
#define OP_MVCH 0116 /* Move Characters - BC */
#define OP_SMO 0117 /* Supplementary Modifier - BC */
#define OP_ANDN 0120 /* Logical AND direct into X */
#define OP_ORN 0121 /* Logical OR direct into X */
#define OP_ERN 0122 /* Logical XOR direct into X */
#define OP_NULL 0123 /* No Operation */
#define OP_LDCT 0124 /* Load Count */
#define OP_MODE 0125 /* Set Mode */
#define OP_MOVE 0126 /* Copy N words */
#define OP_SUM 0127 /* Sum N words */
#define OP_FLOAT 0130 /* Convert Fixed to Float +FP */
#define OP_FIX 0131 /* Convert Float to Fixed +FP */
#define OP_FAD 0132 /* Floating Point Add +FP */
#define OP_FSB 0133 /* Floating Point Subtract +FP */
#define OP_FMPY 0134 /* Floating Point Multiply +FP */
#define OP_FDVD 0135 /* Floating Point Divide +FP */
#define OP_LFP 0136 /* Load Floating Point +FP */
#define OP_SFP 0137 /* Store Floating Point +FP */
#define FMASK 077777777
#define CMASK 060000000
#define BM1 0100000000
#define B0 040000000
#define B1 020000000
#define B2 010000000
#define B3 004000000
#define B8 000100000
#define B15 000040000
#define B14 000020000
#define M9 000000777
#define M12 000007777
#define M15 000077777
#define M22 017777777
#define M23 037777777
#define CNTMSK 077700000
#define CHCMSK 017700000
#define NMASK 037777400
#define MMASK 037777000
#define CHAR_DEV 0 /* Device transfers via characters */
#define WORD_DEV 1 /* Device transfers via words */
struct icl_dib {
uint8 channel; /* Channel number */
uint8 type; /* Type of device */
t_stat (*dev_cmd)(uint32 cmd, uint32 *resp); /* Start io on device */
};
typedef struct icl_dib DIB;
/* Hessitation operations */
int chan_write_char(uint8 channel, uint8 data);
int chan_read_char(uint8 channel, uint8 *data);
int chan_write_word(uint8 channel, uint32 data);
int chan_read_word(uint8 channel, uint32 *data);
int chan_end(uint8 channel);
/* Console tty device routines */
extern t_stat ctyi_cmd(uint32 cmd, uint32 *resp);
extern t_stat ctyo_cmd(uint32 cmd, uint32 *resp);
/* Generic devices common to all */
extern DEVICE cpu_dev;
extern UNIT cpu_unit[];
extern REG cpu_reg[];
/* Global device definitions */
extern DEVICE cty_dev;
extern DEVICE cdr_dev;
extern DEVICE cdp_dev;
extern DEVICE lpr_dev;
extern DEVICE dtc_dev;
extern DEVICE dsk_dev;
extern DEVICE mt_dev;
#endif /* _ICL1900_H_ */

610
ICL1900/icl1900_sys.c Executable file
View File

@@ -0,0 +1,610 @@
/* icl1900_sys.c: ICL 1900 Simulator system interface.
Copyright (c) 2017, 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 "icl1900_defs.h"
#include "sim_card.h"
#include <ctype.h>
t_stat parse_sym(CONST 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[] = "ICL1900";
REG *sim_PC = &cpu_reg[0];
int32 sim_emax = 1;
DEVICE *sim_devices[] = {
&cpu_dev,
// &cty_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_MT > 0
&mt_dev,
#endif
#if NUM_DEVS_DSK > 0
&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 */
' ', '!', '"', '#', '{', '%', '&', '\'', /* 2x */
'(', ')', '*', '+', ',', '-', '.', '/', /* 3x */
'@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', /* 4x */
'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', /* 5x */
'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', /* 6x */
'X', 'Y', 'Z', '[', '$', ']', '^', '_' /* 7x */
};
const char ascii_to_mem[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, 021, 022, 023, 074, 025, 026, 027, /* 4 -1 77 */
/* ( ) * + , - . / */
030, 031, 032, 033, 034, 035, 036, 037,
/* 0 1 2 3 4 5 6 7 */
000, 001, 002, 003, 004, 005, 006, 007,
/* 8 9 : ; < = > ? */
010, 011, 012, 013, 014, 015, 016, 017,
/* @ A B C D E F G */
040, 041, 042, 043, 044, 045, 046, 047, /* 1 -1- 137 */
/* H I J K L M N O */
050, 051, 052, 053, 054, 055, 056, 057,
/* P Q R S T U V W */
060, 061, 062, 063, 064, 065, 066, 067,
/* X Y Z [ \ ] ^ _ */
070, 071, 072, 073, -1, 075, 076, 077,
/* ` a b c d e f g */
-1, 041, 042, 043, 044, 045, 046, 047, /* 14 -1 177 */
/* h i j k l m n o */
050, 051, 052, 053, 054, 055, 056, 057,
/* p q r s t u v w */
060, 061, 062, 063, 064, 065, 066, 067,
/* x y z { | } ~ del*/
070, 071, 072, 024, -1, -1, -1, -1,
};
/* Load a card image file into memory. */
t_stat
sim_load(FILE * fileref, CONST char *cptr, CONST char *fnam, int flag)
{
char buffer[160];
int i, j, k;
int addr, data;
uint8 image[80];
int checksum;
if (match_ext(fnam, "txt")) {
while (fgets(buffer, 100, fileref)) {
/* Convert bits into image */
memset(image, 0, sizeof(image));
for (j = 0; j < 80; j++) {
if (buffer[j] == '\n')
break;
image[j] = ascii_to_mem[buffer[j]];
if (image[j] < 0) {
fprintf(stderr, "Char %c: %s", buffer[j], buffer);
return SCPE_FMT;
}
}
if (image[0] != 073) {
fprintf(stderr, "F: %s", buffer);
return SCPE_FMT;
}
switch(image[3]) {
case 0:
checksum = 0;
for (j = 0; j < 4; j++)
checksum = (checksum << 6) | image[j];
addr = 0;
for (; j < 8; j++)
addr = (addr << 6) | image[j];
checksum += addr;
for (i = 3; i < image[1]; i++) {
data = 0;
for (k = 0; k < 4; k++)
data = (data << 6) | image[j++];
checksum += data;
M[addr++] = data;
}
data = 0;
for (k = 0; k < 4; k++)
data = (data << 6) | image[j++];
data = FMASK & (checksum + data);
if (data != 0)
fprintf(stderr, "Check %08o %08o: %s", addr, data, buffer);
break;
case 1:
fprintf(stderr, "%c%c%c%c\n", buffer[4], buffer[5], buffer[6], buffer[7]);
break;
case 2:
case 3:
case 4:
case 5:
case 6:
break;
default:
fprintf(stderr, "B? :%s", buffer);
return SCPE_FMT;
}
// if (load_rec(image))
// return SCPE_OK;
}
return SCPE_OK;
}
return SCPE_NOFNC;
}
#define TYPE_A 0
#define TYPE_B 1
#define TYPE_C 2
#define TYPE_D 3
/* Opcodes */
t_opcode ops[] = {
"LDX", TYPE_A, /* Load to X */
"ADX", TYPE_A, /* Add to X */
"NGX", TYPE_A, /* Negative to X */
"SBX", TYPE_A, /* Subtract from X */
"LDXC", TYPE_A, /* Load into X with carry */
"ADXC", TYPE_A, /* Add to X with carry */
"NGXC", TYPE_A, /* Negative to X with carry */
"SBXC", TYPE_A, /* Subtract from X with carry */
"STO", TYPE_A, /* Store contents of X */
"ADS", TYPE_A, /* Add X to store */
"NGS", TYPE_A, /* Negative into Store */
"SBS", TYPE_A, /* Subtract from store */
"STOC", TYPE_A, /* Store contents of X with carry */
"ADSC", TYPE_A, /* Add X to store with carry */
"NGSC", TYPE_A, /* Negative into Store with carry */
"SBSC", TYPE_A, /* Subtract from store with carry */
"ANDX", TYPE_A, /* Logical AND into X */
"ORX", TYPE_A, /* Logical OR into X */
"ERX", TYPE_A, /* Logical XOR into X */
"OBEY", TYPE_A, /* Obey instruction at N */
"LDCH", TYPE_A, /* Load Character to X */
"LDEX", TYPE_A, /* Load Exponent */
"TXU", TYPE_A, /* Test X unequal */
"TXL", TYPE_A, /* Test X Less */
"ANDS", TYPE_A, /* Logical AND into store */
"ORS", TYPE_A, /* Logical OR into store */
"ERS", TYPE_A, /* Logical XOR into store */
"STOZ", TYPE_A, /* Store Zero */
"DCH", TYPE_A, /* Deposit Character to X */
"DEX", TYPE_A, /* Deposit Exponent */
"DSA", TYPE_A, /* Deposit Short Address */
"DLA", TYPE_A, /* Deposit Long Address */
"MPY", TYPE_A, /* Multiply */
"MPR", TYPE_A, /* Multiply and Round */
"MPA", TYPE_A, /* Multiply and Accumulate */
"CDB", TYPE_A, /* Convert Decimal to Binary */
"DVD", TYPE_A, /* Unrounded Double Length Divide */
"DVR", TYPE_A, /* Rounded Double Length Divide */
"DVS", TYPE_A, /* Single Length Divide */
"CBD", TYPE_A, /* Convert Binary to Decimal */
"BZE", TYPE_B, /* Branch if X is Zero */
"BZE", TYPE_B,
"BNZ", TYPE_B, /* Branch if X is not Zero */
"BNZ", TYPE_B,
"BPZ", TYPE_B, /* Branch if X is Positive or zero */
"BPZ", TYPE_B,
"BNG", TYPE_B, /* Branch if X is Positive or zero */
"BNG", TYPE_B,
"BUX", TYPE_B, /* Branch on Unit indexing */
"BUX", TYPE_B,
"BDX", TYPE_B, /* Branch on Double Indexing */
"BDX", TYPE_B,
"BCHX", TYPE_B, /* Branch on Character Indexing */
"BCHX", TYPE_B,
"BCT", TYPE_B, /* Branch on Count - BC */
"BCT", TYPE_B,
"CALL", TYPE_B, /* Call Subroutine */
"CALL", TYPE_B,
"EXIT", TYPE_B, /* Exit Subroutine */
"EXIT", TYPE_B,
NULL, TYPE_D, /* Branch unconditional */
NULL, TYPE_D,
"BFP", TYPE_B, /* Branch state of floating point accumulator */
"BFP", TYPE_B,
"LDN", TYPE_A, /* Load direct to X */
"ADN", TYPE_A, /* Add direct to X */
"NGN", TYPE_A, /* Negative direct to X */
"SBN", TYPE_A, /* Subtract direct from X */
"LDNC", TYPE_A, /* Load direct into X with carry */
"ADNC", TYPE_A, /* Add direct to X with carry */
"NGNC", TYPE_A, /* Negative direct to X with carry */
"SBNC", TYPE_A, /* Subtract direct from X with carry */
"SL", TYPE_C, /* Shift Left */
"SLD", TYPE_C, /* Shift Left Double */
"SR", TYPE_C, /* Shift Right */
"SRD", TYPE_C, /* Shift Right Double */
"NORM", TYPE_A, /* Nomarlize Single -2 +FP */
"NORMD", TYPE_A, /* Normalize Double -2 +FP */
"MVCH", TYPE_A, /* Move Characters - BC */
"SMO", TYPE_A, /* Supplementary Modifier - BC */
"ANDN", TYPE_A, /* Logical AND direct into X */
"ORN", TYPE_A, /* Logical OR direct into X */
"ERN", TYPE_A, /* Logical XOR direct into X */
"NULL", TYPE_A, /* No Operation */
"LDCT", TYPE_A, /* Load Count */
"MODE", TYPE_A, /* Set Mode */
"MOVE", TYPE_A, /* Copy N words */
"SUM", TYPE_A, /* Sum N words */
"FLOAT", TYPE_A, /* Convert Fixed to Float +FP */
"FIX", TYPE_A, /* Convert Float to Fixed +FP */
"FAD", TYPE_A, /* Floating Point Add +FP */
"FSB", TYPE_A, /* Floating Point Subtract +FP */
"FMPY", TYPE_A, /* Floating Point Multiply +FP */
"FDVD", TYPE_A, /* Floating Point Divide +FP */
"LFP", TYPE_A, /* Load Floating Point +FP */
"SFP", TYPE_A, /* Store Floating Point +FP */
"140", TYPE_A,
"141", TYPE_A,
"142", TYPE_A,
"143", TYPE_A,
"144", TYPE_A,
"145", TYPE_A,
"146", TYPE_A,
"147", TYPE_A,
"150", TYPE_A,
"151", TYPE_A,
"152", TYPE_A,
"153", TYPE_A,
"154", TYPE_A,
"155", TYPE_A,
"156", TYPE_A,
"157", TYPE_A,
"160", TYPE_A,
"161", TYPE_A,
"162", TYPE_A,
"163", TYPE_A,
"164", TYPE_A,
"165", TYPE_A,
"166", TYPE_A,
"167", TYPE_A,
"170", TYPE_A,
"171", TYPE_A,
"172", TYPE_A,
"173", TYPE_A,
"174", TYPE_A,
"175", TYPE_A,
"176", TYPE_A,
"177", TYPE_A,
};
char *type_d[] = { "BRN", "BVS", "BVSR", "BVC", "BVCR", "BCS", "BCC", "BVCI" };
char type_c[] = { 'C', 'L', 'A', 'V' };
/* Print out an instruction */
void
print_opcode(FILE * of, t_value val)
{
int op;
int x;
int m;
int n;
t_opcode *tab;
op = 0177 & (val >> 14);;
x = 07 & (val >> 21);
m = 03 & (val >> 12);
n = 07777 & val;
tab = &ops[op];
fprintf(of, " *%03o ", op);
switch(tab->type) {
case TYPE_A:
fprintf(of, "%s %o", tab->name, x);
if (m != 0) {
fputc(' ',of);
fputc('0'+m,of);
}
fprintf(of, "/%04o", n);
break;
case TYPE_B:
fprintf(of, "%s %o/%05o", tab->name, x, val & 077777);
break;
case TYPE_C:
fprintf(of, "%s %o", tab->name, x);
if (m != 0) {
fputc(' ',of);
fputc('0'+m,of);
}
fprintf(of, "/%c+%02o", type_c[(n >> 10) & 3], n & 01777);
break;
case TYPE_D:
fprintf(of, "%s %05o", type_d[x], val & 077777);
break;
}
}
/* 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, 24, PV_RZRO);
if (sw & SWMASK('M')) { /* Symbolic Assembly */
print_opcode(of, inst);
}
if (sw & SWMASK('C')) { /* Char mode opcodes */
fputc('\'', of);
for (i = 18; i >= 0; i-=6) {
int ch;
ch = (int)(inst >> i) & 077;
fputc(mem_to_ascii[ch], of);
}
fputc('\'', of);
}
return SCPE_OK;
}
int
find_opcode(char *op, int *val)
{
int i;
int v;
t_opcode *tab;
*val = -1;
if (*op >= '0' && *op <= '7') {
for (v = i = 0; op[i] != '\0'; i++) {
if (op[i] >= '0' && op[i] <= '7')
v = (v << 3) + (op[i] - '0');
else
break;
if (v > 0177)
return -1;
}
}
if (op[i] == 0 && v <= 0177)
return v;
for(i = 0; i <= 0177; i++) {
if (ops[i].name != '\0' && sim_strcasecmp(op, ops[i].name) == 0)
return i;
}
for(i = 0; i < 8; i++) {
if (sim_strcasecmp(op, type_d[i]) == 0) {
*val = i;
return 074;
}
}
return -1;
}
/* 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(CONST char *cptr, t_addr addr, UNIT * uptr, t_value * val, int32 sw)
{
int i;
int n;
int x;
int m;
int op;
char gbuf[100];
t_stat r;
if (sw & SWMASK ('C')) {
cptr = get_glyph_quoted(cptr, gbuf, 0); /* Get string */
x = 18;
n = 0;
m = 0;
for(i = 0; gbuf[i] != 0; i++) {
char c = ascii_to_mem[gbuf[i]];
if (c == -1)
return SCPE_ARG;
n |= c << x;
x -= 6;
if (x < 0) {
val[m++] = n;
n = 0;
x = 18;
}
}
if (x != 18)
val[m++] = n;
return -(m - 1);
}
if (sw & SWMASK ('M')) {
cptr = get_glyph(cptr, gbuf, 0); /* Get opcode */
op = find_opcode(gbuf, &i);
if (op < 0)
return SCPE_ARG;
while (sim_isspace (*cptr)) cptr++;
n = 0;
m = -1;
x = -1;
if (*cptr >= '0' || *cptr <= '7') {
x = *cptr++ - '0';
}
while (sim_isspace (*cptr)) cptr++;
if (*cptr > '0' || *cptr <= '3') {
m = *cptr++ - '0';
}
while (sim_isspace (*cptr)) cptr++;
*val = (0177 & op) << 14;
if (x >= 0)
*val |= (07 & x) << 21;
switch (ops[op].type) {
case TYPE_A: /* OP x m/n or OP x /n */
if (m > 0)
*val |= (m & 03) << 12;
if (*cptr == '/') {
cptr++;
n = get_uint(cptr, 8, 07777, &r);
if (r != SCPE_OK)
return r;
}
break;
case TYPE_B: /* OP x /n */
if (m >= 0)
return SCPE_ARG;
*val |= (m & 03) << 12;
if (*cptr == '/') {
cptr++;
n = get_uint(cptr, 8, 077777, &r);
if (r != SCPE_OK)
return r;
}
break;
case TYPE_C: /* OP x m/c+n or OP X /c+n */
if (m > 0)
*val |= (m & 03) << 12;
if (*cptr == '/') {
cptr++;
for (i = 0; i< 4; i++) {
if (type_c[i] == *cptr) {
cptr++;
break;
}
}
if (*cptr != '+')
return SCPE_ARG;
cptr++;
n = get_uint(cptr, 8, 01777, &r);
if (r != SCPE_OK)
return r;
n |= i << 10;
}
break;
case TYPE_D: /* type_d /n */
if (i < 0 && x >= 0) {
i = x;
x = -1;
}
if (m >= 0 || x >= 0)
return SCPE_ARG;
if (*cptr == '/') {
cptr++;
n = get_uint(cptr, 8, 077777, &r);
if (r != SCPE_OK)
return r;
}
*val |= i << 21;
break;
}
*val |= n;
return 0;
}
n = get_uint(cptr, 8, 077777777, &r);
if (r != SCPE_OK)
return r;
*val = n;
return 0;
}