darcy@druid.uucp (D'Arcy J.M. Cain) (11/16/90)
#!/bin/sh # this is cpm.02 (part 2 of a multipart archive) # do not concatenate these parts, unpack them in order with /bin/sh # file cpm.c continued # if test ! -r _shar_seq_.tmp; then echo 'Please unpack part 1 first!' exit 1 fi (read Scheck if test "$Scheck" != 2; then echo Please unpack part "$Scheck" next! exit 1 else exit 0 fi ) < _shar_seq_.tmp || exit 1 sed 's/^X//' << 'SHAR_EOF' >> 'cpm.c' && X return(-1); X } X X def_drive = *entry; X strcpy(cpm_drive[0],cpm_drive[def_drive]); X entry[0] = entry[1] = ' '; X tail = chop_cmd(entry); X } X X if (*entry == 0) X return(0); X X debug(entry); X X if (strcmp(entry, "DIR") == 0) X fsystem("ls -C %s", tail); X else if (strcmp(entry, "DUMP") == 0) X fsystem("hd %s", tail); X else if (strcmp(entry, "ED") == 0) X fsystem("$EDITOR %s", tail); X else if (strcmp(entry, "ERA") == 0) X fsystem("rm %s", tail); #ifdef CPM_DEBUG X else if (strcmp(entry, "DASM") == 0) X { X if(++dasm_flag > 2) X dasm_flag = 0; X X fprintf(stderr, "DASM is %d\r\n", dasm_flag); X } #endif X else if (strcmp(entry, "SAVE") == 0) X { X char *fname = chop_cmd(tail); X int p = atoi(tail); X X if ((p == 0) || (*fname == 0)) X fprintf(stderr, "Usage: SAVE #pages filename\r\n"); X else X { X if ((fp = fopen(real_name(fname), "wb")) == NULL) X perror("\aCan't open save file"); X else X { X if (fwrite(ram + 256, 256, p, fp) != p) X perror("\aCan't write to file"); X X fclose(fp); X } X } X } X else if (strcmp(entry, "TYPE") == 0) X { X char *ptr; X X while (*tail) X { X ptr = tail; X tail = chop_cmd(ptr); X fsystem("cat %s", ptr); X } X } X else if (strcmp(entry, "EXIT") == 0) X cleanup(0); X else #ifdef CPM_DEBUG X { X time_t start = time(NULL); X int r = run(real_name(entry)); X X fprintf(stderr, "Run took %ld seconds\n\r", time(NULL) - start); X return(r); X } #else X return(run(real_name(entry))); #endif X X return(0); } #endif X void main(int argc, char **argv) { #ifdef COMPILE_TEST X /* test code useful for testing different architectures */ X int test; X X test = (int)(&acc); X printf("Position of A = %d\n", (int)(&A) - test); X printf("Position of FLAGS = %d\n", (int)(&FLAGS) - test); X X test = (int)(&gr); X printf("Position of B = %d\n", (int)(&B) - test); X printf("Position of C = %d\n", (int)(&C) - test); X printf("Position of BC = %d\n", (int)(&BC) - test); X printf("Position of D = %d\n", (int)(&D) - test); X printf("Position of E = %d\n", (int)(&E) - test); X printf("Position of DE = %d\n", (int)(&DE) - test); X printf("Position of H = %d\n", (int)(&H) - test); X printf("Position of L = %d\n", (int)(&L) - test); X printf("Position of HL = %d\n", (int)(&HL) - test); X X AF = 0x1234; X printf("AF = %04.4x, A = %02.2x, FLAGS = %02.2x\n", AF, A, FLAGS); X printf("Flags: S=%d Z=%d H=%d P=%d N=%d C=%d\n", X SIGN, ZERO, HALF_CARRY, PARITY, BCD, CARRY); X acc_bank = 1; X AF = 0x4321; X printf("AF = %04.4x, A = %02.2x, FLAGS = %02.2x\n", AF, A, FLAGS); X printf("Flags: S=%d Z=%d H=%d P=%d N=%d C=%d\n", X SIGN, ZERO, HALF_CARRY, PARITY, BCD, CARRY); X X BC = 0x2345; X printf("BC = %04.4x, B = %02.2x, C = %02.2x\n", BC, B, C); X gr_bank = 1; X BC = 0x5432; X printf("BC = %04.4x, B = %02.2x, C = %02.2x\n", BC, B, C); X gr_bank = 0; X X DE = 0x3456; X printf("DE = %04.4x, D = %02.2x, E = %02.2x\n", DE, D, E); X gr_bank = 1; X DE = 0x6543; X printf("DE = %04.4x, D = %02.2x, E = %02.2x\n", DE, D, E); X gr_bank = 0; X X HL = 0x4567; X printf("HL = %04.4x, H = %02.2x, L = %02.2x\n", HL, H, L); X gr_bank = 1; X HL = 0x7654; X printf("HL = %04.4x, H = %02.2x, L = %02.2x\n", HL, H, L); X gr_bank = 0; X X A = BC = DE = HL = SP = PC = 0; X X while (PC < TEST_SIZE) X { X dump_registers(stdout); X X if (decode()) X { X printf("* * * Processor error * * *\n"); X exit(1); X } X } X X dump_registers(stdout); X X for (test = 0; test < 0x10; test++) X printf("%02.2x ", ram[test]); X X printf("\n"); X for (test = 0xfff0; test < 0x10000; test++) X printf("%02.2x ", ram[test]); X X printf("\nTest code ended normally\n"); X exit(0); #else X X char entry[256]; X int c; X X getcwd(cpm_drive[1], 127); X entry[0] = 0; X debug(""); X X while ((c = getopt(argc, argv, "d:c:r:p:h")) != -1) X { X char *ptr; X int k; X X switch (c) X { X case 'd': X ptr = optarg + 2; X X if (optarg[1] == ':') X k = toupper(*optarg) - '@'; X else X { X k = 1; X ptr = optarg; X X while ((k < 17) && (*cpm_drive[k])) X k++; X } X X if ((k < 1) || (k > 16)) X { X fprintf(stderr, "Can't set up %s\n", optarg); X exit(1); X } X X strcpy(cpm_drive[k], ptr); X break; X X case 'c': X strcpy(entry, optarg); X break; X X case 'r': X reader = open_device(optarg, "r"); X break; X X case 'p': X punch = open_device(optarg, "w"); X break; X X case 'l': X list = open_device(optarg, "w"); X break; X X default: X fprintf(stderr, "Usage:\n"); X fprintf(stderr, "cpm [options]\n"); X fprintf(stderr, " Options:\n"); X fprintf(stderr, " -d [d:]directory map CP/M drive to Unix directory. If the\n"); X fprintf(stderr, " second character is not a colon then the next\n"); X fprintf(stderr, " available drive letter is used otherwise the\n"); X fprintf(stderr, " letter preceding the colon is used.\n"); X fprintf(stderr, " -c command runs the command file then exits. builtins\n"); X fprintf(stderr, " not supported. COM file must exist\n"); X fprintf(stderr, " -[r|p|l] dev This allows the I/O to be routed through the\n"); X fprintf(stderr, " Unix file system. The devices mapped are as\n"); X fprintf(stderr, " follows: r = RDR input, p = PUN output and l for\n"); X fprintf(stderr, " LST output. The dev argument is opened as a Unix\n"); X fprintf(stderr, " file and I/O for specified device is done through\n"); X fprintf(stderr, " it. If the first character is '!' then the rest\n"); X fprintf(stderr, " of the line is taken as a command and popen() is\n"); X fprintf(stderr, " called to handle the I/O.\n"); X fprintf(stderr, " -h Show this help screen\n"); X X exit(1); X } X } X X strcpy(cpm_drive[0], cpm_drive[1]); X def_drive = 1; X X if ((console = open("/dev/tty", O_RDWR)) == -1) X { X perror("Can't open terminal"); X exit(1); X } X X if (ioctl(console, TCGETA, &old_term) == -1) X { X perror("Can't get terminal parameters"); X exit(-1); X } X X termp = old_term; X termp.c_oflag = 0; X termp.c_lflag = ISIG; X termp.c_cc[VEOF] = 1; X termp.c_cc[VSWTCH] = 0xff; X X if (ioctl(console, TCSETA, &termp) == -1) X { X perror("Can't set terminal parameters"); X exit(1); X } X X signal(SIGHUP, cleanup); X signal(SIGINT, cleanup); X signal(SIGQUIT, cleanup); X signal(SIGTERM, cleanup); X debug("Signals captured"); X X setbuf(stdout, NULL); X X fprintf(stderr, "\nCP/U - Control Program for Unix\r\n"); X fprintf(stderr, "CP/M emulator Version 0.900\r\n"); X fprintf(stderr, "Written by D'Arcy J.M. Cain\r\n"); X fprintf(stderr, "darcy@druid.UUCP\r\n"); X X if (*entry) X { X do_command(entry); X ioctl(console, TCSETA, &old_term); X exit(0); X } X X debug("Start main loop"); X X for (;;) X { X fprintf(stderr, "%c> ", def_drive + '@'); X entry[get_str(entry, 128)] = 0; X X if (*entry) X { X if (do_command(entry) == -1) X { X debug("chop_cmd(entry)"); X chop_cmd(entry); X debug("strtoup(entry)"); X strtoup(entry); X debug("fprintf(stderr, \"%s?\r\n\", entry)"); X fprintf(stderr, "%s?\r\n", entry); X } X } X } #endif } SHAR_EOF chmod 0640 cpm.c || echo 'restore of cpm.c failed' Wc_c="`wc -c < 'cpm.c'`" test 26758 -eq "$Wc_c" || echo 'cpm.c: original size 26758, current size' "$Wc_c" # ============= dasm.c ============== sed 's/^X//' << 'SHAR_EOF' > 'dasm.c' && /* dasm X CP/M emulator - instruction disassembler Written by D'Arcy J.M. Cain darcy@druid X */ X #include <stdio.h> #include <string.h> #include "cpm.h" X #define get_prog_word(buf) (buf[1] + (buf[2] << 8)) #define get_prog_byte(buf) (*buf) X static char *get_b_reg(int reg) { X switch(reg & 0x07) X { X case 7: return("A"); X case 6: return("(HL)"); X case 0: return("B"); X case 1: return("C"); X case 2: return("D"); X case 3: return("E"); X case 4: return("H"); X case 5: return("L"); X } X X return(NULL); } X static char *get_w_reg(int reg) { X switch (reg & 0x03) X { X case 2: return("HL"); X case 1: return("DE"); X case 0: return("BC"); X case 3: return("SP"); X } X X return(NULL); } X static char *get_s_reg(int reg) { X switch (reg & 0x03) X { X case 2: return("HL"); X case 1: return("DE"); X case 0: return("BC"); X case 3: return("AF"); X } X X return(NULL); } X static int relative(int r) { X if (r & 0x80) X r |= -256; X X return(PC + r + 2); } X static char *condition(int word) { X switch (word & 0x07) X { X case 0: return("NZ"); X case 1: return("Z"); X case 2: return("NC"); X case 3: return("C"); X case 4: return("PO"); X case 5: return("PE"); X case 6: return("P"); X case 7: return("M"); X } X X return("\a* * * Internal error (condition()) * * *"); } X const char *dasm(const byte *buf) { X static char str[32]; X char s[32]; X X switch (*buf & 0xc0) /* get class of opcode */ X { X case 0x40: /* data transfer */ X if (*buf == 0x76) /* HALT - special case */ X return("HALT"); X X sprintf(str, "LD\t%s, %s", get_b_reg(*buf >> 3), get_b_reg(*buf)); X return(str); X X case 0x80: /* 8 bit math & logic */ X strcpy(s, get_b_reg(*buf)); X strcpy(str, "* * * Internal error * * *"); X math_immediate: /* comes from misc instructions */ X switch ((*buf >> 3) & 7) /* logic op */ X { X case 1: /* ADC */ X sprintf(str, "ADC\tA, %s", s); X break; X X case 0: /* ADD */ X sprintf(str, "ADD\tA, %s", s); X break; X X case 3: /* SBC */ X sprintf(str, "SBC\tA, %s", s); X break; X X case 2: /* SUB */ X sprintf(str, "SUB\tA, %s", s); X break; X X case 4: /* AND */ X sprintf(str, "AND\tA, %s", s); X break; X X case 5: /* XOR */ X sprintf(str, "XOR\tA, %s", s); X break; X X case 6: /* OR */ X sprintf(str, "OR\tA, %s", s); X break; X X case 7: /* CP */ X sprintf(str, "CP\tA, %s", s); X break; X } /* end - logic op */ X X return(str); X X case 0xc0: /* Misc */ X if ((*buf & 0x07) == 0x06) X { X sprintf(s, "0%02.2xH", buf[1]); X goto math_immediate; /* sometimes they're necessary */ X } X X if ((*buf & 0x0f) == 1) /* POP */ X { X sprintf(str, "POP\t%s", get_s_reg(*buf >> 4)); X return(str); X } X X if ((*buf & 0x0f) == 5) /* PUSH */ X { X sprintf(str, "PUSH\t%s", get_s_reg(*buf >> 4)); X return(str); X } X X X switch (*buf & 0x07) /* BRANCH */ X { X case 0: /* RET cc */ X sprintf(str, "RET\t%s", condition(*buf >> 3)); X return(str); X X case 2: /* JP cc */ X sprintf(str, "JP\t%s, 0%02.2x%02.2xH", X condition(*buf >> 3), buf[2], buf[1]); X return(str); X X case 4: /* CALL cc */ X sprintf(str, "CALL\t%s, 0%02.2x%02.2xH", X condition(*buf >> 3), buf[2], buf[1]); X return(str); X X case 7: /* RST n */ X sprintf(str, "RST\t%d", (*buf >> 3) & 0x07); X return(str); X } /* end - BRANCH */ X X switch (*buf) /* misc */ X { X case 0xcd: /* CALL */ X sprintf(str, "CALL\t0%02.2x%02.2xH", buf[2], buf[1]); X return(str); X X case 0xc3: /* JP */ X sprintf(str, "JP\t0%02.2x%02.2xH", buf[2], buf[1]); X return(str); X X case 0xc9: /* RET */ X sprintf(str, "RET"); X return(str); X X case 0xeb: /* EX DE, HL */ X return("EX\tDE, HL"); X X case 0xe9: /* JP (HL) */ X return("JP\t(HL)"); X X case 0xe3: /* EX (SP), HL */ X return("EX\t(SP), HL"); X X case 0xf9: /* LD SP, HL */ X return("LD\tSP, HL"); X X case 0xf3: /* DI */ X return("DI"); X X case 0xfb: /* EI */ X return("EI"); X } /* misc */ X X sprintf(str, "Unrecognized command (0x%02.2x)", *buf); X return(str); X X case 0: X switch (*buf & 0x07) /* misc data (3) */ X { X case 4: /* INC byte */ X sprintf(str, "INC\t%s", get_b_reg(*buf >> 3)); X return(str); X X case 5: /* DEC byte */ X sprintf(str, "DEC\t%s", get_b_reg(*buf >> 3)); X return(str); X X case 6: /* LD byte immediate */ X sprintf(str, "LD\t%s, 0%02.2xH", X get_b_reg(*buf >> 3), buf[1]); X return(str); X } /* end - misc data (3) */ X X switch (*buf & 0x0f) /* misc data (4) */ X { X case 1: /* LD word immediate */ X sprintf(str, "LD\t%s, 0%02.2x%02.2xH", X get_w_reg(*buf >> 4), buf[2], buf[1]); X return(str); X X case 0x03: /* INC word */ X sprintf(str, "INC\t%s", get_w_reg(*buf >> 4)); X return(str); X X case 0x0b: /* DEC word */ X sprintf(str, "DEC\t%s", get_w_reg(*buf >> 4)); X return(str); X X case 0x09: /* ADD HL, ss */ X sprintf(str, "ADD\tHL, %s", get_w_reg(*buf >> 4)); X return(str); X } /* end - misc date (4) */ X X switch (*buf) /* misc data */ X { X case 0: /* NOP */ X return("NOP"); X X case 0x02: /* LD (BC), A */ X return("LD\t(BC), A"); X X case 0x10: X sprintf(str, "DJNZ\t0%04.4xH", relative(buf[1])); X return(str); X X case 0x20: X sprintf(str, "JR\tNZ, 0%04.4xH", relative(buf[1])); X return(str); X X case 0x30: X sprintf(str, "JR\tNC, 0%04.4xH", relative(buf[1])); X return(str); X X case 0x18: X sprintf(str, "JR\t, 0%04.4xH", relative(buf[1])); X return(str); X X case 0x28: X sprintf(str, "JR\tZ, 0%04.4xH", relative(buf[1])); X return(str); X X case 0x38: X sprintf(str, "JR\tC, 0%04.4xH", relative(buf[1])); X return(str); X X case 0x12: /* LD (DE), A */ X return("LD\t(DE), A"); X X case 0x22: /* LD (nn), HL */ X sprintf(str, "LD\t(0%02.2x%02.2xH), HL", buf[2], buf[1]); X return(str); X X case 0x32: /* LD (nn), A */ X sprintf(str, "LD\t(0%02.2x%02.2xH), A", buf[2], buf[1]); X return(str); X X case 0x0a: /* LD A, (BC) */ X return("LD\tA, (BC)"); X X case 0x1a: /* LD A, (DE) */ X return("LD\tA, (DE)"); X X case 0x2a: /* LD HL, (nn) */ X sprintf(str, "LD\tHL, (0%02.2x%02.2xH)", buf[2], buf[1]); X return(str); X X case 0x3a: /* LD A, (nn) */ X sprintf(str, "LD\tA, (0%02.2x%02.2xH)", buf[2], buf[1]); X return(str); X X case 7: /* RLCA */ X return("RLCA"); X X case 0x0f: /* RRCA */ X return("RRCA"); X X case 0x17: /* RLA */ X return("RLA"); X X case 0x1f: /* RRA */ X return("RRA"); X X case 0x27: /* DAA */ X return("DAA"); X X case 0x2f: /* CPL */ X return("CPL"); X X case 0x37: /* SCF */ X return("SCF"); X X case 0x3f: /* CCF */ X return("CCF"); X } /* end - misc date */ X X return("* * * Internal error * * *"); X } /* end class */ X X return("* * * Internal error * * *"); } SHAR_EOF chmod 0640 dasm.c || echo 'restore of dasm.c failed' Wc_c="`wc -c < 'dasm.c'`" test 7099 -eq "$Wc_c" || echo 'dasm.c: original size 7099, current size' "$Wc_c" # ============= decode.c ============== sed 's/^X//' << 'SHAR_EOF' > 'decode.c' && /* X * execute() X * X * There are 256 possible opcodes. The switch statement selects one. X * $Header: /g/zmob/zrun/RCS/execute.c,v 1.1.1.5 84/04/19 17:51:14 bennet Exp $ X */ X #include "cpm.h" X static byte partab[256]= /* Parity table, 1=even */ { X 1,0,0,1,0,1,1,0, 0,1,1,0,1,0,0,1, X 0,1,1,0,1,0,0,1, 1,0,0,1,0,1,1,0, X 0,1,1,0,1,0,0,1, 1,0,0,1,0,1,1,0, X 1,0,0,1,0,1,1,0, 0,1,1,0,1,0,0,1, X 0,1,1,0,1,0,0,1, 1,0,0,1,0,1,1,0, X 1,0,0,1,0,1,1,0, 0,1,1,0,1,0,0,1, X 1,0,0,1,0,1,1,0, 0,1,1,0,1,0,0,1, X 0,1,1,0,1,0,0,1, 1,0,0,1,0,1,1,0, X 0,1,1,0,1,0,0,1, 1,0,0,1,0,1,1,0, X 1,0,0,1,0,1,1,0, 0,1,1,0,1,0,0,1, X 1,0,0,1,0,1,1,0, 0,1,1,0,1,0,0,1, X 0,1,1,0,1,0,0,1, 1,0,0,1,0,1,1,0, X 1,0,0,1,0,1,1,0, 0,1,1,0,1,0,0,1, X 0,1,1,0,1,0,0,1, 1,0,0,1,0,1,1,0, X 0,1,1,0,1,0,0,1, 1,0,0,1,0,1,1,0, X 1,0,0,1,0,1,1,0, 0,1,1,0,1,0,0,1, }; X static byte setmask[] = { 1, 2, 4, 8, 16, 32, 64, 128 }; static byte resmask[] = { ~1, ~2, ~4, ~8, ~16, ~32, ~64, ~128 }; X int pop(void) { X long r = ram[SP++]; X return(r + (ram[SP++] << 8)); } X void push(int v) { X ram[--SP] = v >> 8; X ram[--SP] = v & 0xff; } X int decode(void) { X byte *ptr; X long a, s, s1; X byte opcode = ram[PC++]; X X if (PC >= BDOS) X { X PC = pop(); X return(0); X } X X switch(opcode) X { X case 0: /* 00 NOP */ X when 1: /* 01 LD BC,nn */ X C = ram[PC++]; X B = ram[PC++]; X when 2: /* 02 LD (BC),A */ X ram[BC] = A; X when 3: /* 03 INC BC */ X ++BC; X when 4: /* 04 INC B */ X HALF_CARRY = (lonyb(B) == 0xf); X ++B; X SIGN = B >> 7; X ZERO = B == 0; X PARITY = B == 0x80; X BCD = 0; X when 5: /* 05 DEC B */ X HALF_CARRY = lonyb(B) != 0; X --B; X SIGN = B >> 7; X ZERO = B == 0; X PARITY = B == 0x7f; X BCD = 1; X when 6: /* 06 LD B,n */ X B = ram[PC++]; X when 7: /* 07 RLCA */ X HALF_CARRY = BCD = 0; X CARRY = A >> 7; X A = (A << 1); X if (CARRY) ++A; X when 8: /* 08 EX AF,AF' */ X acc_bank = acc_bank ? 0 : 1; X when 9: /* 09 ADD HL,BC */ X s = BC; X a = (HL & 0xfff) + (s & 0xfff); X s += HL; X HL = s; X BCD = 0; X CARRY = s >> 16; X HALF_CARRY = a >> 12; X when 10: /* 0a LD A,(BC) */ X A = ram[BC]; X when 11: /* 0b DEC BC */ X --BC; X when 12: /* 0c INC C */ X HALF_CARRY = lonyb(C) == 0xf; X ++C; X SIGN = C >> 7; X ZERO = C == 0; X PARITY = C == 0x80; X BCD = 0; X when 13: /* 0d DEC C */ X HALF_CARRY = lonyb(C) != 0; X --C; X SIGN = C >> 7; X ZERO = C == 0; X PARITY = C == 0x7f; X BCD = 1; X when 14: /* 0e LD C,n */ X C = ram[PC++]; X when 15: /* 0f RRCA */ X BCD = HALF_CARRY = 0; X CARRY = A; X A = (A >> 1) | (CARRY ? 128 : 0); X when 16: /* 10 DJNZ e */ X s = (int)(ram[PC++]); X if (--B) PC += s; X when 17: /* 11 LD DE,nn */ X E = ram[PC++]; X D = ram[PC++]; X when 18: /* 12 LD (DE),A */ X ram[DE] = A; X when 19: /* 13 INC DE */ X ++DE; X when 20: /* 14 INC D */ X HALF_CARRY = lonyb(D) == 0xf; X ++D; X SIGN = D >> 7; X ZERO = D == 0; X PARITY = D == 0x80; X BCD = 0; X when 21: /* 15 DEC D */ X HALF_CARRY = lonyb(D) != 0; X --D; X SIGN = D >> 7; X ZERO = D == 0; X PARITY = D == 0x7f; X BCD = 1; X when 22: /* 16 LD D,n */ X D = ram[PC++]; X when 23: /* 17 RLA */ X s = A << 1; X A = s | CARRY; X CARRY = s >> 8; X BCD = HALF_CARRY = 0; X when 24: /* 18 JR e */ X PC += (int)(ram[PC]); X when 25: /* 19 ADD HL,DE */ X s = DE; X a = (HL & 0xfff) + (s & 0xfff); X s += HL; X HL = s; X BCD = 0; X CARRY = s >> 16; X HALF_CARRY = a >> 12; X when 26: /* 1a LD A,(DE) */ X A = ram[DE]; X when 27: /* 1b DEC DE */ X --DE; X when 28: /* 1c INC E */ X HALF_CARRY = lonyb(E) == 0xf; X ++E; X SIGN = E >> 7; X ZERO = E == 0; X PARITY = E == 0x80; X BCD = 0; X when 29: /* 1d DEC E */ X HALF_CARRY = lonyb(E) != 0; X --E; X SIGN = E >> 7; X ZERO = E == 0; X PARITY = E == 0x7f; X BCD = 1; X when 30: /* 1e LD E,n */ X E = ram[PC++]; X when 31: /* 1f RRA */ X CARRY = (s = A | (CARRY << 8)); X A = s >> 1; X BCD = HALF_CARRY = 0; X when 32: /* 20 JR NZ,e */ X if (ZERO) ++PC; X else PC += (int)(ram[PC]); X when 33: /* 21 LD HL,nn */ X L = ram[PC++]; X H = ram[PC++]; X when 34: /* 22 LD (nn),HL */ X TEMPL = ram[PC++]; X TEMPH = ram[PC++]; X ram[TEMP] = L; X ram[TEMP + 1] = H; X when 35: /* 23 INC HL */ X ++HL; X when 36: /* 24 INC H */ X HALF_CARRY = lonyb(H) == 0xf; X ++H; X SIGN = H >> 7; X ZERO = H == 0; X PARITY = H == 0x80; X BCD = 0; X when 37: /* 25 DEC H */ X HALF_CARRY = lonyb(H) != 0; X --H; X SIGN = H >> 7; X ZERO = H == 0; X PARITY = H == 0x7f; X BCD = 1; X when 38: /* 26 LD H,n */ X H = ram[PC++]; X when 39: /* 27 DAA */ X s = A & 0x0f; X a = (A >> 4) & 0x0f; X s1 = 0; X X if (BCD) X { X if (CARRY) X { X if (HALF_CARRY) X s1 = ((a > 5) && (s > 5)) ? 0x9a : 0; X else X s1 = ((a > 6) && (s < 10)) ? 0xa0 : 0; X } X else X if(HALF_CARRY) X s1 = ((a < 9) && (s > 5)) ? 0xfa : 0; X } X else X { X if (CARRY) X { X if(HALF_CARRY) X s1 = ((a < 4) && (s < 4)) ? 0x66 : 0; X else if (a < 3) X s1 = (s < 10) ? 0x60 : 0x66; X } X else X { X if(HALF_CARRY) X { X if (s < 4) X if (a > 9) X { X s1 = 0x66; X CARRY = 1; X } X else s1 = 0x06; X } X else X { X if ((a > 8) && (s > 9)) X { X s1 = 0x66; X CARRY = 1; X } X else if ((a > 9) && (s < 10)) X { X s1 = 0x60; X CARRY = 1; X } X else if ((a < 10) && (s < 10)) X ; X else if ((a < 9) && (s > 9)) X s1 = 6; X } X } X } X X HALF_CARRY = ((int)(A) + (int)(s1)) > 0xf; X A += s1; X SIGN = A >> 7; X ZERO = (A == 0); X PARITY = partab[A]; X when 40: /* 28 JR Z,e */ X if (ZERO) PC += (int)(ram[PC]); X else ++PC; X when 41: /* 29 ADD HL,HL */ X s = HL; X a = (HL & 0xfff) + (s & 0xfff); X s += HL; X HL = s; X BCD = 0; X CARRY = s >> 16; X HALF_CARRY = a >> 12; X when 42: /* 2a LD HL,(nn) */ X TEMPL = ram[PC++]; X TEMPH = ram[PC++]; X L = ram[TEMP]; X H = ram[TEMP + 1]; X when 43: /* 2b DEC HL */ X --HL; X when 44: /* 2c INC L */ X HALF_CARRY = lonyb(L) == 0xf; X ++L; X SIGN = L >> 7; X ZERO = L == 0; X PARITY = L == 0x80; X BCD = 0; X when 45: /* 2d DEC L */ X HALF_CARRY = lonyb(L) != 0; X --L; X SIGN = L >> 7; X ZERO = L == 0; X PARITY = L == 0x7f; X BCD = 1; X when 46: /* 2e LD L,n */ X L = ram[PC++]; X when 47: /* 2f CPL */ X A = ~A; X HALF_CARRY = BCD = 1; X when 48: /* 30 JR NC,e */ X if(CARRY) ++PC; X else PC += (int)(ram[PC]); X when 49: /* 31 LD SP,nn */ X SPL = ram[PC++]; X SPH = ram[PC++]; X when 50: /* 32 LD (nn),A */ X TEMPL = ram[PC++]; X TEMPH = ram[PC++]; X ram[TEMP] = A; X when 51: /* 33 INC SP */ X ++SP; X when 52: /* 34 INC (HL) */ X HALF_CARRY = lonyb(ram[HL]) == 0xf; X ++ram[HL]; X SIGN = ram[HL] >> 7; X ZERO = ram[HL] == 0; X PARITY = ram[HL] == 0x80; X BCD = 0; X when 53: /* 35 DEC (HL) */ X HALF_CARRY = lonyb(ram[HL]) != 0; X --ram[HL]; X SIGN = ram[HL] >> 7; X ZERO = ram[HL] == 0; X PARITY = ram[HL] == 0x7f; X BCD = 1; X when 54: /* 36 LD (HL),n */ X ram[HL] = ram[PC++]; X when 55: /* 37 SCF */ X HALF_CARRY = BCD = 0; X CARRY = 1; X when 56: /* 38 JR C,e */ X if (CARRY) PC += (int)(ram[PC]); X else ++PC; X when 57: /* 39 ADD HL,SP */ X s = SP; X a = (HL & 0xfff) + (s & 0xfff); X s += HL; X HL = s; X BCD = 0; X CARRY = s >> 16; X HALF_CARRY = a >> 12; X when 58: /* 3a LD A,(nn) */ X TEMPL = ram[PC++]; X TEMPH = ram[PC++]; X A = ram[TEMP]; X when 59: /* 3b DEC SP */ X --SP; X when 60: /* 3c INC A */ X HALF_CARRY = lonyb(A) == 0xf; X ++A; X SIGN = A >> 7; X ZERO = A == 0; X PARITY = A == 0x80; X BCD = 0; X when 61: /* 3d DEC A */ X HALF_CARRY = lonyb(A) != 0; X --A; X SIGN = A >> 7; X ZERO = A == 0; X PARITY = A == 0x7f; X BCD = 1; X when 62: /* 3e LD A,n */ X A = ram[PC++]; X when 63: /* 3f CCF */ X HALF_CARRY = CARRY; X CARRY = ~CARRY; X BCD = 0; X when 64: /* 40 LD B,B */ X when 65: /* 41 LD B,C */ X B = C; X when 66: /* 42 LD B,D */ X B = D; X when 67: /* 43 LD B,E */ X B = E; X when 68: /* 44 LD B,H */ X B = H; X when 69: /* 45 LD B,L */ X B = L; X when 70: /* 46 LD B, (HL) */ X B = ram[HL]; X when 71: /* 47 LD B,A */ X B = A; X when 72: /* 48 LD C,B */ X C = B; X when 73: /* 49 LD C,C */ X when 74: /* 4a LD C,D */ X C = D; X when 75: /* 4b LD C,E */ X C = E; X when 76: /* 4c LD C,H */ X C = H; X when 77: /* 4d LD C,L */ X C = L; X when 78: /* 4e LD C, (HL) */ X C = ram[HL]; X when 79: /* 4f LD C,A */ X C = A; X when 80: /* 50 LD D,B */ X D = B; X when 81: /* 51 LD D,C */ X D = C; X when 82: /* 52 LD D,D */ X when 83: /* 53 LD D,E */ X D = E; X when 84: /* 54 LD D,H */ X D = H; X when 85: /* 55 LD D,L */ X D = L; X when 86: /* 56 LD D, (HL) */ X D = ram[HL]; X when 87: /* 57 LD D,A */ X D = A; X when 88: /* 58 LD E,B */ X E = B; X when 89: /* 59 LD E,C */ X E = C; X when 90: /* 5a LD E,D */ X E = D; X when 91: /* 5b LD E,E */ X when 92: /* 5c LD E,H */ X E = H; X when 93: /* 5d LD E,L */ X E = L; X when 94: /* 5e LD E, (HL) */ X E = ram[HL]; X when 95: /* 5f LD E,A */ X E = A; X when 96: /* 60 LD H,B */ X H = B; X when 97: /* 61 LD H,C */ X H = C; X when 98: /* 62 LD H,D */ X H = D; X when 99: /* 63 LD H,E */ X H = E; X when 100: /* 64 LD H,H */ X when 101: /* 65 LD H,L */ X H = L; X when 102: /* 66 LD H, (HL) */ X H = ram[HL]; X when 103: /* 67 LD H,A */ X H = A; X when 104: /* 68 LD L,B */ X L = B; X when 105: /* 69 LD L,C */ X L = C; X when 106: /* 6a LD L,D */ X L = D; X when 107: /* 6b LD L,E */ X L = E; X when 108: /* 6c LD L,H */ X L = H; X when 109: /* 6d LD L,L */ X when 110: /* 6e LD L,(HL) */ X L = ram[HL]; X when 111: /* 6f LD L,A */ X L = A; X when 112: /* 70 LD (HL),B */ X ram[HL] = B; X when 113: /* 71 LD (HL),C */ X ram[HL] = C; X when 114: /* 72 LD (HL),D */ X ram[HL] = D; X when 115: /* 73 LD (HL),E */ X ram[HL] = E; X when 116: /* 74 LD (HL),H */ X ram[HL] = H; X when 117: /* 75 LD (HL),L */ X ram[HL] = L; X when 118: /* 76 HALT */ X return(0x76); X when 119: /* 77 LD (HL),A */ X ram[HL] = A; X when 120: /* 78 LD A,B */ X A = B; X when 121: /* 79 LD A,C */ X A = C; X when 122: /* 7a LD A,D */ X A = D; X when 123: /* 7b LD A,E */ X A = E; X when 124: /* 7c LD A,H */ X A = H; X when 125: /* 7d LD A,L */ X A = L; X when 126: /* 7e LD A,(HL) */ X A = ram[HL]; X when 127: /* 7f LD A,A */ X when 128: /* 80 ADD A,B */ X s = B; X goto add; X case 129: /* 81 ADD A,C */ X s = C; X goto add; X case 130: /* 82 ADD A,D */ X s = D; X goto add; X case 131: /* 83 ADD A,E */ X s = E; X goto add; X case 132: /* 84 ADD A,H */ X s = H; X goto add; X case 133: /* 85 ADD A,L */ X s = L; X goto add; X case 134: /* 86 ADD A,(HL) */ X s = ram[HL]; X goto add; X case 135: /* 87 ADD A,A */ X s = A; X goto add; X case 136: /* 88 ADC A,B */ X s = B; X goto adc; X case 137: /* 89 ADC A,C */ X s = C; X goto adc; X case 138: /* 8a ADC A,D */ X s = D; X goto adc; X case 139: /* 8b ADC A,E */ X s = E; X goto adc; X case 140: /* 8c ADC A,H */ X s = H; X goto adc; X case 141: /* 8d ADC A,L */ X s = L; X goto adc; X case 142: /* 8e ADC A,(HL) */ X s = ram[HL]; X goto adc; X case 143: /* 8f ADC A,A */ X s = A; X adc: X a = A & 0x0f; X s1 = s & 0x0f; X if (CARRY) { s++; a++; } X goto add1; X add: X a = A & 0x0f; X s1 = s & 0x0f; X add1: X BCD = 0; X s += A; X A = s; X a += s1; X set_flags: X CARRY = s >> 8; X HALF_CARRY = a >> 4; X SIGN = s >> 7; X ZERO = s ? 0 : 1; X PARITY = partab[A]; X X when 144: /* 90 SUB A,B */ X s = B; X goto sub; X case 145: /* 91 SUB A,C */ X s = C; X goto sub; X case 146: /* 92 SUB A,D */ X s = D; X goto sub; X case 147: /* 93 SUB A,E */ X s = E; X goto sub; X case 148: /* 94 SUB A,H */ X s = H; X goto sub; X case 149: /* 95 SUB A,L */ X s = L; X goto sub; X case 150: /* 96 SUB A,(HL) */ X s = ram[HL]; X goto sub; X case 151: /* 97 SUB A,A */ X s = A; X goto sub; X case 152: /* 98 SBC A,B */ X s = B; X goto sbc; X case 153: /* 99 SBC A,C */ X s = C; X goto sbc; X case 154: /* 9a SBC A,D */ X s = D; X goto sbc; X case 155: /* 9b SBC A,E */ X s = E; X goto sbc; X case 156: /* 9c SBC A,H */ X s = H; X goto sbc; X case 157: /* 9d SBC A,L */ X s = L; X goto sbc; X case 158: /* 9e SBC A,(HL) */ X s = ram[HL]; X goto sbc; X when 159: /* 9f SBC A,A */ X s = A; X sbc: X a = A & 0x0f; X s1 = s & 0x0f; X if (CARRY) { s--; a--; } X goto sub1; X sub: X a = A & 0x0f; X s1 = s & 0x0f; X sub1: X s = A - s; X A = s; X a -= s1; X BCD = 1; X goto set_flags; X X when 160: /* a0 AND A,B */ X s = B; X goto and; X case 161: /* a1 AND A,C */ X s = C; X goto and; X case 162: /* a2 AND A,D */ X s = D; X goto and; X case 163: /* a3 AND A,E */ X s = E; X goto and; X case 164: /* a4 AND A,H */ X s = H; X goto and; X case 165: /* a5 AND A,L */ X s = L; X goto and; X case 166: /* a6 AND A,(HL) */ X s = ram[HL]; X goto and; X case 167: /* a7 AND A,A */ X s = A; X and: X a = A & 0x0f; X s1 = s & 0x0f; X X s &= A; X A = s; X a &= s; X goto set_flags; X X when 168: /* a8 XOR A,B */ X s = B; X goto xor; X case 169: /* a9 XOR A,C */ X s = C; X goto xor; X case 170: /* aa XOR A,D */ X s = D; X goto xor; X case 171: /* ab XOR A,E */ X s = E; X goto xor; X case 172: /* ac XOR A,H */ X s = H; X goto xor; X case 173: /* ad XOR A,L */ X s = L; X goto xor; X case 174: /* ae XOR A,(HL) */ X s = ram[HL]; X goto xor; X case 175: /* af XOR A,A */ X s = A; X xor: X a = A & 0x0f; X s1 = s & 0x0f; X X s ^= A; X A = s; X a ^= s; X goto set_flags; X X when 176: /* b1 OR B */ X s = B; X goto or; X case 177: /* b1 OR C */ X s = C; X goto or; X case 178: /* b2 OR D */ X s = D; X goto or; X case 179: /* b3 OR E */ X s = E; X goto or; X case 180: /* b4 OR H */ X s = H; X goto or; X case 181: /* b5 OR L */ X s = L; X goto or; X case 182: /* b6 OR (HL) */ SHAR_EOF true || echo 'restore of decode.c failed' echo 'End of part 2, continue with part 3' echo 3 > _shar_seq_.tmp exit 0 -- D'Arcy J.M. Cain (darcy@druid) | D'Arcy Cain Consulting | I support gun control. West Hill, Ontario, Canada | Let's start with the government! + 416 281 6094 |