/* * Equi platform reference implementation * * Created in 2022 by Luxferre, released into public domain * * See equi.md file for the specification and manual * * @license Unlicense * @author Luxferre */ /* Standard includes with size optimizations for TCC */ #ifdef __TINYC__ #include #else #include #include #endif /* * Non-standard includes * To save space, we emulate necessary conio functions on non-6502 systems, not vice versa */ #ifdef __CC65__ #include #else #define cgetc() (fgetc(stdin)) #endif /* Definitions section */ #define ushort unsigned short /* basic 16-bit integer */ #define uchar unsigned char /* basic 8-bit integer */ #define WS sizeof(ushort) /* Equi word size in bytes */ #define CLT_ENTRY_LEN 6u /* Amount of significant compiled word characters */ #define CLT_ENTRY_SIZE (CLT_ENTRY_LEN + WS) /* Full size in bytes taken by one CLT entry */ /* Configuration section (constants overridable at compile-time) */ /* Main and return stack size in bytes */ #ifndef STACK_SIZE #define STACK_SIZE 256u #endif /* Literal stack size in bytes */ #ifndef LIT_STACK_SIZE #define LIT_STACK_SIZE 32u #endif /* GPD (general purpose data) area start address */ #ifndef GPD_AREA_START #define GPD_AREA_START 0x2300u #endif /* Command buffer start address */ #ifndef CMD_BUF_START #define CMD_BUF_START 0x3b80u #endif /* Command buffer size in bytes */ #ifndef CMD_BUF_SIZE #define CMD_BUF_SIZE 15600u #endif /* Some necessary constants and offsets derived from the above values */ #define STACK_SIZE_WORDS (STACK_SIZE / WS) /* Main and return stack size in words */ #define MAIN_STACK_ADDR 0u /* Main stack address */ #define RETURN_STACK_ADDR STACK_SIZE /* Return stack address */ #define LIT_STACK_ADDR (RETURN_STACK_ADDR + STACK_SIZE) /* Literal stack address */ #define PC_ADDR (LIT_STACK_ADDR + LIT_STACK_SIZE) /* Program counter address */ #define CBP_ADDR (PC_ADDR + WS) /* Compilation buffer pointer location address */ #define CLTP_ADDR (CBP_ADDR + WS) /* Compilation lookup table pointer location address */ #define FLAGS_ADDR (CLTP_ADDR + WS) /* Flags register address */ #define GPD_START_LOC_ADDR (FLAGS_ADDR + 1u) /* Location where GPD_AREA_START value is stored */ #define CMD_START_LOC_ADDR (GPD_START_LOC_ADDR + WS) /* Location where CMD_BUF_START value is stored */ #define CMD_SIZE_LOC_ADDR (CMD_START_LOC_ADDR + WS) /* Location where CMD_BUF_SIZE value is stored */ #define CLT_START (CMD_SIZE_LOC_ADDR + 213u) /* should be 0x300 by default */ #define CLT_SIZE (GPD_AREA_START - CLT_START) /* Compilation lookup table size in bytes */ #define CLT_ENTRIES_MAX (CLT_SIZE / CLT_ENTRY_SIZE) /* Maximum amount of entries in CLT, must be integer */ #define GPD_AREA_SIZE (CMD_BUF_START - GPD_AREA_START) /* GPD area size in bytes */ /* * Structures that describe Equi machine RAM using the above configuration */ struct EquiFlags { unsigned int II:1; /* instruction ignore mode */ unsigned int CM:1; /* compilation mode */ unsigned int IM:1; /* interpretation mode */ }; struct CLTEntry { uchar name[CLT_ENTRY_LEN]; /* compiled word name */ ushort loc; /* compiled word location */ }; struct EquiRAM { ushort main_stack[STACK_SIZE_WORDS]; ushort return_stack[STACK_SIZE_WORDS]; uchar literal_stack[LIT_STACK_SIZE]; ushort pc; /* program counter */ ushort msp; /* main stack pointer */ ushort rsp; /* return stack pointer */ uchar lsp; /* literal stack pointer */ ushort cbp; /* compilation buffer pointer */ ushort cltp; /* compilation lookup table pointer */ struct EquiFlags flags; ushort gpd_start; ushort cmd_start; ushort cmd_size; uchar reserved[206u]; /* reserved space */ struct CLTEntry clt[CLT_ENTRIES_MAX]; /* compilation lookup table */ uchar gpd[GPD_AREA_SIZE]; uchar cmdbuf[CMD_BUF_SIZE]; }; /* Before running the main code, instantiate the machine RAM */ static struct EquiRAM ram; /* Also create an alternative view of the same RAM area for direct offset-based access */ static uchar* flatram = (uchar *)&ram; int main(int argc, char* argv[]) { /* initialize the RAM in the most standard way */ ram.gpd_start = GPD_AREA_START; ram.cmd_start = CMD_BUF_START; ram.cmd_size = CMD_BUF_SIZE; printf("Equi command buffer: 0x%X\n", ram.cmd_size); cgetc(); return 0; }