diff --git a/Crazy BIOS/BIOS.asm b/Crazy BIOS/BIOS.asm new file mode 100644 index 0000000..47a6533 --- /dev/null +++ b/Crazy BIOS/BIOS.asm @@ -0,0 +1,164 @@ +; +;----------------[TO DO]---------------- +; DEFINE path to rom, exp, build, etc. +; DEFINE path to including files for rom, exp, loader, etc... +; ... +;--------------------------------------- + +;======================================= +; DEFDEVICE SPRINTER, #4000, 256 + DEVICE SPRINTER +; ENCODING "DOS" +;======================================= + +;------------[LUA functions]------------; + includelua 'Shared_includes/lua/Functions.lua' +;---------------------------------------; + +;-----------[Shared Includes]----------- + INCLUDE 'src/bios/shared/includes.inc' ; Includes +;--------------------------------------- + + + LUA PASS1 + local date, month, year = Get_date_RU(sj.get_define("__DATE__")) + BuildDate = "'" .. date .. "." .. month .. "." .. year .. "'" + sj.insert_define("BUILD_DATE", BuildDate) + ENDLUA + LUA ALLPASS + sj.insert_define("BUILD_DATE", BuildDate) + ENDLUA + + + IF PACKED_MAIN +;------------[MAIN prebuild]------------; + LUA PASS1 + -- настраиваем путь до упаковщика + detected_os = Detect_os() + print ("OS detected:", detected_os) + print () + + if detected_os == "Windows" then + pack_prog = "src\\bin\\hrust.exe Build\\Bin\\temp\\MAIN.PAK Build\\Bin\\temp\\MAIN.BIN" + elseif detected_os == "MacOS" then + pack_prog = "src/bin/mhmt -hst -zxh Build/Bin/temp/MAIN.BIN Build/Bin/temp/MAIN.PAK" + elseif detected_os == "Linux" then + pack_prog = "src/bin/mhmt -hst -zxh Build/Bin/temp/MAIN.BIN Build/Bin/temp/MAIN.PAK" + end + + + -- компиляция для получения сжатого файла MAIN и холостой проход Set_Pictures.asm + if (os.execute("sjasmplus -DPREBUILD=1 -Wall --msg=war --nologo --syntax=w --fullpath --lst=Build/Prebuilds.LST SRC/BIOS/ROM/SETUP/MAIN.ASM")) then + print("--[ MAIN.ASM Prebuild DONE ]--") + if (os.execute(pack_prog)) then + print("--[ Hrusting MAIN.BIN DONE ]--") + print(" ") + else + print("--[ Hrusting MAIN.BIN ERROR!!! ]--") + os.exit(1) + end + else + print("--[ MAIN.ASM Prebuild ERROR!!! ]--") + os.exit(1) + end + ENDLUA +;---------------------------------------; + ENDIF + + IF PACKED_MAIN +;----------[MAIN's referenses]----------; Компиляция для получения адресов меток и процедур + MMU 2 e, 18 ; страница 18 в банку 2 и проверка на границы. + ORG COMPILE_ADDR.MAIN + INCLUDE 'src/bios/ROM/SETUP/MAIN.asm' +;--------------------------------------- + ENDIF + + +; Building page 8 of Sprinter ROM +;-----------------[EXP]----------------- + MMU 0 e, 8 ; страница 8 в банку 0 и проверка на границы + ORG COMPILE_ADDR.EXP + DEFINE+ IsInBIOS 1 + OUTPUT 'Build/Bin/EXP.BIN' + ShowInfo 'EXP block Start', 0 ; !!!!! test + INCLUDE 'src/bios/EXP/EXP.asm' + ShowInfo 'EXP block End', 0 ; !!!!! test + OUTEND +;--------------------------------------- + + + +; Building page 0 of Sprinter ROM +;-----------------[ROM]----------------- + MMU 0 e, 0 ; страница 0 в банку 0 и проверка на границы. + ORG ROM_MAP.ROM + DEFINE+ IsInBIOS 0 + OUTPUT 'Build/Bin/ROM.BIN' + ShowInfo 'ROM block Start', 0 ; !!!!! test + INCLUDE 'src/bios/ROM/ROM.asm' + ShowInfo 'ROM block End', 0 ; !!!!! test + OUTEND + UNDEFINE IsInBIOS +;--------------------------------------- +; + + + +; Building page 12 of Sprinter ROM +;------[Loader with bitstream K30]------ + MMU 0 3, 12 ; страницы 12-15 в банки 0-3. + ORG ROM_MAP.LOADER + OUTPUT 'Build/Bin/LOADER_K30.BIN' + Conf_loader K30 + BLOCK #10000-$,#FF + OUTEND +;--------------------------------------- + + + +; Building page 22 of Sprinter ROM +;------[Loader with bitstream K50]------ + MMU 0 3, 22 ; страницы 22-25 в банки 0-3. + ORG ROM_MAP.LOADER + OUTPUT 'Build/Bin/LOADER_K50.BIN' +;!TODO сделать упаковщик битстрима тут на LUA + Conf_loader K50 + BLOCK #10000-$,#FF + OUTEND +;--------------------------------------- +; + +; Building page 1 of Sprinter ROM +;-----------------[LOGO]----------------- + MMU 1 e, 1 ; страница 1 в банку 1 и проверка на границы. + ORG ROM_MAP.LOGO + OUTPUT 'Build/Bin/LOGO.BIN' + INCLUDE 'src/bios/logo/Set_Pictures.asm' + OUTEND +;--------------------------------------- +; + ;EXPORT ROM_NUMBER ; !FIXIT part1, part2 для Flasher + EXPORT BOARD_INFO.number + EXPORT BOARD_INFO.type + EXPORT BoardID.start + EXPORT BoardID.end + EXPORT FN_CRIPT.cnf + EXPORT ID_SPRINTER.bitstream_ver + EXPORT bitstream_ver_hex + ;EXPORT ID_Version + ;EXPORT ID_SPRINTER.BIOS_ver + ;EXPORT BIOS_ver_hex + ;EXPORT Disk_subsystem_ver_hex + EXPORT EXP_ID.VER ; Версия биоса + EXPORT EXP_ID.MOD + ;EXPORT ROM_ID.VER ; Версия дисковой подсистемы + ;EXPORT ROM_ID.MOD + EXPORT CNF_ID.VER ; Версия конфы + EXPORT CNF_ID.MOD + EXPORT msgStrings.str_ACEX_MODEL + EXPORT msgRusStrings.str_ACEX_MODEL + EXPORT BETA_BUILD + ; LUA ALLPASS + ; print ("DEPACKER", sj.get_label("DEPACKER.PackedMAIN")) + ; print ("UnPacker", sj.get_label("UnPacker.PackedMAIN")) + ; ENDLUA \ No newline at end of file diff --git a/Crazy BIOS/BUILD.a80 b/Crazy BIOS/BUILD.a80 new file mode 100644 index 0000000..8b12e51 --- /dev/null +++ b/Crazy BIOS/BUILD.a80 @@ -0,0 +1,111 @@ +/* +;------------[LUA functions]------------; + includelua 'Shared_Includes/LUA/Functions.lua' +;---------------------------------------; + DEFINE PICTURE_FILE './src/bios/logo/psfathers.bmp' + + + LUA PASS1 + -- Проверяем BMP, достаём из него параметры, режем на куски + bmp_width, bmp_height, bmp_image_size, bmp_image_offset, bmp_colors = Get_bmp8bit_values (sj.get_define("PICTURE_FILE")) + + if bmp_width ~= 128 then sj.error("Invalid BMP width", bmp_width) end + if bmp_height ~= 72 then sj.error("Invalid BMP height", bmp_height) end + if bmp_colors ~= 256 then sj.error("Invalid BMP number of colors", bmp_colors) end + + if not File_save(sj.get_define("PICTURE_FILE"), "./Build/Bin/LOGO_PAL.BIN", bmp_image_offset-1024, 1024) then sj.error("Palete save error!") end + if not File_save(sj.get_define("PICTURE_FILE"), "./Build/Bin/LOGO_DAT.BIN", bmp_image_offset, bmp_image_size) then sj.error("Image data save error!") end + + ENDLUA +*/ + INCLUDE 'shared/defines.inc' + + DEFINE IMG_RECOVERY 'src/bios/shared/recovery.img' + ;DEFINE IMG_RECOVERY 'src/bios/shared/recovery_tst.img' + +; +;[--------------------------------------------------------------------------] + MACRO Set_Block text, blk_addr +.tmp equ $ + BLOCK blk_addr-.tmp,#FF + DISPLAY text, /H, $-.tmp + ENDM +;[--------------------------------------------------------------------------] + + DEFINE SP_128_BIN INCBIN 'src/ZX_ROMS/NEW/SP_128.BIN' + DEFINE SP__48_BIN INCBIN 'src/ZX_ROMS/NEW/SP__48.BIN' + DEFINE SP_TRDOS_BIN INCBIN 'src/ZX_ROMS/NEW/SP_TRDOS.BIN' +;[--------------------------------------------------------------------------] + MACRO ROM_BUILD bitstream + +;PAGE 0 + INCBIN 'Build/Bin/ROM.BIN' + Set_Block 'ROM free space: ', #4000 +; +;PAGE 1 +; INCBIN 'Build/Bin/LOGO_PAL.BIN' +; INCBIN 'Build/Bin/LOGO_DAT.BIN' + INCBIN 'Build/Bin/LOGO.BIN' + Set_Block 'LOGO free space: ', #8000 +; + +; +;PAGE 2 ZX Page - #42 + SP_128_BIN + Set_Block 'SP_128 free space: ', #C000 +; +;PAGE 3 ZX Page - #43 + SP__48_BIN + Set_Block 'SP_48 free space: ', #10000 +; +;PAGE 4 ZX Page - #44 + SP_TRDOS_BIN + Set_Block 'SP_TRD free space: ', #14000 +; +;PAGE 5 Recovery image part 1 + INCBIN IMG_RECOVERY,0,#C000 + DISPLAY "ROM Disk recovery part1, pages 5..7: 1x4000..2x0000" +; + + +; +;PAGE 8 + INCBIN 'Build/Bin/EXP.BIN' + ;INCBIN 'Build/CrazyBlaster.raw' + Set_Block 'EXP free space: ', #24000 +; +;PAGE 9-11 (#09, #0A, #0B) Recovery image part 2 + INCBIN IMG_RECOVERY,#C000,#C000 + DISPLAY "ROM Disk recovery part2, pages 9..11: 2x4000..3x0000" + + Set_Block 'Empty space: ', #30000 +; +;PAGE 12-15 (#0C, #0D, #0E, #0F) + INCBIN bitstream + Set_Block 'Loader & Bitstream free space: ', #40000 +; + ENDM +;[--------------------------------------------------------------------------] + + + + +;[--------------------------------------------------------------------------] + ORG 0 + DISPLAY '[ Building ROM for 1K30 ]' + OUTPUT 'Build/_SPRIN.BIN' + ROM_BUILD 'Build/Bin/LOADER_K30.BIN' + OUTEND + DISPLAY '[ Building ROM for 1K30 done ]' + DISPLAY ' ' + + + DISP 0 + DISPLAY '[ Building ROM for 1K50 ]' + OUTPUT 'Build/_SPRIN50.BIN' + ROM_BUILD 'Build/Bin/LOADER_K50.BIN' + OUTEND + DISPLAY '[ Building ROM for 1K50 done ]' + ENT +;[--------------------------------------------------------------------------] +; \ No newline at end of file diff --git a/Crazy BIOS/exp/BIOS_FUNC.asm b/Crazy BIOS/exp/BIOS_FUNC.asm new file mode 100644 index 0000000..fa6f841 --- /dev/null +++ b/Crazy BIOS/exp/BIOS_FUNC.asm @@ -0,0 +1,766 @@ +; + MACRO _mNoDrive_5xTable numberOFdrives, byteOFword + IF byteOFword + DUP numberOFdrives + DB high FN_RESERVED_5x ;#50 - Дубль. На эту функцию прыгает из основного обработчика + + DB high FN_ABSENT_5x ;#51 + DB high FN_ABSENT_5x ;#52 + DB high FN_ABSENT_5x ;#53 + DB high FN_ABSENT_5x ;#54 + DB high FN_ABSENT_5x ;#55 + DB high FN_ABSENT_5x ;#56 + DB high FN_ABSENT_5x ;#57 + DB high FN_ABSENT_5x ;#58 + DB high FN_ABSENT_5x ;#59 + + DB high DRV_VERSION ;#5A - Дубль. На эту функцию прыгает из основного обработчика + DB high FN_RESERVED_5x ;#5B - Дубль. На эту функцию прыгает из основного обработчика + DB high FN_RESERVED_5x ;#5C - Дубль. На эту функцию прыгает из основного обработчика + DB high FN_RESERVED_5x ;#5D - Дубль. На эту функцию прыгает из основного обработчика + DB high FN_RESERVED_5x ;#5E - Дубль. На эту функцию прыгает из основного обработчика + DB high DRV_LIST ;#5F - Дубль. На эту функцию прыгает из основного обработчика + EDUP + ELSE + DUP numberOFdrives + DB low FN_RESERVED_5x ;#50 - Дубль. На эту функцию прыгает из основного обработчика + + DB low FN_ABSENT_5x ;#51 + DB low FN_ABSENT_5x ;#52 + DB low FN_ABSENT_5x ;#53 + DB low FN_ABSENT_5x ;#54 + DB low FN_ABSENT_5x ;#55 + DB low FN_ABSENT_5x ;#56 + DB low FN_ABSENT_5x ;#57 + DB low FN_ABSENT_5x ;#58 + DB low FN_ABSENT_5x ;#59 + + DB low DRV_VERSION ;#5A - Дубль. На эту функцию прыгает из основного обработчика + DB low FN_RESERVED_5x ;#5B - Дубль. На эту функцию прыгает из основного обработчика + DB low FN_RESERVED_5x ;#5C - Дубль. На эту функцию прыгает из основного обработчика + DB low FN_RESERVED_5x ;#5D - Дубль. На эту функцию прыгает из основного обработчика + DB low FN_RESERVED_5x ;#5E - Дубль. На эту функцию прыгает из основного обработчика + DB low DRV_LIST ;#5F - Дубль. На эту функцию прыгает из основного обработчика + EDUP + ENDIF + ENDM +; + + _mInfoALIGN 256,0 +;=========================================================[ MAIN TABLE ] +; !FIXIT поправить в доке названия функций, часть не совпадает +TAB_FNS: + +; 00 - #3F + DUP #40 + DB low FN_RESERVED + EDUP +; + +; #4x +;-------------- + DB low FN_HDD_INIT ; #40 Инициализация винчестера + DB low FN_HDD_RECAL ; #41 Рекалибровка винчестера + DB low FN_HDD_TEST_IDE ; #42 Тест наличия интерфейса IDE + DB low FN_HDD_PREPARE ; #43 Подготовка винчестера к операции чтения/записи + DB low FN_HDD_READ_BPB ; #44 Читать BPB первого раздела + DB low FN_HDD_READ ; #45 Читать сектора с винчестера + DB low FN_HDD_WRITE ; #46 Писать сектора на винчестер + DB low FN_HDD_PART ; #47 set IDE number (Настройка партиций и master/slave)??? + DB low FN_HDD_READ_NEXT ; #48 Читать следующий сектор (ONLY FOR LBA!) + DB low FN_RESERVED ; #49 + DB low FN_RESERVED ; #4A + DB low FN_RESERVED ; #4B + DB low FN_RESERVED ; #4C + DB low FN_RESERVED ; #4D + DB low FN_RESERVED ; #4E + DB low FN_RESERVED ; #4F +;-------------- +; + +; 5x +;-------------- + DB low FN_RESERVED_5x ;#50 + + DB low FN_5x_Parser_1 ;#51 - Reset drive + DB low FN_5x_Parser_2 ;#52 - Long read + DB low FN_5x_Parser_3 ;#53 - Long write + DB low FN_5x_Parser_4 ;#54 - Verify sectors + DB low FN_5x_Parser_5 ;#55 - Read sectors + DB low FN_5x_Parser_6 ;#56 - Write sectors + DB low FN_5x_Parser_7 ;#57 - Detect + DB low FN_5x_Parser_8 ;#58 - Get Media parameters + DB low FN_5x_Parser_9 ;#59 - Set Media parameters + + DB low DRV_VERSION ;#5A - Version number + DB low FN_RESERVED_5x ;#5B + DB low FN_RESERVED_5x ;#5C + DB low FN_RESERVED_5x ;#5D + DB low FN_5x_Parser_E ;#5E + DB low DRV_LIST ;#5F +;-------------- + +; 60 - #7F + DUP #20 + DB low FN_RESERVED + EDUP + + +; 8x + DB low LP_OPEN_S ; #80 открытие окна + DB low LP_PRINT_ALL ; #81 печать символа в окно + DB low LP_PRINT_SYM ; #82 печать символа без атр + DB low LP_PRINT_ATR ; #83 печать только атрибута + DB low LP_SET_PLACE ; #84 установка позиции печати + DB low LP_PRINT_LINE ; #85 печать строки длиной B + DB low LP_PRINT_LINE2 ; #86 печать строки -//- без атрибутов + DB low LP_PRINT_LINE3 ; #87 печать строки длиной B до D + DB low LP_PRINT_LINE4 ; #88 печать строки -//- без атрибутов + DB low LP_CLS_WIN ; #89 + DB low LP_SCROLL_UD ; #8A + DB low LP_PRINT_LINE5 ; #8B + DB low LP_PRINT_LINE6 ; #8C + DB low LP_CLS_WIN2 ; #8D + DB low LP_GET_PLACE ; #8E + DB low FN_TURBO ; #8F +; 9x + DB low EMM.GetMemSize ; #90 неразрушающее определение объема ОЗУ. + DB low EMM.InitMem ; #91 инициализация распределения памяти + DB low EMM.GetMemRMD ; #92 получить блок памяти для рамдиска + DB low EMM.FreeMemRMD ; #93 освободить блок памяти рамдиска + DB low EMM.GetMemPageRMD ; #94 получить номерa страниц RAM-Disk + DB low EMM.GetMemPageNext ; #95 получить следующую страницу + DB low EMM.GetBanksPorts ; #96 получить адреса портов + DB low EMM.CheckColdInit ; #97 проверка на холодный старт и инициализации если он ;????? нужна ли как API? + DB low RAMD_CALC_PAGE ; #98 Вычисление страницы и адреса в RAM-Disk по абсолютному номеру сектора + DB low SET_DISK_REDIR ; #99 Установить на текущий драйв переназначение (старая функция для TR-DOS!) ;????? + DB low GET_DISK_REDIR ; #9A Получить тип назначения на текущий драйв (старая функция для TR-DOS!) + DB low GET_RAMD_NUM ; #9B получить номер ram disk по его block id + DB low SWAP_RAM_DRIVES ; #9C сменить набор рамдисков ZX <-> Sp2000 + DB low EMM.DivMemBlocks ; #9D разделения блока на два. + DB low EMM.MergeMemBlocks ; #9E слияние двух блоков + DB low EMM.FullInit ; #9F инициализация всей памяти, системных переменных +; Ax + DB low PIC_FN0 ; #A0 ОТКРЫТИЕ ОКНА - Fn 0A0h + DB low PIC_FN1 ; #A1 ВЫВЕСТИ ТОЧКУ + DB low PIC_FN2 ; #A2 ВЫВОД ЛИНИИ COPY + DB low PIC_FN3 ; #A3 ВЫВОД ЛИНИИ FILL + DB low PIC_SET_PAL ; #A4 ВЫВОД ПАЛИТРЫ + DB low PIC_FN5 ; #A5 УСТАНОВКА RGMOD + DB low SET_PAL_INIT ; #A6 A - page_pal, E - номер палитры, B - тип палитры + DB low PIC_FN7 ; #A7 Рисование линии одного цвета + DB low PIC_FN8 ; #A8 Рисование разноцветной линии + DB low PIC_FN9 ; #A9 нет + DB low PIC_FN10 ; #AA нет + DB low PIC_FN11 ; #AB нет + DB low PIC_FN12 ; #AC нет + DB low PIC_FN14 ; #AD нет + DB low PIC_FN14 ; #AE нет + DB low PIC_FN15 ; #AF нет +; Bx + DB low WIN_OPEN ; #B0 открытие окна по описателю + DB low WIN_CLOSE ; #B1 закрытие окна + DB low WIN_COPY ; #B2 сохранение текстового окна в памяти + DB low WIN_RESTORE ; #B3 восстановление текстового окна из памяти + DB low WIN_GET_SYM ; #B4 взять символ + DB low WIN_PUT_SYM ; #B5 положить символ + DB low WIN_SET_ZG ; #B6 загрузка знакогенератора + DB low WIN_MOVE ; #B7 переместить окно + DB low WIN_GET_ZG ; #B8 получить знакогенератор + DB low FN_RESERVED ; #B9 + DB low FN_RESERVED ; #BA + DB low FN_RESERVED ; #BB + DB low FN_RESERVED ; #BC + DB low FN_RESERVED ; #BD + DB low FN_RESERVED ; #BE + DB low FN_RESERVED ; #BF +; Cx + DB low EMM.GetMemSize ; #C0 получить данные об объеме памяти и кол-во своб. стр. + DB low EMM.InitMem ; #C1 инициализация распределения памяти + DB low EMM.GetMem ; #C2 получить блок памяти + DB low EMM.FreeMem ; #C3 освободить блок памяти + DB low EMM.GetMemPage ; #C4 получить номер страницы в блоке памяти + DB low EMM.GetMemBlkPages ; #C5 получить список страниц блока памяти + DB low EMM.GetBanksPorts ; #C6 получить адреса портов окон + DB low EMM.GetMemPageNext ; #C7 получить следующую страницу блока + DB low BLK_RD_WR ; #C8 функция чтения/записи в блок памяти + DB low BLK_TO_RAMD ; #C9 назначить блок RAM-Disk-у + DB low RAMD_CLEAR ; #CA освободить RAM-Disk + DB low RAMD_TO_DRV ; #CB назначить RAM-Disk на дисковод + DB low FDD_TO_DRV ; #CC назначить REAL_DRIVE на дисковод + DB low HDD_TO_DRV ; #CD назначить HDD на дисковод + DB low GET_RAMD_ST ; #CE получить тип назначения на RAM-Disk + DB low GET_DRV_ST ; #CF получить тип назначения на дисковод +; Dx + DB low FN_LIB ; #D0 + DB low FN_LIB ; #D1 + DB low FN_LIB ; #D2 + DB low FN_LIB ; #D3 + DB low FN_LIB ; #D4 + DB low FN_LIB ; #D5 + DB low FN_LIB ; #D6 + DB low FN_LIB ; #D7 + DB low FN_LIB ; #D8 + DB low FN_LIB ; #D9 + DB low FN_LIB ; #DA + DB low FN_LIB ; #DB + DB low FN_LIB ; #DC + DB low FN_LIB ; #DD + DB low FN_LIB ; #DE + DB low FN_LIB ; #DF +; Ex + DB low LP_PR_LINE_DIR ; #E0 + DB low FN_RESERVED ; #E1 + DB low FN_RESERVED ; #E2 + DB low FN_RESERVED ; #E3 + DB low FN_RESERVED ; #E4 + DB low FN_RESERVED ; #E5 + DB low FN_RESERVED ; #E6 + DB low FN_RESERVED ; #E7 + DB low FN_SEND_BYTE ; #E8 послать байт через PC_link + DB low FN_RESEIVE_B ; #E9 принять байт через PC_link + DB low FN_KBD_OUT ; #EA послать байт в клавиатуру + DB low FN_RESERVED ; #EB + DB low FN_RESERVED ; #EC + DB low FN_CRIPT ; #ED + DB low RST_CONF.AY8910 ; #EE для совместимости с софтом Sp97 + DB low FN_VERSION ; #EF +; Fx + DB low RST_CONF.SP97_1 ; #F0 для совместимости с софтом Sp97 + DB low RST_CONF.SP97_2 ; #F1 для совместимости с софтом Sp97 + DB low FN_SYNC ; #F2 установка синхронизации + DB low RST_CONF.CUSTOM ; #F3 для совместимости с софтом Sp97 + DB low DCP_CONFIG ; #F4 функция распределения портов ; [x] + DB low CMOS_TEST ; #F5 + DB low CMOS_RD ; #F6 + DB low CMOS_WR ; #F7 + DB low SET_PORTS ; #F8 + DB low READ_PORTS ; #F9 [x] 26/01/2024 + DB low FN_RESERVED ; #FA [x] 26/01/2024 не работала и не нужна, дублирует SET_PORTS + DB low GOTO_SPEC ; #FB Goto Spectrum! + DB low FN_RESERVED ; #FC + DB low REINIT ; #FD + DB low FN_RESERVED ; #FE SAVE_AUTOSTART. Есть в ZX_EXP.ASM + DB low FN_VERSION ; #FF + +;****************----------------------------************************----------------- + + +; 00 - #3F + DUP #40 + DB high FN_RESERVED + EDUP +; + +;-------------- + DB high FN_HDD_INIT + DB high FN_HDD_RECAL + DB high FN_HDD_TEST_IDE + DB high FN_HDD_PREPARE + DB high FN_HDD_READ_BPB + DB high FN_HDD_READ + DB high FN_HDD_WRITE + DB high FN_HDD_PART + DB high FN_HDD_READ_NEXT + DB high FN_RESERVED + DB high FN_RESERVED + DB high FN_RESERVED + DB high FN_RESERVED + DB high FN_RESERVED + DB high FN_RESERVED + DB high FN_RESERVED +;-------------- + +;-------------- + DB high FN_RESERVED_5x + + DB high FN_5x_Parser_1 + DB high FN_5x_Parser_2 + DB high FN_5x_Parser_3 + DB high FN_5x_Parser_4 + DB high FN_5x_Parser_5 + DB high FN_5x_Parser_6 + DB high FN_5x_Parser_7 + DB high FN_5x_Parser_8 + DB high FN_5x_Parser_9 + + DB high DRV_VERSION + DB high FN_RESERVED_5x + DB high FN_RESERVED_5x + DB high FN_RESERVED_5x + DB high FN_5x_Parser_E + DB high DRV_LIST +;-------------- + +; 60 - #7F + DUP #20 + DB high FN_RESERVED + EDUP + + +; 8x + DB high LP_OPEN_S + DB high LP_PRINT_ALL + DB high LP_PRINT_SYM + DB high LP_PRINT_ATR + DB high LP_SET_PLACE + DB high LP_PRINT_LINE + DB high LP_PRINT_LINE2 + DB high LP_PRINT_LINE3 + DB high LP_PRINT_LINE4 + DB high LP_CLS_WIN + DB high LP_SCROLL_UD + DB high LP_PRINT_LINE5 + DB high LP_PRINT_LINE6 + DB high LP_CLS_WIN2 + DB high LP_GET_PLACE + DB high FN_TURBO +; 9x + DB high EMM.GetMemSize + DB high EMM.InitMem + DB high EMM.GetMemRMD + DB high EMM.FreeMemRMD + DB high EMM.GetMemPageRMD + DB high EMM.GetMemPageNext + DB high EMM.GetBanksPorts + DB high EMM.CheckColdInit + DB high RAMD_CALC_PAGE + DB high SET_DISK_REDIR + DB high GET_DISK_REDIR + DB high GET_RAMD_NUM + DB high SWAP_RAM_DRIVES + DB high EMM.DivMemBlocks + DB high EMM.MergeMemBlocks + DB high EMM.FullInit +; Ax + DB high PIC_FN0 + DB high PIC_FN1 + DB high PIC_FN2 + DB high PIC_FN3 + DB high PIC_SET_PAL + DB high PIC_FN5 + DB high SET_PAL_INIT + DB high PIC_FN7 + DB high PIC_FN8 + DB high PIC_FN9 + DB high PIC_FN10 + DB high PIC_FN11 + DB high PIC_FN12 + DB high PIC_FN14 + DB high PIC_FN14 + DB high PIC_FN15 +; Bx + DB high WIN_OPEN + DB high WIN_CLOSE + DB high WIN_COPY + DB high WIN_RESTORE + DB high WIN_GET_SYM + DB high WIN_PUT_SYM + DB high WIN_SET_ZG + DB high WIN_MOVE + DB high WIN_GET_ZG + DB high FN_RESERVED + DB high FN_RESERVED + DB high FN_RESERVED + DB high FN_RESERVED + DB high FN_RESERVED + DB high FN_RESERVED + DB high FN_RESERVED +; Cx + DB high EMM.GetMemSize + DB high EMM.InitMem + DB high EMM.GetMem + DB high EMM.FreeMem + DB high EMM.GetMemPage + DB high EMM.GetMemBlkPages + DB high EMM.GetBanksPorts + DB high EMM.GetMemPageNext + DB high BLK_RD_WR + DB high BLK_TO_RAMD + DB high RAMD_CLEAR + DB high RAMD_TO_DRV + DB high FDD_TO_DRV + DB high HDD_TO_DRV + DB high GET_RAMD_ST + DB high GET_DRV_ST +; Dx + DB high FN_LIB + DB high FN_LIB + DB high FN_LIB + DB high FN_LIB + DB high FN_LIB + DB high FN_LIB + DB high FN_LIB + DB high FN_LIB + DB high FN_LIB + DB high FN_LIB + DB high FN_LIB + DB high FN_LIB + DB high FN_LIB + DB high FN_LIB + DB high FN_LIB + DB high FN_LIB +; Ex + DB high LP_PR_LINE_DIR + DB high FN_RESERVED + DB high FN_RESERVED + DB high FN_RESERVED + DB high FN_RESERVED + DB high FN_RESERVED + DB high FN_RESERVED + DB high FN_RESERVED + DB high FN_SEND_BYTE + DB high FN_RESEIVE_B + DB high FN_KBD_OUT + DB high FN_RESERVED + DB high FN_RESERVED + DB high FN_CRIPT + DB high RST_CONF.AY8910 + DB high FN_VERSION +; Fx + DB high RST_CONF.SP97_1 + DB high RST_CONF.SP97_2 + DB high FN_SYNC + DB high RST_CONF.CUSTOM + DB high DCP_CONFIG + DB high CMOS_TEST + DB high CMOS_RD + DB high CMOS_WR + DB high SET_PORTS + DB high READ_PORTS + DB high FN_RESERVED + DB high GOTO_SPEC + DB high FN_RESERVED + DB high REINIT + DB high FN_RESERVED + DB high FN_VERSION +//////////////////////////////////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////////////////////////////////// +; +; ,----, ,----,. +; ,/ .`| ,' ,' | +; ,` .' : ,--, ,' .' | +; ; ; / ,---, ,--.'| ,----.' .' +; .'___,/ ,' ,---.'| | | : | | .' +; | : | | | : : : ' : : |--, ,--, ,--, +; ; |.'; ; ,--.--. : : : | ' | ,---. : | ;.' \|'. \/ .`| +; `----' | | / \ : |,-.' | | / \ | | |' \/ / ; +; ' : ;.--. .-. || : ' || | : / / | `----'.'\ ; \ \.' / +; | | ' \__\/: . .| | / :' : |__ . ' / | __ \ . | \ ; ; +; ' : | ," .--.; |' : |: || | '.'|' ; /| / /\/ / : / \ \ \ +; ; |.' / / ,. || | '/ :; : ;' | / | / ,,/ ',- ./__; ; \ +; '---' ; : .' \ : || , / | : | \ ''\ ;| :/\ \ ; +; | , .-./ \ / ---`-' \ \ / \ \ .' `---' `--` +; `--`---' `-'----' `----' `--`-,-' +//////////////////////////////////////////////////////////////////////////////////////// + + + _mInfoALIGN 256,0 +;===========================================================[ 5x TABLE ] +; Drives Numbers: +; 0 FDD +; 1..5 reserved +; 6 RAM-DRV +; 7 reserved +; 8 HDD +; 9..B reserved +; C CDROM +; D..F reserved +TAB_5xFNS: +; --< LOW PART >-- +;-------------------------------------------------------------[ FDD #0 ] +; + DB low FN_RESERVED_5x ;#50 - Дубль. На эту функцию прыгает из основного обработчика + DB low FDD_5x_RESET ;#51 + DB low FDD_5x_LONG_READ ;#52 + DB low FDD_5x_LONG_WRITE ;#53 + DB low FN_ABSENT_5x ;#54 + DB low FDD_5x_READ ;#55 + DB low FDD_5x_WRITE ;#56 + DB low FDD_5x_DETECT ;#57 + DB low FDD_5x_GETMED ;#58 + DB low FDD_5x_SETMED ;#59 + + DB low DRV_VERSION ;#5A - Дубль. На эту функцию прыгает из основного обработчика + DB low FN_RESERVED_5x ;#5B - Дубль. На эту функцию прыгает из основного обработчика + DB low FN_RESERVED_5x ;#5C - Дубль. На эту функцию прыгает из основного обработчика + DB low FN_RESERVED_5x ;#5D - Дубль. На эту функцию прыгает из основного обработчика + DB low FN_RESERVED_5x ;#5E - Дубль. На эту функцию прыгает из основного обработчика + DB low DRV_LIST ;#5F - Дубль. На эту функцию прыгает из основного обработчика +; +;---------------------------------------------------------------------[] + +;-----------------------------[ #1..#5 ] + _mNoDrive_5xTable 5, 0 +;-------------------------------------[] + +;-------------------------------------------------------[ RAM DRIVE #6 ] +; + DB low FN_RESERVED_5x + DB low FN_ABSENT_5x + DB low RMD_5x_LONG_READ + DB low RMD_5x_LONG_WRITE + DB low FN_ABSENT_5x + DB low RMD_5x_READ + DB low RMD_5x_WRITE + DB low FN_ABSENT_5x + DB low RMD_5x_GETMED + DB low RMD_5x_SETMED + + DB low DRV_VERSION + DB low FN_RESERVED_5x + DB low FN_RESERVED_5x + DB low FN_RESERVED_5x + DB low FN_RESERVED_5x + DB low DRV_LIST +;---------------------------------------------------------------------[] + +;---------------------------------[ #7 ] + _mNoDrive_5xTable 1, 0 +;-------------------------------------[] + +;-------------------------------------------------------------[ HDD #8 ] +; + DB low FN_RESERVED_5x + DB low HDD_5x_RESET + DB low HDD_5x_LONG_READ + DB low HDD_5x_LONG_WRITE + DB low HDD_5x_VERIFY + DB low HDD_5x_READ + DB low HDD_5x_WRITE + DB low HDD_5x_DETECT + DB low HDD_5x_GETMED + DB low HDD_5x_SETMED + + DB low DRV_VERSION + DB low FN_RESERVED_5x + DB low FN_RESERVED_5x + DB low FN_RESERVED_5x + DB low FN_RESERVED_5x + DB low DRV_LIST +;---------------------------------------------------------------------[] + +;-----------------------------[ #9..#B ] + _mNoDrive_5xTable 3, 0 +;-------------------------------------[] + +;-----------------------------------------------------------[ CDROM #C ] +; + DB low FN_RESERVED_5x + DB low CD_5x_RESET + DB low CD_5x_LONG_READ + DB low FN_ABSENT_5x + DB low FN_ABSENT_5x + DB low CD_5x_READ + DB low FN_ABSENT_5x + DB low CD_5x_DETECT + DB low FN_ABSENT_5x + DB low FN_ABSENT_5x + + DB low DRV_VERSION + DB low FN_RESERVED_5x + DB low FN_RESERVED_5x + DB low FN_RESERVED_5x + DB low CD_5x_Extended + DB low DRV_LIST +;---------------------------------------------------------------------[] + +;-----------------------------[ #D..#F ] + _mNoDrive_5xTable 3, 0 +;-------------------------------------[] + +; +; --< HIGH PART >-- +;-------------------------------------------------------------[ FDD #0 ] +; + DB high FN_RESERVED_5x ;#50 - Дубль. На эту функцию прыгает из основного обработчика + DB high FDD_5x_RESET ;#51 + DB high FDD_5x_LONG_READ ;#52 + DB high FDD_5x_LONG_WRITE ;#53 + DB high FN_ABSENT_5x ;#54 + DB high FDD_5x_READ ;#55 + DB high FDD_5x_WRITE ;#56 + DB high FDD_5x_DETECT ;#57 + DB high FDD_5x_GETMED ;#58 + DB high FDD_5x_SETMED ;#59 + DB high DRV_VERSION ;#5A - Дубль. На эту функцию прыгает из основного обработчика + DB high FN_RESERVED_5x ;#5B - Дубль. На эту функцию прыгает из основного обработчика + DB high FN_RESERVED_5x ;#5C - Дубль. На эту функцию прыгает из основного обработчика + DB high FN_RESERVED_5x ;#5D - Дубль. На эту функцию прыгает из основного обработчика + DB high FN_RESERVED_5x ;#5E - Extended functions + DB high DRV_LIST ;#5F - Дубль. На эту функцию прыгает из основного обработчика +; +;---------------------------------------------------------------------[] + +;-----------------------------[ #1..#5 ] + _mNoDrive_5xTable 5, 1 +;-------------------------------------[] + +;-------------------------------------------------------[ RAM DRIVE #6 ] +; + DB high FN_RESERVED_5x + DB high FN_ABSENT_5x + DB high RMD_5x_LONG_READ + DB high RMD_5x_LONG_WRITE + DB high FN_ABSENT_5x + DB high RMD_5x_READ + DB high RMD_5x_WRITE + DB high FN_ABSENT_5x + DB high RMD_5x_GETMED + DB high RMD_5x_SETMED + DB high DRV_VERSION + DB high FN_RESERVED_5x + DB high FN_RESERVED_5x + DB high FN_RESERVED_5x + DB high FN_RESERVED_5x + DB high DRV_LIST +;---------------------------------------------------------------------[] + +;---------------------------------[ #7 ] + _mNoDrive_5xTable 1, 1 +;-------------------------------------[] + +;-------------------------------------------------------------[ HDD #8 ] +; + DB high FN_RESERVED_5x + DB high HDD_5x_RESET + DB high HDD_5x_LONG_READ + DB high HDD_5x_LONG_WRITE + DB high HDD_5x_VERIFY + DB high HDD_5x_READ + DB high HDD_5x_WRITE + DB high HDD_5x_DETECT + DB high HDD_5x_GETMED + DB high HDD_5x_SETMED + DB high DRV_VERSION + DB high FN_RESERVED_5x + DB high FN_RESERVED_5x + DB high FN_RESERVED_5x + DB high FN_RESERVED_5x + DB high DRV_LIST +;---------------------------------------------------------------------[] + +;-----------------------------[ #9..#B ] + _mNoDrive_5xTable 3, 1 +;-------------------------------------[] + +;----------------------------------------------------------[ CDROM #C0 ] +; + DB high FN_RESERVED_5x + DB high CD_5x_RESET + DB high CD_5x_LONG_READ + DB high FN_ABSENT_5x + DB high FN_ABSENT_5x + DB high CD_5x_READ + DB high FN_ABSENT_5x + DB high CD_5x_DETECT + DB high FN_ABSENT_5x + DB high FN_ABSENT_5x + DB high DRV_VERSION + DB high FN_RESERVED_5x + DB high FN_RESERVED_5x + DB high FN_RESERVED_5x + DB high CD_5x_Extended + DB high DRV_LIST +;---------------------------------------------------------------------[] + +;-----------------------------[ #D..#F ] + _mNoDrive_5xTable 3, 1 +;-------------------------------------[] +;======================================================================; + +;************************************ +; Вход в функцию по RST18 и RST8 +EXP_FNS_RST18: + PUSH HL + LD L,C + LD H,high TAB_FNS + LD C,(HL) + INC H + LD H,(HL) + LD L,C + EX (SP),HL + RET + +FN_5x_Parser_1: + LD C,#01 + JP FN_5x_Parser +FN_5x_Parser_2: + LD C,#02 + JP FN_5x_Parser +FN_5x_Parser_3: + LD C,#03 + JP FN_5x_Parser +FN_5x_Parser_4: + LD C,#04 + JP FN_5x_Parser +FN_5x_Parser_6: + LD C,#06 + JP FN_5x_Parser +FN_5x_Parser_7: + LD C,#07 + JP FN_5x_Parser +FN_5x_Parser_8: + LD C,#08 + JP FN_5x_Parser +FN_5x_Parser_9: + LD C,#09 + JP FN_5x_Parser +FN_5x_Parser_E: + LD C,#0E + JP FN_5x_Parser +FN_5x_Parser_5: + LD C,5 +FN_5x_Parser: + PUSH HL + LD H,A + AND #F0 + OR C + ; тут в A номер УСТРОЙСТВА + НОМЕР ФУНКЦИИ + LD L,A + LD A,H + LD H,high TAB_5xFNS + LD C,(HL) + INC H + LD H,(HL) + LD L,C + EX (SP),HL + RET + +; Вход в функции БИОС из TR-DOS +EXP_FNS:; отключаем запись в экран спектрума + ;EX (SP),HL + ;IN A,(RGADR) + ;LD L,A + ;LD A,#C0 + ;OUT (PORT_Y),A + ;LD A,H + ;EX (SP),HL ; (SP) = port_y + POP AF + ; + CALL EXP_FNS_RST18 + CALL DOS_ON + ; возвращаем запись в экран спектрума + ;EX (SP),HL + ;PUSH AF + ;LD A,L + ;OUT (RGADR),A + ;POP AF + ;POP HL + ; возврат + JP EXP_FNS_RET + +;! ! ! ! ! ! ! ! +FN_RESERVED_5x: + LD A,1 ;!HARDCODE error code +FN_RESERVED: + SCF + RET +FN_ABSENT_5x: + LD A,#AA ;!HARDCODE error code + SCF + RET +;! ! ! ! ! ! ! ! +; \ No newline at end of file diff --git a/Crazy BIOS/exp/DCP.ASM b/Crazy BIOS/exp/DCP.ASM new file mode 100644 index 0000000..ac401be --- /dev/null +++ b/Crazy BIOS/exp/DCP.ASM @@ -0,0 +1,670 @@ +;-----------------------------------------------------------------------; +; DATA FOR DCP +; вбиваем в таблицу DCP.XLSX нужный внешний порт, +; смотрим смещение для OUT (С),x - это адрес +; +; +; C C E D / A A A A A A A A A +; N N 1 O W 1 1 6 5 1 7 2 1 0 +; F F 2 S R 5 4 3 +; 1 0 8 +; +; CCED/AAAAAAAAA +; NN1OW116517210 +; FF2SR54 3 +;DCP_DATA: 108 +; ....0..11.1110 +; WORD %00000001101110 ; - адрес +; WORD %00001001101111 ; - маска - 0 изменяемые биты, 1 неизменяемые +; BYTE ACEX.Border_FE ; - порт + +; DCP END MARKER +; DW 0,0,0 +;-----------------------------------------------------------------------; +; +; +;-----------------------------------------------------------------------; + DW %00'000'0'0000'0111 + DW %00'010'0'0110'1111 + DB ACEX.VG93_1F + DW %11'010'0'0000'0111 + DW %11'010'0'0110'1111 + DB ACEX.VG93_1F + + DW %00'000'0'0010'0111 + DW %00'010'0'0110'1111 + DB ACEX.VG93_3F + DW %11'010'0'0010'0111 + DW %11'010'0'0110'1111 + DB ACEX.VG93_3F + + DW %00'000'0'0100'0111 + DW %00'010'0'0110'1111 + DB ACEX.VG93_5F + DW %11'010'0'0100'0111 + DW %11'010'0'0110'1111 + DB ACEX.VG93_5F + + DW %00'000'0'0110'0111 + DW %00'010'0'0110'1111 + DB ACEX.VG93_7F + DW %11'010'0'0110'0111 + DW %11'010'0'0110'1111 + DB ACEX.VG93_7F + + DW %00'000'0'0110'1111 + DW %00'011'0'0110'1111 + DB ACEX.VG93_State + DW %11'010'0'0110'1111 + DW %11'011'0'0110'1111 + DB ACEX.VG93_State +; For joystick + DW %00'011'0'0000'0111 + DW %10'011'0'0110'1111 + DB ACEX.JOY_VG93 + DW %10'011'0'0000'0111 + DW %11'011'0'0110'1111 + DB ACEX.JOY_VG93 + +; For VG93 with dos on + DW %00'001'0'0110'1111 + DW %00'011'0'0110'1111 + DB ACEX.JOY_VG93 + +; For VG93 with dos off + DW %11'011'0'0110'1111 + DW %11'011'0'0110'1111 + DB ACEX.JOY_VG93 + + DW %00'000'0'0010'1101 + DW %11'011'1'1111'1111 + DB ACEX.FDD720 + DW %11'000'0'0010'1101 + DW %11'001'1'1111'1111 + DB ACEX.FDD720 + + DW %00'000'0'0011'1101 + DW %11'011'1'1111'1111 + DB ACEX.FDD144 + DW %11'000'0'0011'1101 + DW %11'001'1'1111'1111 + DB ACEX.FDD144 + +;!FIXIT UNKNOWN PORTS ( Z84? ) ----------------------------------------; dos on, только через BC, чтение/запись + DW %10'000'1'0010'1101 + DW %11'010'1'1111'1111 + DB #18 + + DW %10'000'1'0011'1101 + DW %11'010'1'1111'1111 + DB #19 + + DW %10'000'1'1010'1101 + DW %11'010'1'1111'1111 + DB #1A +;----------------------------------------------------------------------; + DW %00'000'1'0010'1101 + DW %11'001'1'1111'1111 + DB ACEX.ISA_CTRL + DW %10'000'1'1011'1101 + DW %11'010'1'1111'1111 + DB ACEX.ISA_CTRL + DW %11'000'1'0010'1101 + DW %11'001'1'1111'1111 + DB ACEX.ISA_CTRL + + DW %00'001'1'0011'1101 + DW %11'001'1'0111'1111 + DB ACEX.CMOS_DATA.READ + DW %11'001'1'0011'1101 + DW %11'001'1'0111'1111 + DB ACEX.CMOS_DATA.READ + + DW %00'000'1'1010'1101 + DW %11'001'1'1111'1111 + DB ACEX.CMOS_ADDR.WRITE + DW %11'000'1'1010'1101 + DW %11'001'1'1111'1111 + DB ACEX.CMOS_ADDR.WRITE + + DW %00'000'1'0011'1101 + DW %11'001'1'0111'1111 + DB ACEX.CMOS_DATA.WRITE + DW %11'000'1'0011'1101 + DW %11'001'1'0111'1111 + DB ACEX.CMOS_DATA.WRITE +; +;---------HDD[v] + DW %00'000'0'0100'0000 + DW %11'000'0'0110'1111 + DB ACEX.IDE_DATA_1F0 + DW %01'000'0'0100'0000 + DW %11'010'0'0110'1111 + DB ACEX.IDE_DATA_1F0 + DW %10'000'0'0100'0000 + DW %11'010'0'0110'1111 + DB ACEX.IDE_DATA_1F0 + DW %11'000'0'0100'0000 + DW %11'000'0'0110'1111 + DB ACEX.IDE_DATA_1F0 + + DW %00'000'0'0100'0001 + DW %00'010'1'1110'1111 + DB ACEX.IDE_ERROR_1F1 + DW %00'010'0'0100'0001 + DW %11'010'1'1110'1111 + DB ACEX.IDE_ERROR_1F1 + DW %11'010'0'0100'0001 + DW %11'010'1'1110'1111 + DB ACEX.IDE_ERROR_1F1 + + DW %00'000'0'0100'0010 + DW %00'010'1'1110'1111 + DB ACEX.IDE_COUNTER_1F2 + DW %00'010'0'0100'0010 + DW %11'010'1'1110'1111 + DB ACEX.IDE_COUNTER_1F2 + DW %11'010'0'0100'0010 + DW %11'010'1'1110'1111 + DB ACEX.IDE_COUNTER_1F2 + + DW %00'000'0'0100'0011 + DW %00'010'1'1110'1111 + DB ACEX.IDE_SECTOR_1F3 + DW %00'010'0'0100'0011 + DW %11'010'1'1110'1111 + DB ACEX.IDE_SECTOR_1F3 + DW %11'010'0'0100'0011 + DW %11'010'1'1110'1111 + DB ACEX.IDE_SECTOR_1F3 + + DW %00'000'0'0100'0100 + DW %00'010'1'1110'1111 + DB ACEX.IDE_CYLINDER_L_1F4 + DW %00'010'0'0100'0100 + DW %11'010'1'1110'1111 + DB ACEX.IDE_CYLINDER_L_1F4 + DW %11'010'0'0100'0100 + DW %11'010'1'1110'1111 + DB ACEX.IDE_CYLINDER_L_1F4 + + DW %00'000'0'0100'0101 + DW %00'010'1'1110'1111 + DB ACEX.IDE_CYLINDER_H_1F5 + DW %00'010'0'0100'0101 + DW %11'010'1'1110'1111 + DB ACEX.IDE_CYLINDER_H_1F5 + DW %11'010'0'0100'0101 + DW %11'010'1'1110'1111 + DB ACEX.IDE_CYLINDER_H_1F5 + + DW %00'000'0'1100'0010 + DW %00'010'1'1110'1111 + DB ACEX.IDE_DEVICE_HEAD_1F6 + DW %00'010'0'1100'0010 + DW %11'010'1'1110'1111 + DB ACEX.IDE_DEVICE_HEAD_1F6 + DW %11'010'0'1100'0010 + DW %11'010'1'1110'1111 + DB ACEX.IDE_DEVICE_HEAD_1F6 + + DW %00'000'0'1100'0011 + DW %00'010'1'1110'1111 + DB ACEX.IDE_STATUS_CMD_1F7 + DW %00'010'0'1100'0011 + DW %11'010'1'1110'1111 + DB ACEX.IDE_STATUS_CMD_1F7 + DW %11'010'0'1100'0011 + DW %11'010'1'1110'1111 + DB ACEX.IDE_STATUS_CMD_1F7 +;---------HDD[^] +; + DW %00'000'0'1100'0100 + DW %00'010'1'1110'1111 + DB ACEX.IDE_CONTROL_3F6 + DW %00'010'0'1100'0100 + DW %11'010'1'1110'1111 + DB ACEX.IDE_CONTROL_3F6 + DW %11'010'0'1100'0100 + DW %11'010'1'1110'1111 + DB ACEX.IDE_CONTROL_3F6 + + DW %00'000'0'1100'0101 + DW %00'010'1'1110'1111 + DB ACEX.IDE_STATUS_3F7 + DW %00'010'0'1100'0101 + DW %11'010'1'1110'1111 + DB ACEX.IDE_STATUS_3F7 + DW %11'010'0'1100'0101 + DW %11'010'1'1110'1111 + DB ACEX.IDE_STATUS_3F7 + + DW %00'000'0'0010'1100 + DW %11'001'1'1111'1111 + DB ACEX.IDE_CHANEL_1 + DW %11'000'0'0010'1100 + DW %11'001'1'1111'1111 + DB ACEX.IDE_CHANEL_1 + + DW %00'000'0'0011'1100 + DW %11'001'1'1111'1111 + DB ACEX.IDE_CHANEL_2 + DW %11'000'0'0011'1100 + DW %11'001'1'1111'1111 + DB ACEX.IDE_CHANEL_2 + + DW %00'000'0'1010'1101 + DW %11'001'1'1111'1111 + DB ACEX.VSYNC320 + DW %11'000'0'1010'1101 + DW %11'001'1'1111'1111 + DB ACEX.VSYNC320 + + DW %00'000'0'1011'1101 + DW %11'001'1'1111'1111 + DB ACEX.VSYNC312 + DW %11'000'0'1011'1101 + DW %11'001'1'1111'1111 + DB ACEX.VSYNC312 + + DW %00'000'0'1010'1100 + DW %11'001'1'1111'1111 + DB ACEX.RESET + DW %11'000'0'1010'1100 + DW %11'001'1'1111'1111 + DB ACEX.RESET + + DW %00'000'0'1011'1100 + DW %11'001'1'1111'1111 + DB ACEX.UNKNOWN ;!FIXIT можно пока убрать + DW %11'000'0'1011'1100 + DW %11'001'1'1111'1111 + DB ACEX.UNKNOWN ;!FIXIT можно пока убрать + + DW %00'010'0'0010'1011 + DW %11'010'0'0110'1011 + DB ACEX.ISA_Control + + DW %00'011'0'0110'1110 + DW %10'011'0'0110'1111 + DB ACEX.ZX_Keyboard + DW %10'011'0'0110'1110 + DW %11'011'0'0110'1111 + DB ACEX.ZX_Keyboard + + DW %00'001'1'1111'1101 + DW %00'001'1'1111'1111 + DB ACEX.AY_FFFD_READ + + DW %00'001'1'1101'1111 + DW %11'001'1'1111'1111 + DB ACEX.Kempston_Mouse + DW %11'001'1'1101'1111 + DW %11'001'1'1111'1111 + DB ACEX.Kempston_Mouse + + DW %00'011'0'0110'0011 + DW %11'011'0'0110'1111 + DB ACEX.CBL_OUT + DW %01'010'0'0110'0011 + DW %11'010'0'0110'1111 + DB ACEX.CBL_OUT + DW %10'010'0'0110'0011 + DW %11'010'0'0110'1111 + DB ACEX.CBL_OUT + DW %00'010'0'0000'0111 + DW %11'011'0'0000'1111 + DB ACEX.CBL_OUT + DW %00'011'0'0000'1000 + DW %11'011'0'0110'1111 + DB ACEX.CBL_OUT + DW %00'010'0'0110'1011 + DW %10'010'0'0110'1111 + DB ACEX.CBL_OUT + DW %10'010'0'0110'1011 + DW %11'010'0'0110'1111 + DB ACEX.CBL_OUT + + DW %00'000'0'0100'0110 + DW %11'001'1'1111'1111 + DB ACEX.CBL_SYS_PORT + DW %11'000'0'0100'0110 + DW %11'001'1'1111'1111 + DB ACEX.CBL_SYS_PORT + + DW %00'000'1'1111'1101 + DW %00'001'1'1111'1111 + DB ACEX.AY_FFFD_WRITE + + DW %00'000'1'0111'1101 + DW %00'001'1'1111'1111 + DB ACEX.AY_BFFD + + DW %00'000'0'0110'1101 + DW %10'000'1'1111'1111 + DB ACEX.Scorp_1FFD + DW %11'000'0'0110'1101 + DW %11'000'1'1111'1111 + DB ACEX.Scorp_1FFD + + DW %00'000'0'1110'1101 + DW %00'100'1'1110'1111 + DB ACEX.Pent_7FFD + DW %00'100'0'1110'1101 + DW %11'110'1'1110'1111 + DB ACEX.Pent_7FFD + DW %11'100'0'1110'1101 + DW %11'100'1'1110'1111 + DB ACEX.Pent_7FFD + DW %10'000'0'0110'1101 + DW %11'100'1'1110'1111 + DB ACEX.Pent_7FFD + + DW %00'000'0'0110'1110 + DW %00'001'0'0110'1111 + DB ACEX.Border_FE + + DW %00'000'0'0101'0110 + DW %11'001'1'1111'1111 + DB ACEX.ALL_MODE + DW %11'000'0'0101'0110 + DW %11'001'1'1111'1111 + DB ACEX.ALL_MODE + + DW %00'000'0'0000'1001 + DW %00'010'0'0110'1111 + DB ACEX.PORT_Y + DW %00'010'0'0000'1001 + DW %11'010'0'0110'1111 + DB ACEX.PORT_Y + DW %11'010'0'0000'1001 + DW %11'010'0'0110'1111 + DB ACEX.PORT_Y + + DW %00'000'0'0100'1001 + DW %00'010'0'0110'1111 + DB ACEX.RGMOD + DW %00'010'0'0100'1001 + DW %11'010'0'0110'1111 + DB ACEX.RGMOD + DW %11'010'0'0100'1001 + DW %11'010'0'0110'1111 + DB ACEX.RGMOD + + DW %00'000'0'0010'0100 + DW %00'000'0'0010'1111 + DB ACEX.CNF_PORT + + DW %00'000'0'0110'1100 + DW %11'001'0'0110'1111 + DB ACEX.SCALE + DW %11'000'0'0110'1100 + DW %11'001'0'0110'1111 + DB ACEX.SCALE + + DW %00'000'0'0000'1010 + DW %00'010'0'0110'1111 + DB ACEX.SLOT0 + DW %00'010'0'0000'1010 + DW %11'010'0'0110'1111 + DB ACEX.SLOT0 + DW %11'010'0'0000'1010 + DW %11'010'0'0110'1111 + DB ACEX.SLOT0 + + DW %00'000'0'0010'1010 + DW %00'010'0'0110'1111 + DB ACEX.SLOT1 + DW %00'010'0'0010'1010 + DW %11'010'0'0110'1111 + DB ACEX.SLOT1 + DW %11'010'0'0010'1010 + DW %11'010'0'0110'1111 + DB ACEX.SLOT1 + + DW %00'000'0'0100'1010 + DW %00'010'0'0110'1111 + DB ACEX.SLOT2 + DW %00'010'0'0100'1010 + DW %11'010'0'0110'1111 + DB ACEX.SLOT2 + DW %11'010'0'0100'1010 + DW %11'010'0'0110'1111 + DB ACEX.SLOT2 + + DW %00'000'0'0110'1010 + DW %00'010'0'0110'1111 + DB ACEX.SLOT3 + DW %00'010'0'0110'1010 + DW %11'010'0'0110'1111 + DB ACEX.SLOT3 + DW %11'010'0'0110'1010 + DW %11'010'0'0110'1111 + DB ACEX.SLOT3 +; DCP END MARKER + DW 0,0,0 +;-----------------------------------------------------------------------; +; + +; +;----------------------------------------------------------------------; +DCP_INIT: + LD C,XL + LD B,XH + LD E,YL + LD D,YH + EXX + + LD HL,#C000 + LD DE,#C001 + LD BC,#3FFF + LD (HL),L + LDIR + + LD IY,DCP_DATA + LD IX,.ret + +.loop: LD L,(IY) + LD H,(IY+1) + LD E,(IY+2) + LD D,(IY+3) + LD B,(IY+4) + JP DCP_CONFIG.PARSE_TABLE + +.ret: LD BC,5 + ADD IY,BC + LD A,(IY+2) + OR (IY+3) + JR NZ,.loop + + EXX + LD XL,C + LD XH,B + LD YL,E + LD YH,D + + ; First IN command - OPEN DCP + IN A,(SLOT3) + JP (HL) +;-----------------------------------------------------------------------; +; + +; +;-----------------------------------------------------------------------; +; Функция дешифратора портов. +; HL - адрес +; DE - маска - 0 изменяемые биты, 1 неизменяемые +; B - порт +; +DCP_CONFIG: + AND A + JP Z,PORTS_INIT + + LD A,R + DI + PUSH AF + + PUSH IX + LD IX,.exit + + IN A,(SLOT3) + EX AF,AF' + LD A,DCP_PAGE + OUT (SLOT3),A + + JR .PARSE_TABLE + +.exit: EX AF,AF' + OUT (SLOT3),A + AND A + POP IX + POP AF + RET PO + EI + RET +.PARSE_TABLE: + LD A,L + AND E + LD L,A + + LD A,H + AND D + OR #C0 + LD H,A + + LD A,D + OR #C0 + LD D,A + +.loop: LD (HL),B + + LD A,L ; замаскировать неизменяемые биты 1-ми + OR E ; для прохождения переноса + INC A ; увеличить адрес + JR Z,.carry ; возник перенос + + OR E + XOR E ; обнулить неизменяемые биты + LD C,A ; изменяемая часть + + LD A,L + AND E ; выделить неизменяемую + OR C + LD L,A ; добавить изменяемую часть + + JR .loop ; цикл + ; A = 0 +.carry: LD A,L ; забить изменяемые биты нулями + AND E + LD L,A + + LD A,H ; замаскировать неизменяемые биты 1-ми + OR D ; для прохождения переноса + INC A ; увеличить адрес + JR Z,.return + + OR D + XOR D + LD C,A ; изменяемая часть + + LD A,H + AND D ; выделить неизменяемую + OR C + LD H,A ; добавить изменяемую часть + JR .loop + +.return: JP (IX) +;-----------------------------------------------------------------------; +; + +;----------------------------------------------------------------------; +;[x] 26/01/2024 +READ_PORTS: + CALL SET_PORTS.Prepare + LD BC,0 + IN B,(C) + JR SET_PORTS.End + +;[x] 26/01/2024 +; WRITE_PORTS: +; SCF +; RET +;----------------------------------------------------------------------; + +; +;-----------------------------------------------------------------------; +;[x] Теперь это не нужно: CALL from 3D13h! Осторожнее с прерываниями, лучше гасить, чтоб не сбить сигнал DOS_ON +; in: A - внутренний порт, B - значение для записи во внутренний порт +; out: B - старое значение внутреннего порта; Перед выходом восстанавливается конфа прописанная в CONFIG_DE. +SET_PORTS: + CALL .Prepare + ; + EX AF,AF' + LD A,B + LD BC,0 + EX AF,AF' + ; + ; Чтение порта + IN A,(C) + ; Запись порта + EX AF,AF' + OUT (C),A ; установить новое значение порта + EX AF,AF' + ; + LD B,A ; прошлое состояние порта + ; +.End: LD A,DCP_PAGE ; установить DCP + LD C,SLOT2 + OUT (C),A + LD A,L + LD (#8000),A ; вернуть порт + LD A,H + LD (#8200),A ; вернуть порт + ; + LD A,SYS_PAGE + OUT (C),A + LD A,(SYS_PAGE.CONFIG_DE-#4000) + OUT (C),D ; вернуть страницу + OUT (SYS_PORT.ROM),A + ; + CALL DOS_OFF + ; + ;[x] SET_PORTS: no need to call from #3D13 and DI. 31/12/23 + BIT 2,E + RET Z + EI + RET + ;AND A + ;RET + ; +.Prepare: + EX AF,AF' + ;[x] SET_PORTS: no need to call from #3D13 and DI. 31/12/23 + AND A + LD A,R + PUSH AF + POP DE + DI + CALL DOS_ON + ; + LD A,CNF_PORT.CNF_0 + ROM.BIOS + OUT (SYS_PORT.ROM),A + ; + LD C,SLOT2 ; получить страницу + IN D,(C) + ; + LD A,DCP_PAGE ; установить новую + OUT (C),A + ; + LD A,(#8000) ; сохранить то что было + LD L,A + LD A,(#8200) + LD H,A + EX AF,AF' ; страница + ; + LD (#8000),A ; установить внутренний порт + LD (#8200),A + OUT (C),D ; вернуть страницу + RET +;-----------------------------------------------------------------------; +; \ No newline at end of file diff --git a/Crazy BIOS/exp/EXP.asm b/Crazy BIOS/exp/EXP.asm new file mode 100644 index 0000000..719bbe5 --- /dev/null +++ b/Crazy BIOS/exp/EXP.asm @@ -0,0 +1,1833 @@ + +; +;************************************************************* +; +; EXPANSION VER 3.00 (C) Peters Plus Ltd. +; EXPANSION VER 3.1 (C) Sprinter Team +; +;************************************************************* + +;*************************************** +;*********** BEGIN EXPANSION *********** +;*************************************** +; Вход по RESET +EXP_START: + JP GLOBAL_RESET + +;--------------------------------------- +;ROM_NUMBER: +;.part1: DW MotherBoardID +;.part2: DB 0 +BOARD_INFO: +.number: DW MotherBoardID +.type: DB MotherBoardType +;--------------------------------------- + +;--------------------------------------- +; BoardID: +; .start: WORD BoardID_start ; BoardID_start +; .end: WORD BoardID_end ; BoardID_end +;--------------------------------------- + +;======================================= + BLOCK 8-$,0 ; first on/off EXPANSION +;программа для вызова BIOS через RST8 из RAM0 +EXP_FNS_2_RET: + PUSH AF + LD A,ROM.BIOS + OUT (SYS_PORT.RAM),A + POP AF + JR RST_18_1 +;======================================= + +;======================================= + BLOCK #10-$,0 +RST_10: +; JR RST10 +;======================================= + +;======================================= + BLOCK #18-$,0 +; RST18h - MAIN BIOS functions + JP EXP_FNS_RST18 +RST_18_1: + CALL EXP_FNS_RST18 +.exit: JR EXP_FNS_2_RET + +;======================================= + +;======================================= + BLOCK #20-$,0 +RST_20: +;======================================= + +;======================================= + BLOCK #28-$,0 +RST_28: +;======================================= + +;======================================= + BLOCK #30-$,0 +RST_30: +;======================================= + +;======================================= + BLOCK #38-$,0 +; INTERUPT Point +RST38: IF TEST_INT + ;INT: + PUSH BC + PUSH AF + + LD C,SLOT3 + IN B,(C) + LD A,SYS_PAGE + OUT (C),A + + LD A,(SYS_PAGE.INT_ID) + CP #AA + JR Z,YESINT + OUT (C),B + JP NOINT +YESINT: PUSH HL + LD HL,(SYS_PAGE.INT_ADRESS) + LD A,H + OR L + LD A,(SYS_PAGE.INT_PAGE) + OUT (C),B + PUSH DE + CALL NZ,EXTINT + POP DE + POP HL +NOINT: POP AF + POP BC + EI + RETI + ELSE + +; PUSH AF +; 1: DEC A +; JR NZ,1B +; POP AF + EI + RETI + ENDIF +;RST10: +; CALL_48 10h +; RET +;======================================= + + +;======================================= + IFN TEST_INT + _mInfoALIGN #10,0 +; any adress < #C0 with mask %xxxx0000 +; таблица для Sprinter POST-Tester-a +TABLE_X: +.v0: DB 00101000b ; "0" +.v1: DB 10111101b ; "1" +.v2: DB 00110010b ; "2" +.v3: DB 00110100b ; "3" +.v4: DB 10100101b ; "4" +.v5: DB 01100100b ; "5" +.v6: DB 01100000b ; "6" +.v7: DB 00111101b ; "7" +.v8: DB 00100000b ; "8" +.v9: DB 00100100b ; "9" +.vA: DB 00100001b ; "A" +.vB: DB 11100000b ; "B" +.vC: DB 01101010b ; "C" +.vD: DB 10110000b ; "D" +.vE: DB 01100010b ; "E" +.vF: DB 01100011b ; "F" + ENDIF +;======================================= +; + +; +;======================================= + IFN TEST_INT +RESTARTS EQU #FFE0 +GLOBAL_RESET: + DI + IM 1 + LD HL,RESTARTS + LD DE,RESTARTS_PROG + LD B,RESTARTS_PROG.Size +.compare: + LD A,(DE) + CP (HL) + JR NZ,NO_RESTART + INC HL + INC DE + DJNZ .compare + JP RESTARTS + ENDIF +;======================================= + _mInfoBLOCK #66-$,0 +NMI_Point: + ; резерв 3 байта для команды JP + ;NOP + ;NOP + ;NOP + RETN +;======================================= + +;SET_BIOS_TO_RAM: ; программа работает на адресе 0C000h +; +; LD SP,#C0C0 +; LD A,#E0 +; LD C,PAGE3 +; IN B,(C) +; CALL SET_ROM_PAGES+#C000 +; JP NO_SUMX_EQ + +;********************************** + +;BEEP: +; PUSH HL +; PUSH DE +; PUSH BC +; PUSH AF +; PUSH IX +; +; LD HL,BEEP_RET +; PUSH HL +; LD HL,SW_ROM +; PUSH HL +; LD HL,03B5h +; PUSH HL +; LD HL,200 +; LD D,H +; LD E,5 +; JP SW_ROM +;BEEP_RET: +; +; POP IX +; POP AF +; POP BC +; POP DE +; POP HL +; RET +;======================================= +; BLOCK MEM_MAP.ID_Version-$,0 ;#C0-$,0 + +ID_Version: DW BIOS_ver_hex +; ID_SPRINTER_FullSize: +; DB ID_SPRINTER.Size + ; запись 1 +ID_SPRINTER: DB 'Firmware v' +.BIOS_ver: DB BIOS_ver_string,' ' + IF BETA_BUILD > 0 + DB BETA_str_ver + ELSE + DB '[',BUILD_DATE,']' + ENDIF + DB 0 +.Record1_Size EQU $-ID_SPRINTER + ; запись 2 + DB 'Sprinter',0 + ; запись 3 ; [x] 24/02/2024 +.bitstream_ver: DB bitstream_ver_string,0 + DB 0 + ; +.Size EQU $-ID_SPRINTER +.Records_Num EQU 3 + +; Check for max length of string + ASSERT ID_SPRINTER.Record1_Size < SYS_PAGE.ID_FLAG.Size, 'ERROR! ID String is to long!' +;======================================= + + +; BLOCK #FC-$,0 +BoardID: +.start: WORD BoardID_start ; BoardID_start +.end: WORD BoardID_end ; BoardID_end + +; ;======================================= +; BLOCK #100-$,0 + + +;======================================= + IF TEST_INT + _mInfoALIGN #10,0 +; any adress < #C0 with mask %xxxx0000 +; таблица для Sprinter POST-Tester-a +TABLE_X: ; таблица для Sprinter POST-Tester-a +.v0: DB %00101000 ; "0" a +.v1: DB %10111101 ; "1" ___ +.v2: DB %00110010 ; "2" f | g | b +.v3: DB %00110100 ; "3" |___| +.v4: DB %10100101 ; "4" e | | c +.v5: DB %01100100 ; "5" |___| +.v6: DB %01100000 ; "6" d +.v7: DB %00111101 ; "7" +.v8: DB %00100000 ; "8" a - 7 +.v9: DB %00100100 ; "9" b - 6 +.vA: DB %00100001 ; "A" f - 4 +.vB: DB %11100000 ; "B" g - 3 +.vC: DB %01101010 ; "C" e - 2 +.vD: DB %10110000 ; "D" c - 1 +.vE: DB %01100010 ; "E" d - 0 +.vF: DB %01100011 ; "F" + ENDIF +;======================================= +; + +; +;======================================= + IF TEST_INT +RESTARTS EQU #FFE0 +; полный перехват ресета сразу после проливки конфы и CAD. +; закидывается в карту портов, поэтому использовать надо хитро. +GLOBAL_RESET: + DI + IM 1 + LD HL,RESTARTS + LD DE,RESTARTS_PROG + LD B,RESTARTS_PROG.Size +.compare: + LD A,(DE) + CP (HL) + JR NZ,NO_RESTART + INC HL + INC DE + DJNZ .compare + JP RESTARTS + ENDIF +;======================================= +; + +; +;-----[перехват RESET не состоялся]----- +NO_RESTART: +; стек ещё не используем!!! + LD SP,IX ; сохранить значение переданное загрузчиком конфы (если старт после ресета) + ; инициализация внутренних портов Z84C15 для POST-Tester-а + LD A,5 ; COM port for Printer OUT + OUT (Z84.SIO.Ch_A.Ctrl),A + LD A,#62 + OUT (Z84.SIO.Ch_A.Ctrl),A + ; + LD A,#CF ; BITS I/O + OUT (Z84.PIO.Port_A.Command),A + XOR A + OUT (Z84.PIO.Port_A.Command),A + OUT (Z84.PIO.Port_A.Data),A ; PRINTER - PORT - all zeros + ; -инициализация системных портов Z84C15- + LD BC,#FF*256 + Z84.SYS.Control + XOR A ; Z84.REG.WaitState_Ctrl + OUT (C),A ; Z84.SYS.Control + INC C ; Z84.REG.WaitState_MemBound + OUT (C),A ; Z84.SYS.Data ; set 0 Waits + ; + DEC C + LD A,3 ; Z84.REG.Misc_Ctrl + OUT (C),A ; Z84.SYS.Control + INC C + ; no boundary set! + ;XOR A ; disable CS0, disable CS1 + LD A,1 ; enable CS0, disable CS1 + OUT (C),A ; Z84.SYS.Data + JP POST_TEST.START +;--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--== + IF TEST_INT +;----------------[int]------------------ +EXTINT: OR A + RET Z + + BIT 7,H + JR Z,.L2 + LD C,SLOT2 + BIT 6,H + JR Z,.L1 + LD C,SLOT3 + +.L1: IN B,(C) + PUSH BC + OUT (C),A + CALL .JPHL + POP BC + OUT (C),B + RET + ; проверка на нулевой слот +.L2: BIT 6,H + LD C,SLOT1 + JR NZ,.L1 ; продолжаем если ненулевой слот + + PUSH HL + + LD HL,-.stackDepth - .switchProcedure.size + .patch-2 + ADD HL,SP + PUSH HL + + LD HL,-.stackDepth - .switchProcedure.size ; memory stack use! + ADD HL,SP ; stack + PUSH HL ; адрес программы .readProcedure + + LD DE,.switchProcedure ; перенести программу на стек + EX DE,HL + LD BC,.switchProcedure.size + LDIR + RET + +; процедура, переносимая на стек для вызова прерывания пользователя из SLOT0 +; осторожнее с PUSH, если надо много, то увеличивай .stackDepth +.switchProcedure: + DEC DE + POP HL + LD (HL),E + INC HL + LD (HL),D + + LD C,SLOT0 + IN B,(C) + POP HL + PUSH BC + OUT (C),A + + XOR A + OUT (SYS_PORT.RAM),A + +.patch EQU $+1-.switchProcedure + CALL .JPHL + + DI + + XOR A + OUT (SYS_PORT.ROM),A + + POP BC + OUT (C),B + + RET +.JPHL: JP (HL) +.stackDepth EQU 64 ; расстояние от конца процедуры до вершины стека. +.switchProcedure.size EQU $-.switchProcedure + ENDIF +;--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--== + + +; ==== POST PROCs ================= + MODULE POST_TEST +START: +; ********************************* +; ===== Point 0 ======= +; ********************************* + + LD A,(TABLE_X.v0) ; высветить "0" ;rdlow-ok + OUT (Z84.PIO.Port_A.Data),A + +; ==== TEST RAM BUS ======== + +POST_1_RAM_BUS: + LD BC,0 + LD HL,#C000 + LD DE,#0055 +.loop: LD (HL),E + INC L + LD (HL),D + DEC L + LD A,(HL) + XOR E + OR C + LD C,A + INC L + LD A,(HL) + XOR D + OR B + LD B,A + DEC L + + DEC E + INC D + JR NZ,.loop + LD A,E + CPL + LD E,A + INC L + INC L + BIT 4,L + JR Z,.loop + + LD A,B + OR C + JR Z,POST_1_OK ; no errors + +; ERROR RAM BUS - CODE 'X'X'X'X... +.error: + LD HL,TABLE_X +.ERB_2: + BIT 0,C + JR Z,.ERB_1 + + ; высветить номер ошибочного бита + LD A,(HL) + AND %1101'1111 ; с запятыми + OUT (Z84.PIO.Port_A.Data),A + + ; пауза + LD DE,0 +.pause: + DEC DE + LD A,D + OR E + JR NZ,.pause + +; RRC BC +.ERB_1: + LD A,C + RRA + RR B + RR C + + ; бесконечный цикл + INC L + LD A,L + AND #AF + LD L,A + JR .ERB_2 + +; ************************************************ +; ===== Point 1 ============== +; ************************************************ +POST_1_OK: + + LD A,(TABLE_X.v1) ; высветить "1" ;rdlow-ok + OUT (Z84.PIO.Port_A.Data),A + +; ===== TEST ADRESS BUS ====== +POST_2_ADRESS_BUS: + LD HL,#C000 + LD DE,#0000 +.fill_mem: ; заполнить память адресами + LD (HL),E + INC L + LD (HL),D + INC HL + INC DE + INC DE + BIT 7,H + JR NZ,.fill_mem + + DEC HL + DEC DE + DEC DE +.check_mem: ; проверить совпадение + LD A,(HL) + CP D + JR NZ,.error + DEC HL + LD A,(HL) + CP E + JR NZ,.error + DEC HL + DEC DE + DEC DE + LD A,H + CP #BF + JR NZ,.check_mem + JR POST_2_OK + +; ошибка адреса CODE: 'XXXX +.error: +.TSAB_4: + LD C,D + LD B,11011111b + LD IX,.TSAB_3 + JR OUT_C_BYTE ; вывести старший байт с запятой +.TSAB_3: + LD C,E + LD B,#FF + LD IX,.TSAB_4 + JR OUT_C_BYTE ; вывести младший без запятой + +; ===== OUT BYTE PROGRAM ======= + +OUT_C_BYTE: + LD A,C + + RRCA + RRCA + RRCA + RRCA + + AND #0F + OR TABLE_X + LD L,A + LD H,0 + LD A,(HL) + AND B + OUT (Z84.PIO.Port_A.Data),A + + EXX + LD DE,0 +.LOOP_WTT2: + DEC DE + LD A,D + OR E + JR NZ,.LOOP_WTT2 + LD A,#FF + OUT (Z84.PIO.Port_A.Data),A +.LOOP_WTT21: + DEC DE + LD A,D + OR E + JR NZ,.LOOP_WTT21 + EXX + + LD A,C + AND #0F + OR TABLE_X + LD L,A + LD A,(HL) + OUT (Z84.PIO.Port_A.Data),A + + EXX + LD DE,0 +.LOOP_WTT3: + DEC DE + LD A,D + OR E + JR NZ,.LOOP_WTT3 + LD A,#FF + OUT (Z84.PIO.Port_A.Data),A +.LOOP_WTT31: + DEC DE + LD A,D + OR E + JR NZ,.LOOP_WTT31 + EXX + + JP (IX) + +; ************************************************ +; ===== Point 2 ========= +; ************************************************ + +POST_2_OK: + LD A,(TABLE_X.v2) ;rdlow-ok + OUT (Z84.PIO.Port_A.Data),A ; вывести "2" + +; ===== INIT DCP ======== +POST_3_INIT_DCP: + LD HL,POST_3_OK ; INIT PORTS + JP DCP_INIT ; процедура инициализации с возвратом в (HL) +; ошибок нет + +; *********************************** +; ===== Point 3 ========= +; *********************************** + +POST_3_OK: + LD A,(TABLE_X.v3) ; вывести "3" ;rdlow-ok + OUT (Z84.PIO.Port_A.Data),A + +; ===== TEST RAM PAGES == + IN A,(SLOT3) + EX AF,AF' ; запомнить +POST_4_PAGES: + LD B,0 +.loop: LD A,#FF + LD I,A + LD A,B + OUT (SLOT3),A + LD A,0 + LD I,A + IN A,(SLOT3) + CP B + JR NZ,.error ; если ошибка переключения Port-а + DJNZ .loop + + EX AF,AF' + OUT (SLOT3),A ; восстановить + JR POST_4_OK + +; *********************************** +; ERROR Port CODE 'XX +.error: LD C,B + LD IX,.error_out_ret +.error_out_ret: + LD B,11011111b + JP OUT_C_BYTE + +; *********************************** +; ===== Point 4 ========= +; *********************************** + +POST_4_OK: + LD A,(TABLE_X.v4) ;rdlow-ok + OUT (Z84.PIO.Port_A.Data),A ; высветить "4" + +;= проверка чистоты шины данных Z84C15 = +POST_5_DATA_BUS: + LD B,0 +.loop: IN A,(0) + CP #FF +; JR NZ,.error ;!!!!! посмотреть + DJNZ .loop + JR POST_5_OK + +; ERROR CODE '_'XX +.error: + LD C,A +.erb1: + LD IX,.erbr1 + LD B,%1101'1111 + JP OUT_C_BYTE +.erbr1: + LD A,%1101'1111 + OUT (Z84.PIO.Port_A.Data),A + + LD DE,0 +.LOOP_WTT4: + DEC DE + LD A,D + OR E + JR NZ,.LOOP_WTT4 + JR .erb1 + +; ********************************** +; ===== Point 5 ========= +; ********************************** + +POST_5_OK: + LD A,(TABLE_X.v5) ;rdlow-ok + OUT (Z84.PIO.Port_A.Data),A ; вывести "5" + +; ********************************** +; POST завершен +; ********************************** + ENDMODULE + + MODULE SET_CONFIG_ID + + IN A,(SLOT3) + EX AF,AF' ; SAVE PAGE3 + +;NO_SUMX_EQ: + + LD A,SYS_PAGE + OUT (SLOT3),A + +;-------------[Save IX:IY]-------------- +; Don't use IY before this point if it`s normal booting!!! + LD IX,0 + XOR A + ADD IX,SP ; восстановить значение переданное загрузчиком конфы (если старт после ресета) +; В этом месте у нас IX:IY из Loader.asm +; Дотащили до сюда метку от лоадера, пока не используется + ;[x] 31/12/2023 подстраховка от недоутечки памяти + LD D,YH + LD E,YL + EX DE,HL + LD DE,SP2000_Loader_Flag + SBC HL,DE + JR NZ,.no_conf_reload + ; + LD D,XH + LD E,XL + EX DE,HL + LD DE,ACEX.Config_ID.Sp2000 + SBC HL,DE + JR NZ,.no_conf_reload + ; + LD A,#80 +.no_conf_reload: + LD R,A + ; + +; !TODO number from loader + ; LD A,YL + ; LD L,A + ; LD A,YH + ; LD H,A + ; LD BC,#0107 ; !!!!! сравнить с 0107h вынести референсом тут и в loader.asm + ; AND A ; если равно - прошла перезагрузка + ; SBC HL,BC + ;JR Z,set_config ;!TODO активация метки IX:IY из лоадера + ;LD IX,ACEX.Config_ID.Sp97_2 + LD HL,ACEX.Config_ID.Sp2000 +set_config: + LD (SYS_PAGE.CONFIG_BYTE),HL ; сохранить номер прошивки + ;LD (SYS_PAGE.CONFIG_BYTE),IX ; сохранить номер прошивки + ;LD HL,(SYS_PAGE.CONFIG_BYTE) ; взять номер прошивки в HL + ; + LD A,CNF_PORT.CNF_0 + CNF_PORT.TURBO.ON + LD (SYS_PAGE.CONFIG_DE),A + + EX AF,AF' + OUT (SLOT3),A ; Restore SLOT3 + + ENDMODULE +;********************************* +; первая инициализация страниц: +; SLOT3=0, SLOT2=2, SLOT1=5, SLOT0=0 + + XOR A + OUT (RGADR),A + OUT (RGMOD),A + OUT (SLOT3),A + OUT (SLOT0),A + LD A,5 ; !HARDCODE page 5 + OUT (SLOT1),A + LD A,2 ; !HARDCODE page 2 + OUT (SLOT2),A + +;********************************* +; Don't use stack (SP) before this point if it`s normal booting!!! + LD SP,#C000 ; Начало использования стека!!! + PUSH HL ; сохранить номер прошивки + + CALL PORTS_INIT ; инициализировать порты + XOR A + OUT (BorderColor),A + CALL EMM.CheckColdInit ; инициализация памяти + POP HL ; конфигурация + JR Reset_Handler.start +; ************************************* +; Считаем, что вход в SETUP всегда !!! +; ************************************* + +; LD A,H +; CP #FF +; JR NZ,NO_SETUP_1 +; LD A,L + + +; JR NZ,NO_SETUP_2 + +;[---------------------------------------------------------------------] + + MODULE Reset_Handler +start: DI + IN A,(SLOT3) + PUSH AF +;----[перехват soft reset #EE port]----- +Check_EE_Port: LD A,ACEX.RET_PORT + LD B,0 + ;[x] SET_PORTS: no need to call from #3D13 and DI. 31/12/23 + ;LD C,BIOS.SET_PORTS + ;CALL @ToBIOS_3D13 ; переустановить внутр. порт #EE + CALL SET_PORTS + ; + LD A,B + AND A + JR Z,Check_Spec_Page + ; + OUT (SLOT3),A ; Set restart page +.After_Hard_Rst: + LD HL,(Spec_Page.RET_addr) ; prog address + LD A,(Spec_Page.page_0) ; PAGE0 + OUT (SLOT0),A + LD A,(Spec_Page.page_1) ; PAGE1 + OUT (SLOT1),A + LD A,(Spec_Page.page_2) ; PAGE2 + OUT (SLOT2),A + LD A,(Spec_Page.Reload_Version) + CP #FF + JR Z,.JPHL ; olg logic + ; new logic +.ver_2: EXX + LD HL,(Spec_Page.Stack_Point) + LD SP,HL + EXX + AND A + LD A,#FF + LD (Spec_Page.Reload_Version),A + LD A,(Spec_Page.page_3) ; PAGE3 + OUT (SLOT3),A + JR Z,.JPHL + PUSH HL + JP EXP_FNS_2_RET +.JPHL: JP (HL) +; +;--[перехват soft/hard reset #41 page]-- +Check_Spec_Page: + LD A,Spec_Page + OUT (SLOT3),A + ; Check for hardreset flag + LD A,(Spec_Page.flag_R) + CP 'R' + JR NZ,No_Reset_handlers + LD A,(Spec_Page.flag_S) + CP 'S' + JR NZ,No_Reset_handlers + LD A,(Spec_Page.flag_T) + CP 'T' + JR NZ,No_Reset_handlers + ; + XOR A + LD (Spec_Page.flag_R),A + JR Check_EE_Port.After_Hard_Rst + ; +;--------------------------------------- +No_Reset_handlers:/* + ; Check ZX ROMS Loaded + LD A,(Spec_Page.flag_Z) + CP 'Z' + JR NZ,.Load_ZXROMS + LD A,(Spec_Page.flag_X) + CP 'X' + JR NZ,.Load_ZXROMS + ; [x] 31/12/23 подстраховка от недоутечки памяти + LD A,R + AND #80 + JR Z,No_Need_To_Load_ZXROMS +.Load_ZXROMS: XOR A + LD R,A + ; + ; Load ZX ROM's +init_rom_address EQU #8200 ;!HARDCODE + ; + LD HL,init_zx_roms + LD DE,init_rom_address + LD BC,init_zx_roms.length + LDIR + ; + CALL init_rom_address + ; + LD HL,#C000 + LD DE,#C001 + LD BC,#3FFF + LD (HL),C + LDIR ; забить FF-ами + ; ставим метку если прогрузили ПЗУ спектрума + DEC DE ; Spec_Page.flag_X + LD A,'X' + LD (DE),A + DEC DE ; Spec_Page.flag_Z + LD A,'Z' + LD (DE),A + ; Заглушка для страницы #41 на всякий пожарный + LD HL,PROG_NO_ROM + LD DE,#C000+Spec_Page.no_zx_rom + LD BC,PROG_NO_ROM.size + LDIR + ; + LD HL,RAM_BIOS_PROG + LD DE,#C000+Spec_Page.to_bios + LD BC,RAM_BIOS_PROG.Length + LDIR + */ +;No_Need_To_Load_ZXROMS: + POP AF + OUT (SLOT3),A +;-------------------------------------------------------------------------------------------------------------------; +;!TODO сделать выбор в Setup, что грузить в vПЗУ при старте. Варианты: +;[ ] 0 - Не грузить ПЗУ спектрума, инитить страницу #41 как в 3.04 +;[ ] 1 - Грузит ПЗУ спектрума из ROM при старте если нет флага ZX +;[ ] 2 - Грузит ПЗУ спектрума из ROM при каждом перезапуске (может быть опасно) +;[ ] 3 - Не грузить ПЗУ спектрума, инитить страницу #41 так, чтоб код в ней подгружал ПЗУ спектрума при обращении +;-------------------------------------------------------------------------------------------------------------------; + ENDMODULE +; +;************************************** +; + MODULE Prepare_For_Setup + +Set_ALL_Mode: LD A,#FF + LD BC,Port_All_Mode + OUT (C),A + +Set_Default_Screen: + CALL FN_SYNC.INT_DEF ; set default int + ld a,128+4 ; !HARDCODE + ;ld c,BIOS.FN_SYNC + ;RST_to_BIOS_18 ; set default vsync + CALL FN_SYNC ; set default vsync +Setup_to_RAM: LD HL,Setup_Starter.Start + LD DE,COMPILE_ADDR.SETUP_STARTER + LD BC,Setup_Starter.Length + LDIR + ; на стек кладётся адрес возврата и дальше тащится всякими костылями, чтоб вернуться назад + CALL Setup_Starter.Exec ; #C000 +PrepareToZX: ; Setup HDD drives for ZX Spectrum mode + DI + LD D,CMOS_CELL.TRDOSmount + CALL CMOS_RD + AND %1010'1010 ; маска для 4-х HDD + JR Z,.start_zx + ; find first good partition + ; + + IN A,(SLOT3) + EX AF,AF + LD A,SYS_PAGE + OUT (SLOT3),A + ; + XOR A + LD H,A + LD L,A + LD (SYS_PAGE.CURRENT_DIR_SEC_L),HL + LD (SYS_PAGE.CURRENT_DIR_SEC_H),HL + EX AF,AF + OUT (SLOT3),A + EX AF,AF + +.loop: CALL FN_HDD_PART + JR NC,.start_zx + POP AF + INC A + CP #10 + JR C,.loop + ; выход в режим zx spectrum +.start_zx: JP ZX_SPECTRUM_MODE + ENDMODULE +;*********************************** +; Инициализация портов +PORTS_INIT: + ; включить TURBO + LD A,CNF_PORT.CNF_0 + CNF_PORT.TURBO.ON + OUT (SYS_PORT.ROM),A + ; ; RESET to ISA + ; LD BC,PORT_ISA + ; LD A,#FF + ; OUT (C),A + ; .isa_reset: + ; DEC A ;!FIXIT может убрать цикл ожидания и запулить 0 в ису после инита клавы? + ; JR NZ,.isa_reset + ; OUT (C),A + ; + ; Инициализация последовательного порта клавиатуры + ; reg 0 + XOR A ;LD A,0 + OUT (Z84.SIO.Ch_A.Ctrl),A + ; reg 4 + LD A,4 + OUT (Z84.SIO.Ch_A.Ctrl),A + ;INC A ;LD A,5 + OUT (Z84.SIO.Ch_A.Ctrl),A + ; reg 3 + LD A,3 + OUT (Z84.SIO.Ch_A.Ctrl),A + LD A,#C1 + OUT (Z84.SIO.Ch_A.Ctrl),A + ; reg 5 + LD A,5 + OUT (Z84.SIO.Ch_A.Ctrl),A + LD A,#62 ;60, 61 + OUT (Z84.SIO.Ch_A.Ctrl),A + ; reg 1 + LD A,1 + OUT (Z84.SIO.Ch_A.Ctrl),A + DEC A ;LD A,0 ; #18 включение прерываний + OUT (Z84.SIO.Ch_A.Ctrl),A +.mouse: ; Инициализация мыши + ; Инициализация таймера мыши + LD A,#55 + OUT (Z84.CTC.Ch_0),A + LD A,#2D + OUT (Z84.CTC.Ch_0),A + ; reg 0 + XOR A ;LD A,0 + OUT (Z84.SIO.Ch_B.Ctrl),A + ; reg 4 + LD A,4 + OUT (Z84.SIO.Ch_B.Ctrl),A + ;LD A,#45 + LD A,#40 + OUT (Z84.SIO.Ch_B.Ctrl),A + ; reg 3 + LD A,3 + OUT (Z84.SIO.Ch_B.Ctrl),A + LD A,#41 + OUT (Z84.SIO.Ch_B.Ctrl),A + ; reg 5 + LD A,5 + OUT (Z84.SIO.Ch_B.Ctrl),A + LD A,#E0 + OUT (Z84.SIO.Ch_B.Ctrl),A + ; reg 1 + LD A,1 + OUT (Z84.SIO.Ch_B.Ctrl),A + DEC A ;LD A,0 + OUT (Z84.SIO.Ch_B.Ctrl),A + ; Инициализация параллельного порта 1 (принтер) + ; для POST-Tester-а + LD A,#CF ; BITS I/O + OUT (Z84.PIO.Port_A.Command),A + XOR A + OUT (Z84.PIO.Port_A.Command),A ; ALL - out + OUT (Z84.PIO.Port_A.Data),A ; DATA - all zeros + ; для printer-a + LD A,#0F ; OUT + OUT (Z84.PIO.Port_A.Command),A + OUT (Z84.PIO.Port_A.Command),A + ; Инициализация параллельного порта 2 (INT/DMA ISA) + LD BC,Z84.PIO.Port_B.Command ;только через регистр BC, иначе Альтера перехватит + LD A,#CF ; BITS I/O + OUT (C),A + LD A,#3F + OUT (C),A + LD A,#C0 + OUT (Z84.PIO.Port_B.Data),A + ; "Заглушение" ковокса и ресет ISA + ; ресет ISA часть 1 + LD BC,PORT_ISA + LD A,#FF + OUT (C),A + ; глушим ковокс + XOR A + OUT (CBL.SYS_PORT),A + LD BC,CBL.OUT + LD A,#80 +.CBL_MUTE: OUT (C),A + DJNZ .CBL_MUTE + ; ресет ISA часть 2 после небольшой паузы + LD BC,PORT_ISA + XOR A + OUT (C),A + ; Сброс контроллера дисковода + ; Включить доступ к контроллеру диска (третья конфа) + LD A,CNF_PORT.CNF_3 + ROM.BIOS + OUT (SYS_PORT.ROM),A + OUT (FDC_93.DrvCTRL),A + push hl + pop hl + LD A,#3C ;!HARDCODE команда для ВГ93 + OUT (FDC_93.DrvCTRL),A + push hl + pop hl + XOR A + OUT (FDC_93.Command),A + ; Выключить доступ к контроллеру диска + LD A,CNF_PORT.CNF_0 + ROM.BIOS + OUT (SYS_PORT.ROM),A + ; set HDD1/not-HDD2 + LD A,IDE.Chanel.Primary + OUT (IDE.Chanel.Set),A + LD BC,#7FFD + LD A,#10 + OUT (C),A ; BASIC_48 mode + LD B,#1F + LD A,01 + OUT (C),A ; RAM-0 mode !!! + ; очистка буферов клавиатуры и мыши в SIO + CALL .clean_kbd_buf + JR .clean_mouse_buf +.clean_kbd_buf: ; Clearing the keyboard buffer + IN A,(Z84.SIO.Ch_A.Ctrl) + RRCA + RET NC + IN A,(Z84.SIO.Ch_A.Data) + JR .clean_kbd_buf +.clean_mouse_buf:; Clearing the mouse buffer + IN A,(Z84.SIO.Ch_B.Ctrl) + RRCA + RET NC + IN A,(Z84.SIO.Ch_B.Data) + JR .clean_mouse_buf +;--------------------------------------- + +;-----------------------------------------------------------------------; + + +;-----------------------------------------------------------------------; +; paths from project DIR + + INCLUDE 'FUNC_4x.ASM' + INCLUDE 'FUNC_CMOS.ASM' + INCLUDE 'BIOS_FUNC.ASM' + INCLUDE 'FUNC_SERVICE.asm' + + INCLUDE 'FLEX.asm' + ; INCLUDE 'EXP_SCR.ASZ' + INCLUDE 'FUNC_PIC.ASM' + INCLUDE 'FUNC_RAM_ROM_DRV.ASM' + INCLUDE 'FUNC_SYS.ASM' + INCLUDE 'FUNC_FOR_TRDOS.ASM' + INCLUDE 'FUNC_5x.asm' + INCLUDE 'FUNC_LOW_PRINT.ASM' +;-----------------------------------------------------------------------; + + +;-----------------------------------------------------------------------; +; #################################### +; #::::::::::::::::::::::::::::::::::#\ +; #::::: Место данных для DCP :::::::#\ +; #::::::::::::::::::::::::::::::::::#\ +; ####################################\ +; \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ +DCP_DATA: INCLUDE 'DCP.ASM' +;-----------------------------------------------------------------------; + +;-----------------------------------------------------------------------; +; +; #-2kb-############################## +; #::::::::::::::::::::::::::::::::::#\ +; #:::: Здесь место для IBM-ZG ::::::#\ +; #::::::::::::::::::::::::::::::::::#\ +; ####################################\ +; \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ +ZG_ADDRESS: INCLUDE 'FONT.ASM' +;-----------------------------------------------------------------------; + + +; +; _ZX_ _ZX_ _ZX_ _ZX_ _ZX_ [___FOR ZX-MODE___] _ZX_ _ZX_ _ZX_ _ZX_ _ZX_ ; + +/* +; +;------------------------[copy zx-roms to zx-pages]---------------------; +; SLOT0 - ROM 8, sys_port - on. +; RAM SLOT0 - page 0 +; для режима zx spectrum +; ВЫПОЛНЯЕТСЯ ИЗ ОЗУ +; !HARDCODE номера страниц для эмулятора ПЗУ +init_zx_roms: + DISP Reset_Handler.init_rom_address + + IN A,(SLOT3) + EX AF,AF' + + DI + LD A,SYS_PORT.EXTENSION + OUT (SYS_PORT.ROM),A + INC A ;!HARDCODE LD A,2 + LD B,3 ; zx-rom number of pages + ; +.loop: EXX + ; + out (ROM.SLOT0),a + or %0100'0000 ; !HARDCODE номера страниц для эмулятора ПЗУ + out (SLOT3),a + and %1011'1111 ; !HARDCODE номера страниц для эмулятора ПЗУ + + LD HL,0 + LD DE,#C000 + LD BC,#4000 + LDIR + + INC A + EXX + DJNZ .loop + + xor a + out (ROM.SLOT0),a + OUT (SYS_PORT.ROM),A + EX AF,AF' + out (SLOT3),a + +;[x] SET_PORTS: no need to call from #3D13 and DI. 31/12/23 + LD A,ACEX.vROM.BASIC_128 ; ROM-ID - BASIC 128 + LD B,#42 ;!HARDCODE page + CALL SET_PORTS + ; + + LD A,ACEX.vROM.BASIC_48 ; ROM-ID - BASIC 48 + LD B,#43 ;!HARDCODE page + CALL SET_PORTS + ; + + LD A,ACEX.vROM.TR_DOS ; ROM-ID - TR-DOS + LD B,#44 ;!HARDCODE page + CALL SET_PORTS + ; + + ; эти страницы пока не используются + LD A,ACEX.vROM.BIOS ; ROM-ID - BIOS + ;LD B,#45 ;!HARDCODE page + LD B,#41 + CALL SET_PORTS + ; + LD A,ACEX.vROM.BIOS_3 ; ROM-ID - BIOS-1 + ;LD B,#46 ;!HARDCODE page + LD B,#41 + CALL SET_PORTS + ; + LD A,ACEX.vROM.BIOS_4 ; ROM-ID - BIOS-2 + ;LD B,#47 ;!HARDCODE page + LD B,#41 + JP SET_PORTS + ; можно задействовать ещё 4 страницы на порты #E4..#E7 + + ENT +.length EQU $-init_zx_roms +;-----------------------------------------------------------------------; +;*/ + +;-----------------------------------------------------------------------; +;!TODO задействовать +GOTO_SPEC: + IN A,(SLOT3) + EX AF,AF' + LD A,SYS_PAGE + OUT (SLOT3),A + LD A,B + LD (SYS_PAGE.CONFIG_DE+1),A + EX AF,AF' + OUT (SLOT3),A + +;NO_SETUP_2: +; CP #FC +; JR Z,SPECTRUM_0 ; Конфигурация AY + +;NO_SETUP_1: +;!TODO сделать активацию винта для параметра из Setup +ZX_SPECTRUM_MODE: + LD A,#FE ; !HARDCODE сделать через метку ACC-off Spectrum-MODE + LD BC,Port_All_Mode + OUT (C),A + +;SND_TEST_RET: + LD SP,#BFFF + + CALL FN_SYNC.INT_PENT + CALL SET_PAL_ZX + + LD E,0 + CALL LP_SET_32 + ; + LD E,0 + LD HL,#5104 + CALL LP_SET_32.X + + ; ????? можно использовать когда-нибудь как-нибудь + ; LD D,#35 + ; CALL CMOS_RD + ; BIT 0,A + ; PUSH AF + ; CALL Z,SPRINTER_1 + ; POP AF + ; PUSH AF + ; CALL NZ,AY8910 + ; POP AF + +SPECTRUM_0: + XOR A ; задача 0, режим 256 килобайт +SPECTRUM_TASK: + LD IX,BASIC_128 + JP INIT_PAGES ; инициализация номеров страниц режима спектрума + +;start_basic: +BASIC_128: + LD SP,#C000 + LD HL,RES128_PROG + LD DE,ZX_VARS.PRINTER_BUFFER ; запуск программы на BASIC-е. + LD BC,LEN_RES128 + LDIR + DI + JP ZX_VARS.PRINTER_BUFFER +;-----------------------------------------------------------------------; +; _ZX_ _ZX_ _ZX_ _ZX_ _ZX_ _ZX_ _ZX_ _ZX_ _ZX_ _ZX_ _ZX_ _ZX_ _ZX_ _ZX_ ; +; + + + + +; +;>$< >$< >$< >$< >$< >$< [ ПЕРЕМЕЩАЕМЫЕ В ОЗУ ] >$< >$< >$< >$< >$< >$< ; + +;--------[ Программа, размещаемая с #5B00 для запуска Spectrum ]--------; +RES128_PROG: + DISP ZX_VARS.PRINTER_BUFFER ;#5B00 + LD A,ROM.BIOS + OUT (SYS_PORT.RAM),A ; Возврат в 128k ROM + LD C,SLOT3 + IN B,(C) + LD A,SYS_PAGE + OUT (SLOT3),A + LD DE,(SYS_PAGE.CONFIG_DE) + XOR A + LD (SYS_PAGE.CONFIG_DE+1),A + OUT (C),B + + LD BC,#1FFD + OUT (C),A ; Scorp порт + LD B,#7F + OUT (C),A ; 128 порт + + LD A,E ; установка конфигурации и режима TURBO + OUT (SYS_PORT.RAM),A ; CONFIG_SET + + INC D + DEC D + ; 0 ВХОД В BASIC-128 + JP Z,0 + ; 1 ВХОД В BASIC-48 + LD A,#10 + OUT (C),A + DEC D + JP Z,0 + ; 2 ВХОД В TR-DOS + LD HL,0 + PUSH HL + DEC D + JP Z,#3D29 + ; 3 ВХОД В EXPANSION + ;!TODO пока не работает. Page #45, BIOS (ZX_EXP) #E0 + XOR A + OUT (C),A + LD A,#02 + LD B,#1F + OUT (C),A + DEC D + JP Z,0 + ; + XOR A + OUT (C),A + LD A,#30 + LD B,#7F + OUT (C),A + ;!TEST + LD A,CNF_PORT.PENT_RESET + CNF_PORT.SCORP_RESET + OUT (CNF_PORT.OFF),A + ; + DEC D + ; 4 ВХОД В TR-DOS с закрытыми 128-ми портами + JP Z,#3D29 + ; 5 ВХОД В BASIC-48 с закрытыми 128-ми портами + JP 0 + ENT +LEN_RES128 EQU $-RES128_PROG +;-----------------------------------------------------------------------; + +;-------------------------------[ #FFE0 ]-------------------------------; +; программа, которая будучи размещенной в #40 странице, +; с адреса RESTARTS, перехватывает RESET +RESTARTS_PROG: ; !TODO LDConf перехват ресета на любой конфе после hardreset + LD HL,RESTARTS + LD B,16 +.loop: + LD (HL),0 + INC HL + DJNZ .loop + NOP + NOP +.Size EQU $-RESTARTS_PROG + ; LD A,1 + ; OUT (SLOT3),A +;-----------------------------------------------------------------------; + +;----------------------------[Setup Starter]----------------------------; + MODULE Setup_Starter +; программа, размещаемая по адресу 0C000h +; для запуска Setup +Start: + DISP COMPILE_ADDR.SETUP_STARTER +Exec: + LD A,CNF_PORT.CNF_0 + ROM.EXTENSION + OUT (SYS_PORT.ROM),A + + LD HL,ROM_MAP.SETUP + LD DE,MEM_MAP.SETUP + LD BC,BLOCK_Setup.Length + LDIR + + LD A,CNF_PORT.CNF_0 + ROM.BIOS + OUT (SYS_PORT.ROM),A + +;-----------[Check SPACE] + LD A,#FE ; !HARDCODE + LD BC,Port_All_Mode ; keyboard int & acc off + OUT (C),A + LD A,high ZXKeys.Line_7 + IN A,(ZXKeys) + CPL + AND 1 +; в регистре A передаётся нажата ли клавиша SPACE. +; потом проверяется в main.asm [space_check] +; и если нажата, то происходит игнор параметра +; "Быстрый старт ПЗУ" во время перезагрузки + EX AF,AF' + + LD A,#FF ; !HARDCODE + OUT (C),A ; keyboard int & acc on, zx_screen & original waits off (for conf >= 3.05) + + EX AF,AF' +;----------------------[] + DI + POP HL ; адрес возврата в EXP из SETUP + LD SP,#8000 ;!HARDCODE + PUSH HL + PUSH AF + JP SETUP_MAIN + ENT +Length EQU $-Setup_Starter.Start + ENDMODULE +;-----------------------------------------------------------------------; + +;---------------------[ ЗАГЛУШКИ ДЛЯ #41 СТРАНИЦЫ]----------------------; +;-------------[RST 08] +RAM_BIOS_PROG: ; for CALL BIOS in #41 page + DISP Spec_Page.to_bios + PUSH AF + LD A,ROM.BIOS + OUT (SYS_PORT.ROM),A + POP AF + RET + ENT +.Length EQU $-RAM_BIOS_PROG +;-------------------[] +; +;-------------[RST 38] +PROG_NO_ROM: + DISP Spec_Page.no_zx_rom + DI + ; + LD A,#FF + OUT (SLOT3),A + OUT (SLOT2),A + OUT (SLOT1),A + ; + LD SP,#BF00 + ; + LD E,0 + LD BC,BIOS.LP_OPEN_S.TXT_80x32_Default + RST ToBIOS + ; + LD DE,0 + LD HL,#2050 + LD C,BIOS.LP_CLS_WIN + RST ToBIOS + ; set scr-2 + LD A,1 + OUT (SCREEN_SWITCH),A + ; + LD HL,MESSAGE_NR + LD DE,#A000 + LD BC,MESSAGE_NR.size + LD A,C + LDIR + ; + LD HL,#A000 + LD D,0 ; delimiter + LD E,COLORS.CGA.FLASH + COLORS.CGA.INC.RED + LD B,A + LD C,BIOS.LP_PRINT_LINE3 + RST ToBIOS + ; +.loop: DI + HALT + JR .loop + ; +MESSAGE_NR: DZ " Spectrum ROM not installed. Use spectrum.exe Press Ctrl+Alt+Del or RESET" +.size EQU $-MESSAGE_NR + ENT +PROG_NO_ROM.size EQU $-PROG_NO_ROM +;-------------------[] +;-----------------------------------------------------------------------; +;>$< >$< >$< >$< >$< >$< >$< >$< >$< >$< >$< >$< >$< >$< >$< >$< >$< >$<; +; + + + +; +; !FIXIT сделать эти фиксированные адреса отдельным файлом и с IF/ELSE и подключать их потом куда надо. +; +;????? посмотреть +;----------------------------------------------------------------------; +; BLOCK #3CC0-$,255 + ; no-magics! +;MAGIC_1: ; ЗАГЛУШКА ДЛЯ MAGIC +; PUSH AF +; LD A,ROM.EXT +; OUT (SYS_PORT.OFF),A +; POP AF +; JP MAGIC_1 +;MAGIC_3: +; PUSH AF +; LD A,ROM.EXT +; OUT (SYS_PORT.OFF),A +; POP AF +; RETN +;MAGIC_2: +;; CALL MG_BEGIN +; JR MAGIC_3 + +;************************* + _mInfoBLOCK #3CE0-$,0 +SW_ROM_1: + LD HL,#259F ;!HARDCODE Show Main Menu in BASIC-128 + PUSH HL + LD HL,#5B00 ;!HARDCODE + LD A,(HL) + CP #F5 ; #F5 - опкод 'PUSH AF'. Проверяется то ли в #5B00 + JR Z,JP_HL_48 ; ВОЗВРАТ К МЕНЮ BASIC128 + POP HL + JR SW_ROM ; ПРОСТОЙ ВОЗВРАТ +;************************* + +; BLOCK #3CF0-$,0 +;JMP_48: +; LD HL,00h +; JR JP_HL_48 +; +; NOP +; NOP +; NOP + +;*************************************** + _mInfoBLOCK #3CF8-$,0 + ; no basic-48! +JP_HL_48: ;!FIXIT assert with ROM + PUSH HL +SW_ROM: ;!FIXIT assert with ROM + PUSH AF + LD A,ROM.BIOS ;!FIXIT неправильное название константы + OUT (SYS_PORT.RAM),A + POP AF + RET +;*************************************** +;----------------------------------------------------------------------; +; + +;!TODO спектрумовские утилиты +;----------------------------------------------------------------------; + ; _mInfoBLOCK #3CFA-$,#FF + ; LD A,0 ;!HARDCODE + ; OUT (SYS_PORT.OFF),A + ; POP AF +;----------------------------------------------------------------------; +; + + +; +;----------------------------------------------------------------------; + _mInfoBLOCK #3D00-$,#FF +DOS_ON: NOP + RET +;*************************************** + +;*************************************** +; BLOCK #3D02-$,FF +; !TODO можно оприходовать тут 17 байтов +; +;*************************************** + +;*************************************** + _mInfoBLOCK #3D13-$,#FF + NOP + JP ToBIOS_18 +;*************************************** + +;*************************************** +; BLOCK #3D17-$,FF +; !TODO можно оприходовать тут 233 байта +; +;*************************************** + +;*************************************** + _mInfoBLOCK #3E00-$,#FF +DOS_OFF: + PUSH AF + LD A,R + DI + PUSH AF + PUSH BC + ; + LD BC,(#5BFF) ; !HARDCODE + LD A,#C9 ; Opcode RET + LD (#5BFF),A ; !HARDCODE + CALL #5BFF ; !HARDCODE + LD (#5BFF),BC ; !HARDCODE + ; + POP BC + POP AF + JP PO,.no_EI + EI +.no_EI: POP AF + RET +;*************************************** + + +;*************************************** +; BLOCK #3E16-$,FF +; !TODO можно оприходовать тут 10 байтов +; +;*************************************** + + +//////////////////////////////////////////////////////////////////////// +;------[ ; !TODO что- то связанное с переменными LIB_TABLE ; ]------ +; _mInfoBLOCK #3E20-$,#FF +; [x] +FN_LIB: + SCF + RET +// +// IN A,(SLOT3) +// LD B,A +// LD A,SYS_PAGE +// OUT (SLOT3),A +// PUSH HL +// LD L,C ; дешефратор API изменился и теперь в C не то, что тут ожидается. Ожидается #A0..AF +// LD H,#C1 +// LD A,(HL) +// POP HL +// AND A +// SCF +// JR Z,FN_LIB_RET +// +// OUT (SLOT3),A +// LD (#C0FE),SP +// LD SP,#C0F0 +// PUSH BC +// CALL #C100 ; !HARDCODE +// POP BC +// LD SP,(#C0FE) +// ; LD A,B +// ; OUT (SLOT3),A +// ; RET +// +//FN_LIB_RET: +// LD A,B +// OUT (SLOT3),A +// ;SCF +// RET +//////////////////////////////////////////////////////////////////////// +;----------------------------------------------------------------------; +; + + + +;!TODO скомпоновать и допаять +;----------------------------------------------------------------------; +; вход A - byte +; B - speed_parameter +FN_KBD_OUT: + AND A + LD E,A + LD D,#FF + JP PE,kbd_parity ; установка паритета PE/PO ??? + LD D,#FE +kbd_parity: + AND A ; первый бит - start-bit - 0 + RL E + RL D ; в DE - 11 бит для передачи + LD C,11 + +kbd_loop: + LD A,5 + OUT (Z84.SIO.Ch_A.Ctrl),A + LD A,#60 + BIT 0,E + JR NZ,no_inv + XOR 2 ; данные +no_inv: + LD L,A + OUT (Z84.SIO.Ch_A.Ctrl),A ; выставить данные + + LD A,5 + OUT (Z84.SIO.Ch_A.Ctrl),A + LD A,L + OR #80 ; синхроимпульс + OUT (Z84.SIO.Ch_A.Ctrl),A ; импульс синхро + LD A,B ; speed_par +kbd_loop1: + PUSH HL + POP HL + DEC A + JR NZ,kbd_loop1 + LD A,5 + OUT (Z84.SIO.Ch_A.Ctrl),A + LD A,L + OUT (Z84.SIO.Ch_A.Ctrl),A ; снять импульс синхро + + LD A,B ; speed_par +kbd_loop2: + PUSH HL + POP HL + DEC A + JR NZ,kbd_loop2 + RR D + RR E + DEC C + JR NZ,kbd_loop + + LD A,5 + OUT (Z84.SIO.Ch_A.Ctrl),A + LD A,#60 + OUT (Z84.SIO.Ch_A.Ctrl),A ; закончить передачу + AND A + RET +;----------------------------------------------------------------------; +; + + + + + +;#######################################################################; +;#######################################################################; +;-----------------------------------------------------------------------; +; ROM-Disk pages ; [x] активирован ROM-DISK + _mInfoALIGN 256,#FF +; BLOCK #3F00-$,#FF +ROM_DISK.Pages.Number: + BYTE ROM_DISK.Pages.Size ; число страниц +; у страниц выставлен bit4 для корректной подстановки +;(подробнее в sp2000.inc - Порт управления страницами ПЗУ) +ROM_DISK.Pages: ; страницы ROM-Disk + ABYTE #10 #05,#06,#07,#09,#0A,#0B ; 98304 bytes +.Size EQU $-ROM_DISK.Pages +;-----------------------------------------------------------------------; +;#######################################################################; +; + +;---------[Return to EXTENSION]--------- + _mInfoBLOCK #3FD0-$,#FF ; ToBIOS_FromEXT +; #3FD0 +; Для вызова функций биоса из страницы 0 ПЗУ (Extension) +RET_to_EXTENSION: + PUSH AF + LD A,ROM.EXTENSION + OUT (SYS_PORT.ROM),A + POP AF + RST ToBIOS_18 + JP RET_to_EXTENSION + +; !TODO Free 6 bytes +;--------------------------------------- +; + + +;---------------[ Free ]---------------- +; + _mInfoBLOCK #3FE0-$,#FF +; !TODO Free 8 bytes and entry point +;SOUND_TEST: +; LD A,ROM.EXPANSION +; OUT (SYS_PORT.ON),A +; JP SND_TEST_RET +;--------------------------------------- +; + +; [x] new portal +;------------[HDD_5x portal]------------ +; точка входа/выхода для функций 5х из EXP + _mInfoBLOCK #3FE8-$,#FF +EXP_HDD: + PUSH AF + LD A,ROM.EXTENSION + OUT (SYS_PORT.ROM),A + POP AF + RET +;--------------------------------------- +; + + +; +;---------------[ Free ]---------------- + _mInfoBLOCK #3FF0-$,#FF +; !TODO Free 8 bytes and entry point +;--------------------------------------- +; + + +; +;----[ From TR-DOS to API #80..#FF ]----- + _mInfoBLOCK #3FF8-$,#FF +; Точка входа/выхода для TR-DOS +EXP_FNS_RET: + PUSH AF + LD A,ROM.BIOS + OUT (SYS_PORT.RAM),A ; Точка входа/выхода из/в TR-DOS при вызове функций BIOS #80..#FF + JP EXP_FNS +;--------------------------------------- +; + +; + _mInfoBLOCK #4000-$,#FF +;======================================================================= \ No newline at end of file diff --git a/Crazy BIOS/exp/EXTENDED/FDD_DRIVER_2.asm b/Crazy BIOS/exp/EXTENDED/FDD_DRIVER_2.asm new file mode 100644 index 0000000..f87db7a --- /dev/null +++ b/Crazy BIOS/exp/EXTENDED/FDD_DRIVER_2.asm @@ -0,0 +1,847 @@ +; !FIXIT ALL +; +;[]===========================================================[] + + + +; FDD.CHANGE: +; LD A,#01 +; AND A +; RET + + + +;[]===========================================================[] +;Function: Get Current Media Parameters +; A - Disk +;Return: +; H - Heads +; L - Sectors +; DE - Cylinders +; IX - Capacity sector in bytes +; B - Flags +; D7 - "1" - High Density, "0" - Double Density +;[]===========================================================[] +;!FIXIT всегда идет работа с данными для диска А +FDD_5x_GETMED: + ;!TEST FDD 720/1440 + IF FDD_NormalCount + LD IY,FDD_INI_TABLE.FDD_0 + DEC A + JR C,.getParams + LD IY,FDD_INI_TABLE.FDD_1 +.getParams: + ENDIF + IN A,(SLOT3) + EX AF,AF' + LD A,SYS_PAGE + OUT (SLOT3),A + ;!TEST FDD 720/1440 + IF FDD_NormalCount + LD L,(IY+1) ;SECTORS + LD H,(IY+2) ;HEADS + LD E,(IY+3) ;CYLINDL + LD D,(IY+4) ;CYLINDH + LD A,(IY+5) ;B_P_S low + LD XL,A + LD A,(IY+6) ;B_P_S High + LD XH,A + LD A,(IY+0) ;F144/720 + ELSE + LD HL,(FDD_INI_TABLE.FDD_0.SECTORS) + LD DE,(FDD_INI_TABLE.FDD_0.CYLINDL) + LD IX,(FDD_INI_TABLE.FDD_0.BytesPerSector) + LD A,(FDD_INI_TABLE.FDD_0.F144) + ENDIF + LD B,A + EX AF,AF' + OUT (SLOT3),A + ;EX AF,AF' + AND A + RET + +;[]===========================================================[] +;Function: Set Current Media Parameters +; A - Disk +; H - Heads +; L - Sectors +; DE - Cylinders +; IX - Capacity sector in bytes +; B - Flags +; D7 - "1" - High Density, "0" - Double Density +;Return: None +;[]===========================================================[] +FDD_5x_SETMED: ;!TEST FDD 720/1440 + IF FDD_NormalCount + LD IY,FDD_INI_TABLE.FDD_0 + DEC A + JR C,.setParams + LD IY,FDD_INI_TABLE.FDD_1 + ENDIF + ; +.setParams: IN A,(SLOT3) + EX AF,AF' + LD A,SYS_PAGE + OUT (SLOT3),A + ; + ;!TEST FDD 720/1440 + IF FDD_NormalCount + LD (IY+1),L ;SECTORS + LD (IY+2),H ;HEADS + LD (IY+3),E ;CYLINDL + LD (IY+4),D ;CYLINDH + LD A,XL + LD (IY+5),A ;B_P_S low + LD A,XH + LD (IY+6),A ;B_P_S High + LD (IY+0),B ;F144/720 + LD A,B + ELSE + LD A,B + LD (FDD_INI_TABLE.FDD_0.SECTORS),HL + LD (FDD_INI_TABLE.FDD_0.CYLINDL),DE + LD (FDD_INI_TABLE.FDD_0.BytesPerSector),IX + LD (FDD_INI_TABLE.FDD_0.F144),A + ENDIF + ; + EX AF,AF' + OUT (SLOT3),A + EX AF,AF' + ; + ;!TEST FDD 720/1440 + IF FDD_NormalCount + AND 1 + JP Z,FN_TURBO.SET_FDD_720 + JP FN_TURBO..SET_FDD_1440 + ELSE + AND A + RET + ENDIF + +;[]===========================================================[] +;Function: Detect Disk Density +; A - Disk +;Return: +; A - Flag D7 - "1" - High Density, "0" - Double Density +;[]===========================================================[] +FDD_5x_DETECT: CALL SAVE_INTERRUPTS.switch_off + CALL SET_DOS_ON + CALL DISK_ID + PUSH AF + CALL SET_DOS_OFF + POP AF + JP SAVE_INTERRUPTS.restore + ;RET + +;[]===========================================================[] +;Function: Reset Disk +; A - Disk +;Return: None +;[]===========================================================[] +FDD_5x_RESET: CALL SAVE_INTERRUPTS.switch_off + CALL SET_DOS_ON + CALL S_FDD + CALL DISK_ID + JR C,.MOTOR_OFF + ; + CALL RESWG + XOR A + OUT (FDC_93.Track),A + IN A,(FDC_93.Command) + ;LD C,A + CALL SET_DOS_OFF + ;LD A,C + AND A + JP SAVE_INTERRUPTS.restore + ;RET +.MOTOR_OFF: ;PUSH AF + LD A,#D0 + OUT (FDC_93.Command),A ;STOP OPERATION + LD A,#00 + OUT (FDC_93.DrvCTRL),A + LD A,#3C + OUT (FDC_93.DrvCTRL),A + CALL SET_DOS_OFF + ; CF=1 + LD A,BIOS.Error.NotReady + ;POP AF + JP SAVE_INTERRUPTS.restore + +;[]===========================================================[] +;Function: Read Sectors +; A - Disk +; HL:IX - Sector +; DE - Address +; B - Sector counter +;Return: +; HL:IX - Sector + Sector counter +; DE - Address + (Sector counter * Size sector) +;[]===========================================================[] +FDD_5x_READ: + EX AF,AF' + IN A,(SLOT3) + EX AF,AF' +;[]===========================================================[] +;Function: Long Read Sectors +; A - Disk +; HL:IX - Sector +; DE - Address +; B - Sector counter +; A'- Memory Page Number +;Return: +; HL:IX - Sector + Sector counter +; DE - Address + (Sector counter * Size sector) +;[]===========================================================[] +FDD_5x_LONG_READ: + CALL SAVE_INTERRUPTS.switch_off + CALL .Start + JP SAVE_INTERRUPTS.restore + ; +.Start: PUSH IY + PUSH BC + PUSH HL + PUSH IX + EX AF,AF' + LD C,A + EX AF,AF' + PUSH BC + CALL SET_DOS_ON + CALL S_FDD + CALL SET_SPEED + CALL NTRACK + POP BC + EX DE,HL +; LD A,B +; OR A +; JP Z,RETDOS + IN A,(SLOT3) + EX AF,AF' + LD A,SYS_PAGE + OUT (SLOT3),A + LD IY,(FDD_INI_TABLE.FDD_0.BytesPerSector) + LD XH,C + LD A,(FDD_INI_TABLE.FDD_0.SECTORS) + LD C,A + EX AF,AF' + OUT (SLOT3),A +.DSK_LP: LD A,D + EXX + CALL SEEK + EXX + PUSH DE + PUSH BC + PUSH HL + CALL READ_SECTOR + JR C,ERRDOS + LD D,YH + LD E,YL + POP HL + POP BC + ADD HL,DE + JR NC,.THISRD + IN A,(SLOT3) + EX AF,AF' + LD A,SYS_PAGE + OUT (SLOT3),A + LD D,#C2 + LD E,XH + LD A,(DE) + LD XH,A + EX AF,AF' + OUT (SLOT3),A + SET 7,H + SET 6,H +.THISRD: POP DE + LD A,C + INC E + CP E + JR NZ,.NINC_T + LD E,0 + INC D +.NINC_T: DJNZ .DSK_LP +.RETDOS: CALL SET_DOS_OFF + LD A,XH + EX AF,AF' + EX DE,HL + POP IX + POP HL + POP BC + POP IY + LD A,B + LD C,B + INC B + DEC B + LD B,0 + JR NZ,.ADD8BIT + INC B +.ADD8BIT: ADD IX,BC + LD BC,0 + ADC HL,BC + LD B,A + XOR A + RET + ; +ERRDOS: POP HL + POP BC + POP DE + CALL SET_DOS_OFF + EX DE,HL + EX AF,AF' + EXX + LD C,XH + EXX + LD A,B + POP IX + POP HL + POP BC + POP IY + PUSH AF + LD C,A + LD A,B + SUB C + LD C,A + LD B,0 + ADD IX,BC + LD C,B + ADC HL,BC + POP BC + EXX + LD A,C + EXX + EX AF,AF' + SCF + RET + +;[]===========================================================[] +;Function: Write Sectors +; A - Disk +; HL:IX - Sector +; DE - Address +; B - Sector counter +;Return: +; HL:IX - Sector + Sector counter +; DE - Address + (Sector counter * Size sector) +;[]===========================================================[] +FDD_5x_WRITE: + EX AF,AF' + IN A,(SLOT3) + EX AF,AF' +;[]===========================================================[] +;Function: Long Write Sectors +; A - Disk +; HL:IX - Sector +; DE - Address +; B - Sector counter +; A'- Memory Page Number +;Return: +; HL:IX - Sector + Sector counter +; DE - Address + (Sector counter * Size sector) +;[]===========================================================[] +FDD_5x_LONG_WRITE: + CALL SAVE_INTERRUPTS.switch_off + CALL .Start + JP SAVE_INTERRUPTS.restore + ; +.Start: PUSH IY + PUSH BC + PUSH HL + PUSH IX + EX AF,AF' + LD C,A + EX AF,AF' + PUSH BC + CALL SET_DOS_ON + CALL S_FDD + CALL SET_SPEED + CALL NTRACK + POP BC + EX DE,HL +; LD A,B +; OR A +; JP Z,RETDOS + IN A,(SLOT3) + EX AF,AF' + LD A,SYS_PAGE + OUT (SLOT3),A + LD IY,(FDD_INI_TABLE.FDD_0.BytesPerSector) + LD XH,C + LD A,(FDD_INI_TABLE.FDD_0.SECTORS) + LD C,A + EX AF,AF' + OUT (SLOT3),A +.DSK_LP2: LD A,D + EXX + CALL SEEK + EXX + PUSH DE + PUSH BC + PUSH HL + CALL WR_SEC + JR C,ERRDOS + LD D,YH + LD E,YL + POP HL + POP BC + ADD HL,DE + JR NC,.THISWR + IN A,(SLOT3) + EX AF,AF' + LD A,SYS_PAGE + OUT (SLOT3),A + LD D,#C2 + LD E,XH + LD A,(DE) + LD XH,A + EX AF,AF' + OUT (SLOT3),A + SET 7,H + SET 6,H +.THISWR: POP DE + LD A,C + INC E + CP E + JR NZ,.NINC_T2 + LD E,0 + INC D +.NINC_T2: DJNZ .DSK_LP2 + CALL SET_DOS_OFF + LD A,XH + EX AF,AF' + EX DE,HL + POP IX + POP HL + POP BC + POP IY + LD A,B + LD C,B + INC B + DEC B + LD B,0 + JR NZ,.ADW8BIT + INC B +.ADW8BIT: ADD IX,BC + LD BC,0 + ADC HL,BC + LD B,A + XOR A + RET + +; +;------------------------------- +;READ SECTOR +;------------------------------- +READ_SECTOR: LD D,5 ;RETRY COUNT +.RRETRY: ;DI + PUSH DE + LD A,E + INC A + OUT (FDC_93.Sector),A +.FDREAD: IN A,(SLOT3) + EX AF,AF' + LD A,XH + OUT (SLOT3),A + ; + LD B,4 ; счётчик + LD C,FDC_93.Data + LD A,#80 ;!HARDCODE COMMAND READ + OUT (FDC_93.Command),A +.FDR001: IN A,(FDC_93.DrvCTRL) ;WAIT INTRQ or DRQ + AND #C0 + JR NZ,.FDR004 + INC DE + LD A,E + OR D + JR NZ,.FDR001 + DJNZ .FDR001 + SCF + JR .FDR005 + ; +.FDR004: INI ;READ BYTE +.FDR002: IN A,(FDC_93.DrvCTRL) + AND #C0 + JR Z,.FDR002 + JP P,.FDR004 +.FDR005: EX AF,AF' + OUT (SLOT3),A + EX AF,AF' + ; + POP DE + ;EI + IN A,(FDC_93.Command) + LD C,A +;R01 ; JP C,ERRRD ;READ ERROR + ; [x] 29/06/2024 + ;JP C,.ERR_XRD + JR NC,.NO_ERR_XRD + DEC D + JR Z,.RSTOP + JR .RRETRY + ; +.NO_ERR_XRD: ; + AND #7F + RET Z + BIT 2,C + JR NZ,.ERDATA + LD A,BIOS.Error.Seek + DEC D + JR Z,.RSTOP + PUSH DE + CALL RESWG ; RESET_WG + LD A,XL + CALL SEEK ; !!!!! посмотреть +.ERR_XRD: POP DE + JR .RRETRY + ; +.ERDATA: DEC D ; POTERIA DANNYH + JR NZ,.RRETRY +.ERRRD: LD A,BIOS.Error.Read +.RSTOP: EX AF,AF' + LD A,#D0 + OUT (FDC_93.Command),A ;STOP OPERATION + EX AF,AF' + BIT 0,C + SCF + RET Z + LD A,BIOS.Error.SectorNotFound + RET +; ; ; + +; +;------------------------------- +;WRITE SECTOR +;------------------------------- +WR_SEC: LD D,5 ;RETRY COUNT +.WRETRY: + ;DI + PUSH DE + LD A,E + INC A + OUT (FDC_93.Sector),A +.FDWRITE: + IN A,(SLOT3) + EX AF,AF' + LD A,XH + OUT (SLOT3),A + LD B,4 + LD C,FDC_93.Data + LD A,#A0 ;COMMAND WRITE + OUT (FDC_93.Command),A +.FDW001: + IN A,(FDC_93.DrvCTRL) ;WAIT INTRQ or DRQ + AND #C0 + JR NZ,.FDW004 + INC DE + LD A,E + OR D + JR NZ,.FDW001 + DJNZ .FDW001 + SCF + JR .FDW005 +.FDW004: + OUTI ;WRITE BYTE +.FDW002: + IN A,(FDC_93.DrvCTRL) + AND #C0 + JR Z,.FDW002 + JP P,.FDW004 +.FDW005: + EX AF,AF' + OUT (SLOT3),A + EX AF,AF' +;------------------------------- + POP DE + ;EI + IN A,(FDC_93.Command) + LD C,A +;R01 + JR C,.ERR_XWR + AND #7F + RET Z + BIT 6,C + LD A,BIOS.Error.WriteProtect + JR NZ,.WSTOP + BIT 2,C + JR NZ,.EWDATA + LD A,BIOS.Error.Seek + DEC D + JR Z,.WSTOP +.ERR_XWR: + PUSH DE + CALL RESWG ; RESET_WG + LD A,XL + CALL SEEK ; !!!!! посмотреть + POP DE + JR .WRETRY +.EWDATA: + DEC D ; POTERIA DANNYH + JR NZ,.WRETRY +.ERRWR: LD A,BIOS.Error.Write +.WSTOP: EX AF,AF' + LD A,#D0 + OUT (FDC_93.Command),A ;STOP OPERATION + EX AF,AF' + BIT 0,C + SCF + RET Z + LD A,BIOS.Error.SectorNotFound + RET + + + + +; +; Врубает третью карту портов +SET_DOS_ON: + EX AF,AF' + LD A,CNF_PORT.CNF_3 + ROM.BIOS + OUT (SYS_PORT.ROM),A ; - OPEN + EX AF,AF' + RET +; Врубает нулевую карту портов +SET_DOS_OFF: + EX AF,AF' + LD A,CNF_PORT.CNF_0 + ROM.BIOS + OUT (SYS_PORT.ROM),A ; - CLOSE + EX AF,AF' + RET + +; +S_FDD: PUSH BC + AND 1 + LD B,A + OR #3C + OUT (FDC_93.DrvCTRL),A + IN A,(SLOT3) + EX AF,AF' + LD A,SYS_PAGE + OUT (SLOT3),A + LD A,(FDD_INI_TABLE.FDD_0.DISK) + AND #FE + OR B + LD (FDD_INI_TABLE.FDD_0.DISK),A + EX AF,AF' + OUT (SLOT3),A + POP BC + RET +; + +; +; MOTOR_OFF: +; PUSH AF +; LD A,#D0 +; OUT (FDC_93.Command),A ;STOP OPERATION +; LD A,#00 +; OUT (FDC_93.DrvCTRL),A +; LD A,#3C +; OUT (FDC_93.DrvCTRL),A +; CALL SET_DOS_OFF +; POP AF +; RET +; + +; +CHANGE_SPEED: IN A,(SLOT3) + EX AF,AF' + LD A,SYS_PAGE + OUT (SLOT3),A + LD A,(FDD_INI_TABLE.FDD_0.F144) + XOR #80 + LD (FDD_INI_TABLE.FDD_0.F144),A + AND #80 + EX AF,AF' + OUT (SLOT3),A + EX AF,AF' + JR Z,FDD.SET720 + ;JP FDD.SET1440 ;ZF=0 +FDD.SET1440: LD A,FDD_Density.SET_1440 + OUT (FDD_Density),A + RET +; +; +SET_SPEED: IN A,(SLOT3) + EX AF,AF' + LD A,SYS_PAGE + OUT (SLOT3),A + LD A,(FDD_INI_TABLE.FDD_0.F144) + AND #80 + EX AF,AF' + OUT (SLOT3),A + EX AF,AF' + JR NZ,FDD.SET1440 + ;JR FDD.SET720 ;ZF=1 +FDD.SET720: LD A,FDD_Density.SET_720 + OUT (FDD_Density),A + RET + +; прерывания должны быть отключены +DISK_ID: EXX + CALL SET_SPEED + IN A,(FDC_93.Track) + OUT (FDC_93.Data),A + LD A,#18 ;!TODO выписать комманды ВГ ;SEARCH ; !HARDCODE + CALL EXECOM + LD C,4 ; счётчик +.loop_reg_C: LD A,#C0 + OUT (FDC_93.Command),A + LD HL,#F000 ; счётчик +.loop_reg_HL: IN A,(FDC_93.DrvCTRL) + AND #C0 + JR Z,.ID_LP4 + ; +.ID_LP2: IN A,(FDC_93.Data) +.ID_LP3: IN A,(FDC_93.DrvCTRL) + AND #C0 + JR Z,.ID_LP3 + JP P,.ID_LP2 + EXX + IN A,(SLOT3) + EX AF,AF' + LD A,SYS_PAGE + OUT (SLOT3),A + LD A,(FDD_INI_TABLE.FDD_0.F144) + EX AF,AF' + OUT (SLOT3),A + EX AF,AF' + AND #80 + RET + ; +.ID_LP4: DEC HL + LD A,H + OR L + JR NZ,.loop_reg_HL + CALL CHANGE_SPEED + DEC C + JR NZ,.loop_reg_C + EXX + SCF + RET +; + +; +SEEK: LD XL,A + LD C,A + IN A,(SLOT3) + EX AF,AF' + LD A,SYS_PAGE + OUT (SLOT3),A + LD A,(FDD_INI_TABLE.FDD_0.DISK) + AND 1 + EX AF,AF' + OUT (SLOT3),A + EX AF,AF' + SRL C + JR C,.GT001 + OR #3C +.GT001: OR #2C + OUT (FDC_93.DrvCTRL),A + IN A,(FDC_93.Track) + CP C + PUSH BC + CALL NZ,P50ms + POP BC + LD A,C + OUT (FDC_93.Data),A + IN A,(FDC_93.Track) + CP C + EX AF,AF' ;R.TRACK==PHISICAL TRACK + LD A,#18 + CALL EXECOM + RET C + EX AF,AF' + LD A,C + OUT (FDC_93.Track),A + RET Z +.STOL: PUSH BC + CALL P50ms + POP BC + RET +; +;P750ms LD B,3 +;PMS2 LD A,255 +; CALL P1ms +; DJNZ PMS2 +; RET +P50ms: LD A,12 +.P1ms: LD C,255 +.PMS: DEC C + JR NZ,.PMS + DEC A + JR NZ,.P1ms + RET +; + +; +RESWG: LD A,8 +EXECOM: OUT (FDC_93.Command),A + LD HL,#0000 ; счётчик +.WREST: DEC HL + LD A,H + OR L + SCF + RET Z + ; + IN A,(FDC_93.DrvCTRL) + AND #80 + JR Z,.WREST + ;AND A + RET +; + +; +;------------------------------- +; HL:IX - SECTOR +; H - TRACK, L - SECTOR +;HL:IX/SECTOR_PER_TRACK +NTRACK: + PUSH HL + EX (SP),IX + POP HL + IN A,(SLOT3) + EX AF,AF' + LD A,SYS_PAGE + OUT (SLOT3),A + LD A,(FDD_INI_TABLE.FDD_0.SECTORS) + LD C,A + LD B,0 + EX AF,AF' + OUT (SLOT3),A + XOR A +.NTRK: INC A + SBC HL,BC + JR NC,.NTRK + EX AF,AF' + LD A,XL + OR XH + JR Z,.NTRK3 + EX AF,AF' + DEC IX + JR .NTRK +.NTRK3: EX AF,AF' + ADD HL,BC + DEC A + LD H,A + RET +; +SAVE_INTERRUPTS: +.switch_off: PUSH AF + LD A,R + LD A,#80 + JP PE,.set_R + XOR A +.set_R: LD R,A + DI + POP AF + RET + ; ; +.restore: PUSH AF + LD A,R + BIT 7,A + JR Z,.set_di + EI + POP AF ; PE + RET + ; +.set_di: DI + POP AF ; PO + RET +;[]===========================================================[] \ No newline at end of file diff --git a/Crazy BIOS/exp/EXTENDED/IDE/CD_DRV.ASM b/Crazy BIOS/exp/EXTENDED/IDE/CD_DRV.ASM new file mode 100644 index 0000000..172205a --- /dev/null +++ b/Crazy BIOS/exp/EXTENDED/IDE/CD_DRV.ASM @@ -0,0 +1,401 @@ +;[x] 18/12/2023. добавление/допиливание API CD-ROM (ATAPI) +;██████████████████████████████████████████████████████████████████████████ +;CD ROM DRIVE DRIVER +;--------------------------------------------------------------- +;Rev Date Name Description +;--------------------------------------------------------------- +; 02-08-2001 DNS Initial this module +;--------------------------------------------------------------- +;======================================================== +SIZESEC EQU #0800 +PKTSIZE EQU 12 +RAM_ATAPI_PK EQU SYS_PAGE.SHARED_BUFFER_32b +RAM_ATAPI_READ EQU SYS_PAGE.SHARED_BUFFER_32b+16 + + ASSERT ((PKTSIZE % 2) = 0), "PKTSIZE must be an even number" + +;[]================================================================[#51] +CD_5x_RESET: + LD C,IDE.Device.CDROM + CALL SELECT_DRIVE + RET C + LD B,50 +.loop: + PUSH BC + CALL CD_TEST + POP BC + RET NC + EI + HALT + DJNZ .loop + RET +;[]================================================================[#51] + + +;[]================================================================[#55] +;Function: Read Sectors +; A - Disk +; HL:IX - Sector +; DE - Address +; B - Sector counter +;Return: +; HL:IX - Sector + Sector counter +; DE - Address + (Sector counter * Size sector) +;READ SECTOR(S) +CD_5x_READ: + EX AF,AF' + IN A,(SLOT3) + EX AF,AF' +;[]================================================================[#52] +;Function: Long Read Sectors +; A - Disk +; HL:IX - Sector +; DE - Address +; B - Sector counter +; A'- Memory Page Number +;Return: +; HL:IX - Sector + Sector counter +; DE - Address + (Sector counter * Size sector) +;LONG READ SECTOR(S) +CD_5x_LONG_READ: + LD C,IDE.Device.CDROM + CALL SELECT_DRIVE + RET C + ; + EXX + LD C,SLOT3 + IN A,(C) + PUSH AF + LD A,SYS_PAGE + OUT (C),A + LD HL,ATAPI_CMD_PACKET.READ + LD DE,RAM_ATAPI_READ + LD BC,PKTSIZE + LDIR + EXX + + LD A,H + LD H,L + LD L,A + LD (RAM_ATAPI_READ + ATAPI_PACKET.SECTOR+0),HL + LD A,XH + LD (RAM_ATAPI_READ + ATAPI_PACKET.SECTOR+2),A ;R01 + LD A,XL + LD (RAM_ATAPI_READ + ATAPI_PACKET.SECTOR+3),A ;R01 + LD A,B + LD (RAM_ATAPI_READ + ATAPI_PACKET.COUNTER+1),A ;R01 + ; + EX AF,AF' + OUT (SLOT3),A + ; + ; POP AF + ; OUT (SLOT3),A + LD HL,RAM_ATAPI_READ + CALL AP_COM + ; + POP BC + LD C,SLOT3 + OUT (C),B + ; + RET +;[]===========================================================[#52, #55] + + +;[]================================================================[#57] +;Function: Detect Disk +; A - Disk +;Return: CF=0 - A=Drive type +; CF=1 - drive not present, A=#02 +CD_5x_DETECT: + LD C,IDE.Device.CDROM + AND %1011'1111 + JP DRV_DETECT +;[]================================================================[#57] + + +;[]================================================================[#5E] +;Function: Extended +; A - Disk +; B - SubFunction +;Return: +; +CD_5x_Extended: + LD C,IDE.Device.CDROM + CALL SELECT_DRIVE + RET C + ; + LD A,B + CP 2 + JR C,TRAY_FN + ; ... + ; ... + LD A,#AA ;!HARDCODE error code + SCF + RET +;[]================================================================[#5E] + + +;----------------------------------------------------------------------; +TRAY_FN: + LD DE,0 ;!FIXIT нужно ли? + LD HL,ATAPI_CMD_PACKET.CLOSE + DEC A + JR Z,AP_COM + LD HL,ATAPI_CMD_PACKET.OPEN + JR AP_COM +;----------------------------------------------------------------------; + + +;----------------------------------------------------------------------; +; INPUT: HL - AP paket (12bytes) +; RETURN: CF - ERROR +; !TODO CD ERRORS to INCLUDES +; #01 - RECOVERED ERROR +; #02 - NOT READY +; #03 - MEDIUM ERROR +; #04 - HARDWARE ERROR +; #05 - ILLEGAL REQUEST +; #06 - UNIT ATTETION +; #07 - DATA PROTECT +; #0B - ABORTED COMMAND +; #80 - TIME OUT +AP_COM: EXX + LD DE,#8000 + CALL CD_WAITPRT + EXX + JR NC,.READY + LD BC,IDE.Write.Command + LD A,IDE.ATAPI.Reset + OUT (C),A + + LD B,#80 +.pause: DJNZ .pause + + EXX + LD DE,#8000 + CALL CD_WAITPRT + EXX + RET C +.READY: + LD C,SLOT3 + IN B,(C) + + PUSH DE + PUSH BC + + LD A,SYS_PAGE + OUT (C),A + LD A,B + LD DE,RAM_ATAPI_PK ;!FIXIT может на стеке выделять место? + LD BC,PKTSIZE + LDIR + + POP BC + POP DE + OUT (C),B + + XOR A + EXX + ;OUT (C),A + ;XOR A + LD BC,IDE.Write.Features + OUT (C),A + LD DE,SIZESEC ;SIZE BLOCK ;!HARDCODE доставать из переменной какой-нибудь + LD BC,IDE.Write.CylinderLow + OUT (C),E + LD BC,IDE.Write.CylinderHigh + OUT (C),D + LD BC,IDE.Write.Command + LD A,IDE.ATAPI.Packet + OUT (C),A + LD DE,#8000 + CALL CD_WAITPRT + EXX + RET C + EXX + LD DE,#0908 + CALL CD_WAITPRT + EXX + BIT IDE.ControlBit.Error,A + JR NZ,.CDERROR + JR NC,.YEP_DRQ + LD A,#80 ; TIME OUT ;!HARDCODE + RET +.YEP_DRQ: + LD C,SLOT3 + IN B,(C) + PUSH BC + LD A,SYS_PAGE + OUT (SLOT3),A + LD HL,RAM_ATAPI_PK + LD BC,IDE.Write.Data + LD A,PKTSIZE/2 +.OUTPKT: + OUTI + OUTI + DEC A + JR NZ,.OUTPKT + + POP BC + OUT (C),B + + LD B,#80 +.pause2: DJNZ .pause2 + +.AP_LOOP: + EXX + LD DE,#8000 + CALL CD_WAITPRT + EXX + RET C + LD BC,IDE.Read.Status + IN A,(C) + BIT IDE.ControlBit.Error,A + JR Z,.NO_ERR +.CDERROR: + LD BC,IDE.Read.Error ;ERROR + IN A,(C) + RRCA + RRCA + RRCA + RRCA + AND #0F + SCF + RET +.NO_ERR: + BIT IDE.ControlBit.DataRequest,A + LD A,BIOS.Error.NoErrors + RET Z ;NO DATA REQUEST + EX DE,HL + LD BC,IDE.Read.CylinderLow + IN E,(C) + LD BC,IDE.Read.CylinderHigh + IN D,(C) ;TRANSFER BLOCK SIZE + LD A,D + OR E + RET Z ;BLOCK = 0 + LD BC,IDE.Read.Counter + IN A,(C) + AND #02 + ;CP #02 + JR NZ,.FROM_CD +;.TO_CD: + LD BC,IDE.Read.Data +.WR_T_CD: + OUTI + OUTI + DEC DE + DEC DE + LD A,D + OR E + JR NZ,.WR_T_CD + EX DE,HL + JR .AP_LOOP +.FROM_CD: + LD A,H + OR L + JR Z,.NULL + LD BC,IDE.Read.Data +.RD_F_CD: + INI + INI + DEC DE + DEC DE + LD A,D + OR E + JR NZ,.RD_F_CD + EX DE,HL + JR .AP_LOOP +.NULL: LD BC,IDE.Read.Data +.RD_N_CD: + IN A,(C) + DEC B + IN A,(C) + DEC B + DEC DE + DEC DE + LD A,D + OR E + JR NZ,.RD_N_CD + ; DE = 0 + JR .AP_LOOP +;----------------------------------------------------------------------; + + +;----------------------------------------------------------------------; +; D - MASK +; E - PATTERN +CD_WAITPRT: + LD BC,IDE.Read.Status + LD A,100 + LD HL,#0000 +.CWAITPX: + EX AF,AF' +.CWAITP0: + IN A,(C) + CP #FF + JR Z,.CWAITP1 + AND D + CP E + JR NZ,.CWAITP2 + AND A + RET +.CWAITP2: + DEC L + JR NZ,.CWAITP0 + DEC H + JR NZ,.CWAITP0 + EX AF,AF' + DEC A + JR NZ,.CWAITPX + EX AF,AF' +.CWAITP1: + SCF + RET +;----------------------------------------------------------------------; + + +;----------------------------------------------------------------------; +CD_TEST LD HL,ATAPI_CMD_PACKET.NOP + LD DE,0 ;!FIXIT нужно ли? + JP AP_COM +;----------------------------------------------------------------------; + + +//////////////////////////////////////////////////////////////////////// +ATAPI_CMD_PACKET: +.NOP: DUP 12 + DB #00 + EDUP +; +.OPEN: DB #1B + DB #00,#00,#00 + DB #02 + DB #00,#00,#00,#00,#00,#00,#00 +; +.CLOSE: DB #1B + DB #00,#00,#00 + DB #03 + DB #00,#00,#00,#00,#00,#00,#00 +; +.READ: DB #28,#00 + DB #00,#00,#00,#00 ; sector dword + DB #00 + DB #00,#01,#00,#00 ; counter dword + DB #00 +; +ATAPI_PACKET: +.SECTOR EQU 2 +.COUNTER EQU 7 +//////////////////////////////////////////////////////////////////////// +; +; E - Second * 10 +; PAUSE LD HL,#0000 +; PAUSE1 DEC L +; JR NZ,PAUSE1 +; DEC H +; JR NZ,PAUSE1 +; DEC E +; JR NZ,PAUSE1 +; RET +; \ No newline at end of file diff --git a/Crazy BIOS/exp/EXTENDED/IDE/HDD_DRV.ASM b/Crazy BIOS/exp/EXTENDED/IDE/HDD_DRV.ASM new file mode 100644 index 0000000..6af223d --- /dev/null +++ b/Crazy BIOS/exp/EXTENDED/IDE/HDD_DRV.ASM @@ -0,0 +1,663 @@ + +;======================================================== +;R03 !25.07.2001! BUG FIX WITH RETURN ERROR CODE +;R02 !24.07.2001! ADD SECONDARY CHANEL +;R01 !16.08.2000! REMOVED "DI" + +/* +;Write +IDE.Write.Command EQU #4153 ; #1F7 Command +IDE.Write.DeviceHead EQU #4152 ; #1F6 Drive Control + +HDW_CLH EQU #0155 ; #1F5 Cylinder High +HDW_CLL EQU #0154 ; #1F4 Cylinder Low +HDW_SEC EQU #0153 ; #1F3 Sector +HDW_CNT EQU #0152 ; #1F2 Counter +HDW_ERR EQU #0151 ; #1F1 Error +HDW_DAT EQU #0150 ; #1F0 Data + +;Read +IDE.Read.Status EQU #4053 ; #1F7 Status (Control) +HDR_DRV EQU #4052 ; #1F6 Drive Control + +HDR_CLH EQU #0055 ; #1F5 Cylinder High +HDR_CLL EQU #0054 ; #1F4 Cylinder Low +HDR_SEC EQU #0053 ; #1F3 Sector +HDR_CNT EQU #0052 ; #1F2 Counter +HDR_ERR EQU #0051 ; #1F1 Error +HDR_DAT EQU #0050 ; #1F0 Data + +;Bits for IDE.Read.Status +;---[] +BSY EQU 7 +RDY EQU 6 +DRQ EQU 3 +ERR EQU 0 +;---[] + +HDD EQU 1 +CDROM EQU 2 + + +;EQU FOR IY+ +IDE.HDD_INIT_TABLE.DRV_Flags EQU 0 +IDE.HDD_INIT_TABLE.SectorsPerTrack EQU 1 +IDE.HDD_INIT_TABLE.HeadsNumber EQU 2 +IDE.HDD_INIT_TABLE.CylinderNumberLow EQU 3 +IDE.HDD_INIT_TABLE.CylinderNumberHigh EQU 4 +IDE.HDD_INIT_TABLE.SectorsPerCylinderLow EQU 5 +IDE.HDD_INIT_TABLE.SectorsPerCylinderHigh EQU 6 +DTYPE_H EQU 7 + +IDE0 EQU #C1C0 +IDE1 EQU #C1C8 +IDE2 EQU #C1D0 +IDE3 EQU #C1D8 +*/ + +;IDE0 DB #FF ;DRIVE/HEAD REGISTER ;00 +; DB #FF ;SECTORS PER TRACK ;01 +; DB #FF ;HEADS ;02 +; DB #FF ;CYLINDERS LOW ;03 +; DB #FF ;CYLINDERS HIGH ;04 +; DB #FF ;SECTOR PER CYLINDER LOW ;05 +; DB #FF ;SECTOR PER CYLINDER HIGH ;06 +; DB #FF ;RESERVED ;07 + +;IDE1 DB #FF ;DRIVE/HEAD REGISTER ;00 +; DB #FF ;SECTORS PER TRACK ;01 +; DB #FF ;HEADS ;02 +; DB #FF ;CYLINDERS LOW ;03 +; DB #FF ;CYLINDERS HIGH ;04 +; DB #FF ;SECTOR PER CYLINDER LOW ;05 +; DB #FF ;SECTOR PER CYLINDER HIGH ;06 +; DB #FF ;RESERVED ;07 + + +WRITE_OUTI_DUPs EQU 32 ; bytes + +;[]================================================================[#51] +;Function: Reset drive +HDD_5x_RESET: ; !FIXIT не ресетится? +;For non-ATAPI drives, the only method a driver has of resetting a drive +; after a major error is to do a "software reset" on the bus. +; Set bit 2 (SRST, value = 4) in the proper Control Register for the +; bus. This will reset both ATA devices on the bus. Then, you have to +; clear that bit again, yourself. The master drive on the bus is +; automatically selected. + XOR A + RET +;[]================================================================[#51] + + +;[]================================================================[#58] +;Function: Get Current Media Parameters +; A - Disk +;Return: +; H - Heads +; L - Sectors per cylinder +; DE - Cylinders +; IX - Capacity sector in bytes +; B - Flags: MASTER/SLAVE, LBA/CHS +HDD_5x_GETMED: + LD C,IDE.Device.HDD + CALL SELECT_DRIVE + RET C + IN A,(SLOT3) + EX AF,AF' + LD A,SYS_PAGE + OUT (SLOT3),A + LD L,(IY+IDE.HDD_INIT_TABLE.SectorsPerTrack) + LD H,(IY+IDE.HDD_INIT_TABLE.HeadsNumber) + LD E,(IY+IDE.HDD_INIT_TABLE.CylinderNumberLow) + LD D,(IY+IDE.HDD_INIT_TABLE.CylinderNumberHigh) + LD B,(IY+IDE.HDD_INIT_TABLE.DRV_Flags) + LD IX,512 ;!HARDCODE sector size + EX AF,AF' + OUT (SLOT3),A + ;EX AF,AF' + AND A + RET +;[]================================================================[#58] + +;[]================================================================[#59] +;Function: Set Current Media Parameters +; A - Disk +; H - Heads +; L - Sectors +; DE - Cylinders +; IX - Capacity sector in bytes +; B - Flags +;Return: None +HDD_5x_SETMED: + LD C,IDE.Device.HDD + CALL SELECT_DRIVE + RET C + IN A,(SLOT3) + EX AF,AF' + LD A,SYS_PAGE + OUT (SLOT3),A + LD (IY+IDE.HDD_INIT_TABLE.SectorsPerTrack),L + LD (IY+IDE.HDD_INIT_TABLE.HeadsNumber),H + LD (IY+IDE.HDD_INIT_TABLE.CylinderNumberLow),E + LD (IY+IDE.HDD_INIT_TABLE.CylinderNumberHigh),D + LD (IY+IDE.HDD_INIT_TABLE.DRV_Flags),B + EX AF,AF' + OUT (SLOT3),A + ;EX AF,AF' + AND A + RET +;[]================================================================[#59] + +;[]================================================================[#55] +;Function: Read Sectors +; A - Disk +; HL:IX - Sector +; DE - Address +; B - Sector counter +;Return: +; HL:IX - Sector + Sector counter +; DE - Address + (Sector counter * Size sector) +;READ SECTOR(S) +HDD_5x_READ: + EX AF,AF' + IN A,(SLOT3) + EX AF,AF' +;[]================================================================[#52] +;Function: Long Read Sectors +; A - Disk +; HL:IX - Sector +; DE - Address +; B - Sector counter +; A'- Memory Page Number +;Return: +; HL:IX - Sector + Sector counter +; DE - Address + (Sector counter * Size sector) +;LONG READ SECTOR(S) +HDD_5x_LONG_READ: + PUSH IY + + SAFE_PORTY_2 + + PUSH BC + PUSH IX + PUSH HL + CALL RDS000 + EX DE,HL + JR C,HERRRD0 + LD A,XH + EX AF,AF' + POP HL + POP IX + POP BC + XOR A + CP B + LD C,B + LD B,A + JR NZ,RNOT256 + INC B + ADD IX,BC + LD B,C + ADC HL,BC + ;EX AF,AF' ;!TEST 21/11/23 + JR RST8RDR + +RNOT256 ADD IX,BC + LD C,B + ADC HL,BC + ;EX AF,AF' ;!TEST 21/11/23 + JR RST8RDR + +HERRRD0 LD B,A + LD C,XL + LD A,XH + EX AF,AF' + POP HL + POP IX + PUSH BC + LD B,0 + ADD IX,BC + LD C,B + ADC HL,BC + POP BC + POP AF + SUB C + LD C,A + LD A,B + LD B,C + ;R03 + SCF + ;EX AF,AF' ;!TEST 21/11/23 + ; +RST8RDR: RESTORE_PORTY + POP IY + ;EX AF,AF' ;!TEST 21/11/23 + RET + + ;READ SECTOR(S) +RDS000: LD C,IDE.Device.HDD + CALL SELECT_DRIVE + RET C + EXX + LD DE,#C140 ;WAIT BUSY=0 & READY=1 & ERR=0 + CALL WAITPRT + EXX + RET C + EX AF,AF' + PUSH AF + PUSH DE + CALL PRESET + POP HL + POP AF + LD XL,0 + LD XH,A + LD BC,IDE.Write.Command + LD A,IDE.ATA.ReadSectorsWithRetry + OUT (C),A +;????? +;SAVE HL! +RDS002: EXX + LD DE,#8908 ;WAIT BUSY=0 & DRQ=1 & ERR=0 + CALL WAITPRT + EXX + RET C + ;NOP ;R01 REMOVED "DI" + IN A,(SLOT3) + EX AF,AF' + LD A,XH + OUT (SLOT3),A + LD BC,IDE.Read.Data + +RDS003: DUP 16 + INI + EDUP + JP NZ,RDS003 +RDS004: DUP 16 + INI + EDUP + JP NZ,RDS004 + + EX AF,AF' + OUT (SLOT3),A +; + LD A,H + OR L + JR NZ,.W44 + LD HL,#C000 + IN A,(SLOT3) + EX AF,AF' + LD A,SYS_PAGE + OUT (SLOT3),A + LD D,#C2 + LD E,XH + LD A,(DE) + LD XH,A + EX AF,AF' + OUT (SLOT3),A + ; +.W44: INC XL ;INC LOADED SECTORS + EXX + LD DE,#C140 ;WAIT BUSY=0 & ERR=0 & READY=1 + CALL WAITPRT + EXX + RET C + LD BC,IDE.Read.Status + IN A,(C) + BIT IDE.ControlBit.DataRequest,A + JP NZ,RDS002 + XOR A + RET +;[]===========================================================[#52, #55] + + +;[]================================================================[#56] +;Function: Write Sectors +; A - Disk +; HL:IX - Sector +; DE - Address +; B - Sector counter +;Return: +; HL:IX - Sector + Sector counter +; DE - Address + (Sector counter * Size sector) +;WRITE SECTOR(S) +HDD_5x_WRITE: + EX AF,AF' + IN A,(SLOT3) + EX AF,AF' +;[]================================================================[#53] +;Function: Long Write Sectors +; A - Disk +; HL:IX - Sector +; DE - Address +; B - Sector counter +; A'- Memory Page Number +;Return: +; HL:IX - Sector + Sector counter +; DE - Address + (Sector counter * Size sector) +;WRITE SECTOR(S) +HDD_5x_LONG_WRITE: + PUSH IY + + SAFE_PORTY_2 + + PUSH IX + PUSH HL + PUSH BC + CALL WRS000 + EX DE,HL + JP C,HERRWR0 + LD A,XH + EX AF,AF' + POP BC + POP HL + POP IX + XOR A + CP B + LD C,B + LD B,A + JR NZ,WNOT256 + INC B + ADD IX,BC + LD B,C + ADC HL,BC + ;EX AF,AF' + JR RST8WRR + +WNOT256 ADD IX,BC + LD C,B + ADC HL,BC + ;EX AF,AF' + JR RST8WRR + +HERRWR0 LD B,A + LD C,XL + LD A,XH + EX AF,AF' + POP HL + POP IX + PUSH BC + LD B,0 + ADD IX,BC + LD C,B + ADC HL,BC + POP BC + POP AF + SUB C + LD C,A + LD A,B + LD B,C + ;R03 + SCF ;R03 + ;EX AF,AF' ;R03 ;!FIXIT намудрил он чёт в этом R03 + ; +RST8WRR: RESTORE_PORTY + POP IY + ;EX AF,AF' + RET + +;WRITE SECTOR(S) +WRS000: + LD C,IDE.Device.HDD + CALL SELECT_DRIVE + RET C + EXX + LD DE,#C140 ;WAIT BUSY=0 & READY=1 & ERR=0 + CALL WAITPRT + EXX + RET C + EX AF,AF' + PUSH AF + PUSH DE + + ;[x] CMOS Write Protect Disabled + IF HDDwriteProtect + PUSH BC + LD D,CMOS_CELL.Options + CALL CMOS_RD + POP BC + AND 1 + JR Z,NO_WriteProtect + POP HL + POP AF + EX AF,AF' + LD XL,0 + LD A,BIOS.Error.WriteProtect + SCF + RET + ENDIF +NO_WriteProtect: + CALL PRESET + POP HL + POP AF + LD XL,0 + LD XH,A + LD BC,IDE.Write.Command + LD A,IDE.ATA.WriteSectorsWithRetry + OUT (C),A +;SAVE HL! +WRS002: EXX + LD DE,#8908 ;WAIT BUSY=0 & DRQ=1 & ERR=0 + CALL WAITPRT + EXX + RET C + + ;DI + IN A,(SLOT3) + EX AF,AF' + LD A,XH + OUT (SLOT3),A + LD BC,IDE.Write.Data + ;LD D,#20 + LD D,512/WRITE_OUTI_DUPs +WRS003: + DUP WRITE_OUTI_DUPs + OUTI + EDUP + DEC D + JR NZ,WRS003 + + EX AF,AF' + OUT (SLOT3),A + //EI +; + LD A,H + OR L + JR NZ,.W33 + LD HL,#C000 + IN A,(SLOT3) + EX AF,AF' + LD A,SYS_PAGE + OUT (SLOT3),A + LD D,#C2 + LD E,XH + LD A,(DE) + LD XH,A + EX AF,AF' + OUT (SLOT3),A +.W33: INC XL ;INC SAVED SECTORS + EXX + LD DE,#C140 ;WAIT BUSY=0 & ERR=0 & READY=1 + CALL WAITPRT + EXX + RET C + LD BC,IDE.Read.Status + IN A,(C) + BIT IDE.ControlBit.DataRequest,A + JP NZ,WRS002 + XOR A + RET +;[]===========================================================[#53, #56] + + +;[]================================================================[#54] +;Function: Verify Sectors +; A - Disk +; HL:IX - Sector +; B - Sector counter +;Return: None +;VERIFY SECTOR(S) +HDD_5x_VERIFY: + PUSH IY + SAFE_PORTY_2 + PUSH IX + PUSH HL + CALL VRS000 + POP HL + POP IX + RESTORE_PORTY + POP IY + RET +;[]================================================================[#54] +;VERIFY SECTOR(S) +VRS000: LD C,IDE.Device.HDD + CALL SELECT_DRIVE + RET C + EXX + LD DE,#C140 ;WAIT BUSY=0 & READY=1 & ERR=0 + CALL WAITPRT + EXX + RET C + PUSH DE + CALL PRESET + POP HL + LD BC,IDE.Write.Command + LD A,IDE.ATA.ReadVerifySectorsWithRetry + OUT (C),A +VRS002: LD BC,IDE.Read.Status + IN A,(C) + BIT IDE.ControlBit.Error,A + JR Z,VRS003 + SCF + RET +VRS003: LD DE,#C140 ;WAIT BUSY=0 & ERR=0 & READY=1 + CALL WAITPRT + RET C + XOR A + RET + +; HL:IX - LBA SECTOR +; B - SECTOR COUNTER +PRESET: LD A,B + LD BC,IDE.Write.Counter + OUT (C),A + IN A,(SLOT3) + EX AF,AF' + LD A,SYS_PAGE + OUT (SLOT3),A + LD A,(IY+IDE.HDD_INIT_TABLE.DRV_Flags) + LD BC,IDE.Write.DeviceHead + OUT (C),A + ;бит CHS/LBA ;!FIXIT сделать метками номера бит + AND %0100'0000 + LD E,XL + LD D,XH + CALL Z,LBA_CHS + LD BC,IDE.Write.Sector + OUT (C),E ;LBA 0..7 + IF IDE_Optimization + INC C ; LD BC,IDE.Write.CylinderLow + OUT (C),D ;LBA 8..15 + INC C ; LD BC,IDE.Write.CylinderHigh + OUT (C),L ;LBA 16..23 + LD BC,IDE.Read.Control + IN A,(C) + AND #F0 ;!HARDCODE DRIVE/HEAD REGISTER PHISICAL DISK bitmask + OR H ;LBA 24..27 + INC B ; LD BC,IDE.Write.DeviceHead + ELSE + LD BC,IDE.Write.CylinderLow + OUT (C),D ;LBA 8..15 + LD BC,IDE.Write.CylinderHigh + OUT (C),L ;LBA 16..23 + LD BC,IDE.Read.Control + IN A,(C) + AND #F0 ;!HARDCODE DRIVE/HEAD REGISTER PHISICAL DISK bitmask + OR H ;LBA 24..27 + LD BC,IDE.Write.DeviceHead + ENDIF + OUT (C),A + EX AF,AF' + OUT (SLOT3),A + AND A + RET + +; HL:DE - SECTOR OFFSET +LBA_CHS: + LD C,(IY+IDE.HDD_INIT_TABLE.SectorsPerCylinderLow) + LD B,(IY+IDE.HDD_INIT_TABLE.SectorsPerCylinderHigh) +; HL:DE / BC => DE:IX HL-OSTATOK +DIV32X: LD XH,D + LD XL,E + EX DE,HL + LD HL,0 + LD A,#20 +DIV011: ADD IX,IX + EX DE,HL + ADC HL,HL + EX DE,HL + ADC HL,HL + SBC HL,BC + JR NC,DIV012 + ADD HL,BC + DEC A + JR NZ,DIV011 + JR DIV014 +DIV012: INC IX + DEC A + JR NZ,DIV011 +DIV014: LD E,(IY+IDE.HDD_INIT_TABLE.SectorsPerTrack) + LD D,0 + XOR A +CHS005: INC A + SBC HL,DE + JR NC,CHS005 + ADD HL,DE + DEC A + LD H,A + LD E,L + INC E + LD D,XL + LD A,XH + LD L,A + RET + +;----------------------------------------------------------------------; +; D - MASK +; E - PATTERN +WAITPRT: + LD BC,IDE.Read.Status + LD HL,#0000 ; задержка ;!HARDCODE + ; +.loop: PUSH HL +; +.loop2: IN A,(C) + AND D + CP E + JR Z,.ok + DEC HL + LD A,L + OR H + JP NZ,.loop2 + ; + POP HL + DEC L + JR NZ,.loop + ; +.error: LD A,BIOS.Error.NotReady + SCF + RET +.ok: POP HL + RET +;----------------------------------------------------------------------; + + +;[]================================================================[#57] +;[x] 18/12/2023. добавление/допиливание API CD-ROM (ATAPI) +;Function: Detect Disk +; A - Disk +;Return: CF=0 - A=Drive type +; CF=1 - drive not present, A=#02 +HDD_5x_DETECT: + LD C,IDE.Device.HDD + JP DRV_DETECT +;[]================================================================[#57] \ No newline at end of file diff --git a/Crazy BIOS/exp/EXTENDED/IDE/shared.asm b/Crazy BIOS/exp/EXTENDED/IDE/shared.asm new file mode 100644 index 0000000..4980061 --- /dev/null +++ b/Crazy BIOS/exp/EXTENDED/IDE/shared.asm @@ -0,0 +1,100 @@ +;[x] 18/12/2023. добавление/допиливание API CD-ROM (ATAPI) + +;======================================================================= +; Вход: A - номер устройства +; C - Тип +SELECT_DRIVE: + AND #0F + LD IY,IDE.INIT_TBL_IDE0 + JR Z,.channel + DEC A + LD IY,IDE.INIT_TBL_IDE1 + ;R02 + JR Z,.channel + DEC A + LD IY,IDE.INIT_TBL_IDE2 + JR Z,.channel + DEC A + LD IY,IDE.INIT_TBL_IDE3 + ; + JR Z,.channel + LD A,BIOS.Error.BadNumber + SCF + RET + ; +.channel: + EXX + IN A,(SLOT3) + PUSH AF + LD A,SYS_PAGE + OUT (SLOT3),A + ; + LD A,(IY+IDE.HDD_INIT_TABLE.DRV_Flags) + AND 1 + LD A,IDE.Chanel.Secondary + JR NZ,.device + LD A,IDE.Chanel.Primary +.device: + OUT (IDE.Chanel.Set),A ;R02 + LD C,(IY+IDE.HDD_INIT_TABLE.DriveType) + LD B,(IY+IDE.HDD_INIT_TABLE.DRV_Flags) + POP AF + OUT (SLOT3),A ;возврат страницы + ; + LD A,C + EXX + CP C + EXX + SCF + LD A,BIOS.Error.BadNumber + RET NZ + ; + LD A,B + AND #F0 + LD BC,IDE.Write.DeviceHead + OUT (C),A + EXX + RET + ; +; NODRIVE: +; LD A,BIOS.Error.BadDrvNumber +; SCF +; RET +;======================================================================= + + +;======================================================================= +;Function: Detect Disk +; A - Disk +; С - Type +;Return: CF=0 - A=Drive type +; CF=1 - drive not present, A=#02 +DRV_DETECT: + CP #84 ;!HARDCODE max IDE drives (#80,#81,#82,#83) + CCF + JR C,.error + + LD HL,IDE.INIT_TBL_IDE0.DriveType + AND 3 + JR Z,.get_param + LD HL,IDE.INIT_TBL_IDE1.DriveType + DEC A + JR Z,.get_param + LD HL,IDE.INIT_TBL_IDE2.DriveType + DEC A + JR Z,.get_param + LD HL,IDE.INIT_TBL_IDE3.DriveType +.get_param: + IN A,(SLOT3) + LD B,A + LD A,SYS_PAGE + OUT (SLOT3),A + + LD A,(HL) + CP C ; compare Type + LD C,SLOT3 + OUT (C),B + RET Z + SCF +.error: LD A,BIOS.Error.BadNumber + RET \ No newline at end of file diff --git a/Crazy BIOS/exp/EXTENDED/RAM_DISK_DRIVER_1.asm b/Crazy BIOS/exp/EXTENDED/RAM_DISK_DRIVER_1.asm new file mode 100644 index 0000000..6c3afe0 --- /dev/null +++ b/Crazy BIOS/exp/EXTENDED/RAM_DISK_DRIVER_1.asm @@ -0,0 +1,189 @@ +;!TODO сделать выбор рамдрайва по значению bit 0..3 регистра А +; например: A = #6E означает: 6 - RAM Drive, #E - диск E: +; +;[]===========================================================[] +;Function: Set Current Media Parameters +; A - Disk +; H - Heads +; L - Sectors +; DE - Cylinders +; IX - Capacity sector in bytes +; B - Flags +;Return: None +;[]===========================================================[] +;!FIXIT +RMD_5x_SETMED: + and a + ret +; A - Disk +; H - Heads +; L - Sectors +; DE - Cylinders +; IX - Capacity sector in bytes +; B - Flags +; DB 'E' - 'A' = 4 +; +; +; +;[]===========================================================[] +;Function: Get Current Media Parameters +; A - Disk +;Return: +; H - Heads +; L - Sectors per cylinder +; DE - Cylinders +; IX - Capacity sector in bytes +; B - Flags: ramblock ID +;[]===========================================================[] +RMD_5x_GETMED: +.SectorSize EQU 512 ;!HARDCODE + AND #0F + CALL GET_RAMD_ST ; получение идентификатора блока + RET C + SCF + RET Z + ; + LD C,A + LD B,#FF +.loop: INC B + PUSH BC + LD A,C + CALL EMM.GetMemPage ; получить физический номер страницы из блока + POP BC + JR NC,.loop + ; CF==1, A==0 - ошибка, A==#FF - ok + INC A + RET NZ ; если выходит, то с флагами CF==1, ZF==1 + + LD E,B + LD B,C + ; тут в E количество страниц в рамдиске, B - ID рамдиска + LD HL,1*256 + #4000/.SectorSize + LD D,0 + LD IX,.SectorSize + RET + +//////////////////////////////////////////////////////////////////////////////////// +RMD_5x_LONG_WRITE: + LD C,#FF + JP RAM_DRV_READ_WRITE +RMD_5x_LONG_READ: + LD C,0 + JP RAM_DRV_READ_WRITE +RMD_5x_WRITE: + LD C,#FF + JP RAM_DRV_NO_LONG +RMD_5x_READ: + LD C,0 + ;JP RAM_DRV_NO_LONG +RAM_DRV_NO_LONG: + EX AF,AF' + IN A,(SLOT3) + EX AF,AF' +; НА входе рег С = 0 если чтение, либо #FF, если запись +RAM_DRV_READ_WRITE: + PUSH HL + PUSH AF + LD L,B + IN A,(SLOT3) + LD H,A + +; LD A,H +; OR L +; JR NZ,.error_stack2 ; if sector_high > 0 +; POP AF + + POP AF + EX (SP),HL + PUSH AF + + LD A,H + OR L + JR NZ,.error_stack2 ; if sector_high > 0 + POP AF + + EX AF,AF' + OUT (SLOT3),A + LD A,C ; в рег C команда чтения или записи + EX AF,AF' +; A' = command + + PUSH BC ; Sector_counter + PUSH DE ; Address + PUSH IX ; Sector_low + + AND #0F ;номер рамдиска + ;LD C,BIOS.GET_RAMD_ST + ;RST_to_BIOS + CALL GET_RAMD_ST +; A = Memory Block ID + + POP DE ; Sector_low + POP HL ; Address + POP BC ; Sector_counter + JR C,.error_stack1 + + SLA E + RL D ; Sector_low * 2 + JR C,.error_stack1 + + + PUSH BC + SLA B ; Sector_counter * 2 - типа у дискеты сектор 512 байтов + JR C,.error_stack2 + + PUSH DE + //PUSH BC + ;LD C,BIOS.BLK_RD_WR + ;RST_to_BIOS + CALL BLK_RD_WR + JR C,.error_stack3 +; hl = address + Sector_low * 256 * Sector_counter + + //POP BC + //SRL B + + POP DE +; de = Sector_low * 2 + + SRL D + RR E +; de = Sector_low + + POP BC +; b = Sector_counter + + LD A,E + ADD A,B + LD E,A + LD A,D + ADC A,0 + LD D,A +; de = Sector_counter + Sector_low + + PUSH DE + POP IX +; ix = Sector_counter + Sector_low + + EX DE,HL +; de = address + Sector_low * 256 * Sector_counter + + LD HL,0 + + POP AF + OUT (SLOT3),A + AND A +;Return: +; HL:IX - Sector + Sector counter +; DE - Address + (Sector counter * Size sector) + RET +.error_stack3: + POP BC +.error_stack2: + POP DE +.error_stack1: + POP AF + OUT (SLOT3),A + SCF + RET +//////////////////////////////////////////////////////////////////////////////////// \ No newline at end of file diff --git a/Crazy BIOS/exp/FLEX.asm b/Crazy BIOS/exp/FLEX.asm new file mode 100644 index 0000000..4f53d96 --- /dev/null +++ b/Crazy BIOS/exp/FLEX.asm @@ -0,0 +1,786 @@ + +SYCLES EQU 0 +;START EQU 1 +ST1 EQU 2 +DPAL1 EQU 3 +ST2 EQU 4 +DPAL2 EQU 5 + + MACRO NEXT_LIN_H + EX AF,AF' + INC A + OUT (RGADR),A + EX AF,AF' + ENDM + + MACRO NEXT_LIN_HP + EX AF,AF' + INC A + OUT (RGADR),A + JR NZ,.MD_NO_INC_H + inc l +.MD_NO_INC_H: + EX AF,AF' + ENDM + + +;***************************************** +; +; Инициализация страниц для +; спектрумовского режима и +; восстановление спектрумовского +; экрана +; +; Возврат по IX +; +; !!! NO USE STACK !!! +; +;***************************************** +; инициализация страниц zx spectrum +INIT_PAGES: + AND A + LD E,A + EX AF,AF' + LD A,E + +; BIT 7,A +; JR Z,SCORPION_256_MODE +; BIT 6,A +; JR Z,PENTAGON_128_MODE +; +;PENTAGON_48_MODE: +; AND 03CH +; OUT (SLOT0),A +; INC A +; OUT (SLOT1),A +; INC A +; OUT (SLOT2),A +; INC A +; LD D,A +; LD BC,1FFDH +; XOR A +; OUT (C),A +; LD B,7FH +; OUT (C),A +; LD A,D +; OUT (SLOT3),A +; JR INIT_VIDEO_REG +; +; +; PENTAGON_128_MODE: +; LD D,8 +; AND #38 +; JR ALL_MODE + +SCORPION_256_MODE: + LD D,16 + AND #30 ; до 4-х спектрумов + +ALL_MODE: + OUT (SLOT0),A + XOR 5 + OUT (SLOT1),A + XOR 7 + OUT (SLOT2),A + OR #0F + LD E,A + +.loop: DEC D + + LD A,D + RLCA + AND #10 + LD BC,#1FFD + OUT (C),A + + LD A,D + AND 7 + OR #40 + LD B,#7F + OUT (C),A + + LD A,E + OUT (SLOT3),A + DEC E + + DEC D + INC D + JR NZ,.loop + +INIT_VIDEO_REG: + XOR A + OUT (RGADR),A ; регистр видео адреса +; OUT (RGSCR),A ; регистр экрана + OUT (RGMOD),A ; регистр моды + + ;!TEST + ; Restore old Spectrum Screen + ;; LD HL,#4000 + ;; LD DE,#4000 + ;; LD BC,#1B00 + ;; LDIR + + ; EX AF,AF' + ; BIT 6,A + ; JR NZ,NO_SCREEN_ALT + + ; EX AF,AF' + + ; LD A,7 ; седьмая экранная страница + ; LD BC,#7FFD + ; OUT (C),A + + ; Restore old Spectrum Screen 2 + ;; LD HL,#C000 + ;; LD DE,#C000 + ;; LD BC,#1B00 + ;; LDIR + + ; XOR A + ; LD BC,#7FFD + ; OUT (C),A + ; + + EX AF,AF' +NO_SCREEN_ALT: + AND A + JP (IX) + +;**************************************** +; Загрузка режима экрана. +;**************************************** + +; CALL SINC_DEF +; CALL SET_PAL_ZX +; RET + +;**************************************** + +;!TODO тут функция +CL0 EQU 200 +CL1 EQU 240 + +SET_PAL_IBM: + LD DE,#8000 + JR SET_PAL_TXT +SET_PAL_ZX: + LD DE,0 +SET_PAL_TXT: + PUSH IX + IN A,(RGADR) + PUSH AF + IN A,(SLOT3) + EX AF,AF' + LD A,#50 + OUT (SLOT3),A + + LD IX,#C3F0 ; !HARDCODE адрес палитры? +.generate_loop: + CALL GENERATE_PAL1 + LD A,E + OUT (RGADR),A + LD (IX),L ; R + LD (IX+1),B ; G + LD (IX+2),C ; B + LD (IX+3),H ; i ? + INC E + JR NZ,.generate_loop + ; + LD BC,4 + ADD IX,BC + INC D + LD A,D + AND 3 + JR NZ,.generate_loop + + EX AF,AF' + OUT (SLOT3),A + POP AF + OUT (RGADR),A + POP IX + RET + +; генерация спектрумовской палитры. +; Вход: E - атрибут, D - номер палитры +; ВЫХОД: L - red, B - green, C - blue, H - intensity +GENERATE_PAL1: XOR A + LD C,A + LD B,A + LD L,A + BIT 7,D + JR NZ,GENERATE_IBM + BIT 1,D + JR NZ,.FLH +.NOF: BIT 0,D + JR Z,.PAPER +.INK: LD A,CL0 + BIT 6,E + JR Z,.NOI1 + LD A,CL1 +.NOI1: BIT 0,E ; BLUE + JR Z,.NO1 + LD C,A +.NO1: BIT 1,E ; RED + JR Z,.PP_NO2 + LD L,A +.PP_NO2: BIT 2,E ; GREEN + JR Z,.PP_NO3 + LD B,A +.PP_NO3: JR .PP_NO6 +; +.FLH: BIT 7,E + JR Z,.NOF + BIT 0,D + JR Z,.INK +.PAPER: LD A,CL0 + BIT 6,E + JR Z,.NOI2 + LD A,CL1 +.NOI2: BIT 3,E ; BLUE + JR Z,.PP_NO4 + LD C,A +.PP_NO4: BIT 4,E ; RED + JR Z,.PP_NO5 + LD L,A +.PP_NO5: BIT 5,E ; GREEN + JR Z,.PP_NO6 + LD B,A +.PP_NO6: LD A,C + AND A + RRA + ADD A,L + RRA + ADD A,B + RRA + LD H,A ; B/W mode + RET +;**************************************** + +GENERATE_IBM: + BIT 7,E + JR Z,.NO_FLH + BIT 1,D + JR Z,.PAPER +.NO_FLH: + BIT 0,D + JR Z,.PAPER +.INK: +.NO_INTENS: + LD A,#A8 +.INTENS: + BIT 0,E ; BLUE + JR Z,.PPI_NO4 + LD C,A +.PPI_NO4: + BIT 2,E ; RED + JR Z,.PPI_NO5 + LD L,A +.PPI_NO5: + BIT 1,E ; GREEN + JR Z,.PPI_NO6 + LD B,A +.PPI_NO6: + LD A,E + AND #0F + CP 6 + JR NZ,.no_correct + LD B,#54 +.no_correct: + BIT 3,E + JR Z,GENERATE_PAL1.PP_NO6 + + LD A,#54 + ADD A,C + LD C,A + LD A,#54 + ADD A,B + LD B,A + LD A,#54 + ADD A,L + LD L,A + JR GENERATE_PAL1.PP_NO6 +.PAPER: + LD A,#A8 + BIT 4,E ; BLUE + JR Z,.PPI_NO4X + LD C,A +.PPI_NO4X: + BIT 6,E ; RED + JR Z,.PPI_NO5X + LD L,A +.PPI_NO5X: + BIT 5,E ; GREEN + JR Z,.PPI_NO6X + LD B,A +.PPI_NO6X: + LD A,E + AND #70 + CP #60 + JR NZ,GENERATE_PAL1.PP_NO6 + LD B,#54 + JR GENERATE_PAL1.PP_NO6 +;**************************************** + +;**************************************** +;**************************************** + +; D - номер графической палитры +SET_PAL_GRAF: + PUSH IX + IN A,(RGADR) + PUSH AF + + IN A,(SLOT3) + EX AF,AF' + LD A,#50 + OUT (SLOT3),A + + + LD IX,#C3E0 + LD A,D + AND 3 + ADD A,A + ADD A,A + LD E,A + LD D,0 + ADD IX,DE + + LD E,0 + + XOR A + LD B,A + LD C,A + LD L,A + LD H,A + +SET_PAL_GR1: + LD A,E + OUT (RGADR),A + + LD (IX),L + LD (IX+1),B + LD (IX+2),C + LD (IX+3),H + + CALL GENERATE_PAL3 + + INC E + LD A,E + CP 40 + JR NZ,SET_PAL_GR1 + + XOR A + LD B,A + LD C,A + LD L,A + LD H,A + +SET_PAL_GR2: + LD A,E + OUT (RGADR),A + + LD (IX),L + LD (IX+1),B + LD (IX+2),C + LD (IX+3),H + + CALL GENERATE_PAL2 + + INC E + JR NZ,SET_PAL_GR2 + + EX AF,AF' + OUT (SLOT3),A + POP AF + OUT (RGADR),A + POP IX + RET +; +;;********************************* +; + +GENERATE_PAL3: ; gray-scale + LD A,B + ADD A,6 + LD B,A + LD C,A + LD L,A + + LD A,C + AND A + RRA + ADD A,L + RRA + ADD A,B + RRA + LD H,A + + RET + +GENERATE_PAL2: ; C - BLUE; L - RED; B - GREEN; H - INTENSITY + LD A,C + ADD A,50 + LD C,A + JR NC,GEN_PAL2_L1 + LD C,0 + LD A,L + ADD A,50 + LD L,A + JR NC,GEN_PAL2_L1 + LD L,0 + LD A,B + ADD A,50 + LD B,A + JR NC,GEN_PAL2_L1 + LD B,0 + +GEN_PAL2_L1: + LD A,C + AND A + RR A + ADD A,L + RR A + ADD A,B + RR A + LD H,A + + RET +; +;;***************************************** + +FN_SYNC: + BIT 7,a + JR Z,.old_mode + + ld h,a + and #60 ; check reserved bits + jr nz,.error + + bit 2,h ; Set V-Sinc? + jr nz,.set_v_sinc + + bit 4,h ; Set Waits? + jr z,.error ; Error - no parameters + +.set_waits: + ld a,h + and 8 ; check waits. Z - no waits, NZ - waits + ld h,#FF + jr z,1F + ld h,#FB +1: + ld bc,(Port_All_Mode) + in a,(C) + and h + out (C),a + RET + +.set_v_sinc: + ld a,h + and 3 + jr z,.SetDefLines + dec a + jr z,.SetCmosLines + dec a + jr z,.Set320Lines +; jr Set312Lines + +.set312lines: + ld a,Port_VSYNC.SET_312L + out (Port_VSYNC),a + + LD C,SLOT3 + IN B,(C) + LD A,SYS_PAGE + OUT (C),A + ld a,(SYS_PAGE.VSyncAndWaits) + and 2 + ld (SYS_PAGE.VSyncAndWaits),a + OUT (C),B + +.end_set_v_sinc: + bit 4,h + ret z + jr .set_waits + + +.Set320Lines: + ld a,Port_VSYNC.SET_320L + out (Port_VSYNC),a + + LD C,SLOT3 + IN B,(C) + LD A,SYS_PAGE + OUT (C),A + ld a,(SYS_PAGE.VSyncAndWaits) + or 1 + ld (SYS_PAGE.VSyncAndWaits),a + OUT (C),B + + jr .end_set_v_sinc + +.SetCmosLines: + LD D,CMOS_CELL.ScreenSET + CALL CMOS_RD + + AND high CMOS_CELL.ScreenSET.Mask.Sinc ; в регистре A значение ScreenSET + jr z,.SetDefLines + + bit 6,a + jr z,.set312lines + + jr .Set320Lines + +.old_mode: + AND A + JR Z,.INT_DEF + DEC A + JR Z,.INT_SCORP + DEC A + JR Z,.INT_PENT + DEC A + JR Z,.INT_ORIG + DEC A + JR Z,.INT_CMOS_SINC + ; [x] кастомный экран по таблице пользователя + DEC A + JR Z,.PROG_SCR + ; +.error: SCF + RET + +.SetDefLines: + LD C,SLOT3 + IN B,(C) + LD A,SYS_PAGE + OUT (C),A + ld a,(SYS_PAGE.VSyncAndWaits) + OUT (C),B + and 1 + jr z,.set312lines + jr .Set320Lines + +.INT_DEF: + LD C,SLOT3 + IN B,(C) + LD A,SYS_PAGE + OUT (C),A + LD DE,(SYS_PAGE.CONFIG_ALL) + OUT (C),B + + CALL Test_CONFIG_ALL + jr nz,.INT_CMOS_SINC + jp (IX) + +.INT_CMOS_SINC: + LD C,SLOT3 + IN B,(C) + LD A,SYS_PAGE + OUT (C),A + LD DE,(SYS_PAGE.CONFIG_ALL) + OUT (C),B + + LD D,CMOS_CELL.ScreenSET + CALL CMOS_RD + + AND high CMOS_CELL.ScreenSET.Mask.Int ; в регистре A значение ScreenSET + JR NZ,.skiptest + + CALL Test_CONFIG_ALL + JP (IX) ; default int (non CMOS) + +.skiptest: + cp #10 + jr z,.INT_SCORP ; scorpion int + + cp #20 + jr z,.INT_PENT ; pentagon int + +; jr ORIG_SINC ; original int + +.INT_ORIG: + LD IX,SCREEN_TABLES.ORIGINAL + JR .PROG_SCR +.INT_SCORP: + LD IX,SCREEN_TABLES.SCORPION + JR .PROG_SCR +.INT_PENT: + LD IX,SCREEN_TABLES.PENTAGON +; JR PROG_SCR +.PROG_SCR: + IN A,(SLOT3) + EX AF,AF' + LD A,SYS_PAGE + OUT (SLOT3),A + EX AF,AF' + LD (SYS_PAGE.COPY_SLOT3),A + IN A,(PORT_Y) + LD (SYS_PAGE.COPY_RGADR),A + + LD (SYS_PAGE.CONFIG_ALL),IX + XOR A + +;----[START]-----------------------[? 1] +.loop_1: + OUT (PORT_Y),A + EX AF,AF' + + LD A,#50 + OUT (SLOT3),A + + LD HL,#C300 + +;----[START]------------------[v 2]----- +.loop_2: + LD C,(IX) +;----[START]-------------[v 3]---------- +.loop_3: +; взять адрес данных для записи в служебную область экрана + LD E,(IX+1) ; take adress of line X + LD D,(IX+2) +;----[START]--------[v 4]--------------- +.loop_4: + LD A,(DE) ; take counter in table 1, line X, column Y + INC DE + AND A + JR Z,.loop_4_exit ; exit if zero-counter + LD B,A + LD A,(DE) + INC DE +;----[START]---[v 5]-------------------- +.loop_5: + LD (HL),A + INC L + LD (HL),0 + INC L + LD (HL),0 + + EX AF,AF' + INC A + OUT (PORT_Y),A + EX AF,AF' + + LD (HL),0 + DEC L + LD (HL),0 + DEC L + LD (HL),A + + EX AF,AF' + INC A + OUT (PORT_Y),A + EX AF,AF' + + DJNZ .loop_5 +;--------------[^ 5]-------------------- + JR .loop_4 +;-------------------[^ 4]--------------- +.loop_4_exit: + INC HL ; next line + INC HL + INC HL + INC HL + IN A,(PORT_Y) + AND #80 + OUT (PORT_Y),A + DEC C + JR NZ,.loop_3 +;------------------------[^ 3]---------- + INC IX ; next counter + INC IX + INC IX + LD A,(IX) + AND A + JR NZ,.loop_2 +;-----------------------------[^ 2]----- + LD A,SYS_PAGE + OUT (SLOT3),A + LD IX,(SYS_PAGE.CONFIG_ALL) + + EX AF,AF' + ADD A,#80 + JR NC,.loop_1 +;----------------------------------[^ 1] + + ; Exit + LD A,(SYS_PAGE.COPY_RGADR) + OUT (PORT_Y),A + LD A,(SYS_PAGE.COPY_SLOT3) + OUT (SLOT3),A +.exit: OR A + RET + +;DE - содержимое CONFIG_ALL +Test_CONFIG_ALL: + LD HL,SCREEN_TABLES.SCORPION + AND A + SBC HL,DE + ld IX,FN_SYNC.INT_SCORP + RET Z + + LD HL,SCREEN_TABLES.ORIGINAL + AND A + SBC HL,DE + ld IX,FN_SYNC.INT_ORIG + RET Z + + LD HL,SCREEN_TABLES.PENTAGON + AND A + SBC HL,DE + ld IX,FN_SYNC.INT_PENT + RET Z + and a + RET + + +;--- Screen data table 1: counter1, data1 .. counterX, dataX +SCREEN_TABLES: +; +; | число | значения | +; | строк | в | +; | /2 | строках | +.SCR: DB 41 , #F8 + DB 3 , #FC + DB 4 , #FC + DB 7 , #FC + DB 9 , #F8 + DB 0 + +;.SCR: DB 41,#F8, 3,#FC, 4,#FC, 7,#FC, 9,#F8, 0 +.INT: DB 40,#FC, 2,#FD, 6,#FC, 7,#FC, 9,#FC, 0 +.INT_SC: DB 41,#F8, 1,#FD, 6,#FC, 7,#FC, 9,#F8, 0 +.BLN: DB 41,#FC, 3,#FC, 4,#FC, 7,#FC, 9,#FC, 0 +.SNC: DB 41,#FC, 3,#FC, 4,#FC, 7,#FC, 9,#FC, 0 +.RES: DB 41,#F8, 3,#FE, 4,#FE, 7,#FE, 9,#F8, 0 +;--------------------------------------- + +;--- Screen data tables 2: counter1, data address1 .. counterX, data addressX +; +; | кол-во | значения | +; | строк | в | +; | | строке | +.PENTAGON: DB 33 : DW .SCR + DB 1 : DW .INT ; DW .BLN + DB 3 : DW .SNC + DB 1 : DW .BLN + DB 1 : DW .SCR + DB 1 : DW .RES + DB 0 ; end +.SCORPION: DB 31 : DW .SCR + DB 1 : DW .INT_SC + DB 1 : DW .SCR + DB 1 : DW .SNC + DB 3 : DW .SNC + DB 1 : DW .BLN + DB 2 : DW .RES + DB 0 ; end +.ORIGINAL: DB 33 : DW .SCR + DB 1 : DW .SNC + DB 1 : DW .INT + DB 2 : DW .SNC + DB 1 : DW .BLN + DB 1 : DW .SCR + DB 1 : DW .RES + DB 0 ; end +;--------------------------------------- +FLEX_END: diff --git a/Crazy BIOS/exp/FONT.ASM b/Crazy BIOS/exp/FONT.ASM new file mode 100644 index 0000000..2ef9370 --- /dev/null +++ b/Crazy BIOS/exp/FONT.ASM @@ -0,0 +1,170 @@ +; Знакогенератор + LUA PASS1 + fL = {} + for i = 1,16 do + fL[i]={} + end + -- 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + fL[1][1] = " -------- -######- -######- -##-##-- ---#---- --###--- ---#---- -------- ######## -------- ######## ----#### --####-- --###### -####### ---##--- " + fL[2][1] = " -------- #------# ######## #######- --###--- -#####-- ---#---- -------- ######## --####-- ##----## -----### -##--##- --##--## -##---## ##-##-## " + fL[3][1] = " -------- #-#--#-# ##-##-## #######- -#####-- --###--- --###--- ---##--- ###--### -##--##- #--##--# ----#### -##--##- --###### -####### --####-- " + fL[4][1] = " -------- #------# ######## #######- #######- #######- -#####-- --####-- ##----## -#----#- #-####-# -#####-# -##--##- --##---- -##---## ###--### " + fL[5][1] = " -------- #-####-# ##----## -#####-- -#####-- #######- #######- --####-- ##----## -#----#- #-####-# ##--##-- --####-- --##---- -##---## ###--### " + fL[6][1] = " -------- #--##--# ###--### --###--- --###--- ##-#-##- -#####-- ---##--- ###--### -##--##- #--##--# ##--##-- ---##--- -###---- -##--### --####-- " + fL[7][1] = " -------- #------# ######## ---#---- ---#---- ---#---- ---#---- -------- ######## --####-- ##----## ##--##-- -######- ####---- ###--##- ##-##-## " + fL[8][1] = " -------- -######- -######- -------- -------- --###--- --###--- -------- ######## -------- ######## -####--- ---##--- ###----- ##------ ---##--- " + -- 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F + fL[1][2] = " #------- ------#- ---##--- -##--##- -####### --#####- -------- ---##--- ---##--- ---##--- -------- -------- -------- -------- -------- -------- " + fL[2][2] = " ###----- ----###- --####-- -##--##- ##-##-## -##---## -------- --####-- --####-- ---##--- ---##--- --##---- -------- --#--#-- ---##--- ######## " + fL[3][2] = " #####--- --#####- -######- -##--##- ##-##-## --###--- -------- -######- -######- ---##--- ----##-- -##----- ##------ -##--##- --####-- ######## " + fL[4][2] = " #######- #######- ---##--- -##--##- -####-## -##-##-- -------- ---##--- ---##--- ---##--- #######- #######- ##------ ######## -######- -######- " + fL[5][2] = " #####--- --#####- ---##--- -##--##- ---##-## -##-##-- -######- -######- ---##--- -######- ----##-- -##----- ##------ -##--##- ######## --####-- " + fL[6][2] = " ###----- ----###- -######- -------- ---##-## --###--- -######- --####-- ---##--- --####-- ---##--- --##---- #######- --#--#-- ######## ---##--- " + fL[7][2] = " #------- ------#- --####-- -##--##- ---##-## ##--##-- -######- ---##--- ---##--- ---##--- -------- -------- -------- -------- -------- -------- " + fL[8][2] = " -------- -------- ---##--- -------- -------- -####--- -------- ######## -------- -------- -------- -------- -------- -------- -------- -------- " + -- 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F + fL[1][3] = " -------- --##---- -##-##-- -##-##-- --##---- -------- --###--- -##----- ---##--- -##----- -------- -------- -------- -------- -------- -----##- " + fL[2][3] = " -------- -####--- -##-##-- -##-##-- -#####-- ##---##- -##-##-- -##----- --##---- --##---- -##--##- --##---- -------- -------- -------- ----##-- " + fL[3][3] = " -------- -####--- -##-##-- #######- ##------ ##--##-- --###--- ##------ -##----- ---##--- --####-- --##---- -------- -------- -------- ---##--- " + fL[4][3] = " -------- --##---- -------- -##-##-- -####--- ---##--- -###-##- -------- -##----- ---##--- ######## ######-- -------- ######-- -------- --##---- " + fL[5][3] = " -------- --##---- -------- #######- ----##-- --##---- ##-###-- -------- -##----- ---##--- --####-- --##---- -------- -------- -------- -##----- " + fL[6][3] = " -------- -------- -------- -##-##-- #####--- -##--##- ##--##-- -------- --##---- --##---- -##--##- --##---- --##---- -------- --##---- ##------ " + fL[7][3] = " -------- --##---- -------- -##-##-- --##---- ##---##- -###-##- -------- ---##--- -##----- -------- -------- --##---- -------- --##---- #------- " + fL[8][3] = " -------- -------- -------- -------- -------- -------- -------- -------- -------- -------- -------- -------- -##----- -------- -------- -------- " + -- 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F + fL[1][4] = " -#####-- --##---- -####--- -####--- ---###-- ######-- --###--- ######-- -####--- -####--- -------- -------- ---##--- -------- -##----- -####--- " + fL[2][4] = " ##---##- -###---- ##--##-- ##--##-- --####-- ##------ -##----- ##--##-- ##--##-- ##--##-- --##---- --##---- --##---- -------- --##---- ##--##-- " + fL[3][4] = " ##--###- --##---- ----##-- ----##-- -##-##-- #####--- ##------ ----##-- ##--##-- ##--##-- --##---- --##---- -##----- ######-- ---##--- ----##-- " + fL[4][4] = " ##-####- --##---- --###--- --###--- ##--##-- ----##-- #####--- ---##--- -####--- -#####-- -------- -------- ##------ -------- ----##-- ---##--- " + fL[5][4] = " ####-##- --##---- -##----- ----##-- #######- ----##-- ##--##-- --##---- ##--##-- ----##-- -------- -------- -##----- -------- ---##--- --##---- " + fL[6][4] = " ###--##- --##---- ##--##-- ##--##-- ----##-- ##--##-- ##--##-- --##---- ##--##-- ---##--- --##---- --##---- --##---- ######-- --##---- -------- " + fL[7][4] = " -#####-- ######-- ######-- -####--- ---####- -####--- -####--- --##---- -####--- -###---- --##---- --##---- ---##--- -------- -##----- --##---- " + fL[8][4] = " -------- -------- -------- -------- -------- -------- -------- -------- -------- -------- -------- -##----- -------- -------- -------- -------- " + -- 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F + fL[1][5] = " -#####-- --##---- ######-- --####-- #####--- #######- #######- --####-- ##--##-- -####--- ---####- ###--##- ####---- ##---##- ##---##- --###--- " + fL[2][5] = " ##---##- -####--- -##--##- -##--##- -##-##-- -##---#- -##---#- -##--##- ##--##-- --##---- ----##-- -##--##- -##----- ###-###- ###--##- -##-##-- " + fL[3][5] = " ##-####- ##--##-- -##--##- ##------ -##--##- -##-#--- -##-#--- ##------ ##--##-- --##---- ----##-- -##-##-- -##----- #######- ####-##- ##---##- " + fL[4][5] = " ##-####- ##--##-- -#####-- ##------ -##--##- -####--- -####--- ##------ ######-- --##---- ----##-- -####--- -##----- #######- ##-####- ##---##- " + fL[5][5] = " ##-####- ######-- -##--##- ##------ -##--##- -##-#--- -##-#--- ##--###- ##--##-- --##---- ##--##-- -##-##-- -##---#- ##-#-##- ##--###- ##---##- " + fL[6][5] = " ##------ ##--##-- -##--##- -##--##- -##-##-- -##---#- -##----- -##--##- ##--##-- --##---- ##--##-- -##--##- -##--##- ##---##- ##---##- -##-##-- " + fL[7][5] = " -####--- ##--##-- ######-- --####-- #####--- #######- ####---- --#####- ##--##-- -####--- -####--- ###--##- #######- ##---##- ##---##- --###--- " + fL[8][5] = " -------- -------- -------- -------- -------- -------- -------- -------- -------- -------- -------- -------- -------- -------- -------- -------- " + -- 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F + fL[1][6] = " ######-- -####--- ######-- -####--- ######-- ##--##-- ##--##-- ##---##- ##---##- ##--##-- #######- -####--- ##------ -####--- ---#---- -------- " + fL[2][6] = " -##--##- ##--##-- -##--##- ##--##-- #-##-#-- ##--##-- ##--##-- ##---##- ##---##- ##--##-- ##---##- -##----- -##----- ---##--- --###--- -------- " + fL[3][6] = " -##--##- ##--##-- -##--##- -##----- --##---- ##--##-- ##--##-- ##---##- -##-##-- ##--##-- #---##-- -##----- --##---- ---##--- -##-##-- -------- " + fL[4][6] = " -#####-- ##--##-- -#####-- --##---- --##---- ##--##-- ##--##-- ##-#-##- --###--- -####--- ---##--- -##----- ---##--- ---##--- ##---##- -------- " + fL[5][6] = " -##----- ##-###-- -##-##-- ---##--- --##---- ##--##-- ##--##-- #######- --###--- --##---- --##--#- -##----- ----##-- ---##--- -------- -------- " + fL[6][6] = " -##----- -####--- -##--##- ##--##-- --##---- ##--##-- -####--- ###-###- -##-##-- --##---- -##--##- -##----- -----##- ---##--- -------- -------- " + fL[7][6] = " ####---- ---###-- ###--##- -####--- -####--- ######-- --##---- ##---##- ##---##- -####--- #######- -####--- ------#- -####--- -------- -------- " + fL[8][6] = " -------- -------- -------- -------- -------- -------- -------- -------- -------- -------- -------- -------- -------- -------- -------- ######## " + + -- 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F + fL[1][7] = " --##---- -------- ###----- -------- ---###-- -------- --###--- -------- ###----- --##---- ----##-- ###----- -###---- -------- -------- -------- " + fL[2][7] = " --##---- -------- -##----- -------- ----##-- -------- -##-##-- -------- -##----- -------- -------- -##----- --##---- -------- -------- -------- " + fL[3][7] = " ---##--- -####--- -##----- -####--- ----##-- -####--- -##----- -###-##- -##-##-- -###---- ----##-- -##--##- --##---- ##--##-- #####--- -####--- " + fL[4][7] = " -------- ----##-- -#####-- ##--##-- -#####-- ##--##-- ####---- ##--##-- -###-##- --##---- ----##-- -##-##-- --##---- #######- ##--##-- ##--##-- " + fL[5][7] = " -------- -#####-- -##--##- ##------ ##--##-- ######-- -##----- ##--##-- -##--##- --##---- ----##-- -####--- --##---- #######- ##--##-- ##--##-- " + fL[6][7] = " -------- ##--##-- -##--##- ##--##-- ##--##-- ##------ -##----- -#####-- -##--##- --##---- ##--##-- -##-##-- --##---- ##-#-##- ##--##-- ##--##-- " + fL[7][7] = " -------- -###-##- ##-###-- -####--- -###-##- -####--- ####---- ----##-- ###--##- -####--- ##--##-- ###--##- -####--- ##---##- ##--##-- -####--- " + fL[8][7] = " -------- -------- -------- -------- -------- -------- -------- #####--- -------- -------- -####--- -------- -------- -------- -------- -------- " + + -- 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F + fL[1][8] = " -------- -------- -------- -------- ---#---- -------- -------- -------- -------- -------- -------- ---###-- ---##--- ###----- -###-##- -------- " + fL[2][8] = " -------- -------- -------- -------- --##---- -------- -------- -------- -------- -------- -------- --##---- ---##--- --##---- ##-###-- ---#---- " + fL[3][8] = " ##-###-- -###-##- ##-###-- -#####-- -#####-- ##--##-- ##--##-- ##---##- ##---##- ##--##-- ######-- --##---- ---##--- --##---- -------- --###--- " + fL[4][8] = " -##--##- ##--##-- -###-##- ##------ --##---- ##--##-- ##--##-- ##-#-##- -##-##-- ##--##-- #--##--- ###----- -------- ---###-- -------- -##-##-- " + fL[5][8] = " -##--##- ##--##-- -##--##- -####--- --##---- ##--##-- ##--##-- #######- --###--- ##--##-- --##---- --##---- ---##--- --##---- -------- ##---##- " + fL[6][8] = " -#####-- -#####-- -##----- ----##-- --##-#-- ##--##-- -####--- #######- -##-##-- -#####-- -##--#-- --##---- ---##--- --##---- -------- ##---##- " + fL[7][8] = " -##----- ----##-- ####---- #####--- ---##--- -###-##- --##---- -##-##-- ##---##- ----##-- ######-- ---###-- ---##--- ###----- -------- #######- " + fL[8][8] = " ####---- ---####- -------- -------- -------- -------- -------- -------- -------- #####--- -------- -------- -------- -------- -------- -------- " + + -- 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F + fL[1][9] = " ----###- ######-- #####--- ######-- -######- ######-- ##-##-## --####-- ##---##- ##-#-##- ##---##- -----##- ##---##- ##---##- -#####-- #######- " + fL[2][9] = " ---####- ##------ ##--##-- ##------ -##--##- ##------ ##-##-## -##--##- ##---##- ##---##- ##--##-- ----###- ###-###- ##---##- ##---##- ##---##- " + fL[3][9] = " --##-##- ##------ ##--##-- ##------ -##--##- ##------ -######- -----##- ##--###- ##--###- ##-##--- ---####- #######- ##---##- ##---##- ##---##- " + fL[4][9] = " -##--##- ######-- ######-- ##------ -##--##- #####--- ---##--- --####-- ##-####- ##-####- #####--- --##-##- ##-#-##- #######- ##---##- ##---##- " + fL[5][9] = " #######- ##---##- ##---##- ##------ -##--##- ##------ -######- -----##- ####-##- ####-##- ##--##-- -##--##- ##---##- ##---##- ##---##- ##---##- " + fL[6][9] = " ##---##- ##---##- ##---##- ##------ -##--##- ##------ ##-##-## ##---##- ###--##- ###--##- ##---##- ##---##- ##---##- ##---##- ##---##- ##---##- " + fL[7][9] = " ##---##- ######-- ######-- ##------ ######## #######- ##-##-## -#####-- ##---##- ##---##- ##---##- ##---##- ##---##- ##---##- -#####-- ##---##- " + fL[8][9] = " -------- -------- -------- -------- ##----## -------- -------- -------- -------- -------- -------- -------- -------- -------- -------- -------- " + + -- 90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F + fL[1][10] = " ######-- -#####-- ######-- ##---##- ---##--- ##----## ##--##-- ##---##- ##-#-##- ##-#-##- ####---- ##----#- ##------ -#####-- ##--###- -######- " + fL[2][10] = " ##---##- ##---##- --##---- ##---##- -######- -##--##- ##--##-- ##---##- ##-#-##- ##-#-##- --##---- ##----#- ##------ ##---##- ##-##-## ##---##- " + fL[3][10] = " ##---##- ##------ --##---- ##---##- ##-##-## --####-- ##--##-- ##---##- ##-#-##- ##-#-##- --##---- ##----#- ##------ -----##- ##-##-## ##---##- " + fL[4][10] = " ######-- ##------ --##---- -######- ##-##-## ---##--- ##--##-- -######- ##-#-##- ##-#-##- --#####- ####--#- ######-- ---####- #####-## -######- " + fL[5][10] = " ##------ ##------ --##---- -----##- ##-##-## --####-- ##--##-- -----##- ##-#-##- ##-#-##- --##--## ##-##-#- ##---##- -----##- ##-##-## --##-##- " + fL[6][10] = " ##------ ##---##- --##---- ##---##- -######- -##--##- ##--##-- -----##- ##-#-##- ##-#-##- --##--## ##-##-#- ##---##- ##---##- ##-##-## -##--##- " + fL[7][10] = " ##------ -#####-- --##---- -#####-- ---##--- ##----## #######- -----##- #######- ######## --#####- ####--#- ######-- -#####-- ##--###- ##---##- " + fL[8][10] = " -------- -------- -------- -------- -------- -------- -----##- -------- -------- ------## -------- -------- -------- -------- -------- -------- " + + -- A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF + fL[1][11] = " -------- -----#-- -------- -------- -------- -------- -------- -------- -------- --##---- -------- -------- -------- -------- -------- -------- " + fL[2][11] = " -------- -####--- -------- -------- -------- -------- -------- -------- -------- -------- -------- -------- -------- -------- -------- -------- " + fL[3][11] = " -####--- ##------ #####--- ######-- -######- -####--- ##-##-## -####--- ##--##-- ##--##-- ##--##-- ----###- ##---##- ##--##-- -####--- ######-- " + fL[4][11] = " ----##-- #####--- ##--##-- ##------ -##--##- ##--##-- -######- ##--##-- ##--##-- ##--##-- ##-##--- ---####- ###-###- ##--##-- ##--##-- ##--##-- " + fL[5][11] = " -#####-- ##--##-- #####--- ##------ -##--##- ######-- ---##--- ---##--- ##-###-- ##-###-- ####---- --##-##- ##-#-##- ######-- ##--##-- ##--##-- " + fL[6][11] = " ##--##-- ##--##-- ##---##- ##------ -##--##- ##------ -######- ##--##-- ###-##-- ###-##-- ##--##-- -##--##- ##---##- ##--##-- ##--##-- ##--##-- " + fL[7][11] = " -######- -####--- ######-- ##------ ######## -#####-- ##-##-## -####--- ##--##-- ##--##-- ##--##-- ##---##- ##---##- ##--##-- -####--- ##--##-- " + fL[8][11] = " -------- -------- -------- -------- ##----## -------- -------- -------- -------- -------- -------- -------- -------- -------- -------- -------- " + + -- B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF + fL[1][12] = " --#---#- -#-#-#-# ##-##-## ---#---- ---#---- ---#---- ---#-#-- -------- -------- ---#-#-- ---#-#-- -------- ---#-#-- ---#-#-- ---#---- -------- " + fL[2][12] = " #---#--- #-#-#-#- -###-### ---#---- ---#---- ---#---- ---#-#-- -------- -------- ---#-#-- ---#-#-- -------- ---#-#-- ---#-#-- ---#---- -------- " + fL[3][12] = " --#---#- -#-#-#-# ##-##-## ---#---- ---#---- ####---- ---#-#-- -------- ####---- ####-#-- ---#-#-- ######-- ####-#-- ---#-#-- ####---- -------- " + fL[4][12] = " #---#--- #-#-#-#- ###-###- ---#---- ---#---- ---#---- ---#-#-- -------- ---#---- -----#-- ---#-#-- -----#-- -----#-- ---#-#-- ---#---- -------- " + fL[5][12] = " --#---#- -#-#-#-# ##-##-## ---#---- ####---- ####---- ####-#-- ######-- ####---- ####-#-- ---#-#-- ####-#-- ######-- ######-- ####---- ####---- " + fL[6][12] = " #---#--- #-#-#-#- -###-### ---#---- ---#---- ---#---- ---#-#-- ---#-#-- ---#---- ---#-#-- ---#-#-- ---#-#-- -------- -------- -------- ---#---- " + fL[7][12] = " --#---#- -#-#-#-# ##-##-## ---#---- ---#---- ---#---- ---#-#-- ---#-#-- ---#---- ---#-#-- ---#-#-- ---#-#-- -------- -------- -------- ---#---- " + fL[8][12] = " #---#--- #-#-#-#- ###-###- ---#---- ---#---- ---#---- ---#-#-- ---#-#-- ---#---- ---#-#-- ---#-#-- ---#-#-- -------- -------- -------- ---#---- " + + -- C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF + fL[1][13] = " ---#---- ---#---- -------- ---#---- -------- ---#---- ---#---- ---#-#-- ---#-#-- -------- ---#-#-- -------- ---#-#-- -------- ---#-#-- ---#---- " + fL[2][13] = " ---#---- ---#---- -------- ---#---- -------- ---#---- ---#---- ---#-#-- ---#-#-- -------- ---#-#-- -------- ---#-#-- -------- ---#-#-- ---#---- " + fL[3][13] = " ---#---- ---#---- -------- ---#---- -------- ---#---- ---##### ---#-#-- ---#-### ---##### ####-### ######## ---#-### ######## ####-### ######## " + fL[4][13] = " ---#---- ---#---- -------- ---#---- -------- ---#---- ---#---- ---#-#-- ---#---- ---#---- -------- -------- ---#---- -------- -------- -------- " + fL[5][13] = " ---##### ######## ######## ---##### ######## ######## ---##### ---#-### ---##### ---#-### ######## ####-### ---#-### ######## ####-### ######## " + fL[6][13] = " -------- -------- ---#---- ---#---- -------- ---#---- ---#---- ---#-#-- -------- ---#-#-- -------- ---#-#-- ---#-#-- -------- ---#-#-- -------- " + fL[7][13] = " -------- -------- ---#---- ---#---- -------- ---#---- ---#---- ---#-#-- -------- ---#-#-- -------- ---#-#-- ---#-#-- -------- ---#-#-- -------- " + fL[8][13] = " -------- -------- ---#---- ---#---- -------- ---#---- ---#---- ---#-#-- -------- ---#-#-- -------- ---#-#-- ---#-#-- -------- ---#-#-- -------- " + + -- D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF + fL[1][14] = " ---#-#-- -------- -------- ---#-#-- ---#---- -------- -------- ---#-#-- ---#---- ---#---- -------- ######## -------- ####---- ----#### ######## " + fL[2][14] = " ---#-#-- -------- -------- ---#-#-- ---#---- -------- -------- ---#-#-- ---#---- ---#---- -------- ######## -------- ####---- ----#### ######## " + fL[3][14] = " ---#-#-- ######## -------- ---#-#-- ---##### ---##### -------- ---#-#-- ######## ---#---- -------- ######## -------- ####---- ----#### ######## " + fL[4][14] = " ---#-#-- -------- -------- ---#-#-- ---#---- ---#---- -------- ---#-#-- ---#---- ---#---- -------- ######## -------- ####---- ----#### ######## " + fL[5][14] = " ######## ######## ######## ---##### ---##### ---##### ---##### ######## ######## ####---- ---##### ######## ######## ####---- ----#### -------- " + fL[6][14] = " -------- ---#---- ---#-#-- -------- -------- ---#---- ---#-#-- ---#-#-- ---#---- -------- ---#---- ######## ######## ####---- ----#### -------- " + fL[7][14] = " -------- ---#---- ---#-#-- -------- -------- ---#---- ---#-#-- ---#-#-- ---#---- -------- ---#---- ######## ######## ####---- ----#### -------- " + fL[8][14] = " -------- ---#---- ---#-#-- -------- -------- ---#---- ---#-#-- ---#-#-- ---#---- -------- ---#---- ######## ######## ####---- ----#### -------- " + + -- F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF + fL[1][15] = " -------- -------- -------- -------- -------- -------- -------- -------- -------- -------- -------- -------- -------- -------- -------- -------- " + fL[2][15] = " -------- -------- -------- -------- ---##--- -------- -------- -------- -------- -------- -------- -------- -------- -------- -------- -------- " + fL[3][15] = " #####--- -####--- ######-- ##--##-- -######- ##---##- ##--##-- ##--##-- ##-#-##- ##-#-##- ####---- ##----#- ##------ -#####-- ##--###- -#####-- " + fL[4][15] = " ##--##-- ##--##-- --##---- ##--##-- ##-##-## -##-##-- ##--##-- ##--##-- ##-#-##- ##-#-##- --##---- ##----#- ##------ ##---##- ##-##-## ##--##-- " + fL[5][15] = " ##--##-- ##------ --##---- -#####-- ##-##-## --###--- ##--##-- -#####-- ##-#-##- ##-#-##- --#####- ####--#- #####--- ---####- #####-## -#####-- " + fL[6][15] = " #####--- ##--##-- --##---- ----##-- -######- -##-##-- ##--##-- ----##-- ##-#-##- ##-#-##- --##--## ##-##-#- ##--##-- ##---##- ##-##-## -##-##-- " + fL[7][15] = " ##------ -####--- --##---- ##--##-- ---##--- ##---##- #######- ----##-- #######- ######## --#####- ####--#- #####--- -#####-- ##--###- ##--##-- " + fL[8][15] = " ##------ -------- -------- -####--- ---##--- -------- -----##- -------- -------- ------## -------- -------- -------- -------- -------- -------- " + + -- E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF + fL[1][16] = " -#--#--- -#--#--- -##----- ---##--- ----#--- ---#---- --##---- -------- -##----- -------- -------- ---##### #-#----- -##----- -------- -------- " + fL[2][16] = " ######-- -------- --##---- --##---- ---#-#-- ---#---- --##---- -------- #--#---- -------- -------- ---#---- ##-#---- #--#---- -------- -------- " + fL[3][16] = " ##------ -####--- ---##--- -##----- ---#---- ---#---- -------- -##--#-- #--#---- -------- -------- ---#---- #--#---- --#----- --####-- -------- " + fL[4][16] = " #####--- ##--##-- --##---- --##---- ---#---- ---#---- ######-- #--##--- -##----- --##---- -------- #--#---- #--#---- -#------ --####-- -------- " + fL[5][16] = " ##------ ######-- -##----- ---##--- ---#---- ---#---- -------- -------- -------- --##---- --##---- -#-#---- #--#---- ####---- --####-- -------- " + fL[6][16] = " ##------ ##------ -------- -------- ---#---- -#-#---- --##---- -##--#-- -------- -------- -------- --##---- -------- -------- --####-- -------- " + fL[7][16] = " #######- -#####-- -####--- -####--- ---#---- --#----- --##---- #--##--- -------- -------- -------- ---#---- -------- -------- -------- -------- " + fL[8][16] = " -------- -------- -------- -------- ---#---- -------- -------- -------- -------- -------- -------- -------- -------- -------- -------- -------- " + + ENDLUA + LUA ALLPASS + for i = 1, 8 do + for j = 1, 16, 1 do + _pc(" DG " .. fL[i][j]) + end + end + ENDLUA +; \ No newline at end of file diff --git a/Crazy BIOS/exp/FUNC_4x.ASM b/Crazy BIOS/exp/FUNC_4x.ASM new file mode 100644 index 0000000..a9b460c --- /dev/null +++ b/Crazy BIOS/exp/FUNC_4x.ASM @@ -0,0 +1,905 @@ +; + MACRO WAIT_HDD + LD BC,IDE.Read.Status +.loop: IN A,(C) + BIT IDE.ControlBit.Busy,A + JR NZ,.loop + ENDM +;______________________________________________________________________: +; + +; GET_BPB_OFFSET: +; ;LD A,SYS_PAGE +; ;LD HL,MS_BPB +; PUSH AF +; PUSH HL +; LD B,1 +; LD IX,#0000 +; LD DE,#0000 +; CALL FN_HDD_READ +; POP IX +; POP AF +; PUSH AF +; PUSH IX +; LD DE,#01BE ;!HARDCODE смещение от начала сектора для таблицы разделов +; ADD IX,DE +; ; +; EX AF,AF' +; IN A,(SLOT3) +; EX AF,AF' +; OUT (SLOT3),A +; ; +; LD E,(IX+8) ; первый сектор (LBA) начала раздела (DWORD) +; LD D,(IX+9) +; LD L,(IX+10) +; LD H,(IX+11) +; ; +; EX AF,AF' +; OUT (SLOT3),A +; EX AF,AF' +; ; +; PUSH HL +; POP IX +; POP HL +; POP AF +; RET +HD_BPB_PREP: + ; [x] 27/01/2024 теперь режим спектрума работает с любым разделом HDD + ;LD D,A + ;IN A,(SLOT3) + ;EX AF,AF' + ; LD A,SYS_PAGE + ; OUT (SLOT3),A + ; LD A,(SYS_PAGE.HD_IDF_ADR.sectors) + ; LD E,A + ;EX AF,AF' + ;OUT (SLOT3),A + ;LD A,D + ;LD D,#00 + ;LD IX,#0000 + ;LD B,#01 + + LD B,A + IN A,(SLOT3) + EX AF,AF' + LD A,SYS_PAGE + OUT (SLOT3),A + LD A,(SYS_PAGE.CURRENT_HDD) + INC A + JR NZ,.configured + ; + LD A,(SYS_PAGE.HD_IDF_ADR.sectors) + LD E,A + LD D,#00 + LD IX,#0000 + JR .done + ; +.configured: + LD IX,(SYS_PAGE.HDD_PARTITION_OFFSET+2) + LD DE,(SYS_PAGE.HDD_PARTITION_OFFSET) +.done: EX AF,AF' + OUT (SLOT3),A + LD A,B + LD B,#01 + ; +HD_PREPARE: + PUSH AF + PUSH HL + CALL HD_CALC_SECS + JR C,.error + ; + LD A,B + LD BC,IDE.Write.Counter ; Установить число секторов для записи + OUT (C),A + + IF IDE_Optimization + INC C + OUT (C),L + INC C + OUT (C),E + INC C + OUT (C),D + ELSE + LD BC,IDE.Write.Sector + OUT (C),L ; СЕКТОР + LD BC,IDE.Write.CylinderLow + OUT (C),E ; дорожка low + LD BC,IDE.Write.CylinderHigh + OUT (C),D ; дорожка high + ENDIF + + LD BC,IDE.Read.Control + IN A,(C) + AND #F0 ; !!!!! посмотреть + OR H + INC B ; IDE.Write.DeviceHead + OUT (C),A + POP HL ; BUFER & PAGE + POP AF + AND A + RET + ; +.error: POP HL + POP AF + SCF + RET + + +NEXT_ADD_SEC: + PUSH AF + + LD A,B + LD BC,IDE.Write.Counter ; Установить число секторов для записи + OUT (C),A + + IF IDE_Optimization + DEC B + INC C + IN A,(C) ; IDE.Read.Sector + ADC A,E + INC B + OUT (C),A ; IDE.Write.Sector + + DEC B + INC C + IN A,(C) ; IDE.Read.CylinderLow + ADC A,D + INC B + OUT (C),A ; IDE.Write.CylinderLow + + DEC B + INC C + IN A,(C) ; IDE.Read.CylinderHigh + ADC A,0 + INC B + OUT (C),A ; IDE.Write.CylinderHigh + + LD BC,IDE.Read.Control + IN A,(C) + ELSE + LD BC,IDE.Read.Sector + IN A,(C) + ADC A,E + INC B + OUT (C),A ; IDE.Write.Sector + + LD BC,IDE.Read.CylinderLow + IN A,(C) + ADC A,D + INC B + OUT (C),A ; IDE.Write.CylinderLow + + LD BC,IDE.Read.CylinderHigh + IN A,(C) + ADC A,0 + INC B + OUT (C),A ; IDE.Write.CylinderHigh + + LD BC,IDE.Read.Control + IN A,(C) + ENDIF + + LD D,A + ADC A,0 + AND #0F + LD E,A + LD A,D + AND #F0 + OR E + INC B + OUT (C),A ; IDE.Write.DeviceHead + + POP AF + RET + +; При исполнении производится вся подготовка к +; операциям чтения/записи вычисление +; цилиндров/головок/секторов и занесение их в регистры винчестера +; далее программа может сама только подать команду читать/писать и +; самостоятельно производить считывание/запись данных в винчестер. +; Команда удобна для работы программ в реальном времени, когда необходимо +; кроме чтения/записи данных производить какие либо иные действия. +FN_HDD_PREPARE: ; ПОДГОТОВКА К ВНЕШНИМ ОПЕРАЦИЯМ R/W + AND A ; чтоб сбросить CF если он стоит и B=0 + INC B + DEC B + RET Z + + CALL HD_WAIT + RET C + + CALL HD_PREPARE + RET C + ; [x] + EX AF,AF' + LD A,#BF ; check buffer address in SLOT3 + SUB H + JR C,.SetCommand + EX AF,AF' + + SAFE_PORTY + + EXX + LD C,SLOT3 + IN B,(C) + EXX + OUT (SLOT3),A + EX AF,AF' + +.SetCommand: + LD BC,IDE.Write.Command + LD A,IDE.ATA.ReadSectorsWithRetry + ; OUT (C),A + AND A + RET + + + +FN_HDD_READ_BPB: + CALL HD_WAIT + RET C + CALL HD_BPB_PREP + JR NC,FN_HDD_READ.L1 + RET + + +; FOR LBA ONLY - NEXT_READ +; HL - bufer, A - page +; B - numer of sectors +; DE - add_par (next+DE) (d.b. 1 for NEXT) +FN_HDD_READ_NEXT: + AND A + INC B + DEC B + RET Z ; ret if 0 sectors + CALL HD_WAIT + RET C + CALL NEXT_ADD_SEC + JR FN_HDD_READ.L1 + ; +; HL - BUFER, A - PAGE +FN_HDD_READ: + AND A + INC B + DEC B + RET Z + CALL HD_WAIT + CALL NC,HD_PREPARE + RET C +.L1: EXX + LD C,SLOT3 + IN B,(C) + EXX + OUT (SLOT3),A + EX AF,AF' + ; + SAFE_PORTY + ; + LD BC,IDE.Write.Command + LD A,IDE.ATA.ReadSectorsWithRetry + OUT (C),A +.L2: WAIT_HDD + ;BIT IDE.ControlBit.DataRequest,A + AND IDE.ControlByte.DataRequest + JR Z,.RET_PortY + ; + ;HD_READ_CONT + LD BC,IDE.Read.Data +.loop_read1: + DUP 16 + INI ; всего 16 раз INI - оптимально. + EDUP + JR NZ,.loop_read1 +.loop_read2: + DUP 16 + INI ; всего 16 раз INI - оптимально. + EDUP + JR NZ,.loop_read2 + ; + LD A,H + OR L + JR NZ,.L2 + ; + LD A,SYS_PAGE + OUT (SLOT3),A + EX AF,AF' + LD H,high SYS_PAGE.RAMD_FAT + LD L,A + LD A,(HL) + OUT (SLOT3),A + EX AF,AF' + LD HL,#C000 + JR .L2 + ; +.RET_PortY: + ZERO_PORTY + ; +HD_RET: EXX + OUT (C),B + EXX + LD BC,IDE.Read.Error + IN A,(C) + AND A + SCF + RET NZ + ; + EX AF,AF' + AND A + RET + + +; HL - BUFER, A - PAGE +FN_HDD_WRITE: + AND A + INC B + DEC B + RET Z + + CALL HD_WAIT + RET C + CALL HD_PREPARE + RET C + + EXX + LD C,SLOT3 + IN B,(C) + EXX + OUT (SLOT3),A + EX AF,AF' + + LD BC,IDE.Write.Command + LD A,IDE.ATA.WriteSectorsWithRetry + OUT (C),A + +HD_WR_L2: + WAIT_HDD + + BIT IDE.ControlBit.DataRequest,A + JR Z,HD_RET + + LD BC,IDE.Write.Data + LD D,32 ;!HARDCODE зависит от счётчика DUP в HD_WR_LOOP +HD_WR_LOOP: + DUP 16 + OUTI ; всего 16 раз OUTI - оптимально. + EDUP + + DEC D + JR NZ,HD_WR_LOOP + + LD A,H + OR L + JR NZ,HD_WR_L2 + + LD A,SYS_PAGE + OUT (SLOT3),A + EX AF,AF' + LD H,high SYS_PAGE.RAMD_FAT + LD L,A + LD A,(HL) + OUT (SLOT3),A + EX AF,AF' + LD HL,#C000 ; !HARDCODE + JR HD_WR_L2 + +;!FIXIT пока работает только с одним каналом (по-старому) +FN_HDD_RECAL: + LD A,IDE.Drive.Master + LD BC,IDE.Write.DeviceHead + OUT (C),A + LD A,IDE.ATA.ExecuteDeviceDiagnostic + CALL HD_CMD_EXE + ;AND A + CP IDE.ControlByte.Error + RET Z + LD BC,IDE.Read.Error + IN A,(C) + CP 1 ; !HARDCODE + RET Z + SCF + RET + + +;????? глянуть +; RET C +; LD A,#1F ; RECALIBRATE +; CALL HD_CMD_EXE +; RET + +; [x] 28/01/2024 работает со всеми каналами +FN_HDD_TEST_IDE: + LD E,#00 + ; TEST Secondary Chanel + LD A,IDE.Chanel.Secondary + OUT (IDE.Chanel.Set),A + CALL .TEST_CHANEL + SLA E + SLA E + ; TEST Primary Chanel + LD A,IDE.Chanel.Primary + OUT (IDE.Chanel.Set),A + CALL .TEST_CHANEL +; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; LD BC,IDE.Write.DeviceHead +; LD A,IDE.Drive.Master +; OUT (C),A +; ; +; CALL TEST_HDD_DRV +; ; +; JR NZ,.NO_HDD1 +; SET 0,E +; .NO_HDD1: +; LD BC,IDE.Write.DeviceHead +; LD A,IDE.Drive.Slave +; OUT (C),A +; ; +; CALL TEST_HDD_DRV +; ; +; JR NZ,.NO_HDD2 +; SET 1,E +; .NO_HDD2: +; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + LD C,SLOT3 + IN B,(C) + LD A,SYS_PAGE + OUT (SLOT3),A + ; + LD A,(SYS_PAGE.CURRENT_HDD) + OUT (C),B + CP #FF + JR Z,.exit + AND 1 + JR Z,.exit + LD A,IDE.Chanel.Secondary + OUT (IDE.Chanel.Set),A +; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +.exit: LD A,E + AND A + SCF + RET Z ; HDD absent ! + AND A + RET + +.TEST_CHANEL: + LD BC,IDE.Write.DeviceHead + LD A,IDE.Drive.Master + OUT (C),A + ; + CALL TEST_HDD_DRV + ; + JR NZ,.NO_HDD1 + SET 0,E +.NO_HDD1: + LD BC,IDE.Write.DeviceHead + LD A,IDE.Drive.Slave + OUT (C),A + ; + CALL TEST_HDD_DRV + ; + RET NZ + SET 1,E + RET + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;-----------------------------------[DIFFERENT] +; Не должна портить регистр E!!! +TEST_HDD_DRV: +; EXP_HDD.ASM variant + LD HL,#01FE + LD BC,IDE.Write.Counter + OUT (C),L + IF IDE_Optimization + INC C + OUT (C),H ; IDE.Write.Sector + ; + DEC C + DEC B + IN A,(C) ; IDE.Read.Counter + CP L + RET NZ + INC C + ELSE + LD BC,IDE.Write.Sector + OUT (C),H + LD BC,IDE.Read.Counter + IN A,(C) + CP L + RET NZ + LD BC,IDE.Read.Sector + ENDIF + IN A,(C) ; IDE.Read.Sector + CP H + RET + +; TEST_HDD_DRV: +; ; EXTENDED.ASM variant +; LD HL,#00FF +; LD BC,IDE.Write.CylinderLow +; OUT (C),L +; IF IDE_Optimization +; INC C +; OUT (C),H ; IDE.Write.CylinderHigh + +; INC B +; DEC C +; IN A,(C) ; Тут регистр BC = #0254 - .CylinderLow +; CP L +; RET NZ +; INC C + +; ELSE +; LD BC,IDE.Write.CylinderHigh +; OUT (C),H +; LD BC,#0254 +; IN A,(C) +; CP L +; RET NZ +; LD BC,#0255 +; ENDIF + +; IN A,(C) ; Тут регистр BC = #0255 - .CylinderHigh +; CP H +; RET + + +; [x] 07/01/2024 bit0 - master/slave, bit1: Primary/Secondary, bit2..3: использующийся раздел в MBR +; !TODO сделать работу с переменными биоса SYS_PAGE.IDE_0..3 +FN_HDD_PART: + DI + PUSH BC + PUSH HL + ; + EX AF,AF' + IN A,(SLOT3) + EX AF,AF' + ; + LD C,A + AND 2 + LD A,IDE.Chanel.Primary + JR Z,.SET_CH + LD A,IDE.Chanel.Secondary +.SET_CH: + OUT (IDE.Chanel.Set),A + ; + LD A,C + PUSH AF + AND 1 + ; + LD A,IDE.Drive.Slave + JR NZ,.SET_Master_Slave + ; + LD A,IDE.Drive.Master +.SET_Master_Slave: + LD BC,IDE.Write.DeviceHead + OUT (C),A + CALL TEST_HDD_DRV + JR NZ,.Error + ; + CALL FN_HDD_INIT.L3 + JR C,.Error + ; + POP BC + LD A,SYS_PAGE + OUT (SLOT3),A + ; + LD A,B + LD (SYS_PAGE.CURRENT_HDD),A + ; + EX AF,AF' + OUT (SLOT3),A + ; + CALL SET_BPB_OFFSET +.exit: POP HL + POP BC + EI + RET + ; +.Error: POP AF + SCF + JR .exit + +; [x] 27/01/2024 адаптирована для корректной работы с FN_HDD_PART +FN_HDD_INIT: + LD C,SLOT3 + IN B,(C) + LD A,SYS_PAGE + OUT (SLOT3),A + ; + LD A,(SYS_PAGE.CURRENT_HDD) + OUT (C),B + INC A + JR Z,FN_HDD_PART + + ; !FIXIT сделать тут выбор первого попавшегося из SYS.IDE_0-3 + CALL TEST_HDD_DRV + SCF + RET NZ + ; LD BC,IDE.Write.DeviceHead + ; LD A,IDE.Drive.Master + ; OUT (C),A + ; CALL TEST_HDD_DRV + ; JR NZ,.ABSENT + ; +.L3: WAIT_HDD + LD BC,IDE.Write.Command + LD A,IDE.ATA.IdentifyDevice ;!FIXIT переделать + OUT (C),A + WAIT_HDD + AND IDE.ControlByte.DataRequest + ;JR NZ,.L2 + SCF + RET Z + ;JR NZ,.L2 + ;SCF + ;RET +; .ABSENT: +; LD BC,IDE.Write.DeviceHead +; LD A,IDE.Drive.Slave +; OUT (C),A +; CALL TEST_HDD_DRV +; JR Z,.L3 +; SCF +; RET + ; +;.L2: + LD BC,IDE.Read.Data + LD HL,SYS_PAGE.HD_IDF_ADR + IN A,(SLOT3) + LD D,A + LD A,SYS_PAGE + OUT (SLOT3),A + INIR + INIR + ; B = 0 + LD H,B + LD L,B + LD A,(SYS_PAGE.HD_IDF_ADR.sectors) ; число секторов + LD C,A + ;LD HL,0 + ;LD B,H + LD A,(SYS_PAGE.HD_IDF_ADR.heads) ; число головок +.loop: ADD HL,BC + DEC A + JR NZ,.loop + LD (SYS_PAGE.HD_IDF_ADR.sec_cyl),HL + WAIT_HDD + LD BC,IDE.Read.Control + IN A,(C) + AND #10 + LD B,A + LD A,(SYS_PAGE.HD_IDF_ADR.heads) ; число головок + DEC A + AND #0F + OR IDE.Drive.Master + OR B + + LD H,A + LD A,(SYS_PAGE.HD_IDF_ADR.LBA_CHS) + ;BIT 1,A + AND %0000'0010 + JR Z,.NO_LBA + SET 6,H +.NO_LBA: + LD BC,IDE.Write.DeviceHead + OUT (C),H + LD A,(SYS_PAGE.HD_IDF_ADR.sectors) ; число секторов +.HDD_CONFIGURED: + LD BC,IDE.Write.Counter + OUT (C),A + LD A,D + OUT (SLOT3),A + LD A,IDE.ATA.InitializeDeviceParameters ; SET HDD PARAMETERS + ;CALL HD_CMD_EXE + ;RET +HD_CMD_EXE: + CALL HD_WAIT + RET C + LD BC,IDE.Write.Command + OUT (C),A +HD_WAIT: + PUSH DE + PUSH BC + PUSH AF + LD DE,0 +.loop: LD BC,IDE.Read.Status + IN A,(C) + AND IDE.ControlByte.Busy + JR Z,.EXIT + DEC DE + LD A,D + OR E + JR NZ,.loop + POP AF + POP BC + POP DE + SCF + RET + ; +.EXIT: POP AF + POP BC + POP DE + AND A + RET + + +; ;EXTENDED.ASM Version +; HDD_LBA: ;???!!!! +; POP BC +; LD L,E +; LD E,D +; LD D,XL +; XOR A +; LD H,A +; RET +; HD_CALC_SECS: +; LD A,XH +; AND A +; SCF +; RET NZ ; ошибка, слишком большой HDD + +; PUSH BC +; LD BC,IDE.Write.DeviceHead +; DEC B +; IN A,(C) +; BIT 6,A +; JR NZ,HDD_LBA +; ; POP BC + + +;EXP_HDD.ASM Version +HD_CALC_SECS: + PUSH BC + LD BC,IDE.Read.Control + IN A,(C) + AND %0100'0000 + POP BC + JR Z,.CHS + ; LBA + LD L,E + LD E,D + LD D,XL + LD A,XH + AND #0F ; LBA 28 + LD H,A + RET + ; CHS +.CHS: LD A,XH + AND A + SCF + RET NZ ; ошибка, слишком большой HDD + ; IX,DE - абсолютный номер сектора + PUSH IX + POP HL + ; + IN A,(SLOT3) + LD C,A + LD A,SYS_PAGE + OUT (SLOT3),A + LD A,C + LD (SYS_PAGE.COPY_SLOT3),A + ; HL,DE - номер сектора + ; BC - число секторов на цилиндре + LD BC,(SYS_PAGE.HD_IDF_ADR.sec_cyl) ; число секторов на цилиндре + LD A,16 ; HL,DE разделить на BC + SCF +.DIV_LOOP: + EX DE,HL + ADD HL,HL + EX DE,HL + ADC HL,HL + ; + SBC HL,BC ; сравнить HL и BC + JR NC,.NO_ADD ; переноса не было - +1! + ADD HL,BC + DEC A + JR NZ,.DIV_LOOP + JR .DIV_END +.NO_ADD: + INC DE + DEC A + JR NZ,.DIV_LOOP +.DIV_END: + ; DE - результат, HL - остаток + ; DE - цилиндр + LD A,(SYS_PAGE.HD_IDF_ADR.sectors) + ; A - число секторов на дорожке + ; HL - номер сектора в цилиндре + LD C,A + ;LD BC,(MS_BPB+S_P_T) ; ЧИСЛО СЕКТОРОВ НА ДОРОЖКЕ + XOR A + LD B,A +.LOOP: SBC HL,BC + INC A + JR NC,.LOOP + ; + DEC A ; A - головка + ADD HL,BC ; L - сектор + INC L + LD H,A ; HL - HEAD,SEC + ; + LD A,(SYS_PAGE.COPY_SLOT3) + OUT (SLOT3),A + AND A + RET + +; [x] 27/01/2024 теперь режим спектрума работает с любым разделом HDD +SET_BPB_OFFSET: + LD A,SYS_PAGE + LD HL,SYS_PAGE.MS_BPB + LD IX,#0000 + LD DE,#0000 + LD B,1 + CALL FN_HDD_READ + ; + EX AF,AF' + IN A,(SLOT3) + EX AF,AF' + OUT (SLOT3),A + ; + LD A,(SYS_PAGE.CURRENT_HDD) + RRCA + RRCA + AND 3 + INC A + LD B,A + ; + ; ; смещение от начала сектора для таблицы разделов c первым сектором LBA для первого раздела + LD HL,SYS_PAGE.MS_BPB - _sMBR_PARTITION_RECORD + _sBOOT_SECTOR.PARTITION_TABLE + LD DE,_sMBR_PARTITION_RECORD +.loop: ADD HL,DE + DJNZ .loop + ; + LD A,_sMBR_PARTITION_RECORD.Start_LBA + ADD L + LD L,A + LD DE,SYS_PAGE.HDD_PARTITION_OFFSET + LD C,_sMBR_PARTITION_RECORD.Size_LBA - _sMBR_PARTITION_RECORD.Start_LBA + LDIR + ; [x] 07/07/2024 fix bug with select empty partition record + EX DE,HL + XOR A + LD B,_sMBR_PARTITION_RECORD.Size_LBA - _sMBR_PARTITION_RECORD.Start_LBA +.loop2: DEC HL + OR (HL) + DJNZ .loop2 + SUB 1 + ; + EX AF,AF' + OUT (SLOT3),A + EX AF,AF' + RET + +; ENDMODULE +;************************************************ + +; ????? +; DB 'HDD_DRV_END' +; Вход: +; C - команда +; 0 - INIT - входных пар нет => A - число поддерживаемых дисков. +; 1 - RESET - выбор диска A - номер диска от 0 => +; 2 - (STATUS) !!!!! TEST? +; 3 - MEDIA CHECK - A - номер диска => A = 0 - old. #FF - new (всегда #FF) !!!!! PREPARE??? +; 4 - READ BPB - A - диск HL - адрес в текущей странице. +; 5 - READ - A - диск, IX:DE сектор, HL - адрес, B - число секторов +; 6 - WRITE - '' - +; 7 - PART +; 8 - READ_NEXT +; +; ошибки - CF - A - ошибка +; +; 0 - нет ошибки +; 1 - неверная команда +; 2 - неверный номер диска +; 3 - неверный формат (не MS-DOS) +; 4 - нет готовности +; 5 - ошибка позиционирования +; 6 - сектор не найден +; 7 - ошибка CRC +; 8 - защита записи +; 9 - ошибка чтения +; 10 - ошибка записи +; 11 - ГЛЮК +; \ No newline at end of file diff --git a/Crazy BIOS/exp/FUNC_5x.asm b/Crazy BIOS/exp/FUNC_5x.asm new file mode 100644 index 0000000..a58032b --- /dev/null +++ b/Crazy BIOS/exp/FUNC_5x.asm @@ -0,0 +1,128 @@ + +; +; It's disk drive BIOS extender for functions 5xh. +;--------------------------------------------------------------- +;Version! Description +;--------------------------------------------------------------- +; 2.32 ! Removed `DI' Disabled Interupt instruction in HDRIVER6 +; ! function load sectors. +; ! Fixed bug waiting slave device in AUTOIDE. + +; +;INT_ADRESS EQU #C124 +;INT_PAGE EQU #C126 +;INT_ID EQU #C127 +;BIOS EQU #3FD0 +; DS #3FD0,#FF + + +DRV_VERSION: + LD HL,0 + LD BC,0 + LD DE,Disk_subsystem_ver_hex + AND A + RET + +DRV_LIST: + IN A,(SLOT3) + PUSH AF + PUSH IY + LD A,SYS_PAGE + OUT (SLOT3),A ; !TODO сделать структурой + LD (IX+0),#04 ; DB 0 ;LEN ;!HARDCODE + LD (IX+1),#00 ; DB 0 ;FDD COUNT + LD (IX+2),#00 ; DB 0 ;HDD COUNT + LD (IX+3),#00 ; DB 0 ;CDROM COUNT +; ; BLOCK 28,0 ;RESERVED ;!TODO сделать RAMDRIVE тут? + LD (IX+4),#00 ; END FLAG + +;Calculating FDD devices + LD HL,FDD_INI_TABLE.FDD_0 + INC (IX+1) + LD B,8 + LD A,#FF +.TFD0: + CP (HL) + INC HL + JR NZ,.YYYFD0 + DJNZ .TFD0 + DEC (IX+1) +.YYYFD0: + LD HL,FDD_INI_TABLE.FDD_1 + INC (IX+1) + LD B,8 + LD A,#FF +.TFD1: + CP (HL) + INC HL + JR NZ,.YYYFD1 + DJNZ .TFD1 + DEC (IX+1) +.YYYFD1: +;Calculating IDE devices + LD IY,IDE.INIT_TBL_IDE0 + LD A,(IY+IDE.HDD_INIT_TABLE.DriveType) ;IDE TYPE 1-HDD, 2-CD-ROM + CP #FF + JR Z,.ABSIDE0 + CP IDE.Device.HDD + JR NZ,.NOT_HD0 + INC (IX+2) +.NOT_HD0: + CP IDE.Device.CDROM + JR NZ,.NOT_CD0 + INC (IX+3) +.NOT_CD0: +.ABSIDE0: + LD IY,IDE.INIT_TBL_IDE1 + LD A,(IY+IDE.HDD_INIT_TABLE.DriveType) ;IDE TYPE 1-HDD, 2-CD-ROM + CP #FF + JR Z,.ABSIDE1 + CP IDE.Device.HDD + JR NZ,.NOT_HD1 + INC (IX+2) +.NOT_HD1: + CP IDE.Device.CDROM + JR NZ,.NOT_CD1 + INC (IX+3) +.NOT_CD1: +.ABSIDE1: + LD IY,IDE.INIT_TBL_IDE2 + LD A,(IY+IDE.HDD_INIT_TABLE.DriveType) ;IDE TYPE 1-HDD, 2-CD-ROM + CP #FF + JR Z,.ABSIDE2 + CP IDE.Device.HDD + JR NZ,.NOT_HD2 + INC (IX+2) +.NOT_HD2: + CP IDE.Device.CDROM + JR NZ,.NOT_CD2 + INC (IX+3) +.NOT_CD2: +.ABSIDE2: + LD IY,IDE.INIT_TBL_IDE3 + LD A,(IY+IDE.HDD_INIT_TABLE.DriveType) ;IDE TYPE 1-HDD, 2-CD-ROM + CP #FF + JR Z,.check_exit + CP IDE.Device.HDD + JR NZ,.NOT_HD3 + INC (IX+2) +.NOT_HD3: + CP IDE.Device.CDROM + JR NZ,.check_exit + INC (IX+3) +.check_exit: + POP IY + POP AF + OUT (SLOT3),A + XOR A + RET + + INCLUDE 'EXTENDED/FDD_DRIVER_2.asm' + INCLUDE 'EXTENDED/RAM_DISK_DRIVER_1.asm' + INCLUDE 'EXTENDED/IDE/HDD_DRV.asm' + INCLUDE 'EXTENDED/IDE/CD_DRV.asm' + INCLUDE 'EXTENDED/IDE/SHARED.asm' + + + ;DISPLAY " EXTENDED end addr: ", /A, $ +; \ No newline at end of file diff --git a/Crazy BIOS/exp/FUNC_CMOS.ASM b/Crazy BIOS/exp/FUNC_CMOS.ASM new file mode 100644 index 0000000..fac1e5d --- /dev/null +++ b/Crazy BIOS/exp/FUNC_CMOS.ASM @@ -0,0 +1,113 @@ +; + MACRO _mCMOS_MAX_TEST + ASSERT CMOS.MAX_ADDRESS = #7F, "WARNING!!! Logick broken with BIT 7 check" + BIT 7,D + SCF + RET NZ + ENDM +; + + +;!FIXIT по доке на функцию должен перед выходом CF ставиться +CMOS_EMU_WR: + PUSH DE + + LD C,SLOT3 + IN B,(C) + LD E,SYS_PAGE + OUT (C),E + LD E,D + LD D,#FF + LD (DE),A + OUT (C),B + + POP DE + RET +; + +; запись в CMOS +CMOS_WR: + ; [x] + _mCMOS_MAX_TEST + ; + CALL CMOS_TEST + JR C,CMOS_EMU_WR +.WR: LD BC,CMOS.Port.Address.Write + OUT (C),D + LD BC,CMOS.Port.Data.Write + OUT (C),A + RET +; + +;!FIXIT по доке на функцию должен перед выходом CF ставиться +CMOS_EMU_RD: + PUSH DE + + LD C,SLOT3 + IN B,(C) + LD E,SYS_PAGE + OUT (C),E + LD E,D + LD D, high SYS_PAGE.CMOS_EMULATOR + LD A,(DE) + OUT (C),B + + POP DE + RET +; + +; чтение из CMOS +CMOS_RD: + ; [x] + _mCMOS_MAX_TEST + ; + CALL CMOS_TEST + JR C,CMOS_EMU_RD +.RD: LD BC,CMOS.Port.Address.Write + OUT (C),D + LD BC,CMOS.Port.Data.Read + IN A,(C) + RET +; + +;Проверка наличия CMOS +CMOS_TEST: + PUSH AF + PUSH DE + PUSH BC + + LD D,CMOS.TEST_CELL ; [x] раньше писало в ячейку чек-суммы + CALL CMOS_RD.RD + LD E,A + CPL + CALL CMOS_WR.WR + CALL CMOS_RD.RD + CPL + CP E + LD A,E + JR NZ,.CMOS_ERR + CALL CMOS_WR.WR + + POP BC + POP DE + POP AF + AND A + RET + ; +.CMOS_ERR: + CALL CMOS_WR.WR + POP BC + POP DE + POP AF + SCF + RET + +; Не портит HL +; GET_CMOS_VALUE: LD A,L +; CALL CMOS_RD +; AND H +; .loop: RRCA +; RRC H +; JR NC,.loop +; RLCA +; RET \ No newline at end of file diff --git a/Crazy BIOS/exp/FUNC_FOR_TRDOS.ASM b/Crazy BIOS/exp/FUNC_FOR_TRDOS.ASM new file mode 100644 index 0000000..10fc2fa --- /dev/null +++ b/Crazy BIOS/exp/FUNC_FOR_TRDOS.ASM @@ -0,0 +1,155 @@ +;!TODO исправить SLOT2 на SLOT3 и затестить +;!TODO добавить описание +GET_DISK_REDIR: + PUSH HL + LD HL,SYS_PAGE.DISK_TYPE-#4000 + IN A,(SLOT2) + EX AF,AF' + LD A,SYS_PAGE + OUT (SLOT2),A + LD A,(ZX_VARS.OPER_DISK) + AND 3 + ADD A,L + LD L,A + LD L,(HL) + EX AF,AF' + OUT (SLOT2),A + LD A,L + POP HL + RET +; + +;!TODO исправить SLOT2 на SLOT3 и затестить, но не пользоваться стеком тогда +;!TODO добавить описание +SET_DISK_REDIR: + PUSH HL + LD HL,SYS_PAGE.DISK_TYPE-#4000 + IN A,(SLOT2) + EX AF,AF' + LD A,SYS_PAGE + OUT (SLOT2),A + LD A,(ZX_VARS.OPER_DISK) + AND 3 + ADD A,L + LD L,A + LD (HL),E + ; + ;LD L,(HL) + LD L,E + ; + EX AF,AF' + OUT (SLOT2),A + LD A,L + POP HL + RET +; + +;!TODO исправить SLOT2 на SLOT3 и затестить +; Disk A, DRV - B +FDD_TO_DRV: + CP 4 + CCF + RET C + LD C,A + + LD A,B + CP 4 + CCF + RET C + + LD HL,SYS_PAGE.DISK_TYPE-#4000 + LD L,B + + IN A,(SLOT2) + LD B,A + LD A,SYS_PAGE + OUT (SLOT2),A + LD (HL),C + LD A,B + OUT (SLOT2),A + + AND A + RET +; + +;!TODO исправить SLOT2 на SLOT3 и затестить +; RAM-Disk A, DRV - B +RAMD_TO_DRV: + CP SYS_PAGE.RAMD_KEYS.NUM + CCF + RET C + LD C,A + LD A,B + CP 4 + CCF + RET C + ; + LD HL,SYS_PAGE.DISK_TYPE-#4000 + LD L,B + ; + IN A,(SLOT2) + LD B,A + LD A,SYS_PAGE + OUT (SLOT2),A + LD A,C + ADD A,4 + LD (HL),A + LD A,B + OUT (SLOT2),A + AND A + RET +; + +;!TODO исправить SLOT2 на SLOT3 и затестить +; HDD A, DRV - B +HDD_TO_DRV: + AND #0F + OR #40 + + LD C,A + LD A,B + CP 4 + CCF + RET C + ; + LD H,high (SYS_PAGE.DISK_TYPE-#4000) + LD L,B + ; + IN A,(SLOT2) + LD B,A + LD A,SYS_PAGE + OUT (SLOT2),A + LD A,C + LD (HL),A + LD A,B + OUT (SLOT2),A + ; + AND A + RET +; + +; не убивает DE и BC +GET_DRV_ST: + CP 4 + CCF + RET C + + PUSH BC + + LD HL,SYS_PAGE.DISK_TYPE-#4000 + ADD A,L + LD L,A + + IN A,(SLOT2) + LD B,A + LD A,SYS_PAGE + OUT (SLOT2),A + LD C,(HL) + LD A,B + OUT (SLOT2),A + + LD A,C + POP BC + AND A + RET +; \ No newline at end of file diff --git a/Crazy BIOS/exp/FUNC_LOW_PRINT.ASM b/Crazy BIOS/exp/FUNC_LOW_PRINT.ASM new file mode 100644 index 0000000..c3d54ea --- /dev/null +++ b/Crazy BIOS/exp/FUNC_LOW_PRINT.ASM @@ -0,0 +1,1914 @@ +; DISPLAY "Low-print-2." +;============================================================== +; +; Программа LOW PRINT for Sprinter-97. +; +;============================================================== + +;============================================================= +; Функции Bios Sprinter-97. +; Рабочая версия 29.05.97 +;============================================================= +; LP_OPEN_WIN Открытие окна +; point 3D13h C=80h Вход: B - код окна. +; B=0 - Spectrum 32x24 B=1 - Spectrum 64x24 +; B=2 - Spectrum 40x24 B=3 - Spectrum 80x24 +; Выход: DE - размер окна +;============================================================= +; LP_PRINT_ALL Вывод символов на экран с текущего знакоместа +; point 3D13h C=81h Вход: A - символ, +; B - число выводимых символов, +; Е - атрибут символа +;============================================================= +; LP_PRINT_SYM Вывод символов на экран с текущего знакоместа +; без атрибута +; point 3D13h C=82h Вход: A - символ, +; B - число выводимых символов, +;============================================================= +; LP_PRINT_ATR Вывод атрибутов на экран с текущего знакоместа +; point 3D13h C=83h Вход: B - число выводимых символов, +; Е - атрибут символа +;============================================================= +; LP_SET_PLACE Установка текущего знакоместа +; point 3D13h C=84h Вход: E - знакоместо по горизонтали +; D - знакоместо по вертикали +;============================================================= +; LP_PRINT_LN Вывод строки символов на экран с текущего +; знакоместа +; point 3D13h C=85h Вход: HL - адрес строки +; B - число выводимых символов, +; Е - атрибут символов +;============================================================= +; LP_PRINT_LN2 Вывод строки символов на экран с текущего +; знакоместа без атрибутов +; point 3D13h C=86h Вход: HL - адрес строки +; B - число выводимых символов, +;============================================================= +; LP_PRINT_LN3 Вывод строки символов на экран с текущего +; знакоместа +; point 3D13h C=87h Вход: HL - адрес строки +; B - число выводимых символов, +; D - разделитель +; Е - атрибут символов +;============================================================= +; LP_PRINT_LN4 Вывод строки символов на экран с текущего +; знакоместа без атрибутов +; point 3D13h C=88h Вход: HL - адрес строки +; B - число выводимых символов, +; D - разделитель +;============================================================= +; LP_CLS_WIN Очистка окна экрана +; point 3D13h C=89h Вход: DE - положение окна +; B - атрибут очистки +; H - высота, L - ширина +;============================================================= + + MACRO TEST_40 ;[x] включил 31/10/23, чисто на Хэллоууууииин + EX AF,AF' + JR C,.LLL + INC D ; режим 40 +.LLL: EX AF,AF' + ; + ENDM + + MACRO DJ_NEXT_HL + ; DEC B + ; CALL Z,LP_NEXT_HL + DJNZ .LLL + CALL LP_NEXT_HL +.LLL: + ENDM + + + + MACRO LP_OPEN_PG + IN A,(SLOT3) + LD C,A + LD A,SYS_PAGE + OUT (SLOT3),A + + LD A,C + LD (SYS_PAGE.COPY_SLOT3),A + IN A,(PORT_Y) + LD (SYS_PAGE.COPY_RGADR),A + ENDM + + MACRO LP_CLOSE_PG + LD A,(SYS_PAGE.COPY_RGADR) + OUT (PORT_Y),A + LD A,(SYS_PAGE.COPY_SLOT3) + OUT (SLOT3),A + ENDM + + +;********************************* +;* LOW LEVEL PRINTER * +;* DE' - ZG * +;* HL' - PLACE ON SCR * +;* C' - ATTRIBUTES * +;* B' - COUNT SYMBS * +;* ZF - inverse * +;* AF' - страница и mode * +;********************************* + + MACRO LP_BEG_PM + EX AF,AF' + EXX + IN A,(SLOT3) + LD C,A + IN A,(PORT_Y) + LD B,A + + LD A,SYS_PAGE + OUT (SLOT3),A + LD (SYS_SP),SP + LD SP,SYS_SP + PUSH BC + + LD HL,(WIN_ID_0.HL) + LD DE,(WIN_ID_0.DE) + LD BC,(WIN_ID_0.BC) + + LD A,E + AND A + RRA + OUT (PORT_Y),A + EXX + EX AF,AF' + ENDM + + MACRO LP_END_PM + EX AF,AF' + EXX + RLA + LD E,A + LD (WIN_ID_0.HL),HL ; место печати + LD (WIN_ID_0.DE),DE + LD (WIN_ID_0.BC),BC + + POP BC + LD A,B + OUT (PORT_Y),A + LD A,C + OUT (SLOT3),A + + LD SP,SYS_SP + EXX + EX AF,AF' + RET + ENDM + +; +;------------------------------------------------------------------[#81] +LP_PRINT_ALL: + CALL LP_BEG_P + EXX + LD C,A + EXX + LD A,#50 + OUT (SLOT3),A + +.loop: EXX + LD A,D + OUT (PORT_Y),A + INC D +.cont: LD (HL),C + EXX + LD A,E + EXX + INC L + LD (HL),A + DEC L + TEST_40 + DJ_NEXT_HL + EXX + DJNZ .loop + + JP LP_END_P +;------------------------------------------------------------------[#81] +; + +; +;------------------------------------------------------------------[#82] +LP_PRINT_SYM: + CALL LP_BEG_P + EXX + LD C,A + EXX + LD A,#50 + OUT (SLOT3),A + +.loop: EXX + LD A,D + OUT (PORT_Y),A +.cont: LD (HL),C + INC D + TEST_40 + DJ_NEXT_HL + EXX + DJNZ .loop + + JP LP_END_P +;------------------------------------------------------------------[#82] +; + +; +;------------------------------------------------------------------[#83] +LP_PRINT_ATR: + CALL LP_BEG_P + LD A,E + EXX + LD C,A + EXX + LD A,#50 + OUT (SLOT3),A + +.loop: EXX + LD A,D + OUT (PORT_Y),A + INC D + INC L + LD (HL),C + DEC L + TEST_40 + DJ_NEXT_HL + EXX + DJNZ .loop + + ;LD A,SYS_PAGE + ;OUT (SLOT3),A + JP LP_END_P +;------------------------------------------------------------------[#83] +; + +; +;------------------------------------------------------------------[#85] +LP_PRINT_LINE: + CALL LP_BEG_P + EXX + LD C,PORT_Y + EXX + LD A,#50 + OUT (SLOT3),A + +.loop: EXX + OUT (C),D + INC D + EXX + LD A,(HL) + INC HL + EXX + LD (HL),A + EXX + LD A,E + EXX + INC L + LD (HL),A + DEC L + TEST_40 + DJ_NEXT_HL + EXX + DJNZ .loop + + ;LD A,SYS_PAGE + ;OUT (SLOT3),A + JP LP_END_P +;------------------------------------------------------------------[#85] +; + +; +;------------------------------------------------------------------[#86] +LP_PRINT_LINE2: + CALL LP_BEG_P + EXX + LD C,PORT_Y + EXX + LD A,#50 + OUT (SLOT3),A + +.loop: LD A,(HL) + INC HL + EXX + OUT (C),D + INC D + LD (HL),A + TEST_40 + DJ_NEXT_HL + EXX + DJNZ .loop + + ;LD A,SYS_PAGE + ;OUT (SLOT3),A + JP LP_END_P +;------------------------------------------------------------------[#86] +; + +; +;------------------------------------------------------------------[#87] +LP_PRINT_LINE3: + CALL LP_BEG_P + LD A,#50 + OUT (SLOT3),A + +.loop: EXX + LD A,D + OUT (PORT_Y),A + INC D + EXX + LD A,(HL) + INC HL + CP D + JR NZ,.NoEnd + DEC HL + ;!TEST + ;LD A,' ' + EXX + LD C,' ' + JP LP_PRINT_ALL.cont + ; +.NoEnd: EXX + LD (HL),A + EXX + LD A,E + EXX + INC L + LD (HL),A + DEC L + TEST_40 + DJ_NEXT_HL + EXX + DJNZ .loop + + JP LP_END_P +;------------------------------------------------------------------[#87] +; + +; +;------------------------------------------------------------------[#88] +LP_PRINT_LINE4: + CALL LP_BEG_P + LD A,#50 + OUT (SLOT3),A + +.loop: EXX + LD A,D + OUT (PORT_Y),A + EXX + LD A,(HL) + INC HL + CP D + JR NZ,.NoEnd + DEC HL + ;!TEST + ;LD A,' ' + EXX + LD C,' ' + JP LP_PRINT_SYM.cont + ; +.NoEnd: EXX + LD (HL),A + INC D + TEST_40 + DJ_NEXT_HL + EXX + DJNZ .loop + + JP LP_END_P +;------------------------------------------------------------------[#88] +; + +; +;------------------------------------------------------------------[#8B] +LP_PRINT_LINE5: + CALL LP_BEG_P + LD A,#50 + OUT (SLOT3),A + +.loop: EXX + LD A,D + OUT (PORT_Y),A + EXX + LD A,(HL) + INC HL + CP D + ;!TEST + ;JR Z,.exit + JR Z,LP_END_P + ; + EXX + LD (HL),A + EXX + LD A,E + EXX + INC L + LD (HL),A + DEC L + INC D + TEST_40 + DJ_NEXT_HL + EXX + DJNZ .loop + +.exit: ;JP LP_END_P +;------------------------------------------------------------------[#8B] +LP_END_P: ; !!!!! ожидается, что портятся только альтернативные регистры и те, что как параметры на входе + LD A,SYS_PAGE + OUT (SLOT3),A +.SYS_PAGE: + EX AF,AF' + EXX + RLA + LD E,A + LD (WIN_ID_0.reg_HL),HL ; место печати + LD (WIN_ID_0.reg_DE),DE + LD (WIN_ID_0.reg_BC),BC + LP_CLOSE_PG + EXX + EX AF,AF' + AND A + RET +.short: EX AF,AF' + EXX + LP_CLOSE_PG + EXX + EX AF,AF' + AND A + RET +; + +; +;------------------------------------------------------------------[#8C] +LP_PRINT_LINE6: + CALL LP_BEG_P + LD A,#50 + OUT (SLOT3),A + +.loop: EXX + LD A,D + OUT (PORT_Y),A + EXX + LD A,(HL) + INC HL + CP D + ;!TEST + ;JR Z,.exit + JR Z,LP_END_P + ; + EXX + LD (HL),A + INC D + TEST_40 + DJ_NEXT_HL + EXX + DJNZ .loop + +.exit: JP LP_END_P +;------------------------------------------------------------------[#8C] +; + + + + + + +; +;------------------------------------------------------------------[#84] +LP_SET_PLACE: ; портятся только альтернативные регистры и те, что как параметры на входе + CALL LP_BEG_P + CALL LP_AT_D + CALL LP_TAB_E + JP LP_END_P.SYS_PAGE +;------------------------------------------------------------------[#84] +; + +; +;------------------------------------------------------------------[#8E] +LP_GET_PLACE: + CALL LP_BEG_P + + LD A,(WIN_ID_0.H_BEG) + NEG + EXX + ADD A,D + EXX + LD E,A + + LD A,(WIN_ID_0.V_BEG) + NEG + EXX + ADD A,L + DEC A + EXX + RRCA + RRCA + AND %0011'1111 + LD D,A + + JP LP_END_P.short +;------------------------------------------------------------------[#8E] +; + +; +;-------------------------------------------------------------[#89, #8D] +;--------------------------------------------------------[#89] +LP_CLS_WIN: + LD C,' ' + JR CLS_WIN +;--------------------------------------------------------[#89] +;--------------------------------------------------------[#8D] +LP_CLS_WIN2: + LD C,A + ;JR CLS_WIN +;--------------------------------------------------------[#8D] +CLS_WIN: CALL LP_BEG_P + LD (SYS_PAGE.SYS_WORK1),BC ; сохранить цвет + PUSH DE + +.loop1: CALL LP_AT_D + CALL LP_TAB_E + PUSH DE + EXX + LD BC,(SYS_PAGE.SYS_WORK1) + EXX + LD B,L + LD A,#50 + OUT (SLOT3),A + +.loop2: EXX + LD A,D + OUT (PORT_Y),A + LD (HL),C + INC L + LD (HL),B + DEC L + INC D + EXX + DJNZ .loop2 + + LD A,SYS_PAGE + OUT (SLOT3),A + POP DE + INC D + DEC H + JR NZ,.loop1 + + POP DE + CALL LP_AT_D + CALL LP_TAB_E + JP LP_END_P.SYS_PAGE +;-------------------------------------------------------------[#89, #8D] +; + +; +;------------------------------------------------------------------[#B8] +WIN_GET_ZG: ; DE - адрес куда переслать фонт + LD HL,ZG_ADDRESS + LD BC,#0800 + LDIR + AND A + RET +;------------------------------------------------------------------[#B8] +; + +; +;------------------------------------------------------------------[#B6] +WIN_SET_ZG: ; LP_SET_ZG: + EX AF,AF' + EXX + LP_OPEN_PG + CALL .SET ;LP_SET_ZG1 + LP_CLOSE_PG + EXX + EX AF,AF' + AND A + RET +.SET: IN A,(SLOT1) + LD (SYS_PAGE.COPY_SLOT1),A + LD A,SHARED_PAGE + OUT (SLOT1),A + EXX + LD BC,Port_All_Mode + IN A,(C) + LD (SYS_PAGE.SYS_WORK1),A + AND #FE ; Spectrum Screen on, accelerator and keyboard interrupt off + OUT (C),A + EX AF,AF' + LD B,A + AND #0F + ADD A,A + OUT (PORT_Y),A + LD A,B + RRCA + RRCA + RRCA + AND #18 + OR #40 + LD H,A + LD L,0 + LD BC,#0800 ;!HARDCODE + EX DE,HL + ;!TEST 11/02/2024 установка шрифта более гибкая без заплётов + LD A,H + SUB #C0 + JR NC,.change + ; + LDIR +.cont: EX DE,HL + LD A,H + RRCA + RRCA + RRCA + DEC A + AND 3 + ADD A,#58 + LD H,A + +.loop: LD (HL),L + INC L + JR NZ,.loop + + LD A,(SYS_PAGE.SYS_WORK1) + LD BC,Port_All_Mode + OUT (C),A + EXX + + EX AF,AF' + LD A,(SYS_PAGE.COPY_SLOT1) + OUT (SLOT1),A + RET +;!TEST 11/02/2024 установка шрифта более гибкая без заплётов +.change: + LD A,(SYS_PAGE.COPY_SLOT3) + OUT (SLOT3),A + LDIR + LD A,SYS_PAGE + OUT (SLOT3),A + JR .cont +;------------------------------------------------------------------[#B6] +; + +;******************************************************* +; +; WIN_MAP_SC - карта экрана +; 0 - hor size +; 1 - ver size +; 2 - hor place +; 3 - ver place +LP_SIZE: ; определение size + LP_OPEN_PG + LD DE,(WIN_ID_0.USER.SIZE_H) + LD A,(WIN_ID_0.USER.MODE) + BIT 5,A + LP_CLOSE_PG + RET NZ + LD A,E + ADD A,A + LD E,A + RET +; + + +LP_AT_D: ; !!!!! ожидается, что портятся только альтернативные регистры и те, что как параметры на входе + LD A,(WIN_ID_0.USER.SIZE_V) + EXX + LD L,A + EXX + LD A,D + EXX +.loop: SUB L + JR NC,.loop + + ADD A,L + ADD A,A + ADD A,A + LD L,A + LD A,(WIN_ID_0.V_BEG) + ADD A,L + LD L,A + INC L + LD H,#C3 + EXX + RET +; + + +; !!!!! ожидается, что портятся только альтернативные регистры и те, что как параметры на входе +LP_TAB_E: + LD A,(WIN_ID_0.SIZE_REL) + EXX + LD D,A + EXX + LD A,E + EXX +.loop: SUB D + JR NC,.loop + JR Z,.loop + + NEG + LD B,A ; сохранить сколько осталось символов в строке + NEG + ADD A,D + LD D,A + LD A,(WIN_ID_0.USER.MODE) + AND %0010'0000 + JR Z,.skip_Dx2 + LD A,D + ADD A,A + LD D,A +.skip_Dx2: + LD A,(WIN_ID_0.H_BEG) + ADD A,D + LD D,A + EXX + RET +;************************************************************* + +; вычисление нового места +LP_NEXT_HL: + LD A,SYS_PAGE + OUT (SLOT3),A + INC L + INC L + INC L + INC L + LD A,(WIN_ID_0.V_END) + CP L + JR NC,LP_NEXT_HL1 + LD HL,(WIN_ID_0.V_BEG) + ;LD A,(WIN_ID_0.V_BEG) + ;LD L,A + INC L + LD H,#C3 ;!HARDCODE +LP_NEXT_HL1: + LD A,(WIN_ID_0.H_BEG) + LD D,A + LD A,(WIN_ID_0.SIZE_REL) + LD B,A + + LD A,#50 + OUT (SLOT3),A + RET + +; !!!!! ожидается, что портятся только альтернативные регистры и те, что как параметры на входе +LP_BEG_P: + EX AF,AF' + EXX + LP_OPEN_PG + LD HL,(WIN_ID_0.reg_HL) + LD DE,(WIN_ID_0.reg_DE) + LD BC,(WIN_ID_0.reg_BC) + LD A,E + AND A + RRA + OUT (PORT_Y),A + EXX + EX AF,AF' + RET + +LP_INI_P: + EX AF,AF' + EXX + LP_OPEN_PG + LD A,(WIN_ID_0.USER.MODE) + CP #C0 + JR NC,LP_INI_NO_ZG ; открытие бордера... + LD A,(WIN_ID_0.USER.MODE_S) + BIT 0,A + JR NZ,LP_INI_NO_ZG ; открытие Spectrum-Screen + + LD A,(WIN_ID_0.USER.MODE) + BIT 4,A + JR Z,LP_INI_NO_ZG ; открытие графического экрана + LD DE,(SYS_PAGE.WIN_ZG) ; знакогенератор + + EXX + EX AF,AF' + CALL WIN_SET_ZG.SET ;LP_SET_ZG1 + EXX + EX AF,AF' + +LP_INI_NO_ZG: + LD A,(WIN_ID_0.H_BEG) + LD D,A + LD A,(WIN_ID_0.V_BEG) + LD L,A + INC L + LD H,#C3 + + AND A + LD A,(WIN_ID_0.USER.MODE) + BIT 5,A + LD A,(WIN_ID_0.USER.SIZE_H) + JR NZ,LP_INI_40 + ADD A,A + SCF + ;!TODO что-то тут подвыпиленно +LP_INI_40: + LD B,A + LD (WIN_ID_0.SIZE_REL),A + + ; LD DE,(SYS_PAGE.WIN_MODE_SC) ; место по горизонтали и страница моды + ; LD HL,(SYS_PAGE.WIN_MODE_SH) ; место по вертикали с адресом + ; INC HL + ; LD B,0 + ; CALL LP_TAB_H2 + + EX AF,AF' + EXX + JP LP_END_P +;******************************************************** + + + +; +;------------------------------------------------------------------[#80] +LP_OPEN_S: + LD A,B + ADD A,A + CP LP_SC_TAB.SIZE + CCF + RET C + PUSH HL + LD HL,LP_SC_TAB + + ADD A,L + LD L,A + LD A,H + ADC A,0 + LD H,A + LD A,(HL) + INC HL + LD H,(HL) + LD L,A + EX (SP),HL + RET +LP_SC_TAB: + DW LP_SET_32 + DW LP_SET_64 + DW LP_SET_40 + DW LP_SET_80 + DW LP_SET_32.X + DW LP_SET_64.X + DW LP_SET_40.X + DW LP_SET_80.X + DW PIC_SET_S1 + DW PIC_SET_S2 + ; DW LP_SET_MNU +.SIZE EQU $-LP_SC_TAB + +;LP_SET_MNU: ; ????? +; SCF +; RET +; LD IX,LP_SCR_MNU +; JP LP_SET_MODE + +LP_SET_32: + LD HL,#4104 +.X: LD IX,LP_SCR_32 + JP LP_SET_MODE + +LP_SET_64: + LD HL,#4104 +.X: LD IX,LP_SCR_64 + JP LP_SET_MODE + +LP_SET_40: + LD HL,#4000 +.X: LD IX,LP_SCR_40 + JP LP_SET_MODE + +LP_SET_80: + LD HL,#4000 +.X: LD IX,LP_SCR_80 + JP LP_SET_MODE + +PIC_SET_S1: + LD IX,PIC_320X256_1 + JP LP_SET_MODE + +PIC_SET_S2: + LD IX,PIC_320X256_2 + JP LP_SET_MODE +;------------------------------------------------------------------[#80] +; + +; +;------------------------------------------------------------------[#B0] +; HL - место на экране по знакоместам (НЕ ИСПОЛЬЗУЕТСЯ) +; IX - описатель окна +WIN_OPEN: + LP_OPEN_PG + LD (SYS_PAGE.WIN_MAP_SC),IX ; карта окна + PUSH DE + LD HL,(SYS_PAGE.WIN_MAP_SC) + LD DE,WIN_ID_0 + LD BC,Window_UserVars + LDIR + LD IX,WIN_ID_0 + POP DE + LD L,(IX+Window_Variables.USER.PLACE_H) + LD H,(IX+Window_Variables.USER.PLACE_V) + LD (IX+Window_Variables.MODE_E),E + JP WIN_OPEN_W1 + + +; HL - PLACE +; IX - SIZE_HOR; IX+1 - SIZE_VER; IX+2,3; IX+4 - MODE; +; E - страница моды. +PIC_FN0: +LP_SET_MODE: + LD A,H + AND #10 ; переместить бит 4 в регистр E + XOR E + LD E,A + LD A,L + AND #3F + ADD HL,HL + ADD HL,HL + LD L,A + LD A,H + AND #3F + LD H,A + LP_OPEN_PG + LD (SYS_PAGE.WIN_MAP_SC),IX ; карта окна + PUSH HL + PUSH DE + LD HL,(SYS_PAGE.WIN_MAP_SC) + LD DE,SYS_PAGE.WIN_MAP_IX + LD BC,Window_UserVars + LDIR + LD IX,SYS_PAGE.WIN_MAP_IX + POP DE + POP HL + LD (IX+Window_Variables.USER.PLACE_H),L + LD (IX+Window_Variables.USER.PLACE_V),H + LD (IX+Window_Variables.MODE_E),E +WIN_OPEN_W1: + LD A,L + ADD A,A + INC A ; вычисление PORT_Y + BIT 4,E + JR NZ,LP_SET_NO_OR + OR #80 ; если вывод на второй экран +LP_SET_NO_OR: + LD (IX+Window_Variables.H_BEG),A + LD D,A + LD A,(IX+Window_Variables.USER.SIZE_H) + ADD A,A + ADD A,D + LD (IX+Window_Variables.H_END),A + LD (SYS_PAGE.WIN_MODE_SC),DE ; место по горизонтали и страница моды + LD A,H + AND #3F + ADD A,A + ADD A,A + LD L,A + LD H,#C3 + LD (SYS_PAGE.WIN_MODE_SH),HL ; место по вертикали с адресом + LD (IX+Window_Variables.V_BEG),A + LD A,(IX+Window_Variables.USER.SIZE_V) + ADD A,A + ADD A,A + ADD A,L + LD (IX+Window_Variables.V_END),A + + LD L,(IX+Window_Variables.V_BEG) + LD H,#C3 + LD B,(IX+Window_Variables.USER.SIZE_V) ; размер по вертикали + + + LD (IX+Window_Variables.WORK_1),0 + LD A,(IX+Window_Variables.USER.MODE) ; знакогенератор плюс режим + LD (IX+Window_Variables.WORK_2),A + BIT 4,A + JR NZ,LP_SET_LOOP ; переход, если текстовый режим + + AND #F0 + LD C,A + LD A,(IX+Window_Variables.USER.GR_X) + RRCA + RRCA + RRCA + LD D,A + AND #0F + OR C + LD (IX+Window_Variables.WORK_2),A + + LD A,D + AND #E0 + LD C,A + LD A,(IX+Window_Variables.USER.GR_Y) + AND #1F + OR C + RLCA + RLCA + RLCA + LD (IX+Window_Variables.WORK_1),A + +LP_SET_LOOP: + LD D,(IX+Window_Variables.H_BEG) ; D - начало строки (PORT_Y) + LD C,(IX+Window_Variables.USER.SIZE_H) ; размер по горизонтали + LD A,(IX+Window_Variables.USER.MODE) ; знакогенератор плюс режим + + PUSH BC + CALL LP_MODE_LINE + POP BC + INC L + INC L + INC L + INC L + DJNZ LP_SET_LOOP + + LD A,(IX+Window_Variables.MODE_E) + AND 1 + OUT (RGMOD),A + ; LD A,(IX+Window_Variables.MODE) + ; BIT 4,A + LP_CLOSE_PG + ; RET Z + CALL LP_INI_P + ; LD A,(SYS_PAGE.WIN_MODE_SC) + ; OUT (RGMOD),A + CALL LP_SIZE + XOR A + RET + +WIN_CLOSE: + SCF + RET + + +; Установка режима на линии +LP_MODE_LINE: + BIT 0,(IX+Window_Variables.USER.MODE_S) + JP NZ,LP_MODE_LINE2 ; идти на спектрум + BIT 4,A + JP Z,LP_MODE_LINE3 ; идти на графику! + DEC D + +; текстовый режим. + + EX AF,AF' + LD A,#50 + OUT (SLOT3),A + LD A,L ; вертикальное положение + CP #80 + JR NC,LP_EXIT_MODE + +LP_MODE_RECURSE: + LD A,D ; горизонтальное положение + AND 7FH + SUB 80 + JR C,LP_MODE_LL + SUB 48 + NEG + + LD E,A ; запомнить + ADD A,D + LD D,A ; новое положение + + LD A,E ; восстановить + RRA + AND 3FH + SUB C + JR NC,LP_EXIT_MODE + NEG + LD C,A ; новое значение C + JR LP_MODE_RECURSE + +LP_MODE_LL: + NEG + RRA + AND 3FH + CP C + JR NC,LP_MODE_LR + LD C,A +LP_MODE_LR: + EX AF,AF' + + INC D +LP_MD_LL1: + EX AF,AF' + LD A,D + OUT (PORT_Y),A + EX AF,AF' + LD (HL),A ; режим + INC D + EX AF,AF' + LD A,D + OUT (PORT_Y),A + EX AF,AF' + LD (HL),A ; режим + INC D + DEC C + JR NZ,LP_MD_LL1 + + EX AF,AF' +LP_EXIT_MODE: + LD A,SYS_PAGE + OUT (SLOT3),A + EX AF,AF' + RET + +; Установка режима на линии +; Spectrum mode +LP_MODE_LINE2: + LD A,(IX+Window_Variables.WORK_2) + LD B,(IX+Window_Variables.WORK_1) + + DEC D + + EX AF,AF' + LD A,#50 + OUT (SLOT3),A + LD A,L ; вертикальное положение + CP #80 + JR NC,LP_EXIT_MODE2 + +LP_MODE_RECURSE2: + LD A,D ; горизонтальное положение + AND #7F + SUB 80 + JR C,LP_MODE_LL2 + SUB 48 + NEG + + LD E,A ; запомнить + ADD A,D + LD D,A ; новое положение + + LD A,E ; восстановить + RRA + AND #3F + SUB C + JR NC,LP_EXIT_MODE2 + NEG + LD C,A ; новое значение C + JR LP_MODE_RECURSE2 + +LP_MODE_LL2: + NEG + RRA + AND #3F + CP C + JR NC,LP_MODE_LR2 + LD C,A +LP_MODE_LR2: + EX AF,AF' + + INC D +LP_MD_LL2: + EX AF,AF' + LD A,D + OUT (PORT_Y),A + EX AF,AF' + LD (HL),A ; режим + INC L + LD (HL),B + INC L + LD (HL),B + DEC L + DEC L + + INC D + BIT 4,A + JR NZ,lp_md_ll3x + INC B +lp_md_ll3x: + EX AF,AF' + LD A,D + OUT (PORT_Y),A + EX AF,AF' + LD (HL),A ; режим + INC L + LD (HL),B + INC L + LD (HL),B + DEC L + DEC L + + INC D + + INC B + JR NZ,LP_NO_ADD_40 + ADD A,40H +LP_NO_ADD_40: + + DEC C + JR NZ,LP_MD_LL2 + + EX AF,AF' +LP_EXIT_MODE2: + LD A,SYS_PAGE + OUT (SLOT3),A + EX AF,AF' + + LD (IX+Window_Variables.WORK_1),B + LD (IX+Window_Variables.WORK_2),A + RET + + +LP_MODE_LINE3: ; Установка режима на линии + +; Grafic Mode + + LD A,(IX+Window_Variables.WORK_1) + LD B,(IX+Window_Variables.WORK_2) + + DEC D + + EX AF,AF' + LD A,#50 + OUT (SLOT3),A + LD A,L ; вертикальное положение + CP #80 + JR NC,LP_EXIT_MODE3 + +LP_MODE_RECURSE3: + LD A,D ; горизонтальное положение + AND #7F + SUB 80 + JR C,LP_MODE_LL3 + SUB 48 + NEG + + LD E,A ; запомнить + ADD A,D + LD D,A ; новое положение + + LD A,E ; восстановить + RRA + AND #3F + SUB C + JR NC,LP_EXIT_MODE3 + NEG + LD C,A ; новое значение C + JR LP_MODE_RECURSE3 + +LP_MODE_LL3: + NEG + RRA + AND #3F + CP C + JR NC,LP_MODE_LR3 + LD C,A +LP_MODE_LR3: + EX AF,AF' + + INC D + + BIT 5,B + JR Z,LP_GR_640 + +LP_MD_LL3: + + EX AF,AF' + LD A,D + OUT (PORT_Y),A + EX AF,AF' + LD (HL),B ; режим + INC L + LD (HL),A ; режим 2 + INC L + LD (HL),0 ; режим 2 + DEC L + DEC L + + INC D + +; EX AF,AF' +; LD A,D +; OUT (PORT_Y),A +; EX AF,AF' +; LD (HL),B ; режим +; INC L +; LD (HL),A ; режим 2 +; DEC L + + INC D + + INC A + LD E,A + AND 7 + JR NZ,LP_NO_INC_B + LD A,E + SUB 8 + LD E,A + INC B +LP_NO_INC_B: + LD A,E + + DEC C + JR NZ,LP_MD_LL3 + +LP_640_RET: + EX AF,AF' +LP_EXIT_MODE3: + LD A,SYS_PAGE + OUT (SLOT3),A + EX AF,AF' + + LD A,(IX+Window_Variables.WORK_1) + ADD A,8 + LD (IX+Window_Variables.WORK_1),A + RET + +LP_GR_640: + EX AF,AF' + LD A,D + OUT (PORT_Y),A + EX AF,AF' + LD (HL),B ; режим 1 + INC L + LD (HL),A ; режим 2 + INC L + LD (HL),0 ; режим 3 + + INC D + + EX AF,AF' + LD A,D + OUT (PORT_Y),A + EX AF,AF' + LD (HL),0 ; режим 3 + DEC L + LD (HL),A ; режим 2 + DEC L + LD (HL),B ; режим 1 + + INC D + + INC A + LD E,A + AND 7 + JR NZ,LP_NO_INC_B6 + LD A,E + SUB 8 + LD E,A + INC B +LP_NO_INC_B6: + LD A,E + + DEC C + JR NZ,LP_GR_640 + JP LP_640_RET + + +;***************************************************************** + + +LP_SCROLL_UD: + DEC B + JR Z,LP_SCROLL_UP + DEC B + JR Z,LP_SCROLL_DN + SCF + RET + +; Вход: +; D - верхняя строка ( от 0 ) +; E - число скроллируемых строк +LP_SCROLL_UP: + DEC E + RET Z + LP_OPEN_PG + LD B,E + LD E,0 ;!FIXIT чёт тут нечисто, подгонка под один вариант окна глобального? + CALL .RUN +.EXIT: LP_CLOSE_PG + RET + ; +.RUN: PUSH BC + CALL LP_AT_D + CALL LP_TAB_E ; вычислить переменные для строки + POP BC +.loop2: EXX + PUSH HL + EXX + POP HL + + LD E,L + LD D,H + INC L + INC L + INC L + INC L + + LD A,(WIN_ID_0.V_END) + CP L + ;JR C,.EXIT ; если конец, то выход + RET C + PUSH BC + + LD A,L + EXX + LD L,A + EXX + + LD A,(WIN_ID_0.USER.SIZE_H) + ADD A,A ; число байт в строке для переноса + ADD A,A + + LD C,A + LD B,0 + + LD A,#50 + OUT (SLOT3),A ; открыть страницу для переноса + EXX + LD A,D ; получить порт начала строки + EXX +.loop1: OUT (PORT_Y),A + INC A ; следующее значение порта + LDI + LDD + OUT (PORT_Y),A + INC A ; следующее значение порта + LDI + LDD + JP PE,.loop1 + + LD A,SYS_PAGE + OUT (SLOT3),A + POP BC + DJNZ .loop2 + RET + + + +; Вход : +; D - верхняя строка ( от 0 ) +; E - число скроллируемых строк +LP_SCROLL_DN: + DEC E ;!FIXIT правильно? + RET Z + + LP_OPEN_PG + LD B,E + LD E,0 + LD A,D + ADD A,B +; DEC A + LD D,A + PUSH BC + CALL LP_AT_D + CALL LP_TAB_E + POP BC + +.loop2: EXX + PUSH HL + EXX + POP HL + + LD E,L + LD D,H + DEC L + DEC L + DEC L + DEC L + + LD A,(WIN_ID_0.V_BEG) + CP L ; .CONT: L >= A + JR Z,.CONT + JR NC,.EXIT ; если конец, то выход +.CONT: PUSH BC + + LD A,L + EXX + LD L,A + EXX + + LD A,(WIN_ID_0.USER.SIZE_H) + ADD A,A + ADD A,A + LD C,A + LD B,0 + + LD A,#50 + OUT (SLOT3),A + EXX + LD A,D + EXX +.loop1: OUT (PORT_Y),A + INC A + LDI + LDD + OUT (PORT_Y),A + INC A + LDI + LDD + JP PE,.loop1 + + LD A,SYS_PAGE + OUT (SLOT3),A + + POP BC + DJNZ .loop2 +.EXIT: LP_CLOSE_PG + RET + + +; DE - место символа в окне +; А - номер окна +; выход: HL - символ/атрибут B - знакогенератор +WIN_GET_SYM: + AND A + SCF + RET NZ + + CALL LP_BEG_P + + CALL LP_AT_D + CALL LP_TAB_E + + LD A,#50 + OUT (SLOT3),A + + EXX + + LD A,D + OUT (PORT_Y),A + + LD A,(HL) + EXX + LD L,A + EXX + INC L + LD A,(HL) + EXX + LD H,A + EXX + DEC L + DEC L + LD A,(HL) + EXX + LD B,A + EXX + INC L + + EXX + JP LP_END_P + ;RET + +; DE - место символа в окне +; А - номер окна +; HL - символ/атрибут +; B - знакогенератор +WIN_PUT_SYM: + AND A + SCF + RET NZ + + CALL LP_BEG_P + + CALL LP_AT_D + CALL LP_TAB_E + + LD A,#50 + OUT (SLOT3),A + + EXX + + LD A,D + OUT (PORT_Y),A + + EXX + LD A,L + EXX + + LD (HL),A + INC L + + EXX + LD A,H + EXX + + LD (HL),A + DEC L + DEC L + + EXX + LD A,B + EXX + + LD (HL),A + INC L + + EXX + JP LP_END_P + + +; HL - размер окна +; DE - положение окна +; A - номер окна +; IX - новое положение окна +WIN_MOVE: + AND A + SCF + RET NZ + PUSH IX + PUSH HL + LD B,SHARED_PAGE + LD IX,SLOT3.MEM_ADDR + CALL WIN_COPY_WIN1 + POP HL + POP DE + LD B,SHARED_PAGE + LD IX,SLOT3.MEM_ADDR + CALL WIN_RESTORE.Start + AND A + RET + + +; HL - размер сохраняемого окна +; DE - место сохраняемого окна +; IX - адрес сохраняемого окна, в странице 4000h +; А - номер окна, B - страница +WIN_COPY: + AND A + SCF + RET NZ +WIN_COPY_WIN1: + CALL LP_BEG_P + + IN A,(SLOT1) + PUSH AF + + CALL LP_AT_D + CALL LP_TAB_E + + LD (SYS_PAGE.SYS_WORK1),SP + + LD A,B + OUT (SLOT3),A + LD A,#50 + OUT (SLOT1),A + + EXX + RES 7,H + LD C,D + EXX + +.COPY_loop2: + LD A,L + EXX + LD B,A + ; + ADD A,A + ADD A,XL + LD XL,A + JR NC,.NO_INC_XH + INC XH +.NO_INC_XH: + LD SP,IX + ; + LD A,C + ADD A,B +.COPY_loop: + DEC A + OUT (PORT_Y),A + LD E,(HL) + INC L + LD D,(HL) + DEC L + PUSH DE + DJNZ .COPY_loop + ; + INC HL + INC HL + INC HL + INC HL + EXX + DEC H + JR NZ,.COPY_loop2 + ; + LD A,SYS_PAGE + OUT (SLOT3),A + LD SP,(SYS_PAGE.SYS_WORK1) + ; + POP AF + OUT (SLOT1),A + JP LP_END_P.short + ;AND A + ;RET + + +; HL - размер сохраняемого окна +; DE - место сохраняемого окна +; IX - адрес данных восстанавливаемого окна +WIN_RESTORE: + AND A + SCF + RET NZ +.Start: + CALL LP_BEG_P + ; + IN A,(SLOT1) + PUSH AF + ; + CALL LP_AT_D + CALL LP_TAB_E + ; + LD (SYS_PAGE.SYS_WORK1),SP + LD SP,IX + ; + LD A,B + OUT (SLOT3),A + LD A,#50 + OUT (SLOT1),A + ; + EXX + RES 7,H + LD C,D + EXX +.L2: LD A,L + EXX + LD B,A + LD A,C +.L1: OUT (PORT_Y),A + INC A + POP DE + LD (HL),E + INC L + LD (HL),D + DEC L + DJNZ .L1 + ; + INC HL + INC HL + INC HL + INC HL + EXX + DEC H + JR NZ,.L2 + + LD A,SYS_PAGE + OUT (SLOT3),A + + LD SP,(SYS_PAGE.SYS_WORK1) + + POP AF + OUT (SLOT1),A + JP LP_END_P.short +;======================================================================; + + + + +;!FIXIT нет описания, недоделана. Печать с управляющими символами +;------------------------------------------------------------------[#E0] +; DE - место символа в окне +; HL - адрес с выводимой строкой +; B - разделитель +LP_PR_LINE_DIR: + CALL LP_BEG_P + LD A,#50 + OUT (SLOT3),A + +.loop: EXX + LD A,D + OUT (PORT_Y),A + EXX + LD A,(HL) + INC HL + CP B + JR Z,.exit + EXX + ; печатаемые символы + CP 14 + JR NC,.print + CP 7 + JR C,.print + ; управляющие символы + SUB 7 + JR Z,LP_BELL ; A = 07 "BELL" + DEC A + JR Z,LP_BACK ; A = 08 "Backspace" + DEC A + JR Z,LP_TAB ; A = 09 "TAB" + DEC A + JR Z,LP_LF ; А = 10 "Line Feed" + DEC A + JR Z,.VT ; А = 11 "Vertical Tabulation" = "Line Feed", если LF работает как CRLF + DEC A + JR Z,LP_CLS ; А = 12 "Form feed" - разрыв страницы, начало нового листа, может работать как VT + DEC A + JR Z,LP_CR ; А = 13 "Carriage Return" + ; + + ; выводить! +.VT: ; ... + ; ... +.print: LD (HL),A + INC D + +.next: ; ... + ; ... + DJ_NEXT_HL + EXX + JR .loop + +.exit: JP LP_END_P +; +; +LP_PRINT_LN_D11: + LD A,#50 + OUT (SLOT3),A + JR LP_PR_LINE_DIR.next + +;!TODO недоделана +LP_BELL: + JR LP_PR_LINE_DIR.next + +LP_BACK: + LD A,SYS_PAGE + OUT (SLOT3),A + + LD A,(WIN_ID_0.H_BEG) + CP D + JR Z,LP_PRINT_LN_D11 + INC B + DEC D + JR LP_PRINT_LN_D11 + +;-------[TAB] +LP_TAB: LD A,SYS_PAGE + OUT (SLOT3),A + LD A,(WIN_ID_0.H_BEG) + SUB D + NEG + AND %0000'0111 + NEG + ADD A,8 + LD C,A + LD A,#50 + OUT (SLOT3),A + +.loop: LD (HL),' ' + INC D + DEC B + JR Z,.end_Line + DEC C + JR NZ,.loop + + JR LP_PR_LINE_DIR.next +.end_Line: + LD A,SYS_PAGE + OUT (SLOT3),A + LD A,(WIN_ID_0.H_BEG) + LD D,A + LD A,(WIN_ID_0.SIZE_REL) + LD B,A + ;JP LP_LF +;-------[TAB end] +LP_LF: LD A,SYS_PAGE + OUT (SLOT3),A + + INC L + INC L + INC L + INC L + + LD A,(WIN_ID_0.V_END) + CP L + JR NC,LP_PRINT_LN_D11 + ;!TEST BIOS SCROLL + ;LD A,(WIN_ID_0.V_BEG) + ;LD L,A ; вернуться наверх без скролла!!! + ;-------------------------------------------------------------\ + PUSH HL + PUSH BC + EXX + PUSH BC + PUSH DE + EXX + + LD A,(WIN_ID_0.USER.SIZE_V) + LD B,A + CALL LP_SCROLL_UP.RUN + + EXX + POP DE + POP BC + EXX + POP BC + POP HL + ;-------------------------------------------------------------/ + ; + ; scrolling ???? + JR LP_PRINT_LN_D11 + +LP_CLS: ; ... + ; scrolling ???? + JR LP_PR_LINE_DIR.next + +LP_CR: LD A,SYS_PAGE + OUT (SLOT3),A + + LD A,(WIN_ID_0.H_BEG) + LD D,A + LD A,(WIN_ID_0.SIZE_REL) + LD B,A + + JR LP_PRINT_LN_D11 +;------------------------------------------------------------------[#E0] + diff --git a/Crazy BIOS/exp/FUNC_PIC.ASM b/Crazy BIOS/exp/FUNC_PIC.ASM new file mode 100644 index 0000000..c080c58 --- /dev/null +++ b/Crazy BIOS/exp/FUNC_PIC.ASM @@ -0,0 +1,512 @@ + +;****************************************************************** +; вход: DE - вертикаль, HL - горизонталь, +; B - цвет точки, A - экран +PIC_FN1: + AND A + SCF + RET NZ + + IN A,(RGADR) + PUSH AF + + IN A,(SLOT3) + EX AF,AF' + LD A,SYS_PAGE + OUT (SLOT3),A + + LD A,(WIN_ID_0.GRAF_Y) + ADD A,E + OUT (RGADR),A + LD A,B + LD BC,(WIN_ID_0.GRAF_X) + ADD HL,BC + LD B,A + LD A,#50 + OUT (SLOT3),A + LD (HL),A + EX AF,AF' + OUT (SLOT3),A + + POP AF + OUT (RGADR),A + RET + +; вход: DE - вертикаль, HL - горизонталь. +; IX - длина линии в точках не 0 !!! +; FILL - by A +; ????? +PIC_FN2: + LD D,A + IN A,(SLOT1) + EX AF,AF' + + LD A,B + ADD A,#50 + OUT (SLOT1),A + + BIT 0,B + LD BC,#40+#4000 + JR Z,PIC_FN2_NO_2ND + LD BC,#40+320+#4000 +PIC_FN2_NO_2ND: + ADD HL,BC + + LD A,E + OUT (RGADR),A + + LD A,XH + AND A + JR Z,PIC_FN2_NO256 +PIC_FN2_256L: + LD B,64 +PIC_FN2_256: + LD (HL),D + INC HL + LD (HL),D + INC HL + LD (HL),D + INC HL + LD (HL),D + INC HL + DJNZ PIC_FN2_256 + DEC A + JR NZ,PIC_FN2_256L + +PIC_FN2_NO256: + LD B,XL + AND A + RR B + JR NC,PIC_FN2_NO1 + LD (HL),D + INC HL + AND A +PIC_FN2_NO1: + RR B + JR NC,PIC_FN2_NO2 + LD (HL),D + INC HL + LD (HL),D + INC HL + AND A +PIC_FN2_NO2: + XOR A + CP B + JR Z,PIC_FN2_NO4 +PIC_FN2_4: + LD (HL),D + INC HL + LD (HL),D + INC HL + LD (HL),D + INC HL + LD (HL),D + INC HL + DJNZ PIC_FN2_4 +PIC_FN2_NO4: + + EX AF,AF' + OUT (SLOT1),A + XOR A + OUT (RGADR),A + RET + +;************************************************************************ +; вход: dE - вертикаль, HL - горизонталь. +; A',HL' - адрес данных во второй странице ! +; BC' - длина данных +; ВЫВОД ЛИНИИ ТОЧЕК +PIC_FN3: + IN A,(SLOT3) + LD C,A + LD A,SYS_PAGE + OUT (SLOT3),A + LD A,C + LD (SYS_PAGE.COPY_SLOT3),A + IN A,(SLOT2) + LD (SYS_PAGE.COPY_SLOT2),A + IN A,(SLOT1) + LD (SYS_PAGE.COPY_SLOT1),A + + LD A,B + ADD A,#50 + OUT (SLOT1),A + + BIT 0,B + LD BC,40H+04000H + JR Z,PIC_FN3_NO_2ND + LD BC,40H+320+04000H +PIC_FN3_NO_2ND: + ADD HL,BC + + LD A,E + OUT (RGADR),A + + LD A,H + EXX + LD D,A + EXX + LD A,L + EXX + LD E,A + EXX + + EX AF,AF' + OUT (SLOT2),A + EX AF,AF' + LD HL,SYS_PAGE.RAMD_FAT + LD L,A + LD A,SYS_PAGE + OUT (SLOT3),A + LD A,(HL) + OUT (SLOT3),A + EXX + LDIR + BIT 6,H + JR Z,PIC_FN3_NO + RES 6,H + EX AF,AF' +PIC_FN3_NO: + EXX + + LD A,SYS_PAGE + OUT (SLOT3),A + LD A,(SYS_PAGE.COPY_SLOT1) + OUT (SLOT1),A + LD A,(SYS_PAGE.COPY_SLOT2) + OUT (SLOT2),A + LD A,(SYS_PAGE.COPY_SLOT3) + OUT (SLOT3),A + + XOR A + OUT (RGADR),A + RET + +;************************************************************************** +;PIC_FN4: +; вход: HL - данные палитры RGB, E - начальный цвет +; D - число цветов, B - PAL-mask, A - page PAL +PIC_SET_PAL: + PUSH IX + + EX AF,AF' + IN A,(RGADR) + PUSH AF ; сохранить положение RGADR + LD A,E + OUT (RGADR),A ; начальный цвет в порт + LD A,D ; сохранить число цветов + EX AF,AF' ; вернуть страницу PAL + + BIT 7,H ; проверить адрес данных + LD C,SLOT3 ; если ниже 8000h + LD D,#C3 ; то граф.экран на странице 3 + JR Z,.NO_PAGE1 + LD D,#43 ; иначе + LD C,SLOT1 ; на странице 1 +.NO_PAGE1: + ADD A,A + PUSH AF + + ADD A,A + AND #1C + XOR #E0 ; младший байт адреса PAL + LD E,A ; DE - адрес в видео-ОЗУ + PUSH DE + POP IX ; адрес палитры + + LD D,B ; маска PAL + EX AF,AF' ; вернуть число цветов + LD B,A ; число цветов + + IN E,(C) ; сохранить страницу 3 + LD A,#50 ; страница графического RAM + OUT (C),A + + POP AF + JR C,PIC_GET_PAL + ; цикл установки цветов палитры +.loopPal: + LD A,(HL) ; B + AND D + LD (IX+2),A + INC HL + + LD A,(HL) ; G + AND D + LD (IX+1),A + INC HL + + LD A,(HL) ; R + AND D + LD (IX+0),A + INC HL + + LD A,(HL) ; Y + AND D + LD (IX+3),A + INC HL + + IN A,(RGADR) + INC A + OUT (RGADR),A + DJNZ .loopPal ; выполнять, пока не 0 + +.exit: OUT (C),E ; восстановить страницу 3 + POP AF + OUT (RGADR),A ; восстановить Y_PORT + POP IX + AND A + RET + +PIC_GET_PAL: + ; цикл чтения цветов палитры +.loopPal: + LD A,(IX+2) + LD (HL),A ; B + INC HL + + LD A,(IX+1) + LD (HL),A ; G + INC HL + + LD A,(IX+0) + LD (HL),A ; R + INC HL + + LD A,(IX+3) + LD (HL),A ; Y + INC HL + + IN A,(RGADR) + INC A + OUT (RGADR),A + DJNZ .loopPal ; выполнять, пока не 0 + + JR PIC_SET_PAL.exit + +;******************************************************************** +PIC_FN5: ; УСТАНОВКА СТРАНИЦЫ MODE + LD A,E + AND 1 + OUT (RGMOD),A + RET +;******************************************************************* +; Установка внутренней палитры +; A - page_pal, E - номер палитры, B - тип палитры +SET_PAL_INIT: + LD D,A + DEC B + JP Z,SET_PAL_GRAF + DEC B + JP Z,SET_PAL_ZX + DEC B + JP Z,SET_PAL_IBM + +; LD IX,PAL_DAT1 +; JR Z,PIC_FN6_L1 +; DEC B +; LD IX,PAL_DAT +; JR Z,PIC_FN6_L1 + + SCF + RET + +;PIC_FN6_L1: +; AND 3 +; ADD A,A +; ADD A,A +; ADD A,#E0 +; LD L,A +; LD H,#43 +; IN A,(SLOT1) +; PUSH AF +; +; LD A,#50 +; OUT (SLOT1),A +; XOR A +; OUT (RGADR),A +; EX AF,AF' +; call PAL_LOOP_M +; +; POP AF +; OUT (SLOT1),A +; XOR A +; OUT (RGADR),A +; +; RET + +;****************************************************************** +; Рисование линии. +; dЕ - вертикаль, HL - горизонталь +; H' - высота, C'/DE',B' - add_parameters +; A - color +PIC_FN7: + LD D,A + IN A,(SLOT1) + PUSH AF + + LD A,B + ADD A,#50 + OUT (SLOT1),A + + BIT 0,B + LD BC,#40+#4000 + JR Z,.no_2nd + LD BC,#40+320+#4000 +.no_2nd: + ADD HL,BC + LD A,E + +.loop: OUT (RGADR),A ; страница видео-ОЗУ + LD (HL),D + + EXX + EX AF,AF' + + DEC H + JR Z,.exit + + LD A,C ; NEXT HORIZONTAL + ADD A,B + LD C,A + LD A,E + EXX + + ADC A,L + LD L,A + + EXX + LD A,D + EXX + + ADC A,H + LD H,A + INC E ; NEXT VERTICAL + EX AF,AF' + INC A + JR .loop + +.exit: EXX + POP AF + OUT (SLOT1),A + XOR A + OUT (RGADR),A + RET + +;****************************************************************** +; Рисование линии. +; dЕ - вертикаль, HL - горизонталь +; H' - высота, C'/DE',B' - add_parameters +; (IX) - colors +PIC_FN8: + IN A,(SLOT1) + PUSH AF + + LD A,B + ADD A,#50 + OUT (SLOT1),A + + BIT 0,B + LD BC,#40+#4000 + JR Z,.no_2nd + LD BC,#40+320+#4000 +.no_2nd: + ADD HL,BC + LD A,E + +.loop: OUT (RGADR),A ; страница видео-ОЗУ + LD D,(IX) + INC IX + LD (HL),D + + EXX + EX AF,AF' + + DEC H + JR Z,.exit + + LD A,C ; NEXT HORIZONTAL + ADD A,B + LD C,A + LD A,E + EXX + + ADC A,L + LD L,A + + EXX + LD A,D + EXX + + ADC A,H + LD H,A + + INC E ; NEXT VERTICAL + + EX AF,AF' + INC A + JR .loop + +.exit: EXX + POP AF + OUT (SLOT1),A + XOR A + OUT (RGADR),A + RET + +;************************************************** +; Вывод спрайта на экран +; HL - горизоталь, dE - вертикаль +; A',HL' - адрес данных +PIC_FN9: + +;********************************* +; HL,E - координаты D - color +; B - Magnify +PIC_FN10: +PIC_FN11: +PIC_FN12: +PIC_FN13: +PIC_FN14: +PIC_FN15: + SCF + RET + +;************************************ +; +; Экранные таблицы +; +;текстовое окно 80x32 +LP_SCR_80: + DB 40,32,0,0,27,0,0,0 + DB 0, 0,0,0, 0,0,0,0 + +;текстовое окно 40x32 +LP_SCR_40: + DB 40,32,0,0,123,0,0,0 + DB 0, 0,0,0, 0,0,0,0 + +;спектрумовское окно 32x24 +LP_SCR_32: + DB 32,24,4,4,48,1,0,0 + DB 0, 0,0,0, 0,0,0,0 + +;текстовое окно 64x24 +LP_SCR_64: + DB 32,24,4,4,155,0,0,0 + DB 0, 0,0,0, 0,0,0,0 + +;графическое окно 0 +PIC_320X256_1: + DB 40,32,0,0,32,0,8,0 + DB 0, 0,0,0, 0,0,0,0 + +;графическое окно 1 +PIC_320X256_2: + DB 40,32,0,0,96,0,48,0 + DB 0, 0,0,0, 0,0, 0,0 + +;************************************ +; + + diff --git a/Crazy BIOS/exp/FUNC_RAM_ROM_DRV.ASM b/Crazy BIOS/exp/FUNC_RAM_ROM_DRV.ASM new file mode 100644 index 0000000..8668e4f --- /dev/null +++ b/Crazy BIOS/exp/FUNC_RAM_ROM_DRV.ASM @@ -0,0 +1,1118 @@ +;===================[ Функции распределения памяти ]===================; +; Выход: BC - FREE MEM в блоках по 16k, HL - FULL MEM +;!TEST все SLOT2 на SLOT1 +; +;----------------------------------------------------------------------; +; Определение объема памяти. +; Выход: BC - FREE MEM в блоках по 16k, HL - FULL MEM +EMM.GetMemSize: + IN A,(SLOT1) + LD B,A + LD A,SYS_PAGE + OUT (SLOT1),A + LD HL,SYS_PAGE.RAMD_FAT - #4000 - #4000 + LD C,0 +.loop: LD A,(HL) + INC L + JR Z,.exit + AND A + JR NZ,.loop + INC C + JR .loop +.exit: LD HL,#100 ;!HARDCODE max mem pages + LD A,B + LD B,0 + OUT (SLOT1),A + RET +;----------------------------------------------------------------------; +; + +;!!!!! Если используется SLOT3 со своими страницами, то не пользоваться +; стеком, там может быть SP в режиме спектрума + +; +;----------------------------------------------------------------------; +; Инициализация распределения памяти. +EMM.InitMem: + PUSH BC + PUSH HL + PUSH DE + + IN A,(SLOT3) + LD C,A + LD A,SYS_PAGE + OUT (SLOT3),A + LD HL,SYS_PAGE.RAMD_FAT ; Адрес RAM FAT в ОЗУ. + ; обнуляем таблицу + XOR A +.loopFree: + LD (HL),A + INC L + JR NZ,.loopFree + ; резервируем спец.страницы и страницы ZX + LD B,RESERVED_PAGES.Blocks + LD DE,RESERVED_PAGES ; таблица занятых системных страниц +.loop: LD A,(DE) + CP #FF + JR Z,.exitLoop +.loopBlk: + INC DE + LD L,A + LD A,(DE) + LD (HL),A + CP #FF + JR NZ,.loopBlk +.exitLoop: + INC DE + DJNZ .loop + LD L,A + LD (HL),A + ; Инициализация ключей RAM-Disks + XOR A + LD HL,SYS_PAGE.RAMD_KEYS; - #4000 - #4000 + LD B,SYS_PAGE.RAMD_KEYS.NUM +.loop2: LD (HL),A + INC L + DJNZ .loop2 + ; [x] 04/11/2023 + LD HL,SYS_PAGE.Sp_RAMD_KEYS; - #4000 - #4000 + LD B,SYS_PAGE.Sp_RAMD_KEYS.NUM +.loop3: LD (HL),A + INC L + DJNZ .loop3 + ; + LD A,C + OUT (SLOT3),A + POP DE + POP HL + POP BC + RET +;---------------------------------------------------------------------[] +RESERVED_PAGES: + ; [x] Block #1 - можно освободить по ID 1 + DB 1,3,4,6,7,8,9,10,11,12,13,14,15 ; for Spectrum + ;!FIXIT страницы 16..31 не зарезервированы, но используются в Pentagon 512 + ; + ; эмулятор ПЗУ ;!FIXIT ROM-Emulator сделать динамические страницы + DB #42,#43,#44,#45,#46,#47;,#48,#49,#4A,#4B ; For (BASIC128, BASIC48, TRDOS, SCORP_ROM)*2, vBIOS, vEXTENSION + DB #FF ; End of the block + ; + ; + ;; Block #2 - нельзя освобождать + DB 0,2,5 ; for Spectrum and BIOS starting + DB DCP_PAGE ; Ports map + DB Spec_Page ; Page for Spectrum mode + ; Screen pages + DB #50,#51,#52,#53,#54,#55,#56,#57 + DB #58,#59,#5A,#5B,#5C,#5D,#5E,#5F + ; + ;DB MODE_PAGE ; ????? + DB CBL.BUFFER_PAGE ; Page for CBL audio + DB SYS_PAGE ; Page for system (BIOS) variables + DB #FF ; End of the block + ; +.Blocks EQU 2 +;----------------------------------------------------------------------; +; + + + +; +;----------------------------------------------------------------------; +; Получить блок памяти N bytes, +; Вход: B - число необходимых блоков +; Выход: L,A - КЛЮЧ RAM-Disk/код ошибки +; CF - признак ошибки +;EMM_FN2M: +EMM.GetMem: + ;PUSH DE + PUSH BC + IN A,(SLOT3) + EX AF,AF' + LD A,SYS_PAGE + OUT (SLOT3),A + LD C,B ; сохранить число нужных блоков + LD HL,SYS_PAGE.RAMD_FAT; - #4000 - #4000 +; Цикл проверки наличия нужных блоков. +.loop: DEC L + JR Z,.noRAM + LD A,(HL) + AND A + JR NZ,.loop + DJNZ .loop + + ; Место есть ! + LD B,C ; Восстановить нужный объем диска + LD C,#FF ; МЕТКА КОНЦА RAM-Disk + LD HL,SYS_PAGE.RAMD_FAT; - #4000 - #4000 + +; Заполнить RAMD_FAT +.loop2: DEC L + LD A,(HL) + AND A + JR NZ,.loop2 + LD (HL),C + LD C,L + DJNZ .loop2 + + ; L - указатель цепочки. + EX AF,AF' + OUT (SLOT3),A + LD A,L + AND A + POP BC + ;POP DE + RET + +.noRAM: LD L,1 ; НЕТ ПАМЯТИ + EX AF,AF' + OUT (SLOT3),A + LD A,L + SCF + POP BC + ;POP DE + RET +;----------------------------------------------------------------------; +; + + + +; +;----------------------------------------------------------------------; +; Получить блок памяти N bytes, для RAM-Disk A +; Вход: B - число необходимых блоков, A - RAM-Disk +; Выход: L,A - КЛЮЧ RAM-Disk/код ошибки +; CF - признак ошибки +;EMM.GetMem: +EMM.GetMemRMD: + PUSH AF + CALL EMM.GetMem + JR C,.error1 + + LD B,A + POP AF + CALL BLK_TO_RAMD + RET NC +.error2: + LD L,2 ; RAM-Disk занят ;!TODO перечислить все варианты ошибок и их номера как для ДСС + LD A,L + RET +.error1: + POP HL ; чистим стек + LD L,A + ;SCF + RET +;----------------------------------------------------------------------; +; + + + +;----------------------------------------------------------------------; +; Освободить блок памяти ключа K +; Вход: A - КЛЮЧ RAM-Disk +EMM.FreeMemRMD: + CALL GET_RAMD_ST + RET C + SCF + RET Z + LD C,A + IN A,(SLOT3) + LD B,A + LD A,SYS_PAGE + OUT (SLOT3),A + LD H,high SYS_PAGE.RAMD_KEYS; - #4000 - #4000 + LD (HL),0 + LD A,B + OUT (SLOT3),A + LD A,C + ;JR EMM.FreeMem +;------[ +; Освободить блок памяти +; Вход: A - НАЧАЛО ЦЕПОЧКИ +; НЕ ПОРТИТЬ DE!!! +;EMM_FN3M: +EMM.FreeMem: + AND A + SCF + RET Z + ; + LD L,A + CP ZX_RAM_ID + CALL Z,SET_ROM_FLAG_ZX + ; + IN A,(SLOT3) + EX AF,AF' + LD A,SYS_PAGE + OUT (SLOT3),A + + LD H,high (SYS_PAGE.RAMD_FAT) + LD A,L +EMM_F3M_L1: + LD L,A + LD A,(HL) ; следующий блок + AND A + JR Z,EMM_FN3M_ERR + LD (HL),0 ; Освободить + CP #FF ; Если не конец + JR NZ,EMM_F3M_L1 ; продолжать + + EX AF,AF' + OUT (SLOT3),A + XOR A ; no error code + RET + +EMM_FN3M_ERR: + EX AF,AF' + OUT (SLOT3),A + LD A,BIOS.Error.BadNumber + SCF + RET +;----------------------------------------------------------------------; +; + + + +; WARNING!!! не трогать DE +;----------------------------------------------------------------------; +; Получить страницу N ключа K +; Вход: A - КЛЮЧ RAM-Disk, B - номер страницы +; Выход: A - страница +EMM.GetMemPageRMD: + CALL GET_RAMD_ST + RET C + SCF + RET Z + ;JR EMM.GetMemPage +;------[ +; Получить страницу N блока K +; Вход: A - блок, B - номер страницы +; Выход: A - страница, IF CF - A=0 - нет блока, A=FF - END +;EMM_FN4M: +EMM.GetMemPage: + LD L,A + IN A,(SLOT1) + EX AF,AF' + LD A,SYS_PAGE + OUT (SLOT1),A + + INC B + LD H,high (SYS_PAGE.RAMD_FAT - #4000 - #4000) +EMM_F4M_L1: + LD A,(HL) + AND A + JR Z,EMM_F4M_ERR + DEC B + JR Z,EMM_F4M_END + LD L,A + CP #FF + JR NZ,EMM_F4M_L1 +EMM_F4M_ERR: + LD L,A + EX AF,AF' + OUT (SLOT1),A + LD A,L + SCF + RET + +EMM_F4M_END: + EX AF,AF' + OUT (SLOT1),A + LD A,L + AND A + RET +;----------------------------------------------------------------------; +; + + + +; +;----------------------------------------------------------------------; +; Получить следующую страницу по FAT +; Вход: A - страница ОЗУ +; Выход: A - следующая страница ОЗУ +;EMM_FN5: +EMM.GetMemPageNext: + LD L,A + AND A + SCF + RET Z + IN A,(SLOT1) + LD H,A + LD A,SYS_PAGE + OUT (SLOT1),A + LD A,H + LD H,high (SYS_PAGE.RAMD_FAT - #4000 - #4000) + LD L,(HL) + OUT (SLOT1),A + LD A,L + AND A + SCF + RET Z + AND A + RET +;----------------------------------------------------------------------; +; + + + +; +;----------------------------------------------------------------------; +; Получить список страниц блока в HL +; Вход: A - блок, HL - адрес буфера - 256 байт. +; Выход: HL - адрес блока, B - длина блока в страницах ОЗУ +;EMM_FN5M: +EMM.GetMemBlkPages: + PUSH DE + PUSH HL + EX DE,HL + LD B,0 + LD L,A + +.loop: LD A,L + LD (DE),A + INC DE + AND A + JR Z,.error + CP #FF + JR Z,.end + ; + IN A,(SLOT1) + LD C,A + LD A,SYS_PAGE + OUT (SLOT1),A + LD H,high (SYS_PAGE.RAMD_FAT - #4000 - #4000) + LD L,(HL) + LD A,C + OUT (SLOT1),A + ; + INC B + JR NZ,.loop + +.error: SCF +.end: POP HL + POP DE + RET + +; RAMDRV.EXE вызывает эту функцию с адресом в SLOT1, поэтому лучше так не оптимизировать +; EMM.GetMemBlkPages: +; PUSH DE +; PUSH HL +; EX DE,HL +; LD B,0 +; LD L,A + +; IN A,(SLOT1) +; LD C,A +; LD A,SYS_PAGE +; OUT (SLOT1),A + +; .loop: LD A,L +; LD (DE),A +; INC DE +; AND A +; JR Z,.error +; CP #FF +; JR Z,.end +; ; +; LD H,high (SYS_PAGE.RAMD_FAT - #4000 - #4000) +; LD L,(HL) +; INC B +; JR NZ,.loop + +; .error: SCF +; .end: LD A,C +; OUT (SLOT1),A +; POP HL +; POP DE +; RET +;----------------------------------------------------------------------; +; + + + +; +;----------------------------------------------------------------------; !FIXIT SAFE_RGADR +;RAMD_R_W: +; ╔════════════════════════════════════════════════╗ +; ║ RD/WR SECTOR ║\ +; ║ HL - BUFER ║\ +; ║ DE - ABS sector в 256b блоках ║\ +; ║ B - число данных в 256b блоках ║\ +; ║ A - block RAM ║\ +; ║ A' - команда чтение/запись/чтение ROM Disk ║\ +; ║ 0 - read, 255 - write, 70 - read ROM DISK ║\ +; ║ ** NOT USED TR-DOS VARS ** ║\ +; ╚════════════════════════════════════════════════╝\ +; \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ +BLK_RD_WR: + AND A + SCF + RET Z + ; + AND A + INC B + DEC B + RET Z + ; + ; сохраняем состояние прерываний + LD C,A + LD A,R + PUSH AF + ; сохраняем PORT_Y + IN A,(PORT_Y) + PUSH AF + LD A,#C0 + OUT (PORT_Y),A + ; + LD A,C + DI + CALL .start + EX AF,AF' + ; восстанавливаем PORT_Y + POP AF + OUT (PORT_Y),A + ; восстанавливаем состояние прерываний + POP AF + JP PO,.noInterrupts + EI +.noInterrupts: + EX AF,AF' + RET + ; + +.start: EX AF,AF' + AND A ; 0 - read + JR Z,.reset_Z + CP #FF ; write + JR Z,.keep_Z + + CP 5 ; old read + JR Z,.reset_Z + CP 6 ; old write + JR Z,.keep_Z + + CP #46 + JP Z,ROM_DISK + + EX AF,AF' + SCF + RET + +.reset_Z: + INC A ; set Z for WRITE +.keep_Z: + EX AF,AF' + ; + + PUSH HL + PUSH BC + LD C,SLOT1 + IN B,(C) + LD H,A + LD A,SYS_PAGE + OUT (SLOT1),A + LD A,H + + LD H,high (SYS_PAGE.RAMD_FAT - #4000 - #4000) + LD L,A + + INC D +.RAMD_LOOP_D: + DEC D + JR Z,.NOT_FOUR_BLK + LD L,(HL) + LD L,(HL) + LD L,(HL) + LD L,(HL) + JR .RAMD_LOOP_D + +.NOT_FOUR_BLK: + LD A,E +.loop: SUB #40 + JR C,.NOT_ONE_BLK + LD L,(HL) + JR .loop + +.NOT_ONE_BLK: + AND #3F + LD D,A ; DE - ADRESS in RAM-Disk + LD E,0 + + LD A,L ; L - текущий банк RAM-Disk + + OUT (C),B ; восстановить страницу + + POP BC ; длина данных + POP HL ; адрес буфера + + BIT 7,H + JR NZ,.BLK_PAGE1 + + LD C,SLOT3 + IN C,(C) + OUT (SLOT3),A + SET 7,D + SET 6,D + JR .BLK_CONT1 + +.BLK_PAGE1: + LD C,SLOT1 + IN C,(C) + OUT (SLOT1),A + RES 7,D + SET 6,D + +.BLK_CONT1: ; DE - RamDisk, HL - data + EX AF,AF' + JR Z,.NO_EX_RW1 ; WRITE + EX DE,HL ; for READ +.NO_EX_RW1: + EX AF,AF' + + LD A,16 +.BLK_LL1: + DUP 16 + LDI + EDUP + + DEC A + JR NZ,.BLK_LL1 + + EX AF,AF' + JR Z,.NO_EX_RW2 ; WRITE + EX DE,HL ; for READ +.NO_EX_RW2: + EX AF,AF' ; DEC C прокрутился 256 раз и вернулся + INC B ; B уже уменьшился на 1, + DEC B + JP Z,.BLK_EXIT_1 + + BIT 6,D + JP NZ,.BLK_CONT1 + + BIT 7,D + JR Z,.BLK_PAGE3_X + + IN A,(SLOT1) + LD E,A + LD D,high (SYS_PAGE.RAMD_FAT - #4000 - #4000) + LD A,SYS_PAGE + OUT (SLOT1),A + LD A,(DE) + OUT (SLOT1),A + LD DE,#4000 + JP .BLK_CONT1 + +.BLK_PAGE3_X: + IN A,(SLOT3) + LD E,A + LD D,high SYS_PAGE.RAMD_FAT + LD A,SYS_PAGE + OUT (SLOT3),A + LD A,(DE) + OUT (SLOT3),A + LD DE,#C000 + + BIT 7,H + JP Z,.BLK_CONT1 + + LD E,A + LD A,C + OUT (SLOT3),A + IN A,(SLOT1) + LD C,A + LD A,E + OUT (SLOT1),A + LD DE,#4000 + JP .BLK_CONT1 + +.BLK_EXIT_1: + LD A,D + DEC A + RLCA + LD A,C + JR C,.BLK_EXIT_2 + OUT (SLOT1),A + RET +.BLK_EXIT_2: + OUT (SLOT3),A + AND A + RET +;----------------------------------------------------------------------; +; + + + +; +;----------------------------------------------------------------------; + ;**************************************** + ;!!!!! READ_ROM_PAGE_X чтение последних + ; 256 байтов ПЗУ в служебную страницу зачем-то + ; READ_ROM_PAGE_X: + ; LD DE,0 + ; LD BC,#100 ; один сектор + ; PUSH DE + ; PUSH BC + ; LD HL,#3F00 + ; LD DE,#FF00 + ; LD A,#1F ; last page ROM + ; JR ROM_DISK.loopRead + ;**************************************** + +; Чтение с ROM-Disk +; HL - адрес, куда читать +; DE - номер сектора (считать по 256b сектор) +; B - число секторов +; A' - размер сектора (1 - 256b, 2 - 512 b) +ROM_DISK: + ; сохраняем состояние прерываний + ;LD A,R + EX AF,AF' + LD C,0 ; счетчик + DEC A + JR Z,.loop + ;JR Z,.start + DEC A + SCF + RET NZ + + EX DE,HL + ADD HL,HL + EX DE,HL + LD A,B + ADD A,A + LD B,A + ;!!!!! + RET C + + DI + CALL .loop +; ; восстанавливаем состояние прерываний +; EX AF,AF' +; JP PO,.noInterrupts +; EI +; .noInterrupts: +; EX AF,AF' +; ; + RET C + AND A + RR D + RR E + XOR A + RET + +; .start: +; DI +; CALL .loop +; ; восстанавливаем состояние прерываний +; EX AF,AF' +; JP PO,.noInterrupts2 +; EI +; .noInterrupts2: +; EX AF,AF' +; ; +; RET + + +.loop: PUSH DE ; номер сектора + PUSH BC + + LD A,E + AND #3F ; ADRESS in ROM-Page + PUSH AF ; сохранить адрес + + EX DE,HL ; DE - адрес буфера + ADD HL,HL + ADD HL,HL ; H - номер банки + + LD A,(ROM_DISK.Pages.Number) + INC H + CP H + LD L,H + LD H, high ROM_DISK.Pages.Number ; ROM-Disk pages! + LD A,(HL) ; PAGE-ROM + + POP HL ; восстановить адрес в ROM-Page + LD L,0 ; если далеко захотели - выход с ошибкой + JR C,.errorExit ; ROM-Disk-end +; DE - буфер +; HL - адрес в ROM +; B - число секторов +; A - ROM-Page +.loopRead: + PUSH HL ; откуда + PUSH DE ; куда + + LD HL,-.stackDepth - .readProcedure.size ; memory stack use! + ADD HL,SP ; stack + + PUSH HL ; адрес программы .readProcedure + + LD DE,.readProcedure ; перенести программу на стек + EX DE,HL + LD BC,.readProcedure.size + LDIR ; программа на стеке + LD BC,#100 ; длина сектора + RET ; исполнить программу .readProcedure, на стеке адреса буфера и ROM +; DE - next address +; HL - ROM address +.readNext: + POP BC ; число секторов + + INC C ; счетчик считанных секторов + DEC B ; сектора кончились? + + JR Z,.normExit + BIT 6,H ; чтение не закончено + + PUSH BC ; сохранить счетчики + JR Z,.loopRead ; читать дальше + POP BC + + POP HL ; номер сектора + + LD A,B + LD B,0 + ADD HL,BC + LD B,A ; вычислить след.сектор + + EX DE,HL ; теперь HL - адрес, DE сектор, B - сколько еще читать + + JP .loop ; начать все снова! +; чтение закончено +.normExit: + POP HL ; сектор, откуда велось чтение + ADD HL,BC ; по возврату: HL - след.адрес + EX DE,HL ; DE - след.сектор + AND A + RET +; ошибка +.errorExit: ; !TODO сделать, чтоб на выходе показывалось количество прочитанных секторов + POP BC + POP DE + SCF + RET +; процедура, переносимая на стек для чтения из ROM-Disk +; осторожнее с PUSH, если надо много, то увеличивай .stackDepth +.readProcedure: + POP DE ; куда + POP HL ; откуда + OUT (ROM.SLOT0),A ; ROM_PAGE + LDIR ; здесь читается из ROM-Disk + LD B,A + XOR A + OUT (ROM.SLOT0),A + OUT (SYS_PORT.ROM),A + LD A,B + JP .readNext +.stackDepth EQU 8 ; расстояние от конца процедуры до вершины стека. +.readProcedure.size EQU $-.readProcedure +;----------------------------------------------------------------------; +; + + + +; +;----------------------------------------------------------------------; +; вход: DE - ram_disk trk_sec, A - RAM-Disk +; выход: HL - адрес, A - page +RAMD_CALC_PAGE: + CP 16 + CCF + RET C ; НЕТ ТАКОГО RAM-Disk + + PUSH AF + LD H,D + LD L,E + ADD HL,HL + ADD HL,HL + LD B,H + LD A,E + OR #C0 + LD C,A ; C - часть адреса, B - страница + POP AF + + CALL EMM.GetMemPageRMD ; ПОЛУЧИТЬ СТРАНИЦУ + LD L,0 + LD H,C + RET +;----------------------------------------------------------------------; +; + + + +; +;----------------------------------------------------------------------; +; Вход: +; A - RAM Disk ID +; Выход: +; A - Number (0..15) +GET_RAMD_NUM: + EX AF,AF' + IN A,(SLOT1) + EX AF,AF' + LD BC,SYS_PAGE * 256 + SLOT1 + OUT (C),B + + LD HL,SYS_PAGE.RAMD_KEYS - #4000 - #4000 + LD BC,SYS_PAGE.RAMD_KEYS.NUM + CPIR + + EX AF,AF' + OUT (SLOT1),A + EX AF,AF' + + SCF + RET PE + + DEC L + LD A,L + SUB low SYS_PAGE.RAMD_KEYS + RET +;----------------------------------------------------------------------; +; + + +; +;----------------------------------------------------------------------; +; [x] 04/11/2023 +; Вход: +; B = 0: swap to Sp +; B = #FF: swap to ZX +; B = #FE: no swap, only get info +; Выход: +; A - current RAM Drives set +SWAP_RAM_DRIVES: + IN A,(SLOT3) + EX AF,AF' + PUSH AF ;на всякий случай + LD A,SYS_PAGE + OUT (SLOT3),A + ; + LD A,(SYS_PAGE.CURRENT_RAM_DRV) + LD C,A + CP B + JR Z,.exit ; уже установлен запрашиваемый набор + ; + LD A,#FE + CP B + JR Z,.exit ; ничего не менять, выдать текущий набор + ; +.swap: LD HL,SYS_PAGE.RAMD_KEYS + LD DE,SYS_PAGE.Sp_RAMD_KEYS + LD B,SYS_PAGE.RAMD_KEYS.NUM +.loop: LD A,(DE) + LD C,A + LD A,(HL) + LD (DE),A + LD A,C + LD (HL),A + INC HL + INC DE + DJNZ .loop + ; + LD A,(SYS_PAGE.CURRENT_RAM_DRV) + XOR #FF + LD (SYS_PAGE.CURRENT_RAM_DRV),A + LD C,A + ; +.exit: EX AF,AF' + OUT (SLOT3),A + POP AF + EX AF,AF' + LD A,C + RET +;----------------------------------------------------------------------; +; + + +; +;----------------------------------------------------------------------; +; на выходе при А = 0 должен быть установлен флаг Z +; не убивает DE и BC +GET_RAMD_ST: + CP SYS_PAGE.RAMD_KEYS.NUM + CCF + RET C + + PUSH BC + + LD HL,SYS_PAGE.RAMD_KEYS - #4000 - #4000 + ADD A,L + LD L,A + + IN A,(SLOT1) + LD B,A + LD A,SYS_PAGE + OUT (SLOT1),A + LD C,(HL) + LD A,B + OUT (SLOT1),A + LD A,C + POP BC + AND A + RET +;----------------------------------------------------------------------; +; + + + +; +;----------------------------------------------------------------------; +; RAM-Disk A, BLK - B +BLK_TO_RAMD: + CP SYS_PAGE.RAMD_KEYS.NUM + CCF + RET C + + PUSH HL + LD L,A + + IN A,(SLOT3) + LD C,A + LD A,SYS_PAGE + OUT (SLOT3),A + LD A,L + LD HL,SYS_PAGE.RAMD_KEYS; - #4000 - #4000 + ADD A,L + LD L,A + LD A,(HL) ; ключ блока + AND A + JR NZ,BLK_BUSY ; RAM-Disk занят - ошибка + LD (HL),B + + LD A,C + OUT (SLOT3),A + + LD A,B + AND A + POP HL + RET + ; +BLK_BUSY: + LD A,C + OUT (SLOT3),A + SCF + POP HL + LD A,L + RET +;----------------------------------------------------------------------; +; + + + +; +;----------------------------------------------------------------------; +; RAM-Disk A +RAMD_CLEAR: + CP SYS_PAGE.RAMD_KEYS.NUM + CCF + RET C + + PUSH HL + LD L,A + + IN A,(SLOT3) + LD C,A + LD A,SYS_PAGE + OUT (SLOT3),A + LD A,L + LD HL,SYS_PAGE.RAMD_KEYS; - #4000 - #4000 ; RAM-Disk свободен + ADD A,L + LD L,A + LD B,A ; запомнить удаляемый рамдиск + LD A,(HL) + AND A + JR Z,BLK_BUSY ; возврат с ошибкой + LD (HL),0 + LD A,C + OUT (SLOT3),A + + AND A + POP HL + RET +;----------------------------------------------------------------------; +; + + + +; +;----------------------------------------------------------------------; +; разделить блок памяти на два блока +; A - блок, B - длина первого блока после разделения +; выход: A - блок 1, B - блок 2 +EMM.DivMemBlocks: + INC B + DEC B + SCF + RET Z + DEC B + LD E,A + CALL EMM.GetMemPage ; получить номер страницы блока + RET C + LD D,A + + IN A,(SLOT3) + EX AF,AF' + LD A,SYS_PAGE + OUT (SLOT3),A + + LD H,high (SYS_PAGE.RAMD_FAT); - #4000 - #4000) + LD L,D + LD A,(HL) + LD (HL),#FF + LD B,A + + EX AF,AF' + OUT (SLOT3),A + + LD A,E + AND A + RET +;----------------------------------------------------------------------; +; + + + +; +;----------------------------------------------------------------------; +; слить два блока памяти в один +; А - блок 1, B - блок 2 +; выход: А - блок +EMM.MergeMemBlocks: + LD E,A + IN A,(SLOT3) + EX AF,AF' + LD A,SYS_PAGE + OUT (SLOT3),A + LD H,high (SYS_PAGE.RAMD_FAT); - #4000 - #4000) + LD L,E + LD C,B + LD B,0 +.EMM_ADD_L: + LD A,(HL) + AND A + JR Z,.EMM_ADD_ERR + CP #FF + JR Z,.EMM_ADD_NEXT + LD L,A + DJNZ .EMM_ADD_L + +.EMM_ADD_ERR: + EX AF,AF' + OUT (SLOT3),A + SCF + RET + +.EMM_ADD_NEXT: + LD A,C + AND A + JR Z,.EMM_ADD_ERR + LD (HL),A + EX AF,AF' + OUT (SLOT3),A + AND A + LD A,E + RET +;----------------------------------------------------------------------; +; \ No newline at end of file diff --git a/Crazy BIOS/exp/FUNC_SERVICE.asm b/Crazy BIOS/exp/FUNC_SERVICE.asm new file mode 100644 index 0000000..4f02b82 --- /dev/null +++ b/Crazy BIOS/exp/FUNC_SERVICE.asm @@ -0,0 +1,444 @@ +; DISPLAY "Service" +; !FIXIT тут можно, походу, дохрена убрать + +; ; страницы с конфой для Sp97, для совместимости с древними прогами +; PG_SP1 equ #EC +; PG_SP2 equ #EE +; PG_AY equ #EA +; ; + +; ;!TODO замутить заливку конфы, рестарт, перехват ресета силами BIOS +; PG_Sp2000 EQU #FE +; PG_Sp2000_REINIT EQU #FD +; +RST_CONF: +;--[] ZX Spectrum +.AY8910: + LD D,#35 ;!HARDCODE REG #35 - BASIC SETTING 1 (SYS_PAGE.CONFIG_DE+1 = #C13B on PAGE #FE) + CALL CMOS_RD + OR 1 + CALL CMOS_WR + + LD BC,Port_All_Mode + IN A,(C) + AND #FE ;!HARDCODE + OUT (C),A ; ACC_OFF + + ;LD A,PG_AY + LD DE,ACEX.Config_ID.Sp97_AY + JR .INT_PLD +;--[] + +;--[] Sprinter ZX +.SP97_1: + LD D,#35 ;!HARDCODE REG #35 - BASIC SETTING 1 (SYS_PAGE.CONFIG_DE+1 = #C13B on PAGE #FE) + CALL CMOS_RD + AND #FE + CALL CMOS_WR + + LD BC,Port_All_Mode + IN A,(C) + AND #FE ;!HARDCODE + OUT (C),A ; ACC_OFF + + ;LD A,PG_SP1 + LD DE,ACEX.Config_ID.Sp97_1 + JR .INT_PLD +;--[] + +;--[] +.SP97_2: + LD BC,Port_All_Mode + IN A,(C) + OR 1 ; ACC_ON + OUT (C),A + ;LD A,PG_SP2 + LD DE,ACEX.Config_ID.Sp97_2 + JR .INT_PLD +;--[] + + +;--[] +;[x] +.SP2000: + LD BC,Port_All_Mode + IN A,(C) + OR 1 ; ACC_ON + OUT (C),A + LD DE,ACEX.Config_ID.Sp2000 + JR .INT_PLD +;--[] + + +;--[] +.CUSTOM: + CP #80 + JR NC,.CHOOSE_CNF + ; only for old FLEX10K soft compatible + LD C,SLOT3 + IN B,(C) + OUT (C),A ; PAGE с прошивкой + LD DE,(#C090) ; PLD-ID + OUT (C),B ; RET page +;--[] ;JR INT_PLD +.INT_PLD: ; only for old FLEX10K soft compatible + LD C,SLOT3 + IN B,(C) + LD A,SYS_PAGE + OUT (C),A + LD (SYS_PAGE.CONFIG_BYTE),DE + OUT (C),B + + LD A,E ; config-byte + CP #FF + LD A,#80 + JR Z,.YES_CBL + XOR A +.YES_CBL: + LD BC,CBL.SYS_PORT + OUT (C),A + + LD A,E ; config-byte + + OR #FE ;!HARDCODE + LD BC,Port_All_Mode ; SYSTEM Spectrum/Sprinter + OUT (C),A + + LD A,#3C + OUT (FDC_93.DrvCTRL),A + + XOR A + RET + ; + ;[x] +.CHOOSE_CNF: + ; [x] + CP ACEX.Config_PG.Sp2000_SoftSetUp + JP Z,.ReturnSoftReset + ; + CP ACEX.Config_PG.Sp2000 + JR Z,.INIT_ACEX + ; + CP ACEX.Config_PG.Sp2000_SetUp + JR Z,.SP2000 + ; + + ; only for old FLEX10K soft compatible + CP ACEX.Config_PG.Sp97_1 + LD DE,ACEX.Config_ID.Sp97_1 + JR Z,.INT_PLD + CP ACEX.Config_PG.Sp97_2 + LD DE,ACEX.Config_ID.Sp97_2 + JR Z,.INT_PLD + CP ACEX.Config_PG.Sp97_AY + LD DE,ACEX.Config_ID.Sp97_AY + JR Z,.INT_PLD + SCF + RET + ; + ;[x] +.INIT_ACEX: + DI + ; устанавливаем нулевую карту портов + LD A,CNF_PORT.CNF_0 + OUT (SYS_PORT.ON),A + ; и так понятно что делает + IN A,(SLOT3) ; сохраняем номер воткнутой страницы + PUSH AF + LD A,Spec_Page + OUT (SLOT3),A + ; проверяем размер блока с конфой и получаем страницы конфы + LD HL,Spec_Page.bitstream_pages + LD A,B + AND A + JR Z,.INIT_ACEX.ReloadConfFromROM + ; + CALL EMM.GetMemBlkPages + LD A,B + JR C,.INIT_ACEX.ERROR + CP BitStream_SizeInPages+1 ; количество страниц в кэш для бистрима плюс одна + JR NC,.INIT_ACEX.ERROR + LD A,(Spec_Page.bitstream_pages) + INC A + JR Z,.INIT_ACEX.ERROR + ; +.INIT_ACEX.ReloadConfFromROM: + ; закидываем в Spec_Page прогу для заливки конфы + LD HL,.INIT_ACEX.PROGRAM + LD DE,Spec_Page.init_acex + LD BC,.INIT_ACEX.PROGRAM.Size + LDIR + ; если ZF=0, то процедура сделает ресет с перезаливкой из BIOS, иначе из КЭШ + CALL Spec_Page.init_acex + LD BC,256*BIOS.REINIT.HARD_RESET + BIOS.REINIT + ; + ; на входе в BC параметры функции BIOS +.INIT_ACEX.ifSoftreset: + ; сохраняем воткнутые страницы в Spec_Page + IN A,(SLOT0) + LD E,A + IN A,(SLOT1) + LD D,A + IN A,(SLOT2) + POP HL ; восстанавливаем номер воткнутой страницы + LD L,A + LD (Spec_Page.page_0),DE + LD (Spec_Page.page_2),HL + ; достаём адрес возврата в вызывающую функцию и сохраняем в Spec_Page + POP DE + LD HL,RST_18_1.exit + XOR A + SBC HL,DE + JR NZ,.set_ret ; NZ - если вызов был по RST #18 + POP DE ; если вызов был в ОЗУ по RST 8 + INC A +.set_ret: + LD (Spec_Page.RET_addr),DE + ; A=0 - SYS_PORT.ON + ; A=1 - SYS_PORT.OFF + LD (Spec_Page.Reload_Version),A + LD HL,0 + ADD HL,SP + LD (Spec_Page.Stack_Point),HL + ; Устанавливаем ключи + LD HL,Spec_Page.flag_R + LD (HL),"R" + INC HL + LD (HL),"S" + INC HL + LD (HL),"T" + ; + ; .. ... ... .. + ;!TODO сделать функцию по заливке своей конфы, перехвату ресета. + ; *. Вход в подфункцию только через RST 08 или #18 + ; *. Сохранить все страницы пользователя в SYS_PAGE для перехвата ресета + ; *. Достать со стека адрес возврата и сохранить в SYS_PAGE для перехвата ресета + ; *. Сохранить куда-нибудь значение стека + ; * + ; .. ... ... .. + ;LD BC,256*BIOS.REINIT.HARD_RESET + BIOS.REINIT + JP_to_BIOS + ; +.ReturnSoftReset: + DI + ; устанавливаем нулевую карту портов + LD A,CNF_PORT.CNF_0 + OUT (SYS_PORT.ON),A + ; и так понятно что делает + IN A,(SLOT3) ; сохраняем номер воткнутой страницы + PUSH AF + LD A,Spec_Page + OUT (SLOT3),A + ; + LD BC,256*BIOS.REINIT.SOFT_RESET + BIOS.REINIT + JR .INIT_ACEX.ifSoftreset + ; + ;;; +.INIT_ACEX.ERROR: + POP AF + OUT (SLOT3),A + SCF + RET +; +.INIT_ACEX.PROGRAM: + DISP Spec_Page.init_acex + ; + SAFE_PORTY + IN A,(FastRAM.ON) + IN A,(SLOT1) + LD (.slot1_page),A + ; + LD A,#FE ; чтоб проверить, что вызывать после CALL NZ,.INIT_ACEX.PROGRAM.LOAD + ; тут ZF должен быть из вызывающей процедуры + CALL NZ,.INIT_ACEX.PROGRAM.LOAD ; если RAM_BLOCK ID не равен 0, то выполняется + INC A ; флаг ZF=0 грузим из ROM + ; +.INIT_ACEX.PROGRAM.SET_KEYS: + LD A,3 + OUT (FastRAM.SLOT0),A ; Страница КЭШ = 3 + ; + LD HL,.INIT_ACEX.Reload_String ; флаг перезагрузки из КЭШ-а + JR Z,.skip ; устанавливаем флаг перезагрузки из КЭШ-а + INC L ; затираем флаг перезагрузки из КЭШ-а +.skip: LD DE,ACEX.LOADER.String_Address-#C000 + LD BC,#10 + LDIR + + LD HL,#FFFF ; залить конфу только при первой перезагрузке + ;LD HL,ACEX.LOADER.Reload_Flag ; заливать конфу при каждой перезагрузке + LD (ACEX.LOADER.Reload_Flag_Address-#C000),HL + ; +.INIT_ACEX.PROGRAM.END: + XOR A + OUT (FastRAM.SLOT0),A + IN A,(FastRAM.OFF) +.slot1_page+1: LD A,0 + OUT (SLOT1),A + RET + ; + ; +.INIT_ACEX.PROGRAM.LOAD: + XOR A ; страница КЭШ + LD HL,Spec_Page.bitstream_pages + OUT (FastRAM.SLOT0),A ; Страница КЭШ = 0 + INC A +.INIT_ACEX.PROGRAM.load_loop: + EX AF,AF' + LD A,(HL) + INC HL + CP #FF + RET Z + OUT (SLOT1),A ; страница с данными файла + EX AF,AF' + ; + ; перекидывание #3000 байтов в КЭШ(0) = #1000 + EXX + LD HL,#4000 + LD DE,#1000 + LD BC,#3000 + LDIR + ; докидывание #1000 байтов в КЭШ(1) = #0000 + ; HL = #7000 + OUT (FastRAM.SLOT0),A ; Страница КЭШ = 1 + INC A + ; + LD D,C ; LD DE,0 + LD B,#10 ; LD BC,#1000 + LDIR + EXX + JR .INIT_ACEX.PROGRAM.load_loop + + +.INIT_ACEX.Reload_String: + DB ACEX.RELOAD_STRING + ; + ENT +.INIT_ACEX.PROGRAM.Size EQU $-.INIT_ACEX.PROGRAM +; +;*************************************** + +;[x] +;--------------------------[;!TODO потестить]--------------------------; +; B - параметр сброса +; B = 1 - RESTART. +; B = 2 - Soft reset +; B = 3 - Hard reset +; B = 4 - Reinit spectrum pages +REINIT: DEC B + JR Z,.Restart ;1 + DEC B + JR Z,.SoftReset ;2 + DEC B + JR Z,.HardReset ;3 + DEC B + SCF + RET NZ +.ReinitZXpages: ;4 + LD DE,RESERVED_PAGES ; таблица занятых системных страниц + LD HL,SYS_PAGE.RAMD_FAT ; Адрес FAT ОЗУ. + + LD C,SLOT3 + IN B,(C) + LD A,SYS_PAGE + OUT (SLOT3),A + + LD A,(DE) +.zxloop: + CP #FF + JR Z,.endzxloop + INC DE + LD L,A + + LD A,(HL) + AND A + JR NZ,.errorzxloop + + LD A,(DE) + LD (HL),A + JR .zxloop + +.errorzxloop: + DEC DE + LD HL,-RESERVED_PAGES-1 + ADD HL,DE + JR NC,.errorzxloop_noChanges + + DEC DE + LD H,high SYS_PAGE.RAMD_FAT + LD A,(DE) + LD L,A + LD A,#FF + LD (HL),A +.errorzxloop_noChanges: + SCF +.endzxloop: + OUT (C),B + RET +; + +;[x] +.HardReset: + DI + LD A,DCP_PAGE + OUT (SLOT1),A ; set DCP page + LD A,ACEX.RESET + LD (#4400),A ; open for WR +.loop: LD BC,#0100 ; цикл сброса + OUT (C),C + LD B,0 + OUT (C),C + JR .loop ; полностью зациклить! +; + +;[x] +.Restart: DI + XOR A + LD BC,#1FFD + OUT (C),A + LD B,#7F + OUT (C),A + OUT (RGADR),A + OUT (RGMOD),A + OUT (SLOT0),A + LD A,5 + OUT (SLOT1),A + LD A,2 + OUT (SLOT2),A + LD A,DCP_PAGE + OUT (SLOT3),A + JP 0 ;Restart +; + +; +.SoftReset: DI + LD A,#10 + LD BC,#1FFD + OUT (C),A ; 8-я страница !! + ; + LD A,RESET_PAGE + OUT (SLOT3),A + LD A,CNF_PORT.TURBO.OFF + OUT (SYS_PORT.ROM),A +.loop2: LD (#C000),A ; Soft RESET !!! + JR .loop2 +; +;----------------------------------------------------------------------; +; + +; +;----------------------------------------------------------------------; +; не должно портить DE +SET_ROM_FLAG_ZX: + EX AF,AF' + IN A,(SLOT3) + EX AF,AF' + LD A,Spec_Page + OUT (SLOT3),A + XOR A + LD (Spec_Page.flag_Z),A + LD (Spec_Page.flag_X),A + EX AF,AF' + OUT (SLOT3),A + RET +;----------------------------------------------------------------------; +; \ No newline at end of file diff --git a/Crazy BIOS/exp/FUNC_SYS.ASM b/Crazy BIOS/exp/FUNC_SYS.ASM new file mode 100644 index 0000000..048d26c --- /dev/null +++ b/Crazy BIOS/exp/FUNC_SYS.ASM @@ -0,0 +1,554 @@ +;----------------------------------------------------------------------; +; Получение адресов портов и данных для восстановления +; Вход: A - номер окна проецирования +; Выход: B - данные, C - адрес порта окна +EMM.GetBanksPorts: + INC A + LD B,A + DJNZ .slot1 + LD C,SLOT0 + IN B,(C) + RET ;45t +.slot1: DJNZ .slot2 + LD C,SLOT1 + IN B,(C) + RET ;58t +.slot2: DJNZ .slot3 + LD C,SLOT2 + IN B,(C) + RET ;71t +.slot3: DJNZ .error + LD C,SLOT3 + IN B,(C) + RET ;84t +.error: SCF + RET ;74t +;----------------------------------------------------------------------; + +;----------------------------------------------------------------------; +; HL - буфер +; !FIXIT SYS_PAGE.CONFIG_BYTE уже не то показывает, и вообще всю бы переделать, поправить в доке, как минимум +FN_VERSION: + PUSH HL + EX DE,HL + ; LD HL,ID_SPRINTER_FullSize + + ; LD B,0 + ; LD C,(HL) + ; INC HL + LD HL,ID_SPRINTER + LD BC,ID_SPRINTER.Size + LDIR + ; + POP HL + LD DE,(ID_Version) ;rdlow-ok + ; + IN A,(SLOT2) + EX AF,AF' + LD A,SYS_PAGE + OUT (SLOT2),A + LD BC,(SYS_PAGE.CONFIG_BYTE-#4000) ; Version PLD ; !TODO через структуру для переменных биоса + EX AF,AF' + OUT (SLOT2),A + LD A,ID_SPRINTER.Records_Num ; Число полей + AND A + RET +;----------------------------------------------------------------------; + +;----------------------------------------------------------------------; +; [x] 28/01/24 добавлена подфункция выдачи инфы про Acex +FN_CRIPT: + DJNZ .Acex_ver + ; + ; BoardID_start old address #312A + ; BoardID_end old address #312D +.board_id: + LD HL,(BOARD_INFO.number) ;rdlow-ok + LD A,(BOARD_INFO.type) ;rdlow-ok + LD BC,(BoardID.start) ;rdlow-ok + LD DE,(BoardID.end) ;rdlow-ok + AND A + RET + ; +.error: LD A,BIOS.Error.InvalidSubFunction + SCF + RET + ; +.Acex_ver: + DJNZ .error + PUSH HL + LD A,R + DI + PUSH AF + ; + LD HL,-.stackDepth - .readProcedure.size ; memory stack use! + ADD HL,SP + PUSH HL ; адрес программы .readProcedure + LD DE,.readProcedure ; перенести программу на стек + EX DE,HL + LD BC,.readProcedure.size + LDIR ; программа на стеке + LD A,+(12 xor %0000'1000) ; !HARDCODE bitstream page in rom + RET +.return:; + POP AF + JP PO,.no_EI + EI +.no_EI: CALL .choose_chip + POP DE + LD BC,.chip_ID_TXT.RecordSize + LDIR +.cnf+1: LD DE,bitstream_ver_hex + AND A + RET + ; +.choose_chip: + XOR A + LD HL, - ACEX.Chip_ID.K30 + ADC HL,DE + LD HL,.chip_ID_TXT.K30 + RET Z + OR A ; снять CF + INC A + LD HL, - ACEX.Chip_ID.K50 + ADC HL,DE + LD HL,.chip_ID_TXT.K50 + RET Z + POP HL ; баланс стека +.error_unknownChip: + SCF + POP HL + LD A,BIOS.Error.UnknownDevice + RET + ; +; процедура, переносимая на стек для чтения Acex ID +; осторожнее с PUSH, если надо много, то увеличивай .stackDepth +.readProcedure: + OUT (ROM.SLOT0),A ; ROM_PAGE + LD DE,(#100 + 3) ; !HARDCODE здесь читается Acex ID + XOR A + OUT (ROM.SLOT0),A + OUT (SYS_PORT.ROM),A + JP .return +.stackDepth EQU 2 ; расстояние от конца процедуры до вершины стека. +.readProcedure.size EQU $-.readProcedure + ; +.chip_ID_TXT: +.chip_ID_TXT.K30: DZ "K30" +.chip_ID_TXT.RecordSize EQU $-.chip_ID_TXT +.chip_ID_TXT.K50 DZ "K50" +;.chip_ID_TXT.K100 DZ "K100" +.chip_ID_TXT.Size EQU $-.chip_ID_TXT +;----------------------------------------------------------------------; + +;----------------------------------------------------------------------; +;EMM_FN7 +EMM.CheckColdInit: + IN A,(SLOT2) + EX AF,AF' + LD A,SYS_PAGE + OUT (SLOT2),A + + LD HL,SYS_PAGE.ID_FLAG - #4000 + ; LD DE,ID_SPRINTER_FullSize + ; LD A,(DE) + ; DEC A + ; INC DE + ; LD B,A + LD B,ID_SPRINTER.Record1_Size + LD DE,ID_SPRINTER +.loop: LD A,(DE) + CP (HL) + JR NZ,INIT_SYS_ALL + INC HL + INC DE + DJNZ .loop + + ; Disable user IM address in SYS_PAGE + XOR A + LD (SYS_PAGE.INT_ID - #4000),A + ; + + EX AF,AF' + OUT (SLOT2),A + RET + + +;MSDOS_COLD_VARS: +EMM.FullInit: + DI + IN A,(SLOT2) + EX AF,AF' + LD A,SYS_PAGE + OUT (SLOT2),A +INIT_SYS_ALL: + DI + ; LD HL,ID_SPRINTER_FullSize + ; LD DE,SYS_PAGE.ID_FLAG - #4000 + ; LD C,(HL) + ; LD B,0 + ; INC HL + LD HL,ID_SPRINTER + LD DE,SYS_PAGE.ID_FLAG - #4000 + LD BC,ID_SPRINTER.Record1_Size + LDIR + + ; Disable user IM address in SYS_PAGE + XOR A + LD (SYS_PAGE.INT_ID - #4000),A + ; + +;!TODO что за переменные? + LD HL,SYS_PAGE.DISK_TYPE-#4000 + LD (HL),DRIVE_CODES.TRDOS.FDD ; FDD A + INC HL + LD (HL),DRIVE_CODES.TRDOS.FDD + 1 ; FDD B + INC HL + LD (HL),DRIVE_CODES.TRDOS.HDD + INC HL + LD (HL),DRIVE_CODES.TRDOS.HDD + INC HL + LD (HL),0 ; SYS_PAGE.COPY_SLOT0 + INC HL + LD (HL),5 ; SYS_PAGE.COPY_SLOT1 + INC HL + LD (HL),2 ; SYS_PAGE.COPY_SLOT2 + INC HL + LD (HL),0 ; SYS_PAGE.COPY_SLOT3 + + LD A,9 + LD (SYS_PAGE.MSD_SECS-#4000),A + XOR A + LD (SYS_PAGE.DS_1440-#4000),A + + LD HL,SYS_PAGE.RAMD_KEYS-#4000 + LD DE,SYS_PAGE.RAMD_KEYS+1-#4000 + LD BC,SYS_PAGE.RAMD_KEYS.NUM-1 + LD (HL),0 + LDIR + ; [x] 04/11/2023 + LD HL,SYS_PAGE.Sp_RAMD_KEYS-#4000 + LD DE,SYS_PAGE.Sp_RAMD_KEYS+1-#4000 + LD BC,SYS_PAGE.Sp_RAMD_KEYS.NUM-1 + LD (HL),0 + LDIR + ; + LD DE,ZG_ADDRESS ; адрес знакогенератора + LD (SYS_PAGE.WIN_ZG-#4000),DE +; +;-----------[new code start]------------; !!!!! посмотреть-причесать +INIT_VSyncAndWaits: + LD D,CMOS_CELL.ScreenSET + CALL CMOS_RD + ld d,a + jr nc,.cmos_OK +; если нет CMOS, то стандартные настройки + ld a,3 + ld (SYS_PAGE.VSyncAndWaits-#4000),A + jr z,INIT_CONFIG_ALL.setDefaultINT + +.cmos_OK: + and high CMOS_CELL.ScreenSET.Mask.Sinc + and #40 + ld a,3 ; 320 lines & no waits + jr z,.setVSyncAndWaits + dec a ; 312 lines & no waits + +.setVSyncAndWaits: + ld (SYS_PAGE.VSyncAndWaits-#4000),A + +INIT_CONFIG_ALL: + ld a,d + and high CMOS_CELL.ScreenSET.Mask.Int + jr z,.setDefaultINT ; set default int + + xor high CMOS_CELL.ScreenSET.Mask.Int + LD HL,SCREEN_TABLES.ORIGINAL ; set original int + jr z,.setINT + + and #10 + LD HL,SCREEN_TABLES.SCORPION ; set scorpion int + jr z,.setINT + +.setDefaultINT: + LD HL,SCREEN_TABLES.PENTAGON ; set pentagon int +.setINT: + LD (SYS_PAGE.CONFIG_ALL-#4000),HL +;------------[new code end]------------- +; + LD DE,CNF_PORT.CNF_0 + ROM.BIOS + LD (SYS_PAGE.CONFIG_DE-#4000),DE + + LD HL,SYS_PAGE.TASK_DATA-#4000 ; убить все задачи + LD DE,SYS_PAGE.TASK_DATA+1-#4000 + LD BC,#FF + LD (HL),0 + LDIR + + EX AF,AF' + OUT (SLOT2),A + + CALL EMM.InitMem + ;************************************************************** + ; Чтение последних 256 байтов ПЗУ в служебную страницу + ; зачем-то, типа, флешер мог там сохранить данные CMOS. + ;READ_ROM_PAGE_X: + ; IN A,(SLOT3) + ; PUSH AF + ; LD A,SYS_PAGE + ; OUT (SLOT3),A + ; CALL READ_ROM_PAGE_X ; READ CMOS-DATA + ; POP AF + ; OUT (SLOT3),A + ;************************************************************** + RET +;----------------------------------------------------------------------; + +;----------------------------------------------------------------------; +FN_TURBO: + CP 2 + JR Z,.TURBO_SWITCH + CP 3 + JR Z,.TURBO_SWITCH + CP #12 + JR Z,.SET_FDD_720 + CP #13 + JR Z,.SET_FDD_1440 + SCF + RET + +;!FIXIT меняем плотность - меняем в системной странице инфу об этом +.SET_FDD_720: + LD A,FDD_Density.SET_720 + OUT (FDD_Density),A + AND A + RET +;!FIXIT меняем плотность - меняем в системной странице инфу об этом +.SET_FDD_1440: + LD A,FDD_Density.SET_1440 + OUT (FDD_Density),A + AND A + RET + +.TURBO_SWITCH: + LD C,A + IN A,(SLOT3) + LD B,A + LD A,SYS_PAGE + OUT (SLOT3),A + ; + ;LD DE,(SYS_PAGE.CONFIG_DE) + ;LD A,E + LD A,(SYS_PAGE.CONFIG_DE) + ; + AND #FC ; !HARDCODE + OR C + ; + ;LD E,A + ;LD (SYS_PAGE.CONFIG_DE),DE + LD (SYS_PAGE.CONFIG_DE),A + AND 3 + ; + OUT (SYS_PORT.ROM),A + LD A,B + OUT (SLOT3),A + AND A + RET +;----------------------------------------------------------------------; + + +;----------------------------------------------------------------------; +;!TODO +;FN_GET_SYS_VAR: +; Вход: HL - номер системной переменной +; Выход: HL - значение системной переменной +; RET +;----------------------------------------------------------------------; + + +;!TODO скомпоновать +;----------------------------------------------------------------------; +FN_SEND_BYTE: + LD E,A ; сохранить байт + CALL SEND_HALF_BYTE ; передать полубайт из Е + RET C ; возврат по ошибке + LD A,E ; сдвинуть байт на 4 бита + RRCA + RRCA + RRCA + RRCA + LD E,A +SEND_HALF_BYTE: ; передать половину байта _E_!! + LD A,E + OR #F0 ; установить старшие биты LPT дата + OUT (Z84.PIO.Port_A.Data),A + LD BC,0 ; счетчик тайм-аута +WAIT_SENT_1: + IN A,(KEMPSTON.PC_Link) ; проверить бит 4 на 1 при готовности PC + BIT 4,A + JR NZ,CONTINUE_SENT + DEC BC + LD A,B + OR C + JR NZ,WAIT_SENT_1 + XOR A + SCF ; тайм-аут + RET +CONTINUE_SENT: ; PC - готов + LD A,E + AND #0F ; сбросить старшие биты LPT - + OUT (Z84.PIO.Port_A.Data),A + ; счетчик тайм-аута + LD BC,0 + ; +WAIT_SENT_2: + IN A,(KEMPSTON.PC_Link) ; проверить бит 4 на 0 - сообщение от PC + BIT 4,A + JR Z,CONTINUE_SENT2 + DEC BC + LD A,B + OR C + JR NZ,WAIT_SENT_2 + LD A,E + OR #F0 ; установить старшие биты LPT дата + OUT (Z84.PIO.Port_A.Data),A + XOR A + SCF ; тайм-аут + RET +CONTINUE_SENT2: ; полубайт передан + LD A,E + OR #F0 ; установить старшие биты LPT дата + OUT (Z84.PIO.Port_A.Data),A + XOR A + RET +;----------------------------------------------------------------------; + +;----------------------------------------------------------------------; +FN_RESEIVE_B: ; принять байт в A + CALL RESEIVE_POLU_BYTE ; принять полубайт + RET C ; возврат по ошибке + RLCA + RLCA + RLCA + RLCA + AND #F0 + LD E,A + CALL RESEIVE_POLU_BYTE ; второй + RET C + AND 0Fh + OR E + RET ; байт принят +RESEIVE_POLU_BYTE: ; принять половину байта в Е + LD A,#F0 ; установить старшие биты LPT дата + OUT (Z84.PIO.Port_A.Data),A + LD BC,0 ; счетчик тайм-аута +WAIT_RES_1: + IN A,(KEMPSTON.PC_Link) ; проверить бит 4 на 1 при готовности PC + BIT 4,A + JR NZ,CONTINUE_RES + DEC BC + LD A,B + OR C + JR NZ,WAIT_RES_1 + XOR A + SCF ; тайм-аут + RET +CONTINUE_RES: ; PC - готов, ждать 0 + XOR A ; сбросить старшие биты LPT - ждем полубайт + OUT (Z84.PIO.Port_A.Data),A + + LD BC,0 ; счетчик тайм-аута + +WAIT_RES_2: + IN A,(KEMPSTON.PC_Link) ; проверить бит 4 на 0 - сообщение от PC + BIT 4,A + JR Z,CONTINUE_RES2 + DEC BC + LD A,B + OR C + JR NZ,WAIT_RES_2 + LD A,#F0 ; установить старшие биты LPT дата + OUT (Z84.PIO.Port_A.Data),A + SCF + RET ; ошибка +CONTINUE_RES2: ; полубайт выставлен +LOOP_EQ: ; прочитать еще раз, что бы совпало + AND #0F + LD B,A + IN A,(KEMPSTON.PC_Link) + AND #0F + CP B + JR NZ,LOOP_EQ + + OR #F0 ; установить старшие биты LPT дата в 1 - принято + OUT (Z84.PIO.Port_A.Data),A + RET +;----------------------------------------------------------------------; +; + +;----------------------------------------------------------------------; +;********************************** +; START_DI: +; PUSH AF +; LD A,R +; LD A,#80 +; JP PE,XX_DI2 +; XOR A +; XX_DI2: LD R,A +; DI +; POP AF +; RET +; +; END_DI: PUSH AF +; LD A,R +; AND #80 +; JR Z,XX_DI3 +; EI +; POP AF ; PE +; RET +; XX_DI3: DI +; POP AF ; PO +; RET +;********************************** + + +;----------------------------------------------------------------------;????? +;DE - куда - страница открыта! +;BC - сколько +;HL - буфер +; +; PUSH BC +; LD H,D +; LD L,E +; ADD HL,BC +; JR C,CUT +; LD HL,BUFER +; LDIR +; POP BC +; RET +;CUT: +; PUSH HL +; LD A,L +; LD L,C +; LD C,A +; LD A,H +; LD H,B +; LD B,A +; +; AND A +; SBC HL,BC +; LD B,H +; LD C,L +; LD HL,BUFER +; LDIR +; CALL NEXT_BANK +; POP BC +; LD A,B +; OR C +; JR Z,LAB +; LDIR +;LAB: POP BC +; RET +;----------------------------------------------------------------------; +;----------------------------------------------------------------------; + diff --git a/Crazy BIOS/loader/bitstream_header.inc b/Crazy BIOS/loader/bitstream_header.inc new file mode 100644 index 0000000..6093006 --- /dev/null +++ b/Crazy BIOS/loader/bitstream_header.inc @@ -0,0 +1,5 @@ +; Header of bitstream which non packed + DB #FF,#FF,#62,#7B,#39,#00;,#FF,#FF ; 1k30 +; Packed: + ;DB #FF,#FF,#62,#7B,#3C,#00;,#01,#FF ; 1k50 +; \ No newline at end of file diff --git a/Crazy BIOS/loader/loader.asm b/Crazy BIOS/loader/loader.asm new file mode 100644 index 0000000..21158c3 --- /dev/null +++ b/Crazy BIOS/loader/loader.asm @@ -0,0 +1,169 @@ +; +;**********************************; +; ACEX Loading program ; +;**********************************; + MACRO Conf_loader altera_chip +.START: DI + LD BC,#FF*256 + Z84.SYS.Control + XOR A ; Z84.REG.WaitState_Ctrl - register - waits + OUT (C),A ; Z84.SYS.Control + INC C ; LD BC,#FFEF + LD A,4 ; Memory waits set to 1 + OUT (C),A ; Z84.SYS.Data + + DEC C ; Z84.SYS.Control + DEC A ; LD A,3 - 3-nd register - boundaries + OUT (C),A ; Z84.REG.Misc_Ctrl + INC C ; cs0 enable, cs1 enable, 32-Bit CRC disable, reset output enable, Clock Divide-by-two + OUT (C),A ; Z84.SYS.Data + + DEC C ; Z84.SYS.Control + DEC A ; LD A,2 - Z84.REG..CS_Boundary 2-nd register - boundaries + OUT (C),A ; Z84.SYS.Data + INC C + LD A,#FE ; boundaries FFFF..F000 - CS1 + OUT (C),A ; EFFF..0000 - CS0 + + JR .LOOP_S1 +;************************************** + BLOCK #38-$,#FF + JP 0 +;************************************** + +.LOOP_S1: + LD HL,#FEF0 ; !HARDCODE + LD DE,.STRING +.LOOP_S: + LD A,(DE) + CP (HL) + JR NZ,.NO_CNF_RAM + INC E + INC L + JR NZ,.LOOP_S ; !!!!! привязка к адресу в HL + +; !TODO убрать вейты для кэша? + LD BC,#FF*256 + Z84.SYS.Control + LD A,Z84.REG.CS_Boundary + OUT (C),A ; 0 register - waits + INC C + LD A,#F0 + OUT (C),A ; boundaries FFFF..1000 - CS1 +; ; 0FFF..0000 - CS0 + LD HL,#1000 ; !!!!! Load bitstream from Fast-RAM + + JR .NEW_SHM + +;************************************** + BLOCK #66-$,#FF + JP 0 +;************************************** + +.NO_CNF_RAM: + LD HL,#0100 ; !!!!! Load bitstream from ROM +.NEW_SHM: +;--------------[conf check]------------- + LD A,H ; сохраняем старший адрес начала конфы, +; начало конфы должно быть с младшим адресом = 0 + EXX + LD L,0 + LD H,A + EX AF,AF' + + ; в HL адрес первого байта конфы + LD DE,.Conf_header + LD B,.Conf_header.length +.conf_header_loop: + LD A,(DE) + CP (HL) + JR NZ,.Conf_Packed + INC DE + INC L + DJNZ .conf_header_loop + + ;XOR A + JR .exit_conf_check +.Conf_Packed: + SCF +.exit_conf_check: + EX AF,AF' + EXX +;--------------------------------------- + + LD DE,#FE00 ;!HARDCODE ; !!!!! Check flag "don't erase fast-ram bitstream" - "IM" + LD A,(#FEE0) + CP "I" + JR NZ,.ONES_CONFIG + LD A,(#FEE1) + CP "M" + JR NZ,.ONES_CONFIG + + DEC D ; multiple config! + +.ONES_CONFIG: + LD IY,SP2000_Loader_Flag + ;LD IX,#FFFD + LD IX,ACEX.Config_ID.Sp2000 + +.LOOP1: + LD A,(HL) + + ex af,AF' + ld b,1 + jr nc,.no_packed_loop + ex af,AF' + + LD B,A ; save byte to B to check later if we worked with zero + OR A + JR NZ,.LOOP1A + INC HL + LD C,(HL) ; set counter + jr .LOOP1A +.no_packed_loop: + ex af,AF' +.LOOP1A: +;---[Sending bits to Altera]---[v] + DUP 7 + LD (DE),A + RRCA + EDUP + LD (DE),A +;------------------------------[^] + INC E + + LD A,B ; was it zero? + OR A + JR NZ,.LOOP1E +; it was zero so we need to decrement counter + DEC C + JR NZ,.LOOP1A +; end of the counter reached +.LOOP1E: + INC HL + JR .LOOP1 + +.STRING: DB ACEX.RELOAD_STRING + +.Conf_header: include 'src/bios/Loader/bitstream_header.inc' +.Conf_header.length EQU $-.Conf_header + +;----------------------; + BLOCK #FE-$,#FF +; Это, скорее всего, рудимент, тот самый байт описателя конфы, +; который ищет загрузчик для Sp97 по старому адресу #C090. +; Воткнул его в конце загрузчика, может потом пригодится. +.DEF_SYM: DW ACEX.Config_ID.Sp2000 +;------------------------------[Loader end] + + DEFINE Altera_Chip altera_chip + LUA + local file_path = 'Build/ACEX/' + local file_ext = '.BIN' + local altera_ver = sj.get_define("Altera_Chip") + sj.insert_define("Altera_File", '"' .. file_path .. altera_ver .. file_ext .. '"') + ENDLUA + UNDEFINE Altera_Chip + + INCBIN Altera_File + UNDEFINE Altera_File + ENDM +; diff --git a/Crazy BIOS/logo/Projects/LOGO.PAK b/Crazy BIOS/logo/Projects/LOGO.PAK new file mode 100644 index 0000000..22efced Binary files /dev/null and b/Crazy BIOS/logo/Projects/LOGO.PAK differ diff --git a/Crazy BIOS/logo/Projects/LOGO.bmp b/Crazy BIOS/logo/Projects/LOGO.bmp new file mode 100644 index 0000000..67ea48b Binary files /dev/null and b/Crazy BIOS/logo/Projects/LOGO.bmp differ diff --git a/Crazy BIOS/logo/Projects/MAIN.xcf b/Crazy BIOS/logo/Projects/MAIN.xcf new file mode 100644 index 0000000..853b628 Binary files /dev/null and b/Crazy BIOS/logo/Projects/MAIN.xcf differ diff --git a/Crazy BIOS/logo/Projects/NY_Kokoshnik.PAK b/Crazy BIOS/logo/Projects/NY_Kokoshnik.PAK new file mode 100644 index 0000000..589defc Binary files /dev/null and b/Crazy BIOS/logo/Projects/NY_Kokoshnik.PAK differ diff --git a/Crazy BIOS/logo/Projects/NY_Kokoshnik.bmp b/Crazy BIOS/logo/Projects/NY_Kokoshnik.bmp new file mode 100644 index 0000000..0c5589e Binary files /dev/null and b/Crazy BIOS/logo/Projects/NY_Kokoshnik.bmp differ diff --git a/Crazy BIOS/logo/Projects/NY_mustache.PAK b/Crazy BIOS/logo/Projects/NY_mustache.PAK new file mode 100644 index 0000000..a0fee19 Binary files /dev/null and b/Crazy BIOS/logo/Projects/NY_mustache.PAK differ diff --git a/Crazy BIOS/logo/Projects/NY_mustache.bmp b/Crazy BIOS/logo/Projects/NY_mustache.bmp new file mode 100644 index 0000000..e423e27 Binary files /dev/null and b/Crazy BIOS/logo/Projects/NY_mustache.bmp differ diff --git a/Crazy BIOS/logo/Projects/test.png b/Crazy BIOS/logo/Projects/test.png new file mode 100644 index 0000000..d8ae63e Binary files /dev/null and b/Crazy BIOS/logo/Projects/test.png differ diff --git a/Crazy BIOS/logo/Set_Pictures.asm b/Crazy BIOS/logo/Set_Pictures.asm new file mode 100644 index 0000000..da95671 --- /dev/null +++ b/Crazy BIOS/logo/Set_Pictures.asm @@ -0,0 +1,199 @@ +; +;------------[LUA functions]------------; + includelua 'Shared_Includes/LUA/Functions.lua' +;---------------------------------------; + + LUA PASS1 + -- Проверяем BMP, достаём из него параметры, режем на куски + bmp_width, bmp_height, bmp_image_size, bmp_image_offset, bmp_colors = Get_bmp8bit_values (sj.get_define("PICTURE_FILE")) + + if bmp_width ~= 128 then sj.error("Invalid BMP width", bmp_width) end + if bmp_height ~= 72 then sj.error("Invalid BMP height", bmp_height) end + if bmp_colors ~= 256 then sj.error("Invalid BMP number of colors", bmp_colors) end + + if not File_save(sj.get_define("PICTURE_FILE"), "./Build/Bin/LOGO_PAL.BIN", bmp_image_offset-1024, 1024) then sj.error("Palete save error!") end + if not File_save(sj.get_define("PICTURE_FILE"), "./Build/Bin/LOGO_DAT.BIN", bmp_image_offset, bmp_image_size) then sj.error("Image data save error!") end + ENDLUA + + LUA ALLPASS + function make_pic_files (fileName, needPal, needPic) + local fileNameBMP = "'" .. fileName .. ".bmp" .. "'" + local fileNamePAL = fileName .. "_PAL.BIN" + local fileNameDAT = fileName .. "_DAT.BIN" + + local bmp_width, bmp_height, bmp_image_size, bmp_image_offset, bmp_colors = Get_bmp8bit_values (fileNameBMP) + + if needPal == 1 then + if bmp_width ~= 128 then sj.error(fileNameBMP .. "Invalid BMP width", bmp_width) end + if bmp_height ~= 72 then sj.error(fileNameBMP .. "Invalid BMP height", bmp_height) end + if bmp_colors ~= 256 then sj.error(fileNameBMP .. "Invalid BMP number of colors", bmp_colors) end + if not File_save(fileNameBMP, fileNamePAL, bmp_image_offset-1024, 1024) then + sj.error(fileNameBMP .. "Palete save error!") + end + end + if needPic == 1 then + local correctWidth = ((bmp_width*3)%4)+bmp_width + if correctWidth > bmp_width then + File_save(fileNameBMP, fileNameDAT, bmp_image_offset, bmp_image_size, bmp_width, correctWidth-bmp_width) + else + File_save(fileNameBMP, fileNameDAT, bmp_image_offset, bmp_image_size) + end + end + + print("Resolution: " .. bmp_width .. "x" .. bmp_height, fileNameDAT) + end + ENDLUA + + MODULE MAIN_LOGO +Pallete: + INCBIN 'Build/Bin/LOGO_PAL.BIN' +.length EQU $-Pallete +Raster: + INCBIN 'Build/Bin/LOGO_DAT.BIN' +.length EQU $-Raster + + IF Pashalki +; !TODO сделать тут табличку-ссылки на нужную таблицу спрайтов и завязать это на даты + + + MACRO _PASHALKI_CODE + IN A,(SLOT3) + EX AF,AF' + LD A,SYS_PAGE + OUT (SLOT3),A + + ld e,(RebootDate.month) + SLA e + xor a + ld + + EX AF,AF' + OUT (SLOT3),A + + + ENDM + +months_table: + WORD days_table.January + WORD days_table.February + WORD days_table.March + WORD days_table.April + WORD days_table.May + WORD days_table.June + WORD days_table.July + WORD days_table.August + WORD days_table.September + WORD days_table.October + WORD days_table.November + WORD days_table.December + +days_table: +.January: DZ 1,2,3,4,5,6,7 +.February EQU 0 +.March EQU 0 +.April EQU 0 +.May EQU 0 +.June EQU 0 +.July EQU 0 +.August EQU 0 +.September EQU 0 +.October EQU 0 +.November EQU 0 +.December: DZ 31 + +NewYear: INCLUDE './src/bios/logo/use/New_Year.inc' +;.March8: INCLUDE './src/bios/logo/use/March_8.inc' + + ENDIF + +/* + + and a + ld b,0 + ld hl,months_table + ld de,months_table+1 + ld a,month + call FIND_NEXT + + ld hl,days_table + adc hl,de + ld ix,hl + ld e,(hl) + inc hl + ld d,(hl) + ex de,hl + ld de,days_table+1 + ld a,day + call FIND_NEXT + + ld hl,sprites_table + adc hl,de + + call Sprites ; в hl адрес в таблице адресов таблиц спрайтов (SP_Table) + + +FIND_NEXT: + ld c,(hl) ; берём длину таблицы BYTE + inc hl + CPIR + jr nz,.nothing + sbc hl,de + sla l + ex de,hl + ret + +days_table: + WORD december_days_table + WORD january_days_table + WORD march_days_table + WORD december_days_table +;----------------[Months table]----------------[v] +months_table: + BYTE months_table.length-1 +.months: + BYTE 01 ; Январь + BYTE 03 ; Март + BYTE 12 ; Декабрь +.length equ $-months_table + + ASSERT months_table.length < 14, ERROR!!! "months_table" should be less than 14 bytes! +;----------------------------------------------[^] + +;-------------[December days table]------------[v] +december_days_table: + BYTE december_days_table.length-1 +.months: + BYTE 31 ; Новый год +.length equ $-december_days_table + + ASSERT december_days_table.length < 33, ERROR!!! "december_days_table" should be less than 33 bytes! +;----------------------------------------------[^] + +;-------------[January days table]-------------[v] +january_days_table: + BYTE january_days_table.length-1 +.months: + BYTE 01 ; Новый год + BYTE 02 ; Новый год + BYTE 03 ; Новый год + BYTE 04 ; Новый год + BYTE 05 ; Новый год + BYTE 06 ; Новый год + BYTE 07 ; Рождество +.length equ $-january_days_table + + ASSERT january_days_table.length < 33, ERROR!!! "january_days_table" should be less than 33 bytes! +;----------------------------------------------[^] + +;-------------[March days table]------------[v] +march_days_table: + BYTE december_days_table.length-1 +.months: + BYTE 08 ; Клара Цеткин и Роза Люксембург +.length equ $-december_days_table + + ASSERT december_days_table.length < 33, ERROR!!! "december_days_table" should be less than 33 bytes! +;----------------------------------------------[^] +*/ + + ENDMODULE diff --git a/Crazy BIOS/logo/clean.cmd b/Crazy BIOS/logo/clean.cmd new file mode 100644 index 0000000..ca561e9 --- /dev/null +++ b/Crazy BIOS/logo/clean.cmd @@ -0,0 +1,4 @@ +@echo off +del *.bin /s +del *.lst /s +del *.log /s diff --git a/Crazy BIOS/logo/compile.log b/Crazy BIOS/logo/compile.log new file mode 100644 index 0000000..4514673 --- /dev/null +++ b/Crazy BIOS/logo/compile.log @@ -0,0 +1,4 @@ +Extractor BMP-files for Sprinter BIOS logo +Copyright (c) 2022 Sprinter Team +File [psfathers.bmp], found 8 bit BMP 128x72, output RGB4 [LOGO_PAL.BIN] and [LOGO_DAT.BIN] +Done. diff --git a/Crazy BIOS/logo/make.cmd b/Crazy BIOS/logo/make.cmd new file mode 100644 index 0000000..9ca40da --- /dev/null +++ b/Crazy BIOS/logo/make.cmd @@ -0,0 +1,23 @@ +rem @echo off +set BIN=..\..\bin +set LOG=compile.log +for /F %%i in ('date /t') do set mydate=%%i +for /F %%i in ('time /t') do set mytime=%%i +set mydt=%mydate% %mytime% + +rem set LOGO_FILE=peters.bmp +set LOGO_FILE=psfathers.bmp + +echo 5. [1/1] BMP LOGO +echo %mydt%: [1/1] BMP LOGO > %LOG% +%BIN%\bmp_extract.exe %LOGO_FILE% /pn LOGO_PAL.BIN /dn LOGO_DAT.BIN /pt 4 >> %LOG% +if errorlevel 1 goto error + +goto quit + +:error +echo ERROR during compile BMP LOGO +pause 0 +exit 3 + +:quit diff --git a/Crazy BIOS/logo/peters.bmp b/Crazy BIOS/logo/peters.bmp new file mode 100644 index 0000000..e8bb78b Binary files /dev/null and b/Crazy BIOS/logo/peters.bmp differ diff --git a/Crazy BIOS/logo/pfathers.bmp b/Crazy BIOS/logo/pfathers.bmp new file mode 100644 index 0000000..5054b67 Binary files /dev/null and b/Crazy BIOS/logo/pfathers.bmp differ diff --git a/Crazy BIOS/logo/psclean.bmp b/Crazy BIOS/logo/psclean.bmp new file mode 100644 index 0000000..abe742f Binary files /dev/null and b/Crazy BIOS/logo/psclean.bmp differ diff --git a/Crazy BIOS/logo/psfathers.bmp b/Crazy BIOS/logo/psfathers.bmp new file mode 100644 index 0000000..3ceffb5 Binary files /dev/null and b/Crazy BIOS/logo/psfathers.bmp differ diff --git a/Crazy BIOS/logo/use/LOGO.bmp b/Crazy BIOS/logo/use/LOGO.bmp new file mode 100644 index 0000000..67ea48b Binary files /dev/null and b/Crazy BIOS/logo/use/LOGO.bmp differ diff --git a/Crazy BIOS/logo/use/NY_Kokoshnik.bmp b/Crazy BIOS/logo/use/NY_Kokoshnik.bmp new file mode 100644 index 0000000..0c5589e Binary files /dev/null and b/Crazy BIOS/logo/use/NY_Kokoshnik.bmp differ diff --git a/Crazy BIOS/logo/use/NY_Kokoshnik_DAT.BIN b/Crazy BIOS/logo/use/NY_Kokoshnik_DAT.BIN new file mode 100644 index 0000000..061d443 --- /dev/null +++ b/Crazy BIOS/logo/use/NY_Kokoshnik_DAT.BIN @@ -0,0 +1 @@ +        Ё                              Ё                ё ЁЁ                        ЁЁ Ё                ф                              ф                   ф                        ф                   ф                           ё  ф                   ф                        ф                   ф  ё                        ё  ф                ю  ф                        ф  ю                х фю                        юф х               ┴вв╬ф                        ф╬би┴             и└и╬nф                        х\╬и╬и          ╬Ы╬Ыsи╡ф                        фз╡sЩ╠в╬       ┴┴║ns3бф└                        ╞фи3sd║┴╬     ╬╡║3~\T╠┌и                        и┌╠Ti~3╡╗╬    Ыо▒y▒▒╬╫з                        ╡╫╬б╚yбТбв   ╡╞KiбndИ║╫в                        в╫иЩddТЖ@└╗ ┴иСK╨└Щ~n╬╠в╗                      ╬в╠┴~С└╫Ty╗┴и╬@┌yб╨sви╞вв                      ║Щ╞ви~╠бn┌K╬╡Ы╬7╫y╒Ж~\└╣з╬                     ЫС╞╗q~yх~╫7╬Ы╡┴С└└~Щ\\╬║~в                    ЩЩ~║┴nTИИ┴╠И┴│ ╬T╠ЙsK3╬║\ЩЫЫ                  вЫИn╣╬3Ks╫K╠И   и╬Ии╠ЩnС╔╡sЩyС                ЫiС~о┴ТnЩ└║╬и    ╬Що@┌ю╬~╫└y~nЩ\и            ╡dЙС~y║╫~└ю┌Kвв╬    ╗╠\С║Kи╡И╬║y~yЩn\Щ╡┴╬  ╬┴╡ЫTKЫЩ~Й║╠Ии║@обT╞┴    б└7фy╡┌С~С╬└Ыss~СЩСССИЙСИЩСЩЩ~sЫ║╬Ы~╨╡Иф@║и    ╗║3╠з╠┌Щ~▒╒└╬оСnssn\TTTTnnyssС╡╔┴╕╒~~╨╨з╠3о┴    ╗╬\И╠в~3\ysnв║╬╡овidTsnddiво╡╬║иssy\3~Ы╨СK╬╗     ╡└yK╠╠СЫ╠ЩsnЙ║╬║╫╣╞оо╞║╫║╬║СdsЖ╠ЫЙ╠╠Tq║╣       Ы╞└║Tи┌о\╡╫~nхебi╡з╔╔ииqТ╕╒Ж~╫║\офиT╣└╬Ы          иС║Ы└3~з┌ds╚╚dИ╣╒╒╔Иdi┬╒n\┌зИ7║и║Ыи             ╡иy╠7╣х┌nsТ~┴╠╣╨┌╣└╬~yЫyT┌ъ╣@└в╗              и╬T┌СsзЩ737И┌Ы@\ЩЩ\@Ы┌С733~зИЖ┌\╬и               ║╡@╬└СвС╞╞хЫ~╣╣T@з┴ЩСх╠╠СбС└╫@и┴                ╬в└в@иСи│i╠3з╚ю~sххз3╠sб│Си@в║и╬                  иС┴└║б┬└Ы3KИЩ┌┌ЩИd3С╬▒││╞║Ыи                      ╗из╬3@╫y77в║ио73y┌K7╬ии│                           │╬\│╫╠└└└└╠╫║ИK╠╗                               и╬n333╬иб╬373\└╡                                 Ы╬yТ╒╬╕╒╫▒╕n╬Ы                                   ╗╗║╬└└╠╡╗┴                                      ┴╗└┴┴║╗┴                                          ╗вв╗                       \ No newline at end of file diff --git a/Crazy BIOS/logo/use/NY_mustache.bmp b/Crazy BIOS/logo/use/NY_mustache.bmp new file mode 100644 index 0000000..189fcbd Binary files /dev/null and b/Crazy BIOS/logo/use/NY_mustache.bmp differ diff --git a/Crazy BIOS/logo/use/NY_mustache_DAT.BIN b/Crazy BIOS/logo/use/NY_mustache_DAT.BIN new file mode 100644 index 0000000..35eb991 --- /dev/null +++ b/Crazy BIOS/logo/use/NY_mustache_DAT.BIN @@ -0,0 +1 @@ +            ■■■■■¤√■■■■■■■■■■∙ъ┘┼       ┘∙■      ■■■■■■■■■■■■■■■■■■■■√ъ┘    ъ■■■ўёъъъў■■■■■■■■■■■■■√ёёёЁў√ ■ў┼  ┘■ё┘┼■■■■■■┼┘ў■■√ъў■■√ъ┘■■■■■■■┘ъ■ё ┘ў┘■■■      ■■■┼┼■■■╖┼■■■       ■■┼∙┘ж┼■            ■■   ■■            ■┼┼ \ No newline at end of file diff --git a/Crazy BIOS/logo/use/New_Year.inc b/Crazy BIOS/logo/use/New_Year.inc new file mode 100644 index 0000000..5489409 --- /dev/null +++ b/Crazy BIOS/logo/use/New_Year.inc @@ -0,0 +1,16 @@ + MODULE _mNewYear + + LUA PASS1 + make_pic_files ("./src/bios/logo/use/NY_Kokoshnik", 0, 1) + make_pic_files ("./src/bios/logo/use/NY_mustache", 0, 1) + print() + ENDLUA + + BYTE 2 ; количество спрайтов + EasterTable 48, 42, 13, 2, sprite1 + EasterTable 37, 6, 69, 26, sprite2 +sprite1: INCBIN './src/bios/logo/use/NY_Kokoshnik_DAT.bin' +sprite2: INCBIN './src/bios/logo/use/NY_mustache_DAT.bin' + + ENDMODULE +; \ No newline at end of file diff --git a/Crazy BIOS/mem_map.txt b/Crazy BIOS/mem_map.txt new file mode 100644 index 0000000..7ac2697 --- /dev/null +++ b/Crazy BIOS/mem_map.txt @@ -0,0 +1,16 @@ +#10 - EXTENSION +#11 - LOGO #2800 bytes +#12 - sp_128 +#13 - sp_48 +#14 - sp_trd +#15 - ROM Disk Recovery +#16 - ROM Disk Recovery +#17 - ROM Disk Recovery +#18 - BIOS +#19 - ROM Disk Recovery +#1A - ROM Disk Recovery +#1B - ROM Disk Recovery +#1C - Loader #100 bytes, bitstream #3F00 bytes +#1D - Bitstream #4000 bytes +#1E - Bitstream #4000 bytes +#1F - Bitstream #4000 bytes \ No newline at end of file diff --git a/Crazy BIOS/rom/BIOS.inc b/Crazy BIOS/rom/BIOS.inc new file mode 100644 index 0000000..8db15b7 --- /dev/null +++ b/Crazy BIOS/rom/BIOS.inc @@ -0,0 +1,5 @@ +;WITH_BUILD EQU 1 ;BIOS NUMBER INCLUDED BUILD NUMBER +TEST_Build EQU 0 +Logo_X_size EQU 128 +Logo_Y_size EQU 72 +;WITH_2IDE EQU 1 ;SECONDARY IDE diff --git a/Crazy BIOS/rom/MEM_MAP.inc b/Crazy BIOS/rom/MEM_MAP.inc new file mode 100644 index 0000000..1852c02 --- /dev/null +++ b/Crazy BIOS/rom/MEM_MAP.inc @@ -0,0 +1,71 @@ +; +; ██████╗ ██████╗ ███╗ ███╗ ███╗ ███╗ █████╗ ██████╗ +; ██╔══██╗██╔═══██╗████╗ ████║ ████╗ ████║██╔══██╗██╔══██╗ +; ██████╔╝██║ ██║██╔████╔██║ ██╔████╔██║███████║██████╔╝ +; ██╔══██╗██║ ██║██║╚██╔╝██║ ██║╚██╔╝██║██╔══██║██╔═══╝ +; ██║ ██║╚██████╔╝██║ ╚═╝ ██║ ██║ ╚═╝ ██║██║ ██║██║ +; ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ +; +ROM_MAP: +.EXP EQU 0 +.ROM EQU 0 +.LOADER EQU 0 +.LOGO EQU 0 + IF PACKED_MAIN +.SETUP EQU #1000 + ELSE +.SETUP EQU BLOCK_Setup + ENDIF +; + +; +; ███╗ ███╗███████╗███╗ ███╗ ███╗ ███╗ █████╗ ██████╗ +; ████╗ ████║██╔════╝████╗ ████║ ████╗ ████║██╔══██╗██╔══██╗ +; ██╔████╔██║█████╗ ██╔████╔██║ ██╔████╔██║███████║██████╔╝ +; ██║╚██╔╝██║██╔══╝ ██║╚██╔╝██║ ██║╚██╔╝██║██╔══██║██╔═══╝ +; ██║ ╚═╝ ██║███████╗██║ ╚═╝ ██║ ██║ ╚═╝ ██║██║ ██║██║ +; ╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ +; +MEM_MAP: +.SETUP EQU COMPILE_ADDR.SETUP +;.ID_Version EQU COMPILE_ADDR.EXP + #C0 +; +; ██████╗ ██████╗ ██████╗ ███████╗ +; ██╔═══██╗██╔══██╗██╔════╝ ██╔════╝ +; ██║ ██║██████╔╝██║ ███╗███████╗ +; ██║ ██║██╔══██╗██║ ██║╚════██║ +; ╚██████╔╝██║ ██║╚██████╔╝███████║ +; ╚═════╝ ╚═╝ ╚═╝ ╚═════╝ ╚══════╝ +; +COMPILE_ADDR: +.EXP EQU 0 +.ROM EQU 0 +.LOADER EQU 0 +.MAIN EQU #8000 +.SETUP EQU #8000 +.DEPACK EQU #D000 +.SETUP_STARTER EQU #C000 +; +; ██████╗ ███████╗██████╗ █████╗ ██████╗██╗ ██╗███████╗██████╗ +; ██╔══██╗██╔════╝██╔══██╗██╔══██╗██╔════╝██║ ██╔╝██╔════╝██╔══██╗ +; ██║ ██║█████╗ ██████╔╝███████║██║ █████╔╝ █████╗ ██████╔╝ +; ██║ ██║██╔══╝ ██╔═══╝ ██╔══██║██║ ██╔═██╗ ██╔══╝ ██╔══██╗ +; ██████╔╝███████╗██║ ██║ ██║╚██████╗██║ ██╗███████╗██║ ██║ +; ╚═════╝ ╚══════╝╚═╝ ╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝ +; + IF PACKED_MAIN + + IFNDEF PREBUILD ; неизвестные метки при прекомпиляции MAIN.BIN +DEPACKER: +.Addr EQU SETUP_MAIN.Depacker +.WorkAddr EQU COMPILE_ADDR.DEPACK +.PackedMAIN EQU UnPacker.PackedMAIN +.UnpackAddr EQU COMPILE_ADDR.MAIN +.CodeLength EQU UnPacker.Length +.UnpackedEXECaddr EQU MAIN_START +.Length EQU DEPACK_DATA.length +;Depacker_start EQU #D000 +;Depacked_logo_start EQU #D900 + ENDIF + + ENDIF diff --git a/Crazy BIOS/rom/ROM.asm b/Crazy BIOS/rom/ROM.asm new file mode 100644 index 0000000..e1dc925 --- /dev/null +++ b/Crazy BIOS/rom/ROM.asm @@ -0,0 +1,427 @@ +; +; MODULE ROM_PART +;------------[Begin of ROM]------------- +ROM_START: + DI + HALT +;--------------------------------------- + +;--------------[checksum]--------------- + BLOCK 4-$,#FF +Check_Sum: + DB #FF,#FF,#FF,#FF ; место для контрольной суммы +;--------------------------------------- + BLOCK #10-$,#FF + RET +;--------------------------------------- + +;!TODO прикрутить к ROM.BIOS +;----------------[int]------------------ + BLOCK #38-$,#FF +; INT: PUSH BC +; PUSH AF + +; LD C,SLOT3 +; IN B,(C) +; LD A,SYS_PAGE +; OUT (C),A + +; LD A,(SYS_PAGE.INT_ID) +; CP #AA +; JR Z,YESINT +; OUT (C),B +; JR NOINT +; YESINT: PUSH HL +; LD HL,(SYS_PAGE.INT_ADRESS) +; LD A,H +; OR L +; LD A,(SYS_PAGE.INT_PAGE) +; OUT (C),B +; CALL NZ,EXTINT +; POP HL +; NOINT: POP AF +; POP BC + EI + RETI +;--------------------------------------- + +;----------------[NMI]------------------ + _mInfoBLOCK #66-$,#FF +NMI: RETN +;--------------------------------------- + +; ;----------------[int]------------------ +; EXTINT: OR A +; RET Z + +; ;LD C,SLOT1 +; BIT 7,H +; JR Z,.L2 +; LD C,SLOT2 +; BIT 6,H +; JR Z,.L1 +; LD C,SLOT3 + +; .L1: IN B,(C) +; PUSH BC +; OUT (C),A +; CALL .JPHL +; POP BC +; OUT (C),B +; RET +; ; проверка на нулевой слот +; .L2: BIT 6,H +; LD C,SLOT1 +; JR NZ,.L1 ; продолжаем если ненулевой слот +; ; ВОТ ТУТ МОЖНО ВЛУПИТЬ ПРОЦЕДУРУ ДЛЯ ПОДСТАНОВКИ СТРАНИЦЫ В SLOT0 И +; ; ПЕРЕХОД ПО ПРЕРЫВАНИЮ В ОБРАБОТЧИК ПОЛЬЗОВАТЕЛЯ ЧЕРЕЗ процедуру на стэк, например + + +; IF TEST_INT +; LD HL,-.stackDepth - .switchProcedure.size + .patch+2 +; ADD HL,SP +; PUSH HL + +; LD HL,-.stackDepth - .switchProcedure.size ; memory stack use! +; ADD HL,SP ; stack +; PUSH HL ; адрес программы .readProcedure + +; LD DE,.switchProcedure ; перенести программу на стек +; EX DE,HL +; LD BC,.switchProcedure.size +; LDIR +; RET + +; ; процедура, переносимая на стек для вызова прерывания пользователя из SLOT0 +; ; осторожнее с PUSH, если надо много, то увеличивай .stackDepth +; .switchProcedure: +; DEC DE +; POP HL +; LD (HL),E +; INC HL +; LD (HL),D + + +; LD C,SLOT0 +; IN B,(C) +; PUSH BC +; OUT (C),A + +; XOR A +; OUT (SYS_PORT.RAM),A +; .patch EQU $+1-.switchProcedure +; CALL .JPHL + +; DI + +; XOR A +; OUT (SYS_PORT.ROM),A + +; POP BC +; OUT (C),B + +; RET +; .JPHL: JP (HL) +; .stackDepth EQU 32 ; расстояние от конца процедуры до вершины стека. +; .switchProcedure.size EQU $-.switchProcedure +; ELSE + +; SCF +; RET +; .JPHL: JP (HL) +; ENDIF +;--------------------------------------- + +/* + + + +*/ + +; +; _ZX_ _ZX_ _ZX_ _ZX_ _ZX_ [___FOR ZX-MODE___] _ZX_ _ZX_ _ZX_ _ZX_ _ZX_ ; + +; +;----------------------------[ FOR ZX-MODE ]----------------------------; +;!HARDCODE на этот адрес #С0 прыгает в vROM Basic-48 по адресу #3CF0 +; можно попробовать переделать этот адрес там + _mInfoBLOCK #C0-$,#FF ;!TEST 0 + INCLUDE 'ZX/ZX_FUNC.ASM' + INCLUDE 'ZX/ZX_MENU.ASM' +;-----------------------------------------------------------------------; +; _ZX_ _ZX_ _ZX_ _ZX_ _ZX_ _ZX_ _ZX_ _ZX_ _ZX_ _ZX_ _ZX_ _ZX_ _ZX_ _ZX_ ; +; + + + + +;-------------[#1000 SETUP]------------- + ShowInfo 'Setup block of ROM start', 0 ; !!!!! test + +BLOCK_Setup EQU $ +; + IF PACKED_MAIN + BLOCK ROM_MAP.SETUP-$,#FF + + DISP COMPILE_ADDR.SETUP + +; Depacker version +SETUP_MAIN: + LD HL,DEPACKER.UnpackedEXECaddr; точка входа в распакованном коде + PUSH HL + LD DE,DEPACKER.WorkAddr ; адрес процедуры депакера + PUSH DE + + LD HL,DEPACKER.Addr + LD BC,DEPACKER.Length + LDIR + + LD HL,DEPACKER.PackedMAIN ; где архив + LD DE,DEPACKER.UnpackAddr ; куда распаковывать + RET + +.Depacker EQU $ + ENT + +;-----------------[v] +DEPACK_DATA: + DISP DEPACKER.WorkAddr + MODULE UnPacker + INCLUDE 'src/bios/ROM/SETUP/DEHRUST.asm' ; !TODO сделать на LUA автовыбор декомпрессора и компрессора +PackedMAIN: INCBIN 'Build/Bin/temp/MAIN.PAK' + ENDMODULE + ENT +DEPACK_DATA.length EQU $-DEPACK_DATA +;-----------------[^] + + + ELSE + DISP COMPILE_ADDR.SETUP + ShowInfo 'Setup block DISP start', 1 ; !!!!! test +SETUP_MAIN: INCLUDE 'src/bios/ROM/SETUP/Main.asm' + ShowInfo 'Setup block DISP end', 1 ; !!!!! test + ENT + ENDIF + + + ShowInfo 'Setup block of ROM end', 0 ; !!!!! test +BLOCK_Setup.Length EQU $-BLOCK_Setup +;--------------------------------------- +; + + + + + +; +; !FIXIT сделать эти фиксированные адреса отдельным файлом и с IF/ELSE и подключать их потом куда надо. +;----------------------------------------------------------------------; +; BLOCK #3CC0-$,255 + ; no-magics! +;MAGIC_1: ; ЗАГЛУШКА ДЛЯ MAGIC +; PUSH AF +; LD A,ROM.EXT +; OUT (SYS_PORT.OFF),A +; POP AF +; JP MAGIC_1 +;MAGIC_3: +; PUSH AF +; LD A,ROM.EXT +; OUT (SYS_PORT.OFF),A +; POP AF +; RETN +;MAGIC_2: +;; CALL MG_BEGIN +; JR MAGIC_3 + +;************************* + _mInfoBLOCK #3CE0-$,#FF ;!TEST 0 +;SW_ROM_1: + LD HL,#259F ;!HARDCODE Show Main Menu in BASIC-128 + PUSH HL + LD HL,#5B00 ;!HARDCODE + LD A,(HL) + CP #F5 ; #F5 - опкод 'PUSH AF'. Проверяется в #5B00 + JR Z,JP_HL_48 ; ВОЗВРАТ К МЕНЮ BASIC128 + POP HL + JR SW_ROM ; ПРОСТОЙ ВОЗВРАТ +;************************* + + _mInfoBLOCK #3CF0-$,#FF ;!TEST 0 +;JMP_48: +; LD HL,00h +; JR JP_HL_48 +; +; NOP +; NOP +; NOP + +;*************************************** + _mInfoBLOCK #3CF8-$,#FF ;!TEST 0 + ; no basic-48! +;P_HL_48: + PUSH HL +;SW_ROM: + PUSH AF + LD A,ROM.BIOS + OUT (SYS_PORT.RAM),A + POP AF + RET +;*************************************** +;----------------------------------------------------------------------; +; + +;!TODO спектрумовские утилиты +;----------------------------------------------------------------------; + ; _mInfoBLOCK #3CFA-$,#FF + ; LD A,0 ;!HARDCODE + ; OUT (SYS_PORT.OFF),A + ; POP AF +;----------------------------------------------------------------------; +; + + +; +;----------------------------------------------------------------------; + _mInfoBLOCK #3D00-$,#FF +;DOS_ON: + NOP + RET +;*************************************** + +;*************************************** +; BLOCK #3D02-$,FF +; !TODO можно оприходовать тут 17 байтов +; +;*************************************** + +;*************************************** + _mInfoBLOCK #3D13-$,#FF + NOP + CALL ToBIOS_FromEXT + JP DOS_OFF +;*************************************** + +;*************************************** +; BLOCK #3D17-$,FF +; !TODO можно оприходовать тут 233 байта +; +;*************************************** + +;*************************************** + _mInfoBLOCK #3E00-$,#FF +;DOS_OFF: + PUSH AF + LD A,R + DI + PUSH AF + PUSH BC + ; + LD BC,(#5BFF) ; !HARDCODE + LD A,#C9 ; Opcode RET + LD (#5BFF),A ; !HARDCODE + CALL #5BFF ; !HARDCODE + LD (#5BFF),BC ; !HARDCODE + ; + POP BC + POP AF + JP PO,.no_EI + EI +.no_EI: POP AF + RET +;*************************************** + + +;*************************************** +; BLOCK #3E16-$,FF +; !TODO можно оприходовать тут 10 байтов +; +;*************************************** +; + + + +; +;--------------------------------------- +; _mInfoBLOCK #3FC6-$,#FF +;!FIXIT переделать ПЗУ трдоса и спектрумов под правильный вызов функций биоса (а не вместо функций 4x функции 0x) +; или можно добавить функции +; TRDOS_HD_CMD: +; ; LD A,C +; ; OR #40 +; ; LD C,A +; POP AF +; SET 6,C +; RST_to_BIOS +; JR RET_TO_TRDOS +;--------------------------------------- +; +;--------------[GOTO BIOS]-------------- +; call BIOS from EXTENSION + _mInfoBLOCK #3FD0-$,#FF ; ToBIOS_FromEXT + PUSH AF + LD A,ROM.BIOS ; set BIOS to slot0 + OUT (SYS_PORT.ROM),A + POP AF + RET +;--------------------------------------- + + +;!FIXIT переделать ПЗУ трдоса и спектрумов под правильный вызов функций биоса (а не вместо функций 4x функции 0x) +;--------[ From TR-DOS to HDD part2]-------- + _mInfoBLOCK #3FD8-$,#FF +TRDOS_HD_CMD: + POP AF + SET 6,C + RST_to_BIOS + JR RET_TO_TRDOS +;--------------------------------------- + + +;!FIXIT остатки от тестов Ивана со звуковой картой +;-------------[SND_TEST_RET]------------- + _mInfoBLOCK #3FE0-$,#FF +; SND_TEST_RET: +; LD A,ROM.BIOS +; OUT (SYS_PORT.RAM),A +; ;JP SOUND_TEST +; JP #0000 +;--------------------------------------- + + +;------------[HDD_5x portal]------------ +; точка входа/выхода для функций 5х из BIOS + _mInfoBLOCK #3FE8-$,#FF +;RET_TO_EXP: + ; PUSH AF + ; LD A,ROM.BIOS + ; OUT (SYS_PORT.ROM),A + ; JP HDD_FN_5x +;--------------------------------------- + + +;!FIXIT Можно поправить номера функций при вызовах из TR-DOS и прыгать сразу в BIOS +;-------[ From TR-DOS to API 4x ]------- + _mInfoBLOCK #3FF0-$,#FF +RET_TO_TRDOS: + PUSH AF + DI + LD A,ROM.BIOS + OUT (SYS_PORT.RAM),A + JR TRDOS_HD_CMD ; тут не хватило места в 1 байт, чтоб сразу сделать JP +;--------------------------------------- + + + +;-----[???????????????????????????]----- + _mInfoBLOCK #3FF8-$,#FF + ; PUSH AF + ; LD A,ROM.BIOS + ; OUT (SYS_PORT.RAM),A + ; JP #0000 +;--------------------------------------- + _mInfoBLOCK #4000-$,#FF +;======================================= + +; ENDMODULE ;ROM_PART +; \ No newline at end of file diff --git a/Crazy BIOS/rom/SETUP/AUTOIDE.asm b/Crazy BIOS/rom/SETUP/AUTOIDE.asm new file mode 100644 index 0000000..fe4131a --- /dev/null +++ b/Crazy BIOS/rom/SETUP/AUTOIDE.asm @@ -0,0 +1,916 @@ +;[BEGIN] +;//MODULE: AUTOIDE +;//CREATE: 27-07-2001 AUTHOR: Denis Parinov +;----------------------------------------------------------------------- +;Rev Date Name Description +;----------------------------------------------------------------------- +;R02 17.08.2023 BAO New AUTODETECT ATA/ATAPI procedure +;R01 01.08.2001 DNS FIX BUG INT "SELECT_IDE" +;R00 24.07.2001 DNS ADD SECONDARY IDE +; 24.07.2001 DNS INITIAL NEW VERSION 2.48 +;======================================================================= + +; MODULE AUTOIDE +/* +;Write +HDW_3F7 EQU #4155 ;3F7H Command +HDW_3F6 EQU #4154 ;3F6H Device Control +;Read +HDR_3F7 EQU #4055 ;3F7H Drive Address +HDR_3F6 EQU #4054 ;3F6H Alt. Status + +;Write +IDE.Write.Command EQU #4153 ; #1F7 Command +HDW_DRV EQU #4152 ; #1F6 Drive Control + +HDW_CLH EQU #0155 ; #1F5 Cylinder High +HDW_CLL EQU #0154 ; #1F4 Cylinder Low +HDW_SEC EQU #0153 ; #1F3 Sector +HDW_CNT EQU #0152 ; #1F2 Counter +HDW_ERR EQU #0151 ; #1F1 Error +HDW_DAT EQU #0150 ; #1F0 Data + +;Read +HDR_CTL EQU #4053 ; #1F7 Status (Control) +HDR_DRV EQU #4052 ; #1F6 Drive Control + +HDR_CLH EQU #0055 ; #1F5 Cylinder High +HDR_CLL EQU #0054 ; #1F4 Cylinder Low +HDR_SEC EQU #0053 ; #1F3 Sector +HDR_CNT EQU #0052 ; #1F2 Counter +HDR_ERR EQU #0051 ; #1F1 Error +HDR_DAT EQU #0050 ; #1F0 Data + +;Bits for HDR_CTL +;---[] +BSY EQU 7 +RDY EQU 6 +DRQ EQU 3 +ERR EQU 0 +;---[] + +HDD EQU 1 +CDROM EQU 2 + + +;EQU FOR IY+ +;---[] +DRVHD_H EQU 0 +SC_PT_H EQU 1 +IDE.HDD_INIT_TABLE.HeadsNumber EQU 2 +CYL_L_H EQU 3 +CYL_H_H EQU 4 +SPCLL_H EQU 5 +SPCLH_H EQU 6 +DTYPE_H EQU 7 +;---[] +;-------[ ;!!!!! hardcoded table]------- +IDE0 EQU #C1C0 +IDE1 EQU #C1C8 +IDE2 EQU #C1D0 +IDE3 EQU #C1D8 +;--------------------------------------- +*/ + +;IDE0 DB #FF ;DRIVE/HEAD REGISTER ;00 +; DB #FF ;SECTORS PER TRACK ;01 +; DB #FF ;HEADS ;02 +; DB #FF ;CYLINDERS LOW ;03 +; DB #FF ;CYLINDERS HIGH ;04 +; DB #FF ;SECTOR PER CYLINDER LOW ;05 +; DB #FF ;SECTOR PER CYLINDER HIGH ;06 +; DB #FF ;DEVICE TYPE ;07 + +;IDE1 DB #FF ;DRIVE/HEAD REGISTER ;00 +; DB #FF ;SECTORS PER TRACK ;01 +; DB #FF ;HEADS ;02 +; DB #FF ;CYLINDERS LOW ;03 +; DB #FF ;CYLINDERS HIGH ;04 +; DB #FF ;SECTOR PER CYLINDER LOW ;05 +; DB #FF ;SECTOR PER CYLINDER HIGH ;06 +; DB #FF ;DEVICE TYPE ;07 + + MODULE CONFIGURE_IDE_DRIVES + + MODULE PAUSES +HALT: +.Time_2s EQU 100 +.SMALL EQU 200 ; 04 сек +.BIG EQU 1550 ; 31 сек +WAIT: +.IDE EQU #0000 +.SMALL EQU #0200 +.ERROR EQU #0400 + ENDMODULE + +WAIT_IDE EQU #0000 +WAIT_SML EQU #1000 +WAIT_ERROR EQU #0400 + +M_CYLL EQU #12 +M_CYLH EQU #13 +M_HEAD EQU #14 +M_SECT EQU #15 + +S_CYLL EQU #16 +S_CYLH EQU #17 +S_HEAD EQU #18 +S_SECT EQU #19 + +SM_CYLL EQU #37 +SM_CYLH EQU #38 +SM_HEAD EQU #39 +SM_SECT EQU #3A + +SS_CYLL EQU #3B +SS_CYLH EQU #3C +SS_HEAD EQU #3D +SS_SECT EQU #3E + + MACRO PAUSE_DJNZ num + IF num<255 + LD B,num +.loop: DJNZ .loop + ELSE + ASSERT 0, "WRONG PAUSE NUMBER!!!" + ENDIF + ENDM + +/////////////////////////////////////////////////////////////////////[v] +START: CALL SetUP_CHANELS + ; + IN A,(SLOT3) + EX AF,AF' + LD A,SYS_PAGE + OUT (SLOT3),A + LD HL,IDE.INIT_TBL_IDE0 + LD BC,256*(IDE.HDD_INIT_TABLE * 4) + #FF ;R02 +;CLEAR HDD VARIABLE +.FILLIDE: + LD (HL),C + INC HL + DJNZ .FILLIDE + EX AF,AF' + OUT (SLOT3),A + + LD IY,IDE.INIT_TBL_IDE0 + XOR A + CALL STEP1_GETCMOS + + LD IY,IDE.INIT_TBL_IDE1 + LD A,#01 + CALL STEP1_GETCMOS + + LD IY,IDE.INIT_TBL_IDE2 + LD A,#02 + CALL STEP1_GETCMOS + + LD IY,IDE.INIT_TBL_IDE3 + LD A,#03 + CALL STEP1_GETCMOS + + ;[x] save hdd parameters to cmos for "setup" in settings + CALL WRITING + ; + CALL ScreenPOS.CRLF + RET +/////////////////////////////////////////////////////////////////////[^] + + +/////////////////////////////////////////////////////////////////////[v] +AUTODETECT: + LD A,L ;DETECT MESSAGE + CALL POSTMSG + CALL ScreenPOS.SUBNAME + LD A,(MasterSlave) + ; + CALL AUTODETECTING +.IDEJUMPBACK: + CALL NC,MODEL + LD A,(SKIP) + INC A + LD A,msgStrings.ideNone + JR Z,.NOSKIPKEY + LD A,msgStrings.ideSkiped +.NOSKIPKEY: + CALL C,POSTMSG + CALL ScreenPOS.CRLF + RET +/////////////////////////////////////////////////////////////////////[^] + + +/////////////////////////////////////////////////////////////////////[v] +; !HARDCODE заменить числа на метки в этой процедуре +STEP1_GETCMOS: + LD (MasterSlave),A + LD H,A ;SAVE DRIVE NUMBER + CALL SELECT_IDE + LD A,IDE.Device.NONE + LD (IDEDEV),A + LD (SKIP),A + LD A,H + ; + AND A + LD BC,CMOS_CELL.DrivesSetup_1.Mask.PriIDEmaster ;#3011 + LD L,msgStrings.detectIdePrMA + JR Z,.choose + ; + DEC A + LD BC,CMOS_CELL.DrivesSetup_1.Mask.PriIDEslave ;#C011 + LD L,msgStrings.detectIdePrSL + JR Z,.choose + ; + DEC A + LD BC,CMOS_CELL.DrivesSetup_2.Mask.SecIDEmaster + LD L,msgStrings.detectIdeSecMA + JR Z,.choose + ; + DEC A + LD BC,CMOS_CELL.DrivesSetup_2.Mask.SecIDEslave + LD L,msgStrings.detectIdeSecSL + JR Z,.choose + SCF + RET + ;0 - AUTODETECT + ;1 - GETTING FROM SETUP + ;2 - CD-ROM (ATAPI device) + ;3 - DISABLED +.choose: + EI + ; + CALL G_VALUE + OR A + JR Z,AUTODETECT ;AUTO DETECT + ; + DEC A + JR Z,SETUP_FROM_CMOS ;Get from CMOS (SETUP) + ; + DEC A + RET NZ ;DON'T CHECK THIS DEVICE + ;JR Z,IT_IS_ATAPI ;CD-ROM +/////////////////////////////////////////////////////////////////////[^] +/////////////////////////////////////////////////////////////////////[v] +IT_IS_ATAPI: + LD A,L ;DETECT MESSAGE + CALL POSTMSG + CALL ScreenPOS.SUBNAME + + LD HL,PAUSES.HALT.BIG + CALL BITS_WAITS.Clear_BUSY + JR C,AUTODETECTING.IDE_ABSENT + + CALL AUTODETECTING.Its_ATAPI + JP AUTODETECT.IDEJUMPBACK +/////////////////////////////////////////////////////////////////////[^] + + +/////////////////////////////////////////////////////////////////////[v] +AUTODETECTING: CALL DETECTORS.CheckChanel + JR C,.IDE_ABSENT + + CALL Bug31SecCheck + JR C,.next + + LD HL,PAUSES.HALT.BIG + CALL BITS_WAITS.Clear_BUSY + JR C,.IDE_ABSENT + +.next: CALL DETECTORS.Counter + JR C,.IDE_ABSENT + + CALL DETECTORS.NOP_Check + JR C,.IDE_ABSENT + + ; CALL DISABLE_8bit ; DISABLE 8 bit data transfer + + CALL DETECTORS.IdentDevCheck + JR C,.IDE_ABSENT + JR Z,.Its_ATA + + ; enter point for ATAPI in setup +.Its_ATAPI: CALL DETECTORS.IdentPDevChk + JR C,.IDE_ABSENT + LD A,IDE.Device.CDROM + LD (IDEDEV),A + JR .get + +.Its_ATA: LD A,IDE.Device.HDD + LD (IDEDEV),A +.get: CALL GETPARAM + JR C,.IDE_ABSENT + ;CALL DisableWriteCache + ;CALL DisableStandBy + AND A + RET + ; +.IDE_ABSENT: LD A,IDE.Device.NONE + LD (IDEDEV),A + LD A,IDE.ATA.Nop + LD BC,IDE.Write.Command + OUT (C),A + DEC B + IN A,(C) ; IDE.Read.Status + SCF + RET +/////////////////////////////////////////////////////////////////////[^] + + +/////////////////////////////////////////////////////////////////////[v] +SETUP_FROM_CMOS: + LD A,H + LD IX,PRIM_MASTER_CMOS_T + OR A + JR Z,.step1 + ; + LD IX,PRIM_SLAVE_CMOS_T + CP 1 + JR Z,.step1 + ; + LD IX,SEC_MASTER_CMOS_T + CP 2 + JR Z,.step1 + ; + LD IX,SEC_SLAVE_CMOS_T +.step1: LD HL,TEMP + LD DE,TEMP+1 + LD BC,511 + LD (HL),0 + LDIR + ; + CALL Bug31SecCheck + JR C,.step2 + ; + LD HL,PAUSES.HALT.BIG + CALL BITS_WAITS.Clear_BUSY + JR C,AUTODETECTING.IDE_ABSENT + ; +.step2: LD A,(IX+2) ;M_HEAD + CALL READCMS + LD (TEMP+3*2),A ; !TODO сделать через структуру. HEADS PER TRACK + ; + LD A,(IX+1) ;M_CYLH + CALL READCMS + PUSH AF + ; + LD A,(IX+0) ;M_CYLL + CALL READCMS + POP HL + LD L,A + LD (TEMP+1*2),HL ; !TODO сделать через структуру. CYLINDERS + ; + LD A,(IX+3) ;M_SECT + CALL READCMS + LD (TEMP+6*2),A ; !TODO сделать через структуру. SECTOR PER TRACK + ; + LD A,IDE.Device.HDD + LD (IDEDEV),A + CALL IDESPEC + RET +/////////////////////////////////////////////////////////////////////[^] + + +/////////////////////////////////////////////////////////////////////[v] +IDESPEC: + IN A,(SLOT3) + EX AF,AF' + LD A,SYS_PAGE + OUT (SLOT3),A + LD A,(IDEDEV) + LD (IY+IDE.HDD_INIT_TABLE.DriveType),A + CP IDE.Device.CDROM + JP Z,.FOR_CDR + ; + LD BC,IDE.Read.Control + IN A,(C) + AND #F0 + LD B,A + LD A,(TEMP+#06) ; !TODO сделать через структуру. HEADS PER TRACK + LD (IY+IDE.HDD_INIT_TABLE.HeadsNumber),A + DEC A + AND #0F + OR B + LD B,A + LD A,(TEMP+#63) ; !TODO сделать через структуру. LBA/NON-LBA bit 1 (FROM ZERO!) + BIT 1,A + JR Z,.NONLBA + ; + SET 6,B +.NONLBA: LD A,B + LD BC,IDE.Write.DeviceHead + OUT (C),A + AND #F0 ;!HARDCODE DRIVE/HEAD REGISTER PHISICAL DISK bitmask + LD HL,ICHANEL + OR (HL) + LD (IY+IDE.HDD_INIT_TABLE.DRV_Flags),A + LD HL,(TEMP+#02) ; !TODO сделать через структуру. CYLINDERS + LD (IY+IDE.HDD_INIT_TABLE.CylinderNumberLow),L + LD (IY+IDE.HDD_INIT_TABLE.CylinderNumberHigh),H + LD A,(TEMP+#0C) ; !TODO сделать через структуру. SECTOR PER TRACK + LD (IY+IDE.HDD_INIT_TABLE.SectorsPerTrack),A + IF IDE_Optimization + LD B,high IDE.Write.Counter + ELSE + LD BC,IDE.Write.Counter + ENDIF + OUT (C),A + LD A,IDE.ATA.InitializeDeviceParameters + CALL IDE_CMD + LD C,(IY+IDE.HDD_INIT_TABLE.SectorsPerTrack) ; Sector per track + LD B,0 + LD H,B + LD L,B + LD A,(IY+IDE.HDD_INIT_TABLE.HeadsNumber) ; Head per HDD + +.loop: ADD HL,BC + DEC A + JR NZ,.loop + + LD (IY+IDE.HDD_INIT_TABLE.SectorsPerCylinderLow),L + LD (IY+IDE.HDD_INIT_TABLE.SectorsPerCylinderHigh),H +.END: ; [x] save hdd parameters to cmos for "setup" in settings + LD A,(IY+IDE.HDD_INIT_TABLE.DRV_Flags) ; for save to cmos in GETPARM + ; + EX AF,AF' + OUT (SLOT3),A + AND A + RET + ; +.FOR_CDR: LD BC,IDE.Read.Control + IN A,(C) + AND #F0 + LD HL,ICHANEL + OR (HL) + LD (IY+IDE.HDD_INIT_TABLE.DRV_Flags),A + JR IDESPEC.END +/////////////////////////////////////////////////////////////////////[^] + + +/////////////////////////////////////////////////////////////////////[v] +IDE_CMD: + PUSH AF + LD HL,PAUSES.WAIT.IDE + LD DE,256*IDE.ControlByte.Busy + 0 + CALL BITS_WAITS.WAIT_PRT + POP HL + RET C + INC B ; LD BC,IDE.Write.Command + OUT (C),H + LD HL,PAUSES.WAIT.IDE + ;LD DE,256*IDE.ControlByte.Busy + 0 + JR BITS_WAITS.WAIT_PRT +/////////////////////////////////////////////////////////////////////[^] + + +/////////////////////////////////////////////////////////////////////[v] +MODEL: LD HL,TEMP+27*2 ; !TODO сделать через структуру. + LD A,(HL) + OR A + JR Z,.unknown + LD B,20 ;!HARDCODE + CALL DWPRINT + AND A + RET +.unknown: + LD A,msgStrings.ideUnknown + CALL POSTMSG + AND A + RET +/////////////////////////////////////////////////////////////////////[^] + + +/////////////////////////////////////////////////////////////////////[v] +BITS_WAITS: +; IN: +; HL - Waiting delay +; DE - MASK : PATTERN +; OUT: +; NC: (PORT & D)-E = 0 +; CF: waiting delay exceeded +.WAIT_PRT: + LD BC,IDE.Read.Status + ; +.loop: IN A,(C) + AND D + CP E + RET Z + DEC HL + CALL SKIPKEY + RET C + LD A,L + OR H + JP NZ,.loop + ; + SCF + RET + ; + +; Pause for clear BUSY and DATA REQUEST +.Clear_BUSY: LD BC,IDE.Read.Status + IN A,(C) + ;!TEST for normal bus with pull-ups + ;CP #FF + ;SCF + ;RET Z + ; + AND IDE.ControlByte.Busy; + IDE.ControlByte.DataRequest + RET Z + ; + HALT + DEC HL + LD A,H + OR L + SCF + RET Z + ; + CALL SKIPKEY + RET C + ; + JR .Clear_BUSY +/////////////////////////////////////////////////////////////////////[^] + + +/////////////////////////////////////////////////////////////////////[v] +SELECT_IDE: + AND A ;%0000'0011 + LD B,IDE.Drive.Master + JR Z,.AUTO_0 + ; + DEC A + LD B,IDE.Drive.Slave + JR Z,.AUTO_0 + ; + DEC A + ;R00 + LD B,IDE.Drive.Master + JR Z,.AUTO_1 + ; + DEC A + LD B,IDE.Drive.Slave +.AUTO_1: LD A,IDE.Chanel.Secondary ;SELECT SECONDARY + OUT (IDE.Chanel.Set),A + JP .AUTO + ; +.AUTO_0: LD A,IDE.Chanel.Primary ;SELECT PRIMARY + OUT (IDE.Chanel.Set),A + ; + XOR A +.AUTO: LD (ICHANEL),A + ;R01 + LD A,B + LD BC,IDE.Write.DeviceHead + OUT (C),A + ; + RET +/////////////////////////////////////////////////////////////////////[^] + + +/////////////////////////////////////////////////////////////////////[v] +SKIPKEY: + EXX + CALL SCANKEY + EXX + SCF + CCF + RET Z + EXX + LD HL,#3E00 ;!HARDCODE + AND A + SBC HL,DE + EXX + SCF + CCF + RET NZ + LD A,0 + LD (SKIP),A + SCF + RET +/////////////////////////////////////////////////////////////////////[^] + + +/////////////////////////////////////////////////////////////////////[v] +; [x] save hdd parameters to cmos for "setup" in settings +; IN: A' = DRV_Flags +SaveToCMOS: + LD A,(IDEDEV) + CP IDE.Device.HDD + RET NZ + + EX AF,AF' + ;LD A,(IY+IDE.HDD_INIT_TABLE.DRV_Flags) + AND %0001'0001 + LD IX,PRIM_MASTER_CMOS_T + JR Z,.save_to_cmos + ; + DEC A + LD IX,SEC_MASTER_CMOS_T + JR Z,.save_to_cmos + ; + CP %0001'0000 + LD IX,SEC_SLAVE_CMOS_T + JR Z,.save_to_cmos + ; + LD IX,PRIM_SLAVE_CMOS_T +.save_to_cmos: + LD HL,(TEMP+1*2) + LD B,L + LD A,(IX+0) + CALL WRITCMS ; Cylinder low + + LD B,H + LD A,(IX+1) + CALL WRITCMS ; Cylinder high + + LD A,(TEMP+3*2) + LD B,A + LD A,(IX+2) + CALL WRITCMS ; Heads + + LD A,(TEMP+6*2) + LD B,A + LD A,(IX+3) + JP WRITCMS ; Heads +/////////////////////////////////////////////////////////////////////[^] + + +/////////////////////////////////////////////////////////////////////[v] +RESET_Slave_ATAPI: + LD A,IDE.Drive.Slave + LD BC,IDE.Write.DeviceHead + OUT (C),A + PAUSE_DJNZ 16 + LD BC,IDE.Write.Command + LD A,IDE.ATAPI.Reset + OUT (C),A + PAUSE_DJNZ 16 + LD A,IDE.Drive.Master + LD BC,IDE.Write.DeviceHead + OUT (C),A + RET +/////////////////////////////////////////////////////////////////////[^] + + +/////////////////////////////////////////////////////////////////////[v] +; Check bug with 31 sec freeze +Bug31SecCheck: LD A,(MasterSlave) + AND 1 + RET NZ + ; + LD HL,PAUSES.HALT.Time_2s + CALL BITS_WAITS.Clear_BUSY + CCF + RET C + ; + JP RESET_Slave_ATAPI +/////////////////////////////////////////////////////////////////////[^] + + +/////////////////////////////////////////////////////////////////////[v] +GETPARAM: + LD HL,PAUSES.WAIT.IDE + LD DE,IDE.ControlByte.DataRequest * 256 + IDE.ControlByte.DataRequest + CALL BITS_WAITS.WAIT_PRT + RET C + LD BC,IDE.Read.Data + LD HL,TEMP + INIR + INIR + CALL IDESPEC + ; [x] save hdd parameters to cmos for "setup" in settings + CALL SaveToCMOS + ; + AND A + RET +/////////////////////////////////////////////////////////////////////[^] + + +/////////////////////////////////////////////////////////////////////[v] +DETECTORS: +;-------; + ; CHECK BY COUNTER PORT. + ; Exit: CF - No device +.test_counter EQU 5 +.Counter: LD A,.test_counter + LD BC,IDE.Write.Counter + OUT (C),A + LD HL,PAUSES.WAIT.SMALL + LD DE,IDE.ControlByte.Busy*256 + 0 + CALL BITS_WAITS.WAIT_PRT + RET C + ; + LD BC,IDE.Read.Counter ; LD BC,IDE.Read.Counter + IN A,(C) + CP .test_counter + RET Z + SCF + RET +;-------; + +;-------; + ; CHECK BY EXECUTING NOP COMMAND AND WAIT. + ; Exit: CF - No device +.NOP_Check: LD E,IDE.ATA.Nop + LD BC,IDE.Write.Command + OUT (C),E + + PAUSE_DJNZ 0 + + LD HL,PAUSES.HALT.SMALL + LD BC,IDE.Read.Status + ;DEC B + ; +.loop: IN A,(C) + SCF + RET Z + ; + AND IDE.ControlByte.Busy + IDE.ControlByte.DataRequest + IDE.ControlByte.Error + CP IDE.ControlByte.Error + RET Z + ; + HALT + DEC HL + LD A,H + OR L + SCF + RET Z ; Absent + ; + CALL SKIPKEY + RET C ; Skipped = Absent + ; + JR .loop +;-------; + +;-------; + ; CHECK WITH Identify Device. + ; Exit: CF - No device + ; NC and ZF - ATA + ; NC and NZ - ATAPI +.IdentDevCheck: LD E,IDE.ATA.IdentifyDevice + LD BC,IDE.Write.Command + OUT (C),E + ; + LD DE,IDE.ControlByte.Busy * 256 + 0 + LD HL,PAUSES.WAIT.IDE + CALL BITS_WAITS.WAIT_PRT + RET C ; Absent + ; + LD BC,IDE.Read.Status + IN A,(C) + RRCA + JR C,.non_ATA + ; + AND (IDE.ControlByte.DataRequest + IDE.ControlByte.Ready) / 2 + SCF + RET Z + ; + XOR A + RET ; ATA + ; +.non_ATA: LD BC,IDE.Read.Error + IN A,(C) + AND IDE.ErrorByte.Abort + RET NZ ; ATAPI + ; + SCF ; Absent + RET +;-------; + +;-------; + ; ATAPI or Absent + ; Exit: CF - No device + ; NC - ATAPI +.IdentPDevChk: LD E,IDE.ATAPI.IdentifyPackedDevice + LD BC,IDE.Write.Command + OUT (C),E + LD HL,PAUSES.WAIT.IDE + LD DE,IDE.ControlByte.Busy*256 + 0 + CALL BITS_WAITS.WAIT_PRT + RET C + ; + LD BC,IDE.Read.Status + IN A,(C) + RRCA + RET C + XOR A + RET +;-------; + +;-------; +; если канал пустой, то читается из порта то, что было выставлено +; последним на шину c чётного адреса в памяти а это первый или второй +; байт кода команды + ALIGN 2 ; тут нужно выравнивание по задуманным адресам для команд чтения из портов +.CheckChanel: LD BC,IDE.Read.Status + IN A,(C) ;#ED78 A=#78 + IN L,(C) ;#ED68 L=#68 + LD D,A + IN A,(C) ;#ED60 A=#ED + LD E,L + ; если пустой: DE=#7868, A=#ED + ; + LD HL,#7868 + #ED + AND A + SBC HL,DE + XOR L + RET NZ ; not absent + SCF + RET ; absent +;-------; +/////////////////////////////////////////////////////////////////////[^] + + +/////////////////////////////////////////////////////////////////////[v] +SetUP_CHANELS: + LD A,1 + CALL .CMD + LD A,3 + CALL .CMD + LD A,0 + CALL .CMD + LD A,2 +.CMD: CALL SELECT_IDE + LD BC,IDE.Write.Command + LD H,IDE.ATA.Nop + OUT (C),H + PAUSE_DJNZ 32 + ; Disable INTRQ + ; LD BC,IDE.Write.DeviceControl + ; LD A,%0000'0010 + ; OUT (C),A + ; PAUSE_DJNZ 32 + ; ; + ; CALL DisableStandBy + ; PAUSE_DJNZ 32 + RET +/////////////////////////////////////////////////////////////////////[^] + + +/////////////////////////////////////////////////////////////////////[v] +; DisableWriteCache: +; LD BC,IDE.Write.Features +; LD A,IDE.ATA.SetFeatures.DisableWriteCache +; OUT (C),A +; LD A,IDE.ATA.SetFeatures +; JP IDE_CMD +/////////////////////////////////////////////////////////////////////[^] + + +/////////////////////////////////////////////////////////////////////[v] +;Disable StandBy timer +; DisableStandBy: +; LD BC,IDE.Write.Counter +; XOR A +; OUT (C),A +; LD A,IDE.ATA.Idle +; JP IDE_CMD +/////////////////////////////////////////////////////////////////////[^] + + +/////////////////////////////////////////////////////////////////////[v] +; DISABLE_8bit: +; LD BC,IDE.Write.Features +; LD A,IDE.ATA.SetFeatures.Disable8bit +; OUT (C),A +; LD A,IDE.ATA.SetFeatures +; JP IDE_CMD +/////////////////////////////////////////////////////////////////////[^] + + +;!FIXIT CMOS переделать под названия ячеек из SP2000.inc +PRIM_MASTER_CMOS_T: + DB M_CYLL,M_CYLH,M_HEAD,M_SECT +PRIM_SLAVE_CMOS_T: + DB S_CYLL,S_CYLH,S_HEAD,S_SECT +SEC_MASTER_CMOS_T: + DB SM_CYLL,SM_CYLH,SM_HEAD,SM_SECT +SEC_SLAVE_CMOS_T: + DB SS_CYLL,SS_CYLH,SS_HEAD,SS_SECT + + +SKIP: BYTE #FF +IDEDEV: BYTE #FF +ICHANEL: BYTE #00 +MasterSlave BYTE #00 + + +;WAITHDD DEC L +; RET NZ +; DEC H +; RET NZ +; DEC E +; RET NZ +; SCF +; RET + +; E - Second * 10 + +;PAUSE LD HL,#0000 +;PAUSE1 DEC L +; JR NZ,PAUSE1 +; DEC H +; JR NZ,PAUSE1 +; DEC E +; JR NZ,PAUSE1 +; RET + + ENDMODULE +; \ No newline at end of file diff --git a/Crazy BIOS/rom/SETUP/DEHRUST.asm b/Crazy BIOS/rom/SETUP/DEHRUST.asm new file mode 100644 index 0000000..c416a5d --- /dev/null +++ b/Crazy BIOS/rom/SETUP/DEHRUST.asm @@ -0,0 +1,242 @@ +; INCLUDE '../mem_map.inc' + +; ORG Depacker_start + +; DeHRUSTer v1.2 +; HL - начало архива +; DE - адрес распаковки + +;--------------[DEPACKER]--------------- +DEHRUST: + PUSH DE + PUSH HL + INC HL + INC HL + LD C,(HL) + INC HL + LD B,(HL) + INC HL + DEC BC + EX DE,HL + ADD HL,BC + EX DE,HL + LD C,(HL) + INC HL + LD B,(HL) + DEC BC + POP HL + ADD HL,BC + SBC HL,DE + ADD HL,DE + JR C,.LL4019 + LD D,H + LD E,L +.LL4019: + LDDR + EX DE,HL + POP DE + LD C,#0C + ADD HL,BC + PUSH HL + POP IX + LD A,#03 +.LL4025: + DEC HL + LD B,(HL) + DEC HL + LD C,(HL) + PUSH BC + DEC A + JR NZ,.LL4025 + LD B,A + EXX + LD D,#BF + LD C,#10 + CALL .LL4115 +.LL4036: + LD A,(IX+#00) + INC IX + EXX +.LL403C: + LD (DE),A + INC DE +.LL403E: + EXX +.LL403F: + ADD HL,HL + DJNZ .LL4045 + CALL .LL4115 +.LL4045: + JR C,.LL4036 + LD E,#01 +.LL4049: + LD A,#80 +.LL404B: + ADD HL,HL + DJNZ .LL4051 + CALL .LL4115 +.LL4051: + RLA + JR C,.LL404B + CP #03 + JR C,.LL405D + ADD A,E + LD E,A + XOR C + JR NZ,.LL4049 +.LL405D: + ADD A,E + CP #04 + JR Z,.LL40C4 + ADC A,#FF + CP #02 + EXX +.LL4067: + LD C,A +.LL4068: + EXX + LD A,#BF + JR C,.LL4082 +.LL406D: + ADD HL,HL + DJNZ .LL4073 + CALL .LL4115 +.LL4073: + RLA + JR C,.LL406D + JR Z,.LL407D + INC A + ADD A,D + JR NC,.LL4084 + SUB D +.LL407D: + INC A + JR NZ,.LL408D + LD A,#EF +.LL4082: + RRCA + CP A +.LL4084: + ADD HL,HL + DJNZ .LL408A + CALL .LL4115 +.LL408A: + RLA + JR C,.LL4084 +.LL408D: + EXX + LD H,#FF + JR Z,.LL409B + LD H,A + INC A + LD A,(IX+#00) + INC IX + JR Z,.LL40A6 +.LL409B: + LD L,A + ADD HL,DE + LDIR +.LL409F: + JR .LL403E +.LL40A1: + EXX + RRC D + JR .LL403F +.LL40A6: + CP #E0 + JR C,.LL409B + RLCA + XOR C + INC A + JR Z,.LL40A1 + SUB #10 +.LL40B1: + LD L,A + LD C,A + LD H,#FF + ADD HL,DE + LDI + LD A,(IX+#00) + INC IX + LD (DE),A + INC HL + INC DE + LD A,(HL) + JP .LL403C +.LL40C4: + LD A,#80 +.LL40C6: + ADD HL,HL + DJNZ .LL40CC + CALL .LL4115 +.LL40CC: + ADC A,A + JR NZ,.LL40F3 + JR C,.LL40C6 + LD A,#FC + JR .LL40F6 +.LL40D5: + LD B,A + LD C,(IX+#00) + INC IX + CCF + JR .LL4068 +.LL40DE: + CP #0F + JR C,.LL40D5 + JR NZ,.LL4067 + LD B,#03 + EX DE,HL +.LL40E7: + POP DE + LD (HL),E + INC HL + LD (HL),D + INC HL + DJNZ .LL40E7 + LD HL,#2758 + EXX + RET +.LL40F3: + SBC A,A + LD A,#EF +.LL40F6: + ADD HL,HL + DJNZ .LL40FC + CALL .LL4115 +.LL40FC: + RLA + JR C,.LL40F6 + EXX + JR NZ,.LL40B1 + BIT 7,A + JR Z,.LL40DE + SUB #EA + ADD A,A + LD B,A +.LL410A: + LD A,(IX+#00) + INC IX + LD (DE),A + INC DE + DJNZ .LL410A + JR .LL409F +.LL4115: + LD B,C + LD L,(IX+#00) + INC IX + LD H,(IX+#00) + INC IX + RET +Length EQU $-DEHRUST + + in a,(#FF) + +;--------------------------------------- + +;---------------[MAIN.HR]--------------- +;Depacker.packcode EQU $$$ +;PackedMAIN EQU $ +; INCBIN 'Build/Bin/temp/MAIN.HR' +;--------------------------------------- +; \ No newline at end of file diff --git a/Crazy BIOS/rom/SETUP/IM2_INT.asm b/Crazy BIOS/rom/SETUP/IM2_INT.asm new file mode 100644 index 0000000..512791a --- /dev/null +++ b/Crazy BIOS/rom/SETUP/IM2_INT.asm @@ -0,0 +1,48 @@ +; +; before_intPointer EQU #C000 +; INT_POINTER EQU #C002 +; INT_HANDLER EQU #C004 + + +before_intPointer EQU $ + BLOCK #FF - low $,0 ; выравнивание на #xxFF +INT_POINTER: WORD 0 + + ASSERT +low INT_POINTER = #FF, 'ERROR! Not valid interrupt pointer!' + IFDEF PREBUILD + ASSERT INT_POINTER-before_intPointer < 16, 'Warning! To much space before INT_POINTER.' + ELSE + IF INT_POINTER-before_intPointer > 16 + DISPLAY 'Warning! To much space before INT_POINTER: ',/D,INT_POINTER-before_intPointer + ENDIF + ENDIF + +INT_HANDLER: + PUSH AF + EX AF,AF' + PUSH AF + PUSH BC + PUSH DE + PUSH HL + EXX + PUSH BC + PUSH DE + PUSH HL + PUSH IX + PUSH IY + CALL KEYSCAN + POP IY + POP IX + POP HL + POP DE + POP BC + EXX + POP HL + POP DE + POP BC + POP AF + EX AF,AF' + POP AF + EI + RETI +; \ No newline at end of file diff --git a/Crazy BIOS/rom/SETUP/KEY.asm b/Crazy BIOS/rom/SETUP/KEY.asm new file mode 100644 index 0000000..8c5f6cf --- /dev/null +++ b/Crazy BIOS/rom/SETUP/KEY.asm @@ -0,0 +1,794 @@ + +; + _mInfoALIGN 256,0 ; выравнивание на адрес #XX00 +SBUF: BLOCK 64,0 + +HEAD: DB 0 +HOST: DB 0 + +; +K_LOCK EQU $-KEYFLAG +LANG_L EQU 7 +PAUSE_L EQU 6 +RES5_L EQU 5 +RES4_L EQU 4 +NUM_L EQU 3 +SCRL_L EQU 2 +INS_L EQU 1 +CAPS_L EQU 0 +KEYFLAG: DB 2 ;D0-Key Pressed +; +K_SHIFT EQU $-KEYFLAG +L_SHIFT EQU 7 +R_SHIFT EQU 6 +X_CTRL EQU 5 +X_ALT EQU 4 +L_CTRL EQU 3 +L_ALT EQU 2 +R_CTRL EQU 1 +R_ALT EQU 0 +KEYCTRL: DB 0 +; +KEYFLG EQU $-KEYFLAG +FLAG_E0 EQU 7 +FLAG_F0 EQU 6 +FLAG_E1 EQU 5 +FLAG_04 EQU 4 +FLAG_03 EQU 3 +FLAG_02 EQU 2 +FLAG_01 EQU 1 +FLAG_00 EQU 0 + DB 0 +; +SOUND_K EQU $-KEYFLAG +FLAG_S7 EQU 7 +FLAG_S6 EQU 6 +FLAG_S5 EQU 5 +FLAG_S4 EQU 4 +FLAG_S3 EQU 3 +FLAG_S2 EQU 2 +SF_ALT EQU 1 +SF_BUFF EQU 0 + DB 3 +; +;UNCODE: DW 0000 +; + +; D15 - LShift +; D14 - RShift +; D13 - CTRL +; D12 - ALT +; D11 - LCTRL +; D10 - LALT +; D9 - RCTRL +; D8 - RALT +; D7 - Language Lock +; D6 - Reserved +; D5 - Reserved +; D4 - Reserved +; D3 - Num Lock +; D2 - Scroll Lock +; D1 - Insert Lock +; D0 - Caps Lock + +; D15 - Keystroke +; D14 +; D13 \ +; D12 \ +; D11 -- Position code (0...5Ah) +; D10 / +; D9 / +; D8 +; D7..D0 - ASCII code + +WAITKEY: + LD HL,HOST + LD A,(HEAD) + CP (HL) + JR Z,WAITKEY + CALL GETSYM + LD A,E + AND A + RET + +SCANKEY: + LD HL,HOST + LD A,(HEAD) + CP (HL) + RET Z + CALL GETSYM + LD A,E + RET + +CTRLKEY: + LD HL,HOST + LD A,(HEAD) + CP (HL) + LD BC,(KEYFLAG) + LD A,#00 + RET Z + DEC A + RET + +PUTSYM: LD HL,HEAD + LD A,(HOST) + SUB 4 + AND #3F + CP (HL) + JR Z,FULL_BF + LD A,(HL) + INC (HL) + INC (HL) + INC (HL) + INC (HL) + RES 6,(HL) + LD L,A + LD H,high SBUF + LD (HL),E + INC L + LD (HL),D + INC L + LD (HL),B + INC L + LD (HL),C + RET + +GETSYM: LD HL,HOST + LD A,(HEAD) + CP (HL) + RET Z + LD A,(HL) + INC (HL) + INC (HL) + INC (HL) + INC (HL) + RES 6,(HL) + LD L,A + LD H,high SBUF + LD E,(HL) + INC L + LD D,(HL) + INC L + LD B,(HL) + INC L + LD C,(HL) + RET + +FULL_BF: + EX AF,AF' + BIT SF_BUFF,(IX+SOUND_K) + JR Z,.FBF + EXX + LD DE,230 + LD HL,50 + CALL BEEP + EXX +.FBF: EX AF,AF' + RET + +KEYSCAN: + LD IX,KEYFLAG +RESCANN: + IN A,(Z84.SIO.Ch_A.Ctrl) + AND 1 + RET Z + ;[x] 18/02/2024 проверка на переполнение буфера + ; A = 1 + ; reg 1 + OUT (Z84.SIO.Ch_A.Ctrl),A + IN A,(Z84.SIO.Ch_A.Ctrl) + AND %0010'0000 ; check receiver overrun error + JP NZ,Receiver_Overrun + ; + IN A,(Z84.SIO.Ch_A.Data) + CP #F0 + JR Z,F0_KEY + CP #E0 + JR Z,E0_KEY + ; + CP #E1 + IF USE_E1_SCANCODE + JR Z,E1_KEY + ELSE + JR Z,RESCANN + ENDIF + ; + BIT FLAG_F0,(IX+KEYFLG) + JR NZ,UN_KEY + ; + LD L,A + CALL XLAT + CALL SHIFTS + RES FLAG_E0,(IX+KEYFLG) + IF USE_E1_SCANCODE + RES FLAG_E1,(IX+KEYFLG) + ENDIF + ; + ;[x] 29/02/2024 выгребсти весь буфер + JR Z,RESCANN ;IT'S SHIFT KEY + ; RET Z ;IT'S SHIFT KEY + ; + CALL INPCODE ;L - AT POS. CODE + ;PUTCODE + LD HL,#1C00 ;Caps Lock + AND A + SBC HL,DE + CALL Z,CAPS_X + + ; !TODO вернуть русский? А зачем? +; LD HL,#B800 ;Ctrl + Space +; AND A +; SBC HL,DE +; CALL Z,RUS_X + + LD HL,#5000 ;Insert + AND A + SBC HL,DE + CALL Z,INS_X + LD HL,#4900 ;Num Lock + AND A + SBC HL,DE + CALL Z,NUM_X + LD HL,#C900 ;Pause Lock + AND A + SBC HL,DE + CALL Z,PAUSE_X + LD HL,#4800 ;Scroll Lock + AND A + SBC HL,DE + CALL Z,SCL_X + ;-----------------------; !!!!! ресет по КАД + ; LD HL,#CF00 ; ; Ctrl + Alt + Del + ; AND A ; + ; SBC HL,DE ; + ; CALL Z,RST_X ; + ;-----------------------; + LD BC,(KEYFLAG) + CALL PUTSYM + JP RESCANN + +E0_KEY: SET FLAG_E0,(IX+KEYFLG) + JR RESCANN + +F0_KEY: SET FLAG_F0,(IX+KEYFLG) + JR RESCANN + + IF USE_E1_SCANCODE +E1_KEY: SET FLAG_E1,(IX+KEYFLG) + JR RESCANN + ENDIF + +UN_KEY: RES FLAG_F0,(IX+KEYFLG) + LD L,A + CALL XLAT + CALL UNSHIFT + RES FLAG_E0,(IX+KEYFLG) + ;LD H,0 + ;LD (UNCODE),HL + RET + +CAPS_X: LD A,(KEYFLAG) + XOR 1<","?",#00,"|" + DB #00,#00,Spc,#00,#00 + DB #00,#00,#00,#00,#00,#00,#00,#00,#00,#00,#00,#00 + DB #00,#00,#00,"/","*","-","+",Ent,#00 + DB #00,#00,#00,#00,#00,#00,#00,#00,#00,#00 +CAPSTAB: + DB "`",Esc,"1","2","3","4","5","6","7","8","9","0","-","=",Bcs + DB Tab,"Q","W","E","R","T","Y","U","I","O","P","[","]" + DB Cps,"A","S","D","F","G","H","J","K","L",";","'",Ent + DB #00,"Z","X","C","V","B","N","M",#2C,".","/",#00,#5C ;"\" + DB #00,#00,Spc,#00,#00 + DB #00,#00,#00,#00,#00,#00,#00,#00,#00,#00,#00,#00 + DB #00,#00,#00,"/","*","-","+",Ent,#00 + DB #00,#00,#00,#00,#00,#00,#00,#00,#00,#00 +SHF2TAB: + DB "~",Esc,"!","@","#","$","%","^","&","*","(",")","_","+",Bcs + DB Tab,"q","w","e","r","t","y","u","i","o","p","{","}" + DB Cps,"a","s","d","f","g","h","j","k","l",":",#22,Ent + DB #00,"z","x","c","v","b","n","m","<",">","?",#00,"|" + DB #00,#00,Spc,#00,#00 + DB #00,#00,#00,#00,#00,#00,#00,#00,#00,#00,#00,#00 + DB #00,#00,#00,"/","*","-","+",Ent,#00 + DB #00,#00,#00,#00,#00,#00,#00,#00,#00,#00 + +/////////////////////////////////////////////////////////////////////// +; _mInfoALIGN 256,0 ; без выравнивания +XLAT_T: +; 0 1 2 3 4 5 6 7 8 9 A B C D E F + DB #00,#43,#00,#3F,#3D,#3B,#3C,#46,#00,#44,#42,#40,#3E,#0F,#00,#00 ;00 + DB #00,#37,#29,#00,#36,#10,#02,#00,#00,#00,#2A,#1E,#1D,#11,#03,#00 ;10 + DB #00,#2C,#2B,#1F,#12,#05,#04,#00,#00,#38,#2D,#20,#14,#13,#06,#00 ;20 + DB #00,#2F,#2E,#22,#21,#15,#07,#00,#00,#00,#30,#23,#16,#08,#09,#00 ;30 + DB #00,#31,#24,#17,#18,#0B,#0A,#00,#00,#32,#33,#25,#26,#19,#0C,#00 ;40 + DB #00,#00,#27,#00,#1A,#0D,#00,#00,#1C,#34,#28,#1B,#00,#35,#00,#00 ;50 + DB #00,#00,#00,#00,#00,#00,#0E,#00,#00,#51,#00,#54,#57,#00,#00,#00 ;60 + DB #50,#4F,#52,#55,#56,#58,#01,#49,#45,#4D,#53,#4C,#4B,#59,#48,#00 ;70 + DB #00,#00,#00,#41,#00,#00,#00,#00,#00,#00,#00,#00,#00,#00,#00,#00 ;80 +XLAT_T.Size EQU $-XLAT_T +/////////////////////////////////////////////////////////////////////// + + +XLAT: BIT FLAG_E0,(IX+KEYFLG) + JR Z,.W_O_E0 + CP #11 ; Right ALT + LD L,#39 + RET Z + + CP #14 ; Right CTRL + LD L,#3A + RET Z + + CP #5A ; enter + LD L,#4E + RET Z + + CP #4A ; / + LD L,#4A + RET Z + + CP #7C ; * - Print Screen + LD L,#47 + RET Z + + LD L,A +.W_O_E0: + ; таблица с выравниванием на 256 + ; LD H,high XLAT_T + ; LD L,(HL) + ; + ; без выравнивания + ; [x] 31/03/2024 исправлен баг с выходом за границы таблицы XLAT_T + CP XLAT_T.Size + LD L,0 + RET NC + ; + LD HL,XLAT_T + ADD A,L + LD L,A + JR NC,.no_inc + INC H +.no_inc: + LD L,(HL) + RET + RET + +; !TODO посмотреть +;INPCODE: +; BIT 1,(IX+1) ;00110000 +; JR NZ,FN_KEY ;LRCAcaRP + +INPCODE: LD D,L + LD E,0 + ; !TODO вернуть русский? А зачем? + ; BIT LANG_L,(IX+K_LOCK) + ; JP NZ,RUSCODE + LD A,(KEYCTRL) + AND 1< 16 +; DISPLAY 'Warning! To much space before INT_POINTER: ',/D,INT_POINTER-before_intPointer +; ENDIF +; ENDIF + +; INT_HANDLER: +; PUSH AF +; EX AF,AF' +; PUSH AF +; PUSH BC +; PUSH DE +; PUSH HL +; EXX +; PUSH BC +; PUSH DE +; PUSH HL +; PUSH IX +; PUSH IY +; CALL KEYSCAN +; POP IY +; POP IX +; POP HL +; POP DE +; POP BC +; EXX +; POP HL +; POP DE +; POP BC +; POP AF +; EX AF,AF' +; POP AF +; EI +; RETI +; ; + +INT_OFF: + DI + LD A,#3F + LD I,A + IM 1 + RET + +INT_ON: + DI + LD A,+high INT_POINTER + LD I,A + LD HL,INT_HANDLER + LD (INT_POINTER),HL + IM 2 + EI + RET +; + +; +;------------------------[go to spectrum from bios]---------------------; +EXIT_SETUP: + CALL INT_OFF +; +; LD BC,#020E +; CALL G_VALUE +; OR A +; LD A,#EC ;SPRINTER +; JR Z,XFLEX +; LD A,#EA ;SPECTRUM +;XFLEX: + LD A,ROM.BIOS + OUT (SYS_PORT.ROM),A + POP HL ; пихается в EXP.ASM в процедуре + JP (HL) +; LD (JMPHL),HL + + ; LD C,#F3 + ; RST_to_BIOS +; JMPHL EQU $+1 +; JP #0000 +;-----------------------------------------------------------------------; + + +INSTALL: + CALL INT_ON + CALL SET_CGA + XOR A + OUT (#FE),A + LD IX,win_descriptor.tab80x32 + LD HL,#0000 + LD E,1 + CALL WIN_OPEN + + LD DE,0 + LD HL,#2050 + LD B,7 + CALL LP_CLS_WIN + + LD DE,0 + LD HL,#0820 + LD B,0 + CALL LP_CLS_WIN + + CALL SETLAND + + CALL GET_ID + LD DE,#0028 ; !HARDCODE + CALL LP_SET_PLACE + LD HL,memBUFFER.ID + LD A,COLORS.CGA.INC.LCYAN + CALL CPRINTZ + ; LD HL,BUILD + ; LD A,COLORS.CGA.INC.LCYAN + ; CALL CPRINTZ + + LD DE,#0128 ; !HARDCODE + CALL LP_SET_PLACE + LD A,msgStrings.copyRightPeters + LD E,COLORS.CGA.INC.LGREEN + CALL POSTMSC + + LD DE,#0228 ; !HARDCODE + CALL LP_SET_PLACE + LD A,msgStrings.copyRightSPTeam + LD E,COLORS.CGA.INC.GREEN + CALL POSTMSC + + IF BETA_BUILD > 0 + LD DE,#0328 + CALL LP_SET_PLACE + LD A,msgStrings.testBIOSmsg + LD E,COLORS.CGA.FLASH + COLORS.CGA.INC.RED + CALL POSTMSC + ENDIF + + IN A,(SLOT3) + PUSH AF + LD A,SYS_PAGE + OUT (SLOT3),A + LD HL,RebootDate + CALL GETTIME + POP AF + OUT (SLOT3),A + RET + +;BUILD: +; db ', BIOS v', Disk_subsystem_ver_txt,0 ; !FIXIT может воткнуть вместе с msgStrings ? + +RSTID: DB "RESTART",0 +.size EQU $-RSTID + +Start_again: + ld sp,STACK-2 +START: + DI + PUSH AF + XOR A + LD (ERRSUM),A + LD (ERRSUM.ErrDateTime),A + +; LD C,#97 +; RST_to_BIOS_18 +; XOR A +; LD C,#F2 +; RST_to_BIOS_18 +;------------------------------ ;!!!!! посмотреть +; CALL KINIT +;------------------------------ ;!!!!! посмотреть + +;--------[Clean keyboard buffer]-------- +; clean_kbd_buf: +; IN A,(Z84.SIO.Ch_A.Ctrl) +; BIT 0,A +; jr z,.exit +; IN A,(Z84.SIO.Ch_A.Data) +; jr clean_kbd_buf +; .exit: +;--------------------------------------- + + +;R08 CALL OPENDOS + CALL ZXCLS + CALL READING + CALL TCHEKSM + CALL NZ,SETDEFX + + ;!TODO CMOS Disabled use of CONFIG_DE (#C13A) word + ;LD A,#1C + ;CALL READCMS + ;PUSH AF + ;LD A,CMOS_CELL.HardwareConfiguration + ;CALL READCMS + ;POP DE + ;LD E,A + ; + + LD C,SLOT3 + IN B,(C) + PUSH BC + LD A,SYS_PAGE + OUT (C),A + +; LD (SYS_PAGE.CONFIG_DE),DE + + LD HL,SYS_PAGE.INT_ADRESS ;EXTENDED INTERRUPT + XOR A + LD (HL),A + INC L + LD (HL),A + INC L + LD (HL),A + INC L + LD (HL),A + POP BC + OUT (C),B + + CALL TRQUICK + CALL FINSTAL + CALL ZXMODE_SETUP + CALL CLEARM + CALL RESCREEN + +;R06 + LD BC,CMOS_CELL.BootUpParams.Mask.QuickStartROM ;#010E + CALL G_VALUE + POP BC + INC B + DEC B + JR NZ,QIGNORE ; результат проверки Space из exp.asm [space_check] + PUSH AF + LD C,SLOT3 + IN B,(C) + PUSH BC + LD A,SYS_PAGE + OUT (C),A + LD HL,SYS_PAGE.RESTART_ID + LD DE,RSTID + LD B,RSTID.size + CALL COMPARE + CALL NZ,SETRSTS + POP BC + OUT (C),B + JR Z,HOTST + POP AF + JR QIGNORE + +SETRSTS: + PUSH AF + LD HL,RSTID + LD DE,SYS_PAGE.RESTART_ID + LD BC,RSTID.size + LDIR + LD HL,PowerOnDate ; !TODO изменить под структуру, когда структура переменных будет готова + CALL GETTIME + POP AF + RET + +HOTST: + POP AF + OR A + JP NZ,EXIT_SETUP +QIGNORE: + CALL INSTALL + LD DE,#0528 + ;CALL ScreenPOS.LOCAT + CALL LP_SET_PLACE + LD A,msgStrings.toSetupButton + LD E,COLORS.CGA.FLASH + COLORS.CGA.INC.WHITE + CALL POSTMSC + + LD DE,#0900 + ;CALL ScreenPOS.LOCAT + CALL LP_SET_PLACE +ERRSUM+1: + LD A,#00 ;MEM Patch! + OR A + JR Z,.ErrDateTime + XOR A + ld (.ErrDateTime+1),a ; если контрольная сумма слетела, то сообщение о кривых дате/времени в кмос не выводим + LD A,msgStrings.cmosChecksumErr + LD E,COLORS.CGA.INC.RED + CALL POSTMSC + CALL ScreenPOS.CRLF + CALL ScreenPOS.CRLF + JR CHEKOK + +.ErrDateTime+1: + LD A,0 + OR A + JR Z,CHEKOK + LD A,msgStrings.cmosDateTimeErr + LD E,COLORS.CGA.INC.RED + CALL POSTMSC + CALL ScreenPOS.CRLF + CALL ScreenPOS.CRLF + +CHEKOK: ;CALL ScreenPOS.GET_CUR + CALL LP_GET_PLACE + PUSH DE + CALL LOGOTYPE + + LD DE,#0000 + ;CALL ScreenPOS.LOCAT + CALL LP_SET_PLACE + LD A,msgStrings.spModel + CALL POSTMSG + CALL PIDNUM + CALL ScreenPOS.CRLF + + LD A,msgStrings.boardID + CALL POSTMSG + CALL PIDBOARD + CALL ScreenPOS.CRLF + + LD A,msgStrings.spCNFver + CALL POSTMSG + CALL CNF_VER_PRINT + CALL ScreenPOS.CRLF + + LD A,msgStrings.spMemory + CALL POSTMSG + CALL EMM.GetMemSize + PUSH BC + CALL PMEMORY + CALL ScreenPOS.CRLF + LD A,msgStrings.memoryAvailable + CALL POSTMSG + POP HL + CALL PMEMORY + CALL ScreenPOS.CRLF + + ;CALL TSTCMOS + CALL CMOS_TEST + + LD A,msgStrings.cmosNone + JR C,CMOS_ABSENT + ; CMOS OK + CALL CMOSINIT + LD A,msgStrings.cmosFound + CALL POSTMSG + LD A,',' + CALL PRINT_CHAR + LD A," " + CALL PRINT_CHAR + LD HL,RebootDate + CALL PRNTIME + CALL ScreenPOS.CRLF + JR INFO_MESSAGE +CMOS_ABSENT: + CALL POSTMSG +INFO_MESSAGE: + ; for recovery boot + ; LD DE,#0428 + ; CALL LP_SET_PLACE + ; LD A,msgStrings.forCtrlBootButton + ; LD E,COLORS.CGA.INC.WHITE + ; CALL POSTMSC + ; + ; For alternative boot + LD DE,#0528 + CALL LP_SET_PLACE + LD A,msgStrings.forAltBootButton + LD E,COLORS.CGA.INC.WHITE + CALL POSTMSC + + + POP DE + CALL LP_SET_PLACE + + CALL TSETUP ;!TODO может пихнуть её на прерывания? + + CALL CONFIGURE_IDE_DRIVES.START + CALL CTRLKEY + LD A,B + ; [x] 05/07/2024 + BIT X_CTRL,A + LD BC,#FFFF ; маркер для PrepareToBOOT, чтоб грузил Recovery + JR NZ,RECOVERY_BOOT + ; + BIT X_ALT,A + JR NZ,ALT_BOOT + ; + CALL TSETUP + ; + LD BC,CMOS_CELL.BootDrives.Mask.SysDisk ;#0710 +RECOVERY_BOOT: + CALL PrepareToBOOT + LD A,msgStrings.bootFail + LD E,COLORS.CGA.INC.LRED + CALL C,POSTMSC + CALL ScreenPOS.CRLF + ; + CALL INT_ON +ALT_BOOT: + LD A,msgStrings.bootAltDrv + LD E,COLORS.CGA.INC.LGREEN + CALL POSTMSC + + LD BC,CMOS_CELL.BootDrives.Mask.AltSysDisk ;#7010 + CALL PrepareToBOOT + LD A,msgStrings.bootFail + LD E,COLORS.CGA.INC.LRED + CALL C,POSTMSC + CALL ScreenPOS.CRLF + + ;NO START DISK - RESTART / SETUP / ZX SPECTRUM mode + LD BC,CMOS_CELL.Options.Mask.RebootMSG ;#021D + CALL G_VALUE + OR A + JP Z,EXIT_SETUP + + CALL ScreenPOS.CRLF + LD A,msgStrings.afterBootFail + LD E,COLORS.CGA.INC.RED + CALL POSTMSC + + ;EI + CALL INT_ON +AGAKEY: CALL WAITKEY + LD HL,#4F00 ; DEL - go to settings + ;AND A + SBC HL,DE + JR Z,ENTER_SETUP + ; + CP #1B ; ESC - go to zx spectrum mode + JP Z,EXIT_SETUP + CP #0D ; ENTER - restart + JP NZ,AGAKEY + XOR A + JP Start_again + +TSETUP: CALL SCANKEY + RET Z + LD HL,#4F00 ; DEL - go to settings + AND A + SBC HL,DE + JR Z,ENTER_SETUP + ; + LD HL,#011B ; ESC + AND A + SBC HL,DE + JR NZ,TSETUP + POP HL ; убираем лишнее + JP EXIT_SETUP +ENTER_SETUP: + XOR A + LD (ITEM_Restore),A + CALL SETTINGS + XOR A + JP Start_again + +COMPARE: + LD A,(DE) + CP (HL) + RET NZ + INC HL + INC DE + DJNZ COMPARE + RET + +; ????? перенести это в функции БИОС? +; HL - data to write: BYTE Hours, minutes, seconds, day, month, century, year. (2022: 20 - century, 22 - year) +writeDateTimeToCmos: ;!FIXIT + LD A,(HL) + LD D,CMOS.Register.hours + CALL CMOS_WR + + INC HL + LD A,(HL) + LD D,CMOS.Register.minutes + CALL CMOS_WR + + INC HL + LD A,(HL) + LD D,CMOS.Register.seconds + CALL CMOS_WR + + INC HL + LD A,(HL) + LD D,CMOS.Register.date + CALL CMOS_WR + + INC HL + LD A,(HL) + LD D,CMOS.Register.month + CALL CMOS_WR + + INC HL + LD A,(HL) + LD D,CMOS.Register.century + CALL CMOS_WR + + INC HL + LD A,(HL) + LD D,CMOS.Register.year + CALL CMOS_WR + RET + +RESCREEN: ;R06 + LD A,CMOS_CELL.ScreenPosition + CALL READCMS + LD B,A + LD A,ACEX.HOLD + JP SET_PORTS + ; PUSH AF + ; IN A,(SLOT3) + ; LD E,A + ; LD A,DCP_PAGE + ; OUT (SLOT3),A + ; LD A,(#C400) ;c400 for first cfg 50176 ; !TODO можно переделать на вызов функции биоса + ; LD D,A + ; LD A,ACEX.HOLD + ; LD (#C400),A + ; POP AF + ; LD BC,0 + ; OUT (C),A + ; LD A,D + ; LD (#C400),A + ; LD A,E + ; OUT (SLOT3),a + ; RET +; +;R07 +; CMOSINIT: +; LD D,10 ;FREQ +; LD C,#F6 ;READ CMOS +; RST_to_BIOS +; CP #26 +; JR NZ,CMSERR +; LD D,12 +; LD C,#F6 +; RST_to_BIOS +; CP #50 +; RET Z +; CMSERR: +; LD D,10 +; LD A,#26 ;FREQ +; LD C,#F7 +; RST_to_BIOS +; LD D,11 +; LD A,#02 ;TIME FORMAT +; LD C,#F7 +; RST_to_BIOS +; LD D,12 +; LD A,#50 +; LD C,#F7 +; RST_to_BIOS +; LD D,13 +; LD A,#80 +; LD C,#F7 +; RST_to_BIOS +; RET + +;------------------- ;!!!!! посмотреть +; 0 - 1-st FDD +; 1 - 2-nd FDD +; 2 - 1-st IDE +; 3 - 2-nd IDE +; 4 - 3-rd IDE +; 5 - 4-th IDE +; 6 - RAM-DISK +; +; -> BC - ячейка и маска для чтения значения кмос для загрузочного драйва + +; +;[ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ] +RECOVERYstart: + LD A,msgStrings.bootRecovery + CALL POSTMSG + ; + + ; Выбор рамдиска для рекавери + _mRECOVERYrdChooseTYPE RECOVERYrdChooseTYPE + + ; прибиваем последний рамдиск, если занят +.killRAMdisk: LD A,SYS_PAGE.RAMD_KEYS.NUM-1 + LD (.RDkey),A + CALL EMM.FreeMemRMD + JR NC,.setRAMdisk + JR Z,.setRAMdisk + RET ; непонятная ошибка - выходим +.setRAMdisk: LD A,(.RDkey) + LD B,ROM_DISK.Pages.Size + CALL EMM.GetMemRMD + JR NC,.IMGread ; свободный рамдиск найден + DEC A + JR Z,.FreeMem ; ошибка - недостаточно памяти, вызываем очистку памяти + RET ; непонятная ошибка - выходим +.FreeMem: CALL EMM.FullInit + JR .killRAMdisk +; + +; Вход: A - RAM block ID +.IMGread: + ; Вариант копирования ROM -> RAM disk + _mRECOVERYmountTYPE RECOVERYmountTYPE +; + ;Exit from "ROM Disk to RAM disk" procedure +.RDkey+*: LD A,0 + OR DRIVE_CODES.SPRINTER.RAM + LD B,A ; передаём загрузочное устройство в OS_LOAD + JP OS_LOAD + ; +;[ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ] +; + +PrepareToBOOT: ;CALL INT_ON + HALT + CALL PORTS_INIT.clean_kbd_buf ;Clearing the keyboard buffer + CALL PORTS_INIT.clean_mouse_buf ;Clearing the mouse buffer + CALL INT_OFF + ; тут не должно быть испорчено значение BC + ; [x] 05/07/2024 + INC BC + LD A,B + OR C + JP Z,RECOVERYstart + DEC BC + ; + CALL G_VALUE + LD B,DRIVE_CODES.SPRINTER.FDD + ; FDD + OR A + JR Z,FDSTART ; FDD A: + INC B + DEC A + JR Z,FDSTART ; FDD B: + ; IDE + LD B,DRIVE_CODES.SPRINTER.HDD + DEC A + JR Z,HDSTART + INC B ;LD B,#81 + DEC A + JR Z,HDSTART + INC B ;LD B,#82 + DEC A + JR Z,HDSTART + INC B ;LD B,#83 + DEC A + JR Z,HDSTART + ; RAM + DEC A + JR Z,RDSTART + ; ROM + DEC A + JP Z,RECOVERYstart + ; Error + SCF + RET + +FDSTART: + PUSH BC + PUSH BC + LD A,msgStrings.bootFdd + CALL POSTMSG + POP AF + CALL FDD_5x_RESET + POP BC + RET C + JP OS_LOAD +;!TODO +CDSTART: + PUSH BC + LD A,msgStrings.bootCd + CALL POSTMSG + POP AF + PUSH AF + CALL PRINT_CHANEL + ; + POP BC + SET 6,B + SCF + RET + +RDSTART: + LD A,msgStrings.bootRamDrv + CALL POSTMSG + LD B,DRIVE_CODES.SPRINTER.RAM ; 6 - тип драйва RAM-DRV, 0 - номер драйва +.loop: PUSH BC + CALL OS_LOAD + POP BC + INC B + LD A,DRIVE_CODES.SPRINTER.RAM + SYS_PAGE.RAMD_KEYS.NUM-1 ; максимальный номер рамдиска + SUB B + JR NC,.loop + RET + + +HDSTART: + IN A,(SLOT3) + EX AF,AF' + LD A,SYS_PAGE + OUT (SLOT3),A + LD A,B + ; + AND #03 ;R02 %00000011 + LD IY,IDE.INIT_TBL_IDE0 + JR Z,.next + ; + LD IY,IDE.INIT_TBL_IDE1 + CP 1 ;R02 + JR Z,.next + ; + LD IY,IDE.INIT_TBL_IDE2 ;R02 + CP 2 ;R02 + JR Z,.next + ; + LD IY,IDE.INIT_TBL_IDE3 ;R02 + ; +.next: LD A,(IY+IDE.HDD_INIT_TABLE.DriveType) + EX AF,AF' + OUT (SLOT3),A + EX AF,AF' + CP IDE.Device.CDROM + JP Z,CDSTART + PUSH AF + PUSH BC + LD A,msgStrings.bootHdd + CALL POSTMSG + POP AF + PUSH AF + CALL PRINT_CHANEL + + POP BC + POP AF + CP #FF + SCF + RET Z +OS_LOAD: + LD HL,#0000 + LD IX,#0001 + LD DE,TEMP + LD A,B + LD BC,1*256 + BIOS.DRV_READ + PUSH AF + RST ToBIOS_18 + + POP BC + RET C + LD A,B + EX AF,AF' + LD HL,TEMP + LD DE,SYSID + LD B,SYSID.length +.loop: LD A,(DE) + CP (HL) + SCF + RET NZ + INC HL + INC DE + DJNZ .loop + EX AF,AF' + PUSH AF + LD A,msgStrings.bootOk + LD E,COLORS.CGA.INC.LGREEN + ;CALL POSTMSG + CALL POSTMSC + CALL ScreenPOS.CRLF + POP AF + POP HL +; JP MOVE0 +MOVE0: DI + IM 1 + LD HL,MOVE1 + LD DE,#7C00 ; !HARDCODE + LD BC,MOVE1.length + LDIR + JP #7C00 +MOVE1: LD SP,#7FFF ; !HARDCODE + LD HL,TEMP + LD DE,#8000 ; !HARDCODE + LD BC,#0200 ; !HARDCODE + LDIR + JP #8000+SYSID.length ;#800C ; !HARDCODE +.length EQU $-MOVE1 +SYSID: DZ "Starting..." +.length EQU $-SYSID + +FD144A: DB #80,#12,#02,#50,#00,#00,#02,FDD_INI_TABLE.FDD +FD720A: DB #00,#09,#02,#50,#00,#00,#02,FDD_INI_TABLE.FDD + +FINSTAL: IN A,(SLOT3) + EX AF,AF' + LD A,SYS_PAGE + OUT (SLOT3),A + LD HL,FDD_INI_TABLE.FDD_0 + LD BC,SYS_PAGE.FDD_TBL.Size*256 + #FF ; table_size*256 + fill_byte +.FILLFDD: LD (HL),C + INC HL + DJNZ .FILLFDD + ; + EX AF,AF' + OUT (SLOT3),A + LD BC,CMOS_CELL.DrivesSetup_1.Mask.FirstFDD ;#0311 + CALL G_VALUE + LD HL,FD720A + OR A + JR Z,.SETFD0 + LD HL,FD144A + DEC A + JR NZ,.NOFDD0 +.SETFD0: IN A,(SLOT3) + EX AF,AF' + LD A,SYS_PAGE + OUT (SLOT3),A + LD DE,FDD_INI_TABLE.FDD_0 + LD BC,#0008 ; !HARDCODE + LDIR + EX AF,AF' + OUT (SLOT3),A +.NOFDD0: LD BC,CMOS_CELL.DrivesSetup_1.Mask.SecondFDD ;#0C11 + CALL G_VALUE + LD HL,FD720A + OR A + JR Z,.SETFD1 + LD HL,FD144A + DEC A + JR NZ,.NOFDD1 +.SETFD1: IN A,(SLOT3) + EX AF,AF' + LD A,SYS_PAGE + OUT (SLOT3),A + LD DE,FDD_INI_TABLE.FDD_1 + LD BC,#0008 ; !HARDCODE + LDIR + EX AF,AF' + OUT (SLOT3),A +.NOFDD1: RET + + +PIDNUM: LD HL,memBUFFER.ID + LD BC,#00FF + XOR A + CPIR + LD A,(HL) + OR A + RET Z + CALL PRINTZ + RET + +PIDBOARD: CALL FN_CRIPT.board_id + ; + PUSH AF + PUSH DE + PUSH HL + PUSH BC + LD A,B + CALL PRNHEX + LD A,'-' + CALL PRINT_CHAR + POP BC + LD A,C + CALL PRNHEX + LD A,'-' + CALL PRINT_CHAR + POP HL + CALL IZPRINT + POP DE + PUSH DE + LD A,D + CALL PRNHEX + POP DE + LD A,E + CALL PRNHEX + LD A,' ' + CALL PRINT_CHAR + POP AF + ; type 0 - Classic + RET Z + ; type 1 - DX + LD HL,.ver_DX + DEC A + JP Z,PRINTZ + ; type 2 - DP + LD HL,.ver_DP + DEC A + JP Z,PRINTZ + ; type 3 - Max + LD HL,.ver_Max + DEC A + JP Z,PRINTZ + RET + ; +.ver_DX: DZ "DX" +.ver_DP: DZ "DP" +.ver_Max: DZ "Max" + + +CNF_VER_PRINT: + LD HL,memBUFFER.ID + IFN BIOS.FN_VERSION.STR.BitstreamVer = 0 + LD BC,BIOS.FN_VERSION.STR.BitstreamVer*256 + XOR A +.loop: CPIR + DJNZ .loop + ENDIF + JP PRINTZ + +;PIDNUM LD A,#0D +; LD HL,ID_BUFFER +; LD BC,#0030 +; CPIR +; RET NZ +; INC HL +; LD BC,#0286 +; RST_to_BIOS_18 +; INC HL +; LD BC,#0586 +; RST_to_BIOS_18 +; INC HL +; LD BC,#0286 +; RST_to_BIOS_18 +; XOR A +; RET + +;PIDDATE +; LD A,#0D +; LD HL,ID_BUFFER +; LD BC,#0030 +; CPIR +; RET NZ +; INC HL +; CPIR +; RET NZ +; INC HL +; LD BC,#0A86 +; JP_to_BIOS + +////////////////////////////////////////////////////////////////////// +; INCLUDE 'IM2_INT.asm' +////////////////////////////////////////////////////////////////////// + +PRNHEX: LD D,A + RRCA + RRCA + RRCA + RRCA + AND #0F + ADD A,#30 + CP #3A + JR C,PRNH1 + ADD A,7 +PRNH1: CALL PRINT_CHAR + LD A,D + AND #0F + ADD A,#30 + CP #3A + JP C,PRINT_CHAR + ADD A,7 + JP PRINT_CHAR + +PHEX: LD D,A + RRCA + RRCA + RRCA + RRCA + AND #0F + ADD A,#30 + CALL PRINT_CHAR + LD A,D + AND #0F + ADD A,#30 + JP PRINT_CHAR + +PRNTIME: + IN A,(SLOT3) + PUSH AF + LD A,SYS_PAGE + OUT (SLOT3),A + LD A,(HL) + CALL PHEX + LD A,":" + CALL PRINT_CHAR + INC L + LD A,(HL) + CALL PHEX + LD A,":" + CALL PRINT_CHAR + INC L + LD A,(HL) + CALL PHEX + POP AF + OUT (SLOT3),A + RET + + +PMEMORY: + ADD HL,HL + ADD HL,HL + ADD HL,HL + ADD HL,HL ; * 16 + CALL IPRINT + LD A,"K" + JP PRINT_CHAR + +ZXCLS: LD HL,#4000 + LD DE,#4001 + LD BC,#1AFF + LD (HL),L + LDIR + RET + +GET_ID: LD HL,memBUFFER.ID + ;LD C,BIOS.FN_VERSION + ;JP_to_BIOS + JP FN_VERSION + + +;R01GET_ID +;R01 LD A,#10 +;R01 LD BC,#1FFD +;R01 OUT (C),A +;R01 LD C,SLOT3 +;R01 IN B,(C) +;R01 PUSH BC +;R01 LD A,#EE +;R01 OUT (C),A +;R01 LD HL,#FFD0 +;R01 LD DE,ID_BUFFER +;R01 LD BC,#30 +;R01 LDIR +;R01 POP BC +;R01 OUT (C),B +;R01 XOR A +;R01 LD BC,#1FFD +;R01 OUT (C),A +;R01 RET + + +RCHAIN: + LD E,L + LDI + DEC L + LD L,(HL) + INC L + RET Z + DEC L + JR RCHAIN + +CCHAIN: + LD HL,MEMMAP2 + LD DE,SYS_PAGE.RAMD_FAT + XOR A +CCHAINC: + CP (HL) + JR Z,NOCOPYC + LD E,L + LDI + DEC L +NOCOPYC: + INC L + JR NZ,CCHAINC + LD HL,TPOINTD + LD DE,SYS_PAGE.RAMD_KEYS + LD BC,SYS_PAGE.RAMD_KEYS.NUM + LDIR + RET + +;---------------------------------------------------------------[] +TRQUICK: +;REGISTER #1E +; %0000'0011 - TR DOS A: Default / FDD / HDD / RMD +; %0000'1100 - TR DOS B: Default / FDD / HDD / RMD +; %0011'0000 - TR DOS C: Default / FDD / HDD / RMD +; %1100'0000 - TR DOS D: Default / FDD / HDD / RMD + LD BC,CMOS_CELL.TRDOSmount.Mask.A ;#031E + LD A,0 + CALL TRDOSX + LD BC,CMOS_CELL.TRDOSmount.Mask.B ;#0C1E + LD A,1 + CALL TRDOSX + LD BC,CMOS_CELL.TRDOSmount.Mask.C ;#301E + LD A,2 + CALL TRDOSX + LD BC,CMOS_CELL.TRDOSmount.Mask.D ;#C01E + LD A,3 +TRDOSX: ; PUSH AF + ; CALL G_VALUE + ; POP BC + ; OR A + ; RET Z + ; LD C,BIOS.FDD_TO_DRV + ; DEC A + ; JP Z,ToBIOS_18 + ; LD C,BIOS.HDD_TO_DRV + ; DEC A + ; JP Z,ToBIOS_18 + ; SCF + ; RET + PUSH AF + CALL G_VALUE + POP BC + OR A + RET Z + DEC A + JP Z,FDD_TO_DRV + DEC A + JP Z,HDD_TO_DRV + SCF + RET +;---------------------------------------------------------------[] + + +;!TODO посмотреть + ;открывает порт #FE на чтение в 3-й карте портов + ;OPENDOS: + ; DI + ; IN A,(SLOT3) + ; EX AF,AF' + ; LD A,#40 + ; OUT (SLOT3),A + ; LD HL,#C000 + ; LD DE,#F000 + ; LD BC,#0400 + ; LDIR + ; LD A,#40 + ; LD (#F26E),A + ; LD (#F27E),A + ; LD (#F2EE),A + ; LD (#F2FE),A + ; LD (#F36E),A + ; LD (#F37E),A + ; LD (#F3EE),A + ; LD (#F3FE),A + ; LD HL,#F000 + ; LD DE,#F400 + ; LD BC,#0C00 + ; LDIR + ; EX AF,AF' + ; OUT (SLOT3),A + ; RET +; + + + +setFRAME: +.double: + LD HL,.dataDoubleAll + JR .setElements +.single: + LD HL,.dataSingleAll + JR .setElements +.high: LD HL,.dataSingleDown + JR .setElements +.low: LD HL,.dataSingleUp + JR .setElements +.medium: + LD HL,.dataSingleMedium +; JR .setElements +.setElements: + LD DE,ElementsBuffer + LD BC,ElementsBuffer.Size + LDIR + RET + +.dataDoubleAll: BYTE "╔╗═║╚╝", "╠╣╦╩" ; #C9,#BB,#CD,#BA,#C8,#BC, #CC,#B9,#CB,#CA +.dataSingleAll: BYTE "┌┐─│└┘", "├┤┬┴" ; #DA,#BF,#C4,#B3,#C0,#D9, #C3,#B4,#C2,#C1 +.dataSingleDown: BYTE "╔╗─║╟╢", "╟╢╤┴" ; #C9,#BB,#C4,#BA,#C7,#B6, #C7,#B6,#D1,#C1 +.dataSingleUp: BYTE "╟╢─║╚╝", "╟╢┬╧" ; #C7,#B6,#C4,#BA,#C8,#BC, #C7,#B6,#C2,#CF +.dataSingleMedium: BYTE "╟╢─║╟╢", "╟╢┬┴" ; #C7,#B6,#C4,#BA,#C7,#B6, #C7,#B6,#C2,#C1 +; +ElementsBuffer: +.UpLeft: BYTE "┌" ; UL - UpLeft +.UpRight: BYTE "┐" ; UR - UpRight +.HorizontalLine: BYTE "─" ; ZL - HorizontalLine +.VerticalLine: BYTE "│" ; VL - VerticalLine +.DownLeft: BYTE "└" ; LL - DownLeft +.DownRight: BYTE "┘" ; LR - DownRight +.LeftCenter: BYTE "├" ; LC - LeftCenter +.RightCenter: BYTE "┤" ; RC - RightCenter +.UpCenter: BYTE "┬" ; UC - UpCenter +.DownCenter: BYTE "┴" ; DC - DownCenter +.Size EQU $-ElementsBuffer +; + + INCLUDE 'VIDEO_IO.asm' + INCLUDE 'AUTOIDE.asm' + INCLUDE 'SETTINGS.asm' + INCLUDE 'KEY.asm' +;....................................... + +KEY: EI + JP WAITKEY + +FindStringAddr: + LD L,A + LD H,0 + LD BC,memBUFFER.Messages + ADD HL,HL + ADD HL,BC + LD A,(HL) + INC HL + LD H,(HL) + LD L,A + RET + +POSTLEN: + CALL FindStringAddr + LD BC,#0100 + XOR A + CPIR + LD A,#FF + SUB C + SRL A + LD C,A + LD A,40 + SUB C + LD E,A + ;JP ScreenPOS.LOCAT + JP LP_SET_PLACE + +SETLAND: + LD A,#0E ; !HARDCODE CMOS ячейка options + CALL READCMS + AND #04 ; !HARDCODE CMOS значение языка + JR NZ,.RUS + ; + LD HL,MSG_ENG + LD DE,memBUFFER.Messages + LD BC,MSG_ENG.size + LDIR + RET + ; +.RUS: LD HL,MSG_RUS + LD DE,memBUFFER.Messages + LD BC,MSG_RUS.size + LDIR + RET + +////////////////////////////////////////////////////////////////////// + INCLUDE 'IM2_INT.asm' +////////////////////////////////////////////////////////////////////// + +POSTMSG: + CALL FindStringAddr + JP PRINTZ + +POSTMSC: + CALL FindStringAddr + LD A,E + JP CPRINTZ + +; +; print boot drive number +PRINT_CHANEL: + AND #0F + LD C,A + ; + LD A,msgStrings.parPriIdeMA + JR Z,.print_chanel + ; + LD A,msgStrings.parPriIdeSl + DEC C + JR Z,.print_chanel + ; + LD A,msgStrings.parSecIdeMA + DEC C + JR Z,.print_chanel + ; + LD A,msgStrings.parSecIdeSl +.print_chanel: + CALL FindStringAddr + ;CALL LP_GET_PLACE + ;LD A,ScreenPOS.SUBNAME.POS + ;SUB E + ;LD B,A + LD B,0 + LD D,#FF + JP LP_PRINT_LINE6 +; + +;----------------------------------------------------------------------[] +;!TODO сделать выбор в Setup, что грузить в vПЗУ при старте. Варианты: +;[ ] 0 - Не грузить ПЗУ спектрума, инитить страницу #41 как в 3.04 +;[ ] 1 - Грузит ПЗУ спектрума из ROM при старте если нет флага ZX +;[ ] 2 - Грузит ПЗУ спектрума из ROM при каждом перезапуске +;[ ] 3 - Не грузить ПЗУ спектрума, инитить страницу #41 так, +; чтоб код в ней подгружал ПЗУ спектрума при обращении +ZXMODE_SETUP: IN A,(SLOT3) + PUSH AF + LD A,Spec_Page + OUT (SLOT3),A + ; + LD BC,CMOS_CELL.Options.Mask.LoadZXroms + CALL G_VALUE + ; + OR A + JR Z,.init_41h + DEC A + JR Z,.CheckAndLoad + DEC A + JR Z,.Load_ZXROMS + ;!TODO + ;DEC A + ;JR Z,.New_init_41h + ; + ; Check ZX ROMS Loaded +.CheckAndLoad: LD A,(Spec_Page.flag_Z) + CP 'Z' + JR NZ,.Load_ZXROMS + LD A,(Spec_Page.flag_X) + CP 'X' + JR NZ,.Load_ZXROMS + ; [x] 31/12/23 подстраховка от недоутечки памяти + LD A,R + AND #80 + JR Z,.No_Need_To_Load_ZXROMS +.Load_ZXROMS: XOR A + LD R,A + ; + ; Load ZX ROM's + call init_zx_roms + ; + LD HL,#C000 + LD DE,#C001 + LD BC,#3FFF + LD (HL),C + LDIR ; забить FF-ами + ; ставим метку если прогрузили ПЗУ спектрума + DEC DE ; Spec_Page.flag_X + LD A,'X' + LD (DE),A + DEC DE ; Spec_Page.flag_Z + LD A,'Z' + LD (DE),A + ; Заглушка для страницы #41 на всякий пожарный +.init_41h: LD HL,PROG_NO_ROM + LD DE,#C000 + Spec_Page.no_zx_rom + LD BC,PROG_NO_ROM.size + LDIR + ; + LD HL,RAM_BIOS_PROG + LD DE,#C000 + Spec_Page.to_bios + LD BC,RAM_BIOS_PROG.Length + LDIR +.No_Need_To_Load_ZXROMS: + POP AF + OUT (SLOT3),A + RET + +; +;--------------------[copy zx-roms to zx-pages]-----------------; +; SLOT0 - ROM 8, sys_port - on. +; RAM SLOT0 - page 0 +; для режима zx spectrum +; ВЫПОЛНЯЕТСЯ ИЗ ОЗУ +; !HARDCODE номера страниц для эмулятора ПЗУ +init_zx_roms: IN A,(SLOT3) + EX AF,AF' + ; + DI + LD A,SYS_PORT.EXTENSION + OUT (SYS_PORT.ROM),A + INC A ;!HARDCODE LD A,2 + LD B,3 ; zx-rom number of pages + ; +.loop: EXX + ; + out (ROM.SLOT0),a + or %0100'0000 ; !HARDCODE номера страниц для эмулятора ПЗУ + out (SLOT3),a + and %1011'1111 ; !HARDCODE номера страниц для эмулятора ПЗУ + ; + LD HL,0 + LD DE,#C000 + LD BC,#4000 + LDIR + ; + INC A + EXX + DJNZ .loop + ; + xor a + out (ROM.SLOT0),a + OUT (SYS_PORT.ROM),A + EX AF,AF' + out (SLOT3),a + ; + ;[x] SET_PORTS: no need to call from #3D13 and DI. 31/12/23 + LD A,ACEX.vROM.BASIC_128 ; ROM-ID - BASIC 128 + LD B,#42 ;!HARDCODE page + CALL SET_PORTS + ; + LD A,ACEX.vROM.BASIC_48 ; ROM-ID - BASIC 48 + LD B,#43 ;!HARDCODE page + CALL SET_PORTS + ; + LD A,ACEX.vROM.TR_DOS ; ROM-ID - TR-DOS + LD B,#44 ;!HARDCODE page + CALL SET_PORTS + ; + ; эти страницы пока не используются + LD A,ACEX.vROM.BIOS ; ROM-ID - BIOS + ;LD B,#45 ;!HARDCODE page + LD B,#41 + CALL SET_PORTS + ; + LD A,ACEX.vROM.BIOS_3 ; ROM-ID - BIOS-1 + ;LD B,#46 ;!HARDCODE page + LD B,#41 + CALL SET_PORTS + ; + LD A,ACEX.vROM.BIOS_4 ; ROM-ID - BIOS-2 + ;LD B,#47 ;!HARDCODE page + LD B,#41 + JP SET_PORTS + ; можно задействовать ещё 4 страницы на порты #E4..#E7 +;---------------------------------------------------------------------[] + + +;--------------------------------------- + INCLUDE 'src/bios/ROM/SETUP/messages.z80' +;--------------------------------------- +; + + STRUCT MAIN_BUFFERS +ID BLOCK #100 +Messages BLOCK MSG_ENG.size +Shared BLOCK 1024 +End BYTE + ENDS + + +memBUFFER MAIN_BUFFERS = $ +STACK EQU #C000 +.size EQU 128 + + + IF memBUFFER.End-1 > #C000-STACK.size + DISPLAY 'memBUFFER.Shared overlaps STACK by: ',/A,(memBUFFER.End-1)-(#C000-STACK.size) + ASSERT memBUFFER.End-1 < #C000-STACK.size + ENDIF + + IFDEF PREBUILD + OUTEND + + DISPLAY '-----[Set_Pictures Prebuild start]-----' + MMU 1 e, 0 ; страница 0 в банку 0 и проверка на границы. + ORG ROM_MAP.LOGO + INCLUDE 'src/bios/logo/Set_Pictures.asm' + DISPLAY '-----[Set_Pictures Prebuild done ]-----' + ELSE + DISPLAY '------------------[Main.asm]------------------' + DISPLAY 'End code address: ',/A,$-1 + DISPLAY 'Code size: ',/A,$-COMPILE_ADDR.MAIN + DISPLAY 'End buffers address: ',/A,memBUFFER.End-1 + DISPLAY 'Free memory: ',/A,#C000-(memBUFFER.End-1)-STACK.size + DISPLAY 'Unused bytes before INT_POINTER: ',/A,INT_POINTER-before_intPointer + ENDIF +; \ No newline at end of file diff --git a/Crazy BIOS/rom/SETUP/SETTINGS.asm b/Crazy BIOS/rom/SETUP/SETTINGS.asm new file mode 100644 index 0000000..175269b --- /dev/null +++ b/Crazy BIOS/rom/SETUP/SETTINGS.asm @@ -0,0 +1,1096 @@ +;U_SETUP: +SETTINGS: + LD A,CMOS_CELL.ScreenSET + CALL READCMS + AND high CMOS_CELL.ScreenSET.Mask.ColorStyle + LD L,A + CALL CSET + LD DE,0 + LD HL,#2050 + LD A,(NORCLR) + LD B,A + CALL LP_CLS_WIN + + + LD A,msgStrings.setupBiosVer + LD DE,#0100 ; ????? + CALL POSTLEN + LD A,msgStrings.setupBiosVer + CALL POSTMSG + LD A,msgStrings.setupCopyRight + LD DE,#0200 + CALL POSTLEN + LD A,msgStrings.setupCopyRight + CALL POSTMSG + LD A,msgStrings.setupUtilityVer + LD DE,#0500 + CALL POSTLEN + LD A,msgStrings.setupUtilityVer + CALL POSTMSG + + CALL setFRAME.double + + LD DE,#0402 + LD BC,#1A4C + CALL PBORDER + + CALL setFRAME.medium + + LD DE,#0602 + LD BC,#134C + CALL PBORDER ;!FIXIT + + CALL setFRAME.single + + LD DE,#062A + LD H,#13 + CALL TLINEV + + LD DE,#1906 + ;CALL ScreenPOS.LOCAT + CALL LP_SET_PLACE + LD A,msgStrings.setupHelpStr1 + CALL POSTMSG + LD DE,#1A06 + ;CALL ScreenPOS.LOCAT + CALL LP_SET_PLACE + LD A,msgStrings.setupHelpStr2 + CALL POSTMSG + LD DE,#1B06 + ;CALL ScreenPOS.LOCAT + CALL LP_SET_PLACE + LD A,msgStrings.setupHelpStr3 + CALL POSTMSG + LD DE,#1C06 + ;CALL ScreenPOS.LOCAT + CALL LP_SET_PLACE + LD A,msgStrings.setupHelpStr4 + CALL POSTMSG + LD BC,SettingsItemsTabsAddrs.max*256 + + + IF NEW_FEATURE + + ; LD HL,CurrentDateTime + ; CALL GETTIME + + ; LD HL,CurrentDateTime + + ; LD A,(HL) + ; AND #F0 + + ENDIF + + +STT1: LD A,C + LD (ITEM),A + PUSH BC + CALL PTEXT + POP BC + INC C + DJNZ STT1 + + LD a,(ITEM_Restore) + LD (ITEM),A + CALL PCURSOR + +AGAIN: LD HL,AGAIN + PUSH HL + CALL KEY +; CURSOR DOWN + LD HL,#5200 + AND A + SBC HL,DE + JP Z,INCITM +; CURSOR UP + LD HL,#5800 + AND A + SBC HL,DE + JP Z,DECITM +; CURSOR RIGHT + LD HL,#5600 + AND A + SBC HL,DE + JP Z,ADDITM +; CURSOR LEFT + LD HL,#5400 + AND A + SBC HL,DE + JP Z,SUBITM +; + + LD HL,#5300 + AND A + SBC HL,DE + JP Z,INCVAL +; - + LD HL,#5900 + AND A + SBC HL,DE + JP Z,DECVAL +; + or - + LD HL,#A400 + AND A + SBC HL,DE + JP Z,INCVAL + CP "+" + JP Z,INCVAL + CP "-" + JP Z,DECVAL + + IF NEW_FEATURE +; ENTER + LD HL,#280D + AND A + SBC HL,DE + JP Z,pressedEnter + ENDIF + +; F2 + LD HL,#3C00 + AND A + SBC HL,DE + JP Z,SAVEV +; F3 + LD HL,#3D00 + AND A + SBC HL,DE + JP Z,CCHANGE +; F5 + LD HL,#3F00 + AND A + SBC HL,DE + JP Z,OLD_VAL +; F7 + LD HL,#4100 + AND A + SBC HL,DE + JP Z,DEF_VAL +; F10 + LD HL,#4400 + AND A + SBC HL,DE + JP Z,SAVEXIT +; ESC + LD HL,#011B + AND A + SBC HL,DE + RET NZ + POP HL + RET + +OLD_VAL: + CALL READING + JR RestartSetup + RET + +DEF_VAL: + CALL SETDEF +;--------------------------------------- +RestartSetup: +;setXYpos + CALL RESCREEN +;setLang + CALL SETLAND +;setVsinc + CALL OnChangeAction.setVsinc +;setInt - Должна быть последней!!! + JP OnChangeAction.setInt +;--------------------------------------- + +SAVEXIT: + CALL WRITING + POP HL + RET + +SAVEV: + CALL WRITING + RET + +SUBITM: + CALL RCURSOR + LD A,(ITEM) + SUB 17 ; !HARDCODE max items in column + JR NC,GODITM2 + XOR A +GODITM2: + LD (ITEM),A + JP PCURSOR + +ADDITM: + CALL RCURSOR + LD A,(ITEM) + ADD A,17 ; !HARDCODE max items in column + CP SettingsItemsTabsAddrs.max + JR C,GODITM + LD A,SettingsItemsTabsAddrs.max + DEC A +GODITM: + LD (ITEM),A + JP PCURSOR + +INCITM: CALL RCURSOR + LD A,(ITEM) + INC A + CP SettingsItemsTabsAddrs.max + JR NZ,1F + XOR A +1: LD (ITEM),A + JP PCURSOR + +DECITM: + CALL RCURSOR + LD A,(ITEM) + OR A + JR NZ,1F + LD A,SettingsItemsTabsAddrs.max +1: DEC A + LD (ITEM),A + JP PCURSOR + +CCHANGE: + LD A,CMOS_CELL.ScreenSET + CALL READCMS + INC A + AND high CMOS_CELL.ScreenSET.Mask.ColorStyle + LD L,A + LD B,A + LD A,CMOS_CELL.ScreenSET + CALL WRITCMS +CSET: LD H,0 + LD DE,STYLES + ADD HL,HL + ADD HL,HL + ADD HL,DE + LD DE,NORCLR + LDI + LDI + LDI + LDI + CALL FSCREEN + ; + ;REFRESH: + LD BC,SettingsItemsTabsAddrs.max*256 + LD A,(ITEM) + PUSH AF +STT2: LD A,C + LD (ITEM),A + PUSH BC + CALL PTEXT + POP BC + INC C + DJNZ STT2 + POP AF + LD (ITEM),A + CALL PCURSOR + RET + +PTEXT: call Get_Item_Address + JP PITEM + +;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\-[v] + IF NEW_FEATURE +; New procedure with IY reg +LocateCursor: + call Get_Item_Address + LD E,(IY+MenusItem.Column) + LD D,(IY+MenusItem.Line) + ld a,(IY+MenusItem.Name) + push iy + call FindStringAddr + LD BC,#0100 + XOR A + CPIR + LD A,#FF + SUB C + ADD A,E + LD E,A + ;CALL ScreenPOS.LOCAT + CALL LP_SET_PLACE + pop iy + ld a,(iy+MenusItem.FirstString) + call FindStringAddr + LD BC,#0100 + XOR A + CPIR + LD A,#FF + SUB C + LD B,A + ret + + ELSE +LocateCursor: + call Get_Item_Address + LD E,(HL) + INC HL + LD D,(HL) + INC HL + ld a,(hl) + inc hl + push hl + call FindStringAddr + LD BC,#0100 + XOR A + CPIR + LD A,#FF + SUB C + ADD A,E + LD E,A + ;CALL ScreenPOS.LOCAT + CALL LP_SET_PLACE + pop hl + INC HL ;SKIP REGISTER + INC HL ;SKIP MASK + INC HL ;SKIP MAX VALUE + ld a,(hl) + call FindStringAddr + LD BC,#0100 + XOR A + CPIR + LD A,#FF + SUB C + LD B,A + ret + ENDIF +;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\-[^] + +PCURSOR: + call LocateCursor + LD A,(CURCLR) + JP PRINTA + +RCURSOR: + call LocateCursor + LD A,(NORCLR) + JP PRINTA + +FSCREEN: + LD DE,#0000 + EI + HALT +FSC1: + PUSH DE + CALL LP_SET_PLACE + + LD A,(NORCLR) + LD E,A + LD B,#50 + CALL LP_PRINT_ATR + + POP DE + LD A,#20 + INC D + CP D + JR NZ,FSC1 + RET + +ITEM: DB #00 +ITEM_Restore: DB #00 + +NORCLR: DB COLORS.CGA.PAPER.BLUE + COLORS.CGA.INC.WHITE +HLTCLR: DB COLORS.CGA.PAPER.BLUE + COLORS.CGA.INC.YELLOW +CURCLR: DB COLORS.CGA.PAPER.RED + COLORS.CGA.INC.WHITE +WRMCLR: DB COLORS.CGA.PAPER.BLUE + COLORS.CGA.INC.WHITE + + +;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\-[v] + IF NEW_FEATURE +; New procedure with IY reg +INCVAL: call Get_Item_Address + ld A,(IY+MenusItem.Type) + AND A + RET NZ ; проверка на тип, дальше если paramLine + + LD A,(IY+MenusItem.CMOSreg) + PUSH AF + CALL READCMS + LD C,A + AND (IY+MenusItem.ValueMask) + CP (IY+MenusItem.ValueMax) + LD A,C + JR Z,OVERI + LD B,(IY+MenusItem.ValueMask) + CALL ADDVAL + ADD A,B + JR OVER +OVERI: XOR (IY+MenusItem.ValueMax) +OVER: LD B,A + POP AF + CALL WRITCMS + PUSH IY + PUSH IY + POP HL + CALL PITEM + POP IY + ld l,(IY+MenusItem.Action) + ld h,(IY+MenusItem.Action+1) + jp (hl) + +DECVAL: call Get_Item_Address + ld A,(IY+MenusItem.Type) + AND A + RET NZ ; проверка на тип, дальше если paramLine + + LD A,(IY+MenusItem.CMOSreg) + PUSH AF + CALL READCMS + LD C,A + AND (IY+MenusItem.ValueMask) + LD A,C + JR Z,OVERD + LD B,(IY+MenusItem.ValueMask) + CALL ADDVAL + SUB B + JR OVER +OVERD: OR (IY+MenusItem.ValueMax) + JR OVER + + +pressedEnter: +; !TODO New Feature + ld a,(iy+MenusItem.Type) + and a + ret z + ld l,(iy+MenusItem.Action) + ld h,(iy+MenusItem.Action+1) + jp (HL) + + ELSE +INCVAL: call Get_Item_Address + INC HL + INC HL + INC HL + LD A,(HL) + INC HL + PUSH AF + CALL READCMS + LD C,A + AND (HL) + INC HL + CP (HL) + LD A,C + JR Z,OVERI + DEC HL + LD B,(HL) + CALL ADDVAL + ADD A,B + JR OVER +OVERI: XOR (HL) +OVER: LD B,A + POP AF + CALL WRITCMS + CALL PTEXT + call Get_Item_Address + dec hl + ld a,(hl) + dec hl + ld l,(hl) + ld h,a + jp (hl) + +DECVAL: call Get_Item_Address + INC HL + INC HL + INC HL + LD A,(HL) + INC HL + PUSH AF + CALL READCMS + LD C,A + AND (HL) + LD A,C + INC HL + JR Z,OVERD + DEC HL + LD B,(HL) + CALL ADDVAL + SUB B + JR OVER +OVERD: + OR (HL) + JR OVER + + ENDIF +;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\-[^] + +; B - MASK +ADDVAL: LD C,#00 +ADDV1: INC C + RRC B + JR NC,ADDV1 + LD B,#80 +ADDV2: RLC B + DEC C + JR NZ,ADDV2 + RET + +;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\-[v] + IF NEW_FEATURE +; IY - item's address +; New procedure with IY reg +PITEM: LD E,(IY+MenusItem.Column) ; x-coordinate + LD D,(IY+MenusItem.Line) ; y-coordinate + ;CALL ScreenPOS.LOCAT + CALL LP_SET_PLACE ; set position of item + LD A,(IY+MenusItem.Name) + CALL POSTMSG + + PUSH IY + LD BC,MenusItem.FirstString + ADD IY,BC + EX (SP),IY + POP HL ; тут адрес строки первого параметра + + LD A,(IY+MenusItem.Type) + AND A + JR NZ,.printParameter ; если это не строка с изменяемым параметром, то просто печать + + LD A,(IY+MenusItem.CMOSreg) ; address of next parametr + CALL READCMS ; read item`s value from cmos + + LD B,(IY+MenusItem.ValueMask) ; item's value mask + AND B +.getParameterNum: + RRCA + RRC B + JR NC,.getParameterNum + RLCA + OR A + jr Z,.printParameter ; первый параметр выводим? + + ld c,a + xor a + ld b,a + add hl,bc ; находим номер параметра +.printParameter: + ld a,(hl) + jp POSTMSG + + ELSE +; !FIXIT вызовы процедур биоса надеются на то, что некоторые регистры не портятся +; HL - item's address +PITEM: LD E,(HL) ; x-coordinate + INC HL + LD D,(HL) ; y-coordinate + INC HL ; address of next parametr + PUSH HL + CALL LP_SET_PLACE ; set position of item + LD A,(HL) + CALL POSTMSG + POP HL + INC HL + LD A,(HL) ; address of next parametr + CALL READCMS ; read item`s value from cmos + INC HL + LD B,(HL) ; item's value mask + INC HL + INC HL + AND B +.getParameterNum: + RRCA + RRC B + JR NC,.getParameterNum + RLCA + OR A + jr Z,.printParameter ; первый параметр выводим? + + ld c,a + xor a + ld b,a + add hl,bc ; находим номер параметра +.printParameter: + ld a,(hl) + jp POSTMSG + ENDIF +;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\-[^] + +; Не портит HL +G_VALUE: + PUSH BC + LD A,C + CALL READCMS + POP BC + AND B +.loop: RRCA + RRC B + JR NC,.loop + RLCA + RET + +; [x] чтоб не влезло куда не надо +READCMS: + LD D,high CMOSARE + LD E,A + CP CMOS.USED_MAX_ADDRESS+1 + JR NC,.error + LD A,(DE) + RET +.error: SCF + RET + +; [x] чтоб не влезло куда не надо +WRITCMS: + LD D,high CMOSARE + LD E,A + CP CMOS.USED_MAX_ADDRESS+1 + JR NC,.error + LD A,B + LD (DE),A + RET +.error: SCF + RET + +CHEKSUM: + LD BC,DEFVAL.Size*256 + CMOS.USED_MIN_ADDRESS + LD H,#DE ;!HARDCODE +.loop: LD A,C + CALL READCMS + LD L,A + LD A,H + SUB L + RLCA + SUB L + LD H,A + INC C + DJNZ .loop + RET + +TCHEKSM: + CALL CHEKSUM + LD A,CMOS_CELL.CheckSum + CALL READCMS + CP H + RET + +; TSTCMOS: +; LD C,BIOS.CMOS_TEST +; JP_to_BIOS + + +; RDCMOS: +; LD C,BIOS.CMOS_RD +; JP_to_BIOS + +; WRCMOS: +; LD C,BIOS.CMOS_WR +; JP_to_BIOS + +READING: + LD D,CMOS.USED_MIN_ADDRESS +.loop: PUSH DE + CALL CMOS_RD + POP DE + LD H,high CMOSARE + LD L,D + LD (HL),A + LD A,CMOS.USED_MAX_ADDRESS+1 + INC D + CP D + JR NZ,.loop + RET + +WRITING: + CALL CHEKSUM + LD B,H + LD A,CMOS.Cell.CheckSum + CALL WRITCMS + LD D,CMOS.USED_MIN_ADDRESS ; !HARDCODE CMOS +.loop: + LD H,high CMOSARE + LD L,D + LD A,(HL) + PUSH DE + CALL CMOS_WR + + POP DE + LD A,CMOS.USED_MAX_ADDRESS+1 + INC D + CP D + JR NZ,.loop + RET + +SETDEFX: + LD A,#FF + LD (ERRSUM),A + CALL SETDEF + JP WRITING + +SETDEF: ;!TODO может бахнуть LDIRом? посмотреть + LD HL,DEFVAL + LD C,DEFVAL.Size + LD A,CMOS.USED_MIN_ADDRESS +.loop: + LD B,(HL) + INC HL + PUSH AF + CALL WRITCMS + POP AF + INC A + DEC C + JR NZ,.loop + + LD A,CMOS_CELL.ZX_RST_TO + LD B,CMOS_CELL.ZX_RST_TO.BASIC_128 + CALL WRITCMS + + LD A,CMOS_CELL.ZX_CONFIG + LD B,CMOS_CELL.ZX_CONFIG.ZX_Sprinter + CALL WRITCMS + + CALL CHEKSUM + LD B,H + LD A,CMOS_CELL.CheckSum + CALL WRITCMS + RET + +;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\-[v] +; New procedure with IY reg + IF NEW_FEATURE +Get_Item_Address: + LD A,(ITEM) + LD L,A + LD H,0 + LD DE,SettingsItemsTabsAddrs + ADD HL,HL + ADD HL,DE + LD A,(HL) + INC HL + LD H,(HL) + LD L,A + PUSH HL + POP IY + RET + + ELSE +Get_Item_Address: + LD A,(ITEM) + LD L,A + LD H,0 + LD DE,SettingsItemsTabsAddrs + ADD HL,HL + ADD HL,DE + LD A,(HL) + INC HL + LD H,(HL) + LD L,A + INC HL + INC HL + RET + ENDIF +;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\-[^] +; + MODULE OnChangeAction +nothing: + ret + + ; !TODO New Feature + ; !TODO замутить что-то типа API для рисования всплывающих окон + IF NEW_FEATURE +SetTime: + xor a + ld hl,#050E + ld de,#0C20 + ld ix,memBUFFER.Shared + CALL WIN_COPY + + LD DE,#0C20 ; !HARDCODE + ld b,5 + DI + +.loop: push bc + push de + CALL LP_SET_PLACE + ; печать атрибутов + LD E,COLORS.CGA.INC.RED + LD B,#0E + CALL LP_PRINT_ATR + + pop de + inc d + pop bc + DJNZ .loop + + CALL setFRAME.single + LD DE,#0C20 ;yx. y=0..1F, x=0..4F координаты левого верхнего угла + LD BC,#050E ;yx. длина и высота линии + CALL PBORDER + + CALL KEY + xor a + ld hl,#050E + ld de,#0C20 + ld ix,memBUFFER.Shared + JP WIN_RESTORE + ENDIF + +setXYpos: + JP RESCREEN + +setVsinc: + ld a,CMOS_CELL.ScreenSET + call READCMS + and high CMOS_CELL.ScreenSET.Mask.Sinc + SCF + jr z,.skip ;320 + SLA A +.skip: ld a,128+7 ;312 + jp nc,FN_SYNC + dec a ;320 +.set: jp FN_SYNC + +setLang: + CALL SETLAND + ld a,(ITEM) + ld (ITEM_Restore),a + pop hl ; delete return adress from stack + jp SETTINGS +setInt: ld a,CMOS_CELL.ScreenSET + call READCMS + and high CMOS_CELL.ScreenSET.Mask.Int + jr nz,.skipDefaultInt + ld a,2 ; Pentagon sync - default + jr .set + +.skipDefaultInt: + SRA A + SRA A + SRA A + SRA A ; byte %00xx0000 --> %000000xx +.set: CALL FN_SYNC + + LD IX,win_descriptor.tab80x32 + LD HL,#0000 + LD E,1 + CALL WIN_OPEN + + ld a,(ITEM) + ld (ITEM_Restore),a + pop hl ; delete return adress from stack + jp SETTINGS + ENDMODULE +; +;-----------------------------------------------------------------------; +;!FIXIT прибраться тут +MEMTEST EQU #80 +SAVERAM EQU #40 +EXTBIOS EQU #20 + +SDELAY2 EQU #10 +SDELAY1 EQU #08 +SDELAY0 EQU #00 +RUS EQU #04 +QSTART EQU #01 + +TMAT_ON EQU #80 +TDL250 EQU #00 +TDL500 EQU #20 +TDL750 EQU #40 +TDL1000 EQU #60 +TRATE6 EQU #00 +TRATE8 EQU #01 +TRATE10 EQU #02 +TRATE12 EQU #03 +TRATE15 EQU #04 +TRATE20 EQU #05 +TRATE24 EQU #06 +TRATE30 EQU #07 +SDFDD1 EQU #00 +SDFDD2 EQU #01 +SDIDE1 EQU #02 +SDIDE2 EQU #03 +SDRAM EQU #04 +ASDFDD1 EQU #00 +ASDFDD2 EQU #10 +ASDRECOVERY EQU #70 +ASDIDE1 EQU #20 +ASDIDE2 EQU #30 +ASDRAM EQU #40 +FD1720 EQU #00 +FD1144 EQU #01 +FD1NONE EQU #02 +FD2720 EQU #00 +FD2144 EQU #04 +FD2NONE EQU #08 +HD1AUTO EQU #00 +HD1STP EQU #01 +HD1NONE EQU #02 +HD2AUTO EQU #00 +HD2STP EQU #04 +HD2NONE EQU #08 +TURBOFF EQU #06 +TURBON EQU #07 +SPRIN EQU #00 +SCORP EQU #08 +PENT EQU #10 +USER EQU #18 +BAS128 EQU #00 +BAS48_ EQU #01 +TRD128 EQU #02 +EXPN EQU #03 +TRD48 EQU #04 +BAS48 EQU #05 +REBOOTM EQU #02 +HDDWP EQU #01 +;-----------------------------------------------------------------------; + +STYLES: +; Color Style 0 + DB COLORS.CGA.PAPER.BLUE + COLORS.CGA.INC.WHITE + DB COLORS.CGA.PAPER.BLUE + COLORS.CGA.INC.YELLOW + DB COLORS.CGA.PAPER.RED + COLORS.CGA.INC.WHITE + DB COLORS.CGA.PAPER.BLUE + COLORS.CGA.INC.WHITE +; Color Style 1 + DB COLORS.CGA.PAPER.BLUE + COLORS.CGA.INC.LGREEN + DB COLORS.CGA.PAPER.BLUE + COLORS.CGA.INC.LMAGENT + DB COLORS.CGA.PAPER.MAGENTA + COLORS.CGA.INC.WHITE + DB COLORS.CGA.PAPER.BLUE + COLORS.CGA.INC.WHITE +; Color Style 2 + DB COLORS.CGA.PAPER.GREEN + COLORS.CGA.INC.LCYAN + DB COLORS.CGA.PAPER.GREEN + COLORS.CGA.INC.YELLOW + DB COLORS.CGA.PAPER.CYAN + COLORS.CGA.INC.BLACK + DB COLORS.CGA.PAPER.GREEN + COLORS.CGA.INC.BLACK +; Color Style 3 + DB COLORS.CGA.PAPER.CYAN + COLORS.CGA.INC.BLACK + DB COLORS.CGA.PAPER.CYAN + COLORS.CGA.INC.YELLOW + DB COLORS.CGA.PAPER.GREEN + COLORS.CGA.INC.BLACK + DB COLORS.CGA.PAPER.CYAN + COLORS.CGA.INC.LGREEN +; Color Style 4 + DB COLORS.CGA.PAPER.CYAN + COLORS.CGA.INC.WHITE + DB COLORS.CGA.PAPER.CYAN + COLORS.CGA.INC.BLACK + DB COLORS.CGA.PAPER.LGRAY + COLORS.CGA.INC.BLUE + DB COLORS.CGA.PAPER.CYAN + COLORS.CGA.INC.YELLOW +; Color Style 5 + DB COLORS.CGA.PAPER.CYAN + COLORS.CGA.INC.BLACK + DB COLORS.CGA.PAPER.CYAN + COLORS.CGA.INC.BROWN + DB COLORS.CGA.PAPER.BROWN + COLORS.CGA.INC.LGRAY + DB COLORS.CGA.PAPER.CYAN + COLORS.CGA.INC.WHITE +; Color Style 6 + DB COLORS.CGA.PAPER.RED + COLORS.CGA.INC.YELLOW + DB COLORS.CGA.PAPER.RED + COLORS.CGA.INC.WHITE + DB COLORS.CGA.PAPER.BLACK + COLORS.CGA.INC.GREEN + DB COLORS.CGA.PAPER.RED + COLORS.CGA.INC.GREEN +; Color Style 7 + DB COLORS.CGA.PAPER.RED + COLORS.CGA.INC.LGRAY + DB COLORS.CGA.PAPER.RED + COLORS.CGA.INC.WHITE + DB COLORS.CGA.PAPER.BLUE + COLORS.CGA.INC.WHITE + DB COLORS.CGA.PAPER.RED + COLORS.CGA.INC.WHITE +; Color Style 8 + DB COLORS.CGA.PAPER.MAGENTA + COLORS.CGA.INC.LCYAN + DB COLORS.CGA.PAPER.MAGENTA + COLORS.CGA.INC.LGREEN + DB COLORS.CGA.PAPER.LGRAY + COLORS.CGA.INC.BLACK + DB COLORS.CGA.PAPER.MAGENTA + COLORS.CGA.INC.WHITE +; Color Style 9 + DB COLORS.CGA.PAPER.MAGENTA + COLORS.CGA.INC.WHITE + DB COLORS.CGA.PAPER.MAGENTA + COLORS.CGA.INC.YELLOW + DB COLORS.CGA.PAPER.GREEN + COLORS.CGA.INC.BLUE + DB COLORS.CGA.PAPER.MAGENTA + COLORS.CGA.INC.LRED +; Color Style 10 + DB COLORS.CGA.PAPER.LGRAY + COLORS.CGA.INC.BLACK + DB COLORS.CGA.PAPER.LGRAY + COLORS.CGA.INC.RED + DB COLORS.CGA.PAPER.CYAN + COLORS.CGA.INC.WHITE + DB COLORS.CGA.PAPER.LGRAY + COLORS.CGA.INC.WHITE +; Color Style 11 + DB COLORS.CGA.PAPER.LGRAY + COLORS.CGA.INC.BLUE + DB COLORS.CGA.PAPER.LGRAY + COLORS.CGA.INC.YELLOW + DB COLORS.CGA.PAPER.MAGENTA + COLORS.CGA.INC.WHITE + DB COLORS.CGA.PAPER.LGRAY + COLORS.CGA.INC.WHITE +; Color Style 12 + DB COLORS.CGA.PAPER.LGRAY + COLORS.CGA.INC.LGREEN + DB COLORS.CGA.PAPER.LGRAY + COLORS.CGA.INC.LCYAN + DB COLORS.CGA.PAPER.GREEN + COLORS.CGA.INC.WHITE + DB COLORS.CGA.PAPER.LGRAY + COLORS.CGA.INC.WHITE +; Color Style 13 + DB COLORS.CGA.PAPER.BLACK + COLORS.CGA.INC.LGREEN + DB COLORS.CGA.PAPER.BLACK + COLORS.CGA.INC.LCYAN + DB COLORS.CGA.PAPER.CYAN + COLORS.CGA.INC.YELLOW + DB COLORS.CGA.PAPER.BLACK + COLORS.CGA.INC.YELLOW +; Color Style 14 (Mono) + DB COLORS.CGA.PAPER.BLACK + COLORS.CGA.INC.LGRAY + DB COLORS.CGA.PAPER.BLACK + COLORS.CGA.INC.WHITE + DB COLORS.CGA.PAPER.LGRAY + COLORS.CGA.INC.BLACK + DB COLORS.CGA.PAPER.BLACK + COLORS.CGA.INC.LGRAY +; Color Style 15 + DB COLORS.CGA.PAPER.BLACK + COLORS.CGA.INC.LMAGENT + DB COLORS.CGA.PAPER.BLACK + COLORS.CGA.INC.LGREEN + DB COLORS.CGA.PAPER.LGRAY + COLORS.CGA.INC.RED + DB COLORS.CGA.PAPER.BLACK + COLORS.CGA.INC.RED + +DEFVAL: DB SAVERAM+EXTBIOS+SDELAY1 ;#0E - OPTIONS + DB TDL250+TRATE30 ;#0F - KEYBOARD + DB SDIDE1+SDFDD1 ;#10 - SYSTEM DISKS + DB FD1720+FD2720+HD1AUTO+HD2AUTO ;#11 - FDD & Primary HDD's + DB 0 ;#12 - CYLINDERS LOW MASTER + DB 0 ;#13 - CYLINDERS HIGH MASTER + DB 0 ;#14 - HEADS MASTER + DB 0 ;#15 - SECTORS MASTER + DB 0 ;#16 - CYLINDERS LOW SLAVE + DB 0 ;#17 - CYLINDERS HIGH SLAVE + DB 0 ;#18 - HEADS SLAVE + DB 0 ;#19 - SECTORS SLAVE + DB 0 ;#1A - Int conf, Screen sync, COLOR STYLE + DB TURBON+SPRIN ;#1B - HARDARE CONF + DB BAS128 ;#1C - RESET MODE + DB REBOOTM + 4 ;#1D - REBOOT + LoadZXroms by ZX flag + DB 0 ;#1E - TRDOS + DB #77 ;#1F - SCREEN POSITION + DB HD1AUTO+HD2AUTO ;#20 - Secondary HDD's +.Size EQU $-DEFVAL + + +;!FIXIT расписать тут ячейки кмоса и это смещение меткой привязать вместо #0E в SETDEF + _mInfoALIGN 256,0 ; выравнивание на адрес #XX00 +CMOSARE: + DS 14 + ; + DB SAVERAM+EXTBIOS ;#0E - OPTIONS + DB TDL250+TRATE30 ;#0F - KEYBOARD + DB SDIDE1+ASDFDD2 ;#10 - SYSTEM DISKS + DB FD1720+FD2720+HD1AUTO+HD2AUTO ;#11 - FDD & HDD + DB 0 ;#12 - CYLINDERS LOW MASTER + DB 0 ;#13 - CYLINDERS HIGH MASTER + DB 0 ;#14 - HEADS MASTER + DB 0 ;#15 - SECTORS MASTER + DB 0 ;#16 - CYLINDERS LOW SLAVE + DB 0 ;#17 - CYLINDERS HIGH SLAVE + DB 0 ;#18 - HEADS SLAVE + DB 0 ;#19 - SECTORS SLAVE + DB 0 ;#1A - Int conf, Screen sync, COLOR STYLE + DB TURBON+SPRIN ;#1B - HARDARE CONF + DB BAS128 ;#1C - RESET MODE + DB REBOOTM ;#1D - REBOOT MSG, HDD W/P + DB %0000'0000 ;#1E - TRDOS + DB %0111'0111 ;#1F - SCREEN POSITION + DB HD1AUTO+HD2AUTO ;#20 - Secondary HDD's + DB %0000'0000 ;#21 + DB %0000'0000 ;#22 + DB %0000'0000 ;#23 + DB %0000'0000 ;#24 + DB %0000'0000 ;#25 + DB %0000'0000 ;#26 + DB %0000'0000 ;#27 + DB %0000'0000 ;#28 + DB %0000'0000 ;#29 + DB %0000'0000 ;#2A + DB %0000'0000 ;#2B + DB %0000'0000 ;#2C + DB %0000'0000 ;#2D + DB %0000'0000 ;#2E + DB %0000'0000 ;#2F + DB %0000'0000 ;#30 + DB %0000'0000 ;#31 + DB #20 ;#32 - CENTURY + DB %0000'0000 ;#33 + DB %0000'0000 ;#34 + DB %0000'0000 ;#35 + DB %0000'0000 ;#36 + DB %0000'0000 ;#37 + DB %0000'0000 ;#38 + DB %0000'0000 ;#39 + DB %0000'0000 ;#3A + DB %0000'0000 ;#3B + DB %0000'0000 ;#3C + DB %0000'0000 ;#3D + DB %0000'0000 ;#3E + DB %0000'0000 ;#3F - CHECKSUM + BLOCK #100 - low $ ; добивка CMOSARE до размера в 256 байтов +;DONT MOVE !!! ADDRESS +; \ No newline at end of file diff --git a/Crazy BIOS/rom/SETUP/VIDEO_IO.asm b/Crazy BIOS/rom/SETUP/VIDEO_IO.asm new file mode 100644 index 0000000..522133d --- /dev/null +++ b/Crazy BIOS/rom/SETUP/VIDEO_IO.asm @@ -0,0 +1,548 @@ + +def_pal_mask EQU #FF +PIC_SET_PAL_FF EQU def_pal_mask*256+BIOS.PIC_SET_PAL + +;; +ScreenPOS: +.SUBNAME: + CALL LP_GET_PLACE + LD E,.SUBNAME.POS ;!HARDCODE autodetected hdd/cdrom info + JP LP_SET_PLACE +.SUBNAME.POS EQU 37 + ; +.CRLF: CALL LP_GET_PLACE + INC D + LD E,#00 + JP LP_SET_PLACE +;; + +;!TODO переделать, а то криво как-то +DWPRINT: + LD A,(HL) + CP ' ' + JR NZ,PRINTDW + INC HL + LD A,(HL) + DEC HL + CP ' ' + JR NZ,PRINTDW + INC HL + INC HL + DJNZ DWPRINT + RET +;!TODO переделать, а то криво как-то +PRINTDW: + PUSH BC + LD E,(HL) + INC HL + LD A,(HL) + INC HL + CALL PRINT_CHAR + LD A,E + CALL PRINT_CHAR + POP BC + DJNZ PRINTDW + RET + +PRINTA: LD E,A + JP LP_PRINT_ATR + +PRINT_CHAR: + LD B,1 + JP LP_PRINT_SYM +; + +TPRINTZ: CALL LP_SET_PLACE +PRINTZ: LD B,0 + LD D,B + JP LP_PRINT_LINE6 + +HPRINTZ: LD B,0 + LD D,B + LD E,COLORS.CGA.INC.WHITE + JP LP_PRINT_LINE5 + +CPRINTZ: LD B,0 + LD D,B + LD E,A + JP LP_PRINT_LINE5 + +;HL - NUMBER +IZPRINT: LD D,1 + JR IPRIN +IPRINT: + LD D,0 +IPRIN: LD BC,10000 + CALL PRINTDG + LD BC,1000 + CALL PRINTDG + LD BC,100 + CALL PRINTDG + LD BC,10 + CALL PRINTDG + LD A,L + ADD A,#30 + JP PRINT_CHAR + +PRINTDG: + LD A,#2F +PDG1: INC A + SBC HL,BC + JR NC,PDG1 + ADD HL,BC + BIT 0,D + JR NZ,PDG2 + CP #30 + RET Z + SET 0,D +PDG2: PUSH BC + CALL PRINT_CHAR + POP BC + RET + +; D - Y +; E - X +; H - CY +TLINEV: + ;CALL ScreenPOS.LOCAT + CALL LP_SET_PLACE + LD A,(ElementsBuffer.UpCenter) + CALL PRSYM + DEC H + DEC H + +.loop: INC D + ;CALL ScreenPOS.LOCAT + CALL LP_SET_PLACE + LD A,(ElementsBuffer.VerticalLine) + CALL PRSYM + DEC H + JR NZ,.loop + + INC D + ;CALL ScreenPOS.LOCAT + CALL LP_SET_PLACE + LD A,(ElementsBuffer.DownCenter) + JP PRSYM + +; D - Y +; E - X +; L - CX +TLINEH: + ;CALL ScreenPOS.LOCAT + CALL LP_SET_PLACE + LD A,(ElementsBuffer.LeftCenter) + CALL PRSYM + DEC L + DEC L + LD A,(ElementsBuffer.HorizontalLine) + LD B,L + + ;CALL PRSYMB + CALL LP_PRINT_SYM + + + LD A,(ElementsBuffer.RightCenter) + JP PRSYM + +; D - Y +; E - X +; B - CY +; C - CX +PBORDER: PUSH BC + LD A,C + DEC A + LD (.BSHI),A + DEC A + LD (.BHOR),A + LD (.BHOR2),A + CALL LP_SET_PLACE + LD A,(ElementsBuffer.UpLeft) + LD H,E + CALL PRSYM + LD A,(ElementsBuffer.HorizontalLine) +.BHOR+1: LD B,1 + CALL LP_PRINT_SYM + + LD A,(ElementsBuffer.UpRight) + CALL PRSYM + POP BC + DEC B + DEC B + INC D + LD E,H + +.loop: PUSH BC + CALL LP_SET_PLACE + LD A,(ElementsBuffer.VerticalLine) + CALL PRSYM + LD A,H +.BSHI+1: ADD A,#00 + LD E,A + CALL LP_SET_PLACE + LD A,(ElementsBuffer.VerticalLine) + CALL PRSYM + POP BC + LD E,H + INC D + DJNZ .loop + + CALL LP_SET_PLACE + LD A,(ElementsBuffer.DownLeft) + CALL PRSYM + LD A,(ElementsBuffer.HorizontalLine) +.BHOR2+1: LD B,1 + CALL LP_PRINT_SYM + LD A,(ElementsBuffer.DownRight) + CALL PRSYM + RET + +PRSYM: LD B,1 + JP LP_PRINT_SYM + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +//////////////////// LOGO \\\\\\\\\\\\\\\\\\\\ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +LOGOTYPE: CALL SHOW_LOGO + LD BC,CMOS_CELL.BootUpParams.Mask.StartDelay + CALL G_VALUE + OR A + JR Z,.EASYDLY ; Delay average + DEC A + JR Z,.SKIPDLY ; Delay disabled + ; Delay enabled + LD B,LOGO_DELAY_NORM +.loop EI + push bc + HALT + CALL go_setup + pop bc + DJNZ .loop + ; Delay average +.SKIPDLY: LD B,LOGO_DELAY_MAX +.MMA: PUSH BC + EI + HALT + DI + CALL FADE + POP BC + DJNZ .MMA + ; ; +.ERASE_LOGO: LD IX,win_descriptor.tab80x32 + LD HL,#0000 + LD E,1 + ; + EI + HALT + DI + CALL WIN_OPEN + ; + LD DE,0 + LD HL,#0920 ;!HARDCODE LOGOTYPE SIZE + LD B,7 + JP LP_CLS_WIN + ; Delay disabled +.EASYDLY: LD B,LOGO_DELAY_MIN +.loop2: EI + HALT + DJNZ .loop2 + DI + JR .ERASE_LOGO +; ; ; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +SHOW_LOGO: LD IX,win_descriptor.tab320x256 + LD HL,#0000 + LD E,1 + CALL WIN_OPEN + + SAFE_PORTY + + DI + LD A,1 + OUT (SYS_PORT.ON),A + OUT (ROM.SLOT0),A + + LD HL,MAIN_LOGO.Pallete + LD DE,memBUFFER.Shared + LD BC,MAIN_LOGO.Pallete.length + LDIR + + XOR A + OUT (ROM.SLOT0),A + OUT (SYS_PORT.ON),A + EI + + LD HL,memBUFFER.Shared + ; A = 0 + LD D,A ; SET DESKTOP PALETTE & CURSOR COLORS + LD E,A + LD B,def_pal_mask + CALL PIC_SET_PAL + + SAFE_PORTY + + DI + LD A,1 + OUT (SYS_PORT.ON),A + ;LD A,1 + OUT (ROM.SLOT0),A + + LD HL,MAIN_LOGO.Raster ; начало картинки в банке ПЗУ + ; CALL DECODE + CALL LOGO_TO_SCREEN + ; + ;--------------[Пасхалка]--------------[] + IF Pashalki + _PASHALKI_CODE + ENDIF + ;--------------------------------------[] + ; + XOR A + OUT (SYS_PORT.ON),A + OUT (ROM.SLOT0),A + EI + RET +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +win_descriptor: +.tab80x32 Window_UserVars{ + 40, ; горизонтальный размер окна в знакоместах + 32, ; вертикальный размер в знакоместах + 0, ; положение окна по горизонтали на экране + 0, ; положение окна по вертикали на экране + %0001'1011, ; режим знакоместа + 0, ; дополнительный режим знакоместа + 0, ; положение по X в поле графики (по знакоместам) + 0 ; положение по Y в поле графики (по знакоместам) + } +.tab320x256 Window_UserVars{ + 16, ; горизонтальный размер окна в знакоместах + 9, ; вертикальный размер в знакоместах + 0, ; положение окна по горизонтали на экране + 0, ; положение окна по вертикали на экране + %0010'0000, ; режим знакоместа + 0, ; дополнительный режим знакоместа + 8, ; положение по X в поле графики (по знакоместам) + 0 ; положение по Y в поле графики (по знакоместам) + } +; + + MACRO _mFADE + LD HL,memBUFFER.Shared + ; A = 0 + LD B,A +.loop: DUP 3 + CP (HL) + JR Z,1F + DEC (HL) +1: INC HL + EDUP + INC HL + DJNZ .loop + ENDM + + +FADE: XOR A + _mFADE + _mFADE + ; A = 0 + LD HL,memBUFFER.Shared + ; LD DE,#0000 + LD D,A + LD E,A + ; + LD B,def_pal_mask + CALL PIC_SET_PAL + + SAFE_PORTY + +go_setup: ; !FIXIT переделать на TSETUP + CALL SCANKEY + RET Z + + CP #1B + JP Z,.to_EXIT_SETUP + + LD HL,#4F00 + AND A + SBC HL,DE + jr nz,go_setup + + LD IX,win_descriptor.tab80x32 + LD HL,#0000 + LD E,1 + CALL WIN_OPEN + JP ENTER_SETUP + +.to_EXIT_SETUP: + LD HL,(RET_TO_EXP_ADDR) + PUSH HL + JP EXIT_SETUP + +;DECODE: +LOGO_TO_SCREEN: + PUSH HL + IN A,(SLOT1) + LD H,A + IN A,(PORT_Y) + LD L,A + EX (SP),HL + + LD A,#50 + OUT (SLOT1),A + LD A,72 ; !HARDCODE координата картинки по Y + высота картинки +.loop: + DEC A + OUT (PORT_Y),A + LD DE,#4040 ; !HARDCODE координата картинки по Х + LD BC,128 ; !HARDCODE длина горизонтальной линии картинки + LDIR + OR A + JP NZ,.loop + + POP BC + LD A,B + OUT (SLOT1),A + LD A,C + OUT (PORT_Y),A + XOR A + RET + + ; IF !ROM_LOGO_TEST + ; LOGPAL: ; palitre for logotype + ; IF TEST_Build + ; INCBIN './test/test2_pal.bin' + ; ELSE + ; INCBIN './original/logo_pal.bin' + ; ENDIF + ; + ; IF ($-LOGPAL) < 1024 + ; BLOCK +(1024-($-LOGPAL)),0 + ; ENDIF + ; ENDIF + +; Original hardcoded pallete for Peters logotype + ; B G R + ; DB #FF,#FF,#FF,#00 + ; DB #8C,#A5,#A5,#00 + ; DB #42,#EF,#EF,#00 + ; DB #DE,#CE,#C6,#00 + ; DB #84,#39,#39,#00 + ; DB #CE,#8C,#84,#00 + ; DB #A5,#39,#31,#00 + ; DB #84,#7B,#7B,#00 + ; DB #63,#5A,#5A,#00 + ; DB #BD,#39,#39,#00 + ; DB #84,#08,#08,#00 + ; DB #AD,#08,#08,#00 + ; DB #18,#00,#00,#00 + ; DB #63,#08,#10,#00 + ; DB #94,#08,#18,#00 + ; DB #00,#00,#00,#00 + + ; PALCOL: + ; ; B G R + ; DB #FF,#FF,#FF,#00 + ; DB #8C,#BD,#BD,#80 + ; DB #BD,#CE,#BD,#00 + ; DB #EF,#CE,#BD,#00 + ; DB #BC,#73,#73,#00 + ; DB #9C,#63,#63,#00 + ; DB #DE,#8C,#8C,#00 + ; DB #8C,#52,#52,#00 + ; DB #BD,#63,#63,#00 + ; DB #52,#10,#10,#00 + ; DB #21,#00,#00,#00 + ; DB #8C,#00,#00,#00 + ; DB #AD,#00,#00,#00 + ; DB #AD,#10,#21,#00 + ; DB #8C,#00,#10,#00 + ; DB #00,#00,#00,#00 + + + +SET_CGA: + CALL SETPAL4 + LD A,4 ; page_pal + LD HL,memBUFFER.Shared + LD DE,#0000 ; D - ELEMENTS,E - COLOR + LD B,def_pal_mask + CALL PIC_SET_PAL + + LD A,6 ; page_pal + LD HL,memBUFFER.Shared + LD DE,#0000 ;D - ELEMENTS,E - COLOR + LD B,def_pal_mask + CALL PIC_SET_PAL + + LD A,7 ; page_pal + LD HL,#80*4+memBUFFER.Shared + LD DE,#8080 ;D - ELEMENTS,E - COLOR + LD B,def_pal_mask + CALL PIC_SET_PAL + ; + + CALL SETPAL5 + LD A,5 ; page_pal + LD HL,memBUFFER.Shared + LD DE,#0000 ;D - ELEMENTS,E - COLOR + LD B,def_pal_mask + CALL PIC_SET_PAL + + LD A,7 ; page_pal + LD HL,memBUFFER.Shared + LD DE,#8000 ;D - ELEMENTS,E - COLOR + LD B,def_pal_mask + CALL PIC_SET_PAL + ; + +SETPAL4: + LD HL,COLORS.CGA.PALETTE + LD DE,memBUFFER.Shared + LD C,#08 + +DCR0: LD B,COLORS.CGA.PALETTE.ColNum + PUSH HL + ; +DCR1: POP HL + PUSH HL + PUSH BC + LDI + LDI + LDI + LDI + POP BC + DJNZ DCR1 + ; + INC SP + INC SP + DEC C + JR NZ,DCR0 + + LD HL,memBUFFER.Shared + LD BC,512 + LDIR + RET + +SETPAL5: + LD HL,COLORS.CGA.PALETTE + LD DE,memBUFFER.Shared + LD B,#08 +DCR01: + PUSH BC + PUSH HL + LD BC,16*4 + LDIR + POP HL + POP BC + DJNZ DCR01 + LD HL,memBUFFER.Shared + LD BC,512 + LDIR + RET + + include 'shared_includes/constants/standart_colors.inc' +; \ No newline at end of file diff --git a/Crazy BIOS/rom/SETUP/messages.z80 b/Crazy BIOS/rom/SETUP/messages.z80 new file mode 100644 index 0000000..596260e --- /dev/null +++ b/Crazy BIOS/rom/SETUP/messages.z80 @@ -0,0 +1,840 @@ + +; OnChangeAction: +; .setLang EQU 1 +; .nothing EQU 2 +; .setXYpos EQU 3 +; .setInt EQU 4 +; .setVsinc EQU 5 +; DEFINE SPTeam_year '2022' +; DEFINE Disk_subsystem_ver_txt '3.05' +; DEFINE SetupVer '2.55' + LUA ALLPASS + function get_key_for_value(t, value) + for column=1,2 do + for line,name in pairs(t[column]) do + if name==value then return column,line end + end + end + return nil + end + + function DeleteValueByDEFINE (t,zero_def,value) + if tonumber(sj.get_define(zero_def)) then + local delCol, delLine = get_key_for_value(t, value) + table.remove (t[delCol], delLine) + end + end + ENDLUA + + LUA PASS1 + SettingsTabsOrder = { + [1]={ + "Lang", -- 1 + "SaveRAMdrvs", -- 2 + "StartDelay", -- 3 + "RebootMsg", -- 4 + "SysDsk", -- 5 + "AltSysDsk", -- 6 + "FddFirst", -- 7 + "FddSecond", -- 8 + "PriIdeMA", -- 9 + "PriIdeSl", -- 10 + "SecIdeMA", -- 11 + "SecIdeSl", -- 12 + "ScreenY", -- 13 + "ScreenX", -- 14 + "FrameInt", -- 15 + "VSync", -- 16 + "QuickStartROM", -- 17 + "MemTest", -- DEFINES.INC --> UnusedSettingsFeatures + "UpdBios", -- DEFINES.INC --> UnusedSettingsFeatures + "TypRate", -- DEFINES.INC --> UnusedSettingsFeatures + "TypDelay", -- DEFINES.INC --> UnusedSettingsFeatures + }, + [2]={ + "LoadZXroms", -- 1 + "TrDosA", -- 2 + "TrDosB", -- 3 + "TrDosC", -- 4 + "TrDosD", -- 5 + "SetTime", -- 6 DEFINES.INC --> NEW_FEATURE + "HddWrPr", -- 7 DEFINES.INC --> HDDwriteProtect + -- 8 + -- 9 + -- 10 + -- 11 + -- 12 + -- 13 + -- 14 + -- 15 + -- 16 + -- 17 + } + } + DeleteValueByDEFINE(SettingsTabsOrder,"NEW_FEATURE","SetTime") + DeleteValueByDEFINE(SettingsTabsOrder,"HDDwriteProtect","HddWrPr") + DeleteValueByDEFINE(SettingsTabsOrder,"UnusedSettingsFeatures","MemTest") + DeleteValueByDEFINE(SettingsTabsOrder,"UnusedSettingsFeatures","UpdBios") + DeleteValueByDEFINE(SettingsTabsOrder,"UnusedSettingsFeatures","TypRate") + DeleteValueByDEFINE(SettingsTabsOrder,"UnusedSettingsFeatures","TypDelay") + -- DeleteValueByDEFINE(SettingsTabsOrder,"UnusedSettingsFeatures","") + -- DeleteValueByDEFINE(SettingsTabsOrder,"UnusedSettingsFeatures","") + ENDLUA +; + +; + MACRO _mSETitemParams itemName? +@.itemName? EQU $ + DEFINE TmpDef itemName? + LUA ALLPASS + local tmpName = sj.get_define("TmpDef") + local column,line = get_key_for_value(SettingsTabsOrder, tmpName) + if (column == nil or line == nil) then sj.error("Settings Tab not found",tmpName) end + if column == 1 then column = _c("firstColumn") else column = _c("secondColumn") end + sj.insert_define("columnNum", column) + sj.insert_define("lineNum", (_c("firstLine")+line-1)) + sj.insert_define("paramName", "msgStrings.par" .. tmpName) + ENDLUA + UNDEFINE TmpDef + ENDM +; + + MACRO _mCreateSettingsItemsTabsAddrs + LUA ALLPASS + for i = 1, #SettingsTabsOrder do + for j = 1, #SettingsTabsOrder[i] do + _pc("DW " .. _c("SettingsItemsTabs." .. SettingsTabsOrder[i][j])) + end + end + ENDLUA + +; создаёт такую структуру: +; DW SettingsItemsTabs.FirstItem +; DW .. +; DW SettingsItemsTabs.LastItem + ENDM + + MACRO _mCreateMsgAddrTable ; !FIXIT доделать на приём параметра "msgRusStrings.msg_", а лучше внутри самому определять эту метку + LUA ALLPASS + for i = 0, _c("tmp_Counter")-1, 1 do + _pc("WORD " .. "msgRusStrings.msg_" .. i) + end + ENDLUA + +; создаёт такую структуру: +; WORD msgRusStrings.msg_0 +; .. +; WORD msgRusStrings.msg_XX ; XX = tmp_Counter + ENDM + +;----------------------------[Settings items table]----------------------------[v] + +; + IF NEW_FEATURE +; New structure for procedure with IY reg + STRUCT MenusItem +Action WORD +Type BYTE +Column BYTE +Line BYTE +Name BYTE +CMOSreg BYTE +ValueMask BYTE +ValueMax BYTE +FirstString BYTE + ENDS + +paramLine EQU 0 +folderLine EQU 1 + + ENDIF +; + +firstColumn EQU 03 ; смещение по X для первого столбца +secondColumn EQU 43 ; смещение по X для второго столбца +firstLine EQU 07 ; смещение по Y для первой строки + +SettingsItemsTabs: + + _mSETitemParams Lang + DW OnChangeAction.setLang ; действие при изменении + IF NEW_FEATURE : DB paramLine : ENDIF ; тип параметра (строка со значением или каталог) + DB columnNum,lineNum ; столбец, строка + DB paramName ; Название параметра + DW CMOS_CELL.BootUpParams.Mask.Language : DB %0000'0100 ; CMOS : MASK + DB msgStrings.valLangEng ; 1-й вариант параметра + DB msgStrings.valLangRus ; 2-й вариант параметра + + + IF UnusedSettingsFeatures ; !TODO + _mSETitemParams MemTest + DW OnChangeAction.nothing + IF NEW_FEATURE : DB paramLine : ENDIF + DB columnNum,lineNum + DB paramName + DW CMOS_CELL.BootUpParams.Mask.MemTest : DB %1000'0000 + DB msgStrings.valDisabled + DB msgStrings.valEnabled + ENDIF + + _mSETitemParams SaveRAMdrvs + DW OnChangeAction.nothing + IF NEW_FEATURE : DB paramLine : ENDIF + DB columnNum,lineNum + DB paramName + DW CMOS_CELL.BootUpParams.Mask.SaveRAMdisks : DB %0100'0000 + DB msgStrings.valDisabled + DB msgStrings.valEnabled + + IF UnusedSettingsFeatures ; !TODO + _mSETitemParams UpdBios + DW OnChangeAction.nothing + IF NEW_FEATURE : DB paramLine : ENDIF + DB columnNum,lineNum + DB paramName + DW CMOS_CELL.BootUpParams.Mask.UpdBios : DB %0010'0000 + DB msgStrings.valDisabled + DB msgStrings.valEnabled + ENDIF + + _mSETitemParams StartDelay + DW OnChangeAction.nothing + IF NEW_FEATURE : DB paramLine : ENDIF + DB columnNum,lineNum + DB paramName + DW CMOS_CELL.BootUpParams.Mask.StartDelay : DB %0001'0000 + DB msgStrings.valDisabled + DB msgStrings.valNormal + DB msgStrings.valEnabled + + IF UnusedSettingsFeatures ; !TODO + _mSETitemParams TypRate + DW OnChangeAction.nothing + IF NEW_FEATURE : DB paramLine : ENDIF + DB columnNum,lineNum + DB paramName + DW CMOS_CELL.Typematic.Mask.Rate : DB %0000'0111 + DB msgStrings.val_6 + DB msgStrings.val_8 + DB msgStrings.val_10 + DB msgStrings.val_12 + DB msgStrings.val_15 + DB msgStrings.val_20 + DB msgStrings.val_24 + DB msgStrings.val_30 + ENDIF + + IF UnusedSettingsFeatures ; !TODO + _mSETitemParams TypDelay + DW OnChangeAction.nothing + IF NEW_FEATURE : DB paramLine : ENDIF + DB columnNum,lineNum + DB paramName + DW CMOS_CELL.Typematic.Mask.Delay : DB %0110'0000 + DB msgStrings.val_250 + DB msgStrings.val_500 + DB msgStrings.val_750 + DB msgStrings.val_1000 + ENDIF + + _mSETitemParams RebootMsg + DW OnChangeAction.nothing + IF NEW_FEATURE : DB paramLine : ENDIF + DB columnNum,lineNum + DB paramName + DW CMOS_CELL.Options.Mask.RebootMSG : DB %0000'0010 + DB msgStrings.valDisabled + DB msgStrings.valEnabled + + _mSETitemParams SysDsk + DW OnChangeAction.nothing + IF NEW_FEATURE : DB paramLine : ENDIF + DB columnNum,lineNum + DB paramName + DW CMOS_CELL.BootDrives.Mask.SysDisk : DB %0000'0111 + DB msgStrings.val1stFDD + DB msgStrings.val2ndFDD + DB msgStrings.val1stIDE + DB msgStrings.val2ndIDE + DB msgStrings.val3rdIDE + DB msgStrings.val4thIDE + DB msgStrings.valRamDsk + DB msgStrings.valRecovery + + _mSETitemParams AltSysDsk + DW OnChangeAction.nothing + IF NEW_FEATURE : DB paramLine : ENDIF + DB columnNum,lineNum + DB paramName + DW CMOS_CELL.BootDrives.Mask.AltSysDisk : DB %0111'0000 + DB msgStrings.val1stFDD + DB msgStrings.val2ndFDD + DB msgStrings.val1stIDE + DB msgStrings.val2ndIDE + DB msgStrings.val3rdIDE + DB msgStrings.val4thIDE + DB msgStrings.valRamDsk + DB msgStrings.valRecovery + + _mSETitemParams FddFirst + DW OnChangeAction.nothing + IF NEW_FEATURE : DB paramLine : ENDIF + DB columnNum,lineNum + DB paramName + DW CMOS_CELL.DrivesSetup_1.Mask.FirstFDD : DB %0000'0000 + DB msgStrings.valAuto + ; DB msgStrings.val720 + ; DB msgStrings.val1440 + ; DB msgStrings.valDash6 + + _mSETitemParams FddSecond + DW OnChangeAction.nothing + IF NEW_FEATURE : DB paramLine : ENDIF + DB columnNum,lineNum + DB paramName + DW CMOS_CELL.DrivesSetup_1.Mask.SecondFDD : DB %0000'0000 + DB msgStrings.valAuto + ; DB msgStrings.val720 + ; DB msgStrings.val1440 + ; DB msgStrings.valDash6 + + _mSETitemParams PriIdeMA + DW OnChangeAction.nothing + IF NEW_FEATURE : DB paramLine : ENDIF + DB columnNum,lineNum + DB paramName + DW CMOS_CELL.DrivesSetup_1.Mask.PriIDEmaster : DB %0011'0000 + DB msgStrings.valAuto + DB msgStrings.valSetup + DB msgStrings.valCdRom + DB msgStrings.valDash6 + + _mSETitemParams PriIdeSl + DW OnChangeAction.nothing + IF NEW_FEATURE : DB paramLine : ENDIF + DB columnNum,lineNum + DB paramName + DW CMOS_CELL.DrivesSetup_1.Mask.PriIDEslave : DB %1100'0000 + DB msgStrings.valAuto + DB msgStrings.valSetup + DB msgStrings.valCdRom + DB msgStrings.valDash6 + + _mSETitemParams SecIdeMA + DW OnChangeAction.nothing + IF NEW_FEATURE : DB paramLine : ENDIF + DB columnNum,lineNum + DB paramName + DW CMOS_CELL.DrivesSetup_2.Mask.SecIDEmaster : DB %0011'0000 + DB msgStrings.valAuto + DB msgStrings.valSetup + DB msgStrings.valCdRom + DB msgStrings.valDash6 + + _mSETitemParams SecIdeSl + DW OnChangeAction.nothing + IF NEW_FEATURE : DB paramLine : ENDIF + DB columnNum,lineNum + DB paramName + DW CMOS_CELL.DrivesSetup_2.Mask.SecIDEslave : DB %1100'0000 + DB msgStrings.valAuto + DB msgStrings.valSetup + DB msgStrings.valCdRom + DB msgStrings.valDash6 + + IF HDDwriteProtect + _mSETitemParams HddWrPr + DW OnChangeAction.nothing + IF NEW_FEATURE : DB paramLine : ENDIF + DB columnNum,lineNum + DB paramName + DW CMOS_CELL.Options.Mask.HDDwriteProtect : DB %0000'0001 + DB msgStrings.valDisabled + DB msgStrings.valEnabled + ENDIF + + _mSETitemParams ScreenY + DW OnChangeAction.setXYpos + IF NEW_FEATURE : DB paramLine : ENDIF + DB columnNum,lineNum + DB paramName + DW CMOS_CELL.ScreenPosition.Mask.X : DB %1110'0000 + DB msgStrings.valMinus7 + DB msgStrings.valMinus6 + DB msgStrings.valMinus5 + DB msgStrings.valMinus4 + DB msgStrings.valMinus3 + DB msgStrings.valMinus2 + DB msgStrings.valMinus1 + DB msgStrings.val_0 + DB msgStrings.valPlus1 + DB msgStrings.valPlus2 + DB msgStrings.valPlus3 + DB msgStrings.valPlus4 + DB msgStrings.valPlus5 + DB msgStrings.valPlus6 + DB msgStrings.valPlus7 + + _mSETitemParams ScreenX + DW OnChangeAction.setXYpos + IF NEW_FEATURE : DB paramLine : ENDIF + DB columnNum,lineNum + DB paramName + DW CMOS_CELL.ScreenPosition.Mask.Y : DB %0000'1110 + DB msgStrings.valPlus7 + DB msgStrings.valPlus6 + DB msgStrings.valPlus5 + DB msgStrings.valPlus4 + DB msgStrings.valPlus3 + DB msgStrings.valPlus2 + DB msgStrings.valPlus1 + DB msgStrings.val_0 + DB msgStrings.valMinus1 + DB msgStrings.valMinus2 + DB msgStrings.valMinus3 + DB msgStrings.valMinus4 + DB msgStrings.valMinus5 + DB msgStrings.valMinus6 + DB msgStrings.valMinus7 + + _mSETitemParams FrameInt + DW OnChangeAction.setInt + IF NEW_FEATURE : DB paramLine : ENDIF + DB columnNum,lineNum + DB paramName + DW CMOS_CELL.ScreenSET.Mask.Int : DB %0011'0000 + DB msgStrings.valDash8 + DB msgStrings.valScorpion + DB msgStrings.valPentagon + DB msgStrings.valSpectrum + + _mSETitemParams VSync + DW OnChangeAction.setVsinc + IF NEW_FEATURE : DB paramLine : ENDIF + DB columnNum,lineNum + DB paramName + DW CMOS_CELL.ScreenSET.Mask.Sinc : DB %1000'0000 + DB msgStrings.valDash8 + DB msgStrings.val312_50 + DB msgStrings.val320_49 + + _mSETitemParams QuickStartROM + DW OnChangeAction.nothing + IF NEW_FEATURE : DB paramLine : ENDIF + DB columnNum,lineNum + DB paramName + DW CMOS_CELL.BootUpParams.Mask.QuickStartROM : DB %0000'0001 + DB msgStrings.parQuickStartSP + DB msgStrings.parQuickStartZX + + _mSETitemParams TrDosA + DW OnChangeAction.nothing + IF NEW_FEATURE : DB paramLine : ENDIF + DB columnNum,lineNum + DB paramName + DW CMOS_CELL.TRDOSmount.Mask.A : DB %0000'0010 + DB msgStrings.valDefault + DB msgStrings.valFDD + DB msgStrings.valHDD + + _mSETitemParams TrDosB + DW OnChangeAction.nothing + IF NEW_FEATURE : DB paramLine : ENDIF + DB columnNum,lineNum + DB paramName + DW CMOS_CELL.TRDOSmount.Mask.B : DB %0000'1000 + DB msgStrings.valDefault + DB msgStrings.valFDD + DB msgStrings.valHDD + + _mSETitemParams TrDosC + DW OnChangeAction.nothing + IF NEW_FEATURE : DB paramLine : ENDIF + DB columnNum,lineNum + DB paramName + DW CMOS_CELL.TRDOSmount.Mask.C : DB %0010'0000 + DB msgStrings.valDefault + DB msgStrings.valFDD + DB msgStrings.valHDD + + _mSETitemParams TrDosD + DW OnChangeAction.nothing + IF NEW_FEATURE : DB paramLine : ENDIF + DB columnNum,lineNum + DB paramName + DW CMOS_CELL.TRDOSmount.Mask.D : DB %1000'0000 + DB msgStrings.valDefault + DB msgStrings.valFDD + DB msgStrings.valHDD + + _mSETitemParams LoadZXroms + DW OnChangeAction.nothing + IF NEW_FEATURE : DB paramLine : ENDIF + DB columnNum,lineNum + DB paramName + DW CMOS_CELL.Options.Mask.LoadZXroms : DB %0000'1000 + DB msgStrings.valLoadZXromsManually + DB msgStrings.valLoadZXromsFlag + DB msgStrings.valLoadZXromsCAD + + IF NEW_FEATURE + _mSETitemParams SetTime + DW OnChangeAction.SetTime + DB folderLine + DB columnNum,lineNum + DB paramName + DB #00,%0000'0000,%0000'0000 + DB msgStrings.valFolder + ENDIF +;--------------------[Items Addresses table]--------------------[] +SettingsItemsTabsAddrs: + _mCreateSettingsItemsTabsAddrs +.max EQU ($-SettingsItemsTabsAddrs)/2 + + ; db on-change routine addr + ; db X,Y + ; db string-name number + ; db CMOS, MASK + ; db string-value number 1, .. , string-value number XX +;----------------------------------------------------------------[] + +;----------------------------[Settings items table]----------------------------[^] + +; +; !TODO добавить экспорт создаваемых переменных в отдельный файл для справки + MACRO _mSetStr Suffix?, Num? +@.Suffix? EQU Num? + LUA ALLPASS + _pl("@.msg_" .. _c("Num?")) + ENDLUA +!tmp_Counter = tmp_Counter + 1 + ENDM +; +; + +; +; !TODO добавить экспорт создаваемых переменных в отдельный файл для справки + MACRO _mSetStrRus Suffix?, Num? + DEFINE TmpDef Suffix? + LUA ALLPASS + if (_c("msgStrings." .. sj.get_define("TmpDef"))) ~= _c("Num?") then + sj.error("Sequence matching between Russian and English strings is broken!!!") + else + _pl("@.msg_" .. _c("Num?")) + end + ENDLUA + UNDEFINE TmpDef +!tmp_Counter = tmp_Counter + 1 + ENDM +; +; +; +;================================================================================================================================== +; Не менять бездумно название метки msgStrings !!! Участвует в LUA макросе в этом же файле. +tmp_Counter DEFL 0 +msgStrings: + _mSetStr copyRightPeters, tmp_Counter : DZ 'Copyright (c) 2002 Peters Plus' + _mSetStr copyRightSPTeam, tmp_Counter : DZ 'Copyright (c) 2009-', SPTeam_year, ' Sprinter Team' + _mSetStr setupBiosVer, tmp_Counter : DZ 'Sprinter BIOS v', BIOS_ver_string + _mSetStr setupCopyRight, tmp_Counter : DZ 'Copyright (c) 2002 Peters Plus, (c) 2009-', SPTeam_year, ' Sprinter Team' + _mSetStr setupUtilityVer, tmp_Counter : DZ 'SETUP Utility v', SetupVer + _mSetStr setupHelpStr1, tmp_Counter : DZ 'ESC : Quit F10 : Save & Exit Setup' + _mSetStr setupHelpStr2, tmp_Counter : DZ 'F2 : Save Values ',24,32,25,32,26,32,27,' : Select Item' ; коды стрелок вместе с пробелами: 24,32,25,32,26,32,27 + _mSetStr setupHelpStr3, tmp_Counter : DZ 'F5 : Old Values PU/PD/+/- : Modify' + _mSetStr setupHelpStr4, tmp_Counter : DZ 'F7 : Default Values F3 : Color ' + _mSetStr toSetupButton, tmp_Counter : DZ ' to enter SETUP' +;_mSetStr forCtrlBootButton, tmp_Counter : DZ ' for Recovery boot' + _mSetStr forAltBootButton, tmp_Counter : DZ ' for Alternative boot' + _mSetStr cmosChecksumErr, tmp_Counter : DZ 'WARNING! CMOS CHECKSUM ERROR, DEFAULT VALUES SET!' + _mSetStr cmosDateTimeErr, tmp_Counter : DZ 'WARNING! CMOS DATE/TIME ERROR, DEFAULT VALUES SET!' + _mSetStr detectIdePrMA, tmp_Counter : DZ ' Detecting IDE Primary Master ... [Press F4 to skip]' + _mSetStr detectIdePrSL, tmp_Counter : DZ ' Detecting IDE Primary Slave ... [Press F4 to skip]' + _mSetStr detectIdeSecMA, tmp_Counter : DZ ' Detecting IDE Secondary Master ... [Press F4 to skip]' + _mSetStr detectIdeSecSL, tmp_Counter : DZ ' Detecting IDE Secondary Slave ... [Press F4 to skip]' + _mSetStr ideUnknown, tmp_Counter : DZ 'Unknown ' + _mSetStr ideNone, tmp_Counter : DZ 'None ' + _mSetStr ideSkiped, tmp_Counter : DZ 'Skipped ' + _mSetStr ideFail, tmp_Counter : DZ 'Fail ' ; !FIXIT strFail + _mSetStr spModel, tmp_Counter : DZ 'Model : ' +.str_ACEX_MODEL EQU $$$+7 ; указатель на строку ниже для патча апдейтером + _mSetStr spCNFver, tmp_Counter : DZ 'Core 1K30 : v' + _mSetStr spMemory, tmp_Counter : DZ 'Memory : ' + _mSetStr cmosFound, tmp_Counter : DZ 'CMOS : Found' + _mSetStr cmosNone, tmp_Counter : DZ 'CMOS : None' + _mSetStr memoryAvailable, tmp_Counter : DZ 'Available : ' +; _mSetStr unknownSTR1, tmp_Counter : DZ "7" +; _mSetStr unknownSTR2, tmp_Counter : DZ "8" + _mSetStr boardID, tmp_Counter : DZ 'Board ID : ' + _mSetStr bootFdd, tmp_Counter : DZ 'Boot from Diskette' +; _mSetStr bootHdd, tmp_Counter : DZ 'Boot from Hard disk ' + _mSetStr bootHdd, tmp_Counter : DZ 'Boot from HDD ' + _mSetStr bootCd, tmp_Counter : DZ 'Boot from CD-ROM ' + _mSetStr bootRamDrv, tmp_Counter : DZ 'Boot from RAM disk' + _mSetStr bootRecovery, tmp_Counter : DZ 'Starting recovery' + _mSetStr bootAltDrv, tmp_Counter : DZ 'Alternative ' + _mSetStr bootFail, tmp_Counter : DZ ' fail' ; !FIXIT strFail + _mSetStr bootOk, tmp_Counter : DZ ' OK' + _mSetStr afterBootFail, tmp_Counter : DZ 'PRESS TO REBOOT, TO ENTER SETUP OR TO ZX-MODE . . .' +; + _mSetStr parLang, tmp_Counter : DZ 'Language (язык) : ' + _mSetStr valLangEng, tmp_Counter : DZ 'English ' + _mSetStr valLangRus, tmp_Counter : DZ 'Русский ' + _mSetStr parMemTest, tmp_Counter : DZ 'Memory test : ' + _mSetStr valDisabled, tmp_Counter : DZ 'Disabled' + _mSetStr valEnabled, tmp_Counter : DZ 'Enabled ' + _mSetStr parSaveRAMdrvs, tmp_Counter : DZ 'Save RAM-disks : ' + _mSetStr parUpdBios, tmp_Counter : DZ 'Update BIOS : ' + _mSetStr parStartDelay, tmp_Counter : DZ 'Start delay : ' + _mSetStr valNormal, tmp_Counter : DZ 'Average ' + _mSetStr parTypRate, tmp_Counter : DZ 'Typematic rate (chars/sec) : ' + _mSetStr val_6, tmp_Counter : DZ '6 ' + _mSetStr val_8, tmp_Counter : DZ '8 ' + _mSetStr val_10, tmp_Counter : DZ '10' + _mSetStr val_12, tmp_Counter : DZ '12' + _mSetStr val_15, tmp_Counter : DZ '15' + _mSetStr val_20, tmp_Counter : DZ '20' + _mSetStr val_24, tmp_Counter : DZ '24' + _mSetStr val_30, tmp_Counter : DZ '30' + _mSetStr parTypDelay, tmp_Counter : DZ 'Typematic delay (Msec) : ' + _mSetStr val_250, tmp_Counter : DZ '250 ' + _mSetStr val_500, tmp_Counter : DZ '500 ' + _mSetStr val_750, tmp_Counter : DZ '750 ' + _mSetStr val_1000, tmp_Counter : DZ '1000' + _mSetStr parRebootMsg, tmp_Counter : DZ 'Reboot message : ' + _mSetStr parSysDsk, tmp_Counter : DZ 'System disk : ' + _mSetStr val1stFDD, tmp_Counter : DZ '1-st FDD' + _mSetStr val2ndFDD, tmp_Counter : DZ '2-nd FDD' + _mSetStr val1stIDE, tmp_Counter : DZ '1-st IDE' + _mSetStr val2ndIDE, tmp_Counter : DZ '2-nd IDE' + _mSetStr val3rdIDE, tmp_Counter : DZ '3-rd IDE' + _mSetStr val4thIDE, tmp_Counter : DZ '4-th IDE' + _mSetStr valRamDsk, tmp_Counter : DZ 'RAM-DISK' + _mSetStr valRecovery, tmp_Counter : DZ 'RECOVERY' + _mSetStr parAltSysDsk, tmp_Counter : DZ 'Alt. system disk : ' + _mSetStr parFddFirst, tmp_Counter : DZ 'FDD first : ' + _mSetStr valAuto, tmp_Counter : DZ 'Auto ' +; _mSetStr val720, tmp_Counter : DZ '720K ' +; _mSetStr val1440, tmp_Counter : DZ '1.44M ' + _mSetStr valDash6, tmp_Counter : DZ '------' + _mSetStr parFddSecond, tmp_Counter : DZ 'FDD second : ' + _mSetStr parPriIdeMA, tmp_Counter : DZ 'Primary IDE Master',#FF,' : ' + _mSetStr valSetup, tmp_Counter : DZ 'Setup ' + _mSetStr valCdRom, tmp_Counter : DZ 'CD-ROM' + _mSetStr parPriIdeSl, tmp_Counter : DZ 'Primary IDE Slave',#FF,' : ' + _mSetStr parSecIdeMA, tmp_Counter : DZ 'Secondary IDE Master',#FF,' : ' + _mSetStr parSecIdeSl, tmp_Counter : DZ 'Secondary IDE Slave',#FF,' : ' + IF HDDwriteProtect + _mSetStr parHddWrPr, tmp_Counter : DZ 'HDD write protect : ' + ENDIF + _mSetStr parScreenY, tmp_Counter : DZ 'Y-screen position : ' + _mSetStr valMinus7, tmp_Counter : DZ '-7' + _mSetStr valMinus6, tmp_Counter : DZ '-6' + _mSetStr valMinus5, tmp_Counter : DZ '-5' + _mSetStr valMinus4, tmp_Counter : DZ '-4' + _mSetStr valMinus3, tmp_Counter : DZ '-3' + _mSetStr valMinus2, tmp_Counter : DZ '-2' + _mSetStr valMinus1, tmp_Counter : DZ '-1' + _mSetStr val_0, tmp_Counter : DZ ' 0' + _mSetStr valPlus1, tmp_Counter : DZ '+1' + _mSetStr valPlus2, tmp_Counter : DZ '+2' + _mSetStr valPlus3, tmp_Counter : DZ '+3' + _mSetStr valPlus4, tmp_Counter : DZ '+4' + _mSetStr valPlus5, tmp_Counter : DZ '+5' + _mSetStr valPlus6, tmp_Counter : DZ '+6' + _mSetStr valPlus7, tmp_Counter : DZ '+7' + _mSetStr parScreenX, tmp_Counter : DZ 'X-screen position : ' + _mSetStr parFrameInt, tmp_Counter : DZ 'Frame interrupt : ' + _mSetStr valDash8, tmp_Counter : DZ '--------' + _mSetStr valScorpion, tmp_Counter : DZ 'Scorpion' + _mSetStr valPentagon, tmp_Counter : DZ 'Pentagon' + _mSetStr valSpectrum, tmp_Counter : DZ 'Spectrum' + _mSetStr parVSync, tmp_Counter : DZ 'V-synchronization : ' + _mSetStr val312_50, tmp_Counter : DZ '312/50Hz' + _mSetStr val320_49, tmp_Counter : DZ '320/49Hz' + _mSetStr parQuickStartROM, tmp_Counter : DZ 'Run in mode : ' + _mSetStr parQuickStartZX, tmp_Counter : DZ 'Spectrum' + _mSetStr parQuickStartSP, tmp_Counter : DZ 'Sprinter' + _mSetStr valDefault, tmp_Counter : DZ 'Default' + _mSetStr valFDD, tmp_Counter : DZ 'FDD ' ; ????? подумать какие варианты возможны + _mSetStr valHDD, tmp_Counter : DZ 'HDD ' ; ????? подумать какие варианты возможны + _mSetStr parTrDosA, tmp_Counter : DZ 'TR DOS A:> : ' + _mSetStr parTrDosB, tmp_Counter : DZ 'TR DOS B:> : ' + _mSetStr parTrDosC, tmp_Counter : DZ 'TR DOS C:> : ' + _mSetStr parTrDosD, tmp_Counter : DZ 'TR DOS D:> : ' + _mSetStr parLoadZXroms, tmp_Counter : DZ 'Load ZX ROMs : ' + _mSetStr valLoadZXromsManually, tmp_Counter : DZ 'Manually ' + _mSetStr valLoadZXromsFlag, tmp_Counter : DZ 'By ZX flag' + _mSetStr valLoadZXromsCAD, tmp_Counter : DZ 'On restart' +; _mSetStrRus valLoadZXromsAuto, tmp_Counter : DZ 'On call ' + IF NEW_FEATURE + _mSetStr parSetTime, tmp_Counter : DZ 'Date and time setup : ' + _mSetStr valFolder, tmp_Counter : DB 16,'ENTER',17,0 + ENDIF + IF BETA_BUILD > 0 + _mSetStr testBIOSmsg, tmp_Counter : DZ 'Test build! ',BUILD_DATE,', ',__TIME__ + ENDIF +; + +MSG_ENG: ; !FIXIT подставить макрос _mCreateMsgAddrTable который надо доделать на приём параметра "msgStrings.msg_" или "msgRusStrings.msg_" + LUA ALLPASS + for i = 0, _c("tmp_Counter")-1, 1 do + _pc("WORD " .. "msgStrings.msg_" .. i) + end + ENDLUA +/* + WORD msgStrings.msg_0 + .. + WORD msgStrings.msg_XX ; XX = tmp_Counter +*/ +MSG_ENG.size EQU $-MSG_ENG +;================================================================================================================================== + +;================================================================================================================================== +tmp_Counter = 0 +msgRusStrings: + _mSetStrRus copyRightPeters, tmp_Counter : DZ 'Copyright (c) 2002 Peters Plus' + _mSetStrRus copyRightSPTeam, tmp_Counter : DZ 'Copyright (c) 2009-', SPTeam_year, ' Sprinter Team' + _mSetStrRus setupBiosVer, tmp_Counter : DZ 'Sprinter BIOS v', BIOS_ver_string + _mSetStrRus setupCopyRight, tmp_Counter : DZ 'Copyright (c) 2002 Peters Plus, (c) 2009-', SPTeam_year, ' Sprinter Team' + _mSetStrRus setupUtilityVer, tmp_Counter : DZ 'SETUP Utility v', SetupVer + _mSetStrRus setupHelpStr1, tmp_Counter : DZ 'ESC : Выйти F10 : Сохранить и выйти' + _mSetStrRus setupHelpStr2, tmp_Counter : DZ 'F2 : Сохранить значения ',24,32,25,32,26,32,27,' : Выбор пункта' + _mSetStrRus setupHelpStr3, tmp_Counter : DZ 'F5 : Старые значения PU/PD/+/- : Изменение' + _mSetStrRus setupHelpStr4, tmp_Counter : DZ 'F7 : Значения по умолчанию F3 : Цвета ' + _mSetStrRus toSetupButton, tmp_Counter : DZ ' для входа в SETUP' +;_mSetStrRus forCtrlBootButton, tmp_Counter : DZ ' для загрузки Recovery' + _mSetStrRus forAltBootButton, tmp_Counter : DZ ' для Альтернативной загрузки' + _mSetStrRus cmosChecksumErr, tmp_Counter : DZ 'ВНИМАНИЕ! ОШИБКА КОНТРОЛЬНОЙ СУММЫ CMOS, УСТАНОВЛЕНЫ ЗНАЧЕНИЯ ПО УМОЛЧАНИЮ' + _mSetStrRus cmosDateTimeErr, tmp_Counter : DZ 'ВНИМАНИЕ! ОШИБКА ДАТЫ/ВРЕМЕНИ CMOS, УСТАНОВЛЕНЫ ЗНАЧЕНИЯ ПО УМОЛЧАНИЮ' + _mSetStrRus detectIdePrMA, tmp_Counter : DZ ' Определяем Первичный IDE Master ... [F4 для пропуска] ' + _mSetStrRus detectIdePrSL, tmp_Counter : DZ ' Определяем Первичный IDE Slave ... [F4 для пропуска]' + _mSetStrRus detectIdeSecMA, tmp_Counter : DZ ' Определяем Вторичный IDE Master ... [F4 для пропуска]' + _mSetStrRus detectIdeSecSL, tmp_Counter : DZ ' Определяем Вторичный IDE Slave ... [F4 для пропуска]' + _mSetStrRus ideUnknown, tmp_Counter : DZ 'Неизвестный ' + _mSetStrRus ideNone, tmp_Counter : DZ 'Нет ' + _mSetStrRus ideSkiped, tmp_Counter : DZ 'Пропущен ' + _mSetStrRus ideFail, tmp_Counter : DZ 'Не определён ' + _mSetStrRus spModel, tmp_Counter : DZ 'Модель : ' +.str_ACEX_MODEL EQU $$$+7 ; указатель на строку ниже для патча апдейтером ; !FIXIT ? вытягивать через FN_CRIPT.Acex_ver ? + _mSetStrRus spCNFver, tmp_Counter : DZ 'Ядро 1K30 : v' + _mSetStrRus spMemory, tmp_Counter : DZ 'Память : ' + _mSetStrRus cmosFound, tmp_Counter : DZ 'CMOS : Найден' + _mSetStrRus cmosNone, tmp_Counter : DZ 'CMOS : Нет' + _mSetStrRus memoryAvailable, tmp_Counter : DZ 'Доступно : ' +; _mSetStrRus unknownSTR1, tmp_Counter : DZ '7' +; _mSetStrRus unknownSTR2, tmp_Counter : DZ '8' + _mSetStrRus boardID, tmp_Counter : DZ 'ID платы : ' + _mSetStrRus bootFdd, tmp_Counter : DZ 'Запуск с дискеты' + _mSetStrRus bootHdd, tmp_Counter : DZ 'Запуск с HDD ' + _mSetStrRus bootCd, tmp_Counter : DZ 'Запуск с CD-ROM ' + _mSetStrRus bootRamDrv, tmp_Counter : DZ 'Запуск с RAM диска' + _mSetStrRus bootRecovery, tmp_Counter : DZ 'Запуск восстановления' + _mSetStrRus bootAltDrv, tmp_Counter : DZ 'Альтернативный ' + _mSetStrRus bootFail, tmp_Counter : DZ ' невозможен' + _mSetStrRus bootOk, tmp_Counter : DZ ' OK' + _mSetStrRus afterBootFail, tmp_Counter : DZ 'НАЖМИТЕ ДЛЯ ПЕРЕЗАГРУЗКИ, ДЛЯ НАСТРОЕК ИЛИ ДЛЯ ZX-MODE . . .' +; + _mSetStrRus parLang, tmp_Counter : DZ 'Язык (language) : ' + _mSetStrRus valLangEng, tmp_Counter : DZ 'English ' + _mSetStrRus valLangRus, tmp_Counter : DZ 'Русский ' + _mSetStrRus parMemTest, tmp_Counter : DZ 'Тестирование памяти : ' + _mSetStrRus valDisabled, tmp_Counter : DZ 'Отключено' + _mSetStrRus valEnabled, tmp_Counter : DZ 'Включено ' + _mSetStrRus parSaveRAMdrvs, tmp_Counter : DZ 'Сохранение RAM-дисков : ' + _mSetStrRus parUpdBios, tmp_Counter : DZ 'Обновление BIOS : ' + _mSetStrRus parStartDelay, tmp_Counter : DZ 'Начальное ожидание : ' + _mSetStrRus valNormal, tmp_Counter : DZ 'Среднее ' + _mSetStrRus parTypRate, tmp_Counter : DZ 'Скорость автоповтора : ' + _mSetStrRus val_6, tmp_Counter : DZ '6 ' + _mSetStrRus val_8, tmp_Counter : DZ '8 ' + _mSetStrRus val_10, tmp_Counter : DZ '10' + _mSetStrRus val_12, tmp_Counter : DZ '12' + _mSetStrRus val_15, tmp_Counter : DZ '15' + _mSetStrRus val_20, tmp_Counter : DZ '20' + _mSetStrRus val_24, tmp_Counter : DZ '24' + _mSetStrRus val_30, tmp_Counter : DZ '30' + _mSetStrRus parTypDelay, tmp_Counter : DZ 'Задержка автоповтора (Мсек): ' + _mSetStrRus val_250, tmp_Counter : DZ '250 ' + _mSetStrRus val_500, tmp_Counter : DZ '500 ' + _mSetStrRus val_750, tmp_Counter : DZ '750 ' + _mSetStrRus val_1000, tmp_Counter : DZ '1000' + _mSetStrRus parRebootMsg, tmp_Counter : DZ 'Сообщение о перезагрузке : ' + _mSetStrRus parSysDsk, tmp_Counter : DZ 'Системный диск : ' + _mSetStrRus val1stFDD, tmp_Counter : DZ '1-ый FDD' + _mSetStrRus val2ndFDD, tmp_Counter : DZ '2-ой FDD' + _mSetStrRus val1stIDE, tmp_Counter : DZ '1-ый IDE' + _mSetStrRus val2ndIDE, tmp_Counter : DZ '2-ой IDE' + _mSetStrRus val3rdIDE, tmp_Counter : DZ '3-ий IDE' + _mSetStrRus val4thIDE, tmp_Counter : DZ '4-ый IDE' + _mSetStrRus valRamDsk, tmp_Counter : DZ 'RAM-DISK' + _mSetStrRus valRecovery, tmp_Counter : DZ 'RECOVERY' + _mSetStrRus parAltSysDsk, tmp_Counter : DZ 'Алт. Системный диск : ' + _mSetStrRus parFddFirst, tmp_Counter : DZ 'FDD первый : ' + _mSetStrRus valAuto, tmp_Counter : DZ 'Авто ' +; _mSetStrRus val720, tmp_Counter : DZ '720K ' +; _mSetStrRus val1440, tmp_Counter : DZ '1.44M ' + _mSetStrRus valDash6, tmp_Counter : DZ '------' + _mSetStrRus parFddSecond, tmp_Counter : DZ 'FDD второй : ' + _mSetStrRus parPriIdeMA, tmp_Counter : DZ 'Primary IDE Master',#FF,' : ' + _mSetStrRus valSetup, tmp_Counter : DZ 'Setup ' + _mSetStrRus valCdRom, tmp_Counter : DZ 'CD-ROM' + _mSetStrRus parPriIdeSl, tmp_Counter : DZ 'Primary IDE Slave',#FF,' : ' + _mSetStrRus parSecIdeMA, tmp_Counter : DZ 'Secondary IDE Master',#FF,' : ' + _mSetStrRus parSecIdeSl, tmp_Counter : DZ 'Secondary IDE Slave',#FF,' : ' + IF HDDwriteProtect + _mSetStrRus parHddWrPr, tmp_Counter : DZ 'Защита записи на HDD : ' + ENDIF + _mSetStrRus parScreenY, tmp_Counter : DZ 'Сдвиг экрана по Y : ' + _mSetStrRus valMinus7, tmp_Counter : DZ '-7' + _mSetStrRus valMinus6, tmp_Counter : DZ '-6' + _mSetStrRus valMinus5, tmp_Counter : DZ '-5' + _mSetStrRus valMinus4, tmp_Counter : DZ '-4' + _mSetStrRus valMinus3, tmp_Counter : DZ '-3' + _mSetStrRus valMinus2, tmp_Counter : DZ '-2' + _mSetStrRus valMinus1, tmp_Counter : DZ '-1' + _mSetStrRus val_0, tmp_Counter : DZ ' 0' + _mSetStrRus valPlus1, tmp_Counter : DZ '+1' + _mSetStrRus valPlus2, tmp_Counter : DZ '+2' + _mSetStrRus valPlus3, tmp_Counter : DZ '+3' + _mSetStrRus valPlus4, tmp_Counter : DZ '+4' + _mSetStrRus valPlus5, tmp_Counter : DZ '+5' + _mSetStrRus valPlus6, tmp_Counter : DZ '+6' + _mSetStrRus valPlus7, tmp_Counter : DZ '+7' + _mSetStrRus parScreenX, tmp_Counter : DZ 'Сдвиг экрана по X : ' + _mSetStrRus parFrameInt, tmp_Counter : DZ 'Кадровое прерывание : ' + _mSetStrRus valDash8, tmp_Counter : DZ '--------' + _mSetStrRus valScorpion, tmp_Counter : DZ 'Скорпион' + _mSetStrRus valPentagon, tmp_Counter : DZ 'Пентагон' + _mSetStrRus valSpectrum, tmp_Counter : DZ 'Спектрум' + _mSetStrRus parVSync, tmp_Counter : DZ 'Верт. синхронизация : ' + _mSetStrRus val312_50, tmp_Counter : DZ '312/50Гц' + _mSetStrRus val320_49, tmp_Counter : DZ '320/49Гц' + _mSetStrRus parQuickStartROM, tmp_Counter : DZ 'Запуск в режиме : ' + _mSetStrRus parQuickStartZX, tmp_Counter : DZ 'Спектрум' + _mSetStrRus parQuickStartSP, tmp_Counter : DZ 'Спринтер' + _mSetStrRus valDefault, tmp_Counter : DZ 'По умолчанию' + _mSetStrRus valFDD, tmp_Counter : DZ 'FDD ' + _mSetStrRus valHDD, tmp_Counter : DZ 'HDD ' + _mSetStrRus parTrDosA, tmp_Counter : DZ 'TR DOS A:> : ' + _mSetStrRus parTrDosB, tmp_Counter : DZ 'TR DOS B:> : ' + _mSetStrRus parTrDosC, tmp_Counter : DZ 'TR DOS C:> : ' + _mSetStrRus parTrDosD, tmp_Counter : DZ 'TR DOS D:> : ' + _mSetStrRus parLoadZXroms, tmp_Counter : DZ 'Загружать ZX ПЗУ : ' + _mSetStrRus valLoadZXromsManually, tmp_Counter : DZ 'Вручную ' + _mSetStrRus valLoadZXromsFlag, tmp_Counter : DZ 'По флагу ZX ' + _mSetStrRus valLoadZXromsCAD, tmp_Counter : DZ 'При рестарте' +; _mSetStrRus valLoadZXromsAuto, tmp_Counter : DZ 'При вызове ' + IF NEW_FEATURE + _mSetStrRus parSetTime, tmp_Counter : DZ 'Дата и время : ' + _mSetStrRus valFolder, tmp_Counter : DB 16,'ВВОД',17,0 + ENDIF + IF BETA_BUILD > 0 + _mSetStrRus testBIOSmsg, tmp_Counter : DZ 'Тестовая сборка! ',BUILD_DATE,', ',__TIME__ + ENDIF +; +MSG_RUS: + _mCreateMsgAddrTable +MSG_RUS.size EQU $-MSG_RUS +;================================================================================================================================== + ASSERT MSG_ENG.size = MSG_RUS.size, "ERROR IN MESSAGE STRINGS: RUS and ENG do not match" +; \ No newline at end of file diff --git a/Crazy BIOS/rom/ZX/ZX_FUNC.ASM b/Crazy BIOS/rom/ZX/ZX_FUNC.ASM new file mode 100644 index 0000000..36d4c70 --- /dev/null +++ b/Crazy BIOS/rom/ZX/ZX_FUNC.ASM @@ -0,0 +1,245 @@ +; Вход через USR 15600 + ASSERT $ = #C0, "Error with RET_FROM_BIOS_TO_BASIC48 address!!!" +RET_FROM_BIOS_TO_BASIC48: + CALL CH_2 + CALL COMAND_LINE ; ВЫПОЛНЕНИЕ КОМАНДЫ, ЕСЛИ ЕСТЬ + ; Вход без команды + JP SW_ROM_1 ; ВОЗВРАТ В << MAIN MENU >> + +;-----------------------------------------------------------------------; +; + + +; +;----------------------------[ ??????????? ]----------------------------; +; TURBO_OFF: +; LD A,D_TBOFF +; OUT (SYS_PORT.ON),A +; RET +; +; TURBO_ON: +; LD A,D_TBON +; OUT (SYS_PORT.ON),A +; RET +; +; JP_HL: JP (HL) +; +;PRINT_LINE: +; LD A,(HL) +; INC HL +; CP 0FFh +; RET Z +; RST 10H +; JR PRINT_LINE +; +; JP RESET_128 +;-----------------------------------------------------------------------; +; + + +;-----------------------------------------------------------------------; +; ******* SERVICE ******* +;-----------------------------------------------------------------------; + +;------[ ДЕШИФРАЦИЯ КОМАНДНОЙ СТРОКИ,ПЕРЕДАННОЙ ДЛЯ "EXPANSION" ]-------; +COMAND_LINE: + LD HL,(#5C5D) ;!HARDCODE CH_ADR +COMAND_LOOP: + LD A,(HL) + INC HL + CP ":" + JR Z,COMAND_L1 + CP ZX_Char.carriage_return + JR NZ,COMAND_LOOP + RET + +COMAND_L1: + LD A,(HL) + CP ZX_Token.rem + RET NZ + INC HL +COMAND_OK: ; ОБНАРУЖЕНА КОМАНДА ДЛЯ 'expansion' + LD A,(HL) + INC HL + CP ':' + JP Z,MENU_S1 + CP ZX_Char.carriage_return + JP Z,MENU_S1 + CP 'I' + JR Z,COMAND_ISD + CP 'i' + JR Z,COMAND_ISD + CP 'T' + JR Z,TASK_SWITCH + CP 't' + JR Z,TASK_SWITCH + DEC HL + POP BC + JP BASIC_MENU +MENU_S1: + POP BC + CALL SERVICE + JP SW_ROM_1 + +COMAND_ISD: + LD A,(HL) + INC HL + CP 'S' + JP Z,COMAND_ISD2 + CP 's' + JP Z,COMAND_ISD2 + RET + +COMAND_ISD2: + POP BC + CALL ISDOS + JP SW_ROM_1 + + +TASK_SWITCH: +; *** Сохранить задачу *** + PUSH IY + PUSH IX + PUSH AF + PUSH BC + PUSH DE + PUSH HL + + EXX + EX AF,AF' + + PUSH AF + PUSH BC + PUSH DE + PUSH HL + + LD A,R + PUSH AF + LD A,I + PUSH AF + + LD A,(HL) + RLCA + RLCA + RLCA + RLCA + AND #30 ; новая задача 0..3 + LD C,A + + IN A,(SLOT3) + LD B,A ; 3-я страница текущей задачи + LD A,SYS_PAGE + OUT (SLOT3),A + + LD IX,SYS_PAGE.TASK_DATA ; данные задач + LD E,(IX) ; старая задача + LD D,0 + ADD IX,DE ; данные текущей задачи + LD E,16 + ADD IX,DE ; смещение данных в таблице задач + + LD (IX+1),B ; сохранить страницу 3 + LD HL,0 + ADD HL,SP + LD (IX+2),L ; сохранить стек задачи + LD (IX+3),H + SET 0,(IX) ; установить флаг сохраненности текущей задачи + RES 1,(IX) ; установить флаг, что задача покинута + + LD IX,SYS_PAGE.TASK_DATA + LD E,C + LD D,0 + ADD IX,DE ; новая задача + LD E,16 + ADD IX,DE ; смещение данных в таблице задач + + BIT 1,(IX) +; JR NZ,TASK_IN_WORK ; задача в работе ??? неверное завершение + ; сбрасывать или просто возвращаться + + BIT 0,(IX) ; была сохранена/нет + JR NZ,TASK_SET ; задача существует + +; задачи не было! + LD IX,SYS_PAGE.TASK_DATA + LD A,C ; задача + LD (IX),A ; установить новую задачу текущей + + JP SPECTRUM_TASK ; запустить новую задачу! +; и пока пофиг распределение памяти! + +TASK_SET: + LD IX,TASK_RESTORE + LD A,C + EXX + JP INIT_PAGES ; переключить все страницы! + +TASK_RESTORE: + EXX + LD A,SYS_PAGE + OUT (SLOT3),A + LD A,C + LD IX,SYS_PAGE.TASK_DATA + LD (IX),A ; установить новую задачу текущей + + LD E,A + LD D,0 + ADD IX,DE ; новая задача + LD E,16 + ADD IX,DE + + LD L,(IX+2) ; вспомнить стек + LD H,(IX+3) + LD SP,HL + LD A,(IX+1) ; вспомнить третью страницу + OUT (SLOT3),A + + + POP AF ; восстановить + LD I,A + POP AF + LD R,A + POP HL + POP DE + POP BC + POP AF + EX AF,AF' + EXX + POP HL + POP DE + POP BC + POP AF + POP IX + POP IY + ; вернуться в задачу + +NO_TASK: + POP BC + JP SW_ROM_1 + +; 259F - ADRESS BASIC128 - MAIN_MENU +;-----------------------------------------------------------------------; + + + +;-----------------------------------------------------------------------; +; *** UTILITES *** +;-----------------------------------------------------------------------; + +; C_0030: ; получить раб обл +; CALL_48X 0030h +; RET +C_19E8: ; очистить раб обл + CALL_48X #19E8 ;!HARDCODE + RET +C_1655: ; получить пространство + CALL_48X #1655 ;!HARDCODE + RET +CLS: +C_0D6B: CALL_48 #0D6B ;!HARDCODE + RET +CH_2: LD A,2 +C_1601: ; OPEN CHANEL + CALL_48 #1601 ;!HARDCODE + RET +; \ No newline at end of file diff --git a/Crazy BIOS/rom/ZX/ZX_MENU.ASM b/Crazy BIOS/rom/ZX/ZX_MENU.ASM new file mode 100644 index 0000000..1b781ec --- /dev/null +++ b/Crazy BIOS/rom/ZX/ZX_MENU.ASM @@ -0,0 +1,747 @@ +; "MENU PROGRAMS." +;********************************* +; FOR INCLUDE !!! +;********************************* +; Обслуживание МЕНЮ +; HL - адрес таблицы программ +; A - номер в таблице +; если A=-1, то возврат, +; иначе выполнение +;***************************** +EXEC_PNT: + INC A + RET Z + ;!FIXIT почему не так? + ; DEC A + ; JR Z,EXEC_HL + ; LD D,0 + ; LD E,A + ; XOR A + ; ADC HL,DE + ; ADC HL,DE + ; +EXEC_PNT_LOOP: + DEC A + JR Z,EXEC_HL + INC HL + INC HL + JR EXEC_PNT_LOOP +EXEC_HL: + LD E,(HL) + INC HL + LD D,(HL) + INC HL + EX DE,HL + JP (HL) +RET_FROM_M: + POP HL + RET + +;**************************************** +; РАБОТА С MENU_128 +;**************************************** +; ВХОД: DE - адрес меню +; BC - длина меню +; ВЫХОД: A - выбранный пункт +;**************************************** +RUN_MENU: + PUSH IX + PUSH DE ; DE - MENU + PUSH BC ; BC - len_menu + + LD A,(DE) + DEC A ; число CMD + CP 9 ; !HARDCODE макисмальное число пунктов меню + JR C,RUN_M_1 +RUN_MN_ERR: + POP BC + POP DE + LD A,#FF ; вернуться с номером 255 - ошибка + POP IX + RET +RUN_M_1: + LD A,(ZX_VARS.PROG.SWAP_ROM) + CP #F5 ; сравнить А с опкодом PUSH AF + JR NZ,RUN_MN_ERR + + + LD HL,LEN_P_M + ADD HL,BC ; HL - нужная длина памяти + LD B,H ; HL -> BC + LD C,L + LD HL,(ZX_VARS.WORK_SPACE) ; HL - начало раб обл + + PUSH BC + PUSH HL + + CALL C_1655 ; получить рабочую память + + POP DE + PUSH DE ; начало раб обл + + LD BC,LEN_P_M ; длина программы меню + LD HL,MENU_128 ; сама программа + LDIR ; программа перемещена. DE - место для MENU + POP BC + PUSH BC ; начало программы + + PUSH DE ; сохранить место для MENU + LD DE,MN_128_S ; данные для shifter + CALL SHIFTER ; изменить данные в соответствии с положением в MEM + POP DE ; вернуть место для MENU + + POP HL ; начало программы + POP IX ; длина данных + POP BC ; длина меню + EX (SP),HL ; HL - меню + LDIR ; переместить данные MENU + + POP HL ; адрес программы MENU + PUSH HL + PUSH IX ; длина раб. обл + CALL JP_HL ; вызов программы MENU + POP BC ; вернуть длину раб обл + POP HL ; и начала программы + + PUSH AF ; сохранить номер выбора + CALL C_19E8 ; освободить память !! + POP AF ; вернуть номер выбора + POP IX + RET ; возврат из программы RUN_MENU +JP_HL: JP (HL) +;************************************** +; 128k MENU +;************************************** +;!HARDCODE +MENU_PROG EQU #25B9 ; #25B9 in sp_128.asm +;SWAP_ROM EQU #5B00 +NEW_SP EQU #1F45 ; L1F45: in sp_128.asm +RET_SP EQU #1F20 ; L1F20: in sp_128.asm + +;************************************** +; Программа вызова MENU_128 из ОЗУ. +;************************************** +MN_128_S: + DB SH_1 - MENU_128+1 + DB SH_2 - MENU_128+1 + DB SH_3 - MENU_128+1 + DB SH_4 - MENU_128+1 + DB SH_5 - MENU_128 + DB SH_6 - MENU_128 + DB SH_7 - MENU_128 + DB SH_8 - MENU_128 + DB SH_9 - MENU_128 + DB SH_A - MENU_128 + DB SH_B - MENU_128 + DB SH_C - MENU_128 + DB 0 +;************************************** +; Эта программа перемещается в озу +;************************************** +MENU_128: + XOR A + OUT (SYS_PORT.RAM),A + CALL ZX_VARS.PROG.SWAP_ROM + CALL NEW_SP + +SH_1: LD DE,MENU_DAT - MENU_128 + LD HL,ZX_VARS.MENU_TBL.JUMP + LD BC,4 + LDIR + +SH_2: LD HL,MENU_128_E - MENU_128 + LD (ZX_VARS.MENU_TBL.JUMP),HL +SH_3: LD HL,MENU_128_E2 - MENU_128 + LD (ZX_VARS.MENU_TBL.TEXT),HL + JP MENU_PROG + +RET_M EQU $-MENU_128 +SH_4: LD HL,MENU_DAT - MENU_128 + LD DE,ZX_VARS.MENU_TBL.JUMP + LD BC,4 + LDIR + + CALL RET_SP + CALL ZX_VARS.PROG.SWAP_ROM + EX AF,AF' + ;LD A,0 + ;OUT (CNF_PORT),A + LD A,SYS_PORT.EXTENSION + OUT (SYS_PORT.ROM),A ;!!!!! версия для ПЗУ + EX AF,AF' + RET +MENU_DAT: + DW 0,0 +MENU_128_E: + DB 8 + DB 0 +SH_5: DW RET_M + DB 1 +SH_6: DW RET_M + DB 2 +SH_7: DW RET_M + DB 3 +SH_8: DW RET_M + DB 4 +SH_9: DW RET_M + DB 5 +SH_A: DW RET_M + DB 6 +SH_B: DW RET_M + DB 7 +SH_C: DW RET_M +MENU_128_E2: + +LEN_P_M EQU $-MENU_128 + +;************************************** +; RST 30 - получение BC SPACES с адреса HL +; #19E8 - освобождение BC spaces с адреса HL +; HL - раб. ячейка +; BC - адрес программы +; DE - адрес данных для перемещения +SHIFTER: + LD A,(DE) ; (DE) - SHIFT IN PROG + AND A + RET Z + INC DE + LD L,A + LD H,0 + + ADD HL,BC ; HL - ADRESS FOR SHIFT + LD A,(HL) ; (HL)=(HL)+BC + ADD A,C + LD (HL),A + INC HL + LD A,(HL) + ADC A,B + LD (HL),A + JR SHIFTER + +;******************************************* +; МЕНЮ : байт 1 - для результата +; байт 2 - число пунктов +1 +; название меню, код 0FFh ( COPY ) +; пункты меню окончание байтом с +; уст, 7-м битом + пустая строка !! +;******************************************* +BASIC_MENU: +; LD A,(HL) +; CP 'S' +; JP Z,SET_SYSTEM + + LD DE,(ZX_VARS.CH_ADR) + PUSH DE + LD (ZX_VARS.CH_ADR),HL + CALL_48X #1C8C ; SYMBOL VAR + CALL_48X #2BF1 ; input txt !!! + ; DE - adr + ; BC - len + PUSH DE + PUSH BC + INC DE + CALL TST_M + JR C,NO_EXE_M + CALL RUN_MENU + LD (IY+0),255 +NO_EXE_M: + POP BC + POP DE + LD (DE),A + POP HL + LD (ZX_VARS.CH_ADR),HL + JP SW_ROM +TST_M: + PUSH DE + PUSH BC + EX DE,HL + LD D,(HL) + INC D + LD A,255 + CPIR + JR NZ,ERR_TST_M +LOOP_TST_M: + LD A,B + OR C + JR Z,ERR_TST_M + + BIT 7,(HL) + INC HL + DEC BC + JR Z,LOOP_TST_M + DEC D + JR NZ,LOOP_TST_M + POP BC + POP DE + AND A + RET + +ERR_TST_M: + POP BC + POP DE + LD A,255 + SCF + RET + +;************************************** + +CALL_DOS_MOVE: + LD HL,DOS_PROG + LD DE,DOS_PROG.Exec + LD BC,DOS_PROG.Size + LDIR + RET +; +; HL - адрес команды, BC - длина команды +CALL_DOS1: + LD C,(HL) + INC HL + LD B,0 + LD DE,(ZX_VARS.E_LINE) + LD (ZX_VARS.CH_ADR),DE + LDIR + LD (ZX_VARS.WORK_SPACE),DE + LD (ZX_VARS.STK_BOT),DE + LD (ZX_VARS.STK_END),DE + CALL CALL_DOS_MOVE + JP DOS_PROG.Exec + +DOS_PROG: + DISP #5C00 - DOS_PROG.Size ;!HARDCODE + //DOS_PROG: +.Exec: PUSH AF + XOR A + OUT (SYS_PORT.RAM),A + POP AF + //DOS_PROG_A+1: +.Patch+2: CALL #3D03 ;!HARDCODE + PUSH AF + ;!FIXIT сделать через условие компиляции ZX_ROM_BIOS + //LD A,0 + //OUT (CNF_PORT),A + LD A,SYS_PORT.EXTENSION + OUT (SYS_PORT.ROM),A ;!!!!! версия для ПЗУ + POP AF + RET + //DOS_PROG_LEN +.Size EQU $ - .Exec + ENT + + ;????? вроде, не используются +CONT_PROG: + LD HL,#1AFD ;!HARDCODE COM_LN: + PUSH HL + LD HL,#5B00 ;!HARDCODE + PUSH HL + LD DE,ZX_VARS.FLG_INPUT + LD BC,1 + LD A,#E8 ;!HARDCODE + LD (DE),A + JP SW_ROM +CALL_DOS: + PUSH HL + PUSH DE + PUSH BC + PUSH AF + CALL CALL_DOS_MOVE + LD A,#13 ;!HARDCODE #13 из AUTO_1303 + LD (DOS_PROG.Patch),A + POP AF + POP BC + POP DE + POP HL + JP DOS_PROG.Exec + ; +; + +;=======================================================================; +;=======================================================================; +;=======================================================================; +SERVICE: + //LD HL,SR_TAB + LD DE,SR_MENU + LD BC,SR_MENU.Size + //PUSH HL + CALL RUN_MENU ;09f3 + LD HL,SR_TAB + //POP HL + CALL EXEC_PNT + JR SERVICE + +SR_TAB: DW UTILIT + DW GOTO_TRDOS.m128 + DW GOTO_TRDOS.m48 + DW TURBO_OFF + DW TURBO_ON + DW CLEAR_RAM + DW RET_FROM_M + +; DC - every last character of a string will have bit 7 set +SR_MENU: + BYTE 8 ; количество пунктов + BYTE 'Options ',#FF ; заголовок меню + DC 'RUN disk.trd' + DC '128 TR-DOS' + DC '48 TR-DOS' + DC 'TURBO OFF ' + DC 'TURBO ON ' + DC 'Clear RAM' + DC 'RETURN' + DC " " ; маркер конца +.Size EQU $-SR_MENU + +;***************************** + +;SR_48R: +GOTO_TRDOS: +.m128: LD A,#10 + JR .RUN +;SR_48: +.m48: LD A,#30 ; Стопор на PORT_128 !!! +;SR_48A: +.RUN: LD BC,#7FFD + OUT (C),A + LD BC,0 ; НА 0 !! + PUSH BC + LD BC,#3D2F ; В DOS ! + PUSH BC + JP SW_ROM + +;******************************* +TURBO_OFF: + LD A,BIOS.FN_TURBO.OFF + LD C,BIOS.FN_TURBO + JP_to_BIOS +TURBO_ON: + LD A,BIOS.FN_TURBO.ON + LD C,BIOS.FN_TURBO + JP_to_BIOS + +;******************************* + +CLEAR_RAM: + DI + LD C,BIOS.FullInit + RST_to_BIOS + ; при очистке памяти из меню спектрума возврат в DSS по CAD + ; будет опасным (RAM Blocks освободились), + ; поэтому отключаем перехват ресета. + LD A,ACEX.RET_PORT + LD BC,BIOS.SET_PORTS + ;[x] SET_PORTS: no need to call from #3D13 and DI. 31/12/23 + ;CALL ToBIOS_3D13 + RST_to_BIOS + ; + EI + RET + +;SR_CL_MEM: +; DI +; LD A,10H +;SR_CL_R2: +; LD BC,1FFDH +; OUT (C),A +; EX AF,AF' +; XOR A +;SR_CL_R1: +; LD BC,7FFDH +; OUT (C),A +; LD HL,0C000H +; LD DE,0C001H +; LD BC,03FFFH +; LD (HL),L +; LDIR +; INC A +; CP 48H +; JR NZ,SR_CL_R1 +; EX AF,AF' +; CP 0 +; JP Z,BASIC_128 ; выход на сброс BASIC 128 +; LD A,0 +; JR SR_CL_R2 + +;***************************** +; *** MENU IS-DOS *** +;***************************** + +ISDOS: + LD HL,IS_TAB + LD DE,IS_MENU + LD BC,IS_MENU.Size + PUSH HL + CALL RUN_MENU + POP HL + CALL EXEC_PNT + JR ISDOS + +IS_TAB: +; DW TR_DOS +; DW SP_DOS + DW SPRINTER_1X + DW AY8910_X + DW PENTAGON + DW SCORPION + DW PENTAGON512 + DW SPRINTER_reset ;SPRINTER_2X + DW RET_FROM_M + +; DC - every last character of a string will have bit 7 set +IS_MENU: + BYTE 8 ; количество пунктов + BYTE 'Hardware',#FF ; заголовок меню + DC 'Sprinter ZX ' + DC 'ZX Spectrum' + DC 'Pentagon 128' + DC 'Scorpion 256' + DC 'Pentagon 512' + DC 'Restart ' + DC 'RETURN' + DC " " ; маркер конца +.Size EQU $-IS_MENU + +;****************************** +;SP_DOS: +; LD B,0E2H +; LD A,0E1H +; JR TR_DOS1 +;TR_DOS: +; LD B,0EAH +; LD A,0E1H +;TR_DOS1: +; CALL DOS_ON +; CALL SET_ROM_PAGES +; CALL DOS_OFF +; RET +;****************************** + + +;************************************************** +;Sprinter ZX +SPRINTER_1X: + CALL _SET_CNF + LD C,BIOS.RST_CONF.SP97_1 + RST_to_BIOS + CALL CNF_PN_320 + LD L,2 ;FN_SYNC.INT_PENT + JR 1F ;!FIXIT метку придумать +; +;ZX Spectrum +AY8910_X: + CALL _SET_CNF + LD C,BIOS.RST_CONF.AY8910 + RST_to_BIOS + + LD A,#FA ; no ACC, Original waits + LD (Port_All_Mode),A + + CALL CNF_SC_312 + LD L,3 ;FN_SYNC.INT_ORIG +1: LD DE,CNF_PORT.CNF_0 + CNF_PORT.TURBO.ON + CALL CONFIG_SET + CALL CLS ;!FIXIT нужно ли? + RET +; + +SCORPION: + CALL _SET_CNF + CALL CNF_SC_312 + LD L,1 ;FN_SYNC.INT_SCORP + LD DE,CNF_PORT.CNF_1 + CNF_PORT.TURBO.ON + JR CONFIG_SET + +PENTAGON: + CALL _SET_CNF + CALL CNF_PN_320 + LD L,2 ;FN_SYNC.INT_PENT + LD DE,CNF_PORT.CNF_2 + CNF_PORT.TURBO.ON + JR CONFIG_SET + +PENTAGON512: + CALL _SET_CNF + CALL CNF_PN_320 + LD L,2 ;FN_SYNC.INT_PENT + LD DE,CNF_PORT.CNF_2 + CNF_PORT.TURBO.ON + CNF_PORT.CNF_512 +; JR CONFIG_SET +CONFIG_SET: + PUSH DE + + EI + HALT + DI + + IN A,(SLOT3) + EX AF,AF' + LD A,SYS_PAGE + OUT (SLOT3),A + LD (SYS_PAGE.CONFIG_DE),DE + ;!FIXIT есть ли смысл делать до FN_SYNC? + LD A,(ZX_VARS.BORDER) + RRCA + RRCA + RRCA + AND 7 + OUT (BorderColor),A + ; + EX AF,AF' + OUT (SLOT3),A + + LD A,L + LD C,BIOS.FN_SYNC + RST_to_BIOS + + LD HL,#4104 ;!HARDCODE + LD E,0 + LD BC,256*4 + BIOS.LP_OPEN_S ;!HARDCODE + RST_to_BIOS + + LD HL,#5104 ;!HARDCODE + LD E,0 + LD BC,256*4 + BIOS.LP_OPEN_S + RST_to_BIOS + + POP DE + LD A,E + OUT (SYS_PORT.ROM),A + + IM 1 + EI + RET + +SPRINTER_reset: + CALL _SET_CNF + LD BC,256*BIOS.REINIT.SOFT_RESET + BIOS.REINIT + JP_to_BIOS + +_SET_CNF: + DI + LD A,CNF_PORT.CNF_0 + CNF_PORT.TURBO.ON + OUT (SYS_PORT.ROM),A + RET + +CNF_SC_312: + LD A,Port_VSYNC.SET_312L + OUT (Port_VSYNC),A + RET + +CNF_PN_320: + LD A,Port_VSYNC.SET_320L + OUT (Port_VSYNC),A + RET + +; LD A,CNF_0 +; OUT (SYS_PORT.ROM),A +; CALL DOS_OFF +; JP 0 + +;***************************** +; *** MENU UTILITES *** +;***************************** +;!FIXIT это запуск c:\disk.trd - не думаю, что это нужно, можно заменить +UTILIT: + LD HL,C_DISK_C + CALL CALL_DOS1 + + ;CALL DOS_ON + ;LD A,0 ; DETECT_HDD + ;CALL EXP_HDD + LD C,BIOS.HDD_INIT + RST_to_BIOS + ;CALL DOS_OFF + + + JR C,DISK_UTILIT + + LD HL,C_DISK_C3 + CALL CALL_DOS1 + +UTIL_DISK: + XOR A + LD C,BIOS.FreeMemRMD + RST_to_BIOS + + LD HL,C_DEMO6 + CALL CALL_DOS1 + + XOR A + LD C,BIOS.GET_RAMD_ST + RST_to_BIOS + + JR C,UTIL_DISK_L1 + JR Z,UTIL_DISK_L1 + + LD HL,C_DISK_C1 + CALL CALL_DOS1 + LD HL,C_DISK_C2 + CALL CALL_DOS1 + RET + +UTIL_DISK_L1: + LD A,(ZX_VARS.OPER_DISK) + INC A + CP 2 + JR Z,DISK_UTIL_RET + LD HL,C_DISK_C5 + CALL CALL_DOS1 + JR UTIL_DISK + +DISK_UTIL_RET: + LD HL,C_DISK_C6 + CALL CALL_DOS1 + RET + +DISK_UTILIT: + LD HL,C_DISK_C4 + CALL CALL_DOS1 + JR UTIL_DISK + +C_DEMO6: DB .Size, ZX_Token.rem, ':/disk.trd', 13,80 +.Size EQU $-C_DEMO6-1 + +;*************************************** + +;VERSION: DEFB 22,21,0 +; DEFB 16,2,"Expansion 3.02  1997 ELSY Co.",16,1,0FFh + +;********************************************** + +DOS_RUN: + LD HL,C_DISK_C1 + CALL CALL_DOS1 + + LD HL,C_DISK_C2 + CALL CALL_DOS1 + RET + +START_TRD: + LD HL,C_DISK_C + CALL CALL_DOS1 + LD HL,C_DISK_C0 + CALL CALL_DOS1 + LD HL,C_DISK_C3 + CALL CALL_DOS1 + RET + +C_DISK_C: DB .Size, ZX_Token.rem, ':', 13,80 +.Size EQU $-C_DISK_C-1 + +C_DISK_C0: DB .Size, ZX_Token.rem, ':/CLEAR E', 13,80 +.Size EQU $-C_DISK_C0-1 + +C_DISK_C1: DB .Size, ZX_Token.rem, ':/RMD E', 13,80 +.Size EQU $-C_DISK_C1-1 + +C_DISK_C2: DB .Size, ZX_Token.rem, ':RUN', 13,80 +.Size EQU $-C_DISK_C2-1 + +C_DISK_C3: DB .Size, ZX_Token.rem, ':/HDD', 13,80 +.Size EQU $-C_DISK_C3-1 + +C_DISK_C4: DB .Size, ZX_Token.rem, ':/FDD', 13,80 +.Size EQU $-C_DISK_C4-1 + +C_DISK_C5: DB .Size, ZX_Token.rem, ':/B:', 13,80 +.Size EQU $-C_DISK_C5-1 + +C_DISK_C6: DB .Size, ZX_Token.rem, ':/A:', 13,80 +.Size EQU $-C_DISK_C6-1 +; \ No newline at end of file diff --git a/Crazy BIOS/rom/_not_used/CrazyBlaster.asm b/Crazy BIOS/rom/_not_used/CrazyBlaster.asm new file mode 100644 index 0000000..bd2b183 --- /dev/null +++ b/Crazy BIOS/rom/_not_used/CrazyBlaster.asm @@ -0,0 +1,1518 @@ + + + INCLUDE 'Shared_Includes/constants/SP2000.inc' + INCLUDE 'Build/updater.inc' +;INCLUDE 'Shared_Includes/structures/FileSystem.inc' +;INCLUDE 'Shared_Includes/macroses/macros.z80' +;INCLUDE 'Shared_Includes/constants/BIOS_EQU.inc' + + DEFINE sec_high 0 + DEFINE sec_low 1 + DEFINE SYS_FN_PAGE 1 +;DEFINE ACEX_ROM_COPY_PAGE 0 + DEFINE bufer_adr #C000 + DEFINE sys_fn_in_sectors #4000 / #200 + DEFINE bios_size_in_sectors 512 + DEFINE flasher_size_in_sectors 1 + DEFINE image_size_in_sectors flasher_size_in_sectors + bios_size_in_sectros + DEFINE TYPE_OF_ACEX 3 ; 3 - 1K30, 5 - 1K50 + +;█████████████████████[ FIRST SECTION - CONF ROM ]█████████████████████; + OUTPUT './Build/CrazyBlaster.raw' + ORG #0000 + ; + ;███████ инициализация системных портов Z84C15 ████████████████; +BEGIN_CB: DI + LD BC,#FF*256 + Z84.SYS.Control + XOR A ; Z84.REG.WaitState_Ctrl + OUT (C),A ; Z84.SYS.Control + INC C ; Z84.REG.WaitState_MemBound + OUT (C),A ; Z84.SYS.Data ; set 0 Waits + ; + DEC C + LD A,3 ; Z84.REG.Misc_Ctrl + OUT (C),A ; Z84.SYS.Control + INC C + ; boundary set! + LD A,1 ; enable CS0, disable CS1 + OUT (C),A ; Z84.SYS.Data + ;███████ инициализация DCP ████████████████████████████████████; + LD HL,INIT_SLOTS +DCP_INIT: LD C,XL + LD B,XH + LD E,YL + LD D,YH + EXX + ; + LD HL,#C000 + LD DE,#C001 + LD BC,#3FFF + LD (HL),L + LDIR + ; + LD IY,DCP_DATA + LD IX,.ret + ; +.loop: LD L,(IY) + LD H,(IY+1) + LD E,(IY+2) + LD D,(IY+3) + LD B,(IY+4) + JP .PARSE_TABLE + ; +.ret: LD BC,5 + ADD IY,BC + LD A,(IY+2) + OR (IY+3) + JR NZ,.loop + ; + EXX + LD XL,C + LD XH,B + LD YL,E + LD YH,D + ; First IN command - OPEN DCP + IN A,(SLOT3) + JP (HL) + ; +.PARSE_TABLE: LD A,L + AND E + LD L,A + ; + LD A,H + AND D + OR #C0 + LD H,A + ; + LD A,D + OR #C0 + LD D,A + ; +.loop_parse: LD (HL),B + ; + LD A,L ; замаскировать неизменяемые биты 1-ми + OR E ; для прохождения переноса + INC A ; увеличить адрес + JR Z,.carry ; возник перенос + ; + OR E + XOR E ; обнулить неизменяемые биты + LD C,A ; изменяемая часть + ; + LD A,L + AND E ; выделить неизменяемую + OR C + LD L,A ; добавить изменяемую часть + ; + JR .loop_parse ; цикл + ; A = 0 +.carry: LD A,L ; забить изменяемые биты нулями + AND E + LD L,A + ; + LD A,H ; замаскировать неизменяемые биты 1-ми + OR D ; для прохождения переноса + INC A ; увеличить адрес + JR Z,.return + ; + OR D + XOR D + LD C,A ; изменяемая часть + ; + LD A,H + AND D ; выделить неизменяемую + OR C + LD H,A ; добавить изменяемую часть + JR .loop_parse +.return: JP (IX) + ;███████ Инициализация страниц ████████████████████████████████; +INIT_SLOTS: XOR A + OUT (SLOT0),A + OUT (SLOT1),A + DEC A + OUT (SLOT2),A + LD A,SYS_PAGE + OUT (SLOT3),A + ;███████ Инициализация портов █████████████████████████████████; + LD A,CNF_PORT.CNF_0 + CNF_PORT.TURBO.ON + OUT (SYS_PORT.ROM),A + ;███████ Инициализация стека ██████████████████████████████████; + LD SP,#4000 + ;███████ Переброс оставшегося кода в RAM ██████████████████████; + LD HL,0 + LD DE,#4000 + LD BC,END_CB + LDIR + XOR A + OUT (FastRAM.SLOT0),A + OUT (SYS_PORT.RAM),A + INC A + OUT (SLOT1),A + IN A,(FastRAM.OFF) + ; ТУТ МЫ УЖЕ В ОЗУ В ТОМ ЖЕ КОДЕ И АДРЕСЕ + ; страницы 0,1,2,#FE + ;██████████████████████████████████████████████████████████████; + ;███████ Рабочий код ██████████████████████████████████████████; + ;██████████████████████████████████████████████████████████████; + ; адрес процедуры ошибки + LD HL,ERROR + PUSH HL + ;███████ Инициализация HDD ████████████████████████████████████; + CALL HDD_INIT + RET C + ;██████ Установка страниц для загрузки данных █████████████████; + CALL Init_Mem + ;██████ Загрузка ██████████████████████████████████████████████; + ; дополнительные функции +LOAD_FNs: LD A,(RESERVED_PAGES.SYS_FN) ; страница буфера, если адрес в окне #C000 (BLOCK_ID) + LD B,sys_fn_in_sectors ; число читаемых секторов + LD HL,bufer_adr ; адрес буфера данных + LD IX,sec_high ; абсолютный номер сектора старшая часть + LD DE,sec_low ; абсолютный номер сектора младшая часть + PUSH HL + CALL FN_HDD_READ + ; Образ BIOS +LOAD_DATA: LD B,4 + LD IY,RESERVED_PAGES.BIOS + POP HL + CALL .LOADER + ; Картинка и Апдейтер + LD B,2 + CALL .LOADER + JP BEGIN_CB_IMG +.LOADER: ; загрузка по 128 секторов +.loop: PUSH HL + PUSH BC + LD A,(IY) + LD B,128 + LD DE,1 + CALL FN_HDD_READ_NEXT + LD BC,4 + ADD IY,BC + POP BC + POP HL + DJNZ .loop + RET + ;██████████████████████████████████████████████████████████████; + + + ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░; + ;░░░░░░ Процедуры ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░; + ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░; +; FOR LBA ONLY - NEXT_READ +; HL - bufer, A - page +; B - numer of sectors +; DE - add_par (next+DE) (d.b. 1 for NEXT) +FN_HDD_READ_NEXT: + AND A + INC B + DEC B + RET Z ; ret if 0 sectors + CALL HD_WAIT + RET C + CALL NEXT_ADD_SEC + JR FN_HDD_READ.L1 + ; +; HL - BUFER, A - PAGE, +FN_HDD_READ: AND A + INC B + DEC B + RET Z + CALL HD_WAIT + CALL NC,HD_PREPARE + RET C +.L1: EXX + LD C,SLOT3 + IN B,(C) + EXX + OUT (SLOT3),A + EX AF,AF' + ; + LD BC,IDE.Write.Command + LD A,IDE.ATA.ReadSectorsWithRetry + OUT (C),A +.L2: CALL WAIT_HDD + AND IDE.ControlByte.DataRequest + JR Z,.HD_RET + ; + LD BC,IDE.Read.Data + INIR + INIR + ; + LD A,H + OR L + JR NZ,.L2 + ; + LD A,SYS_PAGE + OUT (SLOT3),A + EX AF,AF' + LD H,high SYS_PAGE.RAMD_FAT ;!FIXIT читать из таблицы тут + LD L,A + LD A,(HL) + OUT (SLOT3),A + EX AF,AF' + LD HL,#C000 + JR .L2 + ; +.HD_RET: EXX + OUT (C),B + EXX + LD BC,IDE.Read.Error + IN A,(C) + AND A + SCF + RET NZ + ; + EX AF,AF' + AND A + RET + ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░; + + ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░; +NEXT_ADD_SEC: PUSH AF + ; + LD A,B + LD BC,IDE.Write.Counter ; Установить число секторов для записи + OUT (C),A + ; + DEC B + INC C + IN A,(C) ; IDE.Read.Sector + ADC A,E + INC B + OUT (C),A ; IDE.Write.Sector + ; + DEC B + INC C + IN A,(C) ; IDE.Read.CylinderLow + ADC A,D + INC B + OUT (C),A ; IDE.Write.CylinderLow + ; + DEC B + INC C + IN A,(C) ; IDE.Read.CylinderHigh + ADC A,0 + INC B + OUT (C),A ; IDE.Write.CylinderHigh + ; + LD BC,IDE.Read.Control + IN A,(C) + LD D,A + ADC A,0 + AND #0F + LD E,A + LD A,D + AND #F0 + OR E + INC B + OUT (C),A ; IDE.Write.DeviceHead + ; + POP AF + RET + ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░; + + ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░; +HD_PREPARE: PUSH AF + PUSH HL + ; HD_CALC_SECS + LD L,E + LD E,D + LD D,XL + LD A,XH + AND #0F ; LBA 28 + LD H,A + ; + LD A,B + LD BC,IDE.Write.Counter ; Установить число секторов для записи + OUT (C),A + ; + INC C + OUT (C),L + INC C + OUT (C),E + INC C + OUT (C),D + ; + LD BC,IDE.Read.Control + IN A,(C) + AND #F0 ; !!!!! посмотреть + OR H + INC B ; IDE.Write.DeviceHead + OUT (C),A + POP HL ; BUFER & PAGE + POP AF + AND A + RET + ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░; + + ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░; +HDD_INIT: LD A,IDE.Chanel.Primary + OUT (IDE.Chanel.Set),A + CALL TEST_HDD_DRV + SCF + RET NZ + ; + CALL WAIT_HDD + LD BC,IDE.Write.Command + LD A,IDE.ATA.IdentifyDevice ;!FIXIT переделать + OUT (C),A + CALL WAIT_HDD + AND IDE.ControlByte.DataRequest + SCF + RET Z + ; + LD BC,IDE.Read.Data + LD HL,SYS_PAGE.HD_IDF_ADR + INIR + INIR + ; B = 0 + LD H,B + LD L,B + LD A,(SYS_PAGE.HD_IDF_ADR.sectors) ; число секторов + LD C,A + LD A,(SYS_PAGE.HD_IDF_ADR.heads) ; число головок +.loop: ADD HL,BC + DEC A + JR NZ,.loop + LD (SYS_PAGE.HD_IDF_ADR.sec_cyl),HL + CALL WAIT_HDD + LD BC,IDE.Read.Control + IN A,(C) + AND #10 + LD B,A + LD A,(SYS_PAGE.HD_IDF_ADR.heads) ; число головок + DEC A + AND #0F + OR IDE.Drive.Master + OR B + ; + LD H,A + LD A,(SYS_PAGE.HD_IDF_ADR.LBA_CHS) + AND %0000'0010 + SCF + RET Z ; NO_LBA + ; + SET 6,H + LD BC,IDE.Write.DeviceHead + OUT (C),H + LD A,(SYS_PAGE.HD_IDF_ADR.sectors) ; число секторов +.HDD_CONFIGURED: + LD BC,IDE.Write.Counter + OUT (C),A + LD A,IDE.ATA.InitializeDeviceParameters ; SET HDD PARAMETERS +HD_CMD_EXE: CALL HD_WAIT + RET C + LD BC,IDE.Write.Command + OUT (C),A +HD_WAIT: PUSH DE + PUSH BC + PUSH AF + LD DE,0 +.loop: LD BC,IDE.Read.Status + IN A,(C) + AND IDE.ControlByte.Busy + JR Z,.EXIT + DEC DE + LD A,D + OR E + JR NZ,.loop + POP AF + POP BC + POP DE + SCF + RET ; error + ; +.EXIT: POP AF + POP BC + POP DE + AND A + RET + ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░; + + ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░; +WAIT_HDD: LD BC,IDE.Read.Status +.loop: IN A,(C) + BIT IDE.ControlBit.Busy,A + JR NZ,.loop + RET + ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░; + + ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░; +Init_Mem: LD HL,SYS_PAGE.RAMD_FAT; ; Адрес RAM FAT в ОЗУ. + ; обнуляем таблицу + XOR A +.loopFree: LD (HL),A + INC L + JR NZ,.loopFree + ; резервируем спец.страницы и страницы ZX + LD B,RESERVED_PAGES.Blocks + LD DE,RESERVED_PAGES ; таблица занятых системных страниц +.loop: LD A,(DE) + CP #FF + JR Z,.exitLoop +.loopBlk: INC DE + LD L,A + LD A,(DE) + LD (HL),A + CP #FF + JR NZ,.loopBlk +.exitLoop: INC DE + DJNZ .loop + LD L,A + LD (HL),A + RET + ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░; + + ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░; +TEST_HDD_DRV: ;LD HL,#01FE + LD BC,IDE.Write.Counter + OUT (C),L + INC C + OUT (C),H ; IDE.Write.Sector + ; + DEC C + DEC B + IN A,(C) ; IDE.Read.Counter + CP L + RET NZ + INC C + IN A,(C) ; IDE.Read.Sector + CP H + RET + ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░; + +ERROR: ;░░░░░░░ Мигание лампочкой турбы ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░; + LD A,SYS_PORT.TURBO.OFF +.big_loop: LD BC,0 + OUT (SYS_PORT.ROM),A +.loop: DEC BC + INC B + DJNZ .loop + XOR 1 + JR .big_loop + ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░; +END_CB EQU $ +;██████████████████████████████████████████████████████████████████████; + + + + + + ;██████████████████████████████████████████████████████████████; + ;███████ Таблица DCP ██████████████████████████████████████████; +DCP_DATA: DW %00'000'0'0100'0000 + DW %11'000'0'0110'1111 + DB ACEX.IDE_DATA_1F0 + DW %01'000'0'0100'0000 + DW %11'010'0'0110'1111 + DB ACEX.IDE_DATA_1F0 + DW %10'000'0'0100'0000 + DW %11'010'0'0110'1111 + DB ACEX.IDE_DATA_1F0 + DW %11'000'0'0100'0000 + DW %11'000'0'0110'1111 + DB ACEX.IDE_DATA_1F0 + ; + DW %00'000'0'0100'0001 + DW %00'010'1'1110'1111 + DB ACEX.IDE_ERROR_1F1 + DW %00'010'0'0100'0001 + DW %11'010'1'1110'1111 + DB ACEX.IDE_ERROR_1F1 + DW %11'010'0'0100'0001 + DW %11'010'1'1110'1111 + DB ACEX.IDE_ERROR_1F1 + ; + DW %00'000'0'0100'0010 + DW %00'010'1'1110'1111 + DB ACEX.IDE_COUNTER_1F2 + DW %00'010'0'0100'0010 + DW %11'010'1'1110'1111 + DB ACEX.IDE_COUNTER_1F2 + DW %11'010'0'0100'0010 + DW %11'010'1'1110'1111 + DB ACEX.IDE_COUNTER_1F2 + ; + DW %00'000'0'0100'0011 + DW %00'010'1'1110'1111 + DB ACEX.IDE_SECTOR_1F3 + DW %00'010'0'0100'0011 + DW %11'010'1'1110'1111 + DB ACEX.IDE_SECTOR_1F3 + DW %11'010'0'0100'0011 + DW %11'010'1'1110'1111 + DB ACEX.IDE_SECTOR_1F3 + ; + DW %00'000'0'0100'0100 + DW %00'010'1'1110'1111 + DB ACEX.IDE_CYLINDER_L_1F4 + DW %00'010'0'0100'0100 + DW %11'010'1'1110'1111 + DB ACEX.IDE_CYLINDER_L_1F4 + DW %11'010'0'0100'0100 + DW %11'010'1'1110'1111 + DB ACEX.IDE_CYLINDER_L_1F4 + ; + DW %00'000'0'0100'0101 + DW %00'010'1'1110'1111 + DB ACEX.IDE_CYLINDER_H_1F5 + DW %00'010'0'0100'0101 + DW %11'010'1'1110'1111 + DB ACEX.IDE_CYLINDER_H_1F5 + DW %11'010'0'0100'0101 + DW %11'010'1'1110'1111 + DB ACEX.IDE_CYLINDER_H_1F5 + ; + DW %00'000'0'1100'0010 + DW %00'010'1'1110'1111 + DB ACEX.IDE_DEVICE_HEAD_1F6 + DW %00'010'0'1100'0010 + DW %11'010'1'1110'1111 + DB ACEX.IDE_DEVICE_HEAD_1F6 + DW %11'010'0'1100'0010 + DW %11'010'1'1110'1111 + DB ACEX.IDE_DEVICE_HEAD_1F6 + ; + DW %00'000'0'1100'0011 + DW %00'010'1'1110'1111 + DB ACEX.IDE_STATUS_CMD_1F7 + DW %00'010'0'1100'0011 + DW %11'010'1'1110'1111 + DB ACEX.IDE_STATUS_CMD_1F7 + DW %11'010'0'1100'0011 + DW %11'010'1'1110'1111 + DB ACEX.IDE_STATUS_CMD_1F7 + ; + DW %00'000'0'1100'0100 + DW %00'010'1'1110'1111 + DB ACEX.IDE_CONTROL_3F6 + DW %00'010'0'1100'0100 + DW %11'010'1'1110'1111 + DB ACEX.IDE_CONTROL_3F6 + DW %11'010'0'1100'0100 + DW %11'010'1'1110'1111 + DB ACEX.IDE_CONTROL_3F6 + ; + DW %00'000'0'1100'0101 + DW %00'010'1'1110'1111 + DB ACEX.IDE_STATUS_3F7 + DW %00'010'0'1100'0101 + DW %11'010'1'1110'1111 + DB ACEX.IDE_STATUS_3F7 + DW %11'010'0'1100'0101 + DW %11'010'1'1110'1111 + DB ACEX.IDE_STATUS_3F7 + ; + DW %00'000'0'0010'1100 + DW %11'001'1'1111'1111 + DB ACEX.IDE_CHANEL_1 + DW %11'000'0'0010'1100 + DW %11'001'1'1111'1111 + DB ACEX.IDE_CHANEL_1 + ; + DW %00'000'0'0011'1100 + DW %11'001'1'1111'1111 + DB ACEX.IDE_CHANEL_2 + DW %11'000'0'0011'1100 + DW %11'001'1'1111'1111 + DB ACEX.IDE_CHANEL_2 + ; + DW %00'000'0'1010'1100 + DW %11'001'1'1111'1111 + DB ACEX.RESET + DW %11'000'0'1010'1100 + DW %11'001'1'1111'1111 + DB ACEX.RESET + ; + DW %00'000'0'0110'1101 + DW %10'000'1'1111'1111 + DB ACEX.Scorp_1FFD + DW %11'000'0'0110'1101 + DW %11'000'1'1111'1111 + DB ACEX.Scorp_1FFD + ; + DW %00'000'0'1110'1101 + DW %00'100'1'1110'1111 + DB ACEX.Pent_7FFD + DW %00'100'0'1110'1101 + DW %11'110'1'1110'1111 + DB ACEX.Pent_7FFD + DW %11'100'0'1110'1101 + DW %11'100'1'1110'1111 + DB ACEX.Pent_7FFD + DW %10'000'0'0110'1101 + DW %11'100'1'1110'1111 + DB ACEX.Pent_7FFD + ; + DW %00'000'0'0101'0110 + DW %11'001'1'1111'1111 + DB ACEX.ALL_MODE + DW %11'000'0'0101'0110 + DW %11'001'1'1111'1111 + DB ACEX.ALL_MODE + ; + DW %00'000'0'0010'0100 + DW %00'000'0'0010'1111 + DB ACEX.CNF_PORT + ; + DW %00'000'0'0000'1010 + DW %00'010'0'0110'1111 + DB ACEX.SLOT0 + DW %00'010'0'0000'1010 + DW %11'010'0'0110'1111 + DB ACEX.SLOT0 + DW %11'010'0'0000'1010 + DW %11'010'0'0110'1111 + DB ACEX.SLOT0 + ; + DW %00'000'0'0010'1010 + DW %00'010'0'0110'1111 + DB ACEX.SLOT1 + DW %00'010'0'0010'1010 + DW %11'010'0'0110'1111 + DB ACEX.SLOT1 + DW %11'010'0'0010'1010 + DW %11'010'0'0110'1111 + DB ACEX.SLOT1 + ; + DW %00'000'0'0100'1010 + DW %00'010'0'0110'1111 + DB ACEX.SLOT2 + DW %00'010'0'0100'1010 + DW %11'010'0'0110'1111 + DB ACEX.SLOT2 + DW %11'010'0'0100'1010 + DW %11'010'0'0110'1111 + DB ACEX.SLOT2 + ; + DW %00'000'0'0110'1010 + DW %00'010'0'0110'1111 + DB ACEX.SLOT3 + DW %00'010'0'0110'1010 + DW %11'010'0'0110'1111 + DB ACEX.SLOT3 + DW %11'010'0'0110'1010 + DW %11'010'0'0110'1111 + DB ACEX.SLOT3 + ; DCP END MARKER + DW 0,0,0 +;-----------------------------------------------------------------------; +RESERVED_PAGES:; [x] Block #1 - можно освободить по ID 1 + ; Дополнительные процедуры +.SYS_FN: DB SYS_FN_PAGE + ; Образ БИОСа для прошивки +.BIOS: DB #10,#11,#12,#13 + DB #14,#15,#16,#17 + DB #18,#19,#1A,#1B + DB #1C,#1D,#1E,#1F + ; Картинка +.PICTURE: DB 2,3,4,5,6 + ; Образ памяти с прошивальщиком +.FLASHER_RAM: DB 7,8 + DB #FF ; End of the block +.Blocks EQU 1 +.Size EQU $-RESERVED_PAGES +;-----------------------------------------------------------------------; +END_FIRST_SECTION EQU $ +; + DISPLAY "ROM size = ",/A,END_FIRST_SECTION - BEGIN_CB + OUTEND +;██████████████████████████████████████████████████████████████████████; +;██████████████████████████████████████████████████████████████████████; + + + + + +;██████████████████████████████████████████████████████████████████████; +;██████████████████[ SECOND SECTION - IMAGE ON DRIVE ]█████████████████; + OUTPUT './Build/CrazyBlasterIMG.raw' + ORG 0 +BEGIN_CB_IMG: LD HL,RESERVED_PAGES + LD DE,#4000 + RESERVED_PAGES_COPY + LD BC,RESERVED_PAGES.Size + LDIR + LD SP,#4000 + LD A,SYS_FN_PAGE + OUT (SLOT0),A + JP INIT_SCREEN - #4000 + ; +.start_code EQU $ + + ;███████ инициализация экрана █████████████████████████████████; +INIT_SCREEN: CALL FN_SYNC + ; + LD IX,VideoModes.graf_mode320x256 + LD E,%00010001 + CALL WIN_OPEN + ;███████ инициализация палитры ████████████████████████████████; +INIT_PALETTE: ;IN A,(SLOT1) + ;PUSH AF + LD B,#FF + LD HL,PICTURE.bdPallete ;#8FBC ;!HARDCODE PICTURE.bdPallete + LD DE,0 + LD A,1 + CALL SET_PALETTE + CALL SET_PICTURE + CALL SET_BOARD_NUMBER + ; Определение чипа ПЗУ + CALL DETECT_ROM + ; + + ; установка регистров + + ; прыжок на точку входа во флешере + + ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░; +SET_BOARD_NUMBER: + IN A,(SLOT3) + EX AF,AF' + LD A,#18 ;!HARDCODE + OUT (SLOT3),A + ; + LD HL,(BOARD_ID_DATA.Start) + LD (BoardNumOffsets.Start),HL + LD HL,(BOARD_ID_DATA.Number) + LD (BoardNumOffsets.Number),HL + LD HL,(BOARD_ID_DATA.End) + LD (BoardNumOffsets.End),HL + LD A,(BOARD_ID_DATA.Type) + LD (BoardNumOffsets.Type),A + ; + LD A,#10 ;!HARDCODE + OUT (SLOT3),A + LD A,(FOR_ACEX) + LD (#C000 + expBIOS_Vars.msgStrings.str_ACEX_MODEL),A + LD (#C000 + expBIOS_Vars.msgRusStrings.str_ACEX_MODEL),A + ; + EX AF,AF' + OUT (SLOT3),A + RET + ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░; +DISP_WINDOW EQU $ + DISP #4000 + DISP_WINDOW +DETECT_ROM: LD HL,0 + ADD HL,SP + LD SP,#4000 + LD (.sp_save),HL + ; + CALL TEST_ROM_CHIP ;!HARDCODE TEST_ROM_CHIP #8E59 + LD (TST_R.jp),BC ;!HARDCODE TST_R.jp #81D5 + ; +.sp_save+1: LD SP,0000 + XOR A + OUT (SYS_PORT.RAM),A + RET + ENT + ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░; + ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░; + ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░; + ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░; + ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░; +SET_PICTURE: LD A,#FF - MAIN_PICTURE.PIC_Y +.loop_pic: PUSH AF + + LD A,#50 + OUT (SLOT1),A + + POP AF + OUT (PORT_Y),A + + LD HL,.pic_buffer + LD DE,#4000 + Screen_Offset + MAIN_PICTURE.PIC_X + ; + LD BC,MAIN_PICTURE.PIC_WIDTH + LDIR + ; + LD H,A + POP AF + OUT (SLOT1),A + PUSH AF + + LD A,H + DEC A + CP MAIN_PICTURE.PIC_Y-1 + JR NZ,.loop_pic + + POP AF + OUT (SLOT1),A + IM 1 + EI + RET +.pic_buffer: BLOCK MAIN_PICTURE.PIC_WIDTH,0 + ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░; +; Установка режима на линии +LP_MODE_LINE: BIT 0,(IX+Window_Variables.USER.MODE_S) + JP NZ,LP_MODE_LINE2 ; идти на спектрум + BIT 4,A + JP Z,LP_MODE_LINE3 ; идти на графику! + DEC D + ; текстовый режим. + EX AF,AF' + LD A,#50 + OUT (SLOT3),A + LD A,L ; вертикальное положение + CP #80 + JR NC,LP_EXIT_MODE + ; +LP_MODE_RECURSE: + LD A,D ; горизонтальное положение + AND 7FH + SUB 80 + JR C,LP_MODE_LL + SUB 48 + NEG + ; + LD E,A ; запомнить + ADD A,D + LD D,A ; новое положение + ; + LD A,E ; восстановить + RRA + AND 3FH + SUB C + JR NC,LP_EXIT_MODE + NEG + LD C,A ; новое значение C + JR LP_MODE_RECURSE + ; +LP_MODE_LL: NEG + RRA + AND 3FH + CP C + JR NC,LP_MODE_LR + LD C,A +LP_MODE_LR: EX AF,AF' + INC D +LP_MD_LL1: EX AF,AF' + LD A,D + OUT (PORT_Y),A + EX AF,AF' + LD (HL),A ; режим + INC D + EX AF,AF' + LD A,D + OUT (PORT_Y),A + EX AF,AF' + LD (HL),A ; режим + INC D + DEC C + JR NZ,LP_MD_LL1 + EX AF,AF' +LP_EXIT_MODE: LD A,SYS_PAGE + OUT (SLOT3),A + EX AF,AF' + RET + ; + +; Установка режима на линии +; Spectrum mode +LP_MODE_LINE2: LD A,(IX+Window_Variables.WORK_2) + LD B,(IX+Window_Variables.WORK_1) + ; + DEC D + ; + EX AF,AF' + LD A,#50 + OUT (SLOT3),A + LD A,L ; вертикальное положение + CP #80 + JR NC,LP_EXIT_MODE2 + ; +LP_MODE_RECURSE2: + LD A,D ; горизонтальное положение + AND #7F + SUB 80 + JR C,LP_MODE_LL2 + SUB 48 + NEG + ; + LD E,A ; запомнить + ADD A,D + LD D,A ; новое положение + ; + LD A,E ; восстановить + RRA + AND #3F + SUB C + JR NC,LP_EXIT_MODE2 + NEG + LD C,A ; новое значение C + JR LP_MODE_RECURSE2 + ; +LP_MODE_LL2: NEG + RRA + AND #3F + CP C + JR NC,LP_MODE_LR2 + LD C,A +LP_MODE_LR2: EX AF,AF' + INC D +LP_MD_LL2: EX AF,AF' + LD A,D + OUT (PORT_Y),A + EX AF,AF' + LD (HL),A ; режим + INC L + LD (HL),B + INC L + LD (HL),B + DEC L + DEC L + INC D + BIT 4,A + JR NZ,lp_md_ll3x + INC B +lp_md_ll3x: EX AF,AF' + LD A,D + OUT (PORT_Y),A + EX AF,AF' + LD (HL),A ; режим + INC L + LD (HL),B + INC L + LD (HL),B + DEC L + DEC L + INC D + INC B + JR NZ,LP_NO_ADD_40 + ADD A,#40 +LP_NO_ADD_40: DEC C + JR NZ,LP_MD_LL2 + EX AF,AF' +LP_EXIT_MODE2: LD A,SYS_PAGE + OUT (SLOT3),A + EX AF,AF' + LD (IX+Window_Variables.WORK_1),B + LD (IX+Window_Variables.WORK_2),A + RET + ; +; Установка режима на линии +LP_MODE_LINE3: ; Grafic Mode + LD A,(IX+Window_Variables.WORK_1) + LD B,(IX+Window_Variables.WORK_2) + DEC D + EX AF,AF' + LD A,#50 + OUT (SLOT3),A + LD A,L ; вертикальное положение + CP #80 + JR NC,LP_EXIT_MODE3 + ; +LP_MODE_RECURSE3: + LD A,D ; горизонтальное положение + AND #7F + SUB 80 + JR C,LP_MODE_LL3 + SUB 48 + NEG + LD E,A ; запомнить + ADD A,D + LD D,A ; новое положение + LD A,E ; восстановить + RRA + AND #3F + SUB C + JR NC,LP_EXIT_MODE3 + NEG + LD C,A ; новое значение C + JR LP_MODE_RECURSE3 + ; +LP_MODE_LL3: NEG + RRA + AND #3F + CP C + JR NC,LP_MODE_LR3 + LD C,A +LP_MODE_LR3: EX AF,AF' + INC D + BIT 5,B + JR Z,LP_GR_640 + ; +LP_MD_LL3: EX AF,AF' + LD A,D + OUT (PORT_Y),A + EX AF,AF' + LD (HL),B ; режим + INC L + LD (HL),A ; режим 2 + INC L + LD (HL),0 ; режим 2 + DEC L + DEC L + INC D + INC D + INC A + LD E,A + AND 7 + JR NZ,LP_NO_INC_B + LD A,E + SUB 8 + LD E,A + INC B +LP_NO_INC_B: LD A,E + DEC C + JR NZ,LP_MD_LL3 + ; +LP_640_RET: EX AF,AF' +LP_EXIT_MODE3: LD A,SYS_PAGE + OUT (SLOT3),A + EX AF,AF' + LD A,(IX+Window_Variables.WORK_1) + ADD A,8 + LD (IX+Window_Variables.WORK_1),A + RET + ; +LP_GR_640: EX AF,AF' + LD A,D + OUT (PORT_Y),A + EX AF,AF' + LD (HL),B ; режим 1 + INC L + LD (HL),A ; режим 2 + INC L + LD (HL),0 ; режим 3 + INC D + EX AF,AF' + LD A,D + OUT (PORT_Y),A + EX AF,AF' + LD (HL),0 ; режим 3 + DEC L + LD (HL),A ; режим 2 + DEC L + LD (HL),B ; режим 1 + INC D + INC A + LD E,A + AND 7 + JR NZ,LP_NO_INC_B6 + LD A,E + SUB 8 + LD E,A + INC B +LP_NO_INC_B6: LD A,E + DEC C + JR NZ,LP_GR_640 + JP LP_640_RET + ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░; +; вход: HL - данные палитры RGB, E - начальный цвет +; D - число цветов, B - PAL-mask, A - page PAL +SET_PALETTE: PUSH IX + ; + EX AF,AF' + IN A,(RGADR) + PUSH AF ; сохранить положение RGADR + LD A,E + OUT (RGADR),A ; начальный цвет в порт + LD A,D ; сохранить число цветов + EX AF,AF' ; вернуть страницу PAL + ; + BIT 7,H ; проверить адрес данных + LD C,SLOT3 ; если ниже 8000h + LD D,#C3 ; то граф.экран на странице 3 + JR Z,.NO_PAGE1 + LD D,#43 ; иначе + LD C,SLOT1 ; на странице 1 +.NO_PAGE1: ADD A,A + ADD A,A + AND #1C + XOR #E0 ; младший байт адреса PAL + LD E,A ; DE - адрес в видео-ОЗУ + PUSH DE + POP IX ; адрес палитры + ; + LD D,B ; маска PAL + EX AF,AF' ; вернуть число цветов + LD B,A ; число цветов + ; + IN E,(C) ; сохранить страницу 3 + LD A,#50 ; страница графического RAM + OUT (C),A +.loopPal: ; цикл установки цветов палитры + LD A,(HL) ; B + AND D + LD (IX+2),A + INC HL + ; + LD A,(HL) ; G + AND D + LD (IX+1),A + INC HL + ; + LD A,(HL) ; R + AND D + LD (IX+0),A + INC HL + ; + LD A,(HL) ; Y + AND D + LD (IX+3),A + INC HL + ; + IN A,(RGADR) + INC A + OUT (RGADR),A + DJNZ .loopPal ; выполнять, пока не 0 + ; +.exit: OUT (C),E ; восстановить страницу 3 + POP AF + OUT (RGADR),A ; восстановить Y_PORT + POP IX + AND A + RET + ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░; +LP_OPEN_PG: IN A,(SLOT3) + LD C,A + LD A,SYS_PAGE + OUT (SLOT3),A + ; + LD A,C + LD (SYS_PAGE.COPY_SLOT3),A + IN A,(PORT_Y) + LD (SYS_PAGE.COPY_RGADR),A + RET +LP_CLOSE_PG: LD A,(SYS_PAGE.COPY_RGADR) + OUT (PORT_Y),A + LD A,(SYS_PAGE.COPY_SLOT3) + OUT (SLOT3),A + RET + ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░; +WIN_OPEN: CALL LP_OPEN_PG + LD (SYS_PAGE.WIN_MAP_SC),IX ; карта окна + PUSH DE + LD HL,(SYS_PAGE.WIN_MAP_SC) + LD DE,WIN_ID_0 + LD BC,Window_UserVars + LDIR + LD IX,WIN_ID_0 + POP DE + LD L,(IX+Window_Variables.USER.PLACE_H) + LD H,(IX+Window_Variables.USER.PLACE_V) + LD (IX+Window_Variables.MODE_E),E + ; + LD A,L + ADD A,A + INC A ; вычисление PORT_Y + BIT 4,E + JR NZ,.LP_SET_NO_OR + OR #80 ; если вывод на второй экран +.LP_SET_NO_OR: LD (IX+Window_Variables.H_BEG),A + LD D,A + LD A,(IX+Window_Variables.USER.SIZE_H) + ADD A,A + ADD A,D + LD (IX+Window_Variables.H_END),A + LD (SYS_PAGE.WIN_MODE_SC),DE ; место по горизонтали и страница моды + LD A,H + AND #3F + ADD A,A + ADD A,A + LD L,A + LD H,#C3 + LD (SYS_PAGE.WIN_MODE_SH),HL ; место по вертикали с адресом + LD (IX+Window_Variables.V_BEG),A + LD A,(IX+Window_Variables.USER.SIZE_V) + ADD A,A + ADD A,A + ADD A,L + LD (IX+Window_Variables.V_END),A + ; + LD L,(IX+Window_Variables.V_BEG) + LD H,#C3 + LD B,(IX+Window_Variables.USER.SIZE_V) ; размер по вертикали + ; + LD (IX+Window_Variables.WORK_1),0 + LD A,(IX+Window_Variables.USER.MODE) ; знакогенератор плюс режим + LD (IX+Window_Variables.WORK_2),A + BIT 4,A + JR NZ,.LOOP ; переход, если текстовый режим + ; + AND #F0 + LD C,A + LD A,(IX+Window_Variables.USER.GR_X) + RRCA + RRCA + RRCA + LD D,A + AND #0F + OR C + LD (IX+Window_Variables.WORK_2),A + ; + LD A,D + AND #E0 + LD C,A + LD A,(IX+Window_Variables.USER.GR_Y) + AND #1F + OR C + RLCA + RLCA + RLCA + LD (IX+Window_Variables.WORK_1),A + ; +.LOOP: LD D,(IX+Window_Variables.H_BEG) ; D - начало строки (PORT_Y) + LD C,(IX+Window_Variables.USER.SIZE_H) ; размер по горизонтали + LD A,(IX+Window_Variables.USER.MODE) ; знакогенератор плюс режим + ; + PUSH BC + CALL LP_MODE_LINE + POP BC + INC L + INC L + INC L + INC L + DJNZ .LOOP + ; + LD A,(IX+Window_Variables.MODE_E) + AND 1 + OUT (RGMOD),A + CALL LP_CLOSE_PG + CALL LP_INI_P + CALL LP_SIZE + XOR A + RET + ; +LP_INI_P: EX AF,AF' + EXX + CALL LP_OPEN_PG + ; открытие графического экрана + ; LP_INI_NO_ZG: + LD A,(WIN_ID_0.H_BEG) + LD D,A + LD A,(WIN_ID_0.V_BEG) + LD L,A + INC L + LD H,#C3 + + AND A + LD A,(WIN_ID_0.USER.MODE) + BIT 5,A + LD A,(WIN_ID_0.USER.SIZE_H) + JR NZ,LP_INI_40 + ADD A,A + SCF + ;!TODO что-то тут подвыпиленно +LP_INI_40: LD B,A + LD (WIN_ID_0.SIZE_REL),A + EX AF,AF' + EXX + JP LP_END_P + ; +; WIN_MAP_SC - карта экрана +; 0 - hor size +; 1 - ver size +; 2 - hor place +; 3 - ver place +LP_SIZE: ; определение size + CALL LP_OPEN_PG + LD DE,(WIN_ID_0.USER.SIZE_H) + LD A,(WIN_ID_0.USER.MODE) + BIT 5,A + CALL LP_CLOSE_PG + RET NZ + LD A,E + ADD A,A + LD E,A + RET + ; +LP_END_P: LD A,SYS_PAGE + OUT (SLOT3),A +.SYS_PAGE: EX AF,AF' + EXX + RLA + LD E,A + LD (WIN_ID_0.reg_HL),HL ; место печати + LD (WIN_ID_0.reg_DE),DE + LD (WIN_ID_0.reg_BC),BC + CALL LP_CLOSE_PG + EXX + EX AF,AF' + AND A + RET +.short: EX AF,AF' + EXX + CALL LP_CLOSE_PG + EXX + EX AF,AF' + AND A + RET + ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░; +FN_SYNC: LD A,Port_VSYNC.SET_320L + OUT (Port_VSYNC),A + LD C,SLOT3 + IN B,(C) + LD A,SYS_PAGE + OUT (C),A + LD A,(SYS_PAGE.VSyncAndWaits) + OR 1 + LD (SYS_PAGE.VSyncAndWaits),A + ; +.INT_DEF: LD DE,(SYS_PAGE.CONFIG_ALL) + OUT (C),B + LD IX,SCREEN_TABLES.PENTAGON + IN A,(SLOT3) + EX AF,AF' + LD A,SYS_PAGE + OUT (SLOT3),A + EX AF,AF' + LD (SYS_PAGE.COPY_SLOT3),A + IN A,(PORT_Y) + LD (SYS_PAGE.COPY_RGADR),A + LD (SYS_PAGE.CONFIG_ALL),IX + XOR A +;----[START]-----------------------[? 1] +.loop_1: OUT (PORT_Y),A + EX AF,AF' + LD A,#50 + OUT (SLOT3),A + LD HL,#C300 +;----[START]------------------[v 2]----- +.loop_2: LD C,(IX) +;----[START]-------------[v 3]---------- +.loop_3: ; взять адрес данных для записи в служебную область экрана + LD E,(IX+1) ; take adress of line X + LD D,(IX+2) +;----[START]--------[v 4]--------------- +.loop_4: + LD A,(DE) ; take counter in table 1, line X, column Y + INC DE + AND A + JR Z,.loop_4_exit ; exit if zero-counter + LD B,A + LD A,(DE) + INC DE +;----[START]---[v 5]-------------------- +.loop_5: + LD (HL),A + INC L + LD (HL),0 + INC L + LD (HL),0 + ; + EX AF,AF' + INC A + OUT (PORT_Y),A + EX AF,AF' + ; + LD (HL),0 + DEC L + LD (HL),0 + DEC L + LD (HL),A + ; + EX AF,AF' + INC A + OUT (PORT_Y),A + EX AF,AF' + DJNZ .loop_5 +;--------------[^ 5]-------------------- + JR .loop_4 +;-------------------[^ 4]--------------- +.loop_4_exit: INC HL ; next line + INC HL + INC HL + INC HL + IN A,(PORT_Y) + AND #80 + OUT (PORT_Y),A + DEC C + JR NZ,.loop_3 +;------------------------[^ 3]---------- + INC IX ; next counter + INC IX + INC IX + LD A,(IX) + AND A + JR NZ,.loop_2 +;-----------------------------[^ 2]----- + LD A,SYS_PAGE + OUT (SLOT3),A + LD IX,(SYS_PAGE.CONFIG_ALL) + + EX AF,AF' + ADD A,#80 + JR NC,.loop_1 +;----------------------------------[^ 1] + ; Exit + LD A,(SYS_PAGE.COPY_RGADR) + OUT (PORT_Y),A + LD A,(SYS_PAGE.COPY_SLOT3) + OUT (SLOT3),A +.exit: OR A + RET +;--- Screen data table 1: counter1, data1 .. counterX, dataX +SCREEN_TABLES:; | число | значения | +; | строк | в | +; | /2 | строках | +.SCR: DB 41 , #F8 + DB 3 , #FC + DB 4 , #FC + DB 7 , #FC + DB 9 , #F8 + DB 0 +.INT: DB 40,#FC, 2,#FD, 6,#FC, 7,#FC, 9,#FC, 0 +.BLN: DB 41,#FC, 3,#FC, 4,#FC, 7,#FC, 9,#FC, 0 +.SNC: DB 41,#FC, 3,#FC, 4,#FC, 7,#FC, 9,#FC, 0 +.RES: DB 41,#F8, 3,#FE, 4,#FE, 7,#FE, 9,#F8, 0 +;--- Screen data tables 2: counter1, data address1 .. counterX, data addressX +; +; | кол-во | значения | +; | строк | в | +; | | строке | +.PENTAGON: DB 33 : DW .SCR + DB 1 : DW .INT ; DW .BLN + DB 3 : DW .SNC + DB 1 : DW .BLN + DB 1 : DW .SCR + DB 1 : DW .RES + DB 0 ; end + +;--- +VideoModes: +.text_mode80x32: + DB 40 + DB 32 + DB 0 + DB 0 + DB %00011011 + DB 0 + DB 0 + DB 0 +.graf_mode320x256: + DB 80 + DB 32 + DB 0 + DB 0 + DB %01100000 + DB 0 + DB 0 + DB 0 +;---------------------------------------------------------------------; + ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░; + + ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░; +RESERVED_PAGES_COPY: BLOCK RESERVED_PAGES.Size,#FF +.SYS_FN EQU RESERVED_PAGES.SYS_FN - RESERVED_PAGES +.BIOS EQU RESERVED_PAGES.BIOS - RESERVED_PAGES +.PICTURE EQU RESERVED_PAGES.PICTURE - RESERVED_PAGES +.FLASHER_RAM EQU RESERVED_PAGES.FLASHER_RAM - RESERVED_PAGES + ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░; +;-----------------------------------------------------------------------; + BYTE "ACEX 1K" +FOR_ACEX: DB "0" + TYPE_OF_ACEX + BYTE "0" + + BYTE "FULL BOARD ID:" +BOARD_ID_DATA: +.Start: DW #5283 +.Number: DW 0 ; выводится как 5 десятичных цифр: 0..99999 или #0000..#270F +.End: DW #47E8 +.Type: DB 0 + BYTE "--<=END=>--" +END_SECOND_SECTION EQU $ +; + DISPLAY "IMG size = ",/A,END_SECOND_SECTION - BEGIN_CB_IMG + OUTEND +;██████████████████████████████████████████████████████████████████████; \ No newline at end of file diff --git a/Crazy BIOS/rom/_not_used/EasterSprites.asm b/Crazy BIOS/rom/_not_used/EasterSprites.asm new file mode 100644 index 0000000..981249e --- /dev/null +++ b/Crazy BIOS/rom/_not_used/EasterSprites.asm @@ -0,0 +1,41 @@ +Sprites: +; На входе в IX адрес таблицы с выводимыми спрайтами + IN A,(SLOT1) + LD H,A + IN A,(PORT_Y) + LD L,A + PUSH HL + + LD A,#58 + OUT (SLOT1),A + +; ld ix,SP_Table + ld b,(ix+0) + inc ix +.loop: + push bc + LD A,(ix+str_EasterSprites.SpHeight) ; !!!!! координата картинки по Y + высота картинки + ld l,(ix+str_EasterSprites.SpAddress) + ld h,(ix+str_EasterSprites.SpAddress+1) +.putSprite: + DEC A + OUT (PORT_Y),A + LD E,(ix+str_EasterSprites.SpXCoord) ; !HARDCODE координата картинки по Х + LD D,(ix+str_EasterSprites.SpXCoord+1) + LD C,(ix+str_EasterSprites.SpWidth) ; !HARDCODE длина горизонтальной линии картинки + LD B,(ix+str_EasterSprites.SpWidth+1) + LDIR + CP (IX+str_EasterSprites.SpYCoord) + JP NZ,.putSprite + ld c,str_EasterSprites + add ix,bc + pop bc + djnz .loop + + POP BC + LD A,B + OUT (SLOT1),A + LD A,C + OUT (PORT_Y),A + XOR A + RET \ No newline at end of file diff --git a/Crazy BIOS/rom/_not_used/LZ4_DEC.asm b/Crazy BIOS/rom/_not_used/LZ4_DEC.asm new file mode 100644 index 0000000..f25c685 --- /dev/null +++ b/Crazy BIOS/rom/_not_used/LZ4_DEC.asm @@ -0,0 +1,157 @@ +;------------------------------------------------------------------------------ +;hl=src de=dst +lz4decrunch: + ld bc,7 + add hl,bc + ld c,(hl) + inc hl + ld b,(hl) ;ДqДuДВДvД} ДtДrДp ДqДpДzДДДp ДyДx ДxДpДsДАД|ДАДrД{Дp - ДВДpДxД}ДuДВ + inc hl + inc hl + inc hl ;Д~ДpДЙДpД|ДА ДГДwДpДДДНДЗ ДtДpД~Д~ДНДЗ ДГДА ДГД}ДuДЛДuД~ДyДС #0B + + ld a,l + add a,c + ld (.endL+1),a + ld a,h + adc a,b + ld (.endH+1),a ;ДKДАД~ДuДЙД~ДНДz ДpДtДВДuДГ ДГДwДpДДДНДЗ ДtДpД~Д~ДНДЗ + +.loop: + ld a,(hl) + inc hl + ld (.litteral+1),a + and #F0 + jr z,.copy ;ДEДГД|Дy ДtД|ДyД~Дp ДВДpДrД~Дp 0, ДГД{ДАДБДyДВДАДrДpДДДО ДЕДwДu ДБДuДВДuДtДpД~Д~ДНДu ДtДpД~Д~ДНДu + rrca + rrca + rrca + rrca + ld b,0 + ld c,a + cp #0F + call z,.getlength ;ДEДГД|Дy ДtД|ДyД~Дp #0F, ДДДА ДБДАД|ДЕДЙДyДДДО ДtДАДБДАД|Д~ДyДДДuД|ДОД~ДЕДР ДtД|ДyД~ДЕ + + ldir ;ДPДuДВДuДtДpДЙДp Д~ДpДЙДyД~ДpДuДДДГДС ДГДА ДГД|ДuДtДЕДРДЛДuДz ДyД~ДЖДАДВД}ДpДИДyДy ДА ДtД|ДyД~Дu + +.copy: + ld a,l ;ДtДАДГДДДyДsД|Дy Д|Дy ДГДwДpДДДНДu ДtДpД~Д~ДНДu Д{ДАД~ДuДЙД~ДАДsДА ДpДtДВДuДГДp +.endL: + sub #FF + ld a,h +.endH: + sbc a,#FF + ret nc ;Д^ДЖДЖДuД{ДДДyДrД~ДpДС ДБДВДАДrДuДВД{Дp zf=1 + + ld c,(hl) + inc hl + ld b,(hl) ;bc=2byte ДXДДДuД~ДyДu ДxД~ДpДЙДuД~ДyДС ДГД}ДuДЛДuД~ДyДС + inc hl + +.litteral: + ld a,0 ;litteral ДБДuДВДuДБДyДГДpДДДО ДxДtДuДГДО + and #0F + add a,#04 ;cf=0 + + push hl + ld h,d + ld l,e + sbc hl,bc ;hl=de-bc ДIДГДБДАД|ДОДxДЕДzДДДu ДtДpД~Д~ДНДu, Д{ДАДДДАДВДНДu ДЕДwДu ДqДНД|Дy ДВДpДГДКДyДВДuД~ДН, Дr Д{ДpДЙДuДГДДДrДu ДyДГДДДАДЙД~ДyД{Дp ДБДuДВДuДtДpДЙДy + + ld b,0 + ld c,a + cp #0F+#04 + ex (sp),hl + call z,.getlength + ex (sp),hl + + ldir ;ДKДАДБДyДВДАДrДpДДДО ДБДuДВДuД~ДАДГ ДЕДwДu ДВДpДxДrДuДВД~ДЕДДДНДЗ ДtДpД~Д~ДНДЗ + pop hl + jp .loop + +.getlength: ;ДPДАД|ДЕДЙДyДДДО ДtД|ДyД~ДЕ ДqДpДzДДДp ДБДuДВДuДrДАДtДp (ДqДАД|ДОДКДu) bc=ДДДuД{ДЕДЛДpДС ДГДЕД}Д}Дp ДБДuДВДuДrДАДtДp + ld a,(hl) + inc hl + cp #FF ;#FF ДЕДtДrДpДyДrДpДuДДДГДС Д{ДpД{ ДxД~ДpД{, ДxДp Д{ДАДДДАДВДНД} ДГД|ДuДtДЕДuДД ДyД~ДЖДАДВД}ДpДИДyДС ДА ДtД|ДyД~Дu + jr nz,.addlen + inc b + dec bc ;bc += 255 + jr .getlength +.addlen: + add a,c + ld c,a + adc a,b + sub c + ld b,a ;bc=ДtД|ДyД~Дp ДБДuДВДuДtДpДrДpДuД}ДАДsДА ДqДpДzДДДp + ret + +;------------------------------------------------------------------------------ +;in: hl=Д~ДpДЙДpД|ДОД~ДНДz ДpДtДВДuДГ bc=ДtД|ДyД~Дp +;out: bcde=ДВДuДxДЕД|ДОДДДpДД +crc32: + push hl + push bc + + ld de,#FFFF ; 0xFFFFFFFF ? Д~ДpДЙДpД|ДОД~ДАДu ДxД~ДpДЙДuД~ДyДu CRC32, ДyДГДБДАД|ДОДxДЕДuД}ДАДsДА Дr ZIP + ld h,d + ld l,e + ld c,#20 ;ДГДАД{ДВДpДЛДuД~ДyДu + + exx + pop hl + dec hl + inc h + inc l + ld b,l + ld c,h + pop hl +.loop1: + ld a,(hl) + inc hl + exx + + xor e + ld b,8 +.loop2: + srl h + rr l + rr d + rra + jp nc,.skip + ld e,a + ld a,h + xor #ED + ld h,a + ld a,l + xor #B8 + ld l,a + ld a,d + xor #83 + ld d,a + ld a,e +; xor #20 + xor c +.skip: + djnz .loop2 + ld e,a + + exx + djnz .loop1 + dec c + jp nz,.loop1 + exx + + ld a,h ;CRC32, ДyДГДБДАД|ДОДxДЕДuД}ДНДz Дr ZIP, ДБДВДyД~ДyД}ДpДuДД xor ДГ 0xFFFFFFFF Дr Д{ДАД~ДИДu + cpl + ld b,a + ld a,l + cpl + ld c,a + + ld a,d + cpl + ld d,a + ld a,e + cpl + ld e,a + ret diff --git a/Crazy BIOS/rom/_not_used/Logo_Depacker.asm b/Crazy BIOS/rom/_not_used/Logo_Depacker.asm new file mode 100644 index 0000000..b5276d2 --- /dev/null +++ b/Crazy BIOS/rom/_not_used/Logo_Depacker.asm @@ -0,0 +1,89 @@ + CALL #E1D2 + DI + LD (RelocatedCode.SPsave),SP + LD HL,.START + LD DE,#D800 + LD BC,.END-.START + PUSH DE + LDIR + + LD HL,#E1D1 + LD DE,#FFFF + LD BC,#0850 + RET + +RelocatedCode: +.START: + LDDR + LD HL,#F7B0 + LD DE,#D900 + LD B,#00 + LD A,(HL) + BIT 7,A + JR NZ,#D94A + AND #0F + LD B,A + RLD + ADD A,#03 + LD C,A + INC HL + LD A,E + SUB (HL) + INC HL + LD SP,HL + LD H,(HL) + LD L,A + LD A,D + SBC A,B + LD B,H + LD H,A + LD A,B + LD B,#00 + LDIR + LD H,B + LD L,C + ADD HL,SP + JR #D929 + AND #7F + JR Z,#D967 + INC HL + BIT 6,A + JR NZ,#D958 + LD C,A + LDIR + JR #D928 + AND #3F + ADD A,#03 + LD B,A + LD A,(HL) + INC HL + LD C,(HL) + LD (DE),A + INC DE + DJNZ #D960 + LD A,C + JR #D929 + LD SP,#D85B + LD B,#03 + POP HL + DEC SP + POP AF + LD (HL),A + DJNZ #D96C +.SPsave+1: LD SP,#0000 + DI + RET + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP +.END EQU $ +; Картинка на стартовом экране слева сверху + INCBIN 'SP_LOGO.BIN' \ No newline at end of file diff --git a/Crazy BIOS/shared/CompMacro.asm b/Crazy BIOS/shared/CompMacro.asm new file mode 100644 index 0000000..58b5522 --- /dev/null +++ b/Crazy BIOS/shared/CompMacro.asm @@ -0,0 +1,178 @@ +; + MACRO ShowInfo text, in_disp +/* + DISPLAY ' ' + DISPLAY '[*] ', text + IF in_disp + DISPLAY 'ROM:' + DISPLAY ' ORG: ',/H, $$$ + DISPLAY ' PAGE: ',/H, $$$$ + DISPLAY 'MEM:' + DISPLAY ' DISP: ',/H, $ + DISPLAY ' PAGE: ',/H, $$ + ELSE + DISPLAY 'ROM:' + DISPLAY ' ORG: ',/H, $ + DISPLAY ' PAGE: ',/H, $$ + ENDIF + DISPLAY '[X]' + DISPLAY ' ' +*/ + ENDM +; + +; +; Вход: ширина спрайта, высота, координата X, координата Y, адрес спрайта в памяти + MACRO EasterTable width, height, Xcoord, Ycoord, addr + WORD addr ; адрес спрайта в памяти + WORD width ; Ширина + BYTE height+Ycoord ; Высота + Y coord + WORD Xcoord+#4040 ; X coord ; !HARDCODE исправить на метку #4040 - адрес лого + BYTE Ycoord ; Y coord + ENDM +; + +; + MACRO _mRECOVERYrdChooseTYPE vers + IF vers = 1 + ; если RECOVERY не подразумевает 90% безопасность пользовательских рамдисков + ; то выбираем этот вариант, он шустрее, под RECOVERY всегда выбирается RAM Disk 15 + ; + + ELSEIF vers = 2 + + ; Ищем свободный рамдиск + LD B,SYS_PAGE.RAMD_KEYS.NUM +.getRDidLoop: LD A,B + DEC A + LD (RECOVERYstart.RDkey),A + PUSH BC + LD B,ROM_DISK.Pages.Size + CALL EMM.GetMemRMD + POP BC + JR NC,RECOVERYstart.IMGread ; свободный рамдиск найден, выходим из цикла + DEC A + JR Z,RECOVERYstart.FreeMem ; ошибка - недостаточно памяти, вызываем очистку памяти + DJNZ .getRDidLoop + ; + + ELSE + ASSERT 0, Invalid 'RECOVERYrdChooseTYPE' variant - RECOVERYrdChooseTYPE + ENDIF + ENDM +; + MACRO _mRECOVERYmountTYPE vers + IF vers = 1 ; Более быстрый, но захардкоженный вариант + + LD HL,TEMP + CALL EMM.GetMemBlkPages ; кидаем в буфер номера страниц RAM disk + + IN A,(SLOT3) + LD (.slot3save),A + + LD HL,ROM_DISK.Pages.Number + LD B,0 + LD C,(HL) + INC C + LD DE,TEMP+ROM_DISK.Pages.Size + LDIR ; кидаем дальше в буфер номера страниц ROM disk + + LD IY,TEMP+ROM_DISK.Pages.Size ; ROM_DISK.Pages.Number + LD IX,TEMP + LD B,(IY+0) + + LD A,R + PUSH AF + DI +.loopIMGtoRAM: PUSH BC + INC IY + LD A,(IY+0) + OUT (ROM.SLOT0),A + LD A,(IX+0) + OUT (SLOT3),A + INC IX + + LD HL,0 + LD DE,#C000 + LD BC,#4000 + LDIR + + POP BC + DJNZ .loopIMGtoRAM +.slot3save+*: LD A,0 + OUT (SLOT3),A + XOR A + OUT (ROM.SLOT0),A + OUT (SYS_PORT.ROM),A + POP AF + JP PO,.noInterrupts + EI +.noInterrupts: + ; + + ELSEIF vers = 2 ; менее быстрый, но более правильный вариант через функции биоса + + LD (.ramdskID),A + LD DE,0 ; номер сектора + LD B,(ROM_DISK.Pages.Size * #4000)/512 ; счётчик - кол-ва секторов по 512 кб +.loop: + ;read rom disk + PUSH BC + LD A,1 ;размер сектора 256 + EX AF,AF' + LD A,#46 ;чтение из ROM-Disk + EX AF,AF' + LD HL,TEMP ;адрес буфера данных + LD B,2 ;число секторов + CALL BLK_RD_WR + + ;write to ram disk + PUSH DE ;номер сектора + DEC DE + DEC DE + +.ramdskID+*: LD A,0 ;идентификатор блока + EX AF,AF' + LD A,#FF ;запись в RAM-Disk + EX AF,AF' + LD HL,TEMP ;адрес буфера данных + LD B,2 ;число секторов + CALL BLK_RD_WR + + POP DE ;номер сектора + POP BC + DJNZ .loop + ; + + ELSE + ASSERT 0, Invalid 'RECOVERYmountTYPE' variant - RECOVERYmountTYPE + ENDIF + ENDM +; + +; + MACRO RST_to_BIOS + IF (IsInBIOS = 0) && ($ < #4000) + CALL ToBIOS_FromEXT + ELSE + RST ToBIOS_18 + ENDIF + ENDM + +; + +; + MACRO JP_to_BIOS + IF (IsInBIOS = 0) && ($ < #4000) + JP ToBIOS_FromEXT + ELSE + JP ToBIOS_18 + ENDIF + ENDM +; + +; +; MACRO + +; ENDM +; \ No newline at end of file diff --git a/Crazy BIOS/shared/DEFINES.INC b/Crazy BIOS/shared/DEFINES.INC new file mode 100644 index 0000000..3836ab1 --- /dev/null +++ b/Crazy BIOS/shared/DEFINES.INC @@ -0,0 +1,25 @@ +;=======================[All shared EQUs]=======================; +BETA_BUILD EQU 6 ; добавляет строку и сообщение о тестовой сборке на стартовом экране +;======================[All shared defines]=====================; + DEFINE PACKED_MAIN 0 ; паковать MAIN или влезает без этого? + DEFINE SP2000_Loader_Flag #0107 ; + DEFINE IDE_Optimization 1 ; слегка оптимизирует некоторые процедуры работы с HDD + DEFINE NeedSafePort_Y 1 ; если 0, то в режиме без акселя некоторые процедуры могут засрать экран + DEFINE Pashalki 0 ; + DEFINE PICTURE_FILE './src/bios/logo/psfathers.bmp' ; + DEFINE StandartCGApallete 1 ; Подключать палитру из standart_colors.inc + DEFINE BitStream_SizeInPages 4 ; + DEFINE USE_E1_SCANCODE 0 ; +;----[ Задержка в кадрах после отрисовки логотипа (0 = 256) ]---; + DEFINE LOGO_DELAY_MIN 25 ; + DEFINE LOGO_DELAY_NORM 100 ; + DEFINE LOGO_DELAY_MAX 130 ; +;----------------------------[ TEST ]---------------------------; + DEFINE TEST_INT 1 ; Тестовый обработчик пользовательского INT + DEFINE NEW_FEATURE 0 ; !TODO пункты в сетап + DEFINE HDDwriteProtect 0 ; старая фишка для функций 5x + DEFINE RECOVERYmountTYPE 1 ; 1 - быстрый немного захардкоженый вариант. 2 - более "правильный" + DEFINE RECOVERYrdChooseTYPE 1 ; 1 - RECOVERY грузится в диск 15, 2 - ищется свободный рамдиск, если нет, то в 15-ый + DEFINE FDD_NormalCount 0 ; !TODO + DEFINE UnusedSettingsFeatures 0 ; +;===============================================================; \ No newline at end of file diff --git a/Crazy BIOS/shared/RECOVERY.IMG b/Crazy BIOS/shared/RECOVERY.IMG new file mode 100755 index 0000000..4786914 Binary files /dev/null and b/Crazy BIOS/shared/RECOVERY.IMG differ diff --git a/Crazy BIOS/shared/VERSION.inc b/Crazy BIOS/shared/VERSION.inc new file mode 100644 index 0000000..1fda053 --- /dev/null +++ b/Crazy BIOS/shared/VERSION.inc @@ -0,0 +1,42 @@ +;============[For EXP part]============= +;------[Version of BIOS "VER.MOD"]------ +EXP_ID: +.VER EQU 3 ; Номер версии менять тут! +.MOD EQU 06 ; Номер версии менять тут! +BIOS_ver_hex EQU EXP_ID.VER*256+EXP_ID.MOD + + DEFINE BIOS_ver_string '0'+EXP_ID.VER, '.', '0'+EXP_ID.MOD/10, '0'+EXP_ID.MOD-(EXP_ID.MOD/10)*10 + + IF BETA_BUILD > 0 + DEFINE BETA_str_ver "BETA ","0"+BETA_BUILD + ENDIF +;--------------------------------------- + DEFINE BoardID_start #5283 + DEFINE BoardID_end #47E8 + DEFINE MotherBoardID #0000 + DEFINE MotherBoardType #00 ; !TODO 0 - Legacy, 1 - DX, 2 - Max +;======================================= + +;============[For ROM part]============= ;!FIXIT вы не понимаете, это другое)) +;-[Version of disk subsystem "VER.MOD"]- +ROM_ID: +.VER EQU 2 ; Номер версии менять тут! +.MOD EQU 55 ; Номер версии менять тут! +Disk_subsystem_ver_hex EQU ROM_ID.VER*256+ROM_ID.MOD + + DEFINE Disk_subsystem_ver_txt '0'+ROM_ID.VER, '.', '0'+ROM_ID.MOD/10, '0'+ROM_ID.MOD-(ROM_ID.MOD/10)*10 +;--------------------------------------- + +;============[For CNF part]============= +CNF_ID: +.VER EQU 3 ; Номер версии менять тут! +.MOD EQU 05 ; Номер версии менять тут! +bitstream_ver_hex EQU CNF_ID.VER*256+CNF_ID.MOD + + DEFINE bitstream_ver_string '0'+CNF_ID.VER, '.', '0'+CNF_ID.MOD/10, '0'+CNF_ID.MOD-(CNF_ID.MOD/10)*10 +;--------------------------------------- + +;======================================= + DEFINE SPTeam_year '2024' + DEFINE SetupVer '1.60' +;--------------------------------------- \ No newline at end of file diff --git a/Crazy BIOS/shared/includes.inc b/Crazy BIOS/shared/includes.inc new file mode 100644 index 0000000..3773dee --- /dev/null +++ b/Crazy BIOS/shared/includes.inc @@ -0,0 +1,19 @@ +; +;---------[All shared includes]--------- + INCLUDE 'src/bios/shared/DEFINES.INC' ; Shared defines + IF Pashalki + INCLUDE 'Shared_Includes/structures/EasterSprites.inc' + ENDIF + INCLUDE 'Shared_Includes/structures/FileSystem.inc' + INCLUDE 'src/bios/Loader/Loader.asm' ; Bitstream loader as macros + INCLUDE 'src/bios/shared/CompMacro.asm' ; макросы + INCLUDE 'Shared_Includes/constants/SP2000.inc' ; константы + INCLUDE 'Shared_Includes/constants/zx_char_codes.inc' ; константы + INCLUDE 'Shared_Includes/constants/zx_vars.inc' ; + INCLUDE 'Shared_Includes/macroses/macros.z80' + INCLUDE 'src/bios/ROM/MEM_MAP.inc' ; карта памяти + INCLUDE 'src/bios/shared/VERSION.inc' ; Версия EXP и ROM + INCLUDE 'Shared_Includes/constants/BIOS_EQU.inc' + INCLUDE 'src/bios/ROM/BIOS.inc' +;--------------------------------------- +; diff --git a/Crazy Estex DSS/BOOT/DSSBOOT.ASM b/Crazy Estex DSS/BOOT/DSSBOOT.ASM new file mode 100644 index 0000000..54c0231 --- /dev/null +++ b/Crazy Estex DSS/BOOT/DSSBOOT.ASM @@ -0,0 +1,1309 @@ +;------------------------------------------------------------------------------ +;Rev Date Name Decription +;------------------------------------------------------------------------------ +;R04 25-03-2023 BAO ; !FIXIT +;R03 23-01-2000 DNS OPTIMIZE NEW BOOTING PROCEDURE +;R02 08-01-2000 DNS NEW BOOTING PROCEDURE +;R01 25-05-1998 DNS Console printing +;R00 09-11-1998 DNS Color printing start message +; Install CGA palette +; +------------------------------+ +; + System Bootstrap + +; + Initial revision 09 Nov 1998 + +; +------------------------------+ + + MODULE DSS_Boot_Loader + +; BIOS 3.06 загружает один сектор загрузчика и передаёт ему управление. + + ; 0 - оригинальный вариант запуска DSS, 1 - вариант Саймана + DEFINE ORIGINAL_DSS 0 + ; 1 - будет грузить версию Саймана и основную. 0 - только основную. + DEFINE UNIVERSAL_BOOT 1 + +;------------------------------------------------------------------------------ +ORG_ADDRESS EQU #8000 +LOAD_SECTORS EQU SECTORS_OF_LOADER.AFTER_BPB +LOADER_IN_BPB: +.MAX_SIZE EQU _sBOOT_SECTOR.PARTITION_TABLE - _sBOOT_SECTOR_PARAMS_FAT32 +;------------------------------------------------------------------------------ + + DISP ORG_ADDRESS + + OUTPUT 'build/DSSloader.bin' + +;ADRIVE EQU #00 +;CDRIVE EQU #02 + + + +DRIVE: _mSYSID + DI + ; ;!TEST 26/03/2024 + ; LD SP,#C000 + ; ; + LD (DRIVE),A + ;[ ] 17.12.2023 загрузка с активного раздела, а не с первого + XOR A + LD (DRIVE+1),A + ; + LD C,BIOS.DRV_VERSION + RST ToBIOS_18 + ; + LD HL,FAIL + PUSH HL + ; + LD HL,MESSAGES.INCORR + RET C ; goto FAIL + LD A,(DRIVE) + BIT 7,A + JR Z,GOOD_DRIVE + EX DE,HL + LD DE,2*256 + 21 ;!HARDCODE если версия ниже 2.21, то ошибка + SBC HL,DE + LD HL,MESSAGES.INCORR + RET C ; goto FAIL + ; +GOOD_DRIVE: LD DE,#8200 ;!HARDCODE + LD HL,0 + LD IX,2 + LD BC,LOAD_SECTORS*256 + BIOS.DRV_READ ; дозагрузка секторов загрузчика + LD A,(DRIVE) + RST ToBIOS_18 + JP NC,CONTINUE + JR FAIL.NULL +//////////////////////////////////////////////////////////////////////// +FAIL: CALL MESSAGE +.NULL: LD HL,MESSAGES.FAILURE + CALL MESSAGE + JR $ +; +MESSAGE: ;R01 Start + XOR A + OUT (SYS_PORT.ON),A +.loop: LD A,(HL) ;R01 + INC HL + OR A + RET Z + CALL PRINTX + JR .loop +; +PRINTX: CP "\r" ; + JR Z,.CR_ + CP "\n" ; + JR Z,.LF_ + LD BC,1*256 + BIOS.LP_PRINT_SYM + RST ToBIOS_18 + RET + ; +.CR_: LD C,BIOS.LP_GET_PLACE + RST ToBIOS_18 + LD E,0 + LD C,BIOS.LP_SET_PLACE + RST ToBIOS_18 + RET + ; +.LF_: LD C,BIOS.LP_GET_PLACE + RST ToBIOS_18 + LD A,#1F + CP D + JR NZ,.LF2 + PUSH DE + PUSH HL + LD DE,#0020 + LD BC,1*256 + BIOS.LP_SCROLL_UD + RST ToBIOS_18 + ; + LD DE,#1F00 + LD C,BIOS.LP_SET_PLACE + RST ToBIOS_18 + ; + LD A," " + LD BC,#50 + BIOS.LP_PRINT_SYM + RST ToBIOS_18 + POP HL + POP DE + DEC D +.LF2: INC D + LD C,BIOS.LP_SET_PLACE + RST ToBIOS_18 + RET ;R01 +;R01 End + +MESSAGES:; 0 10 20 30 40 50 60 70 80 +.FAILURE: DB "\r\nFatal error! Press RESET to restart.\r\n",0 +.INCORR: DB "\r\nOld BIOS version.\r\n",0 +.ERRPART: DB "\r\nUnknown partition table.",0 +.ERRIBPB: DB "\r\nInvalid BOOT sector.",0 +.NO_SYS: DB "\r\nCan't open SYSTEM.DOS...",0 +.NOSHELL: DB "\r\nCan't open SYSTEM.EXE...",0 +.STARTDO: DB "\r\nStarting DSS... \r\n\n",0 +; +SHELL_NAME: DB '\SYSTEM.EXE /P',0 +ROOT: DB 'X:\',0 +CORE_NAME: DB "SYSTEM DOS" +.Size EQU $-CORE_NAME +//////////////////////////////////////////////////////////////////////// + ASSERT $<#8200, "Error!!! BIOS LOADING ONLY FIRST #200 BYTES" +//////////////////////////////////////////////////////////////////////// + +CONTINUE: LD HL,0 + LD (PARTITION_START_L),HL + LD (PARTITION_START_H),HL + ; + LD BC,1*256 + BIOS.GetMem + RST ToBIOS_18 ;GET PAGE FOR DOS + LD (LOAD_CORE.BANKDOS),A + ; + OUT (SLOT0),A + ; + CALL GET_BPB ;READ BPB + LD HL,MESSAGES.ERRIBPB + RET C ; goto FAIL + CALL GETROOT + ; + LD HL,MESSAGES.NO_SYS + RET C ; goto FAIL + ; [ ] загрузка system.dos больше #4000 байтов + LD HL,(FSIZE1) + LD A,H + OR L + JR NZ,.set_size + LD DE,(FSIZE0) + LD HL,#4000 + SBC HL,DE + JR NC,.set_no_size +.set_size: LD A,#FF +.set_no_size: LD (LOAD_CORE.BIG_CORE),A + OR A + PUSH AF + ; загрузка + EXX + LD HL,(FCLUSTER_H) + EXX + LD HL,(FCLUSTR_L) + LD DE,#C000 + CALL LOAD_CORE + ; [ ] загрузка system.dos больше #4000 байтов + EX AF,AF' + POP AF + JR Z,.no_big_core + EX AF,AF' + JR C,.no_big_core + ; + IN A,(SLOT1) + LD (LOAD_CORE.BANKDOS),A + LD A,SUBLOAD_SIZE + LD (LOAD_CORE.max_sectors),A + LD (LOAD_CORE.BIG_CORE),A ; теперь это счётчик оставшихся секторов + ; + LD A,(BOOT_BUFFER + BOOT_SECTOR.SectorsPerCluster) + CP #20 + 1 ; !HARDCODE кол-во загружаемых секторов + JP NC,INC_SECTOR_NUM + ;CALL R_F_FAT ; next cluster in chain + CALL READ_FROM_FAT ; next cluster in chain + EX DE,HL + EXX + EX DE,HL + EXX + LD DE,#C000 + CALL NC,LOAD_CORE +.no_big_core: ; +RUN_CORE: DI + XOR A + OUT (SYS_PORT.OFF),A + ; + LD A,#10 + LD BC,#7FFD + OUT (C),A + ; + LD A,1 + LD B,#1F ;1FFD + OUT (C),A + ; + ;DOS LOADED + ;IF UNIVERSAL_BOOT + ;[ ] 17.12.2023 загрузка с активного раздела, а не с первого + LD A,(DRIVE+1) ; номер раздела + LD L,A + ; + LD A,(DRIVE) ; номер устройства + LD C,Dss.Version + RST ToDSS + JP C,FAIL.NULL + ; + LD HL,MESSAGES.STARTDO + CALL MESSAGE + ; + XOR A + OUT (SYS_PORT.OFF),A + ; + LD A,(DRIVE) + LD BC,Dss.BootDSK.Set + RST ToDSS + ; + LD BC,Dss.BootDSK.Get + ;ELSE + ; IF ORIGINAL_DSS + ; LD C,Dss.Version + ; RST ToDSS + ; ELSE + ; LD A,(DRIVE) + ; LD C,Dss.Version + ; RST ToDSS + ; JP C,FAIL.NULL + ; LD C,Dss.BootDSK + ; ENDIF ; + ; LD HL,MESSAGES.STARTDO + ; CALL MESSAGE + ; IF ORIGINAL_DSS + ; LD A,(DRIVE) + ; LD BC,Dss.BootDSK.Set + ; RST ToDSS + ; LD BС,Dss.BootDSK.Get + ; ENDIF + ;ENDIF + ; + RST ToDSS + ; + ADD A,"A" + ; + LD HL,ROOT + LD (HL),A + LD C,Dss.ChDir + RST ToDSS + ; + LD HL,SHELL_NAME + LD BC,Dss.Exec + RST ToDSS + +.NoShell: JP NC,FAIL.NULL + LD HL,MESSAGES.NOSHELL + CP DSS_Error.sys.UNEXPECTED_APP_TRMN + JP NZ,FAIL + JP FAIL.NULL + +; +INC_SECTOR_NUM: PUSH DE + CALL CLUSTER_TO_SECTOR + LD DE,#20 ;!HARDCODE количество прочитанных секторов + ADD IX,DE + JR NC,.no_inc + INC HL +.no_inc: ; + POP DE + LD BC,RUN_CORE + PUSH BC + PUSH HL ; для баланса + PUSH HL ; для баланса + JP LOAD_CORE.subload +; + +; +PART_TB: LD HL,(BOOT_BUFFER + BOOT_SECTOR.MBR_SIGNATURE) + LD DE,#AA55 + ; CF = 0 + SBC HL,DE + SCF + RET NZ + ; + PUSH BC + LD IX,BOOT_BUFFER + BOOT_SECTOR.PARTITION_TABLE + LD B, +(_sMBR_PARTITION_TABLE / _sMBR_PARTITION_RECORD) + ; + ;LD HL,YEPDOS + ; +.part_loop: LD A,(IX + _sMBR_PARTITION_RECORD.FS_ID) + ; ЕСЛИ добавится поддержка ещё нескольких типов ФС, то поменять 1fs на 2fs + ; 1 + CP PartitionSysTypes.FAT16_LBA + JR Z,YEPDOS + CP PartitionSysTypes.FAT16 + JR Z,YEPDOS + CP PartitionSysTypes.FAT16_32Mb + JR Z,YEPDOS + CP PartitionSysTypes.FAT12 + JR Z,YEPDOS + CP PartitionSysTypes.FAT32 + JR Z,YEPDOS + CP PartitionSysTypes.FAT32_LBA + JR Z,YEPDOS + ; + ; 2fs + ; EXX + ; LD HL,SUPPORTED_PARTITIONS + ; LD BC,SUPPORTED_PARTITIONS.Size + ; CPIR + ; EXX + ; RET Z ;JR Z,YEPDOS + ; +.next: LD DE,_sMBR_PARTITION_RECORD + ADD IX,DE + DJNZ .part_loop + ; + LD HL,MESSAGES.ERRPART + JP FAIL +; 2fs + ; SUPPORTED_PARTITIONS: + ; ;.Empty DB #00 + ; .FAT12 DB #01 + ; .FAT16_32Mb DB #04 + ; ;.Extended DB #05 + ; .FAT16 DB #06 + ; ;.HPFS_NTFS DB #07 + ; .FAT32 DB #0B + ; .FAT32_LBA DB #0C + ; .FAT16_LBA DB #0E + ; ;.Win_Ext_LBA DB #0F + ; ;.Linux_swap DB #82 + ; ;.Linux DB #83 + ; ;.Linux_extended DB #85 + ; .Size EQU $-SUPPORTED_PARTITIONS +; + +; +YEPDOS: ;[ ] 17.12.2023 загрузка с активного раздела, а не с первого + LD A,#80 + CP (IX + _sMBR_PARTITION_RECORD.isActive) + JR NZ,PART_TB.next + LD A,4 ;!HARDCODE счетчик записей партиций в MBR + SUB B + PUSH AF ; номер загрузочного раздела + ; + LD L,(IX + _sMBR_PARTITION_RECORD.Start_LBA + 0) + LD H,(IX + _sMBR_PARTITION_RECORD.Start_LBA + 1) + PUSH HL + LD (PARTITION_START_L),HL + LD L,(IX + _sMBR_PARTITION_RECORD.Start_LBA + 2) + LD H,(IX + _sMBR_PARTITION_RECORD.Start_LBA + 3) + POP IX + LD (PARTITION_START_H),HL + LD A,(DRIVE) + LD DE,BOOT_BUFFER + LD BC,1*256 + BIOS.DRV_READ + RST ToBIOS_18 + ;[ ] 17.12.2023 загрузка с активного раздела, а не с первого + POP AF + POP BC + LD L,A ; номер загрузочного раздела + LD A,C + ; + RET + ; + +; +GET_BPB: XOR A + LD H,A + LD L,A + LD (FatBuffer.FAT1_SEC_H),HL ; high word first sector FAT #1 + LD (FatBuffer.RootDirFirstSector_H),HL + LD (FatBuffer.SectorsPerFAT_H),A + ; + PUSH HL + POP IX + LD DE,BOOT_BUFFER + LD BC,1*256 + BIOS.DRV_READ + LD A,(DRIVE) + RST ToBIOS_18 + RET C + ; перекидывание части загрузчика из 0 сектора + LD HL,BOOT_BUFFER + (_sBOOT_SECTOR.PARTITION_TABLE - ZERO_SECTOR_OF_BPB.Size) + LD DE,ZERO_SECTOR_OF_BPB + LD BC,ZERO_SECTOR_OF_BPB.Size + LDIR + ; + LD A,(DRIVE) + LD B,A + AND #F0 + LD C,A + CP #80 + JR NZ,.NX1 + CALL PART_TB ;HDD + RET C + ;[ ] 17.12.2023 загрузка с активного раздела, а не с первого + LD (DRIVE+1),HL + ; +.NX1: CP #00 + JR NZ,.NX2 + ; + ; SET_PRM if FDD + PUSH BC + LD A,B + LD C,BIOS.DRV_GET_PAR + RST ToBIOS_18 + LD A,(BOOT_BUFFER + BOOT_SECTOR.SectorsPerTrack) + LD L,A + POP AF + LD C,BIOS.DRV_SET_PAR + RST ToBIOS_18 + ; +.NX2: LD HL,(BOOT_BUFFER + BOOT_SECTOR.MBR_SIGNATURE) + LD DE,#AA55 + ;AND A + SBC HL,DE + SCF + RET NZ + ; + LD A,(BOOT_BUFFER + BOOT_SECTOR.DRIVE_TYPE) + CP #F0 + RET C + ; + LD HL,(BOOT_BUFFER + BOOT_SECTOR.BytesPerSector) + LD A,(BOOT_BUFFER + BOOT_SECTOR.SectorsPerCluster) + LD (FatBuffer.SectorsPerCluster),A + ; calc. first sector FAT + LD HL,(BOOT_BUFFER + BOOT_SECTOR.RESERVED_SECTORS) + LD (FatBuffer.FAT1_SEC_L),HL ; low word first sector FAT #1 + ; + XOR A + LD B,A + LD C,A + EXX + LD H,A + LD L,A + LD D,A + LD E,A + EXX + ; + ;LD BC,0 + LD DE,(BOOT_BUFFER + BOOT_SECTOR.SectorsPerFAT16) + LD A,E + OR D + JR NZ,.skip_high + ; + EXX + LD DE,(BOOT_BUFFER + BOOT_SECTOR.SectorsPerFAT32 + 2) + LD A,E + EXX + ;LD BC,(BOOT_BUFFER + BOOT_SECTOR.SectorsPerFAT32 + 2) + ;LD A,C + LD (FatBuffer.SectorsPerFAT_H),A + LD DE,(BOOT_BUFFER + BOOT_SECTOR.SectorsPerFAT32) + ; +.skip_high: LD (FatBuffer.SectorsPerFAT_L),DE + LD A,(BOOT_BUFFER + BOOT_SECTOR.Number_of_FATs) ; amount FATs + CP 1 + JR Z,.one_FAT + DEC A + ADD HL,DE + EXX + ADC HL,DE + EXX + ;JR NC,.no_inc_BC + ;INC BC +.no_inc_BC: ; +.one_FAT: ; +.loop1: ADD HL,DE + EXX + ADC HL,DE + EXX + ;JR NC,.loop1_1 + ;INC BC +.loop1_1: DEC A + JR NZ,.loop1 + ; + LD (FatBuffer.RootDirFirstSector_L),HL ; first sector DIR + EXX + ; можно сразу тут загнать старший байт, потому-что дла FAT32 следующий расчёт - это прибавление нуля. + LD (FatBuffer.FirstDataSector_H),HL + EXX + ;LD (FatBuffer.FirstDataSector_H),BC + LD BC,(BOOT_BUFFER + BOOT_SECTOR.BytesPerSector) + LD A,B + AND A + ; + RL C + RLA + RL C + RLA + RL C + RLA + ; + LD C,A + LD B,0 ; BC - File handels in sectors + ; + EX DE,HL + LD HL,(BOOT_BUFFER + BOOT_SECTOR.FilesInRootDIR) ; 0 for fat32 + LD A,H + OR L + JR Z,.skip_loop2 + ; + DEC HL + XOR A +.loop2: INC A + RET C + SBC HL,BC + JR NC,.loop2 + ; +.skip_loop2: EX DE,HL + LD C,A ; A - sectors in DIR + LD B,0 + LD (FatBuffer.DirSizeInSectors),A + + ADD HL,BC ; Start DATA area + LD (FatBuffer.FirstDataSector_L),HL + ; B = 0 + ; + LD HL,(BOOT_BUFFER + BOOT_SECTOR.BytesPerSector) + LD A,(FatBuffer.SectorsPerCluster) + ;!TODO FATcacheSize + ; calc. cluster size + XOR 1 + JR Z,.loop3.end + RRA +.loop3: ADD HL,HL + RRA + JP NC,.loop3 +.loop3.end: ; + LD (FatBuffer.BytesPerCluster),HL + ; проверка на размер кластера больше 32 кб - не поддерживается ; !TODO + ; ..... + ; +//////////////////////////////////////////////////////////////////////// + ; + LD HL,(BOOT_BUFFER + BOOT_SECTOR.SectorsPerDrive) + LD BC,0 + LD A,H + OR L + JP NZ,.HDDSMAL + ; + LD HL,(BOOT_BUFFER + BOOT_SECTOR.BPB_BIG_TOTAL_SECTORS_L) + LD BC,(BOOT_BUFFER + BOOT_SECTOR.BPB_BIG_TOTAL_SECTORS_H) +.HDDSMAL: ; + PUSH BC ; Total Sectors high + PUSH HL ; Total Sectors low + XOR A + ;LD H,A + ;LD L,A + ;LD (FatBuffer.CacheBlock),HL + ; A = 0 + LD DE,(FatBuffer.SectorsPerFAT_H) + LD D,A + LD HL,(FatBuffer.SectorsPerFAT_L) + ; DE:HL = SectorsPerFAT + ; + LD A,(BOOT_BUFFER + BOOT_SECTOR.Number_of_FATs) + LD B,A + DEC A + JR Z,.loop_mul_end + ; .Number_of_FATs * .SectorsPerFAT +.loop_mul: ADD HL,HL + EX DE,HL + ADC HL,HL + EX DE,HL + DJNZ .loop_mul +.loop_mul_end: ; .DirSizeInSectors + .Number_of_FATs * .SectorsPerFAT + LD B,0 + LD A,(FatBuffer.DirSizeInSectors) + LD C,A + ADD HL,BC + JR NC,.no_inc_DE + INC DE +.no_inc_DE: ; .RESERVED_SECTORS + .DirSizeInSectors + .Number_of_FATs * .SectorsPerFAT + LD BC,(BOOT_BUFFER + BOOT_SECTOR.RESERVED_SECTORS) + ADD HL,BC + JR NC,.no_inc_de + INC DE +.no_inc_de: ; Total_Sectors - (.RESERVED_SECTORS + .DirSizeInSectors + .Number_of_FATs * .SectorsPerFAT) + AND A + LD B,D + LD C,E + POP DE ; Total Sectors low + EX DE,HL + SBC HL,DE + EX (SP),HL ; Total Sectors high + SBC HL,BC + POP DE ; Total Sectors low + ; HL:DE = DataSec + ; + LD A,(FatBuffer.SectorsPerCluster) + ; HL:DE / A => DE:BC, H=0, L - остаток + ;CALL DIV_by_Shifts + LD C,A + DEC A + JR Z,.DIV_exit + ; + AND E + LD B,A ; остаток + LD A,C + RRCA + ; +.DIV_loop: SRL H + RR L + RR D + RR E + RRCA + JP NC,.DIV_loop + LD A,B +.DIV_exit: LD B,D + LD C,E + EX DE,HL + LD H,0 + LD L,A + ; + ; выясняем разрядность FAT + LD A,D + OR E + JR NZ,.its_FAT32 + ; + LD HL,4084 + SBC HL,BC + LD A,FAT_TYPE.x12 + JR NC,.SET_VARS + ; + LD HL,65524 + SBC HL,BC + LD A,FAT_TYPE.x16 + JR NC,.SET_VARS + ; +.its_FAT32: LD A,(BOOT_BUFFER + BOOT_SECTOR.MainFATnumber) + CP #80 + JR C,.mirrored_FATs ;если все копии FAT используются + ; используется только одна копия FAT + LD HL,(FatBuffer.FAT1_SEC_H) + LD DE,(FatBuffer.SectorsPerFAT_H) + LD D,0 + EXX + LD HL,(FatBuffer.FAT1_SEC_L) + LD DE,(FatBuffer.SectorsPerFAT_L) + AND #0F + JR Z,.first_FAT_active + LD B,A + ; +.fat_calc_loop: ADD HL,DE + EXX + ADC HL,DE + EXX + DJNZ .fat_calc_loop + ; +.first_FAT_active: + LD (FatBuffer.FAT1_SEC_L),HL + EXX + LD (FatBuffer.FAT1_SEC_H),HL +.mirrored_FATs: ; + LD HL,(BOOT_BUFFER + BOOT_SECTOR.RootDirStartCluster) + LD DE,(BOOT_BUFFER + BOOT_SECTOR.RootDirStartCluster+2) + LD (FatBuffer.RootDirStartCluster_L),HL + LD (FatBuffer.RootDirStartCluster_H),DE + CALL CLUSTER_TO_SECTOR.no_prepare + LD (FatBuffer.RootDirFirstSector_L),IX + LD (FatBuffer.RootDirFirstSector_H),HL + LD A,FAT_TYPE.x32 + ; +.SET_VARS: LD (FatBuffer.FAT_TYPE),A + LD DE,0 + CALL READ_FAT_TABLE + AND A + RET + ; + + +;NSECTOR: +; in: HL':HL - CLUSTER +; out: HL:IX - SECTOR +CLUSTER_TO_SECTOR: + EXX + PUSH HL + EXX + POP DE + ; DE:HL - cluster + ; +.no_prepare: PUSH BC + LD BC,-2 + ADD HL,BC + JR C,.no_dec_de + DEC DE +.no_dec_de: ; cluster = cluster - 2 + ; + LD A,(FatBuffer.SectorsPerCluster) + XOR 1 + JR Z,.skip + ; + RRA +.loop: ADD HL,HL + RL E + RL D + ; + RRA + JR NC,.loop + ; +.skip: EX DE,HL + PUSH DE + POP IX + LD DE,(FatBuffer.FirstDataSector_L) + ADD IX,DE + LD DE,(FatBuffer.FirstDataSector_H) + ADC HL,DE + ; + POP BC + RET + ; + + +; поиск system.dos +GETROOT: LD HL,(FatBuffer.RootDirStartCluster_L) + PUSH HL + LD HL,(FatBuffer.RootDirStartCluster_H) + PUSH HL + LD A,(FatBuffer.FAT_TYPE) + CP FAT_TYPE.x32 + LD A,(FatBuffer.DirSizeInSectors) + JR NZ,.load_and_search + ; + LD A,(FatBuffer.SectorsPerCluster);!FIXIT прочтёт только первый кластер каталога на FAT32 +.load_and_search: + LD HL,(FatBuffer.RootDirFirstSector_H) + LD IX,(FatBuffer.RootDirFirstSector_L) + ;LD BC,(PARTITION_START_L) + ;LD DE,(PARTITION_START_H) + ; [x] 28/04/2024. Bug with incorrect reading root dir. Reported by Roman "Romychs" Boykov. + ;ADD IX,BC + ;ADC HL,DE + ; +.NEXT_CLUSTER: CALL GET_ABSOLUTE_SECTOR + CALL .NEXT_SECTOR + ; + POP HL + EXX + POP HL + RET C + RET NZ + CALL READ_FROM_FAT + RET C + EX DE,HL + PUSH HL + EXX + EX DE,HL + PUSH HL + EXX + ; in: HL':HL - CLUSTER + ; out: HL:IX - SECTOR + CALL CLUSTER_TO_SECTOR + LD A,(FatBuffer.SectorsPerCluster) + JR .NEXT_CLUSTER + ; + ; +.NEXT_SECTOR: PUSH AF + ; [x] 28/04/2024. Bug with incorrect reading root dir. Reported by Roman "Romychs" Boykov. + ;ADD IX,BC + ;ADC HL,DE + ; + PUSH IX + PUSH HL + LD BC,1*256 + BIOS.DRV_READ + LD DE,DIR_BUFFER + LD A,(DRIVE) + RST ToBIOS_18 + CALL SEARCH + POP HL + POP IX + POP BC + RET C + RET NZ + LD A,B + ; next sector + LD BC,1 + ; [x] 28/04/2024. Bug with incorrect reading root dir. Reported by Roman "Romychs" Boykov. + ADD IX,BC + ADC HL,BC + DEC HL + ; + DEC A + JR NZ,.NEXT_SECTOR + RET + ; +; ; ; + +; вход: HL:IX - относительный сектор +; выход: HL:IX - абсолютный сектор +GET_ABSOLUTE_SECTOR: + LD DE,(PARTITION_START_L) + ADD IX,DE + LD DE,(PARTITION_START_H) + ADC HL,DE + RET +; + + +SEARCH: LD C,17 ;HANDELS PER SECTOR 512/32 + 1 + LD IX, DIR_BUFFER - FAT_DIRECTORY_RECORD +.SKIPNAM: LD DE,FAT_DIRECTORY_RECORD +.SKIPNAM_DE: ADD IX,DE + DEC C + RET Z + ; + LD A,(IX+FAT_DIRECTORY_RECORD.NAME) + OR A + SCF + RET Z + ; + CP #E5 + JR Z,.SKIPNAM_DE + ; + LD A,(IX+FAT_DIRECTORY_RECORD.ATTRIBUT) + AND FAT_ATTR.DIRECTORY + JR NZ,.SKIPNAM_DE + ; + LD DE,CORE_NAME + PUSH IX + POP HL + LD B,CORE_NAME.Size + ; +.loop: LD A,(DE) + CP (HL) + JR NZ,.SKIPNAM + INC HL + INC DE + DJNZ .loop + ; + PUSH IX + POP HL + LD DE,HANDBUF + LD BC,FAT_DIRECTORY_RECORD + LDIR + ; ZF = 1, CF = 0, A != 0 + AND A ; на выходе ZF = CF = 0 + RET + +; HL - CLUSTER +; DE - ADDRESS +; !TODO сделать тут определение размера SYSTEM.DOS +; [ ] и возможность загрузить больше 1 страницы +LOAD_CORE: LD (READMEM),DE +.loop: PUSH HL + EXX + PUSH HL + EXX + ; + CALL CLUSTER_TO_SECTOR + ; + ;LD A,(FatBuffer.FAT_TYPE) + ; CP FAT_TYPE.x32 + ; JR NZ,.skip_it + ; + ;LD DE,(PARTITION_START_L) + ;ADD IX,DE + ;LD DE,(PARTITION_START_H) + ;ADC HL,DE + CALL GET_ABSOLUTE_SECTOR +;.skip_it: ; + LD DE,(READMEM) + LD A,(BOOT_BUFFER + BOOT_SECTOR.SectorsPerCluster) +.max_sectors+1: CP #20 + JR C,.SMALL_CLUSTER + ; +.subload: LD A,(.max_sectors) + LD B,A + LD C,BIOS.DRV_READ_LONG + LD A,(LOAD_CORE.BANKDOS) + EX AF,AF' + LD A,(DRIVE) + RST ToBIOS_18 + + EXX + POP HL + EXX + POP HL + RET + ; +.SMALL_CLUSTER: LD B,A + LD C,BIOS.DRV_READ_LONG +.BANKDOS+1: LD A,0 + EX AF,AF' + LD A,(DRIVE) + RST ToBIOS_18 + ; + LD HL,(READMEM) + LD DE,(FatBuffer.BytesPerCluster) + ADD HL,DE + LD (READMEM),HL + EXX + POP HL + EXX + POP HL + CCF + RET NC + ; [ ] загрузка system.dos больше #4000 байтов +.BIG_CORE+1: LD A,0 + DEC A + LD (.BIG_CORE),A + RET Z + ; + CALL READ_FROM_FAT + ;CALL R_F_FAT + RET C + EXX + EX DE,HL + EXX + EX DE,HL + JP .loop + ; + + +; +; HL:DE / A => DE:BC, H=0, L - остаток +; DIV_by_Shifts: +; LD C,A +; DEC A +; JR Z,.DIV_exit +; ; +; AND E +; LD B,A ; остаток +; LD A,C +; RRCA +; ; +; .DIV_loop: SRL H +; RR L +; RR D +; RR E +; RRCA +; JP NC,.DIV_loop +; LD A,B +; .DIV_exit: LD B,D +; LD C,E +; EX DE,HL +; LD H,0 +; LD L,A +; RET + + +//// //// //// //// //// //// //// //// //// + //// //// //// //// //// //// //// //// //// + DISPLAY "SECTORS 1..3 DATA ENDS:\t",/H,$,". Size: ",/D,$-ORG_ADDRESS," b. Free: ",/D,512*3-($-ORG_ADDRESS)," b." +ZERO_SECTOR_OF_BPB: +.physical EQU $$$ +//// //// //// //// //// //// //// //// //// + //// //// //// //// //// //// //// //// //// + + +;FAT_BLOCK * Sectors_in_Block = SECTOR_OF_FAT +; in: HL - Cache block +; out: C:HL - logical number +; B = 0 +GET_SECTOR_OF_FAT: + LD A,(FatBuffer.FAT_TYPE) + LD B,FAT_CACHE.Degree_32 ;!FIXIT сделать через переменную + XOR FAT_TYPE.x32 + JR Z,.next + LD B,FAT_CACHE.Degree ;!FIXIT сделать через переменную + XOR A +.next: LD C,A + ; +.loop: ADD HL,HL ;x2 + ADC A,C + DJNZ .loop + ; + LD C,A + RET + ; + + +;вход: HL - номер кластера +;выход: HL - адрес нужной ячейки в странице FATPAGE +; CF - чётный/нечётный адрес кластера +GET_FAT12_CELL: LD D,H + LD E,L + SRL H + RR L ; сдвиг вправо через CF + PUSH AF ; сохр. флаг + ADD HL,DE ; CLUSTER * 1.5 + ; + IF FAT_CACHE.Size_12 < #1800 + ;!FIXIT оптимизировать + LD A,H + LD B,H + ; + AND #1F + ;AND FAT_CACHE.Size_Mask_16 + ; + LD H,A + LD A,B + ; + RLCA + RLCA + RLCA + ;DUP FAT_CACHE.Degree_16 + ; RRCA + ;EDUP + AND #07 + ;AND FAT_CACHE.Part_Mask_16 + ; + ; [ ] поменялся вход в процедуру READ_FAT_TABLE. Раньше номер блока в рег. A передавался + LD DE,(FatBuffer.CacheBlock) ; BC - BLOCK FAT IN CASH + CP E + LD E,A + ; + CALL NZ,READ_FAT_TABLE ; прочитать в кеш 16 секторов FAT-а + ENDIF + ; + LD DE,FATPAGE.cache + ADD HL,DE + POP AF + RET + ; +;вход: HL - номер кластера +;выход: HL - адрес нужной ячейки в странице FATPAGE +GET_FAT16_CELL: LD A,H + LD B,H + AND FAT_CACHE.Size_Mask_16 + LD H,A + LD A,B + ; A=A/16 ; A - BLOCK FAT (1 BLOCK = 8192 BYTES) + DUP FAT_CACHE.Degree_16 + RRCA + EDUP + ;AND #0F + AND FAT_CACHE.Part_Mask_16 + ; + ADD HL,HL ; HL - FAT OFFSET (FROM CASH) + LD DE,(FatBuffer.CacheBlock) ; BC - BLOCK FAT IN CASH + CP E + LD E,A + ; + CALL NZ,READ_FAT_TABLE ; A != C - READ NEW BLOCK FAT + LD DE,FATPAGE.cache ; начало кеша FAT-а + ADD HL,DE ; на ячейку FAT + RET + ; +; +;RE_FAT: +;RX01 +; Прочитать в кеш ХХ секторов FAT-а +; DE - NEW FAT BLOCK +READ_FAT_TABLE: PUSH HL + ; + EX DE,HL + LD (FatBuffer.CacheBlock),HL + ; + CALL GET_SECTOR_OF_FAT + ; + ; BC:HL - номер лог.сектора + LD DE,(FatBuffer.FAT1_SEC_L) + ADD HL,DE + ; + ; EX DE,HL + ; LD XH,D + ; LD XL,E + PUSH HL + POP IX + ; + LD HL,(FatBuffer.FAT1_SEC_H) +.no_inc: ADC HL,BC + ; HL:IX - SECTOR FAT FOR READING + ; + ;LD DE,(PARTITION_START_L) + ;ADD IX,DE + ;LD DE,(PARTITION_START_H) + ;ADC HL,DE + CALL GET_ABSOLUTE_SECTOR + ; + LD DE,FAT_SECTORS_BUFFER + ; + IN A,(SLOT3) + PUSH AF + LD A,SHARED_PAGE + OUT (SLOT3),A + ; + LD A,(FatBuffer.FAT_TYPE) + XOR FAT_TYPE.x32 + LD BC,FAT_CACHE.Sectors_16*256 + BIOS.DRV_READ + JR NZ,.next + LD B,FAT_CACHE.Sectors_32 +.next: LD A,(DRIVE) + RST ToBIOS_18 + ; + POP AF + OUT (SLOT3),A + POP HL + RET + +;вход: HL':HL - номер кластера +;выход: HL - адрес нужной ячейки в странице FATPAGE +GET_FAT32_CELL: ; двигаем влево HL':H + LD A,H + EXX + LD C,A + LD A,H + AND FAT_CACHE.Size_Mask_32 ; #0F + LD H,A + LD A,C + ; + LD B,FAT_CACHE.Degree ; 4 сдвига +.loop_block: RLCA ; << H + RL L ; << L' + RL H ; << H' + DJNZ .loop_block + EXX + ; В итоге тут в HL' номер блока FAT + ; + ; HL - FAT32 OFFSET (FROM CASH) + LD A,H + AND FAT_CACHE.Size_Mask_32 ; #0F + LD H,A + ADD HL,HL + ADD HL,HL + PUSH HL + AND A + ; + EXX + EX DE,HL + LD HL,(FatBuffer.CacheBlock) ; BC - BLOCK FAT IN CASH + SBC HL,DE + CALL NZ,READ_FAT_TABLE ; A != C - READ NEW BLOCK FAT + POP HL + LD DE,FATPAGE.cache ; начало кеша FAT-а + ADD HL,DE ; на ячейку FAT + RET + ; +;------------------------------------------------------------------------------------------------ +; Прочитать из кеша FAT-а номер след. кластера +; вход: hl - номер кластера (младшее слово) +; hl' - номер кластера (старшее слово. только для FAT32) +; выход: hl - номер кластера (младшее слово) +; hl' - номер кластера (старшее слово) +; de - номер след. кластера (младшее слово) +; de' - номер след. кластера (старшее слово) +; если DE':DE = 0, то кластер HL':HL свободен +; CF - конец цепочки +;------------------------------------------------------------------------------------------------ +READ_FROM_FAT: PUSH HL + ; + IN A,(SLOT3) + PUSH AF + LD A,SHARED_PAGE + OUT (SLOT3),A + ; + LD A,(FatBuffer.FAT_TYPE) + CP FAT_TYPE.x16 + JR C,.FAT12 + JR NZ,.FAT32 + ; fat16, просто читать след. номер +.FAT16: CALL GET_FAT16_CELL + LD E,(HL) ; прочитать номер кластера + INC HL + LD D,(HL) + ; + LD HL,SERVICE_SECTORS.FAT16 +.exit: POP AF + OUT (SLOT3),A + ; обнуляем CF и устанавливаем код ошибки = DssErr.sys.NO_ERROR + XOR A + ; проверка на служ. кластеры + SBC HL,DE + POP HL + EXX + LD H,A + LD L,A + LD D,A + LD E,A + EXX + RET + ; + ; +.FAT12: CALL GET_FAT12_CELL + LD E,(HL) + INC HL + LD D,(HL) + LD HL,SERVICE_SECTORS.FAT12 + JR NC,.Correct_2 +.Correct_1: LD A,E + AND #F0 + DUP 4 ; вправо на 4 битa + RR D + RRA + EDUP + LD E,A + JR .exit + ; +.Correct_2: LD A,D + AND #0F + LD D,A + JR .exit + ; +.FAT32: EXX + PUSH HL + EXX + ; + CALL GET_FAT32_CELL + ; прочитать младшее слово номера кластера + LD E,(HL) + INC HL + LD D,(HL) + INC HL + ; прочитать старшее слово номера кластера + LD A,(HL) + INC HL + EX AF,AF' + LD A,(HL) + EXX + AND #0F + LD D,A + EX AF,AF' + LD E,A + EXX + ; обнуляем CF и устанавливаем код ошибки = DssErr.sys.NO_ERROR + XOR A + ; проверка на служ. кластеры младшего слова кластера + LD HL,SERVICE_SECTORS.FAT32.Low + SBC HL,DE + ; проверка на служ. кластеры старшего слова кластера + EXX + LD HL,SERVICE_SECTORS.FAT32.High + SBC HL,DE + POP HL + EXX + POP BC + LD A,B + OUT (SLOT3),A + POP HL + LD A,0 + RET +; ; ; + + + +//// //// //// //// //// //// //// //// //// + //// //// //// //// //// //// //// //// //// + ASSERT ($-ZERO_SECTOR_OF_BPB) <= LOADER_IN_BPB.MAX_SIZE, "---< CRITICAL ERROR! Loader is too big >----" + DISPLAY "SECTORS 0 DATA ENDS:\t\t",/H,$,". Size: ",/D,$-ZERO_SECTOR_OF_BPB," b. Free: ",/D,LOADER_IN_BPB.MAX_SIZE-($-ZERO_SECTOR_OF_BPB)," b." +ZERO_SECTOR_OF_BPB_END: +ZERO_SECTOR_OF_BPB.Size EQU ZERO_SECTOR_OF_BPB_END - ZERO_SECTOR_OF_BPB +//// //// //// //// //// //// //// //// //// + //// //// //// //// //// //// //// //// //// +; + +; +//////////////////////////////////////////////////////////////////////// +; Area for boot sector [512Bytes] +;BOOT _sBOOT_SECTOR_PARAMS = $ +BOOT_BUFFER EQU $ +DIR_BUFFER EQU BOOT_BUFFER+512 +; +;FAT_SECTORS_BUFFER EQU DIR_BUFFER+512 +;VALUE EQU 3*512+FAT_SECTORS_BUFFER +FAT_SECTORS_BUFFER EQU #C000 +VALUE EQU DIR_BUFFER+512 + +FatBuffer _sysFatBuffer = VALUE + + +HANDBUF EQU VALUE + _sysFatBuffer +FCLUSTER_H EQU HANDBUF + FAT_DIRECTORY_RECORD.FIRST_CLUSTER_H +FCLUSTR_L EQU HANDBUF + FAT_DIRECTORY_RECORD.FIRST_CLUSTER_L +FSIZE0 EQU HANDBUF + FAT_DIRECTORY_RECORD.F_SIZE +FSIZE1 EQU HANDBUF + FAT_DIRECTORY_RECORD.F_SIZE + 2 +PARTITION_START_H EQU FSIZE1+2 +PARTITION_START_L EQU PARTITION_START_H+2 +READMEM EQU PARTITION_START_L+2 +;BIG_CORE EQU READMEM+2 + + + + DISPLAY "BOOT_BUFFER ",/H,BOOT_BUFFER + DISPLAY "DIR_BUFFER ",/H,DIR_BUFFER + DISPLAY "FatBuffer ",/H,FatBuffer + + ENT + ENDMODULE + OUTEND +;[]-----------------------------------------------------------[] diff --git a/Crazy Estex DSS/BOOT/README.TXT b/Crazy Estex DSS/BOOT/README.TXT new file mode 100644 index 0000000..8d776c3 --- /dev/null +++ b/Crazy Estex DSS/BOOT/README.TXT @@ -0,0 +1,9 @@ +Программа записи на FDD/HDD boot-загрузчика и файлов системы. + +Фитчи программы: + - В отличие от оригинального boot-инсталлятора, эта может + переписывать уже установленный boot-загрузчик. + - Файлы системы (system.dos, system.exe) могут иметь + любые размеры. + - При загрузке компьютера с дискеты, запрашивается новая + дискета для создания из нее загрузочной. diff --git a/Crazy Estex DSS/BOOT/boot.asm b/Crazy Estex DSS/BOOT/boot.asm new file mode 100644 index 0000000..12a388e --- /dev/null +++ b/Crazy Estex DSS/BOOT/boot.asm @@ -0,0 +1,914 @@ +//////////////////////////////////////////////////////////////////////// +; CHANGELOG +; [x] - загрузка с любого primary active раздела +; [x] - поддержка загрузки с FAT32 раздела +; [x] - загрузка с RAM диска +; [x] - bug fixes and optimizations))) +//////////////////////////////////////////////////////////////////////// + +; Программа записи на FDD/HDD boot-загрузчика и файлов системы. +; +; Загружает сист. файлы из корня диска, с которого была +; загружена система. + +; Фитчи программы: +; В отличие от оригинального boot-инсталлятора, эта может +; переписывать уже установленный boot-загрузчик. +; Файлы системы (system.dos, system.exe) могут иметь +; любые размеры. +; При загрузке компьютера с дискеты, запрашивается новая +; дискета для создания из нее загрузочной. +; +; + STRUCT _sysFatBuffer +;.DRIVE: BYTE #FF +.FAT_TYPE: BYTE #00 ; TYPE FAT (12 - 12bit, 16 - 16bit, 32 - 32bit) ; fat32 +.CacheBlock: WORD #0000 +;.CacheUpdated: BYTE #00 +;.SectorsPerBank: BYTE #00 +.RootDirStartCluster_L: WORD #0000 +.RootDirStartCluster_H: WORD #0000 ; fat32 +.FAT1_SEC_L: WORD #0000 ; MSD_FAT_SEC first sector FAT (FAT_FRM) +.FAT1_SEC_H: WORD #0000 ; fat32 +;.FAT2_SEC_L: WORD #0000 +;.FAT2_SEC_H: WORD #0000 ; fat32 +;.Number_Of_FATs BYTE #02 +.SectorsPerFAT_L WORD #0000 +.SectorsPerFAT_H BYTE #00 +.RootDirFirstSector_L: WORD #0000 ; MSD_CAT_SEC first sector DIR +.RootDirFirstSector_H: WORD #0000 ; MSD_CAT_SEC first sector DIR +.DirSizeInSectors: BYTE #00 ; DIR_SEC_SIZE +.FirstDataSector_L: WORD #0000 ; MSD_DAT_SEC low +.FirstDataSector_H: WORD #0000 ; MSD_DAT_SEC high +.BytesPerCluster: WORD #0000 ; CLUSTER_LEN +;.END_CHAIN_CLUSTER_L: WORD #FFFF +;.END_CHAIN_CLUSTER_H: WORD #0FFF +;.MaxClusterLow: WORD #0000 ; макс. число кластеров (без служ.) +;.MaxClusterHigh: WORD #0000 ; макс. число кластеров (без служ.) +;.BytesPerSector: WORD #0000 +.SectorsPerCluster: BYTE #00 +;.FSINFO_Sector: WORD #01 +;.BPB_SERIAL_NUMBER: DWORD #00000000 +;.BPB_LABEL: BLOCK 11,' ' ; 11 для FAT, 31 для CDFS +;.UPD_FSINFO: BYTE 0 +;.FREE_CLUSTERS_COUNT_L: WORD #FFFF +;.FREE_CLUSTERS_COUNT_H: WORD #FFFF +;.FilesPerSector: BYTE #00 ; число файловых записей в секторе +;.ClustersPerBank: BYTE #00 ; A - Clusters per bank (16k) (число кластеров на блок ОЗУ) +;.READ_PG: BYTE #00 ;!TODO не используются некоторые значения, но задумка неплохая))) +;.S_X_H: DWORD #0000 ; количество секторов на цилиндре + ENDS + includelua 'Shared_includes/lua/Functions.lua' + include 'shared_includes/constants/sp2000.inc' + include 'shared_includes/constants/bios_equ.inc' + include 'shared_includes/constants/dss_equ.inc' + include 'shared_includes/macroses/accelerator.z80' + include 'shared_includes/macroses/macros.z80' + include 'shared_includes/structures/FileSystem.inc' + ;include 'DSS/structures.inc' + include '../DSS/defines.inc' + + LUA PASS1 + local date, month, year = Get_date_RU(sj.get_define("__DATE__")) + BuildDate = "'" .. date .. "." .. month .. "." .. year .. "'" + sj.insert_define("SYS_BUILD_DATE", BuildDate) + ENDLUA + LUA ALLPASS + sj.insert_define("SYS_BUILD_DATE", BuildDate) + ENDLUA + + DEFINE EXEinfoMACRO 0 + DEFINE App_EXE_Version 1 + MACRO _mEXEinfo + BLOCK 10,' ' ; Выравнивание для красивого отображения в HEX + BYTE ' Bootloader ' + BYTE ' installer ' + BYTE ' for DSS. ' + BYTE ' Vasil Ivanov, ' + BYTE ' Anatoliy ' + BYTE ' Belyanskiy. ' + BYTE ' Sprinter Team, ' + BYTE ' 2024 ' + ENDM + + +; версия программы +major_version equ 2 ; ст. номер версии +minor_version equ 1 ; мл. номер +;; +SECTORS_OF_LOADER EQU 4 ; секторов загрузчика +.IN_BPB EQU 1 +.AFTER_BPB EQU 3 + +org_addr EQU #8000 + CLP_Buffer +code_addr EQU BEGIN +program_start EQU BEGIN +stack_point EQU #BFFE +Loader_length EQU 0 + +; +page_buffer equ #C000 ; буфер файлов +;; + + include 'Shared_Includes/constants/EXE_Header.z80' + + ORG org_addr +BEGIN: ;di + in a,(SLOT3) + ld (port+1),a ; сохр. порт + push ix + call save_path ; сохр. тек. диск и путь + ld c,Dss.Version ; узнать версию ДОС + RST ToDSS + ex de,hl ; hl=тек. версия + ld de,#0146 ; 1.70.810 d=версия, e=модификация, bc - номер сборки. de = #0146, bc = 810 dos ver 1.70.810 + and a + sbc hl,de + ;[x] 17.12.2023 загрузка с активного раздела, а не с первого + ;jr nc,version_ok + jr z,.check_build ; если номер версии 1.70 + jr nc,version_ok ; если номер версии больше 1.70 + ; +.old_ver: pop hl + ld a,11 ; индекс строки "Error: Need DSS version 1.70..." + call print_string + ld a,-1 + jp exit + ;[x] 17.12.2023 загрузка с активного раздела, а не с первого +.check_build: ld hl,810 ; 1.70.810 d=версия, e=модификация, bc - номер сборки. de = #0146, bc = 810 dos ver 1.70.810 + sbc hl,bc + jr nc,BEGIN.old_ver + ; +version_ok: xor a ; индекс строки титла + call print_string + pop hl ; ком-строка + ; выделить параметр ком-строки + call get_drive_letter + jp c,help ; нет параметров + ld (disk),a ; заданный номер диска + ; узнать номер boot-диска системы + ld bc,Dss.BootDSK.Get + RST ToDSS + ld (boot_disk),a ; диск (A=0,B=1,..) + ; проверить на совпадение дисков + ld hl,disk + cp (hl) + jr nz,.next + ld hl,confirm_flag + ld (hl),1 ; уст. флаг + ; + ; Чтение в банки файлов системы + ; +.next: ld a,(boot_disk) ; диск загрузки ОС + ld hl,root_path ; "X:\" корень диска + add a,'A' + ld (hl),a + ld c,Dss.ChDir ; смена каталога + RST ToDSS + ;-------------------------------------------- + ; Чтение файла system.exe + ;-------------------------------------------- + ld hl,name2 ; имя файла + call read_file ; вся работа по загрузке файла в страницы + ;jr nc,read_file1_ok + ; освоб. блок памяти +;read_file_err: ld a,(FILE1_PARAMS.id_blck) ; идентиф. блока памяти +; ld c,Dss.FreeMem +; RST ToDSS + ;ld a,DSS_Error.sys.DISK_FULL ; код ошибки + jp c,exit + ; сохр. раб. ячейки файла system.exe +read_file1_ok: ld hl,FILE1_PARAMS ; откуда + ld de,FILE2_PARAMS ; куда + ld bc,FILE2_PARAMS.dataSize + ldir + ;-------------------------------------------- + ; Чтение файла system.dos + ;-------------------------------------------- + ld hl,name1 ; имя файла + call read_file ; вся работа по загрузке файла в страницы + ;jr c,read_file_err + ;ld a,DSS_Error.sys.DISK_FULL; код ошибки + jp c,exit + ;jr nc,read_file2_ok + ; освоб. блок памяти system.exe +; file_err1: ld a,(FILE2_PARAMS.id_blck); идентиф. блока памяти +; ld c,Dss.FreeMem +; RST ToDSS + ;jr read_file_err ; освоб. блок памяти system.dos +confirm_flag+1: ld a,0 + or a + jr z,no_confirm + ld a,(boot_disk) ; сист. диск + cp 2 + jr nc,no_confirm ; не дисководы + ; запросить целевой диск + ld a,(disk) ; заданный номер диска + add a,'A' + ld (messages.lett2),a + ld a,5 ; индекс строки "Insert destination disk..." + call print_string + ld bc,Dss.K_CLEAR + Dss.WaitKey*256; ждем нажатия клавиши + RST ToDSS +no_confirm: ld a,2 ; индекс строки "Installing boot loader..." + call print_string + ; Уст. целевой диск/путь + ld a,(disk) ; целевой диск + ld hl,root_path ; "X:\" строка пути + add a,'A' + ld (hl),a + ld c,Dss.ChDir ; смена тек. каталога + RST ToDSS + ;-------------------------------------------- + ; Записать boot-загрузчик + call write_boot_loader + jr c,write_error ; ошибка работы с девайсом + ; + ld a,3 ; индекс строки "Writing system files..." + call print_string + ; Запись файла system.dos + ld hl,name1 ; имя файла + call write_file + jr c,write_error +ok_write1: ; освободить память + ; ld a,(FILE1_PARAMS.id_blck) ; блок system.dos + ; ld c,Dss.FreeMem + ; RST ToDSS + ; + ; загр. раб. ячейки + ld hl,FILE2_PARAMS ; откуда + ld de,FILE1_PARAMS ; куда + ld bc,FILE1_PARAMS.dataSize + ldir + ; Запись файла system.exe + ld hl,name2 ; имя файла + call write_file + ; освободить память + ; push af + ; ld a,(FILE1_PARAMS.id_blck) ; блок system.exe + ; ld c,Dss.FreeMem + ; RST ToDSS + ; pop af + ; + jr c,write_error + ;jr c,exit ; ошибка + ; + ld a,(disk) ; заданный номер диска + add a,'A' + ld (messages.lett1),a + ld a,1 ; индекс строки "System installed on disk " + call print_string + ld a,(confirm_flag) + or a + jr z,exit + ; запросить системный диск + ld a,(boot_disk) ; сист. диск + cp 2 + jr nc,.not_fdd ; не дисководы + add a,'A' + ld (messages.lett3),a + ld a,6 ; индекс строки "Insert system disk..." + call print_string + ld bc,Dss.K_CLEAR + Dss.WaitKey*256; ждем нажатия клавиши + RST ToDSS +.not_fdd: xor a ; код "Ok" +exit: push af + call restore_path ; восст. тек. диск и путь +port: ld a,-1 ; сохр. порт + out (SLOT3),a + pop af + ld c,Dss.Exit ; выход в ДОС + ld b,a + RST ToDSS + jr $ + ; +help: ld a,8 ; индекс строки "Invalid drive specification" + call print_string + ld a,4 ; индекс строки хэлпа +err_mes: call print_string + ld a,1 ; код ошибки + jr exit + +write_error: ld a,7 ; индекс строки "Can't install boot on this disk" + jr err_mes + + + + +root_path: db 'X:\',0 ; путь + +name1: db "SYSTEM.DOS",0 +name2: db "SYSTEM.EXE",0 + + + +;------------------------------------------------- +; Записать boot-загрузчик на FDD/HDD +; вход: нет +; выход: CF - ошибка работы с девайсом +;------------------------------------------------- +write_boot_loader: + ld a,(disk) ; заданный номер диска + ld c,Dss.DRV.Open ; open device + rst ToDSS.DRV + ret c + ld hl,close_device ; точка выхода + push hl + ld a,(disk) ; заданный номер диска + ld hl,0 ; ст. разряд лог. сектора + ld ix,0 ; мл. разряд + ld de,buffer ; куда + ld bc,1*256 + Dss.DRV.Read ; прочитать 1 сектор (boot) + rst ToDSS.DRV + ret c ; ошибка чтения + ld a,(buffer + _sBOOT_SECTOR_PARAMS.DRIVE_TYPE) + cp #F0 ; 1.44Mb + ret c ; незнакомый формат + jr z,write_to_floppy + cp #F9 ; 720kB + jr z,write_to_floppy + cp #FA ; RAM disk + jr z,write_to_ram_disk + cp #F8 ; винт + jp z,write_to_hard_disk + scf ; незнакомый формат + ret + +; закрыть девайс +close_device: push af ; сохр. флаг + ld a,(disk) ; заданный номер диска + ld c,Dss.DRV.Close ; close device + rst ToDSS.DRV + pop af + ret + + +;------------------------------------------------- +; Запись boot-загрузчика на дискету +; +; вход: данные из buffer +; выход: CF - при ошибке записи +;------------------------------------------------- +write_to_floppy: + ld a,(buffer + BOOT_SECTOR.Number_of_FATs) ; число копий FAT-ов + or a + scf + ret z ; ошибка + dec a ; --число копий + jr z,overwrite_floppy ; загрузчик уже записан, перезаписать его + ; настроить ячейки boot-сектора + ld (buffer + BOOT_SECTOR.Number_of_FATs),a ; число копий FAT-ов + ld hl,(buffer + BOOT_SECTOR.RESERVED_SECTORS) ; зарезерв. секторов + ld bc,(buffer + BOOT_SECTOR.SectorsPerFAT16) ; секторов на FAT + add hl,bc + ld (buffer + BOOT_SECTOR.RESERVED_SECTORS),hl ; зарезерв. секторов + dec hl + ld de,SECTORS_OF_LOADER.AFTER_BPB + and a + sbc hl,de + ret c +overwrite_floppy: + ; перекидывание части загрузчика в 0 сектор + LD HL,DSS_Boot_Loader.ZERO_SECTOR_OF_BPB.physical + LD DE,buffer + (_sBOOT_SECTOR.PARTITION_TABLE - DSS_Boot_Loader.ZERO_SECTOR_OF_BPB.Size) + LD BC,DSS_Boot_Loader.ZERO_SECTOR_OF_BPB.Size + LDIR + ; + ; записать boot-сектор назад + ld a,(disk) ; заданный номер диска + ld hl,0 ; ст. разряд лог. сектора + ld ix,0 ; мл. разряд + ld de,buffer ; откуда + ld bc,1*256 + Dss.DRV.Write ; записать 1 сектор + rst ToDSS.DRV + ret c ; ошибка записи + ; записать загрузчик + ld a,(disk) ; заданный номер диска + ld hl,0 ; ст. разряд лог. сектора + ld ix,1 ; мл. разряд + ld de,code_loader ; откуда (код загрузчика) + ld bc,SECTORS_OF_LOADER.AFTER_BPB*256+Dss.DRV.Write; записать 3 сектора (размер загр.) + rst ToDSS.DRV + ret + + +;------------------------------------------------- +; Запись boot-загрузчика на драйв +; +; вход: нет +; выход: CF-ошибка записи +;------------------------------------------------- +write_to_ram_disk: + CALL write_no_BPB + RET C + ; buffer = sector 0 + ; + JR write_to_BPB + +write_to_hard_disk: + ;[x] 17.12.2023 загрузка с активного раздела, а не с первого + CALL write_no_BPB + RET C + ; buffer = sector 0 + ; + ; проверка на РАМ-диск (разделы на рамдиске пока не поддерживаются) + LD A,B + CP #80-1 ;!HARDCODE HDD number + JR C,write_to_BPB + ; + PUSH BC + CALL Read_MBR + RET NZ + POP BC + PUSH BC + ; set active in buffer + INC C + LD HL,buffer + _sBOOT_SECTOR.PARTITION_TABLE.Record_4 + LD DE,_sMBR_PARTITION_RECORD ; размер одной записи MBR + LD B,_sMBR_PARTITION_TABLE / _sMBR_PARTITION_RECORD; MBR: Number of entries in the partition table +.loop: XOR A + LD (HL),A + ; + LD A,C + CP B + JR NZ,.next + ; + LD A,#80 + LD (HL),A + PUSH HL + INC HL + INC HL + INC HL + INC HL + LD A,(HL) + POP HL + CP PartitionSysTypes.FAT12 + JR Z,.next + CP PartitionSysTypes.FAT16_32Mb + JR Z,.next + CP PartitionSysTypes.FAT16 + JR Z,.next + CP PartitionSysTypes.FAT16_LBA + JR Z,.next + CP PartitionSysTypes.FAT32 + JR Z,.next + CP PartitionSysTypes.FAT32_LBA + JR Z,.next + ; NOT SUPPORTED FS + POP BC + SCF + RET + ; +.next: AND A + SBC HL,DE + DJNZ .loop + ; + JR write_to_BPB.no_push +write_to_BPB: PUSH BC + ; перекидывание части загрузчика в 0 сектор +.no_push: LD HL,DSS_Boot_Loader.ZERO_SECTOR_OF_BPB.physical + LD DE,buffer + (_sBOOT_SECTOR.PARTITION_TABLE - DSS_Boot_Loader.ZERO_SECTOR_OF_BPB.Size) + LD BC,DSS_Boot_Loader.ZERO_SECTOR_OF_BPB.Size + LDIR + ; запись в 0 сектор куска загрузчика + pop af ; заданный номер диска + ld hl,0 ; ст. разряд лог. сектора + ld ix,0 ; мл. разряд + ld de,buffer ; откуда (код загрузчика) + ld bc,1*256 + BIOS.DRV_WRITE ; записать 1 сектор + RST ToBIOS + RET + ; + +; +write_no_BPB: ld a,(disk) ; номер заданного диска + ld de,Dss.DRV.GenIOCTL.Enter + ld bc,Dss.DRV.GenIOCTL.GetParams + rst ToDSS.DRV + ex af,af' + ;[x] 17.12.2023 загрузка с активного раздела, а не с первого + ld b,a + inc c + scf + ret z + dec c + CP #80 ;!HARDCODE тип драйва - HDD + JR NC,.skip_FAT_check + PUSH BC + ; B - PHISICAL DRIVE NUMBER, C - PARTITION RECORD NUMBER IN DRIVE MBR + ; A - PHISICAL DRIVE NUMBER + ; [x] 02/02/2024 проверка на влезаемость загрузчика (чтоб не попортить фат) + CALL Read_MBR + RET NZ + POP BC + LD HL,(buffer + _sBOOT_SECTOR_PARAMS.RESERVED_SECTORS) + ; минимальное расстояние на драйве от нулевого сектора до фата (длина загрузчика + 1) + LD DE,SECTORS_OF_LOADER.AFTER_BPB + 1 + AND A + SBC HL,DE + RET C + ; +.skip_FAT_check:; + push bc + ld a,b + ld hl,0 ; ст. разряд лог. сектора + ld ix,1 ; мл. разряд + ld de,code_loader ; откуда (код загрузчика) + ld bc,SECTORS_OF_LOADER.AFTER_BPB*256+BIOS.DRV_WRITE; записать 3 сектора (размер загр.) + rst ToBIOS + ;[x] 17.12.2023 загрузка с активного раздела, а не с первого + pop bc + ; + ret + + +; in: a - drive +; out CF = 1. +; ZF = 1 - OK, +; ZF = 0 - error +Read_MBR: LD HL,0 + LD IX,0 + LD DE,buffer + LD BC,1*256 + BIOS.DRV_READ + RST ToBIOS + LD HL,(buffer + _sBOOT_SECTOR.MBR_SIGNATURE) + LD DE,#AA55 + AND A + SBC HL,DE + SCF + RET +;------------------------------------------------- +; Выделить заданный диск из ком-строки +; +; вход: hl=буфер строки +; выход: a=номер диска +; CF-при ошибке +;------------------------------------------------- +get_drive_letter: + inc hl ; буфер строки + ld de,buffer ; буфер для выдел. параметра + ld c,Dss.GSwitch ; выделить параметр ком. строки + RST ToDSS + ld de,buffer + ld a,(de) + inc de + ld c,a ; сохр. 'a' + ld a,(de) + inc de + cp ':' + jr nz,get_drive_err ; диск не задан + ld a,(de) + inc de + or a + jr nz,get_drive_err ; > 1 параметра + ld a,c ; восст. 'a' + cp 'A' + jr c,get_drive_err + cp 'z'+1 + jr nc,get_drive_err + and %1101'1111 + sub 'A' + or a + ret + ; +get_drive_err: scf ; ошибка + ret + +;---------------------------------------------------- +; сохр. тек. системный диск и путь +;---------------------------------------------------- +save_path: ld c,Dss.CurDisk ; узнать диск + RST ToDSS + ld (sys_disk),a + ld hl,sys_path + ld c,Dss.CurDir ; узнать путь + RST ToDSS + ret + + +;---------------------------------------------------- +; восст. тек. системный диск и путь +;---------------------------------------------------- +restore_path: ld a,(sys_disk) + ld c,Dss.ChDisk ; смена диска + RST ToDSS + ld hl,sys_path + ld c,Dss.ChDir ; смена пути + RST ToDSS + ret +; + +; +disk: db 0 ; номер заданного диска +boot_disk: db 0 ; номер boot-диска системы + +; раб. ячейки тек. файла +; +; чтение: system.exe, далее system.dos +; запись: system.dos, далее system.exe +FILE1_PARAMS: +.handle: db -1 ; дескриптор файла +.id_blck: db -1 ; идентиф. выдел. блока памяти + ; +.sizeLow: dw 0 ; мл.разряд размера файла +.sizeHigh: dw 0 ; ст.разряд +.dataSize EQU $-FILE1_PARAMS + +; сохр. данные system.exe +FILE2_PARAMS: +.handle: db -1 ; дескриптор файла +.id_blck: db -1 ; идентиф. выдел. блока памяти + ; +.sizeLow: dw 0 ; мл.разряд размера файла +.sizeHigh: dw 0 ; ст.разряд +.dataSize EQU $-FILE2_PARAMS + + ASSERT FILE1_PARAMS.dataSize = FILE2_PARAMS.dataSize, "Erorr! FILE1_PARAMS != FILE2_PARAMS" +; +; +; +; +; +; сообщения +messages: db 0 + db "\r\nBoot and System files Installer v" ;0 + db major_version + '0','.' + db (minor_version / 10) + '0',(minor_version % 10) + '0','.' + db "\r\nBuild date ",SYS_BUILD_DATE + db "\r\nCopyright (c) 2006 Vasil Ivanov." + db "\r\nCopyright (c) 2023-2024 Sprinter Team." + db "\r\n\n",0 + ; + db "System successfully installed on disk " ;1 +.lett1: db "X:\r\n\n",0 + ; + db "Installing boot loader...\r\n\n",0 ;2 + db "Writing system files...\r\n\n",0 ;3 + ; + db "Syntax: SYS X:\r\n" ;4 + db " where X: - drive letter (A..Z)\r\n\n",0 + ; + db "Insert destination disk in drive " ;5 +.lett2: db "X:\r\n" + db "and strike any key when ready ...\r\n\n",0 + ; + db "Insert system disk in drive " ;6 +.lett3: db "X:\r\n" + db "and strike any key when ready ...\r\n\n",0 + ; + db "Can't install boot on this disk\r\n\n",0 ;7 + db "Invalid drive specification\r\n\n",0 ;8 + db " Error: Can't open file\r\n\n",0 ;9 + db " Error: Can't allocate memory\r\n\n",0 ;10 + db " Error: Need DOS version 1.70.811 or higher\r\n\n",0 ;11 + db " Error: Reading error\r\n\n",0 ;12 + db " Error: Can't create file\r\n\n",0 ;13 + db " Error: Writing error\r\n\n",0 ;14 +.endmess: db 0 + + + +; Вывести строку по индексу +; вход: a=индекс строки +print_string: call get_string ; поиск строки по ее индексу в 'a' + ld c,Dss.PChars ; вывод строки + RST ToDSS + ret + + +; поиск строки по ее индексу в 'a' +get_string: ld hl,messages ; список мессаг для индекс. доступа + ld bc,messages.endmess - messages ; размер списка + inc a + ex af,af' + xor a + ex af,af' +get_loop: ex af,af' + cpir + ret po + ret nz + ex af,af' + dec a + jr nz,get_loop + ret + + + + + +;==================================================== +; Вся работа по загрузке файла в страницы +; вход: hl=имя файла +; выход: CF-при ошибке +;==================================================== +read_file: ld a,Dss.Open.R ; на чтение + ld c,Dss.Open ; открыть файл + RST ToDSS + jr nc,.ok ; без ошибок + ; + push af + ld a,9 ; индекс "Can't open file" + call print_string + pop af + ret + ; +.ok: ld (FILE1_PARAMS.handle),a ; дескр. файла + ld hl,0 + ld ix,0 + ld bc,Dss.Move_FP.FrEnd ; указатель на конец файла + RST ToDSS + ld (FILE1_PARAMS.sizeHigh),hl ; ст.разряд размера файла + ld (FILE1_PARAMS.sizeLow),ix ; мл.разряд + call get_memory ; расч. и выдел. страницы под файл + jr c,.not_enough ; не хватает памяти + call file_to_bank ; загр. файл в страницы +.close_file: push af + ld a,(FILE1_PARAMS.handle) ; дескр. файла + ld c,Dss.Close ; закрыть файл + RST ToDSS + pop af + ret + ; +.not_enough: push af + call .close_file + ld a,10 ; индекс "Can't allocate memory" + call print_string + pop af + or a + scf + ret nz + ld a,DSS_Error.sys.NOT_ENOUGH_MEMORY + ret + + + +;---------------------------------------------------- +; По размеру файла рассчитать необходимое +; число страниц и выделить их. +; Выход: CF - при нехватке памяти +;---------------------------------------------------- +get_memory: ld hl,(FILE1_PARAMS.sizeHigh) ; ст.разряд размера файла + ld bc,(FILE1_PARAMS.sizeLow) ; мл.разряд + ld de,#4000 ; делитель (размер страницы) + xor a + scf +malloc1: rr d + rr e + jr c,malloc2 + rr h + rr l + rr b + rr c + jr nc,malloc1 + ld a,1 + jr malloc1 + ; +malloc2: or a + jr z,$+3 ;!FIXIT $ + inc bc + xor a + cp b + scf + ret nz + ; выделить блок памяти + ld b,c ; b=число страниц + ld c,Dss.GetMem + RST ToDSS + ld (FILE1_PARAMS.id_blck),a ; идентиф. блока + ret + + +;---------------------------------------------------- +; Загрузить файл в страницы +;---------------------------------------------------- +file_to_bank: ld hl,0 + ld ix,0 + ld a,(FILE1_PARAMS.handle) ; дескр. файла + ld bc,Dss.Move_FP.FrStart ; указатель на начало файла + RST ToDSS + ld a,(FILE1_PARAMS.id_blck) ; идентиф. блока памяти + ;ld b,0 ; лог. номер страницы в блоке + ld bc,0*256 + BIOS.GetMemPage; получить физ. номер страницы в блоке + rst ToBIOS + ret c +.loop: push af + out (SLOT3),a + ld hl,page_buffer ; #C000 куда + ld de,#4000 ; сколько + ld a,(FILE1_PARAMS.handle) ; дескр. файла + ld c,Dss.Read ; читать файл + RST ToDSS + pop bc + jr c,.error + ; ok + cp -1 ; прочитано меньшее число байт ? + ret z ; да + ld a,b ; a=физич. страница + ld c,BIOS.GetMemPageNext ; получить номер след. физ. страницы блока + rst ToBIOS + ret c + cp #FF + jr nz,.loop ; не последняя страница + ret + ; error +.error: ld a,12 ; индекс "Reading error" + call print_string + scf + ret + + +;==================================================== +; Запись файла на диск +; вход: hl=имя файла +; выход: CF-при ошибке +;==================================================== +write_file: ld a,FAT_ATTR.ARCHIVE ; атрибут "архивный" + ld c,Dss.Create ; создать файл + RST ToDSS + jr nc,.create_ok ; без ошибок + push af + ld a,13 ; индекс "Can't create file" + call print_string + pop af + ret + ; +.create_ok: ld (FILE1_PARAMS.handle),a ; дескр. файла + ld hl,read_file.close_file ; закр. файл + push hl ; точка выхода + ; + ; чтение файла из банок и запись на диск + ld a,(FILE1_PARAMS.id_blck); идентиф. блока памяти + ;ld b,0 ; лог. номер страницы в блоке + ld bc,BIOS.GetMemPage ; получить физ. номер страницы в блоке + rst ToBIOS + ret c +.loop: push af + out (SLOT3),a + ld hl,(FILE1_PARAMS.sizeLow) ; мл.разряд размера файла + ld de,(FILE1_PARAMS.sizeHigh) ; ст.разряд + ld bc,#4000 + xor a + sbc hl,bc + ld b,a + ex de,hl + sbc hl,bc + ex de,hl + jr c,.write_end ; записать остаток + ld (FILE1_PARAMS.sizeLow),hl + ld (FILE1_PARAMS.sizeHigh),de + ; + ld hl,page_buffer ; #C000 откуда + ld de,#4000 ; сколько + ld a,(FILE1_PARAMS.handle) ; дескр. файла + ld c,Dss.Write ; запись файла + RST ToDSS + pop bc + jr c,.error + ; write_ok + ; [ ] Fixed 24/06/2024 какой-то пережиток прошлого + ;cp -1 ; записано меньшее число байт ? + ;ld a,DSS_Error.sys.DISK_FULL + ;scf + ;jr nz,.error ; да, на диске нет места + ; + ld a,b ; a=физич. страница + ld c,BIOS.GetMemPageNext ; получить номер след. физ. страницы блока + rst ToBIOS + ret c + cp #FF + jr nz,.loop ; не последняя страница + ret + ; +.write_end: pop af ; баланс стека + ld de,(FILE1_PARAMS.sizeLow) ; сколько + ld a,e + or d + ret z ; 0 байтов + ld hl,page_buffer ; #C000 откуда + ld a,(FILE1_PARAMS.handle) ; дескр. файла + ld c,Dss.Write ; запись файла + RST ToDSS + ret nc + ; +.error: push af + ld a,14 ; индекс "Writing error" + call print_string + pop af + ret + + + +; ДОС-загрузчик +code_loader: include 'dssboot.asm' ; универсальный загрузчик для старого и нового доса +code_loader.size EQU $-code_loader + ASSERT SECTORS_OF_LOADER*512 >= (code_loader.size), "incorrect value of the SECTORS_OF_LOADER variable" + + + DISPLAY " dssboot size: ", /D,code_loader.size, " bytes. Sectors: ",/D,(code_loader.size/512 + (code_loader.size mod 512)/(code_loader.size mod 512)) + + +; 512 байт, буфер boot-сектора +buffer equ $ +sys_disk equ buffer+512 ; диск системы +sys_path equ sys_disk+1 ; путь системы + diff --git a/Crazy Estex DSS/DSS/API.asm b/Crazy Estex DSS/DSS/API.asm new file mode 100644 index 0000000..bded5af --- /dev/null +++ b/Crazy Estex DSS/DSS/API.asm @@ -0,0 +1,195 @@ + +;[BEGIN] +;//MODULE: DOS_X +;//CREATE: 19-05-1998 AUTHOR: Denis Parinov +;//UPDATE: 24-10-1999 DNS Restore module +;--------------------------------------------------------------- +;Rev Date Name Description +;--------------------------------------------------------------- +;R011 17-04-2023 BAO Временный костыль для недопускания переполнения буфера пути каталога +;R010 15-04-2023 BAO FIXED BUG WITH CHANGE DISK WITHOUT CHANGE PATH +;R009 13-04-2023 BAO FIX BUG WITH PARSING DIRECTORY BUFFER +;R13 06-04-2023 BAO Функцию SETBOOT можно вызвать только раз (если завершится корректно) +;R12 03-04-2023 BAO Добавлена функция рескана драйвов LD C,8 : RST #10 +;R008 - 15-04-2003 DNS SAVE AND RESTORE CUR-PATH MACROS +;R11 - 15-04-2003 DNS ROUTINE FOR STORE CURDISK AND CURDIR +;R10 - 03-04-2003 DNS IMPROVED FN. VERSION +;R09 27-03-2003 DNS PASTED SET/GET BOOT FN. +;R007 06-02-2003 DNS FIX BUG IN MASK ROUTINE, IT ALLOW NAMES WHICH BEGAN FROM "." ".NAM" +;R006 29-01-2003 DNS FIX BUG WITH SET FILE DATE AND TIME +;R005 26-11-2002 DNS FIX ERROR IN CHDIR, DON'T ALLOWED "." FOR ROOT +;R004 19-11-2002 DNS DON'T ALLOW DIR & LABEL ATTR FOR FILES +;R003 19-11-2002 DNS ADD RESET OF VOLUME LABEL ATTRIBUT +;R002 19-11-2002 DNS FIX GET/SET ATTRIBUTES +;R001 16-12-1999 DNS Y2K fix +;R06 21-11-1999 DNS FN. DISKINF SUPPORT ALL DISKS +;R05 21-11-1999 DNS BUG FIX SIGNATURE #55AA IN BOOT SECTOR +;R04 08-11-1999 DNS KILL OLD FUNCTIONS +;R03 23-11-1998 DNS BUG FIX (IX+28) -> (IY+28) +;R02 21-11-1998 DNS CHANGE FUNCTION "MAKE FAT" +;R01 20-11-1998 DNS REPAIR FUNCTION "SAVE" + +; +;--------------------------------------------------------------- + + include 'API/Version.asm' + include 'API/bootDsk.asm' + include 'API/curDisk.asm' + include 'API/diskINF.asm' + include 'API/ScanDRV.asm' + include 'API/Attribute.asm' + include 'API/Create.asm' + include 'API/Delete.asm' + include 'API/Rename.asm' + include 'API/Open.asm' + include 'API/Close.asm' + include 'API/Find.asm' + include 'API/ChnDisk.asm' + include 'API/CurrDir.asm' + include 'API/Time.asm' + include 'API/GetDateTime.asm' + include 'API/SetDateTime.asm' + include 'API/ChDir.asm' + include 'API/MkDir.asm' + include 'API/RmDir.asm' + include 'API/DosName.asm' + include 'API/Read.asm' + include 'API/Write.asm' + include 'API/FreeMem.asm' + include 'API/GetMem.asm' + include 'API/RetMem.asm' + include 'API/SetMem.asm' + include 'API/SetWin.asm' + include 'API/AppInfo.asm' + include 'API/Ex_Path.asm' + include 'API/GSwitch.asm' + include 'API/Environ.ASM' + include 'API/Lib_Sub.asm' + include "API/EXECUTE.ASM" + include "API/Print.asm" + + + + +;R09 + ;Дубль - CHNDISK = OPENDSK + ;CHNDISK: + ; PUSH AF + ; LD C,Dss.DRV.Open + ; RST ToDSS.DRV + ; POP BC + ; JP C,NDISK11 + ; LD A,B + ; LD (CORE_BUFFERS.FatBuffer.DRIVE),A + ; CALL RD_BPB + ; RET C + ; LD A,(LDRIVE) + ; AND A + ; RET + ;NDISK11: + ; CP DSS_Error.sys.INVALID_DRIVE + ; SCF + ; RET Z + ; LD A,DSS_Error.sys.NOT_READY + ; RET +; + + +;R04 + ;SIZE2CL: LD DE,(B_P_C) + ; XOR A + ; SCF + ;S2C01: RR D + ; RR E + ; JR C,S2C02 + ; RR H + ; RR L + ; RR B + ; RR C + ; JP NC,S2C01 + ; LD A,1 + ; JP S2C01 + ;S2C02: OR A + ; RET Z + ; INC BC + ; RET + ;L_SEC_X: DW 0 + ;H_SEC_X: DW 0 +; + + +;GOD EQU 1999-1980*512 + +;FHAND DB " " +; DB " " +; DB #20 +; DW 0,0,0,0,0 +; DW #0000 +; DW 5*32+19+GOD +;SAVEC DW #0000 +;SIZEC DW #0000,#0000 +;============================================= +;//MODULE: DOS_X +;[END] + +;R11 + ; IF SAVE_PATH_MACRO + ; SAVE_CUR_PATH + ; PUSH IX + ; PUSH IY + ; PUSH HL + ; PUSH DE + ; PUSH BC + ; PUSH AF + ; + ; SET_PAGE_X ENVPAGE + ; PUSH AF + ; + ; CALL CURRDSK + ; ADD A,"A" + ; LD HL,TMP_CURDIR_AUTO + ; LD (HL),A + ; INC HL + ; LD A,":" + ; LD (HL),A + ; INC HL + ; CALL CURRDIR_FN + ; + ; POP AF + ; OUT (SLOT3),A + ; + ; POP AF + ; POP BC + ; POP DE + ; POP HL + ; POP IY + ; POP IX + ; RET + ; + ; BACK_CUR_PATH: + ; RET NC + ; .force: PUSH IY + ; PUSH IX + ; PUSH HL + ; PUSH DE + ; PUSH BC + ; PUSH AF + ; + ; SET_PAGE_X ENVPAGE + ; PUSH AF + ; + ; LD HL,TMP_CURDIR_AUTO + ; CALL CHDIR + ; + ; POP AF + ; OUT (SLOT3),A + ; + ; POP AF + ; POP BC + ; POP DE + ; POP HL + ; POP IX + ; POP IY + ; RET + ; ENDIF +; \ No newline at end of file diff --git a/Crazy Estex DSS/DSS/API/AppInfo.asm b/Crazy Estex DSS/DSS/API/AppInfo.asm new file mode 100644 index 0000000..a783749 --- /dev/null +++ b/Crazy Estex DSS/DSS/API/AppInfo.asm @@ -0,0 +1,101 @@ +;--------------------------------------------------------------- +;Rev Date Name Description +;--------------------------------------------------------------- +;R10 13-04-2023 BAO FIX BUG WITH PARSING DIRECTORY BUFFER + +////////////////////////////////////////////////////////////////////// +; !FIXIT тут одни затупы и дебилизм +; Функция #47. Получение информации приложения. +; +; вход: HL - буфер данных +; B - номер подфункции: +; B=0 - получение параметров командной строки +; B=1 - получение полного пути к каталогу программы +; B=2 - получение полного пути и имени файла программы +; выход: нет +; +; APPLICATION INFO +;==================== +; B = 0 - GET APP_PARAM +; B = 1 - GET APP_PATH +; B = 2 - GET APP_FULLNAME +////////////////////////////////////////////////////////////////////// +;LAST_PSP_PTR: DW 0 +APPINFO: INC B + ; + DJNZ .FN1 + ; получение параметров командной строки EX DE,HL + XOR A + LD (DE),A + LD HL,(.LAST_PSP_PTR) + LD C,(HL) + INC C + RET Z + INC HL + LDIR + AND A + RET + +.FN1: DJNZ .FN2 + ; получение полного пути к каталогу программы + EX DE,HL +.LAST_PSP_PTR+1: + LD HL,0 + LD C,(HL) + INC HL + ADD HL,BC + INC HL + INC HL + PUSH HL + LD BC,#100 ;!HARDCODE длина коммандной строки + XOR A + CPIR + DEC HL ;R10 ;[x] исправлен баг с парсингом буфера каталога + DEC HL ;R10,5 - не тестил ;!!!!! + LD BC,#100 ;R10 ;[x] не было этой команды, CPDR мог не прошерстить всё ;!HARDCODE длина коммандной строки + LD A,'\' + CPDR + INC HL + INC HL + POP BC + AND A + SBC HL,BC + ;R10 ;[x] могло всё в космос улететь + LD A,DSS_Error.sys.COMMON_ERROR + JR C,.error + ; + LD A,B ;EX HL,A,BC + LD B,H + LD H,A + LD A,C + LD C,L + LD L,A + LDIR + XOR A + LD (DE),A + RET + ; +.FN2: DJNZ .FN3 + ; получение полного пути и имени файла + EX DE,HL + LD HL,(.LAST_PSP_PTR) + LD C,(HL) + INC HL + ADD HL,BC + INC HL + INC HL + ; +.loop LD A,(HL) + LDI + OR A + JR NZ,.loop + ; + RET + ; +.FN3: + ; + ; ошибка + LD A,DSS_Error.sys.INVALID_FUNCTION +.error: SCF + RET +; \ No newline at end of file diff --git a/Crazy Estex DSS/DSS/API/Attribute.asm b/Crazy Estex DSS/DSS/API/Attribute.asm new file mode 100644 index 0000000..8f07db9 --- /dev/null +++ b/Crazy Estex DSS/DSS/API/Attribute.asm @@ -0,0 +1,102 @@ +//////////////////////////////////////////////////////////////////////// +; INPUT: HL - "C:\DIR1\DIR2\filename.ext",#00 +; A - ATTRIB +; B - MODE +; B = #00 GET ATTRIB +; B = #01 SET ATTRIB +; OUTPUT: A - ATTRIB +//////////////////////////////////////////////////////////////////////// +ATTRIB: ;!TEST Current Dir ;[x] 15/10/23 + LD C,A + ; + IF OLD_DSS_FOR_OLD_EXE + ; [ ] 10/06/24 + LD A,(EXE_VERSION) + OR A + JR Z,.old_EXE + ; + ENDIF + ; + PUSH HL + PUSH BC + CALL DIR_PATH_CHECK + POP BC + POP HL + RET C +.old_EXE: LD A,C + ; + ; + INC B + DJNZ .B_1 + ; B = 0 +.READ: ;!TEST ;[x] 16/11/23 optimize get attribute + ;XOR A + ; + CALL .OPENATR ;R002 + RET C + ;!TEST ;[x] 16/11/23 optimize get attribute + LD A,(HANDBUF + FAT_DIRECTORY_RECORD.ATTRIBUT) + ;LD B,(IY+_sFM.ATTRIBUT) + ;PUSH BC + ;CALL CLOSE + ;POP BC + ;RET C + ;LD A,B + ; + RET + ; +.B_1: DJNZ .B_2 + ; +.WRITE_FN: AND FAT_ATTR.NoVolID ; [x] 2/12/23 фикс для volume ID +.WRITE: PUSH AF + XOR A + ;!TEST ;[x] 16/11/23 optimize get attribute + LD (OPEN_FN.TMP),A + ; + CALL .OPENATR ;R002 + ;!TEST ;[x] 16/11/23 optimize get attribute + CALL NC,OPEN_FN.FM + ; + POP BC + RET C + SET 7,(IY+_sFM.ACCESS_MODE) + ;RES 3,B ;CLEAR LABEL ATTR ;R003 + LD (IY+_sFM.FS_REC.ATTRIBUT),B + PUSH BC + CALL CLOSE_FN +.error: POP BC + RET C + LD A,B + RET + ;R002 +; выход: если CF = 0, то DE = record index +;!TEST 9/11/23 record index +.OPENATR: ;!TEST ;[x] 16/11/23 optimize get attribute + ;LD (OPEN.TMP),A ; раб. ячейка (здесь атрибут записи) + ; + CALL GETWORD ; тест на допуст. имя и настр. на диск + RET C + ; [ ] 26/06/2024 + CALL CHECK_64kb_CLUSTER + RET C + ; + CALL MASK + RET C + LD A,FAT_ATTR.NoVolID + ;!TEST ;[x] 16/11/23 optimize get attribute + JP SEARCH.Custom + ;CALL SEARCH.Custom + ;RET C ; запись не найдена + ;JP OPEN.FM ; на поиск своб. дескриптора + ; + ; + ; [ ] ; !TODO для команды LABEL в Shell + ; 1. проверить что в HL указана только метка в кавычках + ; 2. если метка без недопустимых символов, то делаем её не + ; только в BPB, но и на корневом разделе, иначе удаляем на корневом + ; 3. открываем требуемый диск через .force, чтоб сбросить кэши +.B_2: DJNZ .error_fn + ; +.error_fn: LD A,DSS_Error.sys.INVALID_FUNCTION + SCF + RET \ No newline at end of file diff --git a/Crazy Estex DSS/DSS/API/BootDsk.asm b/Crazy Estex DSS/DSS/API/BootDsk.asm new file mode 100644 index 0000000..0361015 --- /dev/null +++ b/Crazy Estex DSS/DSS/API/BootDsk.asm @@ -0,0 +1,73 @@ +;///////////////////////////////////////////////////////////////////// +; Функция #09. Номер системного диска. +; Возвращает номер диска, c которого загружена система. +; +; При B = 0 (GET) +; выход: A - номер системного диска (0=A,1=B,..) +; При B = 1 (SET - исп. boot-загрузчик системы, после чего функция недоступна) +; вход: H - номер устройства, L - номер раздела на устройстве +; выход: +;///////////////////////////////////////////////////////////////////// +BOOTDSK: + INC B + DEC B + JR Z,.GET + DEC B +.chg: JR Z,.SET ;R13 меняется на JR С,SETBOOT после первого удачного исполнения SETBOOT + LD A,DSS_Error.sys.INVALID_FUNCTION + SCF + RET +.GET: ;GET BOOT DISK +.NUM+1: LD A,0 ;R09 + AND A + RET + ; Сообщить DSS с какого диска загружается система. + ; Исп. загрузчик системы для иниц. ячейки "boot_disk". + +.SET: LD B,H ;SET BOOT DISK + LD C,0 + ;[x] 17.12.2023 загрузка с активного раздела, а не с первого + LD (.part),HL + ; +.loop: PUSH BC + LD A,C + LD DE,Dss.DRV.GenIOCTL.Enter + LD BC,Dss.DRV.GenIOCTL.GetParams + RST ToDSS.DRV + ;[x] 17.12.2023 загрузка с активного раздела, а не с первого + LD A,C ; номер партиции в MBR диска + ; + POP BC + JR C,.NoSupport + EX AF,AF' ;PHISICAL DRIVE NUMBER + CP B + JR NZ,.NoSupport + ;[x] 17.12.2023 загрузка с активного раздела, а не с первого + EX AF,AF' ; номер партиции в MBR диска +.part+1: LD HL,0 + CP L + JR NZ,.NoSupport + ; + ;R13 + LD A,#38 ; opcode for JR C,addr + LD (BOOTDSK.chg),A + ;R13 + LD A,C + LD (BOOTDSK.NUM),A + AND A + RET +.NoSupport: + INC C + LD A,(LDRIVE) + CP C + JR NZ,.loop + SCF + RET +; Номер последнего диска в системе +LDRIVE: DB DSS_MAX_DRIVES_AMOUNT + IF COMPILE_UNUSED_CODE +TDRIVE: DB #00 +TCLUST: DW #0000 +TCOUNT: DW #0000 + ENDIF +; \ No newline at end of file diff --git a/Crazy Estex DSS/DSS/API/ChDir.asm b/Crazy Estex DSS/DSS/API/ChDir.asm new file mode 100644 index 0000000..5a50614 --- /dev/null +++ b/Crazy Estex DSS/DSS/API/ChDir.asm @@ -0,0 +1,44 @@ +//////////////////////////////////////////////////////////////////////// +; Функция #1D. Смена текущего каталога. +; Меняет текущий каталог и текущий диск, если он указан в файловой +; спецификации. Если путь начинается с "\" - это означает путь от +; корневого каталога, иначе от текущего. +; +; вход: HL - указатель на имя каталога +; выход: нет +; +; INPUT: HL - "C:\DIR\DIR\DIR_NAME[\]",0 +//////////////////////////////////////////////////////////////////////// +CHDIR_FN: + ;!TEST Current Dir ;[x] 15/10/23 + ; + IF OLD_DSS_FOR_OLD_EXE + ; [ ] 10/06/24 + LD A,(EXE_VERSION) + OR A + JR Z,CHDIR + ; + ENDIF + ; + PUSH HL + CALL DIR_PATH_CHECK + POP HL + RET C + CALL CHDIR + ; если удачно, то копируем WorkDirectory в CurrentDirectory + JP NC,DIR_PATH_CHANGE.FullCurrent + ; если неудачно, то возвращаемся туда откуда пришли + PUSH AF + LD HL,CORE_BUFFERS.CurrentDirectory + CALL CHDIR + POP AF + RET + ; +CHDIR: CALL GETWORD ; тест на допуст. имя и настр. на диск + RET C + LD HL,TMPNAME + LD A,(HL) + OR A + RET Z + JP OPENDIR +; \ No newline at end of file diff --git a/Crazy Estex DSS/DSS/API/ChnDisk.asm b/Crazy Estex DSS/DSS/API/ChnDisk.asm new file mode 100644 index 0000000..119846c --- /dev/null +++ b/Crazy Estex DSS/DSS/API/ChnDisk.asm @@ -0,0 +1,24 @@ +//////////////////////////////////////////////////////////////////////// +; +; +//////////////////////////////////////////////////////////////////////// +CHNDISK_FN: CALL CHNDISK + RET C + PUSH AF + CALL DIR_PATH_CHANGE.FullCurrent + POP AF + RET +CHNDISK: ;[x] более корректная смена диска + CALL OPENDSK + ; + ;R010 + RET C + LD HL,CORE_BUFFERS.WorkDirectory + LD (HL),0 + PUSH AF + CALL OPENDIR + POP BC + RET C + LD A,B + RET +; \ No newline at end of file diff --git a/Crazy Estex DSS/DSS/API/Close.asm b/Crazy Estex DSS/DSS/API/Close.asm new file mode 100644 index 0000000..92f79ab --- /dev/null +++ b/Crazy Estex DSS/DSS/API/Close.asm @@ -0,0 +1,86 @@ +; [x] fat32 ;!TEST +//////////////////////////////////////////////////////////////////////// +;Входные значения: +; C - #12 +; A - файловый манипулятор +;Выходные значения: +; A - код ошибки, если CF=1 +//////////////////////////////////////////////////////////////////////// +CLOSE_FN: +;R008 ; +;CLOSE: ; + LD (.TMP),A + CALL SET_FM + RET C + LD A,(TASK) + CP (IY+_sFM.TASK_NUM) + LD A,DSS_Error.sys.ACCESS_DENIED + SCF + RET NZ + BIT 7,(IY+_sFM.ACCESS_MODE) + JR Z,.NOTMODF + ; + LD E,(IY+_sFM.DIR_CLUSTER_L) + LD D,(IY+_sFM.DIR_CLUSTER_L+1) + PUSH DE + ; [x] fat32 + LD E,(IY+_sFM.DIR_CLUSTER_H) + LD D,(IY+_sFM.DIR_CLUSTER_H+1) + PUSH DE + ; + ; [x] 15/11/2023 -bug with bad clusters ;!TEST + LD A,(IY+_sFM.DRIVE) + CALL OPENDSK + ; + XOR A + CALL SET_FM + ; [x] fat32 + POP DE + LD (IY+_sFM.DIR_CLUSTER_H),E + LD (IY+_sFM.DIR_CLUSTER_H+1),D + LD (IY+_sFM.FS_REC.FIRST_CLUSTER_H),E + LD (IY+_sFM.FS_REC.FIRST_CLUSTER_H+1),D + ; + POP DE + LD (IY+_sFM.DIR_CLUSTER_L),E + LD (IY+_sFM.DIR_CLUSTER_L+1),D + ; [x] 15/11/2023 -bug with bad clusters ;!TEST + LD (IY+_sFM.FS_REC.FIRST_CLUSTER_L),E + LD (IY+_sFM.FS_REC.FIRST_CLUSTER_L+1),D + ; + CALL LOADDIR +.TMP+1: LD A,0 + CALL SET_FM + ; + SET_PAGE_X DIRPAGE + ; + ;!TEST 9/11/23 record index + ; LD HL,DIR + ; LD DE,FAT_DIRECTORY_RECORD + ; LD C,(IY+_sFM.HANDLE) + ; LD B,(IY+_sFM.HANDLE+1) + ; JR .CLOSE2 + ; .CLOSE1: + ; ADD HL,DE + ; DEC BC + ; .CLOSE2: + ; LD A,B + ; OR C + ; JR NZ,.CLOSE1 + LD L,(IY+_sFM.HANDLE) + LD H,(IY+_sFM.HANDLE+1) + ; + LD D,YH + LD E,YL + EX DE,HL + ;PUSH HL + ;SET_PAGE_X DIRPAGE + ;POP HL + LD BC,FAT_DIRECTORY_RECORD + LDIR + OUT (SLOT3),A + CALL SAVEDIR +.NOTMODF: + LD A,(.TMP) + JP RES_FM +; \ No newline at end of file diff --git a/Crazy Estex DSS/DSS/API/Create.asm b/Crazy Estex DSS/DSS/API/Create.asm new file mode 100644 index 0000000..d41492b --- /dev/null +++ b/Crazy Estex DSS/DSS/API/Create.asm @@ -0,0 +1,121 @@ +//////////////////////////////////////////////////////////////////////// +; INPUT: HL - "C:\DIR1\DIR2\filename.ext",#00 +; A - File attribute +; OUTPUT: A - FM +//////////////////////////////////////////////////////////////////////// +CREATE: ;!TEST Current Dir ;[x] 15/10/23 ;CREATE_FN: + PUSH HL + LD C,A + ; + IF OLD_DSS_FOR_OLD_EXE + ; [ ] 10/06/24 + LD A,(EXE_VERSION) + OR A + JR Z,.old_EXE + ENDIF + ; + PUSH BC + CALL DIR_PATH_CHECK + POP BC + POP HL + RET C +.old_EXE: LD A,C + ; + CALL .Prepare + RET C + CALL SEARCH.File + ; [x] fixed a bug with incorrect search when there were too many files in the directory 12/03/2024 + ;CALL NC,DEL_FN.DELETE ;FILE EXIST RECREAT + CALL NC,.FILE_EXISTS_DEL ;FILE EXIST RECREAT + CP DSS_Error.sys.FILE_NOT_FOUND + JR Z,.DO + SCF + RET +.FILE_EXISTS_DEL: + CALL DELETE_REC_FAT + LD A,DSS_Error.sys.FILE_NOT_FOUND + RET + ; + ; INPUT: HL - "C:\DIR1\DIR2\filename.ext",#00 + ; OUTPUT: A - FM +.NEW: ;!TEST Current Dir ;[x] 15/10/23 + PUSH HL + LD C,A + ; + IF OLD_DSS_FOR_OLD_EXE + ; [ ] 10/06/24 + LD A,(EXE_VERSION) + OR A + JR Z,.old_EXE + ENDIF + ; + PUSH BC + CALL DIR_PATH_CHECK + POP BC + POP HL + RET C +.old_EXE_: LD A,C + ; + CALL .Prepare + RET C + CALL SEARCH.File + ; [x] fixed a bug with incorrect search when there were too many files in the directory 12/03/2024 + ; LD A,DSS_Error.sys.FILE_EXISTS + ; CCF + ; RET C + JR NC,.FILE_EXISTS + CP DSS_Error.sys.FILE_NOT_FOUND + SCF + RET NZ + ; + ; + ;no_file_found +.DO: ; FAT_DIRECTORY_RECORD.NAME + .EXT + LD HL,MASKARE + LD DE,HANDBUF + LD BC,11 + LDIR + EX DE,HL +.TMP+1: LD A,0 + ; FAT_DIRECTORY_RECORD.ATTRIBUT + LD (HL),A + INC HL + LD BC,#0A00 ;!HARDCODE + ; .RESERVED_NT .. .FIRST_CLUSTER_H +.loop1: LD (HL),C + INC HL + DJNZ .loop1 + ; .TIME .. .DATE + CALL WRITE_DATE_TIME_TO_DIRECTORY_RECORD + ; + LD BC,#0600 + ; +.loop2: LD (HL),C + INC HL + DJNZ .loop2 + ; + CALL WRT_HND + RET C + ;CALL SAVEDIR +.PATH0+1: LD HL,0 + XOR A + LD (OPEN_FN.TMP),A + JP OPEN_FN.FILE ;R008 + ; +.Prepare: ;AND #E7 ;R004 %76A00SHR = !FAT_ATTR ;!HARDCODE + AND FAT_ATTR.NoDIRnoVolID + LD (.TMP),A + LD (.PATH0),HL + CALL GETWORD + RET C + ; [ ] 26/06/2024 + CALL CHECK_64kb_CLUSTER + RET C + ; + JP MASK + ; +; [x] fixed a bug with incorrect search when there were too many files in the directory 12/03/2024 +.FILE_EXISTS: LD A,DSS_Error.sys.FILE_EXISTS + CCF + RET +; \ No newline at end of file diff --git a/Crazy Estex DSS/DSS/API/CurDisk.asm b/Crazy Estex DSS/DSS/API/CurDisk.asm new file mode 100644 index 0000000..a3e9f3b --- /dev/null +++ b/Crazy Estex DSS/DSS/API/CurDisk.asm @@ -0,0 +1,30 @@ +;///////////////////////////////////////////////////////////////////// +; Функция #02. Номер текущего диска. +; +; вход: нет +; выход: A - номер диска (0=A,1=B,..) +; C - номер последнего диска в системе +;///////////////////////////////////////////////////////////////////// +CURDISK_FN: + ; + IF OLD_DSS_FOR_OLD_EXE + ; [ ] 10/06/24 + LD A,(EXE_VERSION) + OR A + JR Z,CURDISK + ; + ENDIF + LD A,(LDRIVE) + LD C,A + LD A,(CORE_BUFFERS.CurrentPath) + SUB 'A' + RET NC + LD A,DSS_Error.sys.INVALID_DRIVE + RET +CURDISK: + LD A,(LDRIVE) + LD C,A + LD A,(CORE_BUFFERS.FatBuffer.DRIVE) + AND A + RET +; \ No newline at end of file diff --git a/Crazy Estex DSS/DSS/API/CurrDir.asm b/Crazy Estex DSS/DSS/API/CurrDir.asm new file mode 100644 index 0000000..7ae85dc --- /dev/null +++ b/Crazy Estex DSS/DSS/API/CurrDir.asm @@ -0,0 +1,24 @@ +//////////////////////////////////////////////////////////////////////// +; Функция #1E. Информация о текущем каталоге. +; +; вход: HL - буфер в памяти 256 байт +; выход: A - код ошибки, если CF=1 +//////////////////////////////////////////////////////////////////////// +CURRDIR: LD DE,CORE_BUFFERS.WorkDirectory + JR CURRDIR_FN.skip +CURRDIR_FN: + LD DE,CORE_BUFFERS.CurrentDirectory +.skip: EX DE,HL + LD BC,DIRECTORY_PATH_LENGTH ;[x] 15/11/2023 могло выйти за пределы буфера + XOR A +.loop: CP (HL) + LDI + JP PO,.error ;[x] 15/11/2023 могло выйти за пределы буфера + JR NZ,.loop + RET + ;[x] 15/11/2023 могло выйти за пределы буфера +.error: LD A,DSS_Error.sys.TOO_DEEP_DIR_DEPTH + SCF + RET + ; +; \ No newline at end of file diff --git a/Crazy Estex DSS/DSS/API/Delete.asm b/Crazy Estex DSS/DSS/API/Delete.asm new file mode 100644 index 0000000..8c032f4 --- /dev/null +++ b/Crazy Estex DSS/DSS/API/Delete.asm @@ -0,0 +1,43 @@ +; [x] fat32 ;!TEST +//////////////////////////////////////////////////////////////////////// +; INPUT: HL - "c:\dir\filename.ext",#00 without simbols * ? +//////////////////////////////////////////////////////////////////////// +DEL_FN: ;!TEST + ;!TEST Current Dir ;[x] 15/10/23 + ; + IF OLD_DSS_FOR_OLD_EXE + ; [ ] 10/06/24 + LD A,(EXE_VERSION) + OR A + JR Z,.old_EXE + ENDIF + ; + PUSH HL + CALL DIR_PATH_CHECK + POP HL + RET C + ; +.old_EXE: CALL GETWORD ; тест на допуст. имя и настр. на диск + RET C + ; [ ] 26/06/2024 + CALL CHECK_64kb_CLUSTER + RET C + ; + CALL MASK + RET C + ; + ;!TEST optimization + ;LD HL,MASKARE + ;LD BC,11 + ;LD A,"?" + ;CPIR + ;LD A,DSS_Error.sys.INVALID_NAME + ;SCF + CALL CHECK_NAME + ; + RET Z + CALL LOADDIR + CALL SEARCH.File + RET C + JP DELETE_REC_FAT ; пометить запись как "удаленная" +; \ No newline at end of file diff --git a/Crazy Estex DSS/DSS/API/DiskINF.asm b/Crazy Estex DSS/DSS/API/DiskINF.asm new file mode 100644 index 0000000..bfc6cba --- /dev/null +++ b/Crazy Estex DSS/DSS/API/DiskINF.asm @@ -0,0 +1,260 @@ +;///////////////////////////////////////////////////////////////////// +; [ ] новая подфункция с битом 7 в рег. А +; Возвращает информацию об общем и свободном пространстве дискового +; устройства. +; +; вход: A - номер диска (0=A,1=B .. 25=Z. #FF-текущий) +; При A bit7 = 1: +; A and #7F - номер диска +; HL - буфер (256 байтов) для расширенных данных: +; B != 0 - считать свободное место +; ; +; размер поля - 1 байт +; Файловая система +; ; +; размер поля - 1 байт +; Серийный номер диска +; ; +; размер поля - 1 байт +; Метка диска +; ; +; размер поля - 1 байт +; физический номер диска, номер раздела +; ; +; размер поля - 1 байт +; зарезервировано +; ; +; выход: CF=0: +; A - размер кластера в секторах +; HL':HL - общее кол-во кластеров +; DE':DE - свободных кластеров +; BC - размер сектора в байтах +; CF=1: +; A - код ошибки, если CF=1 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Метка диска проверяется сначала в корневом каталоге и если там ; +; нет, то берётся метка из BPB ; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;///////////////////////////////////////////////////////////////////// +DISKINF: LD C,B + LD B,1 + ; + CP #80 + JP C,.CustomDisk + CP #FF + JR Z,.CurrentDisk + ; more info + LD B,C + AND %0111'1111 + PUSH HL + PUSH AF + CALL .CustomDisk + POP IX + JR C,.error + ; + EX (SP),HL + PUSH DE + PUSH AF + PUSH BC + ;;;; + ; + EX DE,HL + LD HL,FAT_STRING + LD C,5 ;!HARDCODE _sBOOT_SECTOR_PARAMS.ID_FAT.length + CALL .mCOPY_LOOP + ; 12, 16 or 32 + LD A,(CORE_BUFFERS.FatBuffer.FAT_TYPE) + CP FAT_TYPE.x16 + JR C,.next_prm + ; + PUSH DE + DEC DE + LD A,'6' + JR Z,.put_char + ; fat 32 + DEC DE + LD A,'3' +.put_char: LD (DE),A + POP DE + ; +.next_prm: LD HL,CORE_BUFFERS.FatBuffer.BPB_SERIAL_NUMBER + LD C,4 ;!HARDCODE _sBOOT_SECTOR_PARAMS.BPB_SERIAL_NUMBER + CALL .mCOPY_LOOP + ; + ; fat32 + EXX + PUSH DE + PUSH HL + EXX + ;LD HL,CORE_BUFFERS.FatBuffer.BPB_LABEL + PUSH IX + CALL GET_LABEL + LD C,11 ;!HARDCODE _sBOOT_SECTOR_PARAMS.BPB_LABEL + CALL .mCOPY_LOOP + POP AF + PUSH DE + ;LD A,XH + LD DE,Dss.DRV.GenIOCTL.Enter + LD BC,Dss.DRV.GenIOCTL.GetParams + RST ToDSS.DRV + POP DE + ; fat32 + EXX + POP HL + POP DE + EXX + JR C,.error_drv + LD A,2 ;!HARDCODE длина поля №4 2 байта: физ номер диска, номер раздела диска + LD (DE),A + INC DE + EX AF,AF' + LD (DE),A ;физ номер диска + INC DE + LD A,C + LD (DE),A ;номер раздела диска + INC DE + ; +.error_drv: XOR A + LD (DE),A + ;;;; + POP BC + POP AF + POP DE +.error: POP HL + RET + ; + CP #FF ; !FIXIT WorkDirectory + ;!TEST !Current Dir + ;JR Z,CURRDS ;R06 +.CurrentDisk: ; [ ] 10/06/24 + IF OLD_DSS_FOR_OLD_EXE + LD A,(EXE_VERSION) + OR A + LD A,(CORE_BUFFERS.FatBuffer.DRIVE) + JR Z,.old_EXE + ENDIF + ; + LD A,(CORE_BUFFERS.CurrentPath) + SUB 'A' +.old_EXE: LD HL,CORE_BUFFERS.FatBuffer.DRIVE + CP (HL) + JR Z,.CheckFreeSpace + ; +.CustomDisk: PUSH BC + CALL CHNDISK ;R06 + POP BC + RET C + ; +.CheckFreeSpace:; если GetFreeSpace не вызывается + XOR A + OR B + LD BC,(CORE_BUFFERS.FatBuffer.FREE_CLUSTERS_COUNT_L) + EXX + LD BC,(CORE_BUFFERS.FatBuffer.FREE_CLUSTERS_COUNT_H) + EXX + CALL NZ,GetFreeSpace + ; + ;.FRESP2: + ; A = 0 if B != 0 before .GetFreeSpace + ; + LD H,B + LD L,C + LD (CORE_BUFFERS.FatBuffer.FREE_CLUSTERS_COUNT_L),HL + EX DE,HL + EXX + LD H,B + LD L,C + LD (CORE_BUFFERS.FatBuffer.FREE_CLUSTERS_COUNT_H),HL + EX DE,HL + EXX + LD HL,(CORE_BUFFERS.FatBuffer.MaxClusterLow) + DEC HL + ; fat 32 + EXX + LD HL,(CORE_BUFFERS.FatBuffer.MaxClusterHigh) + JR NC,.skip_dec_hl + DEC HL +.skip_dec_hl: EXX + LD BC,(CORE_BUFFERS.FatBuffer.BytesPerSector) + LD A,(CORE_BUFFERS.FatBuffer.SectorsPerCluster) + AND A + RET + ; + ; [ ] 22/11/23 подфункция с доп.инфой +.mCOPY_LOOP: LD B,0 + EX DE,HL + LD (HL),C + EX DE,HL + INC DE + LDIR + RET + ; +; +GetFreeSpace: LD A,1 + LD (CORE_BUFFERS.FatBuffer.UPD_FSINFO),A + LD HL,2 ; fat32 номер кластера от которого считать + XOR A + ; fat32 + EXX + LD H,A + LD L,A + LD B,A + LD C,A + EXX + LD B,A + LD C,A +.loop_free_space:;!FIXIT + PUSH BC + EXX + PUSH BC + EXX + CALL READ_FROM_FAT + EXX + POP BC + EXX + POP BC + CP DSS_Error.sys.DISK_FULL + RET Z + ; fat 32 + EXX + LD A,E + OR D + EXX + OR E + OR D + JR NZ,.skip + ; + INC BC + LD A,B + OR C + JR NZ,.skip + EXX + INC BC + EXX + ; +.skip: INC HL + LD A,L + OR H + JR NZ,.loop_free_space + EXX + INC HL + EXX + JP .loop_free_space + ; +FAT_STRING: DB 'FAT12' +; +; DE - буфер +GET_LABEL: PUSH DE + LD HL,.LABEL_MASK ; "\*.*" имя метки + LD A,FAT_ATTR.VOLUME_ID ; атрибут метки тома + LD B,high Dss.F_First.FATname + CALL F_FIRST + ;LD BC,Dss.F_First.FATname ; f_first, формат 11 + ;RST ToDSS + POP DE + LD HL,CORE_BUFFERS.FatBuffer.BPB_LABEL + RET C + LD HL,BUFFER_FIND.REC_Name + ADD HL,DE + RET +.LABEL_MASK: DB '\*.*',0 \ No newline at end of file diff --git a/Crazy Estex DSS/DSS/API/DosName.asm b/Crazy Estex DSS/DSS/API/DosName.asm new file mode 100644 index 0000000..512de5c --- /dev/null +++ b/Crazy Estex DSS/DSS/API/DosName.asm @@ -0,0 +1,22 @@ +//////////////////////////////////////////////////////////////////////// +;Входные значения: +; C - #44 +; B = 0, преобразовать из 11 символьного формата в формат ДОС +; HL - 11 символов имени файла +; DE - буфер для имени в формате ДОС +; B = 1, преобразовать из формата ДОС в 11 символьный формат +; HL - имя файла в формате ДОС +; DE - 11 символов имени файла +;Выходные значения: +; A - код ошибки, если CF=1 +//////////////////////////////////////////////////////////////////////// +DOSNAME: + INC B + DEC B + JP Z,GetName + DEC B + JP Z,MASK.custom + LD A,DSS_Error.sys.INVALID_FUNCTION + SCF + RET +; \ No newline at end of file diff --git a/Crazy Estex DSS/DSS/API/Environ.asm b/Crazy Estex DSS/DSS/API/Environ.asm new file mode 100644 index 0000000..4a3c1d3 --- /dev/null +++ b/Crazy Estex DSS/DSS/API/Environ.asm @@ -0,0 +1,294 @@ +;[BEGIN] +;//MODULE: ENVIRON +;//CREATE: 10-11-2002 AUTHOR: Denis Parinov +;--------------------------------------------------------------- +;Rev Date Name Description +;--------------------------------------------------------------- +;R02 13-05-2023 BAO Инициализация переменной BOOTDSK при старте +;R03 09-03-2007 VAS Функция ENV_EX теперь обрезает слишком длинную строку перед выходом +;R01 19-11-2002 DNS CORRECT DE ADDRESS IN GETENV +;--------------------------------------------------------------- + +;///////////////////////////////////////////////////////////////////// +; Функция #46. Системное окружение. +; +; вход: B - номер подфункции: +; B=#FF, инициализация +; B=0, получение системного окружения. +; HL - буфер +; B=1, получить переменную окружения. +; HL - имя переменной +; DE - буфер для значения переменной +; B=2, установить/удалить переменную окружения +; HL - ПЕРЕМЕННАЯ=ЗНАЧЕНИЕ +; В конце строки ноль. + +; выход: A - состояние, если CF=0 +; DE - указывает на конец буфера (только для B=1) +; A=#FF - переменная обнаружена +; A=0 - переменная не обнаружена +; A - код ошибки, если CF=1 +;///////////////////////////////////////////////////////////////////// +ENVIRON: + INC B + JR Z,INITENV ; B=#FF + DEC B + JR Z,READENV ; B=0. получить сист. окружение + DEC B + JP Z,GETENV ; B=1. получить перем. окружения + DEC B + JP Z,SETENV ; B=2. установить/удалить перем. окружения + LD A,DSS_Error.sys.INVALID_FUNCTION + SCF + RET + +;------------------------------------------------- +; Инициализация буфера переменных окружения +;------------------------------------------------- +INITENV: + SET_PAGE_X ENVPAGE + PUSH AF + ; + ;R02 + LD A,(BOOTDSK.NUM) + ADD A,'A' + LD (DEFAULT_ENV.boot_disk),A + ; + LD DE,ENVIRONMENT ; начало буфера переменных окружения + XOR A + LD (DE),A + INC DE + LD HL,DEFAULT_ENV + LD BC,DEF_ENV_SIZE + LDIR + LD (DE),A + EX DE,HL + LD DE,ENVIRONMENT + AND A + SBC HL,DE + LD (ENVSIZE),HL + ; + POP AF + OUT (SLOT3),A + AND A + RET + +;------------------------------------------------- +; Получить сист. окружение +;------------------------------------------------- +READENV: + PUSH HL + + SET_PAGE_X ENVPAGE + + LD H,A + LD C,SLOT3 + IN L,(C) + EXX + + LD HL,ENVIRONMENT + INC HL + POP DE + LD BC,(ENVSIZE) + EXX +; +.loop: OUT (C),L + EXX + LD A,(HL) + EXX + OUT (C),H + EXX + LD (DE),A + INC HL + INC DE + DEC BC + LD A,B + OR C + EXX + JR NZ,.loop + //XOR A + ;A=0 + RET + +;------------------------------------------------- +; Получить переменную окружения +;------------------------------------------------- +GETENV: PUSH DE + CALL ENV_EX ; скопир. строку перем. окруж. в буферы + + SET_PAGE_X ENVPAGE + EX AF,AF' + + CALL F_ENV ; RET: DE - VAR VALUE; HL - VAR ADDRESS; BC - ENVIRONMENT SIZE + POP DE + LD A,0 + LD (DE),A + JR NC,.exit +.loop: LD A,(HL) + LDI + OR A + JR NZ,.loop + DEC DE ;R01 + LD A,#FF + +.exit: EX AF,AF' + OUT (SLOT3),A + EX AF,AF' + AND A + RET + +;------------------------------------------------- +; Установить/Удалить переменную окружения +; +; вход: hl=имя перем. и значение, раздел. символом "=" +;------------------------------------------------- +SETENV: CALL ENV_EX ; скопир. строку перем. окруж. в буферы + + SET_PAGE_X ENVPAGE + PUSH AF + + CALL F_ENV ; RET: DE - VAR VALUE; HL - VAR ADDRESS; BC - ENVIRONMENT SIZE + JR NC,PENV + XOR A + CPIR + LD A,B + OR C + JR Z,PENV + LDIR +PENV LD A,(ENVVALUE) + OR A + JR Z,CLR_ENV + LD HL,ENVNAME +F_EVN2 LD A,(HL) + LDI + CP "=" + JR NZ,F_EVN2 + LD HL,ENVVALUE +F_EVN3 LD A,(HL) + LDI + OR A + JR NZ,F_EVN3 +CLR_ENV XOR A + LD (DE),A + LD HL,ENVIRONMENT + EX DE,HL + SBC HL,DE + LD (ENVSIZE),HL +; + POP AF + OUT (SLOT3),A + AND A + RET + + +; RET: +; DE - VAR VALUE +; HL - VAR ADDRESS +; BC - ENVIRONMENT SIZE +F_ENV LD HL,ENVIRONMENT + LD BC,(ENVSIZE) + PUSH HL +F_EVN0 POP DE + LD DE,ENVNAME + XOR A + CPIR + PUSH HL +F_EVN1 LD A,(HL) + OR A + JR Z,END_OF_ENV + LD A,(DE) + CP (HL) + INC HL + INC DE + DEC BC + JR NZ,F_EVN0 + CP "=" + JR NZ,F_EVN1 + SCF +END_OF_ENV + POP DE + RET + +;----------------------------------------------------------- +; Скопировать строку переменной окружения в буферы +; (имя и значение в разные буферы) +; вход: hl=имя перем. и значение, раздел. символом "=" +;----------------------------------------------------------- +ENV_EX: LD B,ENVIRONMENT_STRING_LENGTH ; 255 макс. длина строки (имя+знач.) + LD DE,ENVNAME ; куда +ENV_E0: XOR A + LD (DE),A + LD (ENVVALUE),A + ; скопир. в "ENVNAME" имя переменной +ENV_E1: LD A,(HL) + INC HL + CP "=" + JR Z,EQUAL_SG + OR A + JR Z,ENV_E3 + CALL UPPER + LD (DE),A + INC DE + DJNZ ENV_E1 + ;R03 + ; слишком длинная строка + ld a,b + ld (de),a ; обрезать слишком длинную строку + inc de + ; + SCF + RET + ; значение не задано +ENV_E3: LD A,"=" + LD (DE),A + INC DE + XOR A + LD (DE),A + INC DE + RET + ; значение задано +EQUAL_SG: LD (DE),A ; сохр. "=" + INC DE + XOR A + LD (DE),A ; в конец имени перем. + ; скопир. в "ENVVALUE" значение переменной (строку путей) + LD DE,ENVVALUE ; 512 байт, буфер + LD (DE),A + LD C,#FF ; чтобы "ldi" не портила "b" +ENV_E2 LD A,(HL) + LDI + OR A + RET Z ; конец строки знач. переменной + DJNZ ENV_E2 + ;R03 + ; слишком длинная строка + ld a,b + ld (de),a ; обрезать слишком длинную строку + inc de + ; + SCF + RET + +ENVNAME EQU CORE_BUFFERS.EXEBUFF ;DS 32 +ENVVALUE EQU CORE_BUFFERS.BUFFER //#3800 ; BUFFER ;DS 128 + +ENVSIZE DW DEF_ENV_SIZE ;E_END-ENVIRONMENT ;160 + +ENVIRONMENT EQU ENVADDR + +DEFAULT_ENV: DB 'BOOTDSK=' ;R02 +.boot_disk: DB 'X:',0 ;R02 +; DB 'SYSTEM=C:\system.exe',0 +; DB 'PATH=\SYSTEM\;\COMMAND\;',0 +DEF_ENV_SIZE EQU $-DEFAULT_ENV ;R02 + + +; DB 'SYSTEM=C:\system.exe',0 +; DB 'PATH=\SYSTEM\;\COMMAND\;',0 +; DB 0 +; DB 'SYSTEM=C:\system.exe',0 +; DB 'PATH=C:\;\FN\;',0 +; DB 'OS=ESTEX',0 +; DB 'VAR1=000',0 +; DB 'OSNAME=ESTEX 2002',0 +; DB 0 \ No newline at end of file diff --git a/Crazy Estex DSS/DSS/API/Ex_Path.asm b/Crazy Estex DSS/DSS/API/Ex_Path.asm new file mode 100644 index 0000000..aab7a8b --- /dev/null +++ b/Crazy Estex DSS/DSS/API/Ex_Path.asm @@ -0,0 +1,240 @@ +////////////////////////////////////////////////////////////////////// +; Функция #45. Разбор командной строки. +; +; вход: HL - указатель командной строки +; DE - указатель на буфер пользователя +; B - номер подфункции: +; 0 - Разобрать строку +; 1 - Выделить имя диска +; 2 - Выделить директорию +; 3 - Выделить имя файла +; 4 - Выделить расширение файла +; 5 - Выделить имя диска, путь к файлу, имя файла и расш. файла +; 6 - Зарезервировано ;!TODO преобразовать относительный путь в полный ; [ ] +; 7 - Выделить параметр командной строки +; 8 - Преобразовать из 11 символьного формата в формат ДОС +; 9 - Преобразовать из формата ДОС в 11 символьный формат +; выход: нет +////////////////////////////////////////////////////////////////////// +GLOB_PR EQU 7 ;%10000000 +DRIV_PR EQU 3 ;%00001000 +PATH_PR EQU 2 ;%00000100 +EXTN_PR EQU 1 ;%00000010 +NAM_PR EQU 0 ;%00000001 + +EX_PATH: EXX + LD HL,NM_PATH_A ;BUILT-IN BUFFER FOR PATH ;!!!!! используется общий буфер + LD (NM_PATH),HL + LD HL,NM_NAME_A + LD (NM_NAME),HL + LD HL,NM_EXTN_A + LD (NM_EXTN),HL + LD HL,NM_DRIVE_A + LD (NM_DRIVE),HL + EXX + INC B + DEC B + JR Z,.FULL ;0 ; разобрать строку + DEC B + JR Z,.GET_DRIVE ;1 ; выделить имя диска + DEC B + JR Z,.GET_PATH ;2 ; выделить директорию + DEC B + JR Z,.GET_NAME ;3 ; выделить имя файла + DEC B + JR Z,.GET_TYPE ;4 ; выделить расширение файла + DEC B + JR Z,.GET_ALL_EX ;5 ; выделить диск, путь, файл и расш. + DEC B + JR Z,.EX_RESR ;6 ; зарезервировано + DEC B + JP Z,GSWITCH ;7 ; выделить параметр ком-строки + DEC B + JP Z,GetName ;8 ; преобр. имя 11 -> 8.3 формат + DEC B + JP Z,MASK.custom ;9 ; преобр. имя 8.3 -> 11 формат +.EX_RESR: LD A,DSS_Error.sys.INVALID_FUNCTION + SCF + RET + ; Выделить имя диска +.GET_DRIVE: LD (NM_DRIVE),DE + CALL .FULL + RET C + LD DE,(NM_DRIVE) + LD A,(DE) + DEC A + CP #FF + RET Z + CP "A"-1 + JR C,.GD_error + CP "Z" + JR NC,.GD_error + SUB "A"-1 + RET + ; +.GD_error: LD A,DSS_Error.sys.INVALID_DRIVE + SCF + RET + + ; Выделить директорию +.GET_PATH: LD (NM_PATH),DE + JR .FULL + + ; Выделить имя файла +.GET_NAME: LD (NM_NAME),DE + JR .FULL + + ; Выделить расширение файла +.GET_TYPE: LD (NM_EXTN),DE + JR .FULL + ; Выделить диск, путь, файл и расш. +.GET_ALL_EX: EX DE,HL + LD C,(HL) + INC HL + LD B,(HL) + INC HL + LD (NM_DRIVE),BC + LD C,(HL) + INC HL + LD B,(HL) + INC HL + LD (NM_PATH),BC + LD C,(HL) + INC HL + LD B,(HL) + INC HL + LD (NM_NAME),BC + LD C,(HL) + INC HL + LD B,(HL) + LD (NM_EXTN),BC + EX DE,HL + ;JR EX_FULL + ; Разобрать строку +.FULL: EX AF,AF' + EXX + XOR A + LD HL,(NM_PATH) + LD (HL),A + LD HL,(NM_NAME) ; адрес буфера под имя файла + LD (HL),A + LD HL,(NM_EXTN) + LD (HL),A + LD HL,(NM_DRIVE) + LD (HL),A + EXX + EX AF,AF' +.PAT0: LD DE,TMPBUF + LD BC,#0D01 ;!HARDCODE счетчики +.PAT1: LD A,(HL) + CALL UPPER ; a..z -> A..Z + LD (DE),A + INC HL + INC DE + INC C ; ++счетчик + CP '\' + JR Z,.PATH_YEP + CP ":" + JR Z,.DRIVE_YEP + CP "!" + JR C,.NAME_YEP + CP "?" + JR Z,.GLOBP1 + CP "*" + JR Z,.GLOBP1 +.PAT2: DJNZ .PAT1 + LD A,DSS_Error.sys.INVALID_NAME + SCF + RET + ; +.GLOBP1: EX AF,AF' + SET GLOB_PR,A + EX AF,AF' + JR .PAT2 + ; +.NAME_YEP: LD A,2 + CP C + JR Z,.NOFNAME + PUSH HL + LD HL,TMPBUF + LD DE,(NM_NAME) ; адрес буфера под имя файла + LD B,0 + DEC C + DEC C + LD A,C + LDIR + LD C,A + XOR A + LD (DE),A + LD HL,(NM_NAME) + LD A,"." + CPIR + JR NZ,.NOEXTN + LD C,3 + LD DE,(NM_EXTN) +.EXTSK0: LD A,(HL) + OR A + JR NZ,.EXTSK1 + LD A,' ' + DEC HL +.EXTSK1: LD (DE),A + INC HL + INC DE + DEC C + JR NZ,.EXTSK0 + XOR A + LD (DE),A + EX AF,AF' + SET EXTN_PR,A ; указано расш. файла + EX AF,AF' +.NOEXTN: EX AF,AF' + SET NAM_PR,A ; указано имя файла + EX AF,AF' + POP HL +.NOFNAME: EX AF,AF' + AND A + RET + ; +.DRIVE_YEP: XOR A + LD (DE),A + PUSH HL + LD HL,TMPBUF + LD DE,(NM_DRIVE) + LD B,0 + LDIR + POP HL + EX AF,AF' + SET DRIV_PR,A ; указано имя диска + EX AF,AF' + JP .PAT0 + ; +.PATH_YEP: XOR A + LD (DE),A + PUSH HL + PUSH BC + LD HL,(NM_PATH) + LD BC,#00FF ; !FIXIT глубина буфера не зависит от CurrentDirectory.DEPTH + CPIR + DEC HL + EX DE,HL + LD HL,TMPBUF ; 12 пробелов + POP BC + LD B,0 + LDIR + POP HL + EX AF,AF' + SET PATH_PR,A + EX AF,AF' + JP .PAT0 +;!TODO перенести/заменить на общий +TMPBUF: DB " ",#00 ; 12 пробелов +NM_DRIVE: DW NM_DRIVE_A +NM_NAME: DW NM_NAME_A +NM_EXTN: DW NM_EXTN_A +NM_PATH: DW NM_PATH_A +NM_DRIVE_A: BLOCK 9,0 +NM_NAME_A: DB " ",#00 ; 12 пробелов +NM_EXTN_A: DB " ",0 +NM_PATH_A EQU CORE_BUFFERS.BUFFER ;DS 256 ;!!!!! shared buffer + + diff --git a/Crazy Estex DSS/DSS/API/Execute.ASM b/Crazy Estex DSS/DSS/API/Execute.ASM new file mode 100644 index 0000000..7f22599 --- /dev/null +++ b/Crazy Estex DSS/DSS/API/Execute.ASM @@ -0,0 +1,804 @@ + +;[BEGIN] +;//MODULE: EXECUTE +;//CREATE: 19-05-1998 AUTHOR: Denis Parinov +;//UPDATE: 24-10-1999 DNS Restore module +;------------------------------------------------------------------------------------------------------------------------- +;Rev Date Name Description +;------------------------------------------------------------------------------------------------------------------------- +;R12 20-07-2023 BAO При завершении приложения "аварийно" в возвращаемое приложение передаётся код ошибки и флаг CF=1 +;R11 17-04-2023 BAO OPTIMIZED BUFFERS, FREED UP 768 BYTES FOR CODE +;R09 -- 14-04-2003 DNS NOW EXEC DON'T FOLLOW TO PROGRAM'S DIR +;R08 05-12-2002 DNS FIX BUG WITH INCREMENT TASK ID AND OPEN *.EXE ERROR +;R07 05-12-2002 DNS FIX FOR EXECUTING IN CURRENT DIR WITHOUT PATH +;R06 02-12-2002 DNS FIX BUG WITH NULL-TERMINATED STRING +;R05 02-12-2002 DNS ADD APP_PATH TO THE PROGRAM PREFIX +;R04 26-11-2002 DNS TRY TO FIX EXEC WITH PATH +;R03 19-11-2002 DNS CHECK SUBFN. FOR FN. EXEC +;R02 24-05-1999 DNS FIX CREATE PSP AND +; MOVE EXEC STACK +; 14-05-1999 DNS DECREASE HEADER SIZE FOR EXE-FILE +;------------------------------------------------------------------------------------------------------------------------- +RELATIVE_DIR EQU 0 +ABSOLUTE_DIR EQU 1 + + MACRO _mINCTASK + LD HL,TASK ;R08 + INC (HL) ;R08 + ENDM +; + MACRO _mDECTASK + LD HL,TASK ;R08 + DEC (HL) ;R08 + ENDM +;------------------------------------------------------------------------------------------------------------------------- + +;;; +;TMP_CURDIR_AUTO EQU #FB00 +; не нужно если SAVE_PATH_MACRO = 1 +; TMP_CURDIR EQU #FD00 + + +;/////////////////////////////////////////////////////////////////////// +; Функция #40. Выполнить файл. +; +; вход: HL - указатель на имя файла +; B=0 - загрузить и выполнить программу с коротким именем (без полного пути до программы) +; B=1 - загрузить и выполнить программу с полным путём до программы +; выход: A - код завершения, если CF=0 +; код ошибки, если CF=1 +;--------------------------------------------------------------------- +; Загрузить и выполнить программу. +; функ. #40, B=0. +; +; 1) Открывает exe-файл на чтение; +; 2) Считывает в рабочую область префикс exe-файла; +; 3) Выделяет блок памяти, требуемый для загрузки всего файла или первичного +; загрузчика, если его размер не равен нулю; +; 4) Сохраняет стек; +; 5) Подключает страницы из выделенного блока; +; 6) Строит префикс запуска программы и устанавливает на него регистр IX; +; 7) Считывает файл по адресу указанному в смещении 16 (Адрес расположения +; кода в памяти); +; 8) Закрывает exe-файл, если это не первичный загрузчик; +; 9) Устанавливает стек равным значению из смещения 20 (Адрес расп. стека); +; 10) Передает управление по адресу указанному в смещении 18 (Адрес запуска); +; +; Префикс запуска файла: +; +; -03 1 db ? ; Дескриптор файла, если exe-файл с первичным загрузчиком +; -02 1 db ? ; Идентификатор блока памяти +; -01 1 db ? ; Уровень текущей программы +; +00 1 db ? ; Длина ком-строки +; +01 127 ds ? ; Параметры ком-строки, заканчивается нулем +;/////////////////////////////////////////////////////////////////////// +EXEC: LD (CMDLINE),HL + INC B ;R03 + DEC B ;R03 + JR Z,.VAR_1 ;R03 + DEC B ;R03 + JR Z,.VAR_2 ;R03 + LD A,DSS_Error.sys.INVALID_FUNCTION ;R03 + SCF ;R03 + RET ;R03 + ; +.VAR_1: ;LD (CMDLINE),HL + CALL CHECKPATH ;CHECK FOR '\' - SHORT/FULL NAME + ;LD HL,(CMDLINE) + JR C,EXEC0_SHORT +.VAR_2: CALL EXEC_1 + LD A,DSS_Error.sys.FILE_NOT_FOUND + SCF + RET ; File not found - exit + + ; при выходе с ошибкой, в регистре А - код ошибки +EXEC_1: ;LD (CMDLINE),HL + LD HL,(CMDLINE) + LD A,FAT_ATTR.READ_ONLY + LD (OPEN_FN.TMP),A + CALL GETWORD + RET C + ; LD HL,TMPNAME + ; LD DE,MASKARE + CALL MASK + RET C + CALL TST_EXT + ;LD A,DSS_Error.sys.FILE_NOT_FOUND + RET C + _mINCTASK ;R08 + CALL OPEN_FN.FILE + JR C,.Error + POP HL ; убираем лишний адрес_возврата_в_вызвавшую_процедуру + JP EXEC02 ;R07 CONTINUE EXECUTING PROGRAM +.Error: _mDECTASK ;R08 + AND A + RET + ;JR NC,.noError + ;_mDECTASK ;R08 + ;AND A + ;RET + ; +;.noError: + ;POP HL ; убираем лишний адрес_возврата_в_вызвавшую_процедуру + ;JP EXEC02 ;R07 CONTINUE EXECUTING PROGRAM + ; + ;SHORT NAME + ;TRY TO FIND IN CURRENT DIRECTORY +EXEC0_SHORT: ; если убрать, то будет как в linux - короткое имя запускает EXE только из прописанных директорий, + ; а если нужно запустить файл из текущей директории, то так: ".\run.exe" + CALL EXEC_1 + RET C + ; + ;FILE NOT FOUND, SEARCHING IN PATH + ; GET PATH AND ETC. + LD HL,ENVPATH + LD DE,ENVPAGE.ENVTEMP + LD B,high Dss.Environ.Get + CALL ENVIRON + LD HL,(CMDLINE) + LD DE,CORE_BUFFERS.EXEBUFF +COPYEXN: LD A,(HL) + LDI + OR A + JR NZ,COPYEXN + + CALL FINDPATH + ;[x] 1/10/2023 + LD A,DSS_Error.sys.FILE_NOT_FOUND + RET C + ; + LD HL,(CMDLINE) + JR EXEC.VAR_2 + ; +EXEC02: LD (EXE_FM),A + LD HL,CORE_BUFFERS.EXEBUFF + LD DE,_sEXE_HEADER.UnUsedPoint ; #0080 ;!#0200(512) ;R02 + LD A,(EXE_FM) + CALL READ + JP C,ERREXE + LD IX,CORE_BUFFERS.EXEBUFF + LD HL,(CORE_BUFFERS.EXEBUFF.EXE_EXT) + LD DE,'E'+'X'*256 + ;AND A - не нужно, если бы был CF=1, то чуть выше мы бы ушли на JP C,ERREXE + SBC HL,DE + LD A,DSS_Error.sys.INVALID_EXE + SCF + JP NZ,ERREXE + ;!TEST + ;LD A,(CORE_BUFFERS.EXEBUFF.VERSION) + ;OR A + ;LD A,DSS_Error.sys.UNKNOWN_EXE + ;SCF + ;JP NZ,ERREXE + LD A,MINIMUM_EXE_VERSION + CP (IX + _sEXE_HEADER.VERSION) + LD A,DSS_Error.sys.UNKNOWN_EXE + JP C,ERREXE + ; + ; + LD DE,(CORE_BUFFERS.EXEBUFF.LOADER) + LD A,E + OR D + JP NZ,PRELOAD + ; A=0 + LD H,A + LD L,A + LD XL,A + LD XH,A + ; + LD B,high Dss.Move_FP.FrEnd + LD A,(EXE_FM) + CALL MOVE_FP + LD DE,(CORE_BUFFERS.EXEBUFF.LD_ADDR) + LD A,D + AND #3F + LD D,A + ADD IX,DE + ;!TEST + JR NC,.no_inc_hl + INC HL + ;LD DE,#0000 + ;ADC HL,DE + ; +.no_inc_hl: LD A,XH + SLA A + RL L + RL H + SLA A + RL L + RL H + OR XL + JR Z,.NOINK + INC HL +.NOINK: LD A,H + OR A + JP NZ,ERREXE0 + LD B,L + + LD HL,.RET_1 + LD (_ret),HL + JP _TST_PROC + ; +.RET_1: LD DE,(CORE_BUFFERS.EXEBUFF.LD_ADDR) + XOR A + LD H,A + LD L,A + SBC HL,DE + EX DE,HL ; de=число чит. байт + LD HL,(CORE_BUFFERS.EXEBUFF.LD_ADDR) ; буфер + LD A,(EXE_FM) ; дескр. файла + CALL READ ; чтение из файла + ;!TEST ;[x] no close source EXE file before start 08/11/23 + ; LD A,(EXE_FM) ; дескр. файла + ; CALL CLOSE ; закрыть файл + ; + JP _TST_PROC_2 + ; +RETFAR: LD B,DSS_Error.sys.UNEXPECTED_APP_TRMN + JP LEAVE ; завершить программу (процесс) + +;------------------------------------------------- +; Если расш. файла не задано, задать "exe". +; Если расш. файла задано, сравнить его с "exe". +;------------------------------------------------- +TST_EXT: LD HL,EXE_EXT ; "EXE" + LD DE,MASKARE+8 + LD B,3 + LD A,(DE) + CP ' ' + JR NZ,.loop ; задано расш. + LDI + LDI + LDI + XOR A + RET + ; сравнить расш. с "EXE" +.loop: LD A,(DE) + CP (HL) + SCF + RET NZ ; не совпадает + INC HL + INC DE + DJNZ .loop + XOR A ; Ok + RET + ; +ERREXE0: LD A,DSS_Error.sys.NOT_ENOUGH_MEMORY +ERREXE: PUSH AF + LD A,(EXE_FM) + CALL CLOSE_FN + _mDECTASK + POP AF + RET + ;!TODO сравнить с EXEC02 +PRELOAD: EX DE,HL + LD DE,(CORE_BUFFERS.EXEBUFF.LD_ADDR) + LD A,D + AND #3F + LD D,A + ADD HL,DE + XOR A + SLA H + RLA + SLA H + RLA + LD B,A + LD A,H + OR L + JR Z,NOINK2 + INC B +NOINK2: LD HL,_RET_2 + LD (_ret),HL + JR _TST_PROC + ; +_RET_2: LD HL,(CORE_BUFFERS.EXEBUFF.LD_ADDR) ; буфер + LD DE,(CORE_BUFFERS.EXEBUFF.LOADER) ; число чит. байт + LD A,(EXE_FM) ; дескр. файла + CALL READ ; чтение из файла + JP _TST_PROC_2 +;-------------------------------------------------------------------;[ ] +_TST_PROC: CALL GETMEM + JP C,ERREXE0 + LD (EXE_MEM),A + EXX + POP DE ;снимаем со стека адрес возврата + LD HL,#0000 + ADD HL,SP + LD SP,(EXSTACK) + ; ! Далее стек в нулевой странице! BIOS и не DSS-MAIN не вызывать + PUSH HL ; +2 EXSTACK size for 1 task + PUSH DE ; +2 + ; + IF OLD_DSS_FOR_OLD_EXE + ; [ ] 10/06/24 + LD A,(EXE_VERSION) + PUSH AF ; +2 + ; + ENDIF + ; + IN A,(SLOT3) + LD D,A + IN A,(SLOT2) + LD E,A + IN A,(SLOT1) + PUSH DE ; +2 + PUSH AF ; +2 + LD (EXSTACK),SP + LD SP,HL + ; ; + EXX + ; + ;!TEST 27/03/2024 + LD DE,RAMMAP+3 + LD A,(EXE_MEM) + LD BC,4*256 + BIOS.GetMemPage +.mem_loop: PUSH AF + PUSH BC + DEC B + RST ToBIOS + LD (DE),A + DEC DE + POP BC + POP AF + DJNZ .mem_loop + ; + ; LD DE,RAMMAP + ; ; + ; LD A,(EXE_MEM) + ; LD BC,0*256 + BIOS.GetMemPage + ; RST ToBIOS + ; LD (DE),A + ; INC DE + ; ; + ; LD A,(EXE_MEM) + ; LD BC,1*256 + BIOS.GetMemPage + ; RST ToBIOS + ; LD (DE),A + ; INC DE + ; ; + ; LD A,(EXE_MEM) + ; LD BC,2*256 + BIOS.GetMemPage + ; RST ToBIOS + ; LD (DE),A + ; INC DE + ; ; + ; LD A,(EXE_MEM) + ; LD BC,3*256 + BIOS.GetMemPage + ; RST ToBIOS + ; LD (DE),A + ; + ; + LD HL,(CMDLINE) + LD DE,CORE_BUFFERS.SECTOR_BUFFER+1 + CALL SCOPYS + LD A,#80 ;!HARDCODE cmd line size + SUB B + LD (CORE_BUFFERS.SECTOR_BUFFER),A + ; + LD SP,CORE_BUFFERS.EXEBUFF + _sEXE_HEADER ;R02 + ; ! Далее стек в нулевой странице! BIOS и не DSS-MAIN не вызывать + LD A,SHARED_PAGE + OUT (SLOT1),A + OUT (SLOT2),A + OUT (SLOT3),A + LD HL,(CORE_BUFFERS.EXEBUFF.LD_ADDR) + LD DE,RAMMAP + LD A,H + AND #C0 + ;!TEST + CP #80 + JR Z,FR8000 + JR NC,FRC000 + ; +FR4000: LD A,(DE) + OUT (SLOT1),A + INC DE +FR8000: LD A,(DE) + OUT (SLOT2),A + INC DE +FRC000: LD A,(DE) + OUT (SLOT3),A + CALL M_PSP + ; + LD HL,(CORE_BUFFERS.EXEBUFF.OFFCOD2) + LD IX,(CORE_BUFFERS.EXEBUFF.OFFCOD1) + LD B,high Dss.Move_FP.FrStart + LD A,(EXE_FM) + CALL MOVE_FP + ; + LD SP,#403F ;R02 ;!HARDCODE STACK before start EXE. Устанавливается когда воткнуты SHARED_PAGE +_ret+1: JP 0 + +_TST_PROC_2: LD SP,(CORE_BUFFERS.EXEBUFF.SP_REG) + LD HL,(CORE_BUFFERS.EXEBUFF.LD_ADDR) + LD DE,#0080 ;!HARDCODE CLP_Buffer + XOR A + SBC HL,DE + EX DE,HL + LD XH,D + LD XL,E + LD HL,(CORE_BUFFERS.EXEBUFF.PC_REG) + LD DE,RETFAR ; адрес п/п "неожиданное завершение процесса" + PUSH DE + PUSH HL + ;!TEST Current Dir ;[x] 15/10/23 + PUSH IX + LD HL,CORE_BUFFERS.CurrentPath + LD A,(CORE_BUFFERS.EXEBUFF.VERSION) + ; + IF OLD_DSS_FOR_OLD_EXE + ; [ ] 10/06/24 + LD (EXE_VERSION),A + ; + ENDIF + OR A + JR NZ,.set_path + CALL DIR_PATH_CHANGE.FullCurrent +.set_path: CALL CHDIR_FN + POP IX + ; + RET +;----------------------------------------------------------------------- +; ! вызывается когда стек в нулевой странице! +M_PSP: LD HL,(CORE_BUFFERS.EXEBUFF.LD_ADDR) + DEC H + LD D,H + LD E,L + INC DE + LD BC,#00FF ;!HARDCODE + LD (HL),B + LDIR + EX DE,HL + DEC H + LD DE,#0080 + ADD HL,DE + EX DE,HL + LD XH,D + LD XL,E + LD HL,CORE_BUFFERS.SECTOR_BUFFER + LD C,(HL) + INC C + LDIR + EX DE,HL ;R06 + LD (HL),B + LD A,(TASK) + LD (IX-1),A + LD A,(EXE_MEM) + LD (IX-2),A + LD A,(EXE_FM) + LD (IX-3),A + ;R05 + INC HL + LD (HL),B + INC HL + ;!FIXIT тут восстанавливать правильный каталог + CALL CURDISK + ADD A,'A' + LD (HL),A + INC HL + LD A,':' + LD (HL),A + INC HL + PUSH HL + CALL CURRDIR + ; + POP HL + XOR A + LD BC,#0100 ;!FIXIT нет привязки к CurrentDirectory.DEPTH + CPIR ;!FIXIT нет проверки на выход по BC=0 + DEC HL + DEC HL + LD A,'\' ; + CP (HL) + INC HL + JR Z,.YP_ESLA + LD (HL),A + INC HL +.YP_ESLA: EX DE,HL + LD HL,TMPNAME +.loop: LD A,(HL) + LDI + CP ' '+1 + JR NC,.loop + DEC DE + XOR A + LD (DE),A + LD (APPINFO.LAST_PSP_PTR),IX + ; + RET + ; +SCOPYS: LD BC,#80*256 + ' '+1 ;!HARDCODE cmd line size +.loop: LD A,(HL) + CP C + JR C,.copy + INC HL + DJNZ .loop + XOR A + LD (DE),A + LD B,#80 + RET + ; +.copy: LD BC,#80*256 + ' ' ;!HARDCODE cmd line size +.loop2: LD A,(HL) + LD (DE),A + INC HL + INC DE + CP C + RET C + DJNZ .loop2 + RET +;--------------------------------------------------------------------- +ENVPATH: DB "PATH=",0 +EXE_EXT: DB "EXE" +TASK: DB #01 ; уровень текущей программы +; + IF OLD_DSS_FOR_OLD_EXE +EXE_VERSION: DB #01 ; [ ] 10/06/24 + ENDIF +RAMMAP: DB #00,#00,#00,#00 +ErrorLevel: DB #00 ; код завершения программы (процесса) +EXE_FM: DB #00 ; дескр. файла +EXE_MEM: DB #00 ; идентификатор блока памяти +CMDLINE: DW #0000 +EXSTACK: DW CORE_BUFFERS.XSTACK.Spoint ; адрес стека +;///////////////////////////////////////////////////////////////////// + + + +;///////////////////////////////////////////////////////////////////// +; Функция #41. Завершить программу (процесс). +; +; вход: B - код завершения +; выход: A - код ошибки, если CF=1 +; +; Выход из EXE-файла: +; +; 1) Освобождаются все блоки памяти которые выделялась данному приложению. +; 2) Восстанавливаются страницы которые были подключены до запуска EXE-файла. +; 3) Вспоминается стек. +; 4) В регистр A помещается код возврата и выполняется RET. +; +;///////////////////////////////////////////////////////////////////// +LEAVE: LD A,B + LD (ErrorLevel),A + CALL FREE_PROCESS_MEMORY + ;[x] 10/12/23 close EXE FMs + CALL FREE_PROCESS_FMs + ; + _mDECTASK + LD SP,(EXSTACK) + ; тут стек в нулевой странице! + POP AF ; -2 EXSTACK size for 1 task + POP HL ; -2 + OUT (SLOT1),A + LD A,L + OUT (SLOT2),A + LD A,H + OUT (SLOT3),A + ; [ ] 10/06/24 + IF OLD_DSS_FOR_OLD_EXE + POP AF ; -2 + LD (EXE_VERSION),A + ENDIF + ; + POP DE ; -2 + POP HL ; -2 + LD (EXSTACK),SP + LD SP,HL + ; + ;!TEST + ;EI + ; + EX DE,HL + LD A,(ErrorLevel) + ;R12 + CP DSS_Error.sys.UNEXPECTED_APP_TRMN + JR Z,.error_exit + CP DSS_Error.sys.USER_ABORT + JR NZ,.norm_exit +.error_exit: SCF + JP (HL) + ; +.norm_exit: AND A + JP (HL) +;///////////////////////////////////////////////////////////////////// + +;///////////////////////////////////////////////////////////////////// +; Функция #42. Получить код завершения программы. +; +; вход: нет +; выход: A - код завершения +;///////////////////////////////////////////////////////////////////// +GET_ERR: LD A,(ErrorLevel) + AND A + RET +;///////////////////////////////////////////////////////////////////// + +;----------------------------------------------------------------------- +FREE_PROCESS_MEMORY: + ;LD HL,MEMTAB + LD HL,CORE_BUFFERS.MemoryTable ; массив списка выдел. страниц + LD BC,256 ;!HARDCODE размер блока страниц ОЗУ +.loop: LD A,(TASK) + CPIR + RET NZ + PUSH HL + PUSH BC + DEC HL + AND A + ;LD DE,MEMTAB + LD DE,CORE_BUFFERS.MemoryTable ; массив списка выдел. страниц + SBC HL,DE + LD A,L + CALL RETMEM ; освоб. блок памяти + POP BC + POP HL + JP .loop +;----------------------------------------------------------------------- + + +;----------------------------------------------------------------------- +FREE_PROCESS_FMs: + LD IY,CORE_BUFFERS.FM_BUF - CORE_BUFFERS.FM_BUF.Size + LD DE,CORE_BUFFERS.FM_BUF.Size + LD B,FMCOUNT+1 + LD A,(TASK) +.loop: ADD IY,DE + CP (IY+_sFM.TASK_NUM) + JR NZ,.next + ; close fm + PUSH AF + XOR A + OR (IY+_sFM.TASK_NUM) + JR Z,.skip + PUSH IY + PUSH DE + LD A,FMCOUNT+1 + SUB B + CALL CLOSE_FN + POP DE + POP IY +.skip: POP AF + ; +.next: DJNZ .loop + RET + ; +;----------------------------------------------------------------------- + + +;----------------------------------------------------------------------- +CHECKPATH: ; !TODO сделать проверку на количество циклов + LD A,(HL) + INC HL + CP '\' + RET Z + ; CP '/' ;ALT SLASH + ; RET Z + CP " "+1 + JR NC,CHECKPATH + RET +;----------------------------------------------------------------------- + + +;----------------------------------------------------------------------- +FINDPATH: + SET_PAGE_X ENVPAGE + PUSH AF + ;!TEST + ;CALL CURRDSK_FN + ;ADD A,"A" + ;LD HL,TMP_CURDIR + ;LD (HL),A + ;INC HL + ;LD A,":" + ;LD (HL),A + ;INC HL + ;CALL CURRDIR_FN + ; + CALL .MAKE_PATH_ARRAY + LD HL,ENVPAGE.PATH_PNT_ARRAY +.NEXTPATHI: + LD E,(HL) + INC HL + LD D,(HL) + INC HL + BIT ABSOLUTE_DIR,(HL) + INC HL + PUSH HL + PUSH BC + EX DE,HL + CALL Z,.GOTO_CURDIR + CALL NZ,CHDIR + JR C,.BADPATH + LD HL,CORE_BUFFERS.EXEBUFF + CALL MASK.name + JR C,.BADPATH + CALL TST_EXT + JR C,.BADPATH + CALL SEARCH.File +.BADPATH: + POP BC + POP HL + JR NC,.PATHFOUND + DJNZ .NEXTPATHI + SCF +.PATHFOUND: + POP BC + LD A,B + OUT (SLOT3),A + LD A,DSS_Error.sys.PATH_NOT_FOUND + RET +.GOTO_CURDIR: + PUSH AF + PUSH HL + LD HL,CORE_BUFFERS.CurrentDirectory + CALL CHDIR + POP HL + POP AF + RET +.MAKE_PATH_ARRAY: + LD HL,ENVPAGE.PATH_PNT_ARRAY-1 ;R04 -1 + LD DE,ENVPAGE.ENVTEMP-1 + LD B,#00 +.NEXTAR: + LD (HL),C ;R04 + INC HL ;R04 + XOR A + LD (DE),A + LD C,A + INC DE + LD (HL),E + INC HL + LD (HL),D + INC HL +;R04 LD (HL),C +;R04 INC HL + INC B +.NEXTRT: + LD A,(DE) + CP '\' + JR NZ,.NEXTCH +.NEXTDR: + SET ABSOLUTE_DIR,C +.NEXTRL: + ;SET RELATIVE_DIR,C ;!TODO ???? +.NEXTCH: + LD A,(DE) + CP ";" + JR Z,.NEXTAR + INC DE +; CP "." +; JR Z,NEXTRL + CP ":" + JR Z,.NEXTRT + OR A + JR NZ,.NEXTCH + LD (HL),C ;R04 + INC HL ;R04 + LD (HL),A + INC HL + LD (HL),A + RET +;----------------------------------------------------------------------- + + +;R11 \\\\\\\\\\\\\\\\\\\\\\\\\\\\ +;; +; EXEBUFF: +; DB "EXE" +; DB #00 +; OFFCOD1 DW #0000 +; OFFCOD2 DW #0000 +; LOADER DW #0000 +; DW #0000 +; DW #0000 +; DW #0000 +; LD_ADDR DW #0000 +; PC_REG DW #0000 +; SP_REG DW #0000 +; BLOCK 512-($-EXEBUFF),0 +; ;(!!!HERE STACK FOR EXEC!!!) +; BLOCK 255,0 +; XSTACK DB #00 +;R11 //////////////////////////// +; \ No newline at end of file diff --git a/Crazy Estex DSS/DSS/API/Find.asm b/Crazy Estex DSS/DSS/API/Find.asm new file mode 100644 index 0000000..b25fa19 --- /dev/null +++ b/Crazy Estex DSS/DSS/API/Find.asm @@ -0,0 +1,132 @@ +//////////////////////////////////////////////////////////////////////// +;Входные значения: +; C - #19 +; HL - указатель на файловую спецификацию +; DE - рабочий буфер 44 байта, если B=0, иначе 256 байт +; A - атрибуты, используемые при поиске +; B = #00 - имя найденного файла в формате 11 байт "FilenameExt" +; B = #01 - имя найденного файла в формате DOS "filename.ext",0 +; поиск без ограничение на размер каталога: +; !TODO B = #02 - имя найденного файла в формате DOS + LFN +; !TODO B = #80 - имя найденного файла в формате 11 байт "FilenameExt" +; !TODO B = #81 - имя найденного файла в формате DOS "filename.ext",0 +;Выходные значения: +; A - код ошибки, если CF=1 +//////////////////////////////////////////////////////////////////////// +F_FIRST_FN: CALL F_FIRST.INIT_VARS + PUSH HL + ;!TEST Current Dir ;[x] 15/10/23 + ; [ ] 10/06/24 + IF OLD_DSS_FOR_OLD_EXE + LD A,(EXE_VERSION) + OR A + JR Z,.old_EXE + ENDIF + ; + CALL DIR_PATH_CHECK + RET C + ; +.old_EXE: POP HL + JR F_FIRST.begin + ; +F_FIRST: CALL .INIT_VARS +.begin: CALL GETWORD + ;CALL LOADDIR + RET C + CALL MASK + RET C + LD A,(.TMP) + CALL SEARCH.Custom + RET C + LD HL,MASKARE +.DTABUF+1: + LD DE,0 + LD BC,11 ;!HARDCODE + LDIR +.TMP+1: LD A,0 + LD (DE),A +.FIND_S: + INC DE + ;!TODO лучше тут использовать как в record index для перебора каталога > #4000 bytes + LD BC,FAT_DIRECTORY_RECORD + ADD IX,BC + LD (F_NEXT.CURHND),IX + LD HL,HANDBUF+12 ;!HARDCODE + LD BC,HANDBUF.SIZE-12 ;????? метку вместо числа? + LDIR + LD A,(HANDBUF + FAT_DIRECTORY_RECORD.ATTRIBUT) + LD (DE),A + INC DE + LD HL,HANDBUF +.FNDMODE+1: + LD A,0 + OR A + JR NZ,.FIND_M2 + LD BC,11 ;!HARDCODE + LDIR +.exit: LD A,F_NEXT.NO_NEXT.NO + LD (F_NEXT.NO_NEXT),A + XOR A + RET +.FIND_M2: + ;!TODO LFN + ;CP 2 + ;CALL NC,GetName_LFN + ;CALL C,GetName + ; + CALL GetName + JR .exit + ; +.INIT_VARS: + LD (.TMP),A + LD (.DTABUF),DE + LD A,B + LD (.FNDMODE),A + RET +//////////////////////////////////////////////////////////////////////// +; +; +//////////////////////////////////////////////////////////////////////// +F_NEXT: +.NO_NEXT.YES EQU 0 +.NO_NEXT.NO EQU #FF +.NO_NEXT+1: + LD A,0 + OR A + LD A,DSS_Error.sys.INVALID_ACCESS + SCF + RET Z + LD (F_FIRST.DTABUF),DE + EX DE,HL + LD DE,MASKARE + LD BC,11 ;!HARDCODE + LDIR + + XOR A ; F_NEXT.NO_NEXT.YES + LD (F_NEXT.NO_NEXT),A + + LD A,(HL) + PUSH HL + CALL .NSEARCH + POP DE + RET C + JP F_FIRST.FIND_S +.NSEARCH: + EX AF,AF' + SET_PAGE_X DIRPAGE + ;PUSH AF + EX AF,AF' + CPL + LD C,A + ;!TEST 9/11/23 record index + ; EXX + ; LD DE,0 + ; EXX + ; +.CURHND+2: + LD IX,0 + LD A,XH + OR XL + JP Z,SEARCH.error_too_many_files + JP SEARCH.loop +; \ No newline at end of file diff --git a/Crazy Estex DSS/DSS/API/FreeMem.asm b/Crazy Estex DSS/DSS/API/FreeMem.asm new file mode 100644 index 0000000..0b8bf33 --- /dev/null +++ b/Crazy Estex DSS/DSS/API/FreeMem.asm @@ -0,0 +1,10 @@ +////////////////////////////////////////////////////////////////////// +; Функция #3C. Информация о памяти. +; +; вход: нет +; выход: HL - общее кол-во страниц +; BC - кол-во своб. страниц +////////////////////////////////////////////////////////////////////// +FREEMEM: LD C,BIOS.GetMemSize + JP ToBIOS +; \ No newline at end of file diff --git a/Crazy Estex DSS/DSS/API/GSwitch.asm b/Crazy Estex DSS/DSS/API/GSwitch.asm new file mode 100644 index 0000000..0d5ce7b --- /dev/null +++ b/Crazy Estex DSS/DSS/API/GSwitch.asm @@ -0,0 +1,31 @@ +////////////////////////////////////////////////////////////////////// +; Функция #43. Выделить параметр командной строки. +; +; вход: HL - указатель командной строки +; DE - буфер для выдел. параметра +; выход: HL - указатель на след. параметр ком-строки +; CF=0 - конец строки не достигнут (есть другие параметры) +; CF=1 - конец строки (в буфер перенесён последний параметр или ноль) +; +;ENTRY: HL - COMMAND LINE +; DE - SWITCH BUFFER +;EXIT: BUFFER +////////////////////////////////////////////////////////////////////// +GSWITCH: XOR A + LD (DE),A +.loop1: LD A,(HL) + INC HL + CP " " + RET C + JR Z,.loop1 +.loop2: LD (DE),A + LD A,(HL) + INC HL + INC DE + CP " "+1 + JR NC,.loop2 + CP " " + LD A,0 + LD (DE),A + RET +; \ No newline at end of file diff --git a/Crazy Estex DSS/DSS/API/GetDateTime.asm b/Crazy Estex DSS/DSS/API/GetDateTime.asm new file mode 100644 index 0000000..6cdec69 --- /dev/null +++ b/Crazy Estex DSS/DSS/API/GetDateTime.asm @@ -0,0 +1,24 @@ +//////////////////////////////////////////////////////////////////////// +; Функция #17. Информация о дате и времени файла. +; +; вход: A - дескриптор файла +; выход: D - день +; E - месяц +; IX - год +; H - час +; L - минуты +; B - секунды +; A - код ошибки, если CF=1 +//////////////////////////////////////////////////////////////////////// +GET_D_T: + CALL SET_FM + RET C + ; время/дату из структуры дескр. + LD E,(IY+_sFM.FS_REC.TIME) ; время + LD D,(IY+_sFM.FS_REC.TIME+1) ; + LD C,(IY+_sFM.FS_REC.DATE) ; дата + LD B,(IY+_sFM.FS_REC.DATE+1) ; + CALL RMKTIME ; раскодировать время/дату + AND A + RET +; \ No newline at end of file diff --git a/Crazy Estex DSS/DSS/API/GetMem.asm b/Crazy Estex DSS/DSS/API/GetMem.asm new file mode 100644 index 0000000..9d30112 --- /dev/null +++ b/Crazy Estex DSS/DSS/API/GetMem.asm @@ -0,0 +1,21 @@ +////////////////////////////////////////////////////////////////////// +; Функция #3D. Выделение блока памяти. +; +; вход: B - размер блока в страницах по 16kB +; выход: A - идентификатор блока памяти, если CF=0 +; A - код ошибки, если CF=1 +////////////////////////////////////////////////////////////////////// +GETMEM: LD C,BIOS.GetMem + RST ToBIOS + LD E,A + LD A,DSS_Error.sys.NOT_ENOUGH_MEMORY + RET C + LD D,#00 + ;LD HL,MEMTAB ; массив списка выдел. страниц + LD HL,CORE_BUFFERS.MemoryTable ; массив списка выдел. страниц + ADD HL,DE + LD A,(TASK) ; уровень текущей программы + LD (HL),A + LD A,E + ;AND A + RET \ No newline at end of file diff --git a/Crazy Estex DSS/DSS/API/Lib_Sub.asm b/Crazy Estex DSS/DSS/API/Lib_Sub.asm new file mode 100644 index 0000000..48bb066 --- /dev/null +++ b/Crazy Estex DSS/DSS/API/Lib_Sub.asm @@ -0,0 +1,14 @@ +;[ ] 11/02/2024 - Функция с пополняемыми подфункциями))) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; B = 1 Вызов функции SETUP_CURSORS для восстановления системных шрифтов DSS ; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +LIB_SUB: + DJNZ .B_2 + ; func B = 1 + JP SETUP_CURSORS + ; +.B_2: ; func B > 1 or 0 + SCF + RET + ; +; \ No newline at end of file diff --git a/Crazy Estex DSS/DSS/API/MkDir.asm b/Crazy Estex DSS/DSS/API/MkDir.asm new file mode 100644 index 0000000..581ec75 --- /dev/null +++ b/Crazy Estex DSS/DSS/API/MkDir.asm @@ -0,0 +1,216 @@ +; [x] fat32 ;!TEST +//////////////////////////////////////////////////////////////////////// +; Функция #1B. Создание каталога. +; +; вход: HL - указатель на имя каталога +; выход: A - код ошибки, если CF=1 +; +; INPUT: HL - "C:\DIR\DIR\DIR_NAME",0 +//////////////////////////////////////////////////////////////////////// +MKDIR: +;error +.DIR_EXISTS: LD A,DSS_Error.sys.DIR_EXISTS + CCF + RET + ; +; Entry point ;!TEST Current Dir ;[x] 15/10/23 +.B: ; [ ] 10/06/24 + IF OLD_DSS_FOR_OLD_EXE + LD A,(EXE_VERSION) + OR A + JR Z,.START + ENDIF + ; + PUSH HL + CALL DIR_PATH_CHECK + POP HL + RET C + CALL .START + PUSH AF + LD HL,CORE_BUFFERS.CurrentDirectory + CALL CHDIR + POP AF + RET + ; +.START: CALL GETWORD ; тест на допуст. имя и настр. на диск + RET C + ; [ ] 26/06/2024 + CALL CHECK_64kb_CLUSTER + RET C + ; + CALL MASK + RET C + ;!TEST optimization ранее GETWORD уже загрузил директорию + ;CALL LOADDIR ; прочитать список каталога + ; + CALL SEARCH.Dir ; поиск записи каталога в списке диска + ; [x] fixed a bug with incorrect search when there were too many files in the directory 12/03/2024 + ; LD A,DSS_Error.sys.DIR_EXISTS + ; CCF + ; RET C ; каталог найден + JR NC,.DIR_EXISTS + CP DSS_Error.sys.FILE_NOT_FOUND + SCF + RET NZ + ; + CALL G_CLUST + RET C + ; fat32 + PUSH HL ; младший номер сектора + EXX + PUSH HL ; старший номер сектора + EXX + ; + XOR A ; уменьшить + CALL SET_NEW_FREE_CLUSTERS ; [ ] free clusters for FSInfo + ; + CALL WRITE_TO_FAT ; записать в кеш FAT-а номер кластера + CALL WRITE_FAT_TABLE ; подкл. банку кеша FAT и записать его на диск + LD HL,MASKARE + LD DE,HANDBUF + LD BC,11 + LDIR + EX DE,HL + LD A,FAT_ATTR.DIRECTORY ; атрибут записи каталога + ; FAT_DIRECTORY_RECORD.ATTRIBUT + LD (HL),A + INC HL + LD BC,#0800 ; b=счетчик + ; +.loop1: LD (HL),C + INC HL + DJNZ .loop1 + ; FAT_DIRECTORY_RECORD.FIRST_CLUSTER_H + ; fat32 запись старшего номера кластера .FIRST_CLUSTER_H + POP DE + PUSH DE ; старший номер сектора + LD (HL),E + INC HL + LD (HL),D + INC HL + ; + CALL WRITE_DATE_TIME_TO_DIRECTORY_RECORD + ; запись младшего номера кластера .FIRST_CLUSTER_L + POP BC ; старший номер сектора + POP DE ; младший номер сектора + PUSH DE + PUSH BC + ; FAT_DIRECTORY_RECORD.FIRST_CLUSTER_L + LD (HL),E + INC HL + LD (HL),D + INC HL + ; FAT_DIRECTORY_RECORD.F_SIZE + LD BC,#0400 ; b=счетчик +.loop2: LD (HL),C + INC HL + DJNZ .loop2 + ; + CALL WRT_HND ; скопир. новую запись в список диска (каталога) + ;CALL SAVEDIR ; и сбросить кеш каталога на диск + ; + ; создаём служебные каталоги "." и ".." в созданном каталоге + ; КАТАЛОГ "." + LD HL,CORE_BUFFERS.SECTOR_BUFFER ; буфер + LD (HL),"." ; запись тек. каталога + LD BC,10*256 + ' ' ; !HARDCODE b=счетчик, c=пробел + ; +.loop3: INC HL + LD (HL),C + DJNZ .loop3 + ; скопировать байты 11..31 FAT_DIRECTORY_RECORD + INC HL + LD DE,HANDBUF+FAT_DIRECTORY_RECORD.ATTRIBUT ; ячейка атрибутов файла + EX DE,HL + LD BC,21 ; !HARDCODE + LDIR + ; КАТАЛОГ ".." + EX DE,HL + LD (HL),"." ; запись родит. каталога + INC HL + LD (HL),"." + LD BC,9*256 + ' ' ; b=счетчик, c=пробел +.loop4: INC HL + LD (HL),C + DJNZ .loop4 + ; + INC HL + SET_PAGE_X DIRPAGE + PUSH AF + ; + LD DE,DIRPAGE.buffer + FAT_DIRECTORY_RECORD.ATTRIBUT ; атрибуты записи + ; + LD A,(DIRPAGE.buffer) + CP "." + JR Z,.copy_dir_record + ; + ;LD IX,HANDBUF + XOR A + LD (HANDBUF + FAT_DIRECTORY_RECORD.FIRST_CLUSTER_L),A + LD (HANDBUF + FAT_DIRECTORY_RECORD.FIRST_CLUSTER_L+1),A + LD (HANDBUF + FAT_DIRECTORY_RECORD.FIRST_CLUSTER_H),A + LD (HANDBUF + FAT_DIRECTORY_RECORD.FIRST_CLUSTER_H+1),A + LD DE,HANDBUF + FAT_DIRECTORY_RECORD.ATTRIBUT ; ячейка атрибутов файла +.copy_dir_record: + EX DE,HL + LD BC,HANDBUF.SIZE - FAT_DIRECTORY_RECORD.ATTRIBUT ; 21 + LDIR + POP AF + OUT (SLOT3),A + ; + EX DE,HL + LD D,H + LD E,L + INC DE + LD (HL),0 + LD BC,512-65 ;!HARDCODE sector size + LDIR + ; + POP HL ; старший номер сектора + EXX + POP HL ; младший номер сектора + CALL CLUSTER_TO_SECTOR + LD A,(CORE_BUFFERS.FatBuffer.SectorsPerCluster) ; секторов на кластер +.MKD12: PUSH AF + PUSH HL ; ст. разряд + PUSH IX ; номер лог. сектора + ; + ; IN A,(SLOT3) + ; PUSH AF + ; IN A,(SLOT0) + ; OUT (SLOT3),A + ; ; + ; LD A,(CORE_BUFFERS.FatBuffer.DRIVE) + ; LD DE,CORE_BUFFERS.SECTOR_BUFFER+#C000 + ; LD BC,1*256 + Dss.DRV.Write + ; RST ToDSS.DRV + ; ; + ; POP AF + ; OUT (SLOT3),A + CALL WRITE_SECTOR + ; !FIXIT нет проверки на ошибку + ; + LD HL,CORE_BUFFERS.SECTOR_BUFFER + ; [x] optimization + LD A,(HL) + OR A + JR Z,.skip_clean + ; + LD DE,CORE_BUFFERS.SECTOR_BUFFER+1 + LD BC,511 ;!HARDCODE sector size + LD (HL),0 + LDIR +.skip_clean: ; + POP IX + POP HL + INC IX + LD A,XH + OR XL + JR NZ,.MKD11 + INC HL +.MKD11 POP AF + DEC A + JR NZ,.MKD12 + AND A + RET +; \ No newline at end of file diff --git a/Crazy Estex DSS/DSS/API/Open.asm b/Crazy Estex DSS/DSS/API/Open.asm new file mode 100644 index 0000000..d0393f2 --- /dev/null +++ b/Crazy Estex DSS/DSS/API/Open.asm @@ -0,0 +1,97 @@ +; [x] fat32 ;!TEST +//////////////////////////////////////////////////////////////////////// +; Функция #11. Открытие файла. +; +; вход: HL - указатель на имя файла +; A - режим доступа: +; A=0 чтение/запись +; A=1 чтение +; A=2 запись +; ;!TODO A=3 запись без лишних сохранений кэша FAT +; ;!TODO A=4 записать кэш FAT +; выход: CF=0, A - дескриптор файла. +; CF=1, A - код ошибки. +//////////////////////////////////////////////////////////////////////// +OPEN_FN: ;!TEST Current Dir ;[x] 15/10/23 + ;AND #7F ; ACCESS_MODE bit7 - для внутреннего использования))) ;!TODO + LD (.TMP),A + ; [ ] 10/06/24 + IF OLD_DSS_FOR_OLD_EXE + LD A,(EXE_VERSION) + OR A + JR Z,.old_EXE + ENDIF + ; + PUSH HL + CALL DIR_PATH_CHECK.forceCheck + POP HL + RET C +.old_EXE: ;JR .start + ;!FIXIT сделать как в mkdir или rmdir? +;R008 ; +.start: CALL GETWORD + RET C + CALL MASK + RET C +.FILE: CALL SEARCH.File ; enter point from EXEC, CREATE + RET C +;R002 ;!TEST 9/11/23 record index +.FM: PUSH DE ; сохраняем указатель на запись в каталоге FS (получен из SEARCH) + ; + CALL GET_FM ; enter point from ATTRIB + RET C + LD A,C + EX AF,AF' + ;!TEST 9/11/23 record index указатель на запись в каталоге FS + POP DE + ; EXX + LD (IY+_sFM.HANDLE),E + LD (IY+_sFM.HANDLE+1),D + ; EXX + ; + LD D,YH + LD E,YL + LD HL,HANDBUF + LD BC,HANDBUF.SIZE + LDIR +.TMP+1: LD A,0 + LD (IY+_sFM.ACCESS_MODE),A + LD A,(TASK) + LD (IY+_sFM.TASK_NUM),A + XOR A + LD (IY+_sFM.OptimizedClusters),A + LD (IY+_sFM.KnownCluster_L),A + LD (IY+_sFM.KnownCluster_L+1),A + LD (IY+_sFM.KnownOffset_L),A + LD (IY+_sFM.KnownOffset_L+1),A + ; fat32 + LD (IY+_sFM.KnownCluster_H),A + LD (IY+_sFM.KnownCluster_H+1),A + LD (IY+_sFM.KnownOffset_H),A + LD (IY+_sFM.KnownOffset_H+1),A + ; + LD (IY+_sFM.F_POSITION),A + LD (IY+_sFM.F_POSITION+1),A + LD (IY+_sFM.F_POSITION+2),A + LD (IY+_sFM.F_POSITION+3),A + LD A,(CORE_BUFFERS.FatBuffer.DRIVE) + LD (IY+_sFM.DRIVE),A + ; fat32 + LD HL,CORE_BUFFERS.FM_BUF+_sFM.FS_REC.FIRST_CLUSTER_H + LD E,(HL) + INC HL + LD D,(HL) + LD (IY+_sFM.DIR_CLUSTER_H),E + LD (IY+_sFM.DIR_CLUSTER_H+1),D + ; + LD HL,CORE_BUFFERS.FM_BUF+_sFM.FS_REC.FIRST_CLUSTER_L ; work directory FM + LD E,(HL) + INC HL + LD D,(HL) + LD (IY+_sFM.DIR_CLUSTER_L),E + LD (IY+_sFM.DIR_CLUSTER_L+1),D + ; + EX AF,AF' + AND A + RET +; \ No newline at end of file diff --git a/Crazy Estex DSS/DSS/API/Print.asm b/Crazy Estex DSS/DSS/API/Print.asm new file mode 100644 index 0000000..c8585f7 --- /dev/null +++ b/Crazy Estex DSS/DSS/API/Print.asm @@ -0,0 +1,74 @@ +;/////////////////////////////////////////////////////////////////////// +; Функция #5F. Вывод символа на принтер без ожидания. +; +; Интерпретация байта состояния принтера: +; 0..2 - не используются, обычно уст. в "1" +; 3 - ошибка принтера - есть/нет (1/0) +; 4 - принтер подключен/не подключен (1/0) +; 5 - бумаги нет/есть (1/0) +; 6 - принтер готов/выводит очередной символ (1/0) +; 7 - принтер свободен/занят (1/0) +; +; вход: A - символ +; выход: B - символ +; CF - ошибка, A=байт состояния (биты 7..3) +;/////////////////////////////////////////////////////////////////////// +Z84_SP: +.LPT_A EQU Z84.SIO.Ch_B.Ctrl +.LPT_B EQU Z84.PIO.Port_A.Data +.LPT1_C EQU Z84.PIO.Port_A.Command +.LPT2_D EQU Z84.PIO.Port_B.Data +.LPT2_C EQU Z84.PIO.Port_B.Command +; +PRINT: AND A + LD B,A ; сохраняем символ + ; + LD A,R + DI + PUSH AF + ; reg 0 + XOR A + OUT (Z84_SP.LPT_A),A + LD A,%0001'0000 ; Reset EXT/STATUS interrupts + OUT (Z84_SP.LPT_A),A + XOR A + OUT (Z84_SP.LPT_A),A + IN A,(Z84_SP.LPT_A) ; IN (1Bh): bit 5 - busy, Bit 3 - Ack + LD C,A + BIT 5,A ; IN (19h): bit 5 - Paper Enable, Bit 3 - Select + JR NZ,.LPTBUSY + AND %11011000 + JR Z,.LPTBUSY + LD A,B ; восстанавливаем символ + OUT (Z84_SP.LPT_B),A + POP AF + RET PO + EI + RET + ; +.LPTBUSY: POP AF + LD A,C + SCF + RET PO + EI + RET +; ; ; + +; B - SYMBOL +; CF = 1 - PRINTER BUSY +PRINT_INIT: DI + LD A,#CF + ; port #1F только чеpез LD BC,1F : Out (BC),reg (в альтере идёт перехват этого порта проца, если он в команде явно указан) + LD BC,Z84_SP.LPT2_C + OUT (C),A + ;[x] 29/9/23 + ;LD A,#63 + LD A,63 + ; + OUT (C),A + LD A,#C0 ; Bit 7 - Select (1), Bit 6 - Auto_Line_Feed (1) + OUT (Z84_SP.LPT2_D),A + LD A,#0F ; Init printer port for Out + OUT (Z84_SP.LPT1_C),A + RET +;/////////////////////////////////////////////////////////////////////// \ No newline at end of file diff --git a/Crazy Estex DSS/DSS/API/Read.asm b/Crazy Estex DSS/DSS/API/Read.asm new file mode 100644 index 0000000..9ca4bae --- /dev/null +++ b/Crazy Estex DSS/DSS/API/Read.asm @@ -0,0 +1,171 @@ +; HL - BUFFER ADDRESS +; DE - BLOCK SIZE +; A - FM +READ: LD (.R_POINT),HL + LD (.S_POINT),HL + CALL SET_FM + RET C + CALL .TEST_SIZE + ; + LD A,D + OR E + JP Z,.NOREAD + ; + PUSH DE + LD A,(IY+_sFM.DRIVE) + CALL OPENDSK + JP C,.ERR_1 + CALL GET_OFFSET_IN_SECTORS + ; + JP NZ,.ROV1 +.ROV4: POP BC + PUSH BC + SRL B + JR Z,.ROV2 + LD (.SECTORH),HL + LD (.SECTORL),DE +.R_POINT+2: LD IX,0 + CALL BLOCK_READ + JP C,.ERR_1 + LD DE,(.R_POINT) +.PointerOnBuffer+1: + LD HL,0 // LD HL,(READMEM) + AND A + SBC HL,DE + LD C,H + LD B,0 + ADD HL,DE + LD (.R_POINT),HL + SRL C +.SECTORL+1: LD HL,0 // LD HL,(SECTORL) + ADD HL,BC + EX DE,HL +.SECTORH+1: LD HL,0 // LD HL,(SECTORH) + LD C,B + ADC HL,BC +.ROV2: POP BC + LD A,B + AND #01 + LD B,A + OR C + JP Z,.ROV6 + PUSH BC + LD IX,CORE_BUFFERS.BUFFER+#C000 + LD B,1 + IN A,(SLOT3) + PUSH AF + IN A,(SLOT0) + OUT (SLOT3),A + CALL BLOCK_READ + POP BC + LD C,SLOT3 + OUT (C),B + JP C,.ERR_1 + LD HL,CORE_BUFFERS.BUFFER + LD DE,(.R_POINT) + POP BC + LDIR + LD (.R_POINT),DE +.ROV6: LD HL,(.R_POINT) +.S_POINT+1: LD DE,0 + ;EX DE,HL + AND A + SBC HL,DE + PUSH HL + EX DE,HL + LD XH,D + LD XL,E + LD HL,0 + CALL MOVE_FP.F_current + POP DE +.NOREAD: ; +.COD+1: LD A,0 + OR A + RET + ; +.ROV1: PUSH BC + PUSH HL + PUSH DE + LD IX,CORE_BUFFERS.BUFFER+#C000 + LD B,1 + IN A,(SLOT3) + PUSH AF + IN A,(SLOT0) + OUT (SLOT3),A + CALL BLOCK_READ + POP BC + LD C,SLOT3 + OUT (C),B + POP HL + JP C,.ERR_3 + ; inc HL:DE + LD BC,1 + ADD HL,BC + EX DE,HL + POP HL + LD C,B + ADC HL,BC + ; + EXX + POP DE + LD HL,512 ;!HARDCODE sector size! + AND A + SBC HL,DE + LD B,H + LD C,L + POP HL + AND A + SBC HL,BC + JR NC,.ROV3 + ADD HL,BC + LD B,H + LD C,L + LD HL,0 ;!TODO можно тут упростить дальнейшую ветку? +.ROV3: PUSH HL + LD HL,CORE_BUFFERS.BUFFER + ADD HL,DE + LD DE,(.R_POINT) + LDIR + LD (.R_POINT),DE + EXX + JP .ROV4 + ; +.ERR_3: POP HL + POP HL +.ERR_1: POP BC + ;SCF + RET + ; +.TEST_SIZE: XOR A + LD (READ.COD),A + LD L,(IY+_sFM.F_POSITION) ;FP LOW + LD H,(IY+_sFM.F_POSITION+1) + ADD HL,DE + ; + EXX + ;LD DE,0 ;!TEST + LD L,(IY+_sFM.F_POSITION+2) ;FP HIGH + LD H,(IY+_sFM.F_POSITION+3) + ;!TEST + JR NC,.no_inc_hl + INC HL + ;ADC HL,DE + ; +.no_inc_hl: EXX ;HL':HL - NEW FP + ; + LD C,(IY+_sFM.FS_REC.F_SIZE) + LD B,(IY+_sFM.FS_REC.F_SIZE+1) ;SIZE LOW + AND A + SBC HL,BC + EXX + LD C,(IY+_sFM.FS_REC.F_SIZE+2) ;SIZE HIGH + LD B,(IY+_sFM.FS_REC.F_SIZE+3) + SBC HL,BC + EXX + RET C ;OK READ ALL + EX DE,HL + SBC HL,DE ;VERY BIG + EX DE,HL + LD A,#FF + LD (READ.COD),A + RET \ No newline at end of file diff --git a/Crazy Estex DSS/DSS/API/Rename.asm b/Crazy Estex DSS/DSS/API/Rename.asm new file mode 100644 index 0000000..4acb58f --- /dev/null +++ b/Crazy Estex DSS/DSS/API/Rename.asm @@ -0,0 +1,93 @@ +//////////////////////////////////////////////////////////////////////// +; Функция #10. Переименование файла. +; Глобальные символы * и ? в именах файлов не допускаются. +; +; вход: HL - указатель на старое имя файла +; DE - указатель на новое имя файла +; выход: A - код ошибки, если CF=1 +; +; INPUT: HL - "old_name.ext",#00 without simbols * ? +; DE - "new_name.ext",#00 without simbols * ? +//////////////////////////////////////////////////////////////////////// +RENAME: ;!TEST Current Dir ;[x] 15/10/23 + ; [ ] 10/06/24 + IF OLD_DSS_FOR_OLD_EXE + LD A,(EXE_VERSION) + OR A + JR Z,.old_EXE + ENDIF + ; + PUSH HL + PUSH DE + CALL DIR_PATH_CHECK.forceCheck + POP DE + POP HL + RET C + ; +.old_EXE: ; + ; !TODO воткнуть тут GETWORD, чтоб можно было удалять по относительным путям? + ; + ; [ ] 26/06/2024 + PUSH HL + CALL CHECK_64kb_CLUSTER + POP HL + RET C + + ; + PUSH DE + CALL MASK.name + POP DE + RET C + ;!TEST optimization + ;LD HL,MASKARE + ;LD BC,11 + ;LD A,"?" + ;CPIR + ;LD A,DSS_Error.sys.INVALID_NAME + ;SCF + CALL CHECK_NAME + ; + RET Z + PUSH DE + CALL LOADDIR ; прочитать список каталога + ;LD A,#33 + LD A,FAT_ATTR.NoSYSnoVolID + CALL SEARCH.Custom ; поиск записи в списке диска + POP HL + RET C + ;LD DE,MASKARE + CALL MASK.name + RET C + ;!TEST optimization + ;LD HL,MASKARE + ;LD BC,11 + ;LD A,"?" + ;CPIR + ;LD A,DSS_Error.sys.INVALID_NAME + ;SCF + CALL CHECK_NAME + ; + RET Z + PUSH IX + LD A,FAT_ATTR.NoSYSnoVolID + CALL SEARCH.Custom ; поиск записи в списке диска + POP IX + LD A,DSS_Error.sys.FILE_EXISTS + CCF + RET C + + SET_PAGE_X DIRPAGE + EX AF,AF' + ; + LD HL,MASKARE + LD D,XH + LD E,XL + LD BC,11 + LDIR + ; + CALL DELETE_LFN_RECORDS ; [ ] удаление записи LFN + ; + EX AF,AF' + OUT (SLOT3),A + JP SAVEDIR +; ; ; \ No newline at end of file diff --git a/Crazy Estex DSS/DSS/API/RetMem.asm b/Crazy Estex DSS/DSS/API/RetMem.asm new file mode 100644 index 0000000..4258bf2 --- /dev/null +++ b/Crazy Estex DSS/DSS/API/RetMem.asm @@ -0,0 +1,29 @@ +////////////////////////////////////////////////////////////////////// +; Функция #3E. Освобождение блока памяти. +; +; вход: A - идентификатор блока памяти +; выход: A - код ошибки, если CF=1 +////////////////////////////////////////////////////////////////////// +RETMEM: LD E,A + LD D,#00 + ;LD HL,MEMTAB ; массив списка выдел. страниц + LD HL,CORE_BUFFERS.MemoryTable ; массив списка выдел. страниц + ADD HL,DE + LD A,(TASK) ; уровень текущей программы + CP (HL) + LD A,DSS_Error.sys.INVALID_MEMORY_HND + SCF + RET NZ + ;PUSH DE + LD A,E + LD C,BIOS.FreeMem + RST ToBIOS + ;POP DE + LD A,DSS_Error.sys.INVALID_MEMORY_HND + RET C + ;LD HL,MEMTAB + LD HL,CORE_BUFFERS.MemoryTable + ADD HL,DE + XOR A + LD (HL),A + RET \ No newline at end of file diff --git a/Crazy Estex DSS/DSS/API/RmDir.asm b/Crazy Estex DSS/DSS/API/RmDir.asm new file mode 100644 index 0000000..4df8bfd --- /dev/null +++ b/Crazy Estex DSS/DSS/API/RmDir.asm @@ -0,0 +1,147 @@ +; [x] fat32 ;!TEST +//////////////////////////////////////////////////////////////////////// +; Функция #1C. Удаление каталога. +; Можно удалить только пустой каталог. +; +; вход: HL - указатель на имя каталога +; выход: A - код ошибки, если CF=1 +; +; INPUT: HL - "C:\DIR\DIR\DIR_NAME",0 +//////////////////////////////////////////////////////////////////////// +RMDIR: ;!TEST Current Dir ;[x] 15/10/23 + ; [ ] 10/06/24 + IF OLD_DSS_FOR_OLD_EXE + LD A,(EXE_VERSION) + OR A + JR Z,.START + ENDIF + ; + PUSH HL + CALL DIR_PATH_CHECK + POP HL + RET C + CALL .START + PUSH AF + LD HL,CORE_BUFFERS.CurrentDirectory + CALL CHDIR + CALL DIR_PATH_CHANGE.Current + POP AF + RET + ; +.START: CALL GETWORD + RET C + ; [ ] 26/06/2024 + CALL CHECK_64kb_CLUSTER + RET C + ; + CALL MASK + RET C + ;!TEST optimization + ;LD HL,MASKARE + ;LD BC,11 + ;LD A,"?" + ;CPIR + ;LD A,DSS_Error.sys.INVALID_NAME + ;SCF + CALL CHECK_NAME + ; + RET Z + CALL LOADDIR + CALL SEARCH.Dir + RET C + ; fat32 + LD HL,(HANDBUF+FAT_DIRECTORY_RECORD.FIRST_CLUSTER_H) + EXX + LD HL,(HANDBUF+FAT_DIRECTORY_RECORD.FIRST_CLUSTER_L) + PUSH IX ;!TODO record index. возможно, что может сломаться, если больше страницы + ; + ;!TODO Процедура полного вычитывания каталога (все кластеры). Можно задействовать в других местах +.read_dir_big_loop: + PUSH HL + EXX + PUSH HL + EXX + CALL CLUSTER_TO_SECTOR + LD A,(CORE_BUFFERS.FatBuffer.SectorsPerCluster) + LD B,A + ; начинаем вычитывать содержимое каталога посекторно +.read_dir_loop: ;PUSH AF + PUSH BC + PUSH HL + PUSH IX + ; + ; IN A,(SLOT3) + ; PUSH AF + ; IN A,(SLOT0) + ; OUT (SLOT3),A + ; ; + ; LD DE,CORE_BUFFERS.SECTOR_BUFFER+#C000 + ; LD BC,1*256 + Dss.DRV.Read + ; LD A,(CORE_BUFFERS.FatBuffer.DRIVE) + ; RST ToDSS.DRV + ; POP AF + ; OUT (SLOT3),A + CALL READ_SECTOR + ; !FIXIT нет проверки на ошибку + ; + ;!HARDCODE 16 * 32 = 512; 32 - размер записи, 512 - размер считанного сектора + LD B,16 + LD HL,CORE_BUFFERS.SECTOR_BUFFER +.check_dir_loop: + LD A,(HL) + OR A + JP Z,.dir_empty + CP "." + JR Z,.next_record + CP #E5 ;!HARDCODE байт удаления файла + JR Z,.next_record + LD DE,FAT_DIRECTORY_RECORD.ATTRIBUT ; смещ. до байта атрибутов + ADD HL,DE + LD A,(HL) + SBC HL,DE + AND FAT_ATTR.VOLUME_ID + SCF + JP Z,.error ;DIR NOT EMPTY +.next_record: LD DE,FAT_DIRECTORY_RECORD + ADD HL,DE + DJNZ .check_dir_loop + ; + POP IX + POP HL + INC IX + LD A,XH + OR XL + JR NZ,.no_inc_hl + INC HL +.no_inc_hl: ; POP AF + ; DEC A + ; JR NZ,.read_dir_loop + POP BC + DJNZ .read_dir_loop + ; fat32 + EXX + POP HL ; номер кластера + EXX + POP HL ; номер кластера + CALL READ_FROM_FAT ; прочитать из кеша FAT-а номер след. кластера + EX DE,HL ; hl=номер след. кластера + EXX + EX DE,HL ; hl=номер след. кластера + EXX + JR NC,.read_dir_big_loop ; не конец цепочки + ; +.delete: POP IX + JP DELETE_REC_FAT ; пометить запись как "удаленная" + ; +.dir_empty: ; CF = 0 +.error: ; CF = 1 + POP HL + POP HL + POP HL + POP HL + POP HL + JR NC,.delete + POP HL + LD A,DSS_Error.sys.DIR_NOT_EMPTY + RET +; \ No newline at end of file diff --git a/Crazy Estex DSS/DSS/API/ScanDRV.asm b/Crazy Estex DSS/DSS/API/ScanDRV.asm new file mode 100644 index 0000000..9a43347 --- /dev/null +++ b/Crazy Estex DSS/DSS/API/ScanDRV.asm @@ -0,0 +1,78 @@ +;R12 +;/////////////////////////////////////////////////////////////////////// +; Функция #08 (DSS_RESCAN). Пересканировать девайсы системы. +; +; вход: нет +; выход: A - номер последнего лог. диска в системе +;/////////////////////////////////////////////////////////////////////// +; INCLUDE 'ScanDRV.asm' +;!TODO код дико костыльный и будет переделан вместе с процедурой INITDVC +SCANDRV: +; 1. запоминаем состояние прерываний +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; + LD A,R + DI + PUSH AF +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; +; 2. узнаём букву бут-диска +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; + CALL BOOTDSK.GET +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; +; 3. вызываем рескан +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; + ; A = Boot disk + LD B,A + LD A,Dss.DRV.RescanDRV + LD C,Dss.DRV.RescanDRV + RST ToDSS.DRV + ; проверка на ошибку boot disk lost + LD HL,.BOOT_DSK_LOST + LD E, +(80-.BOOT_DSK_LOST.size)/2 ; coord X + LD BC,.BOOT_DSK_LOST.size + JP C,KERNEL_PANIC + ; + LD (LDRIVE),A +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; +; 4. на всякий случай перечитываем дирректорию +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; + ; [ ] 10/06/24 + IF OLD_DSS_FOR_OLD_EXE + LD A,(EXE_VERSION) + OR A + JR Z,.old_EXE + ENDIF + ; + LD A,(CORE_BUFFERS.CurrentPath) + SUB 'A' + CALL OPENDSK + ; + LD HL,CORE_BUFFERS.CurrentDirectory + CALL CHDIR + JR NC,.exit + LD HL,CORE_BUFFERS.CurrentDirectory + LD (HL),0 +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; +; 5. выход +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; +.exit: POP AF + RET PO + EI + RET + ; +; [ ] 10/06/24 + IF OLD_DSS_FOR_OLD_EXE +.old_EXE: LD A,(CORE_BUFFERS.FatBuffer.DRIVE) + CALL OPENDSK + ; + LD HL,CORE_BUFFERS.WorkDirectory + CALL CHDIR + JR NC,.exit + LD HL,CORE_BUFFERS.WorkDirectory + LD (HL),0 + JR .exit + ENDIF + +.BOOT_DSK_LOST: DZ "Boot drive lost o_O" +.BOOT_DSK_LOST.size EQU $-.BOOT_DSK_LOST +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; +;/////////////////////////////////////////////////////////////////////// diff --git a/Crazy Estex DSS/DSS/API/SetDateTime.asm b/Crazy Estex DSS/DSS/API/SetDateTime.asm new file mode 100644 index 0000000..ee36795 --- /dev/null +++ b/Crazy Estex DSS/DSS/API/SetDateTime.asm @@ -0,0 +1,32 @@ +//////////////////////////////////////////////////////////////////////// +; Функция #18. Изменение даты и времени файла. +; +; вход: A - дескриптор файла +; D - день +; E - месяц +; IX - год +; H - час +; L - минуты +; B - секунды +; выход: A - код ошибки, если CF=1 +//////////////////////////////////////////////////////////////////////// + +;!FIXIT надо? CHECK_64kb_CLUSTER +PUT_D_T: PUSH AF + CALL MK_TIME ; закодировать время/дату + POP AF ; дескриптор + PUSH DE + PUSH BC + CALL SET_FM + POP BC + POP DE + RET C + ; [ ] VFAT + LD (IY + _sFM.FS_REC.TIME),E + LD (IY + _sFM.FS_REC.TIME+1),D + LD (IY + _sFM.FS_REC.DATE),C + LD (IY + _sFM.FS_REC.DATE+1),B + SET 7,(IY + _sFM.ACCESS_MODE) ;R006 ; уст. признак изменения файла + AND A + RET +; \ No newline at end of file diff --git a/Crazy Estex DSS/DSS/API/SetMem.asm b/Crazy Estex DSS/DSS/API/SetMem.asm new file mode 100644 index 0000000..92beb2f --- /dev/null +++ b/Crazy Estex DSS/DSS/API/SetMem.asm @@ -0,0 +1,73 @@ +////////////////////////////////////////////////////////////////////// +; Функция #3F. Изменение блока памяти. +; +; вход: A - идентификатор блока памяти +; B - новый размер блока +; выход: A - код ошибки, если CF=1 +////////////////////////////////////////////////////////////////////// +SETMEM: LD E,A + LD D,#00 + ;LD HL,MEMTAB + LD HL,CORE_BUFFERS.MemoryTable ; массив списка выдел. страниц + ADD HL,DE + LD A,(TASK) + CP (HL) + LD A,DSS_Error.sys.INVALID_MEMORY_HND + SCF + RET NZ + LD D,B + PUSH DE + LD A,E + CALL .SIZEBLK + POP DE + LD A,DSS_Error.sys.INVALID_MEMORY_HND + RET C + LD A,B + CP D + RET Z + JR C,.INCMEM + ; DECMEM + LD B,D + LD A,E + LD C,BIOS.DivMemBlocks + RST ToBIOS + LD A,B + LD C,BIOS.FreeMem + RST ToBIOS + XOR A + RET + ; Добавить страниц памяти к блоку +.INCMEM: + LD A,D + SUB B + LD B,A + LD C,E + PUSH BC + LD C,BIOS.GetMem + RST ToBIOS + POP BC + LD B,A + LD A,DSS_Error.sys.NOT_ENOUGH_MEMORY + RET C + LD A,C + LD C,BIOS.MergeMemBlocks + RST ToBIOS + XOR A + RET + ; +.SIZEBLK: + LD B,#FF + LD C,A +.loop: INC B + PUSH BC + LD A,C + LD C,BIOS.GetMemPage + RST ToBIOS + POP BC + JR NC,.loop + OR A + SCF + RET Z + XOR A + RET +; \ No newline at end of file diff --git a/Crazy Estex DSS/DSS/API/SetWin.asm b/Crazy Estex DSS/DSS/API/SetWin.asm new file mode 100644 index 0000000..c71c2a6 --- /dev/null +++ b/Crazy Estex DSS/DSS/API/SetWin.asm @@ -0,0 +1,96 @@ +////////////////////////////////////////////////////////////////////// +; Функция #38. Подключение страницы памяти. +; +; вход: A - идентиф. блока памяти +; B - номер страницы в блоке (0,1,2,..) +; H - биты 6 и 7 задают номер окна, в которое будет подкл. страница +; выход: A - номер страницы, если CF=0 +; A - код ошибки, если CF=1 +; if B = 0FFh, then logical page number got from DE +////////////////////////////////////////////////////////////////////// +SETWIN: LD C,A + LD A,H + AND %1100'0000 + JR NZ,.no_error + OR %0100'0000 +.no_error: RRCA + OR %100'0010 + LD H,A ;SLOT number + LD A,C +.ALL: LD C,BIOS.GetMemPage + EX DE,HL + RST ToBIOS + EX DE,HL + RET C + LD C,H ;SLOT number + IN B,(C) + OUT (C),A + LD A,B + RET +; SETWIN: BIT 7,H ; if #8000 or high? +; JR Z,SETWIN1 ; no, go to open in SLOT1 +; BIT 6,H ; if #C000 or high? +; JR Z,SETWIN2 ; no, go to open in SLOT2 +; JR SETWIN3 ; yes, go to open in SLOT3 +////////////////////////////////////////////////////////////////////// +; Функция #39. Подключение страницы памяти в первое окно. +; +; вход: A - идентиф. блока памяти +; B - номер страницы в блоке (0,1,2,..) +; выход: A - номер страницы, если CF=0 +; A - код ошибки, если CF=1 +////////////////////////////////////////////////////////////////////// +SETWIN1: LD H,SLOT1 + JR SETWIN.ALL + +; SETWIN1: LD C,BIOS.GetMemPage +; EX DE,HL +; RST ToBIOS +; EX DE,HL +; RET C +; LD C,SLOT1 +; IN B,(C) +; OUT (C),A +; LD A,B +; RET + +////////////////////////////////////////////////////////////////////// +; Функция #3A. Подключение страницы памяти во второе окно. +; +; вход: A - идентиф. блока памяти +; B - номер страницы в блоке (0,1,2,..) +; выход: A - номер страницы, если CF=0 +; A - код ошибки, если CF=1 +////////////////////////////////////////////////////////////////////// +SETWIN2: LD H,SLOT2 + JR SETWIN.ALL +; SETWIN2 LD C,BIOS.GetMemPage +; EX DE,HL +; RST ToBIOS +; EX DE,HL +; RET C +; LD C,SLOT2 +; IN B,(C) +; OUT (C),A +; LD A,B +; RET +////////////////////////////////////////////////////////////////////// +; Функция #3B. Подключение страницы памяти в третье окно. +; +; вход: A - идентиф. блока памяти +; B - номер страницы в блоке (0,1,2,..) +; выход: A - номер страницы, если CF=0 +; A - код ошибки, если CF=1 +////////////////////////////////////////////////////////////////////// +SETWIN3: LD H,SLOT3 + JR SETWIN.ALL +; SETWIN3: LD C,BIOS.GetMemPage +; EX DE,HL +; RST ToBIOS +; EX DE,HL +; RET C +; LD C,SLOT3 +; IN B,(C) +; OUT (C),A +; LD A,B +; RET \ No newline at end of file diff --git a/Crazy Estex DSS/DSS/API/Time.asm b/Crazy Estex DSS/DSS/API/Time.asm new file mode 100644 index 0000000..5bad9af --- /dev/null +++ b/Crazy Estex DSS/DSS/API/Time.asm @@ -0,0 +1,199 @@ +//////////////////////////////////////////////////////////////////////// +; Функция #21. Текущая дата и время. +; +; вход: нет +; выход: D - день +; E - месяц +; IX - год +; H - час +; L - минуты +; B - секунды +; C - день недели +//////////////////////////////////////////////////////////////////////// +SYSTIME: + LD C,BIOS.CMOS_TEST + RST ToBIOS + JP C,.NOCMOS + LD D,CMOS.Register.date + CALL RCMOS + PUSH AF + LD D,CMOS.Register.month + CALL RCMOS + POP DE + LD E,A + PUSH DE + LD D,CMOS.Register.hours + CALL RCMOS + PUSH AF + LD D,CMOS.Register.minutes + CALL RCMOS + POP DE + LD E,A + PUSH DE + LD D,CMOS.Register.seconds + CALL RCMOS + PUSH AF + LD D,CMOS.Register.dayOfWeek + LD C,BIOS.CMOS_RD + RST ToBIOS + POP DE + LD E,A + PUSH DE + LD D,CMOS.Register.year + CALL RCMOS ;READ AND CONVERT TO DECIMAL + PUSH AF + LD D,CMOS.Register.century + LD C,BIOS.CMOS_RD + RST ToBIOS + LD XH,A + + POP AF + CP 80 ;R001, TEST DECIMAL FIX + PUSH AF + JR C,.XXIAGE + LD A,#19 + CP XH + JR Z,.GOODAGE + JR .BADAGE +.XXIAGE: + LD A,#20 + CP XH + JR Z,.GOODAGE +.BADAGE: + PUSH AF + LD D,CMOS.Register.century + LD C,BIOS.CMOS_WR + RST ToBIOS + POP AF + LD XH,A +.GOODAGE: + POP AF + LD XL,A + LD A,XH + CALL BCD2HEX + LD L,A + LD H,0 + LD C,L + LD B,H + LD XH,B + ADD HL,HL + ADD HL,HL + ADD HL,BC + ADD HL,HL ;*10 + LD B,H + LD C,L + ADD HL,HL + ADD HL,HL + ADD HL,BC + ADD HL,HL ;*10(100) + EX DE,HL + ADD IX,DE + POP BC + POP HL + POP DE + AND A + RET +.NOCMOS: +.NC_DAY+1: + LD DE,DAY*256+MONTH ;DAY/MONTH +.NC_HOUR+1: + LD HL,0 ;HOUR/MINUTE +.NC_SEC+1: + LD BC,1 ;SECOND/WEEKDAY +.NC_YEAR+2: + LD IX,YEAR ;YEAR + AND A + RET +; + +//////////////////////////////////////////////////////////////////////// +; Функция #22. Установить текущую дату и время. +; +; вход: D - день +; E - месяц +; IX - год +; H - час +; L - минуты +; B - секунды +; выход: A - код ошибки, если CF=1 +//////////////////////////////////////////////////////////////////////// +SETTIME: + PUSH IX + PUSH BC + PUSH HL + PUSH DE + ; + ; [x] 25/01/2024 + CALL CalcDayOfWeek + PUSH HL + ; + LD C,BIOS.CMOS_TEST + RST ToBIOS + JR C,.NOCMOS2 + ; + ; [x] 25/01/2024 + POP AF + LD D,CMOS.Register.dayOfWeek + LD C,BIOS.CMOS_WR + RST ToBIOS + ; + POP AF + PUSH AF + LD D,CMOS.Register.date + CALL WCMOS + POP BC + LD A,C + LD D,CMOS.Register.month + CALL WCMOS + POP AF + PUSH AF + LD D,CMOS.Register.hours + CALL WCMOS + POP BC + LD A,C + LD D,CMOS.Register.minutes + CALL WCMOS + POP AF + ;PUSH AF ; [ ] баг с установкой дня недели из регистра C. Нашел Hard + LD D,CMOS.Register.seconds + CALL WCMOS + ; [x] баг с установкой дня недели из регистра C. Нашел Hard + ;POP BC + ;LD A,C + ;LD D,CMOS.Register.dayOfWeek + ;LD C,BIOS.CMOS_WR + ;RST ToBIOS + ; + POP HL + XOR A + LD DE,100 +.YR: INC A + SBC HL,DE + JR NC,.YR + ADD HL,DE + DEC A + PUSH HL + LD D,CMOS.Register.century + CALL WCMOS + POP BC + LD A,C + LD D,CMOS.Register.year + CALL WCMOS + AND A + RET +; !FIXIT новый биос выставляет время, если с ним что-то не так. +.NOCMOS2: + POP AF + POP DE + POP HL + POP BC + POP IX + LD C,A + ; + LD (SYSTIME.NC_DAY),DE ;DAY/MONTH + LD (SYSTIME.NC_HOUR),HL ;HOUR/MINUTE + LD (SYSTIME.NC_SEC),BC ;SECOND/WEEKDAY + LD (SYSTIME.NC_YEAR),IX ;YEAR + AND A + RET +; \ No newline at end of file diff --git a/Crazy Estex DSS/DSS/API/Version.asm b/Crazy Estex DSS/DSS/API/Version.asm new file mode 100644 index 0000000..561de06 --- /dev/null +++ b/Crazy Estex DSS/DSS/API/Version.asm @@ -0,0 +1,19 @@ +;///////////////////////////////////////////////////////////////////// +; Функция #00. Версия ДОС. +; Возвращает номер версии дисковой системы. +; вход: нет +; выход: DE = номер версии/модификации +; BC = номер билда (0..999) +;///////////////////////////////////////////////////////////////////// +VERSION: + ;XOR A + ;LD H,A ;!TODO пихать сюда OSINFO + ;LD L,A + LD HL,0 + LD DE,VERS*256+MODF + LD BC,BUILD + RET + +//;R10 +//OSINFO: +//OSINFO_SIG: DB "OSINFOSTRUCTURE",0 \ No newline at end of file diff --git a/Crazy Estex DSS/DSS/API/Write.asm b/Crazy Estex DSS/DSS/API/Write.asm new file mode 100644 index 0000000..ec87280 --- /dev/null +++ b/Crazy Estex DSS/DSS/API/Write.asm @@ -0,0 +1,197 @@ +WRITE.ERR3: + POP HL +WRITE.ERR2: + POP HL +WRITE.ERR1: + POP BC + SCF + RET +WRITE.RD_ONLY: + POP DE + LD A,DSS_Error.sys.READONLY + SCF + RET + +; HL - ADDRESS +; DE - SIZE +; A - FM +WRITE: ;!TEST ;!TODO 5/12/23 ; [ ] избыточные вызовы WRITE_FAT_TABLE + CALL .Start + PUSH AF + LD A,(CORE_BUFFERS.FatBuffer.CacheUpdated) + OR A + CALL NZ,WRITE_FAT_TABLE ; подкл. банку кеша FAT и записать его на диск + POP AF + RET + ; +.Start: LD (.R_POINT),HL + LD (.S_POINT),HL + PUSH DE + CALL SET_FM + JR C,.ERR1 + LD A,(IY+_sFM.ACCESS_MODE) + AND Dss.Open.R + JR NZ,.RD_ONLY + SET 7,(IY + _sFM.ACCESS_MODE) + SET 5,(IY + _sFM.FS_REC.ATTRIBUT) + LD A,(IY + _sFM.DRIVE) + CALL OPENDSK + JR C,.ERR1 + ; [ ] 26/06/2024 + CALL CHECK_64kb_CLUSTER + RET C + ; + CALL GET_OFFSET_IN_SECTORS + ; + JP NZ,.WOV1 + ; +.WOV4: POP BC + PUSH BC + SRL B + JR Z,.WOV2 + PUSH HL + PUSH DE + PUSH BC +.R_POINT+2: LD IX,0 + CALL BLOK_WRITE + POP BC + JR C,.ERR3 + LD C,B + LD HL,(.R_POINT) + LD DE,#0200 ;!HARDCODE +.WOV5: ADD HL,DE + DJNZ .WOV5 + ; B=0 + LD (.R_POINT),HL + ;LD B,0 + POP HL + ADD HL,BC + EX DE,HL + POP HL + LD C,B + ADC HL,BC +.WOV2: POP BC + LD A,B + AND #01 + LD B,A + OR C + JR Z,.WOV6 + PUSH HL + PUSH DE + PUSH BC + LD IX,CORE_BUFFERS.BUFFER+#C000 + LD B,1 + IN A,(SLOT3) + PUSH AF + IN A,(SLOT0) + OUT (SLOT3),A + CALL BLOCK_READ + POP BC + LD C,SLOT3 + OUT (C),B + LD DE,CORE_BUFFERS.BUFFER + LD HL,(.R_POINT) + POP BC + JP C,.ERR2 + LDIR + LD (.R_POINT),HL + POP DE + POP HL + LD IX,CORE_BUFFERS.BUFFER+#C000 + LD B,1 + IN A,(SLOT3) + PUSH AF + IN A,(SLOT0) + OUT (SLOT3),A + CALL BLOK_WRITE + POP BC + LD C,SLOT3 + OUT (C),B + RET C +.WOV6: LD HL,(.R_POINT) +.S_POINT+1: LD DE,0 + ; CF=0 + ;AND A + SBC HL,DE + PUSH HL + EX DE,HL + LD XH,D + LD XL,E + LD HL,0 + CALL MOVE_FP.F_current + CALL MOVE_CP + POP DE + RET NC ; Если размер файла на диске НЕ стал больше, чем был + ; Если размер файла на диске стал больше, чем был + LD L,(IY + _sFM.F_POSITION+0) + LD H,(IY + _sFM.F_POSITION+1) + LD C,(IY + _sFM.F_POSITION+2) + LD B,(IY + _sFM.F_POSITION+3) + LD (IY + _sFM.FS_REC.F_SIZE+0),L + LD (IY + _sFM.FS_REC.F_SIZE+1),H + LD (IY + _sFM.FS_REC.F_SIZE+2),C + LD (IY + _sFM.FS_REC.F_SIZE+3),B + AND A + RET + ; +.WOV1: PUSH BC + PUSH HL + PUSH DE + LD IX,CORE_BUFFERS.BUFFER+#C000 + LD B,1 + IN A,(SLOT3) + PUSH AF + IN A,(SLOT0) + OUT (SLOT3),A + CALL BLOCK_READ + POP BC + LD C,SLOT3 + OUT (C),B + POP DE + POP HL + EXX + POP DE + JP C,.ERR1 + LD HL,512 ;!HARDCODE sector size! + AND A + SBC HL,DE + LD B,H + LD C,L + POP HL + AND A + SBC HL,BC + JR NC,.WOV3 + ADD HL,BC + LD B,H + LD C,L + LD HL,0 +.WOV3: PUSH HL + LD HL,CORE_BUFFERS.BUFFER + ADD HL,DE + LD DE,(.R_POINT) + EX DE,HL + LDIR + LD (.R_POINT),HL + EXX + PUSH HL + PUSH DE + LD IX,CORE_BUFFERS.BUFFER+#C000 + LD B,1 + IN A,(SLOT3) + PUSH AF + IN A,(SLOT0) + OUT (SLOT3),A + CALL BLOK_WRITE + POP BC + LD C,SLOT3 + OUT (C),B + POP HL + JP C,.ERR2 + LD BC,1 + ADD HL,BC + EX DE,HL + POP HL + LD C,B + ADC HL,BC + JP .WOV4 +; \ No newline at end of file diff --git a/Crazy Estex DSS/DSS/CHANGES.LOG b/Crazy Estex DSS/DSS/CHANGES.LOG new file mode 100644 index 0000000..4ea1f7b --- /dev/null +++ b/Crazy Estex DSS/DSS/CHANGES.LOG @@ -0,0 +1,58 @@ +!FIXIT +[ ] D:\>copy dss\system.dos c:\system.dos (bp 812d, 8136) + Can't open source file + +[ ] E:\BIN\MENU>c:\dss + что-то про заполненность директории +[ ] C:\????? или ????? + исполняется как команда + +----------------------------------------------------------------------------------------------------------------------------------------------- +!TODO +Важное: +[ ] перед началом работы любой процедуры записи/чтения драйва устанавливать флаг, чтоб не было повторного вызова (из прерывания, например) +[ ] блокировка файлов в файловых манипуляторах (чтоб не открывать на запись уже открытый на запись файл, например) +Среднее: +[x] перед ресканом драйвов проверять открытые хэндлы и если буква диска меняется, то менять драйв в хэндле +[ ] начать работать с функциями REMOVABLE и MEDIA CHECK rst #18. Возвращать значение #FF, если порядок букв изменился + +Вообще не важное: +[ ] исправить выход из функции #41 при возможном увеличении номера таски на 1 при 255 +----------------------------------------------------------------------------------------------------------------------------------------------- + +DSS 1.70.2 + Изменения после версии 1.70 +CORE: + [+] при чтении/записи файла не происходит "холостое" перечитывание FAT от начала файла + [+] перечитывание BPB теперь делается не на каждый чих, а когда надо (и бага при загрузке с диска "B:" нет :-P ) + [+] изменена работа с RAM DISK, теперь он может быть загрузочным + [+] исправлены баги в функциях: WINCOPY, WINREST, SCROLL, SETVMOD, SELPAGE +SHELL: + [+] исправлен баг с "C:\>CD E:\" + [+] исправлены баги с обработкой буферов командной строки +UNSORTED: + [+] исправлен баг с переключением на другой диск из некорневой директории, когда на новом диске оказывался в несуществующей директории + [+] мелкие и не очень оптимизации + +;Изменения после версии 1.60 +10.02.2003 - Добавлена визуализация курсора в функции ECHOKEY. +06.02.2003 - Исправлена ошибка в разборе имени файла начинающегося с точки. +29.01.2003 - Исправлена ошибка в PUT_D_T, не обновлялась дата в файлах, в которые не производилась запись. +;Изменения после версии 1.60RC +05.12.2002 - Реализована fn. APPINFO 47h, информация о приложении. +26.11.2002 - Исправлена ошибка в CHDIR, не выполнялся запрос "." из ROOT +19.11.2002 - Добавлена корректировка атрибута файла при его создании. +19.11.2002 - Добавлено маскирование аттрибута VOLUME LABEL. +19.11.2002 - Исправлена ошибка с атрибутом system. +17.11.2002 - Реализовано system environment, fn. 46h +07.11.2002 - Добавлен запрет/разрешение прерываний в функции WINCOPY и WINREST +07.11.2002 - Исправлена ошибка в функции SCROLL (A=0) +;Изменения после версии 1.55 +06.08.2001 - Добавлена поддержка Secondary IDE +06.08.2001 - Исправлена ошибка с подразделами второго винчестера +11.07.2001 - Поддержка принтера для Sp2000 +30.07.2001 - Исправлено описание входных параметров функции удаления файла(0Eh); +;Изменения после версии 1.54 +18.07.2001 - Добавлено описание работы с графическим экраном; +18.07.2001 - Добавлено описание параметра функции получения режима экрана(51h); +15.03.2001 - Добавлено описание функции работы с командной строкой(45h); \ No newline at end of file diff --git a/Crazy Estex DSS/DSS/DOS_FM.ASM b/Crazy Estex DSS/DSS/DOS_FM.ASM new file mode 100644 index 0000000..693bf5e --- /dev/null +++ b/Crazy Estex DSS/DSS/DOS_FM.ASM @@ -0,0 +1,207 @@ + +;[BEGIN] +;//MODULE: DOS_FM +;//CREATE: 19-05-1998 AUTHOR: Denis Parinov +;//UPDATE: 24-10-1999 DNS Restore module +;--------------------------------------------------------------- +;Rev Date Name Description +;--------------------------------------------------------------- +; +;--------------------------------------------------------------- + +;FMS DB FMCOUNT + +;ACCESS MODE: +; 00 - READ/WRITE +; 01 - READ +; 02 - WRITE +;FM_BUF: +;File Manipulator (FM) + ; BYTE '. ' ;+00 NAME + ; BYTE ' ' ;+08 EXT + ; BYTE #10 ;+11 ATTRIBUT + ; BYTE 0 ;+12 RESERVED; !TODO следующий кластер для чтения + ; BYTE 0 ;+13 RESERVED; !TODO следующий кластер для записи + ; BLOCK 8,0 ;+14 RESERVED + ; WORD #0000 ;+22 TIME + ; WORD #0000 ;+24 DATE + ; WORD #0000 ;+26 START CLUSTER + ; DWORD #0000 ;+28 SIZE FILE + ; DWORD #0000 ;+32 FILE POSITION (FP) + ; WORD #0000 ;+36 DIRECTORY CLUSTER + ; WORD #0000 ;+38 HANDLE NUMBER + ; BYTE #00 ;+40 DRIVE OR CURRENT + ; BYTE #00 ;+41 ACCESS MODE + ; BYTE #00 ;+42 TASK + ; BYTE #00 ;+43 EMPTY +/* +;!TEST +FM_BUF: _sFM +.Size EQU _sFM + BLOCK (FMCOUNT-1)*FM_BUF.Size, 0 +*/ + +; на выходе без ошибок IY указывает на файловый манипулятор +; MACRO _mFM_FIND +; CP FMCOUNT+1 +; CCF +; RET C +; PUSH DE + +; LD IY,CORE_BUFFERS.FM_BUF +; LD DE,CORE_BUFFERS.FM_BUF.Size +; AND A +; JR Z,.endLoop +; .loop: ADD IY,DE +; DEC A +; JR NZ,.loop +; .endLoop: +; POP DE +; ; A=0 +; OR (IY) ;+00 NAME +; RET +; ENDM +//////////////////////////////////////////////////////////////////////// + +; на выходе без ошибок IY указывает на файловый манипулятор +FM_FIND: CP FMCOUNT+1 + JR NC,.error + ; + PUSH DE + LD IY,CORE_BUFFERS.FM_BUF + LD DE,CORE_BUFFERS.FM_BUF.Size + AND A + JR Z,.endLoop +.loop: ADD IY,DE + DEC A + JR NZ,.loop +.endLoop: POP DE + ; A=0 + OR (IY) ;+00 NAME + RET + ; +.error: XOR A + LD A,DSS_Error.sys.INVALID_HANDLE + RET + +SET_FM: CALL FM_FIND + ; error + ;LD A,DSS_Error.sys.INVALID_HANDLE + ; CF = 1 + SCF + RET Z + ; no error + XOR A ;LD A,DSS_Error.sys.NO_ERROR + ; CF = 0 + RET + + +RES_FM: CALL FM_FIND + ; error + ; LD A,DSS_Error.sys.INVALID_HANDLE + SCF + RET Z + ; no error + XOR A + LD (IY + _sFM.FS_REC.NAME),A + RET +; +GET_FM: LD B,FMCOUNT + LD C,#FF + LD IY,CORE_BUFFERS.FM_BUF - CORE_BUFFERS.FM_BUF.Size + LD DE,CORE_BUFFERS.FM_BUF.Size +.loop: ADD IY,DE + INC C + LD A,(IY + _sFM.FS_REC.NAME) + OR A + RET Z + DJNZ .loop + LD A,DSS_Error.sys.NO_HANDLES + SCF + RET +/* + ;!TODO CHECK LOCKING 10/11/2023 +GET_FM: LD IY,0 + LD (.freeHandle),IY + ; + LD B,FMCOUNT + LD C,#FF + LD IY,CORE_BUFFERS.FM_BUF - CORE_BUFFERS.FM_BUF.Size + LD DE,CORE_BUFFERS.FM_BUF.Size +.loop: ADD IY,DE + INC C + ; CHECK LOCKING + + ; +.cont: LD A,(IY+0) + OR A + RET Z + DJNZ .loop + LD A,DSS_Error.sys.NO_HANDLES + SCF + RET +*/ + + +; HL:IX - OFFSET POINTER +; A - FILE MANIPULATOR +MOVE_FP: CALL SET_FM + RET C + INC B + DJNZ .B_1 + ;from Start File + ; B=0 +.F_start: LD C,B + LD D,B + LD E,B + JP .DO + ; +.B_1: DJNZ .B_2 + ;from Current Position +.F_current: LD C,(IY+_sFM.F_POSITION) + LD B,(IY+_sFM.F_POSITION+1) + LD E,(IY+_sFM.F_POSITION+2) + LD D,(IY+_sFM.F_POSITION+3) +.DO: ADD IX,BC + ADC HL,DE + LD D,XH + LD E,XL + LD (IY+_sFM.F_POSITION),E + LD (IY+_sFM.F_POSITION+1),D + LD (IY+_sFM.F_POSITION+2),L + LD (IY+_sFM.F_POSITION+3),H + XOR A + RET + ; +.B_2: DJNZ .error + ;from End File +.B_end: LD C,(IY + _sFM.FS_REC.F_SIZE) + LD B,(IY + _sFM.FS_REC.F_SIZE+1) + LD E,(IY + _sFM.FS_REC.F_SIZE+2) + LD D,(IY + _sFM.FS_REC.F_SIZE+3) + JP .DO + ; B > 2 +.error: LD A,DSS_Error.sys.INVALID_FUNCTION + SCF + RET +;;;;;;;;; + + + +;FP COMPARE +; CY - FILE POINTER > SIZE +; NC - FILE POINTER < SIZE +MOVE_CP: + LD L,(IY + _sFM.FS_REC.F_SIZE) + LD H,(IY + _sFM.FS_REC.F_SIZE+1) + LD E,(IY + _sFM.F_POSITION) + LD D,(IY + _sFM.F_POSITION+1) + AND A + SBC HL,DE + LD L,(IY + _sFM.FS_REC.F_SIZE+2) + LD H,(IY + _sFM.FS_REC.F_SIZE+3) + LD E,(IY + _sFM.F_POSITION+2) + LD D,(IY + _sFM.F_POSITION+3) + SBC HL,DE + RET +; \ No newline at end of file diff --git a/Crazy Estex DSS/DSS/DOS_Proc.asm b/Crazy Estex DSS/DSS/DOS_Proc.asm new file mode 100644 index 0000000..0ff063e --- /dev/null +++ b/Crazy Estex DSS/DSS/DOS_Proc.asm @@ -0,0 +1,471 @@ +;[BEGIN] +;//MODULE: DOS_X +;//CREATE: 19-05-1998 AUTHOR: Denis Parinov +;//UPDATE: 24-10-1999 DNS Restore module +;--------------------------------------------------------------- +;Rev Date Name Description +;--------------------------------------------------------------- +;R13 06-04-2023 BAO Функцию SETBOOT можно вызвать только раз (если завершится корректно) +;R12 03-04-2023 BAO Добавлена функция рескана драйвов LD C,8 : RST #10 +;R11 - 15-04-2003 DNS ROUTINE FOR STORE CURDISK AND CURDIR +;R10 - 03-04-2003 DNS IMPROVED FN. VERSION +;R09 27-03-2003 DNS PASTED SET/GET BOOT FN. +;R08 14-11-2002 DNS IMPROVE BPB-FUNCTION +;R07 17-12-1999 DNS BUG FIX SIGNATURE #55AA AT 510 OFFSET +;R06 21-11-1999 DNS FN. DISKINF SUPPORT ALL DISKS +;R05 21-11-1999 DNS BUG FIX SIGNATURE #55AA IN BOOT SECTOR +;R04 08-11-1999 DNS KILL OLD FUNCTIONS +;R03 23-11-1998 DNS BUG FIX (IX+28) -> (IY+28) +;R02 21-11-1998 DNS CHANGE FUNCTION "MAKE FAT" +;R01 20-11-1998 DNS REPAIR FUNCTION "SAVE" +;--------------------------------------------------------------- + +;----------------------------------------------------------------------; +; HL - 11 bytes filename "FILENAMEEXT" +; DE - DOS filename "FILENAME.EXT",0 +; GetName: +; LD BC,#08FF +; .GETN1: LD A,(HL) +; CP " " +; JR NZ,.GETN3 +; .GETN2: INC HL +; DJNZ .GETN2 +; JR .GETN4 +; .GETN3: LDI +; DJNZ .GETN1 +; ; +; .GETN4: LD A,(HL) +; CP " " +; LD A,"." +; JR NZ,.GETN5 +; LD A,#00 +; .GETN5: LD (DE),A +; INC DE +; RET Z +; LD B,#03 +; .GETN6: LD A,(HL) +; CP " " +; RET Z +; LDI +; XOR A +; LD (DE),A +; DJNZ .GETN6 +; RET +;---------------;---------------;--------------- +;!TODO LFN +GetName: LD BC,#08FF ;!HARDCODE длина имени + счётчик + LD A,' ' +.loop: CP (HL) + JR Z,.skip + LDI + DJNZ .loop + JP .extension + ; +.skip: LD C,B + LD B,0 + ; CF=0 + ADC HL,BC +.extension: CP (HL) + LD A,"." + JR NZ,.copy_ext + XOR A +.copy_ext: LD (DE),A + INC DE + RET Z ;no copy extension + ; copy extension + LD BC,#03FF ;!HARDCODE длина расширения + счётчик + LD A,' ' +.loop2: CP (HL) + JR Z,.exit + LDI + DJNZ .loop2 +.exit: XOR A + LD (DE),A + RET +;----------------------------------------------------------------------; + + +;----------------------------------------------------------------------; +; Тест на допустимое имя и настроиться на диск. +; вход: hl=строка имени +; выход: (TMPNAME) +GETWORD: ; !TEST + INC HL + LD A,(HL) + DEC HL + CP ':' + JR NZ,.dir_loop + + LD A,(HL) + CP 'a' + JR C,.next + CP 'z'+1 + JR NC,.next + SUB #20 +.next: SUB 'A' + INC HL + INC HL + PUSH HL + CALL CHNDISK + ;CALL OPENDSK + POP HL + RET C + LD A,(HL) + OR A + JR Z,.done + CP ' ' ; + JR Z,.done + CP '\' ; + SCF + LD A,DSS_Error.sys.PATH_NOT_FOUND + RET NZ + INC HL + ; +.dir_loop: LD DE,TMPNAME + LD BC,#0DFF +.loop: LD A,(HL) + INC HL + CP '\' ; + JR Z,.DIR_NAME + ; AND A + ; JR Z,.DIR_NAME + ;CP ':' + ;JR Z,.DRV_NAME + LD (DE),A + INC DE + CP ' '+1 + CCF + RET NC + DJNZ .loop + LD A,DSS_Error.sys.INVALID_NAME + SCF + RET + ; +.done: XOR A + LD (TMPNAME),A + RET + ; +.DIR_NAME: XOR A + LD (DE),A + PUSH HL + LD HL,TMPNAME + CALL OPENDIR + POP HL + RET C + JR .dir_loop +; .DRV_NAME: +; LD A,(TMPNAME) +; CP 'a' +; JR C,.next +; CP '{' +; JR NC,.next +; SUB #20 +; .next: SUB 'A' +; PUSH HL +; ;!TEST CHNDISK OPENDSK +; ;CALL OPENDSK +; CALL CHNDISK +; ; +; POP HL +; RET C +; JR .loop +; + + +; Буфер имени 8.3 формата +TMPNAME: DZ ' ' ; 12 пробелов и 0 ;!FIXIT к буферам +;----------------------------------------------------------------------; + + + +;----------------------------------------------------------------------; +; IN: A - drive number +OPENDSK: ;!TEST DRV.Open обход R10 + LD C,A + LD A,(CORE_BUFFERS.FatBuffer.DRIVE) + CP C + IF CHECK_DRIVE_CHANGE + JR NZ,.open + PUSH BC + LD C,Dss.DRV.MediaCheck + RST ToDSS.DRV + POP BC + ENDIF + JR Z,.exit + +.open: LD A,C + ; +.force: PUSH AF + LD C,Dss.DRV.Open + RST ToDSS.DRV + POP BC + JP C,.error + ;[x] 29/02/2024 fix "open drive error" + LD A,(CORE_BUFFERS.FatBuffer.DRIVE) + LD D,A + PUSH DE + ; + LD A,B + LD (CORE_BUFFERS.FatBuffer.DRIVE),A + ; + CALL RD_BPB + ;[x] 29/02/2024 fix "open drive error" + POP DE + JR C,.error_bpb + ; RET C + ; +.exit: LD A,(LDRIVE) + AND A + RET + ; +.error: CP DSS_Error.sys.INVALID_DRIVE + SCF + RET Z + LD A,DSS_Error.sys.NOT_READY + RET +;[x] 29/02/2024 fix "open drive error"; 20/06/2024 fixed +.error_bpb: PUSH AF ; сохраняем номер ошибки + LD A,(CORE_BUFFERS.FatBuffer.DRIVE) + CP D + JR Z,.next_check + ; + LD A,D + CP #FF + SCF + JR Z,.set_panic + ; + LD (CORE_BUFFERS.FatBuffer.DRIVE),A + CALL OPENDSK.force + LD A,(BOOTDSK.NUM) + LD (CORE_BUFFERS.FatBuffer.DRIVE),A + CALL C,OPENDSK.force + ; +.err_exit: LD A,(CORE_BUFFERS.FatBuffer.DRIVE) + ADD 'A' + LD (CORE_BUFFERS.CurrentPath),A + POP AF + RET + ; +.next_check: LD A,(BOOTDSK.NUM) + CP D + SCF +.reBPB: CALL NZ,OPENDSK.force + ; проверка на ошибку +.set_panic: LD HL,.NOT_READY + LD E, +(80-.NOT_READY.size)/2 ; coord X + LD BC,.NOT_READY.size + JR NC,.err_exit + JP KERNEL_PANIC + ; +.errorCycle: DB 0 +.NOT_READY: DZ "Boot drive error..." +.NOT_READY.size EQU $-.NOT_READY +;----------------------------------------------------------------------; + + +;----------------------------------------------------------------------; +; Преобразовать имя 8.3 -> 11 формат +; вход: hl = 8.3 имя +; de = буфер имени 11 симв. формата +; при ошибке CF - недоп. имя +; +; HL - MASK "file*.t??" +; DE - 11 bytes filename +; RET: C=2 FILE WITHOUT EXTENTION +; C=1 FILE WITH EXTENTION +MASK: LD HL,TMPNAME +.name: LD DE,MASKARE +.custom: PUSH HL + PUSH DE + LD H,D + LD L,E + INC DE + LD (HL),' ' + LD BC,10 ;!HARDCODE = size (FileName + Extension - 1) + LDIR + POP DE + POP HL + LD A,(HL) + CP '.' ;R007 + SCF ;R007 + JR Z,.MASKB ;R007 + CP ' '+1 +.MASKB: LD A,DSS_Error.sys.INVALID_NAME + RET C + LD BC,#0902 ; B - счетчик +.MASK1: LD A,(HL) + CP ' '+1 + CCF + RET NC + CP '"' + JR Z,.MASK_ERR + CP '*' + JR Z,.MASK3 + CP '+' + JR Z,.MASK_ERR + CP ',' + JR Z,.MASK_ERR + CP '.' + JR Z,.MASK5 + CP '/' + JR Z,.MASK_ERR + CP ':' + JR Z,.MASK_ERR + CP ';' + JR Z,.MASK_ERR + CP '<' + JR Z,.MASK_ERR + CP '=' + JR Z,.MASK_ERR + CP '>' + JR Z,.MASK_ERR + CP '[' + JR Z,.MASK_ERR + CP '\' + JR Z,.MASK_ERR + CP ']' + JR Z,.MASK_ERR + CP '|' + JR Z,.MASK_ERR +; CP 'a' ;????? +; JR C,.MASK2 +; CP 'z' + 1 +; JR NC,.MASK2 +; SUB #20 + CALL UPPER ; a..z -> A..Z +.MASK2: LD (DE),A + INC HL + INC DE + DJNZ .MASK1 +.MASK_ERR: + LD A,DSS_Error.sys.INVALID_NAME + SCF + RET +.MASK3: LD A,'?' + INC HL + DJNZ .MASK6 + LD A,DSS_Error.sys.INVALID_NAME + SCF + RET +.MASK6: LD (DE),A + INC DE + DJNZ .MASK6 + LD B,1 + JR .MASK1 +.MASK5: LD A,' ' + INC HL + DJNZ .MASK4 + LD B,4 + DEC C + JP NZ,.MASK1 + LD A,DSS_Error.sys.INVALID_NAME + SCF + RET +.MASK4: LD (DE),A + INC DE + DJNZ .MASK4 + LD B,4 + DEC C + JP NZ,.MASK1 + LD A,DSS_Error.sys.INVALID_NAME + SCF + RET +;----------------------------------------------------------------------; + + + +;----------------------------------------------------------------------; +;!TEST Current Dir ;[x] 15/10/23 +DIR_PATH_CHANGE: +.FullCurrent: LD A,(CORE_BUFFERS.FatBuffer.DRIVE) + ADD 'A' + LD (CORE_BUFFERS.CurrentPath),A + ; +.Current: LD HL,CORE_BUFFERS.CurrentDirectory + JP CURRDIR + ; +.FullWork: LD A,(CORE_BUFFERS.CurrentPath) + SUB 'A' + LD (CORE_BUFFERS.FatBuffer.DRIVE),A + ; +.Work: LD HL,CORE_BUFFERS.WorkDirectory + JP CURRDIR_FN +; +DIR_PATH_CHECK: LD A,(HL) + CP '\' + JR NZ,.notRootDir + ; + CALL .checkDrive + RET Z + LD A,(CORE_BUFFERS.CurrentPath) + SUB 'A' + JP OPENDSK + ; +.notRootDir: INC HL + LD A,(HL) + CP ':' + RET Z + ; +.forceCheck: ;LD HL,CurrentDirectory+1 + LD BC,CORE_BUFFERS.CurrentDirectory.DEPTH-1 + CALL .checkDrive + JR Z,.checkDir + ; + LD HL,CORE_BUFFERS.CurrentPath + LD A,(CORE_BUFFERS.FatBuffer.DRIVE) + ADD 'A' + CP (HL) + JR NZ,.gotoPath + ; +.checkDir: LD HL,CORE_BUFFERS.CurrentDirectory+1 + LD DE,CORE_BUFFERS.WorkDirectory+1 + ; счётчик + LD A,B + LD B,C + EX AF,AF' + ; +.loop: LD A,(DE) + AND A + JR Z,.end + CP (HL) + INC HL + INC DE + JR NZ,.gotoPath + DJNZ .loop + EX AF,AF' + SUB 1 + RET C + EX AF,AF' + DJNZ .loop + ; +.gotoPath: LD C,B + EX AF,AF' + LD B,A + CALL FINDDIR.CHECK_SLASH + LD A,DSS_Error.sys.PATH_NOT_FOUND + RET C + LD HL,CORE_BUFFERS.CurrentPath + JP GETWORD + ; +.end: CP (HL) + RET Z + JR .gotoPath + ; +.checkDrive: LD HL,CORE_BUFFERS.CurrentPath + LD A,(CORE_BUFFERS.FatBuffer.DRIVE) + ADD 'A' + CP (HL) + RET +;----------------------------------------------------------------------; + + +;----------------------------------------------------------------------; +CHECK_NAME: + LD HL,MASKARE +.custom: LD BC,11 ;!HARDCODE + LD A,"?" + CPIR + LD A,DSS_Error.sys.INVALID_NAME + SCF + RET +;----------------------------------------------------------------------; diff --git a/Crazy Estex DSS/DSS/DRV-MAIN.ASM b/Crazy Estex DSS/DSS/DRV-MAIN.ASM new file mode 100644 index 0000000..9a1091a --- /dev/null +++ b/Crazy Estex DSS/DSS/DRV-MAIN.ASM @@ -0,0 +1,356 @@ +;[BEGIN] +;//MODULE: DRV-MAIN AUTHOR: Denis Parinov +;//CREATE: 2003-03-12 +;--------------------------------------------------------------- +;Rev Date Name Description +;--------------------------------------------------------------- +;R00 2003-03-19 DNS Initial version +;--------------------------------------------------------------- + +; ORG #0000 + +;PAGEDRV EQU 0 + + +;===============; + ;!FIXIT в процедуре которая будет отвечать за переход из этой страницы обратно в MAIN для вызова функций + ; ДСС и, возможно, повторному заходу в эту страницу через RST #18 из других страниц (которых пока нет) + ; сделать нечто подобное с программным стеком страниц. Эта процедура их сохраняет, примерно такая же + ; должна восстанавливать. +; PUSH HL +;.SP+1: LD HL,DRV_PAGE.RSTx18_RET_PAGES +; LD (HL),A +; DEC L ; Не HL, а L - чтоб закольцевать область +; LD (.SP),HL +; POP HL +;===============; + +;!TODO +//////////////////////////////////////////////////////////////////////// +; <[NOT USED]> +A0000: JP RST_00 +//////////////////////////////////////////////////////////////////////// + + +; +RST_00: + LD A,DSS_Error.drv.INVALID_COMMAND + SCF + RET +; + +//////////////////////////////////////////////////////////////////////// +; <[BIOS API]> + BLOCK 8-$,#C7 ; #C7 - "RST 0" opcode +A0008: PUSH AF + LD A,SYS_PORT.PAGE8 + OUT (SYS_PORT.ON),A + POP AF + RET +//////////////////////////////////////////////////////////////////////// + + +;!FIXIT +//////////////////////////////////////////////////////////////////////// +; <[DSS API]> + BLOCK #10-$,#C7 ; #C7 - "RST 0" opcode +A0010: ;JP DRV_PAGE.RST_10 + DI : HALT +//////////////////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////////////////// +; <[DRIVE API]> + BLOCK #18-$,#C7 ; #C7 - "RST 0" opcode +;A0018 JP INTDISK +A0018: ;PUSH AF + ;PUSH BC + SCF + RET +DRV_PAGE.MAIN_PAGE_NUMBER+2: + LD BC,0*256 + SLOT0 ; !FIXIT сюда не должны вставляться номера выделенных страниц? + ;JP PORTAL.outDRV +//////////////////////////////////////////////////////////////////////// + + +;!TODO +//////////////////////////////////////////////////////////////////////// +; <[NOT USED]> + BLOCK #20-$,#C7 ; #C7 - "RST 0" opcode +A0020: JP DRV_PAGE.RST_20 +//////////////////////////////////////////////////////////////////////// + + +; +DRV_PAGE.RST_20: + LD A,DSS_Error.drv.INVALID_COMMAND + SCF + RET +; + +;!TODO +//////////////////////////////////////////////////////////////////////// +; <[NOT USED]> + BLOCK #28-$,#C7 ; #C7 - "RST 0" opcode +A0028: JP DRV_PAGE.RST_28 +//////////////////////////////////////////////////////////////////////// + + +; +DRV_PAGE.RST_28: + LD A,DSS_Error.drv.INVALID_COMMAND + SCF + RET +; + +//////////////////////////////////////////////////////////////////////// + BLOCK #30-$,#C7 ; #C7 - "RST 0" opcode +RST_30: JP MOUSE_DRV.API +.RET: OUT (SLOT0),A + JP MOUSE_HANDLER +//////////////////////////////////////////////////////////////////////// + + +;!FIXIT +//////////////////////////////////////////////////////////////////////// +; <[MAIN INT]> ; + BLOCK #38-$,#C7 ; +/* + ;!TEST SIO INT + ; reg 0 - error reset + IF KEYBOARD_INT_ENABLED && MOUSE_INT_ENABLED == 0 + PUSH AF + ; reg 0 - error reset + LD A,%0011'0000 + OUT (Z84.SIO.Ch_A.Ctrl),A + ; reg 0 - return from int + LD A,%0011'1000 + OUT (Z84.SIO.Ch_A.Ctrl),A + POP AF + ELSEIF MOUSE_INT_ENABLED && KEYBOARD_INT_ENABLED == 0 + PUSH AF + ; reg 0 - error reset + LD A,%0011'0000 + OUT (Z84.SIO.Ch_B.Ctrl),A + ; reg 0 - return from int + LD A,%0011'1000 + OUT (Z84.SIO.Ch_B.Ctrl),A + POP AF + ELSEIF MOUSE_INT_ENABLED && KEYBOARD_INT_ENABLED + PUSH AF + ; reg 0 - error reset + LD A,%0011'0000 + OUT (Z84.SIO.Ch_A.Ctrl),A + OUT (Z84.SIO.Ch_B.Ctrl),A + ; reg 0 - return from int + LD A,%0011'1000 + OUT (Z84.SIO.Ch_A.Ctrl),A + OUT (Z84.SIO.Ch_B.Ctrl),A + POP AF + ENDIF + EI ; + RETI ; +*/ +RST_38_DRV: JP .Portal + BLOCK RST_38_IM1.Portal - $,0 +.Portal: PUSH AF + LD A,(DRV_PAGE.MAIN_PAGE_NUMBER) + OUT (SLOT0),A + POP AF + EI + RETI +//////////////////////////////////////////////////////////////////////// + + +; +DRV_PAGE.KEYSCAN: RET ;!FIXIT +; + + +//////////////////////////////////////////////////////////////////////// +; <[ NMI ]> ; +DRV_PAGE.NMI: RETN ; + BLOCK #66-$,#C7; +A0066: JP DRV_PAGE.NMI ; +//////////////////////////////////////////////////////////////////////// + + + +;-------------------------------; +;ADRST10 EQU #00 ; ;!!!!! +;-------------------------------; +;!FIXIT +; DRV_PAGE.RST_10: +; PUSH HL +; LD L,C +; LD H,ADRST10/256 +; LD C,(HL) +; INC H +; LD H,(HL) +; LD L,C +; EX (SP),HL +; RET + + +//////////////////////////////////////////////////////////////////////// +; <[DRIVE PAGE SWITCH]> ; + BLOCK PORTAL.RSTx18_SWITCH_ADDRESS-$-(PORTAL.out_DRV.switch - PORTAL.out_DRV),#C7 +PORTAL.out_DRV: PUSH BC ; +.RETBANK+2: LD BC,SLOT0 + 0*256; ;!!!!! ReScnDRV использует это значение +.switch: OUT (C),B ; + ASSERT $!=84,'-> Portal error!'; + ;Entry point from DSS main page + LD (.RETBANK),A ; + POP BC ; + POP AF ; +.ADCALL+1: CALL DISPATCH ; патчится на INTDISK + JP PORTAL.out_DRV ; +//////////////////////////////////////////////////////////////////////// + + + +//////////////////////////////////////////////////////////////////////// +MOUSE_HANDLER: POP AF + CALL MOUSE_DRV.API + PUSH AF +.CorePage EQU $$$ + 1 + LD A,#FF + JP RST_30.RET +//////////////////////////////////////////////////////////////////////// + + + + +DRV_PAGE.LDRIVE: DB #00 + +DISPATCH: + LD HL,INTDISK + LD (PORTAL.out_DRV.ADCALL),HL +INITDVC_RET_DRIVE: + CALL INITDVC + LD A,(DRV_PAGE.LDRIVE) + AND A + RET + + INCLUDE 'dss/Drivers/media/shared-drv.asm' + INCLUDE 'dss/Drivers/media/ide-drv.asm' + INCLUDE 'dss/Drivers/media/fdd-drv.asm' + INCLUDE 'dss/Drivers/media/ram_disk-drv.asm' + INCLUDE "dss/Drivers/input/MOUSE.ASM" +/////////////////////////// [ DRIVE TABLES ] \\\\\\\\\\\\\\\\\\\\\\\\\\\; +; +;------------------------[shared-drv.asm table]------------------------; +DEVICE EQU $ +.TBL_Entry EQU 3 +.Size EQU DSS_MAX_DRIVES_AMOUNT * .TBL_Entry +.End EQU DEVICE.Size + 1 ; для стоп-байта #FF +;----------------------------------------------------------------------; +; + +; +;-------------------------[ IDE-DRV.ASM table]-------------------------; +;+00 BYTE MASTER/SLAVE PHISICAL DRIVE NUMBER #80/#81/... +;+01 LONG SECTOR OFFSET +;+05 LONG SIZE IN SECTORS +;+09 BYTE PARTITION RECORD NUMBER (in drive MBR) +;+09 FREE +;+15 +LOGDRV EQU DEVICE + DEVICE.End +.TBL_Entry EQU 16 +.Size EQU DSS_MAX_DRIVES_AMOUNT * .TBL_Entry +;!TODO сделать структурой +.PHISICAL_DRV_NUMBER EQU 0 +.SECTOR_OFFSET EQU 1 +.SIZE_IN_SECTORS EQU 5 +.PARTITION_RECORD_NUM EQU 9 +; ВХОД: L - логический номер в таблице +; ВЫХОД: IY - начало записи +; ПОРТИТ: HL, IY. HL<-->DE +; MACRO LOGDRV_ENTRY_FIND tbl_addr +; LD H,0 +; ADD HL,HL +; ADD HL,HL +; ADD HL,HL +; ADD HL,HL +; ;LD B,H +; ;LD C,L +; EX DE,HL +; LD IY,tbl_addr +; ADD IY,DE +; ENDM +;----------------------------------------------------------------------; +; + +; +;-----------------------[ram_disk-drv.asm table]-----------------------; +; ТАБЛИЦА СООТВЕТСТВИЯ МЕЖДУ ФИЗИЧЕСКИМ НОМЕРОМ РАМДИСКА И ЕГО RAM-DISK ID +; Log Number: DB RAM_Drive_Log_Number, RAM_Drive_ID ;(BIOS 0-15), (Block ID for BIOS) +RAMDTBL EQU LOGDRV + LOGDRV.Size +.TBL_Entry EQU 2 +.Size EQU .TBL_Entry * MAX_RAMDRIVES +; RAMDTBL: DUP MAX_RAMDRIVES * RAMDTBL.TBL_Entry +; DB #FF +; EDUP +; .Size EQU $-RAMDTBL +;----------------------------------------------------------------------; +; +////////////////////////////////////////////////////////////////////////; + + +///////////////////////// [ DRIVE TABLES COPY] \\\\\\\\\\\\\\\\\\\\\\\\\; + MODULE OLD_TABLES +; +;------------------------[shared-drv.asm table]------------------------; +DEVICE EQU @RAMDTBL + @RAMDTBL.Size +.TBL_Entry EQU @DEVICE.TBL_Entry +.Size: EQU @DEVICE.Size +.End EQU @DEVICE.End +;----------------------------------------------------------------------; +; + +; +;-------------------------[ IDE-DRV.ASM table]-------------------------; +;+00 BYTE MASTER/SLAVE PHISICAL DRIVE NUMBER #80/#81/... +;+01 LONG SECTOR OFFSET +;+05 LONG SIZE IN SECTORS +;+09 FREE +;+15 +LOGDRV EQU DEVICE + DEVICE.End +.TBL_Entry EQU @LOGDRV.TBL_Entry +.Size EQU @LOGDRV.Size +;----------------------------------------------------------------------; +; + +; +;-----------------------[ram_disk-drv.asm table]-----------------------; +; ТАБЛИЦА СООТВЕТСТВИЯ МЕЖДУ ФИЗИЧЕСКИМ НОМЕРОМ РАМДИСКА И ЕГО RAM-DISK ID +; Log Number: DB RAM_Drive_Log_Number, RAM_Drive_ID ;(BIOS 0-15), (Block ID for BIOS) +RAMDTBL EQU LOGDRV + LOGDRV.Size +.TBL_Entry EQU @RAMDTBL.TBL_Entry +.Size EQU @RAMDTBL.Size +; RAMDTBL: DUP MAX_RAMDRIVES * RAMDTBL.TBL_Entry +; DB #FF +; EDUP +; .Size EQU $-RAMDTBL +;----------------------------------------------------------------------; +; + ENDMODULE +////////////////////////////////////////////////////////////////////////; + ;DISPLAY "DEVICE start: ", /H, DEVICE + ;DISPLAY "Old DEVICE start: ", /H, OLD_TABLES.DEVICE + ;DISPLAY "LOGDRV start: ", /H, LOGDRV + ;DISPLAY "Old LOGDRV start: ", /H, OLD_TABLES.LOGDRV + ;DISPLAY "RAMDTBL start: ", /H, RAMDTBL + ;DISPLAY "Old RAMDTBL start: ", /H, OLD_TABLES.RAMDTBL + +; +;DRV_TEMP_BUFFER: + +;---------[256 bytes stack for return pages of RST #18 callers]--------; +; #3F00 - #3FFF +DRV_PAGE.RSTx18_RET_PAGES EQU #3FFF +;----------------------------------------------------------------------; +; ASSERT ((#4000-DRV_TEMP_BUFFER-256) > (DEVICE.Size + LOGDRV.Size + RAMDTBL.Size)), "No space for DRV_TEMP_BUFFER in DRV-MAIN page" +; ENDMODULE +; OUTEND +;[END] \ No newline at end of file diff --git a/Crazy Estex DSS/DSS/DSS-MAIN.ASM b/Crazy Estex DSS/DSS/DSS-MAIN.ASM new file mode 100644 index 0000000..6b2f37a --- /dev/null +++ b/Crazy Estex DSS/DSS/DSS-MAIN.ASM @@ -0,0 +1,729 @@ + +;[BEGIN] +;//MODULE: DOS-MAIN AUTHOR: Denis Parinov +;//CREATE: A LONG TIME AGO :) +;--------------------------------------------------------------- +;Rev Date Name Description +;--------------------------------------------------------------- +;[ ] увеличить длину PATH и строки BAT +;[ ] путь текущего каталога в DIR выводится с глюком если он длинее 256 байтов +;[ ] путь в приглашении консоли выводится с глюком если путь длинее 256 байтов +;[ ] ;!FIXIT какой-то баг при котором если нет диска и на него полезть, то всё ломается +;R12 24-07-2023 BAO Check minimum BIOS version on boot +;R11 17-04-2023 BAO OPTIMIZED BUFFERS, FREED UP 768 BYTES FOR CODE +;R10 14-04-2023 BAO Аварийный зависон с выводом сообщения при старте системы, если нет свободной памяти +;R09 08-04-2023 BAO Сокращение размера таблицы API до 96 функций (0 - #5F). (Опционально при компиляции) +;R08 15-04-2003 DNS RENAMED FN. OPEN AND CLOSE +;R07 31-03-2003 DNS NEW DEPLOYING ROUTINE +;R06 31-03-2003 DNS RELAYOUTING MEMORY +;R05 27-03-2003 DNS CHANGE DRV. INIT. METHOD +;R04 27-03-2003 DNS DRIVERS MOVE TO SPECIAL PAGE +;R03 14-03-2003 DNS CODE OPTIMIZATION +;R02 19-11-2002 DNS ADD ENVIRONMENT INITIALIZATION +;R01 14-11-2002 DNS CUT AND MOVE BPB-STRUCT +;--------------------------------------------------------------- +; OUTPUT './Build/system.dos' + +; MODULE MAIN +//SPRINTER EQU 2000 + + includelua 'Shared_includes/lua/Functions.lua' + include 'shared_includes/structures/FileSystem.inc' + include 'shared_includes/constants/sp2000.inc' + INCLUDE 'defines.inc' + include 'Structures.inc' + include 'shared_includes/constants/standart_colors.inc' + include 'shared_includes/constants/bios_equ.inc' + include 'shared_includes/constants/dss_equ.inc' + include 'shared_includes/macroses/accelerator.z80' + include 'shared_includes/macroses/macros.z80' + INCLUDE 'VERSION.INC' + INCLUDE 'DSS_MACROSES.Z80' + +;PAGEDRV EQU #00 + +; DIRPAGE EQU 0 +; FATPAGE EQU 1 +; TXTPAGE EQU 2 +; ENVPAGE EQU 2 +; DRVPAGE EQU 3 +; ENVPAGE EQU 3 +; DRVPAGE EQU 4 + +; TXTADDR EQU #C000 +; ENVADDR EQU #E400 + +; DIR EQU #C000 +; FAT EQU #C000 + + +; +; = -- = -- = -- = -- = = -- = -- = = -- = -- = = -- = -- = -- = -- = --; + ORG 0 +; +;' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '; +; <[CLOSE TASK]> ; +RST_0x00: JP RETFAR ; ;EXECUTE.ASM R12 +;' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '; +; + +; +;' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '; +; <[BIOS API]> ; + _mInfoBLOCK 8-$,#FF ; +RST_0x08: PUSH AF ; + LD A,SYS_PORT.PAGE8; + OUT (SYS_PORT.ON),A ; + POP AF ; + RET ; +;' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '; +; + +; +;' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '; +; <[DSS API]> ; + _mInfoBLOCK #10-$,#FF ; +RST_0x10: JP RST_10 ; +;' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '; +; + +; +;' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '; +; <[DRIVE API]> ; + _mInfoBLOCK #18-$,#FF ; +;A0018 JP INTDISK ; +RST_0x18: PUSH AF ; + PUSH BC ; +DRV_PG_NUMBER+2: ; + LD BC,0*256+SLOT0 ; + JP PORTAL.out_MAIN ; +;' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '; +; + +; +;' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '; +; <[NOT USED]> ; + _mInfoBLOCK #20-$,#FF ; +RST_0x20: JP RST_20 ; +;' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '; +; + +; +RST_20: +RST_28: +NOPS: LD A,DSS_Error.sys.INVALID_FUNCTION + SCF + RET +; + +; +;' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '; +; <[NOT USED]> ; + _mInfoBLOCK #28-$,#FF ; +RST_0x28: JP RST_28 ; +;' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '; +; + +; +;' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '; +; <[MOUSE API]> ; + _mInfoBLOCK #30-$,#FF ; +RST_0x30: PUSH AF +.drv_page+1: LD A,#FF + OUT (SLOT0),A + POP AF + RET +;' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '; +; + +//////////////////////////////////////////////////////////////////////// +; <[MAIN INT]> + _mInfoBLOCK #38-$,#FF + ;для того, чтоб софты могли менять обработчик на свой. +RST_38_IM1: JP .Handler +.Handler: CALL INTx38_Handler + EI + RETI + ; +.Portal: PUSH AF + LD A,(RST_0x30.drv_page) + OUT (SLOT0),A + ;POP AF + PUSH HL + LD HL,(RST_38_IM1+1) + XOR A + CP H + JR NZ,.error + LD A,low .Handler + CP L + JR NZ,.error + POP HL + POP AF + CALL INTx38_Handler + JR .Portal + ; +.error: POP HL + POP AF + JR .Portal + ; +//////////////////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////////////////// +; +;NMI: RETN +; + +; +;' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '; +; <[ NMI ]> ; + _mInfoBLOCK #66-$,#FF ; +NMI_0x66: RETN ;JP NMI ; +;' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '; +; +//////////////////////////////////////////////////////////////////////// + +; +RST_10: PUSH HL + LD L,C + + IF SHORT_RSTx10_TABLE + ;[ ] R09 + LD H,A + LD A,#5F + SUB C + JR C,.error + LD A,H + ;[ ] R09 + ENDIF + + LD H,high ADRST10 + LD C,(HL) + INC H + LD H,(HL) + LD L,C + EX (SP),HL + RET + + IF SHORT_RSTx10_TABLE + ;[ ] R09 +.error: POP HL + JR NOPS + ;[ ] R09 + ENDIF +; + +; +;' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '; +; <[DRIVE PAGE SWITCH]> ; + _mInfoBLOCK #80-$,0 ; +;ENTER: ; +PORTAL.out_MAIN: ; + IN A,(C) ; + OUT (C),B ; + ASSERT $!=84,'-> Portal error!'; + POP BC ; + RET ; +;' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '; +; + + +;R01 +; Area for boot sector BootSector. +;BootSector _sBOOT_SECTOR_PARAMS ,{ "DSS_","0"+VERS,".",MODF/10+"0",MODF-(MODF/10)*10+"0" } +; end boot sector +;R01 + +; = -- = -- = -- = -- = = -- = -- = = -- = -- = = -- = -- = -- = -- = --; +; + +; +CLEAR_BUFFER_AND_INIT_PROC: + ;------[CLEAR BUFFERS]------; + ;R07 ;R11 + XOR A + LD HL,CLEAR_ZONE.start + LD DE,CLEAR_ZONE.start+1 + LD BC,CLEAR_ZONE.size-1 + LD (HL),A + LDIR + LD HL,':'*256 + 'X' + LD (CORE_BUFFERS.CurrentPath),HL + LD A,'\' ; + LD (CORE_BUFFERS.CurrentDirectory),A + LD (CORE_BUFFERS.WorkDirectory),A + ; + LD A,#FF + LD (CORE_BUFFERS.FatBuffer.DRIVE),A + ; + ;R07 ;R11 + ;R11 + LD HL,CORE_BUFFERS.FM_BUF + LD (HL),'.' + ;R11 + ;---------------------------; + ;R02 + ;LD B,#FF ;INIT ENVIRONMENT + CALL INITENV + IFN CLASSIC_CURSOR + CALL SETUP_CURSORS + ENDIF + ;R02 + JP VERSION + + + +INTx38_Handler: PUSH AF + EX AF,AF' + PUSH AF + PUSH BC + PUSH DE + PUSH HL + EXX + PUSH BC + PUSH DE + PUSH HL + PUSH IX + PUSH IY + CALL KEYSCAN + LD C,Dss.Mouse.GetPackets + RST ToDSS.Mouse + ;CALL M_INT + IFN CLASSIC_CURSOR + CALL cursor_interrupt; вектор обслуж. курсора ;!!!!! VASIL + ENDIF + POP IY + POP IX + POP HL + POP DE + POP BC + EXX + POP HL + POP DE + POP BC + POP AF + EX AF,AF' + POP AF + RET +;R03 +;R07Allocate memory +; LD BC,#03C2 +; RST ToBIOS +; LD HL,BANKTBL +; LD C,A +; LD B,#FF +;VERINIT INC B +; PUSH BC +; PUSH HL +; LD A,C +; LD C,#C4 +; RST ToBIOS +; POP HL +; POP BC +; LD (HL),A +; INC HL +; JR NC,VERINIT +;R07;R03 +;R07 JP INIT2 ;R03 +; DS $/256+1*256-$,0 c:\bin\menu + +;----------------------------------------------------------------------; +;MEMTAB: BLOCK 256,0 +;----------------------------------------------------------------------; + + _mInfoALIGN 256,0 +;------------------------------------------------------------------------------------------------------------------------; +GO_ZERO EQU #0000 +;FUNCTION ADDRESS ARRAY +ADRST10: ;DS 512 ;,0 +;...............................................[LOW ADDRESS ]: +; 0 1 2 3 4 5 6 7 8 9 DEC HEX + DB low F_START, low CHNDISK_FN, low CURDISK_FN,low DISKINF, low NOPS, low NOPS, low NOPS, low NOPS, low SCANDRV, low BOOTDSK ; 0 00..09 + DB low CREATE, low CREATE.NEW, low NOPS, low NOPS, low DEL_FN, low NOPS, low RENAME, low OPEN_FN, low CLOSE_FN, low READ ; 1 0A..13 + DB low WRITE, low MOVE_FP, low ATTRIB, low GET_D_T, low PUT_D_T, low F_FIRST_FN,low F_NEXT, low MKDIR.B, low RMDIR, low CHDIR_FN ; 2 14..1D + DB low CURRDIR_FN,low NOPS, low NOPS, low SYSTIME, low SETTIME, low NOPS, low NOPS, low NOPS, low NOPS, low NOPS ; 3 1E..27 + DB low NOPS, low NOPS, low NOPS, low NOPS, low NOPS, low NOPS, low NOPS, low NOPS, low WAITKEY, low SCANKEY ; 4 28..31 + DB low ECHOKEY, low CTRLKEY, low NOPS, low K_CLEAR, low K_SETUP, low TESTKEY, low SETWIN, low SETWIN1, low SETWIN2, low SETWIN3 ; 5 32..3B + DB low FREEMEM, low GETMEM, low RETMEM, low SETMEM, low EXEC, low LEAVE, low GET_ERR, low GSWITCH, low DOSNAME, low EX_PATH ; 6 3C..45 + DB low ENVIRON, low APPINFO, low NOPS, low NOPS, low NOPS, low NOPS, low NOPS, low NOPS, low NOPS, low NOPS ; 7 46..4F + DB low SETVMOD, low GETVMOD, low LOCATE, low CURSOR, low SELPAGE, low SCROLL, low CLEAR, low RDCHAR, low WRCHAR, low WINCOPY ; 8 50..59 + DB low WINREST, low PUTCHAR, low PCHARS, low LIB_SUB, low NOPS, low PRINT ; 9 5A..5F + + IFN SHORT_RSTx10_TABLE + ;[ ] R09 + DB low NOPS, low NOPS, low NOPS, low NOPS ; 9 60..63 + DB low NOPS, low NOPS, low NOPS, low NOPS, low GO_ZERO, low GO_ZERO, low GO_ZERO, low GO_ZERO, low GO_ZERO, low GO_ZERO ; 10 64..6D + DUP 13 + DB low GO_ZERO, low GO_ZERO, low GO_ZERO, low GO_ZERO, low GO_ZERO, low GO_ZERO, low GO_ZERO, low GO_ZERO, low GO_ZERO, low GO_ZERO; 110-239 6E-EF + EDUP + DB low NOPS, low NOPS, low NOPS, low NOPS, low NOPS, low NOPS, low NOPS, low NOPS, low NOPS, low NOPS ; 24 F0..F9 + DB low NOPS, low NOPS, low NOPS, low NOPS, low NOPS, low NOPS ; END ; 25 FA..FF + + ELSE ;!TODO free space + + _mInfoBLOCK ADRST10+#100 - $,0 + ;[ ] R09 + ENDIF +;...............................................[HIGH ADDRESS]: + DB high F_START, high CHNDISK_FN,high CURDISK_FN,high DISKINF,high NOPS, high NOPS, high NOPS, high NOPS, high SCANDRV, high BOOTDSK + DB high CREATE, high CREATE.NEW,high NOPS, high NOPS, high DEL_FN, high NOPS, high RENAME, high OPEN_FN,high CLOSE_FN,high READ + DB high WRITE, high MOVE_FP, high ATTRIB, high GET_D_T,high PUT_D_T,high F_FIRST_FN,high F_NEXT, high MKDIR.B,high RMDIR, high CHDIR_FN + DB high CURRDIR_FN,high NOPS, high NOPS, high SYSTIME,high SETTIME,high NOPS, high NOPS, high NOPS, high NOPS, high NOPS + DB high NOPS, high NOPS, high NOPS, high NOPS, high NOPS, high NOPS, high NOPS, high NOPS, high WAITKEY, high SCANKEY + DB high ECHOKEY, high CTRLKEY, high NOPS, high K_CLEAR,high K_SETUP,high TESTKEY, high SETWIN, high SETWIN1,high SETWIN2, high SETWIN3 + DB high FREEMEM, high GETMEM, high RETMEM, high SETMEM, high EXEC, high LEAVE, high GET_ERR,high GSWITCH,high DOSNAME, high EX_PATH + DB high ENVIRON, high APPINFO, high NOPS, high NOPS, high NOPS, high NOPS, high NOPS, high NOPS, high NOPS, high NOPS + DB high SETVMOD, high GETVMOD, high LOCATE, high CURSOR, high SELPAGE,high SCROLL, high CLEAR, high RDCHAR, high WRCHAR, high WINCOPY + DB high WINREST, high PUTCHAR, high PCHARS, high LIB_SUB,high NOPS, high PRINT + + IFN SHORT_RSTx10_TABLE + ;[ ] R09 + DB high NOPS, high NOPS, high NOPS, high NOPS + DB high NOPS, high NOPS, high NOPS, high NOPS, high GO_ZERO,high GO_ZERO,high GO_ZERO,high GO_ZERO,high GO_ZERO, high GO_ZERO + DUP 13 + DB high GO_ZERO,high GO_ZERO,high GO_ZERO,high GO_ZERO,high GO_ZERO,high GO_ZERO,high GO_ZERO,high GO_ZERO,high GO_ZERO, high GO_ZERO + EDUP + DB high NOPS, high NOPS, high NOPS, high NOPS, high NOPS, high NOPS, high NOPS, high NOPS, high NOPS, high NOPS + DB high NOPS, high NOPS, high NOPS, high NOPS, high NOPS, high NOPS ; END + + ELSE + ;!TODO free space + ;_mInfoBLOCK ADRST10+#200 - $,0 + ;[ ] R09 + ENDIF +; DB low WINREST, low PUTCHAR, low PCHARS, low NOPS, low NOPS, low PRINT, low NOPS, low NOPS, low NOPS, low NOPS ; 9 5A..63 +; DB high WINREST,high PUTCHAR,high PCHARS, high NOPS, high NOPS, high PRINT, high NOPS, high NOPS, high NOPS, high NOPS +;---------------------------------------------------------------------------------------------------------------------------------------------------------------; +;[INCLUDE] + ;!TODO заменить по-максимому всё в KEYINTER.ASM на вызовы биоса + INCLUDE "KEYINTER.ASM" + INCLUDE "VIDEO.ASM" + INCLUDE "API.ASM" + INCLUDE "DOS_Proc.asm" + INCLUDE "FS/FAT/FAT.ASM" + INCLUDE "FS/FAT/FAT_X.ASM" + INCLUDE "DOS_FM.ASM" + INCLUDE "Procedures.asm" + INCLUDE "Kernel_Panic.asm" + + +; [ ] 26/06/2024& read only 64kb cluster ; !TODO cluster 64kb +CHECK_64kb_CLUSTER: + LD HL,(CORE_BUFFERS.FatBuffer.BytesPerCluster) + ; CF=0 + ADC HL,HL + LD A,DSS_Error.sys.WRITE_PROTECT + RET NZ + CCF + RET + ; + + +;!FIXIT к буферам +; Массив лог. номеров банок расширения DSS +BANKTBL: BLOCK USING_MEMPAGES+1,#FF ; +1 для COREPAGE +HANDBUF: BLOCK HANDBUF.SIZE,0 +; + +MASKARE: BLOCK 8,0 ; имя файла + BLOCK 3,0 ; расш. + BLOCK 21,0 ; 11+21=32 +; + DISPLAY "DOS-MAIN end address: ",/H,$-1 +; + +;!TODO к буферам! +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* +; 259 +CurrentPath: DB 'X' + DB ':' +CurrentDirectory: DB '\' +.DEPTH: EQU DIRECTORY_PATH_LENGTH + BLOCK CurrentDirectory.DEPTH,0 ; не .DEPTH-1 чтоб был 0 в конце +; +; 257 +WorkDirectory: DB '\' +.DEPTH: EQU DIRECTORY_PATH_LENGTH + BLOCK WorkDirectory.DEPTH,0 ; не .DEPTH-1 чтоб был 0 в конце + +; 516 +*/ +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +; +;> > > > > > > > > > > > > > > > BUFFERS < < < < < < < < < < < < < < < < +; +; +CLEAR_ZONE.start EQU $ + + MODULE CORE_BUFFERS +BUFFERSplace _sBuffers=$ +FM_BUF _sFM = BUFFERSplace.FileManipulator +.Size EQU _sFM +.FullSize EQU FMCOUNT*FM_BUF.Size +FatBuffer _sFatBuffer = BUFFERSplace.FatBuffer +EXEBUFF _sEXE_HEADER = BUFFERSplace.EXE_Header +XSTACK _sStack = BUFFERSplace.Stack +.Spoint EQU XSTACK + _sStack +BUFFER EQU BUFFERSplace.Buffer +SECTOR_BUFFER EQU BUFFER ;!TODO отделить SECTOR_BUFFER от BUFFER +MemoryTable EQU BUFFERSplace.MemoryTable +CurrentPath EQU BUFFERSplace.CurrentPath +CurrentDirectory EQU BUFFERSplace.CurrentDirectory +.DEPTH EQU DIRECTORY_PATH_LENGTH +WorkDirectory EQU BUFFERSplace.WorkDirectory +.DEPTH EQU DIRECTORY_PATH_LENGTH + ENDMODULE +; +; CurrentPath EQU CORE_BUFFERS.BUFFERSplace + _sBuffers +; CurrentDirectory EQU CurrentPath + 2 +; .DEPTH: EQU DIRECTORY_PATH_LENGTH +; ; +; WorkDirectory EQU CurrentDirectory + 1 + CurrentDirectory.DEPTH +; .DEPTH: EQU DIRECTORY_PATH_LENGTH +; +CLEAR_ZONE.size EQU _sBuffers + + + ASSERT (CLEAR_ZONE.start + _sBuffers)<#4000, "Warning!!! OUT OF SLOT0" + + DISPLAY "--- --- --- --- --- --- --- ---" + DISPLAY "CLEAR_ZONE.start ", /H, CLEAR_ZONE.start + DISPLAY "CLEAR_ZONE.Size ", /H, CLEAR_ZONE.size + DISPLAY "--- --- --- --- --- --- --- ---" + DISPLAY "Consist: " + DISPLAY " FM_BUF ", /H, CORE_BUFFERS.FM_BUF + DISPLAY " FM_BUF.Size: ", /H, CORE_BUFFERS.FM_BUF.Size + DISPLAY " FM_BUF.FullSize ", /H, CORE_BUFFERS.FM_BUF.FullSize + DISPLAY " FatBuffer ", /H, CORE_BUFFERS.FatBuffer + DISPLAY " FatBuffer.Size ", /H, CORE_BUFFERS.EXEBUFF - CORE_BUFFERS.FatBuffer + DISPLAY " EXEBUFF ", /H, CORE_BUFFERS.EXEBUFF + DISPLAY " Size ", /H, CORE_BUFFERS.XSTACK - CORE_BUFFERS.EXEBUFF + DISPLAY " XSTACK ", /H, CORE_BUFFERS.XSTACK + DISPLAY " Size ", /H, CORE_BUFFERS.BUFFER - CORE_BUFFERS.XSTACK + DISPLAY " BUFFER ", /H, CORE_BUFFERS.BUFFER + DISPLAY " Size ", /H, CORE_BUFFERS.MemoryTable - CORE_BUFFERS.BUFFER + DISPLAY " MemoryTable ", /H, CORE_BUFFERS.MemoryTable + DISPLAY " Size ", /H, _sBuffers - (CORE_BUFFERS.MemoryTable - CORE_BUFFERS.BUFFERSplace) + DISPLAY "--- --- --- --- --- --- --- ---" + DISPLAY "CLEAR_ZONE.End ", /H, CLEAR_ZONE.start + CLEAR_ZONE.size + DISPLAY "--- --- --- --- --- --- --- ---" + + EXPORT CORE_BUFFERS.BUFFERSplace + EXPORT CORE_BUFFERS.FM_BUF + EXPORT CORE_BUFFERS.FatBuffer + EXPORT CORE_BUFFERS.EXEBUFF + EXPORT CORE_BUFFERS.XSTACK + EXPORT CORE_BUFFERS.BUFFER + EXPORT CORE_BUFFERS.SECTOR_BUFFER + EXPORT CORE_BUFFERS.MemoryTable +/* +;R11 \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ +FM_BUF _sFM=$ +.Size EQU _sFM +.FullSize EQU FMCOUNT*FM_BUF.Size + +;????? а не грузится ли полностью сектор в 512 байтов при загрузке хэдера? +EXEBUFF _sEXE_HEADER=$+FM_BUF.FullSize +; EXEBUFF: +; DB "EXE" +; DB #00 +; OFFCOD1 DW #0000 +; OFFCOD2 DW #0000 +; LOADER DW #0000 +; DW #0000 +; DW #0000 +; DW #0000 +; LD_ADDR DW #0000 +; PC_REG DW #0000 +; SP_REG DW #0000 +; BLOCK 512-($-EXEBUFF),0 + +;(!!!HERE STACK FOR EXEC!!!) +; BLOCK 255,0 +;XSTACK DB #00 +XSTACK EQU EXEBUFF+_sEXE_HEADER+255 + +BUFFER EQU XSTACK+1 +SECTOR_BUFFER EQU BUFFER +;R11 //////////////////////////////// +*/ + +; +;> > > > > > > > > > > > > > > > BUFFERS < < < < < < < < < < < < < < < < +; + + +;||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| +; затрётся после инициализации +;||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + + +; Первый старт системы, после инициализации адрес в таблице меняется на VERSION +F_START: DI + ;[x] 17.12.2023 загрузка с активного раздела, а не с первого + ;LD (.saveDRV),A + LD H,A + LD (.saveDRV),HL ; H - номер устройства, L - номер раздела на устройстве + ; + + ;R12 + LD C,BIOS.DRV_VERSION + RST ToBIOS + JR C,.err_oldBIOS + EX DE,HL + LD DE,MINIMUM_BIOS_VERSION + SBC HL,DE + JR NC,.good + LD A,(.saveDRV+1) + CP 2 ;проверка на загрузку с дискеты, если с дискеты, то можно проигнорить запуск на BIOS ниже 2.55 + JR NC,.err_oldBIOS + LD HL,#C9AF ; XOR A : RET opcodes + LD (DRV_CONTENT + INITDVC.if_old),HL ;!!!!!! + ; + +.good: CALL DEPLOY ;R07 ;эта процедура затрётся после исполнения + RET C ;R10 + CALL KEYBOARD_INIT + CALL PRINT_INIT + LD C,Dss.Mouse.Init + RST ToDSS.Mouse + LD A,(VMODE) + LD C,Dss.Mouse.SetVideoMode + RST ToDSS.Mouse + ;CALL INITDVC ;R05 + ;R05 + LD C,Dss.DRV.Init + RST ToDSS.DRV + LD (LDRIVE),A + ;R05 +.saveDRV+1: + ;[x] 17.12.2023 загрузка с активного раздела, а не с первого + LD HL,0 ; H - номер устройства, L - номер раздела на устройстве + ;LD A,H + ;LD A,0 + ; + LD B,1 + CALL BOOTDSK + RET C + ; + EI + ;Set new address fn. VERSION + LD HL,ADRST10 + LD (HL),low VERSION ;R03 + INC H + LD (HL),high VERSION ;R03 + JP CLEAR_BUFFER_AND_INIT_PROC + ; + ;R12 +.err_oldBIOS: + LD HL,.err_oldBIOS_message + ;LD C,Dss.PChars + ;RST ToDSS + CALL PCHARS + SCF + RET +.err_oldBIOS_message: + DZ "\r\nWARNING! This version of DSS requires BIOS v2.55 or later to boot from IDE." + ; + +DEPLOY: ;Allocate memory + LD BC,USING_MEMPAGES*256 + BIOS.GetMem + RST ToBIOS + RET C ;R10 + LD C,A + + IN A,(SLOT3) + PUSH AF + IN A,(SLOT0) + LD (DRV_CONTENT + DRV_PAGE.MAIN_PAGE_NUMBER),A ;!TEST + OUT (SLOT3),A + + LD A,C + LD HL,BANKTBL + #C000 + LD C,BIOS.GetMemBlkPages + RST ToBIOS + ; должна идти после GetMemBlkPages, чтоб вместо + ; закрывашки #FF поставить страницу COREPAGE + LD HL,BANKTBL + COREPAGE + IN A,(SLOT0) + LD (HL),A + ; для API драйвера мышки + LD (MOUSE_HANDLER.CorePage),A + LD A,(BANKTBL + DRVPAGE) + LD (RST_0x30.drv_page),A + + POP AF + OUT (SLOT3),A + + SET_PAGE_X DRVPAGE + + PUSH AF + LD HL,DRV_CONTENT + LD DE,#C000 + LD BC,DRV_CONTENT.SIZE + LDIR + IN A,(SLOT3) + LD (DRV_PG_NUMBER),A + POP AF + OUT (SLOT3),A + AND A ;R10 + RET + + IF ENVVALUE != CORE_BUFFERS.BUFFER + ASSERT "Warning! ENVVALUE != BUFFER" + //BLOCK 1000,0 + ENDIF + +;--- --- --- --- [Build version] --- --- --- ---; +; C_OSTYPE +;--- --- --- --- --- --- --- --- --- --- --- ---; + + DISPLAY "DEPLOY end address: ",/H,$ +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||; + DISPLAY "Space for DRV-MAIN: ",/A,#4000-$," bytes." +DRV_CONTENT: + DISP 0 + INCLUDE 'DRV-MAIN.ASM' + ENT +DRV_CONTENT.SIZE EQU $-DRV_CONTENT + +BIN_END_ADDRESS EQU $ + + + DISPLAY "END ADDRESS: ",/H,BIN_END_ADDRESS + DISPLAY "Memory leacks when > ",/H, #4000+SUBLOAD_SIZE*512 + ASSERT $ < (#4001+SUBLOAD_SIZE*512),'-> Memory leack!!!'; + ASSERT DRV_CONTENT.SIZE < #4001,'-> Drivers code size > #4000!!!'; +;[END] + +; + + +; DTA DB " " +; DB " " +; DB #20 +; DW 0,0,0,0,0 +; DW 0 +; DW 0 +; CLUSTER DW 0 +; SIZE DW 0,0 +; ASCIIZ DB "FILENAME.EXT",#00 + + +;R06 +;R06 BUFFER +;R06 SECTOR_BUFFER DB ". ",#10 +;R06 DW 0,0,0,0,0 +;R06 DW #0000 +;R06 DW #0000 +;R06 DW #0000 +;R06 DW #0000,0000 +;R06 DB ".. ",#10 +;R06 DW 0,0,0,0,0 +;R06 DW #0000 +;R06 DW #0000 +;R06 DW #0000 +;R06 DW #0000,0000 +;R06 DS 512-64 ;,0 \ No newline at end of file diff --git a/Crazy Estex DSS/DSS/DSS_MACROSES.Z80 b/Crazy Estex DSS/DSS/DSS_MACROSES.Z80 new file mode 100644 index 0000000..776efd5 --- /dev/null +++ b/Crazy Estex DSS/DSS/DSS_MACROSES.Z80 @@ -0,0 +1,220 @@ +; +; MACRO BUFFER_KEYINTER +; _mInfoALIGN 256,0 +; ;KEYBOARD BUFFER +; SBUF: BLOCK 64,0 + + +; HEAD DB #00 +; HOST DB #00 + +; K_LOCK EQU $-KEYFLAG +; LANG_L EQU 7 +; PAUSE_L EQU 6 +; RES5_L EQU 5 +; RES4_L EQU 4 +; NUM_L EQU 3 +; SCRL_L EQU 2 +; INS_L EQU 1 +; CAPS_L EQU 0 +; KEYFLAG DB #02 ;D0-Key Pressed + +; K_SHIFT EQU $-KEYFLAG +; L_SHIFT EQU 7 +; R_SHIFT EQU 6 +; X_CTRL EQU 5 +; X_ALT EQU 4 +; L_CTRL EQU 3 +; L_ALT EQU 2 +; R_CTRL EQU 1 +; R_ALT EQU 0 +; KEYCTRL DB #00 + +; KEYFLG EQU $-KEYFLAG +; FLAG_E0 EQU 7 +; FLAG_F0 EQU 6 +; FLAG_E1 EQU 5 +; FLAG_04 EQU 4 +; FLAG_03 EQU 3 +; FLAG_02 EQU 2 +; FLAG_01 EQU 1 +; FLAG_00 EQU 0 +; DB #00 + +; SOUND_K EQU $-KEYFLAG +; FLAG_S7 EQU 7 +; FLAG_S6 EQU 6 +; FLAG_S5 EQU 5 +; FLAG_S4 EQU 4 +; FLAG_S3 EQU 3 +; FLAG_S2 EQU 2 +; SF_ALT EQU 1 +; SF_BUFF EQU 0 +; DB #03 +; ; +; ; D15 - LShift +; ; D14 - RShift +; ; D13 - CTRL +; ; D12 - ALT +; ; D11 - LCTRL +; ; D10 - LALT +; ; D9 - RCTRL +; ; D8 - RALT +; ; D7 - Language Lock +; ; D6 - Reserved +; ; D5 - Reserved +; ; D4 - Reserved +; ; D3 - Num Lock +; ; D2 - Scroll Lock +; ; D1 - Insert Lock +; ; D0 - Caps Lock +; ; +; ; D15 - Keystroke +; ; D14 +; ; D13 \ +; ; D12 \ +; ; D11 -- Position code (0...5Ah) +; ; D10 / +; ; D9 / +; ; D8 +; ; D7..D0 - ASCII code +; ; +; ENDM +; + +; +; MACRO TABLE_XLAT_T +; _mInfoALIGN 256,0 +; ; 0 1 2 3 4 5 6 7 8 9 A B C D E F +; XLAT_T: DB #00,#43,#00,#3F,#3D,#3B,#3C,#46,#00,#44,#42,#40,#3E,#0F,#00,#00 ;00 +; DB #00,#37,#29,#00,#36,#10,#02,#00,#00,#00,#2A,#1E,#1D,#11,#03,#00 ;10 +; DB #00,#2C,#2B,#1F,#12,#05,#04,#00,#00,#38,#2D,#20,#14,#13,#06,#00 ;20 +; DB #00,#2F,#2E,#22,#21,#15,#07,#00,#00,#00,#30,#23,#16,#08,#09,#00 ;30 +; DB #00,#31,#24,#17,#18,#0B,#0A,#00,#00,#32,#33,#25,#26,#19,#0C,#00 ;40 +; DB #00,#00,#27,#00,#1A,#0D,#00,#00,#1C,#34,#28,#1B,#00,#35,#00,#00 ;50 +; DB #00,#00,#00,#00,#00,#00,#0E,#00,#00,#51,#00,#54,#57,#00,#00,#00 ;60 +; DB #50,#4F,#52,#55,#56,#58,#01,#49,#45,#4D,#53,#4C,#4B,#59,#48,#00 ;70 +; DB #00,#00,#00,#41,#00,#00,#00,#00,#00,#00,#00,#00,#00,#00,#00,#00 ;80 +; ENDM +; + +; +; ВХОД: L - логический номер в таблице +; ВЫХОД: IY - начало записи +; ПОРТИТ: HL, DE, IY. + MACRO LOGDRV_ENTRY_FIND tbl_addr + LD H,0 + ADD HL,HL + ADD HL,HL + ADD HL,HL + ADD HL,HL + EX DE,HL + LD IY,tbl_addr + ADD IY,DE + ENDM +; + +; + MACRO _CALC_DEVICE_ENTRY tbl_addr + CP DSS_MAX_DRIVES_AMOUNT+1 + JR C,.norm + ; Error! + LD A,DSS_MAX_DRIVES_AMOUNT +.norm: LD C,A + ADD A,A + ADD A,C + LD C,A + LD B,0 + LD HL,tbl_addr + ADD HL,BC + ENDM +; + +; + MACRO SET_PAGE_X new_page + LD A,(BANKTBL+new_page) + LD B,A + LD C,SLOT3 + IN A,(SLOT3) + OUT (C),B + ENDM +; + +; + MACRO _mDSS_Version + DB 'DSS_' + db '0'+VERS + db '.' + db MODF/10+'0' + db MODF-(MODF/10)*10+'0' + ENDM +; + +; + MACRO C_OSTYPE + IF OSTYPE = DP + + C_OSNAME + DB "-DP [",#30+REVISION,']',0 + + ELSEIF OSTYPE = BETA + + C_OSNAME + DB '-BETA [',#30+REVISION,']',0 + + ELSEIF OSTYPE = RC + + C_OSNAME + DB '-RC [',#30+REVISION,']',0 + + ELSEIF OSTYPE = RELEASE + + C_OSRELEASE + ;DB "-RELEASE",0 + + ELSE + + C_OSNAME + DB "-UNKNOWN",0 + + ENDIF + ENDM +; + +; + MACRO C_OSNAME + DB "ESTEX",0 + ENDM +; + +; + MACRO C_OSRELEASE + DB "Estex DSS",0 + ENDM +; + +//////////////////////////////////////////////////////////////////////// +; +; MACRO _mSavePath force +; IF SAVE_PATH_MACRO +; PUSH HL +; IF force==1 +; LD HL,BACK_CUR_PATH.force +; ELSE +; LD HL,BACK_CUR_PATH +; ENDIF +; EX (SP),HL +; CALL SAVE_CUR_PATH +; ENDIF +; ENDM +; MACRO _mRestorePath +; IF SAVE_PATH_MACRO +; CALL BACK_CUR_PATH.force +; ENDIF +; ENDM +; MACRO _mRestorStackAfterRestorePath +; IF SAVE_PATH_MACRO +; POP HL ;CLEAR STACK "BACK_CUR_PATH" +; ENDIF +; ENDM +; \ No newline at end of file diff --git a/Crazy Estex DSS/DSS/DSS_MAP.TXT b/Crazy Estex DSS/DSS/DSS_MAP.TXT new file mode 100644 index 0000000..e57b7ad --- /dev/null +++ b/Crazy Estex DSS/DSS/DSS_MAP.TXT @@ -0,0 +1,62 @@ +0000-0038h RESTARTS + +003B-006BH 38h Interrupt + +0066-0068h NMI + +0069-0072h RST10 routine + +0073-007Fh Align space + +0080-0085h CALL interpage gate + +0086-00C3h BPB struct + +00C4-00FAh DSS INIT routine + +00FB-00FFH SPACE + +0100-01FFH MEMORY TABLE (OWNER) + +0200-03FFH FUNCTIONS ADDRESSES + +0400-043FH KEYBOARD BUFFER +0440-0BD1H KEYBOARD DRIVER + +0BD2-0EF5H SCREEN DRIVER + +0EF6-1100H FAT ROUTINES + +1101-1342H DISK IO ROUTINES + +1343-1443H CURRENT DIR NAME BUFFER + +1444-16BDH HANDLES AND FILE IO ROUTINES + +16BE-25C7H FILE AND DIR ROUTINES (DOS5) + +25C8-27ACH EXECUTE ROUTINES + +27AD-2882H MEMORY ROUTINES + +2883-2CAEH EXEC + +?2CAF-2EAEH EXEBUFFER (GLUK?) + +2EAF-2FAEH PROCESS STACK BUFFER + +2FAF-30CBH ENVIRONMENT ROUTINES + +30CC-35E0H MOUSE DRIVER +35E1-36E0H MOUSE IMAGE BUFFER + +36E1-370DH DTA BUFFER + +370D-37FFH SPACE + +3800-39FFH BUFFER & SECTOR BUFFER + + +3832-3833H ENDCODE + +3833-3FFFH FREE-SPACE diff --git a/Crazy Estex DSS/DSS/FS/FAT/FAT.asm b/Crazy Estex DSS/DSS/FS/FAT/FAT.asm new file mode 100644 index 0000000..c577793 --- /dev/null +++ b/Crazy Estex DSS/DSS/FS/FAT/FAT.asm @@ -0,0 +1,1199 @@ +;[BEGIN] +;//MODULE: FAT +;//CREATE: 19-05-1998 AUTHOR: Denis Parinov +;//UPDATE: 24-10-1999 DNS Restore module +;--------------------------------------------------------------- +;Rev Date Name Description +;--------------------------------------------------------------- +;R08 14-11-2002 DNS IMPROVE BPB-FUNCTION +;R07 17-12-1999 DNS BUG FIX SIGNATURE #55AA AT 510 OFFSET +;--------------------------------------------------------------- +;----------------------------------------------------------------------; + +SET_FSInfo: LD A,(CORE_BUFFERS.FatBuffer.FAT_TYPE) + CP FAT_TYPE.x32 + RET NZ + ; + LD A,(CORE_BUFFERS.FatBuffer.UPD_FSINFO) + OR A + RET Z + ; + ; Делаем FSInfo сектор + ; чистим сектор + LD HL,CORE_BUFFERS.SECTOR_BUFFER + LD DE,CORE_BUFFERS.SECTOR_BUFFER+1 + LD (HL),0 + LD BC,512 - 1 ;!HARDCODE размер сектора + LDIR + ; LEAD_SIGNATURE + LD HL,#5252 + LD (CORE_BUFFERS.SECTOR_BUFFER + _sFSinfo.LEAD_SIGNATURE),HL + LD HL,#4161 + LD (CORE_BUFFERS.SECTOR_BUFFER + _sFSinfo.LEAD_SIGNATURE + 2),HL + ; DATA_SIGNATURE + LD HL,#7272 + LD (CORE_BUFFERS.SECTOR_BUFFER + _sFSinfo.DATA_SIGNATURE),HL + LD HL,#6141 + LD (CORE_BUFFERS.SECTOR_BUFFER + _sFSinfo.DATA_SIGNATURE + 2),HL + ; SECTOR_SIGNATURE + LD HL,#AA55 + LD (CORE_BUFFERS.SECTOR_BUFFER + _sFSinfo.SECTOR_SIGNATURE),HL + ; FREE_CLUSTERS_COUNT + LD HL,(CORE_BUFFERS.FatBuffer.FREE_CLUSTERS_COUNT_L) + LD (CORE_BUFFERS.SECTOR_BUFFER + _sFSinfo.FREE_CLUSTERS_COUNT),HL + LD HL,(CORE_BUFFERS.FatBuffer.FREE_CLUSTERS_COUNT_H) + LD (CORE_BUFFERS.SECTOR_BUFFER + _sFSinfo.FREE_CLUSTERS_COUNT+2),HL + ; FIRST_FREE_CLUSTER + LD HL,(G_CLUST.low) + LD (CORE_BUFFERS.SECTOR_BUFFER + _sFSinfo.FIRST_FREE_CLUSTER),HL + LD HL,(G_CLUST.high) + LD (CORE_BUFFERS.SECTOR_BUFFER + _sFSinfo.FIRST_FREE_CLUSTER+2),HL + ; Пишем его на винт + XOR A + LD (CORE_BUFFERS.FatBuffer.UPD_FSINFO),A + JR WRITE_FSinfo +; ; +; Прочитать BPB в SECTOR_BUFFER +READ_BPB: LD C,Dss.DRV.GetBPB + JR RW_SECTOR +; Записать FSinfo из SECTOR_BUFFER +WRITE_FSinfo: LD IX,(CORE_BUFFERS.FatBuffer.FSINFO_Sector) + LD HL,0 + ;JR WRITE_SECTOR +; Записать сектор из SECTOR_BUFFER +; Вход: HL:IX = Logical Block (sector) +WRITE_SECTOR: LD BC,1*256 + Dss.DRV.Write + JR RW_SECTOR +; Прочитать FSinfo в SECTOR_BUFFER +READ_FSinfo: LD IX,(CORE_BUFFERS.FatBuffer.FSINFO_Sector) + LD HL,0 +; Прочитать сектор в SECTOR_BUFFER +; Вход: HL:IX = Logical Block (sector) +READ_SECTOR: LD BC,1*256 + Dss.DRV.Read + ; +RW_SECTOR: IN A,(SLOT3) + PUSH AF + IN A,(SLOT0) + OUT (SLOT3),A + ; + LD A,(CORE_BUFFERS.FatBuffer.DRIVE) + LD DE,CORE_BUFFERS.SECTOR_BUFFER+#C000 + RST ToDSS.DRV + EX AF,AF' + ; + POP AF + OUT (SLOT3),A + EX AF,AF' + RET +; + +; [ ] удаление записи LFN +; +; вход: IX = текущая запись в странице с каталогом FAT для которой +; надо удалить записи LFS +DELETE_LFN_RECORDS: + PUSH IX + LD A,XH + AND #C0 + SUB 1 + LD C,A + ; В регистре C маска для определения выхода за пределы страницы + ; +.find_LFN: LD DE, -(FAT_DIRECTORY_RECORD) + LD A,FAT_ATTR.LFS_Entry + ; +.loop: ADD IX,DE + LD A,XH + CP C + JR Z,.beyond_boundaries + ; + LD A,FAT_ATTR.LFS_Entry + CP (IX+FAT_DIRECTORY_RECORD.ATTRIBUT) + JR NZ,.exit + LD (IX+FAT_DIRECTORY_RECORD.NAME),#E5 + JR .loop + ; +.exit: AND A +.beyond_boundaries: ; !TODO подгрузка другой части каталога. пока заглушка + POP IX + RET +;----------------------------------------------------------------------; + + +; Поиск записи каталога в списке каталога +; +; вход: a = атрибут записи +; выход: de = индекс записи в списке каталога +; (HANDBUF) = file's direcory record +; CF - каталог не найден +SEARCH: +.Dir: ;LD A,FAT_ATTR.DIRECTORY + LD A,FAT_ATTR.HiddenSysDir + CALL .Custom + RET NC + CP DSS_Error.sys.PATH_NOT_FOUND + 1 + RET C + ; + SCF + LD A,DSS_Error.sys.TOO_MANY_FILES_IN_DIR + RET + ; +.File: LD A,FAT_ATTR.NoDIRnoVolID +.Custom: EX AF,AF' ; A = 76ADLSHR + SET_PAGE_X DIRPAGE + ;PUSH AF + EX AF,AF' + ; + CPL + LD C,A + LD IX,DIRPAGE.buffer + ;!TEST 9/11/23 record index + ; оптимизация для индекса записи в списке каталога. + ; Понадобится вернуть для перебора каталога > #4000 байт + ; EXX + ; LD DE,0 + ; EXX + ; +.loop: LD A,(IX+FAT_DIRECTORY_RECORD.NAME) + OR A + JR Z,.error_file_not_found + CP #E5 ;!HARDCODE #E5 - запись в директории свободна, так как файл/директория были удалены + JR Z,.next_record + LD A,(IX+FAT_DIRECTORY_RECORD.ATTRIBUT) + AND C + JR NZ,.next_record + LD HL,MASKARE + LD D,XH + LD E,XL + LD B,11 + EX DE,HL +.loop_compare: + LD A,(DE) + CP '?' + JR Z,.next_char + CP (HL) + JR NZ,.next_record +.next_char: + INC HL + INC DE + DJNZ .loop_compare + ; + LD D,XH + LD E,XL + ;!TEST 9/11/23 record index + ; EXX + ; PUSH DE + ; EXX + PUSH IX + ; + LD HL,HANDBUF + EX DE,HL + LD BC,HANDBUF.SIZE + LDIR + ;!TEST 9/11/23 record index + POP DE + ; + EX AF,AF' + OUT (SLOT3),A + EX AF,AF' + AND A + RET +.next_record: + LD DE,FAT_DIRECTORY_RECORD + ;!TEST 9/11/23 record index + ; EXX + ; INC DE + ; EXX + ; + ADD IX,DE + JR NC,.loop +.error_too_many_files: + EX AF,AF' + OUT (SLOT3),A + LD A,DSS_Error.sys.TOO_MANY_FILES_IN_DIR + SCF + RET + ; +.error_file_not_found: + EX AF,AF' + OUT (SLOT3),A + LD A,DSS_Error.sys.FILE_NOT_FOUND + SCF + RET +;----------------------------------------------------------------------; + +; +;!TODO ? +;GHANDLE: +; PUSH DE +; PUSH HL +; PUSH IX +; CALL TESTDSK +; JP C,G_HAND1 +; CALL LOADDIR +; POP DE +; LD HL,DIR +; LD BC,FAT_DIRECTORY_RECORD +;G_HAND2: +; LD A,D +; OR E +; JP Z,G_HAND3 +; ADD HL,BC +; DEC DE +; JP G_HAND2 +;G_HAND3: +; EXX +; POP DE +; EXX +;G_HAND4: +; EX DE,HL +; LD A,DIRPAGE +; CALL BANK +; EX DE,HL +; LD DE,HANDTA +; +; DUP 32 +; LDI +; EDUP +; +; EXX +; OUT (SLOT3),A +; LD HL,HANDTA +; +; DUP 32 +; LDI +; EDUP +; +; EXX +; POP BC +; DEC BC +; LD A,B +; OR C +; RET Z +; PUSH BC +; JP G_HAND4 +;G_HAND1 POP IX +; POP HL +; POP DE +; RET +;HANDTA BLOCK 32,0 +; + +;----------------------------------------------------------------------; +; FIND "MASKAREA" IN DIRECTORY +; [x] fat32 ;!TEST +; выход: IY:DE - cluster number +FINDDIR: + SET_PAGE_X DIRPAGE + ; + PUSH AF + LD IX,DIRPAGE.buffer +.big_loop: + LD A,(IX + FAT_DIRECTORY_RECORD.NAME) + OR A + JR Z,.error + CP #E5 + JR Z,.next_step + LD A,(IX + FAT_DIRECTORY_RECORD.ATTRIBUT) + AND FAT_ATTR.DIRECTORY + JR Z,.next_step + LD HL,MASKARE + LD D,XH + LD E,XL + EX DE,HL + LD B,11 ;!HARDCODE +.loop: LD A,(DE) + CP "?" + JR Z,.compared + CP (HL) + JR NZ,.next_step +.compared: + INC HL + INC DE + DJNZ .loop + ; + LD A,(IX + FAT_DIRECTORY_RECORD.NAME) + CP "." + JP NZ,.ADDSPEC + LD A,(IX + FAT_DIRECTORY_RECORD.NAME + 1) + CP "." + JP NZ,.IT_DIR + LD HL,CORE_BUFFERS.WorkDirectory + LD D,H + LD E,L + INC HL + LD BC,CORE_BUFFERS.WorkDirectory.DEPTH + XOR A + CPIR + JP PO,.error ;[x] 20/11/23 проверка на выход за границы + DEC HL ;R009 + DEC HL + LD BC,CORE_BUFFERS.WorkDirectory.DEPTH + LD A,'\' + CPDR + INC HL + EX DE,HL + ; CF = 0 + SBC HL,DE + EX DE,HL + JR NZ,.MM3 + INC HL +.MM3: LD (HL),0 + JP .IT_DIR + ; +.next_step: + LD BC,FAT_DIRECTORY_RECORD + ADD IX,BC + JR NC,.big_loop + ; +.error: POP AF + OUT (SLOT3),A + LD A,DSS_Error.sys.PATH_NOT_FOUND + SCF + RET + ; +.ADDSPEC: + LD HL,CORE_BUFFERS.WorkDirectory+1 + LD BC,CORE_BUFFERS.WorkDirectory.DEPTH-1 + CALL .CHECK_SLASH + JR C,.error + ;R011 + LD A,B + AND A + JR NZ,.nxt + LD A,C + CP 8+1+3 ;!HARDCODE имя каталога + точка + расширение + JR C,.error +.nxt: ; + LD E,XL + LD D,XH + ; [x] оптимизация по размеру + EX DE,HL + CALL GetName + EX DE,HL + ; + +; LD BC,256*8 + ' ' ;!HARDCODE +; .MM1: LD A,(DE) +; INC DE +; CP C +; JR Z,.MM2 +; LD (HL),A +; INC HL +; .MM2 DJNZ .MM1 ;x42-40 50-55 +; LD A,(DE) +; INC DE +; CP C +; JR Z,.MM3 +; LD (HL),"." +; INC HL +; LD (HL),A +; INC HL +; LD A,(DE) +; INC DE +; CP C +; JR Z,.MM3 +; LD (HL),A +; INC HL +; LD A,(DE) +; CP C +; JR Z,.MM3 +; LD (HL),A +; .MM2_5: INC HL +; .MM3: LD (HL),0 +; ; JP IT_DIR + ; +.IT_DIR:; fat32 + LD E,(IX + FAT_DIRECTORY_RECORD.FIRST_CLUSTER_H) + LD D,(IX + FAT_DIRECTORY_RECORD.FIRST_CLUSTER_H+1) + LD YH,D + LD YL,E + LD E,(IX + FAT_DIRECTORY_RECORD.FIRST_CLUSTER_L) + LD D,(IX + FAT_DIRECTORY_RECORD.FIRST_CLUSTER_L+1) + POP AF + OUT (SLOT3),A + AND A + RET +.CHECK_SLASH: + XOR A + CPIR + ;[x] 20/11/23 проверка на выход за границы + SCF + RET PO + ; + DEC HL + DEC HL + LD A,'\' ; #5C + CP (HL) + INC HL + RET Z + LD (HL),A + INC HL + LD (HL),0 + ;INC HL + RET +;----------------------------------------------------------------------; + +CHECK_ROOT_CLUSTER: + EX DE,HL + LD HL,(CORE_BUFFERS.FM_BUF.FS_REC.FIRST_CLUSTER_L) ;R005 + LD A,L + OR H + LD HL,(CORE_BUFFERS.FM_BUF.FS_REC.FIRST_CLUSTER_H) + OR L + OR H + EX DE,HL + RET + +;----------------------------------------------------------------------; +; вход: HL - имя директории +; [x] fat32 ;!TEST +OPENDIR: LD IY,CORE_BUFFERS.FM_BUF + LD A,(HL) + OR A + JR NZ,.SUBDIR + ; +.REROOT: LD DE,0 + LD (CORE_BUFFERS.FM_BUF.FS_REC.FIRST_CLUSTER_L),DE + LD (CORE_BUFFERS.FM_BUF.FS_REC.FIRST_CLUSTER_H),DE + CALL LOADDIR + ; CF=0 + LD HL,CORE_BUFFERS.WorkDirectory + LD (HL),'\' + INC HL + LD (HL),#00 + ;AND A + RET + ; +.SUBDIR: CP "." + JR NZ,.SUBDIR2 + ; fat32 + CALL CHECK_ROOT_CLUSTER + JR NZ,.no_root ;R005 + ; "cd ." or "cd .." + ;R005 + INC HL + LD A,(HL) + OR A + DEC HL + JR Z,.REROOT + ; +.no_root: EXX + LD HL,MASKARE + LD DE,MASKARE+1 + LD BC,10 ;!HARDCODE + LD (HL),' ' + LDIR + EXX + LD DE,MASKARE +.loop: LDI + LD A,(HL) + OR A + JR NZ,.loop + JR .SUBDIR3 + ; +.SUBDIR2: CALL MASK.name + RET C + ; fat32 +.SUBDIR3: CALL FINDDIR + RET C + EX DE,HL + LD (CORE_BUFFERS.FM_BUF.FS_REC.FIRST_CLUSTER_L),HL ; fat32 + LD (CORE_BUFFERS.FM_BUF.FS_REC.FIRST_CLUSTER_H),IY ; fat32 + LD HL,#4000 ;!HARDCODE + LD (CORE_BUFFERS.FM_BUF.FS_REC.F_SIZE),HL +;-------------; EX DE,HL +; JP LOADDIR +; Прочитать список каталога +; [x] fat32 ;!TEST +LOADDIR: ;!TODO optimize + CALL LOAD_SAVE_DIR_PREPARE + PUSH AF + EX AF,AF' + JR NZ,.read_dir + LD A,(CORE_BUFFERS.FatBuffer.FAT_TYPE) + CP FAT_TYPE.x32 + JR NZ,.LoadRootDir + ; fat32 + LD HL,(CORE_BUFFERS.FatBuffer.RootDirStartCluster_L) + LD (CORE_BUFFERS.FM_BUF.FS_REC.FIRST_CLUSTER_L),HL + LD HL,(CORE_BUFFERS.FatBuffer.RootDirStartCluster_H) + LD (CORE_BUFFERS.FM_BUF.FS_REC.FIRST_CLUSTER_H),HL + + ;LD HL,(CORE_BUFFERS.FatBuffer.BytesPerCluster) ; !FIXIT вычитывать полностью каталог + LD HL,#4000 ; размер директории + LD (CORE_BUFFERS.FM_BUF.FS_REC.F_SIZE),HL + ; +.read_dir: LD HL,DIRPAGE.buffer ; куда + LD DE,#4000 ; сколько + XOR A ; дескриптор + CALL READ ; чтение из файла + LD (SAVEDIR.DIRSIZE),DE ; число прочит. байтов + POP AF + OUT (SLOT3),A + RET + ; +.LoadRootDir: LD HL,(CORE_BUFFERS.FatBuffer.RootDirFirstSector_H) ;!TODO возможно, хватит LD HL,0 + LD IX,(CORE_BUFFERS.FatBuffer.RootDirFirstSector_L) ; номер лог. сектора + LD A,(CORE_BUFFERS.FatBuffer.DirSizeInSectors) + LD B,32 ; !HARDCODE sector size 512. 16384/(sector 512). размер root-каталога + CP B + JR NC,.RTD1 + LD B,A ; число секторов +.RTD1: LD A,(CORE_BUFFERS.FatBuffer.DRIVE) ; номер диска + LD DE,DIRPAGE.buffer ; буфер + LD C,Dss.DRV.Read ; чтение секторов + RST ToDSS.DRV + POP AF + OUT (SLOT3),A + RET +;----------------------------------------------------------------------; + + +;!TODO FAT procedures +;----------------------------------------------------------------------; + +LOAD_SAVE_DIR_PREPARE: + ;!TODO optimize + XOR A ; FILE MANIPULATOR = 0 + LD H,A + LD L,A + LD IX,0 + LD B,A ; от начала файла + CALL MOVE_FP + ; + SET_PAGE_X DIRPAGE + AND A + EX AF,AF' + ; + LD A,(CORE_BUFFERS.FatBuffer.DRIVE) + LD (IY+_sFM.DRIVE),A + ;!FIXIT переделать на работу без IY + LD A,(IY+_sFM.FS_REC.FIRST_CLUSTER_L) + OR (IY+_sFM.FS_REC.FIRST_CLUSTER_L+1) + OR (IY+_sFM.FS_REC.FIRST_CLUSTER_H) + OR (IY+_sFM.FS_REC.FIRST_CLUSTER_H+1) + ; + EX AF,AF' + RET + +;----------------------------------------------------------------------; +; скопировать запись в список диска (каталога) de ix iy +; и сбросить кеш каталога на диск +; вход: (HANDBUF) - запись каталога +WRT_HND: + SET_PAGE_X DIRPAGE + EX AF,AF' + LD HL,DIRPAGE.buffer + ;!TEST 9/11/23 record index + ; EXX + ; LD DE,0 + ; EXX + ; + LD BC,FAT_DIRECTORY_RECORD +.loop: ;LD A,(IX+00) + LD A,(HL) + OR A + JR Z,.WRT_HN2 + CP #E5 + JR Z,.WRT_HN2 + ;ADD IX,BC + ADD HL,BC + JR NC,.loop ;!FIXIT количество записей каталога = страница + ; + EX AF,AF' + OUT (SLOT3),A + LD A,DSS_Error.sys.ROOT_OVERFLOW + SCF + RET + ; +.WRT_HN2: ;LD D,XH + ;LD E,XL + EX DE,HL + LD HL,HANDBUF + LD BC,HANDBUF.SIZE + LDIR + EX AF,AF' + OUT (SLOT3),A + LD HL,DIRPAGE.buffer + LD BC,(SAVEDIR.DIRSIZE) + DEC BC + ADD HL,BC + AND A + SBC HL,DE + JR NC,SAVEDIR + LD HL,(SAVEDIR.DIRSIZE) + LD BC,(CORE_BUFFERS.FatBuffer.BytesPerCluster) + ADD HL,BC + LD (SAVEDIR.DIRSIZE),HL + AND A + ;JP SAVEDIR +;----------------------------------------------------------------------; +; Сбросить кеш каталога на диск. +; вход: iy=структура дескриптора +; [x] fat32 ;!TEST +SAVEDIR: ;!TODO optimize + CALL LOAD_SAVE_DIR_PREPARE + PUSH AF + EX AF,AF' + JR NZ,.save_dir + ; + LD A,(CORE_BUFFERS.FatBuffer.FAT_TYPE) + CP FAT_TYPE.x32 + JR NZ,.SaveRootDir + ; fat32 + LD HL,(CORE_BUFFERS.FatBuffer.RootDirStartCluster_L) + LD (CORE_BUFFERS.FM_BUF.FS_REC.FIRST_CLUSTER_L),HL + LD HL,(CORE_BUFFERS.FatBuffer.RootDirStartCluster_H) + LD (CORE_BUFFERS.FM_BUF.FS_REC.FIRST_CLUSTER_H),HL + ; +.save_dir: LD HL,DIRPAGE.buffer + ; размер списка каталога size_cash_directory + ;!FIXIT если она нужна, то проверить на баги (например, размер дирректории меньше при открытии и больше после правок) + ; когда будет чтение кусками каталога в кэш, тут ещё счётчик прикрутить +.DIRSIZE+1: LD DE,0 + XOR A + CALL WRITE + POP AF + OUT (SLOT3),A + RET + ; +.SaveRootDir: LD HL,(CORE_BUFFERS.FatBuffer.RootDirFirstSector_H) ;!TODO возможно, хватит LD HL,0 + LD IX,(CORE_BUFFERS.FatBuffer.RootDirFirstSector_L) + LD A,(CORE_BUFFERS.FatBuffer.DirSizeInSectors) + LD B,32 ;!HARDCODE sector size 512, Root Dir max size in sectors + SUB B + JR NC,.RTD1S + ADD A,B + LD B,A +.RTD1S: LD A,(CORE_BUFFERS.FatBuffer.DRIVE) + LD DE,DIRPAGE.buffer + LD C,Dss.DRV.Write + RST ToDSS.DRV + POP AF + OUT (SLOT3),A + RET +;----------------------------------------------------------------------; + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +; [x] fat32 ;!TEST +RD_BPB: ; LD C,SLOT3 + ; IN B,(C) + ; PUSH BC + ; IN A,(SLOT0) + ; OUT (SLOT3),A + ; LD A,(CORE_BUFFERS.FatBuffer.DRIVE) + ; LD DE,CORE_BUFFERS.SECTOR_BUFFER+#C000 ;R08 + ; LD C,Dss.DRV.GetBPB + ; RST ToDSS.DRV + ; POP BC + ; OUT (C),B + CALL READ_BPB + JP C,DOS_X_Error.Not_ready + ; + LD DE,#AA55 ; сигнатура ;R05 + LD HL,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.MBR_SIGNATURE) ;R08 ;R07 + ;R05 + AND A + SBC HL,DE + JP NZ,DOS_X_Error.UnknownBPB + ; + ; ;R08 ; [x] fat32 + ; LD HL,CORE_BUFFERS.SECTOR_BUFFER + ; LD DE,CORE_BUFFERS.BootSector + ; LD BC,_sBOOT_SECTOR_PARAMS_FAT32 ; size + ; LDIR + ; + LD A,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.DRIVE_TYPE) + CP #F0 + JP C,DOS_X_Error.UnknownBPB + ; + LD HL,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.BytesPerSector) + LD (CORE_BUFFERS.FatBuffer.BytesPerSector),HL + LD A,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.SectorsPerCluster) + LD (CORE_BUFFERS.FatBuffer.SectorsPerCluster),A + ; calc. first sector FAT + LD HL,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.RESERVED_SECTORS) + LD (CORE_BUFFERS.FatBuffer.FAT1_SEC_L),HL ; low word first sector FAT #1 + LD (CORE_BUFFERS.FatBuffer.FAT2_SEC_L),HL ; low word first sector FAT #2 + ;[ ] fat32 + XOR A + LD B,A + LD C,A + LD (CORE_BUFFERS.FatBuffer.FAT1_SEC_H),BC ; high word first sector FAT #1 ; [ ] fat32 + LD (CORE_BUFFERS.FatBuffer.FAT2_SEC_H),BC ; high word first sector FAT #1 ; [ ] fat32 + LD (CORE_BUFFERS.FatBuffer.RootDirFirstSector_H),BC + LD (CORE_BUFFERS.FatBuffer.SectorsPerFAT_H),A ; [ ] fat32 + ;LD (CORE_BUFFERS.FatBuffer.END_CHAIN_CLUSTER_H),BC ; [ ] fat32 reset variables + ; + ; + EXX + LD H,A + LD L,A + LD D,A + LD E,A + EXX + LD DE,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.SectorsPerFAT16) + LD A,E + OR D + JR NZ,.skip_high + ; + EXX + LD DE,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.SectorsPerFAT32 + 2) + LD A,E + EXX + ; + LD (CORE_BUFFERS.FatBuffer.SectorsPerFAT_H),A + LD DE,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.SectorsPerFAT32) + ; +.skip_high: LD (CORE_BUFFERS.FatBuffer.SectorsPerFAT_L),DE + LD A,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.Number_of_FATs) ; amount FATs + LD (CORE_BUFFERS.FatBuffer.Number_Of_FATs),A + CP 1 + JR Z,.one_FAT + DEC A + ADD HL,DE + LD (CORE_BUFFERS.FatBuffer.FAT2_SEC_L),HL + EXX + ADC HL,DE + LD (CORE_BUFFERS.FatBuffer.FAT2_SEC_H),HL + EXX + ;JR NC,.no_inc_BC + ;INC BC +.no_inc_BC:;LD (CORE_BUFFERS.FatBuffer.FAT2_SEC_H),BC +.one_FAT: ; +.loop1: ADD HL,DE + ;JR NC,.loop1_1 + ;INC BC + EXX + ADC HL,DE + EXX +.loop1_1: DEC A + JR NZ,.loop1 + ; + LD (CORE_BUFFERS.FatBuffer.RootDirFirstSector_L),HL ; first sector DIR + EXX + ; можно сразу тут загнать старший байт, потому-что дла FAT32 следующий расчёт - это прибавление нуля. + LD (CORE_BUFFERS.FatBuffer.FirstDataSector_H),HL + EXX + ;LD (CORE_BUFFERS.FatBuffer.FirstDataSector_H),BC + ; + LD BC,(CORE_BUFFERS.FatBuffer.BytesPerSector) + LD A,B + AND A + ; + RL C + RLA + RL C + RLA + RL C + RLA + ; + LD C,A + LD B,0 ; BC - File handels per sector + ;;;; + IF COMPILE_UNUSED_CODE + LD (CORE_BUFFERS.FatBuffer.FilesPerSector),A + ENDIF + ; + EX DE,HL + LD HL,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.FilesInRootDIR) ; 0 for fat32 + ; [ ]fat32 ;!TEST + LD A,H + OR L + JR Z,.skip_loop2 + ; + DEC HL + XOR A + ;NEXTAD2 +.loop2: INC A + JP Z,DOS_X_Error.UnknownBPB + SBC HL,BC + JR NC,.loop2 + ; +.skip_loop2: EX DE,HL + LD C,A ; A - sectors in DIR + LD B,0 + LD (CORE_BUFFERS.FatBuffer.DirSizeInSectors),A + + ADD HL,BC ; Start DATA area + LD (CORE_BUFFERS.FatBuffer.FirstDataSector_L),HL + ; B = 0 + ; + LD HL,(CORE_BUFFERS.FatBuffer.BytesPerSector) + LD A,(CORE_BUFFERS.FatBuffer.SectorsPerCluster) + ;!TODO FATcacheSize + ; calc. cluster size + XOR 1 + JR Z,.loop3.end + RRA +.loop3: ADD HL,HL + RRA + JP NC,.loop3 +.loop3.end: ; + LD (CORE_BUFFERS.FatBuffer.BytesPerCluster),HL + ;LD DE,#8001 ; проверка на размер кластера больше 32 кб - не поддерживается ; !TODO + ;AND A + ;SBC HL,DE + ;JP NC,DOS_X_Error.UnknownBPB ; [ ] fixed bug, thanks to @Romychs (Roman Boykov) +//////////////////////////////////////////////////////////////////////// +;!TODO не используется значения вычисляемые и сохраняемые в FatBuffer +; EX DE,HL +; LD HL,#3FFF ;!HARDCODE ;!TODO FATcacheSize +; XOR A +; ;NEXTAD4 ;!FIXIT оптимизировать когда понадобится +;.loop4: INC A +; JP Z,DOS_X_Error.UnknownBPB +; SBC HL,DE +; JR NC,.loop4 +; LD (CORE_BUFFERS.FatBuffer.ClustersPerBank),A ; A - Clusters per bank (16k) +; +; LD HL,0 +; LD BC,(CORE_BUFFERS.SECTOR_BUFFER + _sBOOT_SECTOR_PARAMS.SectorsPerTrack) ; Sector per track +; LD A,(CORE_BUFFERS.SECTOR_BUFFER + _sBOOT_SECTOR_PARAMS.HEADS) +;.BPB_L1: ; calc. sector per cylinder +; ADD HL,BC +; DEC A +; JR NZ,.BPB_L1 +; LD (CORE_BUFFERS.FatBuffer.S_X_H),HL +//////////////////////////////////////////////////////////////////////// + ; [ ] fat32 + LD HL,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.SectorsPerDrive) + LD A,H + OR L + LD DE,(CORE_BUFFERS.FatBuffer.FirstDataSector_L) + JP NZ,.HDDSMAL + ; + EXX + LD HL,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.BPB_BIG_TOTAL_SECTORS_H) + PUSH HL ; Total Sectors high + LD DE,(CORE_BUFFERS.FatBuffer.FirstDataSector_H) + EXX + LD HL,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.BPB_BIG_TOTAL_SECTORS_L) + PUSH HL ; Total Sectors low + AND A + SBC HL,DE + EXX + SBC HL,DE + PUSH HL + EXX + POP BC + ;JP NC,.HDDBIG + ;DEC BC + JP .HDDBIG + ; +.HDDSMAL: ; CF = 0 + LD BC,0 + PUSH BC ; Total Sectors high + PUSH HL ; Total Sectors low + SBC HL,DE + ; +.HDDBIG: CALL SectorToCluster +; LD A,(CORE_BUFFERS.FatBuffer.SectorsPerCluster) +; SCF +; .loop7: RRA +; JR C,.loop7_exit +; RR B +; RR C +; RR H +; RR L +; JP .loop7 + ; +.loop7_exit: INC HL + LD (CORE_BUFFERS.FatBuffer.MaxClusterLow),HL + LD A,L + OR H + JR NZ,.no_inc_bc + INC BC +.no_inc_bc: LD (CORE_BUFFERS.FatBuffer.MaxClusterHigh),BC + ; + XOR A + LD H,A + LD L,A + LD (CORE_BUFFERS.FatBuffer.CacheBlock),HL + LD (CORE_BUFFERS.FatBuffer.CacheUpdated),A + ; A = 0 + LD HL,(CORE_BUFFERS.FatBuffer.SectorsPerFAT_H) + LD H,A + EX DE,HL + LD HL,(CORE_BUFFERS.FatBuffer.SectorsPerFAT_L) + ; DE:HL = SectorsPerFAT + ; + LD A,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.Number_of_FATs) + LD B,A + DEC A + JR Z,.loop_mul_end + ; .Number_of_FATs * .SectorsPerFAT +.loop_mul: ADD HL,HL + EX DE,HL + ADC HL,HL + EX DE,HL + DJNZ .loop_mul +.loop_mul_end: ; .DirSizeInSectors + .Number_of_FATs * .SectorsPerFAT + LD B,0 + LD A,(CORE_BUFFERS.FatBuffer.DirSizeInSectors) + LD C,A + ADD HL,BC + JR NC,.no_inc_DE + INC DE +.no_inc_DE: ; .RESERVED_SECTORS + .DirSizeInSectors + .Number_of_FATs * .SectorsPerFAT + LD BC,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.RESERVED_SECTORS) + ADD HL,BC + JR NC,.no_inc_de + INC DE +.no_inc_de: ; Total_Sectors - (.RESERVED_SECTORS + .DirSizeInSectors + .Number_of_FATs * .SectorsPerFAT) + AND A + LD B,D + LD C,E + POP DE ; Total Sectors low + EX DE,HL + SBC HL,DE + EX (SP),HL ; Total Sectors high + SBC HL,BC + POP DE ; Total Sectors low + ; HL:DE = DataSec + ; + LD A,(CORE_BUFFERS.FatBuffer.SectorsPerCluster) + ; HL:DE / A => DE:BC, H=0, L - остаток + CALL DIV_by_Shifts + ; выясняем разрядность FAT + LD A,D + OR E + JR NZ,.its_FAT32 + ; + LD HL,4084 + SBC HL,BC + JR NC,.its_FAT12 + ; + LD HL,65524 + SBC HL,BC + JR C,.its_FAT32 + ; + ; It's FAT16 + LD HL,#FFFF + LD A,FAT_TYPE.x16 +.set_vars: EXX + LD HL,0 + LD (CORE_BUFFERS.FatBuffer.END_CHAIN_CLUSTER_H),HL + LD (CORE_BUFFERS.FatBuffer.RootDirStartCluster_L),HL + LD (CORE_BUFFERS.FatBuffer.RootDirStartCluster_H),HL + LD HL,CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.FAT.LABEL + EXX + LD DE,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.FAT.SERIAL_NUMBER) + LD BC,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.FAT.SERIAL_NUMBER+2) + JR .SET_VARS + ; +.its_FAT12: LD HL,#0FFF + LD A,FAT_TYPE.x12 + JR .set_vars + ; +.its_FAT32: LD A,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.MainFATnumber) + CP #80 + JR C,.mirrored_FATs ;если все копии FAT используются + ; используется только одна копия FAT + LD HL,(CORE_BUFFERS.FatBuffer.FAT1_SEC_H) + LD DE,(CORE_BUFFERS.FatBuffer.SectorsPerFAT_H) + LD D,0 + EXX + LD HL,(CORE_BUFFERS.FatBuffer.FAT1_SEC_L) + LD DE,(CORE_BUFFERS.FatBuffer.SectorsPerFAT_L) + AND #0F + JR Z,.first_FAT_active + LD B,A + ; +.fat_calc_loop: ADD HL,DE + EXX + ADC HL,DE + EXX + DJNZ .fat_calc_loop + ; +.first_FAT_active: + LD (CORE_BUFFERS.FatBuffer.FAT1_SEC_L),HL + LD (CORE_BUFFERS.FatBuffer.FAT2_SEC_L),HL + EXX + LD (CORE_BUFFERS.FatBuffer.FAT1_SEC_H),HL + LD (CORE_BUFFERS.FatBuffer.FAT2_SEC_H),HL + ; +.mirrored_FATs: LD HL,CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.FAT32.LABEL + ; + EXX + LD HL,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.RootDirStartCluster) + LD (CORE_BUFFERS.FatBuffer.RootDirStartCluster_L),HL + LD DE,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.RootDirStartCluster+2) + LD (CORE_BUFFERS.FatBuffer.RootDirStartCluster_H),DE + ; + CALL CLUSTER_TO_SECTOR.no_prepare + LD (CORE_BUFFERS.FatBuffer.RootDirFirstSector_L),IX + LD (CORE_BUFFERS.FatBuffer.RootDirFirstSector_H),HL + ; + LD HL,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.FSINFO_Sector) + LD (CORE_BUFFERS.FatBuffer.FSINFO_Sector),HL + ; + LD A,FAT_TYPE.x32 + LD HL,#0FFF + LD (CORE_BUFFERS.FatBuffer.END_CHAIN_CLUSTER_H),HL + LD H,L + LD DE,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.FAT32.SERIAL_NUMBER) + LD BC,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.FAT32.SERIAL_NUMBER+2) + ; +.SET_VARS: LD (CORE_BUFFERS.FatBuffer.FAT_TYPE),A + LD (CORE_BUFFERS.FatBuffer.END_CHAIN_CLUSTER_L),HL + LD (CORE_BUFFERS.FatBuffer.BPB_SERIAL_NUMBER),DE + LD (CORE_BUFFERS.FatBuffer.BPB_SERIAL_NUMBER+2),BC + EXX + LD DE,CORE_BUFFERS.FatBuffer.BPB_LABEL + LD BC,11 ;!HARDCODE + LDIR + ; + SET_PAGE_X FATPAGE + PUSH AF + LD DE,0 + CALL READ_FAT_TABLE + POP AF + OUT (SLOT3),A + ; + ; Установить начальный кластер для чтения + LD A,(CORE_BUFFERS.FatBuffer.FAT_TYPE) + CP FAT_TYPE.x32 + JR Z,.set_FSinfo + ; + LD HL,#0001 + LD (G_CLUST.low),HL + DEC L + LD (G_CLUST.high),HL + ; + DEC HL + LD (CORE_BUFFERS.FatBuffer.FREE_CLUSTERS_COUNT_L),HL + LD (CORE_BUFFERS.FatBuffer.FREE_CLUSTERS_COUNT_H),HL + XOR A + RET + ; +.set_FSinfo: CALL READ_FSinfo + ; !FIXIT проверка на ошибку + ; + ; проверка одной из сотни сраных сигнатур + LD HL,(CORE_BUFFERS.SECTOR_BUFFER + _sFSinfo.DATA_SIGNATURE) + LD DE,(CORE_BUFFERS.SECTOR_BUFFER + _sFSinfo.DATA_SIGNATURE + 2) + LD BC,#7272 + SBC HL,BC + JR NZ,.error + EX DE,HL + LD DE,#6141 + SBC HL,DE + JR NZ,.error + ; FREE_CLUSTERS_COUNT + LD BC,(CORE_BUFFERS.SECTOR_BUFFER + _sFSinfo.FREE_CLUSTERS_COUNT) + LD DE,(CORE_BUFFERS.SECTOR_BUFFER + _sFSinfo.FREE_CLUSTERS_COUNT+2) + ; CF = 0 + CALL .check_cluster + JR NC,.skip_FFFF + ; + LD B,#FF + LD C,B + LD D,B + LD E,B + ; +.skip_FFFF: LD (CORE_BUFFERS.FatBuffer.FREE_CLUSTERS_COUNT_L),BC + LD (CORE_BUFFERS.FatBuffer.FREE_CLUSTERS_COUNT_H),DE + ; + ; FIRST_FREE_CLUSTER + LD BC,(CORE_BUFFERS.SECTOR_BUFFER + _sFSinfo.FIRST_FREE_CLUSTER) + LD DE,(CORE_BUFFERS.SECTOR_BUFFER + _sFSinfo.FIRST_FREE_CLUSTER+2) + ; CF = 0 + CALL .check_cluster + JR C,.error + ; + LD (G_CLUST.high),DE + LD (G_CLUST.low),BC + XOR A +.error: LD (CORE_BUFFERS.FatBuffer.UPD_FSINFO),A + RET Z + ;!TODO FREE_CLUSTERS_COUNT + ;LD HL,#FFFF + ;LD (CORE_BUFFERS.FatBuffer.FREE_CLUSTERS_COUNT_L),HL + ;LD (CORE_BUFFERS.FatBuffer.FREE_CLUSTERS_COUNT_H),HL + ; + XOR A + LD H,A + LD L,2 + LD (G_CLUST.low),HL + LD L,H + LD (G_CLUST.high),HL + RET + ; + ;!TODO MaxCluster - максимально допустимый или на 1 больше максимально допустимого? +.check_cluster: LD HL,(CORE_BUFFERS.FatBuffer.MaxClusterLow) + SBC HL,BC + LD HL,(CORE_BUFFERS.FatBuffer.MaxClusterHigh) + SBC HL,DE + RET +;;;;;;;; + +; --> BC:HL - Sector +; <-- BC:HL - Cluster +SectorToCluster: + LD A,B + AND #0F + LD B,A + LD A,(CORE_BUFFERS.FatBuffer.SectorsPerCluster) + SCF +.loop: RRA + RET C + RR B + RR C + RR H + RR L + JP .loop +; + +DOS_X_Error: +.UnknownBPB: LD A,DSS_Error.sys.UNKNOWN_FORMAT + SCF + RET + ; +.Not_ready: LD A,DSS_Error.sys.NOT_READY + ; CF = 1 + RET +; +; +;!TODO к буферам! +/* +FatBuffer: +;.MSG: DB 'FAT' +.DRIVE: DB #FF +.FAT_TYPE: DB #00 ; TYPE FAT (12 - 12bit, 16 - 16bit, 32 - 32bit) ; [x] fat32 +.CacheBlock: DW #00 +.CacheUpdated: DB #00 +;.SectorsPerBank: DB #00 +.RootDirStartCluster_L: DW #0000 +.RootDirStartCluster_H: DW #0000 ; [ ] fat32 +.FAT1_SEC_L: DW #0000 ; MSD_FAT_SEC first sector FAT (FAT_FRM) +.FAT1_SEC_H: DW #0000 ; [ ] fat32 +.FAT2_SEC_L: DW #0000 +.FAT2_SEC_H: DW #0000 ; [ ] fat32 +.SectorsPerFAT_L DW #0000 +.SectorsPerFAT_H DB #00 +.RootDirFirstSector_L: DW #0000 ; MSD_CAT_SEC first sector DIR +.RootDirFirstSector_H: DW #0000 ; MSD_CAT_SEC first sector DIR ; !TODO ограничение в 32 Гига ;!FIXIT не используется +.DirSizeInSectors: DB #00 ; DIR_SEC_SIZE +.FirstDataSector_L: DW #0000 ; MSD_DAT_SEC low +.FirstDataSector_H: DW #0000 ; MSD_DAT_SEC high ; [ ] fat32 было ограничение в 32 Гига +.BytesPerCluster: DW #0000 ; CLUSTER_LEN +.END_CHAIN_CLUSTER_L: DW #FFFF +.END_CHAIN_CLUSTER_H: DW #0FFF ; [ ] fat3 +.MaxClusterLow: DW #0000 ; макс. число кластеров (без служ.) +.MaxClusterHigh: DW #0000 ; макс. число кластеров (без служ.) +; +.BytesPerSector DW #0000 +.SectorsPerCluster DB #00 +.BPB_SERIAL_NUMBER DW 0,0 +.BPB_LABEL BLOCK 11,' ' ; 11 для FAT, 31 для CDFS + IF COMPILE_UNUSED_CODE +.FilesPerSector: DB #00 ; число файловых записей в секторе +.ClustersPerBank: DB #00 ; A - Clusters per bank (16k) (число кластеров на блок ОЗУ) ; ????? это используется? + ENDIF +;.READ_PG: DB #00 ;!TODO не используются некоторые значения, но задумка неплохая))) +;.S_X_H: DW #0000 ; количество секторов на цилиндре ; ????? это используется? +; +*/ +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// \ No newline at end of file diff --git a/Crazy Estex DSS/DSS/FS/FAT/FAT_X.asm b/Crazy Estex DSS/DSS/FS/FAT/FAT_X.asm new file mode 100644 index 0000000..0ee5739 --- /dev/null +++ b/Crazy Estex DSS/DSS/FS/FAT/FAT_X.asm @@ -0,0 +1,1574 @@ +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +; FAT 12-16-32 +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +;[BEGIN] +;//MODULE: FAT_X +;//CREATE: 19-05-1998 AUTHOR: Denis Parinov +;//UPDATE: 24-10-1999 DNS Restore module +;--------------------------------------------------------------- +;Rev Date Name Description +;--------------------------------------------------------------- +;RY01 16-11-1999 DNS ERROR READING FAT CHAIN +;RX01 10-02-1999 DNS UPGRADE FAT CASH +;--------------------------------------------------------------- + +; Удаляет запись в каталоге и освобождает занятую цепочку кластеров +; Вход: IX - указатель на удаляемую запись в DIRPAGE +;!TODO record index. возможно, что может сломаться, если больше страницы +DELETE_REC_FAT: SET_PAGE_X DIRPAGE + EX AF,AF' + CALL DELETE_LFN_RECORDS ; [x] удаление записи LFN + LD (IX + FAT_DIRECTORY_RECORD.NAME),#E5 ; признак удаления файла + ; fat32 + LD L,(IX+FAT_DIRECTORY_RECORD.FIRST_CLUSTER_H) ; № первого кластера + LD H,(IX+FAT_DIRECTORY_RECORD.FIRST_CLUSTER_H+1) + LD A,L + OR H + EXX + LD L,(IX+FAT_DIRECTORY_RECORD.FIRST_CLUSTER_L) ; № первого кластера + LD H,(IX+FAT_DIRECTORY_RECORD.FIRST_CLUSTER_L+1) + OR L + OR H + ; + EX AF,AF' + OUT (SLOT3),A + EX AF,AF' + JP Z,SAVEDIR ; сбросить кеш каталога на диск + ; если размер файла не ноль +.loop: ;EX DE,HL ; hl=номер кластера + ;EXX + ; EX DE,HL + ;EXX + CALL READ_FROM_FAT ; прочитать из кеша FAT-а номер след. кластера + EXX + PUSH DE ; номер след. кластера + PUSH AF + LD DE,#0000 ; номер кластера + EXX + PUSH DE + ; + CALL SET_NEW_FREE_CLUSTER + ; + LD DE,#0000 ; номер кластера + CALL WRITE_TO_FAT.Custom ; записать в кеш FAT-а номер кластера + POP HL + EXX + POP AF + POP HL + ;EX DE,HL + EXX + ;EX DE,HL + JP NC,.loop + CALL WRITE_FAT_TABLE + JP SAVEDIR ; сбросить кеш каталога на диск + +; Установить первым известным кластером для поиска свободного. +; Установится только если меньше предыдущего +; Вход: HL':HL - cluster +; портит DE, BC' и A +; [x] раньше был шанс упереться в "DISK FULL" если G_CLUST указывал на кластер дальше, чем другой свободный +; [ ] free clusters for FSInfo +SET_NEW_FREE_CLUSTER: + LD A,1 ; увеличить + CALL SET_NEW_FREE_CLUSTERS ; [ ] free clusters for FSInfo + ; CF=0 + ; + EX DE,HL + LD HL,(G_CLUST.low) + SBC HL,DE + EX DE,HL + ; + EXX + LD B,D + LD C,E + EX DE,HL + LD HL,(G_CLUST.high) + SBC HL,DE + EX DE,HL + LD D,B + LD E,C + EXX + RET C + ; + JR G_CLUST.set_new + ; LD (G_CLUST.low),HL + ; EXX + ; LD (G_CLUST.high),HL + ; EXX + ; XOR A + ; INC A + ; LD (CORE_BUFFERS.FatBuffer.RESET_FSINFO),A + ; RET + +; +; [x] fat32 ;!TEST +; найти первый свободный кластер ;!TODO проверить перебор кластеров +; выход: HL - младший номер свободного кластера +; HL' - старший номер свободного кластера +G_CLUST: ; +.low+1: LD HL,#0001 + EXX +.high+1: LD HL,#0000 + EXX +.loop: INC HL ; номер кластера + LD A,L + OR H + ; [x] fat32 + EXX + JR NZ,.no_inc + INC HL +.no_inc: EXX + ; + CALL READ_FROM_FAT ; прочитать из кеша FAT-а номер след. кластера + CP DSS_Error.sys.DISK_FULL + SCF + RET Z + ; + EXX + LD A,D + OR E + EXX + OR D + OR E + JR NZ,.loop +.set_new: ; A = 0 + LD (G_CLUST.low),HL + EXX + LD (G_CLUST.high),HL + EXX + INC A + LD (CORE_BUFFERS.FatBuffer.UPD_FSINFO),A + RET + +; Вход: A - уменьшить (0) или увеличить (!0) число свободных кластеров +SET_NEW_FREE_CLUSTERS: + EX AF,AF + PUSH HL + PUSH DE + EXX + PUSH HL + PUSH DE + LD HL,(CORE_BUFFERS.FatBuffer.FREE_CLUSTERS_COUNT_H) + LD A,H + AND L + EXX + LD HL,(CORE_BUFFERS.FatBuffer.FREE_CLUSTERS_COUNT_L) + AND H + AND L + INC A + EXX + JR Z,.no_change + EXX + ; + EX AF,AF + OR A + JR Z,.dec_clusters + ; inc clusters + INC HL + LD A,H + OR L + JR NZ,.set_new + EXX + INC HL + EXX + ; +.set_new: LD A,1 + LD (CORE_BUFFERS.FatBuffer.UPD_FSINFO),A + ; + LD (CORE_BUFFERS.FatBuffer.FREE_CLUSTERS_COUNT_L),HL + EXX + LD (CORE_BUFFERS.FatBuffer.FREE_CLUSTERS_COUNT_H),HL +.no_change: POP DE + POP HL + EXX + POP DE + POP HL + RET + ; +.dec_clusters: LD A,H + OR L + DEC HL + JR NZ,.set_new + EXX + DEC HL + EXX + JP .set_new +; ; + +; +; [x] fat32 ;!TEST +; Прикрепить к последнему кластеру цепочки новый пустой кластер +; Вход: HL':HL - номер кластера к которому прикрепить пустой +; Выход: HL':HL - номер кластера к которому прикрепился пустой +; DE':DE - номер пустого кластера +INC_FAT: PUSH HL ; текущий кластер + EXX + PUSH HL ; текущий кластер + EXX + ; + CALL G_CLUST + ; + EXX + POP DE ; текущий кластер + EXX + POP DE ; текущий кластер + RET C + ; HL':HL - свободный кластер, DE':DE - текущий кластер + ; + EX DE,HL + EXX + EX DE,HL + EXX + ; + CALL WRITE_TO_FAT.Custom ; записать в кеш FAT-а номер кластера + ;!FIXIT <нет контроля ошибки> + ; + PUSH HL + EX DE,HL + EXX + PUSH HL + EX DE,HL + EXX + ; + CALL WRITE_TO_FAT ; записать в кеш FAT-а номер кластера + ;!TEST ;!TODO 2/12/23 ; [ ] баг с избыточной записью WRITE_FAT_TABLE? + ;CALL WRITE_FAT_TABLE ; подкл. банку кеша FAT и записать его на диск + ; + EXX + POP DE + EX DE,HL + EXX + POP DE + EX DE,HL + ; + ; [ ] free clusters for FSInfo + XOR A ; уменьшить + CALL SET_NEW_FREE_CLUSTERS ; [ ] free clusters for FSInfo + RET +;RX01 + + +; [x] fat32 ;!TEST +; вход: hl = младшее слово номера кластера для сравнения с FAT_Max_Cluster +; hl' = старшее слово номера кластера для сравнения с FAT_Max_Cluster (только для fat32) +CHECK_CLUSTER_IS_SMALLER: + LD A,(CORE_BUFFERS.FatBuffer.FAT_TYPE) + XOR FAT_TYPE.x32 + JR NZ,.low ; Z=0 проверяем младшее слово номера кластера + ; проверяем старшее слово номера кластера + EXX + EX DE,HL + LD HL,(CORE_BUFFERS.FatBuffer.MaxClusterHigh) + ; CF = 0 + SBC HL,DE + EX DE,HL + EXX + LD A,DSS_Error.sys.DISK_FULL + RET C + RET NZ + ; проверяем младшее слово номера кластера +.low: EX DE,HL + LD HL,(CORE_BUFFERS.FatBuffer.MaxClusterLow) + SBC HL,DE + EX DE,HL + LD A,DSS_Error.sys.DISK_FULL + RET +; + +; +;[x] fat32 ;!TEST +;------------------------------------------------------------------------------------------------ +; Прочитать из кеша FAT-а номер след. кластера +; вход: hl - номер кластера (младшее слово) +; hl' - номер кластера (старшее слово. только для FAT32) +; выход: hl - номер кластера (младшее слово) +; hl' - номер кластера (старшее слово) +; de - номер след. кластера (младшее слово) +; de' - номер след. кластера (старшее слово) +; если DE':DE = 0, то кластер HL':HL свободен +; CF - конец цепочки +;------------------------------------------------------------------------------------------------ +READ_FROM_FAT: CALL CHECK_CLUSTER_IS_SMALLER + RET C + ; + SET_PAGE_X FATPAGE + ; + PUSH HL + PUSH AF + LD A,(CORE_BUFFERS.FatBuffer.FAT_TYPE) + CP FAT_TYPE.x16 + JR C,.FAT12 + JR NZ,.FAT32 + ; fat16, просто читать след. номер +.FAT16: CALL GET_FAT16_CELL + LD E,(HL) ; прочитать номер кластера + INC HL + LD D,(HL) + ; + LD HL,SERVICE_SECTORS.FAT16 +.exit: POP AF + OUT (SLOT3),A + ; обнуляем CF и устанавливаем код ошибки = DssErr.sys.NO_ERROR + XOR A + ; проверка на служ. кластеры + SBC HL,DE + POP HL + ;!FIXIT fat32 перестраховка + EXX + LD H,A + LD L,A + LD D,A + LD E,A + EXX + RET + ; + ; +.FAT12: CALL GET_FAT12_CELL + LD E,(HL) + INC HL + LD D,(HL) + LD HL,SERVICE_SECTORS.FAT12 + JR NC,.Correct_2 +.Correct_1: LD A,E + AND #F0 + DUP 4 ; вправо на 4 битa + RR D + RRA + EDUP + LD E,A + JR .exit + ; +.Correct_2: LD A,D + AND #0F + LD D,A + JR .exit + ; +.FAT32: EXX + PUSH HL + EXX + ; + CALL GET_FAT32_CELL + ; прочитать младшее слово номера кластера + LD E,(HL) + INC HL + LD D,(HL) + INC HL + ; прочитать старшее слово номера кластера + LD A,(HL) + INC HL + EX AF,AF' + LD A,(HL) + EXX + AND #0F + LD D,A + EX AF,AF' + LD E,A + EXX + ; обнуляем CF и устанавливаем код ошибки = DssErr.sys.NO_ERROR + XOR A + ; проверка на служ. кластеры младшего слова кластера + LD HL,SERVICE_SECTORS.FAT32.Low + SBC HL,DE + ; проверка на служ. кластеры старшего слова кластера + EXX + LD HL,SERVICE_SECTORS.FAT32.High + SBC HL,DE + POP HL + EXX + POP BC + LD A,B + OUT (SLOT3),A + POP HL + LD A,0 + RET +; + +; Вход: HL - Номер первой ячейки кластера в блоке фата +; Портить только HL и A +SET_FAT32_CACHE_BLOCK_CHANGED_REGION: + ;DEC HL + ;LD A,(CORE_BUFFERS.FatBuffer.FAT_TYPE) + ;CP FAT_TYPE.x16 + 1 + ;JR C,.start + ;DEC HL + ;DEC HL + ; +.start: LD A,H + AND #38 + LD HL,#0108 + JR Z,.set_region + ; +.loop: SLA H + AND A + SUB L + JR NZ,.loop + ; +.set_region: LD A,(CORE_BUFFERS.FatBuffer.CacheUpdated) + OR H + LD (CORE_BUFFERS.FatBuffer.CacheUpdated),A + RET + +; +; [x] fat32 ;!TEST +; +; !TODO optimize +; при записи в кэш значения отмечать через OR в ячейке FatBuffer.SectorOfCacheBlock +; бит соответствующий куску в странице кэша, который был изменён и потом скидывать на диск +; только те куски, которые были изменены. +; |--------------------| +; | bit | adresses | +; |-----|--------------| +; | 0 | #0000..#07FF | +; | 1 | #0800..#0FFF | +; | 2 | #1000..#17FF | +; | 3 | #1800..#1FFF | +; | 4 | #2000..#27FF | +; | 5 | #2800..#2FFF | +; | 6 | #3000..#37FF | +; | 7 | #3800..#3FFF | +; |--------------------| +; +;------------------------------------------------------------------------------------------------ +; Записать в кеш FAT-а номер кластера +; вход: hl = младшее слово номера кластера в который записать +; hl' = старшее слово номера кластера в который записать (только для fat32) +; .Custom: +; de = младшее слово номера кластера которое вписать +; de' = старшее слово номера кластера которое вписать (только для fat32) +; выход: HL':HL такие же как и на входе +; .Custom: +; HL':HL и DE':DE такие же как и на входе +;------------------------------------------------------------------------------------------------ +WRITE_TO_FAT: LD DE,(CORE_BUFFERS.FatBuffer.END_CHAIN_CLUSTER_L) ; номер кластера + EXX + LD DE,(CORE_BUFFERS.FatBuffer.END_CHAIN_CLUSTER_H) ; номер кластера + EXX +.Custom: PUSH DE + EXX + PUSH DE + EXX + CALL CHECK_CLUSTER_IS_SMALLER + EXX + POP DE + EXX + POP DE + RET C + ; + EXX + SET_PAGE_X FATPAGE + EXX + PUSH HL + AND A + PUSH AF + PUSH DE ; младший номер кластера который вписать + ; [x] 2/12/23 FAT не всегда мог записаться на HDD + ;LD A,1 + ;LD (CORE_BUFFERS.FatBuffer.CacheUpdated),A + ; + LD A,(CORE_BUFFERS.FatBuffer.FAT_TYPE) + CP FAT_TYPE.x16 + JR C,.FAT12 + JR NZ,.FAT32 + ; +.FAT16: CALL GET_FAT16_CELL + POP DE ; младший номер кластера который вписать + LD (HL),E ; сохр. в кеше FAT-а + INC HL ; номер кластера + LD (HL),D +.exit: ; + IF FAST_FAT_CASHE + ; [ ] ускорение работы с кэшем FAT + CALL SET_FAT32_CACHE_BLOCK_CHANGED_REGION + ; + ENDIF + POP AF ; восст. порт + POP HL + OUT (SLOT3),A + IFN FAST_FAT_CASHE + ; [x] 2/12/23 FAT не всегда мог записаться на HDD + LD A,#FF + LD (CORE_BUFFERS.FatBuffer.CacheUpdated),A + ; + ENDIF + ; CF = 0 + RET + ; +.FAT12: ;!FIXIT переделать на переменные FAT_CACHE + CALL GET_FAT12_CELL + POP DE ; младший номер кластера который вписать + JR C,.Correct_1 ; номер нечётный + LD (HL),E + INC HL + LD A,(HL) + AND #F0 + OR D + LD (HL),A + JR .exit + ; +.Correct_1: ; влево на 4 битa + PUSH DE + EX DE,HL + ADD HL,HL + ADD HL,HL + ADD HL,HL + ADD HL,HL + EX DE,HL + ; + LD A,(HL) + AND #0F + OR E + LD (HL),A ; сохр. в кеше FAT-а + INC HL ; номер кластера + LD (HL),D + POP DE + JR .exit + ; +.FAT32: ; [x] fat32 ;!TEST + EXX + PUSH DE ; старший номер кластера который вписать + PUSH HL ; старшее слово номера кластера в который записать + EXX + CALL GET_FAT32_CELL + EXX + POP HL ; старшее слово номера кластера в который записать + POP DE + PUSH DE ; старший номер кластера который вписать + EXX + POP BC ; старший номер кластера который вписать + POP DE ; младший номер кластера который вписать + ; сохр. в кеше FAT-а номер кластера + LD (HL),E + INC HL + LD (HL),D + INC HL + LD (HL),C + INC HL + LD A,(HL) + AND #F0 + OR B + LD (HL),A + JR .exit +;;;;;;;;; + + + +; [x] fat32 ;!TEST +;FAT_BLOCK * Sectors_in_Block = SECTOR_OF_FAT +; in: HL - Cache block +; out: C:HL - logical number +; B = 0 +GET_SECTOR_OF_FAT: + LD A,(CORE_BUFFERS.FatBuffer.FAT_TYPE) + LD B,FAT_CACHE.Degree_32 ;!FIXIT сделать через переменную + XOR FAT_TYPE.x32 + JR Z,.next + LD B,FAT_CACHE.Degree ;!FIXIT сделать через переменную + XOR A +.next: LD C,A + ; +.loop: ADD HL,HL ;x2 + ADC A,C + DJNZ .loop + ; + LD C,A + RET +; GET_SECTOR_OF_FAT: +; XOR A +; LD B,A +; LD C,A +; DUP FAT_CACHE.Degree ; 4 +; ADD HL,HL ;x2 +; ADC A,C +; EDUP +; LD C,A +; LD A,(CORE_BUFFERS.FatBuffer.FAT_TYPE) +; CP FAT_TYPE.x32 +; RET NZ +; ADD HL,HL ;x2 +; RET NC +; INC C +; RET +;;;;;;;;; + + +; [x] fat32 ;!TEST +;RE_FAT: +;RX01 +; Прочитать в кеш ХХ секторов FAT-а +; DE - NEW FAT BLOCK +READ_FAT_TABLE: PUSH HL + PUSH DE + LD A,(CORE_BUFFERS.FatBuffer.CacheUpdated) + OR A + CALL NZ,WRITE_FAT_TABLE.Start + POP DE + ; + EX DE,HL + LD (CORE_BUFFERS.FatBuffer.CacheBlock),HL + ; + CALL GET_SECTOR_OF_FAT + ; + ; BC:HL - номер лог.сектора + LD DE,(CORE_BUFFERS.FatBuffer.FAT1_SEC_L) + ADD HL,DE + EX DE,HL + LD XH,D + LD XL,E + LD HL,(CORE_BUFFERS.FatBuffer.FAT1_SEC_H) + ; JR NC,.no_inc + ; INC HL +.no_inc: ADC HL,BC + ; HL:IX - SECTOR FAT FOR READING + LD A,(CORE_BUFFERS.FatBuffer.FAT_TYPE) + XOR FAT_TYPE.x32 + LD BC,FAT_CACHE.Sectors_16 * 256 + Dss.DRV.Read ; рег B * FAT_CACHE.Sector_Size = CASH SIZE + JR NZ,.next + LD B,FAT_CACHE.Sectors_32 ; рег B * FAT_CACHE.Sector_Size = CASH SIZE +.next: LD DE,FATPAGE.cache ; куда ; DE - FAT ADDRESS + LD A,(CORE_BUFFERS.FatBuffer.DRIVE) ; номер диска + RST ToDSS.DRV + POP HL + RET + + +; [x] fat32 ;!TEST +; Подключить банку кеша FAT и записать его на диск +WRITE_FAT_TABLE: + SET_PAGE_X FATPAGE + PUSH AF + CALL .Start ;!TODO нет контроля ошибок + POP AF + OUT (SLOT3),A + RET + ; Запись кеша FAT-а на диск +.Start: CALL SET_FSInfo + LD HL,(CORE_BUFFERS.FatBuffer.CacheBlock) + ;FAT_BLOCK * Sectors_in_Block = SECTOR_OF_FAT + CALL GET_SECTOR_OF_FAT + ; B=0, C:HL - смещение в секторах внутри таблицы FAT на начало блока + LD (.pop_offset_HL),HL + LD DE,FAT_CACHE.Sectors_32 + LD A,(CORE_BUFFERS.FatBuffer.FAT_TYPE) + CP FAT_TYPE.x32 + JR Z,.next + LD DE,FAT_CACHE.Sectors_16 ; !FIXIT брать это значение из переменной везде + ; +.next: ADD HL,DE ;+ SIZE CASH (16 SECTORS) + JR NC,.no_inc + INC C +.no_inc: ; C:HL смещение в секторах внутри таблицы FAT на конец блока + ; + ; конец блока выходит за пределы таблицы? + LD B,E ; MAX число секторов для чтения в кэш + LD A,(CORE_BUFFERS.FatBuffer.SectorsPerFAT_H) + LD (.sub_A),A + ;LD DE,(CORE_BUFFERS.BootSector.SectorsPerFAT16) ; секторов на FAT + LD DE,(CORE_BUFFERS.FatBuffer.SectorsPerFAT_L) + AND A + LD A,C + SBC HL,DE +.sub_A+1: SBC A,0 + JR C,.WALLFAT ; СF=1: не выходит + OR A + JP NZ,.ERR + ; + EX DE,HL + ; DE - на сколько секторов конец блока выходит за пределы таблицы. + LD HL,FAT_CACHE.Sectors_16 ; !FIXIT брать это значение из переменной везде + ; CF = 0 + SBC HL,DE + ;SBC A,0 + JR C,.ERR ;!TODO проверить + LD B,L ; число секторов для чтения в кэш +.WALLFAT: ; +.pop_offset_HL+1: + LD HL,0 + ; B = число секторов + LD IX,(CORE_BUFFERS.FatBuffer.FAT1_SEC_H) + LD DE,(CORE_BUFFERS.FatBuffer.FAT1_SEC_L) + PUSH BC + ; сохраняем первую копию FAT. Вход IX:DE - начало таблицы FAT + ; C:HL - смещение внутри таблицы + ; B - количество секторов + CALL .SAVE_FAT_XX + ; [x] если всего одна таблица FAT, то повторной записи не происходит 13/03/2024 + POP BC ; B = число секторов, C = старший байт смещения в секторах + LD HL,(CORE_BUFFERS.FatBuffer.FAT1_SEC_H) + LD DE,(CORE_BUFFERS.FatBuffer.FAT2_SEC_H) + AND A + SBC HL,DE + JR NZ,.not_one_FAT + LD HL,(CORE_BUFFERS.FatBuffer.FAT2_SEC_L) + LD DE,(CORE_BUFFERS.FatBuffer.FAT1_SEC_L) + ; CF = 0 + SBC HL,DE + JR Z,.only_one_FAT + ; +.not_one_FAT: LD A,(CORE_BUFFERS.FatBuffer.FAT_TYPE) + CP FAT_TYPE.x32 + JR NZ,.fat_num_2 + ; + LD A,(CORE_BUFFERS.FatBuffer.Number_Of_FATs) + CP 2 + JR Z,.fat_num_2 + ; сохраняем больше двух копий FAT + LD HL,(CORE_BUFFERS.FatBuffer.FAT2_SEC_H) + LD DE,(CORE_BUFFERS.FatBuffer.SectorsPerFAT_H) + LD D,0 + EXX + LD HL,(CORE_BUFFERS.FatBuffer.FAT2_SEC_L) + LD DE,(CORE_BUFFERS.FatBuffer.SectorsPerFAT_L) + DEC A +.many_fat_loop: EXX + PUSH HL + PUSH HL + POP IX + EXX + PUSH HL + PUSH BC + EX DE,HL + LD HL,(.pop_offset_HL) + CALL .SAVE_FAT_XX + POP BC + POP HL + ; + LD DE,(CORE_BUFFERS.FatBuffer.SectorsPerFAT_L) + ADD HL,DE + EXX + LD DE,(CORE_BUFFERS.FatBuffer.SectorsPerFAT_H) + POP HL + ADC HL,DE + EXX + DEC A + JR NZ,.many_fat_loop + JR .norm_exit + ; + ; сохраняем вторую копию FAT +.fat_num_2: LD IX,(CORE_BUFFERS.FatBuffer.FAT2_SEC_H) + LD DE,(CORE_BUFFERS.FatBuffer.FAT2_SEC_L) + LD HL,(.pop_offset_HL) + CALL .SAVE_FAT_XX +.norm_exit: AND A ;!TODO нет контроля ошибок +.only_one_FAT: ; +.ERR: LD A,0 + LD (CORE_BUFFERS.FatBuffer.CacheUpdated),A + RET + ; Вход: IX:DE - начало таблицы FAT в секторах + ; C:HL - смещение в таблице в секторах + ; B - количество секторов +.SAVE_FAT_XX: ADD HL,DE + JR NC,.no_inc_C + INC C + ; номер лог. сектора +.no_inc_C: LD D,0 + LD E,C + ADD IX,DE + LD D,XH + LD E,XL + EX DE,HL + LD XH,D + LD XL,E + ; HL:IX - смещение внутри раздела на начало нужного блока FAT + LD A,(CORE_BUFFERS.FatBuffer.CacheUpdated) + IF FAST_FAT_CASHE + CP #FF + JR NZ,.SAVE_NOT_ALL_BLOCK + ENDIF + ; + LD DE,FATPAGE.cache ; откуда + LD A,(CORE_BUFFERS.FatBuffer.DRIVE) ; номер диска + LD C,Dss.DRV.Write + JP ToDSS.DRV + ; + IF FAST_FAT_CASHE +.SAVE_NOT_ALL_BLOCK: + ; A = CORE_BUFFERS.FatBuffer.CacheUpdated + ; HL:IX - смещение внутри раздела на начало нужного блока FAT + ; B = максимальное число блоков для записи + EXX + LD HL,FATPAGE.cache + LD DE,#0800 ;!HARDCODE размер региона в блоке КЭШа FAT (байтов) + EXX + LD C,A + LD A,B + + LD B,8 ;!HARDCODE количество регионов в блоке КЭШа FAT + LD DE,4 ;!HARDCODE размер региона в блоке КЭШа FAT (секторов) + ; чтоб не насрать за границы FAT +.region_loop: SUB A,E + JR NC,.good_blk + ; максимально допустимый блок для записи меньше, чем хочется + ADD A,E + LD E,A + ; +.good_blk: SRL C + CALL C,.SAVE_FAT_CACHE_REGION + EXX + ADD HL,DE + EXX + ADD IX,DE + JR NC,.no_inc_HL + INC HL +.no_inc_HL: DJNZ .region_loop + RET + ; HL' - Адрес в странице КЭШа + ; HL:IX - смещение внутри раздела на начало нужного РЕГИОНА блока FAT +.SAVE_FAT_CACHE_REGION: + PUSH AF + PUSH DE + PUSH BC + PUSH HL + PUSH IX + ; + EXX + PUSH HL + PUSH HL + EXX + LD B,E ; кол-во секторов + POP DE ; Адрес в странице КЭШа + LD A,(CORE_BUFFERS.FatBuffer.DRIVE) ; номер диска + LD C,Dss.DRV.Write + RST ToDSS.DRV + ; HL:IX = Sector + Sector counter + ; DE = Address + (Sector counter * Size sector) + EXX + POP HL ; адрес в странице КЭШа + LD DE,#0800 ;!HARDCODE размер региона в блоке КЭШа FAT (байтов) + EXX + ; + POP IX + POP HL + POP BC + POP DE + POP AF + RET + ; DJNZ .region_loop + ; RET + ENDIF +;----------------------------------------------------------------------- +; +;[x] fat32 ;!TEST +;вход: HL':HL - номер кластера +;выход: HL - адрес нужной ячейки в странице FATPAGE +GET_FAT32_CELL: + ; двигаем влево HL':H + LD A,H + EXX + LD C,A + LD A,H + AND FAT_CACHE.Size_Mask_32 ; #0F + LD H,A + LD A,C + ; + LD B,FAT_CACHE.Degree ; 4 сдвига +.loop_block: + RLCA ; << H + RL L ; << L' + RL H ; << H' + DJNZ .loop_block + EXX + ; В итоге тут в HL' номер блока FAT + ; + ; HL - FAT32 OFFSET (FROM CASH) + LD A,H + AND FAT_CACHE.Size_Mask_32 ; #0F + LD H,A + ADD HL,HL + ADD HL,HL + PUSH HL ; [x] fat32 сохраняем на случай, если READ_FAT_TABLE испортит + AND A + ; + EXX + EX DE,HL + LD HL,(CORE_BUFFERS.FatBuffer.CacheBlock) ; BC - BLOCK FAT IN CASH + SBC HL,DE + CALL NZ,READ_FAT_TABLE ; A != C - READ NEW BLOCK FAT + POP HL + LD DE,FATPAGE.cache ; начало кеша FAT-а + ADD HL,DE ; на ячейку FAT + RET +;----------------------------------------------------------------------- +;вход: HL - номер кластера +;выход: HL - адрес нужной ячейки в странице FATPAGE +GET_FAT16_CELL: + LD A,H + LD B,H + ;AND #0F + AND FAT_CACHE.Size_Mask_16 + LD H,A + LD A,B + ; A=A/16 ; A - BLOCK FAT (1 BLOCK = 8192 BYTES) + DUP FAT_CACHE.Degree_16 + RRCA + EDUP + ;AND #0F + AND FAT_CACHE.Part_Mask_16 + ; + ADD HL,HL ; HL - FAT OFFSET (FROM CASH) + ; [x] fat32 поменялся вход в процедуру READ_FAT_TABLE. Раньше номер блока в рег. A передавался + ; LD BC,(CORE_BUFFERS.FatBuffer.CacheBlock) ; BC - BLOCK FAT IN CASH + ; CP C + LD DE,(CORE_BUFFERS.FatBuffer.CacheBlock) ; BC - BLOCK FAT IN CASH + CP E + LD E,A + ; + CALL NZ,READ_FAT_TABLE ; A != C - READ NEW BLOCK FAT + LD DE,FATPAGE.cache ; начало кеша FAT-а + ADD HL,DE ; на ячейку FAT + RET +;----------------------------------------------------------------------- +;вход: HL - номер кластера +;выход: HL - адрес нужной ячейки в странице FATPAGE +; CF - чётный/нечётный адрес кластера +GET_FAT12_CELL: + LD D,H + LD E,L + SRL H + RR L ; сдвиг вправо через CF + PUSH AF ; сохр. флаг + ADD HL,DE ; CLUSTER * 1.5 + ; + IF FAT_CACHE.Size_12 < #1800 + ;!FIXIT оптимизировать + LD A,H + LD B,H + ; + AND #1F + ;AND FAT_CACHE.Size_Mask_16 + ; + LD H,A + LD A,B + ; + RLCA + RLCA + RLCA + ;DUP FAT_CACHE.Degree_16 + ; RRCA + ;EDUP + AND #07 + ;AND FAT_CACHE.Part_Mask_16 + ; + ; [ ] поменялся вход в процедуру READ_FAT_TABLE. Раньше номер блока в рег. A передавался + ; LD BC,(CORE_BUFFERS.FatBuffer.CacheBlock) ; BC - BLOCK FAT IN CASH + ; CP C + LD DE,(CORE_BUFFERS.FatBuffer.CacheBlock) ; BC - BLOCK FAT IN CASH + CP E + LD E,A + ; + CALL NZ,READ_FAT_TABLE ; прочитать в кеш 16 секторов FAT-а + ENDIF + ; + LD DE,FATPAGE.cache + ADD HL,DE + POP AF + RET +;----------------------------------------------------------------------- + + + +;[x] fat32 ;!TEST +;CLUSTER_TO_SECTOR: +; in: HL':HL - CLUSTER +; out: HL:IX - SECTOR +CLUSTER_TO_SECTOR: + EXX + PUSH HL + EXX + POP DE + ; DE:HL - cluster + ; +.no_prepare: PUSH BC + LD BC,-2 + ADD HL,BC + JR C,.no_dec_de + DEC DE +.no_dec_de: ; cluster = cluster - 2 + ; + LD A,(CORE_BUFFERS.FatBuffer.SectorsPerCluster) + XOR 1 + JR Z,.skip + ; + RRA +.loop: ADD HL,HL + RL E + RL D + ; + RRA + JP NC,.loop + ; +.skip: EX DE,HL + LD XL,E + LD XH,D + LD DE,(CORE_BUFFERS.FatBuffer.FirstDataSector_L) + ; [x] fat32 + ;XOR A + ; + ADD IX,DE + ; [x] fat32 + LD DE,(CORE_BUFFERS.FatBuffer.FirstDataSector_H) + ;LD D,A + ;LD E,A + ; + ADC HL,DE + POP BC + RET + +//////////////////////////////////////////////////////////////////////// + +; [x] fat32 ;!TEST +; READ SECTORS OF FILE +; вход: HL:DE - FP (in sectors) +; IY - FM +; IX - buffer in RAM +; B - количество секторов для чтения +BLOCK_READ: LD (READ.PointerOnBuffer),IX + LD A,(CORE_BUFFERS.FatBuffer.SectorsPerCluster) ;SECTORS PER CLUSTER + LD C,A + PUSH BC ; B - количество секторов для чтения, C - SectorsPerCluster + ; HL:DE / A => DE:BC, H=0, L - остаток + CALL DIV_by_Shifts + PUSH HL ; остаток DIV_by_Shifts + ; [x] GET/SAVE CLUSTER NUMBER BEFORE/AFTER READ/WRITE + PUSH BC ; младшее слово номера кластера + PUSH DE ; [x] fat32 старшее слово номера кластера + ; + ; EXX + ; LD L,(IY+_sFM.FS_REC.FIRST_CLUSTER_H) ; START CLUSTER High + ; LD H,(IY+_sFM.FS_REC.FIRST_CLUSTER_H+1) + ; LD A,L + ; OR H + ; EXX + ; LD L,(IY+_sFM.FS_REC.FIRST_CLUSTER_L) ; START CLUSTER Low + ; LD H,(IY+_sFM.FS_REC.FIRST_CLUSTER_L+1) + ; OR L + ; OR H + CALL CHECK_FIRST_CLUSTER + JR Z,.fast_exit_4 + CALL GetSavedCluster + ;HL': HL - известный кластер файла для отсчёта + ;DE : BC - оставшееся смещение в файле в кластерах (D=D+1, B=B+1) + ; + PUSH DE ; [x] оставшееся смещение в файле в кластерах (старшее слово) + JR .enter_loop1 + ; +.fast_exit_5: POP DE +.fast_exit_4: ; [x] GET/SAVE CLUSTER NUMBER BEFORE/AFTER READ/WRITE + POP DE ; [x] fat32 старшее слово номера кластера + POP BC + ; + POP BC + POP DE + AND A + RET + ; [x] fat32 +.loop1_big: PUSH BC + LD BC,0 +.loop1_small: PUSH BC + CALL READ_FROM_FAT + POP BC + JR C,.fast_exit_5 ;RY01 + EX DE,HL + EXX + EX DE,HL + EXX +.enter_loop1: INC B + DEC BC ; ВС - смещение внутри файла в кластерах (младшее слово) + DJNZ .loop1_small + POP BC ; [x] оставшееся смещение в файле в кластерах (старшее слово) + INC B + DEC BC + DJNZ .loop1_big + ;;;; + ; + ;[x] GET/SAVE CLUSTER NUMBER BEFORE/AFTER READ/WRITE + POP DE ; [x] fat32 старшее слово номера кластера + POP BC ; младшее слово номера кластера + CALL SaveGotCluster + ; + POP DE ; D = 0, E = остаток DIV_by_Shifts + POP BC ; B - количество секторов для чтения, C - SectorsPerCluster + ; (SP) = (RET) + ; работа с остатком от деления + LD A,C + SUB E + LD C,A + CP B ; (SectorsPerCluster - остаток) - количество секторов для чтения + JR C,.skip1 ; SIZE > RESIDUE CLUSTER + LD C,B ; SIZE < CLUSTER +.skip1: LD A,B + SUB C + LD B,A + ; + EXX + PUSH HL ; номер кластера старшая часть + EXX + PUSH HL ; номер кластера младшая часть + PUSH BC ; B = количество секторов на дочитку, C = (SectorsPerCluster - остаток) либо количество секторов для чтения + PUSH DE ; D = 0, E = остаток DIV_by_Shifts + CALL CLUSTER_TO_SECTOR + POP DE ; D = 0, E = остаток DIV_by_Shifts + ADD IX,DE + JR NC,.skip2 + INC HL +.skip2: LD DE,(READ.PointerOnBuffer) + LD A,(CORE_BUFFERS.FatBuffer.DRIVE) + LD B,C + LD C,Dss.DRV.Read + RST ToDSS.DRV + ; + JR C,.Error + POP BC ; B = количество секторов на дочитку, C = (SectorsPerCluster - остаток) либо количество секторов для чтения + LD HL,(READ.PointerOnBuffer) + LD DE,(CORE_BUFFERS.FatBuffer.BytesPerSector) + ;!TEST + LD A,B + LD B,C +.loop2: ADD HL,DE + DJNZ .loop2 + ; + LD (READ.PointerOnBuffer),HL + POP DE ; номер кластера младшая часть + EXX + POP HL ; номер кластера старшая часть + EXX + OR A + RET Z ; количество секторов на дочитку = 0? + LD B,A + ; +.loop4: LD HL,CORE_BUFFERS.FatBuffer.SectorsPerCluster + LD A,B + SUB (HL) + LD B,A + LD C,(HL) + JR NC,.BLOKRD7 + LD B,0 + ADD A,(HL) ;0 AND CF + LD C,A + OR A ;CLEAR CF + RET Z + ; +.BLOKRD7: EX DE,HL + PUSH BC + ; HL':HL - номер кластера + CALL READ_FROM_FAT + POP BC + JR C,.ECL1 ;RY01 + ; + EXX + EX DE,HL + PUSH HL ; номер след. кластера (старшее слово) + EXX + EX DE,HL + PUSH HL ; номер след. кластера (младшее слово) + PUSH BC + CALL CLUSTER_TO_SECTOR + LD DE,(READ.PointerOnBuffer) + LD A,(CORE_BUFFERS.FatBuffer.DRIVE) + LD B,C + LD C,Dss.DRV.Read + RST ToDSS.DRV + JR C,.Error + ; + POP BC + LD HL,(READ.PointerOnBuffer) + LD DE,(CORE_BUFFERS.FatBuffer.BytesPerSector) +.loop3: ADD HL,DE + DEC C + JR NZ,.loop3 + LD (READ.PointerOnBuffer),HL + POP DE ; номер след. кластера (младшее слово) + EXX + POP HL ; номер след. кластера (старшее слово) + EXX + JP .loop4 + ; +.Error: POP BC + POP DE + POP HL + ;SCF + RET + ; +.ECL1: AND A + RET + +;----------------------------------------------------------------------- + +; [x] fat32 +; вход: IY - FM +; выход: HL':HL - first cluster +; ZF = 0 если первого кластера нет +CHECK_FIRST_CLUSTER: + EXX + LD L,(IY+_sFM.FS_REC.FIRST_CLUSTER_H) ; START CLUSTER High + LD H,(IY+_sFM.FS_REC.FIRST_CLUSTER_H+1) + LD A,L + OR H + EXX + LD L,(IY+_sFM.FS_REC.FIRST_CLUSTER_L) ; START CLUSTER + LD H,(IY+_sFM.FS_REC.FIRST_CLUSTER_L+1) + OR L + OR H + RET + +; [x] fat32 +; WRITE SECTORS OF FILE +; вход: HL:DE - FP (in sectors) +; IX - data in RAM +; IY - FM +; B - количество секторов для записи +BLOK_WRITE: LD (READ.PointerOnBuffer),IX + LD A,(CORE_BUFFERS.FatBuffer.SectorsPerCluster) ;SECTORS PER CLUSTER + LD C,A + PUSH BC ; B - количество секторов для чтения, C - SectorsPerCluster + ; HL:DE / A => DE:BC, H=0, L - остаток + CALL DIV_by_Shifts + PUSH HL ; остаток DIV_by_Shifts + ;[x] GET/SAVE CLUSTER NUMBER BEFORE/AFTER READ/WRITE + PUSH BC ; младшее слово номера кластера + PUSH DE ; fat32 старшее слово номера кластера + ; + ; EXX + ; LD L,(IY+_sFM.FS_REC.FIRST_CLUSTER_H) ; START CLUSTER High + ; LD H,(IY+_sFM.FS_REC.FIRST_CLUSTER_H+1) + ; LD A,L + ; OR H + ; EXX + ; LD L,(IY+_sFM.FS_REC.FIRST_CLUSTER_L) ; START CLUSTER + ; LD H,(IY+_sFM.FS_REC.FIRST_CLUSTER_L+1) + ; OR L + ; OR H + CALL CHECK_FIRST_CLUSTER + JR NZ,.FindCluster + ; + PUSH BC ; младшее слово номера кластера + PUSH DE ; fat32 старшее слово номера кластера + ; [x] fat32 + CALL G_CLUST + JP C,.Error_6 + ; + LD (IY+_sFM.FS_REC.FIRST_CLUSTER_L),L + LD (IY+_sFM.FS_REC.FIRST_CLUSTER_L+1),H + ; [x] fat32 + EXX + LD (IY+_sFM.FS_REC.FIRST_CLUSTER_H),L ; START CLUSTER High + LD (IY+_sFM.FS_REC.FIRST_CLUSTER_H+1),H + EXX + ; + XOR A + CALL SET_NEW_FREE_CLUSTERS + ; + CALL WRITE_TO_FAT + ;!TEST ;!TODO 2/12/23 ; [ ] баг с избыточной записью WRITE_FAT_TABLE? + ;PUSH HL + ;CALL WRITE_FAT_TABLE ; подкл. банку кеша FAT и записать его на диск + ;POP HL + ; + POP DE ; младшее слово номера кластера + POP BC ; fat32 старшее слово номера кластера + ; + INC B + INC D ; fat32 + PUSH DE + JP .enter_loop + ;[x] GET/SAVE CLUSTER NUMBER BEFORE/AFTER READ/WRITE +.FindCluster: CALL GetSavedCluster + ;HL': HL - известный кластер файла для отсчёта + ;DE : BC - оставшееся смещение в файле в кластерах (D=D+1, B=B+1) + ; + PUSH DE ; оставшееся смещение в файле в кластерах (старшее слово) + JP .enter_loop + ; + ; [x] fat32 +.loop_big: PUSH BC + LD BC,0 +.loop: PUSH BC + CALL READ_FROM_FAT + JR NC,.next + ; end of chain - get new cluster + CALL INC_FAT + JP C,.Error_6 + ; [x] избыточное обращение 01/04/2024 + ;CALL READ_FROM_FAT + ; +.next: POP BC + EX DE,HL + EXX + EX DE,HL + EXX +.enter_loop: INC B + DEC BC + DJNZ .loop + POP BC ; оставшееся смещение в файле в кластерах (старшее слово) + INC B + DEC BC + DJNZ .loop_big + ;;;; + ; + ;[x] GET/SAVE CLUSTER NUMBER BEFORE/AFTER READ/WRITE + POP DE + POP BC + CALL SaveGotCluster + ; + POP DE ; D = 0, E = остаток DIV_by_Shifts + POP BC ; B - количество секторов для чтения, C - SectorsPerCluster + ; (SP) = (RET) + ; + LD A,C + SUB E + LD C,A + CP B ; (SectorsPerCluster - остаток) - количество секторов для чтения + JR C,.skip1 ;SIZE > RESIDUE CLUSTER + LD C,B ;SIZE < CLUSTER +.skip1: LD A,B + SUB C + LD B,A + ; + EXX + PUSH HL ; номер кластера старшая часть + EXX + PUSH HL ; номер кластера младшая часть + PUSH BC ; B = количество секторов на дочитку, C = (SectorsPerCluster - остаток) либо количество секторов для чтения + PUSH DE ; D = 0, E = остаток DIV_by_Shifts + CALL CLUSTER_TO_SECTOR + POP DE ; D = 0, E = остаток DIV_by_Shifts + ADD IX,DE + JR NC,.skip2 + INC HL + ; DOUBLE 1 +.skip2: LD DE,(READ.PointerOnBuffer) + LD A,(CORE_BUFFERS.FatBuffer.DRIVE) + LD B,C + LD C,Dss.DRV.Write + RST ToDSS.DRV + ; + LD A,DSS_Error.sys.WRITE_ERROR + JR C,.Error_3 + POP BC + LD HL,(READ.PointerOnBuffer) + LD DE,(CORE_BUFFERS.FatBuffer.BytesPerSector) + ; + LD A,B + LD B,C +.loop2: ADD HL,DE + DJNZ .loop2 + ; + LD (READ.PointerOnBuffer),HL + POP DE ; номер кластера младшая часть + EXX + POP HL ; номер кластера старшая часть + EXX + ; + OR A + RET Z ; количество секторов на дочитку = 0? + LD B,A + ; +.big_loop: LD HL,CORE_BUFFERS.FatBuffer.SectorsPerCluster + LD A,B + SUB (HL) + LD B,A + LD C,(HL) + JR NC,.WR7 + LD B,0 + ADD A,(HL) ;0 AND CF + LD C,A + OR A ;CLEAR CF + RET Z + ; +.WR7: EX DE,HL + PUSH BC + ; HL':HL - номер кластера + CALL READ_FROM_FAT + JR NC,.WR9 + CALL INC_FAT + JR C,.ErrorFull + ; [x] избыточное обращение 01/04/2024 + ;CALL READ_FROM_FAT + ; +.WR9: POP BC + EXX + EX DE,HL + PUSH HL ; номер след. кластера (старшее слово) + EXX + EX DE,HL + PUSH HL ; номер след. кластера (младшее слово) + PUSH BC + CALL CLUSTER_TO_SECTOR + ; DOUBLE 1 + LD DE,(READ.PointerOnBuffer) + LD A,(CORE_BUFFERS.FatBuffer.DRIVE) + LD B,C + LD C,Dss.DRV.Write + RST ToDSS.DRV + LD A,DSS_Error.sys.WRITE_ERROR + JR C,.Error_3 + POP BC + LD HL,(READ.PointerOnBuffer) + LD DE,(CORE_BUFFERS.FatBuffer.BytesPerSector) +.loop3: ADD HL,DE + DEC C + JR NZ,.loop3 + LD (READ.PointerOnBuffer),HL + POP DE ; номер след. кластера (младшее слово) + EXX + POP HL ; номер след. кластера (старшее слово) + EXX + JP .big_loop + ; +.Error_6: POP BC + POP BC + POP BC +.Error_3: POP BC ;[x] GET/SAVE CLUSTER NUMBER BEFORE/AFTER READ/WRITE + POP BC + POP DE + ;LD A,DSS_Error.sys.WRITE_ERROR + ;SCF + RET + ; +.ErrorFull: POP BC + LD A,DSS_Error.sys.DISK_FULL + ;SCF + RET + +; +;[x] fat32 +;[x] GET/SAVE CLUSTER NUMBER BEFORE/AFTER READ/WRITE +; Вход: DE - смещение в файле в кластерах (старшее слово) +; BC - смещение в файле в кластерах (младшее слово) +; HL - первый кластер файла (младшее слово) +; HL' - первый кластер файла (старшее слово) +; Выход: HL - известный кластер файла для отсчёта (младшее слово) +; HL' - известный кластер файла для отсчёта (старшее слово) +; DE - оставшееся смещение в файле в кластерах (старшее слово, D=D+1) +; BC - оставшееся смещение в файле в кластерах (младшее слово, B=B+1) +; не портит HL, HL' и DE:BC если оптимизация не сработала +GetSavedCluster: + XOR A + CP (IY+_sFM.OptimizedClusters) + JR Z,.noOptimization_0 + ; + PUSH DE + PUSH HL ; первый кластер файла (младшее слово) + ; смещение в файле в кластерах + EX DE,HL + LD E,(IY+_sFM.KnownOffset_H) + LD D,(IY+_sFM.KnownOffset_H+1) + ; проверка старшего слова + AND A + SBC HL,DE + JR C,.noOptimization_2 + ; + PUSH BC + EX DE,HL + LD H,B + LD L,C + LD C,(IY+_sFM.KnownOffset_L) + LD B,(IY+_sFM.KnownOffset_L+1) + ; проверка младшего слова + SBC HL,BC + LD BC,0 + EX DE,HL + SBC HL,BC + JR C,.noOptimization_3 + EX DE,HL + LD B,H + LD C,L + ; DE:BC новое смещение от известного кластера файла (в кластерах) + ; + LD L,(IY+_sFM.KnownCluster_L) + LD H,(IY+_sFM.KnownCluster_L+1) + EXX + LD L,(IY+_sFM.KnownCluster_H) + LD H,(IY+_sFM.KnownCluster_H+1) + EXX + ; баланс стека + POP AF + POP AF + POP AF + ; для цикла DJNZ + INC B + INC D + RET + ; +.noOptimization_3: + POP BC +.noOptimization_2: + POP HL +.noOptimization_1: + POP DE +.noOptimization_0: + INC B + INC D + RET + +;[x] fat32 +;[x] GET/SAVE CLUSTER NUMBER BEFORE/AFTER READ/WRITE +SaveGotCluster: LD A,C + OR B + OR E + OR D + RET Z + ; + LD (IY+_sFM.KnownOffset_L),C + LD (IY+_sFM.KnownOffset_L+1),B + LD (IY+_sFM.KnownOffset_H),E + LD (IY+_sFM.KnownOffset_H+1),D + ; + LD (IY+_sFM.KnownCluster_L),L + LD (IY+_sFM.KnownCluster_L+1),H + EXX + LD (IY+_sFM.KnownCluster_H),L + LD (IY+_sFM.KnownCluster_H+1),H + EXX + ; + LD A,1 + LD (IY+_sFM.OptimizedClusters),A + RET +//////////////////////////////////////////////////////////////////////// + +;----------------------------------------------------------------------; +; Вход: HL - адрес куда писать +; Выход: HL - адрес следующий после записаного +WRITE_DATE_TIME_TO_DIRECTORY_RECORD: + ; [ ] VFAT date + PUSH HL + CALL SYSTIME ; узнать тек. дату и время + CALL MK_TIME ; закодировать время/дату + POP HL + ; FAT_DIRECTORY_RECORD.TIME + LD (HL),E ; de=время + INC HL + LD (HL),D + INC HL + ; FAT_DIRECTORY_RECORD.DATE + LD (HL),C ; день + INC HL + LD (HL),B ; месяц + INC HL + RET +;----------------------------------------------------------------------; + + +;----------------------------------------------------------------------; +;Расчёт смещения в секторах ;!HARDCODE sector size +GET_OFFSET_IN_SECTORS: + LD H,0 ;!HARDCODE max file size = 8 gb + LD E,(IY+_sFM.F_POSITION+1) + LD D,(IY+_sFM.F_POSITION+2) + LD L,(IY+_sFM.F_POSITION+3) + LD A,E + AND #01 + LD B,A + LD C,(IY+_sFM.F_POSITION) + RR L + RR D + RR E + ;HL:DE FP (in sectors) + ;BC FP residue (in bytes) + ; + OR C + RET +;----------------------------------------------------------------------; + +;//MODULE: FAT_X +;[END] \ No newline at end of file diff --git a/Crazy Estex DSS/DSS/KEYINTER.ASM b/Crazy Estex DSS/DSS/KEYINTER.ASM new file mode 100644 index 0000000..18535e4 --- /dev/null +++ b/Crazy Estex DSS/DSS/KEYINTER.ASM @@ -0,0 +1,1276 @@ + +; MODULE KEYINTER +;[BEGIN] +;//MODULE: KEYINTER Keyboard Scan Codes: Set 2 +;//CREATE: 19-05-1998 AUTHOR: Denis Parinov +;//UPDATE: 24-10-1999 DNS Restore module +;------------------------------------------------ +;R02 13-04-2023 BAO FIX BUG IN K_CLEAR WITH STACK OVERFLOW +;R01 10-02-2003 DNS Add cursor visualisation +; + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;KEYBOARD BUFFER + _mInfoALIGN 256,0 +SBUF: BLOCK 64,0 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; _mInfoALIGN 256,0 ;; +; 0 1 2 3 4 5 6 7 8 9 A B C D E F ;; +XLAT_T: DB #00,#43,#00,#3F,#3D,#3B,#3C,#46,#00,#44,#42,#40,#3E,#0F,#00,#00 ;00 ;; + DB #00,#37,#29,#00,#36,#10,#02,#00,#00,#00,#2A,#1E,#1D,#11,#03,#00 ;10 ;; + DB #00,#2C,#2B,#1F,#12,#05,#04,#00,#00,#38,#2D,#20,#14,#13,#06,#00 ;20 ;; + DB #00,#2F,#2E,#22,#21,#15,#07,#00,#00,#00,#30,#23,#16,#08,#09,#00 ;30 ;; + DB #00,#31,#24,#17,#18,#0B,#0A,#00,#00,#32,#33,#25,#26,#19,#0C,#00 ;40 ;; + DB #00,#00,#27,#00,#1A,#0D,#00,#00,#1C,#34,#28,#1B,#00,#35,#00,#00 ;50 ;; + DB #00,#00,#00,#00,#00,#00,#0E,#00,#00,#51,#00,#54,#57,#00,#00,#00 ;60 ;; + DB #50,#4F,#52,#55,#56,#58,#01,#49,#45,#4D,#53,#4C,#4B,#59,#48,#00 ;70 ;; + DB #00,#00,#00,#41,#00,#00,#00,#00,#00,#00,#00,#00,#00,#00,#00,#00 ;80 ;; +.Size EQU $-XLAT_T ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +HEAD DB #00 +HOST DB #00 +; +K_LOCK EQU $-KEYFLAG +LANG_L EQU 7 +PAUSE_L EQU 6 +RES5_L EQU 5 ; not used ;X_SHIFT +RES4_L EQU 4 ; not used +NUM_L EQU 3 +SCRL_L EQU 2 +INS_L EQU 1 +CAPS_L EQU 0 +KEYFLAG DB #02 ;D0-Key Pressed +; +K_SHIFT EQU $-KEYFLAG +L_SHIFT EQU 7 +R_SHIFT EQU 6 +X_CTRL EQU 5 +X_ALT EQU 4 +L_CTRL EQU 3 +L_ALT EQU 2 +R_CTRL EQU 1 +R_ALT EQU 0 +KEYCTRL DB #00 +; +KEYFLG EQU $-KEYFLAG +FLAG_E0 EQU 7 +FLAG_F0 EQU 6 +FLAG_E1 EQU 5 +FLAG_04 EQU 4 +FLAG_03 EQU 3 +FLAG_02 EQU 2 +FLAG_01 EQU 1 +CTRL_SHIFT EQU 0 ; ctrl+shift = change language +KEY_FLG DB #00 +; +SOUND_K EQU $-KEYFLAG +FLAG_S7 EQU 7 +FLAG_S6 EQU 6 +FLAG_S5 EQU 5 +FLAG_S4 EQU 4 +FLAG_S3 EQU 3 +FLAG_S2 EQU 2 +SF_ALT EQU 1 +SF_BUFF EQU 0 + DB #03 +; +UnCODE EQU $-KEYFLAG +UNCODE DW 0 ; последняя отжатая клавиша + +; D15 - LShift +; D14 - RShift +; D13 - CTRL +; D12 - ALT +; D11 - LCTRL +; D10 - LALT +; D9 - RCTRL +; D8 - RALT +; D7 - Language Lock +; D6 - Pause Lock +; D5 - Reserved +; D4 - Reserved +; D3 - Num Lock +; D2 - Scroll Lock +; D1 - Insert Lock +; D0 - Caps Lock + +; D15 - Keystroke +; D14 +; D13 \ +; D12 \ +; D11 -- Position code (0...5Ah) +; D10 / +; D9 / +; D8 +; D7..D0 - ASCII code + + + +WAITKEY LD HL,HOST + LD A,(HEAD) + CP (HL) + JR Z,WAITKEY + CALL GETSYM + LD A,E + AND A + RET + +SCANKEY LD HL,HOST + LD A,(HEAD) + CP (HL) + RET Z + CALL GETSYM + LD A,E + RET +; + +; + IF CLASSIC_CURSOR ;------------------------------; + +ECHOKEY: ;R01 +.CURCOUNT+1: LD A,#FF + INC A + LD (.CURCOUNT),A + AND #FF + JR NZ,.NOTUR +.CURSYM+1: LD A,#00 + XOR #01 + LD (.CURSYM),A + + CALL CURSOR + PUSH DE + + LD A," " + JR Z,.CURSKI + LD A,"_" +.CURSKI: CALL PUTCHAR.NO_SCROLL ;R03; [x] -bug with Vasil's version of cursor + + POP DE + CALL LOCATE + ;LD A,8 ; BACKSPACE + ;CALL PUTCHAR +.NOTUR: CALL SCANKEY + JR Z,ECHOKEY + PUSH DE + PUSH BC + PUSH AF + + CALL CURSOR + PUSH DE + + LD A," " + CALL PUTCHAR.NO_SCROLL ;R03; [x] -bug with Vasil's version of cursor + + ;LD A,8 ; BACKSPACE + ;CALL PUTCHAR + POP DE + POP AF + PUSH DE + ;R01 [v] + CALL PUTCHAR.NO_SCROLL ; [x] -bug with Vasil's version of cursor + + POP DE + CALL LOCATE + + POP BC + POP DE + LD A,E + AND A + RET + + ELSE ;------------------------------; + +delay_curs: EQU 11 ; частота мигания курсора +INS_CUR_ZG: EQU #19 +CURSOR_ZG: EQU #1A +NORM_ZG: EQU #1B + + +ECHOKEY: CALL Cursor_On ; вкл. курсор, установить фокус на "Input Line" + EI +.loop: CALL SCANKEY + JR Z,.loop + PUSH DE + PUSH BC + PUSH AF + CALL Cursor_Off ; выкл. курсор + POP AF + OR A + ; [x] -bug with Vasil's version of cursor + CALL NZ,PUTCHAR.NO_SCROLL ; добавил вывод "a" на экран + POP BC + POP DE + LD A,E + AND A + RET + +Cursor: +.Flag+1: LD A,0 ; флаг курсора 00-нет/01-есть + CPL + LD (.Flag),A +; Включить курсор +Cursor_On: LD C,BIOS.LP_GET_PLACE ; узнать полож. курсора + RST ToBIOS + LD (Cursor_Off.pos),DE + XOR A + LD C,BIOS.WIN_GET_SYM ; получить символ + RST ToBIOS + LD BC,NORM_ZG*256+BIOS.WIN_PUT_SYM ; b=знакоген., с=символ на экран + LD A,(Cursor.Flag) + OR A + JR Z,.put_ + LD B,INS_CUR_ZG ; блок + LD A,(KEYFLAG) ; флаги клавы + AND 1<","?",#00,"|" + DB #00,#00,Spc,#00,#00 + DB #00,#00,#00,#00,#00,#00,#00,#00,#00,#00,#00,#00 + DB #00,#00,#00,"/","*","-","+",Ent,#00 + DB #00,#00,#00,#00,#00,#00,#00,#00,#00,#00 + +CAPSTAB DB "`",Esc,"1","2","3","4","5","6","7","8","9","0","-","=",Bcs + DB Tab,"Q","W","E","R","T","Y","U","I","O","P","[","]" + DB Cps,"A","S","D","F","G","H","J","K","L",";","'",Ent + DB #00,"Z","X","C","V","B","N","M",#2C,".","/",#00,#5C + DB #00,#00,Spc,#00,#00 + DB #00,#00,#00,#00,#00,#00,#00,#00,#00,#00,#00,#00 + DB #00,#00,#00,"/","*","-","+",Ent,#00 + DB #00,#00,#00,#00,#00,#00,#00,#00,#00,#00 + +SHF2TAB DB "~",Esc,"!","@","#","$","%","^","&","*","(",")","_","+",Bcs + DB Tab,"q","w","e","r","t","y","u","i","o","p","{","}" + DB Cps,"a","s","d","f","g","h","j","k","l",":",#22,Ent + DB #00,"z","x","c","v","b","n","m","<",">","?",#00,"|" + DB #00,#00,Spc,#00,#00 + DB #00,#00,#00,#00,#00,#00,#00,#00,#00,#00,#00,#00 + DB #00,#00,#00,"/","*","-","+",Ent,#00 + DB #00,#00,#00,#00,#00,#00,#00,#00,#00,#00 + +;Standart Russian tables +NORMRUS DB #F1,Esc,"1","2","3","4","5","6","7","8","9","0","-","=",Bcs + DB Tab,#A9,#E6,#E3,#AA,#A5,#AD,#A3,#E8,#E9,#A7,#E5,#EA + DB Cps,#E4,#EB,#A2,#A0,#AF,#E0,#AE,#AB,#A4,#A6,#ED,Ent + DB #00,#EF,#E7,#E1,#AC,#A8,#E2,#EC,#A1,#EE,".",#00,#5C + DB #00,#00,Spc,#00,#00 + DB #00,#00,#00,#00,#00,#00,#00,#00,#00,#00,#00,#00 + DB #00,#00,#00,"/","*","-","+",Ent,#00 + DB #00,#00,#00,#00,#00,#00,#00,#00,#00,#00 + +SHIFRUS DB #F0,Esc,"!",#22,"#","$",":",#2C,".",";","?","%","_","+",Bcs + DB Tab,#89,#96,#93,#8A,#85,#8D,#83,#98,#99,#87,#95,#9A + DB Cps,#94,#9B,#82,#80,#8F,#90,#8E,#8B,#84,#86,#9D,Ent + DB #00,#9F,#97,#91,#8C,#88,#92,#9C,#81,#9E,#2C,#00,"|" + DB #00,#00,Spc,#00,#00 + DB #00,#00,#00,#00,#00,#00,#00,#00,#00,#00,#00,#00 + DB #00,#00,#00,"/","*","-","+",Ent,#00 + DB #00,#00,#00,#00,#00,#00,#00,#00,#00,#00 + +CAPSRUS DB #F0,Esc,"1","2","3","4","5","6","7","8","9","0","-","=",Bcs + DB Tab,#89,#96,#93,#8A,#85,#8D,#83,#98,#99,#87,#95,#9A + DB Cps,#94,#9B,#82,#80,#8F,#90,#8E,#8B,#84,#86,#9D,Ent + DB #00,#9F,#97,#91,#8C,#88,#92,#9C,#81,#9E,".",#00,#5C + DB #00,#00,Spc,#00,#00 + DB #00,#00,#00,#00,#00,#00,#00,#00,#00,#00,#00,#00 + DB #00,#00,#00,"/","*","-","+",Ent,#00 + DB #00,#00,#00,#00,#00,#00,#00,#00,#00,#00 + +SHF2RUS DB #F1,Esc,"!",#22,"#","$",":",#2C,".",";","?","%","_","+",Bcs + DB Tab,#A9,#E6,#E3,#AA,#A5,#AD,#A3,#E8,#E9,#A7,#E5,#EA + DB Cps,#E4,#EB,#A2,#A0,#AF,#E0,#AE,#AB,#A4,#A6,#ED,Ent + DB #00,#EF,#E7,#E1,#AC,#A8,#E2,#EC,#A1,#EE,#2C,#00,"|" + DB #00,#00,Spc,#00,#00 + DB #00,#00,#00,#00,#00,#00,#00,#00,#00,#00,#00,#00 + DB #00,#00,#00,"/","*","-","+",Ent,#00 + DB #00,#00,#00,#00,#00,#00,#00,#00,#00,#00 + +;================================ + +;//MODULE: KEYINTER +;[END] +; ENDMODULE \ No newline at end of file diff --git a/Crazy Estex DSS/DSS/KNOWN.BUG b/Crazy Estex DSS/DSS/KNOWN.BUG new file mode 100644 index 0000000..e5f3ea4 --- /dev/null +++ b/Crazy Estex DSS/DSS/KNOWN.BUG @@ -0,0 +1,13 @@ +FIXED: + + function WINCOPY & WINREST не запрещают прерывания перед вызовом BIOS (используется вывод стеком!). + + + при выводе на консоль длинного текста, экран не скролируется. Проверять на достижение 80 позиции! + +? ошибка в функции SCROLL A=0. + ++ ошибка при просмотре каталога в функциях установки атрибутов пропускаются системные файлы. п/п SEARCH MASK=#23 + +- игнорирование ошибок при записи системных областей FAT/DIR, невозможность отработать ошибку write-protect, так как она теряется при попытке записать измененный каталог на диск. Но возникает ошибка file not found так как сразу после создания система открывает файл. + +- ошибка разбора допустимого имени файла, если оно состоит из "." так как подразумевается пробелы точка пробелы. + diff --git a/Crazy Estex DSS/DSS/Kernel_Panic.asm b/Crazy Estex DSS/DSS/Kernel_Panic.asm new file mode 100644 index 0000000..4e26ab6 --- /dev/null +++ b/Crazy Estex DSS/DSS/Kernel_Panic.asm @@ -0,0 +1,81 @@ +; + MACRO PRINT_LINE_KERNEL_PANIC coordY, txtString, txtStringSize, txtColor + LD HL,txtString + LD BC,txtColor*256 + txtStringSize + LD DE,coordY * 256 + (80 - txtStringSize)/2 + CALL .PRINT_LINE + ENDM ; 12 bytes +; +;-----------------------[] +; HL - сообщение +; E - координата X на текстовом экране +; BC - длина сообщения +KERNEL_PANIC: + DI + ; + PUSH DE + PUSH HL + PUSH BC + ; + LD E,1 + LD BC,BIOS.LP_OPEN_S.TXT_80x32_Default + RST ToBIOS + ; + LD HL,#2050 + LD DE,0 + LD BC,256*COLORS.CGA.PAPER.BLUE + BIOS.LP_CLS_WIN + RST ToBIOS + ; + LD A,1 + OUT (SCREEN_SWITCH),A ; set scr-2 + ; + PRINT_LINE_KERNEL_PANIC 13, .kernel_panic, .kernel_panic.size, +(COLORS.CGA.FLASH + COLORS.CGA.PAPER.BLUE + COLORS.CGA.INC.RED) + PRINT_LINE_KERNEL_PANIC 18, .press_CAD, .press_CAD.size, +(COLORS.CGA.PAPER.BLUE + COLORS.CGA.INC.WHITE) + ; + POP BC + POP HL + LD DE,#A000 + LD A,C + LDIR + ; + POP DE + LD D,15 + LD C,BIOS.LP_SET_PLACE + RST ToBIOS + ; + LD HL,#A000 + LD DE,0*256 + COLORS.CGA.PAPER.BLUE + COLORS.CGA.INC.WHITE + LD B,A + LD C,BIOS.LP_PRINT_LINE3 + RST ToBIOS + ; +.loop: DI + HALT + JR .loop + ; +.PRINT_LINE: + PUSH BC + PUSH DE + LD DE,#A000 + LD B,E + LD A,C + LDIR + ; + POP DE + LD C,BIOS.LP_SET_PLACE + RST ToBIOS + ; + POP DE + LD E,D + LD HL,#A000 + LD D,L + LD B,A + LD C,BIOS.LP_PRINT_LINE3 + JP ToBIOS + ; +.kernel_panic: DZ "KERNEL PANIC!" +.kernel_panic.size EQU $-.kernel_panic +; +.press_CAD: DZ "Press Ctrl+Alt+Del or RESET." +.press_CAD.size EQU $-.press_CAD +;-----------------------[] \ No newline at end of file diff --git a/Crazy Estex DSS/DSS/Procedures.asm b/Crazy Estex DSS/DSS/Procedures.asm new file mode 100644 index 0000000..8356e6b --- /dev/null +++ b/Crazy Estex DSS/DSS/Procedures.asm @@ -0,0 +1,346 @@ +;!TODO Procedures +;----------------------------------------------------------------------; +; Закодировать время/дату +; вход: de - день/месяц +; hl - часы/минуты +; b - секунды +; ix - год +; выход: de - время +; bc - месяц/день +; ix - год +; +;INPUT: D - DAY; E - MONTH +; H - HOUR; L - MINUTE +; B - SECOND (0...59) +; IX- YEAR (0...65535) +;OUTPUT: DE - hhhhhmmmmmmsssss h - hour, m - min, s - sec/2 +; BC - yyyyyyymmmmddddd y - year, m - month, d - day +; (1980-2108) +MK_TIME: + LD A,L + RLCA + RLCA + SLA A + RL H + SLA A + RL H + SLA A + RL H + SRL B + OR B + LD L,A + + LD BC,#F844 ;(-1980) + ADD IX,BC + LD A,E + RLCA + RLCA + RLCA + RLCA + AND #F0 + LD B,XL + SLA A + RL B + OR D + LD C,A + EX DE,HL + AND A + RET +;----------------------------------------------------------------------; + +;!TODO Procedures +;----------------------------------------------------------------------; +; Раскодировать время/дату +; вход: de - время +; bc - месяц/день +; ix - год +; выход: de - день/месяц +; hl - часы/минуты +; b - секунды +; ix - год +; +;INPUT: DE - hhhhhmmmmmmsssss h - hour, m - min, s - sec/2 +; BC - yyyyyyymmmmddddd y - year, m - month, d - day +; (1980-2108) +;OUTPUT: D - DAY; E - MONTH +; H - HOUR; L - MINUTE +; B - SECOND (0...59) +; IX- YEAR (0...65535) +RMKTIME: + EX DE,HL + LD A,C + AND #1F + LD D,A + SRL B + RR C + LD A,C + RRCA + RRCA + RRCA + RRCA + AND #0F + LD E,A + LD C,B + LD B,0 + LD IX,1980 + ADD IX,BC + LD A,L + AND #1F + ADD A,A + LD B,A + SRL H + RR L + SRL H + RR L + SRL H + RR L + SRL L + SRL L + AND A + RET +;----------------------------------------------------------------------; + + +;----------------------------------------------------------------------; +; [x] 25/01/2024 +; вход: D - день +; E - месяц +; IX - год +; выход: H - день недели (1 - воскресенье) +CalcDayOfWeek: LD A,D + LD (.day),A + ; x = (14 ? месяц) / 12 + ; y = год ? x + LD A,E + CP 3 + LD A,0 + JR NC,1F + DEC IX + LD A,12 +1: ; y = IX + ; m = месяц + 12 * x ? 2 + ADD E + SUB 2 + ; m = A + ; HL = (31 * m) + LD D,0 + LD E,A + RLA + RLA + RLA + LD H,D + LD L,A + ADD HL,HL + ADD HL,HL + SBC HL,DE + ; (31 * m) = HL + ; BC = (31 * m) / 12 + LD B,H + LD C,L + ; D=0 + LD E,12 + CALL BC_Div_DE + ; (31 * m) / 12 = BC + LD (.m31_12),BC + ; y / 4 + PUSH IX + POP BC + ; D=0 + LD E,4 + CALL BC_Div_DE + ; y / 4 = BC + PUSH BC + ; y / 100 + PUSH IX + POP BC + ; D=0 + LD E,100 + CALL BC_Div_DE + ; y / 100 = BC + PUSH BC + ; y / 400 + PUSH IX + POP BC + LD DE,400 + CALL BC_Div_DE + ; y / 400 = BC + ; y/400 - y/100 + AND A + LD H,B + LD L,C + POP DE + SBC HL,DE + ; y/400 - y/100 = HL + ; y/4 ? y/100 + y/400 + POP DE + ADD HL,DE + ; y/4 ? y/100 + y/400 + (31 * m)/12 +.m31_12+1: LD DE,0 + ADD HL,DE + ; y + y/4 ? y/100 + y/400 + (31 * m)/12 + EX DE,HL + ADD IX,DE + ; день + y + y/4 ? y/100 + y/400 + (31 * m)/12 + LD D,0 +.day+1: LD E,0 + ADD IX,DE + ; 7000 + (день + y + y/4 ? y/100 + y/400 + (31 * m)/12) + LD DE,7000 + ADD IX,DE + ; (7000 + (день + y + y/4 ? y/100 + y/400 + (31 * m)/12)) mod 7 + LD B,XH + LD C,XL + LD DE,7 + CALL BC_Div_DE + ; ДеньНедели = L + LD H,L + INC H + RET +; x = (14 ? месяц) / 12 +; y = год ? x +; m = месяц + 12 * x ? 2 +; ДеньНедели = (7000 + (день + y + y/4 ? y/100 + y/400 + (31 * m)/12)) mod 7 +; Все деления целочисленные (остаток отбрасывается). +;----------------------------------------------------------------------; + + +;----------------------------------------------------------------------; +; a..z -> A..Z +UPPER: CP 'a' + RET C + CP 'z' + 1 + JR NC,.MDUPPER + SUB #20 +.NOUPPER: + RET +.MDUPPER: + CP 'а' ; русская буква а, код #A0 + JR C,.NOUPPER + CP 'п' ; русская буква п, код #B0 + JR NC,.BGUPPER + SUB #20 + RET +.BGUPPER: + CP 'р' ; русская буква р, код #E0 + JR C,.NOUPPER + CP 'Ё' ; русская буква Ё, код #F0 + JR NC,.HGUPPER + SUB #50 + RET +.HGUPPER: CP 'ё' ; русская буква ё, код #F1 + RET NZ + DEC A + RET +;----------------------------------------------------------------------; + + + +;!TODO hardware +;----------------------------------------------------------------------; +; Чтение регистров CMOS +; вход: d=номер регистра +RCMOS: LD C,BIOS.CMOS_RD + RST ToBIOS + ;JP BCD2HEX +; INPUT : A - BCD +; OUTPUT: A - HEX +BCD2HEX: + LD E,A + RRCA + RRCA + RRCA + RRCA + AND #0F + LD D,A + ADD A,A + ADD A,A + ADD A,D + ADD A,A + LD D,A + LD A,E + AND #0F + ADD A,D + RET +;----------------------------------------------------------------------; + +;!TODO hardware +;----------------------------------------------------------------------; +;!FIXIT переделать по доке на Даллас и запись в ячейки часов +; Запись регистров CMOS +; вход: d=номер регистра +WCMOS: CALL HEX2BCD + LD C,BIOS.CMOS_WR + JP ToBIOS + +; INPUT : A - HEX +; OUTPUT: A - BCD +HEX2BCD: + LD BC,#0AFF +.loop: INC C + SUB B + JR NC,.loop + ADD A,B + LD B,A + LD A,C + RLCA + RLCA + RLCA + RLCA + AND #F0 + OR B + RET +;----------------------------------------------------------------------; +; + + +; +;----------------------------------------------------------------------; +;BC/DE ==> BC, remainder in HL +; не портит DE +BC_Div_DE: + ld hl,0 + ld a,b + ld b,16 + ;shift the bits from BC into HL +.div_loop: + sla c + rla + adc hl,hl + sbc hl,de + jr nc,.div_inc_acc + add hl,de + db $FE ;this begins the instruction `cp *`, so it eats the next byte. +.div_inc_acc: + inc c + djnz .div_loop + ld b,a + ret +;----------------------------------------------------------------------; +; + +;----------------------------------------------------------------------; +; HL:DE / A => DE:BC, H=0, L - остаток +DIV_by_Shifts: + LD C,A + DEC A + JR Z,.exit + ; + AND E + LD B,A ; остаток + LD A,C + RRCA + ; +.loop: SRL H + RR L + RR D + RR E + RRCA + JP NC,.loop + LD A,B +.exit: LD B,D + LD C,E + EX DE,HL + LD H,0 + LD L,A + RET +;----------------------------------------------------------------------; \ No newline at end of file diff --git a/Crazy Estex DSS/DSS/Structures.inc b/Crazy Estex DSS/DSS/Structures.inc new file mode 100644 index 0000000..593f5be --- /dev/null +++ b/Crazy Estex DSS/DSS/Structures.inc @@ -0,0 +1,134 @@ +; + STRUCT _sStack ; 256 bytes +.buffer BLOCK 256,0 +;.SPoint BYTE 0 + ENDS +; + +; + STRUCT _sEXE_HEADER ; 512 bytes +.EXE_EXT TEXT 3,{"EX","E"} ; 0-2 EXE Сигнатура +.VERSION BYTE 0 ; 3 Version of EXE file +.OFFCOD1 WORD 00 ; 4-5 С какого смещения в файле будет грузиться код в +.OFFCOD2 WORD 00 ; 6-7 память по адресу (Code_addr) Low addr, High addr. +.LOADER WORD 00 ; 8-9 Размер первичного загрузчика или 0 +.RESERVED BLOCK 6,0 ; 10-15 Reserved +.LD_ADDR WORD 00 ; 16-17 Адрес расположения кода в памяти (#4100-#FFFF) +.PC_REG WORD 00 ; 18-19 Адрес в памяти с которого запустится код (Reg. PC) +.SP_REG WORD 00 ; 20-21 Адрес стека (Reg. SP) +.UnUsedPoint BYTE 0 ; 22 +; в .RESERVED2 нельзя прописать BLOCK 512-.UnUsedPoint,0; поэтому хардкод +.RESERVED2 BLOCK 512-23,0 ; 23-512 Можно использовать под текст для выпендрёжа или не использовать + ENDS +; + +;File Manipulator (FM) +;[ ] fat32 + STRUCT _sFM ; 51 bytes + ; from FAT +; .NAME: TEXT 8,{". "," "} ;+ #00 +00 NAME +; .EXT: TEXT 3,{" "," "} ;+ #08 +08 EXT +; .ATTRIBUT: BYTE #10 ;+ #0B +11 ATTRIBUT +; .RESERVED_NT: BYTE #00 ;+ #0C +12 RESERVED +; .RESERVED_FAT32: BYTE #00 ;+ #0D +13 RESERVED +; .CREATE_TIME_FAT32: WORD #0000 ;+ #0E +14 RESERVED +; .CREATE_DATE_FAT32: WORD #0000 ;+ #10 +16 RESERVED +; .RESERVED_FAT32_1: WORD #0000 ;+ #12 +18 RESERVED +; .FIRST_CLUSTER_H: WORD #0000 ;+ #14 +20 RESERVED +; .TIME: WORD #0000 ;+ #16 +22 TIME +; .DATE: WORD #0000 ;+ #18 +24 DATE +; .FIRST_CLUSTER_L: WORD #0000 ;+ #1A +26 START CLUSTER ; [ ] fat32 +; .F_SIZE: DWORD #00000000 ;+ #1C +28 SIZE FILE +.FS_REC FAT_DIRECTORY_RECORD + ; from Core +.F_POSITION DWORD #00000000 ;+ #20 +32 FILE POSITION (FP) +.DIR_CLUSTER_L WORD #0000 ;+ #24 +36 DIRECTORY CLUSTER LOW +.DIR_CLUSTER_H WORD #0000 ;+ #24 +38 DIRECTORY CLUSTER HIGH ; [x] fat32 +.HANDLE WORD #0000 ;+ #28 +40 HANDLE NUMBER +.DRIVE BYTE #00 ;+ #2A +42 DRIVE OR CURRENT +.ACCESS_MODE BYTE #00 ;+ #2B +43 ACCESS MODE +.TASK_NUM BYTE #00 ;+ #2C +44 TASK +.OptimizedClusters BYTE #00 ;+ #2D +45 +.KnownCluster_L WORD #0000 ;+ #2E +46 Младшее слово номера кластера для которого известно относительное смещение внутри файла +.KnownCluster_H WORD #0000 ;+ #30 +48 Старшее слово номера кластера для которого известно относительное смещение внутри файла +.KnownOffset_L WORD #0000 ;+ #32 +50 Младшее слово смещения (в кластерах) относительно начала файла для сохраненного номера кластера. +.KnownOffset_H WORD #0000 ;+ #34 +52 Старшее слово смещения (в кластерах) относительно начала файла для сохраненного номера кластера. + ENDS + +;ACCESS MODE: A=0 чтение/запись +; A=1 чтение +; A=2 запись +; ;!TODO A=3 запись без лишних сохранений кэша FAT +; ;!TODO A=4 записать кэш FAT +; + +; +; NAM EQU 0 ; LEN4 EQU 31 +; EXT EQU 8 ; POS1 EQU 32 +; ATR EQU 11 ; POS2 EQU 33 +; TIM1 EQU 22 ; POS3 EQU 34 +; TIM2 EQU 23 ; POS4 EQU 35 +; DAT1 EQU 24 ; DIRCLU1 EQU 36 +; DAT2 EQU 25 ; DIRCLU2 EQU 37 +; CLU1 EQU 26 ; HND1 EQU 38 +; CLU2 EQU 27 ; HND2 EQU 39 +; LEN1 EQU 28 ; FDRV EQU 40 +; LEN2 EQU 29 ; AMODE EQU 41 +; LEN3 EQU 30 ; FTASK EQU 42 + +; + STRUCT _sFatBuffer +.DRIVE: BYTE #FF +.FAT_TYPE: BYTE #00 ; TYPE FAT (12 - 12bit, 16 - 16bit, 32 - 32bit) ; fat32 +.CacheBlock: WORD #0000 +.CacheUpdated: BYTE #00 +;.SectorsPerBank: BYTE #00 +.RootDirStartCluster_L: WORD #0000 +.RootDirStartCluster_H: WORD #0000 ; fat32 +.FAT1_SEC_L: WORD #0000 ; MSD_FAT_SEC first sector FAT (FAT_FRM) +.FAT1_SEC_H: WORD #0000 ; fat32 +.FAT2_SEC_L: WORD #0000 +.FAT2_SEC_H: WORD #0000 ; fat32 +.Number_Of_FATs BYTE #02 +.SectorsPerFAT_L WORD #0000 +.SectorsPerFAT_H BYTE #00 +.RootDirFirstSector_L: WORD #0000 ; MSD_CAT_SEC first sector DIR +.RootDirFirstSector_H: WORD #0000 ; MSD_CAT_SEC first sector DIR +.DirSizeInSectors: BYTE #00 ; DIR_SEC_SIZE +.FirstDataSector_L: WORD #0000 ; MSD_DAT_SEC low +.FirstDataSector_H: WORD #0000 ; MSD_DAT_SEC high +.BytesPerCluster: WORD #0000 ; CLUSTER_LEN +.END_CHAIN_CLUSTER_L: WORD #FFFF +.END_CHAIN_CLUSTER_H: WORD #0FFF +.MaxClusterLow: WORD #0000 ; макс. число кластеров (без служ.) +.MaxClusterHigh: WORD #0000 ; макс. число кластеров (без служ.) +.BytesPerSector: WORD #0000 +.SectorsPerCluster: BYTE #00 +.FSINFO_Sector: WORD #01 +.BPB_SERIAL_NUMBER: DWORD #00000000 +.BPB_LABEL: BLOCK 11,' ' ; 11 для FAT, 31 для CDFS +.UPD_FSINFO: BYTE 0 +.FREE_CLUSTERS_COUNT_L: WORD #FFFF +.FREE_CLUSTERS_COUNT_H: WORD #FFFF +;.FilesPerSector: BYTE #00 ; число файловых записей в секторе +;.ClustersPerBank: BYTE #00 ; A - Clusters per bank (16k) (число кластеров на блок ОЗУ) +;.READ_PG: BYTE #00 ;!TODO не используются некоторые значения, но задумка неплохая))) +;.S_X_H: DWORD #0000 ; количество секторов на цилиндре + ENDS +; + +; + STRUCT _sBuffers +.FileManipulator _sFM ; 44 bytes + 44 bytes * (FMCOUNT-1) +.FM_RESERVE BLOCK _sFM * (FMCOUNT-1),0 ; +.FatBuffer _sFatBuffer +;.BootSector BLOCK 90,0 ; _sBOOT_SECTOR_PARAMS: 62 bytes FAT16, 90 bytes FAT32 +.EXE_Header _sEXE_HEADER ; 512 bytes +.Stack _sStack ; 256 bytes +.Buffer BLOCK 512,0 ; FOR BUFFER & SECTOR_BUFFER +.MemoryTable BLOCK 256,0 ; 256 bytes +.CurrentPath WORD 0 +.CurrentDirectory BLOCK DIRECTORY_PATH_LENGTH,0 +.WorkDirectory BLOCK DIRECTORY_PATH_LENGTH,0 + ENDS +; \ No newline at end of file diff --git a/Crazy Estex DSS/DSS/VERSION.INC b/Crazy Estex DSS/DSS/VERSION.INC new file mode 100644 index 0000000..984fa6c --- /dev/null +++ b/Crazy Estex DSS/DSS/VERSION.INC @@ -0,0 +1,56 @@ + IFNDEF INCREASE_BUILD + DEFINE INCREASE_BUILD 0 + ELSE + DEFINE+ INCREASE_BUILD 1 + ENDIF +;------------------[ Достаём текущую дату и BUILD++ ]-----------------[] + LUA PASS1 + dss_date, dss_month, dss_year = Get_date_RU(sj.get_define("__DATE__")) + + if sj.get_define("INCREASE_BUILD") > "0" then + dss_build = increase_build("./DSS/build.txt") + else + dss_build = get_build("./DSS/build.txt") + end + + if dss_build > 999 then + dss_build = 999 + print("WARNING! Build > 999","WARNING! Build > 999","WARNING! Build > 999","WARNING! Build > 999","\aWARNING! Build > 999\a") + end + ENDLUA + LUA ALLPASS + sj.insert_label("lua_DAY", dss_date) + sj.insert_label("lua_MONTH", dss_month) + sj.insert_label("lua_YEAR", dss_year) + sj.insert_label("lua_BUILD", dss_build) + ENDLUA +;---------------------------------------------------------------------[] + +; +; DSS full version +; номер версии (0..9) +VERS EQU 1 +; номер модификации (0..99) +MODF EQU 70 +; номер билда (0..999) +BUILD EQU lua_BUILD +; + + +; Release Types +RELEASE EQU 0 +RC EQU 1 +BETA EQU 2 +DP EQU 3 +; + +; Build Type +OSTYPE EQU BETA +REVISION EQU 1 +; + +; Current date +DAY EQU lua_DAY +MONTH EQU lua_MONTH +YEAR EQU lua_YEAR +; \ No newline at end of file diff --git a/Crazy Estex DSS/DSS/VIDEO.ASM b/Crazy Estex DSS/DSS/VIDEO.ASM new file mode 100644 index 0000000..9aa6285 --- /dev/null +++ b/Crazy Estex DSS/DSS/VIDEO.ASM @@ -0,0 +1,696 @@ + +;[BEGIN] +;//MODULE: VIDEO +;//CREATE: 19-05-1998 AUTHOR: Denis Parinov +;//UPDATE: 24-10-1999 DNS Restore module +;--------------------------------------------------------------- +;Rev Date Name Description +;--------------------------------------------------------------- +;R02 07-11-2002 DNS CORRECT FN. WINCOPY & WINREST, ADD "DI+EI" +;R01 07-11-2002 DNS FIX BUG WITH SCROLLUP FN. (A=0) +;--------------------------------------------------------------- + +;///////////////////////////////////////////////////////////////////// +; Функция #56. Очистить окно. +; +; вход: D - строка левого верхнего угла окна +; E - столбец левого верхнего угла окна +; H - высота окна +; L - ширина окна +; A - символ заполнитель +; B - атрибут заполнитель +; выход: нет +;///////////////////////////////////////////////////////////////////// +CLEAR: LD C,BIOS.LP_CLS_WIN2 + JP ToBIOS + ;AND A + ;RET +; +;///////////////////////////////////////////////////////////////////// +; Функция #5C. Вывод строки на экран. +; +; вход: HL - указатель на строку символов +; выход: HL - указатель на следующую строку символов +; PRINT NULL-TERMINATED CHARS STRING +;///////////////////////////////////////////////////////////////////// +PCHARS: LD A,(HL) + INC HL + OR A + RET Z + CALL PUTCHAR + JP PCHARS + +;///////////////////////////////////////////////////////////////////// +; Функция #5B. Вывод символа на экран в тек. позиции. +; +; вход: A - символ +; выход: нет +;///////////////////////////////////////////////////////////////////// +PUTCHAR: + ;CALL .NO_SCROLL + CP #0E + JR C,.control_characters + ; + LD BC,1*256 + BIOS.LP_PRINT_SYM + ;[x] CR+LF+SCROLL + RST ToBIOS + ; + ; проверка на переход курсора в самое начало (X:Y == 0:0) + CALL CURSOR + LD A,D + OR E + RET NZ + ; +.LFF: PUSH HL + LD BC,1*256 + BIOS.LP_SCROLL_UD + LD DE,#0020 + RST ToBIOS + LD DE,#1F00 + CALL LOCATE + LD A,' ' + LD BC,#50*256 + BIOS.LP_PRINT_SYM + RST ToBIOS + LD DE,#1F00 + CALL LOCATE + POP HL + RET +.TB_: CALL CURSOR + IF TABisSPACES + LD B,E + LD A,E + AND #F8 + ADD A,8 + SUB B + LD B,A + LD A,' ' + LD C,BIOS.LP_PRINT_SYM + JP ToBIOS + ELSE + LD A,E + ADD A,8 + AND #78 ;????? глянуть, что будет если координаты курсора в конце строки почти + LD E,A + JP LOCATE + ENDIF +.BK_: CALL CURSOR + XOR A + CP E + RET Z + DEC E + JP LOCATE + ; +.LF_: CALL CURSOR + LD A,D + CP #1F + JR NC,.LFF + INC D + IFN EnoughtOnly_LF + JP LOCATE + ELSE + CALL LOCATE + ; !!!! НЕ разрывать LF_ и CR_ !!!! + ENDIF +.CR_: CALL CURSOR + LD E,0 + JP LOCATE + ; +.control_characters: + CP #0D + JR Z,.CR_ + CP #0A + JR Z,.LF_ + CP #09 + JR Z,.TB_ + CP #08 + JR Z,.BK_ + CP #07 ; [x] Beep in PChars/PUTCHAR + RET NZ + ; [x] Beep in PChars/PUTCHAR +.BELL: LD DE,1200 + PUSH HL + LD HL,4 + CALL BEEP + POP HL + RET + ; +; [x] -bug with Vasil's version of cursor +.NO_SCROLL: + CP #0E + JR C,.control_characters +._CHAR: LD BC,1*256 + BIOS.LP_PRINT_SYM + JP ToBIOS + ; + +;-----[] +; +; + +;///////////////////////////////////////////////////////////////////// +; Функция #52. Установить положение курсора. +; +; вход: D - строка курсора +; E - колонка курсора +; выход: нет +;///////////////////////////////////////////////////////////////////// +LOCATE: LD C,BIOS.LP_SET_PLACE + JP ToBIOS + +;///////////////////////////////////////////////////////////////////// +; Функция #53. Узнать положение курсора. +; +; вход: нет +; выход: D - строка курсора +; E - колонка курсора +;///////////////////////////////////////////////////////////////////// +CURSOR: LD C,BIOS.LP_GET_PLACE + JP ToBIOS + +;///////////////////////////////////////////////////////////////////// +; Функция #57. Прочитать символ с экрана. +; +; вход: D - строка +; E - колонка +; выход: A - символ +; B - атрибут +;///////////////////////////////////////////////////////////////////// +RDCHAR: XOR A + LD C,BIOS.WIN_GET_SYM + RST ToBIOS + LD A,L + LD B,H + ;AND A + RET + +;///////////////////////////////////////////////////////////////////// +; Функция #58. Вывести символ на экран. +; Управляющие символы выводятся как обычные символы. +; +; вход: D - строка +; E - колонка +; A - символ +; B - атрибут +; выход: нет +;!FIXIT slow как без WIN_GET_SYM тут обойтись? +;///////////////////////////////////////////////////////////////////// +WRCHAR: LD C,A + PUSH BC + PUSH DE + XOR A + LD C,BIOS.WIN_GET_SYM + RST ToBIOS + POP DE + POP HL + XOR A + LD C,BIOS.WIN_PUT_SYM + JP ToBIOS + ;AND A + ;RET + +;///////////////////////////////////////////////////////////////////// +; Функция #59. Сохранить окно экрана. +; +; вход: D - строка +; E - колонка левого верхнего угла окна +; H - высота окна +; L - ширина окна +; B - страница буфера, если IX >= #C000 +; IX - адрес буфера +; выход: нет +;///////////////////////////////////////////////////////////////////// +WINCOPY: AND A + LD A,R ;R02 + PUSH AF ;R02 + XOR A + LD C,BIOS.WIN_COPY + DI ;R02 + RST ToBIOS + POP AF ;R02 + RET PO ;R02 + EI ;R02 + RET + +;///////////////////////////////////////////////////////////////////// +; Функция #5A. Восстановить окно экрана. +; +; вход: D - строка +; E - колонка левого верхнего угла окна +; H - высота окна +; L - ширина окна +; B - страница буфера, если IX >= #C000 +; IX - адрес буфера +; выход: нет +;///////////////////////////////////////////////////////////////////// +WINREST: AND A + LD A,R ;R02 + PUSH AF ;R02 + XOR A + DI ;R02 + LD C,BIOS.WIN_RESTORE + RST ToBIOS + POP AF ;R02 + RET PO ;R02 + EI ;R02 + RET +;///////////////////////////////////////////////////////////////////// +; Функция #55. Скроллинг экрана. +; +; вход: D - строка левого верхнего угла окна +; E - колонка левого верхнего угла окна +; H - высота окна +; L - ширина окна +; B = 1 - прокрутка вверх +; B = 2 - прокрутка вниз +; A = 0 - очищать строку +; выход: нет +;///////////////////////////////////////////////////////////////////// +SCROLL: DJNZ .SCR_DW ;!TODO заменить на BIOS.LP_SCROLL_UD и посмотреть, что шустрее + ;[x] 04/04/23 + ;LD B,A + ;LD C,H + ;PUSH BC + PUSH AF + ; + PUSH DE + PUSH HL + LD XH,D + LD XL,E + INC D + DEC H + LD C,BIOS.WIN_MOVE + ;[x] 29/9/23 + LD A,R + PUSH AF + ; + XOR A + DI ;[x] 29/9/23 + RST ToBIOS + ;[x] 29/9/23 + POP AF + JP PO,.skip_EI + EI +.skip_EI: + POP HL + POP DE + ;[x] 04/04/23 + ;POP BC + POP AF + ;XOR A + ;CP B + AND A + ; + RET NZ + LD A,D + ADD A,H + DEC A ;R01 + LD D,A +.print: PUSH DE ;R01 + CALL LOCATE + LD A,' ' + LD B,L + LD C,BIOS.LP_PRINT_SYM + RST ToBIOS + POP DE ;R01 + JP LOCATE ;R01 + ;AND A + ;RET +.SCR_DW: + DJNZ .SCR_ERR + ;[x] 04/04/23 + ;LD B,A + ;LD C,H + ;PUSH BC + PUSH AF + ; + PUSH DE + PUSH HL + LD XH,D + LD XL,E + INC XH + DEC H + LD C,BIOS.WIN_MOVE + ;[x] 29/9/23 + LD A,R + PUSH AF + ; + XOR A + DI ;[x] 29/9/23 + RST ToBIOS + ; [x] 29/9/23 + POP AF + JP PO,.skip2_EI: + EI +.skip2_EI: + POP HL + POP DE + ;[x] 29/9/23 + ;POP BC + POP AF + ;XOR A + ;CP B + AND A + ; + RET NZ + JP SCROLL.print +.SCR_ERR: + LD A,DSS_Error.sys.INVALID_FUNCTION + SCF + RET + +;///////////////////////////////////////////////////////////////////// +; Функция #54. Выбрать активную страницу экрана. +; +; вход: B - страница экрана 0/1 +; выход: A - код ошибки, если CF=1 +;///////////////////////////////////////////////////////////////////// +SELPAGE: + LD A,(VMODE) + ;BIT 7,A + CP %1000'0000 + JR NC,.SEL2 + PUSH BC + LD C,A + CALL SETVMOD.TEXT_M + POP BC +.SEL2: LD A,B + AND #01 + OUT (SCREEN_SWITCH),A + RET + +;///////////////////////////////////////////////////////////////////// +; Функция #51. Получить текущий режим экрана. +; +; вход: нет +; выход: A - текущий режим экрана +; B - страница экрана 0/1 +;///////////////////////////////////////////////////////////////////// +GETVMOD: + IN A,(SCREEN_SWITCH) + LD B,A + LD A,(VMODE) + AND A + RET + +;///////////////////////////////////////////////////////////////////// +; Функция #50. Выбор режима экрана. +; +; вход: A - режим экрана +; #02 - текстовый 40x32x16 цветов +; #03 - текстовый 80x32x16 цветов +; #81 - графический 320x256x256 цветов +; #82 - графический 640x256x16 цветов +; B - страница экрана 0/1 +; выход: A - код ошибки, если CF=1 +;///////////////////////////////////////////////////////////////////// +SETVMOD:; + CP %1000'0000 + LD C,A + JR NC,GRAPH +.TEXT_M: LD IX,BACKTXT + PUSH IX + EX AF,AF' + LD A,(VMODE) + LD (BACKTXT.VMODE),A + EX AF,AF' + OR A + JR Z,.NOMODE + DEC A + JR Z,.NOMODE + DEC A + LD HL,TAB_40x32 + JR Z,T_40_32 + DEC A + LD HL,TAB_80x32 + JR Z,T_80_32 +.NOMODE: POP IX + LD A,DSS_Error.sys.INVALID_VIDEO_MODE + SCF + RET + +; Установка граф. режимов +GRAPH: CALL SAVETXT + AND #7F + JR Z,G320_16 ; !TODO ? - пока отрабатывает как ошибка + DEC A + JR Z,G320_56 + DEC A + JR Z,G640_16 +; DEC A +; JP Z,G640_56 ; !TODO ? - пока отрабатывает как ошибка +G320_16: LD A,DSS_Error.sys.INVALID_VIDEO_MODE + SCF + RET + +T_80_32: +T_40_32: PUSH BC +; LD HL,TAB2 + LD A,B + RLCA + RLCA + RLCA + RLCA + OR B + AND #11 + XOR #10 + LD E,A +GRAPH_NEXT: + CALL SETMODE + POP BC + LD A,C + LD (VMODE),A + LD A,B + AND #01 + OUT (SCREEN_SWITCH),A + LD A,(VMODE) + LD C,Dss.Mouse.SetVideoMode + RST ToDSS.Mouse + SAFE_PORTY + XOR A + RET + +; T_80_32 PUSH BC +; LD HL,TAB1 +; LD A,B +; RLCA +; RLCA +; RLCA +; RLCA +; OR B +; AND #11 +; XOR #10 +; LD E,A +; CALL SETMODE +; POP BC +; LD A,C +; LD (VMODE),A +; LD A,B +; AND #01 +; OUT (SCREEN_SWITCH),A +; LD A,(VMODE) +; LD C,#81 +; RST #30 +; SAFE_PORTY +; XOR A +; RET + +G320_56 PUSH BC + LD HL,TAB_320x256_0 + LD E,#11 + CALL SETMODE + LD HL,TAB_320x256_1 + LD E,#00 + JP GRAPH_NEXT + ; CALL SETMODE + ; POP BC + ; LD A,C + ; LD (VMODE),A + ; LD A,B + ; AND #01 + ; OUT (SCREEN_SWITCH),A + ; LD A,(VMODE) + ; LD C,#81 + ; RST #30 + ; SAFE_PORTY + ; XOR A + ; RET + +G640_16 PUSH BC + LD HL,TAB_640x256_0 + LD E,#11 + CALL SETMODE + LD HL,TAB_640x256_1 + LD E,#00 + JP GRAPH_NEXT + + ; CALL SETMODE + ; POP BC + ; LD A,C + ; LD (VMODE),A + ; LD A,B + ; AND #01 + ; OUT (SCREEN_SWITCH),A + ; LD A,(VMODE) + ; LD C,#81 + ; RST #30 + ; SAFE_PORTY + ; XOR A + ; RET +VMODE: DB #03 + +;----------------------------------------------------------------------- +; Открыть окно +; вход: hl=описатель окна +; e=флаги окна +; +;02h - TEXT 40 x 32 (16 colors) +;03h - TEXT 80 x 32 (16 colors) +;80h - GRAF 320 x 256 (16 colors) +;81h - GRAF 320 x 256 (256 colors) +;82h - GRAF 640 x 256 (16 colors) +;83h - GRAF 640 x 256 (256 colors) UNUSED +;----------------------------------------------------------------------- +SETMODE: PUSH DE + LD DE,SYS_PAGE.SHARED_BUFFER_32b ; грязный хак. кидает данные в буфер служебной страницы биоса. + LD BC,ScreenDescriptorTable.Size ; БИОС при использовании IX предполагает, что он указывает + IN A,(SLOT3) ; на адрес ниже #C000 и вставляет в третью банку страницу #FE + EX AF,AF' + LD A,SYS_PAGE + OUT (SLOT3),A + LDIR + EX AF,AF' + OUT (SLOT3),A +.skip_EI: POP DE + LD IX,SYS_PAGE.SHARED_BUFFER_32b ; грязный хак. + LD C,BIOS.WIN_OPEN + RST ToBIOS + SAFE_PORTY + XOR A + RET + +;IX+0 ;HORIZONTAL +;IX+1 ;VERTICAL +;IX+2 ;X - COORD +;IX+3 ;Y - COORD +;IX+4 ;MODE +;IX+5 ;EXT MODE +;IX+6 ;VIDEO RAM X OFFSET (SIGNPLACES) +;IX+7 ;VIDEO RAM Y OFFSET (SIGNPLACES) + +; +;....................................................................... +;+0 X размер окна в знакоместах +;+1 Y размер окна в знакоместах +;+2 X полож. окна на экране +;+3 Y полож. окна на экране +;+4 режим знакоместа +;+5 доп. режим знакоместа (bit0=1 спек. адресация экрана) +;+6 X полож. в поле графики (в знакоместах) +;+7 Y полож. в поле графики (в знакоместах) +ScreenDescriptorTable EQU $ +; 80x32. текстовое, знакоместо 16x8, #0B - номер знакоген. +TAB_80x32 DB #28,#20,#00,#00,#1B,#00,#00,#00 ;1 +; 40x32. текстовое, знакоместо 8x8, #0B - номер знакоген. +TAB_40x32 DB #28,#20,#00,#00,#3B,#00,#00,#00 ;2 +; 640x256. графическое, 0-й экран +TAB_640x256_0 DB #28,#20,#00,#00,#00,#00,#00,#00 ;3 +; 320x256. графическое, 0-й экран +TAB_320x256_0 DB #28,#20,#00,#00,#20,#00,#00,#00 ;4 +; 640x256. графическое, 1-й экран +TAB_640x256_1 DB #28,#20,#00,#00,#40,#00,#28,#00 ;5 +; 320x256. графическое, 1-й экран +TAB_320x256_1 DB #28,#20,#00,#00,#60,#00,#28,#00 ;6 +ScreenDescriptorTable.Size EQU ($ - ScreenDescriptorTable)/6 +;....................................................................... +; + +;---------------------------------------------------------------------- +; Сохранить экран текст. режима. +; Для буфера экрана исп. 2-я банка расширения ДОС. +SAVETXT: PUSH AF + LD A,(VMODE) + ;BIT 7,A + CP %1000'0000 + JR NC,.NOSAVET + SUB #02 + JR C,.NOSAVET + ; + PUSH BC + PUSH DE + PUSH HL + PUSH IX + ; + PUSH AF + LD C,BIOS.LP_GET_PLACE + RST ToBIOS + LD (BACKTXT.CURS),DE + POP AF + LD IX,#C000 + LD HL,#2050 + OR A + JR NZ,.SVTEXT1 + LD L,#28 +.SVTEXT1: LD (BACKTXT.WinMax),HL + LD DE,#0000 + LD A,(BANKTBL+TXTPAGE) + LD B,A + + LD C,BIOS.WIN_COPY + ;[x] 29/9/23 + LD A,R + PUSH AF + ; + XOR A + DI + RST ToBIOS + ;[x] 29/9/23 + POP AF + JP PO,.skip_EI + EI +.skip_EI: ; + POP IX + POP HL + POP DE + POP BC +.NOSAVET: POP AF + RET +;---------------------------------------------------------------------- + +BACKTXT: PUSH AF +.VMODE+1: LD A,#00 + ;BIT 7,A + CP %1000'0000 + JR C,NOBACKT + ; + PUSH BC + PUSH DE + PUSH HL + PUSH IX + LD IX,#C000 +.WinMax+1: LD HL,#2050 + LD DE,#0000 + LD A,(BANKTBL+TXTPAGE) + LD B,A + LD C,BIOS.WIN_RESTORE + ;[x] 29/9/23 + LD A,R + PUSH AF + ; + XOR A + DI + RST ToBIOS + ;[x] 29/9/23 + POP AF + JP PO,.no_ei + EI +.no_ei: ; +.CURS+1: LD DE,#0000 + CALL LOCATE + POP IX + POP HL + POP DE + POP BC +NOBACKT: POP AF + RET +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +;//MODULE: VIDEO +;[END] \ No newline at end of file diff --git a/Crazy Estex DSS/DSS/build.txt b/Crazy Estex DSS/DSS/build.txt new file mode 100644 index 0000000..7ccfcb1 --- /dev/null +++ b/Crazy Estex DSS/DSS/build.txt @@ -0,0 +1 @@ +997 \ No newline at end of file diff --git a/Crazy Estex DSS/DSS/defines.inc b/Crazy Estex DSS/DSS/defines.inc new file mode 100644 index 0000000..f53305f --- /dev/null +++ b/Crazy Estex DSS/DSS/defines.inc @@ -0,0 +1,163 @@ +; + DEFINE TEST_FEATURE 0 +; + +; + DEFINE MINIMUM_EXE_VERSION 1 +; + +; + DEFINE SHORT_RSTx10_TABLE 0 ; укороченная таблица функций rst #10. 96 функций. + DEFINE COMPILE_UNUSED_CODE 0 +; + +; MOUSE + DEFINE MOUSE_COM_BAUD 0 ; 1 - 2485, 2 - 4807, else - 1215 (default) + DEFINE MOUSE_INT_ENABLED 0 ; INT from SIO ch. B + DEFINE MOUSE_READ_PORT_TIMEOUT 5*512 ; Костыльный тайм-аут на ожидание байта от мышки. Если = 0, то лишний код не компилится + +; KEYBOARD + DEFINE KEYBOARD_INT_ENABLED 0 ; INT from SIO ch. A + DEFINE CHANGE_LANG_CTRL_SHIFT 1 ; [x] 0: Ctrl + Space, 1: Ctrl + Shift. + DEFINE BREAK_PROCESS_CODE #AC00 ; CTRL+C + DEFINE USE_E1_SCANCODE 0 + DEFINE CLASSIC_CURSOR 0 +; + +;LD_DSK EQU 16 ; максимальное количество логических HDD дисков в системе + +///////////////////////////////////////////////////////////////////////////////////////////////////////////// + DEFINE CHANGE_FREE_CLU_AFTER_DEL 1 + DEFINE FAST_FAT_CASHE 1 + +SERVICE_SECTORS: +.FAT12 EQU #0FEF +.FAT16 EQU #FFEF +.FAT32.High EQU #0FFF +.FAT32.Low EQU #FFEF + +FAT_TYPE: +.x32 EQU #32 +.x16 EQU #16 +.x12 EQU #12 + +; define _bit (1&2 +#exec "/Applications/CrossOver.app/Contents/SharedSupport/CrossOver/bin/wine" --bottle "ZXMAK2" --wait-children --check --start "C:/users/crossover/AppData/Roaming/Microsoft/Windows/Start Menu/ZXMAK2.lnk" +exit +else +echo "\nError!!!" >&2 +fi +#sp_disk="$(hdiutil attach -imagekey diskimage-class=CRawDiskImage /Users/tolik/Library/Application\ Support/CrossOver/Bottles/ZXMAK2/drive_c/ZXMAK2/HDD/sp_disk1.vhd | grep -m 1 -o ^'/dev/disk[[:digit:]]\+')" +#sp_disk="$(hdiutil attach -imagekey diskimage-class=CRawDiskImage /Users/tolik/Library/Application\ Support/CrossOver/Bottles/ZXMAK2/drive_c/sp_disk2.img | grep -m 1 -o ^'/dev/disk[[:digit:]]\+')" +#floptool identify dss_1_62_100.hfe +#qemu-img convert -f raw -O vpc test.img test.vhd +#/Users/tolik/Library/Application\ Support/CrossOver/Bottles/ZXMAK2/drive_c/test_2g.img +#sp_disk="$(hdiutil attach -imagekey diskimage-class=CRawDiskImage /Users/tolik/Library/Application\ Support/CrossOver/Bottles/ZXMAK2/drive_c/ZXMAK2/HDD/HDD256.vhd | grep -m 1 -o ^'/dev/disk[[:digit:]]\+')" +# ls -A -F -G +# rm -r .fseventsd \ No newline at end of file diff --git a/Crazy Estex DSS/SHELL/BATCH.ASM b/Crazy Estex DSS/SHELL/BATCH.ASM new file mode 100644 index 0000000..a33e30c --- /dev/null +++ b/Crazy Estex DSS/SHELL/BATCH.ASM @@ -0,0 +1,546 @@ +; Обработка BAT-файлов +; + +;fhandle +BAT_FM: db 0 ; дескр. bat-файла +;count: db 0 ; число прочит. байт из файла + +; флаг echo-режима +echo_mode: + db true ; 1/0 on/off + +; буфер bat-файла +;T98B9: ds 256 + + + ; IF 0 + ; CALL RUN_BAT + ; CALL BATCH + ; CALL MAKE_BATCH_PRM_ARRAY + ; CALL NEWLINE + ; CALL CMDMODE + ; CALL EVALCMD + ; CALL RUN_BAT + ; ENDIF + +;------------------------------------------------- +; Запуск bat-файла +; вход: hl=имя файла +;------------------------------------------------- +RUN_BAT: + call BATCH + jp c,EXEERR ; ошибка откр. файла (cpp.asm) + ret +;------------------------------------------------- + +; вход: b=число слов "ZERO".."NINE" +MAKE_BATCH_PRM_ARRAY: + dec hl +.loop: inc hl + ld a,(hl) + or a + ret z + cp " " + jr z,.loop + cp 9 ; Tab + jr z,.loop + ex de,hl + ld (hl),e + inc hl + ld (hl),d + inc hl + ex de,hl +.B_FIND_SPACE: + inc hl + ld a,(hl) + cp " "+1 + jr nc,.B_FIND_SPACE + ld (hl),0 + or a + ret z + djnz .loop + ret + + +;------------------------------------------------- +; Загрузка и выполнение BAT-файла +; вход: hl=имя файла +; выход: "CF" - ошибка откр. файла +;------------------------------------------------- +BATCH: + ; [x] 11/12/23 вложенные bat + ld a,(BAT_FM) + or a + jr nz,.new_process + ; + + push hl ; сохр. имя bat-файла + ld de,Buffers.work.buffer ; 512 местный буфер + call copy_string ; скопир. строку (с нулем) + ld hl,Buffers.work.buffer ; 512 местный буфер + ld de,BAT_PRM_ARRAY ; таблица указат. на "ZERO".."NINE" + ld b,BAT_PRM_ARRAY.TOTAL ; число слов "ZERO".."NINE" + call MAKE_BATCH_PRM_ARRAY + jr nz,.B_ALL_P + ld hl,NULL ; ds 2*10 + ex de,hl +.B_CLR_P: + ld (hl),e + inc hl + ld (hl),d + inc hl + djnz .B_CLR_P + ex de,hl +.B_ALL_P:;- + pop hl ; восст. имя bat-файла + + ld a,Dss.Open.R ; на чтение + ld c,Dss.Open ; открыть файл + RST ToDSS + ;push af ; сохр. код ошибки + ;call c,restore_disk_path ; восст. тек. диск и путь + ;R10 + ;CALL Restore_Screen + ;R10 + ;pop af + JR NC,.good + CP DSS_Error.sys.TOO_MANY_FILES_IN_DIR + SCF + RET NZ + LD A,DSS_Error.sys.FILE_NOT_FOUND + RET + ; +.good: ld (BAT_FM),a ; дескр. bat-файла + ; выполн. команд bat-файла + call NEWLINE + ;!TODO вложенные bat. передавать ошибку обратно в вызывающий bat + ;R10 + push af + CALL Restore_Screen + pop af + ;R10 + xor a ;!FIXIT + ret + ; [x] 11/12/23 вложенные bat +.new_process: + ld de,Buffers.work.buffer2 + call copy_string + ; + ld hl,.shell + ld de,Buffers.input_line.Path + call copy_string + ; + ld hl,Buffers.work.buffer2 + ld de,Buffers.input_line.Path + .shell.size - 1 + call copy_string + ; + ld hl,Buffers.input_line.Path + ld bc,Dss.Exec + RST ToDSS + ;!TODO вложенные bat. передавать ошибку обратно в вызывающий bat + xor a + ret + ; + ;rst ToDSS + ; + ; ret nc + ; CP DSS_Error.sys.FILE_NOT_FOUND + ; ret nz + + ; jp z,A83DD ; ошибка откр. файла (cpp.asm) + ; ret + +;.shell: DB '?:\SYSTEM.EXE /C ',0 + +.shell: DB 'SYSTEM.EXE /C ',0 +.shell.size EQU $ - .shell + +;!TODO + ; .ErrorEnv: DB 'ERRORLEVEL=' + ; .ErrorEnv.Code: DB 'xxx',0 + ; .ErrorEnv.Size EQU $ - .ErrorEnv +; + +;--------------------------------------------------- +; Выполнение команд BAT-файла +;--------------------------------------------------- +NEWLINE: + LD (cmd_break.sp),SP ; [x] 11/12/23 cmd_break + ; + ld de,Buffers.input_line.Path +.ADDBAT: push de + call READBAT ; прочитать 128 байт из файла в "Buffers.work.buffer1" + pop de + ;!TODO доделать тут нормальную проверку на облом с чтением файла, выводить ошибку + jp c,cmd_break.exit + or a ; a=число прочит. байт + jr nz,.BATLINE + ; + ex de,hl + ld de,Buffers.input_line.Path + sbc hl,de + jp z,cmd_break.exit; ;[x] убран баг с незакрытым BAT-файлом + ld a,l + ld (Buffers.input_line.Symbols_Num),a ; длина строки + call CMDMODE ; тест на bat-команды + ; ^^^^^^^ + ;!TODO вложенные bat. передавать ошибку обратно в вызывающий bat + JP cmd_break.exit +; .exit: ld a,(BAT_FM) ; дескр. bat-файла +; ld c,Dss.Close ; закрыть файл +; ;!TODO вложенные bat. передавать ошибку обратно в вызывающий bat +; RST ToDSS +; xor a +; ld (BAT_FM),a +; ret + ; +.BATLINE: + ld hl,Buffers.work.buffer1 +.loop: call MOVWORD ; скопир. Buffers.work.buffer1 -> Buffers.input_line.Path + jr c,.ADDBAT + ld a,b + ld (MOVWORD.count),a ; осталось пропарсить прочитанных байтов + push hl + ex de,hl + ld de,Buffers.input_line.Path + sbc hl,de + ld a,l + ld (Buffers.input_line.Symbols_Num),a ; длина строки + call CMDMODE ; тест на bat-команды + ; ^^^^^^^ + ;!TODO вложенные bat. передавать ошибку обратно в вызывающий bat + ld de,Buffers.input_line.Path + pop hl + jr .loop + + +;------------------------------------------------- +; Чтение данных (hl) -> (de), при необходимости +; подкачка из файла. +; +; вход: hl=откуда +; de=куда +;------------------------------------------------- +MOVWORD: +.count+1: ld a,0 ; число прочит. байт из файла + ; [x] 15/12/23 exit if 0 + OR A + SCF + RET Z + ; + ld b,a +.loop: ld a,(hl) + ld (de),a + cp " " + jr c,.loop_ + inc hl + inc de + djnz .loop + scf + ret + ; прочитать доп. блок из файла +.loop2: ld a,(hl) + cp " " + ret nc +.loop_: inc hl + djnz .loop2 + push de + call READBAT ; прочитать 128 байт из файла + pop de + ;!TODO доделать тут нормальную проверку на облом с чтением файла, выводить ошибку + RET C + ;ld hl,BATBUFF ; 128 буфер (ccp.asm) "work_buffer1" + ld hl,Buffers.work.buffer1 + ld b,a ; число прочит. байт + or a + jr nz,.loop2 + scf + ret + +; прочитать 128 байт из файла +READBAT: + ld hl,Buffers.work.buffer1 + ld de,128 ; сколько + ld a,(BAT_FM) ; дескр. bat-файла + ld c,Dss.Read ; чтение файла + RST ToDSS + ld a,e + ; [x] 28/09/23 + JR NC,1F + ;!TODO доделать тут нормальную проверку на облом с чтением файла, сохранять ошибку + LD A,0 ; сохраняем флаг CF + ; +1: ld (MOVWORD.count),a ; число прочит. байт из файла + ret + + +; Тест на bat-команды +; должен соблюдаться баланс стека для cmd_break +CMDMODE: + ;xor a + ;ld (D96A6),a ; (inline.asm) + call EVALCMD ; (batch.asm) + ;ld ix,T96AC ; нужно?? закоментарил (inline.asm) + ;ld hl,T96AE ;;256 буфер (inline.asm) + ld hl,Buffers.input_line.Path + ld a,(hl) + cp "@" ; 40h + jr nz,.A8240 + dec hl + ;ld hl,Buffers.input_line.Symbols_Num;; + dec (hl) + jr z,.A825B + ld c,(hl) ; длина строки + inc hl + ld b,0 + ;ld hl,Buffers.work.buffer+256;; + ld d,h + ld e,l + inc hl + ldir + jr .A825B + ; +.A8240: ld a,(echo_mode) ; флаг echo-режима + or a + jr z,.A825B ; off + ; вывести сист. путь и строку содержимого bat-файла + ;ld de,T96AE ;;256 буфер (inline.asm) + ;ld de,Buffers.input_line.Path + ;call A95DE ; вывод экран. пути с ">" (inline.asm) + ; вывести экран. путь и введ. команду + ld c,BIOS.LP_GET_PLACE ; узнать полож. курсора + RST ToBIOS + ld (YXpos),de ; Y/X начало ком-строки + ld (cursor_position),de ; Y/X позиция курсора + call print_compath ; вывести путь + новая ширина поля ввода + ld de,(YXpos) ; Y/X начало ком-строки + ld c,Dss.Locate ; уст. полож. курсора + RST ToDSS + ;ld hl,Buffers.work.buffer+256;; + ld hl,Buffers.input_line.Symbols_Num ; длина строки + ld a,(hl) + ld b,a + inc hl ;+5 + push bc + ld c,BIOS.LP_PRINT_LINE2 ; вывод строки без атрибутов + RST ToBIOS + pop bc ; b=длина строки + ld a,(width_inpline) ; ширина поля ввода (76..48) + sub b + ;ei + ret z ; правый край экрана + jr c,.A8250; ; строка больше ширины экрана + ; заполнить строку до конца экрана + dec a ; чтобы не сработал скроллинг экрана ;!FIXIT scroll + ld b,a ; число вывод. символов + ld a," " ; символ + ld c,BIOS.LP_PRINT_SYM ; вывод символа без атрибута + RST ToBIOS + ;ei + ;!TEST +.A8250: call newline + ; + ; + ;ld a,(D96AD) ;; длина строки (inline.asm) + ;ld a,(Buffers.input_line.Symbols_Num);- + ;or a + ;ret z + ;call newline + ;jr A8264 + ; +.A825B: ;ld a,(D96AD) ;; длина строки (inline.asm) + ld a,(Buffers.input_line.Symbols_Num) + or a + ret z +;A8264: ld hl,T96AE ;;256 буфер (inline.asm) + ;ld hl,Buffers.input_line.Path + ;dec hl + ; убрать концевые пробелы строки + ld hl,Buffers.input_line.Symbols_Num + ld c,(hl) ; hl=длина строки (inline.asm) + ld b,0 + inc hl + ;ld hl,Buffers.work.buffer+256;; +.A826C: ld a,(hl) + cp " " + jr nz,.A8276 + inc hl + dec c + jr nz,.A826C + ret + ; +.A8276: ld d,h + ld e,l + add hl,bc + ld (hl),b ; 0 в конец строки (первого конц. пробела) + sbc hl,bc + ld a,c + ex af,af' + ld a," " + cpir + jr nz,.A8286 + inc c +.A8286: ex af,af' + sub c + ld c,a ; длина слова или строки ? + ld hl,BATLIST ; команды bat + dos-команды + ; + ; de=Buffers.input_line.Path, c=длина строки (без конц. пробелов) + ; выполн. команду или запустить файл + jp COMP.start + +; должна убрать конц. пробелы и уст. длину строки, если урезалась +EVALCMD: xor a + ld hl,Buffers.input_line.Symbols_Num ;!HARDCODE + ld c,(hl) + ld b,a + inc hl + add hl,bc + ld (hl),a ; 0 в конец строки + sbc hl,bc + ld de,Buffers.work.buffer2 ; 256 буфер + call EVALSTR + ld hl,Buffers.work.buffer2 ;work_buffer+256 + ld de,Buffers.input_line.Path ; куда + ld bc,255 ;!HARDCODE +.loop: ld a,(hl) + ldi + inc b + or a + jr nz,.loop + dec b + ld a,b + ld (Buffers.input_line.Symbols_Num),a ; длина строки (edline.asm) + and a + ret + +; HL - STRING WITH %VAR% +EVALSTR: ld a,(hl) + cp "%" + jr z,.TVARIABLE +.VARL1: ldi + or a + jr nz,EVALSTR + ; A=0 + ld b,a + ld c,a + ld (.TVAR_PNT),bc + ret + ; +.TVARIABLE: +.TVAR_PNT+1: ld bc,0 + ld a,b + or c + ld a,"%" + ld (.TVAR_PNT),de + jr nz,.TVAR1 + inc hl + ld a,(hl) ;!FIXIT я в console.asm исправлял баг с параметром %A например. Тут мои правки или Василя? + cp "9"+1 + jr c,.TVAR0 +.TVAR2: ld a,"%" ; > "9" + dec hl + jp .VARL1 +.TVAR0: cp "0" + jr c,.TVAR2 ; < "0" + ; BATCH PARAM %0, %1, %2 ... + inc hl + push hl + ld (.TVAR_PNT),bc + sub "0" + add a,a + ld c,a + ld hl,BAT_PRM_ARRAY ; таблица указат. на "ZERO".."NINE" + add hl,bc + ld a,(hl) + inc hl + ld h,(hl) + ld l,a + or h + jr z,.NOBTP ; NO BATCH PARM + call copy_string ; скопир. строку (с нулем) + dec de +.NOBTP: pop hl + jp EVALSTR + ; +.TVAR1: push hl + ld h,d + ld l,e + dec hl + and a + sbc hl,bc + jr z,.TNOVAR + ld a,"=" + ld (de),a + inc de + xor a + ld (de),a + ld d,b ; de=буфер значения перем. + ld e,c + ld h,b ; hl=имя перем. + ld l,c + inc hl + ld bc,Dss.Environ.Get ; получить перем. окружения + RST ToDSS +.TNOVAR: pop hl + inc hl + ld bc,0 + ld (.TVAR_PNT),bc + jp EVALSTR + + + +; !! Не делать одну команду > 256 символов)) !! +; + ; BAT-команды (не отделять от дос-команд) +BATLIST: DZ 'PAUSE' : DW cmd_pause + DZ 'REM' : DW cmd_rem + DZ 'EXIT' : DW cmd_break + ; + ; DSS-команды +CMDLIST: DZ 'CD' : DW cmd_chdir + DZ 'DIR' : DW cmd_dir + DZ 'ECHO' : DW cmd_echo + DZ 'ECHO.' : DW cmd_echoLN + DZ 'PATH' : DW cmd_path + DZ 'MD' : DW cmd_mkdir + DZ 'REN' : DW cmd_rename + DZ 'DEL' : DW cmd_del + DZ 'RD' : DW cmd_rmdir + DZ 'INFO' : DW cmd_info + DZ 'SET' : DW cmd_set + DZ 'TIME' : DW cmd_time + DZ 'DATE' : DW cmd_date + DZ 'VER' : DW cmd_version + DZ 'CLS' : DW cmd_cls + DZ 'CHDIR' : DW cmd_chdir + DZ 'MKDIR' : DW cmd_mkdir + DZ 'RENAME' : DW cmd_rename + DZ 'ERASE' : DW cmd_del + DZ 'RMDIR' : DW cmd_rmdir + DZ 'HELP' : DW cmd_help + DZ 'VERSION' : DW cmd_version + DZ 'EXIT' : DW cmd_exit + DZ 'REBOOT' : DW cmd_reboot + DB #00 + + +IZERO DB "ZERO",0 +IONE DB "ONE",0 +ITWO DB "TWO",0 +ITHREE DB "THREE",0 +IFOUR DB "FOUR",0 +IFIVE DB "FIVE",0 +ISIX DB "SIX",0 +ISEVEN DB "SEVEN",0 +IEIGHT DB "EIGHT",0 +ININE DB "NINE",0 + +BAT_PRM_ARRAY: + DW IZERO, IONE, ITWO, ITHREE, IFOUR, IFIVE, ISIX, ISEVEN, IEIGHT, ININE + DW 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ; 10 число слов "ZERO".."NINE" +.TOTAL EQU ($-BAT_PRM_ARRAY)/4 + DISPLAY "First compilation test: 10 = ",/D, BAT_PRM_ARRAY.TOTAL + ASSERT BAT_PRM_ARRAY.TOTAL = 10, "BAT_PRM_ARRAY.TOTAL" +NULL: DB 0 +;TVAR_PNT: DW 0 diff --git a/Crazy Estex DSS/SHELL/Commands/BREAK.ASM b/Crazy Estex DSS/SHELL/Commands/BREAK.ASM new file mode 100644 index 0000000..55e7b69 --- /dev/null +++ b/Crazy Estex DSS/SHELL/Commands/BREAK.ASM @@ -0,0 +1,11 @@ +; [x] 11/12/23 +cmd_break: +.sp+1: LD SP,0 + ;!TODO вложенные bat. передавать ошибку обратно в вызывающий bat +.exit: ld a,(BAT_FM) ; дескр. bat-файла + ld c,Dss.Close ; закрыть файл + RST ToDSS + xor a + ld (BAT_FM),a + ;!TODO вложенные bat. передавать ошибку обратно в вызывающий bat + ret \ No newline at end of file diff --git a/Crazy Estex DSS/SHELL/Commands/CHDIR.ASM b/Crazy Estex DSS/SHELL/Commands/CHDIR.ASM new file mode 100644 index 0000000..20f168c --- /dev/null +++ b/Crazy Estex DSS/SHELL/Commands/CHDIR.ASM @@ -0,0 +1,35 @@ +;/////////////////////////////////////////////////// +; +; CD, CHDIR. Смена каталога +; +;/////////////////////////////////////////////////// +cmd_chdir: + ex de,hl + ld de,Buffers.work.buffer1; + ld c,Dss.GSwitch ; выделить параметр ком-строки + RST ToDSS + xor a + ld hl,Buffers.work.buffer1; + cp (hl) + jr nz,.chdir + ld (hl),"." ; ".." родит. папка + inc hl + ld (hl),"." + inc hl + ld (hl),0 + dec hl + dec hl +.chdir: ld c,Dss.ChDir ; сменить тек. каталог + RST ToDSS + call c,print_err_message ; вывод сообщения + jp Get_Path ; сохр. тек. диск и путь +; ; вывод сист. пути на экран +; ld c,8Eh ; узнать полож. курсора +; RST ToBIOS +; ld (YXpos),de ; Y/X начало ком-строки +; ld (cursor_position),de ; Y/X позиция курсора +; ;call print_compath ; вывести путь + новая ширина поля ввода +; ;ld de,(YXpos) ; Y/X начало ком-строки +; ;ld c,84h ; уст. полож. курсора +; ;RST ToBIOS +; ret diff --git a/Crazy Estex DSS/SHELL/Commands/CLS.ASM b/Crazy Estex DSS/SHELL/Commands/CLS.ASM new file mode 100644 index 0000000..11e9c0c --- /dev/null +++ b/Crazy Estex DSS/SHELL/Commands/CLS.ASM @@ -0,0 +1,65 @@ +;/////////////////////////////////////////////////// +; +; CLS. Очистить экран +; +; Можно задать один аргумент - цвет экрана. +; Если аргумент не задан, исп. по-умолчанию #07. +;/////////////////////////////////////////////////// +cmd_cls: ex de,hl ; hl=ком-строка + ;ld de,T9186 ; буфер под параметр + ld de,Buffers.work.buffer1; + push de + ld c,Dss.GSwitch ; выделить параметр ком-строки + RST ToDSS + pop hl + jp nc,invalid_param ; "Invalid parametr" (>1 парам.) + ld b,7 ; атрибут очистки по-умолчанию + ld a,(hl) + or a + jr z,cls_clear + call ascii2byte + jp c,invalid_param ; "Invalid parametr" + and 7 + ld b,a + inc hl + ld a,(hl) + or a + jr z,cls_clear + ld a,b + rlca + rlca + rlca + rlca + ld b,a + ld a,(hl) + call ascii2byte + jp c,invalid_param ; "Invalid parametr" + or b + ld b,a +cls_clear: ld a,b + ld (color_screen),a ; атрибут + ld de,0 ; Y/X полож. + ld hl,#2050 ; Y/X размер + ld c,BIOS.LP_CLS_WIN ; очистить окно (выводом пробелов) + RST ToBIOS + ; уст. курсор в Home + ld de,0 ; Y/X полож. + ld c,Dss.Locate + RST ToDSS + ret + + +; ascii -> int +ascii2byte: + cp "0" + ret c + cp "9"+1 + jr c,$+10 ;!FIXIT $ + and 5Fh + cp "F"+1 + ccf + ret c + sub 7 + sub "0" + or a + ret diff --git a/Crazy Estex DSS/SHELL/Commands/DATE.ASM b/Crazy Estex DSS/SHELL/Commands/DATE.ASM new file mode 100644 index 0000000..7392470 --- /dev/null +++ b/Crazy Estex DSS/SHELL/Commands/DATE.ASM @@ -0,0 +1,175 @@ +; Обработчики команд DATE и TIME +; + + +;/////////////////////////////////////////////////// +; +; DATE. Вывод или установка даты +; +;/////////////////////////////////////////////////// +cmd_date: + ex de,hl ; hl=ком-строка + ld de,Buffers.work.buffer1; + ld c,Dss.GSwitch ; выделить параметр ком-строки + RST ToDSS + ld de,Buffers.work.buffer1; + ld a,(de) + or a + jr z,.cmd_dt1 + call STR2DEC + jp c,invalid_param ; "Invalid parametr" + xor a + cp h + jp nz,invalid_param ; "Invalid parametr" + ld a,31 + cp l + jp c,invalid_param ; "Invalid parametr" + ld b,l + push bc + call STR2DEC + pop bc + jp c,invalid_param ; "Invalid parametr" + xor a + cp h + jp nz,invalid_param ; "Invalid parametr" + ld a,12 + cp l + jp c,invalid_param ; "Invalid parametr" + ld c,l + push bc + call STR2DEC + push hl + ld c,Dss.SysTime + RST ToDSS + pop ix + pop de + ld c,Dss.SetTime + RST ToDSS +.cmd_dt1: + ld c,Dss.SysTime + RST ToDSS + PUSH BC ; [x] вывод дня недели 26/01/2023 + push ix + push de + ld a,d ; число + ld hl,Buffers.bat_params.PRM1; куда + call PUTB ; десят. вывод в буфер + ld a,"." + ld (hl),a + inc hl + pop de + ld a,e ; число + call PUTB ; десят. вывод в буфер + ld a,"." + ld (hl),a + inc hl + push hl + pop ix + pop hl + call PDIGIT + ; [x] вывод дня недели 26/01/2023 + POP DE + LD D,0 + LD A,E + CP 8 + JR C,.skip + LD E,8 +.skip: LD HL,.days + LD BC,.days.size + CALL LCPIR + ; + LD DE,Buffers.bat_params.PRM2 + CALL ncopy_string + ; + ld de,MAIN_MSG.DATE ; индекс "Current date: %1" + jp ECHO_MESSAGE ; вывести строку + ; +.days: DB 0 + DZ "Sunday" + DZ "Monday" + DZ "Tuesday" + DZ "Wednesday" + DZ "Thursday" + DZ "Friday" + DZ "Saturday" + DZ "check CMOS!" +.days.size EQU $ - .days + + +;/////////////////////////////////////////////////// +; +; TIME. Вывод или установка времени +; +;/////////////////////////////////////////////////// +cmd_time: + ex de,hl + ;ld de,T9186 + ld de,Buffers.work.buffer1; + ld c,Dss.GSwitch + RST ToDSS + ;ld de,T9186 + ld de,Buffers.work.buffer1; + ld a,(de) + or a + jr z,cmd_tm1 + call STR2DEC + jp c,invalid_param ; "Invalid parametr" + xor a + cp h + jp nz,invalid_param ; "Invalid parametr" + ld a,23 + cp l + jp c,invalid_param ; "Invalid parametr" + ld b,l + push bc + call STR2DEC + pop bc + jp c,invalid_param ; "Invalid parametr" + xor a + cp h + jp nz,invalid_param ; "Invalid parametr" + ld a,59 + cp l + jp c,invalid_param ; "Invalid parametr" + ld c,l + push bc + call STR2DEC + pop bc + jp c,invalid_param ; "Invalid parametr" + xor a + cp h + jp nz,invalid_param ; "Invalid parametr" + ld a,59 + cp l + jp c,invalid_param ; "Invalid parametr" + push bc + ld a,l + push af + ld c,Dss.SysTime + RST ToDSS + pop bc + pop hl + ld c,Dss.SetTime + RST ToDSS +cmd_tm1:ld c,Dss.SysTime + RST ToDSS + push bc + push hl + ld a,h ; число + ld hl,Buffers.bat_params.PRM1; куда + call PUTB ; десят. вывод в буфер + ld a,":" + ld (hl),a + inc hl + pop de + ld a,e ; число + call PUTB ; десят. вывод в буфер + ld a,":" + ld (hl),a + inc hl + pop af ; число + call PUTB ; десят. вывод в буфер + xor a + ld (hl),a ; в конец строки + ld de,MAIN_MSG.TIME ; индекс "Current time: %1" + jp ECHO_MESSAGE ; вывести строку diff --git a/Crazy Estex DSS/SHELL/Commands/DEL.ASM b/Crazy Estex DSS/SHELL/Commands/DEL.ASM new file mode 100644 index 0000000..f66a790 --- /dev/null +++ b/Crazy Estex DSS/SHELL/Commands/DEL.ASM @@ -0,0 +1,15 @@ +;/////////////////////////////////////////////////// +; +; DEL, ERASE. Удалить файл +; +;/////////////////////////////////////////////////// +cmd_del: ex de,hl + ld de,Buffers.work.buffer1; + ld c,Dss.GSwitch + RST ToDSS + ld hl,Buffers.work.buffer1; + ld c,Dss.Delete + RST ToDSS + call c,print_err_message ; вывод сообщения + ret +;/////////////////////////////////////////////////// \ No newline at end of file diff --git a/Crazy Estex DSS/SHELL/Commands/DIR.ASM b/Crazy Estex DSS/SHELL/Commands/DIR.ASM new file mode 100644 index 0000000..afdf8a5 --- /dev/null +++ b/Crazy Estex DSS/SHELL/Commands/DIR.ASM @@ -0,0 +1,797 @@ +;/////////////////////////////////////////////////// +; +; DIR. Вывод списка файлов и папок +;/////////////////////////////////////////////////// +cmd_dir: push de + ;;;; [ ] поддержка параметров + ; зануляем все параметры на старте + xor a + ld (Buffers.work.buffer2),a + ld (read_disk_info.full),a + ld (.key_p),a + ; выполняем/настраиваем все найденные параметры в строке + LD C,256-3 ;!HARDCODE длина строки с командой +.parse: ld hl,cmd_dir_options + call RUN_OPTION + jr nc,.end_opt + jp (hl) +.end_opt: ; выводим строку о расчёте свободного места так, чтоб она затёрлась + ld a,(read_disk_info.full) + and a + jr z,.skip + LD DE,MAIN_MSG.CALCULATING + CALL ECHO_MESSAGE + ; 23/05/24 +.skip: ;LD C,Dss.CurDisk ; узнать тек. диск + ;RST ToDSS + ;CALL read_disk_info ; прочитать метку и серийный номер диска + ; + pop de + xor a + ld h,a + ld l,a + ld (FILES),hl + ld (dir_number),hl + ld (S_LOW),hl + ld (S_MED),hl + ld (S_HIGH),a + ; + ex de,hl + ld de,Buffers.work.buffer1 + ld c,Dss.GSwitch ; выделить параметр ком-строки + RST ToDSS + ; + ld a,(Buffers.work.buffer1) + or a + ;jr nz,.SkipMask ; задана маска имён + jr z,.NoSkipMask ; не задана маска имён + ld hl,Buffers.work.buffer1 + ld bc,Dss.EX_Path.GET_ALL + rst ToDSS + ; + and %00001100 ; имя диска и путь + jr z,.SkipMask + ; + ld hl,Buffers.work.buffer2+2 + ld c,Dss.CurDir + rst ToDSS + ld c,Dss.CurDisk + rst ToDSS + add a,"A" + ld (Buffers.work.buffer2),a + ld a,":" + ld (Buffers.work.buffer2+1),a + ; + xor a + ld hl,Buffers.work.buffer1 + ld bc,256 + cpir + ;!FIXIT проверка на ошибку по флагу P/V + dec hl + ex de,hl + ld hl,256-1 + and a + sbc hl,bc + ld b,h + ld c,l + ld a,'\' ; + ex de,hl + cpdr + ;!FIXIT проверка на ошибку по флагу P/V + inc hl + ld (hl),0 + inc hl + ld de,Buffers.bat_params.PRM1 + call ncopy_string ; сохраняем маску файла + ; + ld hl,Buffers.work.buffer1 + ld c,Dss.ChDir + rst ToDSS + ;ld a,DSS_Error.sys.NOT_READY + jp c,print_err_message +.no_error: ; + ld hl,Buffers.bat_params.PRM1 + ld de,Buffers.work.free + call ncopy_string ; восстанавливаем маску файла + ; + ld a,(Buffers.bat_params.PRM1) + or a + jr nz,.SkipMask + ; + ; добавление маски +.NoSkipMask: ld hl,mask_fname ; "*.*" + ld de,Buffers.work.free + call copy_string + ; 23/05/24 +.SkipMask: LD C,Dss.CurDisk ; узнать тек. диск + RST ToDSS + CALL read_disk_info ; прочитать метку и серийный номер диска + JR NC,.NeXt + ; + CALL print_err_message + SCF + RET + ; +.NeXt: CALL Print_Header + ; [ ] 01/10/23 + ld hl,Buffers.work.free ; имя файла + ld de,Buffers.work.buffer1 ; 80 буфер + ld a,FAT_ATTR.NoVolID ; атрибут (все, кроме метки тома) + ld bc,Dss.F_First.FATname ; f_first (формат 11) + RST ToDSS + JR C,.Dir_Empty ;R14 + ; + LD A,32-5 ; количество строк до ожидания клавиши (с вычетом заголовка) ;!HARDCODE + PUSH AF + ; цикл вывода списка файлов/папок +.loop: POP AF +.key_p+1: and #ff + dec a + jr nz,.skip_wait + ld de,MAIN_MSG.PAUSE + call ECHO_MESSAGE ; вывести строку + ld c,Dss.WaitKey + rst ToDSS + dec d + ld de,MAIN_MSG.DIR_ESCAPE + jp z,ECHO_MESSAGE ; закончить по ESC + ;jr nz,.skip_esc + ;xor a + ;ld (.key_p),a ; отменяем ESC +.skip_esc: ld a,32-1 +.skip_wait: PUSH AF + ld hl,Buffers.work.buffer1+33 ; 80 + ;push af + ;ld de,33 + ;add hl,de + call PRNNAME + ; + ld ix,Buffers.work.buffer1 ; 80 + ld a,(ix+32) ; атрибут тек. записи + and FAT_ATTR.DIRECTORY ; папка ? + jr z,.Calc_Size ; нет + ; считаем папки + ; не считаем папкой служебные "." и ".." + ld d,(ix+33) + ld e,(ix+34) + ld hl,-('..') + add hl,de + ld a,h + or l + jr z,.next + ld hl,-('. ') + add hl,de + ld a,h + or l + jr z,.next + ; увеличиваем счётчик папок + ld hl,(dir_number) + inc hl + ld (dir_number),hl + jr .next + ;;R14 +.Dir_Empty: ;push af + ;CALL Print_Header + ;pop af + CALL print_err_message + jr .print + ;;R14 + ; прибавить размер тек. файла +.Calc_Size: ld hl,(FILES) + inc hl + ld (FILES),hl + ld e,(ix+FAT_DIRECTORY_RECORD.F_SIZE+2) + ld d,(ix+FAT_DIRECTORY_RECORD.F_SIZE+3) + ld hl,(S_MED) + ld a,(S_HIGH) + exx + ld e,(ix+FAT_DIRECTORY_RECORD.F_SIZE) + ld d,(ix+FAT_DIRECTORY_RECORD.F_SIZE+1) + ld hl,(S_LOW) + add hl,de + ld (S_LOW),hl + exx + adc hl,de + ld (S_MED),hl + ;exx + adc a,0 + ld (S_HIGH),a + ;exx +.next: ld de,Buffers.work.buffer1 ; 80 буфер + ld c,Dss.F_Next ; поиск след. + RST ToDSS + jp nc,.loop ; назад в цикл, если не конец списка + pop af ; баланс стека + ; Десятичный вывод +.print: ld hl,(FILES) + ld ix,Buffers.bat_params.PRM3; количество файлов + call PDIGIT + ; + ld a,(S_HIGH) + ld hl,(S_MED) ; ст. разряд + exx + ld hl,(S_LOW) ; мл. разряд + ;exx + ; + ;CALL PRINT_DWORD + CALL PRINT_5BYTES + ; + ; [x] вывод количества папок + ; [x] вывод общего количества свободного места + ld hl,SIZE_BUFFER.high ; "000 000 000 000" + ld de,Buffers.bat_params.PRM1; + PRM2. размер файлов в каталоге + ld bc,SIZE_BUFFER.bytes + call ncopy_string.start ; скопир. строку (с нулем), макс. SIZE_BUFFER.bytes симв. + ; + ; Десятичный вывод + ld hl,(dir_number) + ld ix,Buffers.bat_params.PRM4; кол-во каталогов в каталоге + call PDIGIT + ; full capacity + ld a,(full_space_high) + ld hl,(full_space_medium) ; ст. разряд + exx + ld hl,(full_space_low) ; мл. разряд + CALL PRN_DISK_SIZE + ; ; + ld de,MAIN_MSG.DIR_2 ; индекс " %1 file(s), %2 bytes, %3 Dir(s)" + CALL ECHO_MESSAGE ; вывести строку + ; + ; [ ] 23/05/2024 + ld hl,Buffers.work.buffer2 + ld c,Dss.ChDir + ld a,(hl) + or a + call nz,ToDSS + ; + ld a,(read_disk_info.full) + and a + ;ld de,MAIN_MSG.CRLF + ;jp z,ECHO_MESSAGE + RET Z + ; + ; free space + ld a,(free_space_high) + ld hl,(free_space_medium) ; ст. разряд + exx + ld hl,(free_space_low) ; мл. разряд + ; + CALL PRN_DISK_SIZE + ; + ld de,MAIN_MSG.DIR_4 ; индекс " %6 bytes free" + jp ECHO_MESSAGE +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +PRN_DISK_SIZE: call PRINT_5BYTES + ld hl,SIZE_BUFFER.high ; "000 000 000 000" + ld de,Buffers.bat_params.PRM5; and PRM6. куда + ld bc,SIZE_BUFFER.bytes + jp ncopy_string.start ; скопир. строку (с нулем), макс. SIZE_BUFFER.bytes симв. + ; +Print_Header: ; %1 + ld hl,Buffers.bat_params.PRM1 + ld a,'"' + ld (hl),a + inc hl + push hl + ; + ld c,Dss.CurDisk + rst ToDSS + add a,"A" + ; + pop hl + ld (hl),a + inc hl + ld a,'"' + ld (hl),a + inc hl + ;ld (hl),":" + ld (hl),0 + ; %2 + ld hl,serial_string ; строка серийного номера диска + ld de,Buffers.bat_params.PRM2; куда + call ncopy_string ; скопир. строку (с нулем) + ; %3..5 + ;push hl + ld hl,Buffers.work.free + 256 + 128 ; 128 - на всякий случай + ld c,Dss.CurDir + rst ToDSS + ld hl,Buffers.bat_params.PRM3 + ld a,(Buffers.bat_params.PRM1 + 1) + ld (hl),a + inc hl + ld (hl),':' + ; + ld hl,Buffers.bat_params.PRM3 +2 + ld de,Buffers.bat_params.PRM3 +2 + 1 + ld (hl),0 + ld bc,16+16+16-1-2 + ldir + ; + ld hl,Buffers.work.free + 256 + 128; сист. путь + ld de,Buffers.bat_params.PRM3 + 2 ;+PRM4..5. 2 + 48 байтов буфер + call make_short_path + ld de,MAIN_MSG.DIR_1 ; индекс "Volume in drive %1..." + JP ECHO_MESSAGE ; вывести строку + ; + +; Подготовить строку списка файлов/папок +PRNNAME: dec hl + ld a,(hl) + and FAT_ATTR.DIRECTORY + call z,.set_small + inc hl + ; + ld bc,8 + ld de,Buffers.bat_params.PRM1 + ldir + xor a + ld (de),a + ld de,Buffers.bat_params.PRM2; куда + ldi + ldi + ldi + ld (de),a + ld ix,Buffers.work.buffer1 + call PRNSIZE ; вывести в буфер имя файла и его размер (у папки ) + call PRNDATE ; вывести в буфер дату файла/папки + call PRNTIME ; вывести в буфер время файла/папки + ld de,MAIN_MSG.DIR_3 ; индекс "%1 %2 %3 %4 %5" + jp ECHO_MESSAGE ; вывод строки + ; +.set_small: + ld d,h + ld e,l + ld b,11 ;!HARDCODE длина имени DOS +.loop: inc hl + ld a,(hl) + cp 'A' + jr c,.next + cp 'Z'+1 + jr c,.letter + ; + cp 'А' ;#80 + jr c,.next + cp 'Я'+1 ;#9F + 1 + jr nc,.next + ; +.letter: or %0010'0000 + ld (hl),a +.next: djnz .loop + ex de,hl + ret + +; Вывести в буфер имя файла и его размер (у папки ) +PRNSIZE: ld a,(ix+32) + ld hl,DIRIDD ; " " + and FAT_ATTR.DIRECTORY ; папка ? + jr nz,.PRZ ; да + ld l,(ix+FAT_DIRECTORY_RECORD.F_SIZE) ; мл. разряд + ld h,(ix+FAT_DIRECTORY_RECORD.F_SIZE+1) + exx + ld l,(ix+FAT_DIRECTORY_RECORD.F_SIZE+2) ; ст. разряд + ld h,(ix+FAT_DIRECTORY_RECORD.F_SIZE+3) + exx + push ix + call MAKE_LN ; десятичный 32-х разрядный вывод +.not_zero: ld de,SIZE_BUFFER.low ; "0 000 000 000" + ld hl,L32BIT_ ; "0000000000" + ldi + ld a," " + ld (de),a + inc de + ldi + ldi + ldi + ld (de),a + inc de + ldi + ldi + ldi + ld (de),a + inc de + ldi + ldi + ldi + ld hl,SIZE_BUFFER.low ; "0 000 000 000" + pop ix +.PRZ: ld de,Buffers.bat_params.PRM3; 16 буфер + jp ncopy_string ; скопир. строку (с нулем), макс.15 симв. + +; Скопировать в буфер дату файла/папки +PRNDATE: ld c,(ix+FAT_DIRECTORY_RECORD.DATE) + ld b,(ix+FAT_DIRECTORY_RECORD.DATE+1) + ld hl,SIZE_BUFFER.low ; "0 000 000 000" + call MAKE_DATE ; вывод в буфер даты + ld (hl),0 + ld hl,SIZE_BUFFER.low ; "0 000 000 000" + ld de,Buffers.bat_params.PRM4; 16 куда + jp ncopy_string ; скопир. строку (с нулем), макс.15 симв. + +; Скопировать в буфер время файла/папки +PRNTIME: ld b,(ix+22) + ld c,(ix+23) + ld hl,SIZE_BUFFER.low ; "0 000 000 000" + call MAKE_TIME ; скопир. в буфер время файла/папки + ld (hl),0 + ld hl,SIZE_BUFFER.low ; "0 000 000 000" + ld de,Buffers.bat_params.PRM5; 80 буфер строки + jp ncopy_string ; скопир. строку (с нулем), макс.15 симв. + +; в буфер время файла/папки +MAKE_TIME: srl c + rr b + srl c + rr b + srl c + rr b + srl b + srl b + ld a,c + call toNumber + ld (hl),":" ; раздел. времени + inc hl + ld a,b + jr toNumber + +; в буфер дату файла/папки +MAKE_DATE: ld a,c + and #1F + push bc + call toNumber + ld (hl),"." ; раздел. даты + inc hl + pop bc + ld a,c + srl b + rla + rla + rla + rla + and #0F + call toNumber + ld (hl),"." ; раздел. даты + inc hl + ld a,b + add a,80 + cp 100 + jr c,toNumber +.loop: sub 100 + cp 100 + jr nc,.loop + ; +toNumber: ld c,#2F +.loop: inc c + sub 10 + jr nc,.loop + add a,10 + add a,"0" + ld (hl),c + inc hl + ld (hl),a + inc hl + ret +; + +;!TODO перетащить в procedures/math.asm +; Десятичный 32-х разрядный вывод +; HL':HL - число для перевода +; !FIXIT можно объеденить с PDIGIT +MAKE_LN: ld ix,L32BIT_ ; "0000000000" + exx + ld de,#3B9A + exx + ld de,#CA00 + ; DE':DE = 1,000,000,000 + call GET_DIG +.skip_1: exx + ld de,#05F5 + exx + ld de,#E100 + ; DE':DE = 100,000,000 + call GET_DIG ; 100,000,000...999,999,999 + exx + ld de,#98 + exx + ld de,#9680 + ; DE':DE = 10,000,000 + call GET_DIG ; 10,000,000...99,999,999 + exx + ld de,#0F + exx + ld de,#4240 + ; DE':DE = 1,000,000 + call GET_DIG ; 1,000,000...9,999,999 + exx + ld de,#01 + exx + ld de,#86A0 + ; DE':DE = 100,000 + call GET_DIG ; 100,000...999,999 + exx + ld de,#00 + exx + ld de,#2710 + ; DE':DE = 10,000 + call GET_DIG ; 10,000...99,999 + exx + ld de,#00 + exx + ld de,#03E8 + ; DE':DE = 1,000 + call GET_DIG ; 1,000...9,999 + exx + ld de,#00 + exx + ld de,#64 + ; DE':DE = 100 + call GET_DIG ; 100..999 + exx + ld de,#00 + exx + ld de,#0A + ; DE':DE = 10 + call GET_DIG ; 10..99 + ld a,l + add a,"0" + ld (ix+0),a + inc ix + ret + ; +GET_DIG: ld a,"0"-1 + AND A +.loop: inc a + sbc hl,de + exx + sbc hl,de + exx + jp nc,.loop + ; + add hl,de + exx + adc hl,de + exx + ;dec a + cp "0" + jr nz,.putChar + ld b,a + ld a,(ix-1) + cp " " + jr z,.putChar + ld a,b + ; +.putChar: ld (ix+0),a + inc ix + ret +; + +FILES: WORD 0 +S_LOW: WORD 0 +S_MED: WORD 0 +S_HIGH: BYTE 0 +dir_number: WORD 0 +; +full_space_low: WORD 0 +full_space_medium: WORD 0 +full_space_high: BYTE 0 +; + +; !TODO может обойтись одним буфером 00 вместо двух? +L40BIT: db " " ; маркер для ix-1 +.Str: db " " ; 00 +L32BIT_: db " " ; 000000000 +.end: db "0" +; +DIRIDD: db " ",0 +; +SIZE_BUFFER: db " " ; маркер для ix-1 +.high db " " ; "00" +.low: db " ",0,0 ; "0 000 000 000",0,0 +.bytes equ SIZE_BUFFER - $ +; + +;---------------; +SlashMaskFname: db '\' ; +; маска файлов +mask_fname: db "*.*",0 +;---------------; + +cmd_dir_options:; [x] параметр /F - вывод количества свободного места на диске (тормозит, поэтому параметром) + DB 'f' : DW cmd_dir_freeSpace + DB 'p' : DW cmd_dir_pause +.Size EQU ($-cmd_dir_options)/3 +.paramLength EQU 3 +; + +; +cmd_dir_freeSpace: + ; ставим опцию для API DSS DskInfo + ld a,1 + ld (read_disk_info.full),a + jp cmd_dir.parse +; +cmd_dir_pause: ld a,#ff + ld (cmd_dir.key_p),a + jp cmd_dir.parse +/////////////////////////////////////////////////////////////////////////////////////// +GET_BIG_DIG: ld b,"0"-1 + and a +.loop: inc b + sbc hl,de + exx + sbc hl,de + exx + sbc a,c + jp nc,.loop + ; + add hl,de + ; + exx + adc hl,de + exx + adc a,c + ; + ex af,af' + ;dec b + ld a,b + cp "0" + jr nz,.putChar + ld a,(ix-1) + cp " " + jr z,.putChar + ld a,b + ; +.putChar: ld (ix+0),a + ex af,af' + inc ix + ret + ; stop +; A:HL':HL - число для перевода +PRINT_5BYTES: ld ix,L40BIT.Str ; "00" + ld c,#17 + exx + ld de,#4876 + exx + ld de,#E800 + ; C:DE':DE = 100,000,000,000 + call GET_BIG_DIG + ; + ld c,#02 + exx + ld de,#540B + exx + ld de,#E400 + ; C:DE':DE = 10,000,000,000 + CALL GET_BIG_DIG + ; + ld c,#00 + exx + ld de,#3B9A + exx + ld de,#CA00 + ; C:DE':DE = 1,000,000,000 + CALL GET_BIG_DIG + ; + ; DE':DE = 100,000,000 + CALL MAKE_LN.skip_1 + ld de,SIZE_BUFFER.high ; "0 000 000 000" + ld hl,L40BIT.Str ; "0000000000" + ldi + ldi + ld a,(hl) + ldi + cp " " + jr z,1F + ld a,"," ; разд. разрядов +1: ld (de),a + inc de + ldi + ldi + ld a,(hl) + ldi + cp " " + jr z,1F + ld a,"," ; разд. разрядов +1: ld (de),a + inc de + ldi + ldi + ld a,(hl) + ldi + cp " " + jr z,1F + ld a,"," ; разд. разрядов +1: ld (de),a + inc de + ldi + ldi + ldi + scf + ret +/////////////////////////////////////////////////////////////////////////////////////// + + +/////////////////////////////////////////////////////////////////////////////////////// +;----------------------------------------------------------------------; +;Процедура умножения (16*8bit) +;На вход: DE * C +;На выход:A:HL = результат + IFUSED Mult32 +Mult16X8: SUB A + LD L,A + LD H,A + CP C + RET Z + OR D + OR E + RET Z + LD A,C + LD C,#00 + LD B,#08 +.loop: ADD HL,HL + RLA + JR NC,.next + ADD HL,DE + ADC A,C +.next: DJNZ .loop + RET + ENDIF +;----------------------------------------------------------------------; +;----------------------------------------------------------------------; +;Процедура умножения (32bit) +;На вход: HL:DE * BC +;На выход:HL:DE = результат + IFUSED Mult32 +Mult32: PUSH IX + LD IX,#0000 + LD A,#20 + EX DE,HL +.loop: ADD IX,IX + ADC HL,HL + RL E + RL D + JR NC,.no_add + ADD IX,BC + JR NC,no_add + INC HL +.no_add: DEC A + JR NZ,.loop + LD E,LX + LD D,HX + POP IX + RET + ENDIF +;----------------------------------------------------------------------; +;INPUT : DE * BC +;OUTPUT: HL:DE + IFUSED Mult32 +Mult_16x16: LD IX,0 + LD HL,0 + ; + LD A,B + OR C + JR Z,.exit + ; +.loop: SRL B + RR C + JP NC,.no_add + ADD IX,DE + JR NC,.no_add + INC HL + ; +.no_add: LD A,B + OR C + JR Z,.exit + ; + SLA E + RL D + RL L + RL H + JP .loop + ; +.exit: LD D,XH + LD E,XL + RET + ENDIF +/////////////////////////////////////////////////////////////////////////////////////// diff --git a/Crazy Estex DSS/SHELL/Commands/ECHO.ASM b/Crazy Estex DSS/SHELL/Commands/ECHO.ASM new file mode 100644 index 0000000..183a51f --- /dev/null +++ b/Crazy Estex DSS/SHELL/Commands/ECHO.ASM @@ -0,0 +1,58 @@ +;/////////////////////////////////////////////////// +; +; ECHO. Вывод сообщений на экран +; +;/////////////////////////////////////////////////// +cmd_echo: + ex de,hl + ld a,(hl) ; ком-строка + or a + jr z,A862E ; без аргументов + ex de,hl + ; тест аргументов на "on","off" + push de + ld b,3 ; длина сравнения + ld hl,T8C21 ; "ON",0 + call COMPARE ; сравнить строки + pop de + ld a,true ; режим "on" + jr z,A864B + push de + ld b,4 ; длина сравнения + ld hl,T8C24 ; "OFF",0 + call COMPARE ; сравнить строки + pop hl + ld a,false ; режим "off" + jr z,A864B + ; аргументы не "on","off" +A8623: ld c,Dss.PChars + RST ToDSS + jp newline + +; Показать тек. режим эха +A862E: ld a,(echo_mode) ; флаг echo-режима + or a + ld de,7 ; индекс "on" + jr nz,$+5 ; false ;!FIXIT $ + ld de,MAIN_MSG.OFF ; индекс "off" + call FMESAGE ; найти строку по индексу + ld de,Buffers.bat_params.PRM1; куда (аргумент %1) + call ncopy_string ; скопир. строку (с нулем), макс.15 симв. + ld de,MAIN_MSG.ECHO ; индекс "Echo is %1" + jp ECHO_MESSAGE + ; +A864B: ld (echo_mode),a ; флаг echo-режима + ret + + +;/////////////////////////////////////////////////// +; +; Команда "ECHO." Вставка пустой строки на экран +; +;/////////////////////////////////////////////////// +cmd_echoLN: + ex de,hl + ld a,(hl) ; ком-строка + or a + jp z,newline ; без аргументов + jr A8623 ; вывести аргументы diff --git a/Crazy Estex DSS/SHELL/Commands/EXIT.ASM b/Crazy Estex DSS/SHELL/Commands/EXIT.ASM new file mode 100644 index 0000000..78f5b9c --- /dev/null +++ b/Crazy Estex DSS/SHELL/Commands/EXIT.ASM @@ -0,0 +1,12 @@ +;/////////////////////////////////////////////////// +; +; EXIT. Выход в родительский процесс +; +;/////////////////////////////////////////////////// +cmd_exit: +.TASKX+1: ld a,2 ; уровень текущего шелла + dec a + dec a + ret z ; a=2 (primary шелл) + ;pop hl ; восст. баланс стека (убрать вызов COMP в гл. цикле оболочки) + jp back_to_parent_process ; вернуться в родит. процесс diff --git a/Crazy Estex DSS/SHELL/Commands/HELP.ASM b/Crazy Estex DSS/SHELL/Commands/HELP.ASM new file mode 100644 index 0000000..0dbe14e --- /dev/null +++ b/Crazy Estex DSS/SHELL/Commands/HELP.ASM @@ -0,0 +1,8 @@ +;/////////////////////////////////////////////////// +; +; HELP. Вывод экрана помощи +; +;/////////////////////////////////////////////////// +cmd_help: + ld de,MAIN_MSG.HELP ; индекс "COMMANDS: ..." + jp ECHO_MESSAGE diff --git a/Crazy Estex DSS/SHELL/Commands/INFO.ASM b/Crazy Estex DSS/SHELL/Commands/INFO.ASM new file mode 100644 index 0000000..cb29be6 --- /dev/null +++ b/Crazy Estex DSS/SHELL/Commands/INFO.ASM @@ -0,0 +1,127 @@ +;[ ] 24/06/2024 +cmd_info: CALL Get_Path + ; + LD DE,MAIN_MSG.INFO_1 ; индекс "Drive Label Serial number Size" + CALL ECHO_MESSAGE + ; + LD HL,.Collect_Msg + LD C,Dss.PChars + RST ToDSS + ; + LD A,":" + LD (Buffers.bat_params.PRM9+1),A + XOR A + LD (Buffers.bat_params.PRM9+2),A ; Drive "X:",0 + LD (read_disk_info.full),A + ; + LD C,Dss.CurDisk + RST ToDSS + LD B,C + LD C,-1 + ; +.loop: INC C + PUSH BC + LD A,C + LD (.patch_A),A + ADD "A" + LD (Buffers.bat_params.PRM9),A + LD (.Collect_Msg+1),A + ; + LD HL,.Collect_Msg + LD C,Dss.PChars + RST ToDSS + ; +.patch_A+1: LD A,0 + CALL read_disk_info + JR C,.Unformatted_Partition + ; %7 - Volume label + ; serial_string - Volume serial number string + ; full_space_high \ + ; full_space_medium - Partition size + ; full_space_low / + ; + LD HL,serial_string + LD DE,Buffers.bat_params.PRM4 ; Volume serial number string + CALL ncopy_string + ; full capacity + ld a,(full_space_high) + ld hl,(full_space_medium) ; ст. разряд + exx + ld hl,(full_space_low) ; мл. разряд +.convert_hex: CALL PRN_DISK_SIZE + ; %5..6 - Full size + ; + ; форматирование PRM5 + LD HL,Buffers.bat_params.PRM5 - 1 + LD DE,Buffers.bat_params.PRM5 +.clear_spaces: INC HL + LD A,(HL) + CP " " + JR Z,.clear_spaces + AND A + CALL NZ,copy_string + ; +.print_info_2: LD DE,MAIN_MSG.INFO_2 ; индекс "Drive Label Serial number Size" + CALL ECHO_MESSAGE + ; +.next_drv: POP BC + DJNZ .loop + ; + LD A,"\n" + LD C,Dss.PutChar + RST ToDSS + JP RESTORE_ALL.path + ;RET + ; +.Unformatted_Partition: + LD HL,.none_string + LD DE,Buffers.bat_params.PRM4 ; Volume serial number string + CALL ncopy_string + LD HL,.none_string + LD DE,Buffers.bat_params.PRM7 ; Volume label + CALL ncopy_string + LD HL,.Unknown_str + LD DE,Buffers.bat_params.PRM8 ; Volume file system + CALL ncopy_string + ; + POP BC + PUSH BC + LD A,C + CP "C" + JR C,.ItIsFDD + LD DE,Dss.DRV.GenIOCTL.Enter + LD BC,Dss.DRV.GenIOCTL.GetParams + RST ToDSS.DRV ; !FIXIT не возвращает размер сектора, поэтому хардкор по 512 + JR NC,.calc_size +.ItIsFDD: ; + LD HL,.Unknown_str + LD DE,Buffers.bat_params.PRM5 ; Drive size + CALL ncopy_string + JR .print_info_2 + ; HL:DE * 512 = A:HL:H'L' +.calc_size: RL E + RL D + RL L + RL H + LD C,E + LD A,H + LD H,L + LD L,D + EXX + LD H,C + LD L,0 + JR .convert_hex + ; +.Collect_Msg: DZ " A: \r" ; патчится буква драйва в цикле +.Unknown_str: DZ "unknown" +.none_string: DZ "none" + + +/* +0 1 2 3 4 5 6 7 +01234567890123456789012345678901234567890123456789012345678901234567890123456789; +Drive File System Label Serial number Size in bytes + C: FAT32 NO NAME xxxx-xxxx 147,102,629,888 + D: FAT16 SP_SYS xxxx-xxxx 147,102,629,888 + ; +*/ diff --git a/Crazy Estex DSS/SHELL/Commands/MKDIR.ASM b/Crazy Estex DSS/SHELL/Commands/MKDIR.ASM new file mode 100644 index 0000000..a01c513 --- /dev/null +++ b/Crazy Estex DSS/SHELL/Commands/MKDIR.ASM @@ -0,0 +1,17 @@ +;/////////////////////////////////////////////////// +; +; MD, MKDIR. Создать папку +; +;/////////////////////////////////////////////////// +cmd_mkdir: + ex de,hl + ;ld de,T9186 ; буфер + ld de,Buffers.work.buffer1; + ld c,Dss.GSwitch ; выделить параметр ком-строки + RST ToDSS + ;ld hl,T9186 ; имя папки + ld hl,Buffers.work.buffer1; + ld c,Dss.MkDir ; создать папку + RST ToDSS + call c,print_err_message ; вывод сообщения + ret diff --git a/Crazy Estex DSS/SHELL/Commands/PATH.ASM b/Crazy Estex DSS/SHELL/Commands/PATH.ASM new file mode 100644 index 0000000..c7faa99 --- /dev/null +++ b/Crazy Estex DSS/SHELL/Commands/PATH.ASM @@ -0,0 +1,49 @@ +T858C: db "PATH=",0 ; строка + +;/////////////////////////////////////////////////// +; +; PATH. Установка пути +; +;/////////////////////////////////////////////////// +cmd_path: + ld a,(de) ; ком-строка + or a + jr z,A85B9 ; аргументов не было + ; уст. путь + inc de + cp 9 ; Tab + jr z,cmd_path + cp " "+1 + jr c,cmd_path + dec de + ex de,hl + dec hl + ld (hl),"=" + dec hl + ld (hl),"H" + dec hl + ld (hl),"T" + dec hl + ld (hl),"A" + dec hl + ld (hl),"P" ; начало строки имени + ld bc,Dss.Environ.Set ; устан./удалить перем. окружения + RST ToDSS + call c,print_err_message ; вывод сообщения + ret + +; Показать системный путь +A85B9: ;ld de,T9186 ; куда + ld de,Buffers.work.buffer1; + ld hl,T858C ; имя переменной "PATH=" + ld bc,Dss.Environ.Get ; получить переменную окружения + RST ToDSS + jp c,print_err_message ; вывод сообщения + ld hl,T858C ; "PATH=",0 + ld c,Dss.PChars + RST ToDSS + ;ld hl,T9186 ; строка + ld hl,Buffers.work.buffer1; + ld c,Dss.PChars + RST ToDSS + jp newline diff --git a/Crazy Estex DSS/SHELL/Commands/PAUSE.ASM b/Crazy Estex DSS/SHELL/Commands/PAUSE.ASM new file mode 100644 index 0000000..c852082 --- /dev/null +++ b/Crazy Estex DSS/SHELL/Commands/PAUSE.ASM @@ -0,0 +1,22 @@ +;/////////////////////////////////////////////////// +; +; PAUSE. Пауза (в bat-файле) +; +;/////////////////////////////////////////////////// +cmd_pause: + LD de,MAIN_MSG.PAUSE ; индекс "Press any key to continue ..." + CALL ECHO_MESSAGE ; вывод строки + LD A,LF + LD C,Dss.PutChar + RST ToDSS + LD A,R + PUSH AF + LD C,Dss.WaitKey ; ждем нажатия клавиши + EI + RST ToDSS + POP AF + DI + RET PO + EI + RET + ;ret diff --git a/Crazy Estex DSS/SHELL/Commands/REM.ASM b/Crazy Estex DSS/SHELL/Commands/REM.ASM new file mode 100644 index 0000000..4bba462 --- /dev/null +++ b/Crazy Estex DSS/SHELL/Commands/REM.ASM @@ -0,0 +1,10 @@ +;/////////////////////////////////////////////////// +; +; REM. Комментарий (в bat-файле) +; +;/////////////////////////////////////////////////// +cmd_rem:; [x] 15/12/23 может и не понадобится + AND A + ; + ret +; diff --git a/Crazy Estex DSS/SHELL/Commands/REN.ASM b/Crazy Estex DSS/SHELL/Commands/REN.ASM new file mode 100644 index 0000000..7df2136 --- /dev/null +++ b/Crazy Estex DSS/SHELL/Commands/REN.ASM @@ -0,0 +1,23 @@ +;/////////////////////////////////////////////////// +; +; REN, RENAME. Переименовать файл +; +;/////////////////////////////////////////////////// +cmd_rename: + ex de,hl + ;ld de,T9186 + ld de,Buffers.work.buffer1; + ld c,Dss.GSwitch + RST ToDSS + ;ld de,T9206 + ld de,Buffers.work.buffer+256; + ld c,Dss.GSwitch + RST ToDSS + ;ld hl,T9186 + ;ld de,T9206 + ld hl,Buffers.work.buffer1; + ld de,Buffers.work.buffer+256; + ld c,Dss.Rename + RST ToDSS + call c,print_err_message ; вывод сообщения + ret diff --git a/Crazy Estex DSS/SHELL/Commands/RMDIR.ASM b/Crazy Estex DSS/SHELL/Commands/RMDIR.ASM new file mode 100644 index 0000000..86ef838 --- /dev/null +++ b/Crazy Estex DSS/SHELL/Commands/RMDIR.ASM @@ -0,0 +1,17 @@ +;/////////////////////////////////////////////////// +; +; RD, RMDIR. Удалить папку +; +;/////////////////////////////////////////////////// +cmd_rmdir: + ex de,hl + ;ld de,T9186 ; буфер + ld de,Buffers.work.buffer1; + ld c,Dss.GSwitch ; выделить параметр ком-строки + RST ToDSS + ;ld hl,T9186 ; имя папки + ld hl,Buffers.work.buffer1; + ld c,Dss.RmDir ; удалить папку + RST ToDSS + call c,print_err_message ; вывод сообщения + ret diff --git a/Crazy Estex DSS/SHELL/Commands/Reboot.asm b/Crazy Estex DSS/SHELL/Commands/Reboot.asm new file mode 100644 index 0000000..d2a8d66 --- /dev/null +++ b/Crazy Estex DSS/SHELL/Commands/Reboot.asm @@ -0,0 +1,10 @@ +;R12 +cmd_reboot: DI + LD C,BIOS.FullInit + RST ToBIOS + LD BC,2*256 + BIOS.REINIT + RST ToBIOS + + DI + HALT +;R12 \ No newline at end of file diff --git a/Crazy Estex DSS/SHELL/Commands/SET.ASM b/Crazy Estex DSS/SHELL/Commands/SET.ASM new file mode 100644 index 0000000..3eba9b9 --- /dev/null +++ b/Crazy Estex DSS/SHELL/Commands/SET.ASM @@ -0,0 +1,35 @@ +;/////////////////////////////////////////////////// +; +; SET. Установить переменную окружения +; +;/////////////////////////////////////////////////// +cmd_set:ld a,(de) ; ком-строка + or a + jr z,A85EE ; пустая + ; уст. переменную окружения + inc de + cp 9 + jr z,cmd_set + cp " "+1 + jr c,cmd_set + dec de + ex de,hl + ld bc,Dss.Environ.Set + RST ToDSS + call c,print_err_message ; вывод сообщения + ret + +; Показать системное окружение +A85EE: ;ld hl,T9186 ; куда + ld hl,Buffers.work.buffer1; + ld bc,Dss.Environ.Read ; получить сист. окружение + RST ToDSS + ;ld hl,T9186 + ld hl,Buffers.work.buffer1; +A85F8: ld c,Dss.PChars + RST ToDSS + call newline + ld a,(hl) + or a ; конец сист. окружения ? + jr nz,A85F8 ; нет + ret diff --git a/Crazy Estex DSS/SHELL/Commands/VER.ASM b/Crazy Estex DSS/SHELL/Commands/VER.ASM new file mode 100644 index 0000000..443154d --- /dev/null +++ b/Crazy Estex DSS/SHELL/Commands/VER.ASM @@ -0,0 +1,47 @@ +;/////////////////////////////////////////////////// +; +; VER, VERSION. Вывод версии ДОС +; +;/////////////////////////////////////////////////// +cmd_version: + LD C,Dss.Version + RST ToDSS + LD L,D + LD H,E + LD DE,Buffers.bat_params.PRM1 + CALL .Set_Ver_to_PRM ; set DSS version + ;R13 + LD HL,256*CONSOLE_MODF + CONSOLE_VERS + LD BC,CONSOLE_BUILD + LD DE,Buffers.bat_params.PRM2 + CALL .Set_Ver_to_PRM ; set Shell version + ;R13 + LD DE,MAIN_MSG.VERSION + JP ECHO_MESSAGE + +; Вход: +; L - номер версии (0..9) +; H - номер модификации (0..99) +; BC - номер билда (0..999) +; DE - номер параметра +.Set_Ver_to_PRM: + PUSH BC + PUSH HL + LD H,0 + CALL hex2dec_ascii_16bit.n10 ;decim2 номер версии (0..9) + LD A,'.' + LD (DE),A + INC DE + POP HL + LD L,H + LD H,0 + CALL hex2dec_ascii_16bit.n10 ;decim2 номер модификации (0..99) + POP HL + LD A,'.' + LD (DE),A + INC DE + CALL hex2dec_ascii_16bit.n100 ;decim3 номер билда (0..999) + XOR A + LD (DE),A + RET +; \ No newline at end of file diff --git a/Crazy Estex DSS/SHELL/EDLINE.ASM b/Crazy Estex DSS/SHELL/EDLINE.ASM new file mode 100644 index 0000000..e22a51a --- /dev/null +++ b/Crazy Estex DSS/SHELL/EDLINE.ASM @@ -0,0 +1,1009 @@ +; Расчитана на функцию #32 ДОС с новым курсором. +; + +; Функция строки редактирования. Имеет историю вводимых строк. +; Функция использует для своей работы временный буфер: +; +; Buffers.work.buffer - этот буфер использует история +; ;Buffers.work.buffer+256 - возвращается набранная строка +; +; Клавиши: +; Esc - сбросить текущую строку +; Enter - выход из функции (в Buffers.work.buffer+256 готовая строка) +; Ins - смена режима ввода (вставка/замена) +; , курсор - прокрутка истории +; PageUp - в начало истории +; PageDown - в конец истории +; Ctrl+Del - стереть историю +; +; +; Используется как заготовка для шелла ДОС. Выводит системный путь. +; Макс. длина экран. пути 34 символа (с диском), остальное обрезается. +; + + + + +;true equ 1 +;false equ 0 + +max_screen_path equ 32 ; макс. длина экран. пути (без диска) +max_len_comline equ 254 ; макс. длина ком-строки (больше не делать) +history_size equ 256 ; размер history-буфера + +; события (внутренние) +evNothing equ 0 ; нет событий +evKeyboard equ 1 ; нажата обычная клавиша +evCombKey equ 2 ; нажата комбин. клавиш или курсорные + + + + + + +;=========================================================== +; Строка редактирования +; +; Выход из строки по клавише , +; ;в Buffers.work.buffer+256 = набранная строка (или пустая) +;=========================================================== +input_line: + ld a,1 + ld (insert_mode),a + ld c,BIOS.LP_GET_PLACE ; узнать полож. курсора + RST ToBIOS + ld e,4 ; X начало + ld (YXpos),de ; Y/X начало ком-строки + ld (cursor_position),de ; Y/X позиция курсора + call clear_inpline ; очистить структуру ~input line~ + call print_compath ; вывести путь + новая ширина поля ввода + jp event_input_line ; на обраб. строки ввода + + + + +;--------------------------------------------------------------- +; Вывод пути в ком-строке на экран + новая ширина поля ввода +;--------------------------------------------------------------- +print_compath: + ld hl,Buffers.sys_path ; сист. путь + ld de,Buffers.screen_path+2 ; буфер для короткого пути + call make_short_path + xor a + ld (de),a ; зануление строки + ex af,af' ; восст. длину строки + add a,2 ; + длина "X:" + ld b,a + inc a + ld (YXpos),a ; X начало ком-строки + ld a,width_inpline.MAX-1 ; ширина экрана - 1 + sub b + ld (width_inpline),a ; новая ширина поля ввода (76..48) + push bc + ; очистить экран. строку + ld de,(cursor_position) ; Y/X полож. + ld e,0 + ld hl,#0150 ; Y/X размер + ld a,(color_screen) ; атрибут + ld b,a + ld a," " ; символ очистки + ld c,BIOS.LP_CLS_WIN2 ; очистить окно + RST ToBIOS + pop bc + ; вывести экран. путь + ld hl,Buffers.screen_path ; экран. путь + ;call print_inpchar ; вывод строки по счетчику + ld c,BIOS.LP_PRINT_LINE2 + RST ToBIOS; + ld a,">" + ld bc,1*256 + BIOS.LP_PRINT_SYM ; символ без атрибута + RST ToBIOS + ;jr print_inpline ; вывод строки ввода + ;------------------------------------------------- + ; Вывод строки ~input line~ на экран + ;------------------------------------------------- +print_inpline: + ld de,(YXpos) ; Y/X начало ком-строки + ld c,Dss.Locate ; уст. курсор + RST ToDSS + ld hl,Buffers.input_line ; структура буфера ~input line~ + push hl + pop iy + ld a,(iy + Input_Line.Left_Shift) ;+3 смещ. строки за левый край + add a,l + ld l,a + jr nc,$+3 ; !FIXIT + inc h + inc hl + inc hl + inc hl + inc hl + inc hl + ld a,(width_inpline) ; ширина поля + ld c,a + ld b,a + push bc + xor a + ld de,Buffers.work.buffer ; врем. буфер + push de + ld (de),a + inc de + djnz $-2 ; !FIXIT + ld a,(iy + Input_Line.max_Len) + sub (iy + Input_Line.Left_Shift) + cp c + jr nc,$+3 ; !FIXIT + ld c,a + ld a,(iy + Input_Line.Symbols_Num) ; число введ. символов + sub c + jr nc,$+4 ; !FIXIT + add a,c + ld c,a + pop de + push de + ld a,b + or c + jr z,$+4 ; !FIXIT + ldir + pop hl + pop bc + ld a,b ; длина строки + or a + ;call nz,print_inpchar ; вывод строки по счетчику + ld c,BIOS.LP_PRINT_LINE2 + call nz,ToBIOS + ld a,(YXpos) ; X начало ком-строки + ld e,(iy + Input_Line.Cur_X) ;+2 тек. полож. курсора в строке + add a,e + cp width_inpline.MAX ; ширина экрана + jr c,prne1__ + ld b,width_inpline.MAX-1 + sub b + ld d,a ; "наезд" за правый край + ld a,e + sub d + ld (iy + Input_Line.Cur_X),a ;+2 новое полож. курсора + ld a,b +prne1__:ld (cursor_position),a ; X полож. курсора на экране + ret + +; вход: HL - полный путь +; DE - буфер для короткой строки пути +make_short_path:; узнать длину сист. пути + ld (.bufferAddr),de + ld e,l + ld d,h + ld bc,max_len_comline ; 254 + xor a + ld (.flag),a ; сбр. флаг + cpir + dec hl + push hl ; сохр. конец пути + sbc hl,de + ld a,l ; длина строки + cp max_screen_path+1 ; 33 + jr c,.copy + ; длина пути > 32 + ld a,max_screen_path ; 32 + ld (.flag),a ; уст. флаг +.copy: ld c,a ; полная длина строки + ld b,0 + ex af,af' ; сохр. длину строки + pop hl ; восст. конец пути +.bufferAddr+1: ld de,0 ; куда + ; скопировать строку + and a + sbc hl,bc ; hl=начало перекачки + ldir +.flag+1: ld a,0 ; флаг переполн. строки + or a + ret z + ld hl,(.bufferAddr) + ld (hl),'\' + inc hl + ld a,"." + ld (hl),a + inc hl + ld (hl),a + ret + +; Вывод строки по счетчику +;print_inpchar: + ;ld a,(hl) + ;inc hl + ;push hl + ;push bc + ;ld bc,0182h + ;RST ToBIOS +; ld c,86h +; RST ToBIOS + ;pop bc + ;pop hl + ;djnz print_inpchar +; ret + + + + +;------------------------------------------------- +; Чтение событий +;------------------------------------------------- +handle_event: +cursor_position+1: + ld de,0 + ; + ld c,Dss.Locate + RST ToDSS + ld c,Dss.EchoKey ; опрос клавы + RST ToDSS + ld hl,what ; поле событий + ld a,e + or a + jr z,handle_event_comb + ld (hl),evKeyboard ;+0 событие + inc hl + ld (hl),e ;+1 код клавиши + inc hl + ld (hl),d ;+2 скен-код клавиши + ret +handle_event_comb: + ld (hl),evCombKey ;+0 событие + inc hl + ld (hl),b ;+1 флаги клавы + inc hl + ld (hl),d ;+2 код курс. клавиш + ret + +; поле событий +what: ds 3 + +step_scroll equ 1 ; шаг X скроллинга строки + + +;================================================= +; Обработчик событий ~Input Line~ +;================================================= +event_input_line: + call handle_event ; читаем событие + ld hl,event_input_line + push hl + ld iy,Buffers.input_line ; структура буфера ~input line~ + ld hl,what ; список событий + ld a,(hl) + inc hl + cp evKeyboard + jr z,EvComKeys + cp evCombKey + jp z,EvComComb + ret + +; +Enter: pop hl ; восст. баланс стека (выход из обработчика) + xor a + ;ld (Buffers.work.buffer+256),a ; задать пустую строку + ld hl,Buffers.input_line.Symbols_Num ; число введ. символов + ld e,(hl) + cp e + ret z ; пустая строка + ld c," " ; пробел + ld d,a + add hl,de + ld a,(hl) + cp c + jr nz,ent1__ ; нет конц. пробелов + ld b,e + ; убрать конц. пробелы ком-строки + ld a,(hl) + cp c + jr nz,$+8 ;!FIXIT $ + dec hl + dec (iy+4) ; --число введ. символов + djnz $-8 ;!FIXIT $ + inc hl + ld (hl),d ; в конец ком-строки + ld a,b + or a + ret z ; были одни пробелы + ld de,Buffers.input_line.Symbols_Num ; число введ. символов + ld (de),a ; новое число (для history_adding) +ent1__: call history_adding ; добавить строку в history + ; скопир. строку во врем. буфер +; ld hl,Buffers.input_line.Symbols_Num ; откуда +; ld de,Buffers.work.buffer+254 ; куда +; ld a,(hl) ; скопир. строку (с нулем) +; ldi +; or a +; jr nz,$-4 + ;call clear_input_line ; очистить строку ввода +; ld a,(YXpos+1); ; Y начало ком-строки +; inc a +; cp 32 +; jr c,$+3 +; xor a +; ld (YXpos+1),a; + ; восст. буфер +; ld hl,Buffers.work.buffer+254 ; откуда +; ld de,Buffers.input_line.Symbols_Num ; куда +; ld a,(hl) ; скопир. строку (с нулем) +; ldi +; or a +; jr nz,$-4 + ; уст. историю на посл. пустую строку + ld a,(history_count) ; число строк в истории + ld (history_cur_string),a ; номер тек. строки истории + ret + + +; Событие - обычная клавиша +EvComKeys: + ld a,(hl) ;+1 what + cp #1B ; Esc + jp z,clear_input_line ; очистить строку ввода + cp #0D ; Enter + jr z,Enter + cp 8 ; Backspace + jr z,inpline_work + cp " " + ret c +inpline_work: + ld de,input_line_done + push de + ld hl,Buffers.input_line ; структура буфера ~input line~ + ex af,af' + res 7,(iy + Input_Line.ReadyString) ;+1 флаг ReadyString + ld a,(insert_mode) ; режим ввода: 1-inser, 0-overwrite + and 1 + rrca ; вправо (мл.бит -> перенос) + or (iy + Input_Line.ReadyString) + ld (iy + Input_Line.ReadyString),a ;+1 флаг ReadyString + ex af,af' + cp 8 ; Backspace + jp z,back_space + ex af,af' + ld a,(iy + Input_Line.Symbols_Num) ; InputSymb + cp (iy + Input_Line.max_Len) + jr nz,ILn___ + ld a,(iy + Input_Line.Cur_X) + add a,(iy + Input_Line.Left_Shift) + cp (iy + Input_Line.max_Len) + ;ret nc + JR NC,LastChar_BEEP + bit 7,(iy + Input_Line.ReadyString) + ;ret nz + JR NZ,NoMoreChars_BEEP +ILn___: ld a,(iy + Input_Line.Symbols_Num) + sub (iy + Input_Line.Left_Shift) + sub (iy + Input_Line.Cur_X) + jr z,no_insert + dec (iy + Input_Line.Symbols_Num) + bit 7,(iy + Input_Line.ReadyString) + jr z,no_insert + inc (iy + Input_Line.Symbols_Num) + ; ввод в середину текста (вставка) + ld c,a + ld b,0 + ld hl,Buffers.input_line ; структура буфера ~input line~ + ld a,(iy + Input_Line.Symbols_Num) ;+4 число введ. символов + add a,l + ld l,a + jr nc,$+3 ;!FIXIT + inc h + inc hl + inc hl + inc hl + inc hl + inc hl + ld d,h + ld e,l + dec hl + lddr +no_insert: + ld hl,Buffers.input_line ; структура буфера ~input line~ + ld a,(iy + Input_Line.Cur_X) ; X тек. полож. курсора в строке + add a,(iy + Input_Line.Left_Shift) + add a,l + ld l,a + jr nc,$+3 ;!FIXIT + inc h + inc hl + inc hl + inc hl + inc hl + inc hl + ex af,af' + ld (hl),a ; сохр. символ в строке + inc (iy + Input_Line.Symbols_Num) + inc (iy + Input_Line.Cur_X) + ld a,(width_inpline) ; ширина поля ввода + cp (iy + Input_Line.Cur_X) ; X тек. полож. курсора в пределах строки + jr nz,$+8 ;!FIXIT + ; курсор за полем + inc (iy + Input_Line.Left_Shift) ; смещ. строки за левый край + dec (iy + Input_Line.Cur_X) ; X тек. полож. курсора в пределах строки + call print_inpline ; вывести строку на экран + pop de ; восст. баланс стека +input_line_done: + ret +LastChar_BEEP: + ;!TODO если символы привысили максимальное число, то на экране + ; в строке остаётся эхо нажатой клавиши, которая не влезла + ; и висит до нажатия очередной клавиши. Исправить. + LD A,7 ;ASCII BELL + LD C,Dss.PutChar + JP ToDSS + +NoMoreChars_BEEP: + ;!TODO если символы привысили максимальное число, то на экране + ; в строке остаётся эхо нажатой клавиши, которая не влезла + ; и висит до нажатия очередной клавиши. Исправить. + LD A,7 ;ASCII BELL + LD C,Dss.PutChar + JP ToDSS + +; Событие - курс. клавиши или комбинации +EvComComb: + ld b,(hl) ;+1 what + inc hl + ld a,(hl) ;+2 what + ld hl,Buffers.input_line ; структура буфера ~input line~ + ld de,input_line_done ; точка выхода + push de + cp #54 ; курсор влево + jr z,Left + cp #56 ; курсор вправо + jr z,Right + cp #58 ; курсор вверх, пред. строка истории + jp z,history_prev + cp #52 ; курсор вниз, след. строка истории + jp z,history_next + cp #59 ; PageUp, в начало истории + jp z,history_begin + cp #53 ; PageDown, в конец истории + jp z,history_last + cp #4F ; Del, удалить символ в тек. позиции + jp z,Delete + cp #57 ; Home, в начало строки + jp z,Home + cp #51 ; End, в конец строки + jp z,End1 + cp #50 ; Ins, смена режима ввода + jr z,change_insert_mode + bit 5,b ; Ctrl бит + jr z,.exit + cp #4F+#80 ; Ctrl+Del, очистить историю команд + jp z,clear_history +.exit: pop de + ret + +; Смена режима ввода +change_insert_mode: + ld a,(insert_mode) + xor 1 + ld (insert_mode),a + ret + +; Курсор влево +Left: ld a,(iy + Input_Line.Cur_X) + dec a + jp p,ComPrint + ld a,(iy + Input_Line.Left_Shift) ; смещ. строки за левый край + sub step_scroll ; шаг скроллинга + ret c ; курсор в крайнем левом полож. + ld (iy + Input_Line.Left_Shift),a ; X смещ. строки за левый край (в символах) + ld a,(iy + Input_Line.Cur_X) ; X полож. курсора в пределах строки + add a,step_scroll-1 ; шаг скроллинга +ComPrint: + ld (iy + Input_Line.Cur_X),a + jp print_inpline ; вывести строку на экран + +; Курсор вправо +Right: ld a,(iy + Input_Line.Cur_X) ; X полож. курсора в пределах строки + add a,(iy + Input_Line.Left_Shift) ; смещ. строки за левый край + cp (iy+4) ; число введ. символов + ret z + ld a,(width_inpline) ; ширина поля ввода + ld b,a + ld a,(iy + Input_Line.Cur_X) ; X полож. курсора в пределах строки + inc a + cp b + jr nz,ComPrint + inc (iy + Input_Line.Left_Shift) ; смещ. строки за левый край + ld a,(iy + Input_Line.Cur_X) ; X полож. курсора в пределах строки + sub step_scroll-1 ; шаг скроллинга + jr ComPrint + +; Backspace - удалить символ левее курсора +back_space: + ld a,(iy + Input_Line.Cur_X) ; X тек. полож. курсора в строке + or a + jr nz,back_space1 + ld a,(iy + Input_Line.Left_Shift) ; смещ. строки за левый край + sub step_scroll ; шаг скроллинга + ret c + ld (iy + Input_Line.Left_Shift),a + inc (iy + Input_Line.Cur_X) ;+2 тек. полож. курсора в строке +back_space1: + ld hl,Buffers.input_line ; структура буфера ~input line~ + ld a,(iy + Input_Line.Cur_X) ;+2 X тек. полож. курсора в строке + add a,(iy + Input_Line.Left_Shift) ;+3 смещ. строки за левый край + add a,l + ld l,a + jr nc,$+3 ;!FIXIT + inc h + inc hl + inc hl + inc hl + inc hl + inc hl + ld d,h + ld e,l + dec de + ld a,(iy + Input_Line.Symbols_Num) ;+4 число введ. символов + sub (iy + Input_Line.Left_Shift) ; смещ. строки за левый край + sub (iy + Input_Line.Cur_X) ; X полож. курсора в пределах строки + jr z,$+7 ; курсор за концом строки ;!FIXIT + ld c,a + ld b,0 + ldir ; обновить остаток строки + xor a + ld (de),a ; в конец строки + dec (iy + Input_Line.Cur_X) ; X полож. курсора в пределах строки + dec (iy + Input_Line.Symbols_Num) ; число введ. символов + jp print_inpline ; вывести строку на экран + +; Delete - удалить символ в тек. позиции +Delete: ld hl,Buffers.input_line ; структура буфера ~input line~ + ld a,(iy + Input_Line.Cur_X) ; X тек. полож. курсора в строке + inc a + add a,(iy + Input_Line.Left_Shift) ; смещ. строки за левый край + add a,l + ld l,a + jr nc,$+3 ;!FIXIT + inc h + inc hl + inc hl + inc hl + inc hl + inc hl + ld d,h + ld e,l + dec de + ld a,(iy + Input_Line.Symbols_Num) ;+4 число введ. символов + sub (iy + Input_Line.Left_Shift) ; смещ. строки за левый край + sub (iy + Input_Line.Cur_X) ; X тек. полож. курсора в строке + ret z ; курсор за концом строки + ld c,a + ld b,0 + ldir ; обновить остаток строки + xor a + ld (de),a ; в конец строки + dec (iy + Input_Line.Symbols_Num) ; число введ. символов + jp print_inpline ; вывести строку на экран + +; Home - в начало строки +Home: ld a,(iy + Input_Line.Cur_X) ; X тек. полож. курсора в строке + add a,(iy + Input_Line.Left_Shift) ; смещ. строки за левый край + ret z + xor a ; X полож. курсора + ld (iy + Input_Line.Cur_X),a ; X полож. курсора в пределах строки + ld (iy + Input_Line.Left_Shift),a ; смещ. строки за левый край + jp ComPrint ; вывести строку на экран + +; End - в конец строки +End1: ld a,(iy + Input_Line.Symbols_Num) ;+4 число введ. символов + sub (iy + Input_Line.Left_Shift) ;+3 смещ. строки за левый край + cp (iy + Input_Line.Cur_X) ;+2 X тек. полож. курсора в строке + ret z + add a,(iy + Input_Line.Left_Shift) ; смещ. строки за левый край + ld c,a + ld (iy + Input_Line.Left_Shift),0 ; смещ. строки за левый край + ld a,(width_inpline) ; ширина поля ввода + sub c + jr z,EndLp + jr nc,EndNIL + neg +EndLp: inc (iy + Input_Line.Left_Shift) ; X смещ. строки за левый край + sub step_scroll ; шаг скроллинга + jr nc,EndLp +EndNIL: ld a,(iy + Input_Line.Symbols_Num) ; число введ. символов + sub (iy + Input_Line.Left_Shift) ; смещ. строки за левый край + jp ComPrint ; вывести строку на экран + + + + +; Очистить буфер строки +clear_input_line: + call clear_inpline ; очистить структуру ~input line~ + jp print_inpline ; вывести строку на экран + + +; очистить структуру ~input line~ +clear_inpline: + xor a + ld hl,Buffers.input_line ; структура буфера ~input line~ + ld b,(hl) ;+0 макс. длина строки + inc hl + ld (hl),a ;+1 сбр. флаг ReadyString + inc hl + ld (hl),a ;+2 X тек. полож. курсора в строке + inc hl + ld (hl),a ;+3 смещ. строки за левый край + inc hl + ld (hl),a ;+4 число введ. символов + cp b + ret z + inc hl ;+5 буфер редакт. строки + ld (hl),a + djnz $-2 ;!FIXIT + ret + + + +; Вставить строку из history-буфера +; вход: de=структура строки: +0=длина строки, +1=строка +put_from_history: + call clear_inpline ; очистить строку ввода + ld a,(de) ;+0 длина строки + ld c,a +put_history_loop: + inc de + ld hl,Buffers.input_line ; структура буфера ~input line~ + ld a,(iy + Input_Line.Cur_X) ; X тек. полож. курсора в строке + add a,(iy + Input_Line.Left_Shift) + add a,l + ld l,a + jr nc,$+3 ;!FIXIT + inc h + inc hl + inc hl + inc hl + inc hl + inc hl + ld a,(de) + ld (hl),a + inc (iy + Input_Line.Symbols_Num) ; число введ. символов + inc (iy + Input_Line.Cur_X) ; X тек. полож. курсора в строке + ld a,(width_inpline) ; ширина поля ввода + cp (iy + Input_Line.Cur_X) ; X тек. полож. курсора в пределах строки + jr nz,$+8 ;!FIXIT + ; курсор за правым краем поля ввода + inc (iy + Input_Line.Left_Shift) ; смещ. строки за левый край + dec (iy + Input_Line.Cur_X) ; X тек. полож. курсора в пределах строки + dec c + jr nz,put_history_loop + ; вывести строку на экран + jp print_inpline + + + +; Очистить историю команд +clear_history: + call clear_input_line ; очистить строку ~input line~ + xor a + ld (history_count),a ; число строк в history + ld (history_cur_string),a ; номер тек. строки history + ld hl,Buffers.history ; конец посл. строки + ld (history_end),hl + ret + + + + + + +;======================================================================== +; History Код +;======================================================================== + +history_count: + db 0 ; число строк в истории + ; +history_cur_string: + db 0 ; номер тек. строки истории + ; +history_end: + dw Buffers.history ; конец послед. строки истории + + + +;------------------------------------------------- +; В начало истории +;------------------------------------------------- +history_begin: + ld a,(history_count) + or a + ret z ; нет строк + xor a + ld (history_cur_string),a + jr history_copy ; перейти на 1-ю строку + +;------------------------------------------------- +; В конец истории +;------------------------------------------------- +history_last: + ld a,(history_count) + or a + ret z ; нет строк + ld (history_cur_string),a ; уст. послед. пустую строку + jp clear_input_line ; вернуть пустую строку + +;------------------------------------------------- +; Следующая строка +;------------------------------------------------- +history_next: + ld a,(history_count) + or a + ret z ; нет строк + dec a + ld b,a + ld hl,history_cur_string + ld a,(hl) + cp b + jr c,$+7 ;!FIXIT + inc b + ld (hl),b + jp clear_input_line ; вернуть пустую строку + ; + inc a + ld (hl),a + jr history_copy + +;------------------------------------------------- +; Предыдущая строка +;------------------------------------------------- +history_prev: + ld a,(history_count) + or a + ret z ; нет строк + ld b,a + ld hl,history_cur_string + ld a,(hl) + or a + jr z,history_copy ; уперлись в начало истории + cp b + jr c,$+3 ;!FIXIT + ld a,b + dec a + ld (hl),a +; перейти на строку по ее индексу +history_copy: + call history_index + jp put_from_history ; строку из history в буфер ком-строки + +; вход: а=индекс строки +; выход: de=строка (ее структура из history-буфера) +history_index: + ld b,0 + ld hl,Buffers.history ; буфер истории + or a ; индекс строки + jr z,hist_index ; 1-я строка истории + ld c,(hl) ; размер строки + inc c + add hl,bc ; на след. строку + dec a + jr nz,$-4 ;!FIXIT +hist_index: + ex de,hl + ret + + +;----------------------------------------------------------- +; Добавить новую строку в конец буфера истории. +; Если строка не влезает, удаляются самые старые строки до +; тех пор, пока появится достаточно места для новой строки. +;----------------------------------------------------------- +history_adding: + ld de,Buffers.input_line.Symbols_Num ; структура строки + call history_compare ; сравнить строки + ret z ; уже есть такая строка + ld bc,(history_end) ; адрес конца посл. строки + ld hl,Buffers.history + history_size ; адрес конца буфера + and a + sbc hl,bc ; hl=размер своб. места + ld a,(de) ; длина новой строки + inc a + ld c,a + xor a + ld b,a + sbc hl,bc ; умещ. в своб. месте буфера истории ? + jr nc,history_add_ok ; да + ; удалить первую (самую старую) строку из буфера + ;push de + ld de,Buffers.history ; буфер истории + ld a,(de) ; длина 1-й строки + inc a + ld c,a + xor a + ld b,a + ld hl,(history_end) + sbc hl,bc + ld (history_end),hl ; конец посл. строки + ld l,e ; hl=history_buff + ld h,d + add hl,bc ; начало 2-й строки + push hl + ld hl,history_size ; размер буфера + and a + sbc hl,bc + ld c,l ; размер остатка буфера + ld b,h + pop hl ; начало 2-й строки + ldir + ld hl,history_count + dec (hl) ; --число строк в history + ;pop de ; восст. адрес Buffers.input_line.Symbols_Num + jr history_adding + ; +history_add_ok: + ld hl,(history_end) ; адрес конца посл. строки + ex de,hl + ldir + ld (history_end),de ; конец посл. строки + ld hl,history_count + ld a,(hl) + ld (history_cur_string),a ; тек. строка history + inc (hl) ; ++число строк в history + ret + + +; Сравнить строки. Если строки равны, то переместить +; тек. строку в конец истории. +; вход: de=структура строки: +0=длина строки, +1=строка +; выход: Z-есть строка +; NZ-нет строки +history_compare: + ld hl,history_count + ld b,(hl) ; число строк в history + dec b + inc b + jr z,hist_comp_quit ; history-буфер пустой + ex af,af' + xor a ; сбр. индекс сравн. строки + ex af,af' + ld hl,Buffers.history ; буфер истории +history_comp_loop: + push de + ld (move_cur_str+1),hl ; тек. строка истории + ld c,(hl) ; длина тек. строки history + ld a,(de) ; длина новой строки + inc hl + inc de + cp c + jr z,hist_comp_loop ; строки одинаковой длины + ld a,l + add a,c + ld l,a + ld a,h + adc a,0 + ld h,a + jr hist_comp_next + ; +; сравнить строки +hist_comp_loop: + ld a,(de) + cp (hl) + jr nz,hist_comp_notequal ; строки не равны + inc hl + inc de + dec c + jr nz,hist_comp_loop + ; строки равны + jr move_to_end_history ; найденную строку в конец истории + ; +hist_comp_notequal: + inc hl + dec c + jr nz,$-2 ; до конца строки ;!FIXIT $ +hist_comp_next: + pop de + ex af,af' + inc a ; ++индекс сравн. строки + ex af,af' + djnz history_comp_loop +hist_comp_quit: + xor a + dec a ; NZ-флаг + ret + +; переместить тек. строку в конец истории +move_to_end_history: + ld a,(history_count) ; число строк истории + ld c,a + dec c + ex af,af' ; индекс найденной строки + cp c + jr nc,not_move_to_end ; найденная строка уже в конце + ; сохр. строку во врем. буфере +move_cur_str: + ld hl,0 ; тек. строка истории + ld de,Buffers.work.buffer ; врем. буфер + ld c,(hl) ;+0 длина строки + inc c ; учесть ячейку длины строки + xor a + ld b,a + push bc + push hl + ldir + pop de ; куда (на место старой строки) + pop bc + ; сдвинуть остаток буфера на место сохр. строки + push hl + ld hl,(history_end) ; конец посл. строки истории + and a + sbc hl,de + and a + sbc hl,bc + ld c,l ; величина сдвига + ld b,h + pop hl ; откуда + ldir + ; восст. строку из врем. буфера в конец истории + ld hl,Buffers.work.buffer ; врем. буфер + ld c,(hl) + inc c + ld b,a + ldir +not_move_to_end: + ld a,(history_count) + dec a + ld (history_cur_string),a ; тек. строка history + pop de + xor a ; Z флаг + ret + + + + + +;!FIXIT к буферам почти всё +//////////////////////////////////////////////////////////////////////// +; 1 0 +;cursor_position: +; dw 0 ; Y/X полож. курсора + +; 2 0 +width_inpline: +.MAX EQU 80 + db width_inpline.MAX-4 ; тек. ширина поля ввода + +; 3 0 +YXpos: dw 0 ; Y/X начало ком-строки + +; 4 0 +; режим ввода +insert_mode: + db 1 ; 01/00 inser/overwrite + +; 5 0 +; экранный путь +; screen_path: +; db "A:" +; BLOCK max_screen_path+1,0 ; 32+1 + +; 6 0 +; системный путь +; system_path: +; BLOCK 256,0 ;!HARDCODE + +; ; 7 0 +; ; Структура строки ввода ~input line~ +; Buffers.input_line.: +; db max_len_comline ;+0 254 макс. число ввод. символов +; db 0 ;+1 флаг ReadyString +; db 0 ;+2 X тек. полож. курсора в пределах строки +; db 0 ;+3 X смещ. строки за левый край (в символах) +; db 0 ;+4 число введенных символов +; BLOCK max_len_comline+1,0 ;+5 строка ввода + +; ; 8 0 +; ; Буфер истории +; history_buff: +; BLOCK history_size,0 ; 256 + +; ; 9 0 +; ; Рабочий буфер +; Buffers.work.buffer: +; BLOCK 512,0 +//////////////////////////////////////////////////////////////////////// +; \ No newline at end of file diff --git a/Crazy Estex DSS/SHELL/EXEC.ASM b/Crazy Estex DSS/SHELL/EXEC.ASM new file mode 100644 index 0000000..60b77cf --- /dev/null +++ b/Crazy Estex DSS/SHELL/EXEC.ASM @@ -0,0 +1,206 @@ +; раб. ячейка +SAVEHL: dw 0 + + + +;------------------------------------------------------------- +; Разбор и выполнение введенных команд и имен файлов +;------------------------------------------------------------- +COMP: call EVALCMD ; (batch.asm) + ld hl,Buffers.input_line.Path + dec hl + ld c,(hl) ; длина строки + ld b,0 + inc hl ; Buffers.input_line.Path +.loop: ld a,(hl) + cp " " + jr nz,.COMP01 + inc hl + dec c + jr nz,.loop + ret +.COMP01: + ld d,h + ld e,l + add hl,bc + ld (hl),0 + sbc hl,bc + ld a,c + ex af,af' + ld a," " + cpir + jr nz,.COMP005 + inc c +.COMP005: + ex af,af' + sub c + ld c,a + ld hl,CMDLIST ; список команд ДОС-а +.start: call RUN_COMMAND + jr nc,.skip ; NC если не найдена команда + jp (hl) +.skip: ; Не дос-команды. Тест на задание диска и запуск файла + ld h,d + ld l,e + ; hl=Buffers.input_line.Path + ld b,(hl) ;+0 1-й символ + inc hl + ld c,(hl) ;+1 2-й символ + inc hl + ld a,(hl) ;+2 3-й символ + or a ; задан диск типа "x:" ? + jr nz,RUN_EXT ; нет, имеем больше 2-х символов + ld a,":" ; постфикс буквы диска + cp c ; 2-й символ + jr nz,RUN_EXT ; задан не диск + ld a,b ; 1-й символ + cp "a" + jr c,.NOUP + cp "z"+1 + jr nc,.NOUP + and #5F ; a..z -> A..Z +.NOUP: sub "A" ; номер диска + ld c,Dss.ChDisk ; сменить тек. диск + RST ToDSS + jp c,print_err_message ; вывод сообщения + +;!FIXIT тут восстанавливается директория и могут быть глюки на новом ядре + ;!TODO доставать Buffers.sys_path отдельно для каждого диска (или в ядре сделать?) + ; тест на существование папки на целевом диске + IFDEF MANY_SYS_PATHES + ld hl,Buffers.sys_path ; буфер сист. пути + ld c,Dss.ChDir ; уст. тек. путь + RST ToDSS + jp nc,Get_Path ; Ok + ENDIF + ; + + ; уст. корень, нет такой папки на новом диске + ld hl,Buffers.sys_path + 1 ; буфер сист. пути + ld (hl),0 + dec hl + ld (hl),'\' + + ;!TODO доставать system_path отдельно для каждого диска (или в ядре сделать?) + IFDEF MANY_SYS_PATHES + ld c,Dss.ChDir ; уст. тек. путь + RST ToDSS + jp c,print_err_message ; вывод сообщения + ENDIF + ; + jp Get_Path ; Ok + +; задан не диск +RUN_EXT: ex de,hl ; восст. адрес начала строки + ld (SAVEHL),hl ; Buffers.input_line.Path + ld de,EXTBF ; буфер + ld bc,4*256 + Dss.EX_Path ; выделить расш. файла + RST ToDSS + ld hl,(SAVEHL) ; имя файла + jr c,RUN_EXE ; выполнить exe-файл + bit 1,a ; есть расш. ? + jr z,.NON_EXT ; нет + ; есть расш. файла + ld de,EXTBF ; буфер расш. файла + ld hl,BATBF ; "BAT" + ld b,3 ; длина сравнения ;!HARDCODE + call COMPARE ; сравнить строки + ld hl,(SAVEHL) + jp z,RUN_BAT ; выполнить bat-файл (batch.asm) + jr RUN_EXE ; выполнить exe-файл +.NON_EXT: + ld bc,Dss.Exec ; загр. и выполнить программу + RST ToDSS + ;[x] 01/11/23 ;!TEST + PUSH AF + CALL RESTORE_ALL + POP AF + ; + ;[x] 25/10/23 + JP NC,Ret_New_Line ; Ok + ; + ld hl,(SAVEHL) + cp DSS_Error.sys.FILE_NOT_FOUND + jr nz,EXEERR + push hl + ;ld a,(D96AD) ; длина строки (inline.asm) + ld a,(Buffers.input_line.Symbols_Num) ; длина строки + ld b,a +.loop: ld a,(hl) + cp " "+1 + jr c,.next + inc hl + djnz .loop +.next: ld e,b + ld d,0 + add hl,de + push hl + ld e,4 + add hl,de + pop de + ex de,hl + ld c,b + ld b,0 + inc c + lddr + inc hl + ld (hl),"." + inc hl + ld (hl),"B" + inc hl + ld (hl),"A" + inc hl + ld (hl),"T" + pop hl + jp RUN_BAT ; выполнить bat-файл (batch.asm) + + +; Выполнить exe-файл +; hl=имя файла +RUN_EXE: + ld bc,Dss.Exec ; загрузить программу, выполнить файл + RST ToDSS + + ;[x] 01/11/23 ;!TEST + PUSH AF + CALL RESTORE_ALL + POP AF + ; + + ;[x] 25/10/23 + JP NC,Ret_New_Line ; Ok + ; +EXEERR: cp DSS_Error.sys.INVALID_HANDLE ; код ошибки "нет дескриптора" + jp nc,print_err_message ; вывод сообщения + xor a ; индекс "Bad command or file name" + jp print_err_message + +Ret_New_Line: + LD C,Dss.Cursor + RST ToDSS + XOR A + OR E + RET Z + jp newline + +RESTORE_ALL: + ;[x] 01/11/23 ;!TEST + CALL Get_Path + CALL .path + ;R10 + CALL Restore_Screen + ;R10 + RET + ; +.path: ;[x] 01/11/23 ;!TEST + LD A,(Buffers.screen_path) + SUB 'A' + LD C,Dss.ChDisk + RST ToDSS + ; + LD HL,Buffers.sys_path + LD C,Dss.ChDir + RST ToDSS + RET + ; +; \ No newline at end of file diff --git a/Crazy Estex DSS/SHELL/Messages/main_txt.asm b/Crazy Estex DSS/SHELL/Messages/main_txt.asm new file mode 100644 index 0000000..4237a7e --- /dev/null +++ b/Crazy Estex DSS/SHELL/Messages/main_txt.asm @@ -0,0 +1,68 @@ + + MACRO stN Name? +@Name? EQU txtCounter +!txtCounter=txtCounter+1 + ENDM + +MAIN_MSG: +; для удобства: +.DIR_1 EQU .DIR_1_ +.VERSION EQU .VERS_ +.DATE EQU .DATE_ +.TIME EQU .TIME_ +.PAUSE EQU .PAUSE_ +.DIR_ESCAPE EQU .DIR_ESC_ +.INVALID EQU .INV_ +.ECHO EQU .ECHO_ +.ON EQU .ON_ +.OFF EQU .OFF_ +.DIR_2 EQU .DIR_2_ +.DIR_3 EQU .DIR_3_ +.DIR_4 EQU .DIR_4_ +.HELP EQU .HELP_ +.CALCULATING EQU .CALC_ +.CRLF EQU .CRLF_ +.INFO_1 EQU .INFO_1_ +.INFO_2 EQU .INFO_2_ +; +!txtCounter DEFL 0 +; ; не сдвигать____ +.TABLE: : db 0; | + stN .CRLF_ : db CR,LF,0; | + ;________________/ + ; +; 1 2 3 4 5 6 7 +; 01234567890123456789012345678901234567890123456789012345678901234567890123456789; + stN .DIR_1_ : db "Volume in drive %1 %6 %7\r\n" + db "Volume Serial Number is %2, file sistem is %8\r\n" + DZ "\r\nDirectory of %3\r\n\n" + stN .VERS_ : DZ "Estex DSS version %1. Shell version %2.\r\n" ;R13 + stN .DATE_ : DZ "Current date: %1, %2\r\n" ; [x] вывод дня недели 26/01/2023 + stN .TIME_ : DZ "Current time: %1\r\n" + stN .PAUSE_ : DZ "Press any key to continue . . .\r" + stN .DIR_ESC_ : DZ "Command 'DIR' aborted by user \r\n\n" + stN .INV_ : DZ "Invalid parametr\r\n" + stN .ECHO_ : DZ "Echo is %1\r\n" + stN .ON_ : DZ "on" + stN .OFF_ : DZ "off" + stN .DIR_2_ : db "\r\n %3 File(s)\r %1 byte(s)\r\n" + DZ " %4 Dir(s)\r %5 byte(s) capacity\r\n" + stN .DIR_4_ : DZ " Free space %5 byte(s)\r\n" + stN .DIR_3_ : DZ "%4 %5 %3 %1 %2 \r\n" ;DATE TIME SIZE FILENAME EXT + stN .HELP_ : db "COMMANDS:\r\n" + db "CLS INFO REN = RENAME PATH HELP \r\n" + db "CD = CHDIR DEL = ERASE SET VER = VERSION \r\n" + db "MD = MKDIR TIME ECHO EXIT \r\n" + DZ "RD = RMDIR DATE REBOOT DIR [path] [/p /f] \r\n\n" + stN .CALC_ : DZ "Calculating free space...\r" + stN .INFO_1_ : DZ "\r\nDrive File System Label Serial number Size in bytes\r\n" + stN .INFO_2_ : DZ " %9 \r\t %8\r\t\t\t %7\r\t\t\t\t\t %4\r\t\t\t\t\t\t\t %5\r\n" +; ;R11 + db 0 + DZ "Unknown command" +; ; +.TABLE.Size EQU $-.TABLE +; +!txtCounter=0 +; + ; \ No newline at end of file diff --git a/Crazy Estex DSS/SHELL/Procedures/Print.ASM b/Crazy Estex DSS/SHELL/Procedures/Print.ASM new file mode 100644 index 0000000..fc1d8a2 --- /dev/null +++ b/Crazy Estex DSS/SHELL/Procedures/Print.ASM @@ -0,0 +1,115 @@ +;------------------------------------------------- +; Вывод сообщения ошибки по индексу +; вход: a=номер ошибки +;------------------------------------------------- +print_err_message: + ld e,a + ld d,0 + inc de + ld hl,ERR0 ; массив строк + ld bc,ERR0.Size ; размер массива + call LCPIR ; найти строку + call PRINTZ ; формат. вывод строки +; call newline + jp newline + + + +; Вывод строки ошибки +;A850D: +invalid_param: + ld de,MAIN_MSG.INVALID ; индекс "Invalid parametr" + jr ECHO_MESSAGE + + + +;------------------------------------------------- +; Вывод сообщения по индексу +; вход: de=индекс строки +;------------------------------------------------- +ECHO_MESSAGE: + call FMESAGE ; найти строку по индексу + jp PRINTZ ; формат. вывод строки + ;jp A82CC ; узнать и уст. полож. курсора + + +; Найти строку по индексу +; вход: de=индекс строки +; выход: hl=строка +FMESAGE: inc de + ld hl,MAIN_MSG.TABLE ; начало массива строк + ld bc,MAIN_MSG.TABLE.Size ; размер массива +LCPIR: xor a + cpir + ret po + ret nz + ;R11 + XOR A + CP (HL) + JR Z,.no_mess + ; + dec de + ld a,d + or e + jr nz,LCPIR + ret +.no_mess: INC HL + RET + +;[x] исправлен баг с выходом за пределы буфера PRM. Чуть оптимизирована +;----------------------------------------------------------------------; +; Форматированный вывод строки с подстановкой аргументов вместо %1-%9 +; вход: hl=буфер строки +;----------------------------------------------------------------------; +PRINTZ: ld a,(hl) + inc hl + or a + ret z + cp '%' + jr z,.check_PRM +.char: ld c,Dss.PutChar + RST ToDSS + jp PRINTZ +.bad_PRM: + ld a,'%' + jp .char +.check_PRM: + ld a,(hl) + cp '9'+1 + jr nc,.bad_PRM + inc hl + sub '1' + push hl + ;!TEST + ;ld l,a + ;ld h,0 + ;add hl,hl ;1+1=2 + ;add hl,hl ;2+2=4 + ;add hl,hl ;4+4=8 + ;add hl,hl ;8+8=16 размер отдельного подбуфера + ADD A + ADD A + ADD A + ADD A + LD L,A + LD H,0 + ; + ld bc,Buffers.bat_params.PRM1 + add hl,bc + ld c,Dss.PChars ; вывод строки + RST ToDSS + pop hl + jp PRINTZ + + +; буферы аргументов командной строки +; PRM1: BLOCK 16,0 ; аргумент %1 +; PRM2: BLOCK 16,0 ; аргумент %2 +; PRM3: BLOCK 16,0 ; аргумент %3 +; PRM4: BLOCK 16,0 ; аргумент %4 +; PRM5: BLOCK 16,0 ; аргумент %5 +; PRM6: BLOCK 16,0 ; аргумент %6 +; PRM7: BLOCK 16,0 ; аргумент %7 +; PRM8: BLOCK 16,0 ; аргумент %8 +; PRM9: BLOCK 16,0 ; аргумент %9 +; \ No newline at end of file diff --git a/Crazy Estex DSS/SHELL/Procedures/math.asm b/Crazy Estex DSS/SHELL/Procedures/math.asm new file mode 100644 index 0000000..84ae18d --- /dev/null +++ b/Crazy Estex DSS/SHELL/Procedures/math.asm @@ -0,0 +1,75 @@ +;----------------------------------------------------------------------; +; Вывод HL в hex-формате +; hl=число +; de=буфер +hex16_to_str: ld a,h + call hex8_to_str + ld a,l +hex8_to_str: push af + rrca + rrca + rrca + rrca + call .num + pop af + ; +.num: and %0000'1111 + add a,#90 + daa + adc a,#40 + daa + ld (de),a + inc de + ret +;----------------------------------------------------------------------; + + +;----------------------------------------------------------------------; +;!FIXIT есть дубль PDIGIT +; вход: hl=число, de=буфер +hex2dec_ascii_16bit: +.n10: ld ix,.tmp1 + res 7,(ix+0) + jr .decim + ; +.n10000: ld ix,.tmp1 + res 7,(ix+0) + ld bc,100 + call .num16 + jr .skip1 + ; +.n1000: ld ix,.tmp1 + res 7,(ix+0) +.skip1: ld bc,100 + call .num16 + jr .skip2 + ; +.n100: ld ix,.tmp1 + res 7,(ix+0) +.skip2: ld bc,100 + call .num16 + ; +.decim: ld bc,10 + call .num16 + ld a,l + add a,"0" + jr .num16_exit + ; +.num16: ld a,'0'-1 + and a + inc a + sbc hl,bc + jr nc,$-3 ;!FIXIT $ + add hl,bc + cp "0" + jr z,$+6 ;!FIXIT $ + set 7,(ix+0) + bit 7,(ix+0) + ret z +.num16_exit: + ld (de),a ; сохр. в буфере + inc de + ret + ; +.tmp1: BYTE 0 +;----------------------------------------------------------------------; diff --git a/Crazy Estex DSS/SHELL/Procedures/parsers.asm b/Crazy Estex DSS/SHELL/Procedures/parsers.asm new file mode 100644 index 0000000..7cccc6b --- /dev/null +++ b/Crazy Estex DSS/SHELL/Procedures/parsers.asm @@ -0,0 +1,134 @@ +//////////////////////////////////////////////////////////////////////// +; Вход: hl - список команд формата: "строка",0,cmd_addr +; de - строка с командой +; c - длина строки +; Выход: CF=1 - в HL адрес команды на исполнение +; CF=0 - нет опознаной команды +RUN_COMMAND: + push bc + push de + ; +.loop: ld a,(de) + cp "a" + jr c,.skip + cp "z"+1 + jr nc,.skip + and %0101'1111 ; a..z -> A..Z +.skip: cp (hl) + jr nz,.not_cmd ; не команда + inc hl + inc de + dec c + jr nz,.loop + ; + xor a + cp (hl) + jr nz,.not_cmd + pop bc + pop bc + ld a,(de) + cp " " + jr nz,.no_sp + inc de +.no_sp: inc hl + ld a,(hl) + inc hl + ld h,(hl) + ld l,a + scf ; маркер опознаной команды + ret + ;jp (hl) ; на соотв. обработчик команды +.not_cmd: + xor a + LD C,A + CPIR + inc hl + inc hl + pop de + pop bc + ld a,(hl) + or a + jr nz,RUN_COMMAND ; назад в цикл, еще не дошли конца списка дкоманд + ret + ; +//////////////////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////////////////// +; Вход: hl - список ключей формата: "строка",cmd_addr +; de - строка с командой +; c - длина строки с командой +; Выход: CF=1 - в HL адрес ключа на исполнение +; CF=0 - нет опознаного ключа +; !FIXIT переделать эту хрень +RUN_OPTION: +.cont: EX DE,HL + LD B,C +.loop: LD A,(HL) + CP '/' ; + INC HL + JR Z,.got + AND A + RET Z + DJNZ .loop + ; not found key + AND A + RET + ; +.got: LD C,B + INC HL + LD A,(HL) + DEC C + CP ' ' + JR Z,.good + AND A + JR NZ,RUN_OPTION.loop + ;LD C,1 + ; +.good: dec hl + push hl + ld b,cmd_dir_options.Size ;!HARDCODE + ex de,hl + ld a,(de) + OR %0010'0000 + ld de,cmd_dir_options.paramLength ;!HARDCODE + ; +.find: cp (hl) + jr z,.found + add hl,de + djnz .find + ; not found + pop hl + jr RUN_OPTION + ; found +.found: ; затираем найденый ключ + pop de + ex de,hl + ld (hl),' ' + dec hl + ld (hl),' ' + inc hl + inc hl + inc hl + ex de,hl + ;ld A,'/' + ;ex de,hl + ;ld bc,4 + ;CPDR + ;inc hl + ;ld (hl),' ' + ;inc hl + ;ld (hl),' ' + ;inc hl + ;ex de,hl + ; + LD B,C + inc hl + ld a,(hl) + inc hl + ld h,(hl) + ld l,a + scf ; маркер опознаной опции + ret + +//////////////////////////////////////////////////////////////////////// diff --git a/Crazy Estex DSS/SHELL/Procedures/shared.asm b/Crazy Estex DSS/SHELL/Procedures/shared.asm new file mode 100644 index 0000000..b223c6c --- /dev/null +++ b/Crazy Estex DSS/SHELL/Procedures/shared.asm @@ -0,0 +1,221 @@ +;----------------------------------------------------------------------; +; [x] теперь не лезет напрямую, делает через новый параметр функции DskInfo +; иная логика получения метки тома - сначала ищется в корневой директории, +; если там нет, то берётся из BPB +; Вход: выставить переменную read_disk_info.full: +; 0 - не считать свободное место, !0 - считать +; Выход: +; %7 - Volume label +; serial_string - Volume serial number string +; full_space_high \ +; full_space_medium - Partition size +; full_space_low / +; %6 - "has no label" or "has label" +; +read_disk_info: OR #80 + LD HL,Buffers.work.buffer +.full+1: LD B,0 + LD C,Dss.DskInfo + RST ToDSS + RET C + ; Файловая система + ; Серийный номер диска + ; Метка диска в BPB + ; Физический номер диска, номер раздела + ; + ; HL':HL - общее кол-во кластеров + ; DE':DE - свободных кластеров + ; A - размер кластера в секторах + ; BC - размер сектора в байтах + ; max sector (LBA28) #0FFF'FFFF + ; + EX AF,AF' + LD A,D + AND E + EXX + AND D + AND E + EXX + INC A + LD (.full),A + ; + AND H + + EX AF,AF' + ; + ; --> (HL':HL)*BC*A, (DE':DE)*BC*A = B':HL'HL, C':DE':DE + EXX + LD BC,0 + EXX + SRL B + RR C + RRCA + JR C,.loop2 + ; +.loop1: SLA L + RL H + EXX + RL L + RL H + RL B + EXX + ; + SLA E + RL D + EXX + RL E + RL D + RL C + EXX + ; + RRCA + JR NC,.loop1 + ; +.loop2: SLA L + RL H + EXX + RL L + RL H + RL B + EXX + ; + SLA E + RL D + EXX + RL E + RL D + RL C + EXX + ; + SRL B + RR C + JR NC,.loop2 + ; <-- B':HL'HL, C':DE':DE + EXX + LD A,C + LD (free_space_high),A + LD (free_space_medium),DE + ; + LD A,B + LD (full_space_high),A + LD (full_space_medium),HL + EXX + LD (free_space_low),DE + LD (full_space_low),HL + ; +.no_full_space_option: + ; parse + ; copy FS type + LD HL,Buffers.work.buffer + LD DE,Buffers.bat_params.PRM8; куда + LD B,0 + LD C,(HL) ; тут в HL длина поля "Файловая система" + INC HL + LDIR + EX DE,HL + LD (HL),0 + EX DE,HL + ; + LD D,0 + ; ; тут в HL длина поля "Файловая система" + ; LD E,(HL) + ; ADD HL,DE + ; INC HL + ; длина поля "Серийный номер диска" + LD A,(HL) + LD E,A + ADD HL,DE + INC HL + PUSH HL ; указатель на длину поля "Метка диска" + CP 4 ;!HARDCODE длина поля серийного номера + JR NZ,.unknown_serial + DEC HL + ; старшее слово серийника + LD D,(HL) + DEC HL + LD E,(HL) + DEC HL + PUSH HL + EX DE,HL + LD DE,serial_string ; xxxx-xxxx + CALL hex16_to_str + POP HL + ; + LD A,"-" + LD (DE),A + INC DE + ; младшее слово серийника + LD A,(HL) + DEC HL + LD L,(HL) + LD H,A + CALL hex16_to_str + ; +.get_label: ; тут в HL длина поля "Метка диска" + POP HL + LD A,(HL) + INC HL + AND A + JR Z,.no_volume_label ; да + PUSH HL + LD B,A + LD A,' ' + ; +.loop: CP (HL) + JR NZ,.good_label + INC HL + DJNZ .loop + POP HL ; снимаем лишнее + ; нет метки +.no_volume_label:; %6 + LD HL,volume_string_no ; строка + LD DE,Buffers.bat_params.PRM6; куда + CALL ncopy_string ; скопир. строку (с нулем) + XOR A + LD (Buffers.bat_params.PRM7),A + RET + ; +.good_label: POP HL + PUSH HL ; толкаем лишнее + ; есть метка +.volume_label: POP DE ; снимаем лишнее + ; %7 + LD DE,Buffers.bat_params.PRM7 + LD BC,11 ;!HARDCODE длина метки + LDIR + XOR A + LD (DE),A + ; %6 + LD HL,volume_string_yes ; строка + LD DE,Buffers.bat_params.PRM6; куда + XOR A + JP ncopy_string ; скопир. строку (с нулем) + ; + ; если не удалось прочитать серийный номер диска или формат неизвестен +.unknown_serial: ; серийный номер диска - неизвестен ;!HARDCODE ниже + LD HL,serial_string + LD A,'?' + LD B,serial_string.Size +.loop3: LD (HL),A + INC HL + DJNZ .loop3 + LD HL,serial_string+4 + LD (HL),'-' + JR read_disk_info.get_label + ; +/////////////////////////////////////////////////////////////////////// +free_space_low: WORD 0 +free_space_medium: WORD 0 +free_space_high: BYTE 0 +; Серийный номер диска +serial_string: db "xxxx-xxxx" +.Size equ $-serial_string + db 0 ; закрывашка +; +volume_string_no: db "has no label",0 +; +volume_string_yes: db "has label",0 +; +; has_not_full_info: db ' (?)',0 +/////////////////////////////////////////////////////////////////////// +;----------------------------------------------------------------------; \ No newline at end of file diff --git a/Crazy Estex DSS/SHELL/README.txt b/Crazy Estex DSS/SHELL/README.txt new file mode 100644 index 0000000..c4e6a8c --- /dev/null +++ b/Crazy Estex DSS/SHELL/README.txt @@ -0,0 +1,34 @@ +Сорцы рабочие!. Практически ничего не убирал из них, на случай вылезания +глюков. +Команда DIR выводит теперь метку и серийник дисков. + + +bat-команды: + PAUSE + REM + +дос-команды: + CD,CHDIR + CLS + DATE,TIME + DEL,ERASE + DIR + ECHO,ECHO. + EXIT + HELP + MD,MKDIR + PATH + REN,RENAME + RD,RMDIR + SET + VER,VERSION + + +Перемещение по истории команд: + + Esc - сбросить текущую строку + Ins - смена режима ввода (вставка/замена) + курс. клавиши вверх/вниз - прокрутка истории + PageUp - в начало истории + PageDown - в конец истории + Ctrl+Del - стереть историю diff --git a/Crazy Estex DSS/SHELL/SHELL.ASM b/Crazy Estex DSS/SHELL/SHELL.ASM new file mode 100644 index 0000000..8908e4f --- /dev/null +++ b/Crazy Estex DSS/SHELL/SHELL.ASM @@ -0,0 +1,595 @@ +; Последняя редакция: 22.10.2006 +; + + +; - Исправлен фирм. баг, при котором строка в bat-файле, длиннее ширины +; экрана, обрезалась по ширине экрана и остаток строки не выводился. +; - Исправлен фирм. баг, при котором в команде "dir" строка выводимого +; пути имела макс. 15 символов. +; - Пофиксено неверное изменение диска/пути после ошибок выполнения команд. +; - Добавлена команда "ECHO." для вставки пустой строки. +; - Команда DIR выводит метку и серийный номер дисков. +; +; + +; SYSTEM.EXE /S /P +; +; /P Primary command processor +; /S Secondary command processor +; /C Execute batch file + +;=====================================================================[] +;Rev. Date Name Description +;---------------------------------------------------------------------[] +;R14 22-09-2023 BAO Исправлен баг "File not found" в команде DIR на пустом разделе +;R13 03-08-2023 BAO Добавлен вывод номера версии Консоли для команды VERSION +;R12 23-07-2023 BAO Добавлена команда REBOOT - перезагрузка с полной очисткой памяти +;R11 20-07-2023 BAO Поправлена функция LCPIR для корректного выбора сообщения об ошибке при номере ошибки > заготовленных сообщений +;R10 16-05-2023 BAO TEХT MODE AND TEXT ARE RESTORED AFTER RETURNING FROM THE APP +;R08 21-02-2003 DNS FIX BUG IN BAT-PARSER, IT SPLIT STRINGS WHEN LINE BEGAN AT #xx00 OFFSET +;R07 14-12-2002 DNS PARSING BATCH LINE +;R06 12-12-2002 DNS ADD %0, %1, %2 ... +;R05 11-12-2002 DNS IMPLEMENTED %VAR% +;R04 11-12-2002 DNS ADD 'EVALSTRING' ROUTINE +;R03 11-12-2002 DNS NEW VERSION +;R02 19-11-2002 DNS CORRECT SOME ERROR MESSAGES +;R01 19-11-2002 DNS ADD ENVIRONMENT %VARIABLE% IN ECHO +;=====================================================================[] + DEFINE SHELL_COMPILATION 1 + DEFINE App_EXE_Version 1 + + includelua 'Shared_includes/lua/Functions.lua' + include 'shared_includes/constants/bios_equ.inc' + include 'shared_includes/constants/dss_equ.inc' + include 'SHELL/version.inc' + include 'shared_includes/structures/FileSystem.inc' + include 'SHELL/structures.inc' +; +; Program EQU section +;---------------------------------------------------------------------[] +CR EQU 13 +LF EQU 10 +true EQU 1 +false EQU 0 + +Loader_length EQU 0 +code_addr EQU shell +program_start EQU shell +stack_point EQU #C000 +stack_size EQU #100 +org_addr EQU #8000 + CLP_Buffer +;---------------------------------------------------------------------[] +; + + + +;work_buffer1 equ entry - (256+128) ; 2-й раб. буфер ; 128 bytes +;work_buffer2 equ entry - 256 ; 3-й раб. буфер ; 256 bytes + + + + + ; org 7F00h + + ; db "EX" ; exe ID + ; db 45h ; exe тип + ; db 0 ; exe версия + ; dw 512 ; 512, мл. смещ. кода + ; dw 0 ; ст. смещ. кода + ; dw 0 ; end-beg, первичный загрузчик + ; dw 0,0,0 ; резерв + ; dw entry ; адрес загрузки кода + ; dw shell ; адрес передачи управления + ; dw #BFFE ; адрес стека + ; ds 490 ; резерв + + +; Версия/Модификация/Билд шелла +;entry: db "0.01.003" ;!FIXIT перенести в конец + + INCLUDE 'Shared_Includes/constants/EXE_Header.z80' + ORG org_addr +;============================================================== +; Точка входа в Шелл +;============================================================== +shell: ld hl,Buffers + ld de,Buffers+1 + ld (hl),0 + ld bc,Struc_Buffers-1 + ldir + ; + ld hl,":A" + ld (Buffers.screen_path),hl + ld a,max_len_comline + ld (Buffers.input_line),a + ; + ; сохр. уровень тек. шелла + ld a,(ix-1) + ld (cmd_exit.TASKX),a + push ix + call Get_Path ; сохр. тек. диск и путь + pop hl ; hl=ix + ; + ; Тест на опции запуска самого шелла + call GET_CMD + ld a,(RUNMODE) ; бит-флаги опций + bit 7,a ; "P" 7-й бит (идет вызов из boot-загрузчика) + jr nz,FPRIMAR + bit 5,a ; "S" 5-й бит (запуск 2-й копии шелла) + ;jp nz,option_s + jr nz,run_shell + bit 4,a ; "C" 4-й бит (выполнить bat-файл) + jr nz,option_c + bit 6,a ; 6-й бит (вводились дополн. параметры) + jr z,back_to_parent_process + ; вводились дополн. параметры + call CMDMODE ; (batch.asm) выполн. команду или запустить файл + ; ^^^^^^^ + ;!TODO вложенные bat. передавать ошибку обратно в вызывающий bat + call Get_Path ; узнать и сохр. тек. диск и путь + ; + ; Вернуться в родит. процесс +back_to_parent_process: + ; [x] 11/12/23 вложенные bat + and a +.saveA: LD B,0 + JR NC,.exit + LD B,A +.exit: ld c,Dss.Exit + ;ld bc,0*256 + Dss.Exit + ; + JP ToDSS + + + +;--------------------------------------------------------------- +; Опция "S". Запуск 2-й копии шелла. Без отработки AUTOEXEC.BAT. +; Можно выйти по EXIT. +;--------------------------------------------------------------- +; option_s: +; call cmd_version ; версия ДОС +; jr run_shell + + + +;--------------------------------------------------------------- +; Опция "C". Выполнить BAT-файл. +; После выполнения файла, возвращается в родительский процесс. +;--------------------------------------------------------------- +option_c: + ;ld hl,T96AE ; имя bat-файла, 256 буфер (inline.asm) + ;ld hl,Buffers.work.buffer+256;; + ld hl,Buffers.input_line.Path ; имя bat-файла + call BATCH ; обработка bat-файла (batch.asm) + ;!TODO вложенные bat. передавать ошибку обратно в вызывающий bat + jr back_to_parent_process.saveA ; вернуться в родит. процесс + + + +;--------------------------------------------------------------- +; Опция "P". Запуск копии шелла. С отработкой AUTOEXEC.BAT. +; С ней идет вызов шелла из boot-загрузчика. +; Можно выйти по EXIT, но не из запущенного boot-загрузчиком. +;--------------------------------------------------------------- +FPRIMAR: + halt + ld c,Dss.CTRLKey ; узнать сост. клавы в данный момент + RST ToDSS + ld hl,autoexec_fname ; имя файла "system.bat" + ld a,b + and #C0 ; нажаты Shift-ы ? + call z,BATCH ; нет, выполнить bat-файл (batch.asm) +;============================================================== +; Запуск копии шелла +;============================================================== +run_shell: + call newline +run_shell_loop: + ;call A82CC ; узнать и уст. полож. курсора + ; вывести тек.сист. путь и войти в строку редактирования + call Get_Path ; узнать и сохр. тек. диск и путь +run_shell_loop1: + call input_line + call newline ; на новую строку + ld a,(Buffers.input_line.Symbols_Num) ; число введ. символов + or a + jr z,run_shell_loop1 ; пустая + ; Парсинг и выполнение команд + call COMP + jr run_shell_loop ; назад в цикл + + + + + + +; Тест опций шелла +; вход: hl=адрес ком-строки +GET_CMD: + ld e,(hl) ; длина строки + inc hl + ld d,0 + ex de,hl ; hl=длина строки, de=строка + add hl,de + ; убрать концевые пробелы +.loop1: dec hl + ld a,(hl) + cp " " + jr z,.loop1 + inc hl + ld (hl),0 ; в конец ком-строки +.NEXTPRM: + ex de,hl ; hl=тек. адрес в строке +.SKIPSP: + ld a,(hl) + inc hl + cp " " + ret c + jr z,.SKIPSP + dec hl + cp '/' ; опция + jr nz,.PROCESS + ld de,Buffers.work.buffer1 ; 128 буфер для параметра + ld c,Dss.GSwitch ; выдел. параметр ком-строки + RST ToDSS + push af + ex de,hl + ld hl,Buffers.work.buffer1 ; 128 буфер для параметра + inc hl + call set_option_flag ; уст. биты флагов + pop af + jr nc,.NEXTPRM + ret +; уст. бит-флаг +.PROCESS: + ld a,(RUNMODE) + set 6,a ; 6-й бит (вводились дополн. параметры) ;!HARDCODE + ld (RUNMODE),a + ; скопир. параметр из ком-строки + ; в буфер строки редактирования + ;copy_to_input_line: + ld iy,Buffers.input_line ; структура буфера ~input line~ + push hl + call clear_inpline ; обнулить структуру "input line" + pop de ; de=хвост строки +.loop: ld hl,Buffers.input_line ; структура буфера ~input line~ + ld a,(iy + Input_Line.Cur_X) ; X тек. полож. курсора в строке + add a,(iy + Input_Line.Left_Shift) + add a,l + ld l,a + jr nc,1F + inc h +1: inc hl + inc hl + inc hl + inc hl + inc hl + ld a,(de) ; символ из строки + ld (hl),a + or a + ret z ; конец строки + inc (iy + Input_Line.Symbols_Num) ; число введ. символов + inc (iy + Input_Line.Cur_X) ; X тек. полож. курсора в строке + ld a,(width_inpline) ; ширина поля ввода + cp (iy + Input_Line.Cur_X) ; X тек. полож. курсора в пределах строки + jr nz,2F + ; курсор за правым краем поля ввода + inc (iy + Input_Line.Left_Shift) ; смещ. строки за левый край + dec (iy + Input_Line.Cur_X) ; X тек. полож. курсора в пределах строки +2: ld a,(de) ; символ из строки + inc de ; продв. поток + cp " " + jr nc,.loop + ret + +; Тест на опции шелла и уст. бит-флагов +; вход: hl=строка опций +set_option_flag: + ld a,(RUNMODE) ; ячейка бит-флагов + ld c,a + ld a,(hl) + cp "a" + jr c,setopt1 + cp "z"+1 + jr nc,$+4 ;!FIXIT $ + and #5F ; a..z -> A..Z +setopt1: cp "P" ; запуск шелла с отраб. autoexec.bat + jr nz,setopt2 + set 7,c + jr setopt4 + ; +setopt2: cp "S" ; запуск 2-й копии шелла (без отраб. autoexec.bat) + jr nz,setopt3 + set 5,c + jr setopt4 + ; +setopt3: cp "C" ; выполн. bat-файл и вернуться в родит. процесс + ret nz + set 4,c +setopt4: ld a,c + ld (RUNMODE),a + ret + + +; Сохранить тек. диск и путь +;GETPATH: +Get_Path: + ; узнать тек. каталог + ld hl,Buffers.sys_path ; 256 буфер сист. пути + ld c,Dss.CurDir + RST ToDSS +.disk: ; узнать тек. диск + ld c,Dss.CurDisk + RST ToDSS + add a,"A" + ld (Buffers.screen_path),a ; 33 строка экранного пути + ret + + +; Восстановить тек. диск и путь (после ошибки) + IFUSED restore_disk_path + ASSERT restore_path +restore_disk_path: + ; уст. тек. диск + ld a,(Buffers.screen_path) ; 33 строка экранного пути + sub "A" + ld c,Dss.ChDisk + RST ToDSS + ENDIF + + IFUSED restore_path +restore_path: + ; уст. тек. каталог + ld hl,Buffers.sys_path ; 256 буфер сист. пути + ld c,Dss.ChDir + JP ToDSS + ret + ENDIF +; + + +newline: push hl + ld hl,MAIN_MSG.TABLE+1 ; "CR,LF,0" + ld c,Dss.PChars + rst ToDSS + pop hl + ret + +; Сравнение строк +; in: de=string1 +; hl=string2 +; b=длина строки +COMPARE: + ld a,(de) + cp "a" + jr c,.next + cp "z"+1 + jr nc,.next + and 5Fh ; a..z -> A..Z +.next: cp (hl) + ret nz + inc hl + inc de + djnz COMPARE + ret + + +; Скопир. строку (с нулем), макс. 15 символов +; (hl) -> (de) +ncopy_string: + ld bc,15 ; макс. длина строки +.start: ld a,(hl) + ldi + ret po + or a + jr nz,.start + ret + +; Скопир. строку (с нулем) +; (hl) -> (de) +copy_string: + ld a,(hl) + ldi + or a + jr nz,copy_string + ret + + + + + + +; Десятичный вывод в буфер +; вход: a=число +; hl=буфер +PUTB: ld c,2Fh +.loop: inc c + sub 10 + jr nc,.loop + add a,10 + add a,"0" + push af + ld a,c + ld (hl),a + inc hl + pop af + ld (hl),a + inc hl + ret + + + +STR2DEC: + ld hl,0 +.loop: ld a,(de) + inc de + or a + ret z + cp "." ; раздел. даты + ret z + cp "-" ; раздел. даты + ret z + cp ":" ; раздел. времени + ret z + ld b,h + ld c,l + add hl,hl + add hl,hl + add hl,bc + add hl,hl + call .ATODEC + ret c + add a,l + ld l,a + jr nc,.loop + inc h + jr .loop +.ATODEC:; char -> int + cp "0" + ret c + cp "9"+1 + ccf + ret c + sub "0" + ret + +;!FIXIT есть дубл hex2dec_ascii_16bit +PDIGIT: ld de,10000 + ld a,#C8 ; ret z + ld (.RET_Z),a + call .DIG + ld de,1000 + call .DIG + ld de,100 + call .DIG + ld de,10 + call .DIG + ld a,l + add a,"0" + ;!TEST пока не требуется передавать следующий IX дальше + ;ld (ix+0),a + ;inc ix + ;ld (ix+0),0 + LD (IX+0),A + LD (IX+1),0 + ; + ret +.DIG: xor a +.loop: inc a + sbc hl,de + jr nc,.loop + add hl,de + dec a +.RET_Z: ret z + add a,"0" + ld (ix+0),a + inc ix + xor a ; nop + ld (.RET_Z),a + ret + +Restore_Screen: + PUSH AF + LD C,Dss.GetVMod + RST ToDSS + CP #80 + JR C,.exit + LD BC,1 * 256 + Dss.SetVMod + LD A,Dss.SetVMod.txt80x32 + RST ToDSS +.exit: POP AF + RET + + + +; цвет экрана шелла +color_screen: + db 07h + + +; Имя файла "autoexec.bat" +autoexec_fname: + db "system.bat",0 + + +; бит-флаги опций самого шелла +RUNMODE: db 0 + + + +; буфер расш. файла с ограничителем 0 +EXTBF: BLOCK 4,0 + +BATBF: db "BAT" ; расш. bat-файла +T8C21: db "ON",0 +T8C24: db "OFF",0 + + + include 'edline.asm' ; строка редактирования + include 'batch.asm' ; парсинг bat-файлов + include 'exec.asm' ; выполн. введ. команд с консоли + include 'procedures/print.asm' ; функции вывода сообщений + include '../Shared_includes/constants/dss_errors.z80' ; сообщения об ошибках + include 'messages/main_txt.asm' ; сообщения + include 'procedures/parsers.asm' ; функции прочесывания и выбора + include 'procedures/math.asm' ; функции математические + include 'procedures/shared.asm' ; функции разные + ; + include 'Commands/exit.asm' ; выход в родит. процесс + include 'Commands/break.asm' ; выход из парсера bat + include 'Commands/pause.asm' ; пауза + include 'Commands/rem.asm' ; комментарий + include 'Commands/ver.asm' ; вывод версии ДОС + include 'Commands/cls.asm' ; очистка экрана + include 'Commands/date.asm' ; вывод или установка даты/времени + include 'Commands/dir.asm' ; вывод списка директории + include 'Commands/info.asm' ; вывод информации о дисках + include 'Commands/chdir.asm' ; смена тек. каталога + include 'Commands/mkdir.asm' ; создание каталога + include 'Commands/rmdir.asm' ; удаление каталога + include 'Commands/del.asm' ; удаление файла + include 'Commands/ren.asm' ; переименование файла или каталога + include 'Commands/echo.asm' ; эхо-режим + include 'Commands/help.asm' ; вывод экрана помощи + include 'Commands/path.asm' ; задать сист. путь + include 'Commands/set.asm' ; задать переменную окружения + include 'Commands/reboot.asm' ; софт ресет + ; + DISPLAY "Empty space for buffers from ",/H,$ + DISPLAY "Free space from ",/H,$ + Struc_Buffers + assert ($ + Struc_Buffers) < (stack_point - stack_size), "Buffers can leack to stack!" + +Buffers Struc_Buffers = $ + +; 5 0 +; экранный путь +;screen_path: +; db "A:" +; BLOCK max_screen_path+1,0 ; 32+1 +; 6 0 +; системный путь +; system_path: +; BLOCK 256,0 ;!HARDCODE +; 7 0 +; Структура строки ввода ~input line~ +; struct_input_line: +; db max_len_comline ;+0 254 макс. число ввод. символов +; db 0 ;+1 флаг ReadyString +; db 0 ;+2 X тек. полож. курсора в пределах строки +; db 0 ;+3 X смещ. строки за левый край (в символах) +; db 0 ;+4 число введенных символов +; BLOCK max_len_comline+1,0 ;+5 строка ввода + +; 8 0 +; Буфер истории +; history_buff: +; BLOCK history_size,0 ; 256 + +; 9 0 +; Рабочий буфер +; work_buffer: +; BLOCK 512,0 + +; work_buffer1 equ $ ; 2-й раб. буфер ; 128 bytes +; work_buffer2 equ work_buffer1+128 ; 3-й раб. буфер ; 256 bytes +; diff --git a/Crazy Estex DSS/SHELL/build.txt b/Crazy Estex DSS/SHELL/build.txt new file mode 100644 index 0000000..3fa694f --- /dev/null +++ b/Crazy Estex DSS/SHELL/build.txt @@ -0,0 +1 @@ +437 \ No newline at end of file diff --git a/Crazy Estex DSS/SHELL/structures.inc b/Crazy Estex DSS/SHELL/structures.inc new file mode 100644 index 0000000..db0218f --- /dev/null +++ b/Crazy Estex DSS/SHELL/structures.inc @@ -0,0 +1,37 @@ + STRUCT Input_Line +.max_Len BYTE 254 ;+0 254 макс. число ввод. символов +.ReadyString BYTE 0 ;+1 флаг ReadyString +.Cur_X BYTE 0 ;+2 X тек. полож. курсора в пределах строки +.Left_Shift BYTE 0 ;+3 X смещ. строки за левый край (в символах) +.Symbols_Num BYTE 0 ;+4 число введенных символов +.Path BLOCK max_len_comline+1,0 ;+5 строка ввода + ENDS + + STRUCT Work +.buffer BLOCK 512,0 +.buffer1 BLOCK 128,0 +.buffer2 BLOCK 256,0 +.free BLOCK 3840,0 + ENDS + +; буферы аргументов командной строки + STRUCT BAT_PARAMS +.PRM1: BLOCK 16,0 ; аргумент %1 +.PRM2: BLOCK 16,0 ; аргумент %2 +.PRM3: BLOCK 16,0 ; аргумент %3 +.PRM4: BLOCK 16,0 ; аргумент %4 +.PRM5: BLOCK 16,0 ; аргумент %5 +.PRM6: BLOCK 16,0 ; аргумент %6 +.PRM7: BLOCK 16,0 ; аргумент %7 +.PRM8: BLOCK 16,0 ; аргумент %8 +.PRM9: BLOCK 16,0 ; аргумент %9 Buffers.bat_params. + ENDS + + STRUCT Struc_Buffers +.bat_params BAT_PARAMS +.screen_path BLOCK 2 + max_screen_path + 1, 0 ; db "A:" : BLOCK max_screen_path+1,0 +.sys_path BLOCK 256,0 +.input_line Input_Line +.history BLOCK history_size,0 ; 256 +.work Work + ENDS diff --git a/Crazy Estex DSS/SHELL/version.inc b/Crazy Estex DSS/SHELL/version.inc new file mode 100644 index 0000000..d78a3bc --- /dev/null +++ b/Crazy Estex DSS/SHELL/version.inc @@ -0,0 +1,22 @@ +;------------------[ Достаём текущую дату и BUILD++ ]-----------------[] + LUA PASS1 + Console_build = increase_build("./SHELL/build.txt") + if Console_build > 999 then + Console_build = 999 + print("WARNING! Build > 999","WARNING! Build > 999","WARNING! Build > 999","WARNING! Build > 999","\aWARNING! Build > 999\a") + end + ENDLUA + LUA ALLPASS + sj.insert_label("lua_BUILD", Console_build) + ENDLUA +;---------------------------------------------------------------------[] + +; +; Shell full version +; номер версии (0..9) +CONSOLE_VERS EQU 1 +; номер модификации (0..99) +CONSOLE_MODF EQU 2 +; номер билда (0..999) +CONSOLE_BUILD EQU lua_BUILD +; \ No newline at end of file diff --git a/Crazy Updater/Pictures/Flash.bmp b/Crazy Updater/Pictures/Flash.bmp new file mode 100644 index 0000000..9fd46ed Binary files /dev/null and b/Crazy Updater/Pictures/Flash.bmp differ diff --git a/Crazy Updater/Pictures/Flash.inc b/Crazy Updater/Pictures/Flash.inc new file mode 100644 index 0000000..6d12a9a --- /dev/null +++ b/Crazy Updater/Pictures/Flash.inc @@ -0,0 +1,19 @@ +; For Flash.bmp + DEFINE PICTURE_FILE './Pictures/Flash.bmp' + DEFINE mpPB_Start_X 10 ; Начала прогрессбара в картинке + DEFINE mpPB_Erase 38 ; Координата прогрессбара + DEFINE mpPB_Write 62 ; Координата прогрессбара + DEFINE mpPB_Verify 94 ; Координата прогрессбара + DEFINE mpPB_Pixels 127 ; Длина прогрессбара + DEFINE mpPB_Empty_Color 0 ; Цвет пустого прогрессбара + DEFINE mpPB_Color 255 ; Цвет заполненого прогрессбара + DEFINE mpCH_Height 16 ; Высота области с чипом + DEFINE mpCH_Width 160 ; Ширина области с чипом + +/* + STRUCT MAIN_BMP +ChipsPic BLOCK mpCH_Width * mpCH_Height +MainPic BLOCK 160*168 + ENDS +*/ +; \ No newline at end of file diff --git a/Crazy Updater/Pictures/NEW_3_06.bmp b/Crazy Updater/Pictures/NEW_3_06.bmp new file mode 100644 index 0000000..680a19d Binary files /dev/null and b/Crazy Updater/Pictures/NEW_3_06.bmp differ diff --git a/Crazy Updater/Pictures/NEW_3_06.inc b/Crazy Updater/Pictures/NEW_3_06.inc new file mode 100644 index 0000000..6a7f1da --- /dev/null +++ b/Crazy Updater/Pictures/NEW_3_06.inc @@ -0,0 +1,55 @@ +; For NEW_3_06.bmp + DEFINE PICTURE_FILE 'Pictures/NEW_3_06.bmp' +mpPB_VERIFY_Start_X EQU 30 ; Начала прогрессбара в картинке +mpPB_ERASE_Start_X EQU 128 ; Начала прогрессбара в картинке +mpPB_WRITE_Start_X EQU 226 ; Начала прогрессбара в картинке +mpPB_Verify EQU 212 ; Координата прогрессбара +mpPB_Erase EQU 212 ; Координата прогрессбара +mpPB_Write EQU 212 ; Координата прогрессбара +mpPB_Pixels EQU 64 ; Длина прогрессбара +mpPB_Empty_Color EQU 196 ; Цвет пустого прогрессбара +mpPB_Color EQU 15 ; Цвет заполненого прогрессбара +mpCH_Height EQU 44 ; Высота области с чипами +mpCH_Width EQU 320 ; Ширина области с чипами + +MAIN_PICTURE: +.PIC_WIDTH EQU 320 +.PIC_HEIGHT EQU 300 +.PIC_SIZE EQU 96000 +.PIC_OFFSET EQU 1078 +.PIC_X EQU ((320-.PIC_WIDTH)/2) +.PIC_Y EQU ((256-(.PIC_HEIGHT-mpCH_Height))/2) +.CHIP_NAME_OFFSET EQU mpCH_Width * mpCH_Height ; !!!!! название неправильное +.CHIP_PIC_HEIGHT EQU mpCH_Height +.CHIP_PIC_WIDTH EQU mpCH_Width +.CHIP_HEIGHT EQU mpCH_Height/2 +.CHIP_WIDTH EQU mpCH_Width +.CHIP_Y EQU 255+.PIC_Y +.CHIP_X EQU 0 ; !!!!! тупое название, это смещение в картинке для вертикального разделения двух картинок чипов (как в старой версии биоса) +.CHIP_PIC_Y EQU .CHIP_Y +.CHIP_PIC_X EQU .PIC_X +.CHIP_FIRST_X EQU .CHIP_HEIGHT*.CHIP_WIDTH +.CHIP_SECOND_X EQU 0 + +PROGRESS_BAR: +.PICTURE_Y EQU MAIN_PICTURE.PIC_Y ; Смещение начала картинки по Y +.PICTURE_X EQU MAIN_PICTURE.PIC_X ; Смещение начала картинки по X +.ERASE_START_X: EQU mpPB_ERASE_Start_X+.PICTURE_X ; Начала прогрессбара в картинке +.WRITE_START_X: EQU mpPB_WRITE_Start_X+.PICTURE_X ; Начала прогрессбара в картинке +.VERIFY_START_X: EQU mpPB_VERIFY_Start_X+.PICTURE_X ; Начала прогрессбара в картинке +.ERASE EQU mpPB_Erase+.PICTURE_Y ; Координата прогрессбара +.WRITE EQU mpPB_Write+.PICTURE_Y ; Координата прогрессбара +.VERIFY EQU mpPB_Verify+.PICTURE_Y ; Координата прогрессбара +.PIXELS EQU mpPB_Pixels ; Длина прогрессбара, должна умещаться в BYTE +.EMPTY_COLOR EQU mpPB_Empty_Color ; Цвет пустого прогрессбара +.COLOR EQU mpPB_Color ; Цвет заполненого прогрессбара +;.STEP EQU 4 ; количество пикселей на один шаг прогрессбара (8 если шагов 16 и длина 128) + + +/* + STRUCT MAIN_BMP +ChipsPic BLOCK mpCH_Width*mpCH_Height +MainPic BLOCK 320*283 + ENDS +*/ +; \ No newline at end of file diff --git a/Crazy Updater/Pictures/good.bmp b/Crazy Updater/Pictures/good.bmp new file mode 100644 index 0000000..5383d4b Binary files /dev/null and b/Crazy Updater/Pictures/good.bmp differ diff --git a/Crazy Updater/Pictures/good.inc b/Crazy Updater/Pictures/good.inc new file mode 100644 index 0000000..01d9c16 --- /dev/null +++ b/Crazy Updater/Pictures/good.inc @@ -0,0 +1,55 @@ +; For good.bmp + DEFINE PICTURE_FILE 'Pictures/good.bmp' +mpPB_ERASE_Start_X EQU 88 ; Начала прогрессбара в картинке +mpPB_WRITE_Start_X EQU 88 ; Начала прогрессбара в картинке +mpPB_VERIFY_Start_X EQU 88 ; Начала прогрессбара в картинке +mpPB_Erase EQU 167 ; Координата прогрессбара +mpPB_Write EQU 203 ; Координата прогрессбара +mpPB_Verify EQU 131 ; Координата прогрессбара +mpPB_Pixels EQU 159 ; Длина прогрессбара +mpPB_Empty_Color EQU 0 ; Цвет пустого прогрессбара +mpPB_Color EQU 255 ; Цвет заполненого прогрессбара +mpCH_Height EQU 44 ; Высота области с чипом +mpCH_Width EQU 256 ; Ширина области с чипом + +MAIN_PICTURE: +.PIC_WIDTH EQU 256 +.PIC_HEIGHT EQU 278 +.PIC_SIZE EQU 71168 +.PIC_OFFSET EQU 1078 +.PIC_X EQU ((320-.PIC_WIDTH)/2) +.PIC_Y EQU ((256-(.PIC_HEIGHT - mpCH_Height))/2) +.CHIP_NAME_OFFSET EQU mpCH_Width * mpCH_Height ; !!!!! название неправильное +.CHIP_PIC_HEIGHT EQU mpCH_Height +.CHIP_PIC_WIDTH EQU mpCH_Width +.CHIP_HEIGHT EQU mpCH_Height/2 +.CHIP_WIDTH EQU mpCH_Width +.CHIP_Y EQU 233 + .PIC_Y +.CHIP_X EQU 0 ; !!!!! тупое название, это смещение в картинке для вертикального разделения двух картинок чипов (как в старой версии биоса) +.CHIP_PIC_Y EQU .CHIP_Y +.CHIP_PIC_X EQU .PIC_X +.CHIP_FIRST_X EQU .CHIP_HEIGHT * .CHIP_WIDTH +.CHIP_SECOND_X EQU 0 + +PROGRESS_BAR: +.PICTURE_Y EQU MAIN_PICTURE.PIC_Y ; Смещение начала картинки по Y +.PICTURE_X EQU MAIN_PICTURE.PIC_X ; Смещение начала картинки по X +.ERASE_START_X: EQU mpPB_ERASE_Start_X+.PICTURE_X ; Начала прогрессбара в картинке +.WRITE_START_X: EQU mpPB_WRITE_Start_X+.PICTURE_X ; Начала прогрессбара в картинке +.VERIFY_START_X: EQU mpPB_VERIFY_Start_X+.PICTURE_X ; Начала прогрессбара в картинке +.ERASE EQU mpPB_Erase+.PICTURE_Y ; Координата прогрессбара +.WRITE EQU mpPB_Write+.PICTURE_Y ; Координата прогрессбара +.VERIFY EQU mpPB_Verify+.PICTURE_Y ; Координата прогрессбара +.PIXELS EQU mpPB_Pixels ; Длина прогрессбара, должна умещаться в BYTE +.EMPTY_COLOR EQU mpPB_Empty_Color ; Цвет пустого прогрессбара +.COLOR EQU mpPB_Color ; Цвет заполненого прогрессбара +;.STEP EQU 10 ; количество пикселей на один шаг прогрессбара (8 если шагов 16 и длина 128) + + +/* + STRUCT MAIN_BMP +ChipsPic BLOCK mpCH_Width * mpCH_Height +MainPic BLOCK 320*283 + ENDS +*/ +; \ No newline at end of file diff --git a/Crazy Updater/RUN/IMG_File.sh b/Crazy Updater/RUN/IMG_File.sh new file mode 100755 index 0000000..a9da2b4 --- /dev/null +++ b/Crazy Updater/RUN/IMG_File.sh @@ -0,0 +1,13 @@ +#! /bin/zsh +sp_disk="$(hdiutil attach -imagekey diskimage-class=CRawDiskImage /Users/tolik/Documents/MAME/IMG/test_2g.img | grep -m 1 -o ^'/dev/disk[[:digit:]]\+')" +((ERROR_LEVEL +=$?)) +cp Build/$1 /Volumes/TMP_MAME/$1 +((ERROR_LEVEL +=$?)) +sp_disk="$(hdiutil detach "${sp_disk}")" +let "ERROR_LEVEL +=$?" +if [[ "$ERROR_LEVEL" == "0" ]]; then +echo "\nALL DONE!" >&2 +#exec "/Applications/CrossOver.app/Contents/SharedSupport/CrossOver/bin/wine" --bottle "ZXMAK2" --wait-children --check --start "C:/users/crossover/AppData/Roaming/Microsoft/Windows/Start Menu/ZXMAK2.lnk" +else +echo "\nError!!!" >&2 +fi \ No newline at end of file diff --git a/Crazy Updater/UPDATER.ASM b/Crazy Updater/UPDATER.ASM new file mode 100644 index 0000000..cef8c65 --- /dev/null +++ b/Crazy Updater/UPDATER.ASM @@ -0,0 +1,2359 @@ +; ███████╗██╗ █████╗ ███████╗██╗ ██╗███████╗██████╗ +; ██╔════╝██║ ██╔══██╗██╔════╝██║ ██║██╔════╝██╔══██╗ +; █████╗ ██║ ███████║███████╗███████║█████╗ ██████╔╝ +; ██╔══╝ ██║ ██╔══██║╚════██║██╔══██║██╔══╝ ██╔══██╗ +; ██║ ███████╗██║ ██║███████║██║ ██║███████╗██║ ██║ +; ╚═╝ ╚══════╝╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝ + +; [x] - выход в DSS, если чип не поддерживается +; [x] - универсальный EXE для K30 и K50 +; [x] - проверка контрольной суммы для BIOS и битстримов отдельно +; [x] - проверка на несовместимость старого битстрима с новым BIOS при прошивке по опции "R" +; [x] - правильное сохранение полного ID материнской платы +; [x] - правильная версия битстрима в случае обновления только BIOS + + +; +;---------[Compiling parameters]--------; + DEFINE _dIs_Updater 1 ; собирать отдельный прошивальщик или апдейтер вместе с образом ПЗУ + DEFINE _dLogingMode 0 ; + DEFINE _dDEBUG 0 ; компиляция для дебага + DEFINE NeedSafePort_Y 0 ; + DEFINE _dEMULATOR 1 ; 0 - hardware, 1 - "MAME", 2 - "ZXMAK" +;---------------------------------------; +; For _dLogingMode 1 + MACRO SHOW_STEP colors + IF _dLogingMode + PUSH HL + PUSH AF + LD HL,colors + CALL BORDER_FLASH + POP AF + POP HL + ENDIF + ENDM +; For _dLogingMode 1 +; Debug_Steps: +; ._1 EQU COLORS.CGA.BORDER.BLACK*256 + COLORS.CGA.BORDER.BLUE +; ._2 EQU COLORS.CGA.BORDER.BLACK*256 + COLORS.CGA.BORDER.GREEN +; ._3 EQU COLORS.CGA.BORDER.BLACK*256 + COLORS.CGA.BORDER.CYAN +; ._4 EQU COLORS.CGA.BORDER.BLUE*256 + COLORS.CGA.BORDER.GREEN +; ._5 EQU COLORS.CGA.BORDER.BLUE*256 + COLORS.CGA.BORDER.CYAN +; ._6 EQU COLORS.CGA.BORDER.GREEN*256 + COLORS.CGA.BORDER.CYAN + +;======================================= +; IF _dDEBUG +; DEVICE SPRINTER +; ENDIF +;======================================= + +;------------[LUA functions]------------; + INCLUDELUA 'Shared_Includes/LUA/Functions.LUA' +;---------------------------------------; + +;---------[BIOS and BITSTREAMS]---------; + DEFINE BIOS_K30_FILE '../SP_Core/Build/_SPRIN.BIN' + DEFINE BIOS_K30_FILE.BIOSlength 196608 ; !TODO можно цеплять длину из биосовского BUILD.ASM + DEFINE BIOS_K30_FILE.K30_OFFSET 196609 ; + + DEFINE K50_FILE '../SP_Core/Build/Bin/LOADER_K50.BIN' + DEFINE K50_FILE.Length 0 ; если стоит ноль, то подставляется размер файла. обычно 65536 байт + DEFINE LOADER.Length 256 ; !TODO привязаться потом к длине лоадера в исходниках биоса + + LUA PASS1 + -- Вычисляем контрольные суммы файлов + checksum_k30 = Get_checksum(sj.get_define("BIOS_K30_FILE"), sj.get_define("BIOS_K30_FILE.K30_OFFSET"), 0) + checksum_bios = Get_checksum(sj.get_define("BIOS_K30_FILE"), 0, sj.get_define("BIOS_K30_FILE.BIOSlength")) + checksum_k50 = Get_checksum(sj.get_define("K50_FILE"), 0, sj.get_define("K50_FILE.Length")) + checksum_loader = Get_checksum(sj.get_define("K50_FILE"), 0, sj.get_define("LOADER.Length")) + ENDLUA + LUA ALLPASS + sj.insert_define("LUA_CHECKSUM_K30", checksum_k30) + sj.insert_define("LUA_CHECKSUM_BIOS", checksum_bios) + sj.insert_define("LUA_CHECKSUM_K50", checksum_k50) + sj.insert_define("LUA_CHECKSUM_LOADER", checksum_loader) + ENDLUA +;---------------------------------------; + +;------------[Picture setup]------------; +; INCLUDE 'Pictures/Flash.inc' ; <---- Тут выбирается файл картинки и её описатели + INCLUDE 'Pictures/NEW_3_06.inc' ; <---- Тут выбирается файл картинки и её описатели +; INCLUDE 'Pictures/good.inc' ; <---- Тут выбирается файл картинки и её описатели + +/* + LUA PASS1 + -- Проверяем BMP и достаём из него параметры + bmp_width, bmp_height, bmp_image_size, bmp_image_offset, bmp_colors = Get_bmp8bit_values (sj.get_define("PICTURE_FILE")) + ENDLUA + LUA ALLPASS + sj.insert_define("LUA_BMP_WIDTH", bmp_width) + sj.insert_define("LUA_BMP_HEIGHT", bmp_height) + sj.insert_define("LUA_BMP_IMAGE_SIZE", bmp_image_size) + sj.insert_define("LUA_BMP_IMAGE_OFFSET", bmp_image_offset) + ENDLUA +*/ + +Screen_Offset EQU #0000 ; смещение в видеопамяти для данных (0/1 экран, например) + + INCLUDE 'Shared_Includes/structures/bmp.inc' +;---------------------------------------; + INCLUDE 'Shared_includes/constants/SP2000.inc' + INCLUDE 'Shared_includes/constants/dss_equ.inc' + +org_addr EQU SLOT2.MEM_ADDR+CLP_Buffer +stack_size EQU #80 +code_addr EQU Flasher_Start +program_start EQU Flasher_Start + + + MODULE expBIOS_Vars + INCLUDE 'constants/BIOS_EXP.INC' + ENDMODULE + + INCLUDE 'Versions.inc' + INCLUDE 'constants/ROM_CHIPS.inc' + INCLUDE 'Shared_includes/constants/standart_colors.inc' + INCLUDE 'Shared_includes/constants/BIOS_equ.inc' + INCLUDE 'Shared_includes/macroses/macros.z80' + INCLUDE 'Shared_includes/macroses/accelerator.z80' + + + +BoardNumOffsets: ; Смещения в EXP.asm по которым хранятся данные Board Number +.Number EQU expBIOS_Vars.BOARD_INFO.number +.Type EQU expBIOS_Vars.BOARD_INFO.type +.Start EQU expBIOS_Vars.BoardID.start +.End EQU expBIOS_Vars.BoardID.end + +; !FIXIT ; !HARDCODE +ROM_BITSTREAM: +.ROM EQU #1 ; половинка ПЗУ для sys_port_on где сидит битстрим +.PAGE EQU #0C ; страница в половинке ПЗУ для sys_port_on где начинается битстрим +.OFFSET EQU #100 ; смещение в странице по которому начинается битстрим +.CHIP EQU #4 ; смещение в битстриме по которому байт чипа лежит +.K30 EQU #39 ; Байт к30 +.K50 EQU #3C ; Байт к50 + + +; +;[] ============================================== [] + INCLUDE 'Shared_includes/constants/EXE_Header.z80' +;[] ============================================== [] + ORG org_addr +; + + +; IF _dDEBUG +; OUTPUT "Build/Debug.bin" +; ENDIF + +Flasher_Start: +; IF _dIs_Updater + IN A,(SLOT0) + LD (SET_ROM_MODE.Normal.slot0),A + LD A,(IX-3) + LD (FILE_HANDLE),A + LD A,I + LD (SET_ROM_MODE.Normal.int_vector),A + + LD C,Dss.Cursor + RST ToDSS + LD (cursor_restore),DE + + ; TEST CHIP + CALL SET_ROM_MODE.Flash + LD (SAVE_DCP_PORT),HL + ; + CALL TEST_ROM_CHIP + LD (TST_R.jp),BC + PUSH AF + CALL SET_ROM_MODE.Normal + POP AF + JP C,ITs_Unknown_Chip + LD C,Dss.GetVMod + RST ToDSS + JR C,1F ; если ошибка, то оставляем дефолтные значения режима и номера экрана + + LD (vid_mod_save),A + LD A,B + LD (scr_num_save),A + +1: LD IX,VideoModes.graf_mode320x256 + LD E,%00010001 + LD C,BIOS.WIN_OPEN + RST ToBIOS + JP C,Program_exit.video_mode + + LD IX,VideoModes.text_mode80x32 + LD E,%00000001 + LD C,BIOS.WIN_OPEN + RST ToBIOS + JP C,Program_exit.video_mode + + LD DE,0 + LD HL,#2050 + LD B,7 + LD A,32 + LD C,Dss.Clear + RST ToDSS + + LD HL,START_MSG + LD C,Dss.PChars + RST ToDSS + + CALL START_PIC + +; достаём номер версии биоса пользователя и проверяем можно ли его +; обновлять отдельно от битстрима + LD HL,0 ; буфер для строки ID биоса пихаем в ПЗУ, потому что не нужна + LD C,BIOS.FN_VERSION + RST ToBIOS + JR C,.too_old_bios + ; + LD HL,-#0305 ; проверка на биос выше 3.04 + ADD HL,DE + JR NC,.not_305 + ; если версия биоса > 3.04, то номер битстрима получаем иначе + PUSH DE ; на случай ошибки + LD HL,0 ; буфер для строки в ПЗУ - не нужен + LD BC,BIOS.FN_CRIPT.AcexAndBitstream + RST ToBIOS + JR NC,.is_new_bios + POP DE + JR .not_305 +.is_old_bios: ; +.is_new_bios: LD HL,-5 ; такой результат (4) будет на старой тестовой 3.05 в функции FN_CRIPT до добавления в неё версии bitstream + ADD HL,DE + POP HL + JR C,.is_super_new_bios + EX DE,HL +.is_super_new_bios:; +.not_305: LD (SAVE_BITSTREAM.romCNFversion),DE + LD HL,MinBiosVerForUserBitstream + XOR A + SBC HL,DE + LD HL,START_MSG.afterPICyes_R + JR C,.print_next_msg + +.too_old_bios: LD HL,0 + LD (.skip_r_key),HL ; mem patch - NOP : NOP вместо CP 'r' + LD HL,START_MSG.afterPICno_R + +.print_next_msg: + LD C,Dss.PChars + RST ToDSS + + LD C,Dss.Cursor + RST ToDSS + PUSH DE + LD (cursor_restore),DE + +.loop: LD C,Dss.WaitKey + RST ToDSS + OR #20 + CP 'y' + JR Z,.next + +.skip_r_key: CP 'r' + JR Z,.flash_only_bios + + CP 'p' + JP NZ,Program_exit.no_errors + + LD A,(REWRITE.pause) + XOR 1 + LD (REWRITE.pause),A + + LD HL,START_MSG.PauseTXT + LD C,Dss.PChars + RST ToDSS + + LD A,(REWRITE.pause) + OR A + LD HL,START_MSG.PauseON + JR NZ,.showPauseMSG + LD HL,START_MSG.PauseOFF + +.showPauseMSG: LD C,Dss.PChars + RST ToDSS + + LD DE,(cursor_restore) + LD C,Dss.Locate + RST ToDSS + JR .loop +;.exit: call Program_exit.no_errors + +.flash_only_bios: + LD A,#FF + LD (ONLY_BIOS),A + + ; ELSE + ; LD HL,BEGIN_MSG + ; LD C,Dss.PChars + ; RST ToDSS + ; ENDIF + +.next: XOR A + OUT (RGMOD),A + DI + + +;+++++++++++++++++++++++++++++++++++++++ + ; IFN dIs_Updater + ; CALL READ_FROM_FILE + ; ELSE + + CALL BUILD_FIRMWARE + LD A,(FILE_HANDLE) + LD C,Dss.Close + RST ToDSS + ;DI +; JP C,Program_exit.file +; ENDIF +;+++++++++++++++++++++++++++++++++++++++ + DI + + CALL NUMBER_COPY + CALL DrawProgress.done + +REWRITE: + IN A,(SLOT1) + LD (SV_PG1),A + ; !TODO Сделать сообщение об ошибке и пытаться дальше перезаписывать + ;LD A,(COUNT_ALL) + ;INC A + ;LD (COUNT_ALL),A + ;CP 6 ; 5 попыток + ;JR NZ,CONTINUE + ; +;-----------[PAUSE for reROM]-----------; +.pause+1: LD A,0 + AND A + JR Z,CONTINUE + + LD A,COLORS.CGA.BORDER.GREEN + OUT (BorderColor),A +.loop: + IN A,(ZXKeys) + AND %00011111 + XOR %00011111 + JR Z,.loop + + LD A,COLORS.CGA.BORDER.BLACK + OUT (BorderColor),A +;---------------------------------------; + JR CONTINUE + ; !TODO Сделать сообщение об ошибке и пытаться дальше перезаписывать + ; DI + ; HALT +;*********************************************************************** + +NUMBER_COPY: IN A,(SLOT3) + EX AF,AF' + LD A,#18 ;!HARDCODE + OUT (SLOT3),A + + + LD A,SYS_PORT.CNF_0 + OUT (SYS_PORT.ROM),A ; на всякий случай + + LD BC,256+BIOS.FN_CRIPT + RST ToBIOS_18 + JP C,Program_exit.no_BoardID + + LD (#C000+BoardNumOffsets.Start),BC + LD (#C000+BoardNumOffsets.Number),HL + LD (#C000+BoardNumOffsets.End),DE + LD (#C000+BoardNumOffsets.Type),A + + LD A,#10 ;!HARDCODE + OUT (SLOT3),A + LD A,(altera_chip) + LD (#C000+expBIOS_Vars.msgStrings.str_ACEX_MODEL),A + LD (#C000+expBIOS_Vars.msgRusStrings.str_ACEX_MODEL),A + + + EX AF,AF' + OUT (SLOT3),A + + RET + +CONTINUE: + CALL SET_ROM_MODE.Flash + +; di +; ld bc,#FFEE +; ld a,3 ; Z84.REG.Misc_Ctrl 3-rd register - boundaries +; out (c),a ; Z84.SYS.Control +; inc c +; ld a,1 ; cs0 enable, cs1 disable, 32-Bit CRC disable, reset output enable, Clock Divide-by-two +; out (c),a ; Z84.SYS.Data + +; dec c +; ld a,2 ; Z84.REG.CS_Boundary +; out (c),a ; Z84.SYS.Control +; inc c +; ld a,#F3 ; boundaries rom = 0000.3fff +; out (c),a ; Z84.SYS.Data +; ;------------------------------- +; LD BC,#1FFD +; XOR A +; OUT (C),A + +; ld a,#FF +; out (SLOT0),a +; ld a,#FE +; ld i,a ; убрать лишние обращения... + +; ;------------------------------- +; ;!FIXIT remove +; LD BC,ACEX.ROM_RG*256 + ACEX.ROM_RG +; CALL SET_DCP_PORT +; LD (SAVE_DCP_PORT),HL + +// in a,(SLOT1) +// push af +// ld a,DCP_PAGE +// out (SLOT1),a ; set dcp page +// LD A,(#4400) +// LD (SAVE_DCP_PORT.write),A +// LD A,(#4600) +// LD (SAVE_DCP_PORT.read),A +// ld a,ACEX.ROM_RG +// ld (#4400),a ; open for wr +// ld (#4600),a ; open for rd +// pop af +// out (SLOT1),a ; close SLOT1 + + LD A,COLORS.CGA.BORDER.BLACK + OUT (BorderColor),A + + ;LD A,SYS_PORT.CNF_0 + ;OUT (SYS_PORT.ON),A ; CNF0 + +; CALL SAVE_ROM_DATA + + + ;LD B,10 +TST_R: ;PUSH BC + + ; CALL READ_ID_ROM + ; EX DE,HL +.jp+1: LD HL,0 + JP (HL) + ; LD HL,ROM_CHIP.SST39SF020A + ; AND A + ; SBC HL,DE + ; JP Z,SST39SF020 + + ; LD HL,#76BF ; !HARDCODE + ; AND A + ; SBC HL,DE + ; JP Z,SST39SF020 + + ; LD HL,#10BF ; !HARDCODE + ; AND A + ; SBC HL,DE + ; JP Z,SST29EE020 + + ; LD HL,#24BF ; !HARDCODE + ; AND A + ; SBC HL,DE + ; JP Z,SST29EE020 + + ; LD HL,#45DA ; !HARDCODE + ; AND A + ; SBC HL,DE + ; JP Z,W29C020 + + ;POP BC + ;DJNZ TST_R + +ITs_Unknown_Chip: + CALL SET_ROM_MODE.Normal + JP Program_exit.unsupported_chip +;----------------------------------------------------------------------; + /* + LD (.SP),SP + + IN A,(SLOT3) + EX AF,AF' + LD A,Spec_Page + OUT (SLOT3),A + +.slot0+1: LD A,0 + LD (Spec_Page.page_0),A + IN A,(SLOT1) + LD (Spec_Page.page_1),A + IN A,(SLOT2) + LD (Spec_Page.page_2),A + EX AF,AF' + LD (Spec_Page.page_3),A + + LD HL,.restart + LD (Spec_Page.RET_addr),HL + + ; Set Spec_Page + LD A,DCP_PAGE + OUT (SLOT3),A + LD A,ACEX.RET_PORT + LD (#C400),A + LD BC,0 + LD A,Spec_Page + OUT (C),A + ; reset + LD A,16 + LD BC,#1FFD + OUT (C),A + LD A,RESET_PAGE + OUT (SLOT3),A +.loop: LD (#C000),A ; в этот момент подается RESET + JR .loop + ; + +.restart: + LD A,SYS_PORT.CNF_0 + OUT (SYS_PORT.OFF),A +.SP+1: LD SP,0 + JP Program_exit.unsupported_chip + */ +;----------------------------------------------------------------------; + +; ERROR_ROM: ; !TODO сделать нормальный выход в дос если чип не детектится. +; LD A,COLORS.CGA.BORDER.BLACK +; OUT (BorderColor),A +; LD A,COLORS.CGA.BORDER.CYAN +; OUT (BorderColor),A +; JR ERROR_ROM +;======================================= + ; IF _dIs_Updater +;--------------------------------------- +BUILD_FIRMWARE: LD A,DrawProgress.Verify + CALL DrawProgress.start + ; сначала загружаем и чекаем только биос + LD IX,(OFFSETS.BIOS) ; младшее слово смещения в файле + LD HL,(OFFSETS.BIOS+2) ; старшее слово смещения в файле + LD DE,CHECKSUMS.BIOS + LD BC,#101C ; !HARDCODE RAM for Bios file: #10 - first page, #1C - last page+1 + CALL Read_And_Check + + ; выбираем какой битстрим гнать в память + DI + LD A,ROM_BITSTREAM.ROM + OUT (SYS_PORT.ON),A + LD A,ROM_BITSTREAM.PAGE + OUT (ROM.SLOT0),A + LD HL,ROM_BITSTREAM.OFFSET+ROM_BITSTREAM.CHIP + + LD A,(HL) + LD B,A + XOR A + OUT (ROM.SLOT0),A + OUT (SYS_PORT.OFF),A + ; + LD A,B + CP ROM_BITSTREAM.K50 + JR NZ,.chek_k30 + ; + LD A,"5" + JR .save_chip + ; +.chek_k30: CP ROM_BITSTREAM.K30 + JP NZ,Program_exit.conf + LD A,"3" +.save_chip: LD (altera_chip),A ; сохраняем номер чипа 3 или 5 (1K30 или 1K50) + ; +.check_mode: LD A,(ONLY_BIOS) + INC A + JR Z,SAVE_BITSTREAM ; оставляем битстрим пользователя + LD A,B + ;--------------[Check bitstreams] +LOAD_BITSTREAM: + ;---[K30] + CP ROM_BITSTREAM.K30 + JR NZ,.next + LD IX,(OFFSETS.K30) ; младшее слово смещения в файле + LD HL,(OFFSETS.K30+2) ; старшее слово смещения в файле + LD DE,CHECKSUMS.K30 + LD BC,#1C20 ; !HARDCODE high начальная_страница low конечная_страница+1 + JP Read_And_Check + ;------[] +.next: CP ROM_BITSTREAM.K50 + JR NZ,.error + LD IX,(OFFSETS.K50) ; младшее слово смещения в файле + LD HL,(OFFSETS.K50+2) ; старшее слово смещения в файле + LD DE,CHECKSUMS.K50 + LD BC,#1C20 ; !HARDCODE high начальная_страница low конечная_страница+1 + JP Read_And_Check + ;---[check another] + ; на будущее +;1: +; CP ROM_BITSTREAM.XXX +; jr nz,1F +; ld ix,(OFFSETS.XXX) ; младшее слово смещения в файле +; ld hl,(OFFSETS.XXX+2) ; старшее слово смещения в файле +; ld de,CHECKSUMS.XXX +; ld bc,#1C20 ??? ; !HARDCODE high начальная_страница low конечная_страница+1 +; jp Read_And_Check +;----------------[] +.error: JP Program_exit.conf ; если битстрим неизвестный - выход с ошибкой +;------------------------------[] +;--------------------------------------- + +;--------------------------------------- +;-[Сохраняем битстрим пользователя]-[v] +SAVE_BITSTREAM: + IN A,(SLOT3) + PUSH AF + LD A,#1C ; !HARDCODE + OUT (SLOT3),A + + LD A,(FILE_HANDLE) + LD HL,#C000 ; !HARDCODE + LD DE,ROM_BITSTREAM.OFFSET + LD C,Dss.Read ; загружаем loader для конфы + RST ToDSS + DI + JP C,Program_exit.file + AND A + JP NZ,Program_exit.file + +;---[Loader checksum check] + LD BC,0 + LD DE,0 + LD HL,#C000 + +.checksumLoop: + LD A,C + ADD A,(HL) + LD C,A + JR NC,.NO_SM1 + LD A,B + ADD A,(HL) + LD B,A + JR NC,.NO_SM1 + LD A,E + ADD A,(HL) + LD E,A + JR NC,.NO_SM1 + LD A,D + ADD A,(HL) + LD D,A +; JR NC,NO_SM1 +.NO_SM1: + INC L ; проверка контрольной суммы 256 (0-255) байтов лоадера + JR NZ,.checksumLoop + + XOR A + LD HL,(CHECKSUMS.LOADER) + SBC HL,BC + JP NZ,Program_exit.checksum + XOR A + LD HL,(CHECKSUMS.LOADER+2) + SBC HL,DE + JP NZ,Program_exit.checksum +;---[x] + + LD A,ROM_BITSTREAM.ROM + OUT (SYS_PORT.ON),A + LD A,ROM_BITSTREAM.PAGE + OUT (ROM.SLOT0),A + LD HL,ROM_BITSTREAM.OFFSET + LD DE,#C000+ROM_BITSTREAM.OFFSET + LD BC,#4000-ROM_BITSTREAM.OFFSET + LDIR ; сохраняем битстрим 1/4 + + EX AF,AF' + LD A,3 + EX AF,AF' + + EXX + LD BC,SLOT3 + IN B,(C) +.loop: + INC B + OUT (C),B + EXX + + INC A + OUT (ROM.SLOT0),A + + EX DE,HL + LD B,D + LD C,E ; ld hl,0 bc,#4000 + LD DE,#C000 + LDIR ; сохраняем битстрим 2/4 - 4/4 + + EX AF,AF' + DEC A + JR Z,.change_number + EX AF,AF' + + EXX + CALL DrawProgress.next + JP .loop +;-[Сохраняем битстрим пользователя]-[^] +; +.change_number: + XOR A + OUT (ROM.SLOT0),A + OUT (SYS_PORT.OFF),A + +; меняем тут ID конфы в биосе + LD A,#18 ; !HARDCODE страница с EXP + OUT (SLOT3),A +.romCNFversion+1: + LD DE,0 + LD (#C000+expBIOS_Vars.FN_CRIPT.cnf),DE + LD HL,#C000+expBIOS_Vars.ID_SPRINTER.bitstream_ver + LD C,D + M_hex2dec2ascii_8bit 1 + INC HL + LD (HL),'.' + INC HL + LD C,E + M_hex2dec2ascii_8bit 2 + + POP AF + OUT (SLOT3),A + RET +;--------------------------------------- + + +;--------------------------------------- + +; +; на входе IX:IY - смещение +SET_OFFSET: + LD A,(FILE_HANDLE) + LD B,0 + LD C,Dss.Move_FP + RST ToDSS + DI + JP C,Program_exit.file + RET +; + +; Вход: +; ix - младшее слово смещения в файле +; hl - старшее слово смещения в файле +; DE - адрес в памяти с контрольной суммой +; B - начальная страница для файла +; C - конечная страница для файла +Read_And_Check: LD A,B + LD (.first_page),A + LD (Checksum_Check.first_page),A + + LD A,C + LD (.last_page),A + LD (Checksum_Check.last_page),A + + LD (Checksum_Check.compare),DE + + LD A,(FILE_HANDLE) + LD BC,0*256+Dss.Move_FP + RST ToDSS + DI + JP C,Program_exit.file + + IN A,(SLOT3) + PUSH AF + +.first_page+1: LD A,#10 + OUT (SLOT3),A + +.loop: LD A,(FILE_HANDLE) + LD HL,#C000 + LD DE,#4000 + LD C,Dss.Read + RST ToDSS + DI + JP C,Program_exit.file + AND A + LD HL,#4000 + SBC HL,DE + JP NZ,Program_exit.file + + IN A,(SLOT3) + INC A + OUT (SLOT3),A + +; CP #1C +; CALL Z,LOAD_BITSTREAM +.last_page+1: CP #20 + JR NZ,.loop + +Checksum_Check: + + ; LD A,#10 + ; OUT (SLOT3),A + /* + LD A,PROGRESS_BAR.VERIFY + CALL DrawProgress.start + */ +; LD IX,.ch_b + EXX + LD BC,0 + LD DE,0 + EXX +.first_page+1: LD A,#10 + +.main_loop: + OUT (SLOT3),A + PUSH AF + + EXX + LD HL,#C000 +.loop: + LD A,C + ADD A,(HL) + LD C,A + JR NC,.NO_SM1 + LD A,B + ADD A,(HL) + LD B,A + JR NC,.NO_SM1 + LD A,E + ADD A,(HL) + LD E,A + JR NC,.NO_SM1 + LD A,D + ADD A,(HL) + LD D,A +; JR NC,NO_SM1 +.NO_SM1: + INC HL + LD A,H + OR L + JR NZ,.loop + + EXX + LD B,PROGRESS_BAR.PIXELS / 16 +.progress: CALL DrawProgress.next + DJNZ .progress + + POP AF + INC A + +.last_page+1: CP #20 + JR NZ,.main_loop + + EXX + LD (.ch_b),BC + LD (.ch_b+2),DE + EXX + +;---[compare] +.compare+1: LD HL,0 + LD DE,.ch_b + LD B,4 +.ch_loop2: + LD A,(DE) + CP (HL) + JP NZ,Program_exit.checksum + INC HL + INC DE + DJNZ .ch_loop2 +;----------[] + /* + CALL DrawProgress.done + */ + POP AF + OUT (SLOT3),A + RET + +.ch_b: DB 0,0,0,0 +;--------------------------------------- +; ENDIF +; +;======================================= + + +W29C020: +SST29EE020: CALL ROM_PIC._29EE020 + CALL ERASE._29EE020 + CALL WRITE_29EE020 + CALL Pause._200msek + ; + LD A,DrawProgress.Verify + CALL DrawProgress.start + CALL VERIFY + ; + JP RESET + +SST39SF020: CALL ROM_PIC._39SF020 + + LD HL,1000 + LD (Pause.Erase),HL ; mem patch + + ; XOR A ;LD A,DrawProgress.Erase + ; CALL DrawProgress.start + CALL ERASE._39SF020 + + +; LD A,4+D_TBOFF ; отключить турбо при записи 39SF020 +; LD A,4+D_TBON +; OUT (SYS_PORT.OFF),A ; CNF0 + + ; LD A,DrawProgress.Write + ; CALL DrawProgress.start + CALL WRITE_39SF020 + +; LD A,4+D_TBOFF +; LD A,4+D_TBON +; OUT (SYS_PORT.OFF),A ; CNF0 + LD A,DrawProgress.Verify + CALL DrawProgress.start + CALL VERIFY + +; LD A,4+D_TBON +; OUT (SYS_PORT.OFF),A ; CNF0 + + JP RESET + +COUNT_ALL: DB 0 + +;********************************* + +RESET: + DI + +// IN A,(SLOT1) +// PUSH AF +// 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 + LD BC,ACEX.RESET*256+ACEX.RESET + CALL SET_DCP_PORT + + ;nop + ;!TEST Full init после перепрошивки и ресета, на всякий случай + LD A,SYS_PAGE + OUT (SLOT1),A + XOR A + LD (SYS_PAGE.ID_FLAG-#8000),A + ; + POP AF + OUT (SLOT1),A ; Close SLOT1 + LD A,COLORS.CGA.BORDER.BLACK + OUT (BorderColor),A + + LD A,CNF_PORT.CNF_0+CNF_PORT.TURBO.OFF + OUT (SYS_PORT.ON),A ; CNF0 + + CALL Pause._200msek + + LD A,CNF_PORT.CNF_0+CNF_PORT.TURBO.ON + OUT (SYS_PORT.ON),A ; CNF0 + +RESET_LOOP: + ;!TEST + ;LD BC,#0100 + ;OUT (C),C + ;LD BC,0 + ;OUT (C),C + LD A,Port_HardReset.Step1 + OUT (Port_HardReset),A + DEC A + OUT (Port_HardReset),A + ; + JR RESET_LOOP + + DI + HALT +;********************************* + +VERIFY: IN A,(SLOT1) + PUSH AF + CALL Pause._200msek + LD A,#1F + LD (vf_num),A +vf_loop: + LD E,CHIP_CMD.SST.ID_Exit + CALL L29EE.CMD + CALL Pause._50msek + CALL WAIT_TOGGLE + CALL Pause._50msek + ; LD A,DrawProgress.Verify + ; CALL DrawProgress.start + +; если будет ошибка в самом начале образа при верификации записи, то хоть немного подёргается прогрессбар + ;CALL DrawProgress.next + ;CALL DrawProgress.next + + LD A,#10 +TST_X: + EX AF,AF' ;!!!!! + LD HL,#4000 + LD DE,0 +LOOP_VF1X: + LD BC,0 + EX AF,AF' + OUT (SLOT1),A + OUT (C),A + EX AF,AF' + +LOOP_VF1: + ;!TEST + ; LD A,(DE) + ; CP (HL) + ; JR nz,error_xx + + ; INC L + ; INC E + ; JR NZ,LOOP_VF1 + + ; IVAN + LD A,(DE) + XOR (HL) + OR B + LD B,A + INC L + INC E + + LD A,(DE) + XOR (HL) + OR B + LD B,A + INC L + INC E + JR NZ,LOOP_VF1 + + AND A + JR NZ,error_xx + ; + + OUT (C),C ; возвращаем обратно 0 страницу ROM + + LD A,(vf_num) + AND 3 + LD (vf_num),A + + LD A,H + ;AND 7 ;!HARDCODE DrawProgress + ;CP 7 + AND 15 ;!HARDCODE DrawProgress + CP 15 + CALL Z,DrawProgress.next + + INC H + INC D + BIT 7,H + JR Z,LOOP_VF1X ; !!!!! точно LOOP_VF1X, а не LOOP_VF1 ? + + EX AF,AF' + INC A + CP #20 + JR NZ,TST_X + + CALL DrawProgress.done + POP AF + OUT (SLOT1),A + RET + +error_xx: LD A,COLORS.CGA.BORDER.CYAN + OUT (BorderColor),A + + LD A,(vf_num) + DEC A + LD (vf_num),A + JR NZ,vf_loop + JR ERROR_X + +vf_num: DB 3 +;********************************** +ERROR_X: +HALTS: LD BC,0 + OUT (C),C +SV_PG1+1: LD A,0 + OUT (SLOT1),A + JP REWRITE +; JP VERIFY + +;SV_PG1: DB 0 + +;************************************ +; IFN _dIs_Updater +; ;--------------------------------------- +; READ_FROM_FILE: + +; LD A,1 +; LD HL,ROM_FILE +; LD C,Dss.Open +; RST ToDSS +; ; !FIXIT error handler FLASHER +; DI + +; JR C,Program_exit.file +; LD (FILE_HANDLE),A + +; IN A,(SLOT3) +; PUSH AF +; LD A,10h +; OUT (SLOT3),A + +; LOOP_READ: +; LD A,(FILE_HANDLE) +; LD HL,#C000 +; LD DE,#4000 +; LD C,Dss.Read +; RST ToDSS +; DI +; JR C,Program_exit.file +; AND A +; LD HL,#4000 +; SBC HL,DE +; JR NZ,Program_exit.file + +; IN A,(SLOT3) +; INC A +; OUT (SLOT3),A + +; CP #20 +; JR NZ,LOOP_READ + +; LD A,(FILE_HANDLE) +; LD C,Dss.Close +; RST ToDSS +; DI + +; JR C,Program_exit.file + +; Checksum_Check: +; LD A,#10 +; OUT (SLOT3),A + +; LD HL,#C004 ; !TODO Собирать биос сразу с чексуммой? А тут тогда вставлять #FF. +; LD DE,.ch_a +; LD BC,4 +; LDIR + +; LD HL,#FFFF +; LD (#C004),HL ; !TODO если делать как написано выше, то для Апдейтера эту часть убрать условием компиляции +; LD (#C006),HL ; !TODO + +; LD A,PROGRESS_BAR.VERIFY +; CALL DrawProgress.start + +; ; LD IX,.ch_b +; EXX +; LD BC,0 +; LD DE,0 +; EXX +; LD A,#10 + +; .main_loop: +; OUT (SLOT3),A +; PUSH AF + +; EXX +; LD HL,#C000 +; .loop: +; LD A,C +; ADD A,(HL) +; LD C,A +; JR NC,.NO_SM1 +; LD A,B +; ADD A,(HL) +; LD B,A +; JR NC,.NO_SM1 +; LD A,E +; ADD A,(HL) +; LD E,A +; JR NC,.NO_SM1 +; LD A,D +; ADD A,(HL) +; LD D,A +; ; JR NC,NO_SM1 +; .NO_SM1: +; INC HL +; LD A,H +; OR L +; JR NZ,.loop + +; EXX +; LD B,8 + +; .progress: +; CALL DrawProgress.next +; DJNZ .progress + +; POP AF +; INC A + +; CP #20 +; JR NZ,.main_loop + +; EXX +; LD (.ch_b),BC +; LD (.ch_b+2),DE +; EXX + +; LD HL,(.ch_a) +; LD DE,(.ch_b) +; XOR A +; SBC HL,DE +; JR NZ,Program_exit.checksum + +; LD HL,(.ch_a+2) +; LD DE,(.ch_b+2) +; XOR A +; SBC HL,DE +; JR NZ,Program_exit.checksum + +; CALL DrawProgress.done +; POP AF +; OUT (SLOT3),A +; RET + +; .ch_a: DB 0,0,0,0 +; .ch_b: DB 0,0,0,0 + +; ENDIF + +SET_DCP_PORT: + IN A,(SLOT1) + PUSH AF + LD A,DCP_PAGE + OUT (SLOT1),A ; set dcp page + LD A,(#4400) + LD L,A + LD A,(#4600) + LD H,A + LD A,C + LD (#4400),A ; open for wr + LD A,B + LD (#4600),A ; open for rd + POP AF + OUT (SLOT1),A + RET + +;----------------[EXITS]-------------[v] +Program_exit: +.unsupported_chip: + LD HL,PROGRAM_MESSAGES.UNKNOWN_CHIP + LD BC,DSS_Error.sys.COMMON_ERROR*256+Dss.Exit + JR .exit +.no_BoardID: + LD HL,PROGRAM_MESSAGES.NO_BOARDID + LD BC,DSS_Error.sys.COMMON_ERROR*256+Dss.Exit + JR .exit + +.checksum: + LD HL,PROGRAM_MESSAGES.CHECKSUM + LD BC,DSS_Error.sys.CRC_ERROR*256+Dss.Exit + JR .exit + +.conf: + LD HL,PROGRAM_MESSAGES.CONF + LD BC,DSS_Error.sys.COMMON_ERROR*256+Dss.Exit + JR .exit + +.free_mem: + LD HL,PROGRAM_MESSAGES.MEM + LD BC,DSS_Error.sys.NOT_ENOUGH_MEMORY*256+Dss.Exit + JR .exit + +.video_mode: + LD HL,PROGRAM_MESSAGES.VIDEOMODE + LD BC,DSS_Error.sys.INVALID_VIDEO_MODE*256+Dss.Exit + JR .exit + +.file: + LD HL,PROGRAM_MESSAGES.FILE + LD BC,DSS_Error.sys.READ_ERROR*256+Dss.Exit + JR .exit + +.no_errors: + LD HL,PROGRAM_MESSAGES.GOODLUCK + LD BC,DSS_Error.sys.NO_ERROR*256+Dss.Exit +; JR .exit +.exit: PUSH BC + PUSH HL + +vid_mod_save+1: LD A,3 +scr_num_save+1: LD B,1 + LD C,Dss.SetVMod + RST ToDSS + +cursor_restore+1: + LD DE,0000 + LD C,Dss.Locate + RST ToDSS + + POP HL + LD C,Dss.PChars + RST ToDSS + +.loop: POP BC + PUSH BC + RST ToDSS + ; пытаемся выйти любой ценой))) + JR .loop +; +;/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\ +PROGRAM_MESSAGES: +; IF _dIs_Updater +.FILE: DZ 13,10,'Updater:\> Error: Read failure. ROM updater may be corrupted',13,10,10 +.MEM: DZ 13,10,'Updater:\> Error: Not enough free memory!',13,10,10 +; ELSE +; .FILE: DZ 13,10,13,10,'Updater:\> Error: ROM file is corrupt',13,10 +; ENDIF +.VIDEOMODE: DZ 13,10,'Updater:\> Error: Failed to initialize video mode!',13,10,10 +.CHECKSUM: DZ 13,10,'Updater:\> Error: Checksum is not correct!',13,10,10 +.CONF: DZ 13,10,'Updater:\> Error: Unsupported Altera installed!',13,10,10 +.NO_BOARDID: DZ 13,10,'Updater:\> Error: Unable to get board id from BIOS!',13,10,10 +.UNKNOWN_CHIP DZ 13,10,'Updater:\> Error: Unsupported ROM Chip installed!',13,10,10 +.GOODLUCK: DZ 13,10,'Updater:\> Good luck)))',13,10,10 + +; IFN _dIs_Updater +; BEGIN_MSG: DZ 13,10,"FLASH-ROM rewriter for Sprinter. Programmed by Ivan Mak." +; ROM_FILE: DB '_sprin.bin',0,0,0,0,0,0,0,0,0,0,0 +; ENDIF + +; IF _dIs_Updater +END_MSG: DZ 'Your ROM now rewrited! Press RESET please.' +START_MSG: DB 13,10,10 + DB 'ROM updater to ',HARDWARE_VERSION,' hardware and ',BIOS_VERSION,' BIOS',BIOS_BETA_VERSION,'versions.',13,10 + DB '2002 (',#91,') Peters Plus Ltd,',13,10 + DB SP_TEAM_YEAR,' (',#91,') Sprinter Team.',13,10,10,10,10,10 + DB 'Your ROM will be reflashed',13,10 + DB 'This operation can destroy your BIOS information if a power failure occurs!',13,10,10 + DB 'Do not press any keys while reflashing!',13,10 + DB 'After reflashing, your computer will restart.',13,10 + DZ 'Contact Sprinter Team if you need help.',13,10,10 +.afterPICyes_R: DB 'Press "Y" to start full reflashing or "R" for reflashing only BIOS and ZX-ROMs.',13,10 + DB 'If you need a pause to change the ROM before flashing, press "P".',13,10 + DZ 'Press any other key to cancel.',13,10 +.afterPICno_R: DZ 'Press "Y" to start full reflashing or any other key to cancel.',13,10 ; !FIXIT pause +.PauseTXT: DZ 'Pause: ' +.PauseON: DZ 'ON. Green border means waiting for any key to be pressed to continue.' ; /должна быть одинаковая длина\ +.PauseOFF: DZ 'OFF. ' ; \должна быть одинаковая длина/ +; ENDIF +;/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\ +;------------------------------------[^] +; + +;------------------------------------[v] +; IF _dIs_Updater + +READ_ID_ROM: AND A +.no_draw: PUSH AF + LD E,CHIP_CMD.ANY.ID + CALL L29EE.CMD + + CALL Pause._50msek + + LD BC,0 + LD A,#10 + OUT (C),A + LD HL,(0) ; rdlow-ok + OUT (C),C + + POP AF + PUSH HL + PUSH AF + LD E,CHIP_CMD.SST.ID_Exit + CALL L29EE.CMD + POP AF + JR C,.exit + ; + CALL Pause._50msek +.exit: POP HL + RET + +ERASE: +._39SF020: +._29EE020: CALL READ_ID_ROM + CALL Pause._200msek + + LD E,CHIP_CMD.SST.Erase + CALL L29EE.CMD + LD E,#20 ; data protect disable + CALL L29EE.CMD + + CALL Pause._200msek + + LD E,CHIP_CMD.SST.Erase + CALL L29EE.CMD + LD E,#10 ; Full chip erase + CALL L29EE.CMD + + LD A,DrawProgress.Erase + CALL DrawProgress.start + + LD B,128 ; необходимая задержка + LD A,128 / PROGRESS_BAR.PIXELS + OR A + JR NZ,.no_chg_A + LD A,1 + ; +.no_chg_A: PUSH AF +.LOOP_ERAS: CALL Pause._10msek + DEC A + JR NZ,.DJNZ + ; + CALL DrawProgress.next + POP AF + PUSH AF +.DJNZ: DJNZ .LOOP_ERAS + POP AF + CALL WAIT_TOGGLE + + CALL DrawProgress.done + + RET + +;********************************************* + +WRITE_39SF020: LD A,DrawProgress.Write + CALL DrawProgress.start + + ; IN A,(SLOT1) + ; LD (SV_PG1),A + + LD A,#10 + LD HL,#4000 + LD DE,0 + +LOOP_WS2: OUT (SLOT1),A + EX AF,AF' + +LOOP_WB2: LD A,(HL) + CP #FF + JR Z,NO_WRITE + + PUSH DE + LD E,#A0 + CALL L29EE.CMD + POP DE + + LD BC,0 + EX AF,AF' + OUT (C),A + EX AF,AF' + + LD A,(HL) + LD (DE),A + NOP + OUT (C),C + + CALL WAIT_TOGGLE + +NO_WRITE: INC L + INC E + JR NZ,LOOP_WB2 + INC H + INC D + LD A,D + ;AND 7 + ;CP 7 + AND 31 ;!HARDCODE DrawProgress + CP 31 + CALL Z,DrawProgress.next + + LD A,D + CP #40 + JR NZ,LOOP_WB2 + + LD HL,#4000 + LD DE,0 + + CALL DrawProgress.next + CALL DrawProgress.next + + EX AF,AF' + INC A + CP #20 + JR NZ,LOOP_WS2 + + CALL DrawProgress.done + + LD A,(SV_PG1) + OUT (SLOT1),A + RET + /* +ERROR_Y: + DI + HALT + */ +WRITE_29EE020: +; CALL READ_ID_ROM + + CALL L29EE.OFF + CALL Pause._200msek + CALL WAIT_TOGGLE + + LD A,DrawProgress.Write + CALL DrawProgress.start + +; если будет ошибка записи в самом начале, то хоть немного подёргается прогрессбар + CALL DrawProgress.next + CALL DrawProgress.next + + ; IN A,(SLOT1) + ; LD (SV_PG1),A + + LD A,#10 + PUSH AF + LD HL,#4000 + LD DE,0 +LOOP_WS: POP AF + PUSH AF + EX AF,AF' + POP AF + PUSH AF + EX AF,AF' + + PUSH HL + PUSH DE + CALL WRITE_SECTOR + JP C,HALTS ; error + POP DE + POP HL + + + ; = #4000 / (64 / 16) + ; 524288/64 + LD A,D + ;AND 15 + ;CP 15 + AND 31 ;!HARDCODE DrawProgress + CP 31 + CALL Z,DrawProgress.next + + LD BC,#80 + ADD HL,BC + EX DE,HL + ADD HL,BC + EX DE,HL + + LD A,D + CP #40 + JR NZ,LOOP_WS + + LD HL,#4000 + LD DE,#0000 + + POP AF + INC A + CP #20 + PUSH AF + JR NZ,LOOP_WS + POP AF + + CALL DrawProgress.done + + LD A,(SV_PG1) + OUT (SLOT1),A + RET + +; A,HL - BUFER, A',DE - ROM_PLACE +WRITE_SECTOR: OUT (SLOT1),A + EXX + LD B,20 +SECTOR_WRI1: EXX + + PUSH DE + CALL L29EE.WR + POP DE + + PUSH HL + PUSH DE + + LD BC,0 + EX AF,AF' + OUT (C),A + EX AF,AF' + + LD BC,128 ; LEN BLK + LDIR ; WRITE !!! + + OUT (C),C + + CALL Pause._10msek + + CALL WAIT_TOGGLE + + POP DE + POP HL + PUSH HL + PUSH DE + + EX AF,AF' + OUT (C),A + EX AF,AF' + + LD B,128 +LOOP_T: LD A,(DE) + CP (HL) + JR NZ,ERROR_SECTOR + + INC HL + INC DE + DJNZ LOOP_T + + OUT (C),C + + POP BC ; delete stack elements + POP BC + AND A ; ok write_sector + RET + +ERROR_SECTOR: LD B,C + OUT (C),C + + POP DE ; restore adresses + POP HL + + EXX + DJNZ SECTOR_WRI1 + EXX + + SCF ; error return + RET + + +WAIT_TOGGLE: PUSH AF + PUSH DE + PUSH HL + LD HL,0 + + LD A,(0) ; rdlow-ok + LD D,A + +TOGGLE_LOOP: INC HL + LD A,H + OR L + JR Z,TOGGLE_X + +; LD A,0 +; BIT 6,D +; JR Z,ZZZZ1 +; LD A,7 +;ZZZZ1: OUT (0FEh),A + + LD E,D + LD A,(0) ; rdlow-ok + LD D,A + + ; ;!TEST + ; OUT (#FE),A + + XOR E + AND #40 + JR NZ,TOGGLE_LOOP + + POP HL + POP DE + POP AF + AND A + RET + +TOGGLE_X: POP HL + POP DE + POP AF + SCF + RET + +; !TODO сохранять образ или нет? +SAVE_ROM_DATA: IN A,(SLOT1) + PUSH AF + + LD A,#10 +LOOP_SAVE: LD BC,0 + OUT (C),A + OUT (SLOT1),A + LD HL,0 + LD DE,#4000 + LD BC,#4000 + LDIR + INC A + CP #20 + JR NZ,LOOP_SAVE + + POP AF + OUT (SLOT1),A + RET + +;--------------------------------------- +L29EE: +.OFF: LD E,#80 + CALL .CMD + LD E,#20 + JR .CMD + ; +.WR: LD E,#A0 + ;JR .CMD + ; CMD in E register +.CMD: LD BC,0 + ; wr_rom #5555,#AA + LD A,#11 + OUT (C),A ; + LD A,#AA + LD (#1555),A + ; wr_rom #2AAA,#55 + LD A,#10 + OUT (C),A ; + LD A,#55 + LD (#2AAA),A + ; wr_rom #5555,#80 + LD A,#11 + OUT (C),A ; + LD A,E + LD (#1555),A + OUT (C),C + RET +;--------------------------------------- +Pause: +._50msek: + PUSH HL + PUSH AF + LD HL,10000 + JR ._200 + ; +._10msek: PUSH HL + PUSH AF +.Erase+1: LD HL,200 + JR ._200 + ; +._200msek: PUSH HL + PUSH AF + LD HL,20000 +._200: INC HL + DEC HL + INC HL + DEC HL + DEC HL + LD A,H + OR L + JR NZ,._200 + POP AF + POP HL + RET +;*******************************8 +START_PIC: IN A,(SLOT1) + PUSH AF + LD BC,#FF*256+BIOS.PIC_SET_PAL + LD HL,PICTURE.bdPallete + LD DE,0 + LD A,1 + RST ToBIOS + + + LD A,#50 + OUT (SLOT1),A + ACC_SetBlockSize + LD A,0 + ACC_Off + ;xor a + OUT (PORT_Y),A + LD HL,#4000+Screen_Offset + LD DE,#4000+Screen_Offset+1 + LD BC,319 + ACC_FillScreenOneByte + LD (HL),A + LDIR + ACC_Off + POP AF + OUT (SLOT1),A + PUSH AF + ; + LD IX,(OFFSETS.PICTURE_2) ; младшее слово смещения в файле + LD HL,(OFFSETS.PICTURE_2+2) ; старшее слово смещения в файле + LD A,(FILE_HANDLE) + LD B,0 + LD C,Dss.Move_FP + RST ToDSS + JP C,Program_exit.file + ; + DI + ; + IF MAIN_PICTURE.PIC_WIDTH < 256 + ACC_SetBlockSize + LD A,low MAIN_PICTURE.PIC_WIDTH + ACC_Off + ENDIF + ; + LD A,#FF - MAIN_PICTURE.PIC_Y +.loop_pic: PUSH AF + LD A,(FILE_HANDLE) + LD HL,.pic_buffer + LD DE,MAIN_PICTURE.PIC_WIDTH + LD C,Dss.Read + RST ToDSS + DI + JP C,Program_exit.file + AND A + JP NZ,Program_exit.file + + LD A,#50 + OUT (SLOT1),A + + POP AF + OUT (PORT_Y),A + + LD HL,.pic_buffer + LD DE,#4000+Screen_Offset+MAIN_PICTURE.PIC_X + ; + IF MAIN_PICTURE.PIC_WIDTH < 256 + ACC_CopyBlock + LD C,(HL) + LD (DE),A + ACC_Off + ELSE + LD BC,MAIN_PICTURE.PIC_WIDTH + LDIR + ENDIF + ; + LD H,A + POP AF + OUT (SLOT1),A + PUSH AF + + LD A,H + DEC A + CP MAIN_PICTURE.PIC_Y-1 + JR NZ,.loop_pic + + POP AF + OUT (SLOT1),A + IM 1 + EI + RET +.pic_buffer: BLOCK MAIN_PICTURE.PIC_WIDTH,0 + +ROM_PIC: +._39SF020: + LD HL,PICTURE.bdRaster+MAIN_PICTURE.CHIP_FIRST_X ;!!!!! MAIN_PICTURE.CHIP_PIC_WIDTH - MAIN_PICTURE.CHIP_WIDTH + JR .show +._29EE020: + LD HL,PICTURE.bdRaster+MAIN_PICTURE.CHIP_SECOND_X ;!!!!! +.show: + IN A,(SLOT1) + PUSH AF + LD A,#50 + OUT (SLOT1),A + + LD A,MAIN_PICTURE.CHIP_PIC_Y ; !!!!! относится к картинке + +.loop: OUT (PORT_Y),A + LD DE,#4000+Screen_Offset+MAIN_PICTURE.CHIP_PIC_X ; !HARDCODE + LD BC,MAIN_PICTURE.CHIP_WIDTH ; !HARDCODE + LDIR + LD BC,MAIN_PICTURE.CHIP_X ;160-76 ;!!!!! + ADD HL,BC + DEC A + CP MAIN_PICTURE.CHIP_PIC_Y-MAIN_PICTURE.CHIP_HEIGHT+1 ;PLACE_ID-16 ;!!!!! + JR NZ,.loop + + SAFE_PORTY + + POP AF + OUT (SLOT1),A + + RET +;----------------------------------------------------------------------- +DrawProgress: +.Erase EQU 0 +.Write EQU 1 +.Verify EQU 2 +; +.start: PUSH HL + PUSH DE + PUSH BC + LD (.CURRENT_BAR),A + ; + LD D,PROGRESS_BAR.ERASE + LD HL,#4000+Screen_Offset+PROGRESS_BAR.ERASE_START_X + OR A ;CP .Erase + JR Z,.set + ; + LD D,PROGRESS_BAR.WRITE + LD HL,#4000+Screen_Offset+PROGRESS_BAR.WRITE_START_X + CP .Write + JR Z,.set + ; + LD HL,#4000+Screen_Offset+PROGRESS_BAR.VERIFY_START_X + LD D,PROGRESS_BAR.VERIFY + ; +.set: LD A,D + LD (.LINE_PROG),A + LD (.PROGRESS_ST),HL + ; + IN A,(SLOT1) + PUSH AF + LD A,#50 + OUT (SLOT1),A + LD A,(.LINE_PROG) + OUT (PORT_Y),A + ; + ;LD DE,#4000+Screen_Offset+PROGRESS_BAR.START_X+1 + PUSH HL + POP DE + INC DE + LD BC,PROGRESS_BAR.PIXELS-1 + LD (HL),PROGRESS_BAR.EMPTY_COLOR + LDIR + ; + SAFE_PORTY + POP AF + OUT (SLOT1),A + POP BC + POP DE + POP HL + RET + +.next: PUSH HL + PUSH AF + IN A,(SLOT1) + PUSH AF + ; + LD A,#50 + OUT (SLOT1),A + LD A,(.LINE_PROG) + OUT (PORT_Y),A + ; + LD HL,(.PROGRESS_ST) + LD (HL),PROGRESS_BAR.COLOR + INC HL ; !TODO сделать тут проверку на выход за границы + LD (.PROGRESS_ST),HL + SAFE_PORTY + ; + POP AF + OUT (SLOT1),A + POP AF + POP HL + RET + +.done: PUSH BC + PUSH HL + PUSH AF + IN A,(SLOT1) + PUSH AF + ; + LD A,#50 + OUT (SLOT1),A + LD A,(.LINE_PROG) + OUT (PORT_Y),A + LD A,(.CURRENT_BAR) + ; + LD BC,#4000+Screen_Offset+PROGRESS_BAR.ERASE_START_X + OR A ;CP .Erase + JR Z,.sub + LD BC,#4000+Screen_Offset+PROGRESS_BAR.WRITE_START_X + CP .Write + JR Z,.sub + LD BC,#4000+Screen_Offset+PROGRESS_BAR.VERIFY_START_X + ; +.sub: LD HL,(.PROGRESS_ST) + XOR A + SBC HL,BC + LD A,PROGRESS_BAR.PIXELS + SUB L + JR Z,.exit + JR C,.exit + LD B,A + LD HL,(.PROGRESS_ST) + ; +.loop: LD (HL),PROGRESS_BAR.COLOR + INC HL + DJNZ .loop + ; +.exit: SAFE_PORTY + POP AF + OUT (SLOT1),A + POP AF + POP HL + POP BC + RET + ; +.LINE_PROG: BYTE 45 +.PROGRESS_ST: WORD 0 +.CURRENT_BAR: BYTE 0 +;----------------------------------------------------------------------- +; + +; +;======================================= +FILE_HANDLE: DB 0 +;======================================= +; + +; +VideoModes: +.text_mode80x32: + DB 40 + DB 32 + DB 0 + DB 0 + DB %00011011 + DB 0 + DB 0 + DB 0 +.graf_mode320x256: + DB 80 + DB 32 + DB 0 + DB 0 + DB %01100000 + DB 0 + DB 0 + DB 0 +; + +SAVE_DCP_PORT: +.write: BYTE 0 +.read: BYTE 0 +;.temp: WORD 0 + +; +; IF _dIs_Updater +altera_chip: BYTE 0 +CHECKSUMS: +;.BIOS_K30: DWORD LUA_CHECKSUM_K30_BIOS +.BIOS: DWORD LUA_CHECKSUM_BIOS +.K30: DWORD LUA_CHECKSUM_K30 +.K50: DWORD LUA_CHECKSUM_K50 +.LOADER: DWORD LUA_CHECKSUM_LOADER + +ONLY_BIOS: BYTE 0 + +OFFSETS: +.LOADER: DWORD IMAGES.K30 - exe_header +.K30: DWORD IMAGES.K30 - exe_header +.K50: DWORD IMAGES.K50 - exe_header +.BIOS: DWORD IMAGES.BIOS - exe_header +.PICTURE_2 DWORD PICTURE_2 - exe_header + + +TEST_ROM_CHIP: + LD B,10 +.loop: PUSH BC + SCF ;no draw progress + CALL READ_ID_ROM.no_draw + EX DE,HL + ; + LD HL,ROM_CHIP.SST39SF020A + AND A + SBC HL,DE + LD BC,SST39SF020 + JR Z,.detected + ; + LD HL,#76BF ; !HARDCODE + AND A + SBC HL,DE + ;LD BC,SST39SF020 + JR Z,.detected + ; + LD HL,#10BF ; !HARDCODE + AND A + SBC HL,DE + ;LD BC,SST39SF020 + JR Z,.detected + ; + LD HL,#24BF ; !HARDCODE + AND A + SBC HL,DE + ;LD BC,SST39SF020 + JR Z,.detected + ; + LD HL,#45DA ; !HARDCODE + AND A + SBC HL,DE + LD BC,W29C020 + JR Z,.detected + ; + POP BC + DJNZ .loop + LD BC,ITs_Unknown_Chip ; вдруг буду чего переделывать и забуду + SCF + RET +.detected: + POP HL ; снимаем лишнее + RET + + MODULE SET_ROM_MODE +; выход: HL - предыдущий номер внутреннего порта для нулевого внешнего из DCP +Flash: DI + ; Setup Z84 + ;!TODO добавить вэйты для ПЗУ? + ; + ; + ; Enable ROM boundaries + LD BC,#FF*256+Z84.SYS.Control + LD A,Z84.REG.Misc_Ctrl ; 3-rd register for setup boundaries + OUT (C),A ; Z84.SYS.Control + INC C + LD A,1 ; cs0 enable, cs1 disable, 32-Bit CRC disable, reset output enable, Clock Divide-by-two + OUT (C),A ; Z84.SYS.Data + DEC C + LD A,Z84.REG.CS_Boundary + OUT (C),A ; Z84.SYS.Control + INC C + LD A,#F3 ; boundaries rom = 0000.3fff + OUT (C),A ; Z84.SYS.Data + ; ; бордюр портится при записи в порт проца #EE из-за дешифрации карты портов + XOR A + OUT (BorderColor),A + ; SET ROM_RG Port + LD BC,ACEX.ROM_RG*256+ACEX.ROM_RG + CALL SET_DCP_PORT + PUSH HL + ; SET ROM PAGE 8 + LD A,SYS_PORT.CNF_0 + OUT (SYS_PORT.ON),A + ; + LD BC,#1FFD + XOR A + OUT (C),A + ;!TODO возможно, что это для Sp97 + LD A,#FF + OUT (SLOT0),A + LD A,#FE + LD I,A ; убрать лишние обращения... + ; + POP HL + RET +Normal: DI + ; Setup Z84 + ; Set ROM BIOS + XOR A + LD BC,0 + OUT (C),A + ; инициализация системных портов Z84C15 + LD BC,#FF*256+Z84.SYS.Control + XOR A ; Z84.REG.WaitState_Ctrl + OUT (C),A ; Z84.SYS.Control + INC C ; Z84.REG.WaitState_MemBound + OUT (C),A ; Z84.SYS.Data ; set 0 Waits + DEC C + LD A,Z84.REG.Misc_Ctrl + OUT (C),A ; Z84.SYS.Control + INC C + XOR A ; disable CS0, disable CS1 + OUT (C),A ; Z84.SYS.Data + ; ; бордюр портится при записи в порт проца #EE из-за дешифрации карты портов + XOR A + OUT (BorderColor),A + ; SET ROM PAGE 8 + LD A,SYS_PORT.CNF_0 + OUT (SYS_PORT.RAM),A + ; + LD BC,#1FFD + LD A,1 + OUT (C),A + ;!TODO возможно, что это для Sp97 +.slot0+1: LD A,0 + OUT (SLOT0),A +.int_vector+1: LD A,0 + LD I,A + ; RESET ROM_RG Port + LD BC,(SAVE_DCP_PORT) + CALL SET_DCP_PORT + RET + ENDMODULE + + IF _dLogingMode +;ВХОД: H - первый цвет бордюра +; L - второй цвет бордюра +; Мигает двумя цветами на бордюре до нажатия на клавишу +BORDER_FLASH: LD A,H + OUT (BorderColor),A + CALL Pause._200msek + CALL .key + ; + LD A,L + OUT (BorderColor),A + CALL Pause._200msek + CALL .key + JR BORDER_FLASH + ; +.key: XOR A + IN A,(ZXKeys) + AND %0001'1111 + XOR %0001'1111 + RET Z + ; + LD A,COLORS.CGA.BORDER.BLACK + OUT (BorderColor),A + POP HL + RET + ENDIF + +; ENDIF + + /* + DB "End of program." +; + BLOCK #8E00-$,0 +cmos_data: + + BLOCK data_start-$-#66,0 +stack_prog: + */ +; BLOCK data_start-$,0 + + + BLOCK stack_size,0 +stack_point EQU $-2 + +PICTURE TBitMapFileHeader = $ + DISPLAY "incbin length: ",/D,MAIN_PICTURE.PIC_OFFSET+MAIN_PICTURE.CHIP_NAME_OFFSET + + INCBIN PICTURE_FILE,0,MAIN_PICTURE.PIC_OFFSET+MAIN_PICTURE.CHIP_NAME_OFFSET + + ASSERT $ < #10000," Error: EXE-loader too big! " + +; IF _dIs_Updater +Loader_length EQU $-Flasher_Start + DISPLAY "Loader_length: ",/A,Loader_length + +;======================================= +; IF _dDEBUG +; OUTEND +; DEVICE NONE +; ENDIF +;======================================= + DISPLAY PICTURE_FILE,' ',/A,MAIN_PICTURE.PIC_OFFSET+MAIN_PICTURE.CHIP_NAME_OFFSET + + OUTPUT '../SP_Core/Build/updater_picture.bin' +PICTURE_2: INCBIN PICTURE_FILE,MAIN_PICTURE.PIC_OFFSET + MAIN_PICTURE.CHIP_NAME_OFFSET;+MAIN_PICTURE.PIC_WIDTH ; ;!!!!! +.length EQU $ - PICTURE_2 + OUTEND +IMAGES: +.BIOS: INCBIN BIOS_K30_FILE,0,#4000 * #0C ; образ BIOS +.K30: INCBIN BIOS_K30_FILE,#4000 * #0C,#10000 ; битстрим для K30 с загрузчиком +.K50: INCBIN K50_FILE,0,#10000 ; битстрим для K50 с загрузчиком +.end EQU $ +; ELSE +; Loader_length EQU 0 +; ENDIF + +; IF _dIs_Updater + DISPLAY "Image reolution: ",/D,MAIN_PICTURE.PIC_WIDTH,"x",/D,MAIN_PICTURE.PIC_HEIGHT," pixels. Size: ",/D,MAIN_PICTURE.PIC_SIZE," bytes." + DISPLAY "Code ends: ",/A,PICTURE + DISPLAY "Code Length: ",/A,PICTURE-Flasher_Start + DISPLAY "Loader ends: ",/A,Loader_length+Flasher_Start + DISPLAY "Loader Length: ",/A,Loader_length + + DISPLAY "IMAGES.K30 Starts: ",/A,IMAGES.BIOS + DISPLAY "IMAGES.K30 Ends: ",/A,IMAGES.K50 + DISPLAY "IMAGES.K30 Length: ",/A,IMAGES.K50-IMAGES.BIOS + + DISPLAY "IMAGES.K50 Starts: ",/A,IMAGES.K50 + DISPLAY "IMAGES.K50 Ends: ",/A,IMAGES.end + DISPLAY "IMAGES.K50 Length: ",/A,IMAGES.end-IMAGES + + DISPLAY "PIC_Y: ",/H,MAIN_PICTURE.PIC_Y + DISPLAY "PIC_HEIGHT: ",/H,MAIN_PICTURE.PIC_HEIGHT + DISPLAY "CHIP_HEIGHT: ",/H,MAIN_PICTURE.CHIP_HEIGHT + IF _dDEBUG|_dLogingMode + DISPLAY "\nWARNING! Debug version!!! WARNING! Debug version!!! WARNING! Debug version!!!\n" + ENDIF + + + EXPORT BoardNumOffsets.Start + EXPORT BoardNumOffsets.Number + EXPORT BoardNumOffsets.End + EXPORT BoardNumOffsets.Type + EXPORT expBIOS_Vars.msgStrings.str_ACEX_MODEL + EXPORT expBIOS_Vars.msgRusStrings.str_ACEX_MODEL + EXPORT PICTURE.bdPallete + EXPORT TEST_ROM_CHIP + EXPORT TST_R.jp + EXPORT MAIN_PICTURE.PIC_X + EXPORT MAIN_PICTURE.PIC_Y + EXPORT MAIN_PICTURE.PIC_WIDTH + EXPORT Screen_Offset + +; ENDIF +; END +;****************************************************** + + /* +; + LD BC,#FFEE + XOR A + OUT (C),A ; 0 register - waits + INC C + OUT (C),A ; set 0 Waits + + DEC C + LD A,3 ; 3-rd - Misc.Control Register + OUT (C),A + INC C + + XOR A + LD A,1 + + OUT (C),A ; disable CS0,CS1 +; no boundary set! + + LD BC,#7FFD + LD A,#10 + OUT (C),A ; BASIC_48 mode + LD B,#1F + LD A,01 + OUT (C),A ; RAM-0 mode !!! + +; out (slot3),saved_page + + */ + + + /* +PRINT_LINE: ; from HL, zero - end + + IN A,(SLOT1) + EX AF,AF' + LD A,50h + OUT (SLOT1),A + LD A,01h ; first place + OUT (PORT_Y),A + + LD A,(VARX) + AND A + JR NZ,NO_VARS + LD A,(4300h) + LD A,C + LD (VARX),A +NO_VARS: + LD C,A + + LD DE,04301h ; symbol place +PRINT_LOOP: + LD A,(HL) + AND A + JR Z,PRINT_END + + LD (DE),A ; symbol + DEC E + LD A,C + LD (DE),A ; MODE + INC E + INC E + LD A,07h ; color + LD (DE),A + DEC E + + INC HL + IN A,(PORT_Y) + INC A + OUT (PORT_Y),A + JR PRINT_LOOP + + LD BC,(4300h) +PRINT_END: + LD A,#C0 ; close + OUT (PORT_Y),A + EX AF,AF' + OUT (SLOT1),A + + RET + +VARX: DB 0 + */ +; diff --git a/Crazy Updater/Versions.inc b/Crazy Updater/Versions.inc new file mode 100644 index 0000000..67d4e53 --- /dev/null +++ b/Crazy Updater/Versions.inc @@ -0,0 +1,12 @@ +; + LUA ALLPASS + sj.insert_define("SP_TEAM_YEAR", "'" .. os.date("%Y") .. "'") + ENDLUA + DEFINE HARDWARE_VERSION '0'+expBIOS_Vars.CNF_ID.VER, '.', '0'+expBIOS_Vars.CNF_ID.MOD/10, '0'+expBIOS_Vars.CNF_ID.MOD-(expBIOS_Vars.CNF_ID.MOD/10)*10 + DEFINE BIOS_VERSION '0'+expBIOS_Vars.EXP_ID.VER, '.', '0'+expBIOS_Vars.EXP_ID.MOD/10, '0'+expBIOS_Vars.EXP_ID.MOD-(expBIOS_Vars.EXP_ID.MOD/10)*10 + IF expBIOS_Vars.BETA_BUILD > 0 + DEFINE BIOS_BETA_VERSION ' BETA ', '0'+expBIOS_Vars.BETA_BUILD, ' ' + ELSE + DEFINE BIOS_BETA_VERSION ' ' + ENDIF +MinBiosVerForUserBitstream equ #020E ; 2.14 \ No newline at end of file diff --git a/Crazy Updater/constants/BIOS_EXP.inc b/Crazy Updater/constants/BIOS_EXP.inc new file mode 100644 index 0000000..d0ff179 --- /dev/null +++ b/Crazy Updater/constants/BIOS_EXP.inc @@ -0,0 +1,14 @@ +BOARD_INFO.number: EQU 0x00000003 +BOARD_INFO.type: EQU 0x00000005 +BoardID.start: EQU 0x0000008F +BoardID.end: EQU 0x00000091 +FN_CRIPT.cnf: EQU 0x000019EA +ID_SPRINTER.bitstream_ver: EQU 0x00000089 +bitstream_ver_hex: EQU 0x00000305 +EXP_ID.VER: EQU 0x00000003 +EXP_ID.MOD: EQU 0x00000006 +CNF_ID.VER: EQU 0x00000003 +CNF_ID.MOD: EQU 0x00000005 +msgStrings.str_ACEX_MODEL: EQU 0x000024DD +msgRusStrings.str_ACEX_MODEL: EQU 0x00002EED +BETA_BUILD: EQU 0x00000006 diff --git a/Crazy Updater/constants/ROM_CHIPS.inc b/Crazy Updater/constants/ROM_CHIPS.inc new file mode 100644 index 0000000..5a0d9b7 --- /dev/null +++ b/Crazy Updater/constants/ROM_CHIPS.inc @@ -0,0 +1,38 @@ +; CHIP/Manufacturer +ROM_CHIP: + IF _dEMULATOR = 1 ; MAME +.SST39SF010A EQU #76F3 ; 128 kb (#BF - SST) +.SST39SF020A EQU #76F3 ; 256 kb (#BF - SST) +.SST39SF040 EQU #76F3 ; 512 kb (#BF - SST) +.IS28F020 EQU #76F3 ; 256 kb (#D5 - ISSI) + ELSEIF _dEMULATOR = 2 ; ZXMAK +.SST39SF010A EQU #A0C3 ; 128 kb (#BF - SST) +.SST39SF020A EQU #A0C3 ; 256 kb (#BF - SST) +.SST39SF040 EQU #A0C3 ; 512 kb (#BF - SST) +.IS28F020 EQU #A0C3 ; 256 kb (#D5 - ISSI) +; + ELSE ; for hardware +; +.SST39SF010A EQU #B5BF ; 128 kb (#BF - SST) +.SST39SF020A EQU #B6BF ; 256 kb (#BF - SST) +.SST39SF040 EQU #B7BF ; 512 kb (#BF - SST) +.IS28F020 EQU #B4D5 ; 256 kb (#D5 - ISSI) +; + ENDIF + + MODULE CHIP_CMD +ANY: +.ID EQU #90 + +ISSI: +.Read EQU 0 +.Erase EQU #20 +.Verify_Erase EQU #A0 ; to address #EA +.Write EQU #40 +.Verify_Write EQU #C0 +.Reset EQU #FF +SST: +.Erase EQU #80 +.Write EQU #A0 +.ID_Exit EQU #F0 + ENDMODULE \ No newline at end of file diff --git a/Crazy Updater/structures/bmp.inc b/Crazy Updater/structures/bmp.inc new file mode 100644 index 0000000..c7bc2a6 --- /dev/null +++ b/Crazy Updater/structures/bmp.inc @@ -0,0 +1,31 @@ +; + STRUCT MAIN_BMP +ChipsPic BLOCK mpCH_Width * mpCH_Height +;MainPic BLOCK 160*168 ; !!!!!! hardcode +MainPic BYTE + ENDS + + STRUCT TBitMapFileHeader ; = 14 bytes +bfType WORD ; 'BM' +bfSize DWORD ; размер всего файла +bfReserved DWORD 0 ; +bfOffBits DWORD ; начало битового массива относительно начала файла + +;---[File Info] ; = 40 bytes +biSize DWORD 40 ; Количество байтов в DIB header (с этого момента) +biWidth DWORD ; Ширина изображения в пикселях +biHeight DWORD ; Высота изображения в пикселях +biplanes WORD ; Количество плоскостей или цветовых слоев +biBitCount WORD ; Кол-во битов на пиксель +biCompression DWORD ; Тип сжатия +biSizeImage DWORD 0 ; Размер картинки в байтах, если изображение несжатое, то значение рекомендовано устанавливать в ноль +biXPelsPerMeter DWORD ; Горизонтальное разрешение (в пикселях на метр) +biYPelsPerMeter DWORD ; Вертикальное разрешение (в пикселях на метр) +biClrUsed DWORD 0 ; Определяет количество используемых цветов из таблицы +biClrImportant DWORD 0 ; Количество важных для изображения цветов + +;--[File Data] +bdPallete BLOCK #400 +bdRaster MAIN_BMP + ENDS +; \ No newline at end of file