perfaware/part1: Support listing 0050"

This commit is contained in:
doyle 2023-04-16 23:13:04 +10:00
parent 00ad047d9a
commit bd3dc5f2bc
7 changed files with 251 additions and 95 deletions

View File

@ -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 /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

Binary file not shown.

View 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

View 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

View File

@ -196,6 +196,27 @@ S86_Str8 S86_MnemonicOpStr8(S86_MnemonicOp type)
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)
{
// 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_MnemonicOpToRegisterFileMap mnemonic_op_to_register_file_map[] = {
{.mnemonic_op = S86_MnemonicOp_AX, .mnemonic_op_reg16 = S86_MnemonicOp_AX, .reg = &register_file.ax, .byte = S86_RegisterByte_Nil},
{.mnemonic_op = S86_MnemonicOp_AL, .mnemonic_op_reg16 = S86_MnemonicOp_AX, .reg = &register_file.ax, .byte = S86_RegisterByte_Lo},
{.mnemonic_op = S86_MnemonicOp_AH, .mnemonic_op_reg16 = S86_MnemonicOp_AX, .reg = &register_file.ax, .byte = S86_RegisterByte_Hi},
{.mnemonic_op = S86_MnemonicOp_AX, .mnemonic_op_reg16 = S86_MnemonicOp_AX, .reg = &register_file.reg.file.ax, .byte = S86_RegisterByte_Nil},
{.mnemonic_op = S86_MnemonicOp_AL, .mnemonic_op_reg16 = S86_MnemonicOp_AX, .reg = &register_file.reg.file.ax, .byte = S86_RegisterByte_Lo},
{.mnemonic_op = S86_MnemonicOp_AH, .mnemonic_op_reg16 = S86_MnemonicOp_AX, .reg = &register_file.reg.file.ax, .byte = S86_RegisterByte_Hi},
{.mnemonic_op = S86_MnemonicOp_CX, .mnemonic_op_reg16 = S86_MnemonicOp_CX, .reg = &register_file.cx, .byte = S86_RegisterByte_Nil},
{.mnemonic_op = S86_MnemonicOp_CL, .mnemonic_op_reg16 = S86_MnemonicOp_CX, .reg = &register_file.cx, .byte = S86_RegisterByte_Lo},
{.mnemonic_op = S86_MnemonicOp_CH, .mnemonic_op_reg16 = S86_MnemonicOp_CX, .reg = &register_file.cx, .byte = S86_RegisterByte_Lo},
{.mnemonic_op = S86_MnemonicOp_CX, .mnemonic_op_reg16 = S86_MnemonicOp_CX, .reg = &register_file.reg.file.cx, .byte = S86_RegisterByte_Nil},
{.mnemonic_op = S86_MnemonicOp_CL, .mnemonic_op_reg16 = S86_MnemonicOp_CX, .reg = &register_file.reg.file.cx, .byte = S86_RegisterByte_Lo},
{.mnemonic_op = S86_MnemonicOp_CH, .mnemonic_op_reg16 = S86_MnemonicOp_CX, .reg = &register_file.reg.file.cx, .byte = S86_RegisterByte_Lo},
{.mnemonic_op = S86_MnemonicOp_DX, .mnemonic_op_reg16 = S86_MnemonicOp_DX, .reg = &register_file.dx, .byte = S86_RegisterByte_Nil},
{.mnemonic_op = S86_MnemonicOp_DL, .mnemonic_op_reg16 = S86_MnemonicOp_DX, .reg = &register_file.dx, .byte = S86_RegisterByte_Lo},
{.mnemonic_op = S86_MnemonicOp_DH, .mnemonic_op_reg16 = S86_MnemonicOp_DX, .reg = &register_file.dx, .byte = S86_RegisterByte_Hi},
{.mnemonic_op = S86_MnemonicOp_DX, .mnemonic_op_reg16 = S86_MnemonicOp_DX, .reg = &register_file.reg.file.dx, .byte = S86_RegisterByte_Nil},
{.mnemonic_op = S86_MnemonicOp_DL, .mnemonic_op_reg16 = S86_MnemonicOp_DX, .reg = &register_file.reg.file.dx, .byte = S86_RegisterByte_Lo},
{.mnemonic_op = S86_MnemonicOp_DH, .mnemonic_op_reg16 = S86_MnemonicOp_DX, .reg = &register_file.reg.file.dx, .byte = S86_RegisterByte_Hi},
{.mnemonic_op = S86_MnemonicOp_BX, .mnemonic_op_reg16 = S86_MnemonicOp_BX, .reg = &register_file.bx, .byte = S86_RegisterByte_Nil},
{.mnemonic_op = S86_MnemonicOp_BL, .mnemonic_op_reg16 = S86_MnemonicOp_BX, .reg = &register_file.bx, .byte = S86_RegisterByte_Lo},
{.mnemonic_op = S86_MnemonicOp_BH, .mnemonic_op_reg16 = S86_MnemonicOp_BX, .reg = &register_file.bx, .byte = S86_RegisterByte_Hi},
{.mnemonic_op = S86_MnemonicOp_BX, .mnemonic_op_reg16 = S86_MnemonicOp_BX, .reg = &register_file.reg.file.bx, .byte = S86_RegisterByte_Nil},
{.mnemonic_op = S86_MnemonicOp_BL, .mnemonic_op_reg16 = S86_MnemonicOp_BX, .reg = &register_file.reg.file.bx, .byte = S86_RegisterByte_Lo},
{.mnemonic_op = S86_MnemonicOp_BH, .mnemonic_op_reg16 = S86_MnemonicOp_BX, .reg = &register_file.reg.file.bx, .byte = S86_RegisterByte_Hi},
{.mnemonic_op = S86_MnemonicOp_SP, .mnemonic_op_reg16 = S86_MnemonicOp_SP, .reg = &register_file.sp, .byte = S86_RegisterByte_Nil},
{.mnemonic_op = S86_MnemonicOp_BP, .mnemonic_op_reg16 = S86_MnemonicOp_BP, .reg = &register_file.bp, .byte = S86_RegisterByte_Nil},
{.mnemonic_op = S86_MnemonicOp_SI, .mnemonic_op_reg16 = S86_MnemonicOp_SI, .reg = &register_file.si, .byte = S86_RegisterByte_Nil},
{.mnemonic_op = S86_MnemonicOp_DI, .mnemonic_op_reg16 = S86_MnemonicOp_DI, .reg = &register_file.di, .byte = S86_RegisterByte_Nil},
{.mnemonic_op = S86_MnemonicOp_SP, .mnemonic_op_reg16 = S86_MnemonicOp_SP, .reg = &register_file.reg.file.sp, .byte = S86_RegisterByte_Nil},
{.mnemonic_op = S86_MnemonicOp_BP, .mnemonic_op_reg16 = S86_MnemonicOp_BP, .reg = &register_file.reg.file.bp, .byte = S86_RegisterByte_Nil},
{.mnemonic_op = S86_MnemonicOp_SI, .mnemonic_op_reg16 = S86_MnemonicOp_SI, .reg = &register_file.reg.file.si, .byte = S86_RegisterByte_Nil},
{.mnemonic_op = S86_MnemonicOp_DI, .mnemonic_op_reg16 = S86_MnemonicOp_DI, .reg = &register_file.reg.file.di, .byte = S86_RegisterByte_Nil},
{.mnemonic_op = S86_MnemonicOp_ES, .mnemonic_op_reg16 = S86_MnemonicOp_ES, .reg = &register_file.es, .byte = S86_RegisterByte_Nil},
{.mnemonic_op = S86_MnemonicOp_CS, .mnemonic_op_reg16 = S86_MnemonicOp_CS, .reg = &register_file.cs, .byte = S86_RegisterByte_Nil},
{.mnemonic_op = S86_MnemonicOp_SS, .mnemonic_op_reg16 = S86_MnemonicOp_SS, .reg = &register_file.ss, .byte = S86_RegisterByte_Nil},
{.mnemonic_op = S86_MnemonicOp_DS, .mnemonic_op_reg16 = S86_MnemonicOp_DS, .reg = &register_file.ds, .byte = S86_RegisterByte_Nil},
{.mnemonic_op = S86_MnemonicOp_ES, .mnemonic_op_reg16 = S86_MnemonicOp_ES, .reg = &register_file.reg.file.es, .byte = S86_RegisterByte_Nil},
{.mnemonic_op = S86_MnemonicOp_CS, .mnemonic_op_reg16 = S86_MnemonicOp_CS, .reg = &register_file.reg.file.cs, .byte = S86_RegisterByte_Nil},
{.mnemonic_op = S86_MnemonicOp_SS, .mnemonic_op_reg16 = S86_MnemonicOp_SS, .reg = &register_file.reg.file.ss, .byte = S86_RegisterByte_Nil},
{.mnemonic_op = S86_MnemonicOp_DS, .mnemonic_op_reg16 = S86_MnemonicOp_DS, .reg = &register_file.reg.file.ds, .byte = S86_RegisterByte_Nil},
};
// NOTE: Count opcodes, allocate then decode in 1 swoop
@ -1298,7 +1319,7 @@ int main(int argc, char **argv)
}
// NOTE: Simulate instruction ==============================================================
S86_RegisterFileFlags prev_flags = register_file.flags;
S86_RegisterFile prev_register_file = register_file;
switch (opcode->mnemonic) {
case S86_Mnemonic_PUSH: /*FALLTHRU*/
case S86_Mnemonic_POP: /*FALLTHRU*/
@ -1346,12 +1367,9 @@ int main(int argc, char **argv)
case S86_Mnemonic_CALL: /*FALLTHRU*/
case S86_Mnemonic_JMP: /*FALLTHRU*/
case S86_Mnemonic_RET: /*FALLTHRU*/
case S86_Mnemonic_JE_JZ: /*FALLTHRU*/
case S86_Mnemonic_JL_JNGE: /*FALLTHRU*/
case S86_Mnemonic_JLE_JNG: /*FALLTHRU*/
case S86_Mnemonic_JB_JNAE: /*FALLTHRU*/
case S86_Mnemonic_JBE_JNA: /*FALLTHRU*/
case S86_Mnemonic_JP_JPE: /*FALLTHRU*/
case S86_Mnemonic_JO: /*FALLTHRU*/
case S86_Mnemonic_JS: /*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_LOOP: /*FALLTHRU*/
case S86_Mnemonic_LOOPZ_LOOPE: /*FALLTHRU*/
case S86_Mnemonic_LOOPNZ_LOOPNE: /*FALLTHRU*/
case S86_Mnemonic_JCXZ: /*FALLTHRU*/
case S86_Mnemonic_INT: /*FALLTHRU*/
case S86_Mnemonic_INT3: /*FALLTHRU*/
@ -1390,7 +1407,6 @@ int main(int argc, char **argv)
}
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;
if (opcode->src == S86_MnemonicOp_Immediate) {
if (byte_op) {
@ -1413,9 +1429,6 @@ int main(int argc, char **argv)
else
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;
case S86_Mnemonic_ADD: /*FALLTHRU*/
@ -1431,7 +1444,6 @@ int main(int argc, char **argv)
bool subtract = opcode->mnemonic != S86_Mnemonic_ADD;
S86_Register16 dest = *dest_map->reg;
S86_Register16 prev_dest = dest;
bool byte_op = opcode->dest >= S86_MnemonicOp_AL && opcode->dest <= S86_MnemonicOp_BH;
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]);
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;
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);
if (opcode->mnemonic != S86_Mnemonic_CMP)
*dest_map->reg = dest;
}
} break;
case S86_Mnemonic_JNE_JNZ: {
if (!register_file.flags.zero)
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;
}
// 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
if (log_instruction_ptr)
S86_PrintFmt("ip:0x%x->0x%x ", opcode->instruction_ptr, register_file.instruction_ptr);
// NOTE: Flags
if (!S86_RegisterFileFlagsEq(register_file.flags, prev_flags)) {
if (!S86_RegisterFileFlagsEq(register_file.flags, prev_register_file.flags)) {
S86_PrintFmt("flags:");
if (prev_flags.carry)
if (prev_register_file.flags.carry)
S86_PrintFmt("C");
if (prev_flags.parity)
if (prev_register_file.flags.parity)
S86_PrintFmt("P");
if (prev_flags.auxiliary_carry)
if (prev_register_file.flags.auxiliary_carry)
S86_PrintFmt("A");
if (prev_flags.zero)
if (prev_register_file.flags.zero)
S86_PrintFmt("Z");
if (prev_flags.sign)
if (prev_register_file.flags.sign)
S86_PrintFmt("S");
if (prev_flags.overflow)
if (prev_register_file.flags.overflow)
S86_PrintFmt("O");
S86_PrintFmt("->");
@ -1581,28 +1622,28 @@ int main(int argc, char **argv)
if (exec_mode) {
S86_PrintLn(S86_STR8("\nFinal registers:"));
if (register_file.ax.word)
S86_PrintLnFmt(" ax: 0x%04x (%u)", register_file.ax.word, register_file.ax.word);
if (register_file.bx.word)
S86_PrintLnFmt(" bx: 0x%04x (%u)", register_file.bx.word, register_file.bx.word);
if (register_file.cx.word)
S86_PrintLnFmt(" cx: 0x%04x (%u)", register_file.cx.word, register_file.cx.word);
if (register_file.dx.word)
S86_PrintLnFmt(" dx: 0x%04x (%u)", register_file.dx.word, register_file.dx.word);
if (register_file.sp.word)
S86_PrintLnFmt(" sp: 0x%04x (%u)", register_file.sp.word, register_file.sp.word);
if (register_file.bp.word)
S86_PrintLnFmt(" bp: 0x%04x (%u)", register_file.bp.word, register_file.bp.word);
if (register_file.si.word)
S86_PrintLnFmt(" si: 0x%04x (%u)", register_file.si.word, register_file.si.word);
if (register_file.di.word)
S86_PrintLnFmt(" di: 0x%04x (%u)", register_file.di.word, register_file.di.word);
if (register_file.es.word)
S86_PrintLnFmt(" es: 0x%04x (%u)", register_file.es, register_file.es);
if (register_file.ss.word)
S86_PrintLnFmt(" ss: 0x%04x (%u)", register_file.ss, register_file.ss);
if (register_file.ds.word)
S86_PrintLnFmt(" ds: 0x%04x (%u)", register_file.ds, register_file.ds);
if (register_file.reg.file.ax.word)
S86_PrintLnFmt(" ax: 0x%04x (%u)", register_file.reg.file.ax.word, register_file.reg.file.ax.word);
if (register_file.reg.file.bx.word)
S86_PrintLnFmt(" bx: 0x%04x (%u)", register_file.reg.file.bx.word, register_file.reg.file.bx.word);
if (register_file.reg.file.cx.word)
S86_PrintLnFmt(" cx: 0x%04x (%u)", register_file.reg.file.cx.word, register_file.reg.file.cx.word);
if (register_file.reg.file.dx.word)
S86_PrintLnFmt(" dx: 0x%04x (%u)", register_file.reg.file.dx.word, register_file.reg.file.dx.word);
if (register_file.reg.file.sp.word)
S86_PrintLnFmt(" sp: 0x%04x (%u)", register_file.reg.file.sp.word, register_file.reg.file.sp.word);
if (register_file.reg.file.bp.word)
S86_PrintLnFmt(" bp: 0x%04x (%u)", register_file.reg.file.bp.word, register_file.reg.file.bp.word);
if (register_file.reg.file.si.word)
S86_PrintLnFmt(" si: 0x%04x (%u)", register_file.reg.file.si.word, register_file.reg.file.si.word);
if (register_file.reg.file.di.word)
S86_PrintLnFmt(" di: 0x%04x (%u)", register_file.reg.file.di.word, register_file.reg.file.di.word);
if (register_file.reg.file.es.word)
S86_PrintLnFmt(" es: 0x%04x (%u)", register_file.reg.file.es.word, register_file.reg.file.es.word);
if (register_file.reg.file.ss.word)
S86_PrintLnFmt(" ss: 0x%04x (%u)", register_file.reg.file.ss.word, register_file.reg.file.ss.word);
if (register_file.reg.file.ds.word)
S86_PrintLnFmt(" ds: 0x%04x (%u)", register_file.reg.file.ds.word, register_file.reg.file.ds.word);
if (log_instruction_ptr)
S86_PrintLnFmt(" ip: 0x%04x (%u)", register_file.instruction_ptr, register_file.instruction_ptr);

View File

@ -361,10 +361,30 @@ typedef struct S86_RegisterFileFlags {
bool auxiliary_carry;
} 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 {
S86_RegisterFileFlags flags;
uint16_t instruction_ptr;
union {
struct {
S86_Register16 ax;
S86_Register16 bx;
S86_Register16 cx;
@ -379,6 +399,9 @@ typedef struct S86_RegisterFile {
S86_Register16 cs;
S86_Register16 ss;
S86_Register16 ds;
} file;
S86_Register16 array[S86_RegisterFileRegArray_Count];
} reg;
} S86_RegisterFile;
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_MnemonicOpFromSR (uint8_t sr);
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_DecodeEffectiveAddr (S86_Opcode *opcode, S86_BufferIterator *it, uint8_t rm, uint8_t mod, uint8_t w);

Binary file not shown.