Calc.com
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
Diskname.com
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
E_prof.lpr
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 ;готовим порты и выходим
ide+5sby.blk
Реализация режима 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
.......
Продолжение инсталляции