perfaware/part1: Support listing 0055

This commit is contained in:
doyle 2023-04-18 22:38:07 +10:00
parent dd83866f2b
commit d888968ce0
8 changed files with 25357 additions and 20 deletions

View File

@ -243,10 +243,29 @@ set build_dir_listing_0054=%build_dir%\%listing_0054%
copy /Y %script_dir%\%listing_0054% %build_dir% 1>NUL copy /Y %script_dir%\%listing_0054% %build_dir% 1>NUL
copy /Y %script_dir%\%listing_0054%.txt %build_dir% 1>NUL copy /Y %script_dir%\%listing_0054%.txt %build_dir% 1>NUL
%build_dir%\sim8086.exe --exec --log-instruction-ptr %build_dir_listing_0054% > %build_dir_listing_0054%_disassembled.txt pushd %build_dir%
%build_dir%\sim8086.exe --exec --log-instruction-ptr --dump %build_dir_listing_0054% > %build_dir_listing_0054%_disassembled.txt
%build_dir%\sim8086.exe %build_dir_listing_0054% > %build_dir_listing_0054%_disassembled.asm %build_dir%\sim8086.exe %build_dir_listing_0054% > %build_dir_listing_0054%_disassembled.asm
popd
nasm %build_dir_listing_0054%_disassembled.asm nasm %build_dir_listing_0054%_disassembled.asm
fc /B %build_dir_listing_0054% %build_dir_listing_0054%_disassembled || exit /b 1 fc /B %build_dir_listing_0054% %build_dir_listing_0054%_disassembled || exit /b 1
fc /N %build_dir_listing_0054%.txt %build_dir_listing_0054%_disassembled.txt || exit /b 1 fc /N %build_dir_listing_0054%.txt %build_dir_listing_0054%_disassembled.txt || exit /b 1
REM ================================================================================================
set listing_0055=listing_0055_challenge_rectangle
set build_dir_listing_0055=%build_dir%\%listing_0055%
copy /Y %script_dir%\%listing_0055% %build_dir% 1>NUL
copy /Y %script_dir%\%listing_0055%.txt %build_dir% 1>NUL
pushd %build_dir%
%build_dir%\sim8086.exe --exec --log-instruction-ptr --dump %build_dir_listing_0055% > %build_dir_listing_0055%_disassembled.txt
%build_dir%\sim8086.exe %build_dir_listing_0055% > %build_dir_listing_0055%_disassembled.asm
popd
nasm %build_dir_listing_0055%_disassembled.asm
fc /B %build_dir_listing_0055% %build_dir_listing_0055%_disassembled || exit /b 1
fc /N %build_dir_listing_0055%.txt %build_dir_listing_0055%_disassembled.txt || exit /b 1

Binary file not shown.

View File

@ -0,0 +1,53 @@
; ========================================================================
;
; (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 55
; ========================================================================
bits 16
; Start image after one row, to avoid overwriting our code!
mov bp, 64*4
; Draw the solid rectangle red/blue/alpha
mov dx, 64
y_loop_start:
mov cx, 64
x_loop_start:
mov byte [bp + 0], cl ; Red
mov byte [bp + 1], 0 ; Green
mov byte [bp + 2], dl ; Blue
mov byte [bp + 3], 255 ; Alpha
add bp, 4
loop x_loop_start
sub dx, 1
jnz y_loop_start
; Add the line rectangle green
mov bp, 64*4 + 4*64 + 4
mov bx, bp
mov cx, 62
outline_loop_start:
mov byte [bp + 1], 255 ; Top line
mov byte [bp + 61*64*4 + 1], 255 ; Bottom line
mov byte [bx + 1], 255 ; Left line
mov byte [bx + 61*4 + 1], 255 ; Right line
add bp, 4
add bx, 4*64
loop outline_loop_start

File diff suppressed because it is too large Load Diff

View File

@ -831,15 +831,9 @@ S86_Opcode S86_DecodeOpcode(S86_BufferIterator *buffer_it,
*seg_reg = S86_MnemonicOp_Invalid; *seg_reg = S86_MnemonicOp_Invalid;
if (result.effective_addr == S86_EffectiveAddress_Dest && result.effective_addr_loads_mem) { if (result.effective_addr == S86_EffectiveAddress_Dest && result.effective_addr_loads_mem) {
if (result.src == S86_MnemonicOp_DirectAddress || result.word_byte_prefix = (result.wide || result.src >= S86_MnemonicOp_AX && result.src <= S86_MnemonicOp_BX)
result.src == S86_MnemonicOp_Immediate || ? S86_WordBytePrefix_Word
result.src == S86_MnemonicOp_Invalid || : S86_WordBytePrefix_Byte;
(result.src >= S86_MnemonicOp_AL && result.src <= S86_MnemonicOp_BH) ||
(result.src == S86_MnemonicOp_SI)) {
// TODO: Not sure why SI needs the prefix as well, but, according
// to the reference decoder its being emitted here.
result.word_byte_prefix = result.wide ? S86_WordBytePrefix_Word : S86_WordBytePrefix_Byte;
}
} }
size_t buffer_end_index = buffer_it->index; size_t buffer_end_index = buffer_it->index;
@ -856,12 +850,15 @@ typedef struct S86_MnemonicOpToRegisterFileMap {
char const CLI_ARG_EXEC[] = "--exec"; char const CLI_ARG_EXEC[] = "--exec";
char const CLI_ARG_LOG_INSTRUCTION_PTR[] = "--log-instruction-ptr"; char const CLI_ARG_LOG_INSTRUCTION_PTR[] = "--log-instruction-ptr";
char const CLI_ARG_DUMP[] = "--dump";
#define PRINT_USAGE \ #define PRINT_USAGE \
S86_PrintLnFmt("USAGE: sim8086.exe [%.*s] [%.*s] <binary asm file>", \ S86_PrintLnFmt("USAGE: sim8086.exe [%.*s] [%.*s] <binary asm file>", \
S86_ARRAY_UCOUNT(CLI_ARG_EXEC) - 1, \ S86_ARRAY_UCOUNT(CLI_ARG_EXEC) - 1, \
CLI_ARG_EXEC, \ CLI_ARG_EXEC, \
S86_ARRAY_UCOUNT(CLI_ARG_LOG_INSTRUCTION_PTR) - 1, \ S86_ARRAY_UCOUNT(CLI_ARG_LOG_INSTRUCTION_PTR) - 1, \
CLI_ARG_LOG_INSTRUCTION_PTR) CLI_ARG_LOG_INSTRUCTION_PTR, \
S86_ARRAY_UCOUNT(CLI_ARG_DUMP) - 1, \
CLI_ARG_DUMP)
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
// NOTE: Argument handling // NOTE: Argument handling
@ -873,9 +870,11 @@ int main(int argc, char **argv)
S86_Str8 CLI_ARG_EXEC_STR8 = (S86_Str8){(char *)CLI_ARG_EXEC, S86_ARRAY_UCOUNT(CLI_ARG_EXEC) - 1}; S86_Str8 CLI_ARG_EXEC_STR8 = (S86_Str8){(char *)CLI_ARG_EXEC, S86_ARRAY_UCOUNT(CLI_ARG_EXEC) - 1};
S86_Str8 CLI_ARG_LOG_INSTRUCTION_PTR_STR8 = (S86_Str8){(char *)CLI_ARG_LOG_INSTRUCTION_PTR, S86_ARRAY_UCOUNT(CLI_ARG_LOG_INSTRUCTION_PTR) - 1}; S86_Str8 CLI_ARG_LOG_INSTRUCTION_PTR_STR8 = (S86_Str8){(char *)CLI_ARG_LOG_INSTRUCTION_PTR, S86_ARRAY_UCOUNT(CLI_ARG_LOG_INSTRUCTION_PTR) - 1};
S86_Str8 CLI_ARG_DUMP_STR8 = (S86_Str8){(char *)CLI_ARG_DUMP, S86_ARRAY_UCOUNT(CLI_ARG_DUMP) - 1};
bool exec_mode = false; bool exec_mode = false;
bool log_instruction_ptr = false; bool log_instruction_ptr = false;
bool dump = false;
S86_Str8 file_path = {0}; S86_Str8 file_path = {0};
for (int arg_index = 1; arg_index < argc; arg_index++) { for (int arg_index = 1; arg_index < argc; arg_index++) {
char const *arg_cstring = argv[arg_index]; char const *arg_cstring = argv[arg_index];
@ -884,6 +883,8 @@ int main(int argc, char **argv)
exec_mode = true; exec_mode = true;
} else if (S86_Str8_Equals(arg_str8, CLI_ARG_LOG_INSTRUCTION_PTR_STR8)) { } else if (S86_Str8_Equals(arg_str8, CLI_ARG_LOG_INSTRUCTION_PTR_STR8)) {
log_instruction_ptr = true; log_instruction_ptr = true;
} else if (S86_Str8_Equals(arg_str8, CLI_ARG_DUMP_STR8)) {
dump = true;
} else { } else {
if (file_path.size) { if (file_path.size) {
S86_PrintLnFmt("ERROR: Only 1 ASM binary file is supported per invocation [file=\"%.*s\"]", S86_STR8_FMT(file_path)); S86_PrintLnFmt("ERROR: Only 1 ASM binary file is supported per invocation [file=\"%.*s\"]", S86_STR8_FMT(file_path));
@ -1207,8 +1208,9 @@ int main(int argc, char **argv)
else else
S86_PrintLn(S86_STR8("bits 16")); S86_PrintLn(S86_STR8("bits 16"));
uint32_t const S86_MEMORY_SIZE = 1024 * 1024;
S86_RegisterFile register_file = {0}; S86_RegisterFile register_file = {0};
uint8_t *memory = VirtualAlloc(0, 1024 * 1024, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); uint8_t *memory = VirtualAlloc(0, S86_MEMORY_SIZE, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
memcpy(memory, buffer.data, buffer.size); memcpy(memory, buffer.data, buffer.size);
S86_MnemonicOpToRegisterFileMap mnemonic_op_to_register_file_map[] = { S86_MnemonicOpToRegisterFileMap mnemonic_op_to_register_file_map[] = {
@ -1246,14 +1248,15 @@ int main(int argc, char **argv)
// NOTE: Execute the assembly // NOTE: Execute the assembly
// ========================================================================= // =========================================================================
S86_Buffer instruction_buffer = {0};
instruction_buffer.data = (char *)&memory[register_file.instruction_ptr];
instruction_buffer.size = buffer.size;
S86_BufferIterator instruction_it = S86_BufferIteratorInit(instruction_buffer);
bool lock_prefix = false; bool lock_prefix = false;
S86_MnemonicOp seg_reg = S86_CAST(S86_MnemonicOp)0; S86_MnemonicOp seg_reg = S86_CAST(S86_MnemonicOp)0;
for (uint16_t prev_ip = 0; register_file.instruction_ptr < buffer.size; prev_ip = register_file.instruction_ptr) { for (uint16_t prev_ip = 0; register_file.instruction_ptr < buffer.size; prev_ip = register_file.instruction_ptr) {
S86_Buffer instruction_buffer = {0}; instruction_it.index = register_file.instruction_ptr;
instruction_buffer.data = (char *)&memory[register_file.instruction_ptr];
instruction_buffer.size = buffer.size - register_file.instruction_ptr;
S86_BufferIterator instruction_it = S86_BufferIteratorInit(instruction_buffer);
S86_Opcode opcode = S86_DecodeOpcode(&instruction_it, DECODE_TABLE, S86_ARRAY_UCOUNT(DECODE_TABLE), &lock_prefix, &seg_reg); S86_Opcode opcode = S86_DecodeOpcode(&instruction_it, DECODE_TABLE, S86_ARRAY_UCOUNT(DECODE_TABLE), &lock_prefix, &seg_reg);
S86_PrintOpcode(opcode); S86_PrintOpcode(opcode);
@ -1327,7 +1330,6 @@ int main(int argc, char **argv)
case S86_Mnemonic_JNP_JO: /*FALLTHRU*/ case S86_Mnemonic_JNP_JO: /*FALLTHRU*/
case S86_Mnemonic_JNO: /*FALLTHRU*/ case S86_Mnemonic_JNO: /*FALLTHRU*/
case S86_Mnemonic_JNS: /*FALLTHRU*/ case S86_Mnemonic_JNS: /*FALLTHRU*/
case S86_Mnemonic_LOOP: /*FALLTHRU*/
case S86_Mnemonic_LOOPZ_LOOPE: /*FALLTHRU*/ case S86_Mnemonic_LOOPZ_LOOPE: /*FALLTHRU*/
case S86_Mnemonic_JCXZ: /*FALLTHRU*/ case S86_Mnemonic_JCXZ: /*FALLTHRU*/
case S86_Mnemonic_INT: /*FALLTHRU*/ case S86_Mnemonic_INT: /*FALLTHRU*/
@ -1583,6 +1585,12 @@ int main(int argc, char **argv)
register_file.instruction_ptr += S86_CAST(int16_t)opcode.displacement; register_file.instruction_ptr += S86_CAST(int16_t)opcode.displacement;
} break; } break;
case S86_Mnemonic_LOOP: {
register_file.reg.file.cx.word -= 1;
if (register_file.reg.file.cx.word != 0)
register_file.instruction_ptr += S86_CAST(int16_t)opcode.displacement;
} break;
case S86_Mnemonic_LOOPNZ_LOOPNE: { case S86_Mnemonic_LOOPNZ_LOOPNE: {
register_file.reg.file.cx.word -= 1; register_file.reg.file.cx.word -= 1;
if (register_file.reg.file.cx.word != 0 && !register_file.flags.zero) if (register_file.reg.file.cx.word != 0 && !register_file.flags.zero)
@ -1695,4 +1703,10 @@ int main(int argc, char **argv)
} }
S86_Print(S86_STR8("\n")); S86_Print(S86_STR8("\n"));
} }
if (dump) {
char buf[1024];
snprintf(buf, sizeof(buf), "%s_mem_dump.data", file_name);
S86_FileWrite(buf, memory, S86_MEMORY_SIZE);
}
} }

View File

@ -111,6 +111,42 @@ void S86_FileFree(S86_Buffer buffer)
VirtualFree(buffer.data, 0, MEM_RELEASE); VirtualFree(buffer.data, 0, MEM_RELEASE);
} }
bool S86_FileWrite(char const *file_path, void const *buffer, size_t buffer_size)
{
bool result = false;
// NOTE: Open file
// =========================================================================
HANDLE file_handle = CreateFile(
/*LPCSTR lpFileName*/ file_path,
/*DWORD dwDesiredAccess*/ GENERIC_WRITE,
/*DWORD dwShareMode*/ 0,
/*LPSECURITY_ATTRIBUTES lpSecurityAttributes*/ NULL,
/*DWORD dwCreationDisposition*/ CREATE_ALWAYS,
/*DWORD dwFlagsAndAttributes*/ 0,
/*HANDLE hTemplateFile*/ NULL
);
if (file_handle == INVALID_HANDLE_VALUE)
return result;
// NOTE: Write file to disk
// =========================================================================
DWORD bytes_written = 0;
BOOL write_file_result = WriteFile(
/*HANDLE hFile*/ file_handle,
/*LPVOID lpBuffer*/ buffer,
/*DWORD nNumberOfBytesToWrite*/ S86_CAST(DWORD)buffer_size,
/*LPDWORD lpNumberOfBytesWrite*/ &bytes_written,
/*LPOVERLAPPED lpOverlapped*/ NULL
);
S86_ASSERT(bytes_written == buffer_size);
result = write_file_result && bytes_written == buffer_size;
CloseHandle(file_handle);
return result;
};
void S86_Print(S86_Str8 string) void S86_Print(S86_Str8 string)
{ {
if (s86_globals.stdout_handle == NULL) { if (s86_globals.stdout_handle == NULL) {

View File

@ -53,6 +53,7 @@ uint8_t S86_BufferIteratorNextByte(S86_BufferIterator *it);
// ============================================================================ // ============================================================================
S86_Buffer S86_FileRead(char const *file_path); S86_Buffer S86_FileRead(char const *file_path);
void S86_FileFree(S86_Buffer buffer); void S86_FileFree(S86_Buffer buffer);
bool S86_FileWrite(char const *file_path, void const *buffer, size_t buffer_size);
// NOTE: Print // NOTE: Print
// ============================================================================ // ============================================================================

Binary file not shown.