Протокол будет таким
Сначала на шину адреса устанавливаем значения 19, 23, 87. Они отличаются одним битом, поэтому шума между ними быть не должно.
Далее, компьютер читает адреса 86,87,86,87,86,87... каждый байт 86 является тактовым импульсом, т.е. подтверждением приема/передачи байта.
Если синхронизация удалась, то МК выставляет на шину данных ERR_START, а после тактового импульса ERR_OK_WAIT. Код ERR_OK_WAIT может держаться неопределенное кол-во тактов. В это время происходит инициализация флешки.
Потом ERR_OK_WAIT меняется на ERR_OK_NEXT если все нормально. Или возвращается код ошибки.
Компьютер должен переключить порт на выход и передать команду. В примере ниже команда BOOT - единственный байт 0
На это МК отвечает ERR_OK_WAIT (много раз), ERR_OK_ADDR, адрес загрузки L, адрес загрузки H, ERR_OK_WAIT (много раз)
Потом выдает содержимое файла блоками: 0, длина L, длина H, данные (HL раз), ERR_OK_WAIT (много раз)
Если данных не осталось, выдает ERR_OK_READ
Code: Select all
.org 0h
DATA_PORT = 0EE00h
ADDR_PORT = 0EE01h
CTL_PORT = 0EE03h
SEND_MODE = 10001011b ; Настройка: 1 0 0 A СH 0 B CL 1=ввод 0=вывод
RECV_MODE = 10011011b
ERR_START = 040h
ERR_WAIT = 041h
ERR_OK_DISK = 042h
ERR_OK = 043h
ERR_OK_READ = 044h
ERR_OK_ENTRY = 045h
ERR_OK_WRITE = 046h
ERR_OK_ADDR = 047h
Entry:
; Первым этапом происходит синхронизация с контроллером
; 256 попыток. Для этого в регистр C заносится 0
; А в стек заносится адрес перезагрузки 0C000h
LXI B, 0F800h
PUSH B
JMP Boot
NOP
;----------------------------------------------------------------------------
; Отправка и прием байта
Rst1:
INX H ; HL = ADDR_PORT
MVI M, 86
MVI M, 87
DCX H ; HL = DATA_PORT
MOV A, M
RET
;----------------------------------------------------------------------------
; Ожидание готовности МК
Rst2:
WaitForReady:
Rst 1
CPI ERR_WAIT
JZ WaitForReady
RET
;----------------------------------------------------------------------------
RetrySync:
; Попытки
DCR C
RZ ; Ошибка синхронизации, перезагрузка
Boot:
; Режим передачи (освобождаем шину) и инициализируем HL
MVI A, RECV_MODE
CALL SetMode
; Начало любой команды
MVI M, 19
MVI M, 23
MVI M, 87
; Если есть синхронизация, то контроллер ответит ERR_START
Rst 1
CPI ERR_START
JNZ RetrySync
; Дальше будет ERR_OK_WAIT, ERR_OK_NEXT
; Инициализация флешки
Rst 2
CPI ERR_OK_ADDR
JNZ Rst1 ; Ошибка, освобождаем шину и перезагрузка
; ERR_OK_NEXT высталенный МК будет висеть на шине до следующего RST,
; только после него МК освободит шину и мы сможем включить режим передачи.
Rst 1
; Режим передачи
MVI A, SEND_MODE
CALL SetMode
; Код команды
XRA A
Rst 1
; МК читает данные во время тактового импульса, т.е. он уже их прочитал.
; Включаем режим приема, т.е. освобождаем шину.
; Режим приема
MVI A, RECV_MODE
CALL SetMode
; МК захватит шину во время тактового импульса (первого RST)
; Дальше будет ERR_OK_WAIT, ERR_OK_RKS
Rst 2
CPI ERR_OK_RKS
JNZ Rst1 ; Ошибка, освобождаем шину и перезагрузка
; Удаляем из стека 0F800h
POP B
; Адрес загрузки в BC
Rst 1
MOV C, A
Rst 1
MOV B, A
; Сохраняем в стек адрес запуска
PUSH B
; Подождать, пока МК прочитает очередной блок денных
RecvLoop:
Rst 2
CPI ERR_OK_READ
JZ Rst1 ; Всё загружено, освобождаем шину и запуск
ORA A
JNZ 0F800h ; Ошибка, перезагрузка (не отпускаем контроллер)
; Принять очередной блок
Rst 1
MOV E, A
Rst 1
MOV D, A
RecvBlock:
Rst 1
STAX B
INX B
DCX D
MOV A, E
ORA D
JNZ RecvBlock
JMP RecvLoop
; Прием/передача
SetMode:
LXI H, CTL_PORT
MOV M, A
DCX H
DCX H ; HL = ADDR_PORT
RET
.End
108 байт.