From 9a1ce420edbc66f48aeb79ae776dad5f6bfa09db Mon Sep 17 00:00:00 2001 From: Sarah Jamie Lewis Date: Fri, 12 Nov 2021 22:03:26 -0800 Subject: [PATCH] JUMP command --- kernel.asm | 55 +++++++++++++++++++++++++++++++++++++++++------- src/assembler.rs | 24 +++++++++++++++++++++ src/lib.rs | 28 ++++++++++++++++++++++++ strings.asm | 38 ++++++++++++++++++++++++++++++++- 4 files changed, 136 insertions(+), 9 deletions(-) diff --git a/kernel.asm b/kernel.asm index 0ce9655..329786c 100644 --- a/kernel.asm +++ b/kernel.asm @@ -7,6 +7,7 @@ $0000000 ; RAX $0000000 ; R2 - Temp Scratch $0000000 ; R3 - Temp Scratch + label ARG1 $0000000 ; R4 - ARG 1 $0000000 ; R5 - ARG 2 $0000000 ; R6 - ARG 3 @@ -27,6 +28,8 @@ @ $4B0C0: +hlt + import display.asm ; setpos import charset.asm ; charset + hex strings import strings.asm ; draw_char, draw_string @@ -47,6 +50,7 @@ data image boo_os_small.png booos-small.png data image wallpaper.png wallpaper.png data ascii quit_label QUIT +data ascii diss_label JUMP data buffer command_line_input 64 @@ -57,20 +61,32 @@ 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 $4 $5 +; 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 @@ -92,6 +108,34 @@ label shift_terminal: ret + +label disassemble: + 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 +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 disassemble + + ret + label handle_keypress: ; Check for Backspace @@ -104,13 +148,8 @@ label handle_keypress: ; Check for Return loadi $1 $0A tx $2 $4 - jneq +9 - loadi $4 @command_line_input - loadi $5 quit_label - call strcmp - loadi $2 1 - jneq +2 ; if the command is QUIT, then hlt the machine!! A shell is born - hlt + jneq +4 + call do_shell call shift_terminal ret diff --git a/src/assembler.rs b/src/assembler.rs index 3ecc630..6e88fea 100644 --- a/src/assembler.rs +++ b/src/assembler.rs @@ -125,6 +125,18 @@ impl ImageAssembler { println!("{:X}: {:X}", self.ptr, self.memory[self.ptr]); self.ptr += 1; } + "jlt" => { + let addr = self.parse_addr(command_parts[1]); + self.memory[self.ptr] = 0xE4000000 + addr; + println!("{:X}: {:X}", self.ptr, self.memory[self.ptr]); + self.ptr += 1; + } + "jgt" => { + let addr = self.parse_addr(command_parts[1]); + self.memory[self.ptr] = 0xE3000000 + addr; + println!("{:X}: {:X}", self.ptr, self.memory[self.ptr]); + self.ptr += 1; + } "call" => { let addr = self.parse_addr(command_parts[1]); self.memory[self.ptr] = 0xC1000000 + addr; @@ -137,6 +149,12 @@ impl ImageAssembler { println!("{:X}: {:X}", self.ptr, self.memory[self.ptr]); self.ptr += 1; } + "ijmp" => { + let addr = self.parse_addr(command_parts[1]); + self.memory[self.ptr] = 0xEF000000 + addr; + println!("{:X}: {:X}", self.ptr, self.memory[self.ptr]); + self.ptr += 1; + } "import" => { self.assemble(command_parts[1]); } @@ -251,6 +269,12 @@ impl ImageAssembler { println!("{:X}: {:X}", self.ptr, self.memory[self.ptr]); self.ptr += 1; } + "lshift" => { + self.memory[self.ptr] = + (0xa7 << 24) + (a_reg << 16) + (b_reg << 8) + result_reg; + println!("{:X}: {:X}", self.ptr, self.memory[self.ptr]); + self.ptr += 1; + } "shift" => { self.memory[self.ptr] = (0xa5 << 24) + (a_reg << 16) + (b_reg << 8) + result_reg; diff --git a/src/lib.rs b/src/lib.rs index 336fc69..d621721 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -193,6 +193,16 @@ impl Machine { let result = source & bits; self.memory[REGISTER_PAGE + dest_reg] = result; } + // LSHIFT A >> B => C + 0xA7 => { + let source_reg = ((instruction & 0x00FF0000) >> 16) as usize; + let bit_reg = ((instruction & 0x0000FF00) >> 8) as usize; + let dest_reg = (instruction & 0xFF) as usize; + let source = self.memory[REGISTER_PAGE + source_reg]; + let bits = self.memory[REGISTER_PAGE + bit_reg]; + let result = source << bits; + self.memory[REGISTER_PAGE + dest_reg] = result; + } op => { unimplemented!("0x0 Addition Instruction {}", op) } @@ -276,6 +286,24 @@ impl Machine { self.memory[REGISTER_PAGE] = mem - 1; } } + 0xE3 => { + // JMP ADDR if R(1) > R(2) + if self.memory[REGISTER_PAGE + 1] > self.memory[REGISTER_PAGE + 2] { + let mem = instruction & 0x00FFFFFF; + self.memory[REGISTER_PAGE] = mem - 1; + } + } + 0xE4 => { + // JMP ADDR if R(1) > R(2) + if self.memory[REGISTER_PAGE + 1] < self.memory[REGISTER_PAGE + 2] { + let mem = instruction & 0x00FFFFFF; + self.memory[REGISTER_PAGE] = mem - 1; + } + } + 0xEf => { + let mem = instruction & 0x0000FF; + self.memory[REGISTER_PAGE] = self.memory[REGISTER_PAGE+mem as usize]-1; + } op => { unimplemented!("0x0 JMP Instruction {}", op) } diff --git a/strings.asm b/strings.asm index f9e3133..218cfec 100644 --- a/strings.asm +++ b/strings.asm @@ -148,4 +148,40 @@ label num_to_char: loadi $2 char_space add $2 $1 $1 ; Add to Char Space tx $4 $1 - ret \ No newline at end of file + ret + +; $4 contains pointer to a null terminated hex string +; outputs num in $1 +label string_to_num: + loadi $3 0 + loadi $5 4 ; bits to shift each time + + label string_to_num_inner: + rload $4 $1 ; load char at $4 into $1 + loadi $2 $0 ; check that it isn't a null terminator + + jneq +3 + tx $1 $3 + ret + + ; check this is a valid char + loadi $2 20 + jgt +3 + loadi $1 0 + ret + + ; sub 0x30 from char to get a normalized number + loadi $2 $30 + sub $1 $2 $1 + + loadi $2 $A + jlt +3 + loadi $2 $7 + sub $1 $2 $1 + + lshift $3 $5 $3 + add $1 $3 $3 + inc $4 + + jmp string_to_num_inner + ret \ No newline at end of file