@ $00000: label vbuf: @ $4B000: $CB000 ; Set Instruction Pointer to $5B000 label RAX: $0000000 ; RAX $0000000 ; R2 - Temp Scratch $0000000 ; R3 - Temp Scratch label ARG1 $0000000 ; R4 - ARG 1 $0000000 ; R5 - ARG 2 $0000000 ; R6 - ARG 3 $0000000 ; R7 - ARG 4 $0000000 ; R8 - ARG 5 $0000000 ; RX $0000000 ; RY label R(B): $0000000 ; RVBUF (RY * 640) + RX label R(c): $0000001 ; Ghost Post @ $4B040: label CycleCount: $0000000; Cycles label KeyPressedState: $0000000; The ID of a Key Being Pressed (If Any) label _allocator_ptr: $000000 @ $4B0C0: hlt import display.asm ; setpos import charset.asm ; charset + hex strings import strings.asm ; draw_char, draw_string import util.asm ; print_addr import graphics.asm; draw_vline, draw_hline, draw_rect import windows.asm ; Common Strings data ascii TestWindow Test Window data ascii TestWindow2 Test Window The Second data ascii boo_os_version Boo OS v0.0.1 data ascii prompt [sarah@boo] > data ascii Welcome !@#$%^&*()_+=-0987654321 data ascii Introspection We Can Now Do Introspection: data ascii label_rax RAX: data ascii label_rip RIP: data ascii label_cycles Allocated Memory: data ascii label_keypress Current Key Pressed: data image boo_os.png booos.png data image boo_os_small.png booos-small.png data image wallpaper.png wallpaper.png data ascii quit_label QUIT data ascii jump_label JUMP data ascii diss_label DISS data ascii alloc_label ALLOC data ascii window_lol_label WINDOWS data buffer command_line_input 64 data buffers 48 terminal 64 meta ; strcmp compares 2 strings in a byte-by-byte manner, incrementing ptrs as it goes. Returns 1 if both bytes ; point to 0. Returns 0 (fail) if it encounters 2 different bytes ; clobbers $1 $2 $3 $4 $5 label strcmp: loadi $3 $0 label strcmp_loop: rload $4 $1 rload $5 $2 jeq +3 ; if either of these differ then return 0 to indicate these strings don't match loadi $1 0 ret loadi $2 0 jneq +3 ; if both are 0 then we have reached the end of the string loadi $1 1 ret inc $4 inc $5 inc $3 tx $1 $3 ;check expected length tx $2 $6 ;check max length jneq +3 ; if expected_length == max_length loadi $1 1 ; return true ret jmp strcmp_loop label shift_terminal: ; copy terminal 0 to terminal 1 loadi $4 terminal[5] ;src bcopy $4 terminal[6] ; dest ; copy terminal 0 to terminal 1 loadi $4 terminal[4] ;src bcopy $4 terminal[5] ; dest ; copy terminal 0 to terminal 1 loadi $4 terminal[3] ;src bcopy $4 terminal[4] ; dest ; copy terminal 0 to terminal 1 loadi $4 terminal[2] ;src bcopy $4 terminal[3] ; dest ; copy terminal 0 to terminal 1 loadi $4 terminal[1] ;src bcopy $4 terminal[2] ; dest ; copy terminal 0 to terminal 1 loadi $4 terminal[0] ;src bcopy $4 terminal[1] ; dest ; copy command line to terminal 0 loadi $4 command_line_input ;src bcopy $4 terminal[0] ; dest bzero command_line_input ret data ascii diss_nop nop data ascii diss_store store data ascii diss_load load data ascii diss_load_imm loadi (load immediate) data ascii diss_call call data ascii diss_ret ret data ascii diss_unknown unknown opcode ; structure asm block ; start length ; n ptr yo bu label window_lol $00 label append_num_to_string: tx $8 $4 loadi $6 7 label _append_num_to_string_inner: tx $4 $8 ; temp store for command loadi $5 4 ; number of bits to shift mul $6 $5 $5 ; number of bits to shift command >> (count * 8) (3*8, 2*8, 1*8, 0*8) shift $4 $5 $1 ; do the actual shift loadi $5 $00000F and $1 $5 $4 ; clobbers 1 2 3 4 call num_to_char; bappend $4 command_line_input tx $1 $6 loadi $2 0 jneq +2 ret dec $6 jmp _append_num_to_string_inner label _disassemble_cmd: loadi $1 $3A ; ':' bappend $1 command_line_input loadi $1 $20 bappend $1 command_line_input ; space loadi $1 1c ; 28 bits shift $4 $1 $2 ; loadi $5 diss_unknown ; Grab Op Register just in case and put it in $6 loadi $1 $18 ; 24 bits shift $4 $1 $6 ; loadi $1 $0F and $6 $1 $6 ; Grab Address just in case and put it in $7 loadi $3 $00FFFFFF and $4 $3 $7 loadi $C 1 ; default print target reg loadi $D 1 ; default print addr ; 0x0 = Meta loadi $1 $0 jneq +7 loadi $C 0 ; default print target reg loadi $D 0 ; default print addr loadi $1 0 tx $2 $6 jneq +2 loadi $5 diss_nop ; 0x1 = Store loadi $1 $1 jneq +2 loadi $5 diss_store ; 0x2 = LOAD loadi $1 $2 jneq +2 loadi $5 diss_load ; 0x3 = LOAD IMM loadi $1 $3 jneq +2 loadi $5 diss_load_imm ; 0x0C = Call / Ret loadi $1 $C jneq +7 loadi $5 diss_call loadi 1 0 loadi $C 0 ; don't print address tx 2 6 jneq +2 loadi $5 diss_ret label _disassemble_cmd_inner: rload $5 $1 loadi $2 0 jeq +4 ; _print reg bappend $1 command_line_input inc $5 jmp _disassemble_cmd_inner ; Check if we need to prin the register and print it tx $1 $C loadi $2 1 jneq +6 loadi $1 $20 bappend $1 command_line_input ; space tx $4 $6 call num_to_char bappend $4 command_line_input ; check if we need to print the address and print it tx $1 $D loadi $2 1 jneq +6 loadi $1 $20 bappend $1 command_line_input ; space tx $4 $7 loadi $5 command_line_input call append_num_to_string ret label disassemble: call string_to_num ; $1 contains a actual address we want to diss loadi $2 $FFFFFF; jlt +2 ret rload $1 $8 ; call shift_terminal bzero command_line_input loadi $6 7 label _disassemble_inner: tx $4 $8 ; temp store for command loadi $5 4 ; number of bits to shift mul $6 $5 $5 ; number of bits to shift command >> (count * 8) (3*8, 2*8, 1*8, 0*8) shift $4 $5 $1 ; do the actual shift loadi $5 $00000F and $1 $5 $4 ; clobbers 1 2 3 4 call num_to_char; bappend $4 command_line_input tx $1 $6 loadi $2 0 jneq +4 tx $4 $8 call _disassemble_cmd ret dec $6 jmp _disassemble_inner label jump: call string_to_num ijmp $1 ;;lol ret label do_shell: loadi $4 @command_line_input loadi $5 quit_label loadi $6 4 call strcmp loadi $2 1 jneq +2 ; if the command is QUIT, then hlt the machine!! A shell is born hlt loadi $4 @command_line_input loadi $5 diss_label loadi $6 4 call strcmp loadi $2 1 jneq +6 ; if the command is QUIT, then hlt the machine!! A shell is born loadi $4 @command_line_input loadi $5 5 add $4 $5 $4 call disassemble ret loadi $4 @command_line_input loadi $5 jump_label loadi $6 4 call strcmp loadi $2 1 jneq +5 ; if the command is QUIT, then hlt the machine!! A shell is born loadi $4 @command_line_input loadi $5 5 add $4 $5 $4 call jump loadi $4 @command_line_input loadi $5 window_lol_label loadi $6 ff call strcmp loadi $2 1 jneq +4 ; if the command is QUIT, then hlt the machine!! A shell is born loadi $1 1 store $1 window_lol ret loadi $4 @command_line_input loadi $5 alloc_label loadi $6 5 call strcmp loadi $2 1 jneq +6 call shift_terminal bzero command_line_input loadi $4 10; call $FFFFF0 call append_num_to_string ret label handle_keypress: ; Check for Backspace loadi $1 $7F tx $2 $4 jneq +3 bdelete $4 command_line_input ret ; Check for Return loadi $1 $0A tx $2 $4 jneq +4 call do_shell call shift_terminal ret bappend $4 command_line_input ret label kernel_windows_start: nop label kernel_windows_end: nop ; 4 contains the data we want to store label make_node: tx $C $4 ; temp store 4 loadi $4 2 ; each node is 2 words call FFFFF0 ; Allocate space ; 4 now contains a ptr to new space rstore $C $4 ret ; $4 contains the ptr to the new node ; $5 contains the ptr to the end node label append_node: inc $5 rstore $4 $5 ; store the pointer to the new node $4 in the next ptr in $5 store $4 kernel_windows_end ; bump the end pointer ret label _temp_window_list_ptr nop ; Kernel Begins @ $CB000: ; Create a Test Window loadi $4 $30 loadi $5 $30 loadi $6 $A0 loadi $7 $A0 loadi $8 TestWindow call make_window call make_node ; with the data in 4 store $4 kernel_windows_start store $4 kernel_windows_end loadi $4 $55 loadi $5 $70 loadi $6 $F0 loadi $7 $A0 loadi $8 TestWindow2 call make_window call make_node ; with the data in 4 loadi $5 kernel_windows_end rload $5 $5 call append_node ;tore $4 kernel_windows_end ; bump the end pointer label kernel_loop: loadi $9 $0; 640-64 loadi $A $0; 480-64 call set_pos loadi $4 wallpaper.png call draw_image loadi $4 $0 loadi $5 $0 loadi $6 $280 loadi $7 $10 loadi $8 $222222 call draw_filled_rect load $1 window_lol loadi $2 1 jneq +19 load $1 CycleCount loadi $2 $1FF and $1 $2 $4 load $1 CycleCount loadi $2 F shift $1 $2 $1 loadi $2 $F0 and $1 $2 $5 loadi $1 1F add $1 $5 $5 loadi $6 64 loadi $7 64 loadi $8 TestWindow call make_window call make_node ; with the data in 4 loadi $5 kernel_windows_end rload $5 $5 call append_node ; Render All The Windows... load $4 kernel_windows_start label draw_next_window: store $4 _temp_window_list_ptr ; temp store rload $4 $4 call draw_window ; draw this window load $4 _temp_window_list_ptr ; load window pointer from temp inc $4 ; increment the pointer rload $4 $4 tx $1 $4 loadi $2 $0 jeq +2 jmp draw_next_window ;loadi $4 window_2 ;rload $4 $4 ;call draw_window loadi $9 $5; loadi $A $5; call set_pos loadi $4 boo_os_version call draw_string; loadi $9 $1A0; loadi $A $5; call set_pos loadi $4 label_cycles call draw_string; loadi $4 _allocator_ptr call print_addr loadi $9 1; loadi $A 20; call set_pos loadi $1 0 load $2 KeyPressedState store $1 KeyPressedState jeq +3 tx $4 $2 call handle_keypress ; print some shell history loadi $9 5; loadi $A 150; call set_pos loadi $4 @terminal[6] call draw_string; loadi $9 5; loadi $A 160; call set_pos loadi $4 @terminal[5] call draw_string; loadi $9 5; loadi $A 170; call set_pos loadi $4 @terminal[4] call draw_string; loadi $9 5; loadi $A 180; call set_pos loadi $4 @terminal[3] call draw_string; loadi $9 5; loadi $A 190; call set_pos loadi $4 @terminal[2] call draw_string; loadi $9 5; loadi $A 1A0; call set_pos loadi $4 @terminal[1] call draw_string; loadi $9 5; loadi $A 1B0; call set_pos loadi $4 @terminal[0] call draw_string; loadi $9 5; loadi $A 1C0; call set_pos loadi $4 prompt call draw_string; loadi $9 70; loadi $A 1C0; call set_pos loadi $4 @command_line_input call draw_string; updsp jmp kernel_loop; ; Very Very Basic Watermark Memory Allocator @ $FFFFF0: ; $4 contains a length which corresponds to number of bytes label allocator: load $1 _allocator_ptr add $1 $4 $1 store $1 _allocator_ptr loadi $2 $FFFFF0 sub $2 $1 $4 ret