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.

319 lines
4.9 KiB

2 years ago
.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