├── .gitignore ├── README.md ├── assembler ├── assembler.py ├── formats.py ├── preprocessor │ ├── comments.py │ ├── labels.py │ ├── macros.py │ ├── pager.py │ ├── preprocess.py │ └── relatives.py ├── test.s ├── test.schem └── translator │ ├── parseline.py │ └── translate.py ├── chasm_scripts ├── bank1.s ├── bank2.s ├── constants.s └── ports.s ├── emulator ├── alu.py ├── emulator.py ├── instruction.py ├── peripherals │ ├── base.py │ ├── minecraftdisplay.py │ ├── peripherals2-electricBoogaloo │ │ ├── amogus.py │ │ ├── blockRAM.py │ │ ├── craftRom.py │ │ ├── meshGen.py │ │ ├── playerInput.py │ │ └── screen.py │ ├── textures.py │ ├── triangle_backup.py │ └── trianglerom.py └── ports.py ├── main.py ├── minecraft ├── blockToMesh.s ├── combine.py ├── gameloop.s ├── main.s ├── memory.s ├── ports.s ├── textures.s └── world │ ├── block.txt │ ├── generate_world.py │ ├── real world.txt │ ├── test world.txt │ └── world.txt ├── schemgenerator ├── blockdata.py ├── data.txt ├── schem.py ├── templates │ ├── ROM_blank_2KiB.schem │ ├── ROM_blank_4KiB.schem │ ├── base.schem │ └── world_base.schem ├── textschem.py ├── textures.json ├── textures.py ├── textures.schem ├── world.json └── worldschem.py ├── urcl scripts └── MinecraftInMinecraft.urcl └── urcl-explorer ├── .gitignore ├── .gitmodules ├── Procfile ├── README.MD ├── TODO.md ├── URCLpp-compiler ├── .gitconfig ├── .gitmodules ├── Libraries │ ├── LICENSE │ ├── README.md │ ├── String │ │ ├── Is_empty.urcl │ │ ├── about.txt │ │ ├── add_char.urcl │ │ ├── char_at.urcl │ │ ├── count.urcl │ │ ├── ends_with_char.urcl │ │ ├── index_of.urcl │ │ ├── last_index_of.urcl │ │ ├── length.urcl │ │ ├── print.urcl │ │ ├── remove_char.urcl │ │ └── starts_with_char.urcl │ ├── complex_hh │ │ ├── ADD.urcl │ │ ├── DIV.urcl │ │ ├── MLT.urcl │ │ ├── SUB.urcl │ │ └── about.txt │ ├── complex_ww │ │ ├── ADD.urcl │ │ ├── DIV.urcl │ │ ├── MLT.urcl │ │ ├── SUB.urcl │ │ └── about.txt │ ├── example │ │ └── sample.urcl │ └── f32 │ │ └── f32_to_int.urcl ├── README.md ├── bin │ └── urclpp.cmd ├── bot.py ├── compiler2.py └── debug_test.urcl ├── bin ├── urcx-emu └── urcx-emu.cmd ├── editor ├── editor.css ├── editor.ts └── tokenizer.ts ├── emulator ├── breaks.ts ├── compiler.ts ├── devices │ ├── CHUNGUS devices │ │ ├── amogus.ts │ │ ├── blockRAM.ts │ │ ├── blockToMesh.ts │ │ ├── craftingRom.ts │ │ ├── playerInput.ts │ │ └── screen.ts │ ├── clock.ts │ ├── console-io.ts │ ├── device.ts │ ├── display.ts │ ├── gamepad.ts │ ├── gl-display.ts │ ├── keyboard.ts │ ├── rng.ts │ ├── sound.ts │ └── storage.ts ├── emulator.ts ├── instructions.ts ├── parser.ts ├── preprocessor.ts └── util.ts ├── examples ├── aoc21 │ ├── 1-e.txt │ ├── 1-i.txt │ ├── 1.1.urcl │ ├── 1.2.urcl │ ├── 2-e.txt │ ├── 2-i.txt │ ├── 2.1.urcl │ ├── 2.2.urcl │ ├── 3-e.txt │ ├── 3-i.txt │ ├── 3.1.urcl │ └── 3.2.urcl └── urcl │ ├── add.urcl │ ├── audio.urcl │ ├── debug.urcl │ ├── display-io.urcl │ ├── fib.urcl │ ├── game.urcl │ ├── gamepad.urcl │ ├── line.urcl │ ├── pallet-test.urcl │ ├── prime-sieve16.urcl │ ├── prime-sieve32.urcl │ ├── snake.urcl │ ├── snakeds.urcl │ ├── sprites.urcl │ ├── storage.urcl │ ├── tests.urcl │ └── text-io.urcl ├── img └── favicon.png ├── index.css ├── index.html ├── index.ts ├── js ├── editor │ ├── editor.js │ ├── editor.js.map │ ├── tokenizer.js │ └── tokenizer.js.map ├── emulator │ ├── breaks.js │ ├── breaks.js.map │ ├── compiler.js │ ├── compiler.js.map │ ├── devices │ │ ├── CHUNGUS devices │ │ │ ├── amogus.js │ │ │ ├── blockRAM.js │ │ │ ├── blockToMesh.js │ │ │ ├── craftingRom.js │ │ │ ├── playerInput.js │ │ │ └── screen.js │ │ ├── clock.js │ │ ├── clock.js.map │ │ ├── console-io.js │ │ ├── console-io.js.map │ │ ├── device.js │ │ ├── device.js.map │ │ ├── display.js │ │ ├── display.js.map │ │ ├── gamepad.js │ │ ├── gamepad.js.map │ │ ├── gl-display.js │ │ ├── gl-display.js.map │ │ ├── keyboard.js │ │ ├── keyboard.js.map │ │ ├── rng.js │ │ ├── rng.js.map │ │ ├── sound.js │ │ ├── sound.js.map │ │ ├── storage.js │ │ └── storage.js.map │ ├── emulator.js │ ├── emulator.js.map │ ├── instructions.js │ ├── instructions.js.map │ ├── parser.js │ ├── parser.js.map │ ├── preprocessor.js │ ├── preprocessor.js.map │ ├── util.js │ └── util.js.map ├── index.js ├── index.js.map ├── node │ ├── args.js │ ├── args.js.map │ ├── bots │ │ ├── bot-emu.js │ │ └── bot-emu.js.map │ ├── exec.js │ ├── exec.js.map │ ├── urcx-bot.js │ ├── urcx-bot.js.map │ ├── urcx-emu.js │ └── urcx-emu.js.map ├── scroll-out │ ├── scroll-out.js │ └── scroll-out.js.map └── webgl │ ├── shader.js │ └── shader.js.map ├── libs └── urclpp │ └── f32 │ ├── notes.txt │ └── to_int.urcl ├── node ├── args.ts ├── bots │ └── bot-emu.ts ├── exec.ts ├── urcx-bot.ts └── urcx-emu.ts ├── package.json ├── run.cmd ├── scroll-out ├── scoll-out.css └── scroll-out.ts ├── server.py ├── tsconfig.json ├── unscii-16.ttf ├── unscii-16.woff ├── watch.cmd ├── webgl └── shader.ts └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | *__pycache__/ -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # minecraft 2 | Minecraft 3 | -------------------------------------------------------------------------------- /assembler/assembler.py: -------------------------------------------------------------------------------- 1 | from .formats import Instruction 2 | 3 | from .preprocessor.preprocess import preprocess 4 | from .translator.translate import translate 5 | 6 | 7 | def assemble(lines: list[Instruction]) -> list[str]: 8 | """Assemble assembly source code to machine code""" 9 | 10 | lines = preprocess(lines) 11 | lines = translate(lines) 12 | return lines 13 | -------------------------------------------------------------------------------- /assembler/preprocessor/comments.py: -------------------------------------------------------------------------------- 1 | from ..formats import Instruction 2 | 3 | 4 | def remove_comments(lines: list[Instruction]) -> list[Instruction]: 5 | """Remove comments and empty lines""" 6 | 7 | result = [] 8 | for instr in lines: 9 | # Remove comments 10 | if "//" in instr.text: 11 | instr = Instruction( 12 | instr.text[:instr.text.index("//")].strip(), 13 | instr.linenum, 14 | ) 15 | if ";" in instr.text: 16 | instr = Instruction( 17 | instr.text[:instr.text.index(";")].strip(), 18 | instr.linenum, 19 | ) 20 | # Ignore blank lines 21 | if instr.text.strip(): 22 | result.append(Instruction( 23 | instr.text.strip(), 24 | instr.linenum, 25 | )) 26 | return result 27 | -------------------------------------------------------------------------------- /assembler/preprocessor/labels.py: -------------------------------------------------------------------------------- 1 | from ..formats import Instruction 2 | 3 | 4 | def parse_labels(lines: list[Instruction]) -> list[Instruction]: 5 | """Parse labels into jump addresses""" 6 | 7 | labels = {} 8 | index = 0 9 | # Find all labels and their line numbers 10 | while index < len(lines): 11 | if lines[index].is_label(): 12 | # Add to label dict and remove from lines 13 | labels[lines[index].text] = str(index % 2048) 14 | lines.pop(index) 15 | else: 16 | index += 1 17 | 18 | # Convert labels to immediates 19 | resultlines = [] 20 | for instr in lines: 21 | mnemonic, operands = instr.get_mnemonic_and_operands() 22 | # Parse labels 23 | operands = [labels.get(operand, operand) for operand in operands] 24 | # Turn back into assembly instruction 25 | resultlines.append(Instruction( 26 | (mnemonic + " " + ", ".join(operands)).strip(), 27 | instr.linenum, 28 | )) 29 | 30 | return resultlines 31 | -------------------------------------------------------------------------------- /assembler/preprocessor/pager.py: -------------------------------------------------------------------------------- 1 | from ..formats import Instruction, AssemblerError 2 | 3 | 4 | def parse_labelled_pages(lines: list[Instruction]) -> list[Instruction]: 5 | """Add NOPs between labelled pages to fix size at 64 instructions""" 6 | 7 | # (To prevent 64 NOPs at the start of program) 8 | if lines[0].text[0:5] == ".PAGE": 9 | lines.pop(0) 10 | 11 | instructioncount = 0 12 | pagecount = 0 13 | resultlines = [] 14 | for instr in lines: 15 | # If a new page is found and the last one is not full, fill with NOPs 16 | # (which assemble to 00000000 00000000) 17 | if instr.text[0:5] == ".PAGE": 18 | # Raise an error if page size is larger than 64 19 | if instructioncount > 64: 20 | raise AssemblerError( 21 | f"Page {pagecount} too large, contains {instructioncount} \ 22 | instructions (max 64 allowed)" 23 | ) from None 24 | 25 | resultlines.extend([ 26 | Instruction("NOP", instructioncount) # Placeholder line number 27 | for i in range(64 - instructioncount) 28 | ]) 29 | instructioncount = 0 30 | pagecount += 1 31 | 32 | elif instr.text[0:5] == ".BANK": 33 | if instructioncount > 64: 34 | raise AssemblerError( 35 | f"Page {pagecount} too large, contains {instructioncount} \ 36 | instructions (max 64 allowed)" 37 | ) from None 38 | 39 | resultlines.extend([ 40 | Instruction("NOP", instructioncount) # Placeholder line number 41 | for i in range(64 - instructioncount) 42 | ]) 43 | instructioncount = 0 44 | pagecount += 1 45 | while pagecount < 32: 46 | pagecount += 1 47 | resultlines.extend([ 48 | Instruction("NOP", instructioncount) # Placeholder line number 49 | for i in range(64) 50 | ]) 51 | 52 | # Otherwise, add to resultlines 53 | else: 54 | resultlines.append(instr) 55 | # Ignore labels in instruction count 56 | if not instr.is_label(): 57 | instructioncount += 1 58 | 59 | # Raise an error if last page size is larger than 64 60 | if instructioncount > 64: 61 | raise AssemblerError( 62 | f"Page {pagecount} too large, contains {instructioncount} \ 63 | instructions (max 64 allowed)" 64 | ) from None 65 | 66 | return resultlines 67 | 68 | 69 | def parse_pages(lines: list[Instruction]) -> list[Instruction]: 70 | """Split a list of instructions into pages of size 64 instructions each""" 71 | 72 | # TODO: add algorithm to automatically generate pages from long code 73 | return parse_labelled_pages(lines) 74 | -------------------------------------------------------------------------------- /assembler/preprocessor/preprocess.py: -------------------------------------------------------------------------------- 1 | from .comments import remove_comments 2 | from .macros import apply_macros 3 | from .pager import parse_pages 4 | from .labels import parse_labels 5 | from .relatives import parse_relatives 6 | 7 | from ..formats import Instruction 8 | 9 | 10 | def preprocess(lines: list[Instruction]) -> list[Instruction]: 11 | 12 | """ 13 | Preprocess a list of instructions 14 | 15 | Removes comments and empty lines, applies macros, replaces relatives with labels, 16 | splits into pages of 64 instructions, and parses labels, 17 | resulting in a list of assembly instructions only. 18 | """ 19 | 20 | lines = remove_comments(lines) 21 | lines = apply_macros(lines) 22 | lines = parse_relatives(lines) 23 | lines = parse_pages(lines) 24 | lines = parse_labels(lines) 25 | return lines 26 | -------------------------------------------------------------------------------- /assembler/preprocessor/relatives.py: -------------------------------------------------------------------------------- 1 | from ..formats import Instruction 2 | import numpy 3 | 4 | 5 | def parse_relatives(lines: list[Instruction]) -> list[Instruction]: 6 | """find all of the relative addresses and replace them with labels""" 7 | 8 | relativeLabelPrefix = ".assemblerRelativeLabel" 9 | 10 | for line in lines: # scan through program to see if it contains the default relative label prefix. 11 | if line.is_label(): 12 | if line.text[0:len(relativeLabelPrefix)] == relativeLabelPrefix: 13 | relativeLabelPrefix = line.text # if it does, set the prefix to it. That will ensure that the labels are all unique. 14 | 15 | resultLines = [] 16 | newLabels = [] 17 | for index in range(len(lines)): 18 | mnemonic, operands = lines[index].get_mnemonic_and_operands() #extract operand data 19 | newOperands = [] 20 | for operand in operands: 21 | if is_relative(operand): 22 | relative = int(operand[1:]) # isolate the relative position from the relative operand 23 | i, j = 0, 0 24 | dir = numpy.sign(relative) # check which direction to search in 25 | while i != relative: # search for correct location to insert label, ignoring preexisting lables 26 | if lines[index + i + j].is_label(): 27 | j += dir 28 | else: 29 | i += dir 30 | label = relativeLabelPrefix + str(len(newLabels)) # generate a unique name for the new label 31 | newLabels.append(Instruction(label, index + i + j)) # save new label to insert later so this loop doesn't get messed up 32 | newOperands.append(label) # replace relative operand with label 33 | else: 34 | newOperands.append(operand) # any non-relative operands are unchanged, 35 | resultLines.append(Instruction( 36 | (mnemonic + " " + ", ".join(newOperands)).strip(), 37 | index, 38 | )) 39 | 40 | newLabels.sort(reverse = True, key = sort_by_line_num) #sort the list of new labels to start at the end of the program and work backwards 41 | for lable in newLabels: 42 | resultLines.insert(lable.linenum, lable) # now that the loop is done, it's safe to insert the sorted labels 43 | 44 | return resultLines 45 | 46 | 47 | def is_relative(operand) -> bool: 48 | return operand[:1] == "~" 49 | 50 | def sort_by_line_num(e: Instruction) -> int: 51 | return e.linenum 52 | -------------------------------------------------------------------------------- /assembler/test.s: -------------------------------------------------------------------------------- 1 | HLT -------------------------------------------------------------------------------- /assembler/test.schem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sammyuri/minecraft/976e84d3dc8142dd4cf8927036d0d5e54b79152e/assembler/test.schem -------------------------------------------------------------------------------- /assembler/translator/translate.py: -------------------------------------------------------------------------------- 1 | from .parseline import parse_line 2 | 3 | from ..formats import Instruction, AssemblerError 4 | 5 | 6 | def translate(lines: list[Instruction]) -> list[str]: 7 | """Translate a list of assembly instructions to machine code""" 8 | 9 | result = [] 10 | for instr in lines: 11 | try: 12 | machinecode = parse_line(instr) 13 | except AssemblerError as error: 14 | # Add line number (from original source code) to error 15 | raise AssemblerError( 16 | f"Error on line {instr.linenum} ({instr.text}): {error}" 17 | ) from None 18 | else: 19 | result.append(machinecode) 20 | 21 | return result 22 | -------------------------------------------------------------------------------- /chasm_scripts/ports.s: -------------------------------------------------------------------------------- 1 | @DEFINE %craftrom 0 2 | 3 | @DEFINE %rng 1 4 | 5 | @DEFINE %playerinput 2 6 | @DEFINE %switchbanks 3 7 | 8 | @DEFINE %blockram_x 4 9 | @DEFINE %blockram_oobactive 4 10 | @DEFINE %blockram_y 5 11 | @DEFINE %blockram_oobinactive 5 12 | @DEFINE %blockram_z 6 13 | @DEFINE %blockram_id 7 14 | 15 | @DEFINE %meshgen_blockxz 8 16 | @DEFINE %meshgen_blocky 9 17 | @DEFINE %meshgen_itemxz 10 18 | @DEFINE %meshgen_itemy 11 19 | @DEFINE %meshgen_breakphase 12 20 | @DEFINE %meshgen_renderface 12 21 | @DEFINE %meshgen_itemid 13 22 | @DEFINE %meshgen_renderitem 13 23 | @DEFINE %meshgen_direction 14 24 | @DEFINE %meshgen_renderoverlay 14 25 | @DEFINE %meshgen_settings 15 26 | @DEFINE %meshgen_renderscene 15 27 | 28 | @DEFINE %amogus_camx 16 29 | @DEFINE %amogus_camdirx 16 30 | @DEFINE %amogus_camy 17 31 | @DEFINE %amogus_camdiry 17 32 | @DEFINE %amogus_camz 18 33 | @DEFINE %amogus_camdirz 18 34 | @DEFINE %amogus_vertx 19 35 | @DEFINE %amogus_cosyaw 19 36 | @DEFINE %amogus_verty 20 37 | @DEFINE %amogus_sinyaw 20 38 | @DEFINE %amogus_vertz 21 39 | @DEFINE %amogus_vertuv 22 40 | @DEFINE %amogus_camrot 24 41 | @DEFINE %amogus_tex 25 42 | @DEFINE %amogus_settings 26 43 | @DEFINE %amogus_drawtoscreen 28 44 | @DEFINE %amogus_submitvert 29 45 | @DEFINE %amogus_drawquad 30 46 | @DEFINE %amogus_clearbuffer 31 47 | 48 | @DEFINE %screen_nop 32 49 | @DEFINE %screen_x1 33 50 | @DEFINE %screen_y1 34 51 | @DEFINE %screen_x2 35 52 | @DEFINE %screen_y2 36 53 | @DEFINE %screen_drawrect 37 54 | @DEFINE %screen_x1_drawrect 38 55 | @DEFINE %screen_y1_drawrect 39 56 | @DEFINE %screen_x2_drawrect 40 57 | @DEFINE %screen_y2_drawrect 41 58 | @DEFINE %screen_clearrect 42 59 | @DEFINE %screen_x1_clearrect 43 60 | @DEFINE %screen_y1_clearrect 44 61 | @DEFINE %screen_x2_clearrect 45 62 | @DEFINE %screen_y2_clearrect 46 63 | @DEFINE %screen_drawtex 47 64 | @DEFINE %screen_x1_drawtex 48 65 | @DEFINE %screen_y1_drawtex 49 66 | @DEFINE %screen_drawinvtex 50 67 | @DEFINE %screen_x1_drawinvtex 51 68 | @DEFINE %screen_y1_drawinvtex 52 69 | @DEFINE %screen_texid 53 70 | @DEFINE %screen_texid_drawtex 54 71 | @DEFINE %screen_texid_drawinvtex 55 72 | @DEFINE %screen_clearscreen 56 73 | @DEFINE %screen_buffer 57 -------------------------------------------------------------------------------- /emulator/instruction.py: -------------------------------------------------------------------------------- 1 | from enum import Enum, auto 2 | 3 | 4 | class CPUError(Exception): 5 | pass 6 | 7 | 8 | class Opcodes(Enum): 9 | NOP = 0 10 | HLT = 1 11 | STS = 2 12 | CLI = 3 13 | JMP = 4 14 | CAL = 5 15 | RET = 6 16 | BRH = 7 17 | 18 | POI = 8 19 | SLD = 9 20 | PST = 10 21 | PLD = 11 22 | PSH = 12 23 | POP = 13 24 | MST = 14 25 | MLD = 15 26 | 27 | LIM = 16 28 | AIM = 17 29 | CMP = 18 30 | CMA = 19 31 | MOV = 20 32 | ADD = 21 33 | SUB = 22 34 | ADI = 23 35 | BIT = 24 36 | BNT = 25 37 | SHF = 26 38 | SFI = 27 39 | MUL = 28 40 | UDA = 29 41 | UDB = 30 42 | BCT = 31 43 | 44 | 45 | class MCInstruction: 46 | """A machine code instruction""" 47 | def __init__(self, binary: str) -> None: 48 | # Get opcode and operands 49 | self.opcode = Opcodes(int(binary[0:5], 2)) 50 | self.a = int(binary[5:8], 2) 51 | self.b = int(binary[9:12], 2) 52 | self.type = int(binary[12:14], 2) 53 | self.c = int(binary[14:17], 2) 54 | 55 | # Get immediate (if needed) 56 | self.immediate = 0 57 | 58 | if self.opcode in ( # 11-bit immediate 59 | Opcodes.JMP, Opcodes.CAL 60 | ): 61 | self.immediate = 256 * self.a + int(binary[9:17], 2) 62 | 63 | if self.opcode in ( # 8-bit immediate 64 | Opcodes.STS, Opcodes.PST, Opcodes.PLD, Opcodes.MST, Opcodes.MLD, 65 | Opcodes.LIM, Opcodes.AIM, Opcodes.CMP, Opcodes.CMA 66 | ): 67 | self.immediate = int(binary[9:17], 2) 68 | 69 | if self.opcode in ( # 6-bit immediate 70 | Opcodes.BRH, Opcodes.PSH, Opcodes.POP 71 | ): 72 | self.immediate = int(binary[11:17], 2) 73 | 74 | if self.opcode in ( # 5-bit signed immediate 75 | Opcodes.CLI, Opcodes.ADI 76 | ): 77 | self.immediate = (int(binary[12:17], 2) ^ 16) - 16 78 | 79 | if self.opcode in ( # 3-bit immediate 80 | Opcodes.SFI, Opcodes.BCT 81 | ): 82 | self.immediate = self.c 83 | 84 | # Get other control bits (if needed) 85 | if self.opcode == Opcodes.BRH: 86 | self.type = int(binary[9], 2) 87 | if self.opcode == Opcodes.POI: 88 | self.type = int(binary[7], 2) 89 | if self.opcode in (Opcodes.PSH, Opcodes.POP): 90 | self.type = int(binary[9:11], 2) 91 | -------------------------------------------------------------------------------- /emulator/peripherals/base.py: -------------------------------------------------------------------------------- 1 | class Peripheral: 2 | """A basic peripheral""" 3 | def __init__(self, port: int, portrange: int = 1) -> None: 4 | self.port = port 5 | self.portrange = portrange 6 | 7 | def receive(self, data: int, port: int) -> None: 8 | """Receive a byte from the CPU""" 9 | print(f"{port}: {data}") 10 | 11 | def send(self, port: int) -> int: 12 | """Send a byte to the CPU""" 13 | return 0 14 | -------------------------------------------------------------------------------- /emulator/peripherals/peripherals2-electricBoogaloo/craftRom.py: -------------------------------------------------------------------------------- 1 | from base import Peripheral 2 | from ports import IO_Port 3 | from enum import Enum 4 | 5 | class Station(Enum): 6 | table = 0xFD 7 | furnace = 0xFE 8 | 9 | class Ingredient(Enum): 10 | air = 0x0 11 | stick = 0x1 12 | dirt = 0x2 13 | stone = 0x3 14 | cobble = 0x4 15 | log = 0x5 16 | leaves = 0x6 17 | plank = 0x7 18 | coal = 0x8 19 | ironOre = 0x9 20 | sand = 0xA 21 | glass = 0xB 22 | sapling = 0xC 23 | ironIngot = 0xD 24 | apple = 0xE 25 | nonstackable = 0xF 26 | 27 | class Result(Enum): 28 | stone = 0x31 29 | plank = 0x74 30 | table = 0xFD 31 | coal = 0x81 32 | furnace = 0xFE 33 | ironIngot = 0xD1 34 | stick = 0x14 35 | chest = 0xFF 36 | woodPick = 0xF0 37 | woodAxe = 0x1F1 38 | woodShovel = 0xF2 39 | woodSword = 0xF3 40 | stonePick = 0xF4 41 | stoneAxe = 0xF5 42 | stoneShovel = 0xF6 43 | stoneSword = 0xF7 44 | ironPick = 0xF8 45 | ironAxe = 0xF9 46 | ironShovel = 0xFA 47 | ironSword = 0xFB 48 | shears = 0xFC 49 | 50 | RECIPES = { 51 | #smelting recipes 52 | ["4"]: Result.stone, 53 | ["5"]: Result.coal, 54 | ["9"]: Result.ironIngot, 55 | 56 | #crafting recipes 57 | ["770770000"]: Result.table, 58 | ["500000000"]: Result.plank, 59 | ["444404444"]: Result.furnace, 60 | ["777707777"]: Result.chest, 61 | ["700700000"]: Result.stick, 62 | 63 | ["777010010"]: Result.woodPick, 64 | ["444010010"]: Result.stonePick, 65 | ["DDD010010"]: Result.ironPick, 66 | 67 | ["770710010"]: Result.woodAxe, 68 | ["440410010"]: Result.stoneAxe, 69 | ["DD0D10010"]: Result.ironAxe, 70 | 71 | ["700100100"]: Result.woodShovel, 72 | ["400100100"]: Result.stoneShovel, 73 | ["D00100100"]: Result.ironShovel, 74 | 75 | ["700700100"]: Result.woodSword, 76 | ["400400100"]: Result.stoneSword, 77 | ["D00D00100"]: Result.ironSword, 78 | 79 | ["0D0D00000"]: Result.shears, 80 | } 81 | 82 | class craftRom(Peripheral): 83 | station = Station.table 84 | currentRecipe = "000000000" #36 bits > 32 bits, so use a string instead of an int 85 | 86 | def receive(self, data: int, port: IO_Port) -> None: 87 | if (port == IO_Port.CRAFTROM): 88 | if (data == Station.table): 89 | self.station = data 90 | elif (data == Station.furnace): 91 | self.station = data 92 | else: 93 | self.currentRecipe = self.currentRecipe[1:] + hex(data >> 4) #simulate a shift register 94 | 95 | def send(self, port: IO_Port) -> int: 96 | if (port == IO_Port.CRAFTROM): 97 | if (self.station == Station.table): 98 | while (True): #shift the recipe as far left in the crafting grid as it will go 99 | if (self.currentRecipe[0] + self.currentRecipe[3] + self.currentRecipe[6] == "000"): 100 | self.currentRecipe = self.currentRecipe[1:] + "0" 101 | else: 102 | break 103 | while (True): #shift the recipe as far up in the crafting grid as it will go 104 | if (self.currentRecipe[0:3] == "000"): 105 | self.currentRecipe = self.currentRecipe[3:] + "000" 106 | else: 107 | break 108 | return RECIPES[self.currentRecipe.upper()] 109 | elif (self.station == Station.furnace): 110 | return RECIPES[self.currentRecipe[8].upper()] -------------------------------------------------------------------------------- /emulator/peripherals/peripherals2-electricBoogaloo/playerInput.py: -------------------------------------------------------------------------------- 1 | #TODO: translate this from TypeScript -------------------------------------------------------------------------------- /emulator/peripherals/peripherals2-electricBoogaloo/screen.py: -------------------------------------------------------------------------------- 1 | from base import Peripheral 2 | from emulator.peripherals.minecraftdisplay import SCREEN_WIDTH 3 | from ports import IO_Port 4 | 5 | import tkinter as tk 6 | 7 | SCREEN_WIDTH = 96 8 | SCREEN_HEIGHT = 64 9 | SCALE = 8 10 | COLOUR = "yellow" 11 | 12 | class Screen(Peripheral): 13 | def __init__(self, port, portrange): 14 | super().__init__(port, portrange) 15 | 16 | self.root = tk.Tk("Minecraft in Minecraft") 17 | self.root.geometry( 18 | str(SCREEN_WIDTH * SCALE) 19 | + "x" 20 | + str(SCREEN_HEIGHT * SCALE) 21 | ) 22 | 23 | self.screen = tk.Canvas( 24 | self.root, 25 | width = SCREEN_WIDTH * SCALE, 26 | height = SCREEN_HEIGHT * SCALE 27 | ) 28 | self.screen.configure( 29 | bg="#000000", 30 | ) 31 | self.screen.pack() -------------------------------------------------------------------------------- /emulator/peripherals/textures.py: -------------------------------------------------------------------------------- 1 | BASETEXTURES = [ 2 | [ 3 | "11000001", # bedrock 4 | "00011100", 5 | "00000000", 6 | "01100001", 7 | "00111000", 8 | "00100000", 9 | "01110110", 10 | "00000001", 11 | ], 12 | [ 13 | "11111111", # grass side 14 | "10111110", 15 | "00001000", 16 | "01000000", 17 | "00000000", 18 | "00000000", 19 | "00001000", 20 | "00000000", 21 | ], 22 | [ 23 | "00000000", # dirt 24 | "00000010", 25 | "00000000", 26 | "01000000", 27 | "00000000", 28 | "00000000", 29 | "00001000", 30 | "00000000", 31 | ], 32 | # [ 33 | # "00111110", # stone 34 | # "11100011", 35 | # "11111111", 36 | # "10011110", 37 | # "11000111", 38 | # "11011111", 39 | # "10001001", 40 | # "11111110", 41 | # ], 42 | [ 43 | "01001011", # cobble 44 | "10000100", 45 | "10000100", 46 | "01011000", 47 | "11100101", 48 | "01000010", 49 | "00100010", 50 | "00110001", 51 | ], 52 | # [ 53 | # "00100010", # log 54 | # "01000100", 55 | # "01000100", 56 | # "01000100", 57 | # "01000100", 58 | # "00100100", 59 | # "00100010", 60 | # "00100010", 61 | # ], 62 | [ 63 | "10101010", # log 64 | "01010101", 65 | "10101010", 66 | "01010101", 67 | "10101010", 68 | "01010101", 69 | "10101010", 70 | "01010101", 71 | ], 72 | [ 73 | "11110011", # leaf 74 | "01110111", 75 | "10100111", 76 | "11000010", 77 | "00011100", 78 | "11001110", 79 | "01101111", 80 | "11110111", 81 | ], 82 | [ 83 | "11101111", # planks 84 | "11101111", 85 | "11101111", 86 | "00000000", 87 | "11111110", 88 | "11111110", 89 | "11111110", 90 | "00000000", 91 | ], 92 | [ 93 | "01011010", # crafting table 94 | "01100110", 95 | "01111110", 96 | "01010010", 97 | "01010010", 98 | "01011010", 99 | "01011010", 100 | "01111110", 101 | ], 102 | [ 103 | "11111111", # grass top 104 | "11111111", 105 | "11111111", 106 | "11111111", 107 | "11111111", 108 | "11111111", 109 | "11111111", 110 | "11111111", 111 | ], 112 | [ 113 | "00000000", # log top 114 | "01111110", 115 | "01000010", 116 | "01011010", 117 | "01011010", 118 | "01000010", 119 | "01111110", 120 | "00000000", 121 | ], 122 | [ 123 | "00111100", # crafting top 124 | "01111110", 125 | "11000011", 126 | "11010011", 127 | "11001011", 128 | "11000011", 129 | "01111110", 130 | "00111100", 131 | ], 132 | [ 133 | "10101010", # checkerboard 134 | "01010101", 135 | "10101010", 136 | "01010101", 137 | "10101010", 138 | "01010101", 139 | "10101010", 140 | "01010101", 141 | ] 142 | ] 143 | 144 | textures = [] 145 | for texture in BASETEXTURES: 146 | textures.append([]) 147 | for row in texture: 148 | for i in row: 149 | textures[-1].append(int(i)) -------------------------------------------------------------------------------- /emulator/peripherals/trianglerom.py: -------------------------------------------------------------------------------- 1 | from .base import Peripheral 2 | 3 | 4 | class DirectionROM(Peripheral): 5 | def __init__(self, *args, **kwargs): 6 | super().__init__(*args, **kwargs) 7 | 8 | self.values = [ 9 | (2, 0), 10 | (2, 1), 11 | (2, 2), 12 | (1, 2), 13 | (0, 2), 14 | (-1, 2), 15 | (-2, 2), 16 | (-2, 1), 17 | (-2, 0), 18 | (-2, -1), 19 | (-2, -2), 20 | (-1, -2), 21 | (0, -2), 22 | (1, -2), 23 | (2, -2), 24 | (2, -1), 25 | ] 26 | 27 | def send(self, port: int) -> int: 28 | dir = (port) % 16 29 | return (self.values[dir][0] & 15) << 4 | (self.values[dir][1] & 15) 30 | 31 | 32 | class TriangleROM(Peripheral): 33 | def __init__(self, *args, **kwargs): 34 | super().__init__(*args, **kwargs) 35 | 36 | self.values = [ 37 | 0b00100, 0b11010, 0b10110, 38 | 0b00100, 0b01000, 0b11010, 39 | 40 | 0b00001, 0b11111, 0b10011, 41 | 0b00001, 0b01101, 0b11111, 42 | 43 | 0b00000, 0b11011, 0b10010, 44 | 0b00000, 0b01001, 0b11011, 45 | 46 | 0b00101, 0b11110, 0b10111, 47 | 0b00101, 0b01100, 0b11110, 48 | 49 | 0b00000, 0b11101, 0b01001, 50 | 0b00000, 0b10100, 0b11101, 51 | 52 | 0b00110, 0b11011, 0b01111, 53 | 0b00110, 0b10010, 0b11011, 54 | ] 55 | 56 | def send(self, port: int) -> int: 57 | return self.values[port - 128] -------------------------------------------------------------------------------- /emulator/ports.py: -------------------------------------------------------------------------------- 1 | from .peripherals.base import Peripheral 2 | from .peripherals.minecraftdisplay import MinecraftDisplay 3 | from .peripherals.trianglerom import TriangleROM, DirectionROM 4 | 5 | from .emulator import CPUError 6 | 7 | from enum import Enum 8 | 9 | 10 | class Ports: 11 | """IO ports for the CHUNGUS2""" 12 | def __init__(self) -> None: 13 | self.ports = [Peripheral(i) for i in range(256)] 14 | 15 | self.mcdisplay = MinecraftDisplay(64, 32) 16 | for port in range(64, 95): 17 | self.ports[port] = self.mcdisplay 18 | self.trianglerom = TriangleROM(128, 36) 19 | for port in range(128, 128+36): 20 | self.ports[port] = self.trianglerom 21 | self.directionrom = DirectionROM(32, 16) 22 | for port in range(32, 32+16): 23 | self.ports[port] = self.directionrom 24 | 25 | def add_peripheral(self, peri: Peripheral) -> None: 26 | """Add a peripheral""" 27 | for port in range(peri.port, peri.port + peri.portrange): 28 | self.ports[port] = peri 29 | 30 | def port_load(self, port: int) -> int: 31 | """Load from a peripheral""" 32 | return self.ports[port].send(port) 33 | 34 | def port_store(self, port: int, value: int) -> None: 35 | """Output to a peripheral""" 36 | self.ports[port].receive(value, port) 37 | 38 | 39 | class IO_Port(Enum): 40 | CRAFTROM = 0 41 | 42 | RNG = 1 43 | 44 | PLAYERINPUT = 2 45 | 46 | BLOCKRAM_XY = 4 47 | BLOCKRAM_Z = 5 48 | BLOCKRAM_ID = 6 49 | BLOCKRAM_ZI = 7 50 | 51 | MESHGEN_BLOCKXY = 8 52 | MESHGEN_BLOCKZ = 9 53 | MESHGEN_BREAKPHASE = 10 54 | MESHGEN_ITEMXZ = 11 55 | MESHGEN_ITEMY = 12; MESHGEN_RENDERFACE = 12 56 | MESHGEN_ITEMID = 13; MESHGEN_RENDERITEM = 13 57 | MESHGEN_TEX = 14; MESHGEN_RENDEROVERLAY = 14 58 | MESHGEN_SETTINGS = 15; MESHGEN_RENDERSCENE = 15 59 | 60 | AMOGUS_CAMX = 16; AMOGUS_CAMDIRX = 16 61 | AMOGUS_CAMY = 17; AMOGUS_CAMDIRY = 17 62 | AMOGUS_CAMZ = 18; AMOGUS_CAMDIRZ = 18 63 | AMOGUS_VERTX = 19; AMOGUS_COSYAW = 19 64 | AMOGUS_VERTY = 20; AMOGUS_SINYAW = 20 65 | AMOGUS_VERTZ = 21 66 | AMOGUS_VERTUV = 22 67 | AMOGUS_CAMROT = 24 68 | AMOGUS_TEX = 25 69 | AMOGUS_SETTINGS = 26 70 | AMOGUS_DRAWTOSCREEN = 28 71 | AMOGUS_SUBMITVERT = 29 72 | AMOGUS_DRAWQUAD = 30 73 | AMOGUS_CLEARBUFFER = 31 74 | 75 | SCREEN_NOP = 32 76 | SCREEN_X1 = 33 77 | SCREEN_Y1 = 34 78 | SCREEN_X2 = 35 79 | SCREEN_Y2 = 36 80 | SCREEN_DRAWRECT = 37 81 | SCREEN_X1_DRAWRECT = 38 82 | SCREEN_Y1_DRAWRECT = 39 83 | SCREEN_X2_DRAWRECT = 40 84 | SCREEN_Y2_DRAWRECT = 41 85 | SCREEN_CLEARRECT = 42 86 | SCREEN_X1_CLEARRECT = 43 87 | SCREEN_Y1_CLEARRECT = 44 88 | SCREEN_X2_CLEARRECT = 45 89 | SCREEN_Y2_CLEARRECT = 46 90 | SCREEN_DRAWTEX = 47 91 | SCREEN_X1_DRAWTEX = 48 92 | SCREEN_Y1_DRAWTEX = 49 93 | SCREEN_DRAWINVTEX = 50 94 | SCREEN_X1_DRAWINVTEX = 51 95 | SCREEN_Y1_DRAWINVTEX = 52 96 | SCREEN_TEXID = 53 97 | SCREEN_TEXID_DRAWTEX = 54 98 | SCREEN_TEXID_DRAWINVTEX = 55 99 | SCREEN_CLEARSCREEN = 56 100 | SCREEN_BUFFER = 57 -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | from minecraft.combine import get_assembly, get_world 2 | from assembler.preprocessor import preprocess 3 | from assembler.translator import translate 4 | from assembler.formats import Instruction 5 | from emulator.emulator import Chungus2 6 | from schemgenerator.schem import generate_schematic 7 | 8 | import time 9 | 10 | 11 | if __name__ == "__main__": 12 | lines = [] 13 | with open("chasm_scripts/ports.s", "r") as f: 14 | for line in f: 15 | lines.append(line.strip()) 16 | with open("chasm_scripts/constants.s", "r") as f: 17 | for line in f: 18 | lines.append(line.strip()) 19 | with open("chasm_scripts/bank1.s", "r") as f: 20 | for line in f: 21 | lines.append(line.strip()) 22 | with open("chasm_scripts/bank2.s", "r") as f: 23 | for line in f: 24 | lines.append(line.strip()) 25 | lines = [Instruction(line, index) for index, line in enumerate(lines)] 26 | lines = preprocess.preprocess(lines) 27 | #print([e.text for e in lines]) 28 | if True: 29 | lines = lines[0:2048] # bank 1 30 | lines = translate.translate(lines) 31 | generate_schematic(lines, "bank1") 32 | else: 33 | lines = lines[2048:] # bank 2 34 | lines = translate.translate(lines) 35 | generate_schematic(lines, "bank2") 36 | # chungus = Chungus2(lines) 37 | # chungus.set_ram(get_world()) 38 | # print(chungus.run_program(100000000)) 39 | # time.sleep(100) -------------------------------------------------------------------------------- /minecraft/combine.py: -------------------------------------------------------------------------------- 1 | from os import path 2 | 3 | 4 | ORDER = [ 5 | "textures.s", 6 | "ports.s", 7 | "memory.s", 8 | "main.s", 9 | "gameLoop.s", 10 | "blockToMesh.s", 11 | ] 12 | 13 | 14 | def get_assembly() -> list[str]: 15 | assembly = [] 16 | for filename in ORDER: 17 | with open(path.join(path.dirname(__file__), filename), "r") as f: 18 | for line in f: 19 | assembly.append(line.strip()) 20 | return assembly 21 | 22 | def get_world() -> list[int]: 23 | world = [] 24 | with open( 25 | path.join( 26 | path.join( 27 | path.dirname(__file__), "world"), 28 | "world.txt" 29 | ), 30 | "r" 31 | ) as f: 32 | for line in f: 33 | try: 34 | world.append(int(line.strip())) 35 | except ValueError: 36 | print(line) 37 | return world 38 | -------------------------------------------------------------------------------- /minecraft/gameloop.s: -------------------------------------------------------------------------------- 1 | .PAGE 2 | 3 | .runGame 4 | lim r0, 38 ; store starting values for player 5 | mst r0, playerx 6 | lim r0, 27 7 | mst r0, playery 8 | lim r0, 12 9 | mst r0, playerz 10 | mst r0, camx 11 | mst r0, camy 12 | 13 | .gameLoop 14 | pld r1, 64 15 | pst r0, 68 16 | cmp r1, 5 ; move 17 | brt grtreq, .skipMove 18 | mld r2, camx ; get direction data 19 | bsli r1, r1, 2 20 | add r2, r2, r1 21 | aim r2, 15 22 | poi r2 23 | pld r1, %direction 24 | 25 | mld r2, playerx 26 | sxtsri r3, r1, 4 27 | add r3, r3, r2 28 | mst r3, playerx 29 | pst r3, %camx 30 | 31 | mld r2, playerz 32 | bsli r3, r1, 4 33 | sxtsri r3, r3, 4 34 | add r3, r3, r2 35 | mst r3, playerz 36 | pst r3, %camz 37 | 38 | .skipMove 39 | cmp r1, 5 40 | brt nequal, .skipTurnUp 41 | mld r1, camy 42 | adi r1, r1, 1 43 | aim r1, 15 44 | mst r1, camy 45 | pst r1, %yrotation 46 | .skipTurnUp 47 | cmp r1, 6 48 | brt nequal, .skipTurnDown 49 | mld r1, camy 50 | adi r1, r1, -1 51 | aim r1, 15 52 | mst r1, camy 53 | pst r1, %yrotation 54 | .skipTurnDown 55 | cmp r1, 7 56 | brt nequal, .skipTurnLeft 57 | mld r1, camx 58 | adi r1, r1, 1 59 | aim r1, 15 60 | mst r1, camx 61 | pst r1, %xrotation 62 | .skipTurnLeft 63 | cmp r1, 8 64 | brt nequal, .skipTurnRight 65 | mld r1, camx 66 | adi r1, r1, -1 67 | aim r1, 15 68 | mst r1, camx 69 | pst r1, %xrotation 70 | .skipTurnRight 71 | 72 | cal .renderFullMesh 73 | pst r0, 69 74 | jmp .gameLoop 75 | 76 | 77 | ret -------------------------------------------------------------------------------- /minecraft/main.s: -------------------------------------------------------------------------------- 1 | cal .renderFullMesh 2 | pst r0, 69 3 | 4 | cal .runGame 5 | 6 | ; cal .renderFullMesh 7 | ; lim r1, -20 8 | 9 | ; .mainloop 10 | ; pst r1, 72 11 | ; psh r1 12 | ; pst r0, 68 13 | ; cal .renderFullMesh 14 | ; pst r0, 69 15 | ; pop r1 16 | ; adi r1, r1, 4 17 | ; cmp r1, 20 18 | ; brt nzero, .mainloop 19 | 20 | ; lim r1, 15 21 | 22 | ; .mainloop2 23 | ; pst r1, 66 24 | ; psh r1 25 | ; pst r0, 68 26 | ; cal .renderFullMesh 27 | ; pst r0, 69 28 | ; pop r1 29 | ; adi r1, r1, -1 30 | ; cmp r1, -1 31 | ; brt nzero, .mainloop2 32 | 33 | ; lim r1, 15 34 | 35 | ; .mainloop3 36 | ; pst r1, 67 37 | ; psh r1 38 | ; pst r0, 68 39 | ; cal .renderFullMesh 40 | ; pst r0, 69 41 | ; pop r1 42 | ; adi r1, r1, -1 43 | ; cmp r1, -1 44 | ; brt nzero, .mainloop3 45 | 46 | 47 | 48 | hlt 49 | 50 | -------------------------------------------------------------------------------- /minecraft/memory.s: -------------------------------------------------------------------------------- 1 | @DEFINE world 0 2 | 3 | @DEFINE playerx 192 4 | @DEFINE playery 193 5 | @DEFINE playerz 194 6 | @DEFINE camx 195 7 | @DEFINE camy 196 -------------------------------------------------------------------------------- /minecraft/ports.s: -------------------------------------------------------------------------------- 1 | ; ports 2 | @DEFINE %negXFace 128 3 | @DEFINE %posXFace 134 4 | @DEFINE %negZFace 140 5 | @DEFINE %posZFace 146 6 | @DEFINE %negYFace 152 7 | @DEFINE %posYFace 158 8 | 9 | @DEFINE %vertex 64 10 | @DEFINE %texture 65 11 | @DEFINE %xrotation 66 12 | @DEFINE %yrotation 67 13 | @DEFINE %clear 68 14 | @DEFINE %buffer 69 15 | @DEFINE %camx 70 16 | @DEFINE %camy 71 17 | @DEFINE %camz 72 18 | 19 | @DEFINE %controller 64 20 | 21 | @DEFINE %direction 32 -------------------------------------------------------------------------------- /minecraft/textures.s: -------------------------------------------------------------------------------- 1 | ; block IDs 2 | @DEFINE airBlock 0 3 | @DEFINE grassBlock 1 4 | @DEFINE dirtBlock 2 5 | @DEFINE cobbleBlock 3 6 | @DEFINE logBlock 4 7 | @DEFINE leafBlock 5 8 | @DEFINE plankBlock 6 9 | @DEFINE craftingBlock 7 10 | 11 | ; side textures have same IDs as blocks (except for bedrock because air doesn't get rendered normally) 12 | @DEFINE bedrockTexture 0 13 | @DEFINE grassSideTexture 1 14 | @DEFINE dirtTexture 2 ; also grass bottom 15 | @DEFINE cobbleTexture 3 16 | @DEFINE logSideTexture 4 17 | @DEFINE leafTexture 5 18 | @DEFINE plankTexture 6 ; also crafting bottom 19 | @DEFINE craftingSideTexture 7 20 | 21 | ; texture IDs that aren't on the sides of blocks 22 | @DEFINE grassTopTexture 8 23 | @DEFINE logTopTexture 9 24 | @DEFINE craftingTopTexture 10 25 | -------------------------------------------------------------------------------- /minecraft/world/block.txt: -------------------------------------------------------------------------------- 1 | 0 2 | 0 3 | 0 4 | 0 5 | 0 6 | 0 7 | 0 8 | 0 9 | 0 10 | 0 11 | 0 12 | 0 13 | 0 14 | 0 15 | 0 16 | 0 17 | 0 18 | 0 19 | 0 20 | 0 21 | 0 22 | 0 23 | 0 24 | 0 25 | 0 26 | 0 27 | 0 28 | 0 29 | 0 30 | 0 31 | 0 32 | 0 33 | 0 34 | 0 35 | 0 36 | 0 37 | 0 38 | 0 39 | 0 40 | 0 41 | 0 42 | 0 43 | 0 44 | 0 45 | 0 46 | 0 47 | 0 48 | 0 49 | 0 50 | 0 51 | 0 52 | 0 53 | 0 54 | 0 55 | 128 56 | 0 57 | 0 58 | 0 59 | 0 60 | 0 61 | 0 62 | 0 63 | 0 64 | 0 65 | 0 66 | 0 67 | 0 68 | 0 69 | 0 70 | 0 71 | 0 72 | 0 73 | 0 74 | 0 75 | 0 76 | 0 77 | 0 78 | 0 79 | 0 80 | 0 81 | 0 82 | 0 83 | 0 84 | 0 85 | 0 86 | 0 87 | 0 88 | 0 89 | 0 90 | 0 91 | 0 92 | 0 93 | 0 94 | 0 95 | 0 96 | 0 97 | 0 98 | 0 99 | 0 100 | 0 101 | 0 102 | 0 103 | 0 104 | 0 105 | 0 106 | 0 107 | 0 108 | 0 109 | 0 110 | 0 111 | 0 112 | 0 113 | 0 114 | 0 115 | 0 116 | 0 117 | 0 118 | 0 119 | 0 120 | 0 121 | 0 122 | 0 123 | 0 124 | 0 125 | 0 126 | 0 127 | 0 128 | 0 129 | 0 130 | 0 131 | 0 132 | 0 133 | 0 134 | 0 135 | 0 136 | 0 137 | 0 138 | 0 139 | 0 140 | 0 141 | 0 142 | 0 143 | 0 144 | 0 145 | 0 146 | 0 147 | 0 148 | 0 149 | 0 150 | 0 151 | 0 152 | 0 153 | 0 154 | 0 155 | 0 156 | 0 157 | 0 158 | 0 159 | 0 160 | 0 161 | 0 162 | 0 163 | 0 164 | 0 165 | 0 166 | 0 167 | 0 168 | 0 169 | 0 170 | 0 171 | 0 172 | 0 173 | 0 174 | 0 175 | 0 176 | 0 177 | 0 178 | 0 179 | 0 180 | 0 181 | 0 182 | 0 183 | 0 184 | 0 185 | 0 186 | 0 187 | 0 188 | 0 189 | 0 190 | 0 191 | 0 192 | 0 193 | 0 194 | 0 195 | 0 196 | 0 197 | 0 198 | 0 199 | 0 200 | 0 201 | 0 202 | 0 203 | 0 204 | 0 205 | 0 206 | 0 207 | 0 208 | 0 209 | 0 210 | 0 211 | 0 212 | 0 213 | 0 214 | 0 215 | 0 216 | 0 217 | 0 218 | 0 219 | 0 220 | 0 221 | 0 222 | 0 223 | 0 224 | 0 225 | 0 226 | 0 227 | 0 228 | 0 229 | 0 230 | 0 231 | 0 232 | 0 233 | 0 234 | 0 235 | 0 236 | 0 237 | 0 238 | 0 239 | 0 240 | 0 241 | 0 242 | 0 243 | 0 244 | 0 245 | 0 246 | 0 247 | 0 248 | 0 249 | 0 250 | 0 251 | 0 252 | 0 253 | 0 254 | 0 255 | 0 256 | 0 257 | -------------------------------------------------------------------------------- /minecraft/world/real world.txt: -------------------------------------------------------------------------------- 1 | 85 2 | 85 3 | 85 4 | 85 5 | 85 6 | 85 7 | 85 8 | 85 9 | 85 10 | 85 11 | 85 12 | 85 13 | 85 14 | 85 15 | 85 16 | 85 17 | 85 18 | 85 19 | 85 20 | 85 21 | 85 22 | 5 23 | 85 24 | 0 25 | 85 26 | 0 27 | 21 28 | 0 29 | 21 30 | 0 31 | 5 32 | 0 33 | 85 34 | 0 35 | 21 36 | 0 37 | 5 38 | 0 39 | 5 40 | 0 41 | 1 42 | 0 43 | 1 44 | 8 45 | 0 46 | 0 47 | 0 48 | 0 49 | 0 50 | 0 51 | 0 52 | 0 53 | 0 54 | 0 55 | 0 56 | 0 57 | 0 58 | 0 59 | 0 60 | 8 61 | 0 62 | 0 63 | 0 64 | 0 65 | 0 66 | 0 67 | 0 68 | 0 69 | 0 70 | 0 71 | 0 72 | 170 73 | 128 74 | 170 75 | 128 76 | 170 77 | 128 78 | 170 79 | 128 80 | 170 81 | 0 82 | 0 83 | 0 84 | 0 85 | 0 86 | 0 87 | 128 88 | 170 89 | 128 90 | 170 91 | 128 92 | 170 93 | 128 94 | 170 95 | 128 96 | 170 97 | 0 98 | 0 99 | 0 100 | 0 101 | 0 102 | 0 103 | 0 104 | 0 105 | 0 106 | 42 107 | 0 108 | 42 109 | 0 110 | 42 111 | 0 112 | 0 113 | 0 114 | 0 115 | 0 116 | 0 117 | 0 118 | 0 119 | 0 120 | 0 121 | 0 122 | 10 123 | 0 124 | 42 125 | 0 126 | 10 127 | 0 128 | 0 129 | 255 130 | 255 131 | 255 132 | 255 133 | 255 134 | 255 135 | 255 136 | 255 137 | 255 138 | 255 139 | 255 140 | 255 141 | 255 142 | 255 143 | 255 144 | 255 145 | 255 146 | 255 147 | 63 148 | 15 149 | 15 150 | 7 151 | 7 152 | 3 153 | 15 154 | 7 155 | 3 156 | 3 157 | 1 158 | 1 159 | 0 160 | 0 161 | 0 162 | 0 163 | 0 164 | 240 165 | 248 166 | 216 167 | 248 168 | 248 169 | 0 170 | 0 171 | 0 172 | 248 173 | 248 174 | 216 175 | 248 176 | 248 177 | 0 178 | 0 179 | 0 180 | 0 181 | 112 182 | 80 183 | 112 184 | 0 185 | 0 186 | 0 187 | 0 188 | 0 189 | 48 190 | 112 191 | 48 192 | 0 193 | 0 194 | 0 195 | 0 196 | 0 197 | 0 198 | 0 199 | 0 200 | 0 201 | 0 202 | 0 203 | 0 204 | 0 205 | 0 206 | 0 207 | 0 208 | 0 209 | 0 210 | 0 211 | 0 212 | 0 213 | 0 214 | 0 215 | 0 216 | 0 217 | 0 218 | 0 219 | 0 220 | 0 221 | 0 222 | 0 223 | 0 224 | 0 225 | 0 226 | 0 227 | 0 228 | 0 229 | 0 230 | 0 231 | 0 232 | 0 233 | 0 234 | 0 235 | 0 236 | 0 237 | 0 238 | 0 239 | 0 240 | 0 241 | 0 242 | 0 243 | 0 244 | 0 245 | 0 246 | 0 247 | 0 248 | 0 249 | 0 250 | 0 251 | 0 252 | 0 253 | 0 254 | 0 255 | 0 256 | 0 257 | -------------------------------------------------------------------------------- /minecraft/world/test world.txt: -------------------------------------------------------------------------------- 1 | 1 2 | 0 3 | 5 4 | 0 5 | 5 6 | 0 7 | 85 8 | 0 9 | 85 10 | 0 11 | 85 12 | 5 13 | 85 14 | 85 15 | 85 16 | 85 17 | 0 18 | 0 19 | 0 20 | 0 21 | 0 22 | 0 23 | 129 24 | 0 25 | 1 26 | 3 27 | 5 28 | 48 29 | 5 30 | 0 31 | 85 32 | 0 33 | 0 34 | 0 35 | 0 36 | 0 37 | 0 38 | 0 39 | 128 40 | 0 41 | 192 42 | 0 43 | 0 44 | 0 45 | 0 46 | 0 47 | 0 48 | 95 49 | 0 50 | 0 51 | 0 52 | 0 53 | 0 54 | 0 55 | 128 56 | 0 57 | 0 58 | 0 59 | 0 60 | 0 61 | 0 62 | 0 63 | 0 64 | 244 65 | 0 66 | 0 67 | 168 68 | 10 69 | 168 70 | 10 71 | 168 72 | 10 73 | 168 74 | 10 75 | 160 76 | 10 77 | 0 78 | 0 79 | 0 80 | 0 81 | 0 82 | 0 83 | 168 84 | 2 85 | 168 86 | 10 87 | 168 88 | 10 89 | 168 90 | 10 91 | 168 92 | 10 93 | 0 94 | 0 95 | 0 96 | 0 97 | 0 98 | 0 99 | 0 100 | 0 101 | 160 102 | 2 103 | 160 104 | 2 105 | 160 106 | 2 107 | 0 108 | 0 109 | 0 110 | 0 111 | 0 112 | 0 113 | 0 114 | 0 115 | 0 116 | 0 117 | 160 118 | 2 119 | 160 120 | 2 121 | 160 122 | 0 123 | 0 124 | 0 125 | 0 126 | 0 127 | 0 128 | 0 129 | 255 130 | 255 131 | 255 132 | 255 133 | 255 134 | 255 135 | 255 136 | 255 137 | 1 138 | 3 139 | 3 140 | 7 141 | 31 142 | 127 143 | 255 144 | 255 145 | 0 146 | 0 147 | 0 148 | 0 149 | 1 150 | 11 151 | 11 152 | 207 153 | 0 154 | 0 155 | 0 156 | 0 157 | 0 158 | 0 159 | 0 160 | 32 161 | 0 162 | 62 163 | 62 164 | 54 165 | 62 166 | 60 167 | 0 168 | 0 169 | 0 170 | 30 171 | 62 172 | 54 173 | 62 174 | 62 175 | 0 176 | 0 177 | 0 178 | 0 179 | 28 180 | 20 181 | 28 182 | 0 183 | 0 184 | 0 185 | 0 186 | 0 187 | 28 188 | 28 189 | 12 190 | 0 191 | 0 192 | 0 193 | 0 194 | 0 195 | 0 196 | 0 197 | 0 198 | 0 199 | 0 200 | 0 201 | 0 202 | 0 203 | 0 204 | 0 205 | 0 206 | 0 207 | 0 208 | 0 209 | 0 210 | 0 211 | 0 212 | 0 213 | 0 214 | 0 215 | 0 216 | 0 217 | 0 218 | 0 219 | 0 220 | 0 221 | 0 222 | 0 223 | 0 224 | 0 225 | 0 226 | 0 227 | 0 228 | 0 229 | 0 230 | 0 231 | 0 232 | 0 233 | 0 234 | 0 235 | 0 236 | 0 237 | 0 238 | 0 239 | 0 240 | 0 241 | 0 242 | 0 243 | 0 244 | 0 245 | 0 246 | 0 247 | 0 248 | 0 249 | 0 250 | 0 251 | 0 252 | 0 253 | 0 254 | 0 255 | 0 256 | 0 257 | -------------------------------------------------------------------------------- /minecraft/world/world.txt: -------------------------------------------------------------------------------- 1 | 0 2 | 0 3 | 0 4 | 0 5 | 0 6 | 0 7 | 0 8 | 0 9 | 0 10 | 0 11 | 0 12 | 0 13 | 0 14 | 0 15 | 0 16 | 0 17 | 0 18 | 68 19 | 0 20 | 68 21 | 0 22 | 68 23 | 0 24 | 0 25 | 252 26 | 0 27 | 12 28 | 0 29 | 252 30 | 0 31 | 0 32 | 0 33 | 0 34 | 68 35 | 0 36 | 68 37 | 0 38 | 68 39 | 0 40 | 0 41 | 252 42 | 0 43 | 12 44 | 0 45 | 252 46 | 0 47 | 0 48 | 0 49 | 0 50 | 16 51 | 0 52 | 16 53 | 0 54 | 16 55 | 84 56 | 0 57 | 252 58 | 0 59 | 204 60 | 0 61 | 252 62 | 0 63 | 84 64 | 0 65 | 0 66 | 0 67 | 0 68 | 0 69 | 0 70 | 0 71 | 0 72 | 0 73 | 84 74 | 0 75 | 204 76 | 0 77 | 84 78 | 0 79 | 0 80 | 0 81 | 0 82 | 0 83 | 0 84 | 0 85 | 0 86 | 0 87 | 0 88 | 0 89 | 0 90 | 0 91 | 84 92 | 0 93 | 0 94 | 0 95 | 0 96 | 0 97 | 0 98 | 0 99 | 0 100 | 0 101 | 0 102 | 0 103 | 0 104 | 0 105 | 0 106 | 0 107 | 0 108 | 0 109 | 0 110 | 0 111 | 0 112 | 0 113 | 0 114 | 0 115 | 0 116 | 0 117 | 0 118 | 0 119 | 0 120 | 0 121 | 0 122 | 0 123 | 0 124 | 0 125 | 0 126 | 0 127 | 0 128 | 0 129 | 191 130 | 191 131 | 191 132 | 255 133 | 255 134 | 255 135 | 255 136 | 255 137 | 160 138 | 160 139 | 160 140 | 0 141 | 0 142 | 0 143 | 0 144 | 0 145 | 160 146 | 160 147 | 160 148 | 0 149 | 0 150 | 0 151 | 0 152 | 0 153 | 64 154 | 64 155 | 64 156 | 14 157 | 0 158 | 0 159 | 0 160 | 14 161 | 0 162 | 0 163 | 0 164 | 0 165 | 14 166 | 0 167 | 14 168 | 0 169 | 0 170 | 0 171 | 0 172 | 0 173 | 0 174 | 14 175 | 0 176 | 0 177 | 0 178 | 0 179 | 0 180 | 0 181 | 0 182 | 0 183 | 0 184 | 0 185 | 0 186 | 0 187 | 0 188 | 0 189 | 0 190 | 0 191 | 0 192 | 0 193 | 0 194 | 0 195 | 0 196 | 0 197 | 0 198 | 0 199 | 0 200 | 0 201 | 0 202 | 0 203 | 0 204 | 0 205 | 0 206 | 0 207 | 0 208 | 0 209 | 0 210 | 0 211 | 0 212 | 0 213 | 0 214 | 0 215 | 0 216 | 0 217 | 0 218 | 0 219 | 0 220 | 0 221 | 0 222 | 0 223 | 0 224 | 0 225 | 0 226 | 0 227 | 0 228 | 0 229 | 0 230 | 0 231 | 0 232 | 0 233 | 0 234 | 0 235 | 0 236 | 0 237 | 0 238 | 0 239 | 0 240 | 0 241 | 0 242 | 0 243 | 0 244 | 0 245 | 0 246 | 0 247 | 0 248 | 0 249 | 0 250 | 0 251 | 0 252 | 0 253 | 0 254 | 0 255 | 0 256 | 0 257 | -------------------------------------------------------------------------------- /schemgenerator/blockdata.py: -------------------------------------------------------------------------------- 1 | from lib2to3.pytree import convert 2 | from nbt import nbt 3 | 4 | SCHEM_MAX_SIZE = 2048 5 | 6 | 7 | def convert_machinecode(machinecode: list[str]) -> list[str]: 8 | """Convert machine code from 2 bytes to one 16 bit string""" 9 | 10 | return [ 11 | instr[0:8] + instr[9:17] for instr in machinecode 12 | ] 13 | 14 | 15 | def create_barrel(pos: list[int], ss: int) -> nbt.TAG_Compound: 16 | """Generate a barrel with specified signal strength and position""" 17 | 18 | barrel = nbt.TAG_Compound(name="") 19 | 20 | barrel.tags.append(nbt.TAG_Int_Array(name="Pos")) 21 | barrel["Pos"].value = pos.copy() 22 | 23 | itemslist = nbt.TAG_List(name="Items", type=nbt.TAG_Compound) 24 | stacks = min(27, (max(64 * ss, int((27 * 64 / 14) * (ss - 1)) + 63)) // 64) 25 | 26 | for count in range(stacks): 27 | item = nbt.TAG_Compound(name="") 28 | item.tags.append(nbt.TAG_Byte( 29 | name="Slot", 30 | value=count 31 | )) 32 | item.tags.append(nbt.TAG_String( 33 | name="id", 34 | value="minecraft:redstone" 35 | )) 36 | item.tags.append(nbt.TAG_Byte( 37 | name="Count", 38 | value=64 39 | )) 40 | itemslist.tags.append(item) 41 | 42 | barrel.tags.append(itemslist) 43 | barrel.tags.append(nbt.TAG_String(name="Id", value="minecraft:barrel")) 44 | 45 | return barrel 46 | 47 | 48 | def generate_block_data( 49 | machinecode: list[str], blankschem: nbt.NBTFile, large: bool = True 50 | ) -> tuple[bytearray, nbt.TAG_List]: 51 | """Generate block data for a schematic""" 52 | 53 | machinecode = convert_machinecode(machinecode) 54 | 55 | basedata = bytearray(blankschem["BlockData"].value) 56 | blockentities = nbt.TAG_List(name="BlockEntities", type=nbt.TAG_Compound) 57 | 58 | machinecode.extend( 59 | ["0000000000000000" for i in range(SCHEM_MAX_SIZE - len(machinecode))] 60 | ) 61 | 62 | for zoffset in range(0, 2 if large else 1): 63 | for instruction in range(zoffset * 256, (zoffset + 1) * 256): 64 | ilist = [ 65 | machinecode[64 * (instruction // 16) + instruction % 16], 66 | machinecode[64 * (instruction // 16) + instruction % 16 + 16], 67 | machinecode[64 * (instruction // 16) + instruction % 16 + 32], 68 | machinecode[64 * (instruction // 16) + instruction % 16 + 48], 69 | ] 70 | for bit in range(16): 71 | 72 | x = 4 * ((instruction % 256) // 16) 73 | if bit > 7 and instruction % 32 < 16: 74 | x += 2 75 | if bit < 8 and instruction % 32 > 15: 76 | x += 2 77 | y = 15 - ((2 * bit) % 16 + (1 if instruction % 2 == 0 else 0)) 78 | z = 30 + 32 * (int(large) - zoffset) - (2 * (instruction % 16)) 79 | absolute = x + 63 * z + (63 if large else 31) * 63 * y 80 | 81 | ss = 15 - ( 82 | int(ilist[0][bit]) 83 | + int(ilist[1][bit]) * 2 84 | + int(ilist[2][bit]) * 4 85 | + int(ilist[3][bit]) * 8 86 | ) 87 | 88 | if ss == 0: 89 | basedata[absolute] = 3 90 | elif ss != 15: 91 | blockentities.tags.append( 92 | create_barrel([x, y, z], ss) 93 | ) 94 | basedata[absolute] = 2 95 | 96 | return basedata, blockentities 97 | -------------------------------------------------------------------------------- /schemgenerator/schem.py: -------------------------------------------------------------------------------- 1 | from nbt import nbt 2 | from os import path 3 | 4 | from .blockdata import generate_block_data 5 | 6 | 7 | def generate_schematic( 8 | machinecode: list[str], name: str, large: bool = True 9 | ) -> None: 10 | """Generate a schematic from the given machine code instructions""" 11 | 12 | pathto = __file__ 13 | blankschem = nbt.NBTFile( 14 | path.dirname(__file__) 15 | + "/templates/ROM_blank_" 16 | + ("4" if large else "2") 17 | + "KiB.schem", 18 | "rb" 19 | ) 20 | 21 | nbtfile = nbt.NBTFile() 22 | nbtfile.name = "Schematic" 23 | 24 | nbtfile.tags.append(nbt.TAG_Int(name="PaletteMax", value=4)) 25 | 26 | palette = nbt.TAG_Compound(name="Palette") 27 | palette.tags.append(nbt.TAG_Int(name="minecraft:air", value=0)) 28 | palette.tags.append(nbt.TAG_Int(name="minecraft:redstone_block", value=1)) 29 | palette.tags.append(nbt.TAG_Int(name="minecraft:barrel", value=2)) 30 | palette.tags.append(nbt.TAG_Int(name="minecraft:stone", value=3)) 31 | palette.name = "Palette" 32 | nbtfile.tags.append(palette) 33 | 34 | nbtfile.tags.extend([ 35 | nbt.TAG_Int(name="DataVersion", value=blankschem["DataVersion"].value), 36 | nbt.TAG_Int(name="Version", value=blankschem["Version"].value), 37 | nbt.TAG_Short(name="Length", value=blankschem["Length"].value), 38 | nbt.TAG_Short(name="Height", value=blankschem["Height"].value), 39 | nbt.TAG_Short(name="Width", value=blankschem["Width"].value), 40 | nbt.TAG_Int_Array(name="Offset"), 41 | ]) 42 | nbtfile["Offset"].value = blankschem["Offset"].value 43 | 44 | metadata = nbt.TAG_Compound() 45 | metadata.tags = blankschem["Metadata"].tags.copy() 46 | metadata.name = "Metadata" 47 | nbtfile.tags.append(metadata) 48 | 49 | basedata, blockentities = generate_block_data( 50 | machinecode, blankschem, large 51 | ) 52 | 53 | nbtfile.tags.append(nbt.TAG_Byte_Array(name="BlockData")) 54 | nbtfile["BlockData"].value = basedata 55 | nbtfile.tags.append(blockentities) 56 | 57 | nbtfile.write_file(f"{name}.schem") 58 | -------------------------------------------------------------------------------- /schemgenerator/templates/ROM_blank_2KiB.schem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sammyuri/minecraft/976e84d3dc8142dd4cf8927036d0d5e54b79152e/schemgenerator/templates/ROM_blank_2KiB.schem -------------------------------------------------------------------------------- /schemgenerator/templates/ROM_blank_4KiB.schem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sammyuri/minecraft/976e84d3dc8142dd4cf8927036d0d5e54b79152e/schemgenerator/templates/ROM_blank_4KiB.schem -------------------------------------------------------------------------------- /schemgenerator/templates/base.schem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sammyuri/minecraft/976e84d3dc8142dd4cf8927036d0d5e54b79152e/schemgenerator/templates/base.schem -------------------------------------------------------------------------------- /schemgenerator/templates/world_base.schem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sammyuri/minecraft/976e84d3dc8142dd4cf8927036d0d5e54b79152e/schemgenerator/templates/world_base.schem -------------------------------------------------------------------------------- /schemgenerator/textschem.py: -------------------------------------------------------------------------------- 1 | from nbt import nbt 2 | 3 | def generate_block_data(data, blankschem): 4 | def get_block(x, z): 5 | direction = (x + 1) % 2 6 | return 9 + direction if z % 2 == 1 else 7 + direction 7 | 8 | xlength = blankschem["Width"].value 9 | zlength = blankschem["Length"].value 10 | 11 | basedata = bytearray(blankschem["BlockData"].value) 12 | for sprite in range(256): 13 | x, z = sprite % 16, sprite // 16 14 | overallx = 2 * x + 1 15 | overallz = 10 * z 16 | spritedata = data[sprite * 64:(sprite + 1) * 64][::-1] 17 | absolute = overallx + overallz * xlength 18 | for i in range(8): 19 | for j in range(8): 20 | if spritedata[(7 - j) + 8 * (7 - i)] == "0": continue 21 | adjusted = absolute + xlength * j + xlength * zlength * (2 * i + 1) 22 | basedata[adjusted] = get_block(x, j) 23 | return basedata 24 | 25 | 26 | def generate_schematic(data, name="textures"): 27 | blankschem = nbt.NBTFile("templates/base.schem", "rb") 28 | 29 | nbtfile = nbt.NBTFile() 30 | nbtfile.name = "Schematic" 31 | 32 | nbtfile.tags.extend([ 33 | nbt.TAG_Int(name="PaletteMax", value=10), 34 | nbt.TAG_Int(name="DataVersion", value=blankschem["DataVersion"].value), 35 | nbt.TAG_Int(name="Version", value=blankschem["Version"].value), 36 | nbt.TAG_Short(name="Length", value=blankschem["Length"].value), 37 | nbt.TAG_Short(name="Height", value=blankschem["Height"].value), 38 | nbt.TAG_Short(name="Width", value=blankschem["Width"].value), 39 | nbt.TAG_Int_Array(name="Offset"), 40 | ]) 41 | nbtfile["Offset"].value = blankschem["Offset"].value 42 | 43 | metadata = nbt.TAG_Compound() 44 | metadata.tags = blankschem["Metadata"].tags.copy() 45 | metadata.name = "Metadata" 46 | nbtfile.tags.append(metadata) 47 | 48 | palette = nbt.TAG_Compound() 49 | palette.tags = [ 50 | nbt.TAG_Int(name="minecraft:light_gray_terracotta", value=0), 51 | nbt.TAG_Int(name="minecraft:redstone_torch[lit=true]", value=1), 52 | nbt.TAG_Int(name="minecraft:air", value=2), 53 | nbt.TAG_Int(name="minecraft:redstone_wire[east=none,north=side,power=0,south=side,west=none]", value=3), 54 | nbt.TAG_Int(name="minecraft:redstone_wall_torch[facing=south,lit=false]", value=4), 55 | nbt.TAG_Int(name="minecraft:repeater[delay=1,facing=north,locked=false,powered=false]", value=5), 56 | nbt.TAG_Int(name="minecraft:redstone_wall_torch[facing=north,lit=true]", value=6), 57 | nbt.TAG_Int(name="minecraft:redstone_wall_torch[facing=east,lit=false]", value=7), 58 | nbt.TAG_Int(name="minecraft:redstone_wall_torch[facing=west,lit=false]", value=8), 59 | nbt.TAG_Int(name="minecraft:repeater[delay=2,facing=west,locked=false,powered=false]", value=9), 60 | nbt.TAG_Int(name="minecraft:repeater[delay=2,facing=east,locked=false,powered=false]", value=10), 61 | ] 62 | palette.name = "Palette" 63 | nbtfile.tags.append(palette) 64 | 65 | basedata = generate_block_data(data, blankschem) 66 | nbtfile.tags.append(nbt.TAG_Byte_Array(name="BlockData")) 67 | nbtfile["BlockData"].value = basedata 68 | nbtfile.tags.append(nbt.TAG_List(name="BlockEntities", type=nbt.TAG_Compound)) 69 | 70 | nbtfile.write_file(f"{name}.schem") 71 | -------------------------------------------------------------------------------- /schemgenerator/textures.py: -------------------------------------------------------------------------------- 1 | from tkinter import * 2 | from textschem import generate_schematic 3 | from json import dumps 4 | 5 | def resetdata(): 6 | with open("data.txt", "w") as f: 7 | f.write("0" * 256 * 8 * 8) 8 | 9 | def getdata(): 10 | with open("data.txt", "r") as f: 11 | data = list(f.readlines()[0].strip()) 12 | return data 13 | 14 | def writedata(data): 15 | with open("data.txt", "w") as f: 16 | f.write("".join(data)) 17 | jsondata = [] 18 | for i in range(256): 19 | jsondata.append(list(map(int, data[64 * i:64 * (i + 1)]))) 20 | with open("textures.json", "w") as f: 21 | f.write(dumps(jsondata)) 22 | 23 | def clicked(event): 24 | x, y = event.x, event.y 25 | if not (0 <= x < 1024 and 0 <= y < 960): 26 | return 27 | sprite = (x // 64) + (y // 64) * 16 28 | offset = (x % 64) // 8 + ((y % 64) // 8) * 8 29 | data[sprite * 64 + offset] = "0" if data[sprite * 64 + offset] == "1" else "1" 30 | redraw(canvas, data) 31 | 32 | def middleclicked(event): 33 | x, y = event.x, event.y 34 | if not (0 <= x < 1024 and 0 <= y < 960): 35 | return 36 | sprite = (x // 64) + (y // 64) * 16 37 | spriteid2.delete(0, END) 38 | spriteid2.insert(END, str(sprite)) 39 | 40 | def rightclicked(event): 41 | x, y = event.x, event.y 42 | if not (0 <= x < 1024 and 0 <= y < 960): 43 | return 44 | sprite = (x // 64) + (y // 64) * 16 45 | spriteid.delete(0, END) 46 | spriteid.insert(END, str(sprite)) 47 | 48 | def clearsprite(): 49 | try: 50 | id = int(spriteid.get()) 51 | except ValueError: 52 | return 53 | sprite = id * 64 54 | for i in range(64): 55 | data[sprite + i] = "0" 56 | redraw(canvas, data) 57 | 58 | def flipsprite(): 59 | try: 60 | id = int(spriteid.get()) 61 | except ValueError: 62 | return 63 | sprite = id * 64 64 | for i in range(64): 65 | data[sprite + i] = "0" if data[sprite + i] == "1" else "1" 66 | redraw(canvas, data) 67 | 68 | def copysprite(): 69 | try: 70 | id2 = int(spriteid.get()) 71 | except ValueError: 72 | return 73 | try: 74 | id = int(spriteid2.get()) 75 | except ValueError: 76 | return 77 | sprite = id * 64 78 | sprite2 = id2 * 64 79 | for i in range(64): 80 | data[sprite + i] = data[sprite2 + i] 81 | redraw(canvas, data) 82 | 83 | def redraw(canvas, data): 84 | canvas.delete("all") 85 | for i in range(15): 86 | canvas.create_line(i * 64 + 64, 0, i * 64 + 64, 960, fill="white") 87 | for j in range(14): 88 | canvas.create_line(0, j * 64 + 64, 1024, j * 64 + 64, fill="white") 89 | 90 | for i in range(16): 91 | for j in range(15): 92 | index = i * 64 + j * 64 * 16 93 | for y in range(8): 94 | for x in range(8): 95 | if data[index + x + 8 * y] == "1": 96 | canvas.create_rectangle( 97 | i * 64 + x * 8, 98 | j * 64 + y * 8, 99 | i * 64 + x * 8 + 8, 100 | j * 64 + y * 8 + 8, 101 | fill="yellow", 102 | outline="", 103 | ) 104 | 105 | if __name__ == "__main__": 106 | root = Tk() 107 | 108 | canvas = Canvas(root, height=960, width=1024, background="black") 109 | canvas.grid(column=0, row=0, sticky="nesw", columnspan=5) 110 | canvas.bind("", clicked) 111 | canvas.bind("", middleclicked) 112 | canvas.bind("", rightclicked) 113 | 114 | spriteid = Entry(root, width=5) 115 | spriteid.insert(END, "0") 116 | spriteid.grid(column=0, row=1, sticky="nesw") 117 | 118 | spriteid2 = Entry(root, width=5) 119 | spriteid2.insert(END, "0") 120 | spriteid2.grid(column=1, row=1, sticky="nesw") 121 | 122 | clearspritebutton = Button(root, text="Clear sprite", command=clearsprite) 123 | flipspritebutton = Button(root, text="Flip sprite", command=flipsprite) 124 | copyspritebutton = Button(root, text="Copy sprite", command=copysprite) 125 | clearspritebutton.grid(column=2, row=1, sticky="nesw") 126 | flipspritebutton.grid(column=3, row=1, sticky="nesw") 127 | copyspritebutton.grid(column=4, row=1, sticky="nesw") 128 | 129 | data = getdata() 130 | data.extend(["0"] * (16384 - len(data))) 131 | redraw(canvas, data) 132 | 133 | root.mainloop() 134 | 135 | writedata(data) 136 | generate_schematic(data) -------------------------------------------------------------------------------- /schemgenerator/textures.schem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sammyuri/minecraft/976e84d3dc8142dd4cf8927036d0d5e54b79152e/schemgenerator/textures.schem -------------------------------------------------------------------------------- /schemgenerator/world.json: -------------------------------------------------------------------------------- 1 | [[[3,3,3,3,3,3,3,3],[3,3,3,3,3,3,3,3],[3,3,3,3,3,3,3,3],[3,3,3,3,3,3,3,3],[3,3,3,3,3,8,3,3],[3,3,3,3,3,8,8,3],[3,3,3,3,3,8,8,3],[3,3,3,3,1,1,1,1]],[[3,3,9,3,3,3,3,3],[3,3,9,9,3,3,3,3],[3,3,3,3,3,3,3,3],[1,3,3,3,3,3,3,3],[1,1,1,3,8,8,8,3],[1,1,2,1,3,1,8,3],[1,1,1,1,1,1,1,1],[1,1,1,1,1,1,1,1]],[[3,3,9,9,3,3,3,3],[3,3,3,9,3,3,3,3],[1,1,3,3,3,3,9,9],[0,1,1,1,3,3,3,9],[0,0,0,1,1,3,3,3],[0,0,5,0,1,1,1,1],[0,0,0,0,0,1,1,1],[0,0,0,0,0,0,0,0]],[[3,3,3,3,3,3,3,3],[1,1,3,3,3,3,3,3],[0,0,1,1,3,3,9,9],[0,0,0,0,1,3,1,9],[0,0,0,0,0,1,1,1],[0,0,5,0,0,0,1,1],[0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0]],[[1,1,1,3,3,3,3,3],[0,0,1,1,1,3,3,1],[0,0,0,0,1,1,3,10],[0,6,6,6,0,1,10,10],[6,6,6,6,6,0,10,10],[6,6,5,6,6,0,0,0],[6,6,6,6,6,0,0,0],[0,6,6,6,0,0,0,0]],[[0,0,0,1,1,1,1,1],[0,0,0,0,0,1,1,10],[0,0,0,0,0,0,1,10],[6,6,6,6,0,0,0,10],[6,6,6,6,6,0,0,0],[6,6,5,6,6,0,0,0],[6,6,6,6,6,0,0,0],[0,6,6,6,0,0,0,0]],[[0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0],[0,0,6,6,0,0,0,0],[0,6,6,6,0,0,0,0],[0,6,6,0,0,0,0,0],[0,0,0,0,0,0,0,0]],[[0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0],[0,0,6,0,0,0,0,0],[0,6,6,6,0,0,0,0],[0,0,6,0,0,0,0,0],[0,0,0,0,0,0,0,0]]] -------------------------------------------------------------------------------- /urcl-explorer/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .vscode 3 | *.bin 4 | .env 5 | -------------------------------------------------------------------------------- /urcl-explorer/.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "URCLpp-compiler"] 2 | path = URCLpp-compiler 3 | url = https://github.com/Kuggo/URCLpp-compiler.git 4 | -------------------------------------------------------------------------------- /urcl-explorer/Procfile: -------------------------------------------------------------------------------- 1 | worker: node js/node/urcx-bot.js 2 | -------------------------------------------------------------------------------- /urcl-explorer/README.MD: -------------------------------------------------------------------------------- 1 | # URCl Explorer 2 | An IDE for URCL. 3 | See full feature list [below](#Features) 4 | 5 | ## Important notes ⚠️ 6 | Keep in mind that currently there is **no** saving functionality build into the website, thus make sure to save your code to a file before you close your browser tab. 7 | 8 | ## Run 🏃‍♂️ 9 | ### Github Pages 10 | You only need your browser to use urcl-explorer just go to [github pages](https://bramotte.github.io/urcl-explorer) and start writing and running URCL code. 11 | 12 | ### Local Server 13 | To use the URCL website offline you will need to clone the repository to your computer, run a static http server and then connect to that server using your browser. 14 | 15 | First clone the repo to your computer this can be done in the terminal like this: 16 | ```cmd 17 | git clone https://github.com/BramOtte/urcl-explorer.git 18 | ``` 19 | 20 | Then navigate to the folder you just cloned to which is by default urcl-explorer. 21 | ```cmd 22 | cd urcl-explorer 23 | ``` 24 | 25 | Install a static http server, an example of one is http-server which you can install using npm. 26 | But you can use any other http server as long as it gives proper mime-types to javascript files. 27 | ```cmd 28 | npm install -g http-server 29 | ``` 30 | And run it. 31 | ``` 32 | http-server -p 8000 33 | ``` 34 | 35 | Finally, open your browser and visit http://localhost:8000. 36 | 37 | ### Node.js 38 | ``` 39 | node js/node/urcx-emu.js [<...options>] 40 | ``` 41 | 42 | ## Install 🔩 43 | ### Node.js Windows / Linux 44 | Add the bin folder to your [Path environment variable](https://duckduckgo.com/?q=windows+add+to+path) 45 | and run the emulator with the urcx-emu command: 46 | ``` 47 | urcx-emu [<...options>] 48 | ``` 49 | 50 | ## Features 51 | This feature list is not complete yet. 52 | 🚧🚧🚧 53 | ### Devices 54 | #### Console 55 | ##### ports 56 | 57 | #### Display 58 | This device is operated via the [%X, %Y, %COLOR, and %BUFFER ports](https://docs.google.com/spreadsheets/d/1_ztRKWEm2LjHLb3Bxw0JOyZjJ9Drsj-hyOE-TFpwtS4/edit#gid=0&range=B11:B18) 59 | ##### Color modes 60 | The color mode defines how the colors being outputted via the %COLOR port should be displayed. 61 | Mode | Description 62 | --------|------------ 63 | PICO8 | The [color pallet](https://lospec.com/palette-list/pico-8) the fantasy console [PICO-8](https://www.lexaloffle.com/pico-8.php) uses 64 | MONO | The lowest 8 bits represent a brightness value 0 is black 255 is white 65 | BIN | 0 is black any thing else is white 66 | [RGB8](https://en.wikipedia.org/wiki/8-bit_color) | 3 red, 3 green, 2 blue the highest 3 bits represent a red value the next 3 green and the lowest 2 blue 67 | [RGB16](https://en.wikipedia.org/wiki/High_color) | 5 red, 6 green, 5 blue 68 | [RGB24](https://en.wikipedia.org/wiki/List_of_monochrome_and_RGB_color_formats#24-bit_RGB) | 8 red, 8 green, 8 blue 69 | RGB | Automatically picks RGB8, RGB16 or RGB24 depending on the BITS header 70 | [RGBI](https://en.wikipedia.org/wiki/List_of_monochrome_and_RGB_color_formats#4-bit_RGBI) | 1 red, 1 green, 1 blue, 1 intensity, intensity 0 colors are at half brightness with 1 full. 71 | -------------------------------------------------------------------------------- /urcl-explorer/TODO.md: -------------------------------------------------------------------------------- 1 | # https://discord.com/developers/applications 2 | 3 | # \TODO 4 | ## URCL Standart 5 | * Check operant types at compile time 6 | * multiline commments 7 | * take into account bit opperants 8 | * Make == optional 9 | 10 | ## URCL++ Standart 11 | 12 | ## Misc 13 | * check if all array access is bounds checked 14 | * v-sync 15 | * document emulator 16 | * fix the mess that is index.ts 17 | * fix size checks on buffers 18 | * check for negative header values 19 | * handle non normalized for f16 20 | * Optimize text highlighter. 21 | * Add keymaps for buttons 22 | * Storage device download on website 23 | * Add user pallet via image 24 | * add axis port 25 | - add mousex and mousey axis 26 | 27 | 28 | ## bot 29 | * Option to list examples 30 | * add !ports 31 | * escape ``` 32 | * !stop 33 | * !registers 34 | * !memory 35 | * load attachments 36 | * output attachments 37 | * Upload storage file to bot 38 | 39 | ## Low Priority 40 | * make diverent compile steps visible to user (URCL++ -> URCL -> URCL bin) 41 | * hot code reloading 42 | * save and load code from file 43 | * save and load code from localstorage 44 | * 3d device 45 | * integrate existing tools into urcl explorer with python and C# runtime 46 | * compile URCL code to js for greater speed 47 | * compile URCL code to wasm for maximum speed 48 | * add new cool things to this TODO list 49 | * support URCL binary format 50 | * warning for read before write 51 | 52 | # DONE 53 | * Refactor out parser code from emulator 54 | * put stack into memory 55 | * Headers and multiple word lengths 8-32 56 | * Display with Buffer 57 | * Fix freezing when there is a lot of IO 58 | * compiler constants with @ or & 59 | * @BITS = bit count 60 | * @UHALF = upper half of bits (in 8 bits it would be 0b11110000) 61 | * @LHALF = lower half of bits (in 8 bits it would be 0b00001111) 62 | * @MSB = most significant bit (8 bits it would be 0b10000000) 63 | * @SMAX = max signed value (so 127 in 8 bits) 64 | * @SMSB = the second to highest bit (so 0b01000000 in 8 bits) 65 | * fix view of memory and registers in html 66 | * DW 67 | * @define 68 | * f32 litterals 69 | * syntax highlighting 70 | * add line numbers to source code 71 | * fix BSS (sign 32 bit conversion goes wrong) 72 | * add fixed clock speed 73 | * exclude general purpose registers from MINREG 74 | * string litterals 75 | * sound device 76 | * visualize PC in source code 77 | * add something for automated testing either a port or an instruction 78 | * marcos 79 | * Rgb6 rgb12 80 | * Fix to much memory error report 81 | * Add endianess toggle 82 | -------------------------------------------------------------------------------- /urcl-explorer/URCLpp-compiler/.gitconfig: -------------------------------------------------------------------------------- 1 | [submodule] 2 | recurse = true -------------------------------------------------------------------------------- /urcl-explorer/URCLpp-compiler/.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "Libraries"] 2 | path = Libraries 3 | url = https://github.com/Urclpp/urclpp-libraries.git 4 | -------------------------------------------------------------------------------- /urcl-explorer/URCLpp-compiler/Libraries/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Urclpp 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /urcl-explorer/URCLpp-compiler/Libraries/README.md: -------------------------------------------------------------------------------- 1 | # urclpp-libraries 2 | libraries for urclpp 3 | -------------------------------------------------------------------------------- /urcl-explorer/URCLpp-compiler/Libraries/String/Is_empty.urcl: -------------------------------------------------------------------------------- 1 | BITS >= 8 2 | OUTS 1 3 | OPS 2 4 | REG 1 5 | 6 | LLOD $1 SP 1 7 | LOD $1 $1 8 | BNZ +3 $1 9 | DEC $1 $1 10 | RET 11 | IMM $1 0 12 | RET -------------------------------------------------------------------------------- /urcl-explorer/URCLpp-compiler/Libraries/String/about.txt: -------------------------------------------------------------------------------- 1 | String library made by Kuggo 2 | -------------------------------------------------------------------------------- /urcl-explorer/URCLpp-compiler/Libraries/String/add_char.urcl: -------------------------------------------------------------------------------- 1 | BITS >= 8 2 | OUTS 0 3 | OPS 2 4 | REG 3 5 | 6 | LLOD R2 SP 1 7 | LLOD R1 SP 2 8 | LOD R3 R2 9 | INC R3 R3 10 | STR R3 R2 11 | ADD R3 R2 R3 12 | STR R3 R1 13 | RET -------------------------------------------------------------------------------- /urcl-explorer/URCLpp-compiler/Libraries/String/char_at.urcl: -------------------------------------------------------------------------------- 1 | BITS >= 8 2 | OUTS 1 3 | OPS 3 4 | REG 4 5 | 6 | POP R2 7 | POP R3 8 | LOD $4 $2 9 | SUB $4 $4 $3 10 | JMP ~+3 $4 11 | IMM $1 -1 12 | RET 13 | ADD $4 $2 $3 14 | INC $4 $4 15 | LOD $1 $4 16 | RET -------------------------------------------------------------------------------- /urcl-explorer/URCLpp-compiler/Libraries/String/count.urcl: -------------------------------------------------------------------------------- 1 | BITS >= 8 2 | OUTS 1 3 | OPS 3 4 | REG 5 5 | 6 | LLOD R2 SP 1 7 | LLOD R3 SP 2 8 | IMM R1 0 9 | LOD R4 R2 10 | INC R2 R2 11 | LOD R5 R2 12 | BNE ~+2 R5 R3 13 | INC R1 R1 14 | INC R2 R2 15 | DEC R4 R4 16 | BNZ ~-5 R4 17 | RET -------------------------------------------------------------------------------- /urcl-explorer/URCLpp-compiler/Libraries/String/ends_with_char.urcl: -------------------------------------------------------------------------------- 1 | BITS >= 8 2 | OUTS 1 3 | OPS 3 4 | REG 3 5 | 6 | LLOD R2 SP 1 7 | LLOD R3 SP 2 8 | LOD R1 R2 9 | ADD R1 R1 R2 10 | LOD R1 R1 11 | SUB R1 R1 R3 12 | BRZ ~+2 R1 13 | IMM R1 -1 14 | RET 15 | -------------------------------------------------------------------------------- /urcl-explorer/URCLpp-compiler/Libraries/String/index_of.urcl: -------------------------------------------------------------------------------- 1 | BITS >= 8 2 | OUTS 1 3 | OPS 3 4 | REG 4 5 | 6 | LLOD R2 SP 1 7 | LLOD R3 SP 2 8 | LOD R1 R2 9 | PSH R1 10 | SUB R1 R0 R1 11 | INC R2 R2 12 | BRZ ~+5 R1 13 | LOD R4 R2 14 | SUB R4 R4 R3 15 | BRZ ~+4 R4 16 | INC R1 R1 17 | DEC R1 R1 18 | RET 19 | POP R2 20 | ADD R1 R1 R2 21 | RET 22 | -------------------------------------------------------------------------------- /urcl-explorer/URCLpp-compiler/Libraries/String/last_index_of.urcl: -------------------------------------------------------------------------------- 1 | BITS >= 8 2 | OUTS 1 3 | OPS 3 4 | REG 4 5 | 6 | LLOD R2 SP 1 7 | LLOD R3 SP 2 8 | LOD R1 R2 9 | ADD R2 R2 R1 10 | LOD R4 R2 11 | SUB R4 R3 R4 12 | BRZ ~+4 R4 13 | DEC R2 R2 14 | DEC R1 R1 15 | BNZ ~-5 R1 16 | DEC R1 R1 17 | RET 18 | -------------------------------------------------------------------------------- /urcl-explorer/URCLpp-compiler/Libraries/String/length.urcl: -------------------------------------------------------------------------------- 1 | BITS >= 8 2 | OUTS 1 3 | OPS 2 4 | REG 1 5 | 6 | LLOD R1 SP 1 7 | LOD R1 R1 8 | RET -------------------------------------------------------------------------------- /urcl-explorer/URCLpp-compiler/Libraries/String/print.urcl: -------------------------------------------------------------------------------- 1 | BITS >= 8 2 | OUTS 0 3 | OPS 1 4 | REG 3 5 | 6 | LLOD $1 SP 1 // label of input string 7 | LOD $2 $1 8 | INC $1 $1 9 | LOD $3 $1 10 | OUT %1 $3 // TEXT port 11 | INC $1 $1 12 | DEC $2 $2 13 | BNZ ~-4 $2 14 | RET 15 | -------------------------------------------------------------------------------- /urcl-explorer/URCLpp-compiler/Libraries/String/remove_char.urcl: -------------------------------------------------------------------------------- 1 | BITS >= 8 2 | OUTS 0 3 | OPS 3 4 | REG 5 5 | 6 | LLOD R1 SP 2 // Load source to save to stack 7 | JMP .saveStringStack 8 | 9 | .saveStringStack__return 10 | LOD R2 SP 11 | ADD R2 R2 2 12 | LLOD R1 SP R2 // Load destination to use in loop 13 | 14 | ADD R2 R2 2 15 | LLOD R4 SP R2 // Load index of character to be removed 16 | INC R4 R4 17 | 18 | POP R2 // Load size 19 | DEC R2 R2 20 | 21 | IMM R3 1 // Loop counter 22 | 23 | // Main loop 24 | .remove_char_Loop 25 | BRG .remove_char_LoopEnd R3 R2 // End loop if index is greater to size 26 | BRE .remove_char_LoopSkip R3 R4 // If our index is the index to be removed, skip this character 27 | 28 | .remove_char_LoopSkip__return 29 | // Write characters to destination 30 | POP R5 31 | LSTR R1 R3 R5 32 | INC R3 R3 33 | 34 | JMP .remove_char_Loop 35 | 36 | .remove_char_LoopSkip 37 | POP R0 38 | JMP .remove_char_LoopSkip__return 39 | 40 | .remove_char_LoopEnd 41 | STR R1 R2 // R2 already holds new string size since it was decremented earlier 42 | RET 43 | 44 | // Saves string to stack in reverse order 45 | // Inputs - 46 | // R1: const string* 47 | .saveStringStack 48 | LOD R2 R1 49 | 50 | MOV R4 R2 51 | .saveStringStackLoop 52 | BRZ .saveStringStackEnd R2 53 | LOD R3 R2 54 | PSH R3 55 | DEC R2 R2 56 | JMP .saveStringStackLoop 57 | 58 | .saveStringStackEnd 59 | PSH R4 // Push lenght at the end so it is POP-ed first 60 | JMP .saveStringStack__return 61 | -------------------------------------------------------------------------------- /urcl-explorer/URCLpp-compiler/Libraries/String/starts_with_char.urcl: -------------------------------------------------------------------------------- 1 | BITS >= 8 2 | OUTS 1 3 | OPS 3 4 | REG 3 5 | 6 | LLOD R2 SP 1 7 | LLOD R3 SP 2 8 | INC R1 R2 9 | LOD R1 R1 10 | SUB R1 R1 R3 11 | BRZ ~+2 R1 12 | IMM R1 -1 13 | RET 14 | -------------------------------------------------------------------------------- /urcl-explorer/URCLpp-compiler/Libraries/complex_hh/ADD.urcl: -------------------------------------------------------------------------------- 1 | BITS >= 4 2 | OPS 3 3 | REG 3 4 | 5 | POP R2 6 | POP R3 7 | PSH R2 8 | PSH R3 9 | AND R2 R2 @UHALF 10 | AND R3 R3 @UHALF 11 | ADD R1 R2 R3 12 | POP R2 13 | POP R3 14 | AND R2 R2 @LHALF 15 | AND R3 R3 @LHALF 16 | ADD R2 R2 R3 17 | AND R2 R2 @LHALF 18 | OR R1 R1 R2 19 | RET -------------------------------------------------------------------------------- /urcl-explorer/URCLpp-compiler/Libraries/complex_hh/DIV.urcl: -------------------------------------------------------------------------------- 1 | BITS >= 8 2 | OPS 3 3 | REG 5 4 | 5 | POP R2 6 | POP R3 7 | RSH R5 @BITS 8 | 9 | PSH R3 10 | PSH R2 11 | MOV R4, R3 12 | AND R2, R2, @UHALF 13 | AND R3, R3, @UHALF 14 | BSR R2, R2, R5 15 | MLT R1, R2, R3 16 | POP R3 17 | PSH R3 18 | AND R3, R3, @LHALF 19 | BSL R3, R3, R5 20 | NEG R4, R4 21 | AND R4, R4, @LHALF 22 | MLT R3, R3, R4 23 | SUB R1, R1, R3 24 | POP R3 25 | PSH R1 26 | PSH R3 27 | AND R3, R3, @UHALF 28 | MLT R3, R3, R4 29 | POP R4 30 | AND R4, R4, @LHALF 31 | AND R1, R1, @LHALF 32 | MLT R4, R4, R1 33 | ADD R3, R3, R4 34 | BSR R3, R3, R5 35 | POP R1 36 | OR R1, R1, R3 37 | POP R3 38 | AND R4, R3, @LHALF 39 | AND R3, R3, @UHALF 40 | BSR R3, R3, R5 41 | MLT R3, R3, R3 42 | MLT R4, R4, R4 43 | ADD R3, R3, R4 44 | AND R2, R1, @LHALF 45 | AND R1, R1, @UHALF 46 | DIV R2, R2, R3 47 | DIV R1, R1, R3 48 | OR R1, R1, R2 49 | RET -------------------------------------------------------------------------------- /urcl-explorer/URCLpp-compiler/Libraries/complex_hh/MLT.urcl: -------------------------------------------------------------------------------- 1 | BITS >= 8 2 | OPS 3 3 | REG 5 4 | 5 | POP R2 6 | POP R3 7 | RSH R5 @BITS 8 | 9 | PSH R2 10 | MOV R4, R3 11 | MOV R5, R3 12 | AND R2, R2, @UHALF 13 | AND R3, R3, @UHALF 14 | BSR R2, R2, R5 15 | MLT R1, R2, R3 16 | POP R3 17 | PSH R3 18 | AND R3, R3, @LHALF 19 | BSL R3, R3, R5 20 | AND R4, R4, @LHALF 21 | MLT R3, R3, R4 22 | SUB R1, R1, R3 23 | POP R3 24 | PSH R1 25 | PSH R3 26 | AND R3, R3, @UHALF 27 | MLT R3, R3, R4 28 | POP R4 29 | AND R4, R4, @LHALF 30 | AND R1, R1, @UHALF 31 | MLT R4, R4, R1 32 | ADD R3, R3, R4 33 | BSR R3, R3, R5 34 | POP R1 35 | OR R1, R1, R3 36 | RET -------------------------------------------------------------------------------- /urcl-explorer/URCLpp-compiler/Libraries/complex_hh/SUB.urcl: -------------------------------------------------------------------------------- 1 | BITS >= 4 2 | OPS 3 3 | REG 3 4 | 5 | POP R2 6 | POP R3 7 | PSH R2 8 | PSH R3 9 | AND R2, R2, @UHALF 10 | AND R3, R3, @UHALF 11 | ADD R1, R2, R3 12 | POP R2 13 | POP R3 14 | AND R2, R2, @LHALF 15 | AND R3, R3, @LHALF 16 | ADD R2, R2, R3 17 | AND R2, R2, @LHALF 18 | OR R1, R1, R2 19 | RET -------------------------------------------------------------------------------- /urcl-explorer/URCLpp-compiler/Libraries/complex_hh/about.txt: -------------------------------------------------------------------------------- 1 | This Library was provided by Verlio_H 2 | Updates and fixes to the original code were done to adapt it to library file format by Kuggo 3 | This Version of the complex library is the half half version. 1 reg contains both the imaginary and real part of the number in the upper half and lower half of the word. 4 | -------------------------------------------------------------------------------- /urcl-explorer/URCLpp-compiler/Libraries/complex_ww/ADD.urcl: -------------------------------------------------------------------------------- 1 | BITS >= 3 2 | OPS 4 3 | REG 4 4 | 5 | LLOD R1 SP 1 6 | LLOD R2 SP 2 7 | LLOD R3 SP 3 8 | LLOD R4 SP 4 9 | 10 | ADD R1 R1 R3 11 | ADD R2 R2 R4 12 | RET -------------------------------------------------------------------------------- /urcl-explorer/URCLpp-compiler/Libraries/complex_ww/DIV.urcl: -------------------------------------------------------------------------------- 1 | BITS >= 5 2 | OPS 4 3 | REG 4 4 | 5 | LLOD R1 SP 1 6 | LLOD R2 SP 2 7 | LLOD R3 SP 3 8 | LLOD R4 SP 4 9 | 10 | NEG R4 R4 11 | MLT R1 R1 R3 12 | MLT R2 R2 R4 13 | SUB R1 R1 R2 14 | LLOD R1 SP 1 15 | LLOD R2 SP 2 16 | PSH R1 17 | MLT R1 R1 R4 18 | MLT R2 R3 R2 19 | ADD R2 R1 R2 20 | POP R1 21 | NEG R4 R4 22 | MLT R3 R3 R3 23 | MLT R4 R4 R4 24 | ADD R3 R3 R4 25 | DIV R1 R1 R3 26 | DIV R2 R2 R3 27 | LLOD R3 SP 3 28 | OR R2 R2 R3 29 | RET -------------------------------------------------------------------------------- /urcl-explorer/URCLpp-compiler/Libraries/complex_ww/MLT.urcl: -------------------------------------------------------------------------------- 1 | BITS >= 4 2 | OPS 4 3 | REG 4 4 | 5 | LLOD R1 SP 1 6 | LLOD R2 SP 2 7 | LLOD R3 SP 3 8 | LLOD R4 SP 4 9 | 10 | MLT R1 R1 R3 11 | MLT R2 R2 R4 12 | SUB R1 R1 R2 13 | LLOD R1 SP 1 14 | LLOD R2 SP 2 15 | PSH R1 16 | MLT R1 R1 R4 17 | MLT R2 R3 R2 18 | ADD R2 R1 R2 19 | POP R1 20 | RET -------------------------------------------------------------------------------- /urcl-explorer/URCLpp-compiler/Libraries/complex_ww/SUB.urcl: -------------------------------------------------------------------------------- 1 | BITS >= 3 2 | OPS 4 3 | REG 4 4 | 5 | LLOD R1 SP 1 6 | LLOD R2 SP 2 7 | LLOD R3 SP 3 8 | LLOD R4 SP 4 9 | 10 | SUB R1 R1 R3 11 | SUB R2 R2 R4 12 | RET -------------------------------------------------------------------------------- /urcl-explorer/URCLpp-compiler/Libraries/complex_ww/about.txt: -------------------------------------------------------------------------------- 1 | This Library was provided by Verlio_H 2 | Updates and fixes to the original code were done to adapt it to library file format by Kuggo 3 | This Version of the complex library is the word word version. 2 regs make up the imaginary and real part of the numbers 4 | -------------------------------------------------------------------------------- /urcl-explorer/URCLpp-compiler/Libraries/example/sample.urcl: -------------------------------------------------------------------------------- 1 | BITS >= 8 2 | OPS 0 3 | REG 0 4 | 5 | // hello world 6 | 7 | OUT %1 'H' 8 | OUT %1 'e' 9 | OUT %1 'l' 10 | OUT %1 'l' 11 | OUT %1 'o' 12 | OUT %1 ' ' 13 | OUT %1 'W' 14 | OUT %1 'o' 15 | OUT %1 'r' 16 | OUT %1 'l' 17 | OUT %1 'd' 18 | -------------------------------------------------------------------------------- /urcl-explorer/URCLpp-compiler/Libraries/f32/f32_to_int.urcl: -------------------------------------------------------------------------------- 1 | //BITS >= 32 2 | @define @float R1 // const 3 | @define @exponent R2 // var 4 | @define @fraction R3 // out 5 | 6 | POP @float 7 | 8 | // get exponent 9 | BSR @exponent @float 23 10 | AND @exponent @exponent 0xff 11 | SUB @exponent 150 @exponent // 127 + 23 - E 12 | 13 | BGE .return_0 @exponent 23 14 | 15 | // get fraction 16 | AND @fraction @float 0x7fffff // lower 23 bits 17 | OR @fraction @fraction 0x800000 // add 1 to fraction 18 | 19 | BSR @fraction @fraction @exponent 20 | BRP .pos @float 21 | NEG @fraction @fraction 22 | .pos 23 | PSH @fraction 24 | RET 25 | 26 | .return_0 27 | PSH 0 28 | RET 29 | -------------------------------------------------------------------------------- /urcl-explorer/URCLpp-compiler/README.md: -------------------------------------------------------------------------------- 1 | # URCL-compiler 2 | All related to URCL++ files that compile it to URCL. 3 | URCL++ is amazing! change my mind :P 4 | Programming in low level and teaching newbs how assembly works was never this easy with urcl++. This new variation is meant to help the user programm more efficiently and allow for more complex features such as new advanced instructions, macros, smart typing, libraries, etc. Hopefully urclos can be written here B) 5 | Have a good day :) 6 | 7 | ~Kuggo 8 | 9 | ## Prerequisites 10 | - [Python 3](https://www.python.org/) 11 | 12 | ## Setup 13 | Clone the repo and its submodules 14 | ```cmd 15 | git clone --recurse-submodules 16 | ``` 17 | If you already cloned the repo but want to make sure all submodules are up to date run 18 | ```cmd 19 | git submodule update --init --recursive 20 | ``` 21 | 22 | ## Run 23 | Run the compiler by entering the following command in the terminal 24 | ```cmd 25 | python compiler2 [] 26 | ``` 27 | 28 | ## Install 29 | ### Windows 30 | Add the bin folder to your [Path environment variable](https://duckduckgo.com/?q=windows+add+to+path). 31 | Now (re)start the terminal and you can run the compiler anywhere simply by running: 32 | ```cmd 33 | urclpp [] 34 | ``` 35 | -------------------------------------------------------------------------------- /urcl-explorer/URCLpp-compiler/bin/urclpp.cmd: -------------------------------------------------------------------------------- 1 | python %~dp0/../compiler2.py %* 2 | -------------------------------------------------------------------------------- /urcl-explorer/URCLpp-compiler/bot.py: -------------------------------------------------------------------------------- 1 | import discord 2 | import random 3 | import sys 4 | from URCLpp import compiler 5 | from discord.ext import tasks, commands 6 | sys.path.insert(0, r'C:\Users\user\dir') 7 | 8 | 9 | client = commands.Bot(command_prefix='k!') 10 | client.remove_command('help') 11 | 12 | 13 | @client.event 14 | async def on_ready(): 15 | description = 'o JOGO' 16 | await client.change_presence(status=discord.Status.online, activity=discord.Game(name=description, type=3)) 17 | print('\33[6mbot is running') 18 | 19 | 20 | @client.command(aliases=['welp', 'HELP', 'Help', '?']) 21 | async def help(ctx): 22 | await ctx.send("""List of available commands: ``k!help``, ``k!8ball``, ``k!ping``, ``k!compile`` 23 | Don't thank me, thank my power supply""") 24 | 25 | 26 | @client.command() 27 | async def ping(ctx): 28 | await ctx.send(f'ping pog: {round(client.latency*1000)}ms') 29 | 30 | 31 | @client.command(aliases=['yeet', 'YEET', 'YEEEEEEEEET']) 32 | async def yeeter(ctx): 33 | await ctx.send('YEET') 34 | 35 | 36 | @client.command(aliases=['8ball']) 37 | async def _8ball(ctx, *, msg=''): 38 | if msg != '': 39 | if '?' in msg: 40 | answers = ['YEET', 'Yes', 'No', 'Idk', 'no u'] 41 | await ctx.send(f'{random.choice(answers)}') 42 | else: 43 | await ctx.send('Isso é uma pergunta para responder?') 44 | else: 45 | await ctx.send("Don't try to break the bot! >:(") 46 | 47 | 48 | '''@client.command() 49 | async def display_embed(ctx): 50 | embed = discord.Embed( 51 | title='Title', 52 | description="This is a description", 53 | colour=discord.Colour.blue() 54 | ) 55 | 56 | embed.set_footer(text="text at the bottom (footer)") 57 | embed.set_image(url="https://i.imgur.com/9dUECco.jpg") 58 | embed.set_thumbnail(url="https://i.imgur.com/Vh2wpHm.jpg") 59 | embed.set_author(name="EdgarVerdi", icon_url="https://i.imgur.com/EgLSWzE.jpg") 60 | embed.add_field(name="Field Name", value="Field Value", inline=False) 61 | embed.add_field(name="This is a test feature", value="HOW DO U KNOW THIS?!", inline=True) 62 | embed.add_field(name="Field Name", value="Field Value", inline=True) 63 | 64 | await ctx.send(embed=embed)''' 65 | 66 | 67 | @client.command(aliases=['compile']) 68 | async def comp(ctx, *, msg=''): 69 | beginning = timer() 70 | await ctx.send('Compiling...') 71 | start = msg.find('```') + 3 72 | end = msg.find('```', start) 73 | msg = msg[start:end] 74 | if msg == '': 75 | await ctx.send("if you want me to compile, give me just code! >:(") 76 | else: 77 | output = compiler2.compiler(msg) 78 | end = timer() 79 | total_time = end - beginning 80 | total_time = round(total_time * 1000) 81 | await ctx.send(f'Operation Completed in {total_time}ms!') 82 | await ctx.send(f'Output: \n{output}') 83 | 84 | 85 | token = 'token_name' 86 | client.run(token) 87 | -------------------------------------------------------------------------------- /urcl-explorer/URCLpp-compiler/debug_test.urcl: -------------------------------------------------------------------------------- 1 | IMPORT String 2 | @define @var R1 3 | ADD R1 R2 4 | INC @var 5 | LCAL String.print('e') 6 | IN R1 101 7 | LCAL String.char_at(R2 .label 2) 8 | DW "Hello World" 9 | DEC SP 10 | IF R1 == 1 11 | ADD R1 R1 R1 12 | IF R1 == 2 13 | INC @var 14 | ELIF R1 == 3 15 | DEC @var 16 | END 17 | ELSE 18 | ADD R2 R2 19 | END 20 | 21 | WHILE R1 22 | INC R1 23 | END 24 | -------------------------------------------------------------------------------- /urcl-explorer/bin/urcx-emu: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | node ../js/node/urcx-emu.js $@ 3 | -------------------------------------------------------------------------------- /urcl-explorer/bin/urcx-emu.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | node %~dp0/../js/node/urcx-emu.js %* 3 | -------------------------------------------------------------------------------- /urcl-explorer/editor/editor.css: -------------------------------------------------------------------------------- 1 | editor-window { 2 | display: flex; 3 | font-family: "monospace"; 4 | font-size: 1em; 5 | gap: 0.5em; 6 | overflow-x: auto; 7 | overflow-y: auto; 8 | width: 100%; 9 | height: 100%; 10 | white-space: pre; 11 | } 12 | editor-window .code { 13 | width: max-content; 14 | min-width: calc(100% - 4em); 15 | height: 100%; 16 | } 17 | editor-window .line-nrs { 18 | text-align: right; 19 | } 20 | editor-window .colors, editor-window .line-nrs, editor-window textarea { 21 | padding: 0.25ch; 22 | margin: 0.25ch; 23 | font-family: "JetBrains Mono", Consolas, "Courier New", monospace; 24 | font-size: 1em; 25 | line-height: 1em; 26 | } 27 | 28 | editor-window .colors, editor-window textarea { 29 | overflow: visible; 30 | border: none; 31 | white-space: pre; 32 | } 33 | editor-window textarea { 34 | background-color: black; 35 | color: transparent; 36 | caret-color: white; 37 | resize: none; 38 | min-width: 100%; 39 | min-height: 95%; 40 | } 41 | editor-window .colors { 42 | position: absolute; 43 | left: 0px; 44 | top: 0px; 45 | pointer-events: none; 46 | color: #f44747; 47 | height: 100%; 48 | } 49 | 50 | .pc-line { 51 | color: greenyellow; 52 | width: max-content; 53 | } 54 | .pc-line::before { 55 | content: "->"; 56 | } 57 | 58 | .opcode, .dw, .name { 59 | color: #569cd6; 60 | } 61 | .expansion, .comparator { 62 | color: white; 63 | } 64 | .number { 65 | color: #b5cea8; 66 | } 67 | .memory, .port { 68 | color: #4ec9b0; 69 | } 70 | .quote-char, .quote-string, .text { 71 | color: #ce9178; 72 | } 73 | .escape { 74 | color: #d7ba7d 75 | } 76 | .register { 77 | color: #9cdcfe; 78 | } 79 | .white, .white-inline { 80 | text-decoration: underline dashed rgb(69, 69, 69); 81 | } 82 | .macro { 83 | color: #c586c0; 84 | } 85 | .error { 86 | text-decoration: underline wavy red; 87 | } 88 | .comment, .comment-multi { 89 | color: #6a9955; 90 | } 91 | .label, .relative { 92 | color: #dcdcaa 93 | } 94 | 95 | .square-open, .square-close { 96 | color: white; 97 | } 98 | -------------------------------------------------------------------------------- /urcl-explorer/emulator/breaks.ts: -------------------------------------------------------------------------------- 1 | export enum Break { 2 | ONREAD = 1, ONWRITE = 2, 3 | } 4 | declare const __Break__: unique symbol; 5 | export type BreakFlag = number & {[__Break__]: T}; 6 | 7 | export function break_flag(flags: T[]): BreakFlag{ 8 | return flags.reduce((a,b)=>a|b, 0) as any; 9 | } -------------------------------------------------------------------------------- /urcl-explorer/emulator/devices/CHUNGUS devices/craftingRom.ts: -------------------------------------------------------------------------------- 1 | import { Device } from "../device.js"; 2 | import { IO_Port } from "../../instructions.js"; 3 | 4 | export class CraftingRom implements Device { 5 | recipes: any = { 6 | //smelting recipes 7 | ["4"]: Result.stone, 8 | ["5"]: Result.coal, 9 | ["9"]: Result.ironIngot, 10 | ["A"]: Result.glass, 11 | 12 | //crafting recipes 13 | ["770770000"]: Result.table, 14 | ["500000000"]: Result.plank, 15 | ["444404444"]: Result.furnace, 16 | ["777707777"]: Result.chest, 17 | ["700700000"]: Result.stick, 18 | 19 | ["777010010"]: Result.woodPick, 20 | ["444010010"]: Result.stonePick, 21 | ["DDD010010"]: Result.ironPick, 22 | 23 | ["770710010"]: Result.woodAxe, 24 | ["440410010"]: Result.stoneAxe, 25 | ["DD0D10010"]: Result.ironAxe, 26 | 27 | ["700100100"]: Result.woodShovel, 28 | ["400100100"]: Result.stoneShovel, 29 | ["D00100100"]: Result.ironShovel, 30 | 31 | ["700700100"]: Result.woodSword, 32 | ["400400100"]: Result.stoneSword, 33 | ["D00D00100"]: Result.ironSword, 34 | 35 | ["0D0D00000"]: Result.shears, 36 | 37 | }; 38 | station:Station = 0; 39 | currentRecipe:string = "000000000"; //use string because 9 hex values just barely don't fit into 32 bits 40 | inputs = { 41 | [IO_Port.CRAFTROM]: () => { 42 | if (this.station == Station.table) { 43 | for (let i = 0; i < 2; i++) { //shift the recipe as far left in the crafting grid as it will go 44 | if (this.currentRecipe[0] + this.currentRecipe[3] + this.currentRecipe[6] == "000") { 45 | this.currentRecipe = this.currentRecipe.substring(1) + "0"; 46 | } else { 47 | break; 48 | } 49 | } 50 | for (let i = 0; i < 2; i++) { //shift the recipe as far up in the crafting grid as it will go 51 | if (this.currentRecipe.substring(0, 3) == "000") { 52 | this.currentRecipe = this.currentRecipe.substring(3) + "000"; 53 | } else { 54 | break; 55 | } 56 | } 57 | this.currentRecipe = this.currentRecipe.toLocaleUpperCase(); 58 | if (this.currentRecipe in this.recipes) { 59 | return this.recipes[this.currentRecipe]; 60 | } else { 61 | return 0; 62 | } 63 | } else { 64 | this.currentRecipe = this.currentRecipe.toLocaleUpperCase(); 65 | if (this.currentRecipe[8] in this.recipes) { 66 | return this.recipes[this.currentRecipe[8]]; 67 | } else { 68 | return 0; 69 | } 70 | } 71 | } 72 | }; 73 | outputs = { 74 | [IO_Port.CRAFTROM]: (i: number) => { 75 | switch (i) { 76 | case Station.table: 77 | this.station = Station.table; 78 | break; 79 | case Station.furnace: 80 | this.station = Station.furnace; 81 | break; 82 | default: 83 | this.currentRecipe = this.currentRecipe.substring(1) + (i >> 4).toString(16); //simulate a shift register 84 | } 85 | } 86 | }; 87 | } 88 | 89 | enum Station { 90 | table = 0xFD, 91 | furnace = 0xFE, 92 | } 93 | 94 | enum Ingredient { 95 | air = 0x0, 96 | stick = 0x1, 97 | dirt = 0x2, 98 | stone = 0x3, 99 | cobble = 0x4, 100 | log = 0x5, 101 | leaves = 0x6, 102 | plank = 0x7, 103 | coal = 0x8, 104 | ironOre = 0x9, 105 | sand = 0xA, 106 | glass = 0xB, 107 | sapling = 0xC, 108 | ironIngot = 0xD, 109 | apple = 0xE, 110 | nonstackable = 0xF, 111 | } 112 | 113 | enum Result { 114 | stone = 0x31, 115 | plank = 0x74, 116 | table = 0xFD, 117 | coal = 0x81, 118 | furnace = 0xFE, 119 | ironIngot = 0xD1, 120 | stick = 0x14, 121 | chest = 0xFF, 122 | woodPick = 0xF0, 123 | woodAxe = 0x1F1, 124 | woodShovel = 0xF2, 125 | woodSword = 0xF3, 126 | stonePick = 0xF4, 127 | stoneAxe = 0xF5, 128 | stoneShovel = 0xF6, 129 | stoneSword = 0xF7, 130 | ironPick = 0xF8, 131 | ironAxe = 0xF9, 132 | ironShovel = 0xFA, 133 | ironSword = 0xFB, 134 | shears = 0xFC, 135 | glass = 0xB1, 136 | } -------------------------------------------------------------------------------- /urcl-explorer/emulator/devices/clock.ts: -------------------------------------------------------------------------------- 1 | import { IO_Port } from "../instructions.js"; 2 | import { Device } from "./device.js"; 3 | 4 | export class Clock implements Device { 5 | wait_end = 0 6 | time_out?: any; 7 | inputs = { 8 | [IO_Port.WAIT]: this.wait_in, 9 | } 10 | outputs = { 11 | [IO_Port.WAIT]: this.wait_out, 12 | } 13 | wait_out(time: number){ 14 | this.wait_end = Date.now() + time; 15 | } 16 | wait_in(callback: (value: number)=>void) { 17 | this.time_out = setTimeout(()=>callback(1), this.wait_end - Date.now()); 18 | } 19 | 20 | reset(){ 21 | this.wait_end = 0; 22 | if (this.time_out !== undefined){ 23 | clearTimeout(this.time_out); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /urcl-explorer/emulator/devices/console-io.ts: -------------------------------------------------------------------------------- 1 | import { IO_Port } from "../instructions.js"; 2 | import { f32_encode, f32_decode, Word, f16_decode, f16_encode } from "../util.js"; 3 | import { Device } from "./device.js"; 4 | 5 | function sepperate(str: string): string { 6 | let out = ""; 7 | const seg_len = 4; 8 | for (let i = 0; i < str.length; i += seg_len){ 9 | out += "_" + str.substring(i, i + seg_len); 10 | } 11 | if (out.startsWith("_")){ 12 | out = out.substring(1); 13 | } 14 | return out; 15 | } 16 | 17 | export class Console_IO implements Device { 18 | bits = 32; 19 | constructor( 20 | public input: { 21 | read: (callback: ()=>void) => void, 22 | text: string, 23 | }, 24 | public write: (value: string) => void, 25 | private _reset: () => void 26 | ){ 27 | } 28 | inputs = { 29 | [IO_Port.TEXT]: this.text_in, 30 | [IO_Port.NUMB]: this.numb_in, 31 | [IO_Port.FLOAT]: (cb:(n: number)=>void) => { 32 | if (this.bits >= 32){ 33 | this.numb_in(cb, s => f32_encode(Number(s))); 34 | } else if (this.bits >= 16){ 35 | this.numb_in(cb, s => f16_encode(Number(s))); 36 | } else { 37 | throw new Error(`8 bit floats are not supported`); 38 | } 39 | }, 40 | [IO_Port.FIXED]: (cb:(n: number)=>void) => { 41 | this.numb_in(cb, s => Math.floor(Number(s) * (2**(this.bits/2)))) 42 | } 43 | } 44 | outputs = { 45 | [IO_Port.TEXT]: this.text_out, 46 | [IO_Port.NUMB]: this.numb_out, 47 | [IO_Port.UINT]: this.numb_out, 48 | [IO_Port.HEX]: (v: number) => this.write(sepperate(v.toString(16).padStart(Math.ceil(this.bits/4), "0"))), 49 | [IO_Port.BIN]: (v: number) => this.write(sepperate(v.toString(2).padStart(this.bits, "0"))), 50 | [IO_Port.FLOAT]: (v: number) => { 51 | if (this.bits >= 32){ 52 | this.write(f32_decode(v).toString()); 53 | } else if (this.bits >= 16){ 54 | this.write(f16_decode(v).toString()); 55 | } else { 56 | throw new Error(`8 bit floats are not supported`); 57 | } 58 | }, 59 | [IO_Port.FIXED]: (v: number) => { 60 | this.write((v / (2**(this.bits/2))).toString()) 61 | }, 62 | [IO_Port.INT]: (v: number) => { 63 | const sign_bit = 2**(this.bits - 1); 64 | if (v & sign_bit){ 65 | v = (v & (sign_bit-1)) - sign_bit; 66 | } 67 | this.write(v.toString()); 68 | }, 69 | // \TODO: make specific implementations for these 70 | [IO_Port.ASCII]: this.text_out, 71 | [IO_Port.CHAR5]: this.text_out, 72 | [IO_Port.CHAR6]: this.text_out, 73 | [IO_Port.ASCII]: this.text_out, 74 | [IO_Port.UTF8]: this.text_out, 75 | [IO_Port.UTF16]: this.text_out, 76 | [IO_Port.UTF32]: this.text_out, 77 | } 78 | set_text(text: string){ 79 | this.input.text = text; 80 | } 81 | reset(){ 82 | this.input.text = ""; 83 | this._reset(); 84 | } 85 | text_in(callback: (value: Word) => void): undefined | number { 86 | if (this.input.text.length === 0){ 87 | this.input.read(()=>{ 88 | const char_code = this.input.text.codePointAt(0) ?? this.input.text.charCodeAt(0); 89 | this.input.text = this.input.text.slice(1); 90 | callback(char_code); 91 | }); 92 | return undefined 93 | } 94 | const char_code = this.input.text.charCodeAt(0); 95 | this.input.text = this.input.text.slice(1); 96 | return char_code; 97 | } 98 | text_out(value: Word): void { 99 | this.write(String.fromCodePoint(value)); 100 | } 101 | numb_in(callback: (value: Word) => void, parse = parseInt): undefined | number { 102 | if (this.input.text.length !== 0){ 103 | const num = parse(this.input.text); 104 | if (!Number.isNaN(num)){ 105 | this.input.text = this.input.text.trimStart().slice(num.toString().length); 106 | return num; 107 | } 108 | } 109 | this.input.read(()=>{ 110 | const num = this.numb_in(callback, parse); 111 | if (num !== undefined){ 112 | callback(num); 113 | } 114 | }); 115 | } 116 | numb_out(value: Word): void { 117 | this.write(""+value); 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /urcl-explorer/emulator/devices/device.ts: -------------------------------------------------------------------------------- 1 | import { IO_Port } from "../instructions"; 2 | 3 | export type Device_Input = ((callback: (value: number) => void) => void | number) | (() => number); 4 | export type Device_Output = (value: number) => void; 5 | export type Device_Reset = ()=>void; 6 | 7 | export interface Device_Host { 8 | add_io_device(device: Device): void 9 | } 10 | 11 | export interface Device { 12 | inputs?: {[K in IO_Port]?: Device_Input}, 13 | outputs?: {[K in IO_Port]?: Device_Output}, 14 | bits?: number, 15 | reset?: Device_Reset 16 | } 17 | -------------------------------------------------------------------------------- /urcl-explorer/emulator/devices/gamepad.ts: -------------------------------------------------------------------------------- 1 | import { IO_Port } from "../instructions.js"; 2 | import { Device } from "./device.js"; 3 | 4 | 5 | interface Game_Key { 6 | pad: number, 7 | key: Gamepad_Key 8 | } 9 | 10 | export interface Gamepad_Options { 11 | keymap?: Record 12 | } 13 | 14 | export enum Gamepad_Key { 15 | A, B, SELECT, START, LEFT, RIGHT, UP, DOWN 16 | } 17 | const {A, B, SELECT, START, LEFT, RIGHT, UP, DOWN} = Gamepad_Key; 18 | 19 | function k(key: number, pad = 0): Game_Key{ 20 | return {key, pad}; 21 | } 22 | 23 | export class Pad implements Device { 24 | keymap: Record; 25 | pads = [0] 26 | selected = 0 27 | constructor (options: Gamepad_Options = {}){ 28 | this.keymap = options.keymap ?? { 29 | keyk: k(A), keyj: k(B), keyn: k(START), keyv: k(SELECT), keya: k(LEFT), keyd: k(RIGHT), keyw: k(UP), keys: k(DOWN), 30 | }; 31 | addEventListener("keydown", this.onkeydown.bind(this)); 32 | addEventListener("keyup", this.onkeyup.bind(this)); 33 | } 34 | inputs = { 35 | [IO_Port.GAMEPAD]: () => this.pads[this.selected] ?? 0 36 | } 37 | outputs = { 38 | [IO_Port.GAMEPAD]: (i: number) => this.selected = i 39 | } 40 | 41 | private key(e: KeyboardEvent): Game_Key | undefined { 42 | return this.keymap[e.code.toLowerCase()] 43 | } 44 | private onkeydown(e: KeyboardEvent){ 45 | const k = this.key(e); 46 | if (k !== undefined){ 47 | this.pads[k.pad] |= 1 << k.key; 48 | } 49 | } 50 | private onkeyup(e: KeyboardEvent){ 51 | const k = this.key(e); 52 | if (k !== undefined){ 53 | this.pads[k.pad] &= ~(1 << k.key); 54 | } 55 | } 56 | } -------------------------------------------------------------------------------- /urcl-explorer/emulator/devices/keyboard.ts: -------------------------------------------------------------------------------- 1 | import { IO_Port } from "../instructions.js"; 2 | import { Device } from "./device.js"; 3 | 4 | export class Keyboard implements Device { 5 | bits: number = 8; 6 | down: Uint8Array = new Uint8Array(256); 7 | keymap: Record = usb; 8 | offset: number = 0; 9 | constructor (){ 10 | addEventListener("keydown", this.onkeydown.bind(this)); 11 | addEventListener("keyup", this.onkeyup.bind(this)); 12 | } 13 | inputs = { 14 | [IO_Port.KEY]: () => this.down.slice(this.offset, this.offset + this.bits) 15 | .reduceRight((acc, v) => (acc << 1) + v, 0), 16 | } 17 | outputs = { 18 | [IO_Port.KEY]: (i: number) => this.offset = i, 19 | } 20 | private key(k: string) { 21 | return this.keymap[k]; 22 | } 23 | private onkeydown(e: KeyboardEvent){ 24 | const k = this.key(e.code); 25 | if (k !== undefined){ 26 | this.down[k] = 1; 27 | } 28 | } 29 | private onkeyup(e: KeyboardEvent){ 30 | const k = this.key(e.code); 31 | if (k !== undefined){ 32 | this.down[k] = 0; 33 | } 34 | } 35 | } 36 | 37 | const digits = { 38 | Digit1: 1, 39 | Digit2: 2, 40 | Digit3: 3, 41 | Digit4: 4, 42 | Digit5: 5, 43 | Digit6: 6, 44 | Digit7: 7, 45 | Digit8: 8, 46 | Digit9: 9, 47 | Digit0: 10, 48 | } 49 | 50 | const usb = { 51 | KeyA: 0x04, 52 | KeyB: 0x05, 53 | KeyC: 0x06, 54 | KeyD: 0x07, 55 | KeyE: 0x08, 56 | KeyF: 0x09, 57 | KeyG: 0x0A, 58 | KeyH: 0x0B, 59 | KeyI: 0x0C, 60 | KeyJ: 0x0D, 61 | KeyK: 0x0E, 62 | KeyL: 0x0F, 63 | KeyM: 0x10, 64 | KeyN: 0x11, 65 | KeyO: 0x12, 66 | KeyP: 0x13, 67 | KeyQ: 0x14, 68 | KeyR: 0x15, 69 | KeyS: 0x16, 70 | KeyT: 0x17, 71 | KeyU: 0x18, 72 | KeyV: 0x19, 73 | KeyW: 0x1A, 74 | KeyX: 0x1B, 75 | KeyY: 0x1C, 76 | KeyZ: 0x1D, 77 | Digit1: 0x1E, 78 | Digit2: 0x1F, 79 | Digit3: 0x20, 80 | Digit4: 0x21, 81 | Digit5: 0x22, 82 | Digit6: 0x23, 83 | Digit7: 0x24, 84 | Digit8: 0x25, 85 | Digit9: 0x26, 86 | Digit0: 0x27, 87 | Enter: 0x28, 88 | Escape: 0x29, 89 | Backspace: 0x2A, 90 | Tab: 0x2B, 91 | Space: 0x2C, 92 | Minus: 0x2D, 93 | Equal: 0x2E, 94 | BracketLeft: 0x2F, 95 | BracketRight: 0x30, 96 | Backslash: 0x31, 97 | Semicolon: 0x33, 98 | Quote: 0x34, 99 | Backquote: 0x35, 100 | Comma: 0x36, 101 | Period: 0x37, 102 | Slash: 0x38, 103 | CapsLock: 0x39, 104 | F1: 0x3A, 105 | F2: 0x3B, 106 | F3: 0x3C, 107 | F4: 0x3D, 108 | F5: 0x3E, 109 | F6: 0x3F, 110 | F7: 0x40, 111 | F8: 0x41, 112 | F9: 0x42, 113 | F10: 0x43, 114 | F11: 0x44, 115 | F12: 0x45, 116 | PrintScreen: 0x46, 117 | ScrollLock: 0x47, 118 | Pause: 0x48, 119 | Insert: 0x49, 120 | Home: 0x4A, 121 | PageUp: 0x4B, 122 | Delete: 0x4C, 123 | End: 0x4D, 124 | PageDown: 0x4E, 125 | ArrowRight: 0x4F, 126 | ArrowLeft: 0x50, 127 | ArrowDown: 0x51, 128 | ArrowUp: 0x52, 129 | NumLock: 0x53, 130 | NumpadDivide: 0x54, 131 | NumpadMultiply: 0x55, 132 | NumpadSubtract: 0x56, 133 | NumpadAdd: 0x57, 134 | NumpadEnter: 0x58, 135 | Numpad1: 0x59, 136 | Numpad2: 0x5A, 137 | Numpad3: 0x5B, 138 | Numpad4: 0x5C, 139 | Numpad5: 0x5D, 140 | Numpad6: 0x5E, 141 | Numpad7: 0x5F, 142 | Numpad8: 0x60, 143 | Numpad9: 0x61, 144 | Numpad0: 0x62, 145 | NumpadDecimal: 0x63, 146 | IntlBackslash: 0x64, 147 | Power: 0x66, 148 | NumpadEqual: 0x67, 149 | F13: 0x68, 150 | F14: 0x69, 151 | F15: 0x6A, 152 | F16: 0x6B, 153 | F17: 0x6C, 154 | F18: 0x6D, 155 | F19: 0x6E, 156 | F20: 0x6F, 157 | F21: 0x70, 158 | F22: 0x71, 159 | F23: 0x72, 160 | F24: 0x73, 161 | Help: 0x75, 162 | ContextMenu: 0x76, 163 | Props: 0x76, 164 | Select: 0x77, 165 | BrowserStop: 0x78, 166 | MediaStop: 0x78, 167 | Again: 0x79, 168 | Undo: 0x7A, 169 | Copy: 0x7C, 170 | Paste: 0x7D, 171 | Find: 0x7E, 172 | AudioVolumeMute: 0x7F, 173 | VolumeMute: 0x7F, 174 | AudioVolumeUp: 0x80, 175 | AudioVolumeDown: 0x81, 176 | NumpadComma: 0x85, 177 | IntlRo: 0x87, 178 | IntlYen: 0x84, 179 | Lang1: 0x90, 180 | HangulMode: 0x90, 181 | Lang2: 0x91, 182 | Hanja: 0x91, 183 | Lang3: 0x92, 184 | Lang4: 0x93, 185 | Cancel: 0x9B, 186 | NumpadParenLeft: 0xB6, 187 | NumpadParenRight: 0xB7, 188 | ControlLeft: 0xE0, 189 | ShiftLeft: 0xE1, 190 | AltLeft: 0xE2, 191 | OSLeft: 0xE3, 192 | MetaLeft: 0xE3, 193 | ControlRight: 0xE4, 194 | ShiftRight: 0xE5, 195 | AltRight: 0xE6, 196 | OSRight: 0xE7, 197 | MetaRight: 0xE7 198 | }; -------------------------------------------------------------------------------- /urcl-explorer/emulator/devices/rng.ts: -------------------------------------------------------------------------------- 1 | import { IO_Port } from "../instructions.js"; 2 | import { Device } from "./device.js"; 3 | 4 | export class RNG implements Device { 5 | constructor(public bits: number = 8){} 6 | inputs = { 7 | [IO_Port.RNG]: () => 0| Math.random() * (0xffff_ffff >>> (32-this.bits)) 8 | }; 9 | } -------------------------------------------------------------------------------- /urcl-explorer/emulator/devices/sound.ts: -------------------------------------------------------------------------------- 1 | import { IO_Port } from "../instructions.js"; 2 | import { Device } from "./device.js"; 3 | 4 | const base_frequency = 92.499; 5 | 6 | const ramp_up = 0.005; 7 | const ramp_down = 0.01; 8 | 9 | class NoteBlock { 10 | oscillator: OscillatorNode; 11 | gain: GainNode; 12 | constructor(private ctx: AudioContext){ 13 | this.oscillator = this.ctx.createOscillator(); 14 | this.gain = this.ctx.createGain() 15 | this.gain.gain.value = 0 16 | this.gain.connect(this.ctx.destination); 17 | this.oscillator.connect(this.gain); 18 | this.oscillator.type = "square"; 19 | this.oscillator.start(); 20 | 21 | } 22 | play(note: number, length: number, cb: ()=>void){ 23 | if (this.ctx.state === "suspended"){ 24 | this.ctx.resume(); 25 | } 26 | this.oscillator.frequency.value = base_frequency * 2 ** (note/12); 27 | this.gain.gain.setTargetAtTime(0.1, this.ctx.currentTime, ramp_up); 28 | this.gain.gain.setTargetAtTime(0, this.ctx.currentTime + length*0.001, ramp_down); 29 | setTimeout(() => { 30 | cb(); 31 | }, length*0.1+ramp_down); 32 | } 33 | } 34 | 35 | export class Sound implements Device { 36 | ctx = new AudioContext(); 37 | blocks: NoteBlock[] = []; 38 | note: number = 0; 39 | play(note: number, length: number){ 40 | console.log(this.blocks.length, note, length); 41 | let block = this.blocks.pop(); 42 | if (!block){ 43 | block = new NoteBlock(this.ctx); 44 | } 45 | block.play(note, length, () => this.blocks.push(block as NoteBlock)); 46 | } 47 | constructor(){ 48 | } 49 | 50 | outputs = { 51 | [IO_Port.NOTE]: (v: number) => {this.note = v;}, 52 | [IO_Port.NLEG]: (v: number) => {this.play(this.note, v);} 53 | }; 54 | } 55 | -------------------------------------------------------------------------------- /urcl-explorer/emulator/devices/storage.ts: -------------------------------------------------------------------------------- 1 | import { IO_Port } from "../instructions.js"; 2 | import { read16, read32, write16, write32 } from "../util.js"; 3 | import { Device } from "./device.js"; 4 | 5 | export class Storage implements Device { 6 | private little_endian: boolean; 7 | constructor(public bits: number, data: ArrayBufferView, little_endian: boolean, size: number){ 8 | this.little_endian = little_endian; 9 | switch (bits){ 10 | case 8: { 11 | this.address_mask = 0xff; 12 | this.data = new Uint8Array(data.buffer, data.byteOffset, data.byteLength); 13 | if (size > this.data.length){ 14 | const old = this.data; 15 | this.data = new Uint8Array(size); 16 | this.data.set(old); 17 | } 18 | } break; 19 | case 16: { 20 | this.address_mask = 0xffff; 21 | this.data = read16(data, little_endian, size); 22 | } break; 23 | case 32: { 24 | this.address_mask = 0xffffffff; 25 | this.data = read32(data, little_endian, size); 26 | } break; 27 | default: throw new Error(`${bits} is not a supported word length for a Storage device`); 28 | } 29 | } 30 | public get_bytes(){ 31 | if (this.data instanceof Uint8Array){ 32 | return new Uint8Array(this.data.buffer, this.data.byteOffset, this.data.byteLength); 33 | } else if (this.data instanceof Uint16Array){ 34 | return write16(this.data, this.little_endian); 35 | } else if (this.data instanceof Uint32Array){ 36 | return write32(this.data, this.little_endian); 37 | } else { 38 | throw new Error(`${this.bits} is not a supported word length for a Storage device`); 39 | } 40 | } 41 | inputs = { 42 | [IO_Port.ADDR]: this.address_in, 43 | [IO_Port.PAGE]: this.page_in, 44 | [IO_Port.BUS]: this.bus_in, 45 | } 46 | outputs = { 47 | [IO_Port.ADDR]: this.address_out, 48 | [IO_Port.PAGE]: this.page_out, 49 | [IO_Port.BUS]: this.bus_out, 50 | } 51 | private data; 52 | private address_mask; 53 | private address = 0; 54 | address_out(v: number){ 55 | this.address = (this.address & ~this.address_mask) | v; 56 | } 57 | address_in(): number { 58 | return Math.min(2**this.bits, this.data.length - (this.address & ~this.address_mask)); 59 | } 60 | page_out(v: number){ 61 | this.address = (this.address & this.address_mask) | (v << this.bits); 62 | } 63 | page_in(): number { 64 | return Math.ceil(this.data.length / (2 ** this.bits)); 65 | } 66 | bus_out(v: number){ 67 | if (this.address > this.data.length){ 68 | throw Error(`Storage address out of bounds ${this.address} > ${this.data.length}`); 69 | } 70 | this.data[this.address] = v; 71 | } 72 | bus_in(): number{ 73 | if (this.address > this.data.length){ 74 | throw Error(`Storage address out of bounds ${this.address} > ${this.data.length}`); 75 | } 76 | return this.data[this.address]; 77 | } 78 | reset(){ 79 | // console.log("storage reset"); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /urcl-explorer/emulator/preprocessor.ts: -------------------------------------------------------------------------------- 1 | import { f32_encode, warn, Warning } from "./util.js"; 2 | 3 | const f32 = /\d*\.?\d*f32/g; 4 | 5 | export function preprocess(str: string, errors: Warning[]){ 6 | const macros: Record = {}; 7 | const lines = str.replaceAll("\r", "").split("\n"); 8 | let source = ""; 9 | for (let i = 0; i < lines.length; i++){ 10 | const line = lines[i].trim(); 11 | const [start, name, ...rest] = line.split(/[ \t]+/); 12 | if (start.toLowerCase() !== "@define"){ 13 | source += line + "\n"; 14 | continue; 15 | } 16 | if (!name){ 17 | errors.push(warn(i, `no name specified for macro`)); 18 | continue 19 | } 20 | if (macros[name]){ 21 | errors.push(warn(i, `redefinition of macro ${name}`)); 22 | continue; 23 | } 24 | macros[name] = rest.join(" "); 25 | } 26 | let last = ""; 27 | while (source !== last){ 28 | last = source; 29 | for (const [name, macro] of Object.entries(macros)){ 30 | source = source.replaceAll(name, macro); 31 | } 32 | } 33 | const matches = source.match(f32); 34 | if (matches) for (const match of matches){ 35 | const float = parseFloat(match.slice(0, -3)); 36 | if (Number.isNaN(float)){ 37 | errors.push(warn(-1, `${match} is not a number`)); 38 | continue; 39 | } 40 | const int = f32_encode(float); 41 | source = source.replace(match, int.toString()); 42 | } 43 | 44 | return source; 45 | } 46 | -------------------------------------------------------------------------------- /urcl-explorer/examples/aoc21/1-e.txt: -------------------------------------------------------------------------------- 1 | 199 2 | 200 3 | 208 4 | 210 5 | 200 6 | 207 7 | 240 8 | 269 9 | 260 10 | 263 -------------------------------------------------------------------------------- /urcl-explorer/examples/aoc21/1.1.urcl: -------------------------------------------------------------------------------- 1 | BITS == 16 2 | MINREG 8 3 | // count the number of times a depth measurement increases 4 | 5 | @define output r8 6 | @define last r4 7 | @define val r3 8 | 9 | IMM output 0 10 | IN last %NUMB 11 | .loop 12 | IN val %NUMB 13 | BLE .skip val last 14 | INC output output 15 | .skip 16 | MOV last val 17 | IN r1 %TEXT 18 | BNZ .loop r1 19 | 20 | OUT %NUMB output 21 | HLT 22 | 23 | -------------------------------------------------------------------------------- /urcl-explorer/examples/aoc21/1.2.urcl: -------------------------------------------------------------------------------- 1 | // count the number of times a depth measurement increases with a sliding average of 3 2 | BITS == 16 3 | MINREG 8 4 | @define output r8 5 | @define a r7 6 | @define b r6 7 | @define c r5 8 | @define last r4 9 | @define val r3 10 | 11 | IMM output 0 12 | IN a %NUMB 13 | IN b %NUMB 14 | IN c %NUMB 15 | MOV last a 16 | ADD last last b 17 | ADD last last c 18 | .loop 19 | MOV a b 20 | MOV b c 21 | IN c %NUMB 22 | MOV val a 23 | ADD val val b 24 | ADD val val c 25 | BLE .skip val last 26 | INC output output 27 | .skip 28 | MOV last val 29 | IN r1 %TEXT 30 | BNZ .loop r1 31 | 32 | OUT %NUMB output 33 | HLT 34 | 35 | -------------------------------------------------------------------------------- /urcl-explorer/examples/aoc21/2-e.txt: -------------------------------------------------------------------------------- 1 | forward 5 2 | down 5 3 | forward 8 4 | up 3 5 | down 8 6 | forward 2 -------------------------------------------------------------------------------- /urcl-explorer/examples/aoc21/2.1.urcl: -------------------------------------------------------------------------------- 1 | BITS == 32 2 | MINREG 8 3 | @define x r8 4 | @define y r7 5 | @define dir r6 6 | 7 | IMM x 0 8 | IMM y 0 9 | .loop 10 | IN r1 %TEXT 11 | BRZ .hlt r1 12 | BRE .dir r1 'f' 13 | BRE .dir r1 'u' 14 | BRE .dir r1 'n' 15 | SUB r2 r1 '0' 16 | BRG .loop r2 9 17 | BRE .f dir 'f' 18 | BRE .u dir 'u' 19 | BRE .d dir 'n' 20 | JMP .loop 21 | .dir 22 | MOV dir r1 23 | JMP .loop 24 | .f 25 | ADD x x r2 26 | JMP .loop 27 | .u 28 | SUB y y r2 29 | JMP .loop 30 | .d 31 | ADD y y r2 32 | JMP .loop 33 | .hlt 34 | MLT r1 x y 35 | OUT %NUMB r1 36 | HLT -------------------------------------------------------------------------------- /urcl-explorer/examples/aoc21/2.2.urcl: -------------------------------------------------------------------------------- 1 | BITS == 32 2 | MINREG 8 3 | @define x r8 4 | @define y r7 5 | @define dir r6 6 | @define aim r5 7 | IMM x 0 8 | IMM y 0 9 | IMM aim 0 10 | .loop 11 | IN r1 %TEXT 12 | BRZ .hlt r1 13 | BRE .dir r1 'f' 14 | BRE .dir r1 'u' 15 | BRE .dir r1 'n' 16 | SUB r2 r1 '0' 17 | BRG .loop r2 9 18 | BRE .f dir 'f' 19 | BRE .u dir 'u' 20 | BRE .d dir 'n' 21 | JMP .loop 22 | .dir 23 | MOV dir r1 24 | JMP .loop 25 | .f 26 | ADD x x r2 27 | MLT r1 aim r2 28 | ADD y y r1 29 | JMP .loop 30 | .u 31 | SUB aim aim r2 32 | JMP .loop 33 | .d 34 | ADD aim aim r2 35 | JMP .loop 36 | .hlt 37 | MLT r1 x y 38 | OUT %TEXT '\n' 39 | OUT %NUMB x 40 | OUT %TEXT ' ' 41 | OUT %NUMB y 42 | OUT %TEXT ' ' 43 | OUT %NUMB r1 44 | HLT -------------------------------------------------------------------------------- /urcl-explorer/examples/aoc21/3-e.txt: -------------------------------------------------------------------------------- 1 | 00100 2 | 11110 3 | 10110 4 | 10111 5 | 10101 6 | 01111 7 | 00111 8 | 11100 9 | 10000 10 | 11001 11 | 00010 12 | 01010 13 | -------------------------------------------------------------------------------- /urcl-explorer/examples/aoc21/3.1.urcl: -------------------------------------------------------------------------------- 1 | BITS == 32 2 | MINREG 8 3 | @define len r8 4 | @define bits_end r7 5 | @define bit r6 6 | @define half r5 7 | @define gamma r4 8 | @define epsilon r3 9 | 10 | IMM bit 0 11 | IMM len 0 12 | .read_loop 13 | IN r1 %TEXT 14 | BRE .0 r1 '0' 15 | BRE .1 r1 '1' 16 | BRE .le r1 '\n' 17 | BNZ .read_loop r1 18 | JMP .read_end 19 | .0 20 | INC bit bit 21 | JMP .read_loop 22 | .1 23 | LOD r1 bit 24 | INC r1 r1 25 | STR bit r1 26 | INC bit bit 27 | JMP .read_loop 28 | .le 29 | INC len len 30 | ADD bits_end .bits bit 31 | IMM bit 0 32 | JMP .read_loop 33 | .read_end 34 | 35 | IMM gamma 0 36 | DIV half len 2 37 | imm bit .bits 38 | .gamma_loop 39 | LSH gamma gamma 40 | LOD r1 bit 41 | BLE .skip r1 half 42 | INC gamma gamma 43 | .skip 44 | INC bit bit 45 | BRL .gamma_loop bit bits_end 46 | 47 | NOT epsilon gamma 48 | SUB r1 bits_end .bits 49 | BSL r1 1 r1 50 | DEC r1 r1 51 | AND epsilon epsilon r1 52 | 53 | OUT %NUMB gamma 54 | OUT %TEXT '\n' 55 | 56 | OUT %NUMB epsilon 57 | OUT %TEXT '\n' 58 | MLT r1 gamma epsilon 59 | OUT %NUMB r1 60 | 61 | HLT 62 | 63 | .bits 64 | DW 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 65 | -------------------------------------------------------------------------------- /urcl-explorer/examples/aoc21/3.2.urcl: -------------------------------------------------------------------------------- 1 | BITS == 32 2 | MINHEAP 2000 3 | MINREG 16 4 | @define input #0 5 | @define matches #1000 6 | @define len r16 7 | @define half r15 8 | @define clen r14 9 | @define val r13 10 | @define width r12 11 | @define bit r11 12 | @define flip r10 13 | @define i r9 14 | @define j r8 15 | @define count r7 16 | @define o2 r6 17 | @define co2 r5 18 | @define return r4 19 | 20 | IMM val 0 21 | IMM width 0 22 | IMM len 0 23 | .read_loop 24 | IN r1 %TEXT 25 | BRE .0 r1 '0' 26 | BRE .1 r1 '1' 27 | BRE .le r1 '\n' 28 | BNZ .read_loop r1 29 | JMP .read_end 30 | .0 31 | LSH val val 32 | INC bit bit 33 | JMP .read_loop 34 | .1 35 | LSH val val 36 | INC val val 37 | INC bit bit 38 | JMP .read_loop 39 | .le 40 | LSTR input len val 41 | MOV width bit 42 | INC len len 43 | IMM bit 0 44 | IMM val 0 45 | JMP .read_loop 46 | .read_end 47 | 48 | IMM flip 0 49 | CAL .fn 50 | MOV o2 return 51 | IMM flip 1 52 | CAL .fn 53 | MOV co2 return 54 | 55 | MLT r1 o2 co2 56 | OUT %NUMB r1 57 | OUT %TEXT 'e' 58 | HLT 59 | 60 | 61 | .fn 62 | IMM i 0 63 | .copy_loop 64 | LLOD r1 input i 65 | LSTR matches i r1 66 | INC i i 67 | BRL .copy_loop i len 68 | 69 | MOV bit width 70 | MOV clen len 71 | .bit_loop 72 | DEC bit bit 73 | INC half clen 74 | RSH half half 75 | 76 | IMM count 0 77 | IMM i 0 78 | .count_loop 79 | LLOD r1 matches i 80 | BSR r1 r1 bit 81 | AND r1 r1 1 82 | ADD count count r1 83 | INC i i 84 | BRL .count_loop i clen 85 | 86 | IMM r1 0 87 | SETGE r1 count half 88 | AND count r1 1 89 | XOR count count flip 90 | 91 | IMM i 0 92 | IMM j 0 93 | .filter_loop 94 | LLOD r1 matches i 95 | BSR r2 r1 bit 96 | AND r2 r2 1 97 | BNE .skip r2 count 98 | LSTR matches j r1 99 | INC j j 100 | .skip 101 | INC i i 102 | BRL .filter_loop i clen 103 | MOV clen j 104 | BLE .end clen 1 105 | BNZ .bit_loop bit 106 | .end 107 | LLOD return matches 0 108 | RET 109 | -------------------------------------------------------------------------------- /urcl-explorer/examples/urcl/add.urcl: -------------------------------------------------------------------------------- 1 | IMM $1 3 2 | IMM $2 5 3 | ADD $3 $1 $2 4 | -------------------------------------------------------------------------------- /urcl-explorer/examples/urcl/audio.urcl: -------------------------------------------------------------------------------- 1 | BITS == 16 2 | @DEFINE d16 100 // 16th note 3 | @DEFINE d8 200 // 8th note 4 | @DEFINE d4 400 // quarter note 5 | @DEFINE d2 800 // half note 6 | @DEFINE df 1600 // full note 7 | @DEFINE d3_8 600 // 3/8th note 8 | @DEFINE d6 267 // triplet 9 | @DEFINE fs 0 10 | @DEFINE g 1 11 | @DEFINE gs 2 12 | @DEFINE a 3 13 | @DEFINE as 4 14 | @DEFINE b 5 15 | @DEFINE c 6 16 | @DEFINE cs 7 17 | @DEFINE d 8 18 | @DEFINE ds 9 19 | @DEFINE e 10 20 | @DEFINE f 11 21 | 22 | @DEFINE fs1 12 23 | @DEFINE g1 13 24 | @DEFINE gs1 14 25 | @DEFINE a1 15 26 | @DEFINE as1 16 27 | @DEFINE b1 17 28 | @DEFINE c1 18 29 | @DEFINE d1 19 30 | @DEFINE ds1 20 31 | @DEFINE e1 21 32 | @DEFINE f1 22 33 | @DEFINE a2 23 34 | @DEFINE as2 24 35 | @DEFINE b2 25 36 | @DEFINE c2 26 37 | @DEFINE len r8 38 | @DEFINE i r7 39 | 40 | .bar0 41 | DW [ e1 d8 e1 d8 0 d8 e1 d8 0 d8 c1 d8 c1 d4 ] 42 | .bar1 43 | DW [ g1 d4 0 d4 g d4 0 d4 ] 44 | .bar2 45 | DW [ c1 d4 0 d8 g d4 0 d8 e d4 ] 46 | .bar3 47 | DW [ 0 d4 a1 d4 b1 d4 as1 d8 a1 d4 ] 48 | .bar4 49 | DW [ g d6 e1 d6 g1 d6 a2 d4 f1 d8 g1 d8 ] 50 | .bar5 51 | DW [ 0 d8 e1 d4 c1 d8 d1 d8 b1 d4 0 d8 ] // play from bar 2 again 52 | .bar6 53 | DW [ 0 d4 g1 d8 fs1 d8 ds1 d8 e1 d8 ] 54 | .bar7 55 | DW [ gs d8 a1 d8 c1 d8 0 d8 a1 d8 c1 d8 d1 d8 ] 56 | .bar8 57 | DW [ 0 d4 g1 d8 fs1 d8 ds1 d4 e1 d8 ] 58 | .bar9 59 | DW [ 0 d8 c2 d4 c2 d8 c2 d4 0 d8 ] 60 | .bar10 61 | DW [ 0 d4 g1 d8 fs1 d8 ds1 d4 e1 d8 ] 62 | .bar11 63 | DW [ 0 d8 gs d8 a1 d8 c1 d8 0 d8 a1 d8 c1 d8 d1 d8 ] 64 | .bar12 65 | DW [ 0 d4 ds1 d4 0 d8 d1 d4 0 d8 ] 66 | .bar13 67 | DW [ c1 d4 0 d2 0 d4 ] 68 | .bar14 69 | DW [ c1 d8 c1 d8 0 d8 c1 d8 0 d8 c1 d8 d1 d4 ] 70 | .end 71 | DW 72 | 73 | IMM i .bar0 74 | .loop 75 | LOD r1 i 76 | INC i i 77 | LOD len i 78 | INC i i 79 | OUT %NUMB r1 80 | OUT %TEXT ' ' 81 | OUT %NUMB len 82 | OUT %TEXT '\n' 83 | BRZ .br_wait r1 84 | OUT %NOTE r1 85 | CAL .play 86 | JMP .br_note 87 | .br_wait 88 | // BRZ .br_loop len len 89 | CAL .wait 90 | JMP .br_note 91 | // .br_loop 92 | // LOD r1 i 93 | // BRE 94 | // DEC r1 r1 95 | // STR i r1 96 | 97 | // INC i 98 | // LOD r2 i 99 | // INC i 100 | 101 | .br_note 102 | BRL .loop i .end 103 | OUT %TEXT 'H' 104 | HLT 105 | 106 | .play 107 | SUB r1 len 20 108 | OUT %NLEG r1 109 | OUT %WAIT len 110 | IN r0 %WAIT 111 | RET 112 | 113 | .wait 114 | OUT %WAIT len 115 | IN r0 %WAIT 116 | RET 117 | -------------------------------------------------------------------------------- /urcl-explorer/examples/urcl/debug.urcl: -------------------------------------------------------------------------------- 1 | @DEBUG r1 2 | @DEBUG ONREAD r2 3 | @DEBUG ONWRITE r3 4 | @DEBUG #0 5 | @DEBUG .array 6 | @DEBUG ONWRITE .array+1 7 | @DEBUG ONWRITE .array+2 8 | 9 | @DEBUG ONWRITE %NUMB 10 | @DEBUG %TEXT 11 | 12 | IMM r1 10 13 | IMM r2 r1 14 | IMM r3 r2 15 | IMM r2 #0 16 | STR #0 r2 17 | STR .array 5 18 | LOD r3 .array 19 | LLOD r1 .array 1 20 | LSTR .array 1 11 21 | LSTR .array 2 12 22 | LLOD .array 3 13 23 | 24 | @DEBUG 25 | OUT %NUMB '0' 26 | OUT %TEXT 'h' 27 | OUT %TEXT 'e' 28 | OUT %TEXT 'l' 29 | OUT %TEXT 'l' 30 | OUT %TEXT 'o' 31 | 32 | DW 33 | .array 34 | DW [ 0 1 2 3 4 ] -------------------------------------------------------------------------------- /urcl-explorer/examples/urcl/display-io.urcl: -------------------------------------------------------------------------------- 1 | BITS == 32 2 | 3 | IN r2 %X 4 | IMM r3 0 5 | IN r4 %Y 6 | OUT %BUFFER 1 7 | .y_loop 8 | OUT %Y r3 9 | IMM r1 0 10 | .x_loop 11 | OUT %X r1 12 | OUT %COLOR r1 13 | INC r1 r1 14 | BRL .x_loop r1 r2 15 | INC r3 r3 16 | BRL .y_loop r3 r4 17 | IMM r1 0 18 | IMM r3 0 19 | .loop1 20 | OUT %X r1 21 | OUT %Y r3 22 | OUT %COLOR 0 23 | INC r1 r1 24 | INC r3 r3 25 | BRL .loop1 r1 r2 26 | 27 | IMM r1 0 28 | IN r3 %Y 29 | DEC r3 r3 30 | .loop2 31 | OUT %X r1 32 | OUT %Y r3 33 | OUT %COLOR 7 34 | INC r1 r1 35 | DEC r3 r3 36 | BRL .loop2 r1 r2 37 | 38 | OUT %BUFFER 2 39 | -------------------------------------------------------------------------------- /urcl-explorer/examples/urcl/fib.urcl: -------------------------------------------------------------------------------- 1 | IMM $2 1 2 | IMM $3 1 3 | 4 | OUT %NUMB $2 5 | OUT %TEXT '\n' 6 | OUT %NUMB $3 7 | OUT %TEXT '\n' 8 | .loop 9 | ADD $2 $2 $3 10 | OUT %NUMB $2 11 | OUT %TEXT '\n' 12 | BRC .stop $2 $3 13 | ADD $3 $2 $3 14 | OUT %NUMB $3 15 | OUT %TEXT '\n' 16 | BNC .loop $2 $3 17 | .stop 18 | HLT 19 | -------------------------------------------------------------------------------- /urcl-explorer/examples/urcl/game.urcl: -------------------------------------------------------------------------------- 1 | MINREG 16 2 | @DEFINE key r16 3 | @DEFINE last r15 4 | @DEFINE down r14 5 | @DEFINE up r13 6 | @DEFINE x r12 7 | @DEFINE xl r11 8 | @DEFINE y r10 9 | @DEFINE yl r9 10 | @DEFINE vx r8 11 | @DEFINE vy r7 12 | @DEFINE vh r6 13 | @DEFINE speed 100 14 | @DEFINE jump -128 15 | @DEFINE g 4 16 | 17 | OUT %BUFFER 1 18 | .loop 19 | MOV last key 20 | IN key %GAMEPAD 21 | XOR down key last 22 | AND down down key 23 | 24 | XOR up key last 25 | AND up up last 26 | 27 | BRN .skip_skip vy 28 | BGE .skip_g vy 117 29 | .skip_skip 30 | ADD vy vy g 31 | .skip_g 32 | 33 | BRN .skip_stop vy 34 | BNE .skip_stop y 31 35 | IMM vy 0 36 | .skip_stop 37 | 38 | AND r1 down @UP // W 39 | BRZ .up r1 40 | IMM vy jump 41 | .up 42 | 43 | AND r1 down @DOWN // S 44 | BRZ .down r1 45 | OUT %TEXT 'v' 46 | .down 47 | 48 | IMM vx 0 49 | AND r1 key @LEFT // A 50 | BRZ .left r1 51 | NEG vx speed 52 | .left 53 | 54 | AND r1 key @RIGHT // D 55 | BRZ .right r1 56 | IMM vx speed 57 | .right 58 | 59 | AND r1 down @A // K 60 | BRZ .A r1 61 | OUT %TEXT 'A' 62 | .A 63 | 64 | AND r1 down @B // J 65 | BRZ .B r1 66 | OUT %TEXT 'B' 67 | .B 68 | 69 | AND r1 down @START // N 70 | BRZ .start r1 71 | OUT %TEXT '!' 72 | .start 73 | 74 | AND r1 down @SELECT // V 75 | BRZ .select r1 76 | OUT %TEXT '?' 77 | .select 78 | 79 | // add signed x velocity to x 80 | BNC .skip xl vx 81 | INC x x 82 | .skip 83 | BRP .negx vx 84 | ADD x x @MAX 85 | .negx 86 | ADD xl xl vx 87 | 88 | // add signed y velocity to y 89 | BNC .skip2 yl vy 90 | INC y y 91 | .skip2 92 | BRP .negy vy 93 | ADD y y @MAX 94 | .negy 95 | ADD yl yl vy 96 | 97 | OUT %X x 98 | OUT %Y y 99 | OUT %COLOR 0xff 100 | 101 | OUT %BUFFER 2 102 | OUT %BUFFER 0 103 | OUT %BUFFER 1 104 | 105 | OUT %WAIT 16 106 | IN r1 %WAIT 107 | JMP .loop -------------------------------------------------------------------------------- /urcl-explorer/examples/urcl/gamepad.urcl: -------------------------------------------------------------------------------- 1 | @DEFINE key r8 // contains which buttons are down 2 | @DEFINE last r7 // contains which bottons where down last frame 3 | @DEFINE down r6 // contains which buttons went down this frame 4 | @DEFINE up r5 // contains which buttons went up this frame 5 | 6 | 7 | .loop 8 | MOV last key 9 | IN key %GAMEPAD 10 | XOR down key last 11 | AND down down key 12 | 13 | XOR up key last 14 | AND up up last 15 | 16 | // the down registers contains all buttons that went down 17 | // so we AND it with the bit for UP to check if the UP button went down 18 | AND r1 down @UP // W 19 | BRZ .up r1 20 | OUT %TEXT '^' 21 | .up 22 | 23 | AND r1 down @DOWN // S 24 | BRZ .down r1 25 | OUT %TEXT 'v' 26 | .down 27 | 28 | AND r1 down @LEFT // A 29 | BRZ .left r1 30 | OUT %TEXT '<' 31 | .left 32 | 33 | AND r1 down @RIGHT // D 34 | BRZ .right r1 35 | OUT %TEXT '>' 36 | .right 37 | 38 | AND r1 down @A // K 39 | BRZ .A r1 40 | OUT %TEXT 'A' 41 | .A 42 | 43 | AND r1 down @B // J 44 | BRZ .B r1 45 | OUT %TEXT 'B' 46 | .B 47 | 48 | AND r1 down @START // N 49 | BRZ .start r1 50 | OUT %TEXT '!' 51 | .start 52 | 53 | AND r1 down @SELECT // V 54 | BRZ .select r1 55 | OUT %TEXT '?' 56 | .select 57 | 58 | OUT %WAIT 16 59 | IN r1 %WAIT 60 | JMP .loop -------------------------------------------------------------------------------- /urcl-explorer/examples/urcl/line.urcl: -------------------------------------------------------------------------------- 1 | MINREG 16 2 | @DEFINE ax r16 3 | @DEFINE ay r15 4 | @DEFINE bx r14 5 | @DEFINE by r13 6 | @DEFINE dx r12 7 | @DEFINE dy r11 8 | @DEFINE sx r10 9 | @DEFINE sy r9 10 | @DEFINE cx r8 11 | @DEFINE cy r7 12 | @DEFINE x r6 13 | @DEFINE y r5 14 | @DEFINE i r4 15 | 16 | OUT %BUFFER 1 17 | 18 | IMM ax 1 19 | IMM ay 31 20 | IMM bx 27 21 | IMM by 2 22 | CAL .draw_line 23 | OUT %BUFFER 2 24 | 25 | HLT 26 | 27 | .draw_line // in ax, ay, bx, by; var dx, dy, sx, sy, cx, cy, x, y, i 28 | MOV x ax 29 | MOV y ay 30 | 31 | OUT %X x 32 | OUT %Y y 33 | OUT %COLOR 255 34 | 35 | SUB dx bx ax 36 | IMM sx 1 37 | BGE .bx_ge_ax bx ax 38 | IMM sx -1 39 | SUB dx ax bx 40 | .bx_ge_ax 41 | 42 | BRE .draw_line_eq_y ay by 43 | 44 | SUB dy by ay 45 | IMM sy 1 46 | BGE .by_ge_ay by ay 47 | IMM sy -1 48 | SUB dy ay by 49 | .by_ge_ay 50 | 51 | BRE .draw_line_eq_x ax bx 52 | 53 | RSH cx dx // cx = dx >>> 2 54 | RSH cy dy // cy = dy >>> 2 55 | 56 | BRG .else dx dy // if dx < dy 57 | BGE .end dx dy 58 | INC cx cx // cx++ 59 | JMP .end // else if dx > dy 60 | .else // 61 | INC cy cy // cy++ 62 | .end 63 | 64 | ADD i dx dy 65 | .loop // for (i = dx+dy; i != 0; i--) 66 | BGE .cxg cy cx // if cy < cx 67 | SUB cx cx cy// cx -= cy 68 | IMM cy dy // cy = dy 69 | ADD x x sx // x += sx 70 | JMP .cxg_end 71 | .cxg // else 72 | SUB cy cy cx// cy -= cx 73 | IMM cx dx // cx = dx 74 | ADD y y sy // y += sy 75 | .cxg_end 76 | OUT %X x 77 | OUT %Y y 78 | OUT %COLOR 255 79 | DEC i i 80 | BNZ .loop i 81 | RET 82 | 83 | .draw_line_eq_y 84 | BRE .eq_y_ret ax bx 85 | .eq_y_loop 86 | ADD x x sx 87 | OUT %X x 88 | OUT %COLOR 255 89 | BNE .eq_y_loop x bx 90 | .eq_y_ret 91 | RET 92 | 93 | .draw_line_eq_x 94 | BRE .eq_x_ret ay by 95 | .eq_x_loop 96 | ADD y y sy 97 | OUT %Y y 98 | OUT %COLOR 255 99 | BNE .eq_x_loop y by 100 | .eq_x_ret 101 | RET -------------------------------------------------------------------------------- /urcl-explorer/examples/urcl/pallet-test.urcl: -------------------------------------------------------------------------------- 1 | BITS == 32 2 | 3 | IN r2 %X 4 | IMM r3 0 5 | IN r4 %Y 6 | OUT %BUFFER 1 7 | IMM r5 0 8 | .y_loop 9 | OUT %Y r3 10 | IMM r1 0 11 | .x_loop 12 | OUT %X r1 13 | OUT %COLOR r5 14 | INC r5 r5 15 | INC r1 r1 16 | BRL .x_loop r1 r2 17 | INC r3 r3 18 | BRL .y_loop r3 r4 19 | 20 | OUT %BUFFER 2 21 | -------------------------------------------------------------------------------- /urcl-explorer/examples/urcl/prime-sieve16.urcl: -------------------------------------------------------------------------------- 1 | BITS == 16 2 | MINHEAP 33_000 3 | @define n r8 4 | @define i r7 5 | 6 | OUT %NUMB 2 7 | OUT %TEXT '\n' 8 | 9 | IMM n 3 10 | 11 | .loop 12 | RSH r1 n 13 | LOD r1 r1 14 | BNZ .not_prime r1 15 | 16 | OUT %NUMB n 17 | OUT %TEXT '\n' 18 | LSH i n 19 | BLE .not_prime i n 20 | .loop2 21 | ADD i i n 22 | BEV .skip i 23 | RSH r1 i 24 | STR r1 1 25 | .skip 26 | BLE .not_prime i n 27 | BRL .loop2 i 65534 28 | 29 | .not_prime 30 | ADD n n 2 31 | BRL .loop n 65534 32 | -------------------------------------------------------------------------------- /urcl-explorer/examples/urcl/prime-sieve32.urcl: -------------------------------------------------------------------------------- 1 | BITS == 32 2 | 3 | MINHEAP 500_000 4 | @define max_prime 1_000_000 5 | @define n r8 6 | @define i r7 7 | @define a r6 8 | 9 | // not_prime: List[bool] = [False] * 500_000 10 | 11 | // print(2) 12 | OUT %NUMB 2 13 | OUT %TEXT '\n' 14 | 15 | // for n in range(3, max_prime, 2): 16 | IMM n 3 17 | .loop 18 | // if not_prime[n >> 1]: 19 | RSH r1 n 20 | LOD r1 r1 21 | // continue 22 | BNZ .not_prime r1 23 | 24 | // print(n) 25 | OUT %NUMB n 26 | OUT %TEXT '\n' 27 | // for i in range(n*3, 1_000_000, n*2): 28 | LSH a n 29 | ADD i n a 30 | BGE .not_prime i max_prime 31 | .loop2 32 | // not_prime[i >> 1] = True 33 | RSH r1 i 34 | STR r1 1 35 | ADD i i a 36 | BRL .loop2 i max_prime 37 | 38 | .not_prime 39 | ADD n n 2 40 | BRL .loop n max_prime 41 | -------------------------------------------------------------------------------- /urcl-explorer/examples/urcl/snake.urcl: -------------------------------------------------------------------------------- 1 | MINHEAP 2048 2 | BITS == 16 3 | MINREG 32 4 | 5 | 6 | @DEFINE key r32 7 | @DEFINE last r31 8 | @DEFINE down r30 9 | @DEFINE dx r29 10 | @DEFINE dy r28 11 | @DEFINE x r27 12 | @DEFINE y r26 13 | @DEFINE .tail #0 14 | @DEFINE i r25 15 | @DEFINE j r24 16 | @DEFINE l r23 17 | @DEFINE score r22 18 | @DEFINE wait r21 19 | @DEFINE tailmax 2047 20 | @DEFINE black 0 21 | @DEFINE body 11 22 | @DEFINE tail 3 23 | @DEFINE apple 8 24 | 25 | .end_text 26 | DW [ 18 'g' 'a' 'm' 'e' '-' 'o' 'v' 'e' 'r' '\n' 's' 'c' 'o' 'r' 'e' ':' ':' ] 27 | 28 | IMM dx 0 29 | IMM dy 1 30 | IMM score 5 31 | IMM l 0 32 | IMM i 0 33 | IMM j 0 34 | IMM down 0 35 | 36 | OUT %BUFFER 1 37 | 38 | OUT %COLOR 1 39 | 40 | CAL .apple 41 | 42 | MOV r1 x 43 | MOV r2 y 44 | CAL .push 45 | 46 | OUT %BUFFER 2 47 | .loop 48 | MOV last key 49 | IN key %GAMEPAD 50 | XOR r1 key last 51 | AND r1 r1 key 52 | OR down down r1 53 | 54 | INC wait wait 55 | BRL .skip_step wait 4 56 | CAL .step 57 | OUT %BUFFER 2 58 | IMM wait 0 59 | IMM down 0 60 | .skip_step 61 | 62 | OUT %WAIT 15 63 | IN r1 %WAIT 64 | JMP .loop 65 | 66 | .step 67 | AND r1 down @UP // W 68 | BRZ .up r1 69 | BGE .up dy @SMAX 70 | IMM dy -1 71 | IMM dx 0 72 | JMP .input_end 73 | .up 74 | 75 | AND r1 down @DOWN // S 76 | BRZ .down r1 77 | BRN .down dy 78 | IMM dy 1 79 | IMM dx 0 80 | JMP .input_end 81 | .down 82 | 83 | AND r1 down @LEFT // A 84 | BRZ .left r1 85 | BGE .left dx @SMAX 86 | IMM dy 0 87 | IMM dx -1 88 | JMP .input_end 89 | .left 90 | 91 | AND r1 down @RIGHT // D 92 | BRZ .right r1 93 | BRN .right dx 94 | IMM dy 0 95 | IMM dx 1 96 | .right 97 | .input_end 98 | 99 | ADD x x dx 100 | ADD y y dy 101 | AND x x 31 102 | AND y y 31 103 | OUT %X x 104 | OUT %Y y 105 | 106 | IN r1 %COLOR 107 | BRE .ok r1 black 108 | BRE .eat_apple r1 apple 109 | JMP .gameover 110 | .eat_apple 111 | ADD score score 5 112 | CAL .apple 113 | .ok 114 | 115 | OUT %X x 116 | OUT %Y y 117 | OUT %COLOR body 118 | 119 | CAL .peak_end 120 | OUT %X r1 121 | OUT %Y r2 122 | OUT %COLOR tail 123 | 124 | MOV r1 x 125 | MOV r2 y 126 | CAL .push 127 | 128 | BRL .skip l score 129 | CAL .shift 130 | OUT %X r1 131 | OUT %Y r2 132 | OUT %COLOR 0 133 | .skip 134 | RET 135 | 136 | .gameover 137 | IMM r1 .end_text 138 | CAL .print 139 | OUT %NUMB score 140 | HLT 141 | 142 | 143 | .push // out r1, r2 144 | LSTR .tail j r1 145 | INC j j 146 | LSTR .tail j r2 147 | INC j j 148 | AND j j tailmax 149 | INC l l 150 | RET 151 | 152 | .peak_end // out r1, r2 153 | DEC j j 154 | AND j j tailmax 155 | LLOD r2 .tail j 156 | DEC j j 157 | LLOD r1 .tail j 158 | ADD j j 2 159 | AND j j tailmax 160 | RET 161 | 162 | .shift // in r1, r2 163 | LLOD r1 .tail i 164 | INC i i 165 | LLOD r2 .tail i 166 | INC i i 167 | AND i i tailmax 168 | DEC l l 169 | RET 170 | 171 | .apple 172 | .apple_loop 173 | IN r1 %RNG 174 | AND r1 r1 31 175 | OUT %X r1 176 | IN r1 %RNG 177 | AND r1 r1 31 178 | OUT %Y r1 179 | IN r1 %COLOR 180 | BNE .apple_loop r1 black 181 | OUT %COLOR apple 182 | RET 183 | 184 | .print // in var r1 string*r, var r2, r3 185 | LOD r2 r1 186 | ADD r2 r2 r1 187 | INC r1 r1 188 | .print_sub // in var r1 char* start, in const r2 char* end, var r3 189 | .print_loop 190 | LOD r3 r1 191 | OUT %TEXT r3 192 | INC r1 r1 193 | BRL .print_loop r1 r2 194 | RET 195 | -------------------------------------------------------------------------------- /urcl-explorer/examples/urcl/snakeds.urcl: -------------------------------------------------------------------------------- 1 | MINHEAP 2048 2 | BITS == 16 3 | MINREG 32 4 | 5 | @DEFINE down r30 6 | @DEFINE dx r29 7 | @DEFINE dy r28 8 | @DEFINE x r27 9 | @DEFINE y r26 10 | @DEFINE .tail #0 11 | @DEFINE i r25 12 | @DEFINE j r24 13 | @DEFINE l r23 14 | @DEFINE score r22 15 | @DEFINE wait r21 16 | @DEFINE tailmax 2047 17 | @DEFINE black 0 18 | @DEFINE body 11 19 | @DEFINE tail 3 20 | @DEFINE apple 8 21 | 22 | .end_text 23 | DW [ 18 'g' 'a' 'm' 'e' '-' 'o' 'v' 'e' 'r' '\n' 's' 'c' 'o' 'r' 'e' ':' ':' ] 24 | 25 | IMM dx 0 26 | IMM dy 0 27 | IMM score 5 28 | IMM l 0 29 | IMM i 0 30 | IMM j 0 31 | IMM down 0 32 | 33 | OUT %BUFFER 1 34 | OUT %COLOR body 35 | OUT %BUFFER 2 36 | 37 | CAL .apple 38 | 39 | MOV r1 x 40 | MOV r2 y 41 | CAL .push 42 | 43 | .loop 44 | IN down %TEXT 45 | BRE .skip_step down '\n' 46 | CAL .step 47 | OUT %BUFFER 2 48 | .skip_step 49 | JMP .loop 50 | 51 | .step 52 | BNE .up down 'w' 53 | // BGE .up dy @SMAX 54 | IMM dy -1 55 | IMM dx 0 56 | JMP .input_end 57 | .up 58 | 59 | BNE .down down 's' 60 | // BRN .down dy 61 | IMM dy 1 62 | IMM dx 0 63 | JMP .input_end 64 | .down 65 | 66 | BNE .left down 'a' 67 | // BGE .left dx @SMAX 68 | IMM dy 0 69 | IMM dx -1 70 | JMP .input_end 71 | .left 72 | 73 | BNE .right down 'd' 74 | // BRN .right dx 75 | IMM dy 0 76 | IMM dx 1 77 | JMP .input_end 78 | .right 79 | RET 80 | .input_end 81 | 82 | ADD x x dx 83 | ADD y y dy 84 | AND x x 31 85 | AND y y 31 86 | OUT %X x 87 | OUT %Y y 88 | 89 | IN r1 %COLOR 90 | BRE .ok r1 black 91 | BRE .eat_apple r1 apple 92 | JMP .gameover 93 | .eat_apple 94 | ADD score score 5 95 | CAL .apple 96 | .ok 97 | 98 | OUT %X x 99 | OUT %Y y 100 | OUT %COLOR body 101 | 102 | CAL .peak_end 103 | OUT %X r1 104 | OUT %Y r2 105 | OUT %COLOR tail 106 | 107 | MOV r1 x 108 | MOV r2 y 109 | CAL .push 110 | 111 | BRL .skip l score 112 | CAL .shift 113 | OUT %X r1 114 | OUT %Y r2 115 | OUT %COLOR 0 116 | .skip 117 | RET 118 | 119 | .gameover 120 | IMM r1 .end_text 121 | CAL .print 122 | OUT %NUMB score 123 | HLT 124 | 125 | 126 | .push // out r1, r2 127 | LSTR .tail j r1 128 | INC j j 129 | LSTR .tail j r2 130 | INC j j 131 | AND j j tailmax 132 | INC l l 133 | RET 134 | 135 | .peak_end // out r1, r2 136 | DEC j j 137 | AND j j tailmax 138 | LLOD r2 .tail j 139 | DEC j j 140 | LLOD r1 .tail j 141 | ADD j j 2 142 | AND j j tailmax 143 | RET 144 | 145 | .shift // in r1, r2 146 | LLOD r1 .tail i 147 | INC i i 148 | LLOD r2 .tail i 149 | INC i i 150 | AND i i tailmax 151 | DEC l l 152 | RET 153 | 154 | .apple 155 | .apple_loop 156 | IN r1 %RNG 157 | AND r1 r1 31 158 | OUT %X r1 159 | IN r1 %RNG 160 | AND r1 r1 31 161 | OUT %Y r1 162 | IN r1 %COLOR 163 | BNE .apple_loop r1 black 164 | OUT %COLOR apple 165 | RET 166 | 167 | .print // in var r1 string*r, var r2, r3 168 | LOD r2 r1 169 | ADD r2 r2 r1 170 | INC r1 r1 171 | .print_sub // in var r1 char* start, in const r2 char* end, var r3 172 | .print_loop 173 | LOD r3 r1 174 | OUT %TEXT r3 175 | INC r1 r1 176 | BRL .print_loop r1 r2 177 | RET 178 | -------------------------------------------------------------------------------- /urcl-explorer/examples/urcl/sprites.urcl: -------------------------------------------------------------------------------- 1 | BITS == 32 2 | 3 | DW [ 1 2 3 4 5 ] 4 | .sprite 5 | DW [ 0 0 1 1 1 1 0 0 ] 6 | DW [ 0 1 1 1 1 1 1 0 ] 7 | DW [ 1 1 1 1 1 1 1 1 ] 8 | DW [ 1 1 1 1 1 1 1 1 ] 9 | DW [ 1 1 1 1 1 1 1 1 ] 10 | DW [ 1 1 1 1 1 1 1 1 ] 11 | DW [ 0 1 1 1 1 1 1 0 ] 12 | DW [ 0 0 1 1 1 1 0 0 ] 13 | 14 | IMM R1 .sprite 15 | IMM R2 8 // x 16 | IMM R3 1 // y 17 | IMM R4 1 // dir 18 | IN R7 %Y // screen height - ball height 19 | SUB R7 R7 8 20 | IN R8 %X // screen width 21 | 22 | 23 | 24 | .loop 25 | OUT %BUFFER 0 26 | OUT %BUFFER 1 27 | BGE .flip R3 R7 28 | BLE .flip R3 0 29 | JMP .dont_flip 30 | .flip 31 | NEG R4 R4 32 | .dont_flip 33 | ADD R3 R3 R4 34 | PSH R4 35 | PSH R5 36 | PSH R6 37 | cal .draw_sprite8x8 38 | POP R6 39 | POP R5 40 | POP R4 41 | OUT %BUFFER 2 42 | OUT %WAIT 100 43 | IN R6 %WAIT 44 | JMP .loop 45 | HLT 46 | 47 | 48 | // image: R1 const Bin[ 64 ]*, x: R2 const int, y: R3 const int, 49 | // src_x: var R4, src_y: var R5, src_i/color: var R6 50 | // screen_width: const R8 51 | .draw_sprite8x8 52 | IMM R5 0 53 | .loop_y 54 | ADD R5 R5 R3 55 | OUT %Y R5 56 | SUB R5 R5 R3 57 | IMM R4 0 58 | .loop_x 59 | ADD R4 R4 R2 60 | OUT %X R4 61 | SUB R4 R4 R2 62 | MLT R6 R5 8 63 | ADD R6 R6 R4 64 | ADD R6 R6 R1 65 | LOD R6 R6 66 | // OUT %NUMB R6 67 | OUT %COLOR R6 68 | INC R4 R4 69 | BLE .loop_x R4 7 70 | INC R5 R5 71 | BLE .loop_y R5 7 72 | RET 73 | -------------------------------------------------------------------------------- /urcl-explorer/examples/urcl/storage.urcl: -------------------------------------------------------------------------------- 1 | .string 2 | DW 1 3 | DW 2 4 | DW 3 5 | DW 4 6 | DW 5 7 | DW 6 8 | DW 7 9 | DW 8 10 | DW 9 11 | DW 10 12 | DW 11 13 | DW 12 14 | DW 13 15 | DW 0 16 | 17 | DEC r1 .string 18 | .loop 19 | INC r1 r1 20 | LOD r2 r1 21 | OUT %ADDR r1 22 | OUT %BUS r2 23 | BNZ .loop r2 24 | -------------------------------------------------------------------------------- /urcl-explorer/examples/urcl/tests.urcl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sammyuri/minecraft/976e84d3dc8142dd4cf8927036d0d5e54b79152e/urcl-explorer/examples/urcl/tests.urcl -------------------------------------------------------------------------------- /urcl-explorer/examples/urcl/text-io.urcl: -------------------------------------------------------------------------------- 1 | BITS == 8 2 | MINREG 8 3 | MINHEAP 16 4 | RUN ROM 5 | MINSTACK 8 6 | 7 | OUT %TEXT 'W' 8 | OUT %TEXT 'h' 9 | OUT %TEXT 'o' 10 | OUT %TEXT ' ' 11 | OUT %TEXT 'a' 12 | OUT %TEXT 'r' 13 | OUT %TEXT 'e' 14 | OUT %TEXT ' ' 15 | OUT %TEXT 'y' 16 | OUT %TEXT 'o' 17 | OUT %TEXT 'u' 18 | OUT %TEXT '?' 19 | OUT %TEXT ':' 20 | OUT %TEXT ' ' 21 | 22 | 23 | IMM $1 #0 24 | CAL .text_in 25 | OUT %TEXT '\n' 26 | OUT %TEXT 'H' 27 | OUT %TEXT 'e' 28 | OUT %TEXT 'l' 29 | OUT %TEXT 'l' 30 | OUT %TEXT 'o' 31 | OUT %TEXT ' ' 32 | IMM $1 #0 33 | CAL .text_out 34 | HLT 35 | 36 | .text_in // start: in $1 char*, ch: $2 var 37 | IN $2 %TEXT 38 | BRE .text_in_end $2 '\n' 39 | STR $1 $2 40 | INC $1 $1 41 | JMP .text_in 42 | .text_in_end 43 | STR $1 0 44 | RET 45 | .text_out // start: in $1 char*, ch: $2 var 46 | LOD $2 $1 47 | BRE .text_out_end $2 0 48 | OUT %TEXT $2 49 | INC $1 $1 50 | JMP .text_out 51 | .text_out_end 52 | RET 53 | 54 | -------------------------------------------------------------------------------- /urcl-explorer/img/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sammyuri/minecraft/976e84d3dc8142dd4cf8927036d0d5e54b79152e/urcl-explorer/img/favicon.png -------------------------------------------------------------------------------- /urcl-explorer/index.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: "unscii"; 3 | src: url("unscii-16.ttf") format("ttf") url("unscii-16.woff") format("woff"); 4 | } 5 | a { 6 | color: lightgrey; 7 | } 8 | a:visited { 9 | color: lightblue; 10 | } 11 | a:hover { 12 | color: white; 13 | } 14 | 15 | html, body { 16 | margin: 0; 17 | overflow: hidden; 18 | } 19 | body { 20 | --padding: 3ch; 21 | width: calc(100vw - var(--padding)*2); 22 | height: calc(100vh - var(--padding)*2); 23 | padding: var(--padding); 24 | } 25 | main { 26 | display: flex; 27 | gap: 2rem; 28 | flex-grow: 1; 29 | width: 100%; 30 | height: 100%; 31 | } 32 | main > * { 33 | display: flex; 34 | flex-direction: column; 35 | width: max-content; 36 | height: 100%; 37 | flex-basis: 100%; 38 | overflow-x: hidden; 39 | overflow-y: auto; 40 | } 41 | canvas { 42 | background-color: black; 43 | image-rendering: crisp-edges; 44 | image-rendering: pixelated; 45 | border: 0.1rem solid rgb(53, 53, 53); 46 | } 47 | canvas:fullscreen { 48 | border: none; 49 | } 50 | 51 | 52 | html { 53 | font-family: "unscii"; 54 | background: #111; 55 | color: #EEE; 56 | } 57 | 58 | textarea { 59 | background-color: #444; 60 | color: #FFF; 61 | border: 0px; 62 | font-family: "unscii"; 63 | } 64 | 65 | #stdout { 66 | height: 200px; 67 | width: 200px; 68 | overflow: scroll; 69 | background: #000; 70 | color: #FFF; 71 | font-family: "unscii"; 72 | display: block; 73 | white-space: pre; 74 | resize: auto; 75 | } 76 | 77 | #stdin { 78 | background: #444; 79 | color: #fff; 80 | font-family: unscii; 81 | border: 0px; 82 | } 83 | 84 | button { 85 | background: #444; 86 | color: #EEE; 87 | font-family: unscii; 88 | width: 20%; 89 | border: 0px; 90 | filter: brightness(75%); 91 | } 92 | button:hover { 93 | filter: brightness(85%); 94 | } 95 | button:disabled { 96 | filter: brightness(40%); 97 | } 98 | button:active { 99 | filter: brightness(100%); 100 | } 101 | 102 | input { 103 | font-family: unscii; 104 | background: #444; 105 | color: #FFF; 106 | border: 0; 107 | } 108 | 109 | /* Chrome, Safari, Edge, Opera */ 110 | input::-webkit-outer-spin-button, 111 | input::-webkit-inner-spin-button { 112 | -webkit-appearance: none; 113 | margin: 0; 114 | } 115 | 116 | /* Firefox */ 117 | input[type=number] { 118 | -moz-appearance: textfield; 119 | } 120 | 121 | select { 122 | background-color: #444; 123 | color: #EEE; 124 | font-family: unscii; 125 | border: 0px; 126 | } 127 | 128 | #compile-and-run-button { 129 | background: #0D0; 130 | color: #111; 131 | } 132 | 133 | #compile-and-reset-button { 134 | background: #F00; 135 | color: #111; 136 | } 137 | 138 | #pause-button { 139 | background: #66B6FF; 140 | color: #111; 141 | } 142 | 143 | :disabled { 144 | color: #AAA; 145 | } 146 | -------------------------------------------------------------------------------- /urcl-explorer/js/emulator/breaks.js: -------------------------------------------------------------------------------- 1 | export var Break; 2 | (function (Break) { 3 | Break[Break["ONREAD"] = 1] = "ONREAD"; 4 | Break[Break["ONWRITE"] = 2] = "ONWRITE"; 5 | })(Break || (Break = {})); 6 | export function break_flag(flags) { 7 | return flags.reduce((a, b) => a | b, 0); 8 | } 9 | //# sourceMappingURL=breaks.js.map -------------------------------------------------------------------------------- /urcl-explorer/js/emulator/breaks.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"breaks.js","sourceRoot":"","sources":["../../emulator/breaks.ts"],"names":[],"mappings":"AAAA,MAAM,CAAN,IAAY,KAEX;AAFD,WAAY,KAAK;IACb,qCAAU,CAAA;IAAE,uCAAW,CAAA;AAC3B,CAAC,EAFW,KAAK,KAAL,KAAK,QAEhB;AAID,MAAM,UAAU,UAAU,CAAkB,KAAU;IAClD,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAC,CAAC,EAAC,EAAE,CAAA,CAAC,GAAC,CAAC,EAAE,CAAC,CAAQ,CAAC;AAC9C,CAAC"} -------------------------------------------------------------------------------- /urcl-explorer/js/emulator/devices/clock.js: -------------------------------------------------------------------------------- 1 | import { IO_Port } from "../instructions.js"; 2 | export class Clock { 3 | wait_end = 0; 4 | time_out; 5 | inputs = { 6 | [IO_Port.WAIT]: this.wait_in, 7 | }; 8 | outputs = { 9 | [IO_Port.WAIT]: this.wait_out, 10 | }; 11 | wait_out(time) { 12 | this.wait_end = Date.now() + time; 13 | } 14 | wait_in(callback) { 15 | this.time_out = setTimeout(() => callback(1), this.wait_end - Date.now()); 16 | } 17 | reset() { 18 | this.wait_end = 0; 19 | if (this.time_out !== undefined) { 20 | clearTimeout(this.time_out); 21 | } 22 | } 23 | } 24 | //# sourceMappingURL=clock.js.map -------------------------------------------------------------------------------- /urcl-explorer/js/emulator/devices/clock.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"clock.js","sourceRoot":"","sources":["../../../emulator/devices/clock.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAG7C,MAAM,OAAO,KAAK;IACd,QAAQ,GAAG,CAAC,CAAA;IACZ,QAAQ,CAAO;IACf,MAAM,GAAG;QACL,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,OAAO;KAC/B,CAAA;IACD,OAAO,GAAG;QACN,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,QAAQ;KAChC,CAAA;IACD,QAAQ,CAAC,IAAY;QACjB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;IACtC,CAAC;IACD,OAAO,CAAC,QAA+B;QACnC,IAAI,CAAC,QAAQ,GAAG,UAAU,CAAC,GAAE,EAAE,CAAA,QAAQ,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;IAC5E,CAAC;IAED,KAAK;QACD,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC;QAClB,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS,EAAC;YAC5B,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;SAC/B;IACL,CAAC;CACJ"} -------------------------------------------------------------------------------- /urcl-explorer/js/emulator/devices/console-io.js: -------------------------------------------------------------------------------- 1 | import { IO_Port } from "../instructions.js"; 2 | import { f32_encode, f32_decode, f16_decode, f16_encode } from "../util.js"; 3 | function sepperate(str) { 4 | let out = ""; 5 | const seg_len = 4; 6 | for (let i = 0; i < str.length; i += seg_len) { 7 | out += "_" + str.substring(i, i + seg_len); 8 | } 9 | if (out.startsWith("_")) { 10 | out = out.substring(1); 11 | } 12 | return out; 13 | } 14 | export class Console_IO { 15 | input; 16 | write; 17 | _reset; 18 | bits = 32; 19 | constructor(input, write, _reset) { 20 | this.input = input; 21 | this.write = write; 22 | this._reset = _reset; 23 | } 24 | inputs = { 25 | [IO_Port.TEXT]: this.text_in, 26 | [IO_Port.NUMB]: this.numb_in, 27 | [IO_Port.FLOAT]: (cb) => { 28 | if (this.bits >= 32) { 29 | this.numb_in(cb, s => f32_encode(Number(s))); 30 | } 31 | else if (this.bits >= 16) { 32 | this.numb_in(cb, s => f16_encode(Number(s))); 33 | } 34 | else { 35 | throw new Error(`8 bit floats are not supported`); 36 | } 37 | }, 38 | [IO_Port.FIXED]: (cb) => { 39 | this.numb_in(cb, s => Math.floor(Number(s) * (2 ** (this.bits / 2)))); 40 | } 41 | }; 42 | outputs = { 43 | [IO_Port.TEXT]: this.text_out, 44 | [IO_Port.NUMB]: this.numb_out, 45 | [IO_Port.UINT]: this.numb_out, 46 | [IO_Port.HEX]: (v) => this.write(sepperate(v.toString(16).padStart(Math.ceil(this.bits / 4), "0"))), 47 | [IO_Port.BIN]: (v) => this.write(sepperate(v.toString(2).padStart(this.bits, "0"))), 48 | [IO_Port.FLOAT]: (v) => { 49 | if (this.bits >= 32) { 50 | this.write(f32_decode(v).toString()); 51 | } 52 | else if (this.bits >= 16) { 53 | this.write(f16_decode(v).toString()); 54 | } 55 | else { 56 | throw new Error(`8 bit floats are not supported`); 57 | } 58 | }, 59 | [IO_Port.FIXED]: (v) => { 60 | this.write((v / (2 ** (this.bits / 2))).toString()); 61 | }, 62 | [IO_Port.INT]: (v) => { 63 | const sign_bit = 2 ** (this.bits - 1); 64 | if (v & sign_bit) { 65 | v = (v & (sign_bit - 1)) - sign_bit; 66 | } 67 | this.write(v.toString()); 68 | }, 69 | //\TODO: make specific implementations for these 70 | [IO_Port.ASCII]: this.text_out, 71 | [IO_Port.CHAR5]: this.text_out, 72 | [IO_Port.CHAR6]: this.text_out, 73 | [IO_Port.ASCII]: this.text_out, 74 | [IO_Port.UTF8]: this.text_out, 75 | [IO_Port.UTF16]: this.text_out, 76 | [IO_Port.UTF32]: this.text_out, 77 | }; 78 | set_text(text) { 79 | this.input.text = text; 80 | } 81 | reset() { 82 | this.input.text = ""; 83 | this._reset(); 84 | } 85 | text_in(callback) { 86 | if (this.input.text.length === 0) { 87 | this.input.read(() => { 88 | const char_code = this.input.text.codePointAt(0) ?? this.input.text.charCodeAt(0); 89 | this.input.text = this.input.text.slice(1); 90 | callback(char_code); 91 | }); 92 | return undefined; 93 | } 94 | const char_code = this.input.text.charCodeAt(0); 95 | this.input.text = this.input.text.slice(1); 96 | return char_code; 97 | } 98 | text_out(value) { 99 | this.write(String.fromCodePoint(value)); 100 | } 101 | numb_in(callback, parse = parseInt) { 102 | if (this.input.text.length !== 0) { 103 | const num = parse(this.input.text); 104 | if (!Number.isNaN(num)) { 105 | this.input.text = this.input.text.trimStart().slice(num.toString().length); 106 | return num; 107 | } 108 | } 109 | this.input.read(() => { 110 | const num = this.numb_in(callback, parse); 111 | if (num !== undefined) { 112 | callback(num); 113 | } 114 | }); 115 | } 116 | numb_out(value) { 117 | this.write("" + value); 118 | } 119 | } 120 | //# sourceMappingURL=console-io.js.map -------------------------------------------------------------------------------- /urcl-explorer/js/emulator/devices/device.js: -------------------------------------------------------------------------------- 1 | export {}; 2 | //# sourceMappingURL=device.js.map -------------------------------------------------------------------------------- /urcl-explorer/js/emulator/devices/device.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"device.js","sourceRoot":"","sources":["../../../emulator/devices/device.ts"],"names":[],"mappings":""} -------------------------------------------------------------------------------- /urcl-explorer/js/emulator/devices/gamepad.js: -------------------------------------------------------------------------------- 1 | import { IO_Port } from "../instructions.js"; 2 | export var Gamepad_Key; 3 | (function (Gamepad_Key) { 4 | Gamepad_Key[Gamepad_Key["A"] = 0] = "A"; 5 | Gamepad_Key[Gamepad_Key["B"] = 1] = "B"; 6 | Gamepad_Key[Gamepad_Key["SELECT"] = 2] = "SELECT"; 7 | Gamepad_Key[Gamepad_Key["START"] = 3] = "START"; 8 | Gamepad_Key[Gamepad_Key["LEFT"] = 4] = "LEFT"; 9 | Gamepad_Key[Gamepad_Key["RIGHT"] = 5] = "RIGHT"; 10 | Gamepad_Key[Gamepad_Key["UP"] = 6] = "UP"; 11 | Gamepad_Key[Gamepad_Key["DOWN"] = 7] = "DOWN"; 12 | })(Gamepad_Key || (Gamepad_Key = {})); 13 | const { A, B, SELECT, START, LEFT, RIGHT, UP, DOWN } = Gamepad_Key; 14 | function k(key, pad = 0) { 15 | return { key, pad }; 16 | } 17 | export class Pad { 18 | keymap; 19 | pads = [0]; 20 | selected = 0; 21 | constructor(options = {}) { 22 | this.keymap = options.keymap ?? { 23 | keyk: k(A), keyj: k(B), keyn: k(START), keyv: k(SELECT), keya: k(LEFT), keyd: k(RIGHT), keyw: k(UP), keys: k(DOWN), 24 | }; 25 | addEventListener("keydown", this.onkeydown.bind(this)); 26 | addEventListener("keyup", this.onkeyup.bind(this)); 27 | } 28 | inputs = { 29 | [IO_Port.GAMEPAD]: () => this.pads[this.selected] ?? 0 30 | }; 31 | outputs = { 32 | [IO_Port.GAMEPAD]: (i) => this.selected = i 33 | }; 34 | key(e) { 35 | return this.keymap[e.code.toLowerCase()]; 36 | } 37 | onkeydown(e) { 38 | const k = this.key(e); 39 | if (k !== undefined) { 40 | this.pads[k.pad] |= 1 << k.key; 41 | } 42 | } 43 | onkeyup(e) { 44 | const k = this.key(e); 45 | if (k !== undefined) { 46 | this.pads[k.pad] &= ~(1 << k.key); 47 | } 48 | } 49 | } 50 | //# sourceMappingURL=gamepad.js.map -------------------------------------------------------------------------------- /urcl-explorer/js/emulator/devices/gamepad.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"gamepad.js","sourceRoot":"","sources":["../../../emulator/devices/gamepad.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAa7C,MAAM,CAAN,IAAY,WAEX;AAFD,WAAY,WAAW;IACnB,uCAAC,CAAA;IAAE,uCAAC,CAAA;IAAE,iDAAM,CAAA;IAAE,+CAAK,CAAA;IAAE,6CAAI,CAAA;IAAE,+CAAK,CAAA;IAAE,yCAAE,CAAA;IAAE,6CAAI,CAAA;AAC9C,CAAC,EAFW,WAAW,KAAX,WAAW,QAEtB;AACD,MAAM,EAAC,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,EAAC,GAAG,WAAW,CAAC;AAEjE,SAAS,CAAC,CAAC,GAAW,EAAE,GAAG,GAAG,CAAC;IAC3B,OAAO,EAAC,GAAG,EAAE,GAAG,EAAC,CAAC;AACtB,CAAC;AAED,MAAM,OAAO,GAAG;IACZ,MAAM,CAA2B;IACjC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAA;IACV,QAAQ,GAAG,CAAC,CAAA;IACZ,YAAa,UAA2B,EAAE;QACtC,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI;YAC5B,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC;SACrH,CAAC;QACF,gBAAgB,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QACvD,gBAAgB,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IACvD,CAAC;IACD,MAAM,GAAG;QACL,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;KACzD,CAAA;IACD,OAAO,GAAG;QACN,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,GAAG,CAAC;KACtD,CAAA;IAEO,GAAG,CAAC,CAAgB;QACxB,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAA;IAC5C,CAAC;IACO,SAAS,CAAC,CAAgB;QAC9B,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACtB,IAAI,CAAC,KAAK,SAAS,EAAC;YAChB,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC;SAClC;IACL,CAAC;IACO,OAAO,CAAC,CAAgB;QAC5B,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACtB,IAAI,CAAC,KAAK,SAAS,EAAC;YAChB,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;SACrC;IACL,CAAC;CACJ"} -------------------------------------------------------------------------------- /urcl-explorer/js/emulator/devices/keyboard.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"keyboard.js","sourceRoot":"","sources":["../../../emulator/devices/keyboard.ts"],"names":[],"mappings":"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"} -------------------------------------------------------------------------------- /urcl-explorer/js/emulator/devices/rng.js: -------------------------------------------------------------------------------- 1 | import { IO_Port } from "../instructions.js"; 2 | export class RNG { 3 | bits; 4 | constructor(bits = 8) { 5 | this.bits = bits; 6 | } 7 | inputs = { 8 | [IO_Port.RNG]: () => 0 | Math.random() * (0xffff_ffff >>> (32 - this.bits)) 9 | }; 10 | } 11 | //# sourceMappingURL=rng.js.map -------------------------------------------------------------------------------- /urcl-explorer/js/emulator/devices/rng.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"rng.js","sourceRoot":"","sources":["../../../emulator/devices/rng.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAG7C,MAAM,OAAO,GAAG;IACO;IAAnB,YAAmB,OAAe,CAAC;QAAhB,SAAI,GAAJ,IAAI,CAAY;IAAE,CAAC;IACtC,MAAM,GAAG;QACL,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,GAAE,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,WAAW,KAAK,CAAC,EAAE,GAAC,IAAI,CAAC,IAAI,CAAC,CAAC;KAC3E,CAAC;CACL"} -------------------------------------------------------------------------------- /urcl-explorer/js/emulator/devices/sound.js: -------------------------------------------------------------------------------- 1 | import { IO_Port } from "../instructions.js"; 2 | const base_frequency = 92.499; 3 | const ramp_up = 0.005; 4 | const ramp_down = 0.01; 5 | class NoteBlock { 6 | ctx; 7 | oscillator; 8 | gain; 9 | constructor(ctx) { 10 | this.ctx = ctx; 11 | this.oscillator = this.ctx.createOscillator(); 12 | this.gain = this.ctx.createGain(); 13 | this.gain.gain.value = 0; 14 | this.gain.connect(this.ctx.destination); 15 | this.oscillator.connect(this.gain); 16 | this.oscillator.type = "square"; 17 | this.oscillator.start(); 18 | } 19 | play(note, length, cb) { 20 | if (this.ctx.state === "suspended") { 21 | this.ctx.resume(); 22 | } 23 | this.oscillator.frequency.value = base_frequency * 2 ** (note / 12); 24 | this.gain.gain.setTargetAtTime(0.1, this.ctx.currentTime, ramp_up); 25 | this.gain.gain.setTargetAtTime(0, this.ctx.currentTime + length * 0.001, ramp_down); 26 | setTimeout(() => { 27 | cb(); 28 | }, length * 0.1 + ramp_down); 29 | } 30 | } 31 | export class Sound { 32 | ctx = new AudioContext(); 33 | blocks = []; 34 | note = 0; 35 | play(note, length) { 36 | console.log(this.blocks.length, note, length); 37 | let block = this.blocks.pop(); 38 | if (!block) { 39 | block = new NoteBlock(this.ctx); 40 | } 41 | block.play(note, length, () => this.blocks.push(block)); 42 | } 43 | constructor() { 44 | } 45 | outputs = { 46 | [IO_Port.NOTE]: (v) => { this.note = v; }, 47 | [IO_Port.NLEG]: (v) => { this.play(this.note, v); } 48 | }; 49 | } 50 | //# sourceMappingURL=sound.js.map -------------------------------------------------------------------------------- /urcl-explorer/js/emulator/devices/sound.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"sound.js","sourceRoot":"","sources":["../../../emulator/devices/sound.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAG7C,MAAM,cAAc,GAAG,MAAM,CAAC;AAE9B,MAAM,OAAO,GAAG,KAAK,CAAC;AACtB,MAAM,SAAS,GAAG,IAAI,CAAC;AAEvB,MAAM,SAAS;IAGS;IAFpB,UAAU,CAAiB;IAC3B,IAAI,CAAW;IACf,YAAoB,GAAiB;QAAjB,QAAG,GAAH,GAAG,CAAc;QACjC,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;QAC9C,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,CAAA;QACjC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAA;QACxB,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QACxC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnC,IAAI,CAAC,UAAU,CAAC,IAAI,GAAG,QAAQ,CAAC;QAChC,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;IAE5B,CAAC;IACD,IAAI,CAAC,IAAY,EAAE,MAAc,EAAE,EAAY;QAC3C,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,KAAK,WAAW,EAAC;YAC/B,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC;SACrB;QACD,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,KAAK,GAAG,cAAc,GAAG,CAAC,IAAI,CAAC,IAAI,GAAC,EAAE,CAAC,CAAC;QAClE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QACnE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,WAAW,GAAG,MAAM,GAAC,KAAK,EAAE,SAAS,CAAC,CAAC;QAClF,UAAU,CAAC,GAAG,EAAE;YACZ,EAAE,EAAE,CAAC;QACT,CAAC,EAAE,MAAM,GAAC,GAAG,GAAC,SAAS,CAAC,CAAC;IAC7B,CAAC;CACJ;AAED,MAAM,OAAO,KAAK;IACd,GAAG,GAAG,IAAI,YAAY,EAAE,CAAC;IACzB,MAAM,GAAgB,EAAE,CAAC;IACzB,IAAI,GAAW,CAAC,CAAC;IACjB,IAAI,CAAC,IAAY,EAAE,MAAc;QAC7B,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;QAC9C,IAAI,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC;QAC9B,IAAI,CAAC,KAAK,EAAC;YACP,KAAK,GAAG,IAAI,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;SACnC;QACD,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAkB,CAAC,CAAC,CAAC;IACzE,CAAC;IACD;IACA,CAAC;IAED,OAAO,GAAG;QACN,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAS,EAAE,EAAE,GAAE,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,CAAA,CAAC;QAC/C,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAS,EAAE,EAAE,GAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAA,CAAC;KAC5D,CAAC;CACL"} -------------------------------------------------------------------------------- /urcl-explorer/js/emulator/devices/storage.js: -------------------------------------------------------------------------------- 1 | import { IO_Port } from "../instructions.js"; 2 | import { read16, read32, write16, write32 } from "../util.js"; 3 | export class Storage { 4 | bits; 5 | little_endian; 6 | constructor(bits, data, little_endian, size) { 7 | this.bits = bits; 8 | this.little_endian = little_endian; 9 | switch (bits) { 10 | case 8: 11 | { 12 | this.address_mask = 0xff; 13 | this.data = new Uint8Array(data.buffer, data.byteOffset, data.byteLength); 14 | if (size > this.data.length) { 15 | const old = this.data; 16 | this.data = new Uint8Array(size); 17 | this.data.set(old); 18 | } 19 | } 20 | break; 21 | case 16: 22 | { 23 | this.address_mask = 0xffff; 24 | this.data = read16(data, little_endian, size); 25 | } 26 | break; 27 | case 32: 28 | { 29 | this.address_mask = 0xffffffff; 30 | this.data = read32(data, little_endian, size); 31 | } 32 | break; 33 | default: throw new Error(`${bits} is not a supported word length for a Storage device`); 34 | } 35 | } 36 | get_bytes() { 37 | if (this.data instanceof Uint8Array) { 38 | return new Uint8Array(this.data.buffer, this.data.byteOffset, this.data.byteLength); 39 | } 40 | else if (this.data instanceof Uint16Array) { 41 | return write16(this.data, this.little_endian); 42 | } 43 | else if (this.data instanceof Uint32Array) { 44 | return write32(this.data, this.little_endian); 45 | } 46 | else { 47 | throw new Error(`${this.bits} is not a supported word length for a Storage device`); 48 | } 49 | } 50 | inputs = { 51 | [IO_Port.ADDR]: this.address_in, 52 | [IO_Port.PAGE]: this.page_in, 53 | [IO_Port.BUS]: this.bus_in, 54 | }; 55 | outputs = { 56 | [IO_Port.ADDR]: this.address_out, 57 | [IO_Port.PAGE]: this.page_out, 58 | [IO_Port.BUS]: this.bus_out, 59 | }; 60 | data; 61 | address_mask; 62 | address = 0; 63 | address_out(v) { 64 | this.address = (this.address & ~this.address_mask) | v; 65 | } 66 | address_in() { 67 | return Math.min(2 ** this.bits, this.data.length - (this.address & ~this.address_mask)); 68 | } 69 | page_out(v) { 70 | this.address = (this.address & this.address_mask) | (v << this.bits); 71 | } 72 | page_in() { 73 | return Math.ceil(this.data.length / (2 ** this.bits)); 74 | } 75 | bus_out(v) { 76 | if (this.address > this.data.length) { 77 | throw Error(`Storage address out of bounds ${this.address} > ${this.data.length}`); 78 | } 79 | this.data[this.address] = v; 80 | } 81 | bus_in() { 82 | if (this.address > this.data.length) { 83 | throw Error(`Storage address out of bounds ${this.address} > ${this.data.length}`); 84 | } 85 | return this.data[this.address]; 86 | } 87 | reset() { 88 | // console.log("storage reset"); 89 | } 90 | } 91 | //# sourceMappingURL=storage.js.map -------------------------------------------------------------------------------- /urcl-explorer/js/emulator/devices/storage.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"storage.js","sourceRoot":"","sources":["../../../emulator/devices/storage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC7C,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAG9D,MAAM,OAAO,OAAO;IAEG;IADX,aAAa,CAAU;IAC/B,YAAmB,IAAY,EAAE,IAAqB,EAAE,aAAsB,EAAE,IAAY;QAAzE,SAAI,GAAJ,IAAI,CAAQ;QAC3B,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;QACnC,QAAQ,IAAI,EAAC;YACT,KAAK,CAAC;gBAAE;oBACJ,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;oBACzB,IAAI,CAAC,IAAI,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;oBAC1E,IAAI,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAC;wBACxB,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC;wBACtB,IAAI,CAAC,IAAI,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC;wBACjC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;qBACtB;iBACJ;gBAAC,MAAM;YACR,KAAK,EAAE;gBAAE;oBACL,IAAI,CAAC,YAAY,GAAG,MAAM,CAAC;oBAC3B,IAAI,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,EAAE,aAAa,EAAE,IAAI,CAAC,CAAC;iBACjD;gBAAC,MAAM;YACR,KAAK,EAAE;gBAAE;oBACL,IAAI,CAAC,YAAY,GAAG,UAAU,CAAC;oBAC/B,IAAI,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,EAAE,aAAa,EAAE,IAAI,CAAC,CAAC;iBACjD;gBAAC,MAAM;YACR,OAAO,CAAC,CAAC,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,sDAAsD,CAAC,CAAC;SAC3F;IACL,CAAC;IACM,SAAS;QACZ,IAAI,IAAI,CAAC,IAAI,YAAY,UAAU,EAAC;YAChC,OAAO,IAAI,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;SACvF;aAAM,IAAI,IAAI,CAAC,IAAI,YAAY,WAAW,EAAC;YACxC,OAAO,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;SACjD;aAAM,IAAI,IAAI,CAAC,IAAI,YAAY,WAAW,EAAC;YACxC,OAAO,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;SACjD;aAAM;YACH,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,CAAC,IAAI,sDAAsD,CAAC,CAAC;SACvF;IACL,CAAC;IACD,MAAM,GAAG;QACL,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,UAAU;QAC/B,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,OAAO;QAC5B,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,MAAM;KAC7B,CAAA;IACD,OAAO,GAAG;QACN,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,WAAW;QAChC,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,QAAQ;QAC7B,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,OAAO;KAC9B,CAAA;IACO,IAAI,CAAC;IACL,YAAY,CAAC;IACb,OAAO,GAAG,CAAC,CAAC;IACpB,WAAW,CAAC,CAAS;QACjB,IAAI,CAAC,OAAO,GAAG,CAAC,IAAI,CAAC,OAAO,GAAG,CAAC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;IAC3D,CAAC;IACD,UAAU;QACN,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,IAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,OAAO,GAAG,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC;IAC1F,CAAC;IACD,QAAQ,CAAC,CAAS;QACd,IAAI,CAAC,OAAO,GAAG,CAAC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC;IACzE,CAAC;IACD,OAAO;QACH,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAC1D,CAAC;IACD,OAAO,CAAC,CAAS;QACb,IAAI,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAC;YAChC,MAAM,KAAK,CAAC,iCAAiC,IAAI,CAAC,OAAO,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;SACtF;QACD,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAChC,CAAC;IACD,MAAM;QACF,IAAI,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAC;YAChC,MAAM,KAAK,CAAC,iCAAiC,IAAI,CAAC,OAAO,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;SACtF;QACD,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACnC,CAAC;IACD,KAAK;QACD,gCAAgC;IACpC,CAAC;CACJ"} -------------------------------------------------------------------------------- /urcl-explorer/js/emulator/preprocessor.js: -------------------------------------------------------------------------------- 1 | import { f32_encode, warn } from "./util.js"; 2 | const f32 = /\d*\.?\d*f32/g; 3 | export function preprocess(str, errors) { 4 | const macros = {}; 5 | const lines = str.replaceAll("\r", "").split("\n"); 6 | let source = ""; 7 | for (let i = 0; i < lines.length; i++) { 8 | const line = lines[i].trim(); 9 | const [start, name, ...rest] = line.split(/[ \t]+/); 10 | if (start.toLowerCase() !== "@define") { 11 | source += line + "\n"; 12 | continue; 13 | } 14 | if (!name) { 15 | errors.push(warn(i, `no name specified for macro`)); 16 | continue; 17 | } 18 | if (macros[name]) { 19 | errors.push(warn(i, `redefinition of macro ${name}`)); 20 | continue; 21 | } 22 | macros[name] = rest.join(" "); 23 | } 24 | let last = ""; 25 | while (source !== last) { 26 | last = source; 27 | for (const [name, macro] of Object.entries(macros)) { 28 | source = source.replaceAll(name, macro); 29 | } 30 | } 31 | const matches = source.match(f32); 32 | if (matches) 33 | for (const match of matches) { 34 | const float = parseFloat(match.slice(0, -3)); 35 | if (Number.isNaN(float)) { 36 | errors.push(warn(-1, `${match} is not a number`)); 37 | continue; 38 | } 39 | const int = f32_encode(float); 40 | source = source.replace(match, int.toString()); 41 | } 42 | return source; 43 | } 44 | //# sourceMappingURL=preprocessor.js.map -------------------------------------------------------------------------------- /urcl-explorer/js/emulator/preprocessor.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"preprocessor.js","sourceRoot":"","sources":["../../emulator/preprocessor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,IAAI,EAAW,MAAM,WAAW,CAAC;AAEtD,MAAM,GAAG,GAAG,eAAe,CAAC;AAE5B,MAAM,UAAU,UAAU,CAAC,GAAW,EAAE,MAAiB;IACrD,MAAM,MAAM,GAA2B,EAAE,CAAC;IAC1C,MAAM,KAAK,GAAG,GAAG,CAAC,UAAU,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACnD,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAC;QAClC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC7B,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QACpD,IAAI,KAAK,CAAC,WAAW,EAAE,KAAK,SAAS,EAAC;YAClC,MAAM,IAAI,IAAI,GAAG,IAAI,CAAC;YACtB,SAAS;SACZ;QACD,IAAI,CAAC,IAAI,EAAC;YACN,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,6BAA6B,CAAC,CAAC,CAAC;YACpD,SAAQ;SACX;QACD,IAAI,MAAM,CAAC,IAAI,CAAC,EAAC;YACb,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,yBAAyB,IAAI,EAAE,CAAC,CAAC,CAAC;YACtD,SAAS;SACZ;QACD,MAAM,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;KACjC;IACD,IAAI,IAAI,GAAG,EAAE,CAAC;IACd,OAAO,MAAM,KAAK,IAAI,EAAC;QACnB,IAAI,GAAG,MAAM,CAAC;QACd,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAC;YAC/C,MAAM,GAAG,MAAM,CAAC,UAAU,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;SAC3C;KACJ;IACD,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAClC,IAAI,OAAO;QAAE,KAAK,MAAM,KAAK,IAAI,OAAO,EAAC;YACrC,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;YAC7C,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,EAAC;gBACpB,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,KAAK,kBAAkB,CAAC,CAAC,CAAC;gBAClD,SAAS;aACZ;YACD,MAAM,GAAG,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;YAC9B,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC;SAClD;IAED,OAAO,MAAM,CAAC;AAClB,CAAC"} -------------------------------------------------------------------------------- /urcl-explorer/js/node/args.js: -------------------------------------------------------------------------------- 1 | import * as path from "path"; 2 | import { enum_from_str, enum_strings } from "../emulator/util.js"; 3 | export function parse_argv(argv, defs) { 4 | if (argv.length < 2) { 5 | throw new Error(`Argv needs at least 2 elements but got [${argv}]`); 6 | } 7 | const command = argv[0] + " " + path.relative("./", argv[1]); 8 | const args = []; 9 | const flags = Object.assign({}, defs); 10 | for (let i = 2; i < argv.length; i++) { 11 | const arg = argv[i]; 12 | if (!arg.startsWith("-")) { 13 | args.push(arg); 14 | continue; 15 | } 16 | const key = arg.replace(/-/g, "_"); 17 | const value = defs[key]; 18 | if (value === undefined) { 19 | throw Error(`Unknown flag ${key}`); 20 | } 21 | switch (typeof value) { 22 | case "string": 23 | { 24 | if (i + 1 >= argv.length) { 25 | throw Error(`Missing argument value for ${arg} of type string`); 26 | } 27 | flags[key] = argv[++i]; 28 | } 29 | break; 30 | case "boolean": 31 | { 32 | flags[key] = true; 33 | } 34 | break; 35 | case "number": 36 | { 37 | if (i + 1 >= argv.length) { 38 | throw Error(`Missing argument value for ${arg} of type number`); 39 | } 40 | const str = argv[++i]; 41 | const num = Number(str); 42 | if (Number.isNaN(num)) { 43 | throw Error((`${arg}: ${str} is not a number`)); 44 | } 45 | flags[key] = num || 0; 46 | } 47 | break; 48 | case "object": 49 | { 50 | if (i + 1 >= argv.length) { 51 | throw Error(`Missing argument value for ${arg} of type must be one of [${enum_strings(value.in)}]`); 52 | } 53 | const str = argv[++i]; 54 | const num = enum_from_str(value.in, str); 55 | if (num === undefined) { 56 | throw Error(`${arg}: ${str} must be one of [${enum_strings(value.in)}]`); 57 | } 58 | value.val = num; 59 | } 60 | break; 61 | } 62 | } 63 | return { command, args, flags }; 64 | } 65 | export function read_all(stream) { 66 | let string = ""; 67 | return new Promise((resolve, reject) => { 68 | stream.on('data', (chunk) => string += chunk); 69 | stream.on('error', (err) => reject(err)); 70 | stream.on('end', () => resolve(string)); 71 | }); 72 | } 73 | //# sourceMappingURL=args.js.map -------------------------------------------------------------------------------- /urcl-explorer/js/node/args.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"args.js","sourceRoot":"","sources":["../../node/args.ts"],"names":[],"mappings":"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"} -------------------------------------------------------------------------------- /urcl-explorer/js/node/exec.js: -------------------------------------------------------------------------------- 1 | import { spawn } from "child_process"; 2 | export function my_exec(command, ...args) { 3 | return new Promise((res) => { 4 | const py = spawn(command, args); 5 | let out = ""; 6 | let errors = ""; 7 | py.stdout.on("data", (chunk) => { 8 | out += chunk; 9 | }); 10 | py.stderr.on("data", (chunk) => { 11 | errors += chunk; 12 | }); 13 | py.on("error", (err) => { 14 | errors += "\n" + err; 15 | res({ code: 1, out, errors }); 16 | }); 17 | py.on("close", (code, signal) => { 18 | code ||= 0; 19 | res({ code, out, errors }); 20 | }); 21 | }); 22 | } 23 | //# sourceMappingURL=exec.js.map -------------------------------------------------------------------------------- /urcl-explorer/js/node/exec.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"exec.js","sourceRoot":"","sources":["../../node/exec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAEtC,MAAM,UAAU,OAAO,CAAC,OAAe,EAAE,GAAG,IAAc;IACtD,OAAO,IAAI,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE;QACvB,MAAM,EAAE,GAAG,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QAChC,IAAI,GAAG,GAAG,EAAE,CAAC;QACb,IAAI,MAAM,GAAG,EAAE,CAAC;QAEhB,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE;YAC3B,GAAG,IAAI,KAAK,CAAC;QACjB,CAAC,CAAC,CAAC;QACH,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAG,CAAC,KAAK,EAAE,EAAE;YAC5B,MAAM,IAAI,KAAK,CAAA;QACnB,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;YACnB,MAAM,IAAI,IAAI,GAAG,GAAG,CAAC;YACrB,GAAG,CAAC,EAAC,IAAI,EAAE,CAAC,EAAE,GAAG,EAAE,MAAM,EAAC,CAAC,CAAC;QAChC,CAAC,CAAC,CAAA;QAEF,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE;YAC5B,IAAI,KAAK,CAAC,CAAC;YACX,GAAG,CAAC,EAAC,IAAI,EAAE,GAAG,EAAE,MAAM,EAAC,CAAC,CAAC;QAC7B,CAAC,CAAC,CAAA;IACN,CAAC,CAAC,CAAA;AAEN,CAAC"} -------------------------------------------------------------------------------- /urcl-explorer/js/node/urcx-emu.js: -------------------------------------------------------------------------------- 1 | import fs from "fs/promises"; 2 | import { exit, stdin, stdout } from "process"; 3 | import { Console_IO } from "../emulator/devices/console-io.js"; 4 | import { Emulator, Step_Result } from "../emulator/emulator.js"; 5 | import { compile } from "../emulator/compiler.js"; 6 | import { parse } from "../emulator/parser.js"; 7 | import { parse_argv } from "./args.js"; 8 | import { Storage } from "../emulator/devices/storage.js"; 9 | import { URCL_Header } from "../emulator/instructions.js"; 10 | import { RNG } from "../emulator/devices/rng.js"; 11 | function error(msg) { 12 | console.error(`ERROR: ${msg}\n${usage}\n`); 13 | exit(1); 14 | } 15 | const usage = `Usage: urcx-emu [<...options>] 16 | --storage 17 | the file the storage device should open 18 | 19 | --storage-size 20 | how big the storage file will be 21 | 22 | --text-file 23 | file to be read into %TEXT 24 | 25 | --little-endian 26 | read storage with little endian byte order 27 | `; 28 | const { args, flags } = parse_argv(process.argv, { 29 | __storage: "", 30 | __storage_size: 0, 31 | __text_file: "", 32 | __little_endian: false 33 | }); 34 | const { __storage, __storage_size, __text_file, __little_endian } = flags; 35 | if (args.length < 1) { 36 | throw new Error("Not enough arguments"); 37 | } 38 | const urcl = (await fs.readFile(args[0])).toString(); 39 | const emulator = new Emulator({ on_continue }); 40 | const console_io = new Console_IO({ 41 | read(callback) { 42 | stdin.resume(); 43 | stdin.once("data", (data) => { 44 | this.text = data.toString().replace(/\r\n/g, "\n"); 45 | callback(); 46 | stdin.pause(); 47 | }); 48 | }, 49 | text: "", 50 | }, (text) => { stdout.write(text); }, () => { }); 51 | emulator.add_io_device(console_io); 52 | emulator.add_io_device(new RNG()); 53 | const code = parse(urcl); 54 | if (code.errors.length > 0) { 55 | console.error(code.errors, code.warnings); 56 | exit(1); 57 | } 58 | if (code.warnings.length > 0) { 59 | console.warn(code.warnings); 60 | } 61 | const [program, debug_info] = compile(code); 62 | debug_info.file_name = args[0]; 63 | emulator.load_program(program, debug_info); 64 | let storage; 65 | if (__storage) { 66 | const file = (await fs.readFile(__storage)); 67 | let bytes = file; 68 | storage = new Storage(program.headers[URCL_Header.BITS].value, bytes, __little_endian, __storage_size * 1024); 69 | emulator.add_io_device(storage); 70 | } 71 | if (__text_file) { 72 | const text = (await fs.readFile(__text_file, { "encoding": "utf-8" })).toString() + "\0"; 73 | console_io.set_text(text); 74 | } 75 | setTimeout(on_continue, 1); 76 | async function on_continue() { 77 | try { 78 | const [res, its] = emulator.run(2000); 79 | switch (res) { 80 | case Step_Result.Continue: 81 | { 82 | emulator.warn("Long running program"); 83 | setTimeout(on_continue, 1); 84 | } 85 | break; 86 | case Step_Result.Input: break; 87 | case Step_Result.Halt: 88 | { 89 | await on_halt(); 90 | exit(0); 91 | } 92 | break; 93 | default: { 94 | console.error("\nunknown step result"); 95 | } 96 | } 97 | } 98 | catch (e) { 99 | console.error(e.message); 100 | exit(1); 101 | } 102 | } 103 | async function on_halt() { 104 | if (__storage && storage) { 105 | await fs.writeFile(__storage, storage.get_bytes()); 106 | } 107 | } 108 | //# sourceMappingURL=urcx-emu.js.map -------------------------------------------------------------------------------- /urcl-explorer/js/node/urcx-emu.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"urcx-emu.js","sourceRoot":"","sources":["../../node/urcx-emu.ts"],"names":[],"mappings":"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"} -------------------------------------------------------------------------------- /urcl-explorer/js/scroll-out/scroll-out.js: -------------------------------------------------------------------------------- 1 | import { bound } from "../emulator/util.js"; 2 | const max_size = 1_000_000_000; 3 | export class Scroll_Out extends HTMLElement { 4 | scroll_div = document.createElement("div"); 5 | content = document.createElement("div"); 6 | char = document.createElement("div"); 7 | cw = 8; 8 | ch = 8; 9 | lines = [""]; 10 | size = 0; 11 | constructor() { 12 | super(); 13 | this.appendChild(this.scroll_div); 14 | this.scroll_div.appendChild(this.content); 15 | this.onscroll = () => this.update(); 16 | this.onresize = () => this.resize(); 17 | this.char.textContent = "a"; 18 | this.char.style.position = "absolute"; 19 | this.char.style.visibility = "hidden"; 20 | this.appendChild(this.char); 21 | } 22 | update() { 23 | const { ceil: c, floor: f } = Math; 24 | const { clientWidth: cw, clientHeight: ch } = this.char; 25 | const x = this.scrollLeft, y = this.scrollTop; 26 | const w = this.clientWidth, h = this.clientHeight; 27 | this.render(f(x / cw), f(y / ch), c((w + 1) + 1 / cw), c((h + 2) / ch)); 28 | } 29 | resize() { 30 | const { clientWidth: cw, clientHeight: ch } = this.char; 31 | this.cw = cw; 32 | this.ch = ch; 33 | const scroll = this.scrollTop === this.scrollHeight - this.clientHeight; 34 | const W = this.text_width, H = this.lines.length; 35 | this.scroll_div.style.height = `${H * ch}px`; 36 | this.scroll_div.style.width = `${W * cw}px`; 37 | this.update(); 38 | if (scroll) { 39 | this.scrollTop = this.scrollHeight * 2; 40 | } 41 | return scroll; 42 | } 43 | buf = ""; 44 | text_width = 0; 45 | clear() { 46 | this.buf = ""; 47 | this.text_width = 0; 48 | this.lines = [""]; 49 | this.size = 0; 50 | this.resize(); 51 | } 52 | write(text_to_add) { 53 | this.buf += text_to_add; 54 | } 55 | flush() { 56 | if (this.buf.length === 0) { 57 | return; 58 | } 59 | let j = 0; 60 | for (let i = this.buf.indexOf("\n") + 1; i > 0; j = i, i = this.buf.indexOf("\n", i) + 1) { 61 | const line = this.buf.substring(j, i - 1); 62 | const full_line = this.lines[this.lines.length - 1] += line; 63 | this.text_width = Math.max(full_line.length, this.text_width); 64 | this.size += line.length; 65 | this.lines.push(""); 66 | } 67 | const full_line = this.lines[this.lines.length - 1] += this.buf.substring(j, this.buf.length); 68 | this.text_width = Math.max(full_line.length, this.text_width); 69 | this.size += this.buf.length - j; 70 | this.buf = ""; 71 | let i = 0; 72 | for (; this.size > max_size && i + 1 < this.lines.length; i++) { 73 | this.size -= this.lines[i].length; 74 | } 75 | this.lines.splice(0, i); 76 | if (this.lines.length === 1 && this.lines[0].length > max_size) { 77 | this.lines[0] = this.lines[0].substring(this.lines[0].length - max_size); 78 | this.size = max_size; 79 | } 80 | if (!this.resize()) { 81 | this.scrollTop -= this.ch * i; 82 | } 83 | } 84 | render(x, y, w, h) { 85 | const W = this.text_width, H = this.lines.length; 86 | const sx = bound(x, 0, W), ex = bound(x + w, 0, W); 87 | const sy = bound(y, 0, H), ey = bound(y + h, 0, H); 88 | this.content.style.top = `${sy * this.ch}px`; 89 | this.content.style.left = `${sx * this.cw}px`; 90 | let text = ""; 91 | for (let y = sy; y < ey; y++) { 92 | const line = this.lines[y]; 93 | text += line.substring(sx, ex) + "\n"; 94 | } 95 | this.content.textContent = text; 96 | } 97 | } 98 | customElements.define("scroll-out", Scroll_Out); 99 | //# sourceMappingURL=scroll-out.js.map -------------------------------------------------------------------------------- /urcl-explorer/js/webgl/shader.js: -------------------------------------------------------------------------------- 1 | export function createProgram(gl, vertexSource, fragmentSource) { 2 | const vertexShader = loadShader(gl, gl.VERTEX_SHADER, vertexSource); 3 | const fragmentShader = loadShader(gl, gl.FRAGMENT_SHADER, fragmentSource); 4 | const program = gl.createProgram(); 5 | if (program == null) { 6 | throw new Error("failed to create shader program"); 7 | } 8 | gl.attachShader(program, vertexShader); 9 | gl.attachShader(program, fragmentShader); 10 | gl.linkProgram(program); 11 | gl.detachShader(program, vertexShader); 12 | gl.detachShader(program, fragmentShader); 13 | gl.deleteShader(vertexShader); 14 | gl.deleteShader(fragmentShader); 15 | if (!gl.getProgramParameter(program, gl.LINK_STATUS)) { 16 | gl.deleteProgram(program); 17 | const linkErrLog = gl.getProgramInfoLog(program); 18 | throw new Error("Shader program did not link successfully. " 19 | + "Error log: " + linkErrLog); 20 | } 21 | return program; 22 | } 23 | function loadShader(gl, type, source) { 24 | const shader = gl.createShader(type); 25 | if (shader == null) { 26 | throw new Error("Failed to create shader"); 27 | } 28 | gl.shaderSource(shader, source); 29 | gl.compileShader(shader); 30 | if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { 31 | const info = gl.getShaderInfoLog(shader); 32 | gl.deleteShader(shader); 33 | throw new Error("Shader compile error: " + info); 34 | } 35 | return shader; 36 | } 37 | //# sourceMappingURL=shader.js.map -------------------------------------------------------------------------------- /urcl-explorer/js/webgl/shader.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"shader.js","sourceRoot":"","sources":["../../webgl/shader.ts"],"names":[],"mappings":"AACA,MAAM,UAAU,aAAa,CAAC,EAAM,EAAE,YAAoB,EAAE,cAAsB;IAChF,MAAM,YAAY,GAAG,UAAU,CAAC,EAAE,EAAE,EAAE,CAAC,aAAa,EAAE,YAAY,CAAC,CAAC;IACpE,MAAM,cAAc,GAAG,UAAU,CAAC,EAAE,EAAE,EAAE,CAAC,eAAe,EAAE,cAAc,CAAC,CAAC;IAE1E,MAAM,OAAO,GAAG,EAAE,CAAC,aAAa,EAAE,CAAC;IACnC,IAAI,OAAO,IAAI,IAAI,EAAC;QAClB,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;KACpD;IACD,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;IACvC,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC;IAEzC,EAAE,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;IAExB,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;IACvC,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC;IAEzC,EAAE,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC;IAC9B,EAAE,CAAC,YAAY,CAAC,cAAc,CAAC,CAAC;IAEhC,IAAI,CAAC,EAAE,CAAC,mBAAmB,CAAC,OAAO,EAAE,EAAE,CAAC,WAAW,CAAC,EAAE;QACpD,EAAE,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;QAE1B,MAAM,UAAU,GAAG,EAAE,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC;QACjD,MAAM,IAAI,KAAK,CAAC,4CAA4C;cAC1D,aAAa,GAAG,UAAU,CAAC,CAAC;KAC/B;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAS,UAAU,CAAC,EAAM,EAAE,IAAY,EAAE,MAAc;IACtD,MAAM,MAAM,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;IACrC,IAAI,MAAM,IAAI,IAAI,EAAC;QACjB,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;KAC5C;IACD,EAAE,CAAC,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAEhC,EAAE,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;IAEzB,IAAI,CAAC,EAAE,CAAC,kBAAkB,CAAC,MAAM,EAAE,EAAE,CAAC,cAAc,CAAC,EAAE;QACrD,MAAM,IAAI,GAAG,EAAE,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC;QACzC,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;QACxB,MAAM,IAAI,KAAK,CAAC,wBAAwB,GAAG,IAAI,CAAC,CAAC;KAClD;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"} -------------------------------------------------------------------------------- /urcl-explorer/libs/urclpp/f32/notes.txt: -------------------------------------------------------------------------------- 1 | reference: https://en.wikipedia.org/wiki/Single-precision_floating-point_format 2 | format: S: sign bit, E: exponent, F: fraction 3 | v = (-1)**S * 2**E * (1 + F * 2**-23) 4 | SEEEEEEEEFFFFFFFFFFFFFFFFFFFFFFF 5 | -------------------------------------------------------------------------------- /urcl-explorer/libs/urclpp/f32/to_int.urcl: -------------------------------------------------------------------------------- 1 | @define @in R1 2 | @define @out R1 3 | 4 | IMM @in 12345678.6f32 5 | OUT %NUMB @in 6 | OUT %TEXT '\n' 7 | cal .f32_to_int 8 | OUT %NUMB @out 9 | 10 | HLT 11 | 12 | .f32_to_int 13 | BITS >= 32 14 | @define @float @in 15 | @define @exponent R2 16 | @define @fraction @out 17 | // save variables to stack 18 | PSH @exponent 19 | // get exponent 20 | BSR @exponent @float 23 21 | AND @exponent @exponent 0xff 22 | SUB @exponent 150 @exponent // 127 + 23 - E 23 | 24 | BRG .end @exponent 23 25 | 26 | 27 | BRN .neg @float // if float >= 0 28 | AND @fraction @float 0x7fffff// lower 23 bits 29 | OR @fraction @fraction 0x800000// add 1 to fraction 30 | OUT %NUMB @fraction 31 | OUT %TEXT '\n' 32 | BSR @fraction @fraction @exponent 33 | // restore variables from the stack and return 34 | POP @exponent 35 | RET 36 | .neg // else 37 | AND @fraction @float 0x7fffff// lower 23 bits 38 | OR @fraction @fraction 0x800000// add 1 to fraction 39 | BSR @out @fraction @exponent 40 | NEG @out @fraction 41 | // restore variables from the stack and return 42 | POP @exponent 43 | RET 44 | 45 | .end 46 | IMM @out 0 47 | // restore variables from the stack and return 48 | POP @exponent 49 | RET 50 | -------------------------------------------------------------------------------- /urcl-explorer/node/args.ts: -------------------------------------------------------------------------------- 1 | import * as path from "path" 2 | import { enum_from_str, enum_strings } from "../emulator/util.js"; 3 | interface Args { 4 | command: string, 5 | args: string[]; 6 | flags: T; 7 | } 8 | type ArgsDef = Record}> 9 | 10 | export function parse_argv(argv: string[], defs: T): Args { 11 | if (argv.length < 2){ 12 | throw new Error(`Argv needs at least 2 elements but got [${argv}]`); 13 | } 14 | const command = argv[0] + " " + path.relative("./", argv[1]) 15 | const args: string[] = []; 16 | const flags: T = Object.assign({}, defs); 17 | for (let i = 2; i < argv.length; i++){ 18 | const arg = argv[i]; 19 | if (!arg.startsWith("-")){ 20 | args.push(arg); 21 | continue 22 | } 23 | const key = arg.replace(/-/g, "_"); 24 | const value = defs[key]; 25 | if (value === undefined){ 26 | throw Error(`Unknown flag ${key}`); 27 | } 28 | switch (typeof value){ 29 | case "string": { 30 | if (i + 1 >= argv.length){ 31 | throw Error(`Missing argument value for ${arg} of type string`); 32 | } 33 | (flags as any)[key] = argv[++i]; 34 | } break; 35 | case "boolean": { 36 | (flags as any)[key] = true; 37 | } break; 38 | case "number": { 39 | if (i + 1 >= argv.length){ 40 | throw Error(`Missing argument value for ${arg} of type number`); 41 | } 42 | const str = argv[++i]; 43 | const num = Number(str); 44 | if (Number.isNaN(num)){ 45 | throw Error((`${arg}: ${str} is not a number`)); 46 | } 47 | (flags as any)[key] = num || 0; 48 | } break; 49 | case "object": { 50 | if (i + 1 >= argv.length){ 51 | throw Error(`Missing argument value for ${arg} of type must be one of [${enum_strings(value.in)}]`); 52 | } 53 | const str = argv[++i]; 54 | const num = enum_from_str(value.in, str); 55 | if (num === undefined){ 56 | throw Error(`${arg}: ${str} must be one of [${enum_strings(value.in)}]`); 57 | } 58 | value.val = num; 59 | } break; 60 | } 61 | } 62 | return {command, args, flags}; 63 | } 64 | 65 | export function read_all(stream: NodeJS.ReadStream): Promise{ 66 | let string = ""; 67 | return new Promise((resolve, reject) => { 68 | stream.on('data', (chunk: Buffer) => string += chunk); 69 | stream.on('error', (err) => reject(err)); 70 | stream.on('end', () => resolve(string)); 71 | }); 72 | } 73 | -------------------------------------------------------------------------------- /urcl-explorer/node/exec.ts: -------------------------------------------------------------------------------- 1 | import { spawn } from "child_process"; 2 | 3 | export function my_exec(command: string, ...args: string[]): Promise<{out: string, errors: string, code: number}>{ 4 | return new Promise((res) => { 5 | const py = spawn(command, args); 6 | let out = ""; 7 | let errors = ""; 8 | 9 | py.stdout.on("data", (chunk) => { 10 | out += chunk; 11 | }); 12 | py.stderr.on("data" , (chunk) => { 13 | errors += chunk 14 | }); 15 | 16 | py.on("error", (err) => { 17 | errors += "\n" + err; 18 | res({code: 1, out, errors}); 19 | }) 20 | 21 | py.on("close", (code, signal) => { 22 | code ||= 0; 23 | res({code, out, errors}); 24 | }) 25 | }) 26 | 27 | } 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /urcl-explorer/node/urcx-emu.ts: -------------------------------------------------------------------------------- 1 | import fs from "fs/promises"; 2 | import { exit, stdin, stdout } from "process"; 3 | import { Console_IO } from "../emulator/devices/console-io.js"; 4 | import { Emulator, Step_Result } from "../emulator/emulator.js"; 5 | import { compile } from "../emulator/compiler.js"; 6 | import { parse } from "../emulator/parser.js"; 7 | import { parse_argv } from "./args.js"; 8 | import { Storage } from "../emulator/devices/storage.js"; 9 | import { URCL_Header } from "../emulator/instructions.js"; 10 | import { RNG } from "../emulator/devices/rng.js"; 11 | 12 | function error(msg: string){ 13 | console.error(`ERROR: ${msg}\n${usage}\n`); 14 | exit(1); 15 | } 16 | 17 | const usage = `Usage: urcx-emu [<...options>] 18 | --storage 19 | the file the storage device should open 20 | 21 | --storage-size 22 | how big the storage file will be 23 | 24 | --text-file 25 | file to be read into %TEXT 26 | 27 | --little-endian 28 | read storage with little endian byte order 29 | `; 30 | 31 | const {args, flags} = parse_argv(process.argv, { 32 | __storage: "", 33 | __storage_size: 0, 34 | __text_file: "", 35 | __little_endian: false 36 | }); 37 | const {__storage, __storage_size, __text_file, __little_endian} = flags; 38 | if (args.length < 1){ 39 | throw new Error("Not enough arguments"); 40 | } 41 | 42 | const urcl = (await fs.readFile(args[0])).toString(); 43 | 44 | const emulator = new Emulator({on_continue}); 45 | const console_io = new Console_IO({ 46 | read(callback){ 47 | stdin.resume(); 48 | stdin.once("data", (data) => { 49 | this.text = data.toString().replace(/\r\n/g, "\n"); 50 | callback(); 51 | stdin.pause(); 52 | }); 53 | }, 54 | text: "", 55 | }, 56 | (text) => {stdout.write(text)}, 57 | () => {/*nothing todo here program is only executed ones*/} 58 | ); 59 | emulator.add_io_device(console_io) 60 | emulator.add_io_device(new RNG()) 61 | 62 | const code = parse(urcl); 63 | if (code.errors.length > 0){ 64 | console.error(code.errors, code.warnings); 65 | exit(1); 66 | } 67 | if (code.warnings.length > 0){ 68 | console.warn(code.warnings); 69 | } 70 | const [program, debug_info] = compile(code); 71 | debug_info.file_name = args[0]; 72 | 73 | emulator.load_program(program, debug_info); 74 | let storage: undefined | Storage 75 | if (__storage){ 76 | const file: Uint8Array = (await fs.readFile(__storage)); 77 | let bytes = file; 78 | storage = new Storage(program.headers[URCL_Header.BITS].value, bytes, __little_endian, __storage_size*1024); 79 | emulator.add_io_device(storage); 80 | } 81 | 82 | if (__text_file){ 83 | const text = (await fs.readFile(__text_file, {"encoding": "utf-8"})).toString() + "\0"; 84 | console_io.set_text(text); 85 | } 86 | setTimeout(on_continue, 1); 87 | 88 | 89 | async function on_continue(){ 90 | try { 91 | const [res, its] = emulator.run(2000) 92 | switch (res){ 93 | case Step_Result.Continue: { 94 | emulator.warn("Long running program"); 95 | setTimeout(on_continue, 1); 96 | } break; 97 | case Step_Result.Input: break; 98 | case Step_Result.Halt: { 99 | await on_halt(); 100 | exit(0); 101 | } break; 102 | default: { 103 | console.error("\nunknown step result"); 104 | } 105 | } 106 | } catch (e) { 107 | console.error((e as Error).message); 108 | exit(1); 109 | } 110 | } 111 | 112 | 113 | async function on_halt(){ 114 | if (__storage && storage){ 115 | await fs.writeFile(__storage, storage.get_bytes()); 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /urcl-explorer/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "module", 3 | "name": "urcl-emu-ts", 4 | "version": "1.0.0", 5 | "main": "index.js", 6 | "license": "MIT", 7 | "engines": { 8 | "node": "16.x" 9 | }, 10 | "scripts": { 11 | "start": "node js/node/urcx-bot.js" 12 | }, 13 | "devDependencies": { 14 | "@types/gifencoder": "^2.0.1", 15 | "@types/node": "^16.7.13" 16 | }, 17 | "dependencies": { 18 | "canvas": "^2.8.0", 19 | "discord.js": "^13.3.1", 20 | "gifencoder": "^2.0.1", 21 | "node-fetch": "^3.1.0" 22 | }, 23 | "description": "An IDE for URCL", 24 | "directories": { 25 | "example": "examples" 26 | }, 27 | "repository": { 28 | "type": "git", 29 | "url": "git+https://github.com/BramOtte/urcl-explorer.git" 30 | }, 31 | "keywords": [], 32 | "author": "", 33 | "bugs": { 34 | "url": "https://github.com/BramOtte/urcl-explorer/issues" 35 | }, 36 | "homepage": "https://github.com/BramOtte/urcl-explorer#readme" 37 | } 38 | -------------------------------------------------------------------------------- /urcl-explorer/run.cmd: -------------------------------------------------------------------------------- 1 | node js/node/urcx-bot.js 2 | @REM urcx-emu --storage examples/urcl/storage.bin --storage-size 128 examples/urcl/storage.urcl 3 | @REM node js/emulator/urcl-emu.js examples/aoc21/1.1.urcl examples/aoc21/1-i.txt 4 | @REM node js/emulator/urcl-emu.js examples/aoc21/1.2.urcl examples/aoc21/1-e.txt 5 | @REM node js/emulator/urcl-emu.js examples/aoc21/1.2.urcl examples/aoc21/1-i.txt 6 | 7 | @REM node js/emulator/urcl-emu.js examples/aoc21/2.1.urcl examples/aoc21/2-e.txt 8 | @REM node js/emulator/urcl-emu.js examples/aoc21/2.1.urcl examples/aoc21/2-i.txt 9 | @REM node js/emulator/urcl-emu.js examples/aoc21/2.2.urcl examples/aoc21/2-e.txt 10 | @REM node js/emulator/urcl-emu.js examples/aoc21/2.2.urcl examples/aoc21/2-i.txt 11 | 12 | @REM node js/emulator/urcl-emu.js examples/aoc21/3.1.urcl examples/aoc21/3-e.txt 13 | @REM node js/emulator/urcl-emu.js examples/aoc21/3.1.urcl examples/aoc21/3-i.txt 14 | @REM node js/emulator/urcl-emu.js examples/aoc21/3.2.urcl examples/aoc21/3-e.txt 15 | @REM node js/emulator/urcl-emu.js examples/aoc21/3.2.urcl examples/aoc21/3-i.txt 16 | -------------------------------------------------------------------------------- /urcl-explorer/scroll-out/scoll-out.css: -------------------------------------------------------------------------------- 1 | scroll-out { 2 | display: block; 3 | overflow: scroll; 4 | white-space: pre; 5 | width: 40ch; 6 | height: 40ch; 7 | font-family: monospace; 8 | } 9 | 10 | scroll-out :first-child { 11 | position: relative; 12 | width: 0px; 13 | height: 0px; 14 | } 15 | scroll-out :first-child * { 16 | position: absolute; 17 | } 18 | -------------------------------------------------------------------------------- /urcl-explorer/scroll-out/scroll-out.ts: -------------------------------------------------------------------------------- 1 | import { bound } from "../emulator/util.js"; 2 | 3 | const max_size = 1_000_000_000 4 | export class Scroll_Out extends HTMLElement { 5 | scroll_div = document.createElement("div"); 6 | content = document.createElement("div"); 7 | char = document.createElement("div"); 8 | cw: number = 8; 9 | ch: number = 8; 10 | lines: string[] = [""]; 11 | size = 0; 12 | constructor(){ 13 | super(); 14 | this.appendChild(this.scroll_div); 15 | this.scroll_div.appendChild(this.content); 16 | this.onscroll = ()=>this.update(); 17 | this.onresize = ()=>this.resize(); 18 | 19 | 20 | this.char.textContent = "a"; 21 | this.char.style.position = "absolute"; 22 | this.char.style.visibility = "hidden"; 23 | this.appendChild(this.char); 24 | } 25 | update(){ 26 | const {ceil: c, floor: f} = Math; 27 | const {clientWidth: cw, clientHeight: ch} = this.char; 28 | const x = this.scrollLeft, y = this.scrollTop; 29 | const w = this.clientWidth, h = this.clientHeight; 30 | 31 | this.render(f(x/cw), f(y/ch), c((w+1)+1/cw), c((h+2)/ch)); 32 | } 33 | resize(){ 34 | const {clientWidth: cw, clientHeight: ch} = this.char; 35 | this.cw = cw; this.ch = ch 36 | const scroll = this.scrollTop === this.scrollHeight - this.clientHeight; 37 | const W = this.text_width, H = this.lines.length; 38 | this.scroll_div.style.height = `${H*ch}px`; 39 | this.scroll_div.style.width = `${W*cw}px`; 40 | this.update(); 41 | if (scroll){ 42 | this.scrollTop = this.scrollHeight*2; 43 | } 44 | return scroll; 45 | } 46 | private buf = ""; 47 | private text_width = 0; 48 | clear(){ 49 | this.buf = "" 50 | this.text_width = 0; 51 | this.lines = [""]; 52 | this.size = 0; 53 | this.resize(); 54 | } 55 | public write(text_to_add: string){ 56 | this.buf += text_to_add; 57 | } 58 | public flush(){ 59 | if (this.buf.length === 0){ 60 | return; 61 | } 62 | let j = 0; 63 | for(let i = this.buf.indexOf("\n") + 1; i > 0; j = i, i = this.buf.indexOf("\n", i)+1){ 64 | const line = this.buf.substring(j, i-1); 65 | const full_line = this.lines[this.lines.length-1] += line; 66 | this.text_width = Math.max(full_line.length, this.text_width); 67 | this.size += line.length; 68 | this.lines.push(""); 69 | } 70 | const full_line = this.lines[this.lines.length-1] += this.buf.substring(j, this.buf.length); 71 | this.text_width = Math.max(full_line.length, this.text_width); 72 | this.size += this.buf.length-j; 73 | this.buf = ""; 74 | let i = 0; 75 | for (; this.size > max_size && i + 1 < this.lines.length; i++){ 76 | this.size -= this.lines[i].length; 77 | } 78 | this.lines.splice(0, i); 79 | if (this.lines.length === 1 && this.lines[0].length > max_size){ 80 | this.lines[0] = this.lines[0].substring(this.lines[0].length - max_size); 81 | this.size = max_size; 82 | } 83 | 84 | if (!this.resize()){ 85 | this.scrollTop -= this.ch * i; 86 | } 87 | } 88 | public render(x: number, y: number, w: number, h: number){ 89 | const W = this.text_width, H = this.lines.length; 90 | const sx = bound(x, 0, W), ex = bound(x+w, 0, W); 91 | const sy = bound(y, 0, H), ey = bound(y+h, 0, H); 92 | this.content.style.top = `${sy*this.ch}px`; 93 | this.content.style.left = `${sx*this.cw}px`; 94 | let text = ""; 95 | for (let y = sy; y < ey; y++){ 96 | const line = this.lines[y]; 97 | text += line.substring(sx, ex) + "\n"; 98 | } 99 | this.content.textContent = text; 100 | } 101 | } 102 | 103 | customElements.define("scroll-out", Scroll_Out); 104 | -------------------------------------------------------------------------------- /urcl-explorer/server.py: -------------------------------------------------------------------------------- 1 | #Use to create local host 2 | import http.server 3 | import socketserver 4 | 5 | print("starting server...") 6 | 7 | PORT = 1337 8 | 9 | Handler = http.server.SimpleHTTPRequestHandler 10 | Handler.extensions_map.update({ 11 | ".js": "application/javascript", 12 | }); 13 | 14 | httpd = socketserver.TCPServer(("", PORT), Handler) 15 | print("server started") 16 | httpd.serve_forever() -------------------------------------------------------------------------------- /urcl-explorer/unscii-16.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sammyuri/minecraft/976e84d3dc8142dd4cf8927036d0d5e54b79152e/urcl-explorer/unscii-16.ttf -------------------------------------------------------------------------------- /urcl-explorer/unscii-16.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sammyuri/minecraft/976e84d3dc8142dd4cf8927036d0d5e54b79152e/urcl-explorer/unscii-16.woff -------------------------------------------------------------------------------- /urcl-explorer/watch.cmd: -------------------------------------------------------------------------------- 1 | nodemon -e .js,.cmd,.urcl,.txt --exec run 2 | -------------------------------------------------------------------------------- /urcl-explorer/webgl/shader.ts: -------------------------------------------------------------------------------- 1 | type GL = WebGLRenderingContext; 2 | export function createProgram(gl: GL, vertexSource: string, fragmentSource: string){ 3 | const vertexShader = loadShader(gl, gl.VERTEX_SHADER, vertexSource); 4 | const fragmentShader = loadShader(gl, gl.FRAGMENT_SHADER, fragmentSource); 5 | 6 | const program = gl.createProgram(); 7 | if (program == null){ 8 | throw new Error("failed to create shader program"); 9 | } 10 | gl.attachShader(program, vertexShader); 11 | gl.attachShader(program, fragmentShader); 12 | 13 | gl.linkProgram(program); 14 | 15 | gl.detachShader(program, vertexShader); 16 | gl.detachShader(program, fragmentShader); 17 | 18 | gl.deleteShader(vertexShader); 19 | gl.deleteShader(fragmentShader); 20 | 21 | if (!gl.getProgramParameter(program, gl.LINK_STATUS)) { 22 | gl.deleteProgram(program); 23 | 24 | const linkErrLog = gl.getProgramInfoLog(program); 25 | throw new Error("Shader program did not link successfully. " 26 | + "Error log: " + linkErrLog); 27 | } 28 | 29 | return program; 30 | } 31 | 32 | function loadShader(gl: GL, type: number, source: string): WebGLShader { 33 | const shader = gl.createShader(type); 34 | if (shader == null){ 35 | throw new Error("Failed to create shader"); 36 | } 37 | gl.shaderSource(shader, source); 38 | 39 | gl.compileShader(shader); 40 | 41 | if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { 42 | const info = gl.getShaderInfoLog(shader); 43 | gl.deleteShader(shader); 44 | throw new Error("Shader compile error: " + info); 45 | } 46 | return shader; 47 | } --------------------------------------------------------------------------------