Advance on 8086 emulator
This commit is contained in:
parent
6e7a6563d5
commit
a30f4f3287
46
lib/fcbparse.asm
Normal file
46
lib/fcbparse.asm
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
; Parse ASCIIZ string into FCB
|
||||||
|
; IN SI ptr to filename
|
||||||
|
; BX ptr to FCB
|
||||||
|
fcb_parse:
|
||||||
|
push di
|
||||||
|
push ax
|
||||||
|
mov di, bx
|
||||||
|
xor ax, ax
|
||||||
|
stosb
|
||||||
|
.cleanout:
|
||||||
|
push di
|
||||||
|
mov cx, 0x0A
|
||||||
|
mov al, 0x20
|
||||||
|
rep stosb
|
||||||
|
pop di
|
||||||
|
.base_loop:
|
||||||
|
call .read
|
||||||
|
cmp al, 0x2E
|
||||||
|
je .ext_start
|
||||||
|
cmp al, 0x20
|
||||||
|
je .ret
|
||||||
|
stosb
|
||||||
|
jmp .base_loop
|
||||||
|
.ext_start:
|
||||||
|
mov di, bx
|
||||||
|
add di, 9
|
||||||
|
.ext_loop:
|
||||||
|
call .read
|
||||||
|
cmp al, 0x20
|
||||||
|
je .ret
|
||||||
|
stosb
|
||||||
|
jmp .ext_loop
|
||||||
|
.read:
|
||||||
|
lodsb
|
||||||
|
test al, al
|
||||||
|
jz .eret
|
||||||
|
cmp al, 0x0D
|
||||||
|
je .eret
|
||||||
|
ret
|
||||||
|
.eret:
|
||||||
|
dec si
|
||||||
|
pop ax
|
||||||
|
.ret:
|
||||||
|
pop ax
|
||||||
|
pop di
|
||||||
|
ret
|
18
programs/lst2bin.asm
Normal file
18
programs/lst2bin.asm
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
org 0x100
|
||||||
|
|
||||||
|
jmp start
|
||||||
|
|
||||||
|
%include "fcbparse.asm"
|
||||||
|
|
||||||
|
fcb_in:
|
||||||
|
times 20 db 0
|
||||||
|
|
||||||
|
fcb_out:
|
||||||
|
times 20 db 0
|
||||||
|
|
||||||
|
start:
|
||||||
|
mov si, 0x81
|
||||||
|
mov bx, fcb_in
|
||||||
|
mov ax, 0x1234
|
||||||
|
call fcb_parse
|
||||||
|
ret
|
52
utils/emul.c
52
utils/emul.c
@ -13,6 +13,7 @@ union regset {
|
|||||||
int carry, zero;
|
int carry, zero;
|
||||||
|
|
||||||
uint16_t ip = 0x100;
|
uint16_t ip = 0x100;
|
||||||
|
uint16_t flags = 0;
|
||||||
uint16_t scratch;
|
uint16_t scratch;
|
||||||
uint16_t reg;
|
uint16_t reg;
|
||||||
int off;
|
int off;
|
||||||
@ -54,7 +55,29 @@ void dump() {
|
|||||||
printf("%s=%04X ", regnames[i], regset.r16[i]);
|
printf("%s=%04X ", regnames[i], regset.r16[i]);
|
||||||
}
|
}
|
||||||
printf("\n");
|
printf("\n");
|
||||||
printf("IP=%04X : %X\n", ip, mem[ip]);
|
printf("IP=%04X : %02X %02X\n", ip, mem[ip], mem[ip+1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void arith8(int op, int8_t* dst, int src) {
|
||||||
|
// I'll just assume this sign-extends
|
||||||
|
int t = *dst;
|
||||||
|
int p = *dst;
|
||||||
|
switch (op) {
|
||||||
|
case ADD: t += src; break;
|
||||||
|
case OR: t |= src; break;
|
||||||
|
case ADC: t += (src + carry); break;
|
||||||
|
case SBB: t -= (src + carry); break;
|
||||||
|
case AND: t &= src; break;
|
||||||
|
case SUB: t -= src; break;
|
||||||
|
case XOR: t ^= src; break;
|
||||||
|
case CMP: t -= src; break;
|
||||||
|
case TEST: t &= src; break;
|
||||||
|
}
|
||||||
|
zero=!t;
|
||||||
|
// I dont think the following is correct
|
||||||
|
carry=((t ^ p) >> 8) & 1;
|
||||||
|
if (op==CMP || op==TEST) return;
|
||||||
|
*dst = t;
|
||||||
}
|
}
|
||||||
|
|
||||||
void arith16(int op, int16_t* dst, int src) {
|
void arith16(int op, int16_t* dst, int src) {
|
||||||
@ -192,6 +215,28 @@ void step() {
|
|||||||
uint8_t opcode = mem[ip];
|
uint8_t opcode = mem[ip];
|
||||||
ip++;
|
ip++;
|
||||||
switch(opcode) {
|
switch(opcode) {
|
||||||
|
case 0x00: // ARITH r/m8,reg8
|
||||||
|
case 0x08:
|
||||||
|
case 0x10:
|
||||||
|
case 0x18:
|
||||||
|
case 0x20:
|
||||||
|
case 0x28:
|
||||||
|
case 0x30:
|
||||||
|
case 0x38:
|
||||||
|
modrm(BIT8);
|
||||||
|
arith8(opcode >> 3, &RM8, R8(reg));
|
||||||
|
break;
|
||||||
|
case 0x01: // ARITH r/m16,reg16
|
||||||
|
case 0x09:
|
||||||
|
case 0x11:
|
||||||
|
case 0x19:
|
||||||
|
case 0x21:
|
||||||
|
case 0x29:
|
||||||
|
case 0x31:
|
||||||
|
case 0x39:
|
||||||
|
modrm(BIT16);
|
||||||
|
arith16(opcode >> 3, &RM16, R16(reg));
|
||||||
|
break;
|
||||||
case 0x50 ... 0x57: // PUSH reg16
|
case 0x50 ... 0x57: // PUSH reg16
|
||||||
push(R16(opcode-0x50));
|
push(R16(opcode-0x50));
|
||||||
break;
|
break;
|
||||||
@ -216,6 +261,10 @@ void step() {
|
|||||||
modrm(BIT8);
|
modrm(BIT8);
|
||||||
RM8 = R8(reg);
|
RM8 = R8(reg);
|
||||||
break;
|
break;
|
||||||
|
case 0x89: // MOV r/m16,reg16
|
||||||
|
modrm(BIT16);
|
||||||
|
RM16 = R16(reg);
|
||||||
|
break;
|
||||||
case 0x8B: // MOV reg16,r/m16
|
case 0x8B: // MOV reg16,r/m16
|
||||||
modrm(BIT16);
|
modrm(BIT16);
|
||||||
R16(reg) = RM16;
|
R16(reg) = RM16;
|
||||||
@ -303,5 +352,6 @@ int main(int argc, char** argv) {
|
|||||||
fread(mem + ip, 1, sizeof(mem) - ip, fd);
|
fread(mem + ip, 1, sizeof(mem) - ip, fd);
|
||||||
while(1) {
|
while(1) {
|
||||||
step();
|
step();
|
||||||
|
dump();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user