|  | /* i8008.c: Intel 8008 CPU simulator | 
|  |  | 
|  | Copyright (c) 2011, William A. Beech | 
|  |  | 
|  | 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 | 
|  | WILLIAM A. BEECH 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. | 
|  |  | 
|  | Except as contained in this notice, the name of William A. Beech shall not be | 
|  | used in advertising or otherwise to promote the sale, use or other dealings | 
|  | in this Software without prior written authorization from William A. Beech. | 
|  |  | 
|  | cpu          8008 CPU | 
|  |  | 
|  | The register state for the 8008 CPU is: | 
|  |  | 
|  | A<0:7>               Accumulator | 
|  | B<0:7>               B Register | 
|  | C<0:7>               C Register | 
|  | D<0:7>               D Register | 
|  | E<0:7>               E Register | 
|  | H<0:7>               H Register | 
|  | L<0:7>               L Register | 
|  | PC<0:13>             Program counter | 
|  |  | 
|  | The 8008 is an 8-bit CPU, which uses 14-bit registers to address | 
|  | up to 16KB of memory. | 
|  |  | 
|  | The 57 basic instructions come in 1, 2, and 3-byte flavors. | 
|  |  | 
|  | This routine is the instruction decode routine for the 8008. | 
|  | It is called from the simulator control program to execute | 
|  | instructions in simulated memory, starting at the simulated PC. | 
|  | It runs until 'reason' is set non-zero. | 
|  |  | 
|  | General notes: | 
|  |  | 
|  | 1. Reasons to stop.  The simulator can be stopped by: | 
|  |  | 
|  | HLT instruction | 
|  | I/O error in I/O simulator | 
|  | Invalid OP code (if ITRAP is set on CPU) | 
|  |  | 
|  | 2. Interrupts. | 
|  | There are 8 possible levels of interrupt, and in effect they | 
|  | do a hardware CALL instruction to one of 8 possible low | 
|  | memory addresses. | 
|  |  | 
|  | 3. Non-existent memory.  On the 8008, reads to non-existent memory | 
|  | return 0FFh, and writes are ignored.  In the simulator, the | 
|  | largest possible memory is instantiated and initialized to zero. | 
|  | Thus, only writes need be checked against actual memory size. | 
|  |  | 
|  | 4. Adding I/O devices.  These modules must be modified: | 
|  |  | 
|  | 15 Feb 15 - Original file. | 
|  |  | 
|  | */ | 
|  |  | 
|  | #include "system_defs.h" | 
|  |  | 
|  | #define UNIT_V_OPSTOP   (UNIT_V_UF)     /* Stop on Invalid OP? */ | 
|  | #define UNIT_OPSTOP     (1 << UNIT_V_OPSTOP) | 
|  | #define UNIT_V_TRACE    (UNIT_V_UF+1)   /*  Trace switch */ | 
|  | #define UNIT_TRACE      (1 << UNIT_V_TRACE) | 
|  |  | 
|  | /* register masks */ | 
|  | #define BYTE_R  0xFF | 
|  | #define WORD_R14  0x3FFF | 
|  |  | 
|  | /* storage for the rest of the registers */ | 
|  | uint32 A = 0;                           /* accumulator */ | 
|  | uint32 B = 0;                           /* B register */ | 
|  | uint32 C = 0;                           /* C register */ | 
|  | uint32 D = 0;                           /* D register */ | 
|  | uint32 E = 0;                           /* E register */ | 
|  | uint32 H = 0;                           /* H register */ | 
|  | uint32 L = 0;                           /* L register */ | 
|  | uint32 CF = 0;                           /* C - carry flag */ | 
|  | uint32 PF = 0;                           /* P - parity flag */ | 
|  | uint32 ZF = 0;                           /* Z - zero flag */ | 
|  | uint32 SF = 0;                           /* S - sign flag */ | 
|  | uint32 SP = 0;                           /* stack frame pointer */ | 
|  | uint32 saved_PC = 0;                    /* program counter */ | 
|  | uint32 int_req = 0;                     /* Interrupt request */ | 
|  |  | 
|  | int32 PCX;                              /* External view of PC */ | 
|  | int32 PC; | 
|  | UNIT *uptr; | 
|  |  | 
|  | /* function prototypes */ | 
|  | void    store_m(unit32 val); | 
|  | unit32  fetch_m(void); | 
|  | void    set_cpuint(int32 int_num); | 
|  | void    dumpregs(void); | 
|  | int32   fetch_byte(int32 flag); | 
|  | int32   fetch_word(void); | 
|  | uint16  pop_word(void); | 
|  | void    push_word(uint16 val); | 
|  | void    setflag4(int32 reg); | 
|  | void    setlogical(int32 reg); | 
|  | void    setinc(int32 reg); | 
|  | int32   getreg(int32 reg); | 
|  | void    putreg(int32 reg, int32 val); | 
|  | int32   getpair(int32 reg); | 
|  | int32   getpush(int32 reg); | 
|  | void    putpush(int32 reg, int32 data); | 
|  | void    putpair(int32 reg, int32 val); | 
|  | void    parity(int32 reg); | 
|  | int32   cond(int32 con); | 
|  | t_stat  i8008_ex (t_value *vptr, t_addr addr, UNIT *uptr, int32 sw); | 
|  | t_stat  i8008_dep (t_value val, t_addr addr, UNIT *uptr, int32 sw); | 
|  | t_stat  i8008_reset (DEVICE *dptr); | 
|  |  | 
|  | /* external function prototypes */ | 
|  |  | 
|  | extern t_stat i8008_reset (DEVICE *dptr); | 
|  | extern int32 get_mbyte(int32 addr); | 
|  | extern int32 get_mword(int32 addr); | 
|  | extern void put_mbyte(int32 addr, int32 val); | 
|  | extern void put_mword(int32 addr, int32 val); | 
|  | extern int32 sim_int_char; | 
|  | extern uint32 sim_brk_types, sim_brk_dflt, sim_brk_summ; /* breakpoint info */ | 
|  |  | 
|  |  | 
|  | struct idev { | 
|  | int32 (*routine)(); | 
|  | }; | 
|  |  | 
|  | /* This is the I/O configuration table.  There are 256 possible | 
|  | device addresses, if a device is plugged to a port it's routine | 
|  | address is here, 'nulldev' means no device is available | 
|  | */ | 
|  |  | 
|  | extern struct idev dev_table[]; | 
|  |  | 
|  | /* CPU data structures | 
|  |  | 
|  | i8008_dev      CPU device descriptor | 
|  | i8008_unit     CPU unit descriptor | 
|  | i8008_reg      CPU register list | 
|  | i8008_mod      CPU modifiers list | 
|  | */ | 
|  |  | 
|  | UNIT i8008_unit = { UDATA (NULL, 0, 65535) }; /* default 8008 */ | 
|  |  | 
|  | REG i8008_reg[] = { | 
|  | { HRDATA (PC, saved_PC, 16) },      /* must be first for sim_PC */ | 
|  | { HRDATA (A, A, 8) }, | 
|  | { HRDATA (B, B, 8) }, | 
|  | { HRDATA (C, C, 8) }, | 
|  | { HRDATA (D, D, 8) }, | 
|  | { HRDATA (E, E, 8) }, | 
|  | { HRDATA (H, H, 8) }, | 
|  | { HRDATA (L, L, 8) }, | 
|  | { HRDATA (CF, CF, 1) }, | 
|  | { HRDATA (PF, PF, 1) }, | 
|  | { HRDATA (ZF, SF, 1) }, | 
|  | { HRDATA (SF, SF, 1) }, | 
|  | { HRDATA (INTR, int_req, 32) }, | 
|  | { HRDATA (WRU, sim_int_char, 8) }, | 
|  | { NULL } | 
|  | }; | 
|  |  | 
|  | MTAB i8008_mod[] = { | 
|  | { UNIT_OPSTOP, 0, "ITRAP", "ITRAP", NULL }, | 
|  | { UNIT_OPSTOP, UNIT_OPSTOP, "NOITRAP", "NOITRAP", NULL }, | 
|  | { UNIT_TRACE, 0, "NOTRACE", "NOTRACE", NULL }, | 
|  | { UNIT_TRACE, UNIT_TRACE, "TRACE", "TRACE", NULL }, | 
|  | { 0 } | 
|  | }; | 
|  |  | 
|  | DEBTAB i8008_debug[] = { | 
|  | { "ALL", DEBUG_all }, | 
|  | { "FLOW", DEBUG_flow }, | 
|  | { "READ", DEBUG_read }, | 
|  | { "WRITE", DEBUG_write }, | 
|  | { "LEV1", DEBUG_level1 }, | 
|  | { "LEV2", DEBUG_level2 }, | 
|  | { "REG", DEBUG_reg }, | 
|  | { "ASM", DEBUG_asm }, | 
|  | { NULL } | 
|  | }; | 
|  |  | 
|  | DEVICE i8008_dev = { | 
|  | "CPU",                              //name | 
|  | &i8008_unit,                        //units | 
|  | i8008_reg,                          //registers | 
|  | i8008_mod,                          //modifiers | 
|  | 1,                                  //numunits | 
|  | 16,                                 //aradix | 
|  | 16,                                 //awidth | 
|  | 1,                                  //aincr | 
|  | 16,                                 //dradix | 
|  | 8,                                  //dwidth | 
|  | &i8008_ex,                          //examine | 
|  | &i8008_dep,                         //deposit | 
|  | //    &i8008_reset,                       //reset | 
|  | NULL,                               //reset | 
|  | NULL,                               //boot | 
|  | NULL,                               //attach | 
|  | NULL,                               //detach | 
|  | NULL,                               //ctxt | 
|  | DEV_DEBUG,                          //flags | 
|  | 0,                                  //dctrl | 
|  | i8008_debug,                        //debflags | 
|  | NULL,                               //msize | 
|  | NULL                                //lname | 
|  | }; | 
|  |  | 
|  | /* tables for the disassembler */ | 
|  | char *opcode[] = { | 
|  | "*HLT", "*HLT", "RLC", "RFC",           /* 0x00 */ | 
|  | "ADI ", "RST 0", "LAI ,", "RET", | 
|  | "INB", "DCB", "RRC", "RFZ", | 
|  | "ACI ", "RST 1", "LBI ", "*RET", | 
|  | "INC", "DCC", "RAL", "RFS",             /* 0x10 */ | 
|  | "SUI ", "RST 2", "LCI ", "*RET", | 
|  | "IND", "DCD", "RAR", "RFP", | 
|  | "SBI ", "RST 3", "LDI ", "*RET", | 
|  | "INE", "DCE", "???", "RTC",             /* 0x20 */ | 
|  | "NDI ", "RST 4", "LEI ", "*RET", | 
|  | "INH", "DCH", "???", "RTZ", | 
|  | "XRI ", "RST 5", "LHI ", "*RET", | 
|  | "INL", "DCL", "???", "RTS",             /* 0x30 */ | 
|  | "ORI ", "RST 6", "LLI ", "*RET", | 
|  | "???", "???", "???", "RTP", | 
|  | "CPI ", "RST 7", "LMI ", "*RET", | 
|  | "JFC ", "INP ", "CFC ", "INP ",         /* 0x40 */ | 
|  | "JMP ", "INP ", "CAL ", "INP ", | 
|  | "JFZ ", "INP ", "CFZ ", "INP ", | 
|  | "*JMP ", "INP ", "*CAL ", "INP ", | 
|  | "JFS", "OUT ", "CFS ", "OUT ",          /* 0x50 */ | 
|  | "*JMP ", "OUT ", "*CAL ", "OUT ", | 
|  | "JFP ", "OUT ", "CFP ", "OUT ", | 
|  | "*JMP ", "OUT ", "*CAL ", "OUT ", | 
|  | "JTC ", "OUT ", "CTC ", "OUT ",         /* 0x60 */ | 
|  | "*JMP ", "OUT ", "*CAL ", "OUT ", | 
|  | "JTZ ", "OUT ", "CTZ", "OUT ", | 
|  | "*JMP ", "OUT ", "*CAL", "OUT ", | 
|  | "JTS ", "OUT ", "CTS ", "OUT ",         /* 0x70 */ | 
|  | "*JMP ", "OUT ", "*CAL ", "OUT ", | 
|  | "JTP ", "OUT ", "CTP", "OUT ", | 
|  | "*JMP ", "OUT ", "*CAL ", "OUT ", | 
|  | "ADA", "ADB", "ADC", "ADD",             /* 0x80 */ | 
|  | "ADE", "ADH", "ADL", "ADM", | 
|  | "ACA", "ACB", "ACC", "ACD", | 
|  | "ACE", "ACH", "ACL", "ACM", | 
|  | "SUA", "SUB", "SUC", "SUD",             /* 0x90 */ | 
|  | "SUE", "SUH", "SUL", "SUM", | 
|  | "SBA", "SBB", "SBC", "SBD", | 
|  | "SBE", "SBH", "SBL", "SBM", | 
|  | "NDA", "NDB", "NDC", "NDD",             /* 0xA0 */ | 
|  | "NDE", "NDH", "NDL", "NDM", | 
|  | "XRA", "XRB", "XRC", "XRD", | 
|  | "XRE", "XRH", "XRL", "XRM", | 
|  | "ORA", "ORB", "ORC", "ORD",             /* 0xB0 */ | 
|  | "ORE", "ORH", "ORL", "ORM", | 
|  | "CPA", "CPB", "CPC", "CPD", | 
|  | "CPE", "CPH", "CPL", "CPM", | 
|  | "NOP", "LAB", "LAC", "LAD",             /* 0xC0 */ | 
|  | "LAE", "LAH", "LAL", "LAM", | 
|  | "LBA", "LBB", "LBC", "LBD", | 
|  | "LBE", "LBH ", "LBL", "LBM", | 
|  | "LCA", "LCB", "LCC", "LCD",             /* 0xD0 */ | 
|  | "LCE", "LCH", "LCL", "LCM", | 
|  | "LDA", "LDB", "LDC", "LDD", | 
|  | "LDE", "LDH", "LDL", "LDM", | 
|  | "LEA", "LEB", "LEC", "LED",             /* 0xE0 */ | 
|  | "LEE", "LEH", "LEL", "LEM", | 
|  | "LHA", "LHB", "LHC", "LHD", | 
|  | "LHE", "LHH", "LHL", "LHM", | 
|  | "LLA", "LLB", "LLC", "LLD",             /* 0xF0 */ | 
|  | "LLE", "LLH", "LLL", "LLM", | 
|  | "LMA", "LMB", "LMC", "LMD", | 
|  | "LME", "LMH", "LML", "HLT", | 
|  | }; | 
|  |  | 
|  | int32 oplen[256] = { | 
|  | /* | 
|  | 0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F */ | 
|  | 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 2, 1, 2, 1, /* 0X */ | 
|  | 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 2, 1, 2, 1, /* 1X */ | 
|  | 1, 1, 0, 1, 2, 1, 2, 1, 1, 1, 1, 1, 2, 1, 2, 1, /* 2X */ | 
|  | 1, 1, 0, 1, 2, 1, 2, 1, 0, 0, 0, 1, 2, 1, 2, 1, /* 3X */ | 
|  | 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, /* 4X */ | 
|  | 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, /* 5X */ | 
|  | 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, /* 6X */ | 
|  | 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, /* 7X */ | 
|  | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 8X */ | 
|  | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 9X */ | 
|  | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* AX */ | 
|  | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* BX */ | 
|  | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* CX */ | 
|  | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* DX */ | 
|  | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* EX */ | 
|  | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1  /* FX */ | 
|  | }; | 
|  |  | 
|  | uint16 stack_frame[7];                 /* processor stack frame */ | 
|  |  | 
|  | void set_cpuint(int32 int_num) | 
|  | { | 
|  | int_req |= int_num; | 
|  | } | 
|  |  | 
|  | /* instruction simulator */ | 
|  | int32 sim_instr (void) | 
|  | { | 
|  | extern int32 sim_interval; | 
|  | uint32 IR, OP, DAR, reason, hi, lo, i, adr, val; | 
|  |  | 
|  | PC = saved_PC & WORD_R14;             /* load local PC */ | 
|  | reason = 0; | 
|  |  | 
|  | uptr = i8008_dev.units; | 
|  |  | 
|  | /* Main instruction fetch/decode loop */ | 
|  |  | 
|  | while (reason == 0) {               /* loop until halted */ | 
|  |  | 
|  | //        if (PC == 0x1000) {             /* turn on debugging */ | 
|  | //            i8008_dev.dctrl = DEBUG_asm + DEBUG_reg; | 
|  | //            reason = STOP_HALT; | 
|  | //        } | 
|  | if (i8008_dev.dctrl & DEBUG_reg) { | 
|  | dumpregs(); | 
|  | sim_printf("\n"); | 
|  | } | 
|  |  | 
|  | if (sim_interval <= 0) {        /* check clock queue */ | 
|  | if (reason = sim_process_event()) | 
|  | break; | 
|  | } | 
|  | sim_interval--;                 /* countdown clock */ | 
|  |  | 
|  | if (int_req > 0) {              /* interrupt? */ | 
|  | //            sim_printf("\ni8008: int_req=%04X", int_req); | 
|  | ; | 
|  | } else {                    /* 8008 */ | 
|  | if (IE) {          /* enabled? */ | 
|  | push_word(PC);      /* do an RST 7 */ | 
|  | PC = 0x0038; | 
|  | int_req &= ~INT_R; | 
|  | //                    sim_printf("\ni8008: int_req=%04X", int_req); | 
|  | } | 
|  | }                               /* end interrupt */ | 
|  |  | 
|  | if (sim_brk_summ && | 
|  | sim_brk_test (PC, SWMASK ('E'))) { /* breakpoint? */ | 
|  | reason = STOP_IBKPT;        /* stop simulation */ | 
|  | break; | 
|  | } | 
|  |  | 
|  | PCX = PC; | 
|  |  | 
|  | if (uptr->flags & UNIT_TRACE) { | 
|  | dumpregs(); | 
|  | sim_printf("\n"); | 
|  | } | 
|  | IR = OP = fetch_byte(0);        /* instruction fetch */ | 
|  |  | 
|  | if (OP == 0x00 || OP == 0x01 || OP == 0xFF) { /* HLT Instruction*/ | 
|  | reason = STOP_HALT; | 
|  | PC--; | 
|  | continue; | 
|  | } | 
|  |  | 
|  | /* The Big Instruction Decode Switch */ | 
|  |  | 
|  | switch (IR) { | 
|  |  | 
|  | case 0x02:                  /* RLC */ | 
|  | if (A & 0x80) | 
|  | CF = 1; | 
|  | else | 
|  | CF = 0; | 
|  | A = (A << 1) & 0xFF; | 
|  | if (CF) | 
|  | A |= 0x01; | 
|  | A &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0x03:                  /* RFC */ | 
|  | if (CF) | 
|  | ; | 
|  | else | 
|  | PC = pop_word(); | 
|  | break; | 
|  |  | 
|  | case 0x04:                  /* ADI */ | 
|  | A += fetch_byte(1); | 
|  | setflag3(A); | 
|  | A &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0x05:                  /* RST 0 */ | 
|  | case 0x0D:                  /* RST 1 */ | 
|  | case 0x15:                  /* RST 2 */ | 
|  | case 0x1D:                  /* RST 3 */ | 
|  | case 0x25:                  /* RST 4 */ | 
|  | case 0x2D:                  /* RST 5 */ | 
|  | case 0x35:                  /* RST 6 */ | 
|  | case 0x3D:                  /* RST 7 */ | 
|  | val = fetch_byte(); | 
|  | push_word(PC); | 
|  | PC = val << 3; | 
|  | break; | 
|  |  | 
|  | case 0x06:                  /* LAI */ | 
|  | A = fetch_byte(1); | 
|  | A &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0x07:                  /* RET */ | 
|  | PC = pop_word(); | 
|  | break; | 
|  |  | 
|  | case 0x08:                  /* INB */ | 
|  | B++; | 
|  | setflag3(B); | 
|  | B &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0x09:                  /* DCB */ | 
|  | B--; | 
|  | setflag3(B); | 
|  | B &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0x0A:                  /* RRC */ | 
|  | if (A & 0x01) | 
|  | CF = 1; | 
|  | else | 
|  | CF = 0; | 
|  | A = (A >> 1) & 0xFF; | 
|  | if (CF) | 
|  | A |= 0x80; | 
|  | A &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0x0B:                  /* RFZ */ | 
|  | if (ZF) | 
|  | ; | 
|  | else | 
|  | PC = pop_word(); | 
|  | break; | 
|  |  | 
|  | case 0x0C:                  /* ACI */ | 
|  | A += fetch_byte(1); | 
|  | if (CF) | 
|  | A++; | 
|  | setflag3(A); | 
|  | A &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0x0E:                  /* LBI */ | 
|  | B = fetch_byte(1); | 
|  | B &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0x0F:                  /* *RET */ | 
|  | PC = pop_word(); | 
|  | break; | 
|  |  | 
|  | case 0x10:                  /* INC */ | 
|  | C++; | 
|  | setflag3(C); | 
|  | C &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0x11:                  /* DCC */ | 
|  | C--; | 
|  | setflag3(C); | 
|  | C &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0x12:                  /* RAL */ | 
|  | if (A & 0x80) | 
|  | CF = 1; | 
|  | else | 
|  | CF = 0; | 
|  | A = (A << 1) & 0xFF; | 
|  | if (CF) | 
|  | A |= 0x01; | 
|  | A &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0x13:                  /* RFS */ | 
|  | if (SF) | 
|  | ; | 
|  | else | 
|  | PC = pop_word(); | 
|  | break; | 
|  |  | 
|  | case 0x14:                  /* SUI */ | 
|  | A -= fetch_byte(1); | 
|  | setflag3(A); | 
|  | A &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0x16:                  /* LCI */ | 
|  | C = fetch_byte(1); | 
|  | C &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0x17:                  /* *RET */ | 
|  | PC = pop_word(); | 
|  | break; | 
|  |  | 
|  | case 0x18:                  /* IND */ | 
|  | D++; | 
|  | setflag3(D); | 
|  | D &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0x19:                  /* DCD */ | 
|  | D--; | 
|  | setflag3(D); | 
|  | D &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0x1A:                  /* RAR */ | 
|  | if (A & 0x01) | 
|  | CF = 1; | 
|  | else | 
|  | CF = 0; | 
|  | A = (A >> 1) & 0xFF; | 
|  | if (CF) | 
|  | A |= 0x80; | 
|  | A &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0x1B:                  /* RFP */ | 
|  | if (PF) | 
|  | ; | 
|  | else | 
|  | PC = pop_word(); | 
|  | break; | 
|  |  | 
|  | case 0x1C:                  /* SBI */ | 
|  | A -= fetch_byte(1); | 
|  | if (CF) | 
|  | A--; | 
|  | setflag3(A); | 
|  | A &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0x1E:                  /* LDI */ | 
|  | D = fetch_byte(1); | 
|  | D &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0x1F:                  /* *RET */ | 
|  | PC = pop_word(); | 
|  | break; | 
|  |  | 
|  | case 0x20:                  /* INE */ | 
|  | E++; | 
|  | setflag3(E); | 
|  | E &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0x21:                  /* DCE */ | 
|  | E--; | 
|  | setflag3(E); | 
|  | E &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0x23:                  /* RTC */ | 
|  | if (CF) | 
|  | PC = pop_word(); | 
|  | break; | 
|  |  | 
|  | case 0x24:                  /* NDI */ | 
|  | A &= fetch_byte(1); | 
|  | setflag3(A); | 
|  | A &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0x26:                  /* LEI */ | 
|  | E = fetch_byte(1); | 
|  | E &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0x27:                  /* *RET */ | 
|  | PC = pop_word(); | 
|  | break; | 
|  |  | 
|  | case 0x28:                  /* INH */ | 
|  | H++; | 
|  | setflag3(H); | 
|  | H &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0x29:                  /* DCH */ | 
|  | H--; | 
|  | setflag3(H); | 
|  | H &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0x2B:                  /* RTZ */ | 
|  | if (ZF) | 
|  | PC = pop_word(); | 
|  | break; | 
|  |  | 
|  | case 0x2C:                  /* XRI */ | 
|  | A ^= fetch_byte(1); | 
|  | setflag3(A); | 
|  | break; | 
|  |  | 
|  | case 0x2E:                  /* LHI */ | 
|  | H = fetch_byte(1); | 
|  | H &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0x2F:                  /* *RET */ | 
|  | PC = pop_word(); | 
|  | break; | 
|  |  | 
|  | case 0x30:                  /* INL */ | 
|  | L++; | 
|  | setflag3(L); | 
|  | L &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0x31:                  /* DCL */ | 
|  | L--; | 
|  | setflag3(L); | 
|  | L &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0x33:                  /* RTS */ | 
|  | if (SF) | 
|  | PC = pop_word(); | 
|  | break; | 
|  |  | 
|  | case 0x34:                  /* ORI */ | 
|  | A |= fetch_byte(1); | 
|  | setflag3(A); | 
|  | A &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0x36:                  /* LLI */ | 
|  | L = fetch_byte(1); | 
|  | L &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0x37:                  /* *RET */ | 
|  | PC = pop_word(); | 
|  | break; | 
|  |  | 
|  | case 0x3B:                  /* RTP */ | 
|  | if (PF) | 
|  | PC = pop_word(); | 
|  | break; | 
|  |  | 
|  | case 0x3C:                  /* CPI */ | 
|  | DAR = A; | 
|  | DAR -= fetch_byte(1); | 
|  | setflag3(DAR); | 
|  | break; | 
|  |  | 
|  | case 0x3E:                  /* LMI */ | 
|  | val = fetch_byte(1); | 
|  | store_m(val); | 
|  | break; | 
|  |  | 
|  | case 0x3F:                  /* *RET */ | 
|  | PC = pop_word(); | 
|  | break; | 
|  |  | 
|  | case 0x40:                  /* JFC */ | 
|  | DAR = fetch_word(); | 
|  | if (CF) | 
|  | ; | 
|  | else | 
|  | PC = DAR; | 
|  | break; | 
|  |  | 
|  | case 0x41:                  /* INP 0 */ | 
|  | case 0x43:                  /* INP 1 */ | 
|  | case 0x45:                  /* INP 2 */ | 
|  | case 0x47:                  /* INP 3 */ | 
|  | case 0x49:                  /* INP 4 */ | 
|  | case 0x4B:                  /* INP 5 */ | 
|  | case 0x4D:                  /* INP 6 */ | 
|  | case 0x4F:                  /* INP 7 */ | 
|  | /**** fix me! */ | 
|  | break; | 
|  |  | 
|  | case 0x42:                  /* CFC */ | 
|  | adr = fetch_word(); | 
|  | if (CF) | 
|  | ; | 
|  | else { | 
|  | push_word(PC); | 
|  | PC = adr; | 
|  | } | 
|  | break; | 
|  |  | 
|  | case 0x44:                  /* JMP */ | 
|  | PC = fetch_word(); | 
|  | break; | 
|  |  | 
|  | case 0x46:                  /* CAL */ | 
|  | adr = fetch_word(); | 
|  | push_word(PC); | 
|  | PC = adr; | 
|  | break; | 
|  |  | 
|  | case 0x48:                  /* JFZ */ | 
|  | DAR = fetch_word(); | 
|  | if (ZF) | 
|  | ; | 
|  | else | 
|  | PC = DAR; | 
|  | break; | 
|  |  | 
|  | case 0x4A:                  /* CFZ */ | 
|  | adr = fetch_word(); | 
|  | if (ZF) | 
|  | ; | 
|  | else { | 
|  | push_word(PC); | 
|  | PC = adr; | 
|  | } | 
|  | break; | 
|  |  | 
|  | case 0x4C:                  /* *JMP */ | 
|  | PC = fetch_word(); | 
|  | break; | 
|  |  | 
|  | case 0x4E:                  /* *CAL */ | 
|  | adr = fetch_word(); | 
|  | push_word(PC); | 
|  | PC = adr; | 
|  | break; | 
|  |  | 
|  | case 0x50:                  /* JFS */ | 
|  | DAR = fetch_word(); | 
|  | if (SF) | 
|  | ; | 
|  | else | 
|  | PC = DAR; | 
|  | break; | 
|  |  | 
|  | case 0x51:                  /* OUT 8 */ | 
|  | case 0x53:                  /* OUT 9 */ | 
|  | case 0x55:                  /* OUT 10 */ | 
|  | case 0x57:                  /* OUT 11 */ | 
|  | case 0x59:                  /* OUT 12 */ | 
|  | case 0x5B:                  /* OUT 13 */ | 
|  | case 0x5D:                  /* OUT 14 */ | 
|  | case 0x5E:                  /* OUT 15 */ | 
|  | case 0x61:                  /* OUT 16 */ | 
|  | case 0x63:                  /* OUT 17 */ | 
|  | case 0x65:                  /* OUT 18 */ | 
|  | case 0x67:                  /* OUT 19 */ | 
|  | case 0x69:                  /* OUT 20 */ | 
|  | case 0x6B:                  /* OUT 21 */ | 
|  | case 0x6D:                  /* OUT 22 */ | 
|  | case 0x6E:                  /* OUT 23 */ | 
|  | case 0x71:                  /* OUT 24 */ | 
|  | case 0x73:                  /* OUT 25 */ | 
|  | case 0x75:                  /* OUT 26 */ | 
|  | case 0x77:                  /* OUT 27 */ | 
|  | case 0x79:                  /* OUT 28 */ | 
|  | case 0x7B:                  /* OUT 29 */ | 
|  | case 0x7D:                  /* OUT 30 */ | 
|  | case 0x7E:                  /* OUT 31 */ | 
|  | /**** fix me! */ | 
|  | break; | 
|  |  | 
|  | case 0x52:                  /* CFS */ | 
|  | adr = fetch_word(); | 
|  | if (SF) | 
|  | ; | 
|  | else { | 
|  | push_word(PC); | 
|  | PC = adr; | 
|  | } | 
|  | break; | 
|  |  | 
|  | case 0x54:                  /* *JMP */ | 
|  | PC = fetch_word(); | 
|  | break; | 
|  |  | 
|  | case 0x56:                  /* *CAL */ | 
|  | adr = fetch_word(); | 
|  | push_word(PC); | 
|  | PC = adr; | 
|  | break; | 
|  |  | 
|  | case 0x58:                  /* JFP */ | 
|  | DAR = fetch_word(); | 
|  | if (PF) | 
|  | ; | 
|  | else | 
|  | PC = DAR; | 
|  | break; | 
|  |  | 
|  | case 0x5A:                  /* CFP */ | 
|  | adr = fetch_word(); | 
|  | if (PF) | 
|  | ; | 
|  | else { | 
|  | push_word(PC); | 
|  | PC = adr; | 
|  | } | 
|  | break; | 
|  |  | 
|  | case 0x5C:                  /* *JMP */ | 
|  | PC = fetch_word(); | 
|  | break; | 
|  |  | 
|  | case 0x5E:                  /* *CAL */ | 
|  | adr = fetch_word(); | 
|  | push_word(PC); | 
|  | PC = adr; | 
|  | break; | 
|  |  | 
|  | case 0x60:                  /* JTC */ | 
|  | DAR = fetch_word(); | 
|  | if (CF) | 
|  | PC = DAR; | 
|  | break; | 
|  |  | 
|  | case 0x62:                  /* CTC */ | 
|  | adr = fetch_word(); | 
|  | if (CF) { | 
|  | push_word(PC); | 
|  | PC = adr; | 
|  | } | 
|  | break; | 
|  |  | 
|  | case 0x64:                  /* *JMP */ | 
|  | PC = fetch_word(); | 
|  | break; | 
|  |  | 
|  | case 0x66:                  /* *CAL */ | 
|  | adr = fetch_word(); | 
|  | push_word(PC); | 
|  | PC = adr; | 
|  | break; | 
|  |  | 
|  | case 0x68:                  /* JTZ */ | 
|  | DAR = fetch_word(); | 
|  | if (ZF) | 
|  | PC = DAR; | 
|  | break; | 
|  |  | 
|  | case 0x6A:                  /* CTZ */ | 
|  | adr = fetch_word(); | 
|  | if (ZF) { | 
|  | push_word(PC); | 
|  | PC = adr; | 
|  | } | 
|  | break; | 
|  |  | 
|  | case 0x6C:                  /* *JMP */ | 
|  | PC = fetch_word(); | 
|  | break; | 
|  |  | 
|  | case 0x6E:                  /* *CAL */ | 
|  | adr = fetch_word(); | 
|  | push_word(PC); | 
|  | PC = adr; | 
|  | break; | 
|  |  | 
|  | case 0x70:                  /* JTS */ | 
|  | DAR = fetch_word(); | 
|  | if (SF) | 
|  | PC = DAR; | 
|  | break; | 
|  |  | 
|  | case 0x72:                  /* CTS */ | 
|  | adr = fetch_word(); | 
|  | if (SF) { | 
|  | push_word(PC); | 
|  | PC = adr; | 
|  | } | 
|  | break; | 
|  |  | 
|  | case 0x74:                  /* *JMP */ | 
|  | PC = fetch_word(); | 
|  | break; | 
|  |  | 
|  | case 0x76:                  /* *CAL */ | 
|  | adr = fetch_word(); | 
|  | push_word(PC); | 
|  | PC = adr; | 
|  | break; | 
|  |  | 
|  | case 0x78:                  /* JTP */ | 
|  | DAR = fetch_word(); | 
|  | if (PF) | 
|  | PC = DAR; | 
|  | break; | 
|  |  | 
|  | case 0x7A:                  /* CTP */ | 
|  | adr = fetch_word(); | 
|  | if (PF) { | 
|  | push_word(PC); | 
|  | PC = adr; | 
|  | } | 
|  | break; | 
|  |  | 
|  | case 0x7C:                  /* *JMP */ | 
|  | PC = fetch_word(); | 
|  | break; | 
|  |  | 
|  | case 0x7E:                  /* *CAL */ | 
|  | adr = fetch_word(); | 
|  | push_word(PC); | 
|  | PC = adr; | 
|  | break; | 
|  |  | 
|  | case 0x80:                  /* ADA */ | 
|  | A += A; | 
|  | setflag4(A); | 
|  | A &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0x81:                  /* ADB */ | 
|  | A += B; | 
|  | setflag4(A); | 
|  | A &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0x82:                  /* ADC */ | 
|  | A += C; | 
|  | setflag4(A); | 
|  | A &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0x83:                  /* ADD */ | 
|  | A += D; | 
|  | setflag4(A); | 
|  | A &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0x84:                  /* ADE */ | 
|  | A += E; | 
|  | setflag4(A); | 
|  | A &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0x85:                  /* ADH */ | 
|  | A += H; | 
|  | setflag4(A); | 
|  | A &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0x86:                  /* ADL */ | 
|  | A += L; | 
|  | setflag4(A); | 
|  | A &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0x87:                  /* ADM */ | 
|  | A += fetch_m(); | 
|  | setflag4(A); | 
|  | A &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0x88:                  /* ACA */ | 
|  | A += A; | 
|  | if (CF) | 
|  | A++; | 
|  | setflag4(A); | 
|  | A &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0x89:                  /* ACB */ | 
|  | A += B; | 
|  | if (CF) | 
|  | A++; | 
|  | setflag4(A); | 
|  | A &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0x8A:                  /* ACC */ | 
|  | A += C; | 
|  | if (CF) | 
|  | A++; | 
|  | setflag4(A); | 
|  | A &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0x8B:                  /* ACD */ | 
|  | A += D; | 
|  | if (CF) | 
|  | A++; | 
|  | setflag4(A); | 
|  | A &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0x8C:                  /* ACE */ | 
|  | A += E; | 
|  | if (CF) | 
|  | A++; | 
|  | setflag4(A); | 
|  | A &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0x8D:                  /* ACH */ | 
|  | A += H; | 
|  | if (CF) | 
|  | A++; | 
|  | setflag4(A); | 
|  | A &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0x8E:                  /* ACL */ | 
|  | A += L; | 
|  | if (CF) | 
|  | A++; | 
|  | setflag4(A); | 
|  | A &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0x8F:                  /* ACM */ | 
|  | A += fetch_m(); | 
|  | if (CF) | 
|  | A++; | 
|  | setflag4(A); | 
|  | A &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0x90:                  /* SUA */ | 
|  | A -= A; | 
|  | setflag4(A); | 
|  | A &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0x91:                  /* SUB */ | 
|  | A -= B; | 
|  | setflag4(A); | 
|  | A &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0x92:                  /* SUC */ | 
|  | A -= C; | 
|  | setflag4(A); | 
|  | A &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0x93:                  /* SUD */ | 
|  | A -= D; | 
|  | setflag4(A); | 
|  | A &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0x94:                  /* SUE */ | 
|  | A -= E; | 
|  | setflag4(A); | 
|  | A &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0x95:                  /* SUH */ | 
|  | A -= H; | 
|  | setflag4(A); | 
|  | A &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0x96:                  /* SUL */ | 
|  | A -= L; | 
|  | setflag4(A); | 
|  | A &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0x97:                  /* SUM */ | 
|  | A -= fetch_m(); | 
|  | setflag4(A); | 
|  | A &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0x98:                  /* SBA */ | 
|  | A -= A; | 
|  | if (CF) | 
|  | A--; | 
|  | setflag4(A); | 
|  | A &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0x99:                  /* SBB */ | 
|  | A -= B; | 
|  | if (CF) | 
|  | A--; | 
|  | setflag4(A); | 
|  | A &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0x9A:                  /* SBC */ | 
|  | A -= C; | 
|  | if (CF) | 
|  | A--; | 
|  | setflag4(A); | 
|  | A &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0x9B:                  /* SBD */ | 
|  | A -= D; | 
|  | if (CF) | 
|  | A--; | 
|  | setflag4(A); | 
|  | A &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0x9C:                  /* SBE */ | 
|  | A -= E; | 
|  | if (CF) | 
|  | A--; | 
|  | setflag4(A); | 
|  | A &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0x9D:                  /* SBH */ | 
|  | A -= H; | 
|  | if (CF) | 
|  | A--; | 
|  | setflag4(A); | 
|  | A &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0x9E:                  /* SBL */ | 
|  | A -= L; | 
|  | if (CF) | 
|  | A--; | 
|  | setflag4(A); | 
|  | A &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0x9F:                  /* SBM */ | 
|  | A -= fetch_m(); | 
|  | if (CF) | 
|  | A - ; | 
|  | setflag4(A); | 
|  | A &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0xA0:                  /* NDA */ | 
|  | A &= A; | 
|  | setflag4(A); | 
|  | A &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0xA1:                  /* NDB */ | 
|  | A &= B; | 
|  | setflag4(A); | 
|  | A &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0xA2:                  /* NDC */ | 
|  | A &= C; | 
|  | setflag4(A); | 
|  | A &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0xA3:                  /* NDD */ | 
|  | A &= D; | 
|  | setflag4(A); | 
|  | A &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0xA4:                  /* NDE */ | 
|  | A &= E; | 
|  | setflag4(A); | 
|  | A &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0xA5:                  /* NDH */ | 
|  | A &= H; | 
|  | setflag4(A); | 
|  | A &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0xA6:                  /* NDL */ | 
|  | A &= L; | 
|  | setflag4(A); | 
|  | A &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0xA7:                  /* NDM */ | 
|  | A &= fetch_m(); | 
|  | setflag4(A); | 
|  | A &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0xA8:                  /* XRA */ | 
|  | A ^= A; | 
|  | setflag4(A); | 
|  | A &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0xA9:                  /* XRB */ | 
|  | A ^= B; | 
|  | setflag4(A); | 
|  | A &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0xAA:                  /* XRC */ | 
|  | A ^= C; | 
|  | setflag4(A); | 
|  | A &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0xAB:                  /* XRD */ | 
|  | A ^= D; | 
|  | setflag4(A); | 
|  | A &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0xAC:                  /* XRE */ | 
|  | A ^= E; | 
|  | setflag4(A); | 
|  | A &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0xAD:                  /* XRH */ | 
|  | A ^= H; | 
|  | setflag4(A); | 
|  | A &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0xAE:                  /* XRL */ | 
|  | A ^= L; | 
|  | setflag4(A); | 
|  | A &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0xAF:                  /* XRM */ | 
|  | A |= fetch_m(); | 
|  | setflag4(A); | 
|  | A &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0xB0:                  /* ORA */ | 
|  | A |= A; | 
|  | setflag4(A); | 
|  | A &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0xB1:                  /* ORB */ | 
|  | A |= B; | 
|  | setflag4(A); | 
|  | A &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0xB2:                  /* ORC */ | 
|  | A |= C; | 
|  | setflag4(A); | 
|  | A &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0xB3:                  /* ORD */ | 
|  | A |= D; | 
|  | setflag4(A); | 
|  | A &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0xB4:                  /* ORE */ | 
|  | A |= E; | 
|  | setflag4(A); | 
|  | A &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0xB5:                  /* ORH */ | 
|  | A |= H; | 
|  | setflag4(A); | 
|  | A &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0xB6:                  /* ORL */ | 
|  | A |= L; | 
|  | setflag4(A); | 
|  | A &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0xB7:                  /* ORM */ | 
|  | A |= fetch_m(); | 
|  | setflag4(A); | 
|  | A &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0xB8:                  /* CPA */ | 
|  | DAR -= A; | 
|  | setflag4(DAR); | 
|  | A &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0xB9:                  /* CPB */ | 
|  | DAR -= B; | 
|  | setflag4(DAR); | 
|  | A &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0xBA:                  /* CPC */ | 
|  | DAR -= C; | 
|  | setflag4(DAR); | 
|  | A &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0xBB:                  /* CPD */ | 
|  | DAR -= D; | 
|  | setflag4(DAR); | 
|  | A &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0xBC:                  /* CPE */ | 
|  | DAR -= E; | 
|  | setflag4(DAR); | 
|  | A &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0xBD:                  /* CPH */ | 
|  | DAR -= H; | 
|  | setflag4(DAR); | 
|  | A &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0xBE:                  /* CPL */ | 
|  | DAR -= L; | 
|  | setflag4(DAR); | 
|  | A &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0xBF:                  /* CPM */ | 
|  | DAR -= fetch_m(); | 
|  | setflag4(DAR); | 
|  | A &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0xC0:                  /* NOP */ | 
|  | break; | 
|  |  | 
|  | case 0xC1:                  /* LAB */ | 
|  | A = B; | 
|  | A &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0xC2:                  /* LAC */ | 
|  | A = C; | 
|  | A &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0xC3:                  /* LAD */ | 
|  | A = D; | 
|  | A &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0xC4:                  /* LAE */ | 
|  | A = E; | 
|  | A &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0xC5:                  /* LAH */ | 
|  | A = H; | 
|  | A &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0xC6:                  /* LAL */ | 
|  | A = L; | 
|  | A &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0xC7:                  /* LAM */ | 
|  | A = FETCH_M(); | 
|  | A &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0xC8:                  /* LBA */ | 
|  | B = A; | 
|  | B &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0xC9:                  /* LBB */ | 
|  | B = B; | 
|  | B &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0xCA:                  /* LBC */ | 
|  | B = C; | 
|  | B &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0xCB:                  /* LBD */ | 
|  | B = D; | 
|  | B &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0xCC:                  /* LBE */ | 
|  | B = E; | 
|  | B &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0xCD:                  /* LBH */ | 
|  | B = H; | 
|  | B &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0xCE:                  /* LBL */ | 
|  | B = L; | 
|  | B &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0xCF:                  /* LBM */ | 
|  | B = FETCH_M(); | 
|  | B &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0xD0:                  /* LCA */ | 
|  | C = A; | 
|  | C &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0xD1:                  /* LCB */ | 
|  | C = B; | 
|  | C &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0xD2:                  /* LCC */ | 
|  | C = C; | 
|  | C &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0xD3:                  /* LCD */ | 
|  | C = D; | 
|  | C &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0xD4:                  /* LCE */ | 
|  | C = E; | 
|  | C &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0xD5:                  /* LCH */ | 
|  | C = H; | 
|  | C &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0xD6:                  /* LCL */ | 
|  | C = L; | 
|  | C &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0xD7:                  /* LCM */ | 
|  | C = FETCH_M(); | 
|  | C &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0xD8:                  /* LDA */ | 
|  | D = A; | 
|  | D &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0xD9:                  /* LDB */ | 
|  | D = B; | 
|  | D &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0xDA:                  /* LDC */ | 
|  | D = C; | 
|  | D &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0xDB:                  /* LDD */ | 
|  | D = D; | 
|  | D &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0xDC:                  /* LDE */ | 
|  | D = E; | 
|  | D &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0xDD:                  /* LDH */ | 
|  | D = H; | 
|  | D &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0xDE:                  /* LDL */ | 
|  | D = L; | 
|  | D &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0xDF:                  /* LDM */ | 
|  | D = FETCH_M(); | 
|  | D &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0xE0:                  /* LEA */ | 
|  | E = A; | 
|  | E &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0xE1:                  /* LEB */ | 
|  | E = B; | 
|  | E &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0xE2:                  /* LEC */ | 
|  | E = C; | 
|  | E &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0xE3:                  /* LED */ | 
|  | E = D; | 
|  | E &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0xE4:                  /* LEE */ | 
|  | E = E; | 
|  | E &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0xE5:                  /* LEH */ | 
|  | E = H; | 
|  | E &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0xE6:                  /* LEL */ | 
|  | E = L; | 
|  | E &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0xE7:                  /* LEM */ | 
|  | E = FETCH_M(); | 
|  | E &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0xE8:                  /* LHA */ | 
|  | H = A; | 
|  | H &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0xE9:                  /* LHB */ | 
|  | H = B; | 
|  | H &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0xEA:                  /* LHC */ | 
|  | H = C; | 
|  | H &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0xEB:                  /* LHD */ | 
|  | H = D; | 
|  | H &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0xEC:                  /* LHE */ | 
|  | H = E; | 
|  | H &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0xED:                  /* LHH */ | 
|  | H = H; | 
|  | H &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0xEE:                  /* LHL */ | 
|  | H = L; | 
|  | H &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0xEF:                  /* LHM */ | 
|  | H = FETCH_M(); | 
|  | H &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0xF0:                  /* LLA */ | 
|  | L = A; | 
|  | L &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0xF1:                  /* LLB */ | 
|  | L = B; | 
|  | L &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0xF2:                  /* LLC */ | 
|  | L = C; | 
|  | L &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0xF3:                  /* LLD */ | 
|  | L = D; | 
|  | L &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0xF4:                  /* LLE */ | 
|  | L = E; | 
|  | L &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0xF5:                  /* LLH */ | 
|  | L = H; | 
|  | L &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0xF6:                  /* LLL */ | 
|  | L = L; | 
|  | L &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0xF7:                  /* LLM */ | 
|  | L = FETCH_M(); | 
|  | L &= BYTE_R; | 
|  | break; | 
|  |  | 
|  | case 0xF8:                  /* LMA */ | 
|  | store_m(A); | 
|  | break; | 
|  |  | 
|  | case 0xF9:                  /* LMB */ | 
|  | store_m(B); | 
|  | break; | 
|  |  | 
|  | case 0xFA:                  /* LMC */ | 
|  | store_m(C); | 
|  | break; | 
|  |  | 
|  | case 0xFB:                  /* LMD */ | 
|  | store_m(D); | 
|  | break; | 
|  |  | 
|  | case 0xFC:                  /* LME */ | 
|  | store_m(E); | 
|  | break; | 
|  |  | 
|  | case 0xFD:                  /* LMH */ | 
|  | store_m(H); | 
|  | break; | 
|  |  | 
|  | case 0xFE:                  /* LML */ | 
|  | store_m(L); | 
|  | break; | 
|  |  | 
|  | case 0xFF:                  /* LMM */ | 
|  | val = FETCH_M(); | 
|  | store_m(val); | 
|  | break; | 
|  |  | 
|  | default:                    /* undefined opcode */ | 
|  | if (i8008_unit.flags & UNIT_OPSTOP) { | 
|  | reason = STOP_OPCODE; | 
|  | PC--; | 
|  | } | 
|  | break; | 
|  | } | 
|  | } | 
|  |  | 
|  | /* Simulation halted */ | 
|  |  | 
|  | saved_PC = PC; | 
|  | return reason; | 
|  | } | 
|  |  | 
|  | /* store byte to (HL) */ | 
|  | void store_m(uint32 val) | 
|  | { | 
|  | DAR = (H << 8) + L; | 
|  | DAR &= WORD_R14; | 
|  | ret get_mword(DAR); | 
|  | } | 
|  |  | 
|  | /* get byte from (HL) */ | 
|  | uint32 fetch_m(void) | 
|  | { | 
|  | DAR = (H << 8) + L; | 
|  | DAR &= WORD_R14; | 
|  | put_mword(DAR, val); | 
|  | } | 
|  |  | 
|  | /* dump the registers */ | 
|  | void dumpregs(void) | 
|  | { | 
|  | sim_printf("  A=%02X B=%02X C=%02X D=%04X E=%02X H=%04X L=%02X\n", | 
|  | A, B, C, D, E, H, L); | 
|  | sim_printf("    CF=%d ZF=%d SF=%d PF=%d\n", | 
|  | CF, ZF, SF, PF); | 
|  | } | 
|  |  | 
|  | /* fetch an instruction or byte */ | 
|  | int32 fetch_byte(int32 flag) | 
|  | { | 
|  | uint32 val; | 
|  |  | 
|  | val = get_mbyte(PC) & 0xFF;         /* fetch byte */ | 
|  | if (i8008_dev.dctrl & DEBUG_asm || uptr->flags & UNIT_TRACE) {  /* display source code */ | 
|  | switch (flag) { | 
|  | case 0:                     /* opcode fetch */ | 
|  | sim_printf("OP=%02X        %04X %s", val,  PC, opcode[val]); | 
|  | break; | 
|  | case 1:                     /* byte operand fetch */ | 
|  | sim_printf("0%02XH", val); | 
|  | break; | 
|  | } | 
|  | } | 
|  | PC = (PC + 1) & ADDRMASK;           /* increment PC */ | 
|  | val &= BYTE_R; | 
|  | return val; | 
|  | } | 
|  |  | 
|  | /* fetch a word */ | 
|  | int32 fetch_word(void) | 
|  | { | 
|  | uint16 val; | 
|  |  | 
|  | val = get_mbyte(PC) & BYTE_R;       /* fetch low byte */ | 
|  | val |= get_mbyte(PC + 1) << 8;      /* fetch high byte */ | 
|  | if (i8008_dev.dctrl & DEBUG_asm || uptr->flags & UNIT_TRACE)   /* display source code */ | 
|  | sim_printf("0%04XH", val); | 
|  | PC = (PC + 2) & ADDRMASK;           /* increment PC */ | 
|  | val &= WORD_R14; | 
|  | return val; | 
|  | } | 
|  |  | 
|  | /* push a word to the stack frame */ | 
|  | void push_word(uint16 val) | 
|  | { | 
|  | stack_frame[SP] = val; | 
|  | SP++; | 
|  | if (SP == 8) | 
|  | SP = 0; | 
|  | } | 
|  |  | 
|  | /* pop a word from the stack frame */ | 
|  | uint16 pop_word(void) | 
|  | { | 
|  | SP--; | 
|  | if (SP < 0) | 
|  | SP = 7; | 
|  | return stack_frame[SP]; | 
|  | } | 
|  |  | 
|  |  | 
|  | /* Set the <C>arry, <S>ign, <Z>ero and <O>verflow flags following | 
|  | an operation on 'reg'. | 
|  | */ | 
|  |  | 
|  | void setflag4(int32 reg) | 
|  | { | 
|  | if (reg & 0x100) | 
|  | CF = 1; | 
|  | else | 
|  | CF = 0; | 
|  | if (reg & 0x80) | 
|  | SF = 0; | 
|  | else | 
|  | SF = 1; | 
|  | if ((reg & BYTE_R) == 0) | 
|  | ZF = 1; | 
|  | else | 
|  | ZF = 0; | 
|  | parity(reg); | 
|  | } | 
|  |  | 
|  | /* Set the <C>arry, <S>ign and <Z>ero flags following | 
|  | an operation on 'reg'. | 
|  | */ | 
|  |  | 
|  | void setflag3(int32 reg) | 
|  | { | 
|  | CF = 0; | 
|  | if (reg & 0x80) | 
|  | SF = 0; | 
|  | else | 
|  | SF = 1; | 
|  | if ((reg & BYTE_R) == 0) | 
|  | ZF = 1; | 
|  | else | 
|  | ZF = 0; | 
|  | parity(reg); | 
|  | } | 
|  |  | 
|  | /* Set the Parity (PF) flag based on parity of 'reg', i.e., number | 
|  | of bits on even: PF=1, else PF=0 | 
|  | */ | 
|  |  | 
|  | void parity(int32 reg) | 
|  | { | 
|  | int32 bc = 0; | 
|  |  | 
|  | if (reg & 0x01) bc++; | 
|  | if (reg & 0x02) bc++; | 
|  | if (reg & 0x04) bc++; | 
|  | if (reg & 0x08) bc++; | 
|  | if (reg & 0x10) bc++; | 
|  | if (reg & 0x20) bc++; | 
|  | if (reg & 0x40) bc++; | 
|  | if (reg & 0x80) bc++; | 
|  | if (bc & 0x01) | 
|  | PF = 0; | 
|  | else | 
|  | PF = 1; | 
|  | } | 
|  |  | 
|  |  | 
|  |  | 
|  | /* Reset routine */ | 
|  |  | 
|  | t_stat i8008_reset (DEVICE *dptr) | 
|  | { | 
|  | int i; | 
|  |  | 
|  | CF = SF = ZF = PF = 0; | 
|  | saved_PC = 0; | 
|  | int_req = 0; | 
|  | for (i = 0; i < 7; i++) | 
|  | stack_frame[i] = 0; | 
|  | sim_brk_types = sim_brk_dflt = SWMASK ('E'); | 
|  | sim_printf("   8008: Reset\n"); | 
|  | return SCPE_OK; | 
|  | } | 
|  |  | 
|  | /* Memory examine */ | 
|  |  | 
|  | t_stat i8008_ex (t_value *vptr, t_addr addr, UNIT *uptr, int32 sw) | 
|  | { | 
|  | if (addr >= MEMSIZE) | 
|  | return SCPE_NXM; | 
|  | if (vptr != NULL) | 
|  | *vptr = get_mbyte(addr); | 
|  | return SCPE_OK; | 
|  | } | 
|  |  | 
|  | /* Memory deposit */ | 
|  |  | 
|  | t_stat i8008_dep (t_value val, t_addr addr, UNIT *uptr, int32 sw) | 
|  | { | 
|  | if (addr >= MEMSIZE) | 
|  | return SCPE_NXM; | 
|  | put_mbyte(addr, val); | 
|  | return SCPE_OK; | 
|  | } | 
|  |  | 
|  | /* This is the binary loader.  The input file is considered to be | 
|  | a string of literal bytes with no special format. The load | 
|  | starts at the current value of the PC. | 
|  | */ | 
|  |  | 
|  | int32 sim_load (FILE *fileref, char *cptr, char *fnam, int flag) | 
|  | { | 
|  | int32 i, addr = 0, cnt = 0; | 
|  |  | 
|  | if ((*cptr != 0) || (flag != 0)) return SCPE_ARG; | 
|  | addr = saved_PC; | 
|  | while ((i = getc (fileref)) != EOF) { | 
|  | put_mbyte(addr, i); | 
|  | addr++; | 
|  | cnt++; | 
|  | }                                   /* end while */ | 
|  | sim_printf ("%d Bytes loaded.\n", cnt); | 
|  | return (SCPE_OK); | 
|  | } | 
|  |  | 
|  | /* Symbolic output | 
|  |  | 
|  | Inputs: | 
|  | *of   = output stream | 
|  | addr    =       current PC | 
|  | *val    =       pointer to values | 
|  | *uptr   =       pointer to unit | 
|  | sw      =       switches | 
|  | Outputs: | 
|  | status  =       error code | 
|  | */ | 
|  |  | 
|  | t_stat fprint_sym (FILE *of, t_addr addr, t_value *val, | 
|  | UNIT *uptr, int32 sw) | 
|  | { | 
|  | int32 cflag, c1, c2, inst, adr; | 
|  |  | 
|  | cflag = (uptr == NULL) || (uptr == &i8008_unit); | 
|  | c1 = (val[0] >> 8) & 0x7F; | 
|  | c2 = val[0] & 0x7F; | 
|  | if (sw & SWMASK ('A')) { | 
|  | fprintf (of, (c2 < 0x20)? "<%02X>": "%c", c2); | 
|  | return SCPE_OK; | 
|  | } | 
|  | if (sw & SWMASK ('C')) { | 
|  | fprintf (of, (c1 < 0x20)? "<%02X>": "%c", c1); | 
|  | fprintf (of, (c2 < 0x20)? "<%02X>": "%c", c2); | 
|  | return SCPE_OK; | 
|  | } | 
|  | if (!(sw & SWMASK ('M'))) return SCPE_ARG; | 
|  | inst = val[0]; | 
|  | fprintf (of, "%s", opcode[inst]); | 
|  | if (oplen[inst] == 2) { | 
|  | if (strchr(opcode[inst], ' ') != NULL) | 
|  | fprintf (of, ","); | 
|  | else fprintf (of, " "); | 
|  | fprintf (of, "%h", val[1]); | 
|  | } | 
|  | if (oplen[inst] == 3) { | 
|  | adr = val[1] & 0xFF; | 
|  | adr |= (val[2] << 8) & 0xff00; | 
|  | if (strchr(opcode[inst], ' ') != NULL) | 
|  | fprintf (of, ","); | 
|  | else fprintf (of, " "); | 
|  | fprintf (of, "%h", adr); | 
|  | } | 
|  | return -(oplen[inst] - 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 (char *cptr, t_addr addr, UNIT *uptr, t_value *val, int32 sw) | 
|  | { | 
|  | int32 cflag, i = 0, j, r; | 
|  | char gbuf[CBUFSIZE]; | 
|  |  | 
|  | cflag = (uptr == NULL) || (uptr == &i8008_unit); | 
|  | while (isspace (*cptr)) cptr++;                         /* absorb spaces */ | 
|  | if ((sw & SWMASK ('A')) || ((*cptr == '\'') && cptr++)) { /* ASCII char? */ | 
|  | if (cptr[0] == 0) return SCPE_ARG;                  /* must have 1 char */ | 
|  | val[0] = (uint32) cptr[0]; | 
|  | return SCPE_OK; | 
|  | } | 
|  | if ((sw & SWMASK ('C')) || ((*cptr == '"') && cptr++)) { /* ASCII string? */ | 
|  | if (cptr[0] == 0) return SCPE_ARG;                  /* must have 1 char */ | 
|  | val[0] = ((uint32) cptr[0] << 8) + (uint32) cptr[1]; | 
|  | return SCPE_OK; | 
|  | } | 
|  |  | 
|  | /* An instruction: get opcode (all characters until null, comma, | 
|  | or numeric (including spaces). | 
|  | */ | 
|  |  | 
|  | while (1) { | 
|  | if (*cptr == ',' || *cptr == '\0' || | 
|  | isdigit(*cptr)) | 
|  | break; | 
|  | gbuf[i] = toupper(*cptr); | 
|  | cptr++; | 
|  | i++; | 
|  | } | 
|  |  | 
|  | /* Allow for RST which has numeric as part of opcode */ | 
|  |  | 
|  | if (toupper(gbuf[0]) == 'R' && | 
|  | toupper(gbuf[1]) == 'S' && | 
|  | toupper(gbuf[2]) == 'T') { | 
|  | gbuf[i] = toupper(*cptr); | 
|  | cptr++; | 
|  | i++; | 
|  | } | 
|  |  | 
|  | /* kill trailing spaces if any */ | 
|  | gbuf[i] = '\0'; | 
|  | for (j = i - 1; gbuf[j] == ' '; j--) { | 
|  | gbuf[j] = '\0'; | 
|  | } | 
|  |  | 
|  | /* find opcode in table */ | 
|  | for (j = 0; j < 256; j++) { | 
|  | if (strcmp(gbuf, opcode[j]) == 0) | 
|  | break; | 
|  | } | 
|  | if (j > 255)                                            /* not found */ | 
|  | return SCPE_ARG; | 
|  |  | 
|  | val[0] = j;                                             /* store opcode */ | 
|  | if (oplen[j] < 2)                                       /* if 1-byter we are done */ | 
|  | return SCPE_OK; | 
|  | if (*cptr == ',') cptr++; | 
|  | cptr = get_glyph(cptr, gbuf, 0);                        /* get address */ | 
|  | sscanf(gbuf, "%o", &r); | 
|  | if (oplen[j] == 2) { | 
|  | val[1] = r & 0xFF; | 
|  | return (-1); | 
|  | } | 
|  | val[1] = r & 0xFF; | 
|  | val[2] = (r >> 8) & 0xFF; | 
|  | return (-2); | 
|  | } |