; 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.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 ; ;[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 ;!HARDCODE zx page number LD A,5 ;!HARDCODE zx page number OUT (SLOT1),A LD A,2 ;!HARDCODE zx page number 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 RES_FLAG_ZXvROM: 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 ;----------------------------------------------------------------------; ;