; ███████╗██╗ █████╗ ███████╗██╗ ██╗███████╗██████╗ ; ██╔════╝██║ ██╔══██╗██╔════╝██║ ██║██╔════╝██╔══██╗ ; █████╗ ██║ ███████║███████╗███████║█████╗ ██████╔╝ ; ██╔══╝ ██║ ██╔══██║╚════██║██╔══██║██╔══╝ ██╔══██╗ ; ██║ ███████╗██║ ██║███████║██║ ██║███████╗██║ ██║ ; ╚═╝ ╚══════╝╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝ ; [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 0 ; 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 ;------------[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 '../Flasher/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 ; Flasher_Start: 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 ; Читаем INI LD HL,NUMBER_COPY.INI_FILE LD A,Dss.Open.R LD C,Dss.Open RST ToDSS JR C,TEST_CHIP ; PUSH AF LD HL,0 LD IX,0 LD BC,Dss.Move_FP.FrStart RST ToDSS POP AF ; LD HL,NUMBER_COPY.BRD_ID LD DE,NUMBER_COPY.BRD_ID.Size LD C,Dss.Read RST ToDSS ; 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,START_MSG.afterPICno_R 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 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 ; .next: XOR A OUT (RGMOD),A DI ;+++++++++++++++++++++++++++++++++++++++ CALL BUILD_FIRMWARE LD A,(FILE_HANDLE) LD C,Dss.Close RST ToDSS ;+++++++++++++++++++++++++++++++++++++++ DI CALL NUMBER_COPY CALL DrawProgress.done REWRITE: IN A,(SLOT1) LD (SV_PG1),A ;-----------[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 ; NUMBER_COPY: IN A,(SLOT3) EX AF,AF' LD A,#18 ;!HARDCODE OUT (SLOT3),A ; ; LD HL,(.BRD_ID.Start) LD (#C000+BoardNumOffsets.Start),HL LD HL,(.BRD_ID.Number) LD (#C000+BoardNumOffsets.Number),HL LD HL,(.BRD_ID.End) LD (#C000+BoardNumOffsets.End),HL LD A,(.BRD_ID.Type) 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 ; .BRD_ID EQU $ .BRD_ID.Start: DW #5283 .BRD_ID.Number: DW #0000 .BRD_ID.End: DW #47E8 .BRD_ID.Type: DB #00 .AcexType: DB ROM_BITSTREAM.K30 .BRD_ID.Size EQU $-.BRD_ID .INI_FILE: DZ '\flasher\board_id.ini' CONTINUE: CALL SET_ROM_MODE.Flash LD A,COLORS.CGA.BORDER.BLACK OUT (BorderColor),A TST_R: .jp+1: LD HL,0 JP (HL) ITs_Unknown_Chip: CALL SET_ROM_MODE.Normal JP Program_exit.unsupported_chip ;--------------------------------------- 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,(NUMBER_COPY.AcexType) LD B,A 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) ; 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 JP NZ,Program_exit.conf ; если битстрим неизвестный - выход с ошибкой LD IX,(OFFSETS.K50) ; младшее слово смещения в файле LD HL,(OFFSETS.K50+2) ; старшее слово смещения в файле LD DE,CHECKSUMS.K50 LD BC,#1C20 ; !HARDCODE high начальная_страница low конечная_страница+1 JP Read_And_Check ;------------------------------[] ;--------------------------------------- ;██████████████████████████████████████████████████████████████████████; ;-[Сохраняем битстрим пользователя]-[v] ;!FIXIT crazy ; 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 ; .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 .last_page+1: CP #20 JR NZ,.loop Checksum_Check: 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 .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 CALL ERASE._39SF020 CALL WRITE_39SF020 LD A,DrawProgress.Verify CALL DrawProgress.start CALL VERIFY JP RESET COUNT_ALL: DB 0 ;********************************* RESET: DI LD BC,ACEX.RESET*256+ACEX.RESET CALL SET_DCP_PORT ;!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 (CNF_PORT.vBIOS),A ; CNF0 CALL Pause._200msek LD A,CNF_PORT.CNF_0+CNF_PORT.TURBO.ON OUT (CNF_PORT.vBIOS),A ; CNF0 RESET_LOOP: LD A,Port_HardReset.Step1 OUT (Port_HardReset),A DEC A OUT (Port_HardReset),A JR RESET_LOOP ;********************************* 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,#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: ; 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 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 ; 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 START_MSG: DB 13,10,10 DB 'Crazy Blaster 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 '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 .afterPICno_R: DB 'Press "Y" to start full reflashing.',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 .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 ; altera_chip: BYTE 0 CHECKSUMS: .BIOS: DWORD LUA_CHECKSUM_BIOS .K30: DWORD LUA_CHECKSUM_K30 .K50: DWORD LUA_CHECKSUM_K50 .LOADER: DWORD LUA_CHECKSUM_LOADER ; 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,ROM_CHIP.ST29EE020 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,ROM_CHIP.W29C020 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 ; XOR A LD BC,#1FFD 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 vROM PAGE BIOS INC A LD BC,#1FFD OUT (C),A LD A,SYS_PORT.CNF_0 OUT (SYS_PORT.RAM),A ;OUT (CNF_PORT.vBIOS),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 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 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 $ 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