rrcc/asm/stdlib.asm
DataHoarder e92a84b4ac
All checks were successful
continuous-integration/drone/push Build is passing
Added extra missing registers
2021-01-05 12:21:46 +01:00

84 lines
5.2 KiB
NASM

; Standard Library
; These registers are used when passing the first two parameters to a function via FastCall
.constant std_PARAMETER_0 MGMT_SCRATCH_0
.constant std_PARAMETER_1 MGMT_SCRATCH_1
; Also used as single return value
.constant std_RETURN_VALUE MGMT_SCRATCH_0
.constant std_RETURN_VALUE_EXTRA MGMT_SCRATCH_1
.constant RRET std_RETURN_VALUE ;Alias
.constant RRET_X std_RETURN_VALUE_EXTRA ;Alias
.constant P0 std_PARAMETER_0
.constant P1 std_PARAMETER_1
; These are offset registers to be called with <OP>~3 to access stack parameters
.constant P2 %1, +1 ; Equivalent to same address in POPP <Reg>, 1
.constant P3 %1, +2 ; Equivalent to same address in POPP <Reg>, 2
.constant P4 %1, +3 ; Equivalent to same address in POPP <Reg>, 3
.constant P5 %1, +4 ; Equivalent to same address in POPP <Reg>, 4
.constant P6 %1, +5 ; Equivalent to same address in POPP <Reg>, 5
.constant P7 %1, +6 ; Equivalent to same address in POPP <Reg>, 6
.constant P8 %1, +7 ; Equivalent to same address in POPP <Reg>, 7
.constant P9 %1, +8 ; Equivalent to same address in POPP <Reg>, 8
.constant P10 %1, +9 ; Equivalent to same address in POPP <Reg>, 9
.constant P11 %1, +10 ; Equivalent to same address in POPP <Reg>, 10
.constant P12 %1, +11 ; Equivalent to same address in POPP <Reg>, 11
.constant P13 %1, +12 ; Equivalent to same address in POPP <Reg>, 12
.constant P14 %1, +13 ; Equivalent to same address in POPP <Reg>, 13
.constant P15 %1, +14 ; Equivalent to same address in POPP <Reg>, 14
.constant P16 %1, +15 ; Equivalent to same address in POPP <Reg>, 15
; Ephemeral registers to be used within functions. These values may not be kept when calling other functions. They can be used when returning values if necessary.
; Some std functions might restore these values.
.constant std_EPHEMERAL_REGISTER_0 BSM_SCRATCH_START +0x1F0
.constant std_EPHEMERAL_REGISTER_1 std_EPHEMERAL_REGISTER_0 +0x1
.constant std_EPHEMERAL_REGISTER_2 std_EPHEMERAL_REGISTER_0 +0x2
.constant std_EPHEMERAL_REGISTER_3 std_EPHEMERAL_REGISTER_0 +0x3
.constant std_EPHEMERAL_REGISTER_4 std_EPHEMERAL_REGISTER_0 +0x4
.constant std_EPHEMERAL_REGISTER_5 std_EPHEMERAL_REGISTER_0 +0x5
.constant std_EPHEMERAL_REGISTER_6 std_EPHEMERAL_REGISTER_0 +0x6
.constant std_EPHEMERAL_REGISTER_7 std_EPHEMERAL_REGISTER_0 +0x7
.constant std_EPHEMERAL_REGISTER_8 std_EPHEMERAL_REGISTER_0 +0x8
.constant std_EPHEMERAL_REGISTER_9 std_EPHEMERAL_REGISTER_0 +0x9
.constant std_EPHEMERAL_REGISTER_A std_EPHEMERAL_REGISTER_0 +0xa
.constant std_EPHEMERAL_REGISTER_B std_EPHEMERAL_REGISTER_0 +0xb
.constant std_EPHEMERAL_REGISTER_C std_EPHEMERAL_REGISTER_0 +0xc
.constant std_EPHEMERAL_REGISTER_D std_EPHEMERAL_REGISTER_0 +0xd
.constant std_EPHEMERAL_REGISTER_E std_EPHEMERAL_REGISTER_0 +0xe
.constant std_EPHEMERAL_REGISTER_F std_EPHEMERAL_REGISTER_0 +0xf
; Abbreviations
.constant R0 std_EPHEMERAL_REGISTER_0
.constant R1 std_EPHEMERAL_REGISTER_1
.constant R2 std_EPHEMERAL_REGISTER_2
.constant R3 std_EPHEMERAL_REGISTER_3
.constant R4 std_EPHEMERAL_REGISTER_4
.constant R5 std_EPHEMERAL_REGISTER_5
.constant R6 std_EPHEMERAL_REGISTER_6
.constant R7 std_EPHEMERAL_REGISTER_7
.constant R8 std_EPHEMERAL_REGISTER_8
.constant R9 std_EPHEMERAL_REGISTER_9
.constant RA std_EPHEMERAL_REGISTER_A
.constant RB std_EPHEMERAL_REGISTER_B
.constant RC std_EPHEMERAL_REGISTER_C
.constant RD std_EPHEMERAL_REGISTER_D
.constant RE std_EPHEMERAL_REGISTER_E
.constant RF std_EPHEMERAL_REGISTER_F
; FASTCALL uint std_multiply(uint A, uint B). Return value on RRET
; Uses simple addition
; TODO: use add + shift
.constant std_mul @std_multiply
.constant std_multiply @std_multiply
std_multiply:
PUSH BSM_COUNTER_0 ; Save old value of counter
MOV BSM_COUNTER_0, P0 ; Move A to counter
MOV RRET, 0
JUMP @.loop ; Skip first iteration
.multiply:
ADD RRET, RRET, P1 ; Add B to itself A times
.loop: LOOP @.multiply ; Check if 0, if not, decrease A and go back. Use COUNTER[0]
POP BSM_COUNTER_0 ; Restore old value of counter
RET ; Return, no need to get rid of stack as fastcall passed them on registers