Last active
February 12, 2022 06:14
-
-
Save logicplace/f7b9e3f991fd05a533d6eb2d6336b7bb to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <std/mem.pat> | |
#include <std/sys.pat> | |
bitfield u24 { | |
value : 24; | |
}; | |
fn ru(u128 n) { | |
return std::mem::read_unsigned($, n); | |
}; | |
struct Int32 { | |
u8 n; | |
if (n == 0x81) { | |
u8 value; | |
} | |
else if (n == 0x82) { | |
be u16 value; | |
} | |
else if (n == 0x83) { | |
be u24 value; | |
} | |
else if (n == 0x84) { | |
be s32 value; | |
} | |
}; | |
struct Name { | |
u8 len; | |
char string[len]; | |
}; | |
struct Expressions { | |
u8 opers[while(ru(1) < 0xe0)]; | |
}; | |
fn varToLetter(u8 v) { | |
return str(char(v & 0x7f)); | |
}; | |
struct ASWx { | |
be u16 asw [[hidden]]; | |
u8 part_type; | |
Int32 offset [[transform("getInt32")]]; | |
}; | |
struct Header { | |
// Module Begin | |
u8 mb [[hidden]]; | |
Name processor; | |
Name module_name; | |
// Address Descriptor | |
u8 ad [[hidden]]; | |
u8 bits_per_mau; | |
u8 max_maus; | |
if ((ru(1) & 0xfe) == 0xcc) { | |
u8 endianness [[format("getEndian")]]; | |
} | |
// Part pointers | |
ASWx parts[while (ru(2) == 0xd7e2)]; | |
}; | |
struct SectionType { | |
u8 type; | |
if (type == 0xd9) { | |
// Y, addressing mode | |
u8 arg; | |
} | |
}; | |
struct Record { | |
u8 type; | |
if (type == 0xe1) { | |
// ME - Module end | |
} | |
else if (type == 0xe2) { | |
// AS - Assign | |
u8 subtype; | |
if (subtype == 0xc9) { | |
// Value record | |
Int32 symbol_index [[format("getInt32")]]; | |
Expressions value; | |
} | |
else if (subtype == 0xd0) { | |
Int32 section_number [[format("getInt32")]]; | |
Expressions value [[comment("result in MAUs")]]; | |
} | |
else if (subtype == 0xd3) { | |
// Section size | |
Int32 section_number [[format("getInt32")]]; | |
Int32 section_size [[format("getFromMAUs")]]; | |
} | |
} | |
// 0xe3 // IR - Initialize relocation base | |
// 0xe4 // LR - Load with relocation | |
else if (type == 0xe5) { | |
// SB - Section begin | |
Int32 section_number [[format("getInt32")]]; | |
} | |
else if (type == 0xe6) { | |
// ST - Section type | |
Int32 section_number [[format("getInt32")]]; | |
SectionType section_types[while(ru(1) >= 0x80)]; | |
Name section_name [[format("getName")]]; | |
} | |
else if (type == 0xe7) { | |
// SA - Section alignment | |
Int32 section_number [[format("getInt32")]]; | |
Expressions mau_boundary_and_optionally_page_size; | |
//Expression page_size; // Optional | |
} | |
else if (type == 0xe8) { | |
// NI - Internal name (??) | |
Int32 symbol_index [[format("getInt32")]]; | |
Name symbol_name [[format("getName")]]; | |
} | |
// 0xe9 // NX - External name | |
else if (type == 0xea) { | |
// CO - Comment | |
u8 var; | |
Name value [[format("getName")]]; | |
} | |
else if (type == 0xeb) { | |
// DT - Date and time | |
Int32 year [[format("getInt32")]]; | |
u8 month; | |
u8 day; | |
u8 hour; | |
u8 minute; | |
u8 second; | |
} | |
// 0xec // AD - Address description | |
else if (type == 0xed) { | |
// LD - Load | |
Int32 count [[format("getInt32"), transform("getInt32")]]; | |
if (count == 1) { | |
u8 data[count]; | |
} | |
// Not sure if these are be or le | |
else if (count == 2) { | |
u16 data[count]; | |
} | |
// ... | |
} | |
// 0xee // CS - Checksum followed by sum value | |
// 0xef // CS - Checksum (reset sum to 0) | |
// 0xf0 // NN - Name | |
else if (type == 0xf1) { | |
// AT - Attribute | |
u8 subtype; | |
if (subtype == 0xc9) { | |
// Attribute records | |
Int32 symbol_index [[format("getInt32")]]; | |
u8 symbol_type [[format("getSymbolType")]]; | |
if (symbol_type != 0) { | |
u8 num_elements; | |
} | |
} | |
} | |
// 0xf2 // TY - Type | |
// 0xf3 // RI - Retain internal symbol | |
// 0xf4 // WX - Weak external | |
// 0xf5 // LI - Library search list | |
// 0xf6 // LX - Library external | |
// 0xf7 // RE - Replicate | |
else if (type == 0xf8) { | |
// SC - Scope definition | |
u8 block_type; | |
Int32 block_size [[format("getInt32"), comment("0 = unknown")]]; | |
if (block_type == 1) { | |
// unique typedefs for module | |
Name module_name [[format("getName")]]; | |
} | |
else if (block_type == 2) { | |
// global typedefs | |
Name zero_length_name [[format("getName")]]; // ?? | |
} | |
else if (block_type == 3) { | |
// high level module scopr beginning | |
Name module_name [[format("getName")]]; | |
} | |
// 4 // global function | |
// 5 // file name for source line numbers | |
// 6 // local function | |
else if (block_type == 10) { | |
Name module_name [[format("getName")]]; // or filename with path | |
Name input_relocatable_object_filename [[format("getName")]]; | |
Int32 tool_type; | |
/* // Not in Epson's: | |
Name version_with_revision; | |
Int32 year; | |
u8 month; | |
u8 day; | |
u8 hour; | |
u8 minute; | |
u8 second; | |
*/ | |
} | |
else if (block_type == 11) { | |
Name section_name [[format("getName")]]; | |
u8 section_type [[format("getSectionType")]]; | |
Int32 section_index [[format("getInt32")]]; | |
if (ru(1) == 0xd2) { | |
u8 var [[format("varToLetter")]]; | |
Int32 index; | |
} | |
else { | |
Int32 offset [[format("getFromMAUs")]]; | |
} | |
} | |
} | |
// 0xf9 // LN - Line number | |
}; | |
fn getEndian(u8 x) { | |
if (x == 0xcc) return "big"; | |
return "little"; | |
}; | |
fn getInt32(Int32 x) { | |
std::assert(x.n <= 0x84, "Invalid number"); | |
if (x.n <= 0x7f) return x.n; | |
else if (x.n > 0x80) return x.value; | |
return 0; | |
}; | |
fn getFromMAUs(Int32 x) { | |
return getInt32(x) * (header.bits_per_mau / 8); | |
}; | |
fn getName(Name x) { | |
return x.string; | |
}; | |
fn getSymbolType(u8 x) { | |
if (x == 0) return "Unspecified"; | |
if (x == 3) return "8-bit data byte"; | |
if (x == 5) return "16-bit short data word"; | |
if (x == 7) return "32-bit long data word"; | |
if (x == 10) return "32-bit floating point"; | |
if (x == 11) return "64-bit floating point"; | |
if (x == 12) return "10 or 12 byte floating point"; | |
if (x == 15) return "Instruction address"; | |
return "unknown symbol type (" + str(x) + ")"; | |
}; | |
fn getSectionType(u8 x) { | |
if (x == 0) return "Mixture"; | |
if (x == 1) return "Code"; | |
if (x == 2) return "Read/Write data"; | |
if (x == 3) return "Read-only data"; | |
if (x == 4) return "Stack"; | |
if (x == 5) return "Memory"; | |
return "unknown section type (" + str(x) + ")"; | |
}; | |
Header header @ 0x00; | |
std::assert(header.mb == 0xe0, "Invalid header"); | |
Record records[while(!std::mem::eof())] @ sizeof(header); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment