aboutsummaryrefslogtreecommitdiffstats
path: root/resources/asm/monitor.atk16
blob: 9a9484f30954bd71fafdbc5567f4f2d37a6083b9 (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
@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"

@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

; loop forever
@label loop
  calli wait_for_input_newline

  ; BEGIN critical section
  ; disable_interrupts
  ; <work>
  ; enable_interrupts
  ; END
  jpi loop

;;; Subroutines

; TODO: move the implementation body (between stack_stash and stack_restore) to
; a macro so that it can be inlined without function call overhead when needed

@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 := &&char
  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