perfaware/part1: Support listing 0050"
This commit is contained in:
parent
00ad047d9a
commit
bd3dc5f2bc
@ -175,3 +175,18 @@ nasm %build_dir_listing_0049%_disassembled.asm
|
|||||||
|
|
||||||
fc /B %build_dir_listing_0049% %build_dir_listing_0049%_disassembled || exit /b 1
|
fc /B %build_dir_listing_0049% %build_dir_listing_0049%_disassembled || exit /b 1
|
||||||
fc /N %build_dir_listing_0049%.txt %build_dir_listing_0049%_disassembled.txt || exit /b 1
|
fc /N %build_dir_listing_0049%.txt %build_dir_listing_0049%_disassembled.txt || exit /b 1
|
||||||
|
|
||||||
|
REM ================================================================================================
|
||||||
|
set listing_0050=listing_0050_challenge_jumps
|
||||||
|
set build_dir_listing_0050=%build_dir%\%listing_0050%
|
||||||
|
|
||||||
|
copy /Y %script_dir%\%listing_0050% %build_dir% 1>NUL
|
||||||
|
copy /Y %script_dir%\%listing_0050%.txt %build_dir% 1>NUL
|
||||||
|
|
||||||
|
%build_dir%\sim8086.exe --exec --log-instruction-ptr %build_dir_listing_0050% > %build_dir_listing_0050%_disassembled.txt
|
||||||
|
%build_dir%\sim8086.exe %build_dir_listing_0050% > %build_dir_listing_0050%_disassembled.asm
|
||||||
|
|
||||||
|
nasm %build_dir_listing_0050%_disassembled.asm
|
||||||
|
|
||||||
|
fc /B %build_dir_listing_0050% %build_dir_listing_0050%_disassembled || exit /b 1
|
||||||
|
fc /N %build_dir_listing_0050%.txt %build_dir_listing_0050%_disassembled.txt || exit /b 1
|
||||||
|
BIN
part1/listing_0050_challenge_jumps
Normal file
BIN
part1/listing_0050_challenge_jumps
Normal file
Binary file not shown.
38
part1/listing_0050_challenge_jumps.asm
Normal file
38
part1/listing_0050_challenge_jumps.asm
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
; ========================================================================
|
||||||
|
;
|
||||||
|
; (C) Copyright 2023 by Molly Rocket, Inc., All Rights Reserved.
|
||||||
|
;
|
||||||
|
; This software is provided 'as-is', without any express or implied
|
||||||
|
; warranty. In no event will the authors be held liable for any damages
|
||||||
|
; arising from the use of this software.
|
||||||
|
;
|
||||||
|
; Please see https://computerenhance.com for further information
|
||||||
|
;
|
||||||
|
; ========================================================================
|
||||||
|
|
||||||
|
; ========================================================================
|
||||||
|
; LISTING 50
|
||||||
|
; ========================================================================
|
||||||
|
|
||||||
|
bits 16
|
||||||
|
|
||||||
|
mov ax, 10
|
||||||
|
mov bx, 10
|
||||||
|
mov cx, 10
|
||||||
|
|
||||||
|
label_0:
|
||||||
|
cmp bx, cx
|
||||||
|
je label_1
|
||||||
|
|
||||||
|
add ax, 1
|
||||||
|
jp label_2
|
||||||
|
|
||||||
|
label_1:
|
||||||
|
sub bx, 5
|
||||||
|
jb label_3
|
||||||
|
|
||||||
|
label_2:
|
||||||
|
sub cx, 2
|
||||||
|
|
||||||
|
label_3:
|
||||||
|
loopnz label_0
|
38
part1/listing_0050_challenge_jumps.txt
Normal file
38
part1/listing_0050_challenge_jumps.txt
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
--- test\listing_0050_challenge_jumps execution ---
|
||||||
|
mov ax, 10 ; ax:0x0->0xa ip:0x0->0x3
|
||||||
|
mov bx, 10 ; bx:0x0->0xa ip:0x3->0x6
|
||||||
|
mov cx, 10 ; cx:0x0->0xa ip:0x6->0x9
|
||||||
|
cmp bx, cx ; ip:0x9->0xb flags:->PZ
|
||||||
|
je $+7 ; ip:0xb->0x12
|
||||||
|
sub bx, 5 ; bx:0xa->0x5 ip:0x12->0x15 flags:PZ->P
|
||||||
|
jb $+5 ; ip:0x15->0x17
|
||||||
|
sub cx, 2 ; cx:0xa->0x8 ip:0x17->0x1a flags:P->
|
||||||
|
loopnz $-17 ; cx:0x8->0x7 ip:0x1a->0x9
|
||||||
|
cmp bx, cx ; ip:0x9->0xb flags:->CAS
|
||||||
|
je $+7 ; ip:0xb->0xd
|
||||||
|
add ax, 1 ; ax:0xa->0xb ip:0xd->0x10 flags:CAS->
|
||||||
|
jp $+7 ; ip:0x10->0x12
|
||||||
|
sub bx, 5 ; bx:0x5->0x0 ip:0x12->0x15 flags:->PZ
|
||||||
|
jb $+5 ; ip:0x15->0x17
|
||||||
|
sub cx, 2 ; cx:0x7->0x5 ip:0x17->0x1a flags:PZ->P
|
||||||
|
loopnz $-17 ; cx:0x5->0x4 ip:0x1a->0x9
|
||||||
|
cmp bx, cx ; ip:0x9->0xb flags:P->CPAS
|
||||||
|
je $+7 ; ip:0xb->0xd
|
||||||
|
add ax, 1 ; ax:0xb->0xc ip:0xd->0x10 flags:CPAS->P
|
||||||
|
jp $+7 ; ip:0x10->0x17
|
||||||
|
sub cx, 2 ; cx:0x4->0x2 ip:0x17->0x1a flags:P->
|
||||||
|
loopnz $-17 ; cx:0x2->0x1 ip:0x1a->0x9
|
||||||
|
cmp bx, cx ; ip:0x9->0xb flags:->CPAS
|
||||||
|
je $+7 ; ip:0xb->0xd
|
||||||
|
add ax, 1 ; ax:0xc->0xd ip:0xd->0x10 flags:CPAS->
|
||||||
|
jp $+7 ; ip:0x10->0x12
|
||||||
|
sub bx, 5 ; bx:0x0->0xfffb ip:0x12->0x15 flags:->CAS
|
||||||
|
jb $+5 ; ip:0x15->0x1a
|
||||||
|
loopnz $-17 ; cx:0x1->0x0 ip:0x1a->0x1c
|
||||||
|
|
||||||
|
Final registers:
|
||||||
|
ax: 0x000d (13)
|
||||||
|
bx: 0xfffb (65531)
|
||||||
|
ip: 0x001c (28)
|
||||||
|
flags: CAS
|
||||||
|
|
181
part1/sim8086.c
181
part1/sim8086.c
@ -196,6 +196,27 @@ S86_Str8 S86_MnemonicOpStr8(S86_MnemonicOp type)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
S86_Str8 S86_RegisterFileRegArrayStr8(S86_RegisterFileRegArray type)
|
||||||
|
{
|
||||||
|
S86_Str8 result = {0};
|
||||||
|
switch (type) {
|
||||||
|
case S86_RegisterFileRegArray_AX: result = S86_MnemonicOpStr8(S86_MnemonicOp_AX); break;
|
||||||
|
case S86_RegisterFileRegArray_BX: result = S86_MnemonicOpStr8(S86_MnemonicOp_BX); break;
|
||||||
|
case S86_RegisterFileRegArray_CX: result = S86_MnemonicOpStr8(S86_MnemonicOp_CX); break;
|
||||||
|
case S86_RegisterFileRegArray_DX: result = S86_MnemonicOpStr8(S86_MnemonicOp_DX); break;
|
||||||
|
case S86_RegisterFileRegArray_SP: result = S86_MnemonicOpStr8(S86_MnemonicOp_SP); break;
|
||||||
|
case S86_RegisterFileRegArray_BP: result = S86_MnemonicOpStr8(S86_MnemonicOp_BP); break;
|
||||||
|
case S86_RegisterFileRegArray_SI: result = S86_MnemonicOpStr8(S86_MnemonicOp_SI); break;
|
||||||
|
case S86_RegisterFileRegArray_DI: result = S86_MnemonicOpStr8(S86_MnemonicOp_DI); break;
|
||||||
|
case S86_RegisterFileRegArray_ES: result = S86_MnemonicOpStr8(S86_MnemonicOp_ES); break;
|
||||||
|
case S86_RegisterFileRegArray_CS: result = S86_MnemonicOpStr8(S86_MnemonicOp_DS); break;
|
||||||
|
case S86_RegisterFileRegArray_SS: result = S86_MnemonicOpStr8(S86_MnemonicOp_SS); break;
|
||||||
|
case S86_RegisterFileRegArray_DS: result = S86_MnemonicOpStr8(S86_MnemonicOp_DS); break;
|
||||||
|
case S86_RegisterFileRegArray_Count: break;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
void S86_PrintOpcodeMnemonicOp(S86_Opcode opcode, bool src)
|
void S86_PrintOpcodeMnemonicOp(S86_Opcode opcode, bool src)
|
||||||
{
|
{
|
||||||
// TODO: It sucks to have these enums that specify source or dest because
|
// TODO: It sucks to have these enums that specify source or dest because
|
||||||
@ -1213,31 +1234,31 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
S86_RegisterFile register_file = {0};
|
S86_RegisterFile register_file = {0};
|
||||||
S86_MnemonicOpToRegisterFileMap mnemonic_op_to_register_file_map[] = {
|
S86_MnemonicOpToRegisterFileMap mnemonic_op_to_register_file_map[] = {
|
||||||
{.mnemonic_op = S86_MnemonicOp_AX, .mnemonic_op_reg16 = S86_MnemonicOp_AX, .reg = ®ister_file.ax, .byte = S86_RegisterByte_Nil},
|
{.mnemonic_op = S86_MnemonicOp_AX, .mnemonic_op_reg16 = S86_MnemonicOp_AX, .reg = ®ister_file.reg.file.ax, .byte = S86_RegisterByte_Nil},
|
||||||
{.mnemonic_op = S86_MnemonicOp_AL, .mnemonic_op_reg16 = S86_MnemonicOp_AX, .reg = ®ister_file.ax, .byte = S86_RegisterByte_Lo},
|
{.mnemonic_op = S86_MnemonicOp_AL, .mnemonic_op_reg16 = S86_MnemonicOp_AX, .reg = ®ister_file.reg.file.ax, .byte = S86_RegisterByte_Lo},
|
||||||
{.mnemonic_op = S86_MnemonicOp_AH, .mnemonic_op_reg16 = S86_MnemonicOp_AX, .reg = ®ister_file.ax, .byte = S86_RegisterByte_Hi},
|
{.mnemonic_op = S86_MnemonicOp_AH, .mnemonic_op_reg16 = S86_MnemonicOp_AX, .reg = ®ister_file.reg.file.ax, .byte = S86_RegisterByte_Hi},
|
||||||
|
|
||||||
{.mnemonic_op = S86_MnemonicOp_CX, .mnemonic_op_reg16 = S86_MnemonicOp_CX, .reg = ®ister_file.cx, .byte = S86_RegisterByte_Nil},
|
{.mnemonic_op = S86_MnemonicOp_CX, .mnemonic_op_reg16 = S86_MnemonicOp_CX, .reg = ®ister_file.reg.file.cx, .byte = S86_RegisterByte_Nil},
|
||||||
{.mnemonic_op = S86_MnemonicOp_CL, .mnemonic_op_reg16 = S86_MnemonicOp_CX, .reg = ®ister_file.cx, .byte = S86_RegisterByte_Lo},
|
{.mnemonic_op = S86_MnemonicOp_CL, .mnemonic_op_reg16 = S86_MnemonicOp_CX, .reg = ®ister_file.reg.file.cx, .byte = S86_RegisterByte_Lo},
|
||||||
{.mnemonic_op = S86_MnemonicOp_CH, .mnemonic_op_reg16 = S86_MnemonicOp_CX, .reg = ®ister_file.cx, .byte = S86_RegisterByte_Lo},
|
{.mnemonic_op = S86_MnemonicOp_CH, .mnemonic_op_reg16 = S86_MnemonicOp_CX, .reg = ®ister_file.reg.file.cx, .byte = S86_RegisterByte_Lo},
|
||||||
|
|
||||||
{.mnemonic_op = S86_MnemonicOp_DX, .mnemonic_op_reg16 = S86_MnemonicOp_DX, .reg = ®ister_file.dx, .byte = S86_RegisterByte_Nil},
|
{.mnemonic_op = S86_MnemonicOp_DX, .mnemonic_op_reg16 = S86_MnemonicOp_DX, .reg = ®ister_file.reg.file.dx, .byte = S86_RegisterByte_Nil},
|
||||||
{.mnemonic_op = S86_MnemonicOp_DL, .mnemonic_op_reg16 = S86_MnemonicOp_DX, .reg = ®ister_file.dx, .byte = S86_RegisterByte_Lo},
|
{.mnemonic_op = S86_MnemonicOp_DL, .mnemonic_op_reg16 = S86_MnemonicOp_DX, .reg = ®ister_file.reg.file.dx, .byte = S86_RegisterByte_Lo},
|
||||||
{.mnemonic_op = S86_MnemonicOp_DH, .mnemonic_op_reg16 = S86_MnemonicOp_DX, .reg = ®ister_file.dx, .byte = S86_RegisterByte_Hi},
|
{.mnemonic_op = S86_MnemonicOp_DH, .mnemonic_op_reg16 = S86_MnemonicOp_DX, .reg = ®ister_file.reg.file.dx, .byte = S86_RegisterByte_Hi},
|
||||||
|
|
||||||
{.mnemonic_op = S86_MnemonicOp_BX, .mnemonic_op_reg16 = S86_MnemonicOp_BX, .reg = ®ister_file.bx, .byte = S86_RegisterByte_Nil},
|
{.mnemonic_op = S86_MnemonicOp_BX, .mnemonic_op_reg16 = S86_MnemonicOp_BX, .reg = ®ister_file.reg.file.bx, .byte = S86_RegisterByte_Nil},
|
||||||
{.mnemonic_op = S86_MnemonicOp_BL, .mnemonic_op_reg16 = S86_MnemonicOp_BX, .reg = ®ister_file.bx, .byte = S86_RegisterByte_Lo},
|
{.mnemonic_op = S86_MnemonicOp_BL, .mnemonic_op_reg16 = S86_MnemonicOp_BX, .reg = ®ister_file.reg.file.bx, .byte = S86_RegisterByte_Lo},
|
||||||
{.mnemonic_op = S86_MnemonicOp_BH, .mnemonic_op_reg16 = S86_MnemonicOp_BX, .reg = ®ister_file.bx, .byte = S86_RegisterByte_Hi},
|
{.mnemonic_op = S86_MnemonicOp_BH, .mnemonic_op_reg16 = S86_MnemonicOp_BX, .reg = ®ister_file.reg.file.bx, .byte = S86_RegisterByte_Hi},
|
||||||
|
|
||||||
{.mnemonic_op = S86_MnemonicOp_SP, .mnemonic_op_reg16 = S86_MnemonicOp_SP, .reg = ®ister_file.sp, .byte = S86_RegisterByte_Nil},
|
{.mnemonic_op = S86_MnemonicOp_SP, .mnemonic_op_reg16 = S86_MnemonicOp_SP, .reg = ®ister_file.reg.file.sp, .byte = S86_RegisterByte_Nil},
|
||||||
{.mnemonic_op = S86_MnemonicOp_BP, .mnemonic_op_reg16 = S86_MnemonicOp_BP, .reg = ®ister_file.bp, .byte = S86_RegisterByte_Nil},
|
{.mnemonic_op = S86_MnemonicOp_BP, .mnemonic_op_reg16 = S86_MnemonicOp_BP, .reg = ®ister_file.reg.file.bp, .byte = S86_RegisterByte_Nil},
|
||||||
{.mnemonic_op = S86_MnemonicOp_SI, .mnemonic_op_reg16 = S86_MnemonicOp_SI, .reg = ®ister_file.si, .byte = S86_RegisterByte_Nil},
|
{.mnemonic_op = S86_MnemonicOp_SI, .mnemonic_op_reg16 = S86_MnemonicOp_SI, .reg = ®ister_file.reg.file.si, .byte = S86_RegisterByte_Nil},
|
||||||
{.mnemonic_op = S86_MnemonicOp_DI, .mnemonic_op_reg16 = S86_MnemonicOp_DI, .reg = ®ister_file.di, .byte = S86_RegisterByte_Nil},
|
{.mnemonic_op = S86_MnemonicOp_DI, .mnemonic_op_reg16 = S86_MnemonicOp_DI, .reg = ®ister_file.reg.file.di, .byte = S86_RegisterByte_Nil},
|
||||||
|
|
||||||
{.mnemonic_op = S86_MnemonicOp_ES, .mnemonic_op_reg16 = S86_MnemonicOp_ES, .reg = ®ister_file.es, .byte = S86_RegisterByte_Nil},
|
{.mnemonic_op = S86_MnemonicOp_ES, .mnemonic_op_reg16 = S86_MnemonicOp_ES, .reg = ®ister_file.reg.file.es, .byte = S86_RegisterByte_Nil},
|
||||||
{.mnemonic_op = S86_MnemonicOp_CS, .mnemonic_op_reg16 = S86_MnemonicOp_CS, .reg = ®ister_file.cs, .byte = S86_RegisterByte_Nil},
|
{.mnemonic_op = S86_MnemonicOp_CS, .mnemonic_op_reg16 = S86_MnemonicOp_CS, .reg = ®ister_file.reg.file.cs, .byte = S86_RegisterByte_Nil},
|
||||||
{.mnemonic_op = S86_MnemonicOp_SS, .mnemonic_op_reg16 = S86_MnemonicOp_SS, .reg = ®ister_file.ss, .byte = S86_RegisterByte_Nil},
|
{.mnemonic_op = S86_MnemonicOp_SS, .mnemonic_op_reg16 = S86_MnemonicOp_SS, .reg = ®ister_file.reg.file.ss, .byte = S86_RegisterByte_Nil},
|
||||||
{.mnemonic_op = S86_MnemonicOp_DS, .mnemonic_op_reg16 = S86_MnemonicOp_DS, .reg = ®ister_file.ds, .byte = S86_RegisterByte_Nil},
|
{.mnemonic_op = S86_MnemonicOp_DS, .mnemonic_op_reg16 = S86_MnemonicOp_DS, .reg = ®ister_file.reg.file.ds, .byte = S86_RegisterByte_Nil},
|
||||||
};
|
};
|
||||||
|
|
||||||
// NOTE: Count opcodes, allocate then decode in 1 swoop
|
// NOTE: Count opcodes, allocate then decode in 1 swoop
|
||||||
@ -1298,7 +1319,7 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: Simulate instruction ==============================================================
|
// NOTE: Simulate instruction ==============================================================
|
||||||
S86_RegisterFileFlags prev_flags = register_file.flags;
|
S86_RegisterFile prev_register_file = register_file;
|
||||||
switch (opcode->mnemonic) {
|
switch (opcode->mnemonic) {
|
||||||
case S86_Mnemonic_PUSH: /*FALLTHRU*/
|
case S86_Mnemonic_PUSH: /*FALLTHRU*/
|
||||||
case S86_Mnemonic_POP: /*FALLTHRU*/
|
case S86_Mnemonic_POP: /*FALLTHRU*/
|
||||||
@ -1346,12 +1367,9 @@ int main(int argc, char **argv)
|
|||||||
case S86_Mnemonic_CALL: /*FALLTHRU*/
|
case S86_Mnemonic_CALL: /*FALLTHRU*/
|
||||||
case S86_Mnemonic_JMP: /*FALLTHRU*/
|
case S86_Mnemonic_JMP: /*FALLTHRU*/
|
||||||
case S86_Mnemonic_RET: /*FALLTHRU*/
|
case S86_Mnemonic_RET: /*FALLTHRU*/
|
||||||
case S86_Mnemonic_JE_JZ: /*FALLTHRU*/
|
|
||||||
case S86_Mnemonic_JL_JNGE: /*FALLTHRU*/
|
case S86_Mnemonic_JL_JNGE: /*FALLTHRU*/
|
||||||
case S86_Mnemonic_JLE_JNG: /*FALLTHRU*/
|
case S86_Mnemonic_JLE_JNG: /*FALLTHRU*/
|
||||||
case S86_Mnemonic_JB_JNAE: /*FALLTHRU*/
|
|
||||||
case S86_Mnemonic_JBE_JNA: /*FALLTHRU*/
|
case S86_Mnemonic_JBE_JNA: /*FALLTHRU*/
|
||||||
case S86_Mnemonic_JP_JPE: /*FALLTHRU*/
|
|
||||||
case S86_Mnemonic_JO: /*FALLTHRU*/
|
case S86_Mnemonic_JO: /*FALLTHRU*/
|
||||||
case S86_Mnemonic_JS: /*FALLTHRU*/
|
case S86_Mnemonic_JS: /*FALLTHRU*/
|
||||||
case S86_Mnemonic_JNL_JGE: /*FALLTHRU*/
|
case S86_Mnemonic_JNL_JGE: /*FALLTHRU*/
|
||||||
@ -1363,7 +1381,6 @@ int main(int argc, char **argv)
|
|||||||
case S86_Mnemonic_JNS: /*FALLTHRU*/
|
case S86_Mnemonic_JNS: /*FALLTHRU*/
|
||||||
case S86_Mnemonic_LOOP: /*FALLTHRU*/
|
case S86_Mnemonic_LOOP: /*FALLTHRU*/
|
||||||
case S86_Mnemonic_LOOPZ_LOOPE: /*FALLTHRU*/
|
case S86_Mnemonic_LOOPZ_LOOPE: /*FALLTHRU*/
|
||||||
case S86_Mnemonic_LOOPNZ_LOOPNE: /*FALLTHRU*/
|
|
||||||
case S86_Mnemonic_JCXZ: /*FALLTHRU*/
|
case S86_Mnemonic_JCXZ: /*FALLTHRU*/
|
||||||
case S86_Mnemonic_INT: /*FALLTHRU*/
|
case S86_Mnemonic_INT: /*FALLTHRU*/
|
||||||
case S86_Mnemonic_INT3: /*FALLTHRU*/
|
case S86_Mnemonic_INT3: /*FALLTHRU*/
|
||||||
@ -1390,7 +1407,6 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
S86_ASSERT(dest_map);
|
S86_ASSERT(dest_map);
|
||||||
|
|
||||||
uint16_t prev_dest = dest_map->reg->word;
|
|
||||||
bool byte_op = opcode->dest >= S86_MnemonicOp_AL && opcode->dest <= S86_MnemonicOp_BH;
|
bool byte_op = opcode->dest >= S86_MnemonicOp_AL && opcode->dest <= S86_MnemonicOp_BH;
|
||||||
if (opcode->src == S86_MnemonicOp_Immediate) {
|
if (opcode->src == S86_MnemonicOp_Immediate) {
|
||||||
if (byte_op) {
|
if (byte_op) {
|
||||||
@ -1413,9 +1429,6 @@ int main(int argc, char **argv)
|
|||||||
else
|
else
|
||||||
dest_map->reg->word = src_map->reg->word;
|
dest_map->reg->word = src_map->reg->word;
|
||||||
}
|
}
|
||||||
|
|
||||||
S86_Str8 dest_reg16 = S86_MnemonicOpStr8(dest_map->mnemonic_op_reg16);
|
|
||||||
S86_PrintFmt(" ; %.*s:0x%x->0x%x ", S86_STR8_FMT(dest_reg16), prev_dest, dest_map->reg->word);
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case S86_Mnemonic_ADD: /*FALLTHRU*/
|
case S86_Mnemonic_ADD: /*FALLTHRU*/
|
||||||
@ -1431,7 +1444,6 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
bool subtract = opcode->mnemonic != S86_Mnemonic_ADD;
|
bool subtract = opcode->mnemonic != S86_Mnemonic_ADD;
|
||||||
S86_Register16 dest = *dest_map->reg;
|
S86_Register16 dest = *dest_map->reg;
|
||||||
S86_Register16 prev_dest = dest;
|
|
||||||
bool byte_op = opcode->dest >= S86_MnemonicOp_AL && opcode->dest <= S86_MnemonicOp_BH;
|
bool byte_op = opcode->dest >= S86_MnemonicOp_AL && opcode->dest <= S86_MnemonicOp_BH;
|
||||||
|
|
||||||
uint16_t src = 0;
|
uint16_t src = 0;
|
||||||
@ -1518,46 +1530,75 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
int lo_bit_count = _mm_popcnt_u32(S86_CAST(uint32_t)dest.bytes[S86_RegisterByte_Lo]);
|
int lo_bit_count = _mm_popcnt_u32(S86_CAST(uint32_t)dest.bytes[S86_RegisterByte_Lo]);
|
||||||
register_file.flags.parity = lo_bit_count % 2 == 0;
|
register_file.flags.parity = lo_bit_count % 2 == 0;
|
||||||
register_file.flags.zero = false;
|
|
||||||
if (opcode->mnemonic == S86_Mnemonic_ADD || opcode->mnemonic == S86_Mnemonic_SUB)
|
|
||||||
register_file.flags.zero = byte_op ? dest.bytes[dest_map->byte] == 0 : dest.word == 0;
|
register_file.flags.zero = byte_op ? dest.bytes[dest_map->byte] == 0 : dest.word == 0;
|
||||||
|
if (opcode->mnemonic != S86_Mnemonic_CMP)
|
||||||
if (opcode->mnemonic == S86_Mnemonic_CMP) {
|
|
||||||
S86_PrintFmt(" ; ");
|
|
||||||
} else {
|
|
||||||
S86_Str8 dest_reg16 = S86_MnemonicOpStr8(dest_map->mnemonic_op_reg16);
|
|
||||||
S86_PrintFmt(" ; %.*s:0x%x->0x%x ", S86_STR8_FMT(dest_reg16), prev_dest.word, dest.word);
|
|
||||||
*dest_map->reg = dest;
|
*dest_map->reg = dest;
|
||||||
}
|
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case S86_Mnemonic_JNE_JNZ: {
|
case S86_Mnemonic_JNE_JNZ: {
|
||||||
if (!register_file.flags.zero)
|
if (!register_file.flags.zero)
|
||||||
register_file.instruction_ptr += S86_CAST(int16_t)opcode->displacement;
|
register_file.instruction_ptr += S86_CAST(int16_t)opcode->displacement;
|
||||||
S86_PrintFmt(" ; ");
|
} break;
|
||||||
|
|
||||||
|
case S86_Mnemonic_JE_JZ: {
|
||||||
|
if (register_file.flags.zero)
|
||||||
|
register_file.instruction_ptr += S86_CAST(int16_t)opcode->displacement;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case S86_Mnemonic_JP_JPE: {
|
||||||
|
if (register_file.flags.parity)
|
||||||
|
register_file.instruction_ptr += S86_CAST(int16_t)opcode->displacement;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case S86_Mnemonic_JB_JNAE: {
|
||||||
|
if (register_file.flags.carry)
|
||||||
|
register_file.instruction_ptr += S86_CAST(int16_t)opcode->displacement;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case S86_Mnemonic_LOOPNZ_LOOPNE: {
|
||||||
|
register_file.reg.file.cx.word -= 1;
|
||||||
|
if (register_file.reg.file.cx.word != 0 && !register_file.flags.zero)
|
||||||
|
register_file.instruction_ptr += S86_CAST(int16_t)opcode->displacement;
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: Printing ==========================================================================
|
// NOTE: Printing ==========================================================================
|
||||||
|
S86_PrintFmt(" ; ");
|
||||||
|
|
||||||
|
// NOTE: Registers
|
||||||
|
for (size_t index = 0; index < S86_RegisterFileRegArray_Count; index++) {
|
||||||
|
if (register_file.reg.array[index].word != prev_register_file.reg.array[index].word) {
|
||||||
|
S86_Str8 label = S86_RegisterFileRegArrayStr8(index);
|
||||||
|
S86_PrintFmt("%.*s:0x%x->0x%x ",
|
||||||
|
S86_STR8_FMT(label),
|
||||||
|
prev_register_file.reg.array[index].word,
|
||||||
|
register_file.reg.array[index].word);
|
||||||
|
|
||||||
|
// NOTE: In 8086, instructions can only change one register at a
|
||||||
|
// time. Once we find the first delta in the register file, we
|
||||||
|
// exit.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// NOTE: Instruction Pointer
|
// NOTE: Instruction Pointer
|
||||||
if (log_instruction_ptr)
|
if (log_instruction_ptr)
|
||||||
S86_PrintFmt("ip:0x%x->0x%x ", opcode->instruction_ptr, register_file.instruction_ptr);
|
S86_PrintFmt("ip:0x%x->0x%x ", opcode->instruction_ptr, register_file.instruction_ptr);
|
||||||
|
|
||||||
// NOTE: Flags
|
// NOTE: Flags
|
||||||
if (!S86_RegisterFileFlagsEq(register_file.flags, prev_flags)) {
|
if (!S86_RegisterFileFlagsEq(register_file.flags, prev_register_file.flags)) {
|
||||||
S86_PrintFmt("flags:");
|
S86_PrintFmt("flags:");
|
||||||
if (prev_flags.carry)
|
if (prev_register_file.flags.carry)
|
||||||
S86_PrintFmt("C");
|
S86_PrintFmt("C");
|
||||||
if (prev_flags.parity)
|
if (prev_register_file.flags.parity)
|
||||||
S86_PrintFmt("P");
|
S86_PrintFmt("P");
|
||||||
if (prev_flags.auxiliary_carry)
|
if (prev_register_file.flags.auxiliary_carry)
|
||||||
S86_PrintFmt("A");
|
S86_PrintFmt("A");
|
||||||
if (prev_flags.zero)
|
if (prev_register_file.flags.zero)
|
||||||
S86_PrintFmt("Z");
|
S86_PrintFmt("Z");
|
||||||
if (prev_flags.sign)
|
if (prev_register_file.flags.sign)
|
||||||
S86_PrintFmt("S");
|
S86_PrintFmt("S");
|
||||||
if (prev_flags.overflow)
|
if (prev_register_file.flags.overflow)
|
||||||
S86_PrintFmt("O");
|
S86_PrintFmt("O");
|
||||||
|
|
||||||
S86_PrintFmt("->");
|
S86_PrintFmt("->");
|
||||||
@ -1581,28 +1622,28 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
if (exec_mode) {
|
if (exec_mode) {
|
||||||
S86_PrintLn(S86_STR8("\nFinal registers:"));
|
S86_PrintLn(S86_STR8("\nFinal registers:"));
|
||||||
if (register_file.ax.word)
|
if (register_file.reg.file.ax.word)
|
||||||
S86_PrintLnFmt(" ax: 0x%04x (%u)", register_file.ax.word, register_file.ax.word);
|
S86_PrintLnFmt(" ax: 0x%04x (%u)", register_file.reg.file.ax.word, register_file.reg.file.ax.word);
|
||||||
if (register_file.bx.word)
|
if (register_file.reg.file.bx.word)
|
||||||
S86_PrintLnFmt(" bx: 0x%04x (%u)", register_file.bx.word, register_file.bx.word);
|
S86_PrintLnFmt(" bx: 0x%04x (%u)", register_file.reg.file.bx.word, register_file.reg.file.bx.word);
|
||||||
if (register_file.cx.word)
|
if (register_file.reg.file.cx.word)
|
||||||
S86_PrintLnFmt(" cx: 0x%04x (%u)", register_file.cx.word, register_file.cx.word);
|
S86_PrintLnFmt(" cx: 0x%04x (%u)", register_file.reg.file.cx.word, register_file.reg.file.cx.word);
|
||||||
if (register_file.dx.word)
|
if (register_file.reg.file.dx.word)
|
||||||
S86_PrintLnFmt(" dx: 0x%04x (%u)", register_file.dx.word, register_file.dx.word);
|
S86_PrintLnFmt(" dx: 0x%04x (%u)", register_file.reg.file.dx.word, register_file.reg.file.dx.word);
|
||||||
if (register_file.sp.word)
|
if (register_file.reg.file.sp.word)
|
||||||
S86_PrintLnFmt(" sp: 0x%04x (%u)", register_file.sp.word, register_file.sp.word);
|
S86_PrintLnFmt(" sp: 0x%04x (%u)", register_file.reg.file.sp.word, register_file.reg.file.sp.word);
|
||||||
if (register_file.bp.word)
|
if (register_file.reg.file.bp.word)
|
||||||
S86_PrintLnFmt(" bp: 0x%04x (%u)", register_file.bp.word, register_file.bp.word);
|
S86_PrintLnFmt(" bp: 0x%04x (%u)", register_file.reg.file.bp.word, register_file.reg.file.bp.word);
|
||||||
if (register_file.si.word)
|
if (register_file.reg.file.si.word)
|
||||||
S86_PrintLnFmt(" si: 0x%04x (%u)", register_file.si.word, register_file.si.word);
|
S86_PrintLnFmt(" si: 0x%04x (%u)", register_file.reg.file.si.word, register_file.reg.file.si.word);
|
||||||
if (register_file.di.word)
|
if (register_file.reg.file.di.word)
|
||||||
S86_PrintLnFmt(" di: 0x%04x (%u)", register_file.di.word, register_file.di.word);
|
S86_PrintLnFmt(" di: 0x%04x (%u)", register_file.reg.file.di.word, register_file.reg.file.di.word);
|
||||||
if (register_file.es.word)
|
if (register_file.reg.file.es.word)
|
||||||
S86_PrintLnFmt(" es: 0x%04x (%u)", register_file.es, register_file.es);
|
S86_PrintLnFmt(" es: 0x%04x (%u)", register_file.reg.file.es.word, register_file.reg.file.es.word);
|
||||||
if (register_file.ss.word)
|
if (register_file.reg.file.ss.word)
|
||||||
S86_PrintLnFmt(" ss: 0x%04x (%u)", register_file.ss, register_file.ss);
|
S86_PrintLnFmt(" ss: 0x%04x (%u)", register_file.reg.file.ss.word, register_file.reg.file.ss.word);
|
||||||
if (register_file.ds.word)
|
if (register_file.reg.file.ds.word)
|
||||||
S86_PrintLnFmt(" ds: 0x%04x (%u)", register_file.ds, register_file.ds);
|
S86_PrintLnFmt(" ds: 0x%04x (%u)", register_file.reg.file.ds.word, register_file.reg.file.ds.word);
|
||||||
|
|
||||||
if (log_instruction_ptr)
|
if (log_instruction_ptr)
|
||||||
S86_PrintLnFmt(" ip: 0x%04x (%u)", register_file.instruction_ptr, register_file.instruction_ptr);
|
S86_PrintLnFmt(" ip: 0x%04x (%u)", register_file.instruction_ptr, register_file.instruction_ptr);
|
||||||
|
@ -361,10 +361,30 @@ typedef struct S86_RegisterFileFlags {
|
|||||||
bool auxiliary_carry;
|
bool auxiliary_carry;
|
||||||
} S86_RegisterFileFlags;
|
} S86_RegisterFileFlags;
|
||||||
|
|
||||||
|
typedef enum S86_RegisterFileRegArray {
|
||||||
|
S86_RegisterFileRegArray_AX,
|
||||||
|
S86_RegisterFileRegArray_BX,
|
||||||
|
S86_RegisterFileRegArray_CX,
|
||||||
|
S86_RegisterFileRegArray_DX,
|
||||||
|
|
||||||
|
S86_RegisterFileRegArray_SP,
|
||||||
|
S86_RegisterFileRegArray_BP,
|
||||||
|
S86_RegisterFileRegArray_SI,
|
||||||
|
S86_RegisterFileRegArray_DI,
|
||||||
|
|
||||||
|
S86_RegisterFileRegArray_ES,
|
||||||
|
S86_RegisterFileRegArray_CS,
|
||||||
|
S86_RegisterFileRegArray_SS,
|
||||||
|
S86_RegisterFileRegArray_DS,
|
||||||
|
S86_RegisterFileRegArray_Count,
|
||||||
|
} S86_RegisterFileRegArray;
|
||||||
|
|
||||||
typedef struct S86_RegisterFile {
|
typedef struct S86_RegisterFile {
|
||||||
S86_RegisterFileFlags flags;
|
S86_RegisterFileFlags flags;
|
||||||
uint16_t instruction_ptr;
|
uint16_t instruction_ptr;
|
||||||
|
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
S86_Register16 ax;
|
S86_Register16 ax;
|
||||||
S86_Register16 bx;
|
S86_Register16 bx;
|
||||||
S86_Register16 cx;
|
S86_Register16 cx;
|
||||||
@ -379,6 +399,9 @@ typedef struct S86_RegisterFile {
|
|||||||
S86_Register16 cs;
|
S86_Register16 cs;
|
||||||
S86_Register16 ss;
|
S86_Register16 ss;
|
||||||
S86_Register16 ds;
|
S86_Register16 ds;
|
||||||
|
} file;
|
||||||
|
S86_Register16 array[S86_RegisterFileRegArray_Count];
|
||||||
|
} reg;
|
||||||
} S86_RegisterFile;
|
} S86_RegisterFile;
|
||||||
|
|
||||||
bool S86_RegisterFileFlagsEq (S86_RegisterFileFlags lhs, S86_RegisterFileFlags rhs);
|
bool S86_RegisterFileFlagsEq (S86_RegisterFileFlags lhs, S86_RegisterFileFlags rhs);
|
||||||
@ -386,6 +409,7 @@ S86_Str8 S86_MnemonicStr8 (S86_Mnemonic type);
|
|||||||
S86_MnemonicOp S86_MnemonicOpFromWReg (bool w, uint8_t reg);
|
S86_MnemonicOp S86_MnemonicOpFromWReg (bool w, uint8_t reg);
|
||||||
S86_MnemonicOp S86_MnemonicOpFromSR (uint8_t sr);
|
S86_MnemonicOp S86_MnemonicOpFromSR (uint8_t sr);
|
||||||
S86_Str8 S86_MnemonicOpStr8 (S86_MnemonicOp type);
|
S86_Str8 S86_MnemonicOpStr8 (S86_MnemonicOp type);
|
||||||
void S86_PrintOpcodeMnemonicOp(S86_Opcode opcode, bool src);
|
S86_Str8 S86_RegisterFileRegArrayStr8(S86_RegisterFileRegArray type);
|
||||||
|
void S86_PrintOpcodeMnemonicOp (S86_Opcode opcode, bool src);
|
||||||
void S86_PrintOpcode (S86_Opcode opcode);
|
void S86_PrintOpcode (S86_Opcode opcode);
|
||||||
void S86_DecodeEffectiveAddr (S86_Opcode *opcode, S86_BufferIterator *it, uint8_t rm, uint8_t mod, uint8_t w);
|
void S86_DecodeEffectiveAddr (S86_Opcode *opcode, S86_BufferIterator *it, uint8_t rm, uint8_t mod, uint8_t w);
|
||||||
|
BIN
project.rdbg
BIN
project.rdbg
Binary file not shown.
Loading…
Reference in New Issue
Block a user