17dd7cddfSDavid du Colombier /* 27dd7cddfSDavid du Colombier * Can't write 16-bit code for 8a without getting into 37dd7cddfSDavid du Colombier * lots of bother, so define some simple commands and 47dd7cddfSDavid du Colombier * output the code directly. 57dd7cddfSDavid du Colombier * 680ee5cbfSDavid du Colombier * N.B. CALL16(x) kills DI, so don't expect it to be 77dd7cddfSDavid du Colombier * saved across calls. 87dd7cddfSDavid du Colombier */ 97dd7cddfSDavid du Colombier #define rAX 0 /* rX */ 107dd7cddfSDavid du Colombier #define rCX 1 117dd7cddfSDavid du Colombier #define rDX 2 127dd7cddfSDavid du Colombier #define rBX 3 137dd7cddfSDavid du Colombier #define rSP 4 /* SP */ 147dd7cddfSDavid du Colombier #define rBP 5 /* BP */ 157dd7cddfSDavid du Colombier #define rSI 6 /* SI */ 167dd7cddfSDavid du Colombier #define rDI 7 /* DI */ 177dd7cddfSDavid du Colombier 187dd7cddfSDavid du Colombier #define rAL 0 /* rL */ 197dd7cddfSDavid du Colombier #define rCL 1 207dd7cddfSDavid du Colombier #define rDL 2 217dd7cddfSDavid du Colombier #define rBL 3 227dd7cddfSDavid du Colombier #define rAH 4 /* rH */ 237dd7cddfSDavid du Colombier #define rCH 5 247dd7cddfSDavid du Colombier #define rDH 6 257dd7cddfSDavid du Colombier #define rBH 7 267dd7cddfSDavid du Colombier 277dd7cddfSDavid du Colombier #define rES 0 /* rS */ 287dd7cddfSDavid du Colombier #define rCS 1 297dd7cddfSDavid du Colombier #define rSS 2 307dd7cddfSDavid du Colombier #define rDS 3 317dd7cddfSDavid du Colombier #define rFS 4 327dd7cddfSDavid du Colombier #define rGS 5 337dd7cddfSDavid du Colombier 347dd7cddfSDavid du Colombier #define xSI 4 /* rI (index) */ 357dd7cddfSDavid du Colombier #define xDI 5 367dd7cddfSDavid du Colombier #define xBP 6 377dd7cddfSDavid du Colombier #define xBX 7 387dd7cddfSDavid du Colombier 397dd7cddfSDavid du Colombier #define rCR0 0 /* rC */ 407dd7cddfSDavid du Colombier #define rCR2 2 417dd7cddfSDavid du Colombier #define rCR3 3 427dd7cddfSDavid du Colombier #define rCR4 4 437dd7cddfSDavid du Colombier 447dd7cddfSDavid du Colombier #define OP(o, m, ro, rm) BYTE $o; /* op + modr/m byte */ \ 457dd7cddfSDavid du Colombier BYTE $(((m)<<6)|((ro)<<3)|(rm)) 467dd7cddfSDavid du Colombier #define OPrm(o, r, m) OP(o, 0x00, r, 0x06); /* general r <-> m */ \ 477dd7cddfSDavid du Colombier WORD $m; 487dd7cddfSDavid du Colombier #define OPrr(o, r0, r1) OP(o, 0x03, r0, r1); /* general r -> r */ 497dd7cddfSDavid du Colombier 507dd7cddfSDavid du Colombier #define LW(m, rX) OPrm(0x8B, rX, m) /* m -> rX */ 517dd7cddfSDavid du Colombier #define LXW(x, rI, r) OP(0x8B, 0x02, r, rI); /* x(rI) -> r */ \ 527dd7cddfSDavid du Colombier WORD $x 537dd7cddfSDavid du Colombier #define LBPW(x, r) OP(0x8B, 0x02, r, xBP); /* x(rBP) -> r */ \ 547dd7cddfSDavid du Colombier WORD $x 557dd7cddfSDavid du Colombier #define LB(m, rB) OPrm(0x8A, rB, m) /* m -> r[HL] */ 567dd7cddfSDavid du Colombier #define LXB(x, rI, r) OP(0x8A, 0x01, r, rI); /* x(rI) -> r */ \ 577dd7cddfSDavid du Colombier BYTE $x 587dd7cddfSDavid du Colombier #define LBPB(x, r) OP(0x8A, 0x01, r, xBP); /* x(rBP) -> r */ \ 597dd7cddfSDavid du Colombier BYTE $x 607dd7cddfSDavid du Colombier #define SW(rX, m) OPrm(0x89, rX, m) /* rX -> m */ 617dd7cddfSDavid du Colombier #define SXW(r, x, rI) OP(0x89, 0x02, r, rI); /* r -> x(rI) */ \ 627dd7cddfSDavid du Colombier WORD $x 637dd7cddfSDavid du Colombier #define SBPW(r, x) OP(0x89, 0x02, r, xBP); /* r -> x(rBP) */ \ 647dd7cddfSDavid du Colombier WORD $(x) 657dd7cddfSDavid du Colombier #define SBPWI(i, x) OP(0xC7, 0x01, 0, xBP); /* i -> x(rBP) */ \ 667dd7cddfSDavid du Colombier BYTE $(x); WORD $(i) 677dd7cddfSDavid du Colombier #define STB(rB, m) OPrm(0x88, rB, m) /* rB -> m */ 687dd7cddfSDavid du Colombier #define SXB(r, x, rI) OP(0x88, 0x01, r, rI); /* rB -> x(rI) */ \ 697dd7cddfSDavid du Colombier BYTE $x 707dd7cddfSDavid du Colombier #define SBPB(r, x) OP(0x88, 0x01, r, xBP); /* r -> x(rBP) */ \ 717dd7cddfSDavid du Colombier BYTE $x 727dd7cddfSDavid du Colombier #define SBPBI(i, x) OP(0xC6, 0x01, 0, xBP); /* i -> x(rBP) */ \ 737dd7cddfSDavid du Colombier BYTE $(x); BYTE $(i) 747dd7cddfSDavid du Colombier #define LWI(i, rX) BYTE $(0xB8+rX); /* i -> rX */ \ 757dd7cddfSDavid du Colombier WORD $i; 767dd7cddfSDavid du Colombier #define LBI(i, rB) BYTE $(0xB0+rB); /* i -> r[HL] */ \ 777dd7cddfSDavid du Colombier BYTE $i 787dd7cddfSDavid du Colombier 797dd7cddfSDavid du Colombier #define MW(r0, r1) OPrr(0x89, r0, r1) /* r0 -> r1 */ 807dd7cddfSDavid du Colombier #define MFSR(rS, rX) OPrr(0x8C, rS, rX) /* rS -> rX */ 817dd7cddfSDavid du Colombier #define MTSR(rX, rS) OPrr(0x8E, rS, rX) /* rX -> rS */ 827dd7cddfSDavid du Colombier #define MFCR(rC, rX) BYTE $0x0F; /* rC -> rX */ \ 837dd7cddfSDavid du Colombier OP(0x20, 0x03, rC, rX) 847dd7cddfSDavid du Colombier #define MTCR(rX, rC) BYTE $0x0F; /* rX -> rC */ \ 857dd7cddfSDavid du Colombier OP(0x22, 0x03, rC, rX) 867dd7cddfSDavid du Colombier 877dd7cddfSDavid du Colombier #define ADC(r0, r1) OPrr(0x11, r0, r1) /* r0 + r1 -> r1 */ 887dd7cddfSDavid du Colombier #define ADD(r0, r1) OPrr(0x01, r0, r1) /* r0 + r1 -> r1 */ 897dd7cddfSDavid du Colombier #define ADDI(i, r) OP(0x81, 0x03, 0x00, r);/* i+r -> r */ \ 907dd7cddfSDavid du Colombier WORD $i; 917dd7cddfSDavid du Colombier #define AND(r0, r1) OPrr(0x21, r0, r1) /* r0&r1 -> r1 */ 927dd7cddfSDavid du Colombier #define ANDI(i, r) OP(0x81, 0x03, 0x04, r);/* i&r -> r */ \ 937dd7cddfSDavid du Colombier WORD $i; 947dd7cddfSDavid du Colombier #define CLR(r) OPrr(0x31, r, r) /* r^r -> r */ 957dd7cddfSDavid du Colombier #define CLRB(r) OPrr(0x30, r, r) /* r^r -> r */ 967dd7cddfSDavid du Colombier #define CMP(r0, r1) OPrr(0x39, r0, r1) /* r1-r0 -> flags */ 977dd7cddfSDavid du Colombier #define CMPI(i, r) OP(0x81, 0x03, 0x07, r);/* r-i -> flags */ \ 987dd7cddfSDavid du Colombier WORD $i; 9980ee5cbfSDavid du Colombier #define CMPBR(r0, r1) OPrr(0x38, r0, r1) /* r1-r0 -> flags */ 1007dd7cddfSDavid du Colombier #define DEC(r) BYTE $(0x48|r) /* r-1 -> r */ 1017dd7cddfSDavid du Colombier #define DIV(r) OPrr(0xF7, 0x06, r) /* rDX:rAX/r -> rAX, rDX:rAX%r -> rDX */ 1027dd7cddfSDavid du Colombier #define INC(r) BYTE $(0x40|r) /* r+1 -> r */ 1037dd7cddfSDavid du Colombier #define MUL(r) OPrr(0xF7, 0x04, r) /* r*rAX -> rDX:rAX */ 1047dd7cddfSDavid du Colombier #define IMUL(r0, r1) BYTE $0x0F; /* r0*r1 -> r1 */ \ 1057dd7cddfSDavid du Colombier OPrr(0xAF, r1, r0) /* (signed) */ 1067dd7cddfSDavid du Colombier #define OR(r0, r1) OPrr(0x09, r0, r1) /* r0|r1 -> r1 */ 1077dd7cddfSDavid du Colombier #define ORB(r0, r1) OPrr(0x08, r0, r1) /* r0|r1 -> r1 */ 1087dd7cddfSDavid du Colombier #define ORI(i, r) OP(0x81, 0x03, 0x01, r);/* i|r -> r */ \ 1097dd7cddfSDavid du Colombier WORD $i; 1107dd7cddfSDavid du Colombier #define ROLI(i, r) OPrr(0xC1, 0x00, r); /* r<<>>i -> r */ \ 1117dd7cddfSDavid du Colombier BYTE $i; 1127dd7cddfSDavid du Colombier #define SHLI(i, r) OPrr(0xC1, 0x04, r); /* r<<i -> r */ \ 1137dd7cddfSDavid du Colombier BYTE $i; 1147dd7cddfSDavid du Colombier #define SHLBI(i, r) OPrr(0xC0, 0x04, r); /* r<<i -> r */ \ 1157dd7cddfSDavid du Colombier BYTE $i; 1167dd7cddfSDavid du Colombier #define SHRI(i, r) OPrr(0xC1, 0x05, r); /* r>>i -> r */ \ 1177dd7cddfSDavid du Colombier BYTE $i; 1187dd7cddfSDavid du Colombier #define SHRBI(i, r) OPrr(0xC0, 0x05, r); /* r>>i -> r */ \ 1197dd7cddfSDavid du Colombier BYTE $i; 1207dd7cddfSDavid du Colombier #define SUB(r0, r1) OPrr(0x29, r0, r1) /* r1-r0 -> r1 */ 1217dd7cddfSDavid du Colombier #define SUBI(i, r) OP(0x81, 0x03, 0x05, r);/* r-i -> r */ \ 1227dd7cddfSDavid du Colombier WORD $i; 1237dd7cddfSDavid du Colombier 12480ee5cbfSDavid du Colombier #define STOSW STOSL 12580ee5cbfSDavid du Colombier 12680ee5cbfSDavid du Colombier #define CALL16(f) LWI(f, rDI); /* &f -> rDI */ \ 1277dd7cddfSDavid du Colombier BYTE $0xFF; /* (*rDI) */ \ 1287dd7cddfSDavid du Colombier BYTE $0xD7; 1297dd7cddfSDavid du Colombier #define FARJUMP16(s, o) BYTE $0xEA; /* jump to ptr16:16 */ \ 1307dd7cddfSDavid du Colombier WORD $o; WORD $s 1317dd7cddfSDavid du Colombier #define FARJUMP32(s, o) BYTE $0x66; /* jump to ptr32:16 */ \ 1327dd7cddfSDavid du Colombier BYTE $0xEA; LONG $o; WORD $s 1337dd7cddfSDavid du Colombier #define DELAY BYTE $0xEB; /* jmp .+2 */ \ 1347dd7cddfSDavid du Colombier BYTE $0x00 13580ee5cbfSDavid du Colombier #define BIOSCALL(b) INT $b /* INT $b */ 1367dd7cddfSDavid du Colombier 1377dd7cddfSDavid du Colombier #define PEEKW BYTE $0x26; /* MOVW rES:[rBX], rAX */ \ 1387dd7cddfSDavid du Colombier BYTE $0x8B; BYTE $0x07 1397dd7cddfSDavid du Colombier #define POKEW BYTE $0x26; /* MOVW rAX, rES:[rBX] */ \ 1407dd7cddfSDavid du Colombier BYTE $0x89; BYTE $0x07 1417dd7cddfSDavid du Colombier #define OUTPORTB(p, d) LBI(d, rAL); /* d -> I/O port p */ \ 1427dd7cddfSDavid du Colombier BYTE $0xE6; \ 1437dd7cddfSDavid du Colombier BYTE $p; DELAY 1447dd7cddfSDavid du Colombier #define PUSHA BYTE $0x60 1457dd7cddfSDavid du Colombier #define PUSHR(r) BYTE $(0x50|r) /* r -> (--rSP) */ 1467dd7cddfSDavid du Colombier #define PUSHS(rS) BYTE $(0x06|((rS)<<3)) /* rS -> (--rSP) */ 1477dd7cddfSDavid du Colombier #define PUSHI(i) BYTE $0x68; WORD $i; /* i -> --(rSP) */ 1487dd7cddfSDavid du Colombier #define POPA BYTE $0x61 1497dd7cddfSDavid du Colombier #define POPR(r) BYTE $(0x58|r) /* (rSP++) -> r */ 150*afbf1472SDavid du Colombier #define POPS(rS) BYTE $(0x07|((rS)<<3)) /* (rSP++) -> r */ 1517dd7cddfSDavid du Colombier #define NOP BYTE $0x90 /* nop */ 1527dd7cddfSDavid du Colombier 1537dd7cddfSDavid du Colombier #define LGDT(gdtptr) BYTE $0x0F; /* LGDT */ \ 1547dd7cddfSDavid du Colombier BYTE $0x01; BYTE $0x16; \ 1557dd7cddfSDavid du Colombier WORD $gdtptr 1567dd7cddfSDavid du Colombier 15780ee5cbfSDavid du Colombier /* operand size switch. */ 15880ee5cbfSDavid du Colombier #define OPSIZE BYTE $0x66 1597dd7cddfSDavid du Colombier 160