320 lines
14 KiB
C
320 lines
14 KiB
C
/* i650_defs.h: IBM 650 simulator definitions
|
|
|
|
Copyright (c) 2018, Roberto Sancho
|
|
|
|
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
|
|
ROBERTO SANCHO 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" /* simulator defns */
|
|
|
|
/* Simulator stop codes */
|
|
|
|
#define STOP_HALT 1 /* HALT */
|
|
#define STOP_IBKPT 2 /* breakpoint */
|
|
#define STOP_UUO 3 /* invalid opcode */
|
|
#define STOP_CARD 4 /* Stop on card reader/punch error (no card in hopper, read/punch failure, no cards, stop pressed on cdr/cdp*/
|
|
#define STOP_PROG 5 /* Programmed stop */
|
|
#define STOP_OV 6 /* Overflow stop */
|
|
#define STOP_ERRO 7 /* Error in opcode execution: BRD in witch position tested not 8 or 9, TLU failure */
|
|
#define STOP_ADDR 8 /* Address stop: Store attempt on addr 800X, address out of drum mem */
|
|
|
|
|
|
/* Memory */
|
|
#define MAXDRUMSIZE (4000)
|
|
#define DRUMSIZE ((int)(cpu_unit.capac % 10) * 1000) /* actual drum memory size */
|
|
|
|
extern t_int64 DRUM[MAXDRUMSIZE];
|
|
extern int DRUM_NegativeZeroFlag[MAXDRUMSIZE];
|
|
extern char DRUM_Symbolic_Buffer[MAXDRUMSIZE * 80];
|
|
|
|
extern t_int64 IOSync[10];
|
|
extern int IOSync_NegativeZeroFlag[10];
|
|
|
|
#define STOR (cpu_unit.flags & OPTION_STOR)
|
|
#define CNTRL (cpu_unit.flags & OPTION_CNTRL)
|
|
#define FAST (cpu_unit.flags & OPTION_FAST)
|
|
|
|
extern t_int64 IAS[60];
|
|
extern int IAS_NegativeZeroFlag[60];
|
|
extern int IAS_TimingRing;
|
|
|
|
extern int WriteAddr(int AR, t_int64 d, int NegZero);
|
|
extern int ReadAddr(int AR, t_int64 * d, int * NegZero);
|
|
extern CONST char * DecodeOpcode(t_int64 d, int * opcode, int * DA, int * IA);
|
|
extern void vm_init(void);
|
|
|
|
|
|
/* digits contants */
|
|
#define D10 (10000000000LL) // ten digits (10 zeroes)
|
|
#define D8 (100000000L) // eight digits (8 zeroes)
|
|
#define D4 (10000L) // four digits (4 zeroes)
|
|
|
|
|
|
/* Device information block */
|
|
struct dib {
|
|
uint8 upc; /* Units per channel */
|
|
uint32 (*cmd)(UNIT *up, uint16 cmd, uint16 dev);/* Issue command. */
|
|
void (*ini)(UNIT *up, t_bool f);
|
|
};
|
|
|
|
typedef struct dib DIB;
|
|
|
|
/* Debuging controls */
|
|
#define DEBUG_CMD 0x0000010 /* Show device commands */
|
|
#define DEBUG_DETAIL 0x0000020 /* Show details */
|
|
#define DEBUG_EXP 0x0000040 /* Show error conditions */
|
|
#define DEBUG_DATA 0x0000080 /* Show data details */
|
|
|
|
extern DEBTAB dev_debug[];
|
|
extern DEBTAB crd_debug[];
|
|
|
|
/* Returns from read/write */
|
|
#define DATA_OK 0 /* Data transfered ok */
|
|
#define TIME_ERROR 1 /* Channel did not transfer last operation */
|
|
#define END_RECORD 2 /* End of record */
|
|
|
|
/* Returns from device commands */
|
|
#define SCPE_BUSY (1) /* Device is active */
|
|
#define SCPE_NOCARDS (2) /* No cards to read or ti write */
|
|
|
|
/* Global device definitions */
|
|
#ifdef CPANEL
|
|
extern DEVICE cp_dev;
|
|
#endif
|
|
|
|
// max number of cards in deck for carddeck internal command
|
|
#define MAX_CARDS_IN_DECK 10000
|
|
#define MAX_CARDS_IN_READ_TAKE_HOPPER 10
|
|
|
|
extern DIB cdr_dib;
|
|
extern DEVICE cdr_dev;
|
|
extern uint32 cdr_cmd(UNIT *, uint16, uint16);
|
|
extern UNIT cdr_unit[4];
|
|
extern char ReadHopper[3 * MAX_CARDS_IN_READ_TAKE_HOPPER * 80];
|
|
extern int ReadHopperLast[3];
|
|
|
|
extern DIB cdp_dib;
|
|
extern DEVICE cdp_dev;
|
|
extern uint32 cdp_cmd(UNIT *, uint16, uint16);
|
|
extern UNIT cdp_unit[4];
|
|
|
|
/* Device status information stored in u5 */
|
|
#define URCSTA_ERR 0002 /* Error reading record */
|
|
#define URCSTA_BUSY 0010 /* Device is busy */
|
|
#define URCSTA_LOAD 01000 /* Load flag for 533 card reader */
|
|
#define URCSTA_SOAPSYMB 02000 /* Get soap symbolic info when reading the card */
|
|
|
|
|
|
extern struct card_wirings {
|
|
uint32 mode;
|
|
const char *name;
|
|
} wirings[];
|
|
extern char digits_ascii[31];
|
|
extern char mem_to_ascii[101];
|
|
extern int ascii_to_NN(int ch);
|
|
extern uint16 ascii_to_hol[128];
|
|
|
|
|
|
/* Generic devices common to all */
|
|
extern DEVICE cpu_dev;
|
|
extern UNIT cpu_unit;
|
|
extern REG cpu_reg[];
|
|
extern int cycle_time;
|
|
|
|
/* I/O Command codes */
|
|
#define IO_RDS 1 /* Read record */
|
|
#define IO_WRS 4 /* Write one record */
|
|
|
|
extern const char *cpu_description(DEVICE *dptr);
|
|
|
|
/* Opcodes */
|
|
// Instructions on Basic machine
|
|
#define OP_AABL 17 // Add absolute to lower accumulator
|
|
#define OP_AL 15 // Add to lower accumulator
|
|
#define OP_AU 10 // Add to upper accumulator
|
|
#define OP_BRNZ 45 // Branch on accumulator non-zero
|
|
#define OP_BRMIN 46 // Branch on minus accumulator
|
|
#define OP_BRNZU 44 // Branch on non-zero in upper accumulator
|
|
#define OP_BROV 47 // Branch on overflow
|
|
#define OP_BRD1 91 // Branch on 8 in distributor positions 1-10
|
|
#define OP_BRD2 92
|
|
#define OP_BRD3 93
|
|
#define OP_BRD4 94
|
|
#define OP_BRD5 95
|
|
#define OP_BRD6 96
|
|
#define OP_BRD7 97
|
|
#define OP_BRD8 98
|
|
#define OP_BRD9 99
|
|
#define OP_BRD10 90
|
|
#define OP_DIV 14 // Divide
|
|
#define OP_DIVRU 64 // Divide and reset upper accumulator
|
|
#define OP_LD 69 // Load distributor
|
|
#define OP_MULT 19 // Multiply
|
|
#define OP_NOOP 00 // No operation
|
|
#define OP_PCH 71 // Punch a card
|
|
#define OP_RD 70 // Read a card
|
|
#define OP_RAABL 67 // Reset accumulator and add absolute to lower accumulator
|
|
#define OP_RAL 65 // Reset accumulator and add to lower accumulator
|
|
#define OP_RAU 60 // Reset accumulator and add to upper accumulator
|
|
#define OP_RSABL 68 // Reset accumulator and subtract absolute from lower accumulator
|
|
#define OP_RSL 66 // Reset accumulator and subtract from lower accumulator
|
|
#define OP_RSU 61 // Reset accumulator and subtract from upper accumulator
|
|
#define OP_SLT 35 // Shift accumulator left
|
|
#define OP_SCT 36 // Shift accumulator left and count
|
|
#define OP_SRT 30 // Shift accumulator right
|
|
#define OP_SRD 31 // Shift accumulator right and round accumulator
|
|
#define OP_STOP 01 // Stop if console switch is set to stop, otherwise continue as a NO-OP
|
|
#define OP_STD 24 // Store distributor into memory
|
|
#define OP_STDA 22 // Store lower accumulator data address into distributor, then store distributor into memory
|
|
#define OP_STIA 23 // Store lower accumulator instruction address into distributor, then store distributor into memory
|
|
#define OP_STL 20 // Store lower accumulator into memory
|
|
#define OP_STU 21 // Store upper accumulator into memory
|
|
#define OP_SABL 18 // Subtract absolute from lower accumulator
|
|
#define OP_SL 16 // Subtract from lower accumulator
|
|
#define OP_SU 11 // Subtract from upper accumulator
|
|
#define OP_TLU 84 // Table lookup
|
|
// Instructions on Storage Unit
|
|
// opcodes for indexing
|
|
#define OP_AXA 50 // Add to index register A
|
|
#define OP_SXA 51 // Substract from index A
|
|
#define OP_RAA 80 // Reset Add Index A
|
|
#define OP_RSA 81 // Reset Substract Index A
|
|
#define OP_NZA 40 // Branch Non Zero Index A
|
|
#define OP_BMA 41 // Branch Minus Index A
|
|
#define OP_AXB 52 // Add to index register B
|
|
#define OP_SXB 53 // Substract from index B
|
|
#define OP_RAB 82 // Reset Add Index B
|
|
#define OP_RSB 83 // Reset Substract Index B
|
|
#define OP_NZB 42 // Branch Non Zero Index B
|
|
#define OP_BMB 43 // Branch Minus Index B
|
|
#define OP_AXC 58 // Add to index register C
|
|
#define OP_SXC 59 // Substract from index C
|
|
#define OP_RAC 88 // Reset Add Index C
|
|
#define OP_RSC 89 // Reset Substract Index C
|
|
#define OP_NZC 48 // Branch Non Zero Index C
|
|
#define OP_BMC 49 // Branch Minus Index C
|
|
// io for synchronizers 2 & 3
|
|
#define OP_RC1 72 // Read Conditional sync 1
|
|
#define OP_RD2 73 // Read Sync 2
|
|
#define OP_WR2 74 // Write Sync 2
|
|
#define OP_RC2 75 // Read Conditional Sync 2
|
|
#define OP_RD3 76 // Read Sync 3
|
|
#define OP_WR3 77 // Write Sync 3
|
|
#define OP_RC3 78 // Read Conditional Sync 3
|
|
// immediate access storage (ias)
|
|
#define OP_LIB 8 // Load IAS block
|
|
#define OP_LDI 9 // Load IAS
|
|
#define OP_SIB 28 // Store IAS Block
|
|
#define OP_STI 29 // Store IAS
|
|
#define OP_SET 27 // Set IAS Timing Ring
|
|
// floating point
|
|
#define OP_FAD 32 // Floating Add
|
|
#define OP_FSB 33 // Floating Subtract
|
|
#define OP_FMP 39 // Floating Multiply
|
|
#define OP_FDV 34 // Floating Divide
|
|
#define OP_UFA 02 // Unnormalized Floating Add
|
|
#define OP_FAM 37 // Floating Add Absolute (Magnitude)
|
|
#define OP_FSM 38 // Floating Subtract Absolute (Magnitude)
|
|
// Instructions on Control Unit
|
|
// tape
|
|
#define OP_RTN 04 // Read Tape Numeric
|
|
#define OP_RTA 05 // Read Tape Alphameric
|
|
#define OP_WTN 06 // Write Tape Numeric
|
|
#define OP_WTA 07 // Write Tape Alphameric
|
|
#define OP_RTC 03 // Read Tape for Checking
|
|
#define OP_NTS 25 // Branch no Tape Signal
|
|
#define OP_NEF 54 // Branch no End of File
|
|
#define OP_RWD 55 // Rewind Tape
|
|
#define OP_WTM 56 // Write Tape Mark
|
|
#define OP_BST 57 // Backspace Tape
|
|
// ramac disk
|
|
#define OP_SDS 85 // Seek Disk Storage
|
|
#define OP_RDS 86 // Read Disk Storage
|
|
#define OP_WDS 87 // Write Disk Storage
|
|
// inquiry stations
|
|
#define OP_BIN 26 // Branch on Inquiry
|
|
#define OP_RPY 79 // Reply on Inquiry
|
|
|
|
// Valid Data Address (DA)
|
|
#define vda_D 1 // 0000-1999 Drum
|
|
#define vda_A 2 // 8000-8003 Arithmetic unit registers (ACC Low & Hi), Distributor, Console Switches register
|
|
#define vda_I 4 // 8005-8007 Index Registers (IR)
|
|
#define vda_T 8 // 8010-8015 Tape address
|
|
#define vda_S 16 // 9000-9059 Immediate Access Storage (IAS)
|
|
#define vda_9000 32 // 9000 Only addr 9000 valid
|
|
|
|
#define vda_DAITS (vda_D | vda_A | vda_I | vda_T | vda_S )
|
|
#define vda_DAIS (vda_D | vda_A | vda_I | vda_S )
|
|
#define vda_DAS (vda_D | vda_A | vda_S )
|
|
#define vda_DS (vda_D | vda_S )
|
|
|
|
#define opReadDA 1 // opcode fetchs data from DA address
|
|
#define opWriteDA 2 // opcode write data to DA
|
|
|
|
#define opStorUnit 1 // opcode available if IBM 653 Storage Unit is present
|
|
#define opCntrlUnit 2 // opcode available if IBM 652 Control Unit is present
|
|
|
|
#define IL_RD1 1 // interlock on drum area 01-10/51-60 used in reading with RD1
|
|
#define IL_WR1 2 // interlock on drum area 27-36/77-86 used in writing for WR1
|
|
#define IL_RD23 3 // interlock on drum area 39-48/89-98 used in reading with RD2/RD3
|
|
#define IL_WR23 4 // interlock on drum area 13-22/63-72 used in writing for WR2/WR3
|
|
#define IL_IAS 5 // interlock on ias access
|
|
#define IL_array 6 // interlock array definition value
|
|
|
|
/* Symbol tables */
|
|
typedef struct
|
|
{
|
|
uint16 opbase; // opcode number
|
|
const char *name1; // opcode name as in operation manual
|
|
const char *name2; // opcode name as in soap
|
|
uint8 opRW; // =wDA, rDA or zero
|
|
int option; // =0 -> opcode in basic machine, =1 -> Opcode because Storage Unit, =2 -> Opcode because Control Unit
|
|
int validDA; // valid data address for this instruction
|
|
int opInterLock; // Interlock required by opcode
|
|
}
|
|
t_opcode;
|
|
|
|
extern t_opcode base_ops[100];
|
|
|
|
|
|
#define NEGZERO_value 0x7fffFFFFffffFFFF
|
|
#define AccNegative (((AccNegativeZeroFlag) || (ACC[1]<0) || (ACC[0]<0)) ? 1:0)
|
|
#define AbsWord(d) ((d < 0) ? -d:d)
|
|
#define printfw(d,negzero) (int32) AbsWord(d/D4), (int32) AbsWord(d%D4), ((d<0) || (negzero)) ? '-':'+'
|
|
#define printfd printfw(DIST, DistNegativeZeroFlag)
|
|
#define printfa (int32) AbsWord(ACC[1]/D4),(int32) AbsWord(ACC[1]%D4), printfw(AbsWord(ACC[0]), AccNegative)
|
|
|
|
/* Standard control panel wiring for card read/punch/print */
|
|
|
|
#define UNIT_CARD_WIRING ( 0xF00 << UNIT_V_CARD_MODE)
|
|
#define WIRING_8WORD ( 0x000 << UNIT_V_CARD_MODE)
|
|
#define WIRING_SOAP ( 0x100 << UNIT_V_CARD_MODE)
|
|
#define WIRING_IS ( 0x200 << UNIT_V_CARD_MODE)
|
|
#define WIRING_IT ( 0x300 << UNIT_V_CARD_MODE)
|
|
#define WIRING_FORTRANSIT ( 0x400 << UNIT_V_CARD_MODE)
|
|
#define UNIT_CARD_ECHO ( 0x1000 << UNIT_V_CARD_MODE)
|
|
#define UNIT_CARD_PRINT ( 0x2000 << UNIT_V_CARD_MODE)
|
|
|
|
/* Decimal helper functions */
|
|
extern int Get_HiDigit(t_int64 d);
|
|
extern int Shift_Digits(t_int64 * d, int nDigits);
|
|
extern char * word_to_ascii(char * buf, int CharStart, int CharLen, t_int64 d);
|
|
|
|
|
|
|