home *** CD-ROM | disk | FTP | other *** search
/ minnie.tuhs.org / unixen.tar / unixen / PDP-11 / Boot_Images / 2.11_on_rl02 / pdpsim.tz / pdpsim / pdp8_cpu.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-01-29  |  29.5 KB  |  1,072 lines

  1. /* pdp8_cpu.c: PDP-8 CPU simulator
  2.  
  3.    Copyright (c) 1993, 1994, 1995, 1996, Robert M Supnik,
  4.    Digital Equipment Corporation
  5.    Commercial use prohibited
  6.  
  7.    The register state for the PDP-8 is:
  8.  
  9.    AC<0:11>        accumulator
  10.    MQ<0:11>        multiplier-quotient
  11.    L            link flag
  12.    PC<0:11>        program counter
  13.    IF<0:2>        instruction field
  14.    IB<0:2>        instruction buffer
  15.    DF<0:2>        data field
  16.    UF            user flag
  17.    UB            user buffer
  18.    SF<0:6>        interrupt save field
  19.  
  20.    The PDP-8 has three instruction formats: memory reference, I/O transfer,
  21.    and operate.  The memory reference format is:
  22.  
  23.      0  1  2  3  4  5  6  7  8  9 10 11
  24.    +--+--+--+--+--+--+--+--+--+--+--+--+
  25.    |   op   |in|zr|    page offset     |    memory reference
  26.    +--+--+--+--+--+--+--+--+--+--+--+--+
  27.  
  28.    <0:2>    mnemonic    action
  29.  
  30.     000        AND        AC = AC & M[MA]
  31.     001        TAD        L'AC = AC + M[MA]
  32.     010        DCA        M[MA] = AC, AC = 0
  33.     011        ISZ        M[MA] = M[MA] + 1, skip if M[MA] == 0
  34.     100        JMS        M[MA] = PC, PC = MA + 1
  35.     101        JMP        PC = MA
  36.  
  37.    <3:4>    mode        action
  38.     00     page zero        MA = IF'0'IR<5:11>
  39.     01    current page        MA = IF'PC<0:4>'IR<5:11>
  40.     10    indirect page zero    MA = xF'M[IF'0'IR<5:11>]
  41.     11    indirect current page    MA = xF'M[IF'PC<0:4>'IR<5:11>]
  42.  
  43.    where x is D for AND, TAD, ISZ, DCA, and I for JMS, JMP.
  44.  
  45.    Memory reference instructions can access an address space of 32K words.
  46.    The address space is divided into eight 4K word fields; each field is
  47.    divided into thirty-two 128 word pages.  An instruction can directly
  48.    address, via its 7b offset, locations 0-127 on page zero or on the current
  49.    page.  All 32k words can be accessed via indirect addressing and the
  50.    instruction and data field registers.  If an indirect address is in
  51.    locations 0010-0017 of any field, the indirect address is incremented
  52.    and rewritten to memory before use.
  53. */
  54.  
  55. /* The I/O transfer format is as follows:
  56.  
  57.      0  1  2  3  4  5  6  7  8  9 10 11
  58.    +--+--+--+--+--+--+--+--+--+--+--+--+
  59.    |   op   |      device     | pulse  |    I/O transfer
  60.    +--+--+--+--+--+--+--+--+--+--+--+--+
  61.  
  62.    The IO transfer instruction sends the the specified pulse to the
  63.    specified I/O device.  The I/O device may take data from the AC,
  64.    return data to the AC, initiate or cancel operations, or skip on
  65.    status.
  66.  
  67.    The operate format is as follows:
  68.  
  69.    +--+--+--+--+--+--+--+--+--+--+--+--+
  70.    | 1| 1| 1| 0|  |  |  |  |  |  |  |  |    operate group 1
  71.    +--+--+--+--+--+--+--+--+--+--+--+--+
  72.             |  |  |  |  |  |  |  |
  73.             |  |  |  |  |  |  |  +--- increment AC    3
  74.             |  |  |  |  |  |  +--- rotate 1 or 2    4
  75.             |  |  |  |  |  +--- rotate left        4
  76.             |  |  |  |  +--- rotate right        4
  77.             |  |  |  +--- complement L        2
  78.             |  |  +--- complement AC        2
  79.             |  +--- clear L                1
  80.             +-- clear AC                1
  81.  
  82.    +--+--+--+--+--+--+--+--+--+--+--+--+
  83.    | 1| 1| 1| 1|  |  |  |  |  |  |  | 0|    operate group 2
  84.    +--+--+--+--+--+--+--+--+--+--+--+--+
  85.             |  |  |  |  |  |  |
  86.             |  |  |  |  |  |  +--- halt        3
  87.             |  |  |  |  |  +--- or switch register    3
  88.             |  |  |  |  +--- reverse skip sense    1
  89.             |  |  |  +--- skip on L != 0        1
  90.             |  |  +--- skip on AC == 0        1
  91.             |  +--- skip on AC < 0            1
  92.             +-- clear AC                2
  93.  
  94.    +--+--+--+--+--+--+--+--+--+--+--+--+
  95.    | 1| 1| 1| 1|  |  |  |  |  |  |  | 1|    operate group 3
  96.    +--+--+--+--+--+--+--+--+--+--+--+--+
  97.         |  |  |  | \______/
  98.         |  |  |  |     |
  99.         |  |  +--|-----+--- EAE command        3
  100.         |  |     +--- AC -> MQ, 0 -> AC        2
  101.         |  +--- MQ v AC --> AC            2
  102.         +-- clear AC                1
  103.  
  104.   The operate instruction can be microprogrammed to perform operations
  105.   on the AC, MQ, and link.
  106. */
  107.  
  108. /* This routine is the instruction decode routine for the PDP-8.
  109.    It is called from the simulator control program to execute
  110.    instructions in simulated memory, starting at the simulated PC.
  111.    It runs until 'reason' is set non-zero.
  112.  
  113.    General notes:
  114.  
  115.    1. Reasons to stop.  The simulator can be stopped by:
  116.  
  117.     HALT instruction
  118.     breakpoint encountered
  119.     unimplemented instruction and stop_inst flag set
  120.     I/O error in I/O simulator
  121.  
  122.    2. Interrupts.  Interrupts are maintained by three parallel variables:
  123.  
  124.     dev_done     device done flags
  125.     dev_enable    device interrupt enable flags
  126.     int_req        interrupt requests
  127.  
  128.       In addition, int_req contains the interrupt enable flag, the
  129.       CIF not pending flag, and the ION not pending flag.  If all
  130.       three of these flags are set, and at least one interrupt request
  131.       is set, then an interrupt occurs.
  132.  
  133.    3. Non-existent memory.  On the PDP-8, reads to non-existent memory
  134.       return zero, and writes are ignored.  In the simulator, the
  135.       largest possible memory is instantiated and initialized to zero.
  136.       Thus, only writes outside the current field (indirect writes) need
  137.       be checked against actual memory size.
  138.  
  139.    3. Adding I/O devices.  Three modules must be modified:
  140.  
  141.     pdp8_defs.h    add interrupt request definition
  142.     pdp8_cpu.c    add IOT dispatch
  143.     pdp8_sys.c    add pointer to data structures to sim_devices
  144. */
  145.  
  146. #include "pdp8_defs.h"
  147.  
  148. #define ILL_ADR_FLAG    0100000                /* invalid addr flag */
  149. #define save_ibkpt    (cpu_unit.u3)            /* saved bkpt addr */
  150. #define UNIT_V_NOEAE    (UNIT_V_UF)            /* EAE absent */
  151. #define UNIT_NOEAE    (1 << UNIT_V_NOEAE)
  152. #define UNIT_V_MSIZE    (UNIT_V_UF+1)            /* dummy mask */
  153. #define UNIT_MSIZE    (1 << UNIT_V_MSIZE)
  154.  
  155. unsigned short M[MAXMEMSIZE] = { 0 };            /* main memory */
  156. int saved_LAC = 0;                    /* saved L'AC */
  157. int saved_MQ = 0;                    /* saved MQ */
  158. int saved_PC = 0;                    /* saved IF'PC */
  159. int saved_DF = 0;                    /* saved Data Field */
  160. int IB = 0;                        /* Instruction Buffer */
  161. int SF = 0;                        /* Save Field */
  162. int emode = 0;                        /* EAE mode */
  163. int gtf = 0;                        /* EAE gtf flag */
  164. int SC = 0;                        /* EAE shift count */
  165. int UB = 0;                        /* User mode Buffer */
  166. int UF = 0;                        /* User mode Flag */
  167. int OSR = 0;                        /* Switch Register */
  168. int old_PC = 0;                        /* old PC */
  169. int dev_enable = INT_INIT_ENABLE;            /* dev intr enables */
  170. int dev_done = 0;                    /* dev done flags */
  171. int int_req = 0;                    /* intr requests */
  172. int ibkpt_addr = ILL_ADR_FLAG | ADDRMASK;        /* breakpoint addr */
  173. int stop_inst = 0;                    /* trap on ill inst */
  174. extern int sim_int_char;
  175.  
  176. int cpu_ex (int *vptr, int addr, UNIT *uptr, int sw);
  177. int cpu_dep (int val, int addr, UNIT *uptr, int sw);
  178. int cpu_reset (DEVICE *dptr);
  179. int cpu_svc (UNIT *uptr);
  180. int cpu_set_size (UNIT *uptr, int value);
  181.  
  182. /* CPU data structures
  183.  
  184.    cpu_dev    CPU device descriptor
  185.    cpu_unit    CPU unit descriptor
  186.    cpu_reg    CPU register list
  187.    cpu_mod    CPU modifier list
  188. */
  189.  
  190. UNIT cpu_unit = { UDATA (&cpu_svc, UNIT_FIX, MAXMEMSIZE) };
  191.  
  192. REG cpu_reg[] = {
  193.     { ORDATA (PC, saved_PC, 15) },
  194.     { ORDATA (AC, saved_LAC, 12) },
  195.     { FLDATA (L, saved_LAC, 12) },
  196.     { ORDATA (MQ, saved_MQ, 12) },
  197.     { ORDATA (SR, OSR, 12) },
  198.     { GRDATA (IF, saved_PC, 8, 3, 12) },
  199.     { GRDATA (DF, saved_DF, 8, 3, 12) },
  200.     { GRDATA (IB, IB, 8, 3, 12) },
  201.     { ORDATA (SF, SF, 7) },
  202.     { FLDATA (UB, UB, 0) },
  203.     { FLDATA (UF, UF, 0) },
  204.     { ORDATA (SC, SC, 5) },
  205.     { FLDATA (GTF, gtf, 0) },
  206.     { FLDATA (EMODE, emode, 0) },
  207.     { FLDATA (ION, int_req, INT_V_ION) },
  208.     { FLDATA (ION_DELAY, int_req, INT_V_NO_ION_PENDING) },
  209.     { FLDATA (CIF_DELAY, int_req, INT_V_NO_CIF_PENDING) },
  210.     { FLDATA (PWR_INT, int_req, INT_V_PWR) },
  211.     { FLDATA (UF_INT, int_req, INT_V_UF) },
  212.     { ORDATA (INT, int_req, INT_V_ION+1), REG_RO },
  213.     { ORDATA (DONE, dev_done, INT_V_DIRECT), REG_RO },
  214.     { ORDATA (ENABLE, dev_enable, INT_V_DIRECT), REG_RO },
  215.     { FLDATA (NOEAE, cpu_unit.flags, UNIT_V_NOEAE), REG_HRO },
  216.     { ORDATA (OLDPC, old_PC, 15), REG_RO },
  217.     { FLDATA (STOP_INST, stop_inst, 0) },
  218.     { ORDATA (BREAK, ibkpt_addr, 16) },
  219.     { ORDATA (WRU, sim_int_char, 8) },
  220.     { NULL }  };
  221.  
  222. MTAB cpu_mod[] = {
  223.     { UNIT_NOEAE, UNIT_NOEAE, "no EAE", "NOEAE", NULL },
  224.     { UNIT_NOEAE, 0, "EAE", "EAE", NULL },
  225.     { UNIT_MSIZE, 4096, NULL, "4K", &cpu_set_size },
  226.     { UNIT_MSIZE, 8192, NULL, "8K", &cpu_set_size },
  227.     { UNIT_MSIZE, 12288, NULL, "12K", &cpu_set_size },
  228.     { UNIT_MSIZE, 16384, NULL, "16K", &cpu_set_size },
  229.     { UNIT_MSIZE, 20480, NULL, "20K", &cpu_set_size },
  230.     { UNIT_MSIZE, 24576, NULL, "24K", &cpu_set_size },
  231.     { UNIT_MSIZE, 28672, NULL, "28K", &cpu_set_size },
  232.     { UNIT_MSIZE, 32768, NULL, "32K", &cpu_set_size },
  233.     { 0 }  };
  234.  
  235. DEVICE cpu_dev = {
  236.     "CPU", &cpu_unit, cpu_reg, cpu_mod,
  237.     1, 8, 15, 1, 8, 12,
  238.     &cpu_ex, &cpu_dep, &cpu_reset,
  239.     NULL, NULL, NULL };
  240.  
  241. int sim_instr (void)
  242. {
  243. extern int sim_interval;
  244. register int PC, IR, MA, MB, IF, DF, LAC, MQ;
  245. int device, pulse, temp, iot_data, reason;
  246. extern int tti (int pulse, int AC);
  247. extern int tto (int pulse, int AC);
  248. extern int ptr (int pulse, int AC);
  249. extern int ptp (int pulse, int AC);
  250. extern int clk (int pulse, int AC);
  251. extern int lpt (int pulse, int AC);
  252. extern int rk (int pulse, int AC);
  253. extern int rx (int pulse, int AC);
  254. extern int rf60 (int pulse, int AC);
  255. extern int rf61 (int pulse, int AC);
  256. extern int rf62 (int pulse, int AC);
  257. extern int rf64 (int pulse, int AC);
  258. extern int mt70 (int pulse, int AC);
  259. extern int mt71 (int pulse, int AC);
  260. extern int mt72 (int pulse, int AC);
  261. extern int sim_process_event (void);
  262. extern int sim_activate (UNIT *uptr, int interval);
  263.  
  264. /* Restore register state */
  265.  
  266. PC = saved_PC & 007777;                    /* load local copies */
  267. IF = saved_PC & 070000;
  268. DF = saved_DF & 070000;
  269. LAC = saved_LAC & 017777;
  270. MQ = saved_MQ & 07777;
  271. int_req = INT_UPDATE;
  272. reason = 0;
  273.  
  274. /* Main instruction fetch/decode loop */
  275.  
  276. while (reason == 0) {                    /* loop until halted */
  277. if (sim_interval <= 0) {                /* check clock queue */
  278.     if (reason = sim_process_event ()) break;  }
  279.  
  280. if (int_req > INT_PENDING) {                /* interrupt? */
  281.     int_req = int_req & ~INT_ION;            /* interrupts off */
  282.     SF = (UF << 6) | (IF >> 9) | (DF >> 12);    /* form save field */
  283.     IF = IB = DF = UF = UB = 0;            /* clear mem ext */
  284.     old_PC = M[0] = PC;                /* save PC in 0 */
  285.     PC = 1;  }                    /* fetch next from 1 */
  286.  
  287. MA = IF | PC;                        /* form PC */
  288. if (MA == ibkpt_addr) {                    /* breakpoint? */
  289.     save_ibkpt = ibkpt_addr;            /* save ibkpt */
  290.     ibkpt_addr = ibkpt_addr | ILL_ADR_FLAG;        /* disable */
  291.     sim_activate (&cpu_unit, 1);            /* sched re-enable */
  292.     reason = STOP_IBKPT;                /* stop simulation */
  293.     break;  }
  294.  
  295. IR = M[MA];                        /* fetch instruction */
  296. PC = (PC + 1) & 07777;                    /* increment PC */
  297. int_req = int_req | INT_NO_ION_PENDING;            /* clear ION delay */
  298. sim_interval = sim_interval - 1;
  299.  
  300. /* Instruction decoding.
  301.  
  302.    The opcode (IR<0:2>), indirect flag (IR<3>), and page flag (IR<4>)
  303.    are decoded together.  This produces 32 decode points, four per
  304.    major opcode.  For IOT, the extra decode points are not useful;
  305.    for OPR, only the group flag (IR<3>) is used.
  306.  
  307.    The following macros define the address calculations for data and
  308.    jump calculations.  Data calculations return a full 15b extended
  309.    address, jump calculations a 12b field-relative address.
  310.  
  311.    Note that MA contains IF'PC.
  312. */
  313.  
  314. #define ZERO_PAGE    MA = IF | (IR & 0177)
  315. #define CURR_PAGE    MA = (MA & 077600) | (IR & 0177)
  316. #define INDIRECT    if ((MA & 07770) != 00010) MA = DF | M[MA]; \
  317.             else MA = DF | (M[MA] = (M[MA] + 1) & 07777)
  318.  
  319. #define ZERO_PAGE_J    MA = IR & 0177
  320. #define CURR_PAGE_J    MA = (MA & 007600) | (IR & 0177)
  321. #define INDIRECT_J    if ((MA & 07770) != 00010) MA = M[MA]; \
  322.             else MA = (M[MA] = (M[MA] + 1) & 07777)
  323. #define CHANGE_FIELD    IF = IB; UF = UB; \
  324.             int_req = int_req | INT_NO_CIF_PENDING
  325.  
  326. switch ((IR >> 7) & 037) {                /* decode IR<0:4> */
  327.  
  328. /* Opcode 0, AND */
  329.  
  330. case 000:                        /* AND, dir, zero */
  331.     ZERO_PAGE;
  332.     LAC = LAC & (M[MA] | 010000);
  333.     break;
  334. case 001:                        /* AND, dir, curr */
  335.     CURR_PAGE;
  336.     LAC = LAC & (M[MA] | 010000);
  337.     break;
  338. case 002:                        /* AND, indir, zero */
  339.     ZERO_PAGE;
  340.     INDIRECT;
  341.     LAC = LAC & (M[MA] | 010000);
  342.     break;
  343. case 003:                        /* AND, indir, curr */
  344.     CURR_PAGE;
  345.     INDIRECT;
  346.     LAC = LAC & (M[MA] | 010000);
  347.     break;
  348.  
  349. /* Opcode 1, TAD */
  350.  
  351. case 004:                        /* TAD, dir, zero */
  352.     ZERO_PAGE;
  353.     LAC = (LAC + M[MA]) & 017777;
  354.     break;
  355. case 005:                        /* TAD, dir, curr */
  356.     CURR_PAGE;
  357.     LAC = (LAC + M[MA]) & 017777;
  358.     break;
  359. case 006:                        /* TAD, indir, zero */
  360.     ZERO_PAGE;
  361.     INDIRECT;
  362.     LAC = (LAC + M[MA]) & 017777;
  363.     break;
  364. case 007:                        /* TAD, indir, curr */
  365.     CURR_PAGE;
  366.     INDIRECT;
  367.     LAC = (LAC + M[MA]) & 017777;
  368.     break;
  369.  
  370. /* Opcode 2, ISZ */
  371.  
  372. case 010:                        /* ISZ, dir, zero */
  373.     ZERO_PAGE;
  374.     M[MA] = MB = (M[MA] + 1) & 07777;
  375.     if (MB == 0) PC = (PC + 1) & 07777;
  376.     break;
  377. case 011:                        /* ISZ, dir, curr */
  378.            CURR_PAGE;
  379.     M[MA] = MB = (M[MA] + 1) & 07777;
  380.     if (MB == 0) PC = (PC + 1) & 07777;
  381.     break;
  382. case 012:                        /* ISZ, indir, zero */
  383.     ZERO_PAGE;
  384.     INDIRECT;
  385.     MB = (M[MA] + 1) & 07777;
  386.     if (MEM_ADDR_OK (MA)) M[MA] = MB;
  387.     if (MB == 0) PC = (PC + 1) & 07777;
  388.     break;
  389. case 013:                        /* ISZ, indir, curr */
  390.     CURR_PAGE;
  391.     INDIRECT;
  392.     MB = (M[MA] + 1) & 07777;
  393.     if (MEM_ADDR_OK (MA)) M[MA] = MB;
  394.     if (MB == 0) PC = (PC + 1) & 07777;
  395.     break;
  396.  
  397. /* Opcode 3, DCA */
  398.  
  399. case 014:                        /* DCA, dir, zero */
  400.     ZERO_PAGE;
  401.     M[MA] = LAC & 07777;
  402.     LAC = LAC & 010000;
  403.     break;
  404. case 015:                        /* DCA, dir, curr */
  405.     CURR_PAGE;
  406.     M[MA] = LAC & 07777;
  407.     LAC = LAC & 010000;
  408.     break;
  409. case 016:                        /* DCA, indir, zero */
  410.     ZERO_PAGE;
  411.     INDIRECT;
  412.     if (MEM_ADDR_OK (MA)) M[MA] = LAC & 07777;
  413.     LAC = LAC & 010000;
  414.     break;
  415. case 017:                        /* DCA, indir, curr */
  416.     CURR_PAGE;
  417.     INDIRECT;
  418.     if (MEM_ADDR_OK (MA)) M[MA] = LAC & 07777;
  419.     LAC = LAC & 010000;
  420.     break;
  421.  
  422. /* Opcode 4, JMS */
  423.  
  424. case 020:                        /* JMS, dir, zero */
  425.     ZERO_PAGE_J;
  426.     CHANGE_FIELD;
  427.     M[IF | MA] = old_PC = PC;
  428.     PC = (MA + 1) & 07777;
  429.     break;
  430. case 021:                        /* JMS, dir, curr */
  431.     CURR_PAGE_J;
  432.     CHANGE_FIELD;
  433.     M[IF | MA] = old_PC = PC;
  434.     PC = (MA + 1) & 07777;
  435.     break;
  436. case 022:                        /* JMS, indir, zero */
  437.     ZERO_PAGE;
  438.     INDIRECT_J;
  439.     CHANGE_FIELD;
  440.     MA = IF | MA;
  441.     old_PC = PC;
  442.     if (MEM_ADDR_OK (MA)) M[MA] = PC;
  443.     PC = (MA + 1) & 07777;
  444.     break;
  445. case 023:                        /* JMS, indir, curr */
  446.     CURR_PAGE;
  447.     INDIRECT_J;
  448.     CHANGE_FIELD;
  449.     MA = IF | MA;
  450.     old_PC = PC;
  451.     if (MEM_ADDR_OK (MA)) M[MA] = PC;
  452.     PC = (MA + 1) & 07777;
  453.     break;
  454.  
  455. /* Opcode 5, JMP */
  456.  
  457. case 024:                        /* JMP, dir, zero */
  458.     ZERO_PAGE_J;
  459.     CHANGE_FIELD;
  460.     old_PC = PC;
  461.     PC = MA;
  462.     break;
  463. case 025:                        /* JMP, dir, curr */
  464.     CURR_PAGE_J;
  465.     CHANGE_FIELD;
  466.     old_PC = PC;
  467.     PC = MA;
  468.     break;
  469. case 026:                        /* JMP, indir, zero */
  470.     ZERO_PAGE;
  471.     INDIRECT_J;
  472.     CHANGE_FIELD;
  473.     old_PC = PC;
  474.     PC = MA;
  475.     break;
  476. case 027:                        /* JMP, indir, curr */
  477.     CURR_PAGE;
  478.     INDIRECT_J;
  479.     CHANGE_FIELD;
  480.     old_PC = PC;
  481.     PC = MA;
  482.     break;
  483.  
  484. /* Opcode 7, OPR group 1 */
  485.  
  486. case 034:case 035:                    /* OPR, group 1 */
  487.     switch ((IR >> 4) & 017) {            /* decode IR<4:7> */
  488.     case 0:                        /* nop */
  489.         break;
  490.     case 1:                        /* CML */
  491.         LAC = LAC ^ 010000;
  492.         break;
  493.     case 2:                        /* CMA */
  494.         LAC = LAC ^ 07777;
  495.         break;
  496.     case 3:                        /* CMA CML */
  497.         LAC = LAC ^ 017777;
  498.         break;
  499.     case 4:                        /* CLL */
  500.         LAC = LAC & 07777;
  501.         break;
  502.     case 5:                        /* CLL CML = STL */
  503.         LAC = LAC | 010000;
  504.         break;
  505.     case 6:                        /* CLL CMA */
  506.         LAC = (LAC ^ 07777) & 07777;
  507.         break;
  508.     case 7:                        /* CLL CMA CML */
  509.         LAC = (LAC ^ 07777) | 010000;
  510.         break;
  511.     case 010:                    /* CLA */
  512.         LAC = LAC & 010000;
  513.         break;
  514.     case 011:                    /* CLA CML */
  515.         LAC = (LAC & 010000) ^ 010000;
  516.         break;
  517.     case 012:                    /* CLA CMA = STA */
  518.         LAC = LAC | 07777;
  519.         break;
  520.     case 013:                    /* CLA CMA CML */
  521.         LAC = (LAC | 07777) ^ 010000;
  522.         break;
  523.     case 014:                    /* CLA CLL */
  524.         LAC = 0;
  525.         break;
  526.     case 015:                    /* CLA CLL CML */
  527.         LAC = 010000;
  528.         break;
  529.     case 016:                    /* CLA CLL CMA */
  530.         LAC = 07777;
  531.         break;
  532.     case 017:                    /* CLA CLL CMA CML */
  533.         LAC = 017777;
  534.         break;  }                /* end switch opers */
  535.  
  536. /* OPR group 1, continued */
  537.  
  538.     if (IR & 01) LAC = (LAC + 1) & 017777;        /* IAC */
  539.     switch ((IR >> 1) & 07) {            /* decode IR<8:10> */
  540.     case 0:                     /* nop */
  541.         break;
  542.     case 1:                        /* BSW */
  543.         LAC = (LAC & 010000) | ((LAC >> 6) & 077) | ((LAC & 077) << 6);
  544.         break;
  545.     case 2:                        /* RAL */
  546.         LAC = ((LAC << 1) | (LAC >> 12)) & 017777;
  547.         break;
  548.     case 3:                        /* RTL */
  549.         LAC = ((LAC << 2) | (LAC >> 11)) & 017777;
  550.         break;
  551.     case 4:                        /* RAR */
  552.         LAC = ((LAC >> 1) | (LAC << 12)) & 017777;
  553.         break;
  554.     case 5:                        /* RTR */
  555.         LAC = ((LAC >> 2) | (LAC << 11)) & 017777;
  556.         break;
  557.     case 6:                        /* RAL RAR - undef */
  558.         LAC = LAC & (IR | 010000);        /* uses AND path */
  559.         break;
  560.     case 7:                        /* RTL RTR - undef */
  561.         LAC = (LAC & 010000) | (MA & 07600) | (IR & 0177);
  562.         break;  }                /* uses address path */
  563.     break;                        /* end group 1 */
  564.  
  565. /* OPR group 2 */
  566.  
  567. case 036:case 037:                    /* OPR, groups 2, 3 */
  568.     if ((IR & 01) == 0) {                /* group 2 */
  569.         switch ((IR >> 3) & 017) {        /* decode IR<6:8> */
  570.         case 0:                 /* nop */
  571.             break;
  572.         case 1:                    /* SKP */
  573.             PC = (PC + 1) & 07777;
  574.             break;
  575.         case 2:                 /* SNL */
  576.             if (LAC >= 010000) PC = (PC + 1) & 07777;
  577.             break;
  578.         case 3:                 /* SZL */
  579.             if (LAC < 010000) PC = (PC + 1) & 07777;
  580.             break;
  581.         case 4:                 /* SZA */
  582.             if ((LAC & 07777) == 0) PC = (PC + 1) & 07777;
  583.             break;
  584.         case 5:                 /* SNA */
  585.             if ((LAC & 07777) != 0) PC = (PC + 1) & 07777;
  586.             break;
  587.         case 6:                    /* SZA | SNL */
  588.             if ((LAC == 0) || (LAC >= 010000))
  589.                 PC = (PC + 1) & 07777;
  590.             break;
  591.         case 7:                    /* SNA & SZL */
  592.             if ((LAC != 0) && (LAC < 010000)) PC = (PC + 1) & 07777;
  593.             break;
  594.         case 010:                 /* SMA */
  595.             if ((LAC & 04000) != 0) PC = (PC + 1) & 07777;
  596.             break;
  597.         case 011:                 /* SPA */
  598.             if ((LAC & 04000) == 0) PC = (PC + 1) & 07777;
  599.             break;
  600.         case 012:                /* SMA | SNL */
  601.             if (LAC >= 04000) PC = (PC + 1) & 07777;
  602.             break;
  603.         case 013:                /* SPA & SZL */
  604.             if (LAC < 04000) PC = (PC + 1) & 07777;
  605.             break;
  606.         case 014:                /* SMA | SZA */
  607.             if (((LAC & 04000) != 0) || ((LAC & 07777) == 0))
  608.                 PC = (PC + 1) & 07777;
  609.             break;
  610.         case 015:                /* SPA & SNA */
  611.             if (((LAC & 04000) == 0) && ((LAC & 07777) != 0))
  612.                 PC = (PC + 1) & 07777;
  613.             break;
  614.         case 016:                /* SMA | SZA | SNL */
  615.             if ((LAC >= 04000) || (LAC == 0)) PC = (PC + 1) & 07777;
  616.             break;
  617.         case 017:                /* SPA & SNA & SZL */
  618.             if ((LAC < 04000) && (LAC != 0)) PC = (PC + 1) & 07777;
  619.             break;    }            /* end switch skips */
  620.         if (IR & 0200) LAC = LAC & 010000;    /* CLA */
  621.         if ((IR & 06) && UF) int_req = int_req | INT_UF;
  622.         else {    if (IR & 04) LAC = LAC | OSR;        /* OSR */
  623.             if (IR & 02) reason = STOP_HALT;  }    /* HLT */
  624.         break;  }                              /* end group 2 */
  625.  
  626. /* OPR group 3 standard
  627.  
  628.    MQA!MQL exchanges AC and MQ, as follows:
  629.  
  630.     temp = MQ;
  631.     MQ = LAC & 07777;
  632.     LAC = LAC & 010000 | temp;
  633. */
  634.  
  635.     temp = MQ;                    /* group 3 */
  636.     if (IR & 0200) LAC = LAC & 010000;        /* CLA */
  637.     if (IR & 0020) {                /* MQL */
  638.         MQ = LAC & 07777;
  639.         LAC = LAC & 010000;  }
  640.     if (IR & 0100) LAC = LAC | temp;        /* MQA */
  641.     if ((IR & 0056) && (cpu_unit.flags & UNIT_NOEAE)) {
  642.         reason = stop_inst;            /* EAE not present */
  643.         break;  }
  644.  
  645. /* OPR group 3 EAE
  646.  
  647.    The EAE operates in two modes:
  648.  
  649.     Mode A, PDP-8/I compatible
  650.     Mode B, extended capability
  651.  
  652.    Mode B provides eight additional subfunctions; in addition, some
  653.    of the Mode A functions operate differently in Mode B.
  654.  
  655.    The mode switch instructions are decoded explicitly and cannot be
  656.    microprogrammed with other EAE functions (SWAB performs an MQL as
  657.    part of standard group 3 decoding).  If mode switching is decoded,
  658.    all other EAE timing is suppressed.
  659. */
  660.  
  661.     if (IR == 07431) {                /* SWAB */
  662.         emode = 1;                /* set mode flag */
  663.         break;  }
  664.     if (IR == 07447) {                /* SWBA */
  665.         emode = gtf = 0;            /* clear mode, gtf */
  666.         break;  }
  667.  
  668. /* If not switching modes, the EAE operation is determined by the mode
  669.    and IR<6,8:10>:
  670.  
  671.    <6:10>    mode A        mode B        comments
  672.  
  673.    0x000    NOP        NOP
  674.    0x001    SCL        ACS
  675.    0x010    MUY        MUY        if mode B, next = address
  676.    0x011    DVI        DVI        if mode B, next = address
  677.    0x100    NMI        NMI        if mode B, clear AC if
  678.                          result = 4000'0000
  679.    0x101    SHL        SHL        if mode A, extra shift
  680.    0x110    ASR        ASR        if mode A, extra shift
  681.    0x111    LSR        LSR        if mode A, extra shift
  682.    1x000    SCA        SCA
  683.    1x001    SCA + SCL    DAD
  684.    1x010    SCA + MUY    DST
  685.    1x011    SCA + DVI    SWBA            NOP if not detected earlier
  686.    1x100    SCA + NMI    DPSZ        
  687.    1x101    SCA + SHL    DPIC            must be combined with MQA!MQL
  688.    1x110    SCA + ASR    DCM        must be combined with MQA!MQL
  689.    1x111    SCA + LSR    SAM
  690.  
  691.    EAE instructions which fetch memory operands use the CPU's DEFER
  692.    state to read the first word; if the address operand is in locations
  693.    x0010 - x0017, it is autoincremented.
  694. */
  695.  
  696. /* EAE continued */
  697.  
  698.     switch ((IR >> 1) & 027) {            /* decode IR<6,8:10> */
  699.     case 020:                    /* mode A, B: SCA */
  700.         LAC = LAC | SC;
  701.         break;
  702.     case 0:                        /* mode A, B: NOP */
  703.         break;
  704.     case 021:                    /* mode B: DAD */
  705.         if (emode) {
  706.             MA = IF | PC;
  707.             INDIRECT;            /* defer state */
  708.             MQ = MQ + M[MA];
  709.             MA = DF | ((MA + 1) & 07777);
  710.             LAC = (LAC & 07777) + M[MA] + (MQ >> 12);
  711.             MQ = MQ & 07777;
  712.             PC = (PC + 1) & 07777;
  713.             break;  }
  714.         LAC = LAC | SC;                /* mode A: SCA then */
  715.     case 1:                        /* mode B: ACS */
  716.         if (emode) {
  717.             SC = LAC & 037;
  718.             LAC = LAC & 010000;
  719.             break;  }
  720.         SC = (~M[IF | PC]) & 037;        /* mode A: SCL */
  721.         PC = (PC + 1) & 07777;
  722.         break;
  723.     case 022:                    /* mode B: DST */
  724.         if (emode) {
  725.             MA = IF | PC;
  726.             INDIRECT;            /* defer state */
  727.             if (MEM_ADDR_OK (MA)) M[MA] = MQ & 07777;
  728.             MA = DF | ((MA + 1) & 07777);
  729.             if (MEM_ADDR_OK (MA))  M[MA] = LAC & 07777;
  730.             PC = (PC + 1) & 07777;
  731.             break;  }
  732.         LAC = LAC | SC;                /* mode A: SCA then */
  733.     case 2:                        /* MUY */
  734.         MA = IF | PC;
  735.         if (emode) { INDIRECT; }        /* mode B: defer */
  736.         temp = (MQ * M[MA]) + (LAC & 07777);
  737.         LAC = (temp >> 12) & 07777;
  738.         MQ = temp & 07777;
  739.         PC = (PC + 1) & 07777;
  740.         SC = 014;                /* 12 shifts */
  741.         break;
  742.  
  743. /* EAE continued */
  744.  
  745.     case 023:                    /* mode B: SWBA */
  746.         if (emode) break;
  747.         LAC = LAC | SC;                /* mode A: SCA then */
  748.     case 3:                        /* DVI */
  749.         MA = IF | PC;
  750.         if (emode) { INDIRECT; }        /* mode B: defer */
  751.         if ((LAC & 07777) >= M[MA]) {        /* overflow? */
  752.             LAC = LAC | 010000;        /* set link */
  753.             MQ = ((MQ << 1) + 1) & 07777;    /* rotate MQ */
  754.             SC = 01;  }            /* 1 shift */
  755.         else {    temp = ((LAC & 07777) << 12) | MQ;
  756.             MQ = temp / M[MA];
  757.             LAC = temp % M[MA];
  758.             SC = 015;  }            /* 13 shifts */
  759.         PC = (PC + 1) & 07777;
  760.         break;
  761.     case 024:                    /* mode B: DPSZ */
  762.         if (emode) {
  763.             if (((LAC | MQ) & 07777) == 0) PC = (PC + 1) & 07777;
  764.             break;  }
  765.         LAC = LAC | SC;                /* mode A: SCA then */
  766.     case 4:                        /* NMI */
  767.         temp = (LAC << 12) | MQ;        /* preserve link */
  768.         for (SC = 0; ((temp & 017777777) != 0) &&
  769.             (temp & 040000000) == ((temp << 1) & 040000000); SC++)
  770.             temp = temp << 1;
  771.         LAC = (temp >> 12) & 017777;
  772.         MQ = temp & 07777;
  773.         if (emode && ((LAC & 07777) == 04000) && (MQ == 0))
  774.             LAC = LAC & 010000;        /* clr if 4000'0000 */
  775.         break;
  776.     case 025:                    /* mode B: DPIC */
  777.         if (emode) {
  778.             temp = (LAC + 1) & 07777;    /* SWP already done! */
  779.             LAC = MQ + (temp == 0);
  780.             MQ = temp;
  781.             break;  }
  782.         LAC = LAC | SC;                /* mode A: SCA then */
  783.     case 5:                        /* SHL */
  784.         SC = (M[IF | PC] & 037) + (emode ^ 1);    /* shift+1 if mode A */
  785.         temp = ((LAC << 12) | MQ) << SC;    /* preserve link */
  786.         LAC = (temp >> 12) & 017777;
  787.         MQ = temp & 07777;
  788.         PC = (PC + 1) & 07777;
  789.         SC = emode? 037: 0;            /* SC = 0 if mode A */
  790.         break;
  791.  
  792. /* EAE continued */
  793.  
  794.     case 026:                    /* mode B: DCM */
  795.         if (emode) {
  796.             temp = (-LAC) & 07777;        /* SWP already done! */
  797.             LAC = (MQ ^ 07777) + (temp == 0);
  798.             MQ = temp;
  799.             break;  }
  800.         LAC = LAC | SC;                /* mode A: SCA then */
  801.     case 6:                        /* ASR */
  802.         SC = (M[IF | PC] & 037) + (emode ^ 1);    /* shift+1 if mode A */
  803.         temp = ((LAC & 07777) << 12) | MQ;    /* sext from AC0 */
  804.         if (LAC & 04000) temp = temp | ~037777777;
  805.         if (emode && (SC != 0)) gtf = (temp >> (SC - 1)) & 1;
  806.         temp = temp >> SC;
  807.         if (LAC & 04000) temp = temp | (-1 << (32 - SC));
  808.         LAC = (temp >> 12) & 017777;
  809.         MQ = temp & 07777;
  810.         PC = (PC + 1) & 07777;
  811.         SC = emode? 037: 0;            /* SC = 0 if mode A */
  812.         break;
  813.     case 027:                    /* mode B: SAM */
  814.         if (emode) {
  815.             MA = LAC & 07777;
  816.             LAC = MQ + (MA ^ 07777) + 1;    /* L'AC = MQ - AC */
  817.             gtf = (MA <= MQ) ^ ((MA ^ MQ) >> 11);
  818.             break;  }
  819.         LAC = LAC | SC;                /* mode A: SCA then */
  820.     case 7:                        /* LSR */
  821.         SC = (M[IF | PC] & 037) + (emode ^ 1);    /* shift+1 if mode A */
  822.         temp = ((LAC & 07777) << 12) | MQ;    /* clear link */
  823.         if (emode && (SC != 0)) gtf = (temp >> (SC - 1)) & 1;
  824.         temp = temp >> SC;
  825.         LAC = (temp >> 12) & 07777;
  826.         MQ = temp & 07777;
  827.         PC = (PC + 1) & 07777;
  828.         SC = emode? 037: 0;            /* SC = 0 if mode A */
  829.         break;  }                /* end switch */
  830.     break;                        /* end case 7 */
  831.  
  832. /* Opcode 6, IOT */
  833.  
  834. case 030:case 031:case 032:case 033:            /* IOT */
  835.     if (UF) {                    /* privileged? */
  836.         int_req = int_req | INT_UF;
  837.         break;  }
  838.     device = (IR >> 3) & 077;            /* device = IR<3:8> */
  839.     pulse = IR & 07;                /* pulse = IR<9:11> */
  840.     iot_data = LAC & 07777;                /* AC unchanged */
  841.     switch (device) {                /* decode IR<3:8> */
  842.     case 0:                        /* CPU control */
  843.         switch (pulse) {            /* decode IR<9:11> */
  844.         case 0:                    /* SKON */
  845.             if (int_req & INT_ION) PC = (PC + 1) & 07777;
  846.             int_req = int_req & ~INT_ION;
  847.             break;
  848.         case 1:                    /* ION */
  849.             int_req = (int_req | INT_ION) & ~INT_NO_ION_PENDING;
  850.             break;
  851.         case 2:                    /* IOF */
  852.             int_req = int_req & ~INT_ION;
  853.             break;
  854.         case 3:                    /* SRQ */
  855.             if (int_req & INT_ALL) PC = (PC + 1) & 07777;
  856.             break;
  857.         case 4:                    /* GTF */
  858.             LAC = (LAC & 010000) |
  859.                   ((LAC & 010000) >> 1) | (gtf << 10) |
  860.                   (((int_req & INT_ALL) != 0) << 9) |
  861.                   (((int_req & INT_ION) != 0) << 7) | SF;
  862.             break;
  863.         case 5:                    /* RTF */
  864.             gtf = ((LAC & 02000) >> 10);
  865.             UB = (LAC & 0100) >> 6;
  866.             IB = (LAC & 0070) << 9;
  867.             DF = (LAC & 0007) << 12;
  868.             LAC = ((LAC & 04000) << 1) | iot_data;
  869.             int_req = (int_req | INT_ION) & ~INT_NO_CIF_PENDING;
  870.             break;
  871.         case 6:                    /* SGT */
  872.             if (gtf) PC = (PC + 1) & 07777;
  873.             break;
  874.         case 7:                    /* CAF */
  875.             gtf = 0;
  876.             emode = 0;
  877.             int_req = int_req & INT_NO_CIF_PENDING;
  878.             dev_done = 0;
  879.             dev_enable = INT_INIT_ENABLE;
  880.             LAC = 0;
  881.             break;  }            /* end switch pulse */
  882.         continue;                /* skip rest of IOT */
  883.  
  884. /* IOT, continued: memory extension */
  885.  
  886.     case 020:case 021:case 022:case 023:
  887.     case 024:case 025:case 026:case 027:        /* memory extension */
  888.         switch (pulse) {            /* decode IR<9:11> */
  889.         case 1:                 /* CDF */
  890.             DF = (IR & 0070) << 9;
  891.             break;
  892.         case 2:                    /* CIF */
  893.             IB = (IR & 0070) << 9;
  894.             int_req = int_req & ~INT_NO_CIF_PENDING;
  895.             break;
  896.         case 3:                    /* CDF CIF */
  897.             DF = IB = (IR & 0070) << 9;
  898.             int_req = int_req & ~INT_NO_CIF_PENDING;
  899.             break;
  900.         case 4:
  901.             switch (device & 07) {        /* decode IR<5:3> */
  902.             case 0:                /* CINT */
  903.                 int_req = int_req & ~INT_UF;
  904.                 break;
  905.             case 1:                /* RDF */
  906.                 LAC = LAC | (DF >> 9);
  907.                 break;
  908.             case 2:                /* RIF */
  909.                 LAC = LAC | (IF >> 9);
  910.                 break;
  911.             case 3:                /* RIB */
  912.                 LAC = LAC | SF;
  913.                 break;
  914.             case 4:                /* RMF */
  915.                 UB = (SF & 0100) >> 6;
  916.                 IB = (SF & 0070) << 9;
  917.                 DF = (SF & 0007) << 12;
  918.                 int_req = int_req & ~INT_NO_CIF_PENDING;
  919.                 break;
  920.             case 5:                /* SINT */
  921.                 if (int_req & INT_UF) PC = (PC + 1) & 07777;
  922.                 break;
  923.             case 6:                /* CUF */
  924.                 UB = 0;
  925.                 int_req = int_req & ~INT_NO_CIF_PENDING;
  926.                 break;
  927.             case 7:                /* SUF */
  928.                 UB = 1;
  929.                 int_req = int_req & ~INT_NO_CIF_PENDING;
  930.                 break;  }         /* end switch device */
  931.             break;
  932.         default:
  933.             reason = stop_inst;
  934.             break;  }            /* end switch pulse */
  935.         continue;                /* skip rest of IOT */
  936.  
  937. /* IOT, continued: other special cases */
  938.  
  939.     case 010:                    /* power fail */
  940.         switch (pulse) {            /* decode IR<9:11> */
  941.         case 1:                    /* SBE */
  942.             break;
  943.         case 2:                 /* SPL */
  944.             if (int_req & INT_PWR) PC = (PC + 1) & 07777;
  945.             break;
  946.         case 3:                 /* CAL */
  947.             int_req = int_req & ~INT_PWR;
  948.             break;
  949.         default:
  950.             reason = stop_inst;
  951.             break;  }            /* end switch pulse */
  952.         continue;                /* skip rest of IOT */
  953.     default:                    /* unknown device */
  954.         reason = stop_inst;            /* stop on flag */
  955.         continue;                /* skip rest of IOT */
  956.  
  957. /* IOT, continued: I/O devices */
  958.  
  959.     case 1:                        /* PTR */
  960.         iot_data = ptr (pulse, iot_data);
  961.         break;
  962.     case 2:                        /* PTP */
  963.         iot_data = ptp (pulse, iot_data);
  964.         break;
  965.     case 3:                        /* TTI */
  966.         iot_data = tti (pulse, iot_data);
  967.         break;
  968.     case 4:                     /* TTO */
  969.         iot_data = tto (pulse, iot_data);
  970.         break;
  971.     case 013:                    /* CLK */
  972.         iot_data = clk (pulse, iot_data);
  973.         break;
  974.     case 060:                    /* RF08 */
  975.         iot_data = rf60 (pulse, iot_data);
  976.         break;
  977.     case 061:
  978.         iot_data = rf61 (pulse, iot_data);
  979.         break;
  980.     case 062:
  981.         iot_data = rf62 (pulse, iot_data);
  982.         break;
  983.     case 064:
  984.         iot_data = rf64 (pulse, iot_data);
  985.         break;
  986.     case 066:                    /* LPT */
  987.         iot_data = lpt (pulse, iot_data);
  988.         break;
  989.     case 070:                    /* TM8E */
  990.         iot_data = mt70 (pulse, iot_data);
  991.         break;
  992.     case 071:
  993.         iot_data = mt71 (pulse, iot_data);
  994.         break;
  995.     case 072:
  996.         iot_data = mt72 (pulse, iot_data);
  997.         break;
  998.     case 074:                    /* RK8E */
  999.         iot_data = rk (pulse, iot_data);
  1000.         break;
  1001.     case 075:                    /* RX8E */
  1002.         iot_data = rx (pulse, iot_data);
  1003.         break;  }                /* end switch device */
  1004.     LAC = (LAC & 010000) | (iot_data & 07777);
  1005.     if (iot_data & IOT_SKP) PC = (PC + 1) & 07777;
  1006.     if (iot_data >= IOT_REASON) reason = iot_data >> IOT_V_REASON;
  1007.     break;  }                    /* end switch opcode */
  1008. }                            /* end while */
  1009.  
  1010. /* Simulation halted */
  1011.  
  1012. saved_PC = IF | (PC & 07777);                /* save copies */
  1013. saved_DF = DF & 070000;
  1014. saved_LAC = LAC & 017777;
  1015. saved_MQ = MQ & 07777;
  1016. return reason;
  1017. }                            /* end sim_instr */
  1018.  
  1019. /* Reset routine */
  1020.  
  1021. int cpu_reset (DEVICE *dptr)
  1022. {
  1023. int_req = (int_req & (~INT_ION)) | INT_NO_CIF_PENDING;
  1024. saved_DF = IB = (saved_PC >> 12) & 03;
  1025. UF = UB = gtf = emode = 0;
  1026. return cpu_svc (&cpu_unit);
  1027. }
  1028.  
  1029. /* Breakpoint service */
  1030.  
  1031. int cpu_svc (UNIT *uptr)
  1032. {
  1033. if ((ibkpt_addr & ~ILL_ADR_FLAG) == save_ibkpt) ibkpt_addr = save_ibkpt;
  1034. save_ibkpt = -1;
  1035. return SCPE_OK;
  1036. }
  1037.  
  1038. /* Memory examine */
  1039.  
  1040. int cpu_ex (int *vptr, int addr, UNIT *uptr, int sw)
  1041. {
  1042. if (addr >= MEMSIZE) return SCPE_NXM;
  1043. if (vptr != NULL) *vptr = M[addr] & 07777;
  1044. return SCPE_OK;
  1045. }
  1046.  
  1047. /* Memory deposit */
  1048.  
  1049. int cpu_dep (int val, int addr, UNIT *uptr, int sw)
  1050. {
  1051. if (addr >= MEMSIZE) return SCPE_NXM;
  1052. M[addr] = val & 07777;
  1053. return SCPE_OK;
  1054. }
  1055.  
  1056. /* Memory size change */
  1057.  
  1058. int cpu_set_size (UNIT *uptr, int value)
  1059. {
  1060. int i, mc = 0;
  1061. extern int get_yn (char *ques, int deflt);
  1062.  
  1063. if ((value <= 0) || (value > MAXMEMSIZE) || ((value & 07777) != 0))
  1064.     return SCPE_ARG;
  1065. for (i = value; i < MEMSIZE; i++) mc = mc | M[i];
  1066. if ((mc != 0) && (!get_yn ("Really truncate memory [N]?", FALSE)))
  1067.     return SCPE_OK;
  1068. MEMSIZE = value;
  1069. for (i = MEMSIZE; i < MAXMEMSIZE; i++) M[i] = 0;
  1070. return SCPE_OK;
  1071. }
  1072.