2 |
- |
1 |
/*
|
|
|
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.
|
|
|
5 |
*
|
|
|
6 |
* N.B. CALL16(x) kills DI, so don't expect it to be
|
|
|
7 |
* saved across calls.
|
|
|
8 |
*/
|
|
|
9 |
#define rAX 0 /* rX */
|
|
|
10 |
#define rCX 1
|
|
|
11 |
#define rDX 2
|
|
|
12 |
#define rBX 3
|
|
|
13 |
#define rSP 4 /* SP */
|
|
|
14 |
#define rBP 5 /* BP */
|
|
|
15 |
#define rSI 6 /* SI */
|
|
|
16 |
#define rDI 7 /* DI */
|
|
|
17 |
|
|
|
18 |
#define rAL 0 /* rL */
|
|
|
19 |
#define rCL 1
|
|
|
20 |
#define rDL 2
|
|
|
21 |
#define rBL 3
|
|
|
22 |
#define rAH 4 /* rH */
|
|
|
23 |
#define rCH 5
|
|
|
24 |
#define rDH 6
|
|
|
25 |
#define rBH 7
|
|
|
26 |
|
|
|
27 |
#define rES 0 /* rS */
|
|
|
28 |
#define rCS 1
|
|
|
29 |
#define rSS 2
|
|
|
30 |
#define rDS 3
|
|
|
31 |
#define rFS 4
|
|
|
32 |
#define rGS 5
|
|
|
33 |
|
|
|
34 |
#define xSI 4 /* rI (index) */
|
|
|
35 |
#define xDI 5
|
|
|
36 |
#define xBP 6
|
|
|
37 |
#define xBX 7
|
|
|
38 |
|
|
|
39 |
#define rCR0 0 /* rC */
|
|
|
40 |
#define rCR2 2
|
|
|
41 |
#define rCR3 3
|
|
|
42 |
#define rCR4 4
|
|
|
43 |
|
|
|
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 */ \
|
|
|
47 |
WORD $m;
|
|
|
48 |
#define OPrr(o, r0, r1) OP(o, 0x03, r0, r1); /* general r -> r */
|
|
|
49 |
|
|
|
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 */ \
|
|
|
52 |
WORD $x
|
|
|
53 |
#define LBPW(x, r) OP(0x8B, 0x02, r, xBP); /* x(rBP) -> r */ \
|
|
|
54 |
WORD $x
|
|
|
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 */ \
|
|
|
57 |
BYTE $x
|
|
|
58 |
#define LBPB(x, r) OP(0x8A, 0x01, r, xBP); /* x(rBP) -> r */ \
|
|
|
59 |
BYTE $x
|
|
|
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) */ \
|
|
|
62 |
WORD $x
|
|
|
63 |
#define SBPW(r, x) OP(0x89, 0x02, r, xBP); /* r -> x(rBP) */ \
|
|
|
64 |
WORD $(x)
|
|
|
65 |
#define SBPWI(i, x) OP(0xC7, 0x01, 0, xBP); /* i -> x(rBP) */ \
|
|
|
66 |
BYTE $(x); WORD $(i)
|
|
|
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) */ \
|
|
|
69 |
BYTE $x
|
|
|
70 |
#define SBPB(r, x) OP(0x88, 0x01, r, xBP); /* r -> x(rBP) */ \
|
|
|
71 |
BYTE $x
|
|
|
72 |
#define SBPBI(i, x) OP(0xC6, 0x01, 0, xBP); /* i -> x(rBP) */ \
|
|
|
73 |
BYTE $(x); BYTE $(i)
|
|
|
74 |
#define LWI(i, rX) BYTE $(0xB8+rX); /* i -> rX */ \
|
|
|
75 |
WORD $i;
|
|
|
76 |
#define LBI(i, rB) BYTE $(0xB0+rB); /* i -> r[HL] */ \
|
|
|
77 |
BYTE $i
|
|
|
78 |
|
|
|
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)
|
|
|
86 |
|
|
|
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 */ \
|
|
|
90 |
WORD $i;
|
|
|
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 */ \
|
|
|
93 |
WORD $i;
|
|
|
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 */ \
|
|
|
98 |
WORD $i;
|
|
|
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 */ \
|
|
|
109 |
WORD $i;
|
|
|
110 |
#define ROLI(i, r) OPrr(0xC1, 0x00, r); /* r<<>>i -> r */ \
|
|
|
111 |
BYTE $i;
|
|
|
112 |
#define SHLI(i, r) OPrr(0xC1, 0x04, r); /* r<<i -> r */ \
|
|
|
113 |
BYTE $i;
|
|
|
114 |
#define SHLBI(i, r) OPrr(0xC0, 0x04, r); /* r<<i -> r */ \
|
|
|
115 |
BYTE $i;
|
|
|
116 |
#define SHRI(i, r) OPrr(0xC1, 0x05, r); /* r>>i -> r */ \
|
|
|
117 |
BYTE $i;
|
|
|
118 |
#define SHRBI(i, r) OPrr(0xC0, 0x05, r); /* r>>i -> r */ \
|
|
|
119 |
BYTE $i;
|
|
|
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 */ \
|
|
|
122 |
WORD $i;
|
|
|
123 |
|
|
|
124 |
#define STOSW STOSL
|
|
|
125 |
|
|
|
126 |
#define CALL16(f) LWI(f, rDI); /* &f -> rDI */ \
|
|
|
127 |
BYTE $0xFF; /* (*rDI) */ \
|
|
|
128 |
BYTE $0xD7;
|
|
|
129 |
#define FARJUMP16(s, o) BYTE $0xEA; /* jump to ptr16:16 */ \
|
|
|
130 |
WORD $o; WORD $s
|
|
|
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 */ \
|
|
|
134 |
BYTE $0x00
|
|
|
135 |
#define BIOSCALL(b) INT $b /* INT $b */
|
|
|
136 |
|
|
|
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 */ \
|
|
|
142 |
BYTE $0xE6; \
|
|
|
143 |
BYTE $p; DELAY
|
|
|
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 */
|
|
|
152 |
|
|
|
153 |
#define LGDT(gdtptr) BYTE $0x0F; /* LGDT */ \
|
|
|
154 |
BYTE $0x01; BYTE $0x16; \
|
|
|
155 |
WORD $gdtptr
|
|
|
156 |
|
|
|
157 |
/* operand size switch. */
|
|
|
158 |
#define OPSIZE BYTE $0x66
|
|
|
159 |
|