]> git.lizzy.rs Git - plan9front.git/blob - sys/src/boot/pc/x16.h
merge
[plan9front.git] / sys / src / boot / pc / x16.h
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 #define LIDT(idtptr)    BYTE $0x0F;             /* LIDT */                      \
157                         BYTE $0x01; BYTE $0x1e;                                 \
158                         WORD $idtptr
159
160 /* operand size switch. */
161 #define OPSIZE          BYTE $0x66
162 #define ADSIZE          BYTE $0x67