|
|
1.1 ! root 1: /* ! 2: * See the comments at the beginning of bb.c and bbc.h ! 3: * for an outline of how this bitblt works ! 4: ! 5: * The VGA screen on the 386 has an awful bit/byte order: ! 6: * the high order bit of a byte is leftmost, but the low ! 7: * order byte of a word is leftmost. ! 8: * This is a totally littleendian bitblt, so the bytes will ! 9: * have to be bit-reversed before putting them on the screen. ! 10: */ ! 11: typedef uchar Type; ! 12: ! 13: /* ! 14: * Registers: ! 15: */ ! 16: #define As 6 /* ESI */ ! 17: #define Ad 7 /* EDI */ ! 18: #define Rs 0 /* EAX: FIELD works better with this here */ ! 19: #define Rd 3 /* EBX */ ! 20: #define Rt 2 /* EDX */ ! 21: #define Ru 1 /* ECX */ ! 22: #define RX 5 /* EBP */ ! 23: #define SP 4 /* ESP */ ! 24: /* Ri is top-of-stack, if needed */ ! 25: /* Ro is second-top-of-stack, if needed */ ! 26: ! 27: /* ! 28: * Macros for assembling 386 instructions ! 29: */ ! 30: #define MODRM(mod,rm,reg) (((mod)<<6)|((reg)<<3)|(rm)) ! 31: #define SIB(ss,ind,base) (((ss)<<6)|((ind)<<3)|(base)) ! 32: #define RMR(rm,reg) MODRM(3,rm,reg) ! 33: #define IRMR(rm,reg) MODRM(0,rm,reg) ! 34: #define DB(b1,b2,b3,b4) ((b1)|((b2)<<8)|((b3)<<16)|((b4)<<24)) ! 35: #define SB(b1,b2) ((b1)|((b2)<<8)) ! 36: ! 37: #define OR(src,dst) SB(0x0B, RMR(src,dst)) ! 38: #define XOR(src,dst) SB(0x31, RMR(dst,src)) ! 39: #define AND(src,dst) SB(0x21, RMR(dst,src)) ! 40: #define NOT(r) SB(0xF7, RMR(r,2)) ! 41: #define MOV(src,dst) SB(0x89, RMR(dst,src)) ! 42: ! 43: #define Immd(v) *(long*)p = (long)(v); p += 4 ! 44: #define Immdb(b1,b2,b3,b4) Immd(DB(b1,b2,b3,b4)) ! 45: #define Imms(v) *(short*)p = (v); p += 2 ! 46: #define Immsb(b1,b2) Imms(SB(b1,b2)) ! 47: ! 48: #define Load(areg,dst) Immsb(0x8B, IRMR(areg,dst)) ! 49: #define Store(src,areg) Immsb(0x89, IRMR(areg,src)) ! 50: #define Mov(src,dst) Imms(MOV(src,dst)) ! 51: #define Movd(v,dst) *p++ = (0xB8 + (dst)); Immd(v) ! 52: #define Imov(a,i,r) *p++ = 0x8B; Immsb(IRMR(4,r),SIB(2,i,5)); Immd(a) ! 53: #define Or(src,dst) Imms(OR(src,dst)) ! 54: #define Xor(src,dst) Imms(XOR(src,dst)) ! 55: #define And(src,dst) Imms(AND(src,dst)) ! 56: #define Andd(v,dst) if(dst==Rs) {\ ! 57: *p++ = 0x25;\ ! 58: } else {\ ! 59: Immsb(0x81, RMR(dst,4));\ ! 60: }\ ! 61: Immd(v) ! 62: #define Not(r) Imms(NOT(r)) ! 63: #define Inc(r) *p++ = (0x40 + (r)) ! 64: #define Dec(r) *p++ = (0x48 + (r)) ! 65: #define Decsp Immsb(0xFF, IRMR(4,1)); *p++ = SIB(0,4,4) ! 66: #define Shl(r,sh) Immsb(0xC1, RMR(r,4)); *p++ = (sh) ! 67: #define Shr(r,sh) Immsb(0xC1, RMR(r,5)); *p++ = (sh) ! 68: #define Addd(v,r) Immsb(0x81, RMR(r,0)); Immd(v) ! 69: #define Addbsx(v,r) Immsb(0x83, RMR(r,0)); *p++ = v ! 70: #define Addsp(v) Immsb(0x83, RMR(4,0)); *p++ = v ! 71: #define Pushd(v) *p++ = 0x68; Immd(v) ! 72: #define Loop(d) *p = 0xE2; *(p+1) = d; p += 2 ! 73: #define Jmp8(d) *p = 0xEB; *(p+1) = d; p += 2 ! 74: #define Jmp(d) *p++ = 0xE9; Immd(d) ! 75: #define Jg8(d) *p = 0x7F; *(p+1) = d; p += 2 ! 76: #define Jle8(d) *p = 0x7E; *(p+1) = d; p += 2 ! 77: ! 78: #define Ofield(c) Xor(Rd,Rs); Andd(c,Rs); Xor(Rd,Rs) ! 79: #define Olsha_RsRt Mov(Rt,Rs); Shr(Rs,sha) ! 80: #define Olshb_RsRt Mov(Rt,Rs); Shr(Rs,shb) ! 81: #define Olsh_RsRd(sh) Mov(Rd,Rs); Shr(Rs,sh) ! 82: #define Olsh_RtRt(sh) Shr(Rt,sh) ! 83: #define Olsha_RtRt Shr(Rt,sha) ! 84: #define Olsha_RtRu Mov(Ru,Rt); Shr(Rt,sha) ! 85: #define Olshb_RtRu Mov(Ru,Rt); Shr(Rt,shb) ! 86: #define Orsha_RsRt Mov(Rt,Rs); Shl(Rs,sha) ! 87: #define Orshb_RsRt Mov(Rt,Rs); Shl(Rs,shb) ! 88: #define Orsha_RtRu Mov(Ru,Rt); Shl(Rt,sha) ! 89: #define Orshb_RtRu Mov(Ru,Rt); Shl(Rt,shb) ! 90: #define Oorlsha_RsRt Mov(Rt,RX); Shr(RX,sha); Or(RX,Rs) ! 91: #define Oorlshb_RsRt Mov(Rt,RX); Shr(RX,shb); Or(RX,Rs) ! 92: #define Oorlsh_RsRd(sh) Mov(Rd,RX); Shr(RX,sh); Or(RX,Rs) ! 93: #define Oorrsha_RsRt Mov(Rt,RX); Shl(RX,sha); Or(RX,Rs) ! 94: #define Oorrshb_RsRt Mov(Rt,RX); Shl(RX,shb); Or(RX,Rs) ! 95: #define Oorrsha_RtRu Mov(Ru,RX); Shl(RX,sha); Or(RX,Rt) ! 96: #define Oorrshb_RtRu Mov(Ru,RX); Shl(RX,shb); Or(RX,Rt) ! 97: #define Oor_RsRd Or(Rd,Rs) ! 98: #define Add_As(v) Addd(v,As) ! 99: #define Add_Ad(v) Addd(v,Ad) ! 100: #define Initsd(s,d) Movd(s,As); Movd(d,Ad) ! 101: #define Ilabel(c) Pushd(c) ! 102: #define Olabel(c) Pushd(c) ! 103: #define Iloop(lp) Decsp; \ ! 104: tmp = (lp)-(p+2); \ ! 105: if(tmp > -128) { \ ! 106: Jg8(tmp); \ ! 107: } else { \ ! 108: Jle8(5); \ ! 109: tmp = (lp) - (p+5); \ ! 110: Jmp(tmp); \ ! 111: } \ ! 112: Addsp(4) ! 113: #define Oloop(lp) Decsp; \ ! 114: tmp = (lp)-(p+2); \ ! 115: if(tmp > -128) { \ ! 116: Jg8(tmp); \ ! 117: } else { \ ! 118: Jle8(5); \ ! 119: tmp = (lp) - (p+5); \ ! 120: Jmp(tmp); \ ! 121: } \ ! 122: Addsp(4) ! 123: #define Orts *p++ = 0xC3 ! 124: /* load */ ! 125: #define Load_Rs_P Load(As,Rs); Addbsx(4,As) ! 126: #define Load_Rt_P Load(As,Rt); Addbsx(4,As) ! 127: #define Loadzx_Rt_P Load(As,Rt); Addbsx(4,As) ! 128: #define Loador_Rt_P Load(As,Rt); Addbsx(4,As) ! 129: #define Load_Ru_P Load(As,Ru); Addbsx(4,As) ! 130: #define Load_Rd_D(f) Addbsx(-4,As); Load(As,Rd) ! 131: #define Load_Rs_D(f) Addbsx(-4,As); Load(As,Rs) ! 132: #define Load_Rt_D(f) Addbsx(-4,As); Load(As,Rt) ! 133: #define Loadzx_Rt_D(f) Addbsx(-4,As); Load(As,Rt) ! 134: #define Load_Rd(f) Load(As,Rd) ! 135: #define Load_Rs(f) Load(As,Rs) ! 136: #define Load_Rt(f) Load(As,Rt) ! 137: #define Loadzx_Rt(f) Load(As,Rt) ! 138: /* fetch */ ! 139: #define Fetch_Rd_P(f) Load(Ad,Rd); Addbsx(4,Ad) ! 140: #define Fetch_Rd_D(f) Addbsx(-4,Ad); Load(Ad,Rd) ! 141: #define Fetch_Rd(f) Load(Ad,Rd) ! 142: /* store */ ! 143: #define Store_Rs_P Store(Rs,Ad); Addbsx(4,Ad) ! 144: #define Store_Rs_D Addbsx(-4,Ad); Store(Rs,Ad) ! 145: #define Store_Rs Store(Rs,Ad) ! 146: ! 147: #define Inittab(t,s) ! 148: #define Initsh(a,b) ! 149: ! 150: /* emit code to look up n bits of Rt at offset o, answer ulong in Rd */ ! 151: #define Table_RdRt(o,n,l) \ ! 152: Mov(Rt,Rd); \ ! 153: if(o) { Shr(Rd,(o)); } \ ! 154: Andd(((1<<(n))-1),Rd); \ ! 155: Imov(tab,Rd,Rd) ! 156: ! 157: #define Table_RsRt(o,n,l) \ ! 158: Mov(Rt,Rs); \ ! 159: if(o) { Shr(Rs,o); } \ ! 160: Andd(((1<<(n))-1),Rs); \ ! 161: Imov(tab,Rs,Rs) ! 162: ! 163: /* emit code to assemble high n bits of Rd into offset o in Rs */ ! 164: #define Assemble(o,n) \ ! 165: if((o) == 0) { \ ! 166: Olsh_RsRd(32-(n)); \ ! 167: } else if((o) == 32-(n)) { \ ! 168: Or(Rd,Rs); \ ! 169: } else { \ ! 170: Oorlsh_RsRd(32-((o)+(n))); \ ! 171: } ! 172: ! 173: /* concept of shifting-as-you-go doesn't work when filling from low end */ ! 174: #define Assemblex(o,n) Assemble(o,n) ! 175: ! 176: #define Nop ! 177: ! 178: #ifdef TEST ! 179: #define Extrainit \ ! 180: Movd(lrand(),Rs); \ ! 181: Movd(lrand(),Rd); \ ! 182: Movd(lrand(),Rt); \ ! 183: Movd(lrand(),Ru); \ ! 184: Movd(lrand(),RX) ! 185: #else ! 186: #define Extrainit ! 187: #endif ! 188: ! 189: #define Execandfree(memstart,onstack) \ ! 190: (*(void (*)(void))memstart)(); \ ! 191: if(!onstack) \ ! 192: bbfree(memstart, (p-memstart) * sizeof(Type)); ! 193: ! 194: /* emit code seq at fi (at most 3 shorts) */ ! 195: #define Emitop \ ! 196: *(long *)p = *(long *)fi; \ ! 197: *(short *)(p+4) = *(short *)(((char *)fi)+4); \ ! 198: p = (Type*)(((char *)p)+fin) ! 199: ! 200: typedef struct Fstr ! 201: { ! 202: short fetchs; ! 203: short fetchd; ! 204: int n; ! 205: short instr[4]; ! 206: } Fstr; ! 207: ! 208: Fstr fstr[16] = ! 209: { ! 210: [0] 0,0,2, /* Zero */ ! 211: { XOR(Rs,Rs), 0, 0, 0 }, ! 212: ! 213: [1] 1,1,4, /* DnorS */ ! 214: { OR(Rd,Rs), NOT(Rs), 0, 0}, ! 215: ! 216: [2] 1,1,4, /* DandnotS */ ! 217: { NOT(Rs), AND(Rd,Rs), 0, 0}, ! 218: ! 219: [3] 1,0,2, /* notS */ ! 220: { NOT(Rs), 0, 0, 0}, ! 221: ! 222: [4] 1,1,6, /* notDandS */ ! 223: { NOT(Rs), OR(Rd,Rs), NOT(Rs), 0}, ! 224: ! 225: [5] 0,1,4, /* notD */ ! 226: { MOV(Rd,Rs), NOT(Rs), 0, 0}, ! 227: ! 228: [6] 1,1,2, /* DxorS */ ! 229: { XOR(Rd,Rs), 0, 0, 0}, ! 230: ! 231: [7] 1,1,4, /* DnandS */ ! 232: { AND(Rd,Rs), NOT(Rs), 0, 0}, ! 233: ! 234: [8] 1,1,2, /* DandS */ ! 235: { AND(Rd,Rs), 0, 0, 0}, ! 236: ! 237: [9] 1,1,4, /* DxnorS */ ! 238: { XOR(Rd,Rs), NOT(Rs), 0, 0}, ! 239: ! 240: [10] 0,1,2, /* D */ ! 241: { MOV(Rd,Rs), 0, 0, 0}, ! 242: ! 243: [11] 1,1,4, /* DornotS */ ! 244: { NOT(Rs), OR(Rd,Rs), 0, 0}, ! 245: ! 246: [12] 1,0,0, /* S */ ! 247: { 0, 0, 0, 0}, ! 248: ! 249: [13] 1,1,6, /* notDorS */ ! 250: { NOT(Rs), AND(Rd,Rs), NOT(Rs), 0}, ! 251: ! 252: [14] 1,1,2, /* DorS */ ! 253: { OR(Rd,Rs), 0, 0, 0}, ! 254: ! 255: [15] 0,0,4, /* F */ ! 256: { XOR(Rs,Rs), NOT(Rs), 0, 0}, ! 257: }; ! 258: ! 259: #include "tabs.h" ! 260: ! 261: static uchar *tabs[4][4] = ! 262: { ! 263: { 0, (uchar*)tab01l, (uchar*)tab02l, (uchar*)tab03l}, ! 264: {(uchar*)tab10l, 0, (uchar*)tab12l, (uchar*)tab13l}, ! 265: {(uchar*)tab20l, (uchar*)tab21l, 0, (uchar*)tab23l}, ! 266: {(uchar*)tab30l, (uchar*)tab31l, (uchar*)tab32l, 0}, ! 267: }; ! 268: ! 269: static uchar tabosiz[4][4] = /* size in bytes of entries */ ! 270: { ! 271: { 0, 2, 4, 4}, ! 272: { 1, 0, 2, 4}, ! 273: { 1, 1, 0, 2}, ! 274: { 1, 1, 1, 0}, ! 275: }; ! 276: ! 277: enum { ! 278: Progmax = 3000, /* max number of bytes in a bitblt prog */ ! 279: Progmaxnoconv = 200, /* max number when not converting */ ! 280: }; ! 281: ! 282: #ifdef TEST ! 283: void ! 284: prprog(void) ! 285: { ! 286: abort(); /* use db */ ! 287: } ! 288: ! 289: void ! 290: bbexec(void (*memstart)(void), int len, int onstack) ! 291: { ! 292: memstart(); ! 293: if(!onstack) ! 294: bbfree(memstart, len); ! 295: } ! 296: ! 297: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.