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 160