Compare commits
5 Commits
ea0423b9b0
...
5221fe45d9
Author | SHA1 | Date |
---|---|---|
bx | 5221fe45d9 | |
bx | 53c69e77a9 | |
bx | 97b12551e5 | |
bx | 229a7b73fa | |
bx | be640f2540 |
|
@ -0,0 +1 @@
|
||||||
|
*.EXE
|
120
assembler.rb
120
assembler.rb
|
@ -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
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue