diff --git a/part1/build.bat b/part1/build.bat index 7b5b776..1ca2ac3 100644 --- a/part1/build.bat +++ b/part1/build.bat @@ -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 diff --git a/part1/listing_0050_challenge_jumps b/part1/listing_0050_challenge_jumps new file mode 100644 index 0000000..7a95806 Binary files /dev/null and b/part1/listing_0050_challenge_jumps differ diff --git a/part1/listing_0050_challenge_jumps.asm b/part1/listing_0050_challenge_jumps.asm new file mode 100644 index 0000000..8d2f484 --- /dev/null +++ b/part1/listing_0050_challenge_jumps.asm @@ -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 diff --git a/part1/listing_0050_challenge_jumps.txt b/part1/listing_0050_challenge_jumps.txt new file mode 100644 index 0000000..881a107 --- /dev/null +++ b/part1/listing_0050_challenge_jumps.txt @@ -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 + diff --git a/part1/sim8086.c b/part1/sim8086.c index ca7fa92..e71d313 100644 --- a/part1/sim8086.c +++ b/part1/sim8086.c @@ -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 = ®ister_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_AH, .mnemonic_op_reg16 = S86_MnemonicOp_AX, .reg = ®ister_file.ax, .byte = S86_RegisterByte_Hi}, + {.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.reg.file.ax, .byte = S86_RegisterByte_Lo}, + {.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_CL, .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.cx, .byte = S86_RegisterByte_Lo}, + {.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.reg.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_DL, .mnemonic_op_reg16 = S86_MnemonicOp_DX, .reg = ®ister_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_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.reg.file.dx, .byte = S86_RegisterByte_Lo}, + {.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_BL, .mnemonic_op_reg16 = S86_MnemonicOp_BX, .reg = ®ister_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_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.reg.file.bx, .byte = S86_RegisterByte_Lo}, + {.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_BP, .mnemonic_op_reg16 = S86_MnemonicOp_BP, .reg = ®ister_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_DI, .mnemonic_op_reg16 = S86_MnemonicOp_DI, .reg = ®ister_file.di, .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.reg.file.bp, .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.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_CS, .mnemonic_op_reg16 = S86_MnemonicOp_CS, .reg = ®ister_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_DS, .mnemonic_op_reg16 = S86_MnemonicOp_DS, .reg = ®ister_file.ds, .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.reg.file.cs, .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.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,8 +1407,7 @@ 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; + bool byte_op = opcode->dest >= S86_MnemonicOp_AL && opcode->dest <= S86_MnemonicOp_BH; if (opcode->src == S86_MnemonicOp_Immediate) { if (byte_op) { S86_ASSERT(opcode->immediate < S86_CAST(uint8_t)-1); @@ -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*/ @@ -1429,10 +1442,9 @@ int main(int argc, char **argv) } S86_ASSERT(dest_map); - 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; + bool subtract = opcode->mnemonic != S86_Mnemonic_ADD; + S86_Register16 dest = *dest_map->reg; + bool byte_op = opcode->dest >= S86_MnemonicOp_AL && opcode->dest <= S86_MnemonicOp_BH; uint16_t src = 0; if (opcode->src == S86_MnemonicOp_Immediate) { @@ -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); + register_file.flags.zero = byte_op ? dest.bytes[dest_map->byte] == 0 : dest.word == 0; + 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); diff --git a/part1/sim8086.h b/part1/sim8086.h index 983f598..32e651e 100644 --- a/part1/sim8086.h +++ b/part1/sim8086.h @@ -361,31 +361,55 @@ 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; - S86_Register16 ax; - S86_Register16 bx; - S86_Register16 cx; - S86_Register16 dx; + union { + struct { + S86_Register16 ax; + S86_Register16 bx; + S86_Register16 cx; + S86_Register16 dx; - S86_Register16 sp; - S86_Register16 bp; - S86_Register16 si; - S86_Register16 di; + S86_Register16 sp; + S86_Register16 bp; + S86_Register16 si; + S86_Register16 di; - S86_Register16 es; - S86_Register16 cs; - S86_Register16 ss; - S86_Register16 ds; + S86_Register16 es; + 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); -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); -void S86_PrintOpcode (S86_Opcode opcode); -void S86_DecodeEffectiveAddr (S86_Opcode *opcode, S86_BufferIterator *it, uint8_t rm, uint8_t mod, uint8_t w); +bool S86_RegisterFileFlagsEq (S86_RegisterFileFlags lhs, S86_RegisterFileFlags rhs); +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); +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); diff --git a/project.rdbg b/project.rdbg index 8e7dccb..1aa0cfb 100644 Binary files a/project.rdbg and b/project.rdbg differ