Compare commits

...

5 Commits

Author SHA1 Message Date
bx 5221fe45d9 added or immediate (ori) instruction 2021-08-31 10:11:25 +01:00
bx 53c69e77a9 addled shift right logical (srl) 2021-08-30 20:12:26 +01:00
bx 97b12551e5 re-named int to word 2021-08-30 19:38:26 +01:00
bx 229a7b73fa added load upper immediate (lui) op code 2021-08-30 19:36:12 +01:00
bx be640f2540 gitignore EXE files 2021-08-30 17:40:28 +01:00
2 changed files with 100 additions and 21 deletions

1
.gitignore vendored 100644
View File

@ -0,0 +1 @@
*.EXE

View File

@ -7,7 +7,7 @@ def zero_fill(pos)
end end
end end
def int(i) def word(i)
$bytes.push((i & 0x000000ff), $bytes.push((i & 0x000000ff),
(i & 0x0000ff00) >> 8, (i & 0x0000ff00) >> 8,
(i & 0x00ff0000) >> 16, (i & 0x00ff0000) >> 16,
@ -21,13 +21,17 @@ def string(s)
end end
end end
# # # INSTRUCTIONS # # #
def jmp(addr) def jmp(addr)
# TODO: this probs wont show up since we have < 3mb of ram but # TODO: this probs wont show up since we have < 3mb of ram but
# we can't jump to an address with a different 4 most significant bits # we can't jump to an address with a different 4 most significant bits
raise "jmp addr must be 4 byte aligned" if addr % 4 != 0 raise "jmp addr must be 4 byte aligned" if addr % 4 != 0
op = 0b0000_1000_0000_0000_0000_0000_0000_0000 op = 0b0000_1000_0000_0000_0000_0000_0000_0000
op = op | ((addr >> 2) & 0b11_11111111_11111111_11111111) op = op | ((addr >> 2) & 0b11_11111111_11111111_11111111)
int op word op
end end
def jal(addr) def jal(addr)
@ -35,43 +39,117 @@ def jal(addr)
raise "jmp addr must be 4 byte aligned" if addr % 4 != 0 raise "jmp addr must be 4 byte aligned" if addr % 4 != 0
op = 0b0000_1100_0000_0000_0000_0000_0000_0000 op = 0b0000_1100_0000_0000_0000_0000_0000_0000
op = op | ((addr >> 2) & 0b11_11111111_11111111_11111111) op = op | ((addr >> 2) & 0b11_11111111_11111111_11111111)
int op word op
end end
# load upper immediate
# NOTE: val will be shifted left by 16
def lui(val, dest)
# oooooo ----- ttttt iiiiiiiiiiiiiiii
op = 0b001111_00000_00000_0000000000000000
op |= 0xffff & val
op |= (0b11111 & dest) << 16
word op
end
# shift right logical
def srl(src, amt, dest)
# oooooo ----- sssss ddddd hhhhh oooooo
op = 0b000000_00000_00000_00000_00000_000010
op |= (src & 0b11111) << 16
op |= (amt & 0b11111) << 6
op |= (dest & 0b11111) << 11
word op
end
# or immediate
def ori(src, bits, dest)
# oooooo sssss ddddd iiiiiiii iiiiiiii
op = 0b001101_00000_00000_00000000_00000000
op |= (src & 0b11111) << 21
op |= (bits & 0xffff)
op |= (dest & 0x11111) << 16
word op
end
# # # PSEUDO-INSTRUCTIONS # # #
def nop def nop
int 0x00000000 word 0x00000000
end end
$base_addr = 0x80010000 # 0x10000 # 0x80010000
# this is a terrible idea and im doing it
#$labels = {}
#def method_missing(m, *args)
# puts m.to_s
# super
#end
# # # CONSTANTS # # #
$base_addr = 0x80010000 # 0x10000 # 0x80010000
$file_size = 0x800
$gp0 = 0x1F801810
# # # EXE HEADER # # #
string "PS-X EXE" string "PS-X EXE"
zero_fill 0x00f zero_fill 0x00f
int $base_addr # initial pc word $base_addr # initial pc
int 0x00000000 # initial GP/R28 word 0x00000000 # initial GP/R28
int $base_addr # destintation address in RAM word $base_addr # destintation address in RAM
int 0x800 # file size excluding header (must be N * 0x800) word $file_size # file size excluding header (must be N * 0x800)
int 0x00000000 # Unknown/Unused word 0x00000000 # Unknown/Unused
int 0x00000000 # Unknown/Unused word 0x00000000 # Unknown/Unused
int 0x00000000 # Memfill start address word 0x00000000 # Memfill start address
int 0x00000000 # Memfill size in bytes word 0x00000000 # Memfill size in bytes
int 0x801ffff0 # Initial SP/R29 & FP/R30 Base word 0x801ffff0 # Initial SP/R29 & FP/R30 Base
int 0x00000000 # Initial SP/R29 & FP/R30 Offs word 0x00000000 # Initial SP/R29 & FP/R30 Offs
zero_fill 0x4b # Reserved for A(43h) Function zero_fill 0x4b # Reserved for A(43h) Function
# Ascii marker would go here # Ascii marker would go here
zero_fill 0x7ff zero_fill 0x7ff
$exe_header = $bytes[0..]
$bytes = []
# code
# # # PROGRAM CODE # # #
nop ; jmp $base_addr + 16 ; nop ; word 0xdeadbeef
# ops should always be in format of
# src [args] -> dest
lui $gp0 >> 16, 1
ori 1, $gp0, 1
nop ; nop ; nop ; nop
nop ; nop ; nop ; nop
nop ; nop ; nop ; nop
nop ; nop ; nop ; nop
jmp $base_addr
nop nop
nop
jal $base_addr
nop # nop (is always exec'd bc mips)
string "this is a test lol" string "this is a test lol"
int 0xFFAAFFAA
zero_fill 0xfff
zero_fill $file_size - 1
f = File.new "LOADTHIS.EXE", "wb" f = File.new "LOADTHIS.EXE", "wb"
f.write $exe_header.pack("C*")
f.write $bytes.pack("C*") f.write $bytes.pack("C*")
f.close f.close