-
Notifications
You must be signed in to change notification settings - Fork 30
/
Copy pathinteract.mu4
157 lines (115 loc) · 4.92 KB
/
interact.mu4
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
| This file is part of muforth: https://muforth.dev/
|
| Copyright 2002-2025 David Frech. (Read the LICENSE for details.)
| Support common to all 908 and S08 interactions. Things like SWI stack
| frames, reading and writing memory using "indexed" reads and writes.
loading S08 Interaction (common)
variable chatting
variable chat-vector
: chat-cmd ( index - index+1) dup cells constant 1+
does> @ chat-vector @ =if + @execute ^ then 2drop
error" Not connected to a chat-capable target" ;
: chat-fail error" Chat command not implemented" ;
0 ( initial command index)
chat-cmd t.hello ( - in-ram? chunk-size)
chat-cmd t.status ( - dp)
chat-cmd t.run ( pc dp)
chat-cmd t.read ( buf a u)
chat-cmd t.write ( buf a u)
chat-cmd t.flash ( buf a u fcmd - status)
drop ( index)
: >image ['] read-host-image ( read from memory image) du-target ;
: >chat ['] t.read ( read from connected target) du-target ;
: copy-chunk ( 'target len - 'target+len)
| cr ." copy-chunk " 2dup swap u. u.
2dup + push over image+ -rot t.write pop ;
variable /chunk ( chunk size, as reported by debug interface)
256 /chunk ! | Prevents mystifying divide-by-zero errors when not chatting
: copy-region ( a len)
| cr ." copy-region " 2dup swap u. u.
/chunk @ /mod ( r q) swap push
for /chunk @ copy-chunk next pop
=if ( rem) copy-chunk drop ^ then 2drop ;
variable ram-copied ( pointer to first un-copied byte)
: copy-ram
h preserve ram
ram-copied @ dup 0= if drop region drop then
\m here over - copy-region
\m here ram-copied ! ;
variable in-ram? | true if chat running in RAM
defer verify-quietly ( - diff)
( t.hello will copy the flash code to RAM and set ram-copied.)
: hi chatting on >chat t.hello /chunk ! in-ram? !
.ifndef noverify verify-quietly drop .then
now __chatting is __meta __meta ;
: chat-via pop chat-vector ! hi ;
| Since we don't cache top in a register - there aren't any registers for
| that on the S08! - we don't need a stack sentinel. If you want it anyway
| - for a "safety" in case something underflows the stack by one cell
| - feel free to uncomment the following line.
| "cafe constant stack-sentinel
@ram #ram + #24 \m cells - constant dp0
| Synonyms for stack code.
: stack-write t.write ;
: stack-read t.read ;
ld target/common/stacks.mu4
: run ( pc) copy-ram dp@ t.run ; ( don't wait for target)
: runwait ( pc) run t.status dp! ; ( wait for target)
: 'reset ( - pc) \eq Vreset image-@ ;
: reset 'reset runwait ; | for switching to in-ram chat
: go 'reset run ; | for switching to another chat version
| Useful for later code.
: 4# # # # # ;
| Set |@ and |c@ to _some_ form of target fetch. Prefer to get bytes from
| target if we're connected. This word is useful so we can set an initial
| state for target's du and dis so that inspect won't crash when it
| runs |@ to get a default ea.
: >target chatting @ if >chat ^ then >image ;
| Define our own key bindings for memory dumping and disassembly. We'll
| default to host bindings if there isn't one in our array. This way we
| only have to define the "delta" between host and target behaviours.
128 array hc08-seekeys
( Default key action is to run host key code)
host-seekeys hc08-seekeys 128 cells cmove
( Support for dumping memory)
: 1dump ( a)
hex-bytes ( set field width)
>image dup .addr dup .hex-bytes
chatting @ if
-valid
>chat dup _addr dup .hex-bytes
-valid
then
drop ( a) ;
( So we can easily look at the signature embedded into the image.)
: 1dump-chars ( a)
hex-bytes
>target
dup _addr dup .chars
dup .addr dup .hex-bytes
drop ;
hc08-seekeys -1 du-mode dumping >target skip+ skip- 1dump ( a - a')
hc08-seekeys -1 du-mode dumping-chars >target skip+ skip- 1dump-chars ( a - a')
hc08-seekeys -1 du-mode disasming >target dis+ dis- 1dis ( a - a')
hc08-seekeys 'seekeys ! ( switch over to our bindings)
key: d ( a - a 0) dumping 0 ;
key: C ( a - a 0) dumping-chars 0 ; ( small c is "call")
key: i ( a - a 0) disasming 0 ;
host-seekeys 'seekeys ! ( back to host bindings)
( Interactive)
( make an alias so we can still get to host's du)
: _du du ;
| Sometimes, when chatting, we want to dump or disassemble something that
| is in RAM. If we have just compiled it, and haven't yet run any code, the
| host RAM and target RAM are out of sync; and because we show the contents
| of the target RAM when chatting, we see garbage.
|
| To improve this situation, let's copy-ram - if we're chatting and trying
| to look at the ram - before doing a dis.
: ?sync-ram ( a - a)
chatting @ if
h preserve ram
dup ram-copied @ \m here within if copy-ram then
then ;
: du ( a - a') dumping inspect ;
: dis ( a - a') ?sync-ram disasming inspect ;