2 * Can't write 16-bit code for 8a without getting into
3 * lots of bother, so define some simple commands and
4 * output the code directly.
6 * N.B. CALL16(x) kills DI, so don't expect it to be
13 #define rSP 4 /* SP */
14 #define rBP 5 /* BP */
15 #define rSI 6 /* SI */
16 #define rDI 7 /* DI */
18 #define rAL 0 /* rL */
22 #define rAH 4 /* rH */
27 #define rES 0 /* rS */
34 #define xSI 4 /* rI (index) */
39 #define rCR0 0 /* rC */
44 #define OP(o, m, ro, rm) BYTE $o; /* op + modr/m byte */ \
45 BYTE $(((m)<<6)|((ro)<<3)|(rm))
46 #define OPrm(o, r, m) OP(o, 0x00, r, 0x06); /* general r <-> m */ \
48 #define OPrr(o, r0, r1) OP(o, 0x03, r0, r1); /* general r -> r */
50 #define LW(m, rX) OPrm(0x8B, rX, m) /* m -> rX */
51 #define LXW(x, rI, r) OP(0x8B, 0x02, r, rI); /* x(rI) -> r */ \
53 #define LBPW(x, r) OP(0x8B, 0x02, r, xBP); /* x(rBP) -> r */ \
55 #define LB(m, rB) OPrm(0x8A, rB, m) /* m -> r[HL] */
56 #define LXB(x, rI, r) OP(0x8A, 0x01, r, rI); /* x(rI) -> r */ \
58 #define LBPB(x, r) OP(0x8A, 0x01, r, xBP); /* x(rBP) -> r */ \
60 #define SW(rX, m) OPrm(0x89, rX, m) /* rX -> m */
61 #define SXW(r, x, rI) OP(0x89, 0x02, r, rI); /* r -> x(rI) */ \
63 #define SBPW(r, x) OP(0x89, 0x02, r, xBP); /* r -> x(rBP) */ \
65 #define SBPWI(i, x) OP(0xC7, 0x01, 0, xBP); /* i -> x(rBP) */ \
67 #define STB(rB, m) OPrm(0x88, rB, m) /* rB -> m */
68 #define SXB(r, x, rI) OP(0x88, 0x01, r, rI); /* rB -> x(rI) */ \
70 #define SBPB(r, x) OP(0x88, 0x01, r, xBP); /* r -> x(rBP) */ \
72 #define SBPBI(i, x) OP(0xC6, 0x01, 0, xBP); /* i -> x(rBP) */ \
74 #define LWI(i, rX) BYTE $(0xB8+rX); /* i -> rX */ \
76 #define LBI(i, rB) BYTE $(0xB0+rB); /* i -> r[HL] */ \
79 #define MW(r0, r1) OPrr(0x89, r0, r1) /* r0 -> r1 */
80 #define MFSR(rS, rX) OPrr(0x8C, rS, rX) /* rS -> rX */
81 #define MTSR(rX, rS) OPrr(0x8E, rS, rX) /* rX -> rS */
82 #define MFCR(rC, rX) BYTE $0x0F; /* rC -> rX */ \
83 OP(0x20, 0x03, rC, rX)
84 #define MTCR(rX, rC) BYTE $0x0F; /* rX -> rC */ \
85 OP(0x22, 0x03, rC, rX)
87 #define ADC(r0, r1) OPrr(0x11, r0, r1) /* r0 + r1 -> r1 */
88 #define ADD(r0, r1) OPrr(0x01, r0, r1) /* r0 + r1 -> r1 */
89 #define ADDI(i, r) OP(0x81, 0x03, 0x00, r);/* i+r -> r */ \
91 #define AND(r0, r1) OPrr(0x21, r0, r1) /* r0&r1 -> r1 */
92 #define ANDI(i, r) OP(0x81, 0x03, 0x04, r);/* i&r -> r */ \
94 #define CLR(r) OPrr(0x31, r, r) /* r^r -> r */
95 #define CLRB(r) OPrr(0x30, r, r) /* r^r -> r */
96 #define CMP(r0, r1) OPrr(0x39, r0, r1) /* r1-r0 -> flags */
97 #define CMPI(i, r) OP(0x81, 0x03, 0x07, r);/* r-i -> flags */ \
99 #define CMPBR(r0, r1) OPrr(0x38, r0, r1) /* r1-r0 -> flags */
100 #define DEC(r) BYTE $(0x48|r) /* r-1 -> r */
101 #define DIV(r) OPrr(0xF7, 0x06, r) /* rDX:rAX/r -> rAX, rDX:rAX%r -> rDX */
102 #define INC(r) BYTE $(0x40|r) /* r+1 -> r */
103 #define MUL(r) OPrr(0xF7, 0x04, r) /* r*rAX -> rDX:rAX */
104 #define IMUL(r0, r1) BYTE $0x0F; /* r0*r1 -> r1 */ \
105 OPrr(0xAF, r1, r0) /* (signed) */
106 #define OR(r0, r1) OPrr(0x09, r0, r1) /* r0|r1 -> r1 */
107 #define ORB(r0, r1) OPrr(0x08, r0, r1) /* r0|r1 -> r1 */
108 #define ORI(i, r) OP(0x81, 0x03, 0x01, r);/* i|r -> r */ \
110 #define ROLI(i, r) OPrr(0xC1, 0x00, r); /* r<<>>i -> r */ \
112 #define SHLI(i, r) OPrr(0xC1, 0x04, r); /* r<<i -> r */ \
114 #define SHLBI(i, r) OPrr(0xC0, 0x04, r); /* r<<i -> r */ \
116 #define SHRI(i, r) OPrr(0xC1, 0x05, r); /* r>>i -> r */ \
118 #define SHRBI(i, r) OPrr(0xC0, 0x05, r); /* r>>i -> r */ \
120 #define SUB(r0, r1) OPrr(0x29, r0, r1) /* r1-r0 -> r1 */
121 #define SUBI(i, r) OP(0x81, 0x03, 0x05, r);/* r-i -> r */ \
126 #define CALL16(f) LWI(f, rDI); /* &f -> rDI */ \
127 BYTE $0xFF; /* (*rDI) */ \
129 #define FARJUMP16(s, o) BYTE $0xEA; /* jump to ptr16:16 */ \
131 #define FARJUMP32(s, o) BYTE $0x66; /* jump to ptr32:16 */ \
132 BYTE $0xEA; LONG $o; WORD $s
133 #define DELAY BYTE $0xEB; /* jmp .+2 */ \
135 #define BIOSCALL(b) INT $b /* INT $b */
137 #define PEEKW BYTE $0x26; /* MOVW rES:[rBX], rAX */ \
138 BYTE $0x8B; BYTE $0x07
139 #define POKEW BYTE $0x26; /* MOVW rAX, rES:[rBX] */ \
140 BYTE $0x89; BYTE $0x07
141 #define OUTPORTB(p, d) LBI(d, rAL); /* d -> I/O port p */ \
144 #define PUSHA BYTE $0x60
145 #define PUSHR(r) BYTE $(0x50|r) /* r -> (--rSP) */
146 #define PUSHS(rS) BYTE $(0x06|((rS)<<3)) /* rS -> (--rSP) */
147 #define PUSHI(i) BYTE $0x68; WORD $i; /* i -> --(rSP) */
148 #define POPA BYTE $0x61
149 #define POPR(r) BYTE $(0x58|r) /* (rSP++) -> r */
150 #define POPS(rS) BYTE $(0x07|((rS)<<3)) /* (rSP++) -> r */
151 #define NOP BYTE $0x90 /* nop */
153 #define LGDT(gdtptr) BYTE $0x0F; /* LGDT */ \
154 BYTE $0x01; BYTE $0x16; \
156 #define LIDT(idtptr) BYTE $0x0F; /* LIDT */ \
157 BYTE $0x01; BYTE $0x1e; \
160 /* operand size switch. */
161 #define OPSIZE BYTE $0x66
162 #define ADSIZE BYTE $0x67