Skip to content

Instantly share code, notes, and snippets.

@logicplace
Last active February 12, 2022 06:14
Show Gist options
  • Save logicplace/f7b9e3f991fd05a533d6eb2d6336b7bb to your computer and use it in GitHub Desktop.
Save logicplace/f7b9e3f991fd05a533d6eb2d6336b7bb to your computer and use it in GitHub Desktop.
#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