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%.txt %build_dir% 1>NUL
|
||||
|
||||
%build_dir%\sim8086.exe --exec --log-instruction-ptr %build_dir_listing_0054% > %build_dir_listing_0054%_disassembled.txt
|
||||
%build_dir%\sim8086.exe %build_dir_listing_0054% > %build_dir_listing_0054%_disassembled.asm
|
||||
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
|
||||
popd
|
||||
|
||||
nasm %build_dir_listing_0054%_disassembled.asm
|
||||
|
||||
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
|
||||
|
||||
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;
|
||||
|
||||
if (result.effective_addr == S86_EffectiveAddress_Dest && result.effective_addr_loads_mem) {
|
||||
if (result.src == S86_MnemonicOp_DirectAddress ||
|
||||
result.src == S86_MnemonicOp_Immediate ||
|
||||
result.src == S86_MnemonicOp_Invalid ||
|
||||
(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;
|
||||
}
|
||||
result.word_byte_prefix = (result.wide || result.src >= S86_MnemonicOp_AX && result.src <= S86_MnemonicOp_BX)
|
||||
? S86_WordBytePrefix_Word
|
||||
: S86_WordBytePrefix_Byte;
|
||||
}
|
||||
|
||||
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_LOG_INSTRUCTION_PTR[] = "--log-instruction-ptr";
|
||||
char const CLI_ARG_DUMP[] = "--dump";
|
||||
#define PRINT_USAGE \
|
||||
S86_PrintLnFmt("USAGE: sim8086.exe [%.*s] [%.*s] <binary asm file>", \
|
||||
S86_ARRAY_UCOUNT(CLI_ARG_EXEC) - 1, \
|
||||
CLI_ARG_EXEC, \
|
||||
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)
|
||||
{
|
||||
// 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_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 log_instruction_ptr = false;
|
||||
bool dump = false;
|
||||
S86_Str8 file_path = {0};
|
||||
for (int arg_index = 1; arg_index < argc; arg_index++) {
|
||||
char const *arg_cstring = argv[arg_index];
|
||||
@ -884,6 +883,8 @@ int main(int argc, char **argv)
|
||||
exec_mode = true;
|
||||
} else if (S86_Str8_Equals(arg_str8, CLI_ARG_LOG_INSTRUCTION_PTR_STR8)) {
|
||||
log_instruction_ptr = true;
|
||||
} else if (S86_Str8_Equals(arg_str8, CLI_ARG_DUMP_STR8)) {
|
||||
dump = true;
|
||||
} else {
|
||||
if (file_path.size) {
|
||||
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
|
||||
S86_PrintLn(S86_STR8("bits 16"));
|
||||
|
||||
uint32_t const S86_MEMORY_SIZE = 1024 * 1024;
|
||||
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);
|
||||
|
||||
S86_MnemonicOpToRegisterFileMap mnemonic_op_to_register_file_map[] = {
|
||||
@ -1246,15 +1248,16 @@ int main(int argc, char **argv)
|
||||
|
||||
// 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;
|
||||
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) {
|
||||
S86_Buffer instruction_buffer = {0};
|
||||
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);
|
||||
instruction_it.index = register_file.instruction_ptr;
|
||||
S86_Opcode opcode = S86_DecodeOpcode(&instruction_it, DECODE_TABLE, S86_ARRAY_UCOUNT(DECODE_TABLE), &lock_prefix, &seg_reg);
|
||||
S86_PrintOpcode(opcode);
|
||||
|
||||
register_file.instruction_ptr += opcode.byte_size;
|
||||
@ -1327,7 +1330,6 @@ int main(int argc, char **argv)
|
||||
case S86_Mnemonic_JNP_JO: /*FALLTHRU*/
|
||||
case S86_Mnemonic_JNO: /*FALLTHRU*/
|
||||
case S86_Mnemonic_JNS: /*FALLTHRU*/
|
||||
case S86_Mnemonic_LOOP: /*FALLTHRU*/
|
||||
case S86_Mnemonic_LOOPZ_LOOPE: /*FALLTHRU*/
|
||||
case S86_Mnemonic_JCXZ: /*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;
|
||||
} 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: {
|
||||
register_file.reg.file.cx.word -= 1;
|
||||
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"));
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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);
|
||||
void S86_FileFree(S86_Buffer buffer);
|
||||
bool S86_FileWrite(char const *file_path, void const *buffer, size_t buffer_size);
|
||||
|
||||
// NOTE: Print
|
||||
// ============================================================================
|
||||
|
BIN
project.rdbg
BIN
project.rdbg
Binary file not shown.
Loading…
Reference in New Issue
Block a user