DataHoarder
a51287bcee
All checks were successful
continuous-integration/drone/push Build is passing
76 lines
4.4 KiB
NASM
76 lines
4.4 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
|
|
|
|
; 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
|
|
|