;LAST UPDATE: 24.04.2014 savelij
include ../macros.a80
include ../ports_ngs.a80
include ../sdcomand.a80
;АДРЕС ЗАГРУЗКИ НАЙДЕННОЙ ПРОШИВКИ
ADRLOAD EQU 0X8000
RAMCOD EQU 0X4080 ;АДРЕС РАБОТЫ ОСНОВНОГО КОДА
RAM8KB EQU 0X6000 ;АДРЕС БУФЕРА ДЛЯ ПЕРЕБРОСКИ КОДА
STRPAG EQU 0X8000 ;АДРЕС КУДА ЗАГРУЗКИ
FREQUENCY EQU C_20MHZ ;ТЕКУЩАЯ ЧАСТОТА ДЛЯ ОСНОВНОЙ ПРОШИВКИ
ORG 0
DI
LD SP,RAMCOD
XOR A
OUT (VOL1),A
OUT (VOL2),A
OUT (VOL3),A
OUT (VOL4),A
OUT (VOL5),A
OUT (VOL6),A
OUT (VOL7),A
OUT (VOL8),A ;ЗАГЛУШИЛИ МОД ПОРТЫ ДЛЯ ИСПОЛЬЗОВАНИЯ БУФЕРА
; JP RDBYT_DBG ;ОТЛАДОЧНАЯ ФИГНЯ
;ОЖИДАНИЕ ЗАГРУЗКИ ПРОШИВКИ СО СПЕКА
LD B,0 ;ЧИТАЕМ 256 ПОРТ СТАТУСА
IN A,(ZXSTAT) ;НА ПРЕДМЕТ ИЗМЕНЕНИЯ СОСТОЯНИЯ
RRA
JR C,RDBYT01
DJNZ $-5
DEC B ;СЧЕТЧИК ОБНУЛИЛСЯ, СОСТОЯНИЕ ПОРТА НЕ ИЗМЕНИЛОСЬ
JR RDBYT03 ;ГРУЗИМ СТАНДАРТНУЮ ПРОШИВКУ
RDBYT01 IN A,(ZXCMD) ;ЧИТЕМ ПРИШЕДШИЙ БАЙТ ИЗ ПОРТА КОМАНД
LD C,A ;СОХРАНИЛИ ДЛЯ ПРОВЕРКИ
IN A,(ZXDATRD) ;ЧИТЕМ БАЙТ ИЗ ПОРТА ДАННЫХ
OUT (CLRCBIT),A ;СБРОСИЛИ КОМАНД БИТ
CP C ;СРАВНИВАЕМ ПРИШЕДШИЕ БАЙТЫ
JR NZ,RDBYT03 ;НЕ СОВПАЛИ, ГРУЗИМ СТАНДАРТНУЮ ПРОШИВКУ
CP 0X55 ;ПРИШЕЛ БАЙТ 0X55?
JR NZ,RDBYT03 ;ЕСЛИ НЕТ, ГРУЗИМ СТАНДАРТНУЮ ПРОШИВКУ
LD B,0 ;ЧИТАЕМ 256 РАЗ ИЗМЕНЕНИЕ ПОРТА КОМАНД
IN A,(ZXSTAT)
RRA
JR C,RDBYT02
DJNZ $-5
DEC B
JR RDBYT03 ;НЕ ДОЖДАЛИСЬ, ГРУЗИМ СТАНДАРТНУЮ ПРОШИВКУ
RDBYT02 IN A,(ZXCMD) ;ЗАБРАЛИ БАЙТ ИЗ ПОРТА КОМАНД
LD C,A ;СОХРАНИЛИ ДЛЯ ПРОВЕРКИ
IN A,(ZXDATRD) ;ЗАБРАЛИ БАЙТ ИЗ ПОРТА ДАННЫХ
CP C ;СРАВНИЛИ
JR NZ,RDBYT03 ;ЕСЛИ НЕ СОВПАДАЮТ, ГРУЗИМ СТАНДАРТНУЮ ПРОШИВКУ
RDBYT_DBG CP 0XAA ;ЭТО 0XAA?
RDBYT03 EX AF,AF' ;ВРЕМЕННО СПРЯТАЛИ ФЛАГИ ПРОЦЕССОРА
LD HL,GRUZILA
LD DE,RAMCOD
LD BC,RAMCEND-VERLOAD
LDIR ;ПЕРЕНЕСЛИ ОСНОВНОЙ КОД В АДРЕС РАБОТЫ
OUT (CLRCBIT),A ;СБРОСИЛИ КОМАНД БИТ
EX AF,AF' ;ВЕРНУЛИ СПРЯТАННЫЕ ФЛАГИ
JP Z,GRUZIM2 ;ЕСЛИ ВСЕ УСЛОВИЯ СОВПАЛИ, ЗАПУСКАЕМ ЗАГРУЗЧИК
JP GRUZIM0 ;ИНАЧЕ ГРУЗИМ СТАНДАРТНУЮ ПРОШИВКУ ИЗ ПЗУ
GRUZILA
PHASE RAMCOD
VERLOAD DB "Loader"
DW DATA_VERS
;ПУТЬ ДО ФАЙЛА ПРОШИВКИ GS
F_PATH DB "NEOGS.ROM",0
UPDATENAME DB "NGS_ROM.UPD",0
TXT1 DB "not found",0
TXT1E
TXT2 DB "beta",0
TXT2E
TXT3 DB 0;"stable",0
TXT3E
GRUZIM0 CALL RROMSD ;ЗАГРУЖАЕМ И ЗАПУСКАЕМ ПРОШИВКУ С SD КАРТЫ, ЕСЛИ ОНА ТАМ ЕСТЬ
JP GS105 ;ИНАЧЕ ЗАГРУЖАЕМ ПРОШИВКУ ИЗ ПЗУ И ЗАПУСКАЕМ
GRUZIM2 LD A,0X11 ;КОНФИГУРИМ НГС
LD (NGS_MODES),A
OUT (GSCFG0),A ;ОТРУБАЕМ ПЗУ И ВРУБАЕМ ЧАСТОТУ 12МГЦ
XOR A
OUT (MPAG),A ;ВКЛЮЧАЕМ СТРАНИЦУ 0
GRUZIM IN A,(ZXSTAT) ;ПОСТОЯННО ЖДЕМ КОМАНД ОТ СПЕКА
RRA
JR NC,GRUZIM
IN A,(ZXCMD) ;ПОЙМАЛИ КОМАНДУ
CP 0X1D ;ЭТО КОМАНДА ПРОВЕРКИ?
JR NZ,GRUZIM1
LD A,0X76
OUT (ZXDATWR),A ;ОТДАЕМ БАЙТ ИДЕНТИФИКАЦИИ ЗАГРУЗЧИКА
OUT (CLRCBIT),A
JR GRUZIM ;И ПРОДОЛЖАЕМ ЖДАТЬ КОМАНД
GRUZIM1 CP 0XF3
JP Z,GS105 ;ПРИ ПОСТУПЛЕНИИ КОМАНД 0XF3 И
CP 0XF4
JP Z,GS105 ;0XF4 ЗАГРУЖАЕМ И ЗАПУСКАЕМ ПРОШИВКУ ИЗ ПЗУ
CP LOW (FLOADE-FLOADER)/2+1
JP NC,GS105 ;АНАЛОГИЧНО НЕ КОМАНДА ЗАГРУЗЧИКА ПЕРЕХОДИМ НА ОСНОВНОЕ ПЗУ
ADD A,A
LD L,A
LD H,0
LD DE,GRUZIM2
PUSH DE ;НА СТЕКЕ АДРЕС ВОЗВРАТА ПОСЛЕ ИСПОЛНЕНИЯ КОМАНДЫ
LD DE,FLOADER
ADD HL,DE
LD E,(HL)
INC HL
LD D,(HL) ;ЗАБРАЛИ АДРЕС ИСПОЛНЕНИЯ КОМАНДЫ
EX DE,HL
JP (HL) ;ПОЕХАЛИ НА ИСПОЛНЕНИЕ
FLOADER DW LOADROM ;00 ЗАГРУЗКА ROM СО СПЕКА ВМЕСТО СКОПИРОВАННОЙ ИЗ ROM
DW JPLDROM ;01 ЗАПУСК ЗАГРУЖЕННОЙ ПРОШИВКИ
DW GS105 ;02 КОПИРОВАНИЕ ИЗ ROM И ЗАПУСК
DW RROMSD ;03 ЗАГРУЗКА И ЗАПУСК ROM С SD КАРТЫ
DW LOADCOD ;04 ЗАГРУЗКА КОДА СО СПЕКА
DW LDINSD ;05 ЗАГРУЗКА ФАЙЛА С SD КАРТЫ
DW RUNCOD ;06 ЗАПУСК КОДА С ЛЮБОГО АДРЕСА И В ЛЮБОЙ СТРАНИЦЕ
DW STATSD ;07 СТАТУС ЗАГРУЖЕННОГО ФАЙЛА
DW VERPAGE ;08 ВЕРСИЯ В ТЕКСТОВОМ ВИДЕ ДЛЯ УКАЗАННОЙ СТРАНИЦЕ
DW GET_CRC ;09 ПОЛУЧИТЬ CRC16
DW LOADUPDATE ;0A ЗАГРУЗКА ФАЙЛА С ОБНОВЛЕНИЕМ
DW SET_FREQ ;0B УСТАНОВКА ЧАСТОТЫ ПРОЦЕССОРА
FLOADE
SET_FREQ IN A,(ZXDATRD) ;ПРИНЯЛИ НОМЕР ЧАСТОТЫ
BIT 7,A
JR NZ,SET_FREQ2
OUT (CLRCBIT),A ;СБРОСИЛИ КОМАНД БИТ
AND 3
LD L,C_10MHZ ;УСТАНОВКА ЧАСТОТЫ 10 МГЦ
JR Z,SET_FREQ1
DEC A
LD L,C_12MHZ ;УСТАНОВКА ЧАСТОТЫ 12 МГЦ
JR Z,SET_FREQ1
DEC A
LD L,C_20MHZ ;УСТАНОВКА ЧАСТОТЫ 20 МГЦ
JR Z,SET_FREQ1
LD L,C_24MHZ ;УСТАНОВКА ЧАСТОТЫ 24 МГЦ
SET_FREQ1 LD A,(NGS_MODES)
AND %11001111
OR L
LD (NGS_MODES),A
OUT (GSCFG0),A
RET
SET_FREQ2 LD A,(NGS_MODES)
AND 0X30
RRCA
RRCA
RRCA
RRCA
OUT (CLRCBIT),A
OUT (ZXDATWR),A
JP WDN
;ПЕРЕДАЧА НА СПЕК ВЕРСИИ В TXT ВИДЕ
VERPAGE IN A,(ZXDATRD) ;ЗАБРАЛИ БАЙТ НОМЕРА ЗАПРОШЕННОЙ СТРАНИЦЫ ПЗУ
AND 7 ;СТАРШИЕ 5 БИТ В ИГНОРЕ
EX AF,AF' ;ВРЕМЕННО СПРЯТАЛИ ФЛАГИ ПРОЦА
LD A,0X30
OUT (GSCFG0),A ;ВКЛЮЧИЛИ 10 МГЦ И ВЕРНУЛИ ПЗУ
EX AF,AF' ;ВЕРНУЛИ ФЛАГИ
ADD A,A ;НАМ НУЖНА ВТОРЫЕ 32К СТРАНИЦЫ ПЗУ
; AND A ;ВЫБРАНА СТРАНИЦА 0?
; JR NZ,VERPAG1 ;ЕСЛИ НЕТ, ТО ИДЕМ НА ИЗВЛЕЧЕНИЕ ПОСЛЕДНИХ 8 БАЙТ
; LD HL,VERLOAD ;ДЛЯ ЗАГРУЗЧИКА БЕРЕМ ИЗ ДРУГОГО АДРЕСА
; LD DE,RAMCEND
; LD BC,8
; PUSH DE
; LDIR
; POP DE
; JR VERPAG2 ;ПОШЛИ НА ПЕРЕВОДЧИК В ТЕКСТОВЫЙ ВИД
VERPAG1 INC A
OUT (MPAG),A ;ВКЛЮЧИЛИ ПОСЛЕДНИЕ 16К ВЫБРАННОЙ СТРАНИЦЫ ПЗУ
LD HL,0XFFF8
LD BC,8
LD DE,RAMCEND
PUSH DE
LDIR ;ПЕРЕНЕСЛИ 8 БАЙТ ИЗ ХВОСТА ПЗУ
POP DE
VERPAG2 LD A,0X11
OUT (GSCFG0),A ;ОТРУБИЛИ ПЗУ И ВЕРНУЛИ 12МГЦ
XOR A
OUT (MPAG),A ;ВЕРНУЛИ СТРАНИЦУ 0 ОЗУ
LD B,8 ;ПРОВЕРЯМ ПЕРЕНЕСЕННЫЕ 8 БАЙТ, А НЕ 0XFF ЛИ ТАМ?
LD A,(DE)
INC DE
INC A
JR NZ,VFPGA1 ;НЕ 0XFF, ПРОДОЛЖАЕМ
DJNZ $-5
DEC SP ;ТАКИ ВСЕ 8 БАЙТ 0XFF, ВЕРСИИ У ПЗУ СТРАНИЦЫ НЕТУ
DEC SP
POP DE
LD HL,TXT1
LD BC,TXT1E-TXT1
LDIR ;ОТДАТЬ ТЕКСТ ОБ ЭТОМ
JR VFPGA0
VFPGA1 DEC SP
DEC SP
POP DE
CALL UNVERS ;РАСПАКОВКА ПОЛУЧЕННЫХ 8 БАЙТ В ТЕКСТ
VFPGA0 OUT (CLRCBIT),A ;СБРОСИЛИ КОМАНД БИТ
LD HL,RAMCEND
LD BC,ZXDATWR
VFPGA2 LD A,(HL)
OUTI
EX AF,AF'
CALL WDN
EX AF,AF'
AND A
JR NZ,VFPGA2 ;ОТДАЕМ ТЕКСТ ВЕРСИИ ПОКА НЕ ВСТРЕТИТСЯ БАЙТ 0, КОТОРЫЙ ТОЖЕ ОТДАЕМ
RET
;РАСПАКОВЩИК ДАТЫ
UNVERS LD HL,6
ADD HL,DE ;ПРОПУСТИЛИ 6 БАЙТ ТЕКСТА ВЕРСИИ
LD C,(HL) ;ЗАБРАЛИ МЛАДШИЙ БАЙТ ВЕРСИИ
LD (HL)," " ;НА ЕГО МЕСТО ПРОБЕЛ
INC HL
LD B,(HL) ;ЗАБРАЛИ СТАРШИЙ БАЙТ
LD A,C ;ВЗЯЛИ МЛАДШИЙ БАЙТ ВЕРСИИ
AND 0X1F ;НАС ИНТЕРЕСУЮТ МЛАДШИЕ 5 БИТ (ДЕНЬ МЕСЯЦА)
JR NZ,$+4
RES 7,B ;ЕСЛИ ПОЛУЧИЛСЯ 0, ВОЗМОЖНО ЭТО БЕТА ВЕРСИЯ
CP 32
JR C,$+4 ;В МЕСЯЦЕ НЕ МОЖЕТ БЫТЬ БОЛЕЕ 31 ДНЯ
RES 7,B ;ИНАЧЕ ЭТО БЕТА ВЕРСИЯ
CALL A2TXT ;ПЕРЕВОДИМ ПОЛУЧЕННОЕ ЧИСЛО В ТЕКСТ
SRL B ;СДИНУЛИ ВЕРСИЮ НА 1 БИТ ВЛЕВО ЧТОБЫ НОМЕР МЕСЯЦА
RR C ;ОКАЗАЛСЯ В ОДНОМ БАЙТЕ
LD A,C ;ЗАБРАЛИ ЭТОТ БАЙТ
RRCA
RRCA
RRCA
RRCA ;СДВИНУЛИ НУЖНЫЕ БИТЫ В МЛАДШИЕ РАЗРАДЫ БАЙТА
AND 0X0F ;ОСТАВИЛИ НУЖНЫЕ 4 БИТА (НОМЕР МЕСЯЦА)
JR NZ,$+4 ;НОМЕР МЕСЯЦА НЕМОЖЕТ БЫТЬ 0
RES 6,B ;ИНАЧЕ ЭТО БЕТА ВЕРСИЯ
CP 13 ;И НОМЕР МЕСЯЦА НЕ МОЖЕТ БЫТЬ БОЛЬШЕ 12
JR C,$+4
RES 6,B ;ИНАЧЕ БЕТА ВЕРСИЯ
LD (HL),"." ;ОТДЕЛИЛИ НОМЕР ДНЯ МЕСЯЦА ТОЧКОЙ
INC HL
CALL A2TXT ;КОНВЕРТИРОВАЛИ НОМЕР МЕСЯЦА
LD (HL),"." ;ТАК ЖЕ ОТДЕЛИЛИ ТОЧКОЙ
INC HL
LD A,B ;ВЗЯЛИ ОСТАВШИЕСЯ БИТЫ
AND 0X3F ;НАМ НУЖНЫ 6 БИТ НОМЕРА ГОДА
CALL A2TXT ;КОНВЕРТНУЛИ В ТЕКСТ
BIT 6,B ;БЕТА ИЛИ ЫТАБЛ ВЕРСИЯ?
JR NZ,UNVERS1
LD DE,TXT2 ;ВСЕ-ТАКИ БЕТА, О ЧЕМ И ДОБАВЛЯЕМ ТЕКСТ К ВЕРСИИ
LD BC,TXT2E-TXT2
JR UNVERS2
UNVERS1 LD DE,TXT3 ;ВЕРСИЯ СТАБЛ
LD BC,TXT3E-TXT3
UNVERS2 LD (HL)," " ;ПЕРЕД ТЕКСТОМ (БЕТА ИЛИ СТАБЛ) ВСТАВЛЯЕМ ПРОБЕЛ
INC HL
EX DE,HL
LDIR ;ПЕРЕТАЩИЛИ ТЕКСТ
EX DE,HL
LD (HL),0 ;ЗАВЕРШИЛИ СТРОКУ НУЛЕМ
RET
;ПЕРЕВОД "A" В ДЕСЯТИЧНЫЙ ВИД И В ТЕКСТ. ДЛЯ ЧИСЕЛ ОТ 0 ДО 99
A2TXT PUSH HL ;СОХРАНИЛИ АДРЕС КУДА ЛОЖИТЬ СКОНВЕРЧЕННОЕ
LD L,A
LD H,0
LD DE,10
XOR A
DEC A
INC A
SBC HL,DE
JR NC,$-3 ;СЧИТАЕМ КОЛИЧЕСТВО ДЕСЯТКОВ В ЧИСЛЕ
ADD HL,DE ;ВЕРНУЛИ ПЕРЕБОР ВЫЧИТАНИЯ
ADD A,"0" ;ПЕРЕВЕЛИ В ТЕСКТОВЫЙ ВИД ПОЛУЧЕННОЕ ЧИСЛО
LD D,A ;ПОКА СОХРАНИЛИ
LD A,L ;ВЗЯЛИ ОСТАВШИЕСЯ ЕДИНИЦЫ ЧИСЛА
ADD A,"0" ;КОНВЕРТУЛИ В ТЕКСТ
POP HL ;ВЕРНУЛИ АДРЕС КУДА ЛОЖИТЬ
LD (HL),D ;ПОЛОЖИЛИ ДЕСЯТКИ ЗАДАННОГО ЧИСЛА
INC HL
LD (HL),A ;ПОЛОЖИЛИ ЕДИНИЦЫ ТОГО ЖЕ ЧИСЛА
INC HL
RET
;ЗАГРУЗКА С SD КАРТЫ ПО УКАЗАННОМУ ПУТИ
;ПЕРВЫЙ БАЙТ-НОМЕР СТРАНИЦЫ ОЗУ КУДА НАЧИНАТЬ ГРУЗИТЬ
;ДАЛЕЕ БАЙТЫ ТЕКСТОВОЙ СТРОКА ПУТИ И ИМЕНИ ФАЙЛА
;КОНЕЦ СТРОКИ БАЙТ 0, ОН ЖЕ СТОП БАЙТ
LDINSD LD BC,ZXDATRD ;АДРЕС ПОРТА ДАННЫХ
LD HL,RAMCEND ;АДРЕС КУДА СТРОКУ ПУТИ СКЛАДИРОВАТЬ
PUSH HL
IN A,(C) ;ПРИНЯЛИ НОМЕР СТРАНИЦЫ ОТКУДА НАЧИНАТЬ ЗАГРУЗКУ
OUT (CLRCBIT),A ;СБРОСИЛИ КОМАНД БИТ
EX AF,AF'
LDINSD1 CALL WDY
IN A,(C)
LD (HL),A
INC HL
AND A
JR NZ,LDINSD1 ;ПРИНИМАЕМ СТРОКУ ПОКА НЕ ВСТРЕТИТСЯ БАЙТ 0
EX AF,AF'
POP HL
JP LOAD_SD ;ДАЛЕЕ ЗАПУСКАЕМ ЗАГРУЗКУ С SD КАРТЫ
;ЗАГРУЗКА ФАЙЛА С ОБНОВЛЕНИЯМИ
LOADUPDATE LD HL,UPDATENAME ;ИМЯ ФАЙЛА ОБНОВЛЕНИЯ
LD A,2 ;ГРУЗИТЬ НАЧИНАЯ СО 2 СТРАНИЦЫ
OUT (CLRCBIT),A
JP LOAD_SD
;СТАТУС ЗАГРУЗКИ ФАЙЛА С SD КАРТЫ
STATSD LD A,(STATUS)
OUT (ZXDATWR),A
OUT (CLRCBIT),A
RET
;ЗАГРУЗКА И ЗАПУСК ПРОШИВКИ С SD КАРТЫ
;ИМЯ, ПУТЬ И АДРЕС ФИКСИРОВАН
RROMSD LD HL,F_PATH ;АДРЕС СТРОКИ ФИКСИРОВАННОГО ПУТИ ДЛЯ ЗАГРУЗКИ
XOR A
CALL LOAD_SD ;ЗАГРУЖАЕМ
AND A
RET NZ ;ЕСЛИ ОШИБКА, ТО ГРУЗИМ ИЗ ПЗУ
JP JPLDROM
;ЗАПУСК КОДА В ЛЮБОЙ СТРАНИЦЕ
;0-НОМЕР СТРАНИЦЫ ОЗУ
;1-МЛАДШИЙ БАЙТ АДРЕСА ЗАПУСКА
;2-СТАРШИЙ БАЙТ АДРЕСА ЗАПУСКА
RUNCOD LD BC,ZXDATRD ;АДРЕС ПОРТА ДАННЫХ
IN A,(C) ;ПРИНЯЛИ НОМЕР СТРАНИЦЫ ОЗУ
OUT (CLRCBIT),A ;СБРОСИЛИ КОМАНД БИТ
OUT (MPAG),A
CALL WDY
IN L,(C) ;ПРИНЯЛИ МЛАДШИЙ БАЙТ АДРЕСА ЗАПУСКА
CALL WDY
IN H,(C) ;ПРИНЯЛИ СТАРШИЙ БАЙТ АДРЕСА ЗАПУСКА
JP (HL) ;ЗАПУСКАЕМ
;0-НОМЕР СТРАНИЦЫ ОЗУ
;1-МЛАДШИЙ БАЙТ ДЛИНЫ ЗАГРУЗКИ
;2-СТАРШИЙ БАЙТ ДЛИНЫ ЗАГРУЗКИ
;ЗАГРУЗКА НЕ БОЛЕЕ 32КБ
LOADCOD LD BC,ZXDATRD ;АДРЕС ПОРТА ДАННЫХ
LD HL,0X8000 ;АДРЕС НАЧАЛА ЗГРУЗКИ
IN A,(C) ;ПРИНЯЛИ НОМЕР СТРАНИЦЫ ОЗУ
OUT (CLRCBIT),A ;СБРОСИЛИ КОМАНД БИТ
OUT (MPAG),A ;ВКЛЮЧИЛИ ЗАДАННУЮ СТРАНИЦУ ОЗУ
CALL WDY
IN E,(C) ;ПРИНЯЛИ МЛАДШИЙ БАЙТ ДЛИНЫ ЗАГРУЗКИ
CALL WDY
IN D,(C) ;ПРИНЯЛИ СТАРШИЙ БАЙТ ДЛИНЫ ЗГАРУЗКИ
LOADCO1 CALL WDY
INI
LD A,H
AND A
RET Z ;ЕСЛИ ОЗУ КОНЧИЛОСЬ, ВЫХОДИМ
DEC DE
LD A,D
OR E
JR NZ,LOADCO1 ;ГРУЗИМ СКОКА УКАЗАНО
RET
;ЗАГРУЗКА ПРОШИВКИ 32КБ СО СПЕКА
LOADROM XOR A
OUT (MPAG),A ;ВКЛЮЧАЕМ СТРАНИЦУ
LD HL,0X8000 ;АДРЕС ЗАГРУЗКИ
OUT (CLRCBIT),A ;СБРОС КОМАНД БИТА
LD BC,ZXDATRD ;АДРЕС ПОРТА ДАННЫХ
LOADROM1 CALL WDY
INI
LD A,H
AND A
JR NZ,LOADROM1 ;ГРУЗИМ ПОКА ПАМЯТЬ НЕ КОНЧИТСЯ
RET
;ГРУЗИЛКА СТАНДАРТНОЙ ПРОШИВКИ ИЗ ROM
GS105 LD HL,STRPAG ;АДРЕС КУДА ПЕРЕНОСИТЬ
LD A,4 ;ПЕРЕНОСИТЬ 4 КУСКА ПО 8 КИЛОБАЙТ
MOV1 EX AF,AF' ;ПРЯЧЕМ СЧЕТЧИК
LD A,0X30
OUT (GSCFG0),A ;ВКЛЮЧИЛИ ПЗУ
LD A,2
OUT (MPAG),A ;СТРАНИЦУ 2 СО СТАНДАРТНОЙ ПРОШИВКОЙ
PUSH HL
LD DE,RAM8KB
LD BC,0X2000
LDIR ;ПЕРЕНЕСЛИ В БУФЕР 8 КИЛОБАЙТ
LD A,0X31
OUT (GSCFG0),A ;ПЕРЕКЛЮЧИЛИ ПЗУ
XOR A
OUT (MPAG),A ;ВКЛЮЧИЛИ СТРАНИЦУ 0 ОЗУ
POP DE
LD HL,RAM8KB
LD BC,0X2000
LDIR ;ПЕРЕНЕСЛИ ИЗ БУФЕРА 8 КИЛОБАЙТ
EX DE,HL
EX AF,AF'
DEC A
JR NZ,MOV1 ;И ТАК 4 РАЗА
;ЗАПУСК ЗАГРУЖЕННОЙ ПРОШИВКИ
JPLDROM XOR A
OUT (MPAG),A ;ВКЛЮЧИЛИ СТРАНИЦУ 0 ОЗУ
; LD A,0X13 ;ВКЛЮЧИЛИ ЧАСТОТУ 12МГЦ, ОТКЛЮЧИЛИ ПЗУ И ЗАЩИТИЛИ ОЗУ ОТ ЗАПИСИ
; LD A,0X23 ;ВКЛЮЧИЛИ ЧАСТОТУ 20МГЦ, ОТКЛЮЧИЛИ ПЗУ И ЗАЩИТИЛИ ОЗУ ОТ ЗАПИСИ
LD A,3+FREQUENCY ;ВКЛЮЧИЛИ УКАЗАННУЮ ЧАСТОТУ, ОТКЛЮЧИЛИ ПЗУ И ЗАЩИТИЛИ ОЗУ ОТ ЗАПИСИ
OUT (GSCFG0),A
JP 0 ;СТАРТУЕМ СТАНДАРТНУЮ ПРОШИВКУ
;ЖДЕМ ПОКА СПЕК ДАСТ БАЙТ
WDY IN A,(ZXSTAT)
RLA
JR NC,WDY
RET
;ЖДЕМ ПОКА СПЕК ЗАБЕРЕТ БАЙТ ИЗ ПОРТА
WDN IN A,(ZXSTAT)
RLA
JR C,WDN
RET
;ПОДСЧЕТ CRC16
GET_CRC LD A,2
OUT (MPAG),A
DEC A
OUT (GSCFG0),A
LD HL,(0X8000)
SRL H
RR L
SRL H
RR L
SRL H
RR L
SRL H
RR L
LD A,L
LD IYH,A
; LD IX,0X8000
; LD C,(IX+0)
; LD B,(IX+1)
; CALL CRC16
; LD C,(IX+0)
; LD B,(IX+1)
; LD A,0X81
; AND A
; SBC HL,BC
; JR NZ,OUT_ERR ;CRC16 ЗАГОЛОВКА ERROR
LD IX,0X8000+8-0X10
SCHET LD DE,0X10
ADD IX,DE ;В IX АДРЕС ВЫБРАННОГО БЛОКА
LD C,(IX+4)
LD B,(IX+5) ;В BC ДЛИНА БЛОКА
LD E,(IX+1)
LD L,(IX+2)
LD H,(IX+3)
LD A,L
AND 0X7F
LD D,A ;В DE СМЕЩЕНИЕ В СТРАНИЦЕ
ADD HL,HL
LD A,2
ADD A,H
LD IYL,A
OUT (MPAG),A ;НОМЕР СТРАНИЦЫ
PUSH IX
LD IX,0X8000
ADD IX,DE ;В IX АДРЕС НАЧАЛА БЛОКА
CALL CRC16
POP IX
LD C,(IX+6)
LD B,(IX+7)
LD A,0X82
AND A
SBC HL,BC
JR NZ,OUT_ERR
DEC IYH
JR NZ,SCHET
ERR_OK LD A,0X80
;CRC16 ERROR
;0X80-CRC16 БЛОКА OK
;0X81-CRC16 ЗАГОЛОВКА ERROR
;0X82-CRC16 БЛОКА ERROR
OUT_ERR OUT (CLRCBIT),A
OUT (ZXDATWR),A
CALL WDN
LD A,L
OUT (ZXDATWR),A
CALL WDN
LD A,H
OUT (ZXDATWR),A
RET
CRC16 LD HL,0XFFFF
LD DE,0X1021
CRC_0 LD A,(IX)
INC IX
EX AF,AF'
LD A,IXL
OR IXH
JR NZ,CRC_3
INC IYL
LD A,IYL
OUT (MPAG),A
LD IX,0X8000
CRC_3 EX AF,AF'
XOR H
LD H,A
LD A,8
CRC_1 ADD HL,HL
JR NC,CRC_2
EX AF,AF'
LD A,L
XOR E
LD L,A
LD A,H
XOR D
LD H,A
EX AF,AF'
CRC_2 DEC A
JR NZ,CRC_1
DEC BC
LD A,B
OR C
JR NZ,CRC_0
LD A,2
OUT (MPAG),A
RET
;---------------------------------
;ГРУЗИЛКА ФАЙЛА ПО УКАЗАННОМУ ПУТИ
BUF_512 EQU 0X5000 ;0X200 БУФЕР СЕКТОРА
TDIRCLS EQU BUF_512+0X0200 ;0X400 БУФЕР КЛАСТЕРОВ ROOT ДИРЕКТОРИИ
CAL_FAT EQU TDIRCLS+0X0400 ;1 КАЛИБР FAT
BYTSSEC EQU CAL_FAT+1 ;1 КОЛИЧЕСТВО СЕКТОРОВ В КЛАСТЕРЕ
ROOTCLS EQU BYTSSEC+1 ;4 КЛАСТЕР НАЧАЛА ROOT ДИРЕКТОРИИ
ROOTSEC EQU ROOTCLS+4 ;2 РАЗМЕР В СЕКТОРАХ ROOT ДИРЕКТОРИИ
SEC_FAT EQU ROOTSEC+2 ;4 КОЛИЧЕСТВО СЕКТОРОВ ОДНОЙ FAT
RSVDSEC EQU SEC_FAT+4 ;2 РАЗМЕР РЕЗЕРВНОЙ ОБЛАСТИ
STARTRZ EQU RSVDSEC+2 ;4 НАЧАЛО ДИСКА/РАЗДЕЛА
FRSTDAT EQU STARTRZ+4 ;4 АДРЕС ПЕРВОГО СЕКТОРА ДАННЫХ ОТ BPB
SEC_DSC EQU FRSTDAT+4 ;4 КОЛИЧЕСТВО СЕКТОРОВ НА ДИСКЕ/РАЗДЕЛЕ
CLS_DSC EQU SEC_DSC+4 ;4 КОЛИЧЕСТВО КЛАСТЕРОВ НА ДИСКЕ/РАЗДЕЛЕ
FATSTR EQU CLS_DSC+4 ;4 НАЧАЛО ПЕРВОЙ FAT ТАБЛИЦЫ
ADRPATH EQU FATSTR+4 ;2 АДРЕС ТЕКСТА ПУТИ ФАЙЛА
STATUS EQU ADRPATH+2 ;1 СТАТУС ПОСЛЕ ВЫЗОВА LOAD_SD
OLD_SP EQU STATUS+1 ;2 СТЕК ДЛЯ ВЫХОДА
FB_EXT EQU OLD_SP+2 ;B БУФЕР 8.3 ДЛЯ ПОИСКА ИМЕНИ
LVL_DIR EQU FB_EXT+0X0B ;1 НОМЕР УРОВНЯ ДИРЕКТОРИИ
LSTLOAD EQU LVL_DIR+1 ;4 НОМЕР СЕКТОРА ЗАГРУЖЕННОГО В БУФЕР
NGS_MODES EQU LSTLOAD+4 ;1 ТЕКУЩИЙ УСТАНОВЛЕННЫЙ РЕЖИМ
;SD КАРТА НЕ НАЙДЕНА
ZAW003 LD A,0XEE
WR_STAT LD SP,(OLD_SP)
LD (STATUS),A
RET
;ЗАГРУЗКА ФАЙЛА
;НА ВХОДЕ:A-СТРАНИЦА НАЧАЛА ЗАГРУЗКИ
;HL-АДРЕС ТЕКСТОВОЙ СТРОКИ
;ПУТИ К ФАЙЛУ ВМЕСТЕ С ИМЕНЕМ И РАСШИРЕНИЕМ ФАЙЛА. ПУТЬ ПОЛНОСТЬЮ ОТ ROOT
;ЗАГРУЖАЕТСЯ ФАЙЛ ПО РАЗМЕРУ ДОПОЛНЕНОМУ ДО ПОЛНЫХ СЕКТОРОВ (СЕКТОР 512 БАЙТ)
;ПРИМЕР: РАЗМЕР ФАЙЛА =0X80-ПОСЛЕ ДОПОЛНЕНИЯ БУДЕТ ЗАГРУЖЕН 1 СЕКТОР
;=0X401-БУДЕТ ЗАГРУЖЕНО 3 СЕКТОРА
;НА ВЫХОДЕ: A=
;0X00-ФАЙЛ ЗАГРУЖЕН
;0XAA-ФАЙЛ НЕ НАЙДЕН
;0XDD-FAT НЕ ОБНАРУЖЕН
;0XEE-SD КАРТА НЕ ОБНАРУЖЕНА
LOAD_SD LD IYL,A;LY,A ;СОХРАНИЛИ НОМЕР СТРАНИЦЫ КУДА ГРУЗИТЬ
LD (ADRPATH),HL ;СОХРАНИЛИ АДРЕС СТРОКИ ПУТИ
LD (OLD_SP),SP ;СОХРАНИЛИ СТЕК
LD A,0XFF
LD (LSTLOAD+3),A ;ПРИНУДИТЕЛЬНАЯ ЗАГРУЗКА СЕКТОРА БЕЗ ПРОВЕРКИ
LD A,1
OUT (GSCFG0),A ;ОТКЛЮЧИЛИ ПЗУ, ВСЕ СТРАНИЦА ОЗУ
LD A,%10011011
OUT (SCTRL),A ;СКОНФИГУРИЛИ НГС С CS=1 ДЛЯ SD КАРТЫ
LD B,0X10
LOADSD1 LD A,0XFF
OUT (SD_SEND),A ;ПИШЕМ 0X80 БАЙТ 0XFF В ПОРТ КАРТОЧКИ
DJNZ LOADSD1
XOR A ;256 ПОПЫТОК НАЙТИ SD КАРТУ
EX AF,AF'
LD A,1
OUT (SCTRL),A ;ВЫБРАЛИ SD КАРТУ CS=0
ZAW001 LD HL,CMD00
CALL OUTCOM ;ПЕРЕВОДИМ КАРТОЧКУ В РЕЖИМ SPI КОМАНДОЙ 0
CALL IN_OOUT ;ЖДЕМ ОТВЕТА
EX AF,AF'
DEC A
JR Z,ZAW003 ;ЖДЕМ ПО СЧЕПТЧИКУ 256 РАЗ
EX AF,AF'
DEC A
JR NZ,ZAW001 ;ЖДЕМ ПОКА КАРТА ОТВЕТИТ БАЙТОМ 1
LD BC,SD_RSTR
LD HL,CMD08
CALL OUTCOM ;ОПРЕДЕЛЯЕМ СПЕЦИФИКАЦИЮ КАРТЫ
CALL IN_OOUT ;В "A" ОТВЕТ КАРТЫ R1
IN H,(C)
NOP
IN H,(C)
NOP
IN H,(C)
NOP
IN H,(C) ;ПРОЧИТАЛИ ОСТАЛЬНЫЕ БАЙТЫ В НИКУДА
BIT 2,A ;ЕСЛИ ОШИБКА, ТО
LD HL,0 ;КАРТА СПЕЦИФИКАЦИИ 1.0
JR NZ,ZAW006 ;ИНАЧЕ
LD H,0X40 ;КАРТА СПЕЦИФИКАЦИИ 2.0
ZAW006 LD A,CMD_55
CALL OUT_COM ;ЗАПУСКАЕМ ВНУТРЕННЮЮ ИНИЦИАЛИЗАЦИЮ КАРТЫ
CALL IN_OOUT
LD BC,SD_SEND
LD A,ACMD_41
OUT (C),A
LD A,H
OUT (C),A
XOR A
OUT (C),A
NOP
OUT (C),A
NOP
OUT (C),A
DEC A
OUT (C),A
CALL IN_OOUT
AND A
JR NZ,ZAW006 ;ЖДЕМ ПОКА КАРТЫ ПЕРЕЙДЕТ В РЕЖИМ ГОТОВНОСТИ
ZAW004 LD A,CMD_59
CALL OUT_COM ;ПРИНУДИТЕЛЬНО ОТКЛЮЧАЕМ CRC16
CALL IN_OOUT
AND A
JR NZ,ZAW004
ZAW005 LD HL,CMD16
CALL OUTCOM ;ПРИНУДИТЕЛЬНЫЙ РАЗМЕР СЕКТОРА 512 БАЙТ
CALL IN_OOUT
AND A
JR NZ,ZAW005
;ИНИЦИАЛИЗАЦИЯ ПЕРЕМЕННЫХ FAT
WC_FAT LD DE,0
LD B,D
LD C,E
CALL LOADLST ;ЧИТАЕМ СЕКТОР 0 КАРТОЧКИ
PUSH HL
POP IX
LD DE,0X01BE
ADD HL,DE ;ПЕРЕХОДИМ НА СМЕЩЕНИЕ ДЛЯЧ ПРОВЕРОК
LD A,(HL) ;ПРОВЕРЯМ ЧТОБЫ БЫЛ 0, КАРТОЧКИ НЕ МОГУТ БЫТЬ ЗАГРУЗОЧНЫМИ
AND A
JR NZ,RDFAT05 ;ЕСЛИ НЕ 0, ПРОВЕРИТЬ ДРУГОЕ
LD DE,4
ADD HL,DE ;ПЕРЕХОДИМ К ПРОВЕРКЕ ТИПА РАЗДЕЛА
LD A,(HL)
LD B,0
CP 1 ;FAT12?
JR Z,RDFAT06
LD B,2
CP 0X0B ;FAT32?
JR Z,RDFAT06
CP 0X0C ;FAT32?
JR Z,RDFAT06
LD B,1
CP 6 ;FAT16?
JR Z,RDFAT06
CP 4 ;FAT16?
JR Z,RDFAT06
CP 0X0E ;FAT16?
JR NZ,RDFAT05
RDFAT06 LD A,B ;БЕРЕМ ИЗ "B" ТИП РАЗДЕЛА
LD (CAL_FAT),A ;СОХРАНИЛИ
ADD HL,DE
CALL LOADZP ;БЕРЕМ НОМЕР СЕКТОРА НАЧАЛА ОСНОВНОГО РАЗДЕЛА
JR RDFAT00 ;ПЕРЕХОДИМ К ИНИЦИАЛИЗАЦИИ ПЕРЕМЕННЫХ ДЛЯ РАБОТЫ С ФАТОМ
;MBR НЕ ОБНАРУЖЕН, ПРОВЕРЯЕМ СЕКТОР 0 КАРТЫ КАК ОПИСАТЕЛЬ
RDFAT05 LD C,(IX+0X0D) ;C=КОЛИЧЕСТВО СЕКТОРОВ В КЛАСТЕРЕ
XOR A
LD E,A
LD B,8
RR C
ADC A,0
DJNZ $-4 ;КОЛИЧЕСТВО СЕКТОРОВ В КЛАСТЕРЕ ДОЛЖНО БЫТЬ СТЕПЕНЬЮ 2
DEC A
JR NZ,$+3 ;ПРОВЕРИЛИ КОЛИЧЕСТВО БИТ
INC E ;+1, ЕСТЬ ТАКОЕ
LD A,(IX+0X0E)
OR (IX+0X0F)
JR Z,$+3 ;КОЛИЧЕСТВО ЗАРЕЗЕРВИРОВАННЫХ СЕКТОРОВ ДОЛЖНО БЫТЬ >0
INC E ;+1, ЕСТЬ ТАКОЕ
LD A,(IX+0X13)
OR (IX+0X14)
JR NZ,$+3 ;КОЛИЧЕСТВО СЕКТОРОВ НА РАЗДЕЛЕ ДЛЯ ФАТ16?
INC E
LD A,(IX+0X20)
OR (IX+0X21)
OR (IX+0X22)
OR (IX+0X23)
JR NZ,$+3 ;КОЛИЧЕСТВО СЕКТОРОВ НА РАЗДЕЛЕ ДЛЯ ФАТ32?
INC E ;ОДНО ИЗ НИХ ДОЛЖНО БЫТЬ =0, ДРУГОЕ >0
LD A,(IX+0X15)
AND 0XF0
CP 0XF0
JR NZ,$+3 ;СТАРШИЕ БИТЫ ДОЛЖНЫ БЫТЬ В 1
INC E
LD A,E
CP 4 ;УСЛОВИЯ СОВПАЛИ?
LD A,0XDD ;FAT НЕ НАЙДЕН
JP NZ,WR_STAT
LD A,0XFF
LD (CAL_FAT),A ;ТИП ФАТ ПОКА НЕ ОПРЕДЕЛЕН
LD DE,0
LD B,D
LD C,E
RDFAT00 LD (STARTRZ),DE
LD (STARTRZ+2),BC ;ПОЛОЖИЛИ НОМЕР СТАРТОВОГО СЕКТОРА РАЗДЕЛА
CALL LOADLST ;ЗАГРУЗИЛИ ЕГО
LD HL,0
LD DE,(BUF_512+0X16) ;BPB_FATSZ16
LD A,D
OR E
JR NZ,RDFAT01 ;ЕСЛИ НЕ FAT12/16 (BPB_FATSZ16=0)
LD DE,(BUF_512+0X24)
LD HL,(BUF_512+0X26) ;BPB_FATSZ32
;ТО БЕРЕМ ИЗ СМЕЩЕНИЯ +36
RDFAT01 LD (SEC_FAT+2),HL
LD (SEC_FAT),DE ;ЧИСЛО СЕКТОРОВ НА FAT-ТАБЛИЦУ
LD HL,0
LD DE,(BUF_512+0X13) ;BPB_TOTSEC16
LD A,D
OR E
JR NZ,RDFAT02 ;ЕСЛИ НЕ FAT12/16 (BPB_TOTSEC16=0)
LD DE,(BUF_512+0X20)
LD HL,(BUF_512+0X22) ;BPB_TOTSEC32
;ТО БЕРЕМ ИЗ СМЕЩЕНИЯ +32
RDFAT02 LD (SEC_DSC+2),HL
LD (SEC_DSC),DE ;К-ВО СЕКТОРОВ НА ДИСКЕ/РАЗДЕЛЕ
;ВЫЧИСЛЯЕМ ROOTDIRSECTORS
LD BC,(BUF_512+0X0B) ;BPB_BYTSPERSEC
LD DE,(BUF_512+0X11) ;BPB_ROOTENTCNT
LD HL,0
LD A,D
OR E
JR Z,RDFAT03
LD B,H
LD C,L
LD A,0X10
CALL BCDE_A
EX DE,HL
;ЭТО РЕАЛИЗОВАНА ФОРМУЛА
;ROOTDIRSECTORS=((BPB_ROOTENTCNT*32)+(BPB_BYTSPERSEC-1))/BPB_BYTSPERSEC
;В HL=ROOTDIRSECTORS. ЕСЛИ FAT32, ТО HL=0 ВСЕГДА
RDFAT03 PUSH HL ;ROOTDIRSECTORS
LD (ROOTSEC),HL
LD A,(BUF_512+0X10)
LD DE,(SEC_FAT)
LD HL,(SEC_FAT+2)
DEC A
EX DE,HL
ADD HL,HL
EX DE,HL
ADC HL,HL
DEC A
JR NZ,$-6
POP BC ;ПОЛНЫЙ РАЗМЕР FAT-ОБЛАСТИ В СЕКТОРАХ
CALL HLDEPBC ;ПРИБАВИЛИ ROOTDIRSECTORS
LD BC,(BUF_512+0X0E) ;BPB_RSVDSECCNT
LD (RSVDSEC),BC
CALL HLDEPBC ;ПРИБАВИЛИ BPB_RESVDSECCNT
LD (FRSTDAT),DE
LD (FRSTDAT+2),HL ;ПОЛОЖИЛИ НОМЕР ПЕРВОГО СЕКТОРА ДАННЫХ
LD B,H
LD C,L
LD HL,SEC_DSC ;BCDE+32-ое ЧИСЛО ПО АДРЕСУ HL
CALL BCDEHLM ;ВЫЧЛИ ИЗ ПОЛНОГО К-ВА СЕКТОРОВ РАЗДЕЛА
LD A,(BUF_512+0X0D)
LD (BYTSSEC),A
CALL BCDE_A ;РАЗДЕЛИЛИ НА К-ВО СЕКТОРОВ В КЛАСТЕРЕ
LD (CLS_DSC),DE
LD (CLS_DSC+2),BC ;ПОЛОЖИЛИ КОЛ-ВО КЛАСТЕРОВ НА РАЗДЕЛЕ
LD A,(CAL_FAT)
CP 0XFF
JR NZ,RDFAT04
;ОПРЕДЕЛЕНИЕ ТИПА FAT ПРИ ОТСУСТВИИ MBR
LD DE,(SEC_FAT-1)
LD BC,(SEC_FAT+1)
LD E,0 ;BCDE=КОЛИЧЕСТВО СЕКТОРОВ *0X100
PUSH BC
PUSH DE ;СОХРАНИЛИ
SRL B
RR C
RR D
RR E ;BCDE=КОЛИЧЕСТВО СЕКТОРОВ *0X80
LD HL,CLS_DSC ;КОЛИЧЕСТВО КЛАСТЕРОВ НА FAT
PUSH HL ;СОХРАНИЛИ
CALL HLBCDEM ;КОЛИЧЕСТВО КЛАСТЕРОВ-(КОЛИЧЕСТВО СЕКТОРОВ*0X80)
LD A,E
AND 0X80 ;КОЛИЧЕСТВО МЕНЕЕ 128 КЛАСТЕРОВ В СЕКТОРЕ ДЛЯ FAT32
OR D
OR C
OR B
LD A,2
POP HL
POP DE
POP BC
JR Z,RDFAT04 ;FAT32 ЕСЛИ ФЛАГ Z=0
CALL HLBCDEM ;КОЛИЧЕСТВО КЛАСТЕРОВ-(КОЛИЧЕСТВО СЕКТОРОВ*0X100)
LD A,D
OR C
OR B
LD A,1
JR Z,RDFAT04 ;FAT16 ЕСЛИ ФЛАГ Z=0
XOR A ;ИНАЧЕ FAT12
;ДЛЯ FAT12/16 ВЫЧИСЛЯЕМ АДРЕС ПЕРВОГО СЕКТОРА ДИРЕКТОРИИ
;ДЛЯ FAT32 БЕРЕМ ПО СМЕЩЕМИЮ +44, НА ВЫХОДЕ BCDE-СЕКТОР ROOTDIR
RDFAT04 LD (CAL_FAT),A ;УТОЧНИЛИ ТИП ФАТА
EX AF,AF'
LD DE,(RSVDSEC)
LD BC,0
LD HL,STARTRZ
CALL BCDEHLP
LD (FATSTR),DE
LD (FATSTR+2),BC ;ВЫЧИСЛИЛИ И ПОЛОЖИЛИ НОМЕР СЕКТОРА НАЧАЛА FAT-ЕАБЛИЦ
EX AF,AF'
AND A
LD DE,0
LD B,D
LD C,E
JR Z,FSRROO2 ;FAT12-NONE
DEC A
JR Z,FSRROO2 ;FAT16
LD DE,(BUF_512+0X2C)
LD BC,(BUF_512+0X2E) ;FAT32
FSRROO2 LD (ROOTCLS),DE
LD (ROOTCLS+2),BC ;ПОЛОЖИЛИ НОМЕР КЛАСТЕР ROOT ДИРЕКТОРИИ
XOR A
LD (LVL_DIR),A ;НАЧИНАЕМ С ROOT ДИРЕКТОРИИ
LD HL,(ADRPATH) ;ВЕРНУЛИ АДРЕС СТРОКИ ПУТИ ДО ФАЙЛА
FINDFL1 PUSH BC
PUSH DE ;СОХРАНИЛИ НОМЕР КЛАСТЕРА
CALL FNDBUF ;РАСПАКОВКА ЧАСТИ ТЕКСТОВОЙ СТРОКИ ДЛЯ СОЗДАНИЯ МАСКИ ПОИСКА
POP DE
POP BC ;ВОССТАНОВИЛИ НОМЕР КЛАСТЕРА
PUSH HL ;СОХРАНИЛИ ТЕКУЩИЙ АДРЕС ТЕКСТОВОЙ СТРОКИ
LD HL,TDIRCLS ;АДРЕС ТАБЛИЦЫ КЛАСТЕРОВ ТЕКУЩЕЙ ДИРЕКТОРИИ
LD A,D
OR E
OR B
OR C
CALL SAVEZP ;СОХРАНИЛИ В ТАБЛИЦУ НОМЕР ТЕКУЩЕГО КЛАСТЕРА
JR Z,LASTCLS ;ЕСЛИ НОМЕР КЛАСТЕРА 0, ТО ЭТО ROOT ДИРА (ДЛЯ ФАТ12/16)
NEXTCLS PUSH HL
CALL RDFATZP ;ЧИТАЕМ СЛЕДУЩИЙ НОМЕР КЛАСТЕРА ИЗ ЦЕПОЧКИ ДИРЕКТОРИИ
CALL LST_CLS ;ПРОВЕРЯЕМ НА КОНЕЦ ЦЕПОЧКИ
POP HL
JR C,LASTCLS
CALL SAVEZP ;ЕСЛИ НЕПОСЛЕДНИЙ СОХРАНЯЕМ В ТАБЛИЦУ
JR NEXTCLS ;СЛЕДУЮЩИЙ НОМЕР КЛАСТЕРА
LASTCLS LD BC,0XFFFF
CALL SAVEZP ;КЛАДЕМ МАРКЕР КОНЦА ЦЕПОЧКИ
EXX
LD HL,LVL_DIR
LD A,(HL) ;ТЕКУЩИЙ УРОВЕНЬ ДИРЕКТОРИИ
INC (HL) ;СЛЕДУЮЩИЙ УРОВЕНЬ ДИРЕКТОРИИ
AND A
LD BC,0 ;КОЛИЧЕСТВО ЗАПИСЕЙ ROOT ДИРЕКТОРИИ
JR NZ,LASTCLS1
LD A,(CAL_FAT)
CP 2
JR NC,LASTCLS1
LD HL,(ROOTSEC) ;УЖЕ НЕ ROOT ДИРЕКТОРИЯ
ADD HL,HL
ADD HL,HL
ADD HL,HL
ADD HL,HL
ADD HL,HL
LD B,H
LD C,L
LASTCLS1 EXX
FINDFL INC BC ;ИЩЕМ ПО ЗАДАННОЙ МАСКЕ НАЧИНАЯ С 0
CALL RDDIRSC ;ГРУЗИМ ПО НОМЕРУ ОПИСАТЕЛЯ СЕКТОР ДИРЕКТОРИИ
LD A,C
AND 0X0F ;В СЕКТОРЕ МАКСИМУМ 16 ОПИСАТЕЛЕЙ
LD E,A
LD D,0
EX DE,HL
ADD HL,HL
ADD HL,HL
ADD HL,HL
ADD HL,HL
ADD HL,HL
ADD HL,DE ;ПОЛУЧИЛИ АДРЕС НУЖНОГО ОПИСАТЕЛЯ
EXX
DEC BC
LD A,B
OR C
EXX
LD A,0XAA
JP Z,WR_STAT
LD A,(HL) ;ПРОВЕРЯЕМ ПЕРВЫЙ БАЙТ ИМЕНИ ОПИСАТЕЛЯ
AND A
LD A,0XAA ;ЕСЛИ БАЙТ =0, ТО
JP Z,WR_STAT ;ПЕРЕХОД ПО ОШИБКЕ = ФАЙЛ НЕ НАЙДЕН
PUSH HL
PUSH BC
CALL COMPARE ;СРАВНИВАЕМ С ЗАДАННОЙ МАСКОЙ
POP BC
POP DE
PUSH DE
POP IX ;СОДЕРЖИМОЕ IX=АДРЕС ОПИСАТЕЛЯ
JR NZ,FINDFL ;НЕ СОВПАДАЕТ, ПЕРЕХОДИМ К СЛЕДУЮЩЕМУ ОПИСАТЕЛЮ
CALL RD_CLAS ;ЗАБИРАЕМ НОМЕР КЛАСТЕРА ИЗ НАЙДЕННОГО ОПИСАТЕЛЯ
EX (SP),HL ;ВОССТАНОВИЛИ ТЕКУЩИЙ АДРЕС В СТРОКЕ ПУТИ ДО ФАЙЛА
INC SP
INC SP ;МАСКИРОВКА НА СТЕКЕ АДРЕСА РАЗМЕРА В БАЙТАХ ТЕКУЩЕГО ФАЙЛА
LD A,(HL)
AND A ;ТЕКСТОВАЯ СТРОКА КОНЧИЛАСЬ?
JR NZ,FINDFL1 ;ЕСЛИ НЕТ, ТО ИЩЕМ ДАЛЬШЕ
LD A,(IX+0X0B) ;ПРОВЕРЯЕМ ЭТО ДИРА ИЛИ ФАЙЛ?
AND 0X10
LD A,0XAA ;ЕСЛИ ДИРА, ТО ОШИБКА
JP NZ,WR_STAT ;ТЕКСТОВАЯ СТРОКА ДОЛЖНА УКАЗЫВАТЬ НА ФАЙЛ
DEC SP
DEC SP
POP HL ;ВОССТАНОВИЛИ В HL АДРЕС ОТКУДА ВЗЯТЬ РАЗМЕР ФАЙЛА В БАЙТАХ
PUSH BC
PUSH DE
CALL LOADZP ;ЗАБИРАЕМ РАЗМЕР ФАЙЛА (В БАЙТАХ)
LD A,E
AND A
JR Z,$+3 ;МЛАДШИЙ БАЙТ РАЗМЕРА ФАЙЛА =0?
INC D ;УВЕЛИЧИВАЕМ РАЗМЕР НА 256 БАЙТ БЕЗ УЧЕТА МЛАДШЕГО БАЙТА
BIT 0,D ;ПРОВЕРЯЕМ ЧЕТ/НЕЧЕТ
JR Z,$+3 ;ЕСЛИ НЕЧЕТ, ТО
INC D ;УВЕЛИЧИВАЕМ РАЗМЕР ЕЩЕ НА 256 БАЙТ
CALL BCDE200 ;ДЕЛИМ НА 512 (НА РАЗМЕР СЕКТОР)
PUSH DE
EXX
POP HL
EXX
LD A,(BYTSSEC) ;ВЗЯЛИ РАЗМЕР КЛАСТЕРА В СЕКТОРАХ
LD IXH,A ;СОХРАНИЛИ
POP DE
POP BC
LD HL,0X8000 ;АДРЕС ЗАГРУЗКИ
;HX-РАЗМЕР КЛАСТЕРА
;HL'-КОЛ-ВО СЕКТОРОВ ФАЙЛА
;BCDE-НОМЕР СТАРТОВОГО КЛАСТЕРА
;LY-СТАРТОВАЯ СТРАНИЦА ЗАГРУЗКИ
LD A,IYL ;ВОССТАНОВИЛИ СТРАНИЦУ ЗАГРУЗКИ
AND A
JR NZ,CP_PAGE ;ПРОВЕРКА ДЛЯ ЗАГРУЗКИ В СТРАНИЦУ 0
OUT (MPAG),A ;ВКЛЮЧАЕМ СТРАНИЦУ 0
EXX
LD A,L
LD DE,0X41
SBC HL,DE
JR C,$+4 ;ЕСЛИ ФАЙЛ 0X41 И БОЛЕЕ СЕКТОРОВ
LD A,0X40 ;ТО ГРУЗИМ ТОЛЬКО 0X40 ПЕРВЫХ СЕКТОРОВ
EXX
JP LDMINI ;ПЕРЕХОДИМ НА ЗАГРУЗКУ
;ЗАГРУЗКА В СТРАНИЦУ 1 ЗАПРЕЩЕНА
CP_PAGE DEC A
LD A,0XAA
JP Z,WR_STAT
LD A,IYL
;ВКЛЮЧАЕМ СТРАНИЦУ ЗАГРУЗКИ
LDFILE0 OUT (MPAG),A ;ВКЛЮЧАЕМ ЗАДАННУЮ СТРАНИЦУ ДЛЯ ЗАГРУЗКИ
;ЗАГРУЗКА В СТРАНИЦЫ 02...7F
LD_FILE EXX
LD E,IXH
LD D,0 ;DE=РАЗМЕР КЛАСТЕРА В СЕКТОРАХ
AND A
SBC HL,DE ;СВЕРЯЕМ С КОЛИЧЕСТВОМ СЕКТОРОВ ДЛЯ ЗАГРУЗКИ
LD IXL,IXH ;LX=КОЛИЧЕСТВО СЕКТОРОВ ДЛЯ ЗАГРУЗКИ
EXX
JR NC,LDFILE1
EXX ;СЕКТОРОВ ДЛЯ ЗАГРУЗКИ МЕНЬШЕ РАЗМЕРА КЛАСТЕРА
ADD HL,DE
LD A,L
LD IXL,A ;LX=КОЛИЧЕСТВО СЕКТОРОВ ДЛЯ ЗАГРУЗКИ
EXX
LDFILE1 PUSH BC
PUSH DE
PUSH HL
CALL REALSEC ;ПЕРЕВЕЛИ НОМЕР КЛАСТЕРА В НОМЕР РЕАЛЬНОГО СЕКТОРА
LD A,IXL
CP 0X41 ;КОЛИЧЕСТВО СЕКТОРОВ ДЛЯ ЗАГРУЗКИ БОЛЬШЕ 0X40?
JR C,$+4
LD A,0X40 ;БУДЕМ ГРУЗИТЬ 0X40 СЕКТОРОВ
POP HL
LD IYH,A
CALL RDMULTI ;ЗАГРУЖАЕМ СЕКТОРА
LD A,IXH
AND 0X80
JR Z,LDFILE2
LD A,IXL
SUB IYH
JR Z,LDFILE4
JR C,LDFILE4
LD HL,0X40
ADD HL,DE
EX DE,HL
LD HL,0
ADC HL,BC
LD B,H
LD C,L
LD L,A
INC IYL
LD A,IYL
CP 0X40
JR C,LDFILE3
LDFILE4 INC SP
INC SP
INC SP
INC SP
JR LDEFILE
LDFILE3 OUT (MPAG),A ;СЛЕДУЮЩАЯ СТРАНИЦА
LD A,L
LD HL,0X8000
CALL RDMULTI
LDFILE2 POP DE
POP BC
PUSH HL
CALL RDFATZP
CALL LST_CLS
POP HL
JR C,LDEFILE
LD A,IXL
CP IXH
JR C,LDEFILE
LD A,H
AND A
JR NZ,LD_FILE
LD HL,0X8000
INC IYL
LD A,IYL
CP 0X40
JR C,LDFILE0
LDEFILE XOR A
JP WR_STAT
LDMINI EXX
LD L,A
LD A,IXH
LD H,A
CP L
JR C,$+3
LD A,L
EXX
PUSH BC
PUSH DE
PUSH AF
PUSH HL
CALL REALSEC
POP HL
POP AF
CALL RDMULTI
POP DE
POP BC
LD A,H
AND A
RET Z
PUSH HL
CALL RDFATZP
CALL LST_CLS
POP HL
JR C,LDEFILE
EXX
LD A,L
SUB H
EXX
JR NC,LDMINI
JR LDEFILE
SAVEZP LD (HL),E
INC HL
LD (HL),D
INC HL
LD (HL),C
INC HL
LD (HL),B
INC HL
RET
LOADZP LD E,(HL)
INC HL
LD D,(HL)
INC HL
LD C,(HL)
INC HL
LD B,(HL)
INC HL
RET
;ЧТЕНИЕ СЕКТОРА DIR ПО НОМЕРУ BC
RDDIRSC PUSH BC
LD D,B
LD E,C
LD BC,0
LD A,0X10
CALL BCDE_A
LD A,E
PUSH AF
LD A,(BYTSSEC)
PUSH AF
CALL BCDE_A
LD HL,TDIRCLS
EX DE,HL
ADD HL,HL
ADD HL,HL
ADD HL,DE
CALL LOADZP
CALL REALSEC
POP AF
DEC A
LD L,A
POP AF
AND L
LD L,A
LD H,0
ADD HL,DE
EX DE,HL
LD HL,0
ADC HL,BC
LD B,H
LD C,L
CALL LOADLST
POP BC
RET
;ПРОВЕРКА НА ПОСЛЕДНИЙ КЛАСТЕР В ЦЕПОЧКЕ
LST_CLS LD A,(CAL_FAT) ;ЗАВИСИТ ОТ РАЗРЯДНОСТИ ФАТА
AND A
JR NZ,LST_CL1
LD HL,0X0FF7 ;ПРОВЕРКА ДЛЯ ФАТ12
SBC HL,DE
RET
LST_CL1 DEC A
JR NZ,LST_CL2
LST_CL3 LD HL,0XFFF7 ;ПРОВЕРКАМ ДЛЯ ФАТ16 И МЛАДШИХ БИТ ФАТ32
SBC HL,DE
RET
LST_CL2 LD HL,0X0FFF ;ПРОВЕРКА ДЛЯ СТАРШИХ БИТ ФАТ32
SBC HL,BC
RET NZ
JR LST_CL3
;ЧТЕНИЕ СЛЕДУЮЩЕГО НОМЕРА КЛАСТЕРА В ЦЕПОЧКЕ
RDFATZP LD A,(CAL_FAT) ;ЧТЕНИЕ ЗАВИСИТ ОТ РАЗРАДНОСТИ ФАТА
AND A
JR Z,RDFATS0 ;ПЕРЕХОД ВПЕРЕД ДЛЯ ФАТ12
DEC A
JR Z,RDFATS1 ;ПЕРЕХОД ВПЕРЕД ДЛЯ ФАТ16
EX DE,HL ;ЗДЕСЬ ЧТЕНИЕ ДЛЯ ФАТ32
ADD HL,HL
EX DE,HL
LD HL,0
ADC HL,BC
ADC HL,BC ;УМНОЖИЛИ НОМЕР КЛАСТЕРА НА 2
LD A,E
LD E,D
LD D,L
LD C,H
LD B,0 ;РАЗДЕЛИЛИ НОМЕР КЛАСТЕРА НА 256
CALL RDFATS2 ;ЧИТАЕМ МЛАДШИЕ 16 БИТ ИСПОЛЬЗУЯ ЧТЕНИЕ ДЛЯ ФАТ16
INC HL
LD C,(HL)
INC HL
LD B,(HL) ;ПРОЧИТАЛИ ПОСЛЕДУЮЩИЕ СТАРШИЕ 16 БИТ
RET
;ЧТЕНИЕ 16 БИТНОГО НОМЕРА КЛАСТЕРА ИЗ ЦЕПОЧКИ ДЛЯ ФАТ16
RDFATS1 LD BC,0
LD A,E
LD E,D
LD D,C ;РАЗДЕЛИЛИ НОМЕР КЛАСТЕРА НА 256, СТАРШИЕ 16 БИТ =0
RDFATS2 PUSH AF ;ОБЩЕЕ ЧТЕНИЕ 16 БИТНОГО НОМЕРА КЛАСТЕРА ДЛЯ ФАТ16/32
PUSH BC
LD HL,FATSTR
CALL BCDEHLP ;ПРИБАВИЛИ СМЕЩЕНИЕ ОТ НАЧАЛА ФАТ ТАБЛИЦЫ
CALL LOADLST ;ЗАГРУЗИЛИ ВЫЧИСЛЕННЫЙ НОМЕР СЕКТОРА
POP BC
POP AF
LD E,A
LD D,0
ADD HL,DE
ADD HL,DE ;ВЫЧИСЛИЛИ СМЕЩЕНИЕ ДО НУЖНОГО НОМЕРА В ЗАГРУЖЕННОМ СЕКТОРЕ
LD E,(HL)
INC HL
LD D,(HL) ;ПОЛУЧИЛИ 16 БИТ НОМЕРА КЛАСТЕРА
RET
;ЧТЕНИЕ 12 БИТНОГО НОМЕРА КЛАСТЕРА ИЗ ЦЕПОЧКИ ДЛЯ ФАТ12
RDFATS0 LD H,D
LD L,E
ADD HL,HL
ADD HL,DE ;HL=HL*3
SRL H
RR L ;HL=HL/2 - В ИТОГЕ УМНОЖИЛИ НОМЕР КЛАСТЕРА НА 1,5
LD A,E ;A-НАМ ИНТЕРЕСЕН ТОЛЬКО БИТ НОМЕР СТАРОГО НОМЕРА КЛАСТЕРА
LD E,H
LD D,0
LD B,D
LD C,D ;РАЗДЕЛИЛИ НОМЕР КЛАСТЕРА НА 256
SRL E
PUSH AF
PUSH HL
LD HL,FATSTR
CALL BCDEHLP ;ПРИБАВИЛИ СМЕЩЕНИЕ ОТ НАЧАЛА ФАТ ТАБЛИЦЫ
CALL LOADLST ;ЗАГРУЗИЛИ ВЫВЧИСЛЕННЫЙ СЕКТОР
POP BC
LD A,B
AND 1
LD B,A ;BC=СМЕЩЕНИЕ В ЗАГРУЖЕННОМ СЕКТОРЕ
ADD HL,BC ;HL=АДРЕС ОТКУДА ЧИТАТЬ БАЙТЫ НОМЕРА КЛАСТЕРА
LD B,(HL) ;ПРОЧИТАЛИ МЛАДШУЮ ЧАСТЬ НОМЕРА КЛАСТЕРА
INC HL ;АДРЕС СЛЕДУЮЩЕГО БАЙТА
LD A,H
CP HIGH (BUF_512)+2 ;ПРОВЕРКА НА ПЕРЕХОД ГРАНИЦЫ ЗАГРУЖЕННОГО СЕКТОРА
JR NZ,RDFATS4
PUSH BC ;ВЫХОД ЗА ПРЕДЕЛЫ ТЕКУЩЕГО ЗАГРУЖЕННОГО СЕКТОРА
LD BC,0
INC DE
CALL LOADLST ;ЗАГРУЖАЕМ СЛЕДУЮЩИЙ СЕКТОР ФАТ ТАБЛИЦЫ
POP BC
RDFATS4 POP AF
LD D,(HL) ;ЧИТАЕМ СТАРШИЕ БИТЫ НОМЕРА КЛАСТЕРА
LD E,B ;ТЕПЕРЬ DE=НОМЕР СЛЕДУЮЩЕГО КЛАСТЕРА В ЦЕПОЧКЕ
LD BC,0
RRA ;ПРОВЕРЯЕМ БИТ 0 СТАРОГО НОМЕРА КЛАСТЕРА
JR NC,RDFATS3
SRL D ;СДВИГАЕМ НОМЕР ПРОЧИТАННОГО НОМЕРА КЛАСТЕРА В МЛАДШИЕ 12 БИТ
RR E
SRL D
RR E
SRL D
RR E
SRL D
RR E
RDFATS3 LD A,D
AND 0X0F
LD D,A ;СБРОСИЛИ НЕЗНАЧАЩИЕ СТАРШИЕ 4 БИТА У ПОЛУЧЕННОГО НОМЕРА КЛАСТЕРА
RET
;ВЫЧИСЛЕНИЕ РЕАЛЬНОГО СЕКТОРА
;НА ВХОДЕ BCDE=НОМЕР КЛАСТЕРА FAT
;НА ВЫХОДЕ BCDE=НОМЕР РЕАЛЬНОГО СЕКТОРА
REALSEC LD A,B
OR C
OR D
OR E
JR NZ,REALSE1 ;BCDE=0?
LD HL,SEC_FAT ;ЭТО ROOT ДИРЕКТОРИЯ У ФАТ12/16
LD DE,(FATSTR) ;МЕСТОПОЛОЖЕНИЕ ROOT ДИРЫ СРАЗУ ПОСЛЕ ФАТ ТАБЛИЦЫ
LD BC,(FATSTR+2)
PUSH HL
CALL BCDEHLP ;ПРИБАВИЛИ К НАЧАЛУ ФАТ ТАБЛИЦЫ ЕЕ РАЗМЕР
POP HL
JP BCDEHLP ;ПРИБАВИЛИ ЕЩЕ РАЗ И ПОЛУЧИЛИ НОМЕР СЕКТОРА НАЧАЛА ROOT ДИРЫ
REALSE1 LD HL,0XFFFE
EX DE,HL
ADD HL,DE
EX DE,HL
INC HL
ADC HL,BC ;HLDE=НОМЕР КЛАСТЕРА-2
LD A,(BYTSSEC) ;НУЖНО УМНОЖИТЬ НА РАЗМЕР КЛАСТЕРА
JR REALSE2
REALSE3 SLA E
RL D
RL L
RL H
REALSE2 RRCA
JR NC,REALSE3 ;УМНОЖИЛИ НА РАЗМЕР КЛАСТЕРА
LD B,H
LD C,L
LD HL,STARTRZ
CALL BCDEHLP ;ПРИБАВИЛИ СМЕЩЕНИЕ ОТ НАЧАЛА ДИСКА
LD HL,FRSTDAT
JP BCDEHLP ;ПРИБАВИЛИ СМЕЩЕНИЕ ОТ НАЧАЛА РАЗДЕЛА
;BCDE=BCDE/512
BCDE200 LD E,D
LD D,C
LD C,B
LD B,0
LD A,2
JR BCDE_A
;BCDE>>A=BCDE
BCDE_A1 SRL B
RR C
RR D
RR E
BCDE_A RRCA
JR NC,BCDE_A1
RET
;(ADR)-BCDE=BCDE
BCDEHLM LD A,(HL)
INC HL
SUB E
LD E,A
LD A,(HL)
INC HL
SBC A,D
LD D,A
LD A,(HL)
INC HL
SBC A,C
LD C,A
LD A,(HL)
SBC A,B
LD B,A
RET
;(ADR)+BCDE=BCDE
BCDEHLP LD A,(HL)
INC HL
ADD A,E
LD E,A
LD A,(HL)
INC HL
ADC A,D
LD D,A
LD A,(HL)
INC HL
ADC A,C
LD C,A
LD A,(HL)
ADC A,B
LD B,A
RET
;HLDE+BC=HLDE
HLDEPBC EX DE,HL
ADD HL,BC
EX DE,HL
LD BC,0
ADC HL,BC
RET
;BCDE-(ADR)=BCDE
HLBCDEM LD A,E
SUB (HL)
INC HL
LD E,A
LD A,D
SBC A,(HL)
INC HL
LD D,A
LD A,C
SBC A,(HL)
INC HL
LD C,A
LD A,B
SBC A,(HL)
LD B,A
RET
;ГРУЗИЛКА ОДНОГО СЕКТОРА
LOADLST CALL CPNUMSC
JR NZ,LOADLST1
LD HL,BUF_512
RET
LOADLST1 LD HL,BUF_512 ;АДРЕС БУФЕРА СЕКТОРА
LD A,1 ;ГРУЗИТЬ 1 СЕКТОР
PUSH HL
CALL RDMULTI ;ЗАГРУЗИЛИ СЕКТОР
POP HL ;НА ВЫХОДЕ HL=АДРЕС НАЧАЛА БУФЕРА ЗАГРУЖЕННОГО СЕКТОРА
RET
;ПРОВЕРКА НА УЖЕ ЗАГРУЖЕННЫЙ СЕКТОР
CPNUMSC LD HL,LSTLOAD
LD A,(HL)
INC HL
CP E
RET NZ
LD A,(HL)
INC HL
CP D
RET NZ
LD A,(HL)
INC HL
CP C
RET NZ
LD A,(HL)
CP B
RET
;ПОДАЧА КОМАНДЫ В SD КАРТУ БЕЗ ПАРАМЕТРОВ
OUTCOM PUSH BC
LD BC,0X0600+SD_SEND ;ВЫДАТЬ В ПОРТ 6 БАЙТ
OTIR
POP BC
RET
;ВЫДАЧА В ПОРТ SD КАРТЫ КОМАНДЫ С ПАРАМЕТРОМ 0
OUT_COM PUSH BC
LD BC,SD_SEND
OUT (C),A ;ОТПРАВИЛИ КОД КОМАНДЫ
XOR A
OUT (C),A ;БИТЫ 31-24 ПАРАМЕТРА
NOP
OUT (C),A ;БИТЫ 23-16 ПАРАМЕТРА
NOP
OUT (C),A ;БИТЫ 15-8 ПАРАМЕТРА
NOP
OUT (C),A ;БИТЫ 7-0 ПАРАМЕТРА
DEC A
OUT (C),A ;БЕЗ CRC16
POP BC
RET
SECM200 PUSH HL
PUSH BC
LD A,CMD_58
CALL OUT_COM
CALL IN_OOUT
LD BC,SD_RSTR
IN H,(C)
NOP
IN A,(C)
NOP
IN A,(C)
NOP
IN A,(C)
BIT 6,H
POP HL
JR NZ,SECN200
EX DE,HL
ADD HL,HL
EX DE,HL
ADC HL,HL
LD H,L
LD L,D
LD D,E
LD E,0
SECN200 LD A,CMD_18
LD C,SD_SEND
OUT (C),A
NOP
OUT (C),H
NOP
OUT (C),L
NOP
OUT (C),D
NOP
OUT (C),E
LD A,0XFF
OUT (C),A
POP HL
RET
IN_OOUT EXX
LD DE,0X20FF
IN_WAIT IN A,(SD_RSTR)
CP E
JR NZ,IN_EXIT
IN_NEXT DEC D
JR NZ,IN_WAIT
IN_EXIT EXX
RET
CMD00 DB 0X40,0X00,0X00,0X00,0X00,0X95;GO_IDLE_STATE
CMD08 DB 0X48,0X00,0X00,0X01,0XAA,0X87;SEND_IF_COND
CMD16 DB 0X50,0X00,0X00,0X02,0X00,0XFF;SET_BLOCKEN
;МНОГО СЕКТОРНОЕ ЧТЕНИЕ С SD КАРТЫ
RDMULTI EX AF,AF'
CALL SECM200
EX AF,AF'
LD BC,SD_RSTR
RDMULT1 EX AF,AF'
CALL IN_OOUT
CP 0XFE
JR NZ,$-5
INIR
NOP
INIR
NOP
IN A,(C)
NOP
IN A,(C)
EX AF,AF'
DEC A
JR NZ,RDMULT1
LD A,CMD_12
CALL OUT_COM
CALL IN_OOUT
INC A
JR NZ,$-4
RET
;ВЫБОРКА НОМЕРА КЛАСТЕРА ИЗ ФАЙЛОВОГО ОПИСАТЕЛЯ
RD_CLAS EX DE,HL
LD DE,0X14 ;СТАРШИЕ 16 БИТ ЧИТАЕМ ИЗ СМЕЩЕНИЯ +20
ADD HL,DE
LD C,(HL)
INC HL
LD B,(HL)
LD E,5 ;МЛАДШИЕ 16 БИТ ЧИТАЕМ ИЗ СМЕЩЕНИЯ +26
ADD HL,DE
LD E,(HL)
INC HL
LD D,(HL)
INC HL
RET
;ПРОВЕРКА ПО МАСКЕ
COMPARE LD DE,FB_EXT
LD B,0X0B
LD A,(DE)
CP (HL)
RET NZ
INC HL
INC DE
DJNZ $-5
RET
;РАСПАКОВЩИК ПУТИ К ФАЙЛУ
FNDBUF LD BC,0X0802
LD DE,FB_EXT
FNDBUF4 LD A,(HL)
INC HL
CP "."
JR Z,FNDBUF2
CP "/"
JR Z,FNDBUF5
LD (DE),A
INC DE
DJNZ FNDBUF4
LD A,(HL)
AND A
RET Z
INC HL
JR FNDBUF3
FNDBUF5 LD A,C
AND A
RET Z
FNDBUF2 LD A,B
AND A
JR Z,FNDBUF3
LD A," "
LD (DE),A
INC DE
DJNZ $-2
FNDBUF3 LD B,3
DEC C
DEC HL
LD A,(HL)
CP "/"
JR Z,FNDBUF4
INC HL
JR FNDBUF4
RAMCEND
DEPHASE