ORG
#5DC0
LD C,#43 ;анализируем командную строку
RST #10
RET C
JR Z,#5DD0 ;если
было указано имя файла и путь к нему, путь открывается
;HL указывает на
имя файла
;Работаем с файлом под курсором
LD C,#8B ;пишем "Please wait" на месте курсора
RST #10
LD C,#8A ;читаем параметры панельного
курсора, в A - номер файла в каталоге
RST #10
LD C,#26 ;открываем файл номер A в текущем каталоге
JR #5DD3
;Если был
указан путь к файлу, то открываем файл по его имени.
#5DD0 EXX ;HL-имя файла
LD C,#34 ;открываем
файл по его имени в HL
#5DD3 RST #10
RET C
EXX ;HL-описатель файла
LD IX,0 ;счётчик
КС файла (изначально там 0)
LD DE,#001A ;+26
- место в описателе под КС файла
ADD HL,DE
LD (#5E0E+1),HL ;сохраняем адрес КС файла в описателе
LD DE,#FFF6
ADD HL,DE ;+16
- самый старший байт длины файла
LD D,(HL) ;самый
старший байт длины файла (*65536)
DEC HL
LD E,(HL) ;старший
байт длины файла (*256)
DEC HL
LD A,(HL) ;младший
байт длины файла
LD B,A ;сначала
считаем сумму младших байтов с конца файла
AND A ;если младший байт длины файла=0, то
длина кратна 256 байт
JR NZ,#5DEF ;если
длина файла не кратна 256 байт, то в DE будет номер
;последнего блока файла
DEC DE ;последний блок файла (длина
выражается в нумерации 1..х,
;а номер блока выражается в 0..х, поэтому уменьшаем на 1)
;сейчас
читаем последний блока файла в электронный диск и подсчитываем сумму байтов в
блоке.
#5DEF LD C,#2D ;читаем
блок DE в электронный диск
RST #10
RET C
PUSH BC
EXX ;HL-адрес блока на электронном диске
POP BC
LD D,0
#5DF8 LD E,(HL) ;суммируем
все байты в блоке
ADD IX,DE
INC HL
DJNZ #5DF8 ;пока
не посчитаем весь блок
EXX
LD A,D ;номер
блока проверяем на 0
OR E
DEC DE ;уменьшаем номер блока (КС
считается с конца файла)
LD B,0 ;256 байт в блоке
JR NZ,#5DEF ;если
не все блоки, то считаем снова
PUSH IX ;тут
находится подсчитанная сумма всех байт в файле
POP DE
XOR A ;CF=0
SBC HL,HL ;обнуляем HL
SBC HL,DE ;КС=0-сумма
#5E0E LD (#0000),HL ;заносим КС в описатель
LD C,#28 ;закрываем файл с сохранением
описателя
RST #10
RET C
LD C,#02 ;делаем flush
RST #10
RET C
XOR A ;выходим
RET
ORG
#5DC4
BEGIN LD C,#45 ;берем
адрес внутреннего буфера командной строки в HL'
RST #10
EXX
LD BC,#FFFB ;смещение
-5
ADD HL,BC
LD E,(HL) ;берем
адрес первого символа после имени запускаемой программы
INC HL
LD D,(HL)
A0 LD A,(DE)
INC DE
CP #0D ;конец
строки?
JR Z,A3 ;в
командной строке не было введено ничего, поэтому работаем с устройством
;текущей панели
CP #20
JR Z,A0 ;ищем
первый значимый байт (имя устройства)
;Тут недоработка. Если указать в
командной строке всякую ерунду типа diskname 12345, то символ "1" программа расценит как имя
устройства и установит признак того, что имя уже введено, тогда как дальше
программа не распознает символ ":". После этого кусок
"2345" пойдет как имя устройства, и программа переименует текущее устройство.
Для устранения этой недоработки можно следующий кусок кода исключить, а вместо
него ввести исправленный:
Этот кусок кода добавляем
LD B,A ;потенциальное
имя устройства сохраняем
EX DE,HL
LD A,(HL) ;проверяем
следующий байт на ":"
CP ":"
DEC HL
JR NZ,A3 ;если
нет, то прямо переходим к вводу текста в окне
LD A,B ;все
задано верно, поэтому восстанавливаем
LD (A4+1),A ;имя устройства и заносим
его как признак того, что имя
;задано в командной строке
|
Убираем этот кусок
LD (A4+1),A ;устанавливаем
признак того, что работаем
;с параметрами, указанными в командной строке, и что не
надо выводить окно
EX DE,HL
LD A,(HL) ;следующий байт после имени устройства
CP ":" ;должен
быть двоеточие
DEC HL
JR NZ,A1 ;неверно, поэтому полагаем, что сразу
указано новое имя устройства
;в командной строке
|
LD A,(HL) ;название устройства
LD C,#4A ;преобразуем
в номер устройства
RST #10
RET NZ ;неправильное имя устройства
LD B,A
LD C,#1C ;переключаемся
на введенное устройство
RST #10
RET C
INC HL ;адрес указателя ":"
INC HL ;адрес нового имени устройства,
введенного в командной строке
;тут в HL передается адрес с новым названием
устройства
A1 PUSH HL
LD A,#0D ;ищем
конец строки в пределах 12 байт имени (11 байт имя +1 байт #0D)
LD BC,12
CPIR
LD BC,11 ;длина имени
POP DE ;новое имя
JR NZ,A2 ;код
конца строки не найден
SBC HL,DE ;длина
введенного имени+1
LD C,L
LD B,H ;=0
DEC BC ;реальная длина введенного имени
LD A,B
OR C
JR Z,A3 ;если
длина 0
A2 EX DE,HL ;переносим имя в буфер
LD DE,BUFER
LDIR
A3 LD C,#8A
RST #10
EXX
LD A,B ;номер текущей панели
LD BC,#0001 ;координаты для левой панели
AND A
JR Z,$+5
LD BC,#1016 ;координаты для правой панели
LD IX,WIN ;заносим
в вектор окна
LD (IX+0),B
LD (IX+6),C
LD DE,0 ;0-й блок устройства
LD C,6 ;читаем в кэш
RST #10
RET C
EXX
INC HL
INC HL
LD (NAME),HL ;адрес имени устройства в
кэше
LD (BLOCK0),DE ;адрес 0-го блока устройства в
кэше
A4 LD A,0 ;номер
устройства
OR A
JR NZ,A5 ;если
номер устройства был указан в командной строке
CALL INPUT1 ;переносим название текущего устройства в
буфер
LD IX,WIN ;переносим
цвета из вектора Unicolor в
вектор окна
LD HL,(UNCO)
LD (WIN+4),HL
LD A,2
LD C,#61 ;открываем окно
RST #10
LD C,#66 ;печатаем текст окна
RST #10
CALL INPUT ;вводим имя устройства и помещаем его в буфер
JR NZ,EXIT ;если
был выход при помощи спец. клавишей
A5 LD DE,(NAME) ;адрес имени диска в кэше
LD HL,BUFER
LD B,11
A6 LD A,(DE) ;сравниваем введенное
имя с названием диска
CP (HL)
JR NZ,A7 ;если
не равны то переносим имя и сохраняем 0-й блок
INC HL
INC DE
DJNZ A6
JR EXIT ;если имена совпадают, то просто
выходим
A7 LD DE,(NAME) ;сохраняем 0-й блок из кэша
LD HL,BUFER
LD BC,11
LDIR
LD DE,(BLOCK0)
LD C,#2E
RST #10
RET C
LD C,#02 ;делаем flush
RST #10
RET C
EXIT XOR A ;выход
LD A,#F8
RET
DEFM "UnCo"
DEFB 2
UNCO DEFB #0F,#01
WIN DEFB 0,6,3,15,15,1,1,17
DEFM "Label:"
TEXT DEFM
"12345678ABC"
DEFB 3
;Ввод
текста в окно
INPUT LD HL,BUFER ;перенос текста
из буфера в вектор окна
LD DE,TEXT
LD BC,8
LDIR
INPUT0 LD HL,#0106 ;смещение
в окне для нового текста
LD C,#6B
RST #10
LD HL,TEXT
LD A,11 ;длина вводимого текста
LD DE,#0B00 ;E'CSR,
M'CSR
LD BC,#016E ;высота
окна =1 + код рестарта
RST #10 ;вводим текст
RET NZ ;если был выход по
спецклавише
AND A
JR Z,INPUT0 ;если
ничего не ввели
INPUT1 LD BC,11 ;перенос
текста из вектора окна в буфер
LD DE,TEXT
LDIR
XOR A
RET
BUFER DEFS 11
NAME EQU BEGIN-4
BLOCK0 EQU
BEGIN-2
ORG #8000
DEFW INIT ;адрес ПП инициализации принтера
DEFW B_OUT ;адрес
ПП вывода байта на принтер
DEFW B_OUT6 ;адрес
команды выхода из ПП вывода байта в порт
A_OUT DEFW B_OUT2 ;адрес
ПП вывода байта в порт
PARAM DEFB
3 ;этот байт задается внешней программой и служит для
управления
;печатью
DEFW 0,0
DEFB 1 ;признак lpr
DEFW 0
;ПП вывода байта в регистре A на принтер
B_OUT LD HL,PARAM ;байт
с параметрами печати
CP #0D ;байт
ВК?
JR NZ,B_OUT1 ;если нет, то просто
выводим байт и выходим
BIT 0,(HL) ;проверка,
печатать ли #0A после #0D
JR Z,B_OUT1 ;не печатать
CALL B_OUT1 ;выводим #0D
RET C
LD A,#0A ;печатаем #0A
B_OUT1 LD HL,(A_OUT) ;адрес ПП вывода байта в
порт
JP (HL) ;переходим
;ПП вывода байта А в порт
B_OUT2 DI ;на
время работы с портами запрещаем прерывания
LD E,A ;сохраняем
байт
LD A,#0F ;выходные
сигналы порта в 1
OUT (#5F),A
B_OUT3 EI
LD C,#09 ;проверка, нажата ли какая-либо
клавиша
RST #10
JR NZ,B_OUT4 ;не нажата
LD C,#07 ;что за клавиша нажата?
RST #10
CP #10 ;SS+A?
JR Z,B_OUT7 ;выход с ошибкой
CP #16 ;BREAK?
JR Z,B_OUT7 ;выход с ошибкой
B_OUT4 DI
IN A,(#5F)
RLA ;BSY→CF
JR C,B_OUT3 ;если принтер занят, то ждем
готовности
LD A,E
OUT (#3F),A ;посылаем байт
LD A,#0E ;Strobe=0
OUT (#5F),A
NOP ;пауза
NOP
B_OUT5 XOR A
LD A,#0F ;Strobe=1
OUT (#5F),A
EI
B_OUT6 RET
;Выход с ошибкой 151 - принтер не готов
B_OUT7 LD A,151
SCF
RET
;ПП инициализации принтера
INIT CP #FE
RET NC
INIT1 LD A,0 ;признак
инициализации
OR A
RET NZ ;если ≠0, то инициализация
проводилась
LD A,#88 ;РУС для ВВ55
LD (INIT1+1),A ;заносим в признак инициализации
OUT (#7F),A ;заносим в РУС
JR B_OUT5 ;готовим
порты и выходим
Реализация режима Standby:
DEFW INSTALL
.......
Заголовок драйвера
.......
;+#29 от начала драйвера
STIME DEFW
#01F4 ;значение времени до
включения режима Standby
устанавливается
;программой ide_tune.com
DEFW 0
;ПП установки Standby. Вызывается каждое прерывание
STANDBY LD HL,0 ;счётчик времени, которое
осталось до включения Standby
DEC HL ;уменьшаем каждое прерывание
LD (STANDBY+1),HL ;сохраняем
LD A,L ;проверка
на 0
OR H
RET NZ ;пока не 0, Standby не включаем
SBY1 IN A,(#F0) ;ждем
готовности винчестера
RLCA
JR C,SBY1
LD A,#A0 ;устройство
Master (было бы корректнее брать этот байт
из заголовка
OUT (#D0),A ;драйвера +#28)
LD A,#E0 ;команда Standby immediate
OUT (#F0),A
RET
;ПП инсталляции на устройство
INSTALL DI
EX AF,AF' ;сохраняем A
LD HL,(STIME) ;время
до включения Standby из заголовка драйвера
LD A,H ;проверка
на 0
OR L
JR Z,INST2 ;если
равно 0, то режим Standby не
задействуется
LD (STANDBY+1),HL ;заносим в ПП установки Standby
INST1 LD A,0 ;признак
установки параметра времени Standby
OR A
JR NZ,INST2 ;если
уже установили, то повторно не надо устанавливать
OR #FF ;установка
признака
LD (INST1+1),A
LD HL,STANDBY ;добавление ПП установки Standby в обработку прерывания
LD C,#1E
RST #10
RET C
INST2 EX AF,AF' ;восстанавливаем A
.......
Продолжение инсталляции