-
Notifications
You must be signed in to change notification settings - Fork 20
Expand file tree
/
Copy pathmaze.sparc
More file actions
157 lines (146 loc) · 3.11 KB
/
maze.sparc
File metadata and controls
157 lines (146 loc) · 3.11 KB
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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
# Maze generator in SPARC64 assembly language
# Joe Wingbermuehle
# 2017-08-17
# Compile with: gcc -x assembler maze.sparc
# Size of the maze (must be odd).
.equ width, 39
.equ height, 23
.section .text
.global main
.add_pc:
jmp %o7 + 8
add %o7, %l7, %l7
main:
save %sp, -128, %sp
sethi %hi(_GLOBAL_OFFSET_TABLE_ - 4), %l7
call .add_pc
add %l7, %lo(_GLOBAL_OFFSET_TABLE_ + 4), %l7
call .initialize
nop
call srand
nop
sethi %hi(.offsets), %o1
or %o1, %lo(.offsets), %o1
ldx [%l7 + %o1], %o1
sethi %hi(.maze), %o0
or %o0, %lo(.maze), %o0
ldx [%l7 + %o0], %o0
mov %o0, %l0
call .carve
add %o0, width * 2 + 2, %o0
mov space_value, %l1
add %l0, width + 2, %l0
stb %l1, [%l0]
add %l0, width * (height - 3) + width - 5, %l0
stb %l1, [%l0]
call .draw
mov %l7, %o0
mov 0, %i0
ret
restore
# Carve the maze starting at i0 (a pointer into the maze array).
# Pointer to offsets in i1
.carve:
save %sp, -128, %sp
mov %i1, %o1
.carve_restart:
mov space_value, %l6
call rand
stb %l6, [%i0]
and %o0, 3, %o2 ! Direction to try in %o2
mov 4, %l0 ! Number of tries in %l0
.carve_loop:
add %i1, %o2, %l1
ldsb [%l1], %l1 ! Offset in %l1
add %i0, %l1, %l2 ! First address in %l2
add %l2, %l1, %o0 ! Second address in %o0
ldub [%l2], %l4
ldub [%o0], %l5
addcc %l4, %l5, %l4
bne %icc, .carve_next
nop
call .carve
stb %l6, [%l2]
.carve_next:
add %o2, 1, %o2
subcc %l0, 1, %l0
bne .carve_loop
and %o2, 3, %o2
ret
restore
# Initialize the maze array.
# This is a leaf that modifies %l0, %l1, %l2, %l3
.initialize:
mov width * height, %l0
sethi %hi(.maze), %l1
or %l1, %lo(.maze), %l1
ldx [%l7 + %l1], %l1
mov %l1, %l3
mov space_value, %l2
.init_fill:
stb %g0, [%l1]
subcc %l0, 1, %l0
bne %icc, .init_fill
add %l1, 1, %l1
mov width, %l0
mov %l3, %l1
mov space_value, %l2
.init_top_bottom:
stb %l2, [%l1]
stb %l2, [%l1 + width * height - width]
subcc %l0, 1, %l0
bne %icc, .init_top_bottom
add %l1, 1, %l1
mov height, %l0
mov %l3, %l1
.init_sides:
stb %l2, [%l1]
stb %l2, [%l1 + width - 1]
subcc %l0, 1, %l0
bne %icc, .init_sides
add %l1, width, %l1
jmp %o7 + 8
nop
# Draw the maze.
# This takes the data offset as its only argument.
.draw:
save %sp, -128, %sp
sethi %hi(.maze), %l0
or %l0, %lo(.maze), %l0
ldx [%i0 + %l0], %l0
mov height, %l1
.draw_line:
mov width, %l2
.draw_cell:
ldub [%l0], %l3
sethi %hi(.wall), %o0
or %o0, %lo(.wall), %o0
ldx [%i0 + %o0], %o0
add %o0, %l3, %o0
call printf
nop
subcc %l2, 1, %l2
bne %icc, .draw_cell
add %l0, 1, %l0
sethi %hi(.nl), %o0
or %o0, %lo(.nl), %o0
call printf
ldx [%i0 + %o0], %o0
subcc %l1, 1, %l1
bne %icc, .draw_line
nop
ret
restore
.section .data
.offsets:
.byte -1, 1, -width, width
.nl: .asciz "\n"
# .space and .wall must be adjacent.
.wall: .asciz "[]"
.space: .asciz " "
# Use the size of the ".wall" as the value for spaces.
# This allows us to just add this value to get to the right
# string to display when drawing.
.equ space_value, .space - .wall
.section .bss
.comm .maze, width * height