; 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_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,BIOS.REINIT.HARD_RESET ; ; на входе в 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,BIOS.REINIT.HARD_RESET 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,BIOS.REINIT.SOFT_RESET JR .INIT_ACEX.ifSoftreset ; ;;; .INIT_ACEX.ERROR: POP AF 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 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 - 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] .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 ; [ ] 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 ; ;----------------------------------------------------------------------; ; Вход: 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 ;----------------------------------------------------------------------; ;