p1es/assembler.rb

154 lines
2.6 KiB
Ruby
Raw Normal View History

2021-08-30 16:27:37 +00:00
$bytes = []
def zero_fill(pos)
while ($bytes.length <= pos) do
$bytes.push(0)
end
end
2021-08-30 18:38:26 +00:00
def word(i)
2021-08-30 16:27:37 +00:00
$bytes.push((i & 0x000000ff),
(i & 0x0000ff00) >> 8,
(i & 0x00ff0000) >> 16,
(i & 0xff000000) >> 24)
end
def string(s)
$bytes.push *s.bytes
while (($bytes.length % 4) != 0) do
$bytes.push 0
end
end
def jmp(addr)
# 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
raise "jmp addr must be 4 byte aligned" if addr % 4 != 0
op = 0b0000_1000_0000_0000_0000_0000_0000_0000
op = op | ((addr >> 2) & 0b11_11111111_11111111_11111111)
2021-08-30 18:38:26 +00:00
word op
2021-08-30 16:27:37 +00:00
end
def jal(addr)
# TODO: same problem as jmp
raise "jmp addr must be 4 byte aligned" if addr % 4 != 0
op = 0b0000_1100_0000_0000_0000_0000_0000_0000
op = op | ((addr >> 2) & 0b11_11111111_11111111_11111111)
2021-08-30 18:38:26 +00:00
word op
2021-08-30 16:27:37 +00:00
end
def nop
2021-08-30 18:38:26 +00:00
word 0x00000000
2021-08-30 16:27:37 +00:00
end
# load upper immediate
def lui(reg, val)
# oooooo ----- ttttt iiiiiiiiiiiiiiii
op = 0b001111_00000_00000_0000000000000000
op |= (0b11111 & reg) << 16
op |= 0xffff & val
2021-08-30 18:38:26 +00:00
word op
end
2021-08-30 19:12:26 +00:00
# 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
# this is a terrible idea and im doing it
#$labels = {}
#def method_missing(m, *args)
# puts m.to_s
# super
#end
2021-08-30 19:12:26 +00:00
# # # CONSTANTS # # #
2021-08-30 16:27:37 +00:00
$base_addr = 0x80010000 # 0x10000 # 0x80010000
2021-08-30 19:12:26 +00:00
$file_size = 0x800
2021-08-30 16:27:37 +00:00
# # # EXE HEADER # # #
2021-08-30 16:27:37 +00:00
string "PS-X EXE"
zero_fill 0x00f
2021-08-30 18:38:26 +00:00
word $base_addr # initial pc
word 0x00000000 # initial GP/R28
word $base_addr # destintation address in RAM
2021-08-30 19:12:26 +00:00
word $file_size # file size excluding header (must be N * 0x800)
2021-08-30 18:38:26 +00:00
word 0x00000000 # Unknown/Unused
word 0x00000000 # Unknown/Unused
word 0x00000000 # Memfill start address
word 0x00000000 # Memfill size in bytes
word 0x801ffff0 # Initial SP/R29 & FP/R30 Base
word 0x00000000 # Initial SP/R29 & FP/R30 Offs
2021-08-30 16:27:37 +00:00
zero_fill 0x4b # Reserved for A(43h) Function
# Ascii marker would go here
zero_fill 0x7ff
$exe_header = $bytes[0..]
$bytes = []
2021-08-30 16:27:37 +00:00
# # # PROGRAM CODE # # #
nop
nop
2021-08-30 19:12:26 +00:00
lui 2, 0
lui 3, 0
lui 2, 1
nop
srl 2, 14, 3
srl 2, 1, 6
2021-08-30 16:27:37 +00:00
nop
2021-08-30 19:12:26 +00:00
2021-08-30 16:27:37 +00:00
nop
nop
jmp $base_addr
nop
2021-08-30 19:12:26 +00:00
2021-08-30 16:27:37 +00:00
string "this is a test lol"
2021-08-30 18:38:26 +00:00
word 0xFFAAFFAA
word 0b001001_11101_11101_11111111_11111111
word 0b001000_11101_11101_11111111_11111111
2021-08-30 18:38:26 +00:00
word 0xAAFFAAFF
word 0b001001_00101_00101_11111111_11111111
word 0b001000_00101_00101_11111111_11111111
2021-08-30 16:27:37 +00:00
2021-08-30 19:12:26 +00:00
zero_fill $file_size - 1
2021-08-30 16:27:37 +00:00
f = File.new "LOADTHIS.EXE", "wb"
f.write $exe_header.pack("C*")
2021-08-30 16:27:37 +00:00
f.write $bytes.pack("C*")
f.close