; Convert string to integer ; Arguments: ; r1 - Pointer to string ; Result: ; r1 - Parsed integer ; r2 - Pointer to first rejected input byte ; Clobbers: ; flags ; r3 - last character read pub fn_atoi: load_8 r3, [r1] cmp r3, 0x30 ; '0' jne fn_atoi_dec ; No prefix, parse decimal add r1, r1, 1 load_8 r3, [r1] ; From "boxBOX", or an octal digit cmp r3, 0x30 ; '0' jl atoi_badprefix cmp r3, 0x37 ; '7' jle fn_atoi_oct add r1, r1, 1 ; Not octal; 2-byte prefix and r3, r3, 0x5f ; to uppercase cmp r3, 0x42 ; 'B' je fn_atoi_bin cmp r3, 0x4F ; 'O' je fn_atoi_oct cmp r3, 0x58 ; 'X' je fn_atoi_hex ; not a valid prefix, but we did see a zero atoi_badprefix: mov r2, r1 mov r1, 0 ; Only exists because conditional register jumps are not allowed atoi_done: jmp r13 ; Convert decimal string to integer ; Arguments: ; r1 - Pointer to string ; Result: ; r1 - Parsed integer ; r2 - Pointer to first rejected input byte ; Clobbers: ; flags ; r3 - last character read pub fn_atoi_dec: mov r2, r1 mov r1, 0 atoi_dec_loop: load_8 r3, [r2] cmp r3, 0x30 ; '0' jl atoi_done cmp r3, 0x39 ; '9' jg atoi_done add r2, r2, 1 sub r3, r3, 0x30 ; '0' lsl flags, r1, 2 add r1, r1, flags lsl r1, r1, 1 add r1, r1, r3 jmp atoi_dec_loop ; Convert binary string to integer ; Arguments: ; r1 - Pointer to string ; Result: ; r1 - Parsed integer ; r2 - Pointer to first rejected input byte ; Clobbers: ; flags ; r3 - last character read pub fn_atoi_bin: mov r2, r1 mov r1, 0 atoi_bin_loop: load_8 r3, [r2] cmp r3, 0x30 ; '0' jl atoi_done cmp r3, 0x39 ; '1' jg atoi_done add r2, r2, 1 sub r3, r3, 0x30 ; '0' lsl r1, r1, 1 add r1, r1, r3 jmp atoi_bin_loop ; Convert octal string to integer ; Arguments: ; r1 - Pointer to string ; Result: ; r1 - Parsed integer ; r2 - Pointer to first rejected input byte ; Clobbers: ; flags ; r3 - last character read pub fn_atoi_oct: mov r2, r1 mov r1, 0 atoi_oct_loop: load_8 r3, [r2] cmp r3, 0x30 ; '0' jl atoi_done cmp r3, 0x39 ; '7' jg atoi_done add r2, r2, 1 sub r3, r3, 0x30 ; '0' lsl r1, r1, 3 add r1, r1, r3 jmp atoi_oct_loop ; Convert hexadecimal string to integer ; Arguments: ; r1 - Pointer to string ; Result: ; r1 - Parsed integer ; r2 - Pointer to first rejected input byte ; Clobbers: ; flags ; r3 - last character read pub fn_atoi_hex: mov r2, r1 mov r1, 0 atoi_hex_loop: load_8 r3, [r2] cmp r3, 0x30 ; '0' jl atoi_done cmp r3, 0x39 ; '9' jg atoi_hex_letter add r2, r2, 1 sub r3, r3, 0x30 ; '0' lsl r1, r1, 4 add r1, r1, r3 jmp atoi_hex_loop atoi_hex_letter: and r3, r3, 0x5f ; to uppercase cmp r3, 0x41 ; 'A' jl atoi_done cmp r3, 0x46 ; 'F' jg atoi_done add r2, r2, 1 sub r3, r3, 0x37 ; 'A' - 10 lsl r1, r1, 4 add r1, r1, r3 jmp atoi_hex_loop