Advance on 8086 emulator

This commit is contained in:
Nero 2019-10-01 21:35:01 +00:00
parent 6e7a6563d5
commit a30f4f3287
3 changed files with 115 additions and 1 deletions

46
lib/fcbparse.asm Normal file
View 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
View 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

View File

@ -13,6 +13,7 @@ union regset {
int carry, zero;
uint16_t ip = 0x100;
uint16_t flags = 0;
uint16_t scratch;
uint16_t reg;
int off;
@ -54,7 +55,29 @@ void dump() {
printf("%s=%04X ", regnames[i], regset.r16[i]);
}
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) {
@ -192,6 +215,28 @@ void step() {
uint8_t opcode = mem[ip];
ip++;
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
push(R16(opcode-0x50));
break;
@ -216,6 +261,10 @@ void step() {
modrm(BIT8);
RM8 = R8(reg);
break;
case 0x89: // MOV r/m16,reg16
modrm(BIT16);
RM16 = R16(reg);
break;
case 0x8B: // MOV reg16,r/m16
modrm(BIT16);
R16(reg) = RM16;
@ -303,5 +352,6 @@ int main(int argc, char** argv) {
fread(mem + ip, 1, sizeof(mem) - ip, fd);
while(1) {
step();
dump();
}
}