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
 | |
| 
 |