You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
318 lines
4.9 KiB
318 lines
4.9 KiB
.include "instr.inc"
|
|
.text
|
|
|
|
.global _start
|
|
_start:
|
|
|
|
_entry_Null:
|
|
.fill 8, 1, 0xff
|
|
|
|
_entry_PrintStr:
|
|
jp bios_PrintStr
|
|
|
|
.fill (0x10 - (. - _start)), 1, 0
|
|
_entry_StrCmp:
|
|
jp bios_StrCmp
|
|
|
|
.fill (0x18 - (. - _start)), 1, 0
|
|
_entry_FindIndex:
|
|
jp bios_FindIndex
|
|
|
|
.fill (0x20 - (. - _start)), 1, 0
|
|
_entry_ConvertHex:
|
|
jp bios_ConvertHex
|
|
|
|
.fill (0x28 - (. - _start)), 1, 0
|
|
_entry_MemCpy:
|
|
jp bios_MemCpy
|
|
|
|
.fill (0x30 - (. - _start)), 1, 0
|
|
_entry_ReadStr:
|
|
jp bios_ReadStr
|
|
|
|
.fill (0x38 - (. - _start)), 1, 0
|
|
_entry_StrTrim:
|
|
jp bios_StrTrim
|
|
|
|
.fill (0x40 - (. - _start)), 1, 0
|
|
_entry_MemSet:
|
|
|
|
bios_ret:
|
|
ret
|
|
|
|
# in: R2=str
|
|
bios_PrintStr:
|
|
cp_r2 0x1000
|
|
jp_hi bios_ret
|
|
|
|
# Interpret special bytes
|
|
ldrb_r0_r2
|
|
cp_r0 0
|
|
jp_eq bios_PrintStr_ret
|
|
cp_r0 0xf0
|
|
jp_eq bios_PrintStr_ram_word
|
|
cp_r0 0xf1
|
|
jp_eq bios_PrintStr_ram_byte
|
|
|
|
# Print the byte
|
|
copr_putc
|
|
inc_r2
|
|
jp bios_PrintStr
|
|
|
|
bios_PrintStr_ret:
|
|
ret
|
|
|
|
bios_PrintStr_ram_word:
|
|
# Grab the word pointed to
|
|
inc_r2
|
|
ldr_r0_r2
|
|
cp_r0 0x1000
|
|
jp_hi bios_ret
|
|
ldr_r0_r0
|
|
|
|
# Print it
|
|
call bios_PrintHex_word
|
|
inc_r2
|
|
inc_r2
|
|
jp bios_PrintStr
|
|
|
|
bios_PrintStr_ram_byte:
|
|
# Grab the byte pointed to
|
|
inc_r2
|
|
ldr_r0_r2
|
|
cp_r0 0x1000
|
|
jp_hi bios_ret
|
|
ldrb_r0_r0
|
|
|
|
# Print it
|
|
call bios_PrintHex_byte
|
|
inc_r2
|
|
inc_r2
|
|
jp bios_PrintStr
|
|
|
|
# in: R2=one R3=two
|
|
# re: R0=res
|
|
bios_StrCmp:
|
|
cp_r2 0x1000
|
|
jp_hi bios_ret
|
|
cp_r3 0x1000
|
|
jp_hi bios_ret
|
|
|
|
# Check the bytes
|
|
ldrb_r0_r2
|
|
ldrb_r1_r3
|
|
cp_r0_r1
|
|
jp_ne bios_StrCmp_ret
|
|
cp_r0 0
|
|
jp_eq bios_StrCmp_ret
|
|
|
|
# Keep looping
|
|
inc_r2
|
|
inc_r3
|
|
jp bios_StrCmp
|
|
|
|
bios_StrCmp_ret:
|
|
ret
|
|
|
|
bios_PrintHex_word:
|
|
swap_r0
|
|
call bios_PrintHex
|
|
swap_r0
|
|
|
|
bios_PrintHex_byte:
|
|
call bios_PrintHex
|
|
ret
|
|
|
|
bios_PrintHex:
|
|
# Print the high nybble
|
|
push_r0
|
|
shr_r0
|
|
shr_r0
|
|
shr_r0
|
|
shr_r0
|
|
and_r0 0xf
|
|
call bios_PrintHex_nybble
|
|
pop_r0
|
|
|
|
# Print the low nybble
|
|
push_r0
|
|
and_r0 0xf
|
|
call bios_PrintHex_nybble
|
|
pop_r0
|
|
ret
|
|
|
|
bios_PrintHex_nybble:
|
|
add_r0 bios_PrintHex_chars
|
|
ldrb_r0_r0
|
|
copr_putc
|
|
ret
|
|
|
|
bios_PrintHex_chars:
|
|
.ascii "0123456789ABCDEF"
|
|
|
|
# in: R2=table R3=value
|
|
# re: R0=index (err=-1)
|
|
bios_FindIndex:
|
|
ld_r1 -1
|
|
|
|
bios_FindIndex_loop:
|
|
inc_r1
|
|
cp_r2 0x1000
|
|
jp_hi bios_ret
|
|
ldrb_r0_r2
|
|
inc_r2
|
|
|
|
cp_r0 0xff
|
|
jp_eq bios_FindIndex_end
|
|
cp_r0_r3
|
|
jp_ne bios_FindIndex_loop
|
|
ld_r0_r1
|
|
ret
|
|
|
|
bios_FindIndex_end:
|
|
ld_r0 -1
|
|
ret
|
|
|
|
bios_FindIndexUnsafe:
|
|
ld_r1 -1
|
|
|
|
bios_FindIndexUnsafe_loop:
|
|
inc_r1
|
|
ldrb_r0_r2
|
|
inc_r2
|
|
|
|
cp_r0 0xff
|
|
jp_eq bios_FindIndexUnsafe_end
|
|
cp_r0_r3
|
|
jp_ne bios_FindIndexUnsafe_loop
|
|
ld_r0_r1
|
|
ret
|
|
|
|
bios_FindIndexUnsafe_end:
|
|
ld_r0 -1
|
|
ret
|
|
|
|
.ascii "\0\0\0"
|
|
.ascii "Glitch Research Laboratory GLVM BIOS version 1.3"
|
|
.ascii " / "
|
|
.ascii "Do not distribute!"
|
|
.ascii " / "
|
|
.ascii "FOOLS2023_{DumpingWasAnInsideJob}"
|
|
.ascii "\0\0\0"
|
|
|
|
# in: R2=mem
|
|
# re: R0=res (err=-1)
|
|
bios_ConvertHex:
|
|
ld_r3 0
|
|
|
|
bios_ConvertHex_loop:
|
|
cp_r2 0x1000
|
|
jp_hi bios_ret
|
|
ldrb_r0_r2
|
|
inc_r2
|
|
|
|
cp_r0 0
|
|
jp_eq bios_ConvertHex_end
|
|
cp_r0 '\n'
|
|
jp_eq bios_ConvertHex_end
|
|
|
|
# Move previous r3 value to high nybble
|
|
add_r3_r3
|
|
add_r3_r3
|
|
add_r3_r3
|
|
add_r3_r3
|
|
|
|
# Find the index of the character
|
|
push_r2
|
|
push_r3
|
|
ld_r2 bios_ConvertHex_hextable
|
|
ld_r3_r0
|
|
call bios_FindIndexUnsafe
|
|
pop_r3
|
|
pop_r2
|
|
cp_r0 -1
|
|
jp_eq bios_ConvertHex_ret
|
|
|
|
# Get the value of the character
|
|
ld_r1 bios_ConvertHex_valtable
|
|
add_r1_r0
|
|
ldrb_r1_r1
|
|
|
|
# Add current nybble to result
|
|
add_r3_r1
|
|
jp bios_ConvertHex_loop
|
|
|
|
bios_ConvertHex_end:
|
|
ld_r0_r3
|
|
|
|
bios_ConvertHex_ret:
|
|
ret
|
|
|
|
bios_ConvertHex_hextable:
|
|
.ascii "0123456789abcdefABCDEF"
|
|
.byte 0xff
|
|
|
|
bios_ConvertHex_valtable:
|
|
.byte 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
|
|
.byte 10, 11, 12, 13, 14, 15
|
|
.byte 0xff
|
|
|
|
# in: R1=size R2=dst R3=src
|
|
bios_MemCpy:
|
|
cp_r3 0x1000
|
|
jp_hi bios_ret
|
|
cp_r2 0x1000
|
|
jp_hi bios_ret
|
|
ldrb_r0_r3
|
|
strb_r0_r2
|
|
inc_r3
|
|
inc_r2
|
|
dec_r1
|
|
cp_r1 0
|
|
jp_ne bios_MemCpy
|
|
ret
|
|
|
|
# in: R2=mem R3=size
|
|
bios_ReadStr:
|
|
copr_getc
|
|
cp_r2 0x1000
|
|
jp_hi bios_ret
|
|
strb_r0_r2
|
|
|
|
# Read until the next newline
|
|
cp_r0 '\n'
|
|
jp_eq bios_ReadStr_end
|
|
|
|
# Skip characters if the size has ran out
|
|
cp_r3 0
|
|
jp_eq bios_ReadStr_skip
|
|
inc_r2
|
|
dec_r3
|
|
bios_ReadStr_skip:
|
|
jp bios_ReadStr
|
|
|
|
bios_ReadStr_end:
|
|
# Add string terminator
|
|
inc_r2
|
|
ld_r0 0
|
|
strb_r0_r2
|
|
ret
|
|
|
|
# in: R2=mem
|
|
bios_StrTrim:
|
|
# Find the first whitespace
|
|
ldrb_r0_r2
|
|
cp_r0 '\n'
|
|
jp_eq bios_StrTrim_end
|
|
cp_r0 0
|
|
jp_eq bios_StrTrim_end
|
|
inc_r2
|
|
jp bios_StrTrim
|
|
|
|
bios_StrTrim_end:
|
|
# Write a string terminator
|
|
ld_r0 0
|
|
cp_r2 0x1000
|
|
jp_hi bios_ret
|
|
strb_r0_r2
|
|
ret
|
|
|