Initial commit

This commit is contained in:
Quinten Kock 2023-07-17 08:21:15 +02:00
commit ba898f2132
5 changed files with 119 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
sectcl.bin

20
Makefile Normal file
View File

@ -0,0 +1,20 @@
sectcl.bin: sectcl.nasm
nasm sectcl.nasm -f bin -o sectcl.bin
hexdump: sectcl.bin
hexdump -C sectcl.bin
qemu: sectcl.bin
qemu-system-i386 -fda sectcl.bin
gdb: sectcl.bin
gdb -ex "target remote | qemu-system-i386 -S -gdb stdio -fda sectcl.bin -m 16" -ex "break *0x7c00" -ex "continue"
objdump: sectcl.bin
objdump -D -Mintel,i8086 -b binary -m i386 sectcl.bin
quecl: quecl.c
gcc -Os -o quecl quecl.c -Wall -Wextra
clean:
rm sectcl.bin

2
README.md Normal file
View File

@ -0,0 +1,2 @@
# An attempt at a single-sector x86-16 Tcl interpreter
Inspired by sectorFORTH, sectorLISP and Picol.

64
quecl.c Normal file
View File

@ -0,0 +1,64 @@
// Quecl - a quecto-sized Tcl-inspired programming language
#include <stddef.h>
#include <stdio.h>
#define MEM_SIZE 32 * 1024 // 32 kilobytes
char MEMORY[MEM_SIZE];
size_t basepointer = 0;
size_t stack = 0;
size_t GetLine() {
// reads a line of user input into MEMORY
char c;
size_t ptr = stack;
do {
c = getchar();
MEMORY[stack++] = c;
} while (c != '\n');
MEMORY[stack++] = 0;
return ptr;
}
size_t GetVerbatim(size_t start) {
// Verbatim words are words that start with {
// Braces nest and can be escaped
unsigned int level = 0; // first char is {
size_t ptr = stack;
char c;
do {
c = MEMORY[start++];
// TODO: implement \-escaping
if(c == '{') level++;
if(c == '}') level--;
MEMORY[stack++] = 0;
} while(c != 0 && level > 0);
MEMORY[stack++] = 0;
return ptr;
}
size_t GetWord(size_t start) {
// Start indicates a memory address
// Returns a single "word"
// Rules of tcl words: [] (and $) work everywhere
// having { at the start means that the string is verbatim
// {} can be nested
// [] is command substitution: essentially calling eval
if(MEMORY[start] == '{') return GetVerbatim(start);
int quote = MEMORY[start] == '"';
char c;
size_t ptr = stack;
do {
c = MEMORY[start++];
// TODO: implement [] and maybe $
if(c == '\\') c = MEMORY[start++];
// TODO: implement 'smarter' escaping, e.g. \n
MEMORY[stack++] = c;
} while(c != '"' || (quote && c <= ' '));
return ptr;
}
int main() {
}

32
sectcl.nasm Normal file
View File

@ -0,0 +1,32 @@
; x86-16 BIOS bootloader
[BITS 16]
[ORG 0x7C00]
; jmp 0x7C00:start
start:
call GetChar
jmp start
; REGISTERS
; SP: 'top of memory'
; BP: points to variable map
; others: general purpose
GetChar:
xor AX,AX ; clear AH
int 0x16 ; read key via BIOS
; read key is now in AL
; fallthrough to PutChar to echo read key
PutChar:
mov AH,0xe ; TTY mode
int 0x10 ; print character in AL
cmp AL, 13 ; if \r, print \r\n and return \n
jne .ret
mov AL, 10
call PutChar
.ret: ret
; fill up sector, add boot signature
TIMES 510 - ($ - $$) db 0
DW 0xAA55