aboutsummaryrefslogtreecommitdiffstats
path: root/atk16_asm/builtin_asm/std_mem.atk16
blob: 58558792486d0f4a98068f0054d7063915d0f41a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
@label memset
  ; sets a specified number of words in memory to a specified value
  ; parameters:             RA = offset (offset in memory to start at)
  ;                         RB = n (number of words to set)
  ;                         RC = val (value to set the words to)
  ; returns:                void
  stack_stash RD RE
  ldi 0 RD                  ; RD := i (counter), initially 0
@label memset_loop
  sub RB RD RE              ; RE := n – i (unused value)
  bri zero memset_done      ; exit the loop

  add RA RD RE              ; RE := RA + i (address of the word to set)
  str RC RE                 ; set the word at address RE to value in RC

  inc RD                    ; i := i + 1
  jpi memset_loop           ; repeat the loop
@label memset_done
  stack_restore RD RE
  return

@label memcopy
  ; copies a specified number of words from one location in memory to another
  ; parameters:             RA = src (source address)
  ;                         RB = dest (destination address)
  ;                         RC = n (number of words to copy)
  ; returns:                void
  stack_stash RD RE RF
  ldi 0 RD                  ; RD := i (counter), initially 0
@label memcopy_loop
  sub RC RD RE              ; RE := n – i (unused value)
  bri zero memcopy_done     ; exit the loop

  add RA RD RE              ; RE := src + i (address of the word to copy)
  ldr RE RE                 ; RE := the word at address RE
  add RB RD RF              ; RF := dest + i (address of the word to copy to)
  str RE RF                 ; set the word at address RF to the word in RE

  inc RD                    ; i := i + 1
  jpi memcopy_loop          ; repeat the loop
@label memcopy_done
  stack_restore RD RE RF
  return

@label memcompare
  ; compares two blocks of memory
  ; parameters:             RA = src1 (source address 1)
  ;                         RB = src2 (source address 2)
  ;                         RC = n (number of words to compare)
  ; returns:                RG = 1 if the blocks are equal, 0 otherwise
  stack_stash RA RB RC RD RE
  ldi 0 RG                  ; RD := 0 (result)

@label memcompare_loop
  subi RC 0 RC
  bri zero memcompare_result_equal   ; exit the loop

  ldr RA RD                 ; RD := left value
  ldr RB RE                 ; RE := right value

  sub RD RE RD              ; RD := left - right
  bri zero memcompare_continue      ; if left == right, continue the loop

  jpi memcompare_end        ; if left != right, exit the loop

@label memcompare_continue
  inc RA                    ; RA := RA + 1
  inc RB                    ; RB := RB + 1
  dec RC                    ; RC := RC - 1
  jpi memcompare_loop       ; repeat the loop

@label memcompare_result_equal
  ldi 1 RG                  ; RG := 1 (result)

@label memcompare_end
  stack_restore RA RB RC RD RE
  return


@label string_compare
  ; compares two strings
  ; parameters:             RA = str1 (source address 1)
  ;                         RB = str2 (source address 2)
  ; returns:                RG = 1 if the strings are equal, 0 otherwise

  stack_stash RA RB RC RD RE
  ldi 0 RG                  ; RD := 0 (result)

  ldr RA RD                 ; RD := left string length
  ldr RB RE                 ; RE := right string length

  sub RD RE RD              ; RD := left length - right length
  bri zero string_compare_same_length      ; if equal length, use memcompare

  jpi string_compare_end    ; else if different length, exit

@label string_compare_same_length
  inc RA
  inc RB
  mov RE RC
  calli memcompare          ; return value implicitly returned in RG

@label string_compare_end
  stack_restore RA RB RC RD RE
  return