Mercurial > repos > blastem
comparison gen_x86.c @ 18:3e7bfde7606e
M68K to x86 translation works for a limited subset of instructions and addressing modes
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Tue, 04 Dec 2012 19:13:12 -0800 |
parents | c0f339564819 |
children | d2e43d64e999 |
comparison
equal
deleted
inserted
replaced
17:de0085d4ea40 | 18:3e7bfde7606e |
---|---|
29 #define OP_MOV_I8R 0xB0 | 29 #define OP_MOV_I8R 0xB0 |
30 #define OP_MOV_IR 0xB8 | 30 #define OP_MOV_IR 0xB8 |
31 #define OP_RETN 0xC3 | 31 #define OP_RETN 0xC3 |
32 #define OP_MOV_IEA 0xC6 | 32 #define OP_MOV_IEA 0xC6 |
33 #define OP_CALL 0xE8 | 33 #define OP_CALL 0xE8 |
34 #define OP_JMP 0xE9 | |
35 #define OP_JMP_BYTE 0xEB | |
34 #define OP_CALL_EA 0xFF | 36 #define OP_CALL_EA 0xFF |
35 | 37 |
36 #define OP2_JCC 0x80 | 38 #define OP2_JCC 0x80 |
37 #define OP2_SETCC 0x90 | 39 #define OP2_SETCC 0x90 |
38 | 40 |
47 | 49 |
48 #define BIT_IMMED_RAX 0x4 | 50 #define BIT_IMMED_RAX 0x4 |
49 #define BIT_DIR 0x2 | 51 #define BIT_DIR 0x2 |
50 #define BIT_SIZE 0x1 | 52 #define BIT_SIZE 0x1 |
51 | 53 |
52 #define M68K_N_REG RBX | |
53 #define M68K_V_REG BH | |
54 #define M68K_Z_REG RDX | |
55 #define M68K_C_REG DH | |
56 | |
57 #define M68K_SCRATCH RCX | |
58 | 54 |
59 enum { | 55 enum { |
60 X86_RAX = 0, | 56 X86_RAX = 0, |
61 X86_RCX, | 57 X86_RCX, |
62 X86_RDX, | 58 X86_RDX, |
77 X86_R13, | 73 X86_R13, |
78 X86_R14, | 74 X86_R14, |
79 X86_R15 | 75 X86_R15 |
80 } x86_regs_enc; | 76 } x86_regs_enc; |
81 | 77 |
82 enum { | |
83 MODE_REG_INDIRECT = 0, | |
84 MODE_REG_DISPLACE8 = 0x40, | |
85 MODE_REG_DIPSLACE32 = 0x80, | |
86 MODE_REG_DIRECT = 0xC0 | |
87 } x86_modes; | |
88 | |
89 uint8_t * x86_rr_sizedir(uint8_t * out, uint8_t opcode, uint8_t src, uint8_t dst, uint8_t size) | 78 uint8_t * x86_rr_sizedir(uint8_t * out, uint8_t opcode, uint8_t src, uint8_t dst, uint8_t size) |
90 { | 79 { |
91 //TODO: Deal with the fact that AH, BH, CH and DH can only be in the R/M param when there's a REX prefix | 80 //TODO: Deal with the fact that AH, BH, CH and DH can only be in the R/M param when there's a REX prefix |
92 uint8_t tmp; | 81 uint8_t tmp; |
93 if (size == SZ_W) { | 82 if (size == SZ_W) { |
158 } else { | 147 } else { |
159 opcode |= BIT_SIZE; | 148 opcode |= BIT_SIZE; |
160 } | 149 } |
161 *(out++) = opcode | dir; | 150 *(out++) = opcode | dir; |
162 *(out++) = MODE_REG_DISPLACE8 | base | (reg << 3); | 151 *(out++) = MODE_REG_DISPLACE8 | base | (reg << 3); |
152 if (base == RSP) { | |
153 //add SIB byte, with no index and RSP as base | |
154 *(out++) = (RSP << 3) | RSP; | |
155 } | |
163 *(out++) = disp; | 156 *(out++) = disp; |
164 return out; | 157 return out; |
165 } | 158 } |
166 | 159 |
167 uint8_t * x86_rrind_sizedir(uint8_t * out, uint8_t opcode, uint8_t reg, uint8_t base, uint8_t size, uint8_t dir) | 160 uint8_t * x86_rrind_sizedir(uint8_t * out, uint8_t opcode, uint8_t reg, uint8_t base, uint8_t size, uint8_t dir) |
193 } else { | 186 } else { |
194 opcode |= BIT_SIZE; | 187 opcode |= BIT_SIZE; |
195 } | 188 } |
196 *(out++) = opcode | dir; | 189 *(out++) = opcode | dir; |
197 *(out++) = MODE_REG_INDIRECT | base | (reg << 3); | 190 *(out++) = MODE_REG_INDIRECT | base | (reg << 3); |
191 if (base == RSP) { | |
192 //add SIB byte, with no index and RSP as base | |
193 *(out++) = (RSP << 3) | RSP; | |
194 } | |
198 return out; | 195 return out; |
199 } | 196 } |
200 | 197 |
201 uint8_t * x86_ir(uint8_t * out, uint8_t opcode, uint8_t op_ex, uint8_t al_opcode, int32_t val, uint8_t dst, uint8_t size) | 198 uint8_t * x86_ir(uint8_t * out, uint8_t opcode, uint8_t op_ex, uint8_t al_opcode, int32_t val, uint8_t dst, uint8_t size) |
202 { | 199 { |
249 } | 246 } |
250 } | 247 } |
251 return out; | 248 return out; |
252 } | 249 } |
253 | 250 |
251 uint8_t * x86_irdisp8(uint8_t * out, uint8_t opcode, uint8_t op_ex, int32_t val, uint8_t dst, int8_t disp, uint8_t size) | |
252 { | |
253 uint8_t sign_extend = 0; | |
254 if ((size == SZ_D || size == SZ_Q) && val <= 0x7F && val >= -0x80) { | |
255 sign_extend = 1; | |
256 opcode |= BIT_DIR; | |
257 } | |
258 if (size == SZ_W) { | |
259 *(out++) = PRE_SIZE; | |
260 } | |
261 | |
262 if (size == SZ_Q || dst >= R8 || (size == SZ_B && dst >= RSP && dst <= RDI)) { | |
263 *out = PRE_REX; | |
264 if (size == SZ_Q) { | |
265 *out |= REX_QUAD; | |
266 } | |
267 if (dst >= R8) { | |
268 *out |= REX_RM_FIELD; | |
269 dst -= (R8 - X86_R8); | |
270 } | |
271 out++; | |
272 } | |
273 if (dst >= AH && dst <= BH) { | |
274 dst -= (AH-X86_AH); | |
275 } | |
276 if (size != SZ_B) { | |
277 opcode |= BIT_SIZE; | |
278 } | |
279 *(out++) = opcode; | |
280 *(out++) = MODE_REG_DISPLACE8 | dst | (op_ex << 3); | |
281 *(out++) = disp; | |
282 *(out++) = val; | |
283 if (size != SZ_B && !sign_extend) { | |
284 val >>= 8; | |
285 *(out++) = val; | |
286 if (size != SZ_W) { | |
287 val >>= 8; | |
288 *(out++) = val; | |
289 val >>= 8; | |
290 *(out++) = val; | |
291 } | |
292 } | |
293 return out; | |
294 } | |
295 | |
254 | 296 |
255 uint8_t * add_rr(uint8_t * out, uint8_t src, uint8_t dst, uint8_t size) | 297 uint8_t * add_rr(uint8_t * out, uint8_t src, uint8_t dst, uint8_t size) |
256 { | 298 { |
257 return x86_rr_sizedir(out, OP_ADD, src, dst, size); | 299 return x86_rr_sizedir(out, OP_ADD, src, dst, size); |
258 } | 300 } |
260 uint8_t * add_ir(uint8_t * out, int32_t val, uint8_t dst, uint8_t size) | 302 uint8_t * add_ir(uint8_t * out, int32_t val, uint8_t dst, uint8_t size) |
261 { | 303 { |
262 return x86_ir(out, OP_IMMED_ARITH, OP_EX_ADDI, OP_ADD, val, dst, size); | 304 return x86_ir(out, OP_IMMED_ARITH, OP_EX_ADDI, OP_ADD, val, dst, size); |
263 } | 305 } |
264 | 306 |
307 uint8_t * add_irdisp8(uint8_t * out, int32_t val, uint8_t dst_base, int8_t disp, uint8_t size) | |
308 { | |
309 return x86_irdisp8(out, OP_IMMED_ARITH, OP_EX_ADDI, val, dst_base, disp, size); | |
310 } | |
311 | |
312 uint8_t * add_rrdisp8(uint8_t * out, uint8_t src, uint8_t dst_base, int8_t disp, uint8_t size) | |
313 { | |
314 return x86_rrdisp8_sizedir(out, OP_ADD, src, dst_base, disp, size, 0); | |
315 } | |
316 | |
317 uint8_t * add_rdisp8r(uint8_t * out, uint8_t src_base, int8_t disp, uint8_t dst, uint8_t size) | |
318 { | |
319 return x86_rrdisp8_sizedir(out, OP_ADD, dst, src_base, disp, size, BIT_DIR); | |
320 } | |
321 | |
265 uint8_t * or_rr(uint8_t * out, uint8_t src, uint8_t dst, uint8_t size) | 322 uint8_t * or_rr(uint8_t * out, uint8_t src, uint8_t dst, uint8_t size) |
266 { | 323 { |
267 return x86_rr_sizedir(out, OP_OR, src, dst, size); | 324 return x86_rr_sizedir(out, OP_OR, src, dst, size); |
268 } | 325 } |
269 uint8_t * or_ir(uint8_t * out, int32_t val, uint8_t dst, uint8_t size) | 326 uint8_t * or_ir(uint8_t * out, int32_t val, uint8_t dst, uint8_t size) |
270 { | 327 { |
271 return x86_ir(out, OP_IMMED_ARITH, OP_EX_ORI, OP_OR, val, dst, size); | 328 return x86_ir(out, OP_IMMED_ARITH, OP_EX_ORI, OP_OR, val, dst, size); |
272 } | 329 } |
273 | 330 |
331 uint8_t * or_irdisp8(uint8_t * out, int32_t val, uint8_t dst_base, int8_t disp, uint8_t size) | |
332 { | |
333 return x86_irdisp8(out, OP_IMMED_ARITH, OP_EX_ORI, val, dst_base, disp, size); | |
334 } | |
335 | |
336 uint8_t * or_rrdisp8(uint8_t * out, uint8_t src, uint8_t dst_base, int8_t disp, uint8_t size) | |
337 { | |
338 return x86_rrdisp8_sizedir(out, OP_OR, src, dst_base, disp, size, 0); | |
339 } | |
340 | |
341 uint8_t * or_rdisp8r(uint8_t * out, uint8_t src_base, int8_t disp, uint8_t dst, uint8_t size) | |
342 { | |
343 return x86_rrdisp8_sizedir(out, OP_OR, dst, src_base, disp, size, BIT_DIR); | |
344 } | |
345 | |
274 uint8_t * and_rr(uint8_t * out, uint8_t src, uint8_t dst, uint8_t size) | 346 uint8_t * and_rr(uint8_t * out, uint8_t src, uint8_t dst, uint8_t size) |
275 { | 347 { |
276 return x86_rr_sizedir(out, OP_AND, src, dst, size); | 348 return x86_rr_sizedir(out, OP_AND, src, dst, size); |
277 } | 349 } |
278 | 350 |
279 uint8_t * and_ir(uint8_t * out, int32_t val, uint8_t dst, uint8_t size) | 351 uint8_t * and_ir(uint8_t * out, int32_t val, uint8_t dst, uint8_t size) |
280 { | 352 { |
281 return x86_ir(out, OP_IMMED_ARITH, OP_EX_ANDI, OP_AND, val, dst, size); | 353 return x86_ir(out, OP_IMMED_ARITH, OP_EX_ANDI, OP_AND, val, dst, size); |
282 } | 354 } |
283 | 355 |
356 uint8_t * and_irdisp8(uint8_t * out, int32_t val, uint8_t dst_base, int8_t disp, uint8_t size) | |
357 { | |
358 return x86_irdisp8(out, OP_IMMED_ARITH, OP_EX_ANDI, val, dst_base, disp, size); | |
359 } | |
360 | |
361 uint8_t * and_rrdisp8(uint8_t * out, uint8_t src, uint8_t dst_base, int8_t disp, uint8_t size) | |
362 { | |
363 return x86_rrdisp8_sizedir(out, OP_AND, src, dst_base, disp, size, 0); | |
364 } | |
365 | |
366 uint8_t * and_rdisp8r(uint8_t * out, uint8_t src_base, int8_t disp, uint8_t dst, uint8_t size) | |
367 { | |
368 return x86_rrdisp8_sizedir(out, OP_AND, dst, src_base, disp, size, BIT_DIR); | |
369 } | |
370 | |
284 uint8_t * xor_rr(uint8_t * out, uint8_t src, uint8_t dst, uint8_t size) | 371 uint8_t * xor_rr(uint8_t * out, uint8_t src, uint8_t dst, uint8_t size) |
285 { | 372 { |
286 return x86_rr_sizedir(out, OP_XOR, src, dst, size); | 373 return x86_rr_sizedir(out, OP_XOR, src, dst, size); |
287 } | 374 } |
288 | 375 |
289 uint8_t * xor_ir(uint8_t * out, int32_t val, uint8_t dst, uint8_t size) | 376 uint8_t * xor_ir(uint8_t * out, int32_t val, uint8_t dst, uint8_t size) |
290 { | 377 { |
291 return x86_ir(out, OP_IMMED_ARITH, OP_EX_XORI, OP_XOR, val, dst, size); | 378 return x86_ir(out, OP_IMMED_ARITH, OP_EX_XORI, OP_XOR, val, dst, size); |
292 } | 379 } |
293 | 380 |
381 uint8_t * xor_irdisp8(uint8_t * out, int32_t val, uint8_t dst_base, int8_t disp, uint8_t size) | |
382 { | |
383 return x86_irdisp8(out, OP_IMMED_ARITH, OP_EX_XORI, val, dst_base, disp, size); | |
384 } | |
385 | |
386 uint8_t * xor_rrdisp8(uint8_t * out, uint8_t src, uint8_t dst_base, int8_t disp, uint8_t size) | |
387 { | |
388 return x86_rrdisp8_sizedir(out, OP_XOR, src, dst_base, disp, size, 0); | |
389 } | |
390 | |
391 uint8_t * xor_rdisp8r(uint8_t * out, uint8_t src_base, int8_t disp, uint8_t dst, uint8_t size) | |
392 { | |
393 return x86_rrdisp8_sizedir(out, OP_XOR, dst, src_base, disp, size, BIT_DIR); | |
394 } | |
395 | |
294 uint8_t * sub_rr(uint8_t * out, uint8_t src, uint8_t dst, uint8_t size) | 396 uint8_t * sub_rr(uint8_t * out, uint8_t src, uint8_t dst, uint8_t size) |
295 { | 397 { |
296 return x86_rr_sizedir(out, OP_SUB, src, dst, size); | 398 return x86_rr_sizedir(out, OP_SUB, src, dst, size); |
297 } | 399 } |
298 | 400 |
299 uint8_t * sub_ir(uint8_t * out, int32_t val, uint8_t dst, uint8_t size) | 401 uint8_t * sub_ir(uint8_t * out, int32_t val, uint8_t dst, uint8_t size) |
300 { | 402 { |
301 return x86_ir(out, OP_IMMED_ARITH, OP_EX_SUBI, OP_SUB, val, dst, size); | 403 return x86_ir(out, OP_IMMED_ARITH, OP_EX_SUBI, OP_SUB, val, dst, size); |
302 } | 404 } |
303 | 405 |
406 uint8_t * sub_irdisp8(uint8_t * out, int32_t val, uint8_t dst_base, int8_t disp, uint8_t size) | |
407 { | |
408 return x86_irdisp8(out, OP_IMMED_ARITH, OP_EX_SUBI, val, dst_base, disp, size); | |
409 } | |
410 | |
411 uint8_t * sub_rrdisp8(uint8_t * out, uint8_t src, uint8_t dst_base, int8_t disp, uint8_t size) | |
412 { | |
413 return x86_rrdisp8_sizedir(out, OP_SUB, src, dst_base, disp, size, 0); | |
414 } | |
415 | |
416 uint8_t * sub_rdisp8r(uint8_t * out, uint8_t src_base, int8_t disp, uint8_t dst, uint8_t size) | |
417 { | |
418 return x86_rrdisp8_sizedir(out, OP_SUB, dst, src_base, disp, size, BIT_DIR); | |
419 } | |
420 | |
304 uint8_t * cmp_rr(uint8_t * out, uint8_t src, uint8_t dst, uint8_t size) | 421 uint8_t * cmp_rr(uint8_t * out, uint8_t src, uint8_t dst, uint8_t size) |
305 { | 422 { |
306 return x86_rr_sizedir(out, OP_CMP, src, dst, size); | 423 return x86_rr_sizedir(out, OP_CMP, src, dst, size); |
307 } | 424 } |
308 | 425 |
309 uint8_t * cmp_ir(uint8_t * out, int32_t val, uint8_t dst, uint8_t size) | 426 uint8_t * cmp_ir(uint8_t * out, int32_t val, uint8_t dst, uint8_t size) |
310 { | 427 { |
311 return x86_ir(out, OP_IMMED_ARITH, OP_EX_CMPI, OP_CMP, val, dst, size); | 428 return x86_ir(out, OP_IMMED_ARITH, OP_EX_CMPI, OP_CMP, val, dst, size); |
429 } | |
430 | |
431 uint8_t * cmp_irdisp8(uint8_t * out, int32_t val, uint8_t dst_base, int8_t disp, uint8_t size) | |
432 { | |
433 return x86_irdisp8(out, OP_IMMED_ARITH, OP_EX_CMPI, val, dst_base, disp, size); | |
434 } | |
435 | |
436 uint8_t * cmp_rrdisp8(uint8_t * out, uint8_t src, uint8_t dst_base, int8_t disp, uint8_t size) | |
437 { | |
438 return x86_rrdisp8_sizedir(out, OP_CMP, src, dst_base, disp, size, 0); | |
439 } | |
440 | |
441 uint8_t * cmp_rdisp8r(uint8_t * out, uint8_t src_base, int8_t disp, uint8_t dst, uint8_t size) | |
442 { | |
443 return x86_rrdisp8_sizedir(out, OP_CMP, dst, src_base, disp, size, BIT_DIR); | |
312 } | 444 } |
313 | 445 |
314 uint8_t * mov_rr(uint8_t * out, uint8_t src, uint8_t dst, uint8_t size) | 446 uint8_t * mov_rr(uint8_t * out, uint8_t src, uint8_t dst, uint8_t size) |
315 { | 447 { |
316 return x86_rr_sizedir(out, OP_MOV, src, dst, size); | 448 return x86_rr_sizedir(out, OP_MOV, src, dst, size); |
358 } | 490 } |
359 if (dst >= AH && dst <= BH) { | 491 if (dst >= AH && dst <= BH) { |
360 dst -= (AH-X86_AH); | 492 dst -= (AH-X86_AH); |
361 } | 493 } |
362 if (size == SZ_B) { | 494 if (size == SZ_B) { |
363 *(out++) = OP_MOV_I8R; | 495 *(out++) = OP_MOV_I8R | dst; |
364 } else if (size == SZ_Q && sign_extend) { | 496 } else if (size == SZ_Q && sign_extend) { |
365 *(out++) = OP_MOV_IEA | BIT_SIZE; | 497 *(out++) = OP_MOV_IEA | BIT_SIZE; |
366 *(out++) = MODE_REG_DIRECT | dst; | 498 *(out++) = MODE_REG_DIRECT | dst; |
367 } else { | 499 } else { |
368 *(out++) = OP_MOV_IR; | 500 *(out++) = OP_MOV_IR | dst; |
369 } | 501 } |
370 *(out++) = val; | 502 *(out++) = val; |
371 if (size != SZ_B) { | 503 if (size != SZ_B) { |
372 val >>= 8; | 504 val >>= 8; |
373 *(out++) = val; | 505 *(out++) = val; |
389 } | 521 } |
390 } | 522 } |
391 return out; | 523 return out; |
392 } | 524 } |
393 | 525 |
526 uint8_t * mov_irdisp8(uint8_t * out, int32_t val, uint8_t dst, int8_t disp, uint8_t size) | |
527 { | |
528 if (size == SZ_W) { | |
529 *(out++) = PRE_SIZE; | |
530 } | |
531 if (size == SZ_Q || dst >= R8 || (size == SZ_B && dst >= RSP && dst <= RDI)) { | |
532 *out = PRE_REX; | |
533 if (size == SZ_Q) { | |
534 *out |= REX_QUAD; | |
535 } | |
536 if (dst >= R8) { | |
537 *out |= REX_RM_FIELD; | |
538 dst -= (R8 - X86_R8); | |
539 } | |
540 out++; | |
541 } | |
542 if (dst >= AH && dst <= BH) { | |
543 dst -= (AH-X86_AH); | |
544 } | |
545 *(out++) = OP_MOV_IEA | (size == SZ_B ? 0 : BIT_SIZE); | |
546 *(out++) = MODE_REG_DISPLACE8 | dst; | |
547 *(out++) = disp; | |
548 | |
549 *(out++) = val; | |
550 if (size != SZ_B) { | |
551 val >>= 8; | |
552 *(out++) = val; | |
553 if (size != SZ_W) { | |
554 val >>= 8; | |
555 *(out++) = val; | |
556 val >>= 8; | |
557 *(out++) = val; | |
558 } | |
559 } | |
560 return out; | |
561 } | |
562 | |
394 uint8_t * pushf(uint8_t * out) | 563 uint8_t * pushf(uint8_t * out) |
395 { | 564 { |
396 *(out++) = OP_PUSHF; | 565 *(out++) = OP_PUSHF; |
397 return out; | 566 return out; |
398 } | 567 } |
449 *(out++) = OP2_SETCC | cc; | 618 *(out++) = OP2_SETCC | cc; |
450 *(out++) = MODE_REG_INDIRECT | dst; | 619 *(out++) = MODE_REG_INDIRECT | dst; |
451 return out; | 620 return out; |
452 } | 621 } |
453 | 622 |
454 uint8_t * jcc(uint8_t * out, uint8_t cc, int32_t disp) | 623 uint8_t * jcc(uint8_t * out, uint8_t cc, uint8_t * dest) |
455 { | 624 { |
625 ptrdiff_t disp = dest-(out+2); | |
456 if (disp <= 0x7F && disp >= -0x80) { | 626 if (disp <= 0x7F && disp >= -0x80) { |
457 *(out++) = OP_JCC | cc; | 627 *(out++) = OP_JCC | cc; |
458 *(out++) = disp; | 628 *(out++) = disp; |
459 } else { | 629 } else { |
460 *(out++) = PRE_2BYTE; | 630 disp = dest-(out+6); |
461 *(out++) = OP2_JCC | cc; | 631 if (disp <= 0x7FFFFFFF && disp >= -2147483648) { |
632 *(out++) = PRE_2BYTE; | |
633 *(out++) = OP2_JCC | cc; | |
634 *(out++) = disp; | |
635 disp >>= 8; | |
636 *(out++) = disp; | |
637 disp >>= 8; | |
638 *(out++) = disp; | |
639 disp >>= 8; | |
640 *(out++) = disp; | |
641 } else { | |
642 printf("%p - %p = %lX\n", dest, out + 6, disp); | |
643 return NULL; | |
644 } | |
645 } | |
646 return out; | |
647 } | |
648 | |
649 uint8_t * jmp(uint8_t * out, uint8_t * dest) | |
650 { | |
651 ptrdiff_t disp = dest-(out+2); | |
652 if (disp <= 0x7F && disp >= -0x80) { | |
653 *(out++) = OP_JMP_BYTE; | |
462 *(out++) = disp; | 654 *(out++) = disp; |
463 disp >>= 8; | 655 } else { |
464 *(out++) = disp; | 656 disp = dest-(out+5); |
465 disp >>= 8; | 657 if (disp <= 0x7FFFFFFF && disp >= -2147483648) { |
466 *(out++) = disp; | 658 *(out++) = OP_JMP; |
467 disp >>= 8; | 659 *(out++) = disp; |
468 *(out++) = disp; | 660 disp >>= 8; |
661 *(out++) = disp; | |
662 disp >>= 8; | |
663 *(out++) = disp; | |
664 disp >>= 8; | |
665 *(out++) = disp; | |
666 } else { | |
667 printf("%p - %p = %lX\n", dest, out + 6, disp); | |
668 return NULL; | |
669 } | |
469 } | 670 } |
470 return out; | 671 return out; |
471 } | 672 } |
472 | 673 |
473 uint8_t * call(uint8_t * out, uint8_t * fun) | 674 uint8_t * call(uint8_t * out, uint8_t * fun) |
481 disp >>= 8; | 682 disp >>= 8; |
482 *(out++) = disp; | 683 *(out++) = disp; |
483 disp >>= 8; | 684 disp >>= 8; |
484 *(out++) = disp; | 685 *(out++) = disp; |
485 } else { | 686 } else { |
486 //TODO: Implement far call | 687 //TODO: Implement far call??? |
487 printf("%p - %p = %ld, %d, %d, %d\n", fun, out + 5, disp, disp <= 0x7FFFFFFF, disp >= (-2147483648), -2147483648); | 688 printf("%p - %p = %lX\n", fun, out + 5, disp); |
488 return NULL; | 689 return NULL; |
489 } | 690 } |
490 return out; | 691 return out; |
491 } | 692 } |
492 | 693 |