blob: dc336331bb601c71d0a2f9d4fe1e0b85ffc720e2 [file] [log] [blame] [raw]
/* 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 MAXMEMSIZE (4000)
#define MEMSIZE cpu_unit.capac /* actual memory size */
#define MEMMASK (MEMSIZE - 1) /* Memory bits */
#define MEM_ADDR_OK(x) (((uint32) (x)) < MEMSIZE)
extern t_int64 DRUM[MAXMEMSIZE];
extern int DRUM_NegativeZeroFlag[MAXMEMSIZE];
extern int WriteDrum(int AR, t_int64 d, int NegZero);
extern int ReadDrum(int AR, t_int64 * d, int * NegZero);
/* 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
extern DIB cdr_dib;
extern DEVICE cdr_dev;
extern uint32 cdr_cmd(UNIT *, uint16, uint16);
extern UNIT cdr_unit[];
extern DIB cdp_dib;
extern DEVICE cdp_dev;
extern uint32 cdp_cmd(UNIT *, uint16, uint16);
extern UNIT cdp_unit[];
/* 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 */
/* Character codes in IBM 650 as stated in p4 Andree Programming the IBM 650 Mag Drum
Also stated in www.bitsavers.org/pdf/ibm/650/28-4028_FOR_TRANSIT.pdf p37
*/
#define CHR_BLANK 00
#define CHR_DOT 18 // card code: 12-3-8 .
#define CHR_RPARENT 19 // 12-4-8 )
#define CHR_AMPERSAND 20 // 12 +
#define CHR_DOLLAR 28 // 11-3-8 $
#define CHR_STAR 29 // 11-4-8 *
#define CHR_NEG 30 // 11 - minus sign for negative value
#define CHR_SLASH 31 // 0-1 /
#define CHR_COMMA 38 // 0-3-8 ,
#define CHR_LPARENT 39 // 0-4-8 (
#define CHR_EQUAL 48 // 3-8 =
#define CHR_MINUS 49 // 4-8 -
#define CHR_A 61
#define CHR_B 62
#define CHR_C 63
#define CHR_D 64
#define CHR_E 65
#define CHR_F 66
#define CHR_G 67
#define CHR_H 68
#define CHR_I 69
#define CHR_J 71
#define CHR_K 72
#define CHR_L 73
#define CHR_M 74
#define CHR_N 75
#define CHR_O 76
#define CHR_P 77
#define CHR_Q 78
#define CHR_R 79
#define CHR_S 82
#define CHR_T 83
#define CHR_U 84
#define CHR_V 85
#define CHR_W 86
#define CHR_X 87
#define CHR_Y 88
#define CHR_Z 89
#define CHR_0 90
#define CHR_1 91
#define CHR_2 92
#define CHR_3 93
#define CHR_4 94
#define CHR_5 95
#define CHR_6 96
#define CHR_7 97
#define CHR_8 98
#define CHR_9 99
extern char digits_ascii[40];
extern char mem_to_ascii[100];
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 */
#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
#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 UNIT_CARD_ECHO ( 0x1000 << UNIT_V_CARD_MODE)
#define UNIT_CARD_PRINT ( 0x2000 << UNIT_V_CARD_MODE)
struct card_wirings {
uint32 mode;
const char *name;
};
/* 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);