diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..da66e67 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.vscode +programs \ No newline at end of file diff --git a/examples/clear_screen.asm b/examples/clear_screen.asm new file mode 100644 index 0000000..1d63917 --- /dev/null +++ b/examples/clear_screen.asm @@ -0,0 +1,30 @@ +.include _hwdefs.asm +.include _clrdefs.asm + +;; Variables +.org SYSRAM +stack: byte[128] + +;; Main +.org SYSROM +lds stack +jss cls + +hlt + +;; Clear the screen +FUNC cls: + ldp screen.char + ldc $00 ;; Blank + ldq screen.color + ldb CLR_BLACK ;; Black + .cls_loop: { + stc *p++ + stb *q++ + lda pl + cmp (lo(COLOR)) + jnz .cls_loop + lda ph + cmp (hi(COLOR)) + jnz } +rts diff --git a/examples/fibonacci.asm b/examples/fibonacci.asm new file mode 100644 index 0000000..63a632e --- /dev/null +++ b/examples/fibonacci.asm @@ -0,0 +1,8 @@ +lda 1 +ldb 0 + +fib_loop: +ldc b +ldb a +add c +jlt fib_loop ; Stop when carry flag is set \ No newline at end of file diff --git a/examples/functions.asm b/examples/functions.asm new file mode 100644 index 0000000..e52cfc1 --- /dev/null +++ b/examples/functions.asm @@ -0,0 +1,50 @@ +.include _hwdefs.asm +.include _clrdefs.asm + +;; Defines +.define VARS $0100 + +;; Variables +.org SYSRAM +stack: byte[128] + +.org VARS +hello_str: "Hello world!\0" + +;; Main +.org SYSROM +lds stack + +jss cls + +ldp screen.char +ldq hello_str +jss print + +hlt + +;; Clear the screen +FUNC cls: + ldp screen.char + ldc $00 ;; Blank + ldq screen.color + ldb CLR_BLACK ;; Black + .cls_loop: { + stc *p++ + stb *q++ + lda pl + cmp (lo(COLOR)) + jnz .cls_loop + lda ph + cmp (hi(COLOR)) + jnz } +rts + +;; Print string (Q) to the current screen cursor (P) +FUNC print: + lda *q++ + jpz .print_end + sta *p++ + jmp print + .print_end: +rts diff --git a/examples/helloworld.asm b/examples/helloworld.asm new file mode 100644 index 0000000..d33bc46 --- /dev/null +++ b/examples/helloworld.asm @@ -0,0 +1,16 @@ +.org $0100 ; Static data +hello_str: +"Hello world\0" + +.org $0000 ; Program must start at $0000 +ldp $0800 ; Char display +ldq hello_str + +print: +lda *q++ +jpz print_end +sta *p++ +jmp print + +print_end: +hlt diff --git a/examples/increment_reg.asm b/examples/increment_reg.asm new file mode 100644 index 0000000..38112ac --- /dev/null +++ b/examples/increment_reg.asm @@ -0,0 +1,8 @@ +; This program adds 1 to register A until it equals 64, then halts. + +loop: +inc a +cmp 64 +jnz loop + +hlt \ No newline at end of file diff --git a/memoryMap.md b/memoryMap.md new file mode 100644 index 0000000..d87c386 --- /dev/null +++ b/memoryMap.md @@ -0,0 +1,45 @@ +## Boot ROM +Execution starts here, at address `$0000`.
+The main program is located here, or the OS bootloader if an OS is present. + +## GPIO +Contains hardware multiplication (`$0400 * $0401 -> $0400`) and division (`$0402 / $0403 -> $0402 r $0403`), popcount (`$0404 -> $0404`), and a timer (`$0405`).
+Value written to timer register = number of game ticks (32 ms) between interrupt triggers.
+Write 0 to disable. + +## Keyboard +Read address `$0500` to get the next key event
+7-bit Windows VKey code, MSB 1 = press, 0 = release
+Returns 0 if buffer is empty. +Write 1 to `$0500` to enable keyboard interrupts, 0 to disable. + +## Serial Peripheral Interface +Not yet implemented. + +## Robot Controller +Write to `$0701` to control the robot. Each bit is an action - MSB to LSB: Plant brick, destroy brick, move forward, backward, left, right, up, down.
+Write a 6-bit color ID to `$0700` to set the color of the bricks the robot plants.
+Read `$0700` to get the color of the brick the robot is on. MSB = brick exists. Returns 0 if no brick. + + +## Text Display +Write ASCII values to `$0800` to `$0BFF` to display characters at certain positions on screen.
+`$0800` is top left, `$0BFF` is bottom right, rows are 64 bytes. + +## Text Display Color +Write 6-bit color IDs to `$0C00` to `$0FFF` to set the color of characters on screen.
+MSB = whether to invert character mask (i.e. for highlighting). + +## System RAM +The OS may use this memory for the stack, system variables, etc.
+If no OS is present, this memory can be used for any purpose, etc.
+Located at `$1000` to `$1FFF`. + +## User ROM +User program and data can go here.
+If no OS is present, the boot ROM will need to jump into this code.
+Located at `$2000` to `$2FFF`. + +## User RAM +Your code can use this memory for variables, arrays, a heap, etc.
+Located at `$3000` to `$3FFF`. diff --git a/readme.md b/readme.md index f7a0ded..4e4b167 100644 --- a/readme.md +++ b/readme.md @@ -4,20 +4,20 @@ For a list of instructions, see [instructionList.txt](instructionList.txt). ## How to use the assembler: 1. Install `bllua3` from [https://notabug.org/redo/bllua3](https://notabug.org/redo/bllua3) -2. Download this repo somewhere into the Blockland folder. +2. Download this repo into `Add-Ons/8608` or anywhere within one of Blockland's main directories. 3. In BL console, execute: ``` - luaexec("your_path/assembler-8608.lua"); + luaexec("Add-Ons/8608/assembler-8608.lua"); ``` 4. To assemble a program, place a 1x1f ghost brick on the top-left corner of the ROM, face forward, and in BL console do: ``` - AssembleBuildFile("other_path/filename.asm", "RomX RomY RomZ"); + AssembleBuildFile("Add-Ons/8608/examples/program.asm", "RomX RomY RomZ"); ``` where `RomX` is the width of the ROM, `RomY` is the depth front to back, and `RomZ` is the height in bits, i.e., "16 16 8". - + You can also run the assembler from the command line to get a memory dump and disassembly in stdout, if you have lua installed: ``` - luajit "your_path/assembler-8608.lua" "other_path/filename.asm" + luajit "Add-Ons/8608/assembler-8608.lua" "Add-Ons/8608/examples/program.asm" ``` ## How to use the emulator: @@ -27,3 +27,5 @@ For a list of instructions, see [instructionList.txt](instructionList.txt). love . C:/path/filename.asm ``` +## Memory Map +[memory map](memoryMap.md)