summaryrefslogtreecommitdiff
path: root/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'main.cpp')
-rw-r--r--main.cpp199
1 files changed, 11 insertions, 188 deletions
diff --git a/main.cpp b/main.cpp
index 12fdd32..bab7d46 100644
--- a/main.cpp
+++ b/main.cpp
@@ -1,6 +1,10 @@
/* SPDX-License-Identifier: Unlicense
*/
+#include "disasm.h"
+#include "data_buffer.h"
+#include "common.h"
+
#define OPTPARSE_IMPLEMENTATION
#define OPTPARSE_API static
#include "optparse/optparse.h"
@@ -8,9 +12,9 @@
#include <cassert>
#include <cinttypes>
#include <cstdio>
+#include <cstdint>
#include <cstdlib>
#include <cstring>
-#include <cstdint>
#include <cerrno>
#include <climits>
@@ -27,32 +31,6 @@
* Trace data parser is needed. Maybe just using atol(3) will be ok.
*/
-constexpr size_t kInstructionSizeStepBytes = 2;
-
-struct DataBuffer {
- static constexpr size_t kInitialSize = 4 * 1024;
- uint8_t *buffer{new uint8_t[kInitialSize]};
- size_t buffer_size{kInitialSize};
- size_t occupied_size{};
- void Expand(size_t new_size) {
- if (new_size <= buffer_size) {
- return;
- }
- uint8_t *new_buffer{new uint8_t[new_size]};
- assert(new_buffer);
- memcpy(new_buffer, buffer, occupied_size);
- delete [] buffer;
- buffer = new_buffer;
- buffer_size = new_size;
- }
- ~DataBuffer() {
- delete [] buffer;
- buffer = nullptr;
- buffer_size = 0;
- occupied_size = 0;
- }
-};
-
enum class TracedNodeType {
kInstruction,
kData,
@@ -68,166 +46,6 @@ struct DisasmNode {
~DisasmNode();
};
-static size_t disasm_verbatim(
- char *out, size_t out_sz, uint16_t instr, uint32_t offset, const DataBuffer &)
-{
- snprintf(out, out_sz, " .short 0x%04x | traced @%08x\n", instr, offset);
- return kInstructionSizeStepBytes;
-}
-
-static size_t disasm_mfff0_v4e70(
- char *out, size_t out_sz, uint16_t instr, uint32_t offset, const DataBuffer &code)
-{
- if (instr == 0x4e70) {
- snprintf(out, out_sz, " reset | %04x @%08x\n", instr, offset);
- } else if (instr == 0x4e71) {
- snprintf(out, out_sz, " nop | %04x @%08x\n", instr, offset);
- } else if (instr == 0x4e72) {
- snprintf(out, out_sz, " .short 0x%04x | stop (not implemented) @%08x\n", instr, offset);
- } else if (instr == 0x4e73) {
- snprintf(out, out_sz, " rte | %04x @%08x\n", instr, offset);
- } else if (instr == 0x4e75) {
- snprintf(out, out_sz, " rts | %04x @%08x\n", instr, offset);
- } else if (instr == 0x4e76) {
- snprintf(out, out_sz, " trapv | %04x @%08x\n", instr, offset);
- } else if (instr == 0x4e77) {
- snprintf(out, out_sz, " rtr | %04x @%08x\n", instr, offset);
- } else {
- return disasm_verbatim(out, out_sz, instr, offset, code);
- }
- return kInstructionSizeStepBytes;
-}
-
-static inline uint16_t GetU16BE(uint8_t *buffer)
-{
- return (static_cast<uint16_t>(buffer[0]) << 8) | static_cast<uint16_t>(buffer[1]);
-}
-
-static inline int16_t GetI16BE(uint8_t *buffer)
-{
- return (static_cast<uint16_t>(buffer[0]) << 8) | static_cast<uint16_t>(buffer[1]);
-}
-
-static inline int32_t GetI32BE(uint8_t *buffer)
-{
- return (static_cast<uint32_t>(buffer[0]) << 24) |
- (static_cast<uint32_t>(buffer[1]) << 16) |
- (static_cast<uint32_t>(buffer[2]) << 8) |
- static_cast<uint32_t>(buffer[3]);
-}
-
-static size_t disasm_jsr(
- char *out, size_t out_sz, uint16_t instr, uint32_t offset, const DataBuffer & code)
-{
- const int addrmode = instr & 0x3f;
- const int m = (addrmode >> 3) & 0x7;
- const int xn = addrmode & 0x7;
- switch (m) {
- case 0: // 4e80 .. 4e87
- case 1: // 4e88 .. 4e8f
- return disasm_verbatim(out, out_sz, instr, offset, code);
- case 2: // 4e90 .. 4e97
- snprintf(out, out_sz, " jsr %%a%d@ | %04x @%08x\n", xn, instr, offset);
- return kInstructionSizeStepBytes;
- case 3: // 4e98 .. 4e9f
- case 4: // 4ea0 .. 4ea7
- return disasm_verbatim(out, out_sz, instr, offset, code);
- case 5: // 4ea8 .. 4eaf, Displacement
- {
- const int16_t dispmt = GetI16BE(code.buffer + offset + kInstructionSizeStepBytes);
- const uint16_t dispmt_u = static_cast<uint16_t>(dispmt);
- snprintf(
- out, out_sz,
- " jsr %%a%d@(%d:w) | %04x %04x @%08x\n",
- xn, dispmt, instr, dispmt_u, offset);
- return 4;
- }
- break;
- case 6: // 4eb0 .. 4eb7, Brief Extension Word
- {
- const uint16_t briefext = GetU16BE(code.buffer + offset + kInstructionSizeStepBytes);
- const int m_0d_1a = (briefext >> 15) & 1;
- const int xn2 = (briefext >> 12) & 7;
- const int s_0w_1l = (briefext >> 11) & 1;
- const int8_t dispmt = briefext & 0xff;
- snprintf(
- out, out_sz,
- " jsr %%a%d@(%d,%%%c%d:%c) | %04x %04x @%08x\n",
- xn, dispmt, m_0d_1a ? 'a' : 'd', xn2, s_0w_1l ? 'l' : 'w', instr, briefext, offset);
- return 4;
- }
- break;
- case 7: // 4eb8 .. 4ebf, some are with Brief Extension Word
- switch (xn) {
- case 0: // 4eb8 (xxx).W
- {
- const int32_t dispmt = GetI16BE(code.buffer + offset + kInstructionSizeStepBytes);
- const uint16_t dispmt_u = static_cast<uint16_t>(dispmt);
- snprintf(
- out, out_sz,
- " jsr 0x%x:w | %04x %04x @%08x\n",
- dispmt, instr, dispmt_u, offset);
- return 4;
- }
- return disasm_verbatim(out, out_sz, instr, offset, code);
- case 1: // 4eb9 (xxx).L
- {
- const int32_t dispmt = GetI32BE(code.buffer + offset + kInstructionSizeStepBytes);
- const uint16_t dispmt_u_p1 = static_cast<uint16_t>(dispmt >> 16) & 0xffff;
- const uint16_t dispmt_u_p2 = static_cast<uint16_t>(dispmt) & 0xffff;
- snprintf(
- out, out_sz,
- " jsr 0x%x:l | %04x %04x %04x @%08x\n",
- dispmt, instr, dispmt_u_p1, dispmt_u_p2, offset);
- return 6;
- }
- return disasm_verbatim(out, out_sz, instr, offset, code);
- case 2: // 4eba, Displacement
- {
- const int16_t dispmt = GetI16BE(code.buffer + offset + kInstructionSizeStepBytes);
- const uint16_t dispmt_u = static_cast<uint16_t>(dispmt);
- snprintf(
- out, out_sz,
- " jsr %%pc@(%d:w) | %04x %04x @%08x\n",
- dispmt, instr, dispmt_u, offset);
- return 4;
- }
- break;
- case 3: // 4ebb
- {
- const uint16_t briefext = GetU16BE(code.buffer + offset + kInstructionSizeStepBytes);
- const int m_0d_1a = (briefext >> 15) & 1;
- const int xn2 = (briefext >> 12) & 7;
- const int s_0w_1l = (briefext >> 11) & 1;
- const int8_t dispmt = briefext & 0xff;
- snprintf(
- out, out_sz,
- " jsr %%pc@(%d,%%%c%d:%c) | %04x %04x @%08x\n",
- dispmt, m_0d_1a ? 'a' : 'd', xn2, s_0w_1l ? 'l' : 'w', instr, briefext, offset);
- return 4;
- }
- break;
- case 4: // 4ebc
- case 5: // 4ebd
- case 6: // 4ebe
- return disasm_verbatim(out, out_sz, instr, offset, code);
- }
- break;
- }
- return disasm_verbatim(out, out_sz, instr, offset, code);
-}
-
-static size_t disasm(
- char *out, size_t out_sz, uint16_t instr, uint32_t offset, const DataBuffer & code)
-{
- if ((instr & 0xfff0) == 0x4e70) {
- return disasm_mfff0_v4e70(out, out_sz, instr, offset, code);
- } else if ((instr & 0xffc0) == 0x4e80) {
- return disasm_jsr(out, out_sz, instr, offset, code);
- }
- return disasm_verbatim(out, out_sz, instr, offset, code);
-}
-
void DisasmNode::Disasm(const DataBuffer &code)
{
constexpr size_t kBufferSize = 100;
@@ -237,7 +55,11 @@ void DisasmNode::Disasm(const DataBuffer &code)
// We assume that no MMU and ROM is always starts with 0
assert(this->offset < code.occupied_size);
const uint16_t instr = GetU16BE(code.buffer + this->offset);
- this->size = disasm(asm_str, kBufferSize, instr, this->offset, code);
+ const size_t rendered_sz = m68k_disasm(
+ asm_str, kBufferSize, &this->size, instr, this->offset, code);
+ const size_t comment_rendered_sz = m68k_render_raw_data_comment(
+ asm_str + rendered_sz, kBufferSize - rendered_sz, this->offset, this->size, code);
+ (void) comment_rendered_sz;
}
DisasmNode::~DisasmNode()
@@ -315,6 +137,7 @@ static void RenderDisassembly(FILE *output, const DisasmMap &disasm_map, const D
if (node) {
assert(node->asm_string);
fputs(node->asm_string, output);
+ fputc('\n', output);
i += node->size;
} else {
fprintf(output, " .short 0x%02x%02x\n", code.buffer[i], code.buffer[i + 1]);