-
Notifications
You must be signed in to change notification settings - Fork 30
/
Copy pathchat-serial-core.mu4
138 lines (111 loc) · 4.08 KB
/
chat-serial-core.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
| This file is part of muforth: https://muforth.dev/
|
| Copyright 2002-2025 David Frech. (Read the LICENSE for details.)
loading PIC18 Serial chat (core)
hex
| Taking inspiration from the wildly successful HC08 serial chat protocol.
|
| Responds to the following commands. NOTE: these are hex values!
|
| 00 - 0f Idle - these command bytes are ignored
|
| 10 get-version - send 4 byte commit (little endian) to host
| 11 set-prog-addr - set the program (flash) memory address pointer
| 12 set-data-addr - set the data memory address pointer
| 13 get-data-addr - get the current value of the data mem ptr
| 14 run - load PC from flash-addr
| 15 read-prog-n - read n bytes from program memory, incr pointer
| 16 read-data-n - read n bytes from data memory, incr pointer
| 17 write-data - write a byte to data memory, incr pointer
|
| These are Q-series commands for programming the flash, config, and
| eeprom.
|
| 18 set-nvm-addr - set NVMADR from prog-addr
| 19 nvm-read - execute an NVM read command, return data read
| 1a nvm-write - execute an NVM write command, return status
|
| 1b - ff Idle - these command bytes are ignored
| Some useful synonyms. I don't like TBLPTR and TABLAT. They aren't
| mnemonic! TBLPTR points into the program memory space. Why not PROGADR
| and PROGDATA?
aka TBLPTRU equ PROGADRU
aka TBLPTRH equ PROGADRH
aka TBLPTRL equ PROGADRL
aka TABLAT equ PROGDATA
| We are going to use FSR0 to point to data memory. Let's call it DP - data
| pointer.
|
| XXX Hmm. This collides with my plan to use DP to mean data stack pointer
| everywhere. Maybe DSP/RSP/MSP is better after all?
assembler
aka FSR0 equ DP ( data pointer)
aka FSR0H equ DPH ( data pointer, high byte)
aka POSTINC0 equ @dp+ ( read or write a data memory location, incr pointer)
forth
__meta
boot
0 , ( startup rjmp)
( Load device-specific support.)
.ifdef 1xk50
ld target/PIC18/device/chat-k.mu4
.else
ld target/PIC18/device/chat-q.mu4
.then
| Compile the first 32 bits of the current muforth Git commit. When asked
| for the version, return these four bytes, in little-endian order.
label get-version
muforth-commit drop 8 evaluate >3210
ldi send-byte c ldi send-byte c ldi send-byte c ldi send-byte j ;c
label set-prog-addr
recv-byte c PROGADRL ) st
recv-byte c PROGADRH ) st
recv-byte c PROGADRU ) st ret ;c
label set-data-addr
recv-byte c DP ) st
recv-byte c DPH ) st ret ;c
label get-data-addr
DP ) ld send-byte c
DPH ) ld send-byte j ;c
( Jump indirect to prog-addr.)
label run
PROGADRU ) ld PCLATU ) st
PROGADRH ) ld PCLATH ) st
PROGADRL ) ld PCL ) st ( this jumps!) ;c
| Doing streaming reads from program memory space is critical to making
| verifying the flash fast.
( INDF1 points to a scratch byte at the end of ram.)
label read-prog-n
recv-byte c INDF1 ) st ( count)
begin prog@+ PROGDATA ) ld send-byte c INDF1 ) decsz again ret ;c
| We don't necessarily need to do streaming reads from data space, but it's
| much faster to read multiple bytes at a time. The code is longer, though:
| single byte read is two instructions; multi-byte is seven!
label read-data-n
recv-byte c INDF1 ) st ( count)
begin @dp+ ) ld send-byte c INDF1 ) decsz again ret ;c
label write-data
recv-byte c @dp+ ) st ret ;c
label process-serial
@ram #ram + 1- FSR1 lda ( point to last byte of ram, as scratch)
recv-byte c ( command) -0f addi
W ) decsnz ( 10) get-version j
W ) decsnz ( 11) set-prog-addr j
W ) decsnz ( 12) set-data-addr j
W ) decsnz ( 13) get-data-addr j
W ) decsnz ( 14) run j
W ) decsnz ( 15) read-prog-n j
W ) decsnz ( 16) read-data-n j
W ) decsnz ( 17) write-data j
.ifndef 1xk50 ( Q-series support)
W ) decsnz ( 18) set-nvm-addr j
W ) decsnz ( 19) nvm-read j
W ) decsnz ( 1a) nvm-write j
.else ( K50 support)
( not yet implemented!)
.then
( unknown command) ret ;c
here 0 goto dup \a rjmp goto
label startup
chip-init c
begin process-serial c again ;c