mirror of
https://github.com/KarolS/millfork.git
synced 2024-08-17 11:29:00 +00:00
79 lines
2.1 KiB
Markdown
79 lines
2.1 KiB
Markdown
[< back to index](../index.md)
|
|
|
|
# 8086 support disclaimer
|
|
|
|
Millfork does not support Intel 8086 directly.
|
|
Instead, it generates Intel 8080 code and translates it automatically to 8086 machine code.
|
|
For convenience, Z80 instructions using `IX` are also translated.
|
|
|
|
This means that:
|
|
|
|
* code is going to be large and slow;
|
|
|
|
* there is no support for writing 8086 assembly;
|
|
|
|
* Millfork currently translates majority of Intel 8080 assembly instructions to 8086 machine code,
|
|
so you can write 8080/Z80 assembly instead.
|
|
|
|
For example, code like
|
|
|
|
asm {
|
|
LD HL, x
|
|
LD BC, i
|
|
ADD HL, BC
|
|
JP C, skip
|
|
LD A, IX(5)
|
|
LD (HL), A
|
|
skip:
|
|
}
|
|
|
|
is compiled to
|
|
|
|
MOV BX, x
|
|
MOV CX, i
|
|
ADD BX, CX
|
|
JNC .next
|
|
JMP skip
|
|
.next:
|
|
MOV AL, BYTE PTR [BP+5]
|
|
MOV BYTE PTR [BX], AL
|
|
skip:
|
|
|
|
Generated assembly output uses Intel 8086 syntax.
|
|
|
|
#### Major deficiencies of generated code
|
|
|
|
* hardware multiplication is not used
|
|
|
|
* many 16-bit operations are not used
|
|
|
|
* many operations are restricted to the `AL` register
|
|
|
|
* the overflow flag is not used
|
|
|
|
* `DAS` is not used
|
|
|
|
* conditional jumps are never optimized to short 2-byte jumps and always use 5 bytes
|
|
|
|
* the `SI` register is reloaded before every use
|
|
|
|
* the converter translates the `DAD` instruction (16-bit `ADD` on Z80) to `ADD`,
|
|
which may change behaviour of assembly code,
|
|
as 8080's `DAD` changes only the carry flag, and 8086's `ADD` changes many flags.
|
|
Luckily, this is not an issue with Millfork code, as the optimizer does not assume anything about flags after that instruction.
|
|
The proper sequence is `LAHF`/`ADD r1,r2`/`RCR SI,1`/`SAHF`/`RCL SI,1`, but it is obviously too slow.
|
|
|
|
#### Register mapping
|
|
|
|
The registers are translated as following:
|
|
|
|
A → AL
|
|
B → CH C → CL BC → CX
|
|
D → DH E → DL DE → DX
|
|
H → BH L → BL HL → BX
|
|
SP → SP
|
|
IX → BP
|
|
|
|
The `SI` register is used as a temporary register for holding the address in `LDAX`/`STAX`
|
|
(`LD (DE),A`/`LD(BC),A`/`LD A,(DE)`/`LD A,(BC)` on Z80).
|