Initial commit
This commit is contained in:
commit
ba898f2132
|
|
@ -0,0 +1 @@
|
|||
sectcl.bin
|
||||
|
|
@ -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
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
# An attempt at a single-sector x86-16 Tcl interpreter
|
||||
Inspired by sectorFORTH, sectorLISP and Picol.
|
||||
|
|
@ -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() {
|
||||
|
||||
}
|
||||
|
|
@ -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
|
||||
Loading…
Reference in New Issue