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:
1120
ICL1900/Makefile
Executable file
1120
ICL1900/Makefile
Executable file
File diff suppressed because it is too large
Load Diff
2001
ICL1900/icl1900_cpu.c
Normal file
2001
ICL1900/icl1900_cpu.c
Normal file
File diff suppressed because it is too large
Load Diff
226
ICL1900/icl1900_defs.h
Executable file
226
ICL1900/icl1900_defs.h
Executable 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
610
ICL1900/icl1900_sys.c
Executable 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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user