; _ ____ ____ __ ; | | | _ \ / ___|___ _ __ / _| ; | | | | | | | / _ \| '_ \| |_ ; | |___| |_| | |__| (_) | | | | _| ; |_____|____/ \____\___/|_| |_|_| ; _____ ____ _ _ ____ _ ; | ___|__ _ __ / ___| _ __ _ __(_)_ __ | |_ ___ _ __ / ___|___ _ __ ___ _ __ _ _| |_ ___ _ __ ; | |_ / _ \| '__| \___ \| '_ \| '__| | '_ \| __/ _ \ '__| | | / _ \| '_ ` _ \| '_ \| | | | __/ _ \ '__| ; | _| (_) | | ___) | |_) | | | | | | | || __/ | | |__| (_) | | | | | | |_) | |_| | || __/ | ; |_| \___/|_| |____/| .__/|_| |_|_| |_|\__\___|_| \____\___/|_| |_| |_| .__/ \__,_|\__\___|_| ; |_| |_| ;----------------------------------------------------------------------; ; Версия проги и инфо для понтов: DEFINE Ver_ID "0.6 beta" DEFINE e_mail "Tolik.Trek@gmail.com" ; Подгрузка файла с константами BIOS и DSS: include 'Shared_Includes/constants/sp2000.inc' include 'Shared_Includes/constants/dss_equ.inc' include 'Shared_Includes/constants/BIOS_equ.inc' ; Макросы MACRO _PrintStr LD C,Dss.PChars RST ToDSS ENDM ;----------------------------------------------------------------------; DEFINE App_EXE_Version 1 stack_point EQU #C000 ; адрес стека SP_Win EQU 64 ; мнимый контроль пересечения стека с кодом org_addr EQU #8000 + CLP_Buffer ; адрес компиляции. program_start EQU START code_addr EQU START Loader_length EQU 0 ; _______ _______ ____ __ _ ; | ____\ \/ / ____| | _ \ _ __ ___ / _(_)_ __ ; | _| \ /| _| | |_) | '__/ _ \ |_| \ \/ / ; | |___ / \| |___ | __/| | | __/ _| |> < ; |_____/_/\_\_____| |_| |_| \___|_| |_/_/\_\ ;-----------------; INCLUDE 'Shared_Includes/constants/EXE_Header.z80' ORG org_addr ;-----------------; ; __ __ _ ; | \/ | __ _(_)_ __ ; | |\/| |/ _` | | '_ \ ; | | | | (_| | | | | | ; |_| |_|\__,_|_|_| |_| START: ;-----------------; Чистим буфер акселем DI LD HL,Buffer LD D,D ; Установить размер блока LD A,255 ; Размер блока LD C,C LD A,0 LD (HL),A LD B,B ; Выключаем аксель EI ;-----------------; Сохраняем текущие страницы ; IN A,(SLOT0) ; LD (page0_save),A IN A,(SLOT1) LD (page1_save),A IN A,(SLOT2) LD (page2_save),A IN A,(SLOT3) LD (page3_save),A ;-----------------; ;-----------------; Сохраняем настройки экрана PUSH IX LD C,Dss.GetVMod RST ToDSS POP IX JP NC,1f LD HL,error_Vmode JP BadExit 1: LD (VMod),A LD A,B LD (VModPage),A ;-----------------; ;-----------------; Сохраняем дефолтные страницы DI LD A,Spec_Page OUT (SLOT3),A ; открыть спец-страницу LD HL,#FFF0 LD DE,page0_def LDI LDI LDI LDI LD A,(page3_save) OUT (SLOT3),A ; вернуть страницу EI ;-----------------; ;-----------------; LD (dss_line),IX ; Сохраняем указатель на строку запуска. LD A,(IX) ; тут DSS кладёт длину параметров ком.строки AND A ; проверяем на отсутствие параметров JP NZ,1F ; запуска в ком.строке. Если их нет, LD HL,Help_Msg ; то печатаем инструкцию и выходим _PrintStr ; из программы с нормальным кодом LD B,0 ; завершения. JP Exit ; ;-----------------; ;-----------------; Разбираем и активируем ключи 1: CALL Set_keys ; на выходе: CF=0 - нет ошибки JR NC,1F ; СF=1 - есть ошибка LD HL,error_ComStr ; Если разобрали с ошибками JP BadExit ; то выход с ошибкой ;-----------------; ;-----------------; если норм. завершение set_keys 1: ; CALL TestConf ; проверка конфы. на выходе: CF=0 - нет ошибк JR NC,1F ; СF=1 - есть ошибка LD HL,error_confFile ; Если косяк с файлом прошивки JP BadExit ; то выход с ошибкой ;-----------------; ;-----------------; если норм. завершение TestConf 1: ; CALL TakeMem ; Выделение памяти для конфы 65536 байт JR NC,1F LD HL,error_freeMem ; Если недостаточно памяти JP BadExit ; то выход с ошибкой ;-----------------; ;-----------------; если норм. завершение TakeMem 1: ; CALL Load_conf ; Читаем прошивку из файла (меняет PAGE3) LD A,(page3_save) ; восстанавливаем страницу OUT (SLOT3),A ; памяти после смены JR NC,1F LD HL,error_readConf ; Если ошибка при чтении прошивки из файла JP BadExit ; то выход с чем? Правильно, с ошибкой ;-----------------; ;-----------------; если норм. завершение Load_conf 1: LD A,(ram_blk_id) LD B,A LD A,#FE LD C,BIOS.RST_CONF.CUSTOM RST ToBIOS JP ReloadRET ;-----------------; ;-----------------; 7 бед - 1 ресет ; RESET: DI ; LD A,DCP_PAGE ; OUT (SLOT1),A ; set DCP page ; LD A,ACEX.RESET ; LD (#4400),A ; open for WR ; LD (#4600),A ; open for RD ; ; ; .LOOP: LD BC,#100 ; OUT (C),C ; LD B,0 ; OUT (C),C ; JR .LOOP ; полностью зациклить! ;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ; ; ____ _ _ ____ _____ _____ ; | _ \ ___| | ___ __ _ __| | | _ \| ____|_ _| ; | |_) / _ \ |/ _ \ / _` |/ _` | | |_) | _| | | ; | _ < __/ | (_) | (_| | (_| | | _ <| |___ | | ; |_| \_\___|_|\___/ \__,_|\__,_| |_| \_\_____| |_| ; Место, куда будет возврат после ; перезагрузки новой прошивки ;-----------------; ReloadRET: DI ;LD SP,(SP_Save) LD A,CNF_PORT.CNF_0 ; конфигурация и отключение ПЗУ OUT (SYS_PORT.OFF),A ; LD A,(page0_save) ; SET PAGE DOS ; OUT (SLOT0),A ; LD A,(page3_save) ; возврат старой страницы PAGE3 ; OUT (SLOT3),A ;-----------------; ;-----------------; Работа программы с новой прошивкой LD A,(e_key) AND A JP Z,1F LD HL,EXEfileBuff ; Запуск EXE LD BC,0040h RST ToDSS ;-----------------; ;-----------------; 1: ;DI LD A,(a_key) ; Выход без восстановления дефолтной конфы? AND A JP NZ,NextReloadRET LD B,0 LD A,#FE LD C,BIOS.RST_CONF.CUSTOM RST ToBIOS JP NextReloadRET ;******************************************************* ; _ _ _ ; | \ | | _____ _| |_ ; | \| |/ _ \ \/ / __| ; | |\ | __/> <| |_ ; |_| \_|\___/_/\_\\__| ; ____ _ _ ____ _____ _____ ; | _ \ ___| | ___ __ _ __| | | _ \| ____|_ _| ; | |_) / _ \ |/ _ \ / _` |/ _` | | |_) | _| | | ; | _ < __/ | (_) | (_| | (_| | | _ <| |___ | | ; |_| \_\___|_|\___/ \__,_|\__,_| |_| \_\_____| |_| ; Подготовка к завершению после ресета и ; возврата родной прошивки ;-----------------; NextReloadRET: DI ; ;-----------------; Затираем следы нестоковой конфы ; LD A,Spec_Page ; OUT (SLOT3),A ; открыть спец-страницу ; LD H,#FF ; LD L,H ; LD SP,HL ; PUSH HL ; PUSH HL ; PUSH HL ; PUSH HL ; PUSH HL ; PUSH HL ; PUSH HL ; PUSH HL ; LD (0FFF3h),A ; сохраняем страницы ; ld A,(page0_save) ; LD (0FFF0h),A ; DOS-PAGE ; ld A,(page1_save) ; LD (0FFF1h),A ; ld A,(page2_save) ; XOR A ; выставляем страницы, которые ставятся при ресете ; LD (0FFF0h),A ; page 0 ; LD A,5 ; LD (0FFF1h),A ; page 1 ; LD A,2 ; LD (0FFF2h),A ; page 2 ; LD A,40h ; LD (0FFF3h),A ; page 3 ; XOR A ; LD D,A ; LD E,A ; LD (#FFF4),DE ; адрес программы перезапуска ; LD (#FFFE),DE ; флаг перезапуска ; LD A,'Z' ; LD (#FFFE),A ; LD A,'X' ; LD (#FFFF),A ; флаг перезапуска ;-----------------; ; ;LD SP,(SP_Save) LD A,CNF_PORT.CNF_0 ; конфигурация и отключение ПЗУ OUT (SYS_PORT.OFF),A ;LD A,(page0_save) ; SET PAGE DOS ;OUT (SLOT0),A LD A,(page1_save) OUT (SLOT1),A ; Глянуть, может не надо возвращать одну из страниц??? LD A,(page3_save) OUT (SLOT3),A ;JP NormExit ;******************************************************* ; _____ _ _ ____ _ ; | ____|_ _(_) |_ | _ \ _ __ ___ ___( )___ ; | _| \ \/ / | __| | |_) | '__/ _ \ / __|// __| ; | |___ > <| | |_ | __/| | | (_) | (__ \__ \ ; |_____/_/\_\_|\__| |_| |_| \___/ \___| |___/ ;-----------------; NormExit: LD HL,WellDone _PrintStr LD B,0 JR Exit ;-----------------; ; В HL строка с ошибкой BadExit: _PrintStr LD B,1 ; код ошибки ;JR Exit ;-----------------; ;-----------------; Exit: PUSH BC LD HL,FirstHandler LD C,12h LD B,(LastHandler-FirstHandler) .loop: ; Закрываем все открытые файлы, LD A,(HL) ; если есть. В цикле. AND A JR Z,1F PUSH HL PUSH BC RST ToDSS POP BC POP HL 1: INC HL DJNZ .loop ;-----------------; ;-----------------; освобождаем память, если клянчили LD A,(ram_blk_id) CP 0 JR Z,1F LD C,#C3 RST ToBIOS ;-----------------; ;-----------------; восстанавливаем экран LD C,53h RST ToDSS PUSH DE LD A,(VModPage) LD B,A LD A,(VMod) LD C,50h RST ToDSS LD C,52h POP DE RST ToDSS ;-----------------; ;-----------------; Выход в DOS 1: POP BC LD C,41h RST ToDSS DI HALT ;-----------------; ;******************************************************* ; ____ _ _ ; / ___| ___| |_ | | _____ _ _ ___ ; \___ \ / _ \ __| | |/ / _ \ | | / __| ; ___) | __/ |_ | < __/ |_| \__ \ ; |____/ \___|\__| |_|\_\___|\__, |___/ ; |___/ ; Получаем ключи запуска, распихиваем их по углам, ; настраиваем начальные условия работы. ;-----------------; Set_keys: LD HL,(dss_line) INC HL LD (NextParameter),HL .CheckChar: CALL .GetParam JP NC,1F CCF ; Если последний параметр в строке = 0 RET ; то выходим. Разбор окончен 1: LD A,(Buffer+1) ; В основном цикле CheckChar мы AND A ; ждём только один символ в JP Z,1F ; ключе. Поэтому если их больше, SCF ; то выходим с ошибкой. RET ; Выход с ошибкой. 1: ; Проверка/установка ключа LD C,A ; ТУТ ЖДЁМ, что в А лежит 0 и используем BC LD B,A ; как смещение в памяти, где хранятся ключи LD A,(Buffer) RES 5,A ; делаем маленький символ большим))) CP 'A' ; проверяем параметр на нужный JR Z,.set_keys_a CP 'C' JR Z,.set_keys_c CP 'E' JR Z,.set_keys_e CP 'X' JR Z,.set_keys_x CP 'L' JR Z,.set_keys_l SCF ; ошибка в параметре RET ; выход с ошибкой ;-----------------; ;-----------------; .set_keys_l: INC C .set_keys_a: INC C .set_keys_x: INC C .set_keys_e: INC C .set_keys_c: ; EX DE,HL ; НЕ ТЕРЯТЬ УКАЗАТЕЛЬ НА СЛЕДУЮЩИЙ ПАРАМЕТР! LD HL,key_buff ; Вычисляем ячейку хранения ключа ADD HL,BC LD A,(HL) ; и проверяем нет ли там уже ключа. ;AND A ; если есть, значит ключ введён 2 раза ;SCF NEG RET NZ ; ошибка - повтор ключа. выход ; OR C ; Тут ОЖИДАЕТСЯ, что А=0. Если С=0, то это ключ "A" LD A,1 ; Признак установки ключа - не ноль. LD (HL),A ; установили ключ ; EX DE,HL ; НЕ ТЕРЯТЬ УКАЗАТЕЛЬ НА СЛЕДУЮЩИЙ ПАРАМЕТР! ; JR Z,.CheckChar ; если ключ "A" то следующий круг цикла SUB C ; Тут ОЖИДАЕТСЯ, что А=1. Если С>1, то это ключ без параметров ; JR Z,.CheckChar ; если ключ "X" то следующий круг цикла JR C,.CheckChar ; если ключ больше ключа 'e', то следующий круг цикла PUSH BC CALL .GetParam ; получаем следующий параметр строки DOS к найденому ключу POP BC RET C ; выход, если ошибка ; EX DE,HL ; НЕ ТЕРЯТЬ УКАЗАТЕЛЬ НА СЛЕДУЮЩИЙ ПАРАМЕТР! LD HL,FirstHandler ; вычисляем ячейку хранения хендлера ADD HL,BC ; DEC HL LD (.fileHandler),HL ; и подставляем её прямо в код ".OpenFile" ; EX DE,HL ; НЕ ТЕРЯТЬ УКАЗАТЕЛЬ НА СЛЕДУЮЩИЙ ПАРАМЕТР! ; PUSH HL ; НЕ ТЕРЯТЬ УКАЗАТЕЛЬ НА СЛЕДУЮЩИЙ ПАРАМЕТР! CALL .OpenFile ; Открытие файла (или проверка наличия) по имени из буфера ; POP HL ; НЕ ТЕРЯТЬ УКАЗАТЕЛЬ НА СЛЕДУЮЩИЙ ПАРАМЕТР! RET C ; выход, если ошибка JP .CheckChar ; погнали на следующий виток разбора ключей ;-----------------; ;-----------------; .GetParam: LD HL,(NextParameter) LD C,43h ; тут выделяем параметр запуска LD DE,Buffer ; буфер для операций со строками RST #10 ; получаем в буфере следующий параметр LD (NextParameter),HL CCF LD A,(Buffer) AND A RET NZ ; Нормальный возврат C = 0 SCF RET ; Возврат с ошибкой C = 1 ;-----------------; ;-----------------; .OpenFile: LD HL,key_save ; прописываем ключ в код для проверки на EXE LD (HL),C ; втыкаем значение ключа в код LD BC,#0045 ; проверяем буфер на корректность имени файла LD HL,Buffer ; ????? сделать проверку на корректность всего пути????? RST ToDSS RET C ; ошибка в строке AND %00000011 ; проверяем, что есть имя и XOR %00000011 ; расширение файла (0 и 1 биты) SCF RET NZ ; ошибка файла - выход LD A,0 LD C,11h LD HL,Buffer RST ToDSS ; открытие файла RET C ; ошибка файла - выход LD (.fileHandler),A ; сохраняем хендлер .fileHandler EQU $-2 ;-----------------; ;-----------------; Проверяем обрабатываемый ключ key_save EQU $+1 LD A,#FF ; сюда воткнётся значение из регистра C XOR 1 ; если 1, то это ключ "E" RET NZ ; если нет, то выход из процедуры. ;-----------------; ;-----------------; Проверка расширения файла LD BC,#0445 ; С ключом "E" проверяем файл LD HL,Buffer ; на расширение "EXE" выделив LD DE,BufferEXE ; из строки имени расширение RST ToDSS ; файла в отдельный буфер на 4 байта ;-----------------; ;-----------------; тестим буфер расширения посимвольно LD DE,IsEXE LD HL,BufferEXE LD BC,IsEXElength-IsEXE 2: LD A,(DE) RES 5,(HL) ; делаем маленький символ большим))) CPI INC DE JP PO,3F ; если последний символ проверен, то JP на проверку JP Z,2B ; если символ совпадает, то повтор 3: SCF ; сюда попадём когда BC=0 или символ не совпал RET NZ ; если вышли из цикла и символ не совпал - ошибка, XOR A ; если всё ништяк (???- закрываем открытый EXE и???) выходим EX AF,AF' LD HL,Buffer LD DE,EXEfileBuff LD BC,#00FF 1: LDI EX AF,AF' CP (HL) JR Z,1F EX AF,AF' JP PE,1B 1: LD A,0 LD (DE),A LD A,(ExeHandler) LD C,12h RST ToDSS RET ;******************************************************* ; _____ _ ____ __ ; |_ _|__ ___| |_ / ___|___ _ __ / _| ; | |/ _ \/ __| __| | | / _ \| '_ \| |_ ; | | __/\__ \ |_ | |__| (_) | | | | _| ; |_|\___||___/\__| \____\___/|_| |_|_| ; Проверяем размер и заголовок файла прошивки ; (???добавить ключ для отмены???) ;-----------------; TestConf: LD A,(ConfHandler) AND A ; проверка на отсутствие хендлера SCF RET Z ; выход с ошибкой если файл не открыт EX AF,AF' ; сохраняем хендлер, экономим такты))) LD A,(x_key) ; если проверка (ключ X) на хедер и размер AND A ; файла отключена, то пропускаем .TestConfHeader JR NZ,1F EX AF,AF' ; восстановили хендлер, сэкономили такты))) CALL .TestConfHeader RET C 1: CALL .TestConfSize RET ;-----------------; .TestConfHeader: LD HL,Buffer LD DE,8 LD C,13h ; читаем в буфер первые 8 байт RST ToDSS ; для сравнения с шаблоном RET C ; ; ковыряем буфер посимвольно LD DE,IsNormConf ; шаблон для сравнения LD HL,Buffer LD BC,IsNormConfLen-IsNormConf 2: LD A,(DE) CPI INC DE JP PO,3F ; если последний символ проверен, то JP на проверку JP Z,2B ; если символ совпадает, то повтор 3: ; сюда попадём когда BC=0 или символ не совпал. RET Z ; если BC=0 и последний символ совпал (Z=1) SCF ; если BC=0 и символ не совпал - ошибка RET ;-----------------; .TestConfSize: LD B,2 ; Ставим указатель на конец файла CALL .set_fp ; чтоб узнать его размер RET C LD A,H ; Размер файла в HL:IX. Нет смысла, если он больше OR L ; 61152 байта, поэтому проверяем, что в HL ноль. SCF RET NZ LD A,(x_key) ; Сравниваем размер файла с эталлоным для 1K30 (59215 или #E74F) AND A ; либо (при установленном ключе X) с максимально возможным JR NZ,2F ; для текущего загрузчика в BIOS (61152 или #EEE0) ; ; Тут проверка на точное соответствие для 1K30 LD HL,(ConfSize) LD A,H SUB XH JR NZ,1F LD A,L SUB XL 1: SCF RET NZ JP 3F ; ; Тут проверка на непривышение 61152 байта 2: LD HL,(MaxConfSize) PUSH IX POP BC SBC HL,BC RET C 3: LD B,0 ; Возвращаем указатель CALL .set_fp ; в файле на его начало RET ;-----------------; .set_fp: ; Входное значение в регистре B LD A,(ConfHandler) ; Хэндлер файла с которым сейчас работаем LD HL,0 LD IX,0 LD C,15h RST ToDSS ; установка указателя в файле RET ;******************************************************* ; _____ _ __ __ ; |_ _|_ _| | _____ | \/ | ___ _ __ ___ ; | |/ _` | |/ / _ \ | |\/| |/ _ \ '_ ` _ \ ; | | (_| | < __/ | | | | __/ | | | | | ; |_|\__,_|_|\_\___| |_| |_|\___|_| |_| |_| ; Выделяем память под загрузку прошивки - 64 кб ;-----------------; TakeMem: LD BC,#04C2 ; Запрос на выделение 64 Кб памяти под конфу RST ToBIOS RET C ; завершение - нехватка памяти LD (ram_blk_id),A LD C,#C5 ; запрос номеров выделенных страниц LD HL,ram_pages ; буфер для перечисления страниц RST ToBIOS RET C ; завершение - ошибка в ID блока LD A,B CP 4 SCF RET NZ ; завершение - некорректное кол-во блоков CCF RET ;******************************************************* ; _ _ ____ __ ; | | ___ __ _ __| | / ___|___ _ __ / _| ; | | / _ \ / _` |/ _` | | | / _ \| '_ \| |_ ; | |__| (_) | (_| | (_| | | |__| (_) | | | | _| ; |_____\___/ \__,_|\__,_| \____\___/|_| |_|_| ; Загружаем прошивку в память ;Процедура щёлкает PAGE3 без сохранения/восстановления ; предыдущего состояния. ;-----------------; Load_conf: LD HL,ram_pages LD B,4 .loop: LD A,(HL) OUT (SLOT3),A PUSH HL PUSH BC ; CALL .loopRead ; ; Параметры: DE - сколько считать в страницу LD A,(ConfHandler) ; а куда грузить - рассчитывается (#0000 - DE) LD HL,#C000 LD DE,#4000 LD C,Dss.Read RST ToDSS POP BC POP HL RET C AND A ; достигнут конец файла? RET NZ ; если A<>0, то да. Выход INC HL DJNZ .loop RET ;******************************************************* ; ____ _ _ ; / ___| ___| |_ / \ ___ _____ __ ; \___ \ / _ \ __| / _ \ / __/ _ \ \/ / ; ___) | __/ |_ / ___ \ (_| __/> < ; |____/ \___|\__| /_/ \_\___\___/_/\_\ ; Перекидываем прошивку в кэш и освобождаем память, ; если нет второй прошивки ; (???освобождение памяти недоделанно???) ;-----------------; ; Set_Acex_Data: ; DI ; IN A,(FastRAM.ON) ; Включение кэша ; LD A,(ram_pages) ; OUT (SLOT1),A ; страница с данными файла ; XOR A ; OUT (FastRAM.SLOT0),A ; Страница КЭШ = 0 ; LD HL,#5000 ; перекидывание данных в страницу КЭШ = 0 ; LD DE,#1000 ; LD BC,#3000 ; LDIR ; INC A ; OUT (FastRAM.SLOT0),A ; Страница КЭШ = 1 ; LD A,(ram_pages+1) ; OUT (SLOT1),A ; следующая страница с данными файла ; LD H,D ; LD HL,4000h ; LD D,E ; LD DE,0000h ; LD B,H ; LD BC,4000h ; LDIR ; LD A,2 ; OUT (FastRAM.SLOT0),A ; Страница КЭШ = 2 ; LD A,(ram_pages+2) ; OUT (SLOT1),A ; следующая страница с данными файла ; EX DE,HL ; LD HL,4000h ; LD D,E ; LD DE,0000h ; LD B,H ; LD BC,4000h ; LDIR ; LD A,3 ; OUT (FastRAM.SLOT0),A ; Страница КЭШ = 3 ; LD A,(ram_pages+3) ; OUT (SLOT1),A ; следующая страница с данными файла ; LD H,D ; LD HL,4000h ; LD D,E ; LD DE,0000h ; LD BC,#3EDF ; LDIR ; LD HL,Reload_String ; флаг перезагрузки из КЭШ-а ; LD DE,#3EF0 ; LD C,#10 ; LD BC, 16 ; LDIR ; LD HL,(ConfMultKeys) ; Если тут устанавливаем не 'IM' ключи ; LD A,(l_key) ; то "no multiple! перезагрузка только одна", ; AND A ; иначе - хз, ещё не пробовал. ; JR Z,1F ; LD HL,(ConfMultKeys+2) ; 1: LD (#3EE0),HL ; LD A,(page1_save) ; возврат страницы 1 ; OUT (SLOT1),A ; XOR A ; Отключение кэша ; OUT (FastRAM.SLOT0),A ; пишем в FastRAM.SLOT0 ноль, иначе в ; IN A,(FastRAM.OFF) ; нулевое окно биос или ДСС не воткнутся ; RET ;******************************************************* ; ____ _ ____ _____ _____ ; / ___| ___| |_ | _ \| ____|_ _| ; \___ \ / _ \ __| | |_) | _| | | ; ___) | __/ |_ | _ <| |___ | | ; |____/ \___|\__| |_| \_\_____| |_| ; Настройки перед ресетом ; Установка адреса возврата после reboot ; Сохранение активных страниц ; Адрес программы для возврата в регистре DE ;-----------------; ; Set_Ret: ; DI ; LD A,Spec_Page ; OUT (SLOT3),A ; открыть спец-страницу ; LD (#FFF3),A ; сохраняем в спецстраницу номер Spec_Page ; LD (#FFF4),DE ; адрес программы перезапуска ; LD DE,#FFF0 ; сохраняем страницы 0-2 в спецстранице ; LD HL,page0_save ; LDI ; LDI ; LDI ; LD A,'Z' ; флаги перезапуска ; LD (#FFFE),A ; LD A,'X' ; LD (#FFFF),A ; LD A,(page3_save) ; Восстанавливаем начальную страницу 3 ; OUT (SLOT3),A ; EI ; RET ;******************************************************* ;(.)(.) (.)(.) (.)(.) (.)(.) (.)(.) (.)(.) (.)(.) ; Подгрузка файла с переменными, константами и буферами: INCLUDE "Consts.inc" ; the_end EQU $ ; IF (the_end>(stack_point-SP_Win)) DISPLAY "the_end = ",/H,the_end DISPLAY "ST_Point-SP_Win = ",/H,(stack_point-SP_Win) ASSERT 0, "Code + Stack = Love!!! (((((" ENDIF IF (LastHandler=FirstHandler) or ((LastHandler-FirstHandler)>255) DISPLAY "FirstHandler = ",/H,FirstHandler DISPLAY "LastHandler = ",/H,LastHandler ASSERT 0, "Косяк в блоке хранения хендлеров!!!" ENDIF ;(.)(.) (.)(.) (.)(.) (.)(.) (.)(.) (.)(.) (.)(.)