Files
equi/equi.c
T

134 lines
3.7 KiB
C

/*
* Equi platform reference implementation
*
* Created in 2022 by Luxferre, released into public domain
*
* See equi.md file for the specification and manual
*
* @license Unlicense <https://unlicense.org>
* @author Luxferre
*/
/* Standard includes with size optimizations for TCC */
#ifdef __TINYC__
#include <tcclib.h>
#else
#include <stdlib.h>
#include <stdio.h>
#endif
/*
* Non-standard includes
* To save space, we emulate necessary conio functions on non-6502 systems, not vice versa
*/
#ifdef __CC65__
#include <conio.h>
#else
#define cgetc() (fgetc(stdin))
#define cputc(c) (fputc(c, stdout))
#endif
/* Definitions section */
#define EQUI_VER "0.0.1"
#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 */
#define BS 8u /* Backspace character code */
/* 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
/* Command buffer size in bytes */
#ifndef GPD_AREA_SIZE
#define GPD_AREA_SIZE 6400u
#endif
/* Command buffer size in bytes */
#ifndef CMD_BUF_SIZE
#define CMD_BUF_SIZE 15600u
#endif
/* Maximum amount of CLT entries */
#ifndef CLT_ENTRIES_MAX
#define CLT_ENTRIES_MAX 512u
#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 */
/*
* Structures that describe Equi machine RAM using the above configuration
*/
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 */
unsigned int II:1; /* instruction ignore mode */
unsigned int CM:1; /* compilation mode */
unsigned int IM:1; /* interpretation mode */
ushort gpd_start;
ushort cmd_start;
ushort cmd_size;
ushort ibp; /* input buffer pointer */
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 = (uchar *)&ram.gpd - (uchar *)&ram.main_stack;
ram.cmd_start = (uchar *)&ram.cmdbuf - (uchar *)&ram.main_stack;
ram.cmd_size = CMD_BUF_SIZE;
ram.pc = ram.cmd_start; /* Start execution from the start of command buffer */
ram.ibp = ram.cmd_start; /* Start input buffering from the start of command buffer */
printf("Welcome to Equi v" EQUI_VER " by Luxferre, 2022\n\nCLT: 0x%X (%d bytes)\nGPD: 0x%X (%d bytes)\nCommand buffer: 0x%X (%d bytes)\nEqui ready\n\n",
(uchar *)&ram.clt - (uchar *)&ram.main_stack,
(uchar *)&ram.gpd - (uchar *)&ram.clt,
ram.gpd_start,
ram.cmd_start - ram.gpd_start,
ram.cmd_start, ram.cmd_size);
cputc('>');
cgetc();
return 0;
}