Rev 115 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
35 | savelij | 1 | |
181 | savelij | 2 | ; LAST UPDATE: 11.12.2024 savelij |
35 | savelij | 3 | |
115 | savelij | 4 | include ../macros.a80 |
5 | include ../ports_ngs.a80 |
||
6 | include ../sdcomand.a80 |
||
35 | savelij | 7 | |
181 | savelij | 8 | ; адрес загрузки найденной прошивки |
9 | ADRLOAD EQU 0x8000 |
||
35 | savelij | 10 | |
181 | savelij | 11 | RAMCOD EQU 0x4080 ; адрес работы основного кода |
12 | RAM8KB EQU 0x6000 ; адрес буфера для переброски кода |
||
13 | STRPAG EQU 0x8000 ; адрес куда загрузки |
||
35 | savelij | 14 | |
181 | savelij | 15 | FREQUENCY EQU C_20MHZ ; текущая частота для основной прошивки |
112 | savelij | 16 | |
69 | savelij | 17 | ORG 0 |
35 | savelij | 18 | DI |
19 | LD SP,RAMCOD |
||
20 | XOR A |
||
21 | OUT (VOL1),A |
||
22 | OUT (VOL2),A |
||
23 | OUT (VOL3),A |
||
24 | OUT (VOL4),A |
||
25 | OUT (VOL5),A |
||
26 | OUT (VOL6),A |
||
27 | OUT (VOL7),A |
||
181 | savelij | 28 | OUT (VOL8),A ; заглушили мод порты для использования буфера |
35 | savelij | 29 | |
181 | savelij | 30 | ; JP RDBYT_DBG ; отладочная фигня |
38 | savelij | 31 | |
181 | savelij | 32 | ; ожидание загрузки прошивки со спека |
33 | LD B,0 ; читаем 256 порт статуса |
||
34 | .L1 IN A,(ZXSTAT) ; на предмет изменения состояния |
||
35 | savelij | 35 | RRA |
36 | JR C,RDBYT01 |
||
181 | savelij | 37 | DJNZ .L1 |
38 | DEC B ; счетчик обнулился, состояние порта не изменилось |
||
39 | JR RDBYT03 ; грузим стандартную прошивку |
||
35 | savelij | 40 | |
181 | savelij | 41 | RDBYT01 IN A,(ZXCMD) ; читем пришедший байт из порта команд |
42 | LD C,A ; сохранили для проверки |
||
43 | IN A,(ZXDATRD) ; читем байт из порта данных |
||
44 | OUT (CLRCBIT),A ; сбросили команд бит |
||
45 | CP C ; сравниваем пришедшие байты |
||
46 | JR NZ,RDBYT03 ; не совпали, грузим стандартную прошивку |
||
47 | CP 0x55 ; пришел байт 0x55? |
||
48 | JR NZ,RDBYT03 ; если нет, грузим стандартную прошивку |
||
49 | LD B,0 ; читаем 256 раз изменение порта команд |
||
35 | savelij | 50 | IN A,(ZXSTAT) |
51 | RRA |
||
52 | JR C,RDBYT02 |
||
53 | DJNZ $-5 |
||
54 | DEC B |
||
181 | savelij | 55 | JR RDBYT03 ; не дождались, грузим стандартную прошивку |
35 | savelij | 56 | |
181 | savelij | 57 | RDBYT02 IN A,(ZXCMD) ; забрали байт из порта команд |
58 | LD C,A ; сохранили для проверки |
||
59 | IN A,(ZXDATRD) ; забрали байт из порта данных |
||
60 | CP C ; сравнили |
||
61 | JR NZ,RDBYT03 ; если не совпадают, грузим стандартную прошивку |
||
62 | RDBYT_DBG CP 0xAA ; это 0xAA? |
||
63 | RDBYT03 EX AF,AF' ; временно спрятали флаги процессора |
||
35 | savelij | 64 | LD HL,GRUZILA |
65 | LD DE,RAMCOD |
||
66 | LD BC,RAMCEND-VERLOAD |
||
181 | savelij | 67 | LDIR ; перенесли основной код в адрес работы |
68 | OUT (CLRCBIT),A ; сбросили команд бит |
||
69 | EX AF,AF' ; вернули спрятанные флаги |
||
70 | JP Z,GRUZIM2 ; если все условия совпали, запускаем загрузчик |
||
71 | JP GRUZIM0 ; иначе грузим стандартную прошивку из пзу |
||
35 | savelij | 72 | |
73 | GRUZILA |
||
69 | savelij | 74 | PHASE RAMCOD |
35 | savelij | 75 | |
76 | VERLOAD DB "Loader" |
||
105 | savelij | 77 | DW DATA_VERS |
35 | savelij | 78 | |
181 | savelij | 79 | ; путь до файла прошивки GS |
69 | savelij | 80 | F_PATH DB "NEOGS.ROM",0 |
35 | savelij | 81 | |
69 | savelij | 82 | UPDATENAME DB "NGS_ROM.UPD",0 |
83 | |||
35 | savelij | 84 | TXT1 DB "not found",0 |
85 | TXT1E |
||
86 | TXT2 DB "beta",0 |
||
87 | TXT2E |
||
69 | savelij | 88 | TXT3 DB 0;"stable",0 |
35 | savelij | 89 | TXT3E |
90 | |||
181 | savelij | 91 | GRUZIM0 CALL RROMSD ; загружаем и запускаем прошивку с SD карты, если она там есть |
92 | JP GS105 ; иначе загружаем прошивку из пзу и запускаем |
||
35 | savelij | 93 | |
181 | savelij | 94 | GRUZIM2 LD A,0x11 ; конфигурим НГС |
112 | savelij | 95 | LD (NGS_MODES),A |
181 | savelij | 96 | OUT (GSCFG0),A ; отрубаем пзу и врубаем частоту 12МГЦ |
35 | savelij | 97 | XOR A |
181 | savelij | 98 | OUT (MPAG),A ; включаем страницу 0 |
99 | GRUZIM IN A,(ZXSTAT) ; постоянно ждем команд от спека |
||
35 | savelij | 100 | RRA |
78 | savelij | 101 | JR NC,GRUZIM |
181 | savelij | 102 | IN A,(ZXCMD) ; поймали команду |
103 | CP 0x1D ; это команда проверки? |
||
35 | savelij | 104 | JR NZ,GRUZIM1 |
181 | savelij | 105 | LD A,0x76 |
106 | OUT (ZXDATWR),A ; отдаем байт идентификации загрузчика |
||
35 | savelij | 107 | OUT (CLRCBIT),A |
181 | savelij | 108 | JR GRUZIM ; и продолжаем ждать команд |
35 | savelij | 109 | |
181 | savelij | 110 | GRUZIM1 CP 0xF3 |
111 | JP Z,GS105 ; при поступлении команд 0xF3 и |
||
112 | CP 0xF4 |
||
113 | JP Z,GS105 ; 0xF4 загружаем и запускаем прошивку из пзу |
||
35 | savelij | 114 | CP LOW (FLOADE-FLOADER)/2+1 |
181 | savelij | 115 | JP NC,GS105 ; аналогично не команда загрузчика переходим на основное пзу |
35 | savelij | 116 | ADD A,A |
117 | LD L,A |
||
118 | LD H,0 |
||
119 | LD DE,GRUZIM2 |
||
181 | savelij | 120 | PUSH DE ; на стеке адрес возврата после исполнения команды |
35 | savelij | 121 | LD DE,FLOADER |
122 | ADD HL,DE |
||
123 | LD E,(HL) |
||
124 | INC HL |
||
181 | savelij | 125 | LD D,(HL) ; забрали адрес исполнения команды |
35 | savelij | 126 | EX DE,HL |
181 | savelij | 127 | JP (HL) ; поехали на исполнение |
35 | savelij | 128 | |
181 | savelij | 129 | FLOADER DW LOADROM ; 00 загрузка rom со спека вместо скопированной из ROM |
130 | DW JPLDROM ; 01 запуск загруженной прошивки |
||
131 | DW GS105 ; 02 копирование из ROM и запуск |
||
132 | DW RROMSD ; 03 загрузка и запуск ROM с SD карты |
||
133 | DW LOADCOD ; 04 загрузка кода со спека |
||
134 | DW LDINSD ; 05 загрузка файла с SD карты |
||
135 | DW RUNCOD ; 06 запуск кода с любого адреса и в любой странице |
||
136 | DW STATSD ; 07 статус загруженного файла |
||
137 | DW VERPAGE ; 08 версия в текстовом виде для указанной страницы |
||
138 | DW GET_CRC ; 09 получить CRC16 |
||
139 | DW LOADUPDATE ; 0A загрузка файла с обновлением |
||
140 | DW SET_FREQ ; 0B установка частоты процессора |
||
35 | savelij | 141 | FLOADE |
142 | |||
181 | savelij | 143 | SET_FREQ IN A,(ZXDATRD) ; приняли номер частоты |
112 | savelij | 144 | BIT 7,A |
145 | JR NZ,SET_FREQ2 |
||
181 | savelij | 146 | OUT (CLRCBIT),A ; сбросили команд бит |
112 | savelij | 147 | AND 3 |
181 | savelij | 148 | LD L,C_10MHZ ; установка частоты 10 МГЦ |
112 | savelij | 149 | JR Z,SET_FREQ1 |
150 | DEC A |
||
181 | savelij | 151 | LD L,C_12MHZ ; установка частоты 12 МГЦ |
112 | savelij | 152 | JR Z,SET_FREQ1 |
153 | DEC A |
||
181 | savelij | 154 | LD L,C_20MHZ ; установка частоты 20 МГЦ |
112 | savelij | 155 | JR Z,SET_FREQ1 |
181 | savelij | 156 | LD L,C_24MHZ ; установка частоты 24 МГЦ |
112 | savelij | 157 | SET_FREQ1 LD A,(NGS_MODES) |
158 | AND %11001111 |
||
159 | OR L |
||
160 | LD (NGS_MODES),A |
||
161 | OUT (GSCFG0),A |
||
162 | RET |
||
163 | |||
164 | SET_FREQ2 LD A,(NGS_MODES) |
||
181 | savelij | 165 | AND 0x30 |
112 | savelij | 166 | RRCA |
167 | RRCA |
||
168 | RRCA |
||
169 | RRCA |
||
170 | OUT (CLRCBIT),A |
||
171 | OUT (ZXDATWR),A |
||
172 | JP WDN |
||
173 | |||
181 | savelij | 174 | ; передача на спек версии в текстовом виде |
175 | VERPAGE IN A,(ZXDATRD) ; забрали байт номера запрошенной страницы пзу |
||
176 | AND 7 ; старшие 5 бит в игноре |
||
177 | EX AF,AF' ; временно спрятали флаги проца |
||
178 | LD A,0x30 |
||
179 | OUT (GSCFG0),A ; включили 10 МГЦ и вернули пзу |
||
180 | EX AF,AF' ; вернули флаги |
||
181 | ADD A,A ; нам нужна вторые 32К страницы пзу |
||
182 | ; AND A ; выбрана страница 0? |
||
183 | ; JR NZ,VERPAG1 ; если нет, то идем на извлечение последних 8 байт |
||
184 | ; LD HL,VERLOAD ; для загрузчика берем из другого адреса |
||
69 | savelij | 185 | ; LD DE,RAMCEND |
186 | ; LD BC,8 |
||
187 | ; PUSH DE |
||
188 | ; LDIR |
||
189 | ; POP DE |
||
181 | savelij | 190 | ; JR VERPAG2 ; пошли на переводчик в текстовый вид |
35 | savelij | 191 | |
192 | VERPAG1 INC A |
||
181 | savelij | 193 | OUT (MPAG),A ; включили последние 16К выбранной страницы пзу |
194 | LD HL,0xFFF8 |
||
35 | savelij | 195 | LD BC,8 |
196 | LD DE,RAMCEND |
||
197 | PUSH DE |
||
181 | savelij | 198 | LDIR ; перенесли 8 байт из хвоста пзу |
35 | savelij | 199 | POP DE |
181 | savelij | 200 | VERPAG2 LD A,0x11 |
201 | OUT (GSCFG0),A ; отрубили пзу и вернули 12МГЦ |
||
35 | savelij | 202 | XOR A |
181 | savelij | 203 | OUT (MPAG),A ; вернули страницу 0 озу |
204 | LD B,8 ; проверям перенесенные 8 байт, а не 0xFF ли там? |
||
35 | savelij | 205 | LD A,(DE) |
206 | INC DE |
||
207 | INC A |
||
181 | savelij | 208 | JR NZ,VFPGA1 ; не 0xFF, продолжаем |
35 | savelij | 209 | DJNZ $-5 |
181 | savelij | 210 | DEC SP ; таки все 8 байт 0xFF, версии у пзу страницы нету |
35 | savelij | 211 | DEC SP |
212 | POP DE |
||
213 | LD HL,TXT1 |
||
214 | LD BC,TXT1E-TXT1 |
||
181 | savelij | 215 | LDIR ; отдать текст об этом |
35 | savelij | 216 | JR VFPGA0 |
217 | |||
218 | VFPGA1 DEC SP |
||
219 | DEC SP |
||
220 | POP DE |
||
181 | savelij | 221 | CALL UNVERS ; распаковка полученных 8 байт в текст |
222 | VFPGA0 OUT (CLRCBIT),A ; сбросили команд бит |
||
35 | savelij | 223 | LD HL,RAMCEND |
224 | LD BC,ZXDATWR |
||
69 | savelij | 225 | VFPGA2 LD A,(HL) |
35 | savelij | 226 | OUTI |
69 | savelij | 227 | EX AF,AF' |
35 | savelij | 228 | CALL WDN |
69 | savelij | 229 | EX AF,AF' |
35 | savelij | 230 | AND A |
181 | savelij | 231 | JR NZ,VFPGA2 ; отдаем текст версии пока не встретится байт 0, который тоже отдаем |
35 | savelij | 232 | RET |
233 | |||
181 | savelij | 234 | ; распаковщик даты |
35 | savelij | 235 | UNVERS LD HL,6 |
181 | savelij | 236 | ADD HL,DE ; пропустили 6 байт текста версии |
237 | LD C,(HL) ; забрали младший байт версии |
||
238 | LD (HL)," " ; на его место пробел |
||
35 | savelij | 239 | INC HL |
181 | savelij | 240 | LD B,(HL) ; забрали старший байт |
241 | LD A,C ; взяли младший байт версии |
||
242 | AND 0x1F ; нас интересуют младшие 5 бит (день месяца) |
||
243 | JR NZ,.L1 |
||
244 | RES 7,B ; если получился 0, возможно это бета версия |
||
245 | .L1 CP 32 |
||
246 | JR C,.L2 ; в месяце не может быть более 31 дня |
||
247 | RES 7,B ; иначе это бета версия |
||
248 | .L2 CALL A2TXT ; переводим полученное число в текст |
||
249 | SRL B ; сдинули версию на 1 бит влево чтобы номер месяца |
||
250 | RR C ; оказался в одном байте |
||
251 | LD A,C ; забрали этот байт |
||
35 | savelij | 252 | RRCA |
253 | RRCA |
||
254 | RRCA |
||
181 | savelij | 255 | RRCA ; сдвинули нужные биты в младшие разрады байта |
256 | AND 0x0F ; оставили нужные 4 бита (номер месяца) |
||
257 | JR NZ,.L3 ; номер месяца неможет быть 0 |
||
258 | RES 6,B ; иначе это бета версия |
||
259 | .L3 CP 13 ; и номер месяца не может быть больше 12 |
||
260 | JR C,.L4 |
||
261 | RES 6,B ; иначе бета версия |
||
262 | .L4 LD (HL),"." ; отделили номер дня месяца точкой |
||
35 | savelij | 263 | INC HL |
181 | savelij | 264 | CALL A2TXT ; конвертировали номер месяца |
265 | LD (HL),"." ; так же отделили точкой |
||
35 | savelij | 266 | INC HL |
181 | savelij | 267 | LD A,B ; взяли оставшиеся биты |
268 | AND 0x3F ; нам нужны 6 бит номера года |
||
269 | CALL A2TXT ; конвертнули в текст |
||
270 | BIT 6,B ; бета или стабл версия? |
||
271 | JR NZ,.L5 |
||
272 | LD DE,TXT2 ; все-таки бета, о чем и добавляем текст к версии |
||
35 | savelij | 273 | LD BC,TXT2E-TXT2 |
181 | savelij | 274 | JR .L6 |
35 | savelij | 275 | |
181 | savelij | 276 | .L5 LD DE,TXT3 ; версия стабл |
35 | savelij | 277 | LD BC,TXT3E-TXT3 |
181 | savelij | 278 | .L6 LD (HL)," " ; перед текстом (бета или стабл) вставляем пробел |
35 | savelij | 279 | INC HL |
280 | EX DE,HL |
||
181 | savelij | 281 | LDIR ; перетащили текст |
35 | savelij | 282 | EX DE,HL |
181 | savelij | 283 | LD (HL),0 ; завершили строку нулем |
35 | savelij | 284 | RET |
285 | |||
181 | savelij | 286 | ; перевод "A" в десятичный вид и в текст. для чисел от 0 до 99 |
287 | A2TXT PUSH HL ; сохранили адрес куда ложить сконверченное |
||
35 | savelij | 288 | LD L,A |
289 | LD H,0 |
||
290 | LD DE,10 |
||
291 | XOR A |
||
292 | DEC A |
||
181 | savelij | 293 | .L1 INC A |
35 | savelij | 294 | SBC HL,DE |
181 | savelij | 295 | JR NC,.L1 ; считаем количество десятков в числе |
296 | ADD HL,DE ; вернули перебор вычитания |
||
297 | ADD A,"0" ; перевели в тесктовый вид полученное число |
||
298 | LD D,A ; пока сохранили |
||
299 | LD A,L ; взяли оставшиеся единицы числа |
||
300 | ADD A,"0" ; конвертули в текст |
||
301 | POP HL ; вернули адрес куда ложить |
||
302 | LD (HL),D ; положили десятки заданного числа |
||
35 | savelij | 303 | INC HL |
181 | savelij | 304 | LD (HL),A ; положили единицы того же числа |
35 | savelij | 305 | INC HL |
306 | RET |
||
307 | |||
181 | savelij | 308 | ; загрузка с SD карты по указанному пути |
309 | ; первый байт-номер страницы озу куда начинать грузить |
||
310 | ; далее байты текстовой строка пути и имени файла |
||
311 | ; конец строки байт 0, он же стоп байт |
||
312 | LDINSD LD BC,ZXDATRD ; адрес порта данных |
||
313 | LD HL,RAMCEND ; адрес куда строку пути складировать |
||
35 | savelij | 314 | PUSH HL |
181 | savelij | 315 | IN A,(C) ; приняли номер страницы откуда начинать загрузку |
316 | OUT (CLRCBIT),A ; сбросили команд бит |
||
69 | savelij | 317 | EX AF,AF' |
318 | LDINSD1 CALL WDY |
||
35 | savelij | 319 | IN A,(C) |
320 | LD (HL),A |
||
321 | INC HL |
||
322 | AND A |
||
181 | savelij | 323 | JR NZ,LDINSD1 ; принимаем строку пока не встретится байт 0 |
69 | savelij | 324 | EX AF,AF' |
35 | savelij | 325 | POP HL |
181 | savelij | 326 | JP LOAD_SD ; далее запускаем загрузку с SD карты |
35 | savelij | 327 | |
181 | savelij | 328 | ; загрузка файла с обновлениями |
329 | LOADUPDATE LD HL,UPDATENAME ; имя файла обновления |
||
330 | LD A,2 ; грузить начиная со 2 страницы |
||
69 | savelij | 331 | OUT (CLRCBIT),A |
332 | JP LOAD_SD |
||
333 | |||
181 | savelij | 334 | ; статус загрузки файла с SD карты |
35 | savelij | 335 | STATSD LD A,(STATUS) |
336 | OUT (ZXDATWR),A |
||
337 | OUT (CLRCBIT),A |
||
338 | RET |
||
339 | |||
181 | savelij | 340 | ; загрузка и запуск прошивки с SD карты |
341 | ; имя, путь и адрес фиксирован |
||
342 | RROMSD LD HL,F_PATH ; адрес строки фиксированного пути для загрузки |
||
35 | savelij | 343 | XOR A |
181 | savelij | 344 | CALL LOAD_SD ; загружаем |
35 | savelij | 345 | AND A |
181 | savelij | 346 | RET NZ ; если ошибка, то грузим из пзу |
35 | savelij | 347 | JP JPLDROM |
348 | |||
181 | savelij | 349 | ; запуск кода в любой странице |
350 | ; 0 - номер страницы озу |
||
351 | ; 1 - младший байт адреса запуска |
||
352 | ; 2 - старший байт адреса запуска |
||
353 | RUNCOD LD BC,ZXDATRD ; адрес порта данных |
||
354 | IN A,(C) ; приняли номер страницы озу |
||
355 | OUT (CLRCBIT),A ; сбросили команд бит |
||
35 | savelij | 356 | OUT (MPAG),A |
357 | CALL WDY |
||
181 | savelij | 358 | IN L,(C) ; приняли младший байт адреса запуска |
35 | savelij | 359 | CALL WDY |
181 | savelij | 360 | IN H,(C) ; приняли старший байт адреса запуска |
361 | JP (HL) ; запускаем |
||
35 | savelij | 362 | |
181 | savelij | 363 | ; 0 - номер страницы озу |
364 | ; 1 - младший байт длины загрузки |
||
365 | ; 2 - старший байт длины загрузки |
||
366 | ; загрузка не более 32КБ |
||
367 | LOADCOD LD BC,ZXDATRD ; адрес порта данных |
||
368 | LD HL,0x8000 ; адрес начала зaгрузки |
||
369 | IN A,(C) ; приняли номер страницы озу |
||
370 | OUT (CLRCBIT),A ; сбросили команд бит |
||
371 | OUT (MPAG),A ; включили заданную страницу озу |
||
35 | savelij | 372 | CALL WDY |
181 | savelij | 373 | IN E,(C) ; приняли младший байт длины загрузки |
35 | savelij | 374 | CALL WDY |
181 | savelij | 375 | IN D,(C) ; приняли старший байт длины загрузки |
35 | savelij | 376 | LOADCO1 CALL WDY |
377 | INI |
||
378 | LD A,H |
||
379 | AND A |
||
181 | savelij | 380 | RET Z ; если озу кончилось, выходим |
35 | savelij | 381 | DEC DE |
382 | LD A,D |
||
383 | OR E |
||
181 | savelij | 384 | JR NZ,LOADCO1 ; грузим скока указано |
35 | savelij | 385 | RET |
386 | |||
181 | savelij | 387 | ; загрузка прошивки 32КБ со спека |
35 | savelij | 388 | LOADROM XOR A |
181 | savelij | 389 | OUT (MPAG),A ; включаем страницу |
390 | LD HL,0x8000 ; адрес загрузки |
||
391 | OUT (CLRCBIT),A ; сброс команд бита |
||
392 | LD BC,ZXDATRD ; адрес порта данных |
||
112 | savelij | 393 | LOADROM1 CALL WDY |
35 | savelij | 394 | INI |
395 | LD A,H |
||
396 | AND A |
||
181 | savelij | 397 | JR NZ,LOADROM1 ; грузим пока память не кончится |
35 | savelij | 398 | RET |
399 | |||
181 | savelij | 400 | ; грузилка стандартной прошивки из ROM |
401 | GS105 LD HL,STRPAG ; адрес куда переносить |
||
402 | LD A,4 ; переносить 4 куска по 8 килобайт |
||
403 | MOV1 EX AF,AF' ; прячем счетчик |
||
404 | LD A,0x30 |
||
405 | OUT (GSCFG0),A ; включили пзу |
||
35 | savelij | 406 | LD A,2 |
181 | savelij | 407 | OUT (MPAG),A ; страницу 2 со стандартной прошивкой |
35 | savelij | 408 | PUSH HL |
409 | LD DE,RAM8KB |
||
181 | savelij | 410 | LD BC,0x2000 |
411 | LDIR ; перенесли в буфер 8 килобайт |
||
412 | LD A,0x31 |
||
413 | OUT (GSCFG0),A ; переключили пзу |
||
35 | savelij | 414 | XOR A |
181 | savelij | 415 | OUT (MPAG),A ; включили страницу 0 озу |
35 | savelij | 416 | POP DE |
417 | LD HL,RAM8KB |
||
181 | savelij | 418 | LD BC,0x2000 |
419 | LDIR ; перенесли из буфера 8 килобайт |
||
35 | savelij | 420 | EX DE,HL |
69 | savelij | 421 | EX AF,AF' |
35 | savelij | 422 | DEC A |
181 | savelij | 423 | JR NZ,MOV1 ; и так 4 раза |
35 | savelij | 424 | |
181 | savelij | 425 | ; запуск загруженной прошивки |
35 | savelij | 426 | JPLDROM XOR A |
181 | savelij | 427 | OUT (MPAG),A ; включили страницу 0 озу |
428 | ; LD A,0x13 ; включили частоту 12МГЦ, отключили пзу и защитили озу от записи |
||
429 | ; LD A,0x23 ; включили частоту 20МГЦ, отключили пзу и защитили озу от записи |
||
430 | LD A,3+FREQUENCY ; включили указанную частоту, отключили пзу и защитили озу от записи |
||
105 | savelij | 431 | OUT (GSCFG0),A |
181 | savelij | 432 | JP 0 ; стартуем стандартную прошивку |
35 | savelij | 433 | |
181 | savelij | 434 | ; ждем пока спек даст байт |
35 | savelij | 435 | WDY IN A,(ZXSTAT) |
436 | RLA |
||
437 | JR NC,WDY |
||
438 | RET |
||
439 | |||
181 | savelij | 440 | ; ждем пока спек заберет байт из порта |
35 | savelij | 441 | WDN IN A,(ZXSTAT) |
442 | RLA |
||
443 | JR C,WDN |
||
444 | RET |
||
445 | |||
181 | savelij | 446 | ; подсчет CRC16 |
35 | savelij | 447 | GET_CRC LD A,2 |
448 | OUT (MPAG),A |
||
449 | DEC A |
||
450 | OUT (GSCFG0),A |
||
181 | savelij | 451 | LD HL,(0x8000) |
35 | savelij | 452 | SRL H |
453 | RR L |
||
454 | SRL H |
||
455 | RR L |
||
456 | SRL H |
||
457 | RR L |
||
458 | SRL H |
||
459 | RR L |
||
69 | savelij | 460 | LD A,L |
461 | LD IYH,A |
||
181 | savelij | 462 | ; LD IX,0x8000 |
69 | savelij | 463 | ; LD C,(IX+0) |
464 | ; LD B,(IX+1) |
||
465 | ; CALL CRC16 |
||
466 | ; LD C,(IX+0) |
||
467 | ; LD B,(IX+1) |
||
181 | savelij | 468 | ; LD A,0x81 |
69 | savelij | 469 | ; AND A |
470 | ; SBC HL,BC |
||
181 | savelij | 471 | ; JR NZ,OUT_ERR ; CRC16 заголовка ERROR |
472 | LD IX,0x8000+8-0x10 |
||
473 | SCHET LD DE,0x10 |
||
474 | ADD IX,DE ; в IX адрес выбранного блока |
||
35 | savelij | 475 | LD C,(IX+4) |
181 | savelij | 476 | LD B,(IX+5) ; в BC длина блока |
35 | savelij | 477 | LD E,(IX+1) |
478 | LD L,(IX+2) |
||
479 | LD H,(IX+3) |
||
480 | LD A,L |
||
181 | savelij | 481 | AND 0x7F |
482 | LD D,A ; в DE смещение в странице |
||
35 | savelij | 483 | ADD HL,HL |
484 | LD A,2 |
||
485 | ADD A,H |
||
69 | savelij | 486 | LD IYL,A |
181 | savelij | 487 | OUT (MPAG),A ; номер страницы |
35 | savelij | 488 | PUSH IX |
181 | savelij | 489 | LD IX,0x8000 |
490 | ADD IX,DE ; в IX адрес начала блока |
||
35 | savelij | 491 | CALL CRC16 |
492 | POP IX |
||
493 | LD C,(IX+6) |
||
494 | LD B,(IX+7) |
||
181 | savelij | 495 | LD A,0x82 |
35 | savelij | 496 | AND A |
497 | SBC HL,BC |
||
498 | JR NZ,OUT_ERR |
||
69 | savelij | 499 | DEC IYH |
500 | JR NZ,SCHET |
||
181 | savelij | 501 | ERR_OK LD A,0x80 |
35 | savelij | 502 | |
181 | savelij | 503 | ; CRC16 ERROR |
504 | ; 0x80 - CRC16 блока ok |
||
505 | ; 0x81 - CRC16 заголовка error |
||
506 | ; 0x82 - CRC16 блока ERROR |
||
35 | savelij | 507 | OUT_ERR OUT (CLRCBIT),A |
508 | OUT (ZXDATWR),A |
||
509 | CALL WDN |
||
510 | LD A,L |
||
511 | OUT (ZXDATWR),A |
||
512 | CALL WDN |
||
513 | LD A,H |
||
514 | OUT (ZXDATWR),A |
||
515 | RET |
||
516 | |||
181 | savelij | 517 | CRC16 LD HL,0xFFFF |
518 | LD DE,0x1021 |
||
35 | savelij | 519 | CRC_0 LD A,(IX) |
520 | INC IX |
||
69 | savelij | 521 | EX AF,AF' |
522 | LD A,IXL |
||
523 | OR IXH |
||
35 | savelij | 524 | JR NZ,CRC_3 |
69 | savelij | 525 | INC IYL |
526 | LD A,IYL |
||
35 | savelij | 527 | OUT (MPAG),A |
181 | savelij | 528 | LD IX,0x8000 |
69 | savelij | 529 | CRC_3 EX AF,AF' |
35 | savelij | 530 | XOR H |
531 | LD H,A |
||
532 | LD A,8 |
||
533 | CRC_1 ADD HL,HL |
||
534 | JR NC,CRC_2 |
||
69 | savelij | 535 | EX AF,AF' |
35 | savelij | 536 | LD A,L |
537 | XOR E |
||
538 | LD L,A |
||
539 | LD A,H |
||
540 | XOR D |
||
541 | LD H,A |
||
69 | savelij | 542 | EX AF,AF' |
35 | savelij | 543 | CRC_2 DEC A |
544 | JR NZ,CRC_1 |
||
545 | DEC BC |
||
546 | LD A,B |
||
547 | OR C |
||
548 | JR NZ,CRC_0 |
||
69 | savelij | 549 | LD A,2 |
550 | OUT (MPAG),A |
||
35 | savelij | 551 | RET |
552 | |||
553 | ;--------------------------------- |
||
181 | savelij | 554 | ; грузилка файла по указанному пути |
35 | savelij | 555 | |
181 | savelij | 556 | INIT_VAR 0x5000 |
557 | SETVAR BUF_512, 0x200 ; буфер сектора |
||
558 | SETVAR TDIRCLS, 0x400 ; буфер кластеров ROOT директории |
||
559 | SETVAR CAL_FAT, BYTE ; калибр FAT |
||
560 | SETVAR BYTSSEC, BYTE ; количество секторов в кластере |
||
561 | SETVAR ROOTCLS, DWORD ; кластер начала ROOT директории |
||
562 | SETVAR ROOTSEC, WORD ; размер в секторах ROOT директории |
||
563 | SETVAR SEC_FAT, DWORD ; количество секторов одной FAT |
||
564 | SETVAR RSVDSEC, WORD ; размер резервной области |
||
565 | SETVAR STARTRZ, DWORD ; начало диска/раздела |
||
566 | SETVAR FRSTDAT, DWORD ; адрес первого сектора данных от BPB |
||
567 | SETVAR SEC_DSC, DWORD ; количество секторов на диске/разделе |
||
568 | SETVAR CLS_DSC, DWORD ; количество кластеров на диске/разделе |
||
569 | SETVAR FATSTR, DWORD ; начало первой FAT таблицы |
||
570 | SETVAR ADRPATH, WORD ; адрес текста пути файла |
||
571 | SETVAR STATUS, BYTE ; статус после вызова LOAD_SD |
||
572 | SETVAR OLD_SP, WORD ; стек для выхода |
||
573 | SETVAR FB_EXT, 0x0B ; буфер 8.3 для поиска имени |
||
574 | SETVAR LVL_DIR, BYTE ; номер уровня директории |
||
575 | SETVAR LSTLOAD, DWORD ; номер сектора загруженного в буфер |
||
576 | SETVAR NGS_MODES, BYTE ; текущий установленный режим |
||
35 | savelij | 577 | |
181 | savelij | 578 | ; SD карта не найдена |
579 | ZAW003 LD A,0xEE |
||
35 | savelij | 580 | WR_STAT LD SP,(OLD_SP) |
581 | LD (STATUS),A |
||
582 | RET |
||
583 | |||
181 | savelij | 584 | ; загрузка файла |
585 | ; на входе: A - страница начала загрузки |
||
586 | ; HL - адрес текстовой строки |
||
587 | ; пути к файлу вместе с именем и расширением файла. путь полностью от ROOT |
||
588 | ; загружается файл по размеру дополненому до полных секторов (сектор 512 байт) |
||
589 | ; пример: размер файла =0x80-после дополнения будет загружен 1 сектор |
||
590 | ; =0x401 - будет загружено 3 сектора |
||
591 | ; на выходе: A = |
||
592 | ; 0x00 - файл загружен |
||
593 | ; 0xAA - файл не найден |
||
594 | ; 0xDD - FAT не обнаружен |
||
595 | ; 0xEE - SD карта не обнаружена |
||
596 | LOAD_SD LD IYL,A ; сохранили номер страницы куда грузить |
||
597 | LD (ADRPATH),HL ; сохранили адрес строки пути |
||
598 | LD (OLD_SP),SP ; сохранили стек |
||
599 | LD A,0xFF |
||
600 | LD (LSTLOAD+3),A ; принудительная загрузка сектора без проверки |
||
35 | savelij | 601 | LD A,1 |
181 | savelij | 602 | OUT (GSCFG0),A ; отключили пзу, все страница озу |
603 | LD A,M_SDNCS+M_SNCLR;%10011011 |
||
604 | OUT (SCTRL),A ; сконфигурили нгс с CS=1 для SD карты |
||
605 | LD B,0x10 |
||
606 | .L1 LD A,0xFF |
||
607 | OUT (SD_SEND),A ; пишем 0x80 байт 0xFF в порт карточки |
||
608 | DJNZ .L1 |
||
609 | XOR A ; 256 попыток найти SD карту |
||
69 | savelij | 610 | EX AF,AF' |
181 | savelij | 611 | LD A,M_SDNCS |
612 | OUT (SCTRL),A ; выбрали SD карту CS=0 |
||
613 | .L2 LD HL,CMD00 |
||
614 | CALL OUTCOM ; переводим карточку в режим SPI командой 0 |
||
615 | CALL IN_OOUT ; ждем ответа |
||
69 | savelij | 616 | EX AF,AF' |
35 | savelij | 617 | DEC A |
181 | savelij | 618 | JR Z,ZAW003 ; ждем по счептчику 256 раз |
69 | savelij | 619 | EX AF,AF' |
35 | savelij | 620 | DEC A |
181 | savelij | 621 | JR NZ,.L2 ; ждем пока карта ответит байтом 1 |
35 | savelij | 622 | LD BC,SD_RSTR |
623 | LD HL,CMD08 |
||
181 | savelij | 624 | CALL OUTCOM ; определяем спецификацию карты |
625 | CALL IN_OOUT ; в "A" ответ карты R1 |
||
35 | savelij | 626 | IN H,(C) |
627 | NOP |
||
628 | IN H,(C) |
||
629 | NOP |
||
630 | IN H,(C) |
||
631 | NOP |
||
181 | savelij | 632 | IN H,(C) ; прочитали остальные байты в никуда |
633 | BIT 2,A ; если ошибка, то |
||
634 | LD HL,0 ; карта спецификации 1.0 |
||
635 | JR NZ,.L3 ; иначе |
||
636 | LD H,0x40 ; карта спецификации 2.0 |
||
637 | .L3 LD A,CMD_55 |
||
638 | CALL OUT_COM ; запускаем внутреннюю инициализацию карты |
||
35 | savelij | 639 | CALL IN_OOUT |
181 | savelij | 640 | in (c) ;in f,(c) |
641 | in (c) ;in f,(c) |
||
35 | savelij | 642 | LD BC,SD_SEND |
643 | LD A,ACMD_41 |
||
644 | OUT (C),A |
||
645 | LD A,H |
||
646 | OUT (C),A |
||
647 | XOR A |
||
648 | OUT (C),A |
||
649 | NOP |
||
650 | OUT (C),A |
||
651 | NOP |
||
652 | OUT (C),A |
||
653 | DEC A |
||
654 | OUT (C),A |
||
655 | CALL IN_OOUT |
||
656 | AND A |
||
181 | savelij | 657 | JR NZ,.L3 ; ждем пока карты перейдет в режим готовности |
658 | .L4 LD A,CMD_59 |
||
659 | CALL OUT_COM ; принудительно отключаем CRC16 |
||
35 | savelij | 660 | CALL IN_OOUT |
661 | AND A |
||
181 | savelij | 662 | JR NZ,.L4 |
663 | .L5 LD HL,CMD16 |
||
664 | CALL OUTCOM ; принудительный размер сектора 512 байт |
||
35 | savelij | 665 | CALL IN_OOUT |
666 | AND A |
||
181 | savelij | 667 | JR NZ,.L5 |
35 | savelij | 668 | |
181 | savelij | 669 | ; инициализация переменных FAT |
35 | savelij | 670 | WC_FAT LD DE,0 |
671 | LD B,D |
||
672 | LD C,E |
||
181 | savelij | 673 | CALL LOADLST ; читаем сектор 0 карточки |
35 | savelij | 674 | PUSH HL |
675 | POP IX |
||
181 | savelij | 676 | LD DE,0x01BE |
677 | ADD HL,DE ; переходим на смещение для проверок |
||
678 | LD A,(HL) ; проверям чтобы был 0, карточки не могут быть загрузочными |
||
35 | savelij | 679 | AND A |
181 | savelij | 680 | JR NZ,.L2 ; если не 0, проверить другое |
35 | savelij | 681 | LD DE,4 |
181 | savelij | 682 | ADD HL,DE ; переходим к проверке типа раздела |
35 | savelij | 683 | LD A,(HL) |
684 | LD B,0 |
||
181 | savelij | 685 | CP 1 ; FAT12? |
686 | JR Z,.L1 |
||
35 | savelij | 687 | LD B,2 |
181 | savelij | 688 | CP 0x0B ; FAT32? |
689 | JR Z,.L1 |
||
690 | CP 0x0C ; FAT32? |
||
691 | JR Z,.L1 |
||
35 | savelij | 692 | LD B,1 |
181 | savelij | 693 | CP 6 ; FAT16? |
694 | JR Z,.L1 |
||
695 | CP 4 ; FAT16? |
||
696 | JR Z,.L1 |
||
697 | CP 0x0E ; FAT16? |
||
698 | JR NZ,.L2 |
||
699 | .L1 LD A,B ; берем из "B" тип раздела |
||
700 | LD (CAL_FAT),A ; сохранили |
||
35 | savelij | 701 | ADD HL,DE |
181 | savelij | 702 | CALL LOADZP ; берем номер сектора начала основного раздела |
703 | JR .R1 ; переходим к инициализации переменных для работы с фатом |
||
35 | savelij | 704 | |
181 | savelij | 705 | ; MBR не обнаружен, проверяем сектор 0 карты как описатель |
706 | .L2 LD C,(IX+0x0D) ; C = количество секторов в кластере |
||
35 | savelij | 707 | XOR A |
708 | LD E,A |
||
709 | LD B,8 |
||
181 | savelij | 710 | .L3 RR C |
35 | savelij | 711 | ADC A,0 |
181 | savelij | 712 | DJNZ .L3 ; количество секторов в кластере должно быть степенью 2 |
35 | savelij | 713 | DEC A |
181 | savelij | 714 | JR NZ,.L4 ; проверили количество бит |
715 | INC E ; +1, есть такое |
||
716 | .L4 LD A,(IX+0x0E) |
||
717 | OR (IX+0x0F) |
||
718 | JR Z,.L5 ; количество зарезервированных секторов должно быть >0 |
||
719 | INC E ; +1, есть такое |
||
720 | .L5 LD A,(IX+0x13) |
||
721 | OR (IX+0x14) |
||
722 | JR NZ,.L6 ; количество секторов на разделе для ФАТ16? |
||
35 | savelij | 723 | INC E |
181 | savelij | 724 | .L6 LD A,(IX+0x20) |
725 | OR (IX+0x21) |
||
726 | OR (IX+0x22) |
||
727 | OR (IX+0x23) |
||
728 | JR NZ,.L7 ; количество секторов на разделе для ФАТ32? |
||
729 | INC E ; од но из них должно быть =0, другое >0 |
||
730 | .L7 LD A,(IX+0x15) |
||
731 | AND 0xF0 |
||
732 | CP 0xF0 |
||
733 | JR NZ,.L8 ; старшие биты должны быть в 1 |
||
35 | savelij | 734 | INC E |
181 | savelij | 735 | .L8 LD A,E |
736 | CP 4 ; условия совпали? |
||
737 | LD A,0xDD ; FAT не найден |
||
35 | savelij | 738 | JP NZ,WR_STAT |
181 | savelij | 739 | LD A,0xFF |
740 | LD (CAL_FAT),A ; тип фат пока не определен |
||
35 | savelij | 741 | LD DE,0 |
742 | LD B,D |
||
743 | LD C,E |
||
744 | |||
181 | savelij | 745 | .R1 LD (STARTRZ),DE |
746 | LD (STARTRZ+2),BC ; положили номер стартового сектора раздела |
||
747 | CALL LOADLST ; загрузили его |
||
35 | savelij | 748 | LD HL,0 |
181 | savelij | 749 | LD DE,(BUF_512+0x16) ; BPB_FATSZ16 |
35 | savelij | 750 | LD A,D |
751 | OR E |
||
181 | savelij | 752 | JR NZ,.R2 ; если не FAT12/16 (BPB_FATSZ16=0) |
753 | LD DE,(BUF_512+0x24) |
||
754 | LD HL,(BUF_512+0x26) ; BPB_FATSZ32 |
||
755 | ; то берем из смещения +36 |
||
756 | .R2 LD (SEC_FAT+2),HL |
||
757 | LD (SEC_FAT),DE ; число секторов на FAT-таблицу |
||
35 | savelij | 758 | LD HL,0 |
181 | savelij | 759 | LD DE,(BUF_512+0x13) ; BPB_TOTSEC16 |
35 | savelij | 760 | LD A,D |
761 | OR E |
||
181 | savelij | 762 | JR NZ,.R3 ; если не FAT12/16 (BPB_TOTSEC16=0) |
763 | LD DE,(BUF_512+0x20) |
||
764 | LD HL,(BUF_512+0x22) ; BPB_TOTSEC32 |
||
765 | ; то берем из смещения +32 |
||
766 | .R3 LD (SEC_DSC+2),HL |
||
767 | LD (SEC_DSC),DE ; к-во секторов на диске/разделе |
||
35 | savelij | 768 | |
181 | savelij | 769 | ; вычисляем ROOTDIRSECTORS |
770 | LD BC,(BUF_512+0x0B) ; BPB_BYTSPERSEC |
||
771 | LD DE,(BUF_512+0x11) ; BPB_ROOTENTCNT |
||
35 | savelij | 772 | LD HL,0 |
773 | LD A,D |
||
774 | OR E |
||
181 | savelij | 775 | JR Z,.R4 |
35 | savelij | 776 | LD B,H |
777 | LD C,L |
||
181 | savelij | 778 | LD A,0x10 |
35 | savelij | 779 | CALL BCDE_A |
780 | EX DE,HL |
||
781 | |||
181 | savelij | 782 | ; это реализована формула |
783 | ; ROOTDIRSECTORS = ((BPB_ROOTENTCNT*32) + (BPB_BYTSPERSEC-1)) / BPB_BYTSPERSEC |
||
784 | ; В HL=ROOTDIRSECTORS. если FAT32, то HL=0 всегда |
||
35 | savelij | 785 | |
181 | savelij | 786 | .R4 PUSH HL ; ROOTDIRSECTORS |
35 | savelij | 787 | LD (ROOTSEC),HL |
181 | savelij | 788 | LD A,(BUF_512+0x10) |
35 | savelij | 789 | LD DE,(SEC_FAT) |
790 | LD HL,(SEC_FAT+2) |
||
791 | DEC A |
||
181 | savelij | 792 | .R5 EX DE,HL |
35 | savelij | 793 | ADD HL,HL |
794 | EX DE,HL |
||
795 | ADC HL,HL |
||
796 | DEC A |
||
181 | savelij | 797 | JR NZ,.R5 |
798 | POP BC ; полный размер FAT-области в секторах |
||
799 | CALL HLDEPBC ; прибавили ROOTDIRSECTORS |
||
800 | LD BC,(BUF_512+0x0E) ; BPB_RSVDSECCNT |
||
35 | savelij | 801 | LD (RSVDSEC),BC |
181 | savelij | 802 | CALL HLDEPBC ; прибавили BPB_RESVDSECCNT |
35 | savelij | 803 | LD (FRSTDAT),DE |
181 | savelij | 804 | LD (FRSTDAT+2),HL ; положили номер первого сектора данных |
35 | savelij | 805 | LD B,H |
806 | LD C,L |
||
181 | savelij | 807 | LD HL,SEC_DSC ; BCDE + 32-ое число по адресу HL |
808 | CALL BCDEHLM ; вычли из полного к-ва секторов раздела |
||
809 | LD A,(BUF_512+0x0D) |
||
35 | savelij | 810 | LD (BYTSSEC),A |
181 | savelij | 811 | CALL BCDE_A ; разделили на к-во секторов в кластере |
35 | savelij | 812 | LD (CLS_DSC),DE |
181 | savelij | 813 | LD (CLS_DSC+2),BC ; положили кол-во кластеров на разделе |
35 | savelij | 814 | |
112 | savelij | 815 | LD A,(CAL_FAT) |
181 | savelij | 816 | CP 0xFF |
817 | JR NZ,.R6 |
||
818 | ; определение типа FAT при отсуствии MBR |
||
112 | savelij | 819 | LD DE,(SEC_FAT-1) |
820 | LD BC,(SEC_FAT+1) |
||
181 | savelij | 821 | LD E,0 ; BCDE = количество секторов *0x100 |
112 | savelij | 822 | PUSH BC |
181 | savelij | 823 | PUSH DE ; сохранили |
112 | savelij | 824 | SRL B |
825 | RR C |
||
826 | RR D |
||
181 | savelij | 827 | RR E ; BCDE = количество секторов *0x80 |
828 | LD HL,CLS_DSC ; количество кластеров на FAT |
||
829 | PUSH HL ; сохранили |
||
830 | CALL HLBCDEM ; количество кластеров-(количество секторов*0x80) |
||
112 | savelij | 831 | LD A,E |
181 | savelij | 832 | AND 0x80 ; количество менее 128 кластеров в секторе для FAT32 |
112 | savelij | 833 | OR D |
834 | OR C |
||
835 | OR B |
||
836 | LD A,2 |
||
837 | POP HL |
||
838 | POP DE |
||
839 | POP BC |
||
181 | savelij | 840 | JR Z,.R6 ; FAT32 если флаг Z=0 |
841 | CALL HLBCDEM ; количество кластеров-(количество секторов*0x100) |
||
112 | savelij | 842 | LD A,D |
843 | OR C |
||
844 | OR B |
||
35 | savelij | 845 | LD A,1 |
181 | savelij | 846 | JR Z,.R6 ; FAT16 если флаг Z=0 |
847 | XOR A ; иначе FAT12 |
||
35 | savelij | 848 | |
181 | savelij | 849 | ; для FAT12/16 вычисляем адрес первого сектора директории |
850 | ; для FAT32 берем по смещемию +44, на выходе BCDE - сектор ROOTDIR |
||
851 | .R6 LD (CAL_FAT),A ; уточнили тип фата |
||
112 | savelij | 852 | EX AF,AF' |
35 | savelij | 853 | LD DE,(RSVDSEC) |
854 | LD BC,0 |
||
855 | LD HL,STARTRZ |
||
856 | CALL BCDEHLP |
||
857 | LD (FATSTR),DE |
||
181 | savelij | 858 | LD (FATSTR+2),BC ; вычислили и положили номер сектора начала FAT-таблиц |
112 | savelij | 859 | EX AF,AF' |
35 | savelij | 860 | AND A |
861 | LD DE,0 |
||
862 | LD B,D |
||
863 | LD C,E |
||
181 | savelij | 864 | JR Z,.F1 ; FAT12 - none |
35 | savelij | 865 | DEC A |
181 | savelij | 866 | JR Z,.F1 ; FAT16 |
867 | LD DE,(BUF_512+0x2C) |
||
868 | LD BC,(BUF_512+0x2E) ; FAT32 |
||
869 | .F1 LD (ROOTCLS),DE |
||
870 | LD (ROOTCLS+2),BC ; положили номер кластер ROOT директории |
||
35 | savelij | 871 | |
112 | savelij | 872 | XOR A |
181 | savelij | 873 | LD (LVL_DIR),A ; начинаем с ROOT директории |
874 | LD HL,(ADRPATH) ; вернули адрес строки пути до файла |
||
875 | .F6 PUSH BC |
||
876 | PUSH DE ; сохранили номер кластера |
||
877 | CALL FNDBUF ; распаковка части текстовой строки для создания маски поиска |
||
35 | savelij | 878 | POP DE |
181 | savelij | 879 | POP BC ; восстановили номер кластера |
880 | PUSH HL ; сохранили текущий адрес текстовой строки |
||
35 | savelij | 881 | |
181 | savelij | 882 | LD HL,TDIRCLS ; адрес таблицы кластеров текущей директории |
35 | savelij | 883 | LD A,D |
884 | OR E |
||
885 | OR B |
||
886 | OR C |
||
181 | savelij | 887 | CALL SAVEZP ; сохранили в таблицу номер текущего кластера |
888 | JR Z,.F3 ; если номер кластера 0, то это ROOT дира (для ФАТ12/16) |
||
889 | .F2 PUSH HL |
||
890 | CALL RDFATZP ; читаем следущий номер кластера из цепочки директории |
||
891 | CALL LST_CLS ; проверяем на конец цепочки |
||
35 | savelij | 892 | POP HL |
181 | savelij | 893 | JR C,.F3 |
894 | CALL SAVEZP ; если непоследний сохраняем в таблицу |
||
895 | JR .F2 ; следующий номер кластера |
||
35 | savelij | 896 | |
181 | savelij | 897 | .F3 LD BC,0xFFFF |
898 | CALL SAVEZP ; кладем маркер конца цепочки |
||
112 | savelij | 899 | EXX |
900 | LD HL,LVL_DIR |
||
181 | savelij | 901 | LD A,(HL) ; текущий уровень директории |
902 | INC (HL) ; следующий уровень директории |
||
112 | savelij | 903 | AND A |
181 | savelij | 904 | LD BC,0 ; количество записей ROOT директории |
905 | JR NZ,.F4 |
||
112 | savelij | 906 | LD A,(CAL_FAT) |
907 | CP 2 |
||
181 | savelij | 908 | JR NC,.F4 |
909 | LD HL,(ROOTSEC) ; уже не ROOT директория |
||
112 | savelij | 910 | ADD HL,HL |
911 | ADD HL,HL |
||
912 | ADD HL,HL |
||
913 | ADD HL,HL |
||
914 | ADD HL,HL |
||
915 | LD B,H |
||
916 | LD C,L |
||
181 | savelij | 917 | .F4 EXX |
35 | savelij | 918 | |
181 | savelij | 919 | .F5 INC BC ; ищем по заданной маске начиная с 0 |
920 | CALL RDDIRSC ; грузим по номеру описателя сектор директории |
||
35 | savelij | 921 | LD A,C |
181 | savelij | 922 | AND 0x0F ; в секторе максимум 16 описателей |
35 | savelij | 923 | LD E,A |
924 | LD D,0 |
||
925 | EX DE,HL |
||
926 | ADD HL,HL |
||
927 | ADD HL,HL |
||
928 | ADD HL,HL |
||
929 | ADD HL,HL |
||
930 | ADD HL,HL |
||
181 | savelij | 931 | ADD HL,DE ; получили адрес нужного описателя |
112 | savelij | 932 | EXX |
933 | DEC BC |
||
934 | LD A,B |
||
935 | OR C |
||
936 | EXX |
||
181 | savelij | 937 | LD A,0xAA |
112 | savelij | 938 | JP Z,WR_STAT |
181 | savelij | 939 | LD A,(HL) ; проверяем первый байт имени описателя |
35 | savelij | 940 | AND A |
181 | savelij | 941 | LD A,0xAA ; если байт =0, то |
942 | JP Z,WR_STAT ; переход по ошибке = файл не найден |
||
35 | savelij | 943 | PUSH HL |
944 | PUSH BC |
||
181 | savelij | 945 | CALL COMPARE ; сравниваем с заданной маской |
35 | savelij | 946 | POP BC |
947 | POP DE |
||
948 | PUSH DE |
||
181 | savelij | 949 | POP IX ; содержимое IX = адрес описателя |
950 | JR NZ,.F5 ; не совпадает, переходим к следующему описателю |
||
951 | CALL RD_CLAS ; забираем номер кластера из найденного описателя |
||
952 | EX (SP),HL ; восстановили текущий адрес в строке пути до файла |
||
35 | savelij | 953 | INC SP |
181 | savelij | 954 | INC SP ; маскировка на стеке адреса размера в байтах текущего файла |
35 | savelij | 955 | LD A,(HL) |
181 | savelij | 956 | AND A ; текстовая строка кончилась? |
957 | JR NZ,.F6 ; если нет, то ищем дальше |
||
958 | LD A,(IX+0x0B) ; проверяем это дира или файл? |
||
959 | AND 0x10 |
||
960 | LD A,0xAA ; если дира, то ошибка |
||
961 | JP NZ,WR_STAT ; текстовая строка должна указывать на файл |
||
35 | savelij | 962 | DEC SP |
963 | DEC SP |
||
181 | savelij | 964 | POP HL ; восстановили в HL адрес откуда взять размер файла в байтах |
35 | savelij | 965 | PUSH BC |
966 | PUSH DE |
||
181 | savelij | 967 | CALL LOADZP ; забираем размер файла (в байтах) |
35 | savelij | 968 | LD A,E |
969 | AND A |
||
181 | savelij | 970 | JR Z,.F8 ; младший байт размера файла =0? |
971 | INC D ; увеличиваем размер на 256 байт без учета младшего байта |
||
972 | .F8 BIT 0,D ; проверяем чет/нечет |
||
973 | JR Z,.F9 ; если нечет, то |
||
974 | INC D ; увеличиваем размер еще на 256 байт |
||
975 | .F9 CALL BCDE200 ; делим на 512 (на размер сектор) |
||
35 | savelij | 976 | PUSH DE |
977 | EXX |
||
978 | POP HL |
||
979 | EXX |
||
181 | savelij | 980 | LD A,(BYTSSEC) ; взяли размер кластера в секторах |
981 | LD IXH,A ; сохранили |
||
35 | savelij | 982 | POP DE |
983 | POP BC |
||
181 | savelij | 984 | LD HL,0x8000 ; адрес загрузки |
35 | savelij | 985 | |
181 | savelij | 986 | ; HX - размер кластера |
987 | ; HL' - кол-во секторов файла |
||
988 | ; BCDE - номер стартового кластера |
||
989 | ; LY - стартовая страница загрузки |
||
35 | savelij | 990 | |
181 | savelij | 991 | LD A,IYL ; восстановили страницу загрузки |
35 | savelij | 992 | AND A |
181 | savelij | 993 | JR NZ,CP_PAGE ; проверка для загрузки в страницу 0 |
994 | OUT (MPAG),A ; включаем страницу 0 |
||
35 | savelij | 995 | EXX |
996 | LD A,L |
||
181 | savelij | 997 | LD DE,0x41 |
35 | savelij | 998 | SBC HL,DE |
181 | savelij | 999 | JR C,.F7 ; если файл 0x41 и более секторов |
1000 | LD A,0x40 ; то грузим только 0x40 первых секторов |
||
1001 | .F7 EXX |
||
1002 | JP LDMINI ; переходим на загрузку |
||
35 | savelij | 1003 | |
181 | savelij | 1004 | ; загрузка в страницу 1 запрещена |
35 | savelij | 1005 | CP_PAGE DEC A |
181 | savelij | 1006 | LD A,0xAA |
35 | savelij | 1007 | JP Z,WR_STAT |
112 | savelij | 1008 | LD A,IYL |
35 | savelij | 1009 | |
181 | savelij | 1010 | ; включаем страницу загрузки |
1011 | LDFILE0 OUT (MPAG),A ; включаем заданную страницу для загрузки |
||
35 | savelij | 1012 | |
181 | savelij | 1013 | ; загрузка в страницы 02...7F |
35 | savelij | 1014 | LD_FILE EXX |
112 | savelij | 1015 | LD E,IXH |
181 | savelij | 1016 | LD D,0 ; DE = размер кластера в секторах |
35 | savelij | 1017 | AND A |
181 | savelij | 1018 | SBC HL,DE ; сверяем с количеством секторов для загрузки |
1019 | LD IXL,IXH ; LX = количество секторов для загрузки |
||
35 | savelij | 1020 | EXX |
181 | savelij | 1021 | JR NC,.L1 |
1022 | EXX ; секторов для загрузки меньше размера кластера |
||
35 | savelij | 1023 | ADD HL,DE |
1024 | LD A,L |
||
181 | savelij | 1025 | LD IXL,A ; LX = количество секторов для загрузки |
35 | savelij | 1026 | EXX |
1027 | |||
181 | savelij | 1028 | .L1 PUSH BC |
35 | savelij | 1029 | PUSH DE |
1030 | PUSH HL |
||
181 | savelij | 1031 | CALL REALSEC ; перевели номер кластера в номер реального сектора |
112 | savelij | 1032 | LD A,IXL |
181 | savelij | 1033 | CP 0x41 ; количество секторов для загрузки больше 0x40? |
1034 | JR C,.L2 |
||
1035 | LD A,0x40 ; будем грузить 0x40 секторов |
||
1036 | .L2 POP HL |
||
112 | savelij | 1037 | LD IYH,A |
181 | savelij | 1038 | CALL RDMULTI ; загружаем сектора |
112 | savelij | 1039 | LD A,IXH |
181 | savelij | 1040 | AND 0x80 |
1041 | JR Z,.L5 |
||
112 | savelij | 1042 | LD A,IXL |
1043 | SUB IYH |
||
181 | savelij | 1044 | JR Z,.L3 |
1045 | JR C,.L3 |
||
1046 | LD HL,0x40 |
||
35 | savelij | 1047 | ADD HL,DE |
1048 | EX DE,HL |
||
1049 | LD HL,0 |
||
1050 | ADC HL,BC |
||
1051 | LD B,H |
||
1052 | LD C,L |
||
1053 | LD L,A |
||
112 | savelij | 1054 | INC IYL |
1055 | LD A,IYL |
||
181 | savelij | 1056 | CP 0x40 |
1057 | JR C,.L4 |
||
1058 | .L3 INC SP |
||
35 | savelij | 1059 | INC SP |
1060 | INC SP |
||
1061 | INC SP |
||
1062 | JR LDEFILE |
||
1063 | |||
181 | savelij | 1064 | .L4 OUT (MPAG),A ; следующая страница |
35 | savelij | 1065 | LD A,L |
181 | savelij | 1066 | LD HL,0x8000 |
35 | savelij | 1067 | CALL RDMULTI |
181 | savelij | 1068 | .L5 POP DE |
35 | savelij | 1069 | POP BC |
1070 | PUSH HL |
||
1071 | CALL RDFATZP |
||
1072 | CALL LST_CLS |
||
1073 | POP HL |
||
38 | savelij | 1074 | JR C,LDEFILE |
112 | savelij | 1075 | LD A,IXL |
1076 | CP IXH |
||
35 | savelij | 1077 | JR C,LDEFILE |
1078 | LD A,H |
||
1079 | AND A |
||
1080 | JR NZ,LD_FILE |
||
181 | savelij | 1081 | LD HL,0x8000 |
112 | savelij | 1082 | INC IYL |
1083 | LD A,IYL |
||
181 | savelij | 1084 | CP 0x40 |
35 | savelij | 1085 | JR C,LDFILE0 |
1086 | LDEFILE XOR A |
||
1087 | JP WR_STAT |
||
1088 | |||
1089 | LDMINI EXX |
||
1090 | LD L,A |
||
112 | savelij | 1091 | LD A,IXH |
35 | savelij | 1092 | LD H,A |
1093 | CP L |
||
1094 | JR C,$+3 |
||
1095 | LD A,L |
||
1096 | EXX |
||
1097 | PUSH BC |
||
1098 | PUSH DE |
||
1099 | PUSH AF |
||
1100 | PUSH HL |
||
1101 | CALL REALSEC |
||
1102 | POP HL |
||
1103 | POP AF |
||
1104 | CALL RDMULTI |
||
1105 | POP DE |
||
1106 | POP BC |
||
1107 | LD A,H |
||
1108 | AND A |
||
1109 | RET Z |
||
1110 | PUSH HL |
||
1111 | CALL RDFATZP |
||
1112 | CALL LST_CLS |
||
1113 | POP HL |
||
38 | savelij | 1114 | JR C,LDEFILE |
35 | savelij | 1115 | EXX |
1116 | LD A,L |
||
1117 | SUB H |
||
1118 | EXX |
||
1119 | JR NC,LDMINI |
||
1120 | JR LDEFILE |
||
1121 | |||
1122 | SAVEZP LD (HL),E |
||
1123 | INC HL |
||
1124 | LD (HL),D |
||
1125 | INC HL |
||
1126 | LD (HL),C |
||
1127 | INC HL |
||
1128 | LD (HL),B |
||
1129 | INC HL |
||
1130 | RET |
||
1131 | |||
1132 | LOADZP LD E,(HL) |
||
1133 | INC HL |
||
1134 | LD D,(HL) |
||
1135 | INC HL |
||
1136 | LD C,(HL) |
||
1137 | INC HL |
||
1138 | LD B,(HL) |
||
1139 | INC HL |
||
1140 | RET |
||
1141 | |||
181 | savelij | 1142 | ; чтение сектора DIR по номеру BC |
35 | savelij | 1143 | RDDIRSC PUSH BC |
1144 | LD D,B |
||
1145 | LD E,C |
||
1146 | LD BC,0 |
||
181 | savelij | 1147 | LD A,0x10 |
35 | savelij | 1148 | CALL BCDE_A |
1149 | LD A,E |
||
1150 | PUSH AF |
||
1151 | LD A,(BYTSSEC) |
||
1152 | PUSH AF |
||
1153 | CALL BCDE_A |
||
1154 | LD HL,TDIRCLS |
||
1155 | EX DE,HL |
||
1156 | ADD HL,HL |
||
1157 | ADD HL,HL |
||
1158 | ADD HL,DE |
||
1159 | CALL LOADZP |
||
1160 | CALL REALSEC |
||
1161 | POP AF |
||
1162 | DEC A |
||
1163 | LD L,A |
||
1164 | POP AF |
||
1165 | AND L |
||
1166 | LD L,A |
||
1167 | LD H,0 |
||
1168 | ADD HL,DE |
||
1169 | EX DE,HL |
||
1170 | LD HL,0 |
||
1171 | ADC HL,BC |
||
1172 | LD B,H |
||
1173 | LD C,L |
||
1174 | CALL LOADLST |
||
1175 | POP BC |
||
1176 | RET |
||
1177 | |||
181 | savelij | 1178 | ; проверка на последний кластер в цепочке |
1179 | LST_CLS LD A,(CAL_FAT) ; зависит от разрядности фата |
||
35 | savelij | 1180 | AND A |
1181 | JR NZ,LST_CL1 |
||
181 | savelij | 1182 | LD HL,0x0FF7 ; проверка для ФАТ12 |
35 | savelij | 1183 | SBC HL,DE |
1184 | RET |
||
1185 | |||
1186 | LST_CL1 DEC A |
||
1187 | JR NZ,LST_CL2 |
||
181 | savelij | 1188 | LST_CL3 LD HL,0xFFF7 ; проверкам для ФАТ16 и младших бит ФАТ32 |
35 | savelij | 1189 | SBC HL,DE |
1190 | RET |
||
1191 | |||
181 | savelij | 1192 | LST_CL2 LD HL,0x0FFF ; проверка для старших бит ФАТ32 |
35 | savelij | 1193 | SBC HL,BC |
1194 | RET NZ |
||
1195 | JR LST_CL3 |
||
1196 | |||
181 | savelij | 1197 | ; чтение следующего номера кластера в цепочке |
1198 | RDFATZP LD A,(CAL_FAT) ; чтение зависит от разрадности фата |
||
35 | savelij | 1199 | AND A |
181 | savelij | 1200 | JR Z,RDFATS0 ; переход вперед для ФАТ12 |
35 | savelij | 1201 | DEC A |
181 | savelij | 1202 | JR Z,RDFATS1 ; переход вперед для ФАТ16 |
1203 | EX DE,HL ; здесь чтение для ФАТ32 |
||
35 | savelij | 1204 | ADD HL,HL |
1205 | EX DE,HL |
||
1206 | LD HL,0 |
||
1207 | ADC HL,BC |
||
181 | savelij | 1208 | ADC HL,BC ; умножили номер кластера на 2 |
35 | savelij | 1209 | LD A,E |
1210 | LD E,D |
||
1211 | LD D,L |
||
1212 | LD C,H |
||
181 | savelij | 1213 | LD B,0 ; разделили номер кластера на 256 |
1214 | CALL RDFATS2 ; читаем младшие 16 бит используя чтение для ФАТ16 |
||
35 | savelij | 1215 | INC HL |
1216 | LD C,(HL) |
||
1217 | INC HL |
||
181 | savelij | 1218 | LD B,(HL) ; прочитали последующие старшие 16 бит |
35 | savelij | 1219 | RET |
1220 | |||
181 | savelij | 1221 | ; чтение 16 битного номера кластера из цепочки для ФАТ16 |
35 | savelij | 1222 | RDFATS1 LD BC,0 |
1223 | LD A,E |
||
1224 | LD E,D |
||
181 | savelij | 1225 | LD D,C ; разделили номер кластера на 256, старшие 16 бит =0 |
1226 | RDFATS2 PUSH AF ; общее чтение 16 битного номера кластера для ФАТ16/32 |
||
35 | savelij | 1227 | PUSH BC |
1228 | LD HL,FATSTR |
||
181 | savelij | 1229 | CALL BCDEHLP ; прибавили смещение от начала фат таблицы |
1230 | CALL LOADLST ; загрузили вычисленный номер сектора |
||
35 | savelij | 1231 | POP BC |
1232 | POP AF |
||
1233 | LD E,A |
||
1234 | LD D,0 |
||
1235 | ADD HL,DE |
||
181 | savelij | 1236 | ADD HL,DE ; вычислили смещение до нужного номера в загруженном секторе |
35 | savelij | 1237 | LD E,(HL) |
1238 | INC HL |
||
181 | savelij | 1239 | LD D,(HL) ; получили 16 бит номера кластера |
35 | savelij | 1240 | RET |
1241 | |||
181 | savelij | 1242 | ; чтение 12 битного номера кластера из цепочки для ФАТ12 |
35 | savelij | 1243 | RDFATS0 LD H,D |
1244 | LD L,E |
||
1245 | ADD HL,HL |
||
181 | savelij | 1246 | ADD HL,DE ; HL = HL * 3 |
35 | savelij | 1247 | SRL H |
181 | savelij | 1248 | RR L ; HL = HL / 2 - в итоге умножили номер кластера на 1,5 |
1249 | LD A,E ; A - нам интересен только бит номер старого номера кластера |
||
35 | savelij | 1250 | LD E,H |
1251 | LD D,0 |
||
1252 | LD B,D |
||
181 | savelij | 1253 | LD C,D ; разделили номер кластера на 256 |
35 | savelij | 1254 | SRL E |
1255 | PUSH AF |
||
1256 | PUSH HL |
||
1257 | LD HL,FATSTR |
||
181 | savelij | 1258 | CALL BCDEHLP ; прибавили смещение от начала фат таблицы |
1259 | CALL LOADLST ; загрузили вывчисленный сектор |
||
35 | savelij | 1260 | POP BC |
1261 | LD A,B |
||
1262 | AND 1 |
||
181 | savelij | 1263 | LD B,A ; BC = смещение в загруженном секторе |
1264 | ADD HL,BC ; HL = адрес откуда читать байты номера кластера |
||
1265 | LD B,(HL) ; прочитали младшую часть номера кластера |
||
1266 | INC HL ; адрес следующего байта |
||
35 | savelij | 1267 | LD A,H |
181 | savelij | 1268 | CP HIGH (BUF_512)+2 ; проверка на переход границы загруженного сектора |
35 | savelij | 1269 | JR NZ,RDFATS4 |
181 | savelij | 1270 | PUSH BC ; выход за пределы текущего загруженного сектора |
35 | savelij | 1271 | LD BC,0 |
1272 | INC DE |
||
181 | savelij | 1273 | CALL LOADLST ; загружаем следующий сектор фат таблицы |
35 | savelij | 1274 | POP BC |
1275 | RDFATS4 POP AF |
||
181 | savelij | 1276 | LD D,(HL) ; читаем старшие биты номера кластера |
1277 | LD E,B ; теперь DE = номер следующего кластера в цепочке |
||
35 | savelij | 1278 | LD BC,0 |
181 | savelij | 1279 | RRA ; проверяем бит 0 старого номера кластера |
35 | savelij | 1280 | JR NC,RDFATS3 |
181 | savelij | 1281 | SRL D ; сдвигаем номер прочитанного номера кластера в младшие 12 бит |
35 | savelij | 1282 | RR E |
1283 | SRL D |
||
1284 | RR E |
||
1285 | SRL D |
||
1286 | RR E |
||
1287 | SRL D |
||
1288 | RR E |
||
1289 | RDFATS3 LD A,D |
||
181 | savelij | 1290 | AND 0x0F |
1291 | LD D,A ; сбросили незначащие старшие 4 бита у полученного номера кластера |
||
35 | savelij | 1292 | RET |
1293 | |||
181 | savelij | 1294 | ; вычисление реального сектора |
1295 | ; на входе BCDE = номер кластера FAT |
||
1296 | ; на выходе BCDE = номер реального сектора |
||
35 | savelij | 1297 | REALSEC LD A,B |
1298 | OR C |
||
1299 | OR D |
||
1300 | OR E |
||
181 | savelij | 1301 | JR NZ,REALSE1 ; BCDE = 0? |
1302 | LD HL,SEC_FAT ; это root директория у ФАТ12/16 |
||
1303 | LD DE,(FATSTR) ; местоположение ROOT диры сразу после фат таблицы |
||
35 | savelij | 1304 | LD BC,(FATSTR+2) |
1305 | PUSH HL |
||
181 | savelij | 1306 | CALL BCDEHLP ; прибавили к началу фат таблицы ее размер |
35 | savelij | 1307 | POP HL |
181 | savelij | 1308 | JP BCDEHLP ; прибавили еще раз и получили номер сектора начала ROOT диры |
35 | savelij | 1309 | |
181 | savelij | 1310 | REALSE1 LD HL,0xFFFE |
35 | savelij | 1311 | EX DE,HL |
1312 | ADD HL,DE |
||
1313 | EX DE,HL |
||
1314 | INC HL |
||
181 | savelij | 1315 | ADC HL,BC ; HLDE = номер кластера - 2 |
1316 | LD A,(BYTSSEC) ; нужно умножить на размер кластера |
||
35 | savelij | 1317 | JR REALSE2 |
1318 | |||
1319 | REALSE3 SLA E |
||
1320 | RL D |
||
1321 | RL L |
||
1322 | RL H |
||
1323 | REALSE2 RRCA |
||
181 | savelij | 1324 | JR NC,REALSE3 ; умножили на размер кластера |
35 | savelij | 1325 | LD B,H |
1326 | LD C,L |
||
1327 | LD HL,STARTRZ |
||
181 | savelij | 1328 | CALL BCDEHLP ; прибавили смещение от начала диска |
35 | savelij | 1329 | LD HL,FRSTDAT |
181 | savelij | 1330 | JP BCDEHLP ; прибавили смещение от начала раздела |
35 | savelij | 1331 | |
181 | savelij | 1332 | ; BCDE = BCDE / 512 |
35 | savelij | 1333 | BCDE200 LD E,D |
1334 | LD D,C |
||
1335 | LD C,B |
||
1336 | LD B,0 |
||
1337 | LD A,2 |
||
1338 | JR BCDE_A |
||
1339 | |||
181 | savelij | 1340 | ; BCDE = BCDE >> A |
35 | savelij | 1341 | BCDE_A1 SRL B |
1342 | RR C |
||
1343 | RR D |
||
1344 | RR E |
||
1345 | BCDE_A RRCA |
||
1346 | JR NC,BCDE_A1 |
||
1347 | RET |
||
1348 | |||
181 | savelij | 1349 | ; BCDE = (ADR) - BCDE |
35 | savelij | 1350 | BCDEHLM LD A,(HL) |
1351 | INC HL |
||
1352 | SUB E |
||
1353 | LD E,A |
||
1354 | LD A,(HL) |
||
1355 | INC HL |
||
1356 | SBC A,D |
||
1357 | LD D,A |
||
1358 | LD A,(HL) |
||
1359 | INC HL |
||
1360 | SBC A,C |
||
1361 | LD C,A |
||
1362 | LD A,(HL) |
||
1363 | SBC A,B |
||
1364 | LD B,A |
||
1365 | RET |
||
1366 | |||
181 | savelij | 1367 | ; BCDE = (ADR) + BCDE |
35 | savelij | 1368 | BCDEHLP LD A,(HL) |
1369 | INC HL |
||
1370 | ADD A,E |
||
1371 | LD E,A |
||
1372 | LD A,(HL) |
||
1373 | INC HL |
||
1374 | ADC A,D |
||
1375 | LD D,A |
||
1376 | LD A,(HL) |
||
1377 | INC HL |
||
1378 | ADC A,C |
||
1379 | LD C,A |
||
1380 | LD A,(HL) |
||
1381 | ADC A,B |
||
1382 | LD B,A |
||
1383 | RET |
||
1384 | |||
181 | savelij | 1385 | ; HLDE = HLDE + BC |
35 | savelij | 1386 | HLDEPBC EX DE,HL |
1387 | ADD HL,BC |
||
1388 | EX DE,HL |
||
1389 | LD BC,0 |
||
1390 | ADC HL,BC |
||
1391 | RET |
||
1392 | |||
181 | savelij | 1393 | ; BCDE = BCDE - (ADR) |
112 | savelij | 1394 | HLBCDEM LD A,E |
1395 | SUB (HL) |
||
1396 | INC HL |
||
1397 | LD E,A |
||
1398 | LD A,D |
||
1399 | SBC A,(HL) |
||
1400 | INC HL |
||
1401 | LD D,A |
||
1402 | LD A,C |
||
1403 | SBC A,(HL) |
||
1404 | INC HL |
||
1405 | LD C,A |
||
1406 | LD A,B |
||
1407 | SBC A,(HL) |
||
1408 | LD B,A |
||
35 | savelij | 1409 | RET |
1410 | |||
181 | savelij | 1411 | ; грузилка одного сектора |
112 | savelij | 1412 | LOADLST CALL CPNUMSC |
1413 | JR NZ,LOADLST1 |
||
1414 | LD HL,BUF_512 |
||
1415 | RET |
||
1416 | |||
181 | savelij | 1417 | LOADLST1 LD HL,BUF_512 ; адрес буфера сектора |
1418 | LD A,1 ; грузить 1 сектор |
||
35 | savelij | 1419 | PUSH HL |
181 | savelij | 1420 | CALL RDMULTI ; загрузили сектор |
1421 | POP HL ; на выходе HL=адрес начала буфера загруженного сектора |
||
35 | savelij | 1422 | RET |
1423 | |||
181 | savelij | 1424 | ; проверка на уже загруженный сектор |
112 | savelij | 1425 | CPNUMSC LD HL,LSTLOAD |
1426 | LD A,(HL) |
||
1427 | INC HL |
||
1428 | CP E |
||
1429 | RET NZ |
||
1430 | LD A,(HL) |
||
1431 | INC HL |
||
1432 | CP D |
||
1433 | RET NZ |
||
1434 | LD A,(HL) |
||
1435 | INC HL |
||
1436 | CP C |
||
1437 | RET NZ |
||
1438 | LD A,(HL) |
||
1439 | CP B |
||
1440 | RET |
||
1441 | |||
181 | savelij | 1442 | ; подача команды в SD карту без параметров |
35 | savelij | 1443 | OUTCOM PUSH BC |
181 | savelij | 1444 | LD BC,0x0600+SD_SEND ; выдать в порт 6 байт |
35 | savelij | 1445 | OTIR |
1446 | POP BC |
||
1447 | RET |
||
1448 | |||
181 | savelij | 1449 | ; выдача в порт SD карты команды с параметром 0 |
35 | savelij | 1450 | OUT_COM PUSH BC |
1451 | LD BC,SD_SEND |
||
181 | savelij | 1452 | in (c) ;in f,(c) |
1453 | in (c) ;in f,(c) |
||
1454 | OUT (C),A ; отправили код команды |
||
35 | savelij | 1455 | XOR A |
181 | savelij | 1456 | OUT (C),A ; биты 31-24 параметра |
35 | savelij | 1457 | NOP |
181 | savelij | 1458 | OUT (C),A ; биты 23-16 параметра |
35 | savelij | 1459 | NOP |
181 | savelij | 1460 | OUT (C),A ; биты 15-8 параметра |
35 | savelij | 1461 | NOP |
181 | savelij | 1462 | OUT (C),A ; биты 7-0 параметра |
35 | savelij | 1463 | DEC A |
181 | savelij | 1464 | OUT (C),A ; без CRC16 |
35 | savelij | 1465 | POP BC |
1466 | RET |
||
1467 | |||
1468 | SECM200 PUSH HL |
||
1469 | PUSH BC |
||
1470 | LD A,CMD_58 |
||
181 | savelij | 1471 | LD BC,SD_RSTR |
35 | savelij | 1472 | CALL OUT_COM |
1473 | CALL IN_OOUT |
||
1474 | IN H,(C) |
||
1475 | NOP |
||
1476 | IN A,(C) |
||
1477 | NOP |
||
1478 | IN A,(C) |
||
1479 | NOP |
||
1480 | IN A,(C) |
||
1481 | BIT 6,H |
||
1482 | POP HL |
||
181 | savelij | 1483 | JR NZ,.L1 |
35 | savelij | 1484 | EX DE,HL |
1485 | ADD HL,HL |
||
1486 | EX DE,HL |
||
1487 | ADC HL,HL |
||
1488 | LD H,L |
||
1489 | LD L,D |
||
1490 | LD D,E |
||
1491 | LD E,0 |
||
181 | savelij | 1492 | .L1 LD A,CMD_18 |
35 | savelij | 1493 | LD C,SD_SEND |
181 | savelij | 1494 | in (c) ;in f,(c) |
1495 | in (c) ;in f,(c) |
||
35 | savelij | 1496 | OUT (C),A |
1497 | NOP |
||
1498 | OUT (C),H |
||
1499 | NOP |
||
1500 | OUT (C),L |
||
1501 | NOP |
||
1502 | OUT (C),D |
||
1503 | NOP |
||
1504 | OUT (C),E |
||
181 | savelij | 1505 | LD A,0xFF |
35 | savelij | 1506 | OUT (C),A |
1507 | POP HL |
||
1508 | RET |
||
1509 | |||
1510 | IN_OOUT EXX |
||
181 | savelij | 1511 | LD DE,0x30FF |
1512 | .L1 IN A,(SD_RSTR) |
||
35 | savelij | 1513 | CP E |
181 | savelij | 1514 | JR NZ,.L2 |
1515 | DEC D |
||
1516 | JR NZ,.L1 |
||
1517 | .L2 EXX |
||
35 | savelij | 1518 | RET |
1519 | |||
181 | savelij | 1520 | CMD00 DB 0x40,0x00,0x00,0x00,0x00,0x95;GO_IDLE_STATE |
1521 | CMD08 DB 0x48,0x00,0x00,0x01,0xAA,0x87;SEND_IF_COND |
||
1522 | CMD16 DB 0x50,0x00,0x00,0x02,0x00,0xFF;SET_BLOCKEN |
||
35 | savelij | 1523 | |
181 | savelij | 1524 | ; много секторное чтение с SD карты |
69 | savelij | 1525 | RDMULTI EX AF,AF' |
35 | savelij | 1526 | CALL SECM200 |
69 | savelij | 1527 | EX AF,AF' |
35 | savelij | 1528 | LD BC,SD_RSTR |
181 | savelij | 1529 | .L1 EX AF,AF' |
1530 | .L2 CALL IN_OOUT |
||
1531 | CP 0xFE |
||
1532 | JR NZ,.L2 |
||
35 | savelij | 1533 | INIR |
1534 | NOP |
||
1535 | INIR |
||
1536 | NOP |
||
1537 | IN A,(C) |
||
1538 | NOP |
||
1539 | IN A,(C) |
||
69 | savelij | 1540 | EX AF,AF' |
35 | savelij | 1541 | DEC A |
181 | savelij | 1542 | JR NZ,.L1 |
35 | savelij | 1543 | LD A,CMD_12 |
1544 | CALL OUT_COM |
||
181 | savelij | 1545 | .L3 CALL IN_OOUT |
35 | savelij | 1546 | INC A |
181 | savelij | 1547 | JR NZ,.L3 |
35 | savelij | 1548 | RET |
1549 | |||
181 | savelij | 1550 | ; выборка номера кластера из файлового описателя |
35 | savelij | 1551 | RD_CLAS EX DE,HL |
181 | savelij | 1552 | LD DE,0x14 ; старшие 16 бит читаем из смещения +20 |
35 | savelij | 1553 | ADD HL,DE |
1554 | LD C,(HL) |
||
1555 | INC HL |
||
1556 | LD B,(HL) |
||
181 | savelij | 1557 | LD E,5 ; младшие 16 бит читаем из смещения +26 |
35 | savelij | 1558 | ADD HL,DE |
1559 | LD E,(HL) |
||
1560 | INC HL |
||
1561 | LD D,(HL) |
||
1562 | INC HL |
||
1563 | RET |
||
1564 | |||
181 | savelij | 1565 | ; проверка по маске |
35 | savelij | 1566 | COMPARE LD DE,FB_EXT |
181 | savelij | 1567 | LD B,0x0B |
35 | savelij | 1568 | LD A,(DE) |
1569 | CP (HL) |
||
1570 | RET NZ |
||
1571 | INC HL |
||
1572 | INC DE |
||
1573 | DJNZ $-5 |
||
1574 | RET |
||
1575 | |||
181 | savelij | 1576 | ; распаковщик пути к файлу |
1577 | FNDBUF LD BC,0x0802 |
||
35 | savelij | 1578 | LD DE,FB_EXT |
1579 | FNDBUF4 LD A,(HL) |
||
1580 | INC HL |
||
112 | savelij | 1581 | CP "." |
35 | savelij | 1582 | JR Z,FNDBUF2 |
112 | savelij | 1583 | CP "/" |
35 | savelij | 1584 | JR Z,FNDBUF5 |
1585 | LD (DE),A |
||
1586 | INC DE |
||
1587 | DJNZ FNDBUF4 |
||
1588 | LD A,(HL) |
||
1589 | AND A |
||
1590 | RET Z |
||
1591 | INC HL |
||
1592 | JR FNDBUF3 |
||
1593 | |||
1594 | FNDBUF5 LD A,C |
||
1595 | AND A |
||
1596 | RET Z |
||
1597 | FNDBUF2 LD A,B |
||
1598 | AND A |
||
1599 | JR Z,FNDBUF3 |
||
112 | savelij | 1600 | LD A," " |
35 | savelij | 1601 | LD (DE),A |
1602 | INC DE |
||
1603 | DJNZ $-2 |
||
1604 | FNDBUF3 LD B,3 |
||
1605 | DEC C |
||
1606 | DEC HL |
||
1607 | LD A,(HL) |
||
112 | savelij | 1608 | CP "/" |
35 | savelij | 1609 | JR Z,FNDBUF4 |
1610 | INC HL |
||
1611 | JR FNDBUF4 |
||
1612 | RAMCEND |
||
69 | savelij | 1613 | DEPHASE |