; 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: CALL .ACC_OFF LD DE,ACEX.Config_ID.Sp97_AY JR .INT_PLD ;LD A,CNF_PORT.CNF_1 ;OUT (SYS_PORT.ON),A ;RET ;--[] ;--[] Sprinter ZX .SP97_1: CALL .ACC_OFF LD DE,ACEX.Config_ID.Sp97_1 JR .INT_PLD ;--[] ;--[] .SP97_2: CALL .ACC_ON LD DE,ACEX.Config_ID.Sp97_2 JR .INT_PLD ;--[] ;--[] ;[x] .SP2000: CALL .ACC_ON LD DE,ACEX.Config_ID.Sp2000 JR .INT_PLD ;--[] ;--[] .CUSTOM: LD C,A ; устанавливаем нулевую карту портов LD A,CNF_PORT.CNF_0 OUT (SYS_PORT.ON),A LD A,C ; CP #80 ;!FIXIT тут теперь может любое число быть у старых прог ; [ ] free zx pages JR NC,.CHOOSE_CNF ; only for old FLEX10K soft compatible .crutch: 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 ; восстанавливаем карту портов - походу, не нужно ;LD C,SLOT3 ;IN B,(C) ; LD A,SYS_PAGE ; OUT (C),A ; LD A,(SYS_PAGE.CONFIG_DE.CNF_PORT) ;OUT (C),B ;OUT (SYS_PORT.ON),A XOR A RET ; ;[x] .CHOOSE_CNF: ; [ ] bug with "free zx pages" LD A,high ZX_MEM_PORT.Scorpion IN A,(ZX_MEM_PORT) ;!HARDCODE RRCA LD A,C JR C,.not_vRAM_page ; IN A,(SLOT3) CP C LD A,C JR Z,.crutch ; [x] .not_vRAM_page: CP ACEX.Config_PG.Sp2000_SoftRestartNow JP Z,.ReturnSoftReset ; CP ACEX.Config_PG.Sp2000_AcexSetUpNow JR Z,.INIT_ACEX ; CP ACEX.Config_PG.Sp2000_SetUp JR Z,.SP2000 ; CP ACEX.Config_PG.Sp2000_SoftRestartSet JR Z,.SetUpSoftReset ; CP ACEX.Config_PG.Sp2000_AcexSetUpSet JR Z,.SetUpHardReset ; ; 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 ; ; B - ID рамблока с bitstream ;[x] .INIT_ACEX: LD C,B LD B,high BIOS.REINIT.HARD_RESET CALL .PrepareResetSetUp LD B,C CALL .PrepareHardReset JR C,.INIT_ACEX.ERROR LD B,high BIOS.REINIT.HARD_RESET JR .set_ret_addr ; DI ; 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 B,high BIOS.REINIT.HARD_RESET ; POP HL ; ; ; ;вход: B - параметр функции BIOS REINIT ; ; H - Spec_Page.page_3 ; .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 (Spec_Page.Stack_Point),SP ; ; ; LD A,high BIOS.REINIT.HARD_RESET ; CP B ; JR NZ,.reinit ; ; Устанавливаем ключи для HARD reset ; 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,BIOS.REINIT.HARD_RESET ; .reinit: JP REINIT ; .SetUpHardReset: LD C,B LD B,high BIOS.REINIT.HARD_RESET CALL .PrepareResetSetUp LD (Spec_Page.RET_addr),DE LD A,#FF LD (Spec_Page.Reload_Version),A LD B,C CALL .PrepareHardReset JR .INIT_ACEX.ERROR ; нормальный выход в данном случае ; .ReturnSoftReset: CALL .PrepareSoftReset CALL .PrepareResetSetUp ; достаём адрес возврата в вызывающую функцию и сохраняем в Spec_Page .set_ret_addr: 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 (Spec_Page.Stack_Point),SP JP REINIT ; .SetUpSoftReset: PUSH DE CALL .PrepareSoftReset CALL .PrepareResetSetUp POP DE LD (Spec_Page.RET_addr),DE LD A,#FF LD (Spec_Page.Reload_Version),A LD A,(Spec_Page.page_3) OUT (SLOT3),A RET ; DI ; LD A,ACEX.RET_PORT ; LD B,Spec_Page ; CALL SET_PORTS ; ; ; ; и так понятно что делает ; IN A,(SLOT3) ; сохраняем номер воткнутой страницы ; LD H,A ; LD A,Spec_Page ; OUT (SLOT3),A ; ; ; LD B,high BIOS.REINIT.SOFT_RESET ; JR .INIT_ACEX.ifSoftreset ; ;;; .INIT_ACEX.ERROR: LD A,(Spec_Page.page_3) OUT (SLOT3),A ;SCF RET ; ;--[] .ACC_OFF: LD BC,Port_All_Mode IN A,(C) AND Port_All_Mode.DEFAULT - Port_All_Mode.SPECTRUM_MODE_OFF OUT (C),A RET ; .ACC_ON: LD BC,Port_All_Mode IN A,(C) OR 1 ; ACC_ON OUT (C),A 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 LD A,(Spec_Page.page_1) 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 ;--[] .PrepareSoftReset: LD A,ACEX.RET_PORT LD B,Spec_Page CALL SET_PORTS LD B,high BIOS.REINIT.SOFT_RESET RET .PrepareResetSetUp: DI ; сохраняем воткнутые страницы в Spec_Page IN A,(SLOT3) LD H,A LD A,Spec_Page OUT (SLOT3),A ; IN A,(SLOT2) LD L,A LD (Spec_Page.page_2),HL IN A,(SLOT0) LD (Spec_Page.page_0),A IN A,(SLOT1) LD (Spec_Page.page_1),A ; LD A,high BIOS.REINIT.HARD_RESET CP B LD HL,Spec_Page.flag_R JR NZ,.kill_flag ; Устанавливаем ключи для HARD reset LD (HL),"R" INC HL .kill_flag: LD (HL),"S" INC HL LD (HL),"T" ; ; .. ... ... .. ; [ ] ;!TODO сделать функцию по заливке своей конфы, перехвату ресета. ; *. Вход в подфункцию только через RST 08 или #18 ; *. Сохранить все страницы пользователя в SYS_PAGE для перехвата ресета ; *. Достать со стека адрес возврата и сохранить в SYS_PAGE для перехвата ресета ; *. Сохранить куда-нибудь значение стека ; * ; .. ... ... .. RET ; ; B - ramblock bitstream .PrepareHardReset: ; проверяем размер блока с конфой и получаем страницы конфы LD HL,Spec_Page.bitstream_pages LD A,B AND A JR Z,.INIT_ACEX.ReloadConfFromROM ; CALL EMM.GetMemBlkPages RET C ; ERROR LD A,BitStream_SizeInPages ; количество страниц в кэш для бистрима CP B RET C ; ERROR LD A,(Spec_Page.bitstream_pages) INC A SCF RET Z ; 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, иначе из КЭШ JP Spec_Page.init_acex ;--[] ;*************************************** ;[x] ;--------------------------[;!TODO потестить]--------------------------; ; B - параметр сброса ; B = 1 - RESTART. ; B = 2 - Soft reset ; B = 3 - Hard reset ; B = 4 - Free memory except ZX 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 ; ; 4 .FreeNoZxMem: DI LD C,SLOT3 IN B,(C) LD A,SYS_PAGE OUT (C),A LD (SYS_PAGE.SP_SAVE),SP LD SP,SYS_PAGE.SYS_SP PUSH BC ; чистим буфер LD HL,SYS_PAGE.SHARED_BUFFER_256b LD DE,SYS_PAGE.SHARED_BUFFER_256b + 1 LD BC,255 LD (HL),0 LDIR ; LD IX,SYS_PAGE.Block_IDs LD H,high SYS_PAGE.RAM_TABLE LD D,high SYS_PAGE.SHARED_BUFFER_256b LD BC,2*256 + #FF ; 2 = vRAM и VROM ID's CALL SAVE_CHAINS ; CALL EMM.InitMem ; LD HL,SYS_PAGE.SHARED_BUFFER_256b LD DE,SYS_PAGE.RAM_TABLE CALL RESTORE_CHAINS ; CF=0 POP BC LD SP,(SYS_PAGE.SP_SAVE) OUT (C),B RET ;[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 ; [ ] 16/09/24 free zx pages! ;LD A,5 ;OUT (SLOT1),A ;LD A,2 ;OUT (SLOT2),A OUT (SLOT2),A DEC A OUT (SLOT1),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 ; ;[x] .HardReset: DI LD A,SYS_PORT.CNF_0 OUT (SYS_PORT.ROM),A ; LD A,Z84.REG.Misc_Ctrl OUT (Z84.SYS.Control),A LD A,%0000'0011 ; CS1/CS0 enabled OUT (Z84.SYS.Data),A ; 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,C OUT (C),C JR .loop ; полностью зациклить! ; ;----------------------------------------------------------------------; ; Вход: H - RAM_TABLE ; D - Buffer for RAM_TABLE ; IX - указатель на последовательность из RAM BLOCK ID ; B - кол-во RAM BLOCK ID в последовательности ; C - #FF (чтоб LDI не ломало DJNZ счётчик) SAVE_CHAINS: LD A,(IX) INC IX OR A LD L,A CALL NZ,COPY_CHAIN DJNZ SAVE_CHAINS RET ; Вход: H - RAM_TABLE ; L - RAM BLOCK ID ; D - Buffer for RAM_TABLE COPY_CHAIN: LD E,L LDI DEC L LD L,(HL) INC L RET Z DEC L JR COPY_CHAIN ;--------------; ; Вход: HL - копия RAM_TABLE откуда копировать ; DE - RAM_TABLE RESTORE_CHAINS: XOR A .loop: CP (HL) JR Z,.NoCopy LD E,L LDI DEC L .NoCopy: INC L JR NZ,.loop RET ;----------------------------------------------------------------------; ;----------------------------------------------------------------------; ; старый вариант освобождения страниц спектрума через RAM BLK ID 1 ;----------------------------------------------------------------------; ; JR Z,.HardReset ;3 ; DEC B ; .ReinitZXpages: ;4 ; LD DE,RESERVED_PAGES ; таблица занятых системных страниц ; LD HL,SYS_PAGE.RAM_TABLE ; Адрес 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.RAM_TABLE ; LD A,(DE) ; LD L,A ; LD A,#FF ; LD (HL),A ; .errorzxloop_noChanges: ; SCF ; .endzxloop: ; OUT (C),B ; RET ;----------------------------------------------------------------------; ;