perfaware/part1: Support listing 0055
This commit is contained in:
parent
dd83866f2b
commit
d888968ce0
@ -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
|
||||||
|
BIN
part1/listing_0055_challenge_rectangle
Normal file
BIN
part1/listing_0055_challenge_rectangle
Normal file
Binary file not shown.
53
part1/listing_0055_challenge_rectangle.asm
Normal file
53
part1/listing_0055_challenge_rectangle.asm
Normal 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
|
25214
part1/listing_0055_challenge_rectangle.txt
Normal file
25214
part1/listing_0055_challenge_rectangle.txt
Normal file
File diff suppressed because it is too large
Load Diff
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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) {
|
||||||
|
@ -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
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
BIN
project.rdbg
BIN
project.rdbg
Binary file not shown.
Loading…
Reference in New Issue
Block a user