-
Notifications
You must be signed in to change notification settings - Fork 0
/
command_DAE_VAE_LAE_DA_VA_LA_KA.asm
354 lines (337 loc) · 9.13 KB
/
command_DAE_VAE_LAE_DA_VA_LA_KA.asm
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
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
; This file is part of Programator.
;
; Programator is free software: you can redistribute it and/or
; modify it under the terms of the GNU General Public License as
; published by the Free Software Foundation, either version 3 of the
; License, or (at your option) any later version.
;
; Programator is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
; General Public License for more details.
;
; You should have received a copy of the GNU General Public License
; along with Programator. If not, see <https://www.gnu.org/licenses/>.
;
; Copyright (c) 2022, 2024 Aleksander Mazur
;
; Procedury obsługi poleceń:
; - DAE [begin-address [end-address]] - zrzut EEPROM, sygnatury, kalibracji, fuse-bitów, lock-bitów
; - VAE - weryfikacja EEPROM (a także sygnatury, kalibracji, fuse-bitów, lock-bitów)
; - LAE - ładowanie pamięci EEPROM
; - DA [begin-address [end-address]] - zrzut pamięci programu
; - VA - weryfikacja pamięci programu
; - LA - ładowanie pamięci programu
; - KA - kasowanie pamięci programu
; Czyli obsługa AVR (np. ATtiny2313)
;-----------------------------------------------------------
; DAE [begin-address [end-address]]
if USE_HELP_DESC
dw s_help_DAE
endif
command_dump_avr_eeprom:
; domyślnie DAE 0 7F
acall avr_init
clr A
mov R2, A
mov R3, A
mov R4, A
mov R5, #7Fh ; 128 B EEPROMu
acall get_address_range
; mamy zakres zrzutu: R2:R3 bajtów poczynając od R4:R5
mov A, R2
jz command_dump_avr_eeprom_ok
ajmp error_illopt_fwd
command_dump_avr_eeprom_ok:
mov DPTR, #cb_dump_avr_eeprom
ajmp dump_hex_file
cb_dump_avr_eeprom:
setb RS0
mov R4, AR4
mov R5, AR5
mov R7, AR7
mov R0, #input
cb_dump_avr_eeprom_loop:
acall avr_read_eeprom_R4R5
bcall cb_common_store_increment
djnz R7, cb_dump_avr_eeprom_loop
cb_dump_avr_ret:
; koniec
ajmp cb_ret_RS_input_OK
;-----------------------------------------------------------
; DA [begin-address [end-address]]
if USE_HELP_DESC
dw s_help_DA
endif
command_dump_avr_flash:
; domyślnie DA 0 7FF
acall avr_init
clr A
mov R2, A
mov R3, A
mov R4, #7h
mov R5, #0FFh
acall get_address_range
; mamy zakres zrzutu: R2:R3 bajtów poczynając od R4:R5
mov DPTR, #cb_dump_avr_flash
ajmp dump_hex_file
cb_dump_avr_flash:
setb RS0
mov R4, AR4
mov R5, AR5
mov R7, AR7
mov R0, #input
cb_dump_avr_flash_loop:
acall avr_read_flash_R4R5
bcall cb_common_store_increment
djnz R7, cb_dump_avr_flash_loop
; koniec
sjmp cb_dump_avr_ret
;-----------------------------------------------------------
; VAE
if USE_HELP_DESC
dw s_help_VAE
endif
command_verify_avr_eeprom:
acall ensure_no_args
acall avr_init
mov DPTR, #cb_verify_avr_eeprom
ajmp load_hex_file
cb_verify_avr_eeprom:
acall avr_read_eeprom_R4R5
acall avr_common_verify
djnz R7, cb_verify_avr_eeprom
cb_avr_code_G:
ajmp cb_lv_code_G
;-----------------------------------------------------------
; VA
if USE_HELP_DESC
dw s_help_VA
endif
command_verify_avr_flash:
acall ensure_no_args
acall avr_init
mov DPTR, #cb_verify_avr_flash
ajmp load_hex_file
cb_verify_avr_flash:
acall avr_read_flash_R4R5
acall avr_common_verify
djnz R7, cb_verify_avr_flash
sjmp cb_avr_code_G
;-----------------------------------------------------------
; LAE
if USE_HELP_DESC
dw s_help_LAE
endif
command_load_avr_eeprom:
acall ensure_no_args
acall avr_init
mov DPTR, #cb_load_avr_eeprom
ajmp load_hex_file
cb_load_avr_eeprom:
cjne R7, #1, cb_load_avr_eeprom_not_one_byte
; tylko 1 bajt
; Write EEPROM Memory: 1100 0000 000x xxxx xbbb bbbb iiii iiii
mov A, #11000000b
acall avr_write_eeprom_AR4R5atR0
jc cb_avr_code_F
sjmp cb_load_avr_eeprom_finish
cb_load_avr_eeprom_next:
bcall cb_common_increment
mov A, R5
anl A, #00000011b
jnz cb_load_avr_eeprom_not_one_byte
; cofamy się o 4 bajty, żeby mieć adres wypełnionej strony, a nie następnej
clr C
mov A, R5
subb A, #4
mov R5, A
mov A, R4
subb A, #0
mov R4, A
; zapisujemy stronę, bo jest cała gotowa
acall avr_write_eeprom_R4R5
jc cb_avr_code_F
; wracamy do następnej strony
mov A, R5
add A, #4
mov R5, A
mov A, R4
addc A, #0
mov R4, A
cb_load_avr_eeprom_not_one_byte:
; Load EEPROM Memory Page: 1100 0001 0000 0000 0000 00bb iiii iiii
mov A, #11000001b
acall avr_transfer_byte
clr A
acall avr_transfer_byte
mov A, R5
anl A, #00000011b
acall avr_transfer_byte
mov A, @R0
acall avr_transfer_byte
djnz R7, cb_load_avr_eeprom_next
; zapisujemy stronę, bo skończyły się dane wejściowe
mov A, R5
anl A, #11111100b
mov R5, A
acall avr_write_eeprom_R4R5
cb_load_avr_eeprom_finish:
jnc cb_avr_code_G
cb_avr_code_F:
mov A, #'F'
ret
;-----------------------------------------------------------
; LA
if USE_HELP_DESC
dw s_help_LA
endif
command_load_avr_flash:
acall ensure_no_args
acall avr_init
mov DPTR, #cb_load_avr_flash
ajmp load_hex_file
cb_load_avr_flash_next:
bcall cb_common_increment
cb_load_avr_flash:
; Load Program Memory Page: 0100 H000 000x xxxx xxxx bbbb iiii iiii
; zapisuje 1 bajt pod adres bbbbH (w ramach strony o 16 słowach 16-bitowych)
mov A, R5
rrc A
mov A, #01000000b
mov ACC.3, C
acall avr_transfer_byte ; 40h | ((R5 & 1) << 3)
clr A
acall avr_transfer_byte ; 0
mov A, R5
clr C
rrc A
acall avr_transfer_byte ; R5 >> 1
mov A, @R0
acall avr_transfer_byte
djnz R7, cb_load_avr_flash_next
; strona załadowana, teraz trzeba ją wpalić
; Write Program Memory Page: 0100 1100 0000 00aa bbbb xxxx xxxx xxxx
; w R4:R5 mamy adres ostatnio wpisanego bajtu;
; musimy go przesunąć o 1 bit w prawo, aby uzyskać adres słowa
mov A, R4
clr C
rrc A
mov R4, A
mov A, R5
rrc A
mov R5, A
mov A, #01001100b
acall avr_write_eeprom_AR4R5atR0
ajmp cb_load_avr_eeprom_finish
;-----------------------------------------------------------
; Odczytuje bajt spod podanego adresu EEPROM lub podobnie zorganizowanej pamięci
; Przeprowadza cały 4-bajtowy transfer
; R4:R5 - adres i rozkaz wg poniższego schematu
; starszy bajt adresu (R4) rozbijamy na 2 części:
; - 5 starszych bitów będzie najstarszymi bitami pierwszego bajtu komendy
; - 3 młodsze bity będą bitami 3,2,1 drugiego bajtu komendy (tj. z przesunięciem o 1 bit w lewo)
; młodszy bajt adresu (R5) będzie wysyłany jako trzeci bajt komendy
; R4 = xxxx xyyy -> xxxx x000 0000 yyy0
; czyli:
; 30h = Read Signature Byte (R5 mod 4)
; 38h = Read Calibration Byte (R5=0,1)
; 50h = Read Fuse Bits (R5=x)
; 54h = Read Extended Fuse Bits (R5=x)
; 58h = Read Lock Bits (R5=x)
; 5Ch = Read Fuse High Bits (R5=x)
; A0h = Read EEPROM Memory (R5 mod 128 w przypadku ATtiny2313)
; 0 jest przekształcane na A0h (dzięki czemu zrzut EEPROM ma adresy od 0)
; Zwraca odczytany bajt w A
; Niszczy C, R6
avr_read_eeprom_R4R5:
mov A, R4
jnz avr_read_eeprom_R4R5_nz
mov A, #0A0h ; 00 -> A0 (EEPROM)
avr_read_eeprom_R4R5_nz:
anl A, #11111000b
acall avr_transfer_byte ; R4 & 0F8h
mov A, R4
anl A, #00000111b
rl A
acall avr_transfer_byte ; (R4 & 7) << 1
mov A, R5
acall avr_transfer_byte ; R5
ajmp avr_transfer_byte
;-----------------------------------------------------------
; Odczytuje bajt spod podanego adresu pamięci flash
; Przeprowadza cały 4-bajtowy transfer
; R4:R5 - adres bajtu
; Zwraca odczytany bajt w A
; Niszczy C, R6
avr_read_flash_R4R5:
; Read Program Memory:
; 0010 H000 0aaa aaaa bbbb bbbb oooo oooo
; czyta 1 bajt spod adresu aaaa aaab bbbb bbbH
mov A, R5
rrc A
mov A, #00100000b
mov ACC.3, C
acall avr_transfer_byte ; 20h | ((R5 & 1) << 3)
mov A, R4
clr C
rrc A
acall avr_transfer_byte ; R4 >> 1
mov A, R4
rrc A
mov A, R5
rrc A
acall avr_transfer_byte ; ((R4 & 1) << 7) | (R5 >> 1)
ajmp avr_transfer_byte
;-----------------------------------------------------------
; Wspólna podprocedura weryfikacji
; A = wartość odczytana z pamięci
; R0 = adres w RAM, gdzie jest spodziewana wartość do porównania z A
; Musi być włączony bank rejestrów #0
; Jeśli wartości są różne, funkcja wraca poziom wyżej, zwracając kod V
; Jeśli wartości są równe, funkcja wykonuje cb_common_increment i wraca normalnie
avr_common_verify:
mov R2, A
mov A, @R0
cjne A, AR2, avr_common_verify_fail
bjmp cb_common_increment
avr_common_verify_fail:
; zdejmujemy ze stosu adres naszego bezpośredniego wywołania
pop ACC
pop ACC
mov A, #'V'
ret
;-----------------------------------------------------------
; Zapisuje wypełnioną wcześniej stronę pamięci EEPROM
; i czeka na faktyczne zakończenie zapisu
avr_write_eeprom_R4R5:
; Write EEPROM Memory Page: 1100 0010 00xx xxxx xbbb bb00 xxxx xxxx
mov A, #11000010b
;-----------------------------------------------------------
; Wysyła A, R4, R5, @R0
; i czeka na faktyczne zakończenie zapisu
; Zwraca odczytany bajt w A
; Niszczy C, R6
avr_write_eeprom_AR4R5atR0:
acall avr_transfer_byte
mov A, R4
acall avr_transfer_byte
mov A, R5
acall avr_transfer_byte
mov A, @R0
acall avr_transfer_byte
ajmp avr_wait_until_ready
;-----------------------------------------------------------
; KA
if USE_HELP_DESC
dw s_help_KA
endif
command_avr_chip_erase:
acall ensure_no_args
acall avr_init
; Chip Erase: 1010 1100 100x xxxx xxxx xxxx xxxx xxxx
mov A, #10101100b
mov R4, #10000000b
acall avr_write_eeprom_AR4R5atR0
jc avr_error
ret