Browse code

Add basic in-Uxn debugger and usage example.

Andrew Alderwick authored on 05/01/2022 17:27:50
Showing 2 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,16 @@
1
+( devices )
2
+
3
+|00 @System     &vector $2 &wst      $1 &rst    $1 &eaddr  $2 &ecode  $1 &pad     $1 &r       $2 &g      $2 &b     $2 &debug  $1 &halt $1
4
+|10 @Console    &vector $2 &read     $1 &pad    $5 &write  $1 &error  $1
5
+
6
+( program )
7
+
8
+|0100 @Reset ( -> )
9
+	~projects/library/debugger.tal
10
+	#0123 #4567 #89ab #cdef
11
+	LIT2r 1234 LIT2r 5678 LIT2r 9abc LIT2r def0
12
+	( BREAKPOINT )
13
+	( LIT2r 0000 DIVr )
14
+	&loop INCk ,&loop JMP
15
+	BRK
16
+
0 17
new file mode 100644
... ...
@@ -0,0 +1,180 @@
1
+( in-Uxn debugger )
2
+
3
+( To use, include this file just before the BRK in the program reset routine, e.g.:
4
+
5
+	|0100 ( -> )
6
+		( theme )
7
+		#0fe5 .System/r DEO2
8
+		#0fc5 .System/g DEO2
9
+		#0f25 .System/b DEO2
10
+	~projects/library/debugger.tal
11
+	BRK
12
+
13
+The debugger will catch stack errors that arise after that point.
14
+
15
+)
16
+
17
+%BREAKPOINT { LIT2r :debug JSR2r }
18
+
19
+@debug-start
20
+;debug-vector .System/vector DEO2
21
+;debug-end JMP2
22
+
23
+@debug ( pc* -- )
24
+	#0001 SUB2 .System/eaddr DEO2
25
+	.System/ecode DEIk #f8 AND #06 EOR SWP DEO
26
+	,debug-vector/main JMP
27
+
28
+@debug-vector ( -> )
29
+	STH STH STH STH ( <- only run in case of working stack overflow )
30
+	&main
31
+
32
+	( flush the working stack )
33
+	.System/wst DEI ;debug-wst/ptr STA
34
+	&flush-wst
35
+	.System/wst DEI #00 EQU ,&end-flush-wst JCN
36
+	#00 .System/wst DEI #0002 SUB2 ;debug-wst/dat ADD2 STA
37
+	,&flush-wst JMP
38
+	&end-flush-wst
39
+
40
+	( in case of working stack overflow, we need to append the four return stack bytes )
41
+	.System/ecode DEI #02 NEQ ,&skip-wst-append JCN
42
+	#00 ;debug-wst/ptr LDAk ( 00 ptr-hi ptr-lo ptr / ... z y x w )
43
+		DUP #04 ADD OVR2 STA
44
+		ROT ROT ADD2 ( start* / ... z y x w )
45
+		INC2 DUP2 #0004 ADD2 SWP2 ( end* start* / ... z y x w )
46
+		&loop
47
+		DUP2 STHr ROT ROT STA
48
+		INC2
49
+		GTH2k ,&loop JCN
50
+		POP2 POP2
51
+	&skip-wst-append
52
+
53
+	( flush the return stack )
54
+	.System/rst DEI ;debug-rst/ptr STA
55
+	&flush-rst
56
+	.System/rst DEI #00 EQU ,&end-flush-rst JCN
57
+	STHr #00 .System/rst DEI ;debug-rst/dat ADD2 STA
58
+	,&flush-rst JMP
59
+	&end-flush-rst
60
+
61
+	( Version 0.1 functionality: print the error and exit )
62
+	;debug-print-error JSR2
63
+	#01 .System/halt DEO
64
+	BRK
65
+
66
+@debug-print-opcode ( instr -- )
67
+	DUP ,&not-brk JCN
68
+	POP ;&brk-msg ;debug-print JMP2 ( tail call )
69
+	&brk-msg "BRK 00
70
+	&not-brk
71
+	#00 OVR #1f AND #03 MUL ;&opcode-names ADD2 ( instr addr* )
72
+	LDAk .Console/write DEO INC2
73
+	LDAk .Console/write DEO INC2
74
+	LDA  .Console/write DEO
75
+	DUP #1f AND ,&not-lit JCN
76
+	#7f AND
77
+	&not-lit
78
+	DUP #20 AND #00 EQU ,&not-2 JCN
79
+	LIT '2 .Console/write DEO
80
+	&not-2
81
+	DUP #80 AND #00 EQU ,&not-k JCN
82
+	LIT 'k .Console/write DEO
83
+	&not-k
84
+	    #40 AND #00 EQU ,&not-r JCN
85
+	LIT 'r .Console/write DEO
86
+	&not-r
87
+	JMP2r
88
+
89
+	&opcode-names
90
+		"LITINCPOPDUPNIPSWPOVRROT
91
+		"EQUNEQGTHLTHJMPJCNJSRSTH
92
+		"LDZSTZLDRSTRLDASTADEIDEO
93
+		"ADDSUBMULDIVANDORAEORSFT
94
+
95
+@debug-print ( addr* -- )
96
+	LDAk #00 EQU ,&end JCN
97
+	LDAk .Console/write DEO
98
+	INC2
99
+	,debug-print JMP
100
+	&end POP2 JMP2r
101
+
102
+@debug-print-error
103
+	;&halted-msg ,debug-print JSR
104
+	#00 .System/ecode DEI #07 AND #20 SFT2 ;&messages-table ADD2
105
+	LDA2k ,debug-print JSR
106
+	INC2 INC2 LDA2 ,debug-print JSR
107
+	;&executing-msg ,debug-print JSR
108
+	.System/eaddr DEI2 LDA ;debug-print-opcode JSR2
109
+	;&at-msg ,debug-print JSR
110
+	.System/eaddr DEI2 ;debug-print-hex-short JSR2
111
+	#0a .Console/write DEO
112
+	;&wst-msg ,debug-print JSR
113
+	;&contents-msg ,debug-print JSR
114
+	;debug-wst ;debug-print-stack JSR2
115
+	#0a .Console/write DEO
116
+	;&rst-msg ,debug-print JSR
117
+	;&contents-msg ,debug-print JSR
118
+	;debug-rst ;debug-print-stack JSR2
119
+	#0a .Console/write DEO
120
+	JMP2r
121
+
122
+	&messages-table
123
+		:&wst-msg :&underflow-msg
124
+		:&rst-msg :&underflow-msg
125
+		:&wst-msg :&overflow-msg
126
+		:&rst-msg :&overflow-msg
127
+		:&wst-msg :&divzero-msg
128
+		:&rst-msg :&divzero-msg
129
+		:&userdef-msg :&breakpoint-msg
130
+		:&userdef-msg :&custom-msg
131
+
132
+	&halted-msg "Halted: 2000 ( #0002, at 0x0100 )
133
+	&wst-msg "Working-stack 2000
134
+	&rst-msg "Return-stack 2000
135
+	&userdef-msg "User-defined 2000
136
+	&underflow-msg "underflow 00
137
+	&overflow-msg "overflow 00
138
+	&divzero-msg "division 20 "by 20 "zero 00
139
+	&breakpoint-msg "breakpoint 00
140
+	&custom-msg "custom 20 "error 00
141
+	&executing-msg 20 "executing 2000
142
+	&at-msg 20 "at 20 "0x 00
143
+	&contents-msg "contents: 00
144
+
145
+@debug-print-hex-short ( value* -- )
146
+	SWP ,debug-print-hex-byte JSR
147
+	( fall through )
148
+
149
+@debug-print-hex-byte ( value -- )
150
+	DUP #04 SFT ,debug-print-hex-nibble JSR
151
+	#0f AND
152
+	( fall through )
153
+
154
+@debug-print-hex-nibble ( value -- )
155
+	#30 ADD DUP #39 GTH #27 MUL ADD
156
+	.Console/write DEO
157
+	JMP2r
158
+
159
+@debug-print-stack ( addr* -- )
160
+	LDAk ,&not-empty JCN
161
+	POP2 ;&empty-msg ;debug-print JMP2 ( tail call )
162
+	&not-empty
163
+	LDAk STH INC2 ( dat* / count )
164
+	&loop
165
+		STHkr #00 EQU ,&end JCN
166
+		#20 .Console/write DEO
167
+		LDAk ,debug-print-hex-byte JSR
168
+		INC2
169
+		LITr 01 SUBr
170
+		,&loop JMP
171
+	&end
172
+	POP2 POPr
173
+	JMP2r
174
+	
175
+	&empty-msg 20 "(empty) 00
176
+
177
+@debug-wst &ptr $1 &dat $ff
178
+@debug-rst &ptr $1 &dat $ff
179
+@debug-end
180
+