mega refactor:
essentially completely reorganised the project. previous contents of the dsa folder have now been split into emulator/ tooling/ and libraries/ libraries is for common functionality across crates, tooling is for core binaries needed for building and debugging DSA projects, including dsx client/server/build emulator contains the dsa_emulator crate that implements the core DSA emulator, the dsa_gui crate that implements the graphical user interface for the emulator & all future tooling under a unified application, and finally the dsa_cli crate which will eventually provide lightweight wrapper for the core emulator, simply providing a tool for running DSA binaries without the overhead of a heavy GUI.
This commit is contained in:
@@ -0,0 +1,173 @@
|
||||
include print: "./print.dsa"
|
||||
|
||||
|
||||
dw DISPLAY: 0x30000
|
||||
dw stack: 0x10000
|
||||
|
||||
// colour table — AABBGGRR format
|
||||
dw COL0: 0xFFFFFFFF // white
|
||||
dw COL1: 0xFF0000FF // red
|
||||
dw COL2: 0xFF00FF00 // green
|
||||
dw COL3: 0xFFFF0000 // blue
|
||||
dw COL4: 0xFF00FFFF // yellow
|
||||
dw COL_IDX: 0
|
||||
|
||||
// registers:
|
||||
// rg0 = x position
|
||||
// rg1 = y position
|
||||
// rg2 = x direction (1 = right, 0 = left)
|
||||
// rg3 = y direction (1 = down, 0 = up)
|
||||
// rg5 = current colour
|
||||
|
||||
db startup: "Starting animation..."
|
||||
|
||||
_init:
|
||||
ldw stack, bpr
|
||||
mov bpr, spr
|
||||
|
||||
start:
|
||||
lwi startup, rg0
|
||||
push rg0
|
||||
call print::print
|
||||
pop zero
|
||||
|
||||
lli 0, rg0
|
||||
lli 0, rg1
|
||||
lli 1, rg2
|
||||
lli 1, rg3
|
||||
lli 0, rg8
|
||||
stw rg8, COL_IDX
|
||||
|
||||
ldw COL0, rg5
|
||||
|
||||
frame_loop:
|
||||
// --- clear display ---
|
||||
ldw DISPLAY, rg4
|
||||
lwi 76800, rga
|
||||
|
||||
clear_loop:
|
||||
stw zero, rg4
|
||||
addi rg4, 4, rg4
|
||||
subi rga, 1, rga
|
||||
jnz rga, clear_loop
|
||||
|
||||
// --- draw square ---
|
||||
mov rg1, rg6
|
||||
|
||||
draw_y_loop:
|
||||
lli 20, rg8
|
||||
add rg1, rg8, rg8
|
||||
ilt rg6, rg8, rg9
|
||||
jez rg9, draw_done
|
||||
mov rg0, rg7
|
||||
|
||||
draw_x_loop:
|
||||
lli 20, rg8
|
||||
add rg0, rg8, rg8
|
||||
ilt rg7, rg8, rg9
|
||||
jez rg9, draw_x_done
|
||||
shl rg6, 8, rg8
|
||||
shl rg6, 6, rg9
|
||||
add rg8, rg9, rg8
|
||||
add rg8, rg7, rg8
|
||||
shl rg8, 2, rg8
|
||||
ldw DISPLAY, rg9
|
||||
add rg9, rg8, rg8
|
||||
stw rg5, rg8
|
||||
addi rg7, 1, rg7
|
||||
jmp draw_x_loop
|
||||
|
||||
draw_x_done:
|
||||
addi rg6, 1, rg6
|
||||
jmp draw_y_loop
|
||||
|
||||
draw_done:
|
||||
// --- track bounces this frame ---
|
||||
lli 0, rgb
|
||||
lli 0, rgc
|
||||
|
||||
// --- check x walls ---
|
||||
lli 1, rg8
|
||||
ieq rg2, rg8, rg9
|
||||
jez rg9, check_x_left_wall
|
||||
|
||||
check_x_right_wall:
|
||||
lli 300, rg8
|
||||
ige rg0, rg8, rg9
|
||||
jez rg9, move_x
|
||||
lli 0, rg2
|
||||
lli 1, rgb
|
||||
jmp move_x
|
||||
|
||||
check_x_left_wall:
|
||||
ieq rg0, zero, rg9
|
||||
jez rg9, move_x
|
||||
lli 1, rg2
|
||||
lli 1, rgb
|
||||
|
||||
move_x:
|
||||
lli 1, rg8
|
||||
ieq rg2, rg8, rg9
|
||||
jez rg9, do_x_left
|
||||
addi rg0, 1, rg0
|
||||
jmp check_y_walls
|
||||
do_x_left:
|
||||
subi rg0, 1, rg0
|
||||
|
||||
check_y_walls:
|
||||
lli 1, rg8
|
||||
ieq rg3, rg8, rg9
|
||||
jez rg9, check_y_up_wall
|
||||
|
||||
check_y_down_wall:
|
||||
lli 220, rg8
|
||||
ige rg1, rg8, rg9
|
||||
jez rg9, move_y
|
||||
lli 0, rg3
|
||||
lli 1, rgc
|
||||
jmp move_y
|
||||
|
||||
check_y_up_wall:
|
||||
ieq rg1, zero, rg9
|
||||
jez rg9, move_y
|
||||
lli 1, rg3
|
||||
lli 1, rgc
|
||||
|
||||
move_y:
|
||||
lli 1, rg8
|
||||
ieq rg3, rg8, rg9
|
||||
jez rg9, do_y_up
|
||||
addi rg1, 1, rg1
|
||||
jmp check_corner
|
||||
do_y_up:
|
||||
subi rg1, 1, rg1
|
||||
|
||||
check_corner:
|
||||
and rgb, rgc, rg8
|
||||
jez rg8, delay
|
||||
|
||||
// advance colour index
|
||||
ldw COL_IDX, rg8
|
||||
addi rg8, 1, rg8
|
||||
lli 5, rg9
|
||||
ige rg8, rg9, rg9
|
||||
jez rg9, store_col_idx
|
||||
lli 0, rg8
|
||||
|
||||
store_col_idx:
|
||||
stw rg8, COL_IDX
|
||||
|
||||
// load colour from table: address = COL0 + idx * 4
|
||||
shl rg8, 2, rg8
|
||||
lwi COL0, rg9
|
||||
add rg9, rg8, rg8
|
||||
ldw rg8, rg5
|
||||
|
||||
delay:
|
||||
lwi 2000000, rg8
|
||||
delay_loop:
|
||||
subi rg8, 1, rg8
|
||||
jnz rg8, delay_loop
|
||||
jmp frame_loop
|
||||
|
||||
hlt
|
||||
Binary file not shown.
@@ -0,0 +1,19 @@
|
||||
include print: "./print.dsa"
|
||||
db msg: "hello world"
|
||||
dw stack: 0x10000
|
||||
_init:
|
||||
ldw stack, bpr
|
||||
mov bpr, spr
|
||||
lwi 1000000, rg5
|
||||
|
||||
_loop:
|
||||
call print::reset
|
||||
lwi msg, rg0
|
||||
push rg0
|
||||
call print::print
|
||||
pop zero
|
||||
subi rg5, 1, rg5
|
||||
igt rg5, zero, rg4
|
||||
jnz rg4, _loop
|
||||
|
||||
hlt
|
||||
Binary file not shown.
@@ -0,0 +1,161 @@
|
||||
; ==== symbols ====
|
||||
; clear 0x000001d0 TEXT global
|
||||
; _loop 0x00000018 TEXT global
|
||||
; print_whitespace 0x00000150 TEXT global
|
||||
; _print_hex_nibble_number 0x00000140 TEXT global
|
||||
; _init 0x00000000 TEXT global
|
||||
; _print_loop 0x00000068 TEXT global
|
||||
; print_hex_byte 0x000000e0 TEXT global
|
||||
; _print_hex_byte 0x00000100 TEXT global
|
||||
; _end 0x00000200 TEXT global
|
||||
; print_byte 0x000000ac TEXT global
|
||||
; _newline_mod 0x0000019c TEXT global
|
||||
; reset 0x000001b8 TEXT global
|
||||
; _newline_done 0x000001ac TEXT global
|
||||
; msg 0x00000218 DATA global
|
||||
; display 0x00000228 DATA global
|
||||
; current 0x0000022c DATA global
|
||||
; _clear_loop 0x000001e8 TEXT global
|
||||
; _print_hex_nibble 0x00000124 TEXT global
|
||||
; print 0x00000040 TEXT global
|
||||
; stack 0x00000224 DATA global
|
||||
; _print_end 0x00000084 TEXT global
|
||||
; newline 0x00000174 TEXT global
|
||||
|
||||
; ==== data ====
|
||||
db "hello world"
|
||||
dw 0x00000000
|
||||
dw 0x00000010
|
||||
dw 0x00000000
|
||||
dw 0x00000002
|
||||
dw 0x00000002
|
||||
|
||||
; ==== text ====
|
||||
_init:
|
||||
ldw stack, Bpr, 0x0000
|
||||
mov Bpr, Spr
|
||||
lwi 0x000f4240, Rg5
|
||||
_loop:
|
||||
call reset
|
||||
lwi msg, Rg0
|
||||
push Rg0
|
||||
call print
|
||||
pop Zero
|
||||
subi Rg5, Rg5, 0x0001
|
||||
igt Rg5, Zero, Rg4
|
||||
jnz Rg4, _loop
|
||||
hlt
|
||||
print:
|
||||
push Bpr
|
||||
mov Spr, Bpr
|
||||
push Rg0
|
||||
push Rg1
|
||||
push Rg2
|
||||
push Rg3
|
||||
ldw Bpr, Rg0, 0x0008
|
||||
ldw current, Rg1, 0x0000
|
||||
_print_loop:
|
||||
ldb Rg0, Rg2, 0x0000
|
||||
ieq Rg2, Zero, Rg3
|
||||
jnz Rg3, _print_end
|
||||
stb Rg2, Rg1, 0x0000
|
||||
addi Rg0, Rg0, 0x0001
|
||||
addi Rg1, Rg1, 0x0001
|
||||
jmp _print_loop
|
||||
_print_end:
|
||||
stw current, Rg1, 0x0000
|
||||
pop Rg3
|
||||
pop Rg2
|
||||
pop Rg1
|
||||
pop Rg0
|
||||
mov Bpr, Spr
|
||||
pop Bpr
|
||||
ret
|
||||
print_byte:
|
||||
push Bpr
|
||||
mov Spr, Bpr
|
||||
push Rg0
|
||||
push Rg1
|
||||
ldw Bpr, Rg0, 0x0008
|
||||
ldw current, Rg1, 0x0000
|
||||
stb Rg0, Rg1, 0x0000
|
||||
addi Rg1, Rg1, 0x0001
|
||||
pop Rg1
|
||||
pop Rg0
|
||||
jmp _end
|
||||
print_hex_byte:
|
||||
push Bpr
|
||||
mov Spr, Bpr
|
||||
ldw Bpr, Rg0, 0x0008
|
||||
ldw current, Rg1, 0x0000
|
||||
call _print_hex_byte
|
||||
jmp _end
|
||||
_print_hex_byte:
|
||||
lli Rg2, 0x000f
|
||||
push Rg0
|
||||
shr Rg0, Rg0, Zero, 4
|
||||
and Rg0, Rg2, Rg0
|
||||
call _print_hex_nibble
|
||||
pop Rg0
|
||||
and Rg0, Rg2, Rg0
|
||||
call _print_hex_nibble
|
||||
ret
|
||||
_print_hex_nibble:
|
||||
lli Rg3, 0x000a
|
||||
ilt Rg0, Rg3, Rg4
|
||||
jnz Rg4, _print_hex_nibble_number
|
||||
addi Rg0, Rg0, 0x0037
|
||||
stb Rg0, Rg1, 0x0000
|
||||
addi Rg1, Rg1, 0x0001
|
||||
ret
|
||||
_print_hex_nibble_number:
|
||||
addi Rg0, Rg0, 0x0030
|
||||
stb Rg0, Rg1, 0x0000
|
||||
addi Rg1, Rg1, 0x0001
|
||||
ret
|
||||
print_whitespace:
|
||||
push Bpr
|
||||
mov Spr, Bpr
|
||||
ldw current, Rg1, 0x0000
|
||||
lli Rg0, 0x0020
|
||||
stb Rg0, Rg1, 0x0000
|
||||
addi Rg1, Rg1, 0x0001
|
||||
jmp _end
|
||||
newline:
|
||||
push Bpr
|
||||
mov Spr, Bpr
|
||||
ldw display, Rg0, 0x0000
|
||||
ldw current, Rg1, 0x0000
|
||||
sub Rg1, Rg0, Rg2
|
||||
lli Rg3, 0x0050
|
||||
_newline_mod:
|
||||
ilt Rg2, Rg3, Rg4
|
||||
jnz Rg4, _newline_done
|
||||
sub Rg2, Rg3, Rg2
|
||||
jmp _newline_mod
|
||||
_newline_done:
|
||||
sub Rg1, Rg2, Rg1
|
||||
addi Rg1, Rg1, 0x0050
|
||||
jmp _end
|
||||
reset:
|
||||
push Bpr
|
||||
mov Spr, Bpr
|
||||
ldw display, Rg1, 0x0000
|
||||
jmp _end
|
||||
clear:
|
||||
push Bpr
|
||||
mov Spr, Bpr
|
||||
lli Rg0, 0x01f4
|
||||
ldw display, Rg1, 0x0000
|
||||
_clear_loop:
|
||||
subi Rg0, Rg0, 0x0001
|
||||
stw Zero, Rg1, 0x0000
|
||||
addi Rg1, Rg1, 0x0004
|
||||
igt Rg0, Zero, Rg4
|
||||
jnz Rg4, _clear_loop
|
||||
jmp _end
|
||||
_end:
|
||||
stw current, Rg1, 0x0000
|
||||
mov Bpr, Spr
|
||||
pop Bpr
|
||||
ret
|
||||
@@ -0,0 +1,272 @@
|
||||
// a simple brainf##k interpreter,
|
||||
// because I already wrote a compiler lol.
|
||||
|
||||
include print "./print.dsa"
|
||||
|
||||
// "prints first 16 fibonacci numbers"
|
||||
db program: "++++++++++++++++++++++++++++++++++++++++++++
|
||||
>++++++++++++++++++++++++++++++++
|
||||
>++++++++++++++++
|
||||
>
|
||||
>+
|
||||
<<
|
||||
[
|
||||
>>
|
||||
>
|
||||
>++++++++++
|
||||
<<
|
||||
[->+>-[>+>>]>[+[-<+>]>+>>]<<<<<<]
|
||||
>[<+>-]
|
||||
>[-]
|
||||
>>
|
||||
>++++++++++
|
||||
<
|
||||
[->-[>+>>]>[+[-<+>]>+>>]<<<<<]
|
||||
>[-]
|
||||
>>[++++++++++++++++++++++++++++++++++++++++++++++++.[-]]
|
||||
<[++++++++++++++++++++++++++++++++++++++++++++++++.[-]]
|
||||
<<<++++++++++++++++++++++++++++++++++++++++++++++++.[-]
|
||||
<<<<<<<.>.
|
||||
>>[>>+<<-]
|
||||
>[>+<<+>-]
|
||||
>[<+>-]
|
||||
<<<-
|
||||
]
|
||||
<<++..."
|
||||
|
||||
db error: "Invalid Instruction!"
|
||||
dh counter: 0xFF
|
||||
dw stack: 0x10000
|
||||
dw input_addr: 0x30000
|
||||
resb data: 1024
|
||||
|
||||
// set up a stack so we can call functions
|
||||
_init:
|
||||
ldw stack, bpr
|
||||
mov bpr, spr
|
||||
|
||||
init:
|
||||
ldw counter, rg7
|
||||
|
||||
start:
|
||||
call bf_reset
|
||||
|
||||
// load the start of the program into rg0
|
||||
lwi program, rg0
|
||||
lwi data, rg1
|
||||
// rg0 is our instruction pointer
|
||||
// rg1 is our data pointer
|
||||
// rg2 is the value at the data pointer
|
||||
// rg3 stores the current instruction
|
||||
// rg4 is the expression nesting level.
|
||||
|
||||
lli 43, rg8 // + = 43 increment
|
||||
lli 45, rg9 // - = 45 decrement
|
||||
lli 62, rga // > = 62 increment pointer
|
||||
lli 60, rgb // < = 60 decrement pointer
|
||||
lli 46, rgc // . = 46 output
|
||||
lli 44, rgd // , = 44 input
|
||||
lli 91, rge // [ = 91 loop start
|
||||
lli 93, rgf // ] = 93 loop end
|
||||
|
||||
loop_start:
|
||||
// load the current instruction into rg3
|
||||
ldb rg0, rg3
|
||||
|
||||
// switch on the instruction
|
||||
ieq rg3, rg8, rg4
|
||||
jnz rg4, increment
|
||||
ieq rg3, rg9, rg4
|
||||
jnz rg4, decrement
|
||||
ieq rg3, rga, rg4
|
||||
jnz rg4, inc_ptr
|
||||
ieq rg3, rgb, rg4
|
||||
jnz rg4, dec_ptr
|
||||
ieq rg3, rgc, rg4
|
||||
jnz rg4, output
|
||||
ieq rg3, rgd, rg4
|
||||
jnz rg4, input
|
||||
ieq rg3, rge, rg4
|
||||
jnz rg4, expr_start
|
||||
ieq rg3, rgf, rg4
|
||||
jnz rg4, expr_end
|
||||
ieq rg3, zero, rg4
|
||||
jnz rg4, end
|
||||
|
||||
// if we get here, we don't know what the instruction is
|
||||
lwi error, rg2
|
||||
push rg0
|
||||
push rg1
|
||||
push rg2
|
||||
call print::print
|
||||
pop zero
|
||||
pop rg1
|
||||
pop rg0
|
||||
|
||||
db success: "Success!"
|
||||
end:
|
||||
call print::newline
|
||||
lwi success, rg0
|
||||
push rg0
|
||||
call print::print
|
||||
pop zero
|
||||
|
||||
subi rg7, 1
|
||||
jnz rg7, start
|
||||
hlt
|
||||
|
||||
loop_end:
|
||||
addi rg0, 1, rg0
|
||||
jmp loop_start
|
||||
|
||||
// ------------------------------------------
|
||||
// increment the current cell
|
||||
increment:
|
||||
addi rg2, 1, rg2
|
||||
jmp loop_end
|
||||
|
||||
// ------------------------------------------
|
||||
// decrement the current cell
|
||||
decrement:
|
||||
subi rg2, 1, rg2
|
||||
jmp loop_end
|
||||
|
||||
// ------------------------------------------
|
||||
// increment the pointer
|
||||
inc_ptr:
|
||||
stw rg2, rg1
|
||||
addi rg1, 4
|
||||
ldw rg1, rg2
|
||||
jmp loop_end
|
||||
|
||||
// ------------------------------------------
|
||||
// decrement the pointer
|
||||
dec_ptr:
|
||||
stw rg2, rg1
|
||||
subi rg1, 4
|
||||
ldw rg1, rg2
|
||||
jmp loop_end
|
||||
|
||||
// ------------------------------------------
|
||||
// print the byte in the current cell
|
||||
output:
|
||||
push rg0
|
||||
push rg1
|
||||
push rg2
|
||||
call print::print_byte
|
||||
pop zero
|
||||
pop rg1
|
||||
pop rg0
|
||||
jmp loop_end
|
||||
|
||||
// ------------------------------------------
|
||||
// read a byte into the current cell
|
||||
input:
|
||||
ldw input_addr, rg2
|
||||
jmp loop_end
|
||||
|
||||
// ------------------------------------------
|
||||
// handle an open bracket instruction
|
||||
expr_start:
|
||||
ieq rg2, zero, rg4
|
||||
jez rg4, loop_end
|
||||
|
||||
_traverse_right_start:
|
||||
// push a register that definitely has a nonzero value
|
||||
// when we pop this value from the stack
|
||||
// we know we've finished traversing.
|
||||
push rg8
|
||||
|
||||
_traverse_right:
|
||||
addi rg0, 1, rg0
|
||||
ldb rg0, rg3
|
||||
|
||||
ieq rg3, rge, rg4
|
||||
jnz rg4, open_right
|
||||
ieq rg3, rgf, rg4
|
||||
jnz rg4, close_right
|
||||
ieq rg3, zero, rg4
|
||||
jnz rg4, end
|
||||
jmp _traverse_right
|
||||
|
||||
open_right:
|
||||
// push zero to the stack
|
||||
push zero
|
||||
jmp _traverse_right
|
||||
|
||||
close_right:
|
||||
// check if we've reached the bottom of the stack
|
||||
pop rg4
|
||||
ieq rg4, zero, rg5
|
||||
jnz rg5, _traverse_right
|
||||
|
||||
// go to next instruction after closing bracket
|
||||
addi rg0, 1, rg0
|
||||
jmp loop_start
|
||||
|
||||
// ------------------------------------------
|
||||
// handle the close bracket instruction
|
||||
expr_end:
|
||||
ieq rg2, zero, rg4
|
||||
jnz rg4, loop_end
|
||||
|
||||
_traverse_left_start:
|
||||
push rg8
|
||||
|
||||
_traverse_left:
|
||||
subi rg0, 1, rg0
|
||||
ldb rg0, rg3
|
||||
|
||||
ieq rg3, rge, rg4
|
||||
jnz rg4, open_left
|
||||
ieq rg3, rgf, rg4
|
||||
jnz rg4, close_left
|
||||
ieq rg3, zero, rg4
|
||||
jnz rg4, end
|
||||
jmp _traverse_left
|
||||
|
||||
open_left:
|
||||
// check if we've reached the bottom of the stack
|
||||
pop rg4
|
||||
ieq rg4, zero, rg5
|
||||
jnz rg5, _traverse_left
|
||||
|
||||
// go to next instruction after open bracket
|
||||
addi rg0, 1, rg0
|
||||
jmp loop_start
|
||||
|
||||
close_left:
|
||||
// push zero to the stack
|
||||
push zero
|
||||
jmp _traverse_left
|
||||
|
||||
|
||||
// ------------------------------------------
|
||||
// reset interpreter
|
||||
// clears screen, resets cursor and clears data buffer.
|
||||
bf_reset: func
|
||||
push rg0
|
||||
push rg1
|
||||
|
||||
// clear screen and reset cursor
|
||||
call print::clear
|
||||
call print::reset
|
||||
|
||||
// clear data buffer (resb data: 1024 = 256 words)
|
||||
lli 256, rg0
|
||||
lwi data, rg1
|
||||
_bf_reset_clear_data:
|
||||
subi rg0, 1, rg0
|
||||
stw zero, rg1
|
||||
addi rg1, 4, rg1
|
||||
igt rg0, zero, rg4
|
||||
jnz rg4, _bf_reset_clear_data
|
||||
|
||||
pop rg1
|
||||
pop rg0
|
||||
|
||||
// reload interpreter state
|
||||
lwi program, rg0
|
||||
lwi data, rg1
|
||||
lli 0, rg2
|
||||
return
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,592 @@
|
||||
; ==== symbols ====
|
||||
; _print_hex_nibble 0x00000328 TEXT global
|
||||
; increment 0x000000ec TEXT global
|
||||
; _clear_loop 0x000003ec TEXT global
|
||||
; end 0x000000c0 TEXT global
|
||||
; reset 0x000003bc TEXT global
|
||||
; _print_end 0x00000288 TEXT global
|
||||
; decrement 0x000000f4 TEXT global
|
||||
; open_left 0x000001c8 TEXT global
|
||||
; open_right 0x0000017c TEXT global
|
||||
; expr_end 0x00000198 TEXT global
|
||||
; newline 0x00000378 TEXT global
|
||||
; input 0x0000013c TEXT global
|
||||
; loop_start 0x00000050 TEXT global
|
||||
; loop_end 0x000000e4 TEXT global
|
||||
; _traverse_right 0x00000158 TEXT global
|
||||
; dec_ptr 0x0000010c TEXT global
|
||||
; expr_start 0x0000014c TEXT global
|
||||
; print_hex_byte 0x000002e4 TEXT global
|
||||
; print_byte 0x000002b0 TEXT global
|
||||
; success 0x000009e8 DATA global
|
||||
; data 0x000005e8 DATA global
|
||||
; error 0x000005c4 DATA global
|
||||
; clear 0x000003d4 TEXT global
|
||||
; _print_hex_byte 0x00000304 TEXT global
|
||||
; _bf_reset_clear_data 0x00000208 TEXT global
|
||||
; bf_reset 0x000001e4 TEXT global
|
||||
; _end 0x00000404 TEXT global
|
||||
; _traverse_left_start 0x000001a0 TEXT global
|
||||
; _init 0x00000000 TEXT global
|
||||
; counter 0x000005dc DATA global
|
||||
; _print_loop 0x0000026c TEXT global
|
||||
; print_whitespace 0x00000354 TEXT global
|
||||
; inc_ptr 0x000000fc TEXT global
|
||||
; current 0x000009f8 DATA global
|
||||
; _traverse_right_start 0x00000154 TEXT global
|
||||
; print 0x00000244 TEXT global
|
||||
; init 0x00000010 TEXT global
|
||||
; stack 0x000005e0 DATA global
|
||||
; _traverse_left 0x000001a4 TEXT global
|
||||
; start 0x0000001c TEXT global
|
||||
; close_left 0x000001dc TEXT global
|
||||
; input_addr 0x000005e4 DATA global
|
||||
; close_right 0x00000184 TEXT global
|
||||
; display 0x000009f4 DATA global
|
||||
; _newline_done 0x000003b0 TEXT global
|
||||
; program 0x0000041c DATA global
|
||||
; _newline_mod 0x000003a0 TEXT global
|
||||
; _print_hex_nibble_number 0x00000344 TEXT global
|
||||
; output 0x0000011c TEXT global
|
||||
|
||||
; ==== data ====
|
||||
db "++++++++++++++++++++++++++++++++++++++++++++>++++++++++++++++++++++++++++++++>++++++++++++++++>>+<<[>>>>++++++++++<<[->+>-[>+>>]>[+[-<+>]>+>>]<<<<<<]>[<+>-]>[-]>>>++++++++++<[->-[>+>>]>[+[-<+>]>+>>]<<<<<]>[-]>>[++++++++++++++++++++++++++++++++++++++++++++++++.[-]]<[++++++++++++++++++++++++++++++++++++++++++++++++.[-]]<<<++++++++++++++++++++++++++++++++++++++++++++++++.[-]<<<<<<<.>.>>[>>+<<-]>[>+<<+>-]>[<+>-]<<<-]<<++..."
|
||||
db "Invalid Instruction!"
|
||||
dw 0x00000000
|
||||
dw 0x000000ff
|
||||
dw 0x00000000
|
||||
dw 0x00000001
|
||||
dw 0x00000003
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
db "Success!"
|
||||
dw 0x00000000
|
||||
dw 0x00000000
|
||||
dw 0x00000002
|
||||
dw 0x00000002
|
||||
|
||||
; ==== text ====
|
||||
_init:
|
||||
ldw stack, Bpr, 0x0000
|
||||
mov Bpr, Spr
|
||||
init:
|
||||
ldw counter, Rg7, 0x0000
|
||||
start:
|
||||
call bf_reset
|
||||
lwi program, Rg0
|
||||
lwi data, Rg1
|
||||
lli Rg8, 0x002b
|
||||
lli Rg9, 0x002d
|
||||
lli Rga, 0x003e
|
||||
lli Rgb, 0x003c
|
||||
lli Rgc, 0x002e
|
||||
lli Rgd, 0x002c
|
||||
lli Rge, 0x005b
|
||||
lli Rgf, 0x005d
|
||||
loop_start:
|
||||
ldb Rg0, Rg3, 0x0000
|
||||
ieq Rg3, Rg8, Rg4
|
||||
jnz Rg4, increment
|
||||
ieq Rg3, Rg9, Rg4
|
||||
jnz Rg4, decrement
|
||||
ieq Rg3, Rga, Rg4
|
||||
jnz Rg4, inc_ptr
|
||||
ieq Rg3, Rgb, Rg4
|
||||
jnz Rg4, dec_ptr
|
||||
ieq Rg3, Rgc, Rg4
|
||||
jnz Rg4, output
|
||||
ieq Rg3, Rgd, Rg4
|
||||
jnz Rg4, input
|
||||
ieq Rg3, Rge, Rg4
|
||||
jnz Rg4, expr_start
|
||||
ieq Rg3, Rgf, Rg4
|
||||
jnz Rg4, expr_end
|
||||
ieq Rg3, Zero, Rg4
|
||||
jnz Rg4, end
|
||||
lwi error, Rg2
|
||||
push Rg0
|
||||
push Rg1
|
||||
push Rg2
|
||||
call print
|
||||
pop Zero
|
||||
pop Rg1
|
||||
pop Rg0
|
||||
end:
|
||||
call newline
|
||||
lwi success, Rg0
|
||||
push Rg0
|
||||
call print
|
||||
pop Zero
|
||||
subi Rg7, Rg7, 0x0001
|
||||
jnz Rg7, start
|
||||
hlt
|
||||
loop_end:
|
||||
addi Rg0, Rg0, 0x0001
|
||||
jmp loop_start
|
||||
increment:
|
||||
addi Rg2, Rg2, 0x0001
|
||||
jmp loop_end
|
||||
decrement:
|
||||
subi Rg2, Rg2, 0x0001
|
||||
jmp loop_end
|
||||
inc_ptr:
|
||||
stw Rg2, Rg1, 0x0000
|
||||
addi Rg1, Rg1, 0x0004
|
||||
ldw Rg1, Rg2, 0x0000
|
||||
jmp loop_end
|
||||
dec_ptr:
|
||||
stw Rg2, Rg1, 0x0000
|
||||
subi Rg1, Rg1, 0x0004
|
||||
ldw Rg1, Rg2, 0x0000
|
||||
jmp loop_end
|
||||
output:
|
||||
push Rg0
|
||||
push Rg1
|
||||
push Rg2
|
||||
call print_byte
|
||||
pop Zero
|
||||
pop Rg1
|
||||
pop Rg0
|
||||
jmp loop_end
|
||||
input:
|
||||
ldw input_addr, Rg2, 0x0000
|
||||
jmp loop_end
|
||||
expr_start:
|
||||
ieq Rg2, Zero, Rg4
|
||||
jez Rg4, loop_end
|
||||
_traverse_right_start:
|
||||
push Rg8
|
||||
_traverse_right:
|
||||
addi Rg0, Rg0, 0x0001
|
||||
ldb Rg0, Rg3, 0x0000
|
||||
ieq Rg3, Rge, Rg4
|
||||
jnz Rg4, open_right
|
||||
ieq Rg3, Rgf, Rg4
|
||||
jnz Rg4, close_right
|
||||
ieq Rg3, Zero, Rg4
|
||||
jnz Rg4, end
|
||||
jmp _traverse_right
|
||||
open_right:
|
||||
push Zero
|
||||
jmp _traverse_right
|
||||
close_right:
|
||||
pop Rg4
|
||||
ieq Rg4, Zero, Rg5
|
||||
jnz Rg5, _traverse_right
|
||||
addi Rg0, Rg0, 0x0001
|
||||
jmp loop_start
|
||||
expr_end:
|
||||
ieq Rg2, Zero, Rg4
|
||||
jnz Rg4, loop_end
|
||||
_traverse_left_start:
|
||||
push Rg8
|
||||
_traverse_left:
|
||||
subi Rg0, Rg0, 0x0001
|
||||
ldb Rg0, Rg3, 0x0000
|
||||
ieq Rg3, Rge, Rg4
|
||||
jnz Rg4, open_left
|
||||
ieq Rg3, Rgf, Rg4
|
||||
jnz Rg4, close_left
|
||||
ieq Rg3, Zero, Rg4
|
||||
jnz Rg4, end
|
||||
jmp _traverse_left
|
||||
open_left:
|
||||
pop Rg4
|
||||
ieq Rg4, Zero, Rg5
|
||||
jnz Rg5, _traverse_left
|
||||
addi Rg0, Rg0, 0x0001
|
||||
jmp loop_start
|
||||
close_left:
|
||||
push Zero
|
||||
jmp _traverse_left
|
||||
bf_reset:
|
||||
push Bpr
|
||||
mov Spr, Bpr
|
||||
push Rg0
|
||||
push Rg1
|
||||
call clear
|
||||
call reset
|
||||
lli Rg0, 0x0100
|
||||
lwi data, Rg1
|
||||
_bf_reset_clear_data:
|
||||
subi Rg0, Rg0, 0x0001
|
||||
stw Zero, Rg1, 0x0000
|
||||
addi Rg1, Rg1, 0x0004
|
||||
igt Rg0, Zero, Rg4
|
||||
jnz Rg4, _bf_reset_clear_data
|
||||
pop Rg1
|
||||
pop Rg0
|
||||
lwi program, Rg0
|
||||
lwi data, Rg1
|
||||
lli Rg2, 0x0000
|
||||
mov Bpr, Spr
|
||||
pop Bpr
|
||||
ret
|
||||
print:
|
||||
push Bpr
|
||||
mov Spr, Bpr
|
||||
push Rg0
|
||||
push Rg1
|
||||
push Rg2
|
||||
push Rg3
|
||||
ldw Bpr, Rg0, 0x0008
|
||||
ldw current, Rg1, 0x0000
|
||||
_print_loop:
|
||||
ldb Rg0, Rg2, 0x0000
|
||||
ieq Rg2, Zero, Rg3
|
||||
jnz Rg3, _print_end
|
||||
stb Rg2, Rg1, 0x0000
|
||||
addi Rg0, Rg0, 0x0001
|
||||
addi Rg1, Rg1, 0x0001
|
||||
jmp _print_loop
|
||||
_print_end:
|
||||
stw current, Rg1, 0x0000
|
||||
pop Rg3
|
||||
pop Rg2
|
||||
pop Rg1
|
||||
pop Rg0
|
||||
mov Bpr, Spr
|
||||
pop Bpr
|
||||
ret
|
||||
print_byte:
|
||||
push Bpr
|
||||
mov Spr, Bpr
|
||||
push Rg0
|
||||
push Rg1
|
||||
ldw Bpr, Rg0, 0x0008
|
||||
ldw current, Rg1, 0x0000
|
||||
stb Rg0, Rg1, 0x0000
|
||||
addi Rg1, Rg1, 0x0001
|
||||
pop Rg1
|
||||
pop Rg0
|
||||
jmp _end
|
||||
print_hex_byte:
|
||||
push Bpr
|
||||
mov Spr, Bpr
|
||||
ldw Bpr, Rg0, 0x0008
|
||||
ldw current, Rg1, 0x0000
|
||||
call _print_hex_byte
|
||||
jmp _end
|
||||
_print_hex_byte:
|
||||
lli Rg2, 0x000f
|
||||
push Rg0
|
||||
shr Rg0, Rg0, Zero, 4
|
||||
and Rg0, Rg2, Rg0
|
||||
call _print_hex_nibble
|
||||
pop Rg0
|
||||
and Rg0, Rg2, Rg0
|
||||
call _print_hex_nibble
|
||||
ret
|
||||
_print_hex_nibble:
|
||||
lli Rg3, 0x000a
|
||||
ilt Rg0, Rg3, Rg4
|
||||
jnz Rg4, _print_hex_nibble_number
|
||||
addi Rg0, Rg0, 0x0037
|
||||
stb Rg0, Rg1, 0x0000
|
||||
addi Rg1, Rg1, 0x0001
|
||||
ret
|
||||
_print_hex_nibble_number:
|
||||
addi Rg0, Rg0, 0x0030
|
||||
stb Rg0, Rg1, 0x0000
|
||||
addi Rg1, Rg1, 0x0001
|
||||
ret
|
||||
print_whitespace:
|
||||
push Bpr
|
||||
mov Spr, Bpr
|
||||
ldw current, Rg1, 0x0000
|
||||
lli Rg0, 0x0020
|
||||
stb Rg0, Rg1, 0x0000
|
||||
addi Rg1, Rg1, 0x0001
|
||||
jmp _end
|
||||
newline:
|
||||
push Bpr
|
||||
mov Spr, Bpr
|
||||
ldw display, Rg0, 0x0000
|
||||
ldw current, Rg1, 0x0000
|
||||
sub Rg1, Rg0, Rg2
|
||||
lli Rg3, 0x0050
|
||||
_newline_mod:
|
||||
ilt Rg2, Rg3, Rg4
|
||||
jnz Rg4, _newline_done
|
||||
sub Rg2, Rg3, Rg2
|
||||
jmp _newline_mod
|
||||
_newline_done:
|
||||
sub Rg1, Rg2, Rg1
|
||||
addi Rg1, Rg1, 0x0050
|
||||
jmp _end
|
||||
reset:
|
||||
push Bpr
|
||||
mov Spr, Bpr
|
||||
ldw display, Rg1, 0x0000
|
||||
jmp _end
|
||||
clear:
|
||||
push Bpr
|
||||
mov Spr, Bpr
|
||||
lli Rg0, 0x01f4
|
||||
ldw display, Rg1, 0x0000
|
||||
_clear_loop:
|
||||
subi Rg0, Rg0, 0x0001
|
||||
stw Zero, Rg1, 0x0000
|
||||
addi Rg1, Rg1, 0x0004
|
||||
igt Rg0, Zero, Rg4
|
||||
jnz Rg4, _clear_loop
|
||||
jmp _end
|
||||
_end:
|
||||
stw current, Rg1, 0x0000
|
||||
mov Bpr, Spr
|
||||
pop Bpr
|
||||
ret
|
||||
@@ -0,0 +1,65 @@
|
||||
|
||||
include print: "./print.dsa"
|
||||
|
||||
db success: "Success!"
|
||||
dw framebuffer: 0x30000
|
||||
dw stack: 0x10000
|
||||
|
||||
_init:
|
||||
ldw stack, bpr
|
||||
mov bpr, spr
|
||||
|
||||
start:
|
||||
ldw framebuffer, rg0 // rg0 = display base address
|
||||
lli 0, rg1 // rg1 = y (0..240)
|
||||
|
||||
y_loop:
|
||||
lli 0, rg2 // rg2 = x (0..320)
|
||||
|
||||
x_loop:
|
||||
// red = x >> 1 (0..159, left to right gradient)
|
||||
shr rg2, zero, 1, rg4
|
||||
|
||||
// green = y (0..239, top to bottom gradient)
|
||||
mov rg1, rg5
|
||||
|
||||
// blue = constant 128
|
||||
lli 0x80, rg6
|
||||
|
||||
// pack as 0xAABBGGRR (LE reads as RGBA)
|
||||
// start with red in bits 0-7
|
||||
mov rg4, rg7
|
||||
|
||||
// green into bits 8-15
|
||||
shl rg5, zero, 8, rg5
|
||||
or rg7, rg5, rg7
|
||||
|
||||
// blue into bits 16-23
|
||||
shl rg6, zero, 16, rg6
|
||||
or rg7, rg6, rg7
|
||||
|
||||
// alpha into bits 24-31
|
||||
lli 0xFF, rg6
|
||||
shl rg6, zero, 24, rg6
|
||||
or rg7, rg6, rg7
|
||||
|
||||
stw rg7, rg0 // write pixel
|
||||
addi rg0, 4, rg0 // next pixel
|
||||
|
||||
addi rg2, 1, rg2
|
||||
lli 320, rg6
|
||||
ilt rg2, rg6, rg6
|
||||
jnz rg6, x_loop
|
||||
|
||||
addi rg1, 1, rg1
|
||||
lli 240, rg6
|
||||
ilt rg1, rg6, rg6
|
||||
jnz rg6, y_loop
|
||||
|
||||
|
||||
_end:
|
||||
lwi success: rg0
|
||||
push rg0
|
||||
call print::print
|
||||
pop zero
|
||||
hlt
|
||||
Binary file not shown.
@@ -0,0 +1,58 @@
|
||||
include print: "./print.dsa"
|
||||
include serial: "./serial.dsa"
|
||||
|
||||
dw idt: 0xFFFF0000
|
||||
setup_base: func
|
||||
push rg0
|
||||
push rg1
|
||||
push rg2
|
||||
push rg3
|
||||
|
||||
ldw idt, idr // load the IDT into the IDR
|
||||
|
||||
// set all 256 interrupt addresses to point to guard
|
||||
lwi _guard, rg1 // load address of guard handler
|
||||
addi idr, 1024, rg2 // counter for 256 entries
|
||||
_loop_start:
|
||||
stw rg1, rg2 // store guard into current IDT entry
|
||||
subi rg2, 4, rg2 // decrement counter
|
||||
ieq rg2, idr, rg3 // check if we've reached the base address
|
||||
jez rg3, _loop_start // repeat until all entries set
|
||||
|
||||
// make sure we can handle an invalid interrupt
|
||||
lwi _handle_invalid_interrupt, rg0
|
||||
stw rg0, idr, 0
|
||||
|
||||
pop rg3
|
||||
pop rg2
|
||||
pop rg1
|
||||
pop rg0
|
||||
return
|
||||
|
||||
setup_io: func
|
||||
push rg0
|
||||
|
||||
lwi serial::isr, rg0
|
||||
stw rg0, idr, 128 // 32*4, interrupt idx 32
|
||||
|
||||
pop rg0
|
||||
return
|
||||
|
||||
|
||||
db _invalid_int: "FATAL: Invalid Interrupt!"
|
||||
_handle_invalid_interrupt:
|
||||
call print::reset
|
||||
lwi _invalid_int, rg0
|
||||
push rg0
|
||||
call print::print
|
||||
pop zero
|
||||
hlt
|
||||
|
||||
db _err: "FATAL: Interrupt handler was not set!"
|
||||
_guard:
|
||||
call print::reset
|
||||
lwi _err, rg0
|
||||
push rg0
|
||||
call print::print
|
||||
pop zero
|
||||
hlt
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,336 @@
|
||||
// lib:
|
||||
// print.dsa
|
||||
|
||||
// usage:
|
||||
//
|
||||
// include print "<relative path>"
|
||||
//
|
||||
// usage for print:
|
||||
// push (register containing address of string)
|
||||
// call print::print
|
||||
//
|
||||
// usage for reset:
|
||||
// call print::reset
|
||||
//
|
||||
// usage for clear:
|
||||
// call print::clear
|
||||
//
|
||||
// usage for print_byte:
|
||||
// push (register containing byte)
|
||||
// call print::print_byte
|
||||
//
|
||||
// usage for print_word:
|
||||
// push (register containing word)
|
||||
// call print::print_word
|
||||
//
|
||||
// usage for print_num:
|
||||
// push (register containing number to print in decimal)
|
||||
// call print::print_num
|
||||
//
|
||||
|
||||
dw display: 0x20000
|
||||
dw current: 0x20000
|
||||
|
||||
// ------------------------------------------
|
||||
// prints the string at addr(arg[0]) to the screen.
|
||||
print: func
|
||||
push rg0
|
||||
push rg1
|
||||
push rg2
|
||||
push rg3
|
||||
|
||||
ldw bpr, rg0, 8
|
||||
ldw current, rg1
|
||||
|
||||
_print_loop:
|
||||
ldb rg0, rg2
|
||||
ieq rg2, zero, rg3
|
||||
jnz rg3, _print_end
|
||||
stb rg2, rg1
|
||||
|
||||
addi rg0, 1
|
||||
addi rg1, 1
|
||||
|
||||
jmp _print_loop
|
||||
|
||||
_print_end:
|
||||
stw rg1, current
|
||||
|
||||
pop rg3
|
||||
pop rg2
|
||||
pop rg1
|
||||
pop rg0
|
||||
return
|
||||
|
||||
// ------------------------------------------
|
||||
// println:
|
||||
// push bpr
|
||||
// mov spr, bpr
|
||||
|
||||
// ldw bpr, rg0, 8
|
||||
// ldw current, rg1
|
||||
|
||||
// _println_loop:
|
||||
// ldb rg0, acc
|
||||
// ieq acc, zero, rg4
|
||||
// jnz rg4, _println_end
|
||||
// stb acc, rg1
|
||||
|
||||
// addi rg0, 1
|
||||
// addi rg1, 1
|
||||
|
||||
// jmp _println_loop
|
||||
|
||||
// _println_end:
|
||||
// call print_newline
|
||||
// jmp _end
|
||||
|
||||
// ------------------------------------------
|
||||
// prints the value of arg[0] to the screen.
|
||||
// print_word:
|
||||
// push bpr
|
||||
// mov spr, bpr
|
||||
|
||||
// ldw bpr, rg0, 8
|
||||
// ldw current, rg1
|
||||
|
||||
// addi rg1, 3
|
||||
|
||||
// stb rg0, rg1
|
||||
// subi rg1, 1
|
||||
// shr rg0, 8
|
||||
// stb rg0, rg1
|
||||
// subi rg1, 1
|
||||
// shr rg0, 8
|
||||
// stb rg0, rg1
|
||||
// subi rg1, 1
|
||||
// shr rg0, 8
|
||||
// stb rg0, rg1
|
||||
|
||||
// addi rg1, 4
|
||||
// jmp _end
|
||||
|
||||
// ------------------------------------------
|
||||
// prints the last byte of arg[0] to the screen.
|
||||
print_byte: func
|
||||
push rg0
|
||||
push rg1
|
||||
|
||||
ldw bpr, rg0, 8
|
||||
ldw current, rg1
|
||||
|
||||
stb rg0, rg1
|
||||
addi rg1, 1
|
||||
stw rg1, current
|
||||
|
||||
pop rg1
|
||||
pop rg0
|
||||
return
|
||||
|
||||
// ------------------------------------------
|
||||
// prints the value of arg[0] to the screen in hex.
|
||||
// print_hex_word:
|
||||
// push bpr
|
||||
// mov spr, bpr
|
||||
|
||||
// ldw current, rg1
|
||||
|
||||
// ldb bpr, rg0, 8
|
||||
// push rg0
|
||||
// call _print_hex_byte
|
||||
// addi spr, 4
|
||||
|
||||
// ldb bpr, rg0, 9
|
||||
// push rg0
|
||||
// call _print_hex_byte
|
||||
// addi spr, 4
|
||||
|
||||
// ldb bpr, rg0, 10
|
||||
// push rg0
|
||||
// call _print_hex_byte
|
||||
// addi spr, 4
|
||||
|
||||
// ldb bpr, rg0, 11
|
||||
// push rg0
|
||||
// call _print_hex_byte
|
||||
// addi spr, 4
|
||||
|
||||
// jmp _end
|
||||
|
||||
// ------------------------------------------
|
||||
// prints the last byte of arg[0] to the screen in hex.
|
||||
print_hex_byte: func
|
||||
ldw bpr, rg0, 8
|
||||
ldw current, rg1
|
||||
|
||||
call _print_hex_byte
|
||||
jmp _end
|
||||
|
||||
// function body
|
||||
_print_hex_byte:
|
||||
lli 0xF, rg2
|
||||
push rg0
|
||||
|
||||
shr rg0, 4
|
||||
and rg0, rg2, rg0
|
||||
call _print_hex_nibble
|
||||
pop rg0
|
||||
|
||||
and rg0, rg2, rg0
|
||||
call _print_hex_nibble
|
||||
ret
|
||||
|
||||
// print a hex digit
|
||||
_print_hex_nibble:
|
||||
lli 10, rg3
|
||||
ilt rg0, rg3, rg4
|
||||
jnz rg4, _print_hex_nibble_number
|
||||
addi rg0, 0x37, rg0
|
||||
stb rg0, rg1
|
||||
addi rg1, 1
|
||||
ret
|
||||
|
||||
// helper function.
|
||||
_print_hex_nibble_number:
|
||||
addi rg0, 0x30, rg0
|
||||
stb rg0, rg1
|
||||
addi rg1, 1
|
||||
ret
|
||||
|
||||
// ------------------------------------------
|
||||
// print whitespace
|
||||
print_whitespace: func
|
||||
ldw current, rg1
|
||||
lli 0x20, rg0
|
||||
stb rg0, rg1
|
||||
addi rg1, 1
|
||||
jmp _end
|
||||
|
||||
// ------------------------------------------
|
||||
// print newline
|
||||
// print_newline:
|
||||
// push bpr
|
||||
// mov spr, bpr
|
||||
|
||||
// ldw display, rg0
|
||||
// ldw current, rg1
|
||||
|
||||
// sub rg1, rg0, rg0
|
||||
|
||||
// lwi 80, rg2
|
||||
// push rg0
|
||||
// push rg1
|
||||
// push rg2
|
||||
// push rg0
|
||||
// push rg2
|
||||
// call maths::divmod
|
||||
// pop zero // result
|
||||
// pop rg3 // remainder
|
||||
// pop rg0
|
||||
// pop rg1
|
||||
// pop rg2
|
||||
|
||||
// sub rg1, rg3, rg2
|
||||
// addi rg2, 80, rg1
|
||||
|
||||
// jmp _end
|
||||
|
||||
newline:
|
||||
push bpr
|
||||
mov spr, bpr
|
||||
|
||||
ldw display, rg0
|
||||
ldw current, rg1
|
||||
|
||||
sub rg1, rg0, rg2 // offset from base
|
||||
lli 80, rg3
|
||||
|
||||
_newline_mod:
|
||||
ilt rg2, rg3, rg4
|
||||
jnz rg4, _newline_done
|
||||
sub rg2, rg3, rg2
|
||||
jmp _newline_mod
|
||||
|
||||
_newline_done:
|
||||
// rg2 = offset % 80 (position within current line)
|
||||
sub rg1, rg2, rg1 // go back to line start
|
||||
addi rg1, 80, rg1 // advance to next line
|
||||
|
||||
jmp _end
|
||||
|
||||
// ------------------------------------------
|
||||
// prints arg[0] as a decimal number to the screen.
|
||||
// print_num:
|
||||
// push bpr
|
||||
// mov spr, bpr
|
||||
|
||||
// ldw bpr, rg0, 8
|
||||
// lli 0, rg5
|
||||
|
||||
// ieq rg0, zero, rg4
|
||||
// jez rg4, _print_num_extract_digits
|
||||
|
||||
// lli 0x30, rg6
|
||||
// push rg6
|
||||
// lli 1, rg5
|
||||
// jmp _print_num_output
|
||||
|
||||
// _print_num_extract_digits:
|
||||
// ieq rg0, zero, rg4
|
||||
// jnz rg4, _print_num_output
|
||||
|
||||
// push rg0
|
||||
// lli 10, rg1
|
||||
// push rg1
|
||||
// call maths::divmod
|
||||
// pop rg0 // quotient
|
||||
// pop rg1 // remainder
|
||||
|
||||
// addi rg1, 0x30, rg6
|
||||
// push rg6
|
||||
// inc rg5
|
||||
|
||||
// jmp _print_num_extract_digits
|
||||
|
||||
// _print_num_output:
|
||||
// ldw current, rg1
|
||||
|
||||
// _print_num_output_loop:
|
||||
// ieq rg5, zero, rg4
|
||||
// jnz rg4, _print_num_done
|
||||
|
||||
// pop rg6
|
||||
// stb rg6, rg1
|
||||
// addi rg1, 1
|
||||
// dec rg5
|
||||
|
||||
// jmp _print_num_output_loop
|
||||
|
||||
// _print_num_done:
|
||||
// jmp _end
|
||||
|
||||
// ------------------------------------------
|
||||
// resets the cursor position to 0x20000 (0,0)
|
||||
reset: func
|
||||
ldw display, rg1
|
||||
jmp _end
|
||||
|
||||
// ------------------------------------------
|
||||
// clears the screen
|
||||
clear: func
|
||||
lli 500, rg0
|
||||
ldw display, rg1
|
||||
|
||||
_clear_loop:
|
||||
subi rg0, 1, rg0
|
||||
stw zero, rg1
|
||||
addi rg1, 4
|
||||
igt rg0, zero, rg4
|
||||
jnz rg4, _clear_loop
|
||||
jmp _end
|
||||
|
||||
// ------------------------------------------
|
||||
// return — saves current, restores frame, returns
|
||||
_end:
|
||||
stw rg1, current
|
||||
return
|
||||
@@ -0,0 +1,135 @@
|
||||
// Serial port address in MMIO
|
||||
dw UART: 0x40000
|
||||
|
||||
// Reserve space for our read buffer
|
||||
resb SERIAL_BUFFER: 1025 // final byte is a null terminator
|
||||
dw SER_READ_PTR: 0
|
||||
dw SER_WRITE_PTR: 0
|
||||
|
||||
reset: func
|
||||
push rg0
|
||||
|
||||
lwi SERIAL_BUFFER, rg0
|
||||
stw rg0, SER_READ_PTR, 0
|
||||
stw rg0, SER_WRITE_PTR, 0
|
||||
|
||||
pop rg0
|
||||
return
|
||||
|
||||
isr:
|
||||
push rg0
|
||||
push rg1
|
||||
push rg2
|
||||
|
||||
ldw UART, rg0
|
||||
ldb rg0, rg1, 2 // load ser_in_valid flag
|
||||
|
||||
// no serial input
|
||||
jez rg1, _isr_end
|
||||
|
||||
// we should have a valid byte to read at offset 3
|
||||
ldb rg0, rg1, 3 // data byte
|
||||
stb zero, rg0, 2 // unset ser_in_valid
|
||||
|
||||
// write data to ptr and increment
|
||||
ldw SER_WRITE_PTR, rg2
|
||||
stb rg1, rg2
|
||||
addi rg2, 1
|
||||
|
||||
// load buff+1024
|
||||
lwi SERIAL_BUFFER, rg0
|
||||
addi rg0, 1024, rg1
|
||||
|
||||
// if ptr != buff+1024, nowrap.
|
||||
ine rg1, rg2, rg1
|
||||
jnz rg1, _isr_nowrap
|
||||
|
||||
lwi SERIAL_BUFFER, rg2 // set the pointer
|
||||
|
||||
_isr_nowrap:
|
||||
stw rg2, SER_WRITE_PTR
|
||||
|
||||
_isr_end:
|
||||
pop rg2
|
||||
pop rg1
|
||||
pop rg0
|
||||
iret
|
||||
|
||||
// serial_readline: waits until a null byte is received
|
||||
// returns nothing, data is in SERIAL_BUFFER starting at SER_READ_PTR
|
||||
readline: func
|
||||
push rg0
|
||||
push rg1
|
||||
_readline_wait:
|
||||
// check if write ptr == read ptr (buffer empty)
|
||||
ldw SER_WRITE_PTR, rg0
|
||||
ldw SER_READ_PTR, rg1
|
||||
ieq rg0, rg1, rg0
|
||||
jnz rg0, _readline_halt // nothing written yet, halt
|
||||
|
||||
// check if the byte just before write ptr is null
|
||||
ldw SER_WRITE_PTR, rg0
|
||||
// handle wrap: if write ptr == SERIAL_BUFFER, check last byte of buffer
|
||||
lwi SERIAL_BUFFER, rg1
|
||||
ieq rg0, rg1, rg1
|
||||
jnz rg1, _readline_check_wrap
|
||||
|
||||
// normal case: read byte at write_ptr - 1
|
||||
subi rg0, 1, rg0
|
||||
ldb rg0, rg1, 0
|
||||
jez rg1, _readline_done
|
||||
jmp _readline_halt
|
||||
|
||||
_readline_check_wrap:
|
||||
// write ptr is at start of buffer, last byte is at SERIAL_BUFFER + 1023
|
||||
lwi SERIAL_BUFFER, rg0
|
||||
addi rg0, 1023, rg0
|
||||
ldb rg0, rg1, 0
|
||||
jez rg1, _readline_done
|
||||
|
||||
_readline_halt:
|
||||
hlt
|
||||
jmp _readline_wait
|
||||
|
||||
_readline_done:
|
||||
pop rg1
|
||||
pop rg0
|
||||
return
|
||||
|
||||
// _serial_send: trashes rg2, rg3, rg4, rg5
|
||||
// byte to send in rg0
|
||||
_serial_send:
|
||||
ldw UART, rg5
|
||||
_serial_wait:
|
||||
ldb rg5, rg2, 0
|
||||
lli 0x01, rg3
|
||||
ieq rg2, rg3, rg4
|
||||
jnz rg4, _serial_wait
|
||||
stb rg0, rg5, 1
|
||||
stb rg3, rg5, 0 // rg3 is still 0x01 from above
|
||||
ret
|
||||
|
||||
print: func
|
||||
push rg0
|
||||
push rg1
|
||||
ldw bpr, rg0, 8
|
||||
_serial_print_loop:
|
||||
ldb rg0, rg1
|
||||
jez rg1, _serial_print_end
|
||||
push rg0
|
||||
mov rg1, rg0
|
||||
call _serial_send
|
||||
pop rg0
|
||||
addi rg0, 1, rg0
|
||||
jmp _serial_print_loop
|
||||
_serial_print_end:
|
||||
pop rg1
|
||||
pop rg0
|
||||
return
|
||||
|
||||
print_byte: func
|
||||
push rg0
|
||||
ldw bpr, rg0, 8
|
||||
call _serial_send
|
||||
pop rg0
|
||||
return
|
||||
@@ -0,0 +1,40 @@
|
||||
include serial: "./serial.dsa"
|
||||
include idt: "./idt.dsa"
|
||||
include print: "./print.dsa"
|
||||
|
||||
dw stack: 0x10000
|
||||
_init:
|
||||
ldw stack, bpr
|
||||
mov bpr, spr
|
||||
call idt::setup_base
|
||||
call idt::setup_io
|
||||
|
||||
call serial::reset
|
||||
|
||||
db hello: "Test message, hello world etc etc."
|
||||
main:
|
||||
//lwi hello, rg0
|
||||
//push rg0
|
||||
//call serial::print
|
||||
//pop zero
|
||||
|
||||
// lwi hello, rg0
|
||||
// push rg0
|
||||
// call print::print
|
||||
// pop zero
|
||||
|
||||
//lwi buff, rg0
|
||||
//lwi 32, rg1
|
||||
//push rg0
|
||||
//push rg1
|
||||
|
||||
call serial::readline
|
||||
|
||||
lwi serial::SERIAL_BUFFER, rg0
|
||||
push rg0
|
||||
call serial::print
|
||||
pop zero
|
||||
|
||||
call serial::reset
|
||||
hlt
|
||||
jmp main
|
||||
Reference in New Issue
Block a user