.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