Re: an 8086 PC emulator
Posted: Fri Jun 17, 2011 1:12 pm
here's the code. what it does is exercise the CPU's EA calculation with a ton of different values in every addressing mode, then compare what it came up with against calculating the same using the ADD instruction.thepowersgang wrote:If you could provide that test program, that would be lovely. I hope to have this running DOS sometime soon
Code: Select all
; testea.asm - A program to test the Intel 8086 CPU's
; various addressing mode calculations. Designed to
; verify correct functionality of my 8086 PC emulator, Fake86.
org 100h
;cli
push cs
pop ds
mov si, offset banner
call printmsg
;call printmsg
mov ax, 0F000h
mov es, ax
jmp loopmain
disptest dw 1234h
loopmain:
mov cx, oper1
add cx, oper2
mov bx, oper1
mov si, oper2
lea ax, [bx+si]
cmp ax, cx
jz bxdi
mov si, offset strfailbxsi
call printmsg
bxdi:
mov bx, oper1
mov di, oper2
lea ax, [bx+di]
cmp ax, cx
jz bpsi
mov si, offset strfailbxdi
call printmsg
bpsi:
mov bp, oper1
mov si, oper2
lea ax, [bp+si]
cmp ax, cx
jz bpdi
mov si, offset strfailbpsi
call printmsg
bpdi:
mov bp, oper1
mov di, oper2
lea ax, [bp+di]
cmp ax, cx
jz testsi
mov si, offset strfailbpdi
call printmsg
testsi:
mov si, oper1
lea ax, [si]
cmp ax, oper1
jz testdi
mov si, offset strfailsi
call printmsg
testdi:
mov di, oper1
lea ax, [di]
cmp ax, oper1
jz testbx
mov si, offset strfaildi
call printmsg
testbx:
mov bx, oper1
lea ax, [bx]
cmp ax, oper1
jz disp16
mov si, offset strfailbx
call printmsg
disp16:
mov bx, oper1
lea ax, [bx+8000h]
add bx, 8000h
cmp ax, bx
jz disp8
mov si, offset strfaildisp16
call printmsg
disp8:
mov bx, oper1
db 8Dh, 01000111b, 80h ;lea ax, [bx+80h]
add bx, 0FF80h
cmp ax, bx
jz nexttest
mov si, offset strfaildisp8
call printmsg
nexttest:
add oper2, 80h
cmp oper2, 0
jnz loopmain
mov si, offset dot
call printmsg
add oper1, 80h
cmp oper1, 0h
jnz loopmain
mov si, offset strgood
call printmsg
finished:
ret
pass:
mov si, offset strgood
call printmsg
ret
fail:
mov si, offset strfail
call printmsg
jmp finished
printmsg:
mov ah, 0Eh
cld
lodsb
cmp al, 0
jz done
int 10h
jmp printmsg
done:
ret
banner db '8086 CPU effective address calculation test utility',13,10
db 'Written on 3/4/2011 by Mike Chambers',13,10,13,10
db 'Testing EA calcs, this may take several minutes.',13,10
db 'Testing addressing modes', 0
strgood db 'passed!',13,10,0
strfail db 'FAILED!',13,10,0
dot db '.',0
strfailbxsi db 'failure in [BX+SI]',13,10,0
strfailbxdi db 'failure in [BX+DI]',13,10,0
strfailbpsi db 'failure in [BP+SI]',13,10,0
strfailbpdi db 'failure in [BP+DI]',13,10,0
strfailsi db 'failure in [SI]',13,10,0
strfaildi db 'failure in [DI]',13,10,0
strfaildisp16 db 'failure in [BX+Disp16]',13,10,0
strfaildisp8 db 'failure in [BX+Disp8]',13,10,0
strfailbx db 'failure in [BX]',13,10,0
oper1 dw 0
oper2 dw 0
disp dw 0
and here's another one to test your conditional branching:
Code: Select all
; branch.asm - A program to test the Intel 8086 CPU's
; various conditional branching operations. Designed to
; verify corrent functionality of my 8086 PC emulator, Fake86.
org 100h
cli
push cs
pop ds
mov si, offset banner
call printmsg
testjc:
mov si, offset strjc
call printmsg
call blankflags
call setcf
jc testjc2
call fail
jmp testjnc
testjc2:
call blankflags
mov bx, offset testjnc
push bx
jc fail
pop bx ;not used, just cleaning up the stack
call pass
testjnc:
mov si, offset strjnc
call printmsg
call blankflags
jnc testjnc2
call fail
jmp testjz
testjnc2:
call blankflags
call setcf
mov bx, offset testjz
push bx
jnc fail
pop bx
call pass
testjz:
mov si, offset strjz
call printmsg
call blankflags
call setzf
jz testjz2
call fail
jmp testjnz
testjz2:
call blankflags
mov bx, offset testjnz
push bx
jz fail
pop bx
call pass
testjnz:
mov si, offset strjnz
call printmsg
call blankflags
jnz testjnz2
call fail
jmp testjs
testjnz2:
call blankflags
call setzf
mov bx, offset testjs
push bx
jnz fail
pop bx
call pass
testjs:
mov si, offset strjs
call printmsg
call blankflags
call setsf
js testjs2
call fail
jmp testjns
testjs2:
call blankflags
mov bx, offset testjns
push bx
js fail
pop bx
call pass
testjns:
mov si, offset strjns
call printmsg
call blankflags
jns testjns2
call fail
jmp testjo
testjns2:
call blankflags
call setsf
mov bx, offset testjo
push bx
jns fail
pop bx
call pass
testjo:
mov si, offset strjo
call printmsg
call blankflags
call setof
jo testjo2
call fail
jmp testjno
testjo2:
call blankflags
mov bx, offset testjno
push bx
jo fail
pop bx
call pass
testjno:
mov si, offset strjno
call printmsg
call blankflags
jno testjno2
call fail
jmp testjp
testjno2:
call blankflags
call setof
mov bx, offset testjp
push bx
jno fail
pop bx
call pass
testjp:
mov si, offset strjp
call printmsg
call blankflags
call setpf
jp testjp2
call fail
jmp testjnp
testjp2:
call blankflags
mov bx, offset testjnp
push bx
jp fail
pop bx
call pass
testjnp:
mov si, offset strjnp
call printmsg
call blankflags
jnp testjnp2
call fail
jmp testja
testjnp2:
call blankflags
call setpf
mov bx, offset testja
push bx
jnp fail
pop bx
call pass
testja:
mov si, offset strja
call printmsg
call blankflags ;case 1
ja testja2
call fail
jmp testjbe
testja2: ;case 2
call blankflags
call setcf
mov bx, offset testjbe
push bx
ja fail
pop bx
testja3:
call blankflags
call setzf
mov bx, offset testjbe
push bx
ja fail
pop bx
testja4:
call blankflags
call setcf
call setzf
mov bx, offset testjbe
push bx
ja fail
pop bx
call pass
testjbe:
mov si, offset strjbe
call printmsg
call blankflags ;case 1
call setcf
jbe testjbe2
call fail
jmp testjg
testjbe2:
call blankflags
call setzf
jbe testjbe3
call fail
jmp testjg
testjbe3:
call blankflags
call setcf
call setzf
jbe testjbe4
call fail
jmp testjg
testjbe4:
call blankflags
mov bx, offset testjg
push bx
jbe fail
pop bx
call pass
testjg:
mov si, offset strjg
call printmsg
call blankflags
jg testjg2:
call fail
jmp testjge
testjg2:
call blankflags
call setzf
mov bx, offset testjge
push bx
jg fail
pop bx
testjg3:
call blankflags
call setsf
call setzf
mov bx, offset testjge
push bx
jg fail
pop bx
testjg4:
call blankflags
call setof
call setzf
mov bx, offset testjge
push bx
jg fail
pop bx
testjg5:
call blankflags
call setsf
call setof
call setzf
mov bx, offset testjge
push bx
jg fail
pop bx
testjg6:
call blankflags
call setsf
call setof
mov bx, offset testjge
push bx
jg pass
pop bx
call fail
testjge:
mov si, offset strjge
call printmsg
call blankflags
jge testjge2
call fail
jmp testjl
testjge2:
call blankflags
call setsf
mov bx, offset testjl
push bx
jge fail
pop bx
testjge3:
call blankflags
call setof
mov bx, offset testjl
push bx
jge fail
pop bx
call pass
testjl:
mov si, offset strjl
call printmsg
call blankflags
call setsf
jl testjl2
call fail
jmp testjle
testjl2:
call blankflags
call setof
jl testjl3
call fail
jmp testjle
testjl3:
call blankflags
call setsf
call setof
mov bx, offset testjle
push bx
jl fail
pop bx
testjl4:
call blankflags
mov bx, offset testjle
push bx
jl fail
pop bx
call pass
testjle:
mov si, offset strjle
call printmsg
call blankflags
call setzf
jle testjle2
call fail
jmp finished
testjle2:
call blankflags
call setsf
jle testjle3
call fail
jmp finished
testjle3:
call blankflags
call setof
jle testjle4
call fail
jmp finished
testjle4:
call blankflags
call setsf
call setzf
jle testjle5
call fail
jmp finished
testjle5:
call blankflags
call setof
call setzf
jle testjle6
call fail
jmp finished
testjle6:
call blankflags
call setsf
call setof
call setzf
jle testjle7
call fail
jmp finished
testjle7:
call blankflags
mov bx, offset finished
push bx
jle fail
call pass
finished:
ret
pass:
mov si, offset strgood
call printmsg
ret
fail:
mov si, offset strfail
call printmsg
ret
blankflags:
xor ax, ax
push ax
popf
ret
setcf:
stc
ret
setof:
pushf
pop ax
or ah, 00001000b
push ax
popf
ret
setsf:
pushf
pop ax
or al, 10000000b
push ax
popf
ret
setzf:
pushf
pop ax
or al, 01000000b
push ax
popf
ret
setpf:
pushf
pop ax
or al, 00000100b
push ax
popf
ret
printmsg:
mov ah, 0Eh
cld
lodsb
cmp al, 0
jz done
int 10h
jmp printmsg
done:
ret
banner db '8086 CPU conditional branch test utility',13,10
db 'Written on 3/4/2011 by Mike Chambers',13,10,13,10,0
strjc db 'Testing JC/JB/JNAE (jump if CF=1)... ',0
strjnc db 'Testing JNC/JNB/JAE (jump if CF=0)... ',0
strjz db 'Testing JZ/JE (jump if ZF=1)... ',0
strjnz db 'Testing JNZ/JNE (jump if ZF=0)... ',0
strjs db 'Testing JS (jump if SF=1)... ',0
strjns db 'Testing JNS (jump if SF=0)... ',0
strjo db 'Testing JO (jump if OF=1)... ',0
strjno db 'Testing JNO (jump if OF=0)... ',0
strjp db 'Testing JP/JPE (jump if PF=1)... ',0
strjnp db 'Testing JNP/JPO (jump if PF=0)... ',0
strja db 'Testing JA/JNBE (jump if CF=0 and ZF=0)... ',0
strjbe db 'Testing JBE/JNA (jump if CF=1 or ZF=1)... ',0
strjg db 'Testing JG/JNLE (jump if SF=OF and ZF=0)... ',0
strjge db 'Testing JGE/JNL (jump if SF=OF)... ',0
strjl db 'Testing JL/JNGE (jump if SF<>OF)... ',0
strjle db 'Testing JLE/JNG (jump if SF<>OF or ZF=1)... ',0
strgood db 'passed!',13,10,0
strfail db 'FAILED!',13,10,0