📄 op.c
字号:
#include <stdio.h>#include "io.h"#include "ex.h"#include "st.h"#include "res.h"#include "op.h"#define ELEMENTS(Arr) (sizeof(Arr)/sizeof(Arr[0]))/* Translate controls: X: . = x # = #x / = /x n = Rn A = A B = AB C = C D = DPTR i = @Ri @ = @DPTR > = @A+DPTR $ = @A+PC Y: (x) L = Long Code Address P = Paged Code Address R = Relative Code Address D = Direct Register Address (x/) B = Bit Address (@) w = Word b = Byte (i) i = Register Pointer R0/R1 (n) n = Register R0/R1/R2/R3/R4/R5/R6/R7 x = Reverse Order of Next 2 Operands. */Mode ModeTab[] = {/* acall */ { 0x11, ".", "P" },/* add */ { 0x24, "A#", "b" }, { 0x26, "Ai", "i" }, { 0x25, "A.", "D" }, { 0x28, "An", "n" },/* addc */ { 0x34, "A#", "b" }, { 0x36, "Ai", "i" }, { 0x35, "A.", "D" }, { 0x38, "An", "n" },/* ajmp */ { 0x01, ".", "P" },/* anl */ { 0x54, "A#", "b" }, { 0x56, "Ai", "i" }, { 0x55, "A.", "D" }, { 0x58, "An", "n" }, { 0xb0, "C/", "B" }, { 0x82, "C.", "B" }, { 0x53, ".#", "Db" }, { 0x52, ".A", "D" },/* cjne */ { 0xb6, "i#.", "ibR" },{ 0xb4, "A#.", "bR" },{ 0xb5, "A..", "DR" }, { 0xb8, "n#.", "nbR" },/* clr */ { 0xe4, "A", "" }, { 0xc2, ".", "B" }, { 0xc3, "C", "" },/* cpl */ { 0xf4, "A", "" }, { 0xb2, ".", "B" }, { 0xb3, "C", "" },/* da */ { 0xd4, "A", "" },/* dec */ { 0x16, "i", "i" }, { 0x14, "A", ""}, { 0x15, ".", "D" }, { 0x18, "n", "n" },/* div */ { 0x84, "B", "" },/* djnz */ { 0xd5, "..", "DR" }, { 0xd8, "n.", "nR" },/* inc */ { 0x06, "i", "i" }, { 0x04, "A", "" }, { 0x05, ".", "D" }, { 0xa3, "D", "" }, { 0x08, "n", "n" },/* jb */ { 0x20, "..", "BR" },/* jbc */ { 0x10, "..", "BR" },/* jc */ { 0x40, ".", "R" },/* jmp */ { 0x73, ">", "" },/* jnb */ { 0x30, "..", "BR" },/* jnc */ { 0x50, ".", "R" },/* jnz */ { 0x70, ".", "R" },/* jz */ { 0x60, ".", "R" },/* lcall */ { 0x12, ".", "L" },/* ljmp */ { 0x02, ".", "L" },/* mov */ { 0x76, "i#", "ib" }, { 0xf6, "iA", "i" }, { 0xa6, "i.", "iD" }, { 0x74, "A#", "b" }, { 0xe6, "Ai", "i" }, { 0xe5, "A.", "D" }, { 0xe8, "An", "n" }, { 0x92, ".C", "B" }, { 0xa2, "C.", "B" }, { 0x75, ".#", "Db" }, { 0x86, ".i", "iD" },{ 0xf5, ".A", "D" }, { 0x85, "..", "xDD" },{ 0x88, ".n", "nD" },{ 0x90, "D#", "w" }, { 0x78, "n#", "nb" }, { 0xf8, "nA", "n" }, { 0xa8, "n.", "nD" },/* movc */ { 0x93, "A>", "" }, { 0x83, "A$", "" },/* movx */ { 0xf0, "@A", "" }, { 0xf2, "iA", "i" }, { 0xe0, "A@", "" }, { 0xe2, "Ai", "i" },/* mul */ { 0xa4, "B", "" },/* nop */ { 0x00, "", "" },/* orl */ { 0x44, "A#", "b" }, { 0x46, "Ai", "i" }, { 0x45, "A.", "D" }, { 0x48, "An", "n" }, { 0xa0, "C/", "B" }, { 0x72, "C.", "B" }, { 0x43, ".#", "Db" }, { 0x42, ".A", "D" },/* pop */ { 0xd0, ".", "D" },/* push */ { 0xc0, ".", "D" },/* ret */ { 0x22, "", "" },/* reti */ { 0x32, "", "" },/* rl */ { 0x23, "A", "" },/* rlc */ { 0x33, "A", "" },/* rr */ { 0x03, "A", "" },/* rrc */ { 0x13, "A", "" },/* setb */ { 0xd2, ".", "B" }, { 0xd3, "C", "" },/* sjmp */ { 0x80, ".", "R" },/* subb */ { 0x94, "A#", "b" }, { 0x96, "Ai", "i" }, { 0x95, "A.", "D" }, { 0x98, "An", "n" },/* swap */ { 0xc4, "A", "" },/* xch */ { 0xc6, "Ai", "i" }, { 0xc5, "A.", "D" }, { 0xc8, "An", "n" },/* xchd */ { 0xd6, "Ai", "i" },/* xrl */ { 0x64, "A#", "b" }, { 0x66, "Ai", "i" }, { 0x65, "A.", "D" }, { 0x68, "An", "n" }, { 0x63, ".#", "Db" },{ 0x62, ".A", "D" }};Code CodeTab[] = { { "acall", 1 }, { "add", 4 }, { "addc", 4 }, { "ajmp", 1 }, { "anl", 8 }, { "cjne", 4 }, { "clr", 3 }, { "cpl", 3 }, { "da", 1 }, { "dec", 4 }, { "div", 1 }, { "djnz", 2 }, { "inc", 5 }, { "jb", 1 }, { "jbc", 1 }, { "jc", 1 }, { "jmp", 1 }, { "jnb", 1 }, { "jnc", 1 }, { "jnz", 1 }, { "jz", 1 }, { "lcall", 1 }, { "ljmp", 1 }, { "mov", 18 }, { "movc", 2 }, { "movx", 4 }, { "mul", 1 }, { "nop", 1 }, { "orl", 8 }, { "pop", 1 }, { "push", 1 }, { "ret", 1 }, { "reti", 1 }, { "rl", 1 }, { "rlc", 1 }, { "rr", 1 }, { "rrc", 1 }, { "setb", 2 }, { "sjmp", 1 }, { "subb", 4 }, { "swap", 1 }, { "xch", 3 }, { "xchd", 1 }, { "xrl", 6 }, { 0, 0 }};/* Argument buffer. */#define A_MAX 4char XBuf[A_MAX + 1]; Exp XExp[A_MAX];void OpInit(void) { Code *OC; Mode *M; int I, J; for (OC = CodeTab, M = ModeTab; OC < CodeTab + ELEMENTS(CodeTab); OC++) { OC->Start = M; M += OC->Modes; if (M > ModeTab + ELEMENTS(ModeTab)) fprintf(stderr, "Bad opcode initialization.\n"), exit(1); }}void ParseArgs(byte Mnem) { Lexical L = OldL; Code *CP; Mode *MP; int XReg; char *XP, *S; Exp *EP, E; byte Op; word W; XP = XBuf, EP = XExp; do { L = Scan(); if (L == SEMI) { if (XP > XBuf) ERROR("Extra ','."); break; } switch (L) { case POUND: *XP = '#', Scan(), *EP++ = Parse(2); break; case DIV: *XP = '/', Scan(), *EP++ = Parse(2); break; case AT: L = Scan(); switch (L) { case REGISTER: switch ((Register)Value) { case ACC: if (Scan() != PLUS) ERROR("Cannot use @A."), *XP = ' '; else if (Scan() != REGISTER) ERROR("Missing DPTR or PC after @A+"), *XP = ' '; else { switch (Value) { case ACC:ERROR("Cannot use @A+A"), *XP = ' '; break; case AB:ERROR("Cannot use @A+AB."); *XP = ' '; break; case CY:ERROR("Cannot use @A+C."); *XP = ' '; break; case DPTR: *XP = '>'; break; case PC: *XP = '$'; break; default:ERROR("Cannot use @A+Rn"); *XP = ' '; break; } Scan(); } break; case AB: ERROR("Cannot use @AB."); *XP = ' '; break; case CY: ERROR("Cannot use @C."); *XP = ' '; break; case DPTR: *XP = '@'; Scan(); break; case PC: ERROR("Cannot use @PC."); *XP = ' '; break; default: Value -= (short)R0; if (Value != 0 && Value != 1) { ERROR("Register in @Rn out of range."); *XP = ' '; } else *XP = 'i', XReg = Value; Scan(); break; } break; default: ERROR("Register must appear after @."); *XP = ' '; break; } break; case REGISTER: switch ((Register)Value) { case ACC: *XP = 'A'; break; case AB: *XP = 'B'; break; case CY: *XP = 'C'; break; case DPTR: *XP = 'D'; break; case PC: ERROR("Cannot use PC as a register."); *XP = '.', *EP++ = MakeExp(AddrX, SegP, (word)LOC); break; default: *XP = 'n', XReg = Value - (short)R0; break; } Scan(); break; default: *XP = '.', *EP++ = Parse(2); break; } L = OldL; if (XP++ >= XBuf + A_MAX) { ERROR("Too many arguments specified."); return; while (L != SEMI && L != 0) L = Scan(); break; } } while (L == COMMA); if (!Active) return; *XP = 0, *EP = 0; CP = CodeTab + Mnem; for (MP = CP->Start; MP < CP->Start + CP->Modes; MP++) if (strcmp(XBuf, MP->X) == 0) break; if (MP >= CP->Start + CP->Modes) { ERROR("Invalid addressing mode: %s.", CP->Name); return; } Op = MP->OpCode; S = MP->Y, EP = XExp; switch (*S) { case 'n': S++; Op |= XReg&7; break;/* Register R0/R1/R2/R3/R4/R5/R6/R7 */ case 'i': S++; Op |= XReg&1; break;/* Register Pointer @R0/@R1 */ case 'x': E = EP[0], EP[0] = EP[1], EP[1] = E; S++; break; case 'P': Reloc(Op, 'P', *EP++); return; /* P Paged Address */ } PByte(Op); for (; *S != 0; S++) Reloc(0, *S, *EP++);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -