Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 42bc666c11 | |||
| 1d38aca523 |
@@ -2,107 +2,38 @@
|
||||
#![allow(unused)]
|
||||
use std::{fmt, sync::mpsc::Sender};
|
||||
|
||||
// pub struct Logger {}
|
||||
|
||||
// impl Logger {
|
||||
// pub const fn new() -> Self {
|
||||
// Self {}
|
||||
// pub struct Entry {
|
||||
// etype: EntryType,
|
||||
// pub message: String,
|
||||
// }
|
||||
|
||||
// pub fn log(&self, message: &str) {
|
||||
// _ = self;
|
||||
// println!("\x1b[32mINFO:\x1b[0m {message}");
|
||||
// #[derive(Copy, Clone, Eq, PartialEq)]
|
||||
// enum EntryType {
|
||||
// Debug,
|
||||
// Info,
|
||||
// Warn,
|
||||
// Error,
|
||||
// Fatal,
|
||||
// }
|
||||
|
||||
// impl fmt::Display for EntryType {
|
||||
// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
// write!(
|
||||
// f,
|
||||
// "{:<5}",
|
||||
// match self {
|
||||
// Self::Debug => "DEBUG",
|
||||
// Self::Info => "INFO",
|
||||
// Self::Warn => "WARN",
|
||||
// Self::Error => "ERROR",
|
||||
// Self::Fatal => "FATAL",
|
||||
// }
|
||||
// )
|
||||
// }
|
||||
// }
|
||||
|
||||
// #[derive(Debug)]=
|
||||
// pub struct Logger {
|
||||
// pub sender: Sender<Entry>,
|
||||
// }
|
||||
|
||||
// impl Logger {
|
||||
// pub fn new(sender: Sender<Entry>) -> Self {
|
||||
// Self { sender }
|
||||
// }
|
||||
|
||||
// pub fn debug<T: fmt::Display>(&self, message: T) {
|
||||
// self.sender
|
||||
// .send(Entry {
|
||||
// etype: EntryType::Debug,
|
||||
// message: message.to_string(),
|
||||
// })
|
||||
// .unwrap();
|
||||
// }
|
||||
|
||||
// pub fn info<T: fmt::Display>(&self, message: T) {
|
||||
// self.sender
|
||||
// .send(Entry {
|
||||
// etype: EntryType::Info,
|
||||
// message: message.to_string(),
|
||||
// })
|
||||
// .unwrap();
|
||||
// }
|
||||
|
||||
// pub fn warn<T: fmt::Display>(&self, message: T) {
|
||||
// self.sender
|
||||
// .send(Entry {
|
||||
// etype: EntryType::Warn,
|
||||
// message: message.to_string(),
|
||||
// })
|
||||
// .unwrap();
|
||||
// }
|
||||
|
||||
// pub fn error<T: fmt::Display>(&self, message: T) {
|
||||
// self.sender
|
||||
// .send(Entry {
|
||||
// etype: EntryType::Error,
|
||||
// message: message.to_string(),
|
||||
// })
|
||||
// .unwrap();
|
||||
// }
|
||||
|
||||
// pub fn fatal<T: fmt::Display>(&self, message: T) {
|
||||
// self.sender
|
||||
// .send(Entry {
|
||||
// etype: EntryType::Fatal,
|
||||
// message: message.to_string(),
|
||||
// })
|
||||
// .unwrap();
|
||||
// impl fmt::Display for Entry {
|
||||
// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
// write!(f, "{}: {}", self.etype, self.message)
|
||||
// }
|
||||
// }
|
||||
|
||||
pub struct Entry {
|
||||
etype: EntryType,
|
||||
pub message: String,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Eq, PartialEq)]
|
||||
enum EntryType {
|
||||
Debug,
|
||||
Info,
|
||||
Warn,
|
||||
Error,
|
||||
Fatal,
|
||||
}
|
||||
|
||||
impl fmt::Display for EntryType {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"{:<5}",
|
||||
match self {
|
||||
Self::Debug => "DEBUG",
|
||||
Self::Info => "INFO",
|
||||
Self::Warn => "WARN",
|
||||
Self::Error => "ERROR",
|
||||
Self::Fatal => "FATAL",
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Entry {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "{}: {}", self.etype, self.message)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,8 @@ pub fn generate_ast(input: &str, logger: &Logger) -> Result<Program, CompilerErr
|
||||
|
||||
let lexer = lexer::Lexer::new(&input);
|
||||
let tokens = lexer.collect::<Vec<_>>();
|
||||
println!("{tokens:#?}");
|
||||
|
||||
// println!("{tokens:#?}");
|
||||
|
||||
logger.info(&format!("Parsing {} Tokens...", tokens.len()));
|
||||
|
||||
|
||||
@@ -800,8 +800,6 @@ impl Parser {
|
||||
}
|
||||
|
||||
fn parse_type(&mut self) -> ParseResult<TypeId, CompilerError> {
|
||||
println!("yes {:?}", self.peek_next()?);
|
||||
|
||||
// parse primitive or named type
|
||||
if expect_tt!(self.peek_next()?, Identifier).accepted() {
|
||||
return self.parse_type_identifier();
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
use std::path::Path;
|
||||
use std::thread::sleep;
|
||||
use std::time::Duration;
|
||||
use std::{env, fs};
|
||||
|
||||
use crate::emulator::system::model::{Command, Running};
|
||||
use crate::emulator::{config::Config, system::model::State};
|
||||
|
||||
pub fn run_cli() -> Result<(), Box<dyn std::error::Error>> {
|
||||
// Initialize channels and read in configuration.
|
||||
let (cmd_sender, cmd_receiver) = std::sync::mpsc::channel();
|
||||
let (state_sender, state_reciever) = std::sync::mpsc::channel();
|
||||
|
||||
// not needed for now.
|
||||
// let config = Config::load(Path::new(".dsa.emulator.toml"))?;
|
||||
|
||||
crate::setup_emulator(cmd_receiver, state_sender, None);
|
||||
|
||||
// run CLI.
|
||||
let mut state = State::new(cmd_sender, state_reciever);
|
||||
|
||||
let mut bin_path: Option<String> = None;
|
||||
for (i, arg) in env::args().enumerate().skip(1) {
|
||||
// check for args --bin and <bin_path>
|
||||
if arg == "--bin" {
|
||||
bin_path = Some(env::args().nth(i + 1).expect("Binary path not provided"));
|
||||
}
|
||||
}
|
||||
|
||||
let binary =
|
||||
fs::read(bin_path.expect("unreachable")).expect("unable to read binary file");
|
||||
state.send(Command::Write(0, binary));
|
||||
println!("{:?}", state.running);
|
||||
|
||||
sleep(Duration::from_secs(1));
|
||||
|
||||
state.update().unwrap();
|
||||
state.cmd_sender.send(Command::Start).unwrap();
|
||||
loop {
|
||||
sleep(Duration::from_millis(20));
|
||||
state.send(Command::DisplayRequest);
|
||||
state.send(Command::RunningRequest);
|
||||
state.update().expect("update failed");
|
||||
|
||||
for ch in state.serial_buff.drain(..) {
|
||||
print!("{}", ch as char);
|
||||
}
|
||||
|
||||
if state.running == Running::Halted {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
pub mod cli;
|
||||
#[cfg(feature = "config")]
|
||||
pub mod config;
|
||||
pub mod misc;
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
pub const DISPLAY_ADDRESS: u32 = 0x20000;
|
||||
pub const SERIAL_ADDRESS: u32 = DISPLAY_ADDRESS + 2000;
|
||||
@@ -135,6 +135,9 @@ pub fn run_emulator(
|
||||
Vec::new()
|
||||
}),
|
||||
));
|
||||
let _ = state_tx.send(StateUpdate::Serial(
|
||||
processor.serial_buff.drain(..).collect(),
|
||||
));
|
||||
}
|
||||
Command::StackRequest if update => {
|
||||
let _ = state_tx.send(StateUpdate::StackView(
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
pub mod cache;
|
||||
pub mod constants;
|
||||
pub mod emulator;
|
||||
pub mod memory;
|
||||
pub mod model;
|
||||
|
||||
@@ -28,6 +28,7 @@ pub enum Command {
|
||||
WriteBlock(Address, Box<[u8; 256]>),
|
||||
|
||||
// request emulator state.
|
||||
SerialRequest,
|
||||
MemRequest(Address, u32),
|
||||
DisplayRequest,
|
||||
StackRequest,
|
||||
@@ -79,6 +80,7 @@ pub struct State {
|
||||
pub error_log: Vec<String>,
|
||||
|
||||
pub instruction_history: Vec<(u32, u32)>,
|
||||
pub serial_buff: Vec<u8>,
|
||||
}
|
||||
|
||||
impl State {
|
||||
@@ -95,6 +97,7 @@ impl State {
|
||||
display_view: vec![],
|
||||
error_log: vec![],
|
||||
instruction_history: vec![],
|
||||
serial_buff: vec![],
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,6 +124,9 @@ impl State {
|
||||
StateUpdate::InstructionHistory(history) => {
|
||||
self.instruction_history.extend(history);
|
||||
}
|
||||
StateUpdate::Serial(buffer) => {
|
||||
self.serial_buff.extend(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
if self.error_log.len() > 256 {
|
||||
@@ -148,6 +154,7 @@ impl State {
|
||||
|
||||
pub enum StateUpdate {
|
||||
Registers(RegFile),
|
||||
Serial(Vec<u8>),
|
||||
Running(Running),
|
||||
Instructions(usize),
|
||||
StackView(Vec<u8>),
|
||||
|
||||
@@ -5,6 +5,7 @@ use std::{
|
||||
|
||||
use crate::emulator::system::{
|
||||
cache::Cache,
|
||||
constants::{DISPLAY_ADDRESS, SERIAL_ADDRESS},
|
||||
memory::MemoryUnit,
|
||||
model::{IODevice, ProcessorError, RegFile},
|
||||
};
|
||||
@@ -19,6 +20,8 @@ pub struct Processor {
|
||||
|
||||
pub void: u32,
|
||||
pub cache: Cache,
|
||||
|
||||
pub serial_buff: Vec<u8>,
|
||||
}
|
||||
|
||||
impl Processor {
|
||||
@@ -31,6 +34,8 @@ impl Processor {
|
||||
io_devices,
|
||||
void: 0,
|
||||
cache: Cache::new(),
|
||||
|
||||
serial_buff: Vec::with_capacity(32768),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,7 +102,7 @@ impl Processor {
|
||||
}
|
||||
|
||||
pub fn display(&mut self) -> Result<Vec<u8>, ProcessorError> {
|
||||
Ok(self.memory.read_range(0x20000, 2000))
|
||||
Ok(self.memory.read_range(DISPLAY_ADDRESS, 2000))
|
||||
}
|
||||
|
||||
pub fn cmp(&mut self, a: u32, b: u32) {
|
||||
@@ -267,30 +272,41 @@ impl Executable for Instruction {
|
||||
// Stores a byte from SrcReg in memory address (base + offset) The effective
|
||||
// address must be byte-aligned.
|
||||
Self::StoreByte(a) => {
|
||||
cpu.memory.write_byte(
|
||||
cpu.get(a.r2)? + u32::from(a.immediate),
|
||||
cpu.get(a.r1)? as u8,
|
||||
);
|
||||
let addr = cpu.get(a.r2)? + u32::from(a.immediate);
|
||||
let val = cpu.get(a.r1)? as u8;
|
||||
if addr == SERIAL_ADDRESS {
|
||||
cpu.serial_buff.push(val);
|
||||
}
|
||||
cpu.memory.write_byte(addr, val);
|
||||
}
|
||||
|
||||
// Stores a half-word from SrcReg in memory address (base + offset) The
|
||||
// effective address must be 2-byte-aligned.
|
||||
Self::StoreHalfword(a) => {
|
||||
// split the value into bytes and then write two bytes
|
||||
let addr = cpu.get(a.r2)? + u32::from(a.immediate);
|
||||
let bytes = (cpu.get(a.r1)? as u16).to_le_bytes();
|
||||
cpu.memory
|
||||
.write_byte(cpu.get(a.r2)? + u32::from(a.immediate), bytes[0]);
|
||||
cpu.memory
|
||||
.write_byte(cpu.get(a.r2)? + u32::from(a.immediate) + 1, bytes[1]);
|
||||
|
||||
if addr == SERIAL_ADDRESS {
|
||||
cpu.serial_buff.extend(bytes);
|
||||
}
|
||||
|
||||
// split the value into bytes and then write two bytes
|
||||
cpu.memory.write_byte(addr, bytes[0]);
|
||||
cpu.memory.write_byte(addr + 1, bytes[1]);
|
||||
}
|
||||
|
||||
// Stores a word from SrcReg in memory address (base + offset) The effective
|
||||
// address must be 4-byte-aligned.
|
||||
Self::StoreWord(a) => {
|
||||
cpu.memory.write_word(
|
||||
cpu.get(a.r2)? + u32::from(a.immediate),
|
||||
cpu.get(a.r1)?,
|
||||
)?;
|
||||
let addr = cpu.get(a.r2)? + u32::from(a.immediate);
|
||||
let val = cpu.get(a.r1)?;
|
||||
let bytes = val.to_le_bytes();
|
||||
|
||||
if addr == SERIAL_ADDRESS {
|
||||
cpu.serial_buff.extend(bytes);
|
||||
}
|
||||
|
||||
cpu.memory.write_word(addr, val)?;
|
||||
}
|
||||
|
||||
// Loads a 16-bit literal value into reg, setting the bottom 16 bits of the
|
||||
|
||||
@@ -448,7 +448,7 @@ impl Editor {
|
||||
}
|
||||
|
||||
let mut assembler = Assembler::new(&dsa_path);
|
||||
compiler.start();
|
||||
assembler.start();
|
||||
|
||||
// Or block until done
|
||||
self.output = match assembler.output() {
|
||||
|
||||
@@ -1,9 +1,15 @@
|
||||
use std::env;
|
||||
use std::path::Path;
|
||||
use std::sync::Arc;
|
||||
|
||||
use dsa_rs::emulator::{config::Config, misc::rpc::get_rpc_client_or_none};
|
||||
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
if env::args().any(|arg| arg == "--cli") {
|
||||
dsa_rs::emulator::cli::run_cli()?;
|
||||
std::process::exit(0);
|
||||
}
|
||||
|
||||
// Initialize channels and read in configuration.
|
||||
let (cmd_sender, cmd_receiver) = std::sync::mpsc::channel();
|
||||
let (state_sender, state_reciever) = std::sync::mpsc::channel();
|
||||
|
||||
@@ -0,0 +1,244 @@
|
||||
// lib:
|
||||
// print_serial.dsa
|
||||
|
||||
// usage:
|
||||
//
|
||||
// include print_serial "<relative path>"
|
||||
//
|
||||
// usage for print:
|
||||
// push (register containing address of string)
|
||||
// push pcx
|
||||
// jmp print_serial::print
|
||||
//
|
||||
// usage for print_byte:
|
||||
// push (register containing byte)
|
||||
// push pcx
|
||||
// jmp print_serial::print_byte
|
||||
//
|
||||
// usage for print_word:
|
||||
// push (register containing word)
|
||||
// push pcx
|
||||
// jmp print_serial::print_word
|
||||
//
|
||||
// usage for print_hex_byte:
|
||||
// push (register containing byte)
|
||||
// push pcx
|
||||
// jmp print_serial::print_hex_byte
|
||||
//
|
||||
// usage for print_hex_word:
|
||||
// push (register containing word)
|
||||
// push pcx
|
||||
// jmp print_serial::print_hex_word
|
||||
//
|
||||
// usage for print_num:
|
||||
// push (register containing number to print in decimal)
|
||||
// push pcx
|
||||
// jmp print_serial::print_num
|
||||
//
|
||||
// usage for println:
|
||||
// push (register containing address of string)
|
||||
// push pcx
|
||||
// jmp print_serial::println
|
||||
//
|
||||
|
||||
include maths "../maths/core.dsa"
|
||||
|
||||
dw serial: 0x207D0 // 0x20000 + 2000
|
||||
|
||||
// ------------------------------------------
|
||||
// prints the string at addr(arg[0]) to the serial port.
|
||||
print:
|
||||
push bpr
|
||||
mov spr, bpr
|
||||
|
||||
ldw bpr, rg0, 8
|
||||
lwi 0x207D0, rg1
|
||||
|
||||
_print_loop:
|
||||
ldb rg0, acc
|
||||
cmp acc, zero
|
||||
jeq _end
|
||||
stb acc, rg1
|
||||
|
||||
addi rg0, 1
|
||||
jmp _print_loop
|
||||
|
||||
// ------------------------------------------
|
||||
// prints the string at addr(arg[0]) followed by a newline to the serial port.
|
||||
println:
|
||||
push bpr
|
||||
mov spr, bpr
|
||||
|
||||
ldw bpr, rg0, 8
|
||||
lwi 0x207D0, rg1
|
||||
|
||||
_println_loop:
|
||||
ldb rg0, acc
|
||||
cmp acc, zero
|
||||
jeq _println_end
|
||||
stb acc, rg1
|
||||
|
||||
addi rg0, 1
|
||||
jmp _println_loop
|
||||
|
||||
_println_end:
|
||||
lli 0x0A, rg2 // newline character
|
||||
stb rg2, rg1
|
||||
jmp _end
|
||||
|
||||
// ------------------------------------------
|
||||
// prints the word in arg[0] as 4 raw bytes to the serial port.
|
||||
print_word:
|
||||
push bpr
|
||||
mov spr, bpr
|
||||
|
||||
ldw bpr, rg0, 8
|
||||
lwi 0x207D0, rg1
|
||||
|
||||
stb rg0, rg1
|
||||
shr rg0, 8
|
||||
stb rg0, rg1
|
||||
shr rg0, 8
|
||||
stb rg0, rg1
|
||||
shr rg0, 8
|
||||
stb rg0, rg1
|
||||
jmp _end
|
||||
|
||||
// ------------------------------------------
|
||||
// prints the last byte of arg[0] to the serial port.
|
||||
print_byte:
|
||||
push bpr
|
||||
mov spr, bpr
|
||||
|
||||
ldw bpr, rg0, 8
|
||||
lwi 0x207D0, rg1
|
||||
|
||||
stb rg0, rg1
|
||||
jmp _end
|
||||
|
||||
// ------------------------------------------
|
||||
// prints the value of arg[0] to the serial port in hex.
|
||||
print_hex_word:
|
||||
push bpr
|
||||
mov spr, bpr
|
||||
|
||||
lwi 0x207D0, 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 serial port in hex.
|
||||
print_hex_byte:
|
||||
push bpr
|
||||
mov spr, bpr
|
||||
|
||||
ldw bpr, rg0, 8
|
||||
lwi 0x207D0, 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
|
||||
return
|
||||
|
||||
// print a hex digit
|
||||
_print_hex_nibble:
|
||||
lli 10, rg3
|
||||
cmp rg0, rg3
|
||||
jlt _print_hex_nibble_number
|
||||
addi rg0, 0x37, rg0
|
||||
stb rg0, rg1
|
||||
return
|
||||
|
||||
_print_hex_nibble_number:
|
||||
addi rg0, 0x30, rg0
|
||||
stb rg0, rg1
|
||||
return
|
||||
|
||||
// ------------------------------------------
|
||||
// prints arg[0] as a decimal number to the serial port.
|
||||
print_num:
|
||||
push bpr
|
||||
mov spr, bpr
|
||||
|
||||
ldw bpr, rg0, 8
|
||||
lli 0, rg5
|
||||
|
||||
cmp rg0, zero
|
||||
jne _print_num_extract_digits
|
||||
|
||||
lli 0x30, rg6
|
||||
push rg6
|
||||
lli 1, rg5
|
||||
jmp _print_num_output
|
||||
|
||||
_print_num_extract_digits:
|
||||
cmp rg0, zero
|
||||
jeq _print_num_output
|
||||
|
||||
push rg0
|
||||
lli 10, rg1
|
||||
push rg1
|
||||
call maths::divmod
|
||||
pop rg0
|
||||
pop rg1
|
||||
|
||||
addi rg1, 0x30, rg6
|
||||
push rg6
|
||||
inc rg5
|
||||
|
||||
jmp _print_num_extract_digits
|
||||
|
||||
_print_num_output:
|
||||
lwi 0x207D0, rg1
|
||||
|
||||
_print_num_output_loop:
|
||||
cmp rg5, zero
|
||||
jeq _print_num_done
|
||||
|
||||
pop rg6
|
||||
stb rg6, rg1
|
||||
dec rg5
|
||||
|
||||
jmp _print_num_output_loop
|
||||
|
||||
_print_num_done:
|
||||
// fall through to _end
|
||||
|
||||
// ------------------------------------------
|
||||
// return
|
||||
_end:
|
||||
mov bpr, spr
|
||||
pop bpr
|
||||
return
|
||||
+140
-9
@@ -1,12 +1,143 @@
|
||||
// program to just test compute power
|
||||
// GENERATED BY DSC COMPILER
|
||||
// Generated at 2026-02-23 17:29:47
|
||||
|
||||
dw large_num: 0x333333 // 333,333 instructions
|
||||
start:
|
||||
ldw large_num, rg0
|
||||
// Imports
|
||||
include print: "./lib/io/print.dsa"
|
||||
include alloc: "./lib/memory/block_alloc.dsa"
|
||||
|
||||
// run approx 1m instructions
|
||||
loop:
|
||||
dec rg0
|
||||
cmp rg0, zero
|
||||
jgt loop
|
||||
// Globals & Reserved Memory
|
||||
|
||||
// Entry Point
|
||||
dw stack: 0x010000
|
||||
db message: "Process Exited with code:"
|
||||
_init:
|
||||
ldw stack, bpr, 0
|
||||
mov bpr, spr
|
||||
push zero
|
||||
call main
|
||||
call print::print_newline
|
||||
lwi message, rg0
|
||||
push rg0
|
||||
call print::print
|
||||
pop zero
|
||||
call print::print_hex_word
|
||||
pop zero
|
||||
hlt
|
||||
|
||||
// Return
|
||||
_ret:
|
||||
mov bpr, spr
|
||||
pop bpr
|
||||
return
|
||||
|
||||
db str_16: "successful free of ptr"
|
||||
// fn main() -> u32
|
||||
main:
|
||||
push bpr
|
||||
mov spr, bpr
|
||||
lli 32, rg0
|
||||
lli 64, rg1
|
||||
// push arg 1
|
||||
push rg0
|
||||
// push arg 0
|
||||
push rg1
|
||||
call alloc::init
|
||||
pop rg2
|
||||
pop zero
|
||||
push rg2
|
||||
// push arg 0
|
||||
push rg2
|
||||
call print::print_hex_word
|
||||
pop zero
|
||||
call print::print_newline
|
||||
ldw spr, rg0, 0
|
||||
stw rg0, spr, 0
|
||||
// push arg 0
|
||||
push rg0
|
||||
call alloc::alloc
|
||||
pop rg1
|
||||
push rg1
|
||||
// push arg 0
|
||||
push rg1
|
||||
call print::print_hex_word
|
||||
pop zero
|
||||
lli 200, rg0
|
||||
ldw spr, rg1, 0
|
||||
stw rg0, rg1, 0
|
||||
stw rg1, spr, 0
|
||||
call print::print_newline
|
||||
ldw spr, rg0, 4
|
||||
stw rg0, spr, 4
|
||||
// push arg 0
|
||||
push rg0
|
||||
call alloc::alloc
|
||||
pop rg2
|
||||
push rg2
|
||||
// push arg 0
|
||||
push rg2
|
||||
call print::print_hex_word
|
||||
pop zero
|
||||
call print::print_newline
|
||||
ldw spr, rg0, 4
|
||||
ldw rg0, rg2, 0
|
||||
stw rg0, spr, 4
|
||||
// push arg 0
|
||||
push rg2
|
||||
call print::print_num
|
||||
pop zero
|
||||
ldw spr, rg2, 4
|
||||
stw rg2, spr, 4
|
||||
addi spr, 4, rg3
|
||||
ldw spr, rg2, 8
|
||||
stw rg2, spr, 8
|
||||
// push arg 1
|
||||
push rg3
|
||||
// push arg 0
|
||||
push rg2
|
||||
call alloc::free
|
||||
pop zero
|
||||
pop zero
|
||||
ldw spr, rg2, 8
|
||||
stw rg2, spr, 8
|
||||
// push arg 0
|
||||
push rg2
|
||||
call alloc::alloc
|
||||
pop rg3
|
||||
push rg3
|
||||
call print::print_newline
|
||||
ldw spr, rg2, 0
|
||||
stw rg2, spr, 0
|
||||
// push arg 0
|
||||
push rg2
|
||||
call print::print_hex_word
|
||||
pop zero
|
||||
call print::print_newline
|
||||
ldw spr, rg2, 8
|
||||
stw rg2, spr, 8
|
||||
// push arg 0
|
||||
push rg2
|
||||
call print::print_hex_word
|
||||
pop zero
|
||||
ldw spr, rg2, 8
|
||||
lli 0, rg4
|
||||
cmp rg2, rg4
|
||||
lli 1, rg5
|
||||
jeq _cmp_end_12
|
||||
lli 0, rg5
|
||||
_cmp_end_12:
|
||||
cmp rg5, zero
|
||||
jeq _else_14
|
||||
_then_13:
|
||||
lwi str_16, rg4
|
||||
stw rg2, spr, 8
|
||||
// push arg 0
|
||||
push rg4
|
||||
call print::print
|
||||
pop zero
|
||||
jmp _end_15
|
||||
_else_14:
|
||||
nop
|
||||
_end_15:
|
||||
lli 0, rg4
|
||||
stw rg4, bpr, 8
|
||||
jmp _ret
|
||||
Reference in New Issue
Block a user