blob: d3b8756a449b02a31cde091cc75548833f93e090 (
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
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
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
|
@use monitor_macros:*
@include %bootstrap
@include %std_mem
@include %std_term
@include %std_bump_alloc
; Constants
@data text_buffer_size 2048
@data input_buffer_size 64
; Global variable pointers
; 0xE800 - 0xEFFF: sprite buffer space that is unused in this program
@data text_cursor_p 0xE800
@data input_buffer_p 0xE801
@data input_cursor_p 0xE802
@data title_string " »» ATK16 monitor v0.1 »»"
@data subtitle_string " Run [help] for a list of commands"
@data prompt_string " > "
@label main
; initialize heap allocator
calli bump_reset
; initialize global variables
; BEGIN text_cursor_p = text_mem
ldi text_cursor_p RA
ldr RA RA
ldi vt_text_mem RB
ldr RB RB
str RB RA
; END
; BEGIN input_buffer_p = alloc(64)
ldi input_buffer_size RA
calli bump_alloc
ldi input_buffer_p RA
ldr RA RA
str RG RA
; END
; use memset to clear the text buffer
; BEGIN memset(text_mem, 0, text_buffer_size)
ldi vt_text_mem RA ; RA := text buffer address pointer
ldr RA RA ; RA := text buffer address
ldi text_buffer_size RB ; RB := pointer to text_buffer_size
ldr RB RB ; RB := text_buffer_size
ldi 0 RC ; RC := 0
calli memset
; END
set_graphics_mode gr_text_mode
m_newline RA RB
; BEGIN put_string(title_string)
ldi title_string RA
calli put_string
; END
m_newline RA RB
; BEGIN put_string(subtitle_string)
ldi subtitle_string RA
calli put_string
; END
m_newline RA RB
m_newline RA RB
ldi prompt_string RA
calli put_string
; loop forever
@label loop
; BEGIN critical section
m_set_critical RA RB
calli is_newline_pressed
subi RG 1 RG ; if is_newline_pressed() == 1, then loop_newline_pressed
bri zero loop_newline_pressed
jpi loop_finally
@label loop_newline_pressed
; TODO
jpi loop_finally
@label loop_finally
m_clear_critical RA RB
; END critical section
jpi loop
;;; Subroutines
@label newline
; move cursor to the beginning of the next line
; parameters: none
; returns: none
stack_stash RA RB
m_newline RA RB
stack_restore RA RB
return
@label put_char
; put a character at the current cursor position
; parameters: RA = character to put
; returns: none
stack_stash RB RC
m_put_char RA RB RC
stack_restore RB RC
return
@label put_string
; put a string at the current cursor position
; parameters: RA = string_p
; returns: none
stack_stash RA RB RC RD RE
ldr RA RB ; RB := string length
addi RA 1 RC ; RC := pointer to first character
@label put_string_loop
subi RB 0 RB ; exit if RB has been decremented to 0
bri zero put_string_done ; i.e. no more characters to put
ldr RC RA ; RA := character to put
m_put_char RA RD RE ; inline the put_char subroutine to avoid function call overhead
inc RC
subi RB 1 RB
jpi put_string_loop
@label put_string_done
stack_restore RA RB RC RD RE
return
@label wait_for_input_newline
; wait for a newline character in the input buffer
; parameters: none
; returns: RG = key code
stack_stash RA RB
ldi 10 RB ; RB := newline character
@label wait_for_input_newline_loop
ldi input_cursor_p RA ; RA := data segment pointer
ldr RA RA ; RA := 0xE802
ldr RA RA ; RA := &char
ldr RA RA ; RA := char
sub RA RB RA ; if RA == newline, then stop waiting
bri zero wait_for_input_newline_done
jpi wait_for_input_newline_loop
@label wait_for_input_newline_done
stack_restore RA RB
return
@label is_newline_pressed
; check if the last character in the input buffer is a newline
; parameters: none
; returns: RG = 1 if newline is pressed, 0 otherwise
stack_stash RA RB
ldi 10 RB ; RB := newline character
ldi input_cursor_p RA ; RA := data segment pointer
ldr RA RA ; RA := 0xE802
ldr RA RA ; RA := &char
ldr RA RA ; RA := char
ldi 1 RG ; RG := 1
sub RA RB RA ; if RA == newline, then return RG = 1
bri zero is_newline_pressed_done
ldi 0 RG ; else return RG = 0
@label is_newline_pressed_done
stack_restore RA RB
return
|