diff options
109 files changed, 1 insertions, 4395 deletions
diff --git a/.gitignore b/.gitignore index e9ab7f3..c73d5a5 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ code.o *.img thefile riscv +pc-thingg diff --git a/pc-thing/aliases.txt b/pc-thing/aliases.txt deleted file mode 100644 index 9eda816..0000000 --- a/pc-thing/aliases.txt +++ /dev/null @@ -1 +0,0 @@ -jsr=jmr \ No newline at end of file diff --git a/pc-thing/assembler.md b/pc-thing/assembler.md deleted file mode 100644 index ee7abcc..0000000 --- a/pc-thing/assembler.md +++ /dev/null @@ -1,123 +0,0 @@ -# basic syntax - -unlike 99.9% of assembly languages, in this one, arguments are separated by spaces (no comma), also indentation doesn't matter, neither do labels, the cpu starts executing from top to bottom, code also doesn't have to be in a label for it to be executed - -example: - -```asm -start: - mov a 1 ; put 1 into the a register - mov b 2 ; put 2 into the b register - add ; add registers a and b and put it in c - str c 0 ; store c at address 0 - - ld a 0 ; load address 0 into a - mov b 14 ; put 14 into the b register - mul -``` - -# list of cool features that come with the assembler - -## code labels - -code labels add a way for you to make jumps without constantly changing the destinations because they're tied to line numbers - -example: -```asm -start: - mov a 1 ; change the 1 to a 0 to change result - cmp a 0 - jnz zero - jmp one ; else, jump to one - - zero: - halt ; if zero, halt - - one: - jmp one ; if one, infinite loop -``` - -## macros - -macros allow you to shorten how you do basic tasks (such as storing data in memory) - -example: -```asm -.macro store(val, addr) \ - put a @val\ - str a @addr - -store 1 0 -store 2 1 -store 2763 2 -``` - -## labels - -basically a mix of a macro and a code label - -example: -```asm -.label one 1 ; one - -mov a one ; one -> reg A -str a 0 ; reg A -> 0x0 -``` - -## using code - -`#using` allows you to include code from other files - -example: -```asm -start: - mov a -1 ; 65535 - str a 16 ; put our number into 16 - #using printer.a - jmr print_num ; print number at 16 (well not print but stringify) - mov a 1 ; syscall 1 - write - mov b 1 ; fd 1 - stdout - mov c 32 ; from address 32 - sys ; syscall -``` -this will use printing code from `printer.a` to print the number 65535 - -## data - -to insert data in your code (for example: a string) you can use the `.str` or `.hex` instruction(?) thingies - -dunno how to call them, anyways, example - -```asm -mov a 1 ; write -mov b 1 ; stdout -mov c [string] -sys -end - -string: -.str "is your refrigerator running?" -``` - -oh and btw, if you're using a label to keep track of their location (actually, what else would you use), reference them by doing `[NAME]` instead of `NAME` because due to some jank with how the emulator/assembler/whatever works i needed to offset the location for `NAME` references for jump instructions to work - -here's an example of using them as variable storage - -```asm -init: - mov a 1 - str a [counter] - -increment: - ld a [counter] - mov b 1 - add - str c [counter] - -counter: -.hex 0 -``` - -## - -also i think raw code doesnt support indentation \ No newline at end of file diff --git a/pc-thing/assembler.ts b/pc-thing/assembler.ts deleted file mode 100644 index 4ac2a93..0000000 --- a/pc-thing/assembler.ts +++ /dev/null @@ -1,250 +0,0 @@ -import dedent from "npm:dedent"; -import { PC } from "./pc.ts"; -const pc = new PC() -const labels: Record<string, string> = {} - -const code = new TextDecoder() - .decode(Deno.readFileSync(Deno.args[0] ?? 'code.a')) - -const aliases = Object.fromEntries(new TextDecoder() - .decode(Deno.readFileSync('aliases.txt')).split('\n').map(a=>a.split('='))) - -const macros: Record<string, (args: string[]) => string> = {} - -interface DataAddr { - line: number, - offset: number -} - -interface ObjectFile { - // number is the ammount of bytes to skip - code: (string | number)[], - offset: number, - // line number, data - data: [number, number[]][] -} - -const object: ObjectFile = { - code: [], - data: [], - offset: 2**16 / 2 -} - -const advAliases: Record<string, string> = { - 'mov,reg,addr': dedent`\ - mov d @1 - ld @0 d`, - 'mov,addr,reg': dedent`\ - mov d @0 - str d @1`, - 'str,reg,addr': dedent`\ - mov d @1 - str d @0`, - 'ld,reg,addr': dedent`\ - mov d @1 - ld @0 d`, - 'add,': `add c a b`, - 'sub,': `sub c a b`, - 'mul,': `mul c a b`, - 'div,': `div c a b`, -} - -function processCode(rcode: string, offset: number = 0): (string | number)[] { - const code: (string | number)[] = rcode - .split('\n') - .map(l => l.trim()) - .map(l => l.replace(/\s*(?<!(?<!\"[^"]*)\"[^"]*);.*$/gm, '')) - .map(l => l.replace(/(?<!(?<!\"[^"]*)\"[^"]*)'(.)'/g, (_, char) => char.charCodeAt(0).toString())) - .map(l => l.replace(/0x([0-9A-Fa-f]+)/g, (_, hex: string) => ''+parseInt(hex, 16))) - .filter(l => l) - .reduce((acc, l) => { - if (acc[acc.length - 1] && acc[acc.length - 1].endsWith('\\')) { - acc[acc.length - 1] = acc[acc.length - 1].slice(0, -1) + '\n' - acc[acc.length - 1] += l - return acc - } - acc.push(l) - return acc - }, [] as string[]); - const result: (string | number)[] = [] - - let i = offset; - let li = 0; - //parse macros - while (li < code.length) { - const el = code[li]; - if (typeof el == 'number') { - li++; - continue; - } - const sel = el.split(' '); - li++; - if (sel[0] == '.macro') { - sel.shift(); - let tx = sel.join(' '); - const pattern = /([A-z\-_0-9]+)\((.*?)\)\s*/g - const match = [...tx.matchAll(pattern)][0] - tx = tx.replace(pattern, '').replaceAll('\\n', '\n'); - if (!match) throw 'knives at you' - const args = (match[2] ?? '').split(/,\s*/g) - macros[match[1]] = (args_: string[]) => { - let s = tx; - let i = 0 - for (const a of args_) { - s = s.replaceAll('@'+args[i], a) - i++ - } - return s - } - continue; - } - i++ - } - - // parse other - i = offset; - li = 0; - while (li < code.length) { - const el = code[li]; - if (typeof el == 'number') { - li++; - continue; - } - const sel = el.split(' '); - li++; - if (el.endsWith(":")) { - console.log(sel[0], i) - labels[sel[0].replace(/:$/g,'')] = '$'+i; - labels[`[${sel[0].replace(/:$/g,'')}]`] = `[${i}]`; - continue; - } - if (sel[0] == '.label') { - labels[sel[1]] = sel[2]; - continue; - } - if (macros[sel[0]]) { - const macro = macros[sel[0]] - sel.shift() - const r = macro(sel).split('\n') - i+=r.length - continue; - } - if (sel[0] == '.macro') { - continue; - } - if (sel[0] == '.offset') { - continue; - } - if (sel[0] == '#using') { - const newCode = processCode(new TextDecoder().decode(Deno.readFileSync(sel[1])), i + 1) - i += newCode.length + 1 - continue; - } - i++ - } - - i = offset; - li = 0; - while (li < code.length) { - let el = code[li]; - if (typeof el == 'number') { - result.push(el); - li++; - continue; - } - let sel = el.split(' '); - if (aliases[sel[0]]) el = el.replace(sel[0], aliases[sel[0]]); - li++; - if (macros[sel[0]]) { - for (const label of Object.keys(labels).sort((a, b) => b.length - a.length)) { - el = el.split(' ').map(a => a == label ? labels[label] : a).join(' ') - } - sel = el.split(' ') - const macro = macros[sel[0]] - sel.shift() - let rr = macro(sel) - for (const label of Object.keys(labels).sort((a, b) => b.length - a.length)) { - rr = rr.replace(label, labels[label]) - } - const r = rr.split('\n') - result.push(...r) - i+=r.length - continue; - } - if (el.endsWith(":")) { - continue; - } - if (sel[0] == '.label') { - continue; - } - if (sel[0] == '.macro') { - continue; - } - if (sel[0] == '.offset') { - object.offset = +sel[1] - continue; - } - if (sel[0] == '#using') { - const newCode = processCode(new TextDecoder().decode(Deno.readFileSync(sel[1])), i + 1) - result.push(`jmp $${i+newCode.length+1}`) // skip over included code - result.push(...newCode) - i += newCode.length + 1 - continue; - } - if (sel[0] == '.hex') { - object.data.push([ - i, - [parseInt(sel[1], 16)] - ]) - result.push(1) - i++; - continue; - } - if (sel[0] == '.str') { - const str = [...el.matchAll(/"(.*?)(?<!\\)"/g)][0][1].replaceAll('\\"', '"') - object.data.push([ - i, - new Array(str.length).fill(0).map((_, i) => str.charCodeAt(i)) - ]) - result.push(str.length) - i++; - continue; - } - for (const label of Object.keys(labels).sort((a, b) => b.length - a.length)) { - el = el.split(' ').map(a => a == label ? labels[label] : a).join(' ') - } - const [cmd, ...args] = el.split(' '); - const argtypes = args.map((a: string) => { - if (pc.regNames.split('').includes(a)) return 'reg'; - if (a.match(/^\$[0-9A-Fa-f]+$/g)) return 'addr'; - return 'val'; - }) - if (advAliases[`${cmd},${argtypes.join(',')}`]) { - el = advAliases[`${cmd},${argtypes.join(',')}`].replace(/@([0-9]+)/g, (_m, arg) => { - if (argtypes[+arg] == 'addr') { - return args[+arg].replace('$', '') - } - return args[+arg] - }) - result.push(...el.split('\n')); - i += el.split('\n').length; - continue; - } - result.push(el.replace(/\$[0-9A-Fa-f]+/g, (_, addr) => addr)) - i++ - } - return result -} - -object.code = processCode(code+'\nend') - -// console.log(labels) - -// for (const label of Object.keys(labels)) { -// result.push(`ld a ${labels[label]}`); -// result.push(`mov b ${labels[label]}`); -// result.push(`mov c 0`); -// result.push(`dbg ${label}`) -// } - -Deno.writeTextFileSync('code.o', JSON.stringify(object)) diff --git a/pc-thing/build-bootloader.sh b/pc-thing/build-bootloader.sh deleted file mode 100755 index 2bdb6bf..0000000 --- a/pc-thing/build-bootloader.sh +++ /dev/null @@ -1,7 +0,0 @@ -deno -A assembler.ts code/bootloader.a -deno -A ramgen.ts -cat iram.bin > diskloader.bin -deno -A assembler.ts code/move-bootloader.a -deno -A ramgen.ts -cat iram.bin > bootloader.bin -cat diskloader.bin >> iram.bin \ No newline at end of file diff --git a/pc-thing/build-disk.sh b/pc-thing/build-disk.sh deleted file mode 100755 index f09f086..0000000 --- a/pc-thing/build-disk.sh +++ /dev/null @@ -1,3 +0,0 @@ -deno -A assembler.ts $1 -deno -A ramgen.ts disk.img -truncate -s 1440K thefile \ No newline at end of file diff --git a/pc-thing/code.a b/pc-thing/code.a deleted file mode 100644 index abb6021..0000000 --- a/pc-thing/code.a +++ /dev/null @@ -1,9 +0,0 @@ -start: - mov a -1 ; 65535 - str a 16 ; put our number into 16 - #using printer.a - jmr print_num ; print number at 16 (well not print but stringify) - mov a 1 ; write - mov b 1 ; stdout - mov c 32 ; address - sys ; syscall \ No newline at end of file diff --git a/pc-thing/code/.vscode/settings.json b/pc-thing/code/.vscode/settings.json deleted file mode 100644 index b943dbc..0000000 --- a/pc-thing/code/.vscode/settings.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "deno.enable": true -} \ No newline at end of file diff --git a/pc-thing/code/bootloader.a b/pc-thing/code/bootloader.a deleted file mode 100644 index 66a221c..0000000 --- a/pc-thing/code/bootloader.a +++ /dev/null @@ -1,109 +0,0 @@ -.offset 0x6000 ; bootloader is in 0x6000, copied there by another script -start: - mov a 0 - str a [gottenNZ] - ; currSector -> A - mov a [currSector] - ld a a - str a 0x7cff - - mov b 512 - mul - str c [sectorOffset] - - mov a 0 - str a [bytePointer] - - mov a 0 - str a [ptrThing] - - copySector: - mov a [sectorOffset] - ld a a - mov b [bytePointer] - ld b b - add c a b - ; - swp a c - mov b 0x8000 ; default code position - add c a b - str c [targetPointer] - - ; ld a [sectorOffset] - mov a 0x7d00 - ; add - ; swp c a - mov b [ptrThing] - ld b b - add c a b - mov b [targetPointer] - ld b b - ; swp c b - ; a <- $b - ld a b - push a ; push b - ld a c - ; push c ; push c - str b a ; $b <- c - pop a - ; $c <- b - str c a - ; swpm c b - - ld a c - mov b 0 - cmr a a b - mov b 1 - xor c a b - swp a c - mov b [gottenNZ] - ld b b - or c a b - mov a [gottenNZ] - str c a - - ;continue loop - ; pointer to 8xxx - mov a [ptrThing] - ld a a - mov b 1 - add c a b - mov a [ptrThing] - str c a - - ; pointer offset for sector thing - mov a [bytePointer] - ld a a - mov b 1 - add - str c [bytePointer] - - ; offset == 513 - cmp c 513 - jz copySector - ; continue main loop - mov a [currSector] - ld a a - mov b 1 - add c a b - mov a [currSector] - str c a - mov a [gottenNZ] - ld a a - cmp a 0 - jz start - ;escaped - jmp 0x8001 - -ptrThing: -.hex 0 -currSector: -.hex 0 -sectorOffset: -.hex 0 -bytePointer: -.hex 0 -gottenNZ: -.hex 0 -targetPointer: -.hex 0 \ No newline at end of file diff --git a/pc-thing/code/calc.a b/pc-thing/code/calc.a deleted file mode 100644 index 2aa1b02..0000000 --- a/pc-thing/code/calc.a +++ /dev/null @@ -1,74 +0,0 @@ -.label len 1 - -jmp start -read_input: - mov a 0 - mov b 0 - mov c 64 - sys - mov b 1 - sub - str c len - ret - -str_to_num: - ; pointer to current character - .label ptr 2 - ld a len - mov b 63 - add - str c ptr - .label mult 3 - mov a 1 - str a mult - .label num 4 - mov a 0 - str a num - .label zero 48 - stm_loop: - ;load char, subtract zero, multiply by 10 - ld b ptr - ldr a b - mov b zero - sub - swp c a - ld b mult - mul - - ; add to num - swp c b - ld a num - add - str c num - - ld a mult - mov b 10 - mul - str c mult - - ; move pointer - ld a ptr - mov b 1 - sub - str c ptr - cmp c 63 - jz stm_loop - ret - -start: - jmr read_input - jmr str_to_num - ld a 4 - str a 8 ; store number 1 to 8 - jmr read_input - jmr str_to_num - ld a 4 ; load number from read - ld b 8 - add - str c 16 ; put our number into 16 - #using printer.a - jmr print_num ; print number at 16 (well not print but stringify) - mov a 1 ; write - mov b 1 ; stdout - mov c 32 ; address - sys ; syscall \ No newline at end of file diff --git a/pc-thing/code/code-1.a b/pc-thing/code/code-1.a deleted file mode 100644 index 02be1b2..0000000 --- a/pc-thing/code/code-1.a +++ /dev/null @@ -1,6 +0,0 @@ -start: - mov a 42 - str a 0 - #using sub1.a - jmr do_the_thing - ld a 0 \ No newline at end of file diff --git a/pc-thing/code/disk.a b/pc-thing/code/disk.a deleted file mode 100644 index 35eb106..0000000 --- a/pc-thing/code/disk.a +++ /dev/null @@ -1,7 +0,0 @@ -start: - ; get sector 0 - mov a 0 - str a 0x7cff - - ; jump to the sector - jmp 0x7d01 \ No newline at end of file diff --git a/pc-thing/code/glumbo-buff.a b/pc-thing/code/glumbo-buff.a deleted file mode 100644 index 8964ef3..0000000 --- a/pc-thing/code/glumbo-buff.a +++ /dev/null @@ -1,285 +0,0 @@ -; GLUMBO - the 2d game thing - -.macro store(reg, val, addr) \ - put @reg @val\ - str @reg @addr -.macro storer(reg, val, addr) \ - put @reg @val\ - srr @reg @addr -.macro inc(addr) \ - ld a @addr\ - put b 1\ - add\ - str c @addr - -jmp start -get_coord: - ld a tmp2 ; Y(0-4) -> a - mov b width ; width (5) -> b - mul ; Y(0-4) * width (5) - - mov a grid_start ; grid start address -> a - swp c b ; (offset from y) -> b - add ; offsetY + gridStart - swp c a ; -> a - ld b tmp1 ; X(0-4) -> b - add ; loc + X - - str c tmp3 ; location -> tmp3 - ret - -start: - .label width 20 - .label height 10 - - .label grid_start 512 - ; temp vars - .label tmp1 0 - .label tmp2 1 - .label tmp3 2 - .label tmp4 3 - .label tmp5 4 - - .label px 16 - .label py 17 - .label inp 128 - .label rowBuff 256 - store a 2 px - store a 2 py - - store a 0 tmp1 ; x - store a 0 tmp2 ; y - mov a 2 - mov b 1 - sys - grid_loop: - ;get coord - jmr get_coord - ;store tile - ; storer a 46 c - ;main loop stuff - ; place tile - ; get X % (width - 1) to check if on x edge - store a 46 tmp4 - mov a width ; width -> A - mov b 1 ; 1 -> b - sub ; c = width - 1 - swp c b ; -> b - ld a tmp1 ; x -> a - mod ; c = x % (w - 1) - mov a 0 ; - crr c c a ; c = c == 0? - str c tmp5 ; c -> tmp5 - - ; Y % (height - 1 ) - mov a height ; height -> A - mov b 1 ; 1 -> b - sub ; c = height - 1 - swp c b ; -> b - ld a tmp2 ; x -> a - mod ; c = x % (w - 1) - mov a 0 - crr a c a ; a = c == 0? - - ld b tmp5 - or - cmp c 1 - - jz do_the_store ; edge ? continue : jmp do_the_store - store a 35 tmp4 ; store 35 at tmp4 - do_the_store: - ld b tmp3 ; location -> b - ld a tmp4 ; tmp4 (character) -> a - srr a b ; store the tile - ;;;;;;;;;;;;;;;;;;;;;;;;; - mov a width ; width -> a - mov b 1 ; 1 -> b - sub ; c = width - 1 - ld a tmp1 ; X(0-4) -> a - cmr a c ; X(0-4) == width - jnz ifz ; go to ifz if X(0-4) == width (5) - ifnz: ; X is not 0 - ld a tmp1 ; X -> a - mov b 1 ; 1 -> b - add ; X + 1 - str c tmp1 ; X = X + 1 - jmp continue_loop ; continue - ifz: ; X is 0 - store a 0 tmp1 ; set X to 1 - ld a tmp2 ; Y(0-4) -> a - mov b 1 ; 1 -> b - add ; c = Y + 1 - str c tmp2 ; Y = c - jmp continue_loop ; continue - continue_loop: - mov a height - mov b 0 - sub - ld a tmp2 ; get Y (0-4) - cmr a c ; Y == height+1 ? - jz grid_loop ; if not, continue - ; escaped - main_loop: - jmr print - ; get input - mov a 0 - mov b 0 - mov c inp - sys - jmr parse_input - jmp main_loop - -parse_input: - .macro case(addr, val, ln) \ - ld a @addr\ - cmp a @val\ - jnz @ln - .macro break() jmp default - - case inp 119 case_w - case inp 115 case_s - case inp 97 case_a - case inp 100 case_d - - case inp 99 case_c - case inp 3 case_c - break - - case_w: - ld a py - cmp a 0 - jnz default - mov b 1 - sub - str c py - break - - case_s: - ; width-1 - mov a height - mov b 1 - sub - - ld a py - cmr a c - jnz default - mov b 1 - add - str c py - break - - case_a: - ld a px - cmp a 0 - jnz default - mov b 1 - sub - str c px - break - - case_d: - ; width-1 - mov a width - mov b 1 - sub - - ld a px - cmr a c - jnz default - mov b 1 - add - str c px - break - - case_c: - end - break - - default: - ret - -print: - .label tmp6 5 - mov a 1 - mov b 1 - mov c [clear] - sys - store a 0 tmp1 ; x - store a 0 tmp2 ; y - store a 0 tmp6 ; rowBuff index - print_loop: - ;get coord - jmr get_coord - ; get tile - ld a tmp1 ; x - ld b px ; player x - crr c a b - str c tmp4 - ld a tmp2 ; y - ld b py ; player y - crr b a b - ld a tmp4 - and - cmp c 1 - - ld a tmp6 ; buff pointer - mov b rowBuff ; + buff loc - add ; - ld a tmp3 ; tile pointer? - ldr b a ; load tile into b - - jz set_normal - mov b 64 - set_normal: - srr b c ; store b to c - ; store a 0 129 - ;loop - mov a width - mov b 1 - sub - ld a tmp1 ; X(0-4) -> a - cmr a c ; X(0-4) == width - jnz p_ifz ; go to ifz if X(0-4) == width - p_ifnz: ; X is not 0 - ld a tmp1 ; X -> a - mov b 1 ; 1 -> b - add ; X + 1 - str c tmp1 ; X = X + 1 - inc tmp6 - jmp continue_ploop ; continue - p_ifz: ; X is 0 - store a 0 tmp6 - store a 10 128 - store a 0 129 - mov a 1 - mov b 1 - mov c 128 - sys - store a 0 tmp1 ; set X to 1 - ld a tmp2 ; Y(0-4) -> a - mov b 1 ; 1 -> b - add ; c = Y + 1 - str c tmp2 ; Y = c - ; print - ; print - mov a 1 - mov b 1 - mov c rowBuff - sys - ; ld c 128 - ; dbg a - jmp continue_ploop ; continue - continue_ploop: - mov a height - mov b 0 - sub - ld a tmp2 ; get Y (0-4) - cmr a c ; Y == width+1 ? - jz print_loop ; if not, continue - ret -clear: -.hex 1b -.str "[2J" -.hex 1b -.str "[0;0H" -.hex 0 \ No newline at end of file diff --git a/pc-thing/code/glumbo.a b/pc-thing/code/glumbo.a deleted file mode 100644 index 72accf6..0000000 --- a/pc-thing/code/glumbo.a +++ /dev/null @@ -1,271 +0,0 @@ -; GLUMBO - the 2d game thing - -.macro store(reg, val, addr) \ - put @reg @val\ - str @reg @addr -.macro storer(reg, val, addr) \ - put @reg @val\ - srr @reg @addr - -jmp start -get_coord: - ld a tmp2 ; Y(0-4) -> a - mov b width ; width (5) -> b - mul ; Y(0-4) * width (5) - - mov a grid_start ; grid start address -> a - swp c b ; (offset from y) -> b - add ; offsetY + gridStart - swp c a ; -> a - ld b tmp1 ; X(0-4) -> b - add ; loc + X - - str c tmp3 ; location -> tmp3 - ret - -start: - .label width 20 - .label height 10 - - .label grid_start 512 - ; temp vars - .label tmp1 0 - .label tmp2 1 - .label tmp3 2 - .label tmp4 3 - .label tmp5 4 - - .label px 16 - .label py 17 - .label inp 256 - store a 2 px - store a 2 py - - store a 0 tmp1 ; x - store a 0 tmp2 ; y - mov a 2 - mov b 1 - sys - grid_loop: - ;get coord - jmr get_coord - ;store tile - ; storer a 46 c - ;main loop stuff - ; place tile - ; get X % (width - 1) to check if on x edge - store a 46 tmp4 - mov a width ; width -> A - mov b 1 ; 1 -> b - sub ; c = width - 1 - swp c b ; -> b - ld a tmp1 ; x -> a - mod ; c = x % (w - 1) - mov a 0 ; - crr c c a ; c = c == 0? - str c tmp5 ; c -> tmp5 - - ; Y % (height - 1 ) - mov a height ; height -> A - mov b 1 ; 1 -> b - sub ; c = height - 1 - swp c b ; -> b - ld a tmp2 ; x -> a - mod ; c = x % (w - 1) - mov a 0 - crr a c a ; a = c == 0? - - ld b tmp5 - or - cmp c 1 - - jz do_the_store ; edge ? continue : jmp do_the_store - store a 35 tmp4 ; store 35 at tmp4 - do_the_store: - ld b tmp3 ; location -> b - ld a tmp4 ; tmp4 (character) -> a - srr a b ; store the tile - ;;;;;;;;;;;;;;;;;;;;;;;;; - mov a width ; width -> a - mov b 1 ; 1 -> b - sub ; c = width - 1 - ld a tmp1 ; X(0-4) -> a - cmr a c ; X(0-4) == width - jnz ifz ; go to ifz if X(0-4) == width (5) - ifnz: ; X is not 0 - ld a tmp1 ; X -> a - mov b 1 ; 1 -> b - add ; X + 1 - str c tmp1 ; X = X + 1 - jmp continue_loop ; continue - ifz: ; X is 0 - store a 0 tmp1 ; set X to 1 - ld a tmp2 ; Y(0-4) -> a - mov b 1 ; 1 -> b - add ; c = Y + 1 - str c tmp2 ; Y = c - jmp continue_loop ; continue - continue_loop: - mov a height - mov b 0 - sub - ld a tmp2 ; get Y (0-4) - cmr a c ; Y == height+1 ? - jz grid_loop ; if not, continue - ; escaped - main_loop: - jmr print - ; get input - mov a 0 - mov b 0 - mov c inp - sys - jmr parse_input - jmp main_loop - -parse_input: - .macro case(addr, val, ln) \ - ld a @addr\ - cmp a @val\ - jnz @ln - .macro break() jmp default - - case inp 119 case_w - case inp 115 case_s - case inp 97 case_a - case inp 100 case_d - - case inp 99 case_c - case inp 3 case_c - break - - case_w: - ld a py - cmp a 0 - jnz default - mov b 1 - sub - str c py - break - - case_s: - ; width-1 - mov a width - mov b 1 - sub - - ld a py - cmr a c - jnz default - mov b 1 - add - str c py - break - - case_a: - ld a px - cmp a 0 - jnz default - mov b 1 - sub - str c px - break - - case_d: - ; width-1 - mov a width - mov b 1 - sub - - ld a px - cmr a c - jnz default - mov b 1 - add - str c px - break - - case_c: - halt - break - - default: - ret - -print: - mov a 1 - mov b 1 - mov c [clear] - sys - store a 0 tmp1 ; x - store a 0 tmp2 ; y - print_loop: - ;get coord - jmr get_coord - ; get tile - ld a tmp3 - ldr b a - str b 128 - store a 0 129 - - ;TODO - make player tile be a @ or something - ld a tmp1 ; x - ld b px ; player x - crr c a b - str c tmp4 - ld a tmp2 ; y - ld b py ; player y - crr b a b - ld a tmp4 - and - cmp c 1 - jz print_normal - store a 64 128 - print_normal: - ; print - mov a 1 - mov b 1 - mov c 128 - sys - ; ld c 128 - ; dbg a - ;loop - mov a width - mov b 1 - sub - ld a tmp1 ; X(0-4) -> a - cmr a c ; X(0-4) == width - jnz p_ifz ; go to ifz if X(0-4) == width - p_ifnz: ; X is not 0 - ld a tmp1 ; X -> a - mov b 1 ; 1 -> b - add ; X + 1 - str c tmp1 ; X = X + 1 - jmp continue_ploop ; continue - p_ifz: ; X is 0 - store a 10 128 - store a 0 129 - mov a 1 - mov b 1 - mov c 128 - sys - store a 0 tmp1 ; set X to 1 - ld a tmp2 ; Y(0-4) -> a - mov b 1 ; 1 -> b - add ; c = Y + 1 - str c tmp2 ; Y = c - jmp continue_ploop ; continue - continue_ploop: - mov a height - mov b 0 - sub - ld a tmp2 ; get Y (0-4) - cmr a c ; Y == width+1 ? - jz print_loop ; if not, continue - ret -clear: -.hex 1b -.str "[2J" -.hex 1b -.str "[0;0H" -.hex 0 \ No newline at end of file diff --git a/pc-thing/code/hi.a b/pc-thing/code/hi.a deleted file mode 100644 index 62b1db8..0000000 --- a/pc-thing/code/hi.a +++ /dev/null @@ -1,11 +0,0 @@ -start: - mov a 1 - mov b 1 - mov c [helloworld] - sys - halt - -helloworld: -.str "Hello, World!" -.hex 0xA -.hex 0 \ No newline at end of file diff --git a/pc-thing/code/memman.a b/pc-thing/code/memman.a deleted file mode 100644 index 2398cd6..0000000 --- a/pc-thing/code/memman.a +++ /dev/null @@ -1,154 +0,0 @@ -; MEMMAN - memory manager - -jmp start - -#using code/printer.a - -; code from calc.a -; call with length in A -str_to_num: - ; pointer to current character - ; ld a len - ld b [stm_start] - add - str c [ptr] - mov a 1 - str a [mult] - mov a 0 - str a [num] - .label zero 48 - stm_loop: - ;load char, subtract zero, multiply by 10 - ld b [ptr] - ldr a b - mov b zero - sub - swp c a - ld b [mult] - mul - - ; add to num - swp c b - ld a [num] - add - str c [num] - - ld a [mult] - mov b 10 - mul - str c [mult] - - ; move pointer - ld a [ptr] - mov b 1 - sub - str c [ptr] - ld b [stm_start] - cmr c b - jz stm_loop - ret - -get_input: - mov a 0 - mov b 0 - mov c [input] - sys - str a [len] - ret - -parse_input: - mov a 0 - str a [inp_ptr] - - .macro case(addr, val, ln) \ - ld a @addr\ - cmp a @val\ - jnz @ln - .macro break() jmp default - - case [input] 'g' case_g - break - - case_g: - ; get pointer to number - mov a [input] - mov b 1 - add - str c [stm_start] - ; get new length - ld a [len] - mov b 2 ; subtract 2 for command + \n at the end - sub - swp c a - jmr str_to_num - ld a [num] - dbg 3 - str a 16 - jmr print_num - ; print the output - mov a 1 ; write - mov b 1 ; stdout - mov c 32 ; address - sys ; syscall - mov a 1 - mov b 1 - mov c [colon_space] - sys - ldm a [num] - str a 16 - jmr print_num - ; print the output - mov a 1 ; write - mov b 1 ; stdout - mov c 32 ; address - sys ; syscall - break - - default: - ret - - -start: - mov a 2 - mov b 0 - sys - jmr get_input - jmr parse_input - halt - -startup_message: -.str "welcome to mem man the memory manager of the memory of managing the memory" -.hex 0xa -.str "yeah" -.hex 0xa -.hex 0xa -.hex 0 -err: -.str "what the fuck is this" -.hex 0xa -.hex 0 -ptr: -.hex 0 -mult: -.hex 0 -num: -.hex 0 -; 256 bytes of input -input: -.str "0000000000000000000000000000000000000000000000000000000000000000" -.str "0000000000000000000000000000000000000000000000000000000000000000" -.str "0000000000000000000000000000000000000000000000000000000000000000" -.str "0000000000000000000000000000000000000000000000000000000000000000" -.str "0000000000000000000000000000000000000000000000000000000000000000" -.str "0000000000000000000000000000000000000000000000000000000000000000" -.str "0000000000000000000000000000000000000000000000000000000000000000" -.str "0000000000000000000000000000000000000000000000000000000000000000" -len: -.hex 0 -inp_ptr: -.hex 0 -stm_start: -.hex 0 -colon_space: -.str ": " -.hex 0 \ No newline at end of file diff --git a/pc-thing/code/move-bootloader.a b/pc-thing/code/move-bootloader.a deleted file mode 100644 index 306f2fe..0000000 --- a/pc-thing/code/move-bootloader.a +++ /dev/null @@ -1,62 +0,0 @@ -start: - ; init stack - mov a 0x6000 - mov b 0x7000 - str b a - copyLoop: - mov a [codePointer] - ld a a - mov b 0x6000 - add c a b - mov a [targetPointer] - str c a - - mov a codeStart - mov b [codePointer] - ld b b - add c a b - - mov a [targetPointer] - ld a a - ; swp a c - ; a <- $b - ld d c - push d ; push b - ld d a - ; push a ; push a - str c d ; $b <- a - pop d - ; $a <- b - str a d - ; swpm c b - - mov a [codePointer] - ld a a - mov b 1 - add c a b - ; mov a - str c [codePointer] - ; continue loop - mov b [targetPointer] - ; (byte we just copied) -> B - ld b b - ; (next byte) -> A - ld a c - ; C = A (aka next byte) == 0 - cmr c a 0 - ; A = B (aka last byte) == 1E (end instruction) - cmr a b 0x1e - swp c b ; C -> B - and c a b; c=a&&b - mov a 1 - cmp c a ; c==1? - jz copyLoop ; continue if c != 1 - jmp 0x6001 - - -targetPointer: -.hex 0 -codePointer: -.hex 0 -; start of bootloader -codeStart: \ No newline at end of file diff --git a/pc-thing/code/move-bootloader.c b/pc-thing/code/move-bootloader.c deleted file mode 100644 index 1aa938a..0000000 --- a/pc-thing/code/move-bootloader.c +++ /dev/null @@ -1,11 +0,0 @@ -#define codeStart 900 - -int main() { - // set up stack - *(volatile unsigned char *)0x7000 = 0x6000; - volatile unsigned char* codePointer = 0; - while () - { - volatile unsigned char* targetPointer = 0x6000 + codePointer; - } -} \ No newline at end of file diff --git a/pc-thing/code/printer.a b/pc-thing/code/printer.a deleted file mode 100644 index 87b66ba..0000000 --- a/pc-thing/code/printer.a +++ /dev/null @@ -1,111 +0,0 @@ -; print the number at 0xF -print_num: - ; non-address definitions - .label zero 48 - .label out_start 32 - ; define stuff in memory - .label number 16 - .label mult 17 - mov a 1 - str a mult - .label currnum 18 - .label tmp1 19 - .label out_pointer 20 - mov a out_start - str a out_pointer - .label swap_counter 21 - - loop_start: - ; get num-(num%mult) - ld a number - ld b mult - mod - swp c b - sub - str c tmp1 - - ; get num-(num%(mult*10)) - mov a 10 - ld b mult - mul - swp c b - ld a number - mod - swp c b - sub - - ; subtract the thingies to get the current digit - swp c b - ld a tmp1 - sub - swp c a - ld b mult - div - str c currnum - - ; add zero to currnum and store at out_pointer - swp a c ; currnum -> A - mov b zero - add - ld a out_pointer - srr c a ; store c to address at a (which is out_pointer) - - ; continue loop - ; increment out_pointer - ld a out_pointer - mov b 1 - add - str c out_pointer - ; increment mult - ld a mult - mov b 10 - mul - str c mult - - swp c b ; mult -> b - ld a number ; get number - mod ; get mod, will be equal to number if reached end - cmr c a ; compare result of mod and number (which is still in a) - jz loop_start ; jump if not equal - ; escaped from loop; swapping around memory to flip the text - ld a out_pointer - mov b out_start - sub - swp c a - mov b 2 - div - str c swap_counter - cmp c 0 - jnz end_swap - start_swap: - ; ptr - counter - ld b swap_counter - ld a out_pointer - sub - str c tmp1 - ; start + counter - ld a swap_counter ; 1 - mov b 1 - sub ; 1 - swp c b ; 1 -> b - mov a out_start ; 32 - add ; 32 + 1 = 33 - swp c b - ld a tmp1 - swpm a b - ld a swap_counter - mov b 1 - sub - str c swap_counter - cmp c 0 - jz start_swap - end_swap: - ; add \n\0 - ld b out_pointer - mov a 10 ; \n - srr a b - mov a 1 - add - mov a 0 ; \0 - srr a c - ret diff --git a/pc-thing/code/strlib.a b/pc-thing/code/strlib.a deleted file mode 100644 index a18da3b..0000000 --- a/pc-thing/code/strlib.a +++ /dev/null @@ -1,128 +0,0 @@ -; number to string -; a - pointer to output -; b - number to print -num_to_str: - str a out_pointer - str a out_start - str b [number] - ; non-address definitions - .label zero 48 - ; define stuff in memory - ; .label number 16 - ; .label mult 17 - ; mov a 1 - ; str a mult - ; .label currnum 18 - ; .label tmp1 19 - ; .label swap_counter 21 - - loop_start: - ; get num-(num%mult) - ld a [number] - ld b [mult] - mod - swp c b - sub - str c [tmp1] - - ; get num-(num%(mult*10)) - mov a 10 - ld b [mult] - mul - swp c b - ld a [number] - mod - swp c b - sub - - ; subtract the thingies to get the current digit - swp c b - ld a [tmp1] - sub - swp c a - ld b [mult] - div - str c [currnum] - - ; add zero to currnum and store at out_pointer - swp a c ; currnum -> A - mov b zero - add - ld a [out_pointer] - srr c a ; store c to address at a (which is out_pointer) - - ; continue loop - ; increment out_pointer - ld a [out_pointer] - mov b 1 - add - str c [out_pointer] - ; increment mult - ld a [mult] - mov b 10 - mul - str c [mult] - - swp c b ; mult -> b - ld a [number] ; get number - mod ; get mod, will be equal to number if reached end - cmr c a ; compare result of mod and number (which is still in a) - jz loop_start ; jump if not equal - ; escaped from loop; swapping around memory to flip the text - ld a [out_pointer] - ld b [out_start] - sub - swp c a - mov b 2 - div - str c [swap_counter] - cmp c 0 - jnz end_swap - start_swap: - ; ptr - counter - ld b [swap_counter] - ld a [out_pointer] - sub - str c [tmp1] - ; start + counter - ld a [swap_counter] ; 1 - mov b 1 - sub ; 1 - swp c b ; 1 -> b - ld a [out_start] ; 32 - add ; 32 + 1 = 33 - swp c b - ld a [tmp1] - dbg 304 - swpm a b - ld a [swap_counter] - mov b 1 - sub - str c [swap_counter] - cmp c 0 - jz start_swap - end_swap: - ; add \n\0 - ld b [out_pointer] - mov a 10 ; \n - srr a b - mov a 1 - add - mov a 0 ; \0 - srr a c - ret - -out_pointer: -.hex 0 -out_start: -.hex 0 -number: -.hex 0 -mult: -.hex 1 -currnum: -.hex 0 -tmp1: -.hex 0 -swap_counter: -.hex 0 \ No newline at end of file diff --git a/pc-thing/code/sub1.a b/pc-thing/code/sub1.a deleted file mode 100644 index e84f782..0000000 --- a/pc-thing/code/sub1.a +++ /dev/null @@ -1,6 +0,0 @@ -do_the_thing: - ld a 0 - mov b 1 - sub - str c 0 - ret \ No newline at end of file diff --git a/pc-thing/code/test_aliases.a b/pc-thing/code/test_aliases.a deleted file mode 100644 index f63b4f5..0000000 --- a/pc-thing/code/test_aliases.a +++ /dev/null @@ -1,3 +0,0 @@ -start: - mov a 50 - mov $0 a \ No newline at end of file diff --git a/pc-thing/code/test_clock.a b/pc-thing/code/test_clock.a deleted file mode 100644 index fe0f539..0000000 --- a/pc-thing/code/test_clock.a +++ /dev/null @@ -1,53 +0,0 @@ -.label counter 0 - -jmp start - -interrupt: - ld a counter - mov b 1 - add - swp c a - mov b 100 - mod - str c counter - cmp c 0 - jnz print_numb - ret - -#using code/printer.a - -print_numb: - ld a [counter] - mov b 1 - add - str c [counter] - str c 16 ; put our number into 16 - jmr print_num ; print number at 16 (well not print but stringify) - mov a 1 ; write - mov b 1 ; stdout - mov c 32 ; address - sys ; syscall - ret - - -start: - mov a helloworld - mov b 1 - sub - mov a 1 - mov b 1 - sys - mov a interrupt - mov b 1 - sub - str c 0x7000 - ; nl: - ; jmp nl - halt - -helloworld: -.str "Hello, World!" -.hex a -.hex 0 -counter: -.hex 0 \ No newline at end of file diff --git a/pc-thing/code/test_strlib.a b/pc-thing/code/test_strlib.a deleted file mode 100644 index ce65675..0000000 --- a/pc-thing/code/test_strlib.a +++ /dev/null @@ -1,10 +0,0 @@ -#using code/strlib.a -start: - mov a 16 - mov b -1 - jmr num_to_str - mov a 1 - mov b 1 - mov c 16 - sys - end \ No newline at end of file diff --git a/pc-thing/code/wozmon.a b/pc-thing/code/wozmon.a deleted file mode 100644 index 5462c4d..0000000 --- a/pc-thing/code/wozmon.a +++ /dev/null @@ -1,160 +0,0 @@ -; The WOZ Monitor for the Apple 1 -; Written by Steve Wozniak in 1976 - - -; Page 0 Variables - -.label XAML 0x24 ; Last "opened" location Low -.label XAMH 0x25 ; Last "opened" location High -.label STL 0x26 ; Store address Low -.label STH 0x27 ; Store address High -.label L 0x28 ; Hex value parsing Low -.label H 0x29 ; Hex value parsing High -.label YSAV 0x2A ; Used to see if hex value is given -.label MODE 0x2B ; $00=XAM, $7F=STOR, $AE=BLOCK XAM - - -; Other Variables - -.label IN 0x0200 ; Input buffer to $027F -.label KBD 0xD010 ; PIA.A keyboard input -.label KBDCR 0xD011 ; PIA.A keyboard control register -.label DSP 0xD012 ; PIA.B display output register -.label DSPCR 0xD013 ; PIA.B display control register - - .org $FF00 - .export RESET - -RESET: ;CLD ; Clear decimal arithmetic mode. - ;CLI - MOV Y 0x7F ; Mask for DSP data direction register. - STY DSP ; Set it up. - MOV A 0xA7 ; KBD and DSP control register mask. - STA KBDCR ; Enable interrupts, set CA1, CB1, for - STA DSPCR ; positive edge sense/output mode. -NOTCR: CMP #'_'+$80 ; "_"? - BEQ BACKSPACE ; Yes. - CMP 0x9B ; ESC? - BEQ ESCAPE ; Yes. - INY ; Advance text index. - BPL NEXTCHAR ; Auto ESC if > 127. -ESCAPE: LD A #'\'+$80 ; "\". - JSR ECHO ; Output it. -GETLINE: LD A 0x8D ; CR. - JSR ECHO ; Output it. - LD Y 0x01 ; Initialize text index. -BACKSPACE: DEY ; Back up text index. - BMI GETLINE ; Beyond start of line, reinitialize. -NEXTCHAR: LD A KBDCR ; Key ready? - BPL NEXTCHAR ; Loop until ready. - LD A KBD ; Load character. B7 should be ‘1’. - STA IN,Y ; Add to text buffer. - JSR ECHO ; Display character. - CMP 0x8D ; CR? - BNE NOTCR ; No. - LD Y 0xFF ; Reset text index. - LD A 0x00 ; For XAM mode. - TAX ; 0->X. -SETSTOR: ASL ; Leaves $7B if setting STOR mode. -SETMODE: STA MODE ; $00=XAM, $7B=STOR, $AE=BLOCK XAM. -BLSKIP: INY ; Advance text index. -NEXTITEM: LD A IN,Y ; Get character. - CMP 0x8D ; CR? - BEQ GETLINE ; Yes, done this line. - CMP #'.'+$80 ; "."? - BCC BLSKIP ; Skip delimiter. - BEQ SETMODE ; Set BLOCK XAM mode. - CMP #':'+$80 ; ":"? - BEQ SETSTOR ; Yes. Set STOR mode. - CMP #'R'+$80 ; "R"? - BEQ RUN ; Yes. Run user program. - STX L ; $00->L. - STX H ; and H. - STY YSAV ; Save Y for comparison. -NEXTHEX: LD A IN,Y ; Get character for hex test. - EOR 0xB0 ; Map digits to $0-9. - CMP 0x0A ; Digit? - BCC DIG ; Yes. - ADC 0x88 ; Map letter "A"-"F" to $FA-FF. - CMP 0xFA ; Hex letter? - BCC NOTHEX ; No, character not hex. -DIG: ASL - ASL ; Hex digit to MSD of A. - ASL - ASL - LD X 0x04 ; Shift count. -HEXSHIFT: ASL ; Hex digit left, MSB to carry. - ROL L ; Rotate into LSD. - ROL H ; Rotate into MSD’s. - DEX ; Done 4 shifts? - BNE HEXSHIFT ; No, loop. - INY ; Advance text index. - BNE NEXTHEX ; Always taken. Check next character for hex. -NOTHEX: CPY YSAV ; Check if L, H empty (no hex digits). - BEQ ESCAPE ; Yes, generate ESC sequence. - BIT MODE ; Test MODE byte. - BVC NOTSTOR ; B6=0 STOR, 1 for XAM and BLOCK XAM - LD A L ; LSD’s of hex data. - STA (STL,X) ; Store at current ‘store index’. - INC STL ; Increment store index. - BNE NEXTITEM ; Get next item. (no carry). - INC STH ; Add carry to ‘store index’ high order. -TONEXTITEM: JMP NEXTITEM ; Get next command item. -RUN: JMP (XAML) ; Run at current XAM index. -NOTSTOR: BMI XAMNEXT ; B7=0 for XAM, 1 for BLOCK XAM. - LD X 0x02 ; Byte count. -SETADR: LD A L-1,X ; Copy hex data to - STA STL-1,X ; ‘store index’. - STA XAML-1,X ; And to ‘XAM index’. - DEX ; Next of 2 bytes. - BNE SETADR ; Loop unless X=0. -NXTPRNT: BNE PRDATA ; NE means no address to print. - LD A 0x8D ; CR. - JSR ECHO ; Output it. - LD A XAMH ; ‘Examine index’ high-order byte. - JSR PRBYTE ; Output it in hex format. - LD A XAML ; Low-order ‘examine index’ byte. - JSR PRBYTE ; Output it in hex format. - LD A #':'+$80 ; ":". - JSR ECHO ; Output it. -PRDATA: LD A 0xA0 ; Blank. - JSR ECHO ; Output it. - LD A (XAML,X) ; Get data byte at ‘examine index’. - JSR PRBYTE ; Output it in hex format. -XAMNEXT: STX MODE ; 0->MODE (XAM mode). - LD A XAML - CMP L ; Compare ‘examine index’ to hex data. - LD A XAMH - SBC H - BCS TONEXTITEM ; Not less, so no more data to output. - INC XAML - BNE MOD8CHK ; Increment ‘examine index’. - INC XAMH -MOD8CHK: LD A XAML ; Check low-order ‘examine index’ byte - AND 0x07 ; For MOD 8=0 - BPL NXTPRNT ; Always taken. -PRBYTE: PHA ; Save A for LSD. - LSR - LSR - LSR ; MSD to LSD position. - LSR - JSR PRHEX ; Output hex digit. - PLA ; Restore A. -PRHEX: AND 0x0F ; Mask LSD for hex print. - ORA #'0'+$80 ; Add "0". - CMP 0xBA ; Digit? - BCC ECHO ; Yes, output it. - ADC 0x06 ; Add offset for letter. -ECHO: BIT DSP ; DA bit (B7) cleared yet? - BMI ECHO ; No, wait for display. - STA DSP ; Output character. Sets DA. - RTS ; Return. - - BRK ; unused - BRK ; unused - -; Interrupt Vectors - - .WORD $0F00 ; NMI - .WORD RESET ; RESET - .WORD $0000 ; BRK/IRQ \ No newline at end of file diff --git a/pc-thing/instructions.md b/pc-thing/instructions.md deleted file mode 100644 index 5d2a555..0000000 --- a/pc-thing/instructions.md +++ /dev/null @@ -1,437 +0,0 @@ -# instructions - -the base instruction set (some instructions may be undocumented) - -table of contents: - - [ADD](#add) - - [AND](#and) - - [CLR](#clr) - - [CMP](#cmp) - - [CMR](#cmr) - - [CRR](#crr) - - [DBG](#dbg) - - [DIV](#div) - - [HALT](#halt) - - [JMP](#jmp) - - [JMR](#jmr) - - [JNZ](#jnz) - - [JNZR](#jnzr) - - [JZ](#jz) - - [LD](#ld) - - [LDM](#ldm) - - [LDR](#ldr) - - [MOD](#mod) - - [MOV](#mov) - - [MUL](#mul) - - [NOT](#not) - - [OR](#or) - - [PUT](#put) - - [RET](#ret) - - [SHL](#SHL) - - [SHR](#SHR) - - [SRM](#srm) - - [SRR](#srr) - - [STR](#str) - - [SUB](#sub) - - [SWP](#swp) - - [SWPM](#swpm) - - [SYS](#sys) - + [read (0)](#read-0) - + [write (1)](#read-1) - + [set raw (2)](#set-raw-2) - - [XOR](#xor) - -## ADD - -add - -usage: -``` -add -``` - -adds registers `a` and `b` and puts the output in `c` - -## AND - -bitwise and - -usage: -``` -and -``` - -bitwise and's registers `a` and `b` and puts the output in `c` - - -## CLR - -clear return buffer - -usage: -``` -clr -``` - -pops the most recent value from the return stack - -## CMP - -compare - -usage: -``` -cmp (reg1) (value) -``` - -compares reg1 and value, if equal, sets return flag to 1, else sets it to 0 - -## CMR - -compare register - -usage: -``` -cmr (reg1) (reg2) -``` - -compares reg1 and reg2, if equal, sets return flag to 1, else sets it to 0 - -## CRR - -compare register register - -usage: -``` -cmr (reg1) (reg2) (reg3) -``` - -compares reg2 and reg3, if equal, sets reg1 1, else sets it to 0 - -## DBG - -debug - -usage: -``` -dbg (breakpoint name) -``` - -dumps ram and halts executing until the user presses enter - -## DIV - -divide - -usage: -``` -div -``` - -divides register `a` by register `b` and stores output in `c`, the output is floored - -## HALT - -halt - -usage: -``` -halt -``` - -halts the CPU - -## JMP - -jump - -usage: -``` -jmp (line) -``` - -jumps to line - -## JMR - -jump with return - -usage: -``` -jmp (line) -``` - -same as jump, but adds the original line to the return stack - -## JNZ - -jump if non-zero - -usage: -``` -jnz (line) -``` - -jump to line if the return flag is not zero - -## JNZR - -jump if non-zero compare (deprecated) - -usage: -``` -jnzr (reg1) (reg2) -``` - -jumps to line at reg1 if reg2 is not zero, deprecated, use [`jnz`](#jnz) and [`cmp`](#cmp) instead - -## JZ - -jump if zero - -usage: -``` -jnz (line) -``` - -jump to line if the return flag is zero - -## LD - -load from memory - -usage: -``` -ld (reg) (addr) -``` - -loads data at address addr into register reg - -## LDM - -load from memory from memory (deprecated) - -usage: -``` -ldm (reg) (addr) -``` - -loads data at address at address addr into register reg, deprecated, use [`ld`](#ld) and [`ldr`](#ldr) instead - -## LDR - -load from memory at register - -usage: -``` -ld (reg1) (reg2) -``` - -loads data at address at reg1 into register reg2 - -## MOD - -modulo - -usage: -``` -mod -``` - -does the modulo operation on `a` and `b` and stores in `c` - -## MOV - -see [`put`](#put) - -## MUL - -multiply - -usage: -``` -mul -``` - -multiplies `a` by `b` and stores in `c` - -## NOT - -bitwise not - -usage: -``` -not -``` - -bitwise not's register `a` and puts the output in `c` - -## OR - -bitwise or - -usage: -``` -or -``` - -bitwise or's registers `a` and `b` and puts the output in `c` - -## PUT - -put - -usage: -``` -put (reg) (num) -``` - -puts num in register reg - -## RET - -return - -usage: -``` -ret -``` - -returns to last value in return stack - -## SHL - -shift left - -usage: -``` -shl (reg) (by) -``` - -shifts the value of `reg` to the left by `by` - -## SHR - -shift right - -usage: -``` -shr (reg) (by) -``` - -shifts the value of `reg` to the right by `by` - -## SRM - -deprecated - -im too lazy to document this, basically the [`ldm`](#ldm) of [`str`](#str), use [`srr`](#srr) instead - -## SRR - -store register - -usage: -``` -srr (reg1) (reg2) -``` - -store value of reg1 at address in reg2 - -## STR - -store - -usage: -``` -srr (reg1) (addr) -``` - -store value of reg1 at address addr - -## SUB - -subtract - -usage: -``` -sub -``` - -subtracts register `b` from register `a` and puts the output in `c` - -## SWP - -swap - -usage: -``` -swp (reg1) (reg2) -``` - -swaps registers reg1 and reg2 - -## SWPM - -swap memory - -usage: -``` -swp (reg1) (reg2) -``` - -swaps addresses at reg1 and at reg2 - -## SYS - -syscall - -usage: -``` -sys (syscall_id) (...args) -``` - -syscall, used for interacting with the system - -NOTE: the arguments for the syscall are stored in the registers `a` `b` and `c`, not in the instruction call - -syscalls: - -### read (0) - -``` -sys 0 (fd) (addr) -``` - -reads data from file descriptor fd and puts it in ram, starting with addr, the data is null (0x00) terminated - -the most common file descriptor you'll see is 0, stdin - -also sets register `a` to the length of the read input - -### write (1) - -``` -sys 1 (fd) (addr) -``` - -write data starting from addr (null-terminated) into file descriptor fd - -### set raw (2) - -``` -sys 1 (raw?) -``` - -set tty raw mode - -## XOR - -bitwise exclusive or - -usage: -``` -xor -``` - -bitwise xor's registers `a` and `b` and puts the output in `c` \ No newline at end of file diff --git a/pc-thing/instructions/add.ts b/pc-thing/instructions/add.ts deleted file mode 100644 index 93a5018..0000000 --- a/pc-thing/instructions/add.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { PC } from "../pc.ts"; - -export default { - function(this: PC) { - this.registers[2] = this.registers[0] + this.registers[1] - }, - args: 0 -} \ No newline at end of file diff --git a/pc-thing/instructions/and.ts b/pc-thing/instructions/and.ts deleted file mode 100644 index 77a28e0..0000000 --- a/pc-thing/instructions/and.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { PC } from "../pc.ts"; - -export default { - function(this: PC) { - this.registers[2] = this.registers[0] & this.registers[1] - }, - args: 0 -} \ No newline at end of file diff --git a/pc-thing/instructions/clr.ts b/pc-thing/instructions/clr.ts deleted file mode 100644 index bbbe422..0000000 --- a/pc-thing/instructions/clr.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { PC } from "../pc.ts"; - -export default { - function(this: PC) { - this.returnStack.pop(); - }, - args: 0 -} \ No newline at end of file diff --git a/pc-thing/instructions/cmp.ts b/pc-thing/instructions/cmp.ts deleted file mode 100644 index 1b2db94..0000000 --- a/pc-thing/instructions/cmp.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { PC } from "../pc.ts"; - -export default { - function(this: PC, [reg, val]: number[]) { - const r = this.lib.parseReg(reg) - this.returnFlag = +(this.registers[r] == +val) - }, - args: 2 -} \ No newline at end of file diff --git a/pc-thing/instructions/cmr.ts b/pc-thing/instructions/cmr.ts deleted file mode 100644 index c92d939..0000000 --- a/pc-thing/instructions/cmr.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { PC } from "../pc.ts"; - -export default { - function(this: PC, [reg1, reg2]: number[]) { - const r1 = this.lib.parseReg(reg1) - const r2 = this.lib.parseReg(reg2) - this.returnFlag = +(this.registers[r1] == this.registers[r2]) - }, - args: 2 -} \ No newline at end of file diff --git a/pc-thing/instructions/crp.ts b/pc-thing/instructions/crp.ts deleted file mode 100644 index c334ed5..0000000 --- a/pc-thing/instructions/crp.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { PC } from "../pc.ts"; - -export default { - function(this: PC, [reg1, reg2, val]: number[]) { - const r1 = this.lib.parseReg(reg1) - const r2 = this.lib.parseReg(reg2) - this.registers[r1] = +(this.registers[r2] == val) - }, - args: 3 -} \ No newline at end of file diff --git a/pc-thing/instructions/crr.ts b/pc-thing/instructions/crr.ts deleted file mode 100644 index cea6995..0000000 --- a/pc-thing/instructions/crr.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { PC } from "../pc.ts"; - -export default { - function(this: PC, [reg1, reg2, reg3]: number[]) { - const r1 = this.lib.parseReg(reg1) - const r2 = this.lib.parseReg(reg2) - const r3 = this.lib.parseReg(reg3) - this.registers[r1] = +(this.registers[r2] == this.registers[r3]) - }, - args: 3 -} \ No newline at end of file diff --git a/pc-thing/instructions/dbg.ts b/pc-thing/instructions/dbg.ts deleted file mode 100644 index 6781fbf..0000000 --- a/pc-thing/instructions/dbg.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { PC } from "../pc.ts"; - -export default { - function(this: PC, [msg]: string[]) { - console.log(msg, this.mem, this.registers, this.returnFlag, this.returnStack); - const b = new Uint8Array(1); - Deno.stdin.readSync(b) - if (b[0] == 'c'.charCodeAt(0)) { - this.programPointer = 0xFFFF - 1 - } - }, - args: 1 -} \ No newline at end of file diff --git a/pc-thing/instructions/dec.ts b/pc-thing/instructions/dec.ts deleted file mode 100644 index df46769..0000000 --- a/pc-thing/instructions/dec.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { PC } from "../pc.ts"; - -export default { - function(this: PC, [reg, by]: number[]) { - const r = this.lib.parseReg(reg); - this.registers[r] -= by - }, - args: 2 -} \ No newline at end of file diff --git a/pc-thing/instructions/decr.ts b/pc-thing/instructions/decr.ts deleted file mode 100644 index 12e7fd9..0000000 --- a/pc-thing/instructions/decr.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { PC } from "../pc.ts"; - -export default { - function(this: PC, [reg1, reg2]: number[]) { - const r1 = this.lib.parseReg(reg1); - const r2 = this.lib.parseReg(reg2); - this.registers[r1] -= this.registers[r2] - }, - args: 2 -} \ No newline at end of file diff --git a/pc-thing/instructions/div.ts b/pc-thing/instructions/div.ts deleted file mode 100644 index dbad7e1..0000000 --- a/pc-thing/instructions/div.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { PC } from "../pc.ts"; - -export default { - function(this: PC) { - this.registers[2] = Math.floor(this.registers[0] / this.registers[1]) - }, - args: 0 -} \ No newline at end of file diff --git a/pc-thing/instructions/halt.ts b/pc-thing/instructions/halt.ts deleted file mode 100644 index 4685f2b..0000000 --- a/pc-thing/instructions/halt.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { PC } from "../pc.ts"; - -export default { - function(this: PC) { - // this.programPointer = 0xFFFF - 1 - this.halted = true - }, - args: 0 -} \ No newline at end of file diff --git a/pc-thing/instructions/inc.ts b/pc-thing/instructions/inc.ts deleted file mode 100644 index 180546e..0000000 --- a/pc-thing/instructions/inc.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { PC } from "../pc.ts"; - -export default { - function(this: PC, [reg, by]: number[]) { - const r = this.lib.parseReg(reg); - this.registers[r] += by - }, - args: 2 -} \ No newline at end of file diff --git a/pc-thing/instructions/incr.ts b/pc-thing/instructions/incr.ts deleted file mode 100644 index 5f1d529..0000000 --- a/pc-thing/instructions/incr.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { PC } from "../pc.ts"; - -export default { - function(this: PC, [reg1, reg2]: number[]) { - const r1 = this.lib.parseReg(reg1); - const r2 = this.lib.parseReg(reg2); - this.registers[r1] += this.registers[r2] - }, - args: 2 -} \ No newline at end of file diff --git a/pc-thing/instructions/jmp.ts b/pc-thing/instructions/jmp.ts deleted file mode 100644 index 00db338..0000000 --- a/pc-thing/instructions/jmp.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { PC } from "../pc.ts"; - -export default { - function(this: PC, [addr]: string[]) { - this.programPointer = Number(addr) - 1 - }, - args: 1 -} \ No newline at end of file diff --git a/pc-thing/instructions/jmr.ts b/pc-thing/instructions/jmr.ts deleted file mode 100644 index 25f5334..0000000 --- a/pc-thing/instructions/jmr.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { PC } from "../pc.ts"; - -export default { - function(this: PC, [addr]: string[]) { - this.returnStack.push(this.programPointer) - this.programPointer = Number(addr) - 1 - }, - args: 1 -} \ No newline at end of file diff --git a/pc-thing/instructions/jnz.ts b/pc-thing/instructions/jnz.ts deleted file mode 100644 index e5b539f..0000000 --- a/pc-thing/instructions/jnz.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { PC } from "../pc.ts"; - -export default { - function(this: PC, [addr]: string[]) { - if (this.returnFlag == 0) return; - this.programPointer = +addr - 1 - }, - args: 1 -} \ No newline at end of file diff --git a/pc-thing/instructions/jnzr.ts b/pc-thing/instructions/jnzr.ts deleted file mode 100644 index 00f1569..0000000 --- a/pc-thing/instructions/jnzr.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { PC } from "../pc.ts"; - -export default { - function(this: PC, [reg1, reg2]: number[]) { - const r1 = this.lib.parseReg(reg1) - const r2 = this.lib.parseReg(reg2) - if (this.registers[r1] == 0) return; - this.programPointer = this.registers[r2] - 1 - }, - args: 2 -} \ No newline at end of file diff --git a/pc-thing/instructions/jz.ts b/pc-thing/instructions/jz.ts deleted file mode 100644 index 0e105b3..0000000 --- a/pc-thing/instructions/jz.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { PC } from "../pc.ts"; - -export default { - function(this: PC, [addr]: string[]) { - if (this.returnFlag != 0) return; - this.programPointer = +addr - 1 - }, - args: 1 -} \ No newline at end of file diff --git a/pc-thing/instructions/ld.ts b/pc-thing/instructions/ld.ts deleted file mode 100644 index 977f343..0000000 --- a/pc-thing/instructions/ld.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { PC } from "../pc.ts"; - -export default { - function(this: PC, [reg, addr]: number[]) { - const r = this.lib.parseReg(reg) - this.registers[r] = this.getMem(Number(addr)) - }, - args: 2 -} \ No newline at end of file diff --git a/pc-thing/instructions/ldm.ts b/pc-thing/instructions/ldm.ts deleted file mode 100644 index c82425a..0000000 --- a/pc-thing/instructions/ldm.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { PC } from "../pc.ts"; - -export default { - function(this: PC, [reg, addr]: number[]) { - this.registers[this.lib.parseReg(reg)] = this.getMem(this.getMem(Number(addr))) - }, - args: 2 -} \ No newline at end of file diff --git a/pc-thing/instructions/ldr.ts b/pc-thing/instructions/ldr.ts deleted file mode 100644 index 724b94c..0000000 --- a/pc-thing/instructions/ldr.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { PC } from "../pc.ts"; - -export default { - function(this: PC, [reg1, reg2]: number[]) { - this.registers[this.lib.parseReg(reg1)] = this.getMem(this.registers[this.lib.parseReg(reg2)]) - }, - args: 2 -} \ No newline at end of file diff --git a/pc-thing/instructions/mod.ts b/pc-thing/instructions/mod.ts deleted file mode 100644 index 24b96d5..0000000 --- a/pc-thing/instructions/mod.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { PC } from "../pc.ts"; - -export default { - function(this: PC) { - this.registers[2] = this.registers[0] % this.registers[1] - }, - args: 0 -} \ No newline at end of file diff --git a/pc-thing/instructions/mul.ts b/pc-thing/instructions/mul.ts deleted file mode 100644 index b625a07..0000000 --- a/pc-thing/instructions/mul.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { PC } from "../pc.ts"; - -export default { - function(this: PC) { - this.registers[2] = this.registers[0] * this.registers[1] - }, - args: 0 -} \ No newline at end of file diff --git a/pc-thing/instructions/not.ts b/pc-thing/instructions/not.ts deleted file mode 100644 index 6416a5c..0000000 --- a/pc-thing/instructions/not.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { PC } from "../pc.ts"; - -export default { - function(this: PC) { - this.registers[2] = ~this.registers[0] - }, - args: 0 -} \ No newline at end of file diff --git a/pc-thing/instructions/or.ts b/pc-thing/instructions/or.ts deleted file mode 100644 index 5a8b593..0000000 --- a/pc-thing/instructions/or.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { PC } from "../pc.ts"; - -export default { - function(this: PC) { - this.registers[2] = this.registers[0] | this.registers[1] - }, - args: 0 -} \ No newline at end of file diff --git a/pc-thing/instructions/put.ts b/pc-thing/instructions/put.ts deleted file mode 100644 index a35806e..0000000 --- a/pc-thing/instructions/put.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { PC } from "../pc.ts"; - -export default { - function(this: PC, [reg, data]: number[]) { - const r = this.lib.parseReg(reg) - this.registers[r] = Number(data) ?? 0 - }, - args: 2 -} \ No newline at end of file diff --git a/pc-thing/instructions/ret.ts b/pc-thing/instructions/ret.ts deleted file mode 100644 index 6a42313..0000000 --- a/pc-thing/instructions/ret.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { PC } from "../pc.ts"; - -export default { - function(this: PC) { - const ret = this.returnStack.pop(); - if (ret == undefined) throw 'whar' - this.programPointer = ret - }, - args: 0 -} \ No newline at end of file diff --git a/pc-thing/instructions/sbc.ts b/pc-thing/instructions/sbc.ts deleted file mode 100644 index 928aa61..0000000 --- a/pc-thing/instructions/sbc.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { PC } from "../pc.ts"; - -export default { - function(this: PC, [reg1, reg2]: number[]) { - const r1 = this.lib.parseReg(reg1); - const r2 = this.lib.parseReg(reg2); - this.registers[r1] -= this.registers[r2] - this.returnFlag - }, - args: 2 -} \ No newline at end of file diff --git a/pc-thing/instructions/shl.ts b/pc-thing/instructions/shl.ts deleted file mode 100644 index 68345bb..0000000 --- a/pc-thing/instructions/shl.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { PC } from "../pc.ts"; - -export default { - function(this: PC, [reg, by]: number[]) { - const r = this.lib.parseReg(reg); - this.registers[r] = this.registers[r] << by - }, - args: 2 -} \ No newline at end of file diff --git a/pc-thing/instructions/shr.ts b/pc-thing/instructions/shr.ts deleted file mode 100644 index 15e9345..0000000 --- a/pc-thing/instructions/shr.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { PC } from "../pc.ts"; - -export default { - function(this: PC, [reg, by]: number[]) { - const r = this.lib.parseReg(reg); - this.registers[r] = this.registers[r] >> by - }, - args: 2 -} \ No newline at end of file diff --git a/pc-thing/instructions/srm.ts b/pc-thing/instructions/srm.ts deleted file mode 100644 index b3c71fa..0000000 --- a/pc-thing/instructions/srm.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { PC } from "../pc.ts"; - -export default { - function(this: PC, [reg, addr]: number[]) { - this.setMem(this.getMem(Number(addr)), this.registers[this.lib.parseReg(reg)]) - }, - args: 2 -} \ No newline at end of file diff --git a/pc-thing/instructions/srr.ts b/pc-thing/instructions/srr.ts deleted file mode 100644 index 0a7e5c6..0000000 --- a/pc-thing/instructions/srr.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { PC } from "../pc.ts"; - -export default { - function(this: PC, [reg1, reg2]: number[]) { - const r1 = this.lib.parseReg(reg1) - const r2 = this.registers[this.lib.parseReg(reg2)] - this.setMem(Number(r2), this.registers[r1] & 0xFFFF) - }, - args: 2 -} \ No newline at end of file diff --git a/pc-thing/instructions/str.ts b/pc-thing/instructions/str.ts deleted file mode 100644 index bdcae63..0000000 --- a/pc-thing/instructions/str.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { PC } from "../pc.ts"; - -export default { - function(this: PC, [reg, addr]: number[]) { - const r = this.lib.parseReg(reg) - this.setMem(Number(addr), this.registers[r] & 0xFFFF) - }, - args: 2 -} \ No newline at end of file diff --git a/pc-thing/instructions/sub.ts b/pc-thing/instructions/sub.ts deleted file mode 100644 index 8e4d894..0000000 --- a/pc-thing/instructions/sub.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { PC } from "../pc.ts"; - -export default { - function(this: PC) { - this.registers[2] = this.registers[0] - this.registers[1] - }, - args: 0 -} \ No newline at end of file diff --git a/pc-thing/instructions/swp.ts b/pc-thing/instructions/swp.ts deleted file mode 100644 index 48ee9b6..0000000 --- a/pc-thing/instructions/swp.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { PC } from "../pc.ts"; - -export default { - function(this: PC, [reg1, reg2]: number[]) { - const r1 = this.lib.parseReg(reg1) - const r2 = this.lib.parseReg(reg2) - const data1 = Number(this.registers[r1]) - const data2 = Number(this.registers[r2]) - this.registers[r1] = data2 - this.registers[r2] = data1 - }, - args: 2 -} \ No newline at end of file diff --git a/pc-thing/instructions/swpm.ts b/pc-thing/instructions/swpm.ts deleted file mode 100644 index f4856a2..0000000 --- a/pc-thing/instructions/swpm.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { PC } from "../pc.ts"; - -export default { - function(this: PC, [reg1, reg2]: number[]) { - const addr1 = this.registers[this.lib.parseReg(reg1)] - const addr2 = this.registers[this.lib.parseReg(reg2)] - const data1 = 0 + this.getMem(+addr1) - const data2 = 0 + this.getMem(+addr2) - this.setMem(+addr1, data2) - this.setMem(+addr2, data1) - }, - args: 2 -} \ No newline at end of file diff --git a/pc-thing/instructions/sys.ts b/pc-thing/instructions/sys.ts deleted file mode 100644 index 5131bf2..0000000 --- a/pc-thing/instructions/sys.ts +++ /dev/null @@ -1,55 +0,0 @@ -// deno-lint-ignore-file no-case-declarations no-process-globals -import { PC } from "../pc.ts"; - -export default { - function(this: PC) { - switch (this.registers[0]) { - case 0: - switch (this.registers[1]) { - case 0: - const data = new Uint8Array(1024) - const len = Deno.stdin.readSync(data) ?? 0 - let i = 0; - while (i < len) { - this.mem[this.registers[2] + i] = data[i] - i++ - } - this.registers[0] = len - this.mem[this.registers[2] + i] = 0 - break; - - default: - throw 'unknown fd' - } - break; - case 1: - const writeBuff = []; - let i = this.registers[2]; - while (this.mem[i] != 0 && i <= this.mem.length) { - writeBuff.push(this.mem[i]); - i++ - } - switch (this.registers[1]) { - case 1: - process.stdout.write(writeBuff.map(a => String.fromCharCode(a)).join('')) - break; - - case 2: - process.stderr.write(writeBuff.map(a => String.fromCharCode(a)).join('')) - break; - - default: - throw 'unknown fd' - } - break; - - case 2: - Deno.stdin.setRaw(this.registers[1] ? true : false); - break; - - default: - throw 'unknown syscall id ' + this.registers[0] - } - }, - args: 0 -} \ No newline at end of file diff --git a/pc-thing/instructions/xor.ts b/pc-thing/instructions/xor.ts deleted file mode 100644 index 4cccecd..0000000 --- a/pc-thing/instructions/xor.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { PC } from "../pc.ts"; - -export default { - function(this: PC) { - this.registers[2] = this.registers[0] ^ this.registers[1] - }, - args: 0 -} \ No newline at end of file diff --git a/pc-thing/instructions_new/add.ts b/pc-thing/instructions_new/add.ts deleted file mode 100644 index 5d211d3..0000000 --- a/pc-thing/instructions_new/add.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { PC } from "../pc.ts"; - -export default { - function(this: PC, [reg1, reg2, reg3]: number[]) { - const r1 = this.lib.parseReg(reg1); - const r2 = this.lib.parseReg(reg2); - const r3 = this.lib.parseReg(reg3); - this.returnFlag = +((this.registers[r2] + this.registers[r3]) != 0); - this.registers[r1] = this.registers[r2] + this.registers[r3] - }, - args: 3 -} \ No newline at end of file diff --git a/pc-thing/instructions_new/and.ts b/pc-thing/instructions_new/and.ts deleted file mode 100644 index 12db601..0000000 --- a/pc-thing/instructions_new/and.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { PC } from "../pc.ts"; - -export default { - function(this: PC, [reg1, reg2, reg3]: number[]) { - const r1 = this.lib.parseReg(reg1); - const r2 = this.lib.parseReg(reg2); - const r3 = this.lib.parseReg(reg3); - this.registers[r1] = this.registers[r2] & this.registers[r3]; - }, - args: 3 -} \ No newline at end of file diff --git a/pc-thing/instructions_new/cmp.ts b/pc-thing/instructions_new/cmp.ts deleted file mode 100644 index f97322a..0000000 --- a/pc-thing/instructions_new/cmp.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { PC } from "../pc.ts"; - -export default { - function(this: PC, [reg1, reg2]: number[]) { - const r1 = this.lib.parseReg(reg1); - const r2 = this.lib.parseReg(reg2); - this.returnFlag = +(this.registers[r1] == this.registers[r2]); - }, - args: 2 -} \ No newline at end of file diff --git a/pc-thing/instructions_new/cmr.ts b/pc-thing/instructions_new/cmr.ts deleted file mode 100644 index a83b46c..0000000 --- a/pc-thing/instructions_new/cmr.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { PC } from "../pc.ts"; - -export default { - function(this: PC, [reg1, reg2, reg3]: number[]) { - const r1 = this.lib.parseReg(reg1); - const r2 = this.lib.parseReg(reg2); - const r3 = this.lib.parseReg(reg3); - this.registers[r1] = +(this.registers[r2] == this.registers[r3]); - }, - args: 3 -} \ No newline at end of file diff --git a/pc-thing/instructions_new/div.ts b/pc-thing/instructions_new/div.ts deleted file mode 100644 index c78cd93..0000000 --- a/pc-thing/instructions_new/div.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { PC } from "../pc.ts"; - -export default { - function(this: PC, [reg1, reg2, reg3]: number[]) { - const r1 = this.lib.parseReg(reg1); - const r2 = this.lib.parseReg(reg2); - const r3 = this.lib.parseReg(reg3); - this.returnFlag = +((this.registers[r2] / this.registers[r3]) != 0); - this.registers[r1] = this.registers[r2] / this.registers[r3] - }, - args: 3 -} \ No newline at end of file diff --git a/pc-thing/instructions_new/halt.ts b/pc-thing/instructions_new/halt.ts deleted file mode 100644 index 4685f2b..0000000 --- a/pc-thing/instructions_new/halt.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { PC } from "../pc.ts"; - -export default { - function(this: PC) { - // this.programPointer = 0xFFFF - 1 - this.halted = true - }, - args: 0 -} \ No newline at end of file diff --git a/pc-thing/instructions_new/jmp.ts b/pc-thing/instructions_new/jmp.ts deleted file mode 100644 index f3bbc79..0000000 --- a/pc-thing/instructions_new/jmp.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { PC } from "../pc.ts"; - -export default { - function(this: PC, [reg1]: number[]) { - const r1 = this.lib.parseReg(reg1); - this.programPointer = this.registers[r1] - }, - args: 1 -} \ No newline at end of file diff --git a/pc-thing/instructions_new/jmr.ts b/pc-thing/instructions_new/jmr.ts deleted file mode 100644 index f7b0c00..0000000 --- a/pc-thing/instructions_new/jmr.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { PC } from "../pc.ts"; - -export default { - function(this: PC, [reg1]: number[]) { - const r1 = this.lib.parseReg(reg1); - this.returnStack.push(this.programPointer); - this.programPointer = this.registers[r1]; - }, - args: 1 -} \ No newline at end of file diff --git a/pc-thing/instructions_new/jnz.ts b/pc-thing/instructions_new/jnz.ts deleted file mode 100644 index d600f59..0000000 --- a/pc-thing/instructions_new/jnz.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { PC } from "../pc.ts"; - -export default { - function(this: PC, [reg1]: number[]) { - if (this.returnFlag == 0) return; - const r1 = this.lib.parseReg(reg1); - this.programPointer = this.registers[r1] - }, - args: 1 -} \ No newline at end of file diff --git a/pc-thing/instructions_new/jz.ts b/pc-thing/instructions_new/jz.ts deleted file mode 100644 index 0d4f64c..0000000 --- a/pc-thing/instructions_new/jz.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { PC } from "../pc.ts"; - -export default { - function(this: PC, [reg1]: number[]) { - if (this.returnFlag != 0) return; - const r1 = this.lib.parseReg(reg1); - this.programPointer = this.registers[r1] - }, - args: 1 -} \ No newline at end of file diff --git a/pc-thing/instructions_new/ld.ts b/pc-thing/instructions_new/ld.ts deleted file mode 100644 index 8d6c30d..0000000 --- a/pc-thing/instructions_new/ld.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { PC } from "../pc.ts"; - -export default { - function(this: PC, [reg1, reg2]: number[]) { - const r1 = this.lib.parseReg(reg1); - const r2 = this.lib.parseReg(reg2); - this.returnFlag = +(this.getMem(this.registers[r2]) != 0); - this.registers[r1] = this.getMem(this.registers[r2]) - }, - args: 2 -} \ No newline at end of file diff --git a/pc-thing/instructions_new/mod.ts b/pc-thing/instructions_new/mod.ts deleted file mode 100644 index 8f1a343..0000000 --- a/pc-thing/instructions_new/mod.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { PC } from "../pc.ts"; - -export default { - function(this: PC, [reg1, reg2, reg3]: number[]) { - const r1 = this.lib.parseReg(reg1); - const r2 = this.lib.parseReg(reg2); - const r3 = this.lib.parseReg(reg3); - this.returnFlag = +((this.registers[r2] % this.registers[r3]) != 0); - this.registers[r1] = this.registers[r2] % this.registers[r3] - }, - args: 3 -} \ No newline at end of file diff --git a/pc-thing/instructions_new/mov.ts b/pc-thing/instructions_new/mov.ts deleted file mode 100644 index a35806e..0000000 --- a/pc-thing/instructions_new/mov.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { PC } from "../pc.ts"; - -export default { - function(this: PC, [reg, data]: number[]) { - const r = this.lib.parseReg(reg) - this.registers[r] = Number(data) ?? 0 - }, - args: 2 -} \ No newline at end of file diff --git a/pc-thing/instructions_new/mul.ts b/pc-thing/instructions_new/mul.ts deleted file mode 100644 index bf3f12c..0000000 --- a/pc-thing/instructions_new/mul.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { PC } from "../pc.ts"; - -export default { - function(this: PC, [reg1, reg2, reg3]: number[]) { - const r1 = this.lib.parseReg(reg1); - const r2 = this.lib.parseReg(reg2); - const r3 = this.lib.parseReg(reg3); - this.returnFlag = +((this.registers[r2] * this.registers[r3]) != 0); - this.registers[r1] = this.registers[r2] * this.registers[r3] - }, - args: 3 -} \ No newline at end of file diff --git a/pc-thing/instructions_new/not.ts b/pc-thing/instructions_new/not.ts deleted file mode 100644 index 241897a..0000000 --- a/pc-thing/instructions_new/not.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { PC } from "../pc.ts"; - -export default { - function(this: PC, [reg1, reg2]: number[]) { - const r1 = this.lib.parseReg(reg1); - const r2 = this.lib.parseReg(reg2); - this.returnFlag = +((~this.registers[r1]) != 0); - this.registers[r1] = ~this.registers[r2]; - }, - args: 2 -} \ No newline at end of file diff --git a/pc-thing/instructions_new/or.ts b/pc-thing/instructions_new/or.ts deleted file mode 100644 index bd7cc7e..0000000 --- a/pc-thing/instructions_new/or.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { PC } from "../pc.ts"; - -export default { - function(this: PC, [reg1, reg2, reg3]: number[]) { - const r1 = this.lib.parseReg(reg1); - const r2 = this.lib.parseReg(reg2); - const r3 = this.lib.parseReg(reg3); - this.returnFlag = +((this.registers[r2] | this.registers[r3]) != 0); - this.registers[r1] = this.registers[r2] | this.registers[r3]; - }, - args: 3 -} \ No newline at end of file diff --git a/pc-thing/instructions_new/pop.ts b/pc-thing/instructions_new/pop.ts deleted file mode 100644 index 83ece88..0000000 --- a/pc-thing/instructions_new/pop.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { PC } from "../pc.ts"; - -export default { - function(this: PC, [reg1]: number[]) { - if (!this.getMem(0x7000)) throw 'no stack pointer'; - if (this.getMem(0x7001) == 0) throw 'stack underflow'; - const r1 = this.lib.parseReg(reg1); - this.registers[r1] = this.getMem(this.getMem(0x7001) + 1); - this.setMem(0x7001, this.getMem(0x7001) - 1) - }, - args: 1 -} \ No newline at end of file diff --git a/pc-thing/instructions_new/push.ts b/pc-thing/instructions_new/push.ts deleted file mode 100644 index b9dd718..0000000 --- a/pc-thing/instructions_new/push.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { PC } from "../pc.ts"; - -export default { - function(this: PC, [reg1]: number[]) { - if (!this.getMem(0x7000)) throw 'no stack pointer'; - if (this.getMem(0x7001) == 256) throw 'stack overflow'; - const r1 = this.lib.parseReg(reg1); - this.setMem(this.getMem(0x7000) + this.getMem(0x7001), this.registers[r1]) - this.setMem(0x7001, this.getMem(0x7001) + 1) - }, - args: 1 -} \ No newline at end of file diff --git a/pc-thing/instructions_new/ret.ts b/pc-thing/instructions_new/ret.ts deleted file mode 100644 index 04b5cc3..0000000 --- a/pc-thing/instructions_new/ret.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { PC } from "../pc.ts"; - -export default { - function(this: PC) { - const returnAddr = this.returnStack.pop(); - if (!returnAddr) throw 'return stack empty'; - this.programPointer = returnAddr; - }, - args: 1 -} \ No newline at end of file diff --git a/pc-thing/instructions_new/shl.ts b/pc-thing/instructions_new/shl.ts deleted file mode 100644 index 16bb382..0000000 --- a/pc-thing/instructions_new/shl.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { PC } from "../pc.ts"; - -export default { - function(this: PC, [reg1, reg2]: number[]) { - const r1 = this.lib.parseReg(reg1); - const r2 = this.lib.parseReg(reg2); - this.returnFlag = +((this.registers[r1] << this.registers[r2]) != 0); - this.registers[r1] <<= this.registers[r2] - }, - args: 2 -} \ No newline at end of file diff --git a/pc-thing/instructions_new/shr.ts b/pc-thing/instructions_new/shr.ts deleted file mode 100644 index 09bf005..0000000 --- a/pc-thing/instructions_new/shr.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { PC } from "../pc.ts"; - -export default { - function(this: PC, [reg1, reg2]: number[]) { - const r1 = this.lib.parseReg(reg1); - const r2 = this.lib.parseReg(reg2); - this.returnFlag = +((this.registers[r1] >> this.registers[r2]) != 0); - this.registers[r1] >>= this.registers[r2] - }, - args: 2 -} \ No newline at end of file diff --git a/pc-thing/instructions_new/str.ts b/pc-thing/instructions_new/str.ts deleted file mode 100644 index aa4c2d5..0000000 --- a/pc-thing/instructions_new/str.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { PC } from "../pc.ts"; - -export default { - function(this: PC, [reg1, reg2]: number[]) { - const r1 = this.lib.parseReg(reg1); - const r2 = this.lib.parseReg(reg2); - this.setMem(this.registers[r1], this.registers[r2]); - }, - args: 2 -} \ No newline at end of file diff --git a/pc-thing/instructions_new/sub.ts b/pc-thing/instructions_new/sub.ts deleted file mode 100644 index c7b4e94..0000000 --- a/pc-thing/instructions_new/sub.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { PC } from "../pc.ts"; - -export default { - function(this: PC, [reg1, reg2, reg3]: number[]) { - const r1 = this.lib.parseReg(reg1); - const r2 = this.lib.parseReg(reg2); - const r3 = this.lib.parseReg(reg3); - this.returnFlag = +((this.registers[r2] - this.registers[r3]) != 0); - this.registers[r1] = this.registers[r2] - this.registers[r3] - }, - args: 3 -} \ No newline at end of file diff --git a/pc-thing/instructions_new/swp.ts b/pc-thing/instructions_new/swp.ts deleted file mode 100644 index 7d07aea..0000000 --- a/pc-thing/instructions_new/swp.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { PC } from "../pc.ts"; - -export default { - function(this: PC, [reg1, reg2]: number[]) { - const r1 = this.lib.parseReg(reg1) - const r2 = this.lib.parseReg(reg2); - [this.registers[r1], this.registers[r2]] = - [this.registers[r2], this.registers[r1]] - // const data1 = Number(this.registers[r1]) - // const data2 = Number(this.registers[r2]) - // this.registers[r1] = data2 - // this.registers[r2] = data1 - }, - args: 2 -} \ No newline at end of file diff --git a/pc-thing/instructions_new/sys.ts b/pc-thing/instructions_new/sys.ts deleted file mode 100644 index fc27af9..0000000 --- a/pc-thing/instructions_new/sys.ts +++ /dev/null @@ -1,60 +0,0 @@ -// deno-lint-ignore-file no-case-declarations no-process-globals -import { PC } from "../pc.ts"; - -declare global { - const process: any; -} - -export default { - function(this: PC) { - if (typeof process == 'undefined') throw 'process global is undefined'; - switch (this.registers[0]) { - case 0: - switch (this.registers[1]) { - case 0: - const data = new Uint8Array(1024) - const len = Deno.stdin.readSync(data) ?? 0 - let i = 0; - while (i < len) { - this.mem[this.registers[2] + i] = data[i] - i++ - } - this.registers[0] = len - this.mem[this.registers[2] + i] = 0 - break; - - default: - throw 'unknown fd' - } - break; - case 1: - const writeBuff = []; - let i = this.registers[2]; - while (this.mem[i] != 0 && i <= this.mem.length) { - writeBuff.push(this.mem[i]); - i++ - } - switch (this.registers[1]) { - case 1: - process.stdout.write(writeBuff.map(a => String.fromCharCode(a)).join('')) - break; - - case 2: - process.stderr.write(writeBuff.map(a => String.fromCharCode(a)).join('')) - break; - - default: - throw 'unknown fd' - } - break; - - case 2: - Deno.stdin.setRaw(this.registers[1] ? true : false); - break; - - default: - throw 'unknown syscall id ' + this.registers[0] - } - }, - args: 0 -} \ No newline at end of file diff --git a/pc-thing/instructions_new/xor.ts b/pc-thing/instructions_new/xor.ts deleted file mode 100644 index 135e1cf..0000000 --- a/pc-thing/instructions_new/xor.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { PC } from "../pc.ts"; - -export default { - function(this: PC, [reg1, reg2, reg3]: number[]) { - const r1 = this.lib.parseReg(reg1); - const r2 = this.lib.parseReg(reg2); - const r3 = this.lib.parseReg(reg3); - this.returnFlag = +((this.registers[r2] ^ this.registers[r3]) != 0); - this.registers[r1] = this.registers[r2] ^ this.registers[r3]; - }, - args: 3 -} \ No newline at end of file diff --git a/pc-thing/lib.ts b/pc-thing/lib.ts deleted file mode 100644 index a1cd815..0000000 --- a/pc-thing/lib.ts +++ /dev/null @@ -1,5 +0,0 @@ -export function parseReg(arg: number): number { - if (!'abcd'.split('').includes(String.fromCharCode(arg).toLowerCase())) - throw `invalid register "${String.fromCharCode(arg)}"`; - return 'abcd'.split('').indexOf(String.fromCharCode(arg).toLowerCase()) -} \ No newline at end of file diff --git a/pc-thing/pc.ts b/pc-thing/pc.ts deleted file mode 100644 index a007189..0000000 --- a/pc-thing/pc.ts +++ /dev/null @@ -1,68 +0,0 @@ -import * as lib from "./lib.ts"; -type Registers = [number, number, number, number] -export class PC { - registers: Registers = new Array<number>(4).fill(0) as Registers - regNames: string = 'abcd' - halted: boolean = false - mem = new Array<number>(2**16).fill(0) - getSegment: undefined | ((segment: number) => Uint16Array) = undefined; - getMem(addr: number): number { - if (addr < 0 || addr > 2**16) - throw 'invalid address'; - //TODO - memory mapping - return this.mem[addr]; - } - setMem(addr: number, data: number) { - if (this.getSegment && addr == 0x7cff) { - const segment = this.getSegment(data) - for (let i = 0; i < 512; i++) { - this.mem[0x7d00 + i] = segment.length > i ? segment[i] : 0; - } - return; - } - if (addr >= 0x7d00 && addr <= 0x7fff && this.getSegment) { - return; - } - this.mem[addr] = Math.floor(data) % 2**16 - } - programPointer: number = 0; - lib = lib - returnFlag = 0; - returnStack: number[] = [] - // the instruction set, in no particular order :3 - instructions: Record<number, string> = { - 0: 'mov', - 1: 'swp', - 2: 'ld', - 3: 'str', - 4: 'add', - 5: 'sub', - 6: 'mul', - 7: 'div', - 8: 'mod', - 9: 'shl', - 10: 'shr', - 11: 'cmp', - 12: 'cmr', - 13: 'and', - 14: 'or', - 15: 'xor', - 16: 'not', - 17: 'push', - 18: 'pop', - 19: 'halt', - 20: 'sys', // extra - 21: 'jmp', - 22: 'jnz', - 23: 'jz', - 24: 'jmr', - 25: 'ret', - - 31: 'end' - } - constructor(diskSupport = false) { - if (diskSupport) { - this.mem[0x7cff] = (2**16) - 1 - } - } -} \ No newline at end of file diff --git a/pc-thing/ramgen.ts b/pc-thing/ramgen.ts deleted file mode 100644 index f6e419f..0000000 --- a/pc-thing/ramgen.ts +++ /dev/null @@ -1,116 +0,0 @@ -import { PC } from "./pc.ts"; -const pc = new PC() - -const commands = [] -const commandData: Record<string, any> = {} - -const dir = Deno.readDirSync('instructions_new'); - -for (const filename of dir) { - commands.push(filename.name.replace(/\..*?$/g, '')) - commandData[filename.name.replace(/\..*?$/g, '')] = (await import('./instructions_new/' + filename.name)).default -} - -commands.push('end') - -commandData.end = { - args: 0 -} - -interface ObjectFile { - // number is the ammount of bytes to skip - code: (string | number)[], - offset: number, - // line number, data - data: [number, number[]][] -} - -// console.log(commands, commands.length, (commands.length - 1).toString(16)) - -const object: ObjectFile = JSON.parse(new TextDecoder().decode(Deno.readFileSync('code.o'))) - -const code = object.code - -const offset = object.offset ?? 2**16 / 2 - -const ram = [] - -const instructions = [] - -for (const element of code) { - if (typeof element == 'number') { - instructions.push(element) - continue; - } - const [command, ...args] = element.split(' '); - switch (command) { - case '.hex': - instructions.push([parseInt(args[0], 16)]); - continue; - // deno-lint-ignore no-case-declarations - case '.str': - const str = [...element.matchAll(/"(.*?)(?<!\\)"/g)][0][1].replaceAll('\\"', '"') - instructions.push(new Array(str.length).fill(0).map((_, i) => str.charCodeAt(i))); - continue; - } - const parsedArgs = args.map(arg => { - if (arg.startsWith('$')) return arg // line numbers can pass - if (arg.match(/^\[.*\]$/)) return arg // line numbers can pass - if (!isNaN(+arg)) { - // make sure its a uint16 - return Math.floor(+arg) & 0xFFFF - } - arg = arg.toLowerCase(); - if (!pc.regNames.split('').includes(arg)) throw 'whar '+arg - return arg - }) - const inst = Object.entries(pc.instructions).find(([_, b]) => b == command); - if (!inst) throw 'erm,, what the sigma ' + command + ' (' + inst + ')' - if (!commandData[command]) throw 'no command data for ' + command + ' (' + inst + ')' - if (commandData[command].args != args.length) - throw `mismatch of ${command} arg length ${commandData[command].args} != ${args.length}` - instructions.push([+inst[0], ...parsedArgs]) -} - -const instructionAddresses: number[] = []; - -let addr = offset; -for (const instr of instructions) { - instructionAddresses.push(addr); - addr += typeof instr == 'number' ? instr : instr.length -} - -let i = 0 -for (const instr of instructions) { - // console.log(instr, Array.isArray(instr) ? instr[0].toString(16) : null) - if (typeof instr == 'number') { - // console.log(ram.length, instr, new Array<number>(instr).fill(0)) - ram.push(...new Array<number>(instr).fill(0)) - continue; - } - const newInstr: number[] = instr.map<number>(i => { - if (typeof i !== 'string') return i; - const m = i.match(/^\[(.*)\]$/) - if (m) { - const ln = m[1] - if (!instructionAddresses[+ln]) throw 'a '+i - // console.log(i, instructionAddresses[+i.replace('$', '')]) - return instructionAddresses[+ln] - } - if (!i.startsWith('$')) return i.charCodeAt(0); - if (!instructionAddresses[+i.replace('$', '')]) throw 'a '+i - // console.log(i, instructionAddresses[+i.replace('$', '')]) - return instructionAddresses[+i.replace('$', '')] - }) - // console.log(instructionAddresses[i], (instructionAddresses[i] * 2).toString(16), commands[newInstr[0]], newInstr) - ram.push(...newInstr) - i++ -} - - -for (const element of object.data) { - // console.log(instructionAddresses[element[0]] - offset, element[0], element[1]) - ram.splice(instructionAddresses[element[0]] - offset, element[1].length, ...element[1]) -} - -Deno.writeFileSync(Deno.args[0] ?? 'iram.bin', Uint8Array.from(ram.map(a => [a & 0x00FF, (a & 0xFF00) >> 8]).flatMap(([a, b]) => [a, b]))) diff --git a/pc-thing/readme.md b/pc-thing/readme.md deleted file mode 100644 index 047d8c0..0000000 --- a/pc-thing/readme.md +++ /dev/null @@ -1,19 +0,0 @@ -# shitPC - -an emulator for a fictional 16 bit computer thingy - -the system has: - -- 3 registers: A, B and C (16-bit) - -- 65535 addressable locations (each one storing 16 bits) - -- interrupt support - -- basic I/O - -- its own assembly language - -- disk support - -see [instructions.md](instructions.md) to see the documentation for the instructions or [assembler.md](assembler.md) to see the documentation for the assembler \ No newline at end of file diff --git a/pc-thing/redme.txt b/pc-thing/redme.txt deleted file mode 100644 index 73e3813..0000000 --- a/pc-thing/redme.txt +++ /dev/null @@ -1,5 +0,0 @@ -deno -A assembler.ts && deno -A ramgen.ts && hexdump -C iram.bin -this shit compiles - -deno -A runtime_new.ts -this shit runs \ No newline at end of file diff --git a/pc-thing/runtime.ts b/pc-thing/runtime.ts deleted file mode 100644 index cde4b95..0000000 --- a/pc-thing/runtime.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { PC } from "./pc.ts"; - -class Runtime { - pc: PC = new PC() - instructions: Map<string, (this: PC, argv: string[]) => void> = new Map() - - addInstruction(name: string, instruction: (this: PC, argv: string[]) => void) { - this.instructions.set(name, instruction) - } - - run(line: string) { - line = line.replace(/\s*;.*$/gm, '') - if (!line) return; - const [instr, ...argv] = line.split(' ') - const instructionId = instr.toLowerCase() - if (!this.instructions.has(instructionId)) - throw 'unknown instruction'; - const instruction = this.instructions.get(instructionId); - if (!instruction) - throw 'unknown instruction'; - instruction.call(this.pc, argv) - } -} - -const runtime = new Runtime() - -const dir = Deno.readDirSync('instructions'); - -for (const filename of dir) { - runtime.addInstruction(filename.name.replace(/\..*?$/g, ''), - (await import('./instructions/'+filename.name)).default) -} - -const code = new TextDecoder().decode(Deno.readFileSync('code.p')).split('\n') - -runtime.pc.programPointer = 0 -while (runtime.pc.programPointer < code.length) { - const line = code[runtime.pc.programPointer] - try { - runtime.run(line) - // console.debug('0'.repeat(4 - String(runtime.pc.programPointer).length) + - // runtime.pc.programPointer, - // runtime.pc.registers, line) - } catch (error) { - console.error(error, 'at', line); - throw 'Unexpected error while running program' - } - runtime.pc.programPointer++ -} - -console.debug('end of execution, dumping ram', runtime.pc.mem) -Deno.writeFileSync('ram.bin', Uint8Array.from(runtime.pc.mem.map(a => [a & 0x00FF, (a & 0xFF00) >> 8]).flatMap(([a, b]) => [a, b]))) -new Deno.Command('hexdump', { - args: ['-C', 'ram.bin'] -}).spawn() \ No newline at end of file diff --git a/pc-thing/runtime_new.ts b/pc-thing/runtime_new.ts deleted file mode 100644 index f0045d6..0000000 --- a/pc-thing/runtime_new.ts +++ /dev/null @@ -1,134 +0,0 @@ -import { PC } from "./pc.ts"; - -type instruction = { function: (this: PC, argv: number[]) => void, args: number } - -class Runtime { - pc: PC = new PC(true) - instructions: Record<string, instruction> = {} - instructionNames: string[] = [] - - addInstruction(name: string, instruction: instruction) { - this.instructionNames.push(name) - this.instructions[name] = instruction - } - - run(line: number[]) { - const instructionId = this.pc.instructions[line.shift() ?? -1] - if (instructionId == undefined || !this.instructions[instructionId]) - throw 'unknown instruction (1)'; - const instruction = this.instructions[instructionId]; - if (!instruction) - throw 'unknown instruction (2)'; - try { - instruction.function.call(this.pc, line) - } catch (error) { - console.error(error, 'at', this.pc.programPointer, instructionId) - } - } -} - -const disk = [...Deno.readFileSync('disk.img')].reduce<number[]>((result, value, index, array) => { - if (index % 2 === 0) { - result.push(value | (array[index + 1] << 8)) - } - return result; -}, []) - -const runtime = new Runtime() - -runtime.pc.getSegment = function getSegment(segment: number): Uint16Array { - const seg = disk.slice(segment * 512, (segment + 1) * 512); - console.log(`getSegment( ${segment} ):`, seg) - return Uint16Array.from(seg.fill(seg.length, 512)) -} - -const dir = Deno.readDirSync('instructions_new'); - -for (const filename of dir) { - runtime.addInstruction(filename.name.replace(/\..*?$/g, ''), - (await import('./instructions_new/' + filename.name)).default) -} - -runtime.addInstruction('end', { function: () => { }, args: 0 }) - -const iram = Deno.readFileSync("iram.bin") - -runtime.pc.mem = runtime.pc.mem.toSpliced(65534 / 2 + 1, 0, ...[...iram].reduce<number[]>((result, value, index, array) => { - if (index % 2 === 0) { - result.push(value | (array[index + 1] << 8)) - } - return result; -}, [])) - -runtime.pc.programPointer = 65536 / 2 - -const haltEvents = new EventTarget() - -function waitUntilNotInterrupted(): Promise<void> { - return new Promise((resolve) => { - const callback = () => { - resolve() - haltEvents.removeEventListener('unHalted', callback) - } - haltEvents.addEventListener('unHalted', callback) - }) -} - -function gotoInterrupt() { - // console.log("INTERRUPT!", runtime.pc.mem[0x7000]) - if (!runtime.pc.mem[0x7000]) - return; - runtime.pc.halted = false - haltEvents.dispatchEvent(new Event('unHalted')); - runtime.pc.returnStack.push(runtime.pc.programPointer - 1); - runtime.pc.programPointer = runtime.pc.mem[0x7000] -} - -const interruptInterval = setInterval(gotoInterrupt, 10) - -const endInst = (Object.entries(runtime.pc.instructions) as [unknown, string][] as [number, string][]) - .find(([_, b]: [number, string]) => b == 'end') -if (!endInst) throw 'where the fuck is the end instruction' -const endInstId = endInst[0]; - - -let c = 0 -while ( - runtime.pc.mem[runtime.pc.programPointer] != endInstId && - runtime.pc.programPointer != 0xFFFF - 1) { - try { - const definition = Object.entries(runtime.pc.instructions).find(([a]) => +a == runtime.pc.mem[runtime.pc.programPointer]) - if (!definition || !definition[1]) throw `what the fuck is that (unknown instruction) -at ${runtime.pc.programPointer} (${runtime.pc.programPointer.toString(16)}/${(runtime.pc.programPointer * 2).toString(16)}/${(runtime.pc.programPointer * 2 - (2 ** 16)).toString(16)}) -instruction: ${runtime.pc.mem[runtime.pc.programPointer]}` - const instruction = definition[1] - runtime.pc.programPointer++ - // console.debug(instruction, runtime.instructions, definition) - const args = []; - if (Deno.args.includes('-d')) - console.debug(runtime.pc.programPointer, definition, instruction, runtime.pc.mem[runtime.pc.programPointer + 1]) - while (args.length < runtime.instructions[instruction].args) { - args.push(runtime.pc.mem[runtime.pc.programPointer]) - runtime.pc.programPointer++ - } - runtime.run([+definition[0], ...args]) - // runtime.pc.programPointer++ - c++ - } catch (error) { - console.error(error); - break; - } - if (runtime.pc.halted) { - await waitUntilNotInterrupted() - } -} - -clearInterval(interruptInterval) - -if (Deno.args.includes('-d')) - console.debug(Object.values(runtime.pc.instructions)) -console.debug('end of execution, dumping ram', runtime.pc.mem) -Deno.writeFileSync('ram.bin', Uint8Array.from(runtime.pc.mem.map(a => [a & 0x00FF, (a & 0xFF00) >> 8]).flatMap(([a, b]) => [a, b]))) -new Deno.Command('hexdump', { - args: ['-C', 'ram.bin'] -}).spawn() diff --git a/pc-thing/shit-instruction-set-2 b/pc-thing/shit-instruction-set-2 deleted file mode 100644 index 08864fb..0000000 --- a/pc-thing/shit-instruction-set-2 +++ /dev/null @@ -1,62 +0,0 @@ -# the SHIT PC(R) INSTRUCTION SET(TM) 2 # - -> format: -> -> OPCODE[ARGS] -> (OUT/VOID) - -## Math ## -``` -ADD[REG1, REG2, REG3] -> (REG1) Add -SUB[REG1, REG2, REG3] -> (REG1) Subtract -MUL[REG1, REG2, REG3] -> (REG1) Multiply -DIV[REG1, REG2, REG3] -> (REG1) Divide -MOD[REG1, REG2, REG3] -> (REG1) Modulo -SHL[REG1, REG2] -> (REG1) Shift left -SHR[REG1, REG2] -> (REG1) Shift right -CMP[REG1, REG2] -> (VOID) Compare -CMR[REG1, REG2, REG3] -> (REG1) Compare Register -AND[REG1, REG2, REG3] -> (REG1) Logical AND -OR[REG1, REG2, REG3] -> (REG1) Logical OR -XOR[REG1, REG2, REG3] -> (REG1) Logical XOR -NOT[REG1, REG2] -> (REG1) Logical NOT -``` -## Registers ## -``` -MOV[REG, VAL] -> (REG) Move -SWP[REG1, REG2] -> (REG1, REG2) Swap register -``` -## Memory ## -``` -LD[REG1, REG2] -> (REG1) Load from address -STR[REG1, REG2] -> ($REG1) Set address -``` -## Jumping & stuff ## -``` -JMP[REG] -> (VOID) Jump to address -JNZ[REG] -> (VOID) Jump if flag is non-zero -JZ[REG] -> (VOID) Jump if flag is zero -JMR[REG] -> (VOID) Jump with return -RET[] -> (VOID) Return -``` -## Stack ## -> [!NOTE] -> The stack limit is 256, and it is only enabled once $7000h is set to a stack address -> -> $7001h has the pointer -> -> Keep in mind that the stack pointer goes **down** from that address -``` -PUSH[REG] -> (VOID) Push to stack -POP[REG] -> (REG) Pop from stack -``` -## System ## -``` -HALT[] -> (VOID) Halt the processor -``` - -#### extra #### - -this might get replaced with a thing yin the ram in the future possibly -``` -SYS[TYPE, ...] -> (VOID) Systemcall -``` \ No newline at end of file diff --git a/pc-thing/test.ts b/pc-thing/test.ts deleted file mode 100644 index ff6e23c..0000000 --- a/pc-thing/test.ts +++ /dev/null @@ -1,3 +0,0 @@ -const data = new Uint8Array(1024) -console.log(Deno.stdin.readSync(data), data) - diff --git a/pc-thing/the_e_programming_language/ast.json b/pc-thing/the_e_programming_language/ast.json deleted file mode 100644 index faf9b67..0000000 --- a/pc-thing/the_e_programming_language/ast.json +++ /dev/null @@ -1,79 +0,0 @@ -[ - { - "type": "VariableDeclaration", - "identifier": "buff", - "value": { - "type": "Number", - "value": 0 - }, - "vtype": "int", - "length": 4 - }, - { - "type": "VariableDeclaration", - "identifier": "counter", - "value": { - "type": "Number", - "value": 0 - }, - "vtype": "int", - "length": 1 - }, - { - "type": "FunctionDeclaration", - "name": "_start", - "body": [ - { - "type": "While", - "condition": { - "type": "BinaryExpression", - "operator": "<", - "left": { - "type": "Identifier", - "name": "counter" - }, - "right": { - "type": "Number", - "value": 4 - } - }, - "branch": [ - { - "type": "Assignment", - "identifier": { - "type": "Identifier", - "name": "buff", - "offset": { - "type": "Identifier", - "name": "counter" - } - }, - "value": { - "type": "Identifier", - "name": "counter" - } - }, - { - "type": "Assignment", - "identifier": { - "type": "Identifier", - "name": "counter" - }, - "value": { - "type": "BinaryExpression", - "operator": "+", - "left": { - "type": "Identifier", - "name": "counter" - }, - "right": { - "type": "Number", - "value": 1 - } - } - } - ] - } - ] - } -] \ No newline at end of file diff --git a/pc-thing/the_e_programming_language/ast.ts b/pc-thing/the_e_programming_language/ast.ts deleted file mode 100644 index 80210d8..0000000 --- a/pc-thing/the_e_programming_language/ast.ts +++ /dev/null @@ -1,357 +0,0 @@ -import { Token, TokenType } from "./tokenizer.ts"; - -export interface ASTNode { - type: string; -} - -export interface VariableDeclarationNode extends ASTNode { - type: "VariableDeclaration"; - identifier: string; - value: ASTNode; - vtype: string; - length: number; -} - -export interface FunctionDeclarationNode extends ASTNode { - type: "FunctionDeclaration"; - name: string; - // params: string[]; - body: ASTNode[]; -} - -export interface AssignmentNode extends ASTNode { - type: "Assignment"; - identifier: IdentifierNode; - value: ASTNode; -} - -export interface BinaryExpressionNode extends ASTNode { - type: "BinaryExpression"; - operator: string; - left: ASTNode; - right: ASTNode; -} - -export interface LiteralNode extends ASTNode { - type: "Literal"; - value: string; -} - -export interface NumberNode extends ASTNode { - type: "Number"; - value: number; -} - -export interface IdentifierNode extends ASTNode { - type: "Identifier"; - name: string; - offset?: ASTNode; -} - -export interface FunctionCallNode extends ASTNode { - type: "FunctionCall"; - identifier: string; - args: ASTNode[]; -} - -// export interface BranchFunctionCallNode extends ASTNode { -// type: "BranchFunctionCall"; -// identifier: string; -// args: ASTNode[]; -// branches: ASTNode[][]; -// } - -// export interface StartBlockNode extends ASTNode { -// type: "StartBlock"; -// body: ASTNode[]; -// } - -export interface IfNode extends ASTNode { - type: "If"; - condition: ASTNode; - thenBranch: ASTNode[]; - elseBranch?: ASTNode[]; -} - -export interface WhileNode extends ASTNode { - type: "While"; - condition: ASTNode; - branch: ASTNode[]; -} - -// export interface ForNode extends ASTNode { -// type: "For"; -// times: ASTNode; -// varname: ASTNode; -// branch: ASTNode[]; -// } - -// export interface GreenFlagNode extends ASTNode { -// type: "GreenFlag"; -// branch: ASTNode[]; -// } - -// use 1 or 0 for boolean -// export interface BooleanNode extends ASTNode { -// type: "Boolean"; -// value: boolean; -// } - -// export interface IncludeNode extends ASTNode { -// type: "Include"; -// itype: string; -// path: string; -// } - -// export interface ListDeclarationNode extends ASTNode { -// type: "ListDeclaration"; -// identifier: string; -// value: ASTNode[]; -// vtype: 'list' | 'global' -// } - -export default class AST { - private tokens: Token[]; - position: number = 0; - - constructor(tokens: Token[]) { - this.tokens = tokens; - } - - private peek(ahead = 0): Token { - return this.tokens[this.position + ahead]; - } - - private advance(): Token { - return this.tokens[this.position++]; - } - - private match(...types: TokenType[]): boolean { - if (types.includes(this.peek().type)) { - this.advance(); - return true; - } - return false; - } - - private matchTk(types: TokenType[], token = this.peek()): boolean { - if (types.includes(token.type)) { - return true; - } - return false; - } - - private expect(type: TokenType, errorMessage: string): Token { - if (this.peek().type === type) { - return this.advance(); - } - console.error('trace: tokens', this.tokens, '\nIDX:', this.position); - throw new Error(errorMessage); - } - - parse(): ASTNode[] { - const nodes: ASTNode[] = []; - while (this.peek().type !== TokenType.EOF) { - nodes.push(this.parseStatement()); - } - return nodes; - } - - private parseStatement(): ASTNode { - if (this.matchTk([TokenType.TYPE])) { - const type = this.advance().value - let len = 1; - if (this.match(TokenType.LBRACKET)) { - len = Number(this.expect(TokenType.NUMBER, 'expected number after [').value); - this.expect(TokenType.RBRACKET, 'expected ] after length') - } - const identifier = this.expect(TokenType.IDENTIFIER, "expected var name after type (hint: functions dont have return types yet").value; - this.expect(TokenType.ASSIGN, "expected = after var name"); - const value = this.parseAssignment(false); - return { type: "VariableDeclaration", identifier, value, vtype: type, length: len } as VariableDeclarationNode; - } - - if (this.match(TokenType.FN_DECL)) { - const name = this.expect(TokenType.IDENTIFIER, "expected function name after fn").value; - // this.expect(TokenType.LPAREN, "Expected '(' after function name"); - // const params: string[] = []; - // if (!this.match(TokenType.RPAREN)) { - // do { - // params.push(this.expect(TokenType.IDENTIFIER, "Expected parameter name").value); - // } while (this.match(TokenType.COMMA)); - // this.expect(TokenType.RPAREN, "Expected ')' after parameters"); - // } - this.expect(TokenType.LBRACE, "expected '{' before function body"); - const body = this.parseBlock(); - return { type: "FunctionDeclaration", name, body } as FunctionDeclarationNode; - } - - if (this.match(TokenType.IF)) { - this.expect(TokenType.LPAREN, "Expected '(' after 'if'"); - const condition = this.parseAssignment(); - this.expect(TokenType.RPAREN, "Expected ')' after if condition"); - this.expect(TokenType.LBRACE, "Expected '{' after if condition"); - const thenBranch = this.parseBlock(); - let elseBranch: ASTNode[] | undefined; - if (this.match(TokenType.ELSE)) { - this.expect(TokenType.LBRACE, "Expected '{' after 'else'"); - elseBranch = this.parseBlock(); - } - return { type: "If", condition, thenBranch, elseBranch } as IfNode; - } - - if (this.match(TokenType.WHILE)) { - this.expect(TokenType.LPAREN, "Expected '(' after 'while'"); - const condition = this.parseAssignment(); - this.expect(TokenType.RPAREN, "Expected ')' after while condition"); - this.expect(TokenType.LBRACE, "Expected '{' after while condition"); - const branch = this.parseBlock(); - return { type: "While", condition, branch } as WhileNode; - } - - // if (this.match(TokenType.FOR)) { - // this.expect(TokenType.LPAREN, "Expected '(' after 'for'"); - // const varname = this.parseAssignment(); - // const of = this.expect(TokenType.IDENTIFIER, 'expected of'); - // if (of.value !== 'of') throw new Error('expected of'); - // const times = this.parseAssignment(); - // this.expect(TokenType.RPAREN, "Expected ')' after for"); - // this.expect(TokenType.LBRACE, "Expected '{' after for"); - // const branch = this.parseBlock(); - - // return { type: "For", varname, times, branch } as ForNode; - // } - - // if (this.match(TokenType.GREENFLAG)) { - // this.expect(TokenType.LBRACE, "Expected '{' after greenflag"); - // const branch = this.parseBlock(); - - // return { type: "GreenFlag", branch } as GreenFlagNode; - // } - - return this.parseAssignment(); - } - - private parseBlock(): ASTNode[] { - const nodes: ASTNode[] = []; - - while (!this.match(TokenType.RBRACE)) { - nodes.push(this.parseStatement()); - } - - return nodes; - } - - private parseAssignment(allowStuff = true): ASTNode { - - const expr = this.parseBinaryExpression(allowStuff); - if (this.match(TokenType.ASSIGN)) { - if (expr.type !== "Identifier") - throw new Error("invalid assignment target; expected an identifier"); - const value = allowStuff ? this.parseAssignment() : this.parsePrimary(false); - // let offset = undefined; - // if (this.match(TokenType.LBRACKET)) { - // offset = this.parseAssignment(); - // this.expect(TokenType.RBRACKET, 'expected ]') - // } - return { type: "Assignment", identifier: (expr as IdentifierNode), value } as AssignmentNode; - } - return expr; - } - - private parseBinaryExpression(allowStuff = false): ASTNode { - let left = this.parseCall(allowStuff); - - while (this.peek().type === TokenType.BINOP) { - const operator = this.advance().value; - const right = this.parseCall(); - left = { type: "BinaryExpression", operator, left, right } as BinaryExpressionNode; - } - return left; - } - - private parseCall(allowStuff = false): ASTNode { - let expr = this.parsePrimary(allowStuff); - - while (this.peek().type === TokenType.LPAREN) { - expr = this.finishCall(expr); - } - return expr; - } - - private finishCall(callee: ASTNode): ASTNode { - this.expect(TokenType.LPAREN, "Expected '(' after function name"); - //TODO - arguments - // const args: ASTNode[] = []; - // if (this.peek().type !== TokenType.RPAREN) { - // do { - // args.push(this.parseAssignment()); - // } while (this.match(TokenType.COMMA)); - // } - this.expect(TokenType.RPAREN, "Expected ')' after arguments"); - - - // if (this.peek().type === TokenType.LBRACE) { - // const branches: ASTNode[][] = []; - // do { - // this.expect(TokenType.LBRACE, "Expected '{' for branch block"); - // branches.push(this.parseBlock()); - // } while (this.peek().type === TokenType.LBRACE); - - // if (callee.type !== "Identifier") - // throw new Error("Branch function call expects an identifier"); - // return { - // type: "BranchFunctionCall", - // identifier: (callee as IdentifierNode).name, - // args, - // branches, - // } as BranchFunctionCallNode; - // } - - - if (callee.type !== "Identifier") - throw new Error("Function call expects an identifier"); - return { - type: "FunctionCall", - identifier: (callee as IdentifierNode).name, - // args, - } as FunctionCallNode; - } - - private parsePrimary(allowOther = true): ASTNode { - const token = this.peek(); - - if (this.match(TokenType.NUMBER)) { - return { type: "Number", value: Number(token.value) } as NumberNode; - } - - if (this.match(TokenType.LITERAL)) { - return { type: "Literal", value: token.value } as LiteralNode; - } - - if (this.match(TokenType.IDENTIFIER) && allowOther) { - - // if (["True", "true", "False", "false"].includes(token.value)) { - // return { - // type: "Boolean", - // value: token.value === "True" || token.value === "true" - // } as BooleanNode; - // } - let offset = undefined; - if (this.match(TokenType.LBRACKET)) { - offset = this.parseAssignment(); - this.expect(TokenType.RBRACKET, 'expected ]') - } - return { type: "Identifier", name: token.value, offset } as IdentifierNode; - } - - if (this.match(TokenType.LPAREN) && allowOther) { - const expr = this.parseAssignment(); - this.expect(TokenType.RPAREN, "Expected ')' after expression"); - return expr; - } - - throw new Error(`Unexpected token: ${token.type}`); - } - -} \ No newline at end of file diff --git a/pc-thing/the_e_programming_language/code.txt b/pc-thing/the_e_programming_language/code.txt deleted file mode 100644 index f45a592..0000000 --- a/pc-thing/the_e_programming_language/code.txt +++ /dev/null @@ -1,11 +0,0 @@ -mov 97,0 -mov 98,0 -str 98,97 -mov 97,0 -mov 98,4 -str 98,97 -pop 97 -mov 98,0 -cmp 97,98 -mov 97,18 -jnz 97 \ No newline at end of file diff --git a/pc-thing/the_e_programming_language/compiler.ts b/pc-thing/the_e_programming_language/compiler.ts deleted file mode 100644 index 37538f7..0000000 --- a/pc-thing/the_e_programming_language/compiler.ts +++ /dev/null @@ -1,151 +0,0 @@ -import { ASTNode, BinaryExpressionNode, FunctionDeclarationNode, NumberNode, VariableDeclarationNode, WhileNode } from "./ast.ts"; -// import { PC } from "../pc.ts"; -// const pc = new PC(); - -type Opcode = - 'mov' | - 'swp' | - 'ld' | - 'str' | - 'add' | - 'sub' | - 'mul' | - 'div' | - 'mod' | - 'shl' | - 'shr' | - 'cmp' | - 'cmr' | - 'and' | - 'or' | - 'xor' | - 'not' | - 'push' | - 'pop' | - 'halt' | - 'sys' | - 'jmp' | - 'jnz' | - 'jz' | - 'jmr' | - 'ret' | - 'end'; -type Register = 97 | 98 | 99 | 100 - -interface Instruction { - opcode: Opcode, - args: (Register | number)[] -} - -const types: Record<string, number> = { - 'int' : 1, - 'bool': 1, - 'char': 1 -} - -const A: Register = 97; -const B: Register = 98; -// deno-lint-ignore no-unused-vars -const C: Register = 99; -// deno-lint-ignore no-unused-vars -const D: Register = 100; - -export default class Compiler { - vars: Record<string, [number, number]> = {}; - functions: Record<string, number> = {}; - AST: ASTNode[]; - lastAddr: number = 0; - instructions: Instruction[] = []; - constructor (ast: ASTNode[]) { - this.AST = ast - } - compile (node: ASTNode) { - if ((node as VariableDeclarationNode).type == 'VariableDeclaration') { - const varDeclNode = node as VariableDeclarationNode; - if (!types[varDeclNode.vtype]) throw 'unknown type'; - const addr = this.vars[varDeclNode.identifier] = - [this.lastAddr, types[varDeclNode.vtype] * varDeclNode.length]; - this.lastAddr += types[varDeclNode.vtype] * varDeclNode.length; - if (varDeclNode.value.type != 'Number') throw 'a'; - this.instructions.push({ - opcode: 'mov', - args: [A, (varDeclNode.value as NumberNode).value] - }) - this.instructions.push({ - opcode: 'mov', - args: [B, addr[0]] - }) - this.instructions.push({ - opcode: 'str', - args: [B, A] - }) - } else if ((node as FunctionDeclarationNode).type == 'FunctionDeclaration') { - const fnDeclNode = node as FunctionDeclarationNode; - this.functions[fnDeclNode.name] = this.instructions - .map(k => 1 + k.args.length) - .reduce((prev, curr) => { - return prev + curr - }, 0); - for (const node of fnDeclNode.body) { - this.compile(node) - } - } else if ((node as BinaryExpressionNode).type == 'BinaryExpression') { - const binExpNode = node as BinaryExpressionNode; - this.instructions.push({ - opcode: 'pop', - args: [A] - }) - this.instructions.push({ - opcode: 'pop', - args: [B] - }) - switch (binExpNode.operator) { - case '+': - this.instructions.push({ - opcode: 'add', - args: [A, A, B] - }) - break; - - default: - throw 'oh no' - } - this.instructions.push({ - opcode: 'push', - args: [A] - }) - } else if ((node as WhileNode).type == 'While') { - const whileNode = node as WhileNode; - const start = this.instructions - .map(k => 1 + k.args.length) - .reduce((prev, curr) => { - return prev + curr - }, 0); - for (const node of whileNode.branch) { - this.compile(node) - } - this.instructions.push({ - opcode: 'pop', - args: [A] - }) - this.instructions.push({ - opcode: 'mov', - args: [B, 0] - }) - this.instructions.push({ - opcode: 'cmp', - args: [A, B] - }) - this.instructions.push({ - opcode: 'mov', - args: [A, start] - }) - this.instructions.push({ - opcode: 'jnz', - args: [A] - }) - } else { - console.error(`!!! UNIMPLEMENTED NODE `, node.type, node) - } - } -} \ No newline at end of file diff --git a/pc-thing/the_e_programming_language/lang.ts b/pc-thing/the_e_programming_language/lang.ts deleted file mode 100755 index 5c00b98..0000000 --- a/pc-thing/the_e_programming_language/lang.ts +++ /dev/null @@ -1,31 +0,0 @@ -import Tokenizer from "./tokenizer.ts"; -import ASTGen from "./ast.ts"; -import Compiler from "./compiler.ts"; -const input = Deno.readTextFileSync('test.e') - -const tokenizer = new Tokenizer(input); -const tokens = tokenizer.tokenize(); - -console.log(tokens) - -const astGenerator = new ASTGen(tokens); - -let ast; -try { - ast = astGenerator.parse() -} catch (error) { - console.error(error); - console.log('at', astGenerator.position, tokens.map((a, i) => i == astGenerator.position ? `${a.type}(${a.value}) <--` : `${a.type}(${a.value})`).join('\n')) - Deno.exit(1) -} - -console.log(ast) - -const compiler = new Compiler(ast); - -for (const node of compiler.AST) { - compiler.compile(node) -} - -Deno.writeTextFileSync('ast.json', JSON.stringify(ast, null, 4)) -Deno.writeTextFileSync('code.txt', compiler.instructions.map(i => `${i.opcode}${i.args.length > 0 ? ' ' : ''}${i.args.join(',')}`).join('\n')) \ No newline at end of file diff --git a/pc-thing/the_e_programming_language/test-2.e b/pc-thing/the_e_programming_language/test-2.e deleted file mode 100755 index 3b1b371..0000000 --- a/pc-thing/the_e_programming_language/test-2.e +++ /dev/null @@ -1,6 +0,0 @@ -int[8] a = 0 -int test = 5 -fn _start { -a[4] = 5 -a[test] = 6 -} \ No newline at end of file diff --git a/pc-thing/the_e_programming_language/test.e b/pc-thing/the_e_programming_language/test.e deleted file mode 100755 index 4996d5c..0000000 --- a/pc-thing/the_e_programming_language/test.e +++ /dev/null @@ -1,43 +0,0 @@ -// comments exist -// -// types (in addresses (they store 2 bytes if you forgot)): -// int - 1 -// char - 1 -// bool - 1 -// uuh yeah,, theyre all 1 address ;-; -// -// $VARNAME is the address of the var, when used in mov it means that we get that var -// [$VARNAME] is the address of the var, but when it's used in mov it means we set to the address - -// translates to: -// mov a 0 -// mov $counter a -// prob not gonna make it do assembly tho -int[4] buff = 0 -int counter = 0 - -fn _start { - // translates to - // <inner code> - // mov a $counter - // mov b 4 - // cmp a b - // jz $start_of_inner_code - while (counter < 4) { - // translates to - // mov a [$buff] - // mov b [$counter] - // add a a b - // mov b $counter - // str a b - buff[counter] = counter - // translates to - // mov a $counter ; further translates to: - // ; mov a $counter - // ; ld a a - // mov b 1 - // add a a b - // str $counter a - counter = counter + 1 - } -} \ No newline at end of file diff --git a/pc-thing/the_e_programming_language/test.e.txt b/pc-thing/the_e_programming_language/test.e.txt deleted file mode 100755 index c8d09c5..0000000 --- a/pc-thing/the_e_programming_language/test.e.txt +++ /dev/null @@ -1,43 +0,0 @@ -// comments exist -// -// types (in addresses (they store 2 bytes if you forgot)): -// int - 1 -// char - 1 -// bool - 1 -// uuh yeah,, theyre all 1 address ;-; -// -// $VARNAME is the address of the var, when used in mov it means that we get that var -// [$VARNAME] is the address of the var, but when it's used in mov it means we set to the address - -// translates to: -// mov a 0 -// mov $counter a -// prob not gonna make it do assembly tho -int counter = 0 -int[4] buff = 0 - -fn _start { - // translates to - // <inner code> - // mov a $counter - // mov b 4 - // cmp a b - // jz $start_of_inner_code - while (counter < 4) { - // translates to - // mov a [$buff] - // mov b [$counter] - // add a a b - // mov b $counter - // str a b - buff[counter] = counter - // translates to - // mov a $counter ; further translates to: - // ; mov a $counter - // ; ld a a - // mov b 1 - // add a a b - // str $counter a - counter = counter + 1 - } -} \ No newline at end of file diff --git a/pc-thing/the_e_programming_language/tokenizer.ts b/pc-thing/the_e_programming_language/tokenizer.ts deleted file mode 100755 index 57d0131..0000000 --- a/pc-thing/the_e_programming_language/tokenizer.ts +++ /dev/null @@ -1,171 +0,0 @@ -export enum TokenType { - TYPE = "TYPE", - FN_DECL = "FN_DECL", - LITERAL = "LITERAL", - NUMBER = "NUMBER", - LPAREN = "LPAREN", - RPAREN = "RPAREN", - LBRACE = "LBRACE", - RBRACE = "RBRACE", - LBRACKET = "LBRACKER", - RBRACKET = "RBRACKER", - COMMA = "COMMA", - WHILE = "WHILE", - IF = "IF", - ELSE = "ELSE", - ASSIGN = "ASSIGN", - BINOP = "BINOP", - IDENTIFIER = "IDENTIFIER", - - EOF = "EOF", -} - -export interface Token { - type: TokenType; - value: string; -} - -const types = ['int', 'bool', 'char'] - -// i hardly know her -export default class Tokenizer { - private source: string; - private position: number = 0; - - constructor(source: string) { - this.source = source; - } - - private isAlpha(char: string): boolean { - return /[a-zA-Z_#]/.test(char); - } - - private isDigit(char: string): boolean { - return /-?[\d\.]/.test(char); - } - - private isWhitespace(char: string): boolean { - return /\s/.test(char); - } - - private advance(): string { - return this.source[this.position++]; - } - - private peek(): string { - return this.source[this.position] || ""; - } - - private match(expected: string): boolean { - if (this.peek() === expected) { - this.position++; - return true; - } - return false; - } - - tokenize(): Token[] { - const tokens: Token[] = []; - - let inComment = false; - let global = 0; - - while (this.position < this.source.length) { - const char = this.advance(); - - if (global > 0) global--; - - if (inComment) { - if (char == '\n') inComment = false; - continue; - } else if (char == '/' && this.peek() == '/') { - inComment = true - } else if (this.isWhitespace(char)) { - continue; - } else if (this.isAlpha(char)) { - let identifier = char; - while (this.isAlpha(this.peek()) || this.isDigit(this.peek())) { - identifier += this.advance(); - } - - // if (identifier === "#include") { - // // while(this.isWhitespace(this.peek()) && this.position < this.source.length) { - // // this.advance() - // // } - // // if (this.advance() != '<') throw "Expected a < after #include" - // // let id = '' - // // while (this.peek() != '>' - // // && (this.isAlpha(this.peek()) || this.isDigit(this.peek()))) { - // // id += this.advance(); - // // } - // // if (this.advance() != '>') throw "Expected a > after #include <..." - // tokens.push({ type: TokenType.INCLUDE, value: identifier }); - // } else if (identifier === "var") tokens.push({ type: TokenType.VAR, value: global > 0 ? 'global' : identifier }); - // else if (identifier === "list") tokens.push({ type: TokenType.LIST, value: global > 0 ? 'global' : identifier }); - // else if (identifier === "global") global = 2; - if (identifier === "fn") tokens.push({ type: TokenType.FN_DECL, value: identifier }); - else if (identifier === "if") tokens.push({ type: TokenType.IF, value: identifier }); - else if (identifier === "else") tokens.push({ type: TokenType.ELSE, value: identifier }); - else if (identifier === "while") tokens.push({ type: TokenType.WHILE, value: identifier }); - else if (types.includes(identifier)) tokens.push({ type: TokenType.TYPE, value: identifier }); - // else if (identifier === "for") tokens.push({ type: TokenType.FOR, value: identifier }); - else tokens.push({ type: TokenType.IDENTIFIER, value: identifier }); - } else if (this.isDigit(char)) { - let number = char; - while (this.isDigit(this.peek())) { - number += this.advance(); - } - tokens.push({ type: TokenType.NUMBER, value: number }); - } else if (char === '"') { - let string = ""; - while (this.peek() !== '"' && this.peek() !== "") { - string += this.advance(); - } - if (!this.match('"')) { - throw new Error("Unterminated string"); - } - tokens.push({ type: TokenType.LITERAL, value: string }); - } else if (char === "(") tokens.push({ type: TokenType.LPAREN, value: char }); - else if (char === ")") tokens.push({ type: TokenType.RPAREN, value: char }); - else if (char === "{") tokens.push({ type: TokenType.LBRACE, value: char }); - else if (char === "}") tokens.push({ type: TokenType.RBRACE, value: char }); - else if (char === "[") tokens.push({ type: TokenType.LBRACKET, value: char }); - else if (char === "]") tokens.push({ type: TokenType.RBRACKET, value: char }); - else if (char === ",") tokens.push({ type: TokenType.COMMA, value: char }); - else if (char === "+") tokens.push({ type: TokenType.BINOP, value: char }); - else if (char === "-") tokens.push({ type: TokenType.BINOP, value: char }); - else if (char === "*") tokens.push({ type: TokenType.BINOP, value: char }); - else if (char === "/") tokens.push({ type: TokenType.BINOP, value: char }); - else if (char === "%") tokens.push({ type: TokenType.BINOP, value: char }); - else if (char === "=" && this.peek() === '=') { - tokens.push({ type: TokenType.BINOP, value: char }); - this.advance(); - } - else if (char === "&" && this.peek() === '&') { - tokens.push({ type: TokenType.BINOP, value: char }); - this.advance(); - } - else if (char === "!" && this.peek() === '=') { - tokens.push({ type: TokenType.BINOP, value: '!=' }); - this.advance(); - } - else if (char === "<" && this.peek() === '=') { - tokens.push({ type: TokenType.BINOP, value: '<=' }); - this.advance(); - } - else if (char === ">" && this.peek() === '=') { - tokens.push({ type: TokenType.BINOP, value: '>=' }); - this.advance(); - } - else if (char === ">") tokens.push({ type: TokenType.BINOP, value: char }); - else if (char === "<") tokens.push({ type: TokenType.BINOP, value: char }); - else if (char === "=") tokens.push({ type: TokenType.ASSIGN, value: char }); - else { - throw new Error(`Unexpected character: ${char}`); - } - } - - tokens.push({ type: TokenType.EOF, value: "" }); - return tokens; - } -} \ No newline at end of file |