; _mInfoALIGN 256,0 TAB_FNS: ; !FIXIT поправить в доке названия функций, часть не совпадает ; 8x /* 80 */ DW LP_OPEN_S ; открытие окна /* 81 */ DW LP_PRINT_ALL ; печать символа в окно /* 82 */ DW LP_PRINT_SYM ; печать символа без атр /* 83 */ DW LP_PRINT_ATR ; печать только атрибута /* 84 */ DW LP_SET_PLACE ; установка позиции печати /* 85 */ DW LP_PRINT_LINE ; печать строки длиной B /* 86 */ DW LP_PRINT_LINE2 ; печать строки -//- без атрибутов /* 87 */ DW LP_PRINT_LINE3 ; печать строки длиной B до D /* 88 */ DW LP_PRINT_LINE4 ; печать строки -//- без атрибутов /* 89 */ DW LP_CLS_WIN /* 8A */ DW LP_SCROLL_UD /* 8B */ DW LP_PRINT_LINE5 /* 8C */ DW LP_PRINT_LINE6 /* 8D */ DW LP_CLS_WIN2 /* 8E */ DW LP_GET_PLACE /* 8F */ DW FN_TURBO ; 9x /* 90 */ DW EMM.GetMemSize ; неразрушающее определение объема ОЗУ. /* 91 */ DW EMM.InitMem ; инициализация распределения памяти /* 92 */ DW EMM.GetMemRMD ; получить блок памяти для рамдиска /* 93 */ DW EMM.FreeMemRMD ; освободить блок памяти рамдиска /* 94 */ DW EMM.GetMemPageRMD ; получить номерa страниц RAM-Disk /* 95 */ DW EMM.GetMemPageNext ; получить следующую страницу /* 96 */ DW EMM.GetBanksPorts ; получить адреса портов /* 97 */ DW EMM.CheckColdInit ; проверка на холодный старт и инициализации если он ;????? нужна ли как API? /* 98 */ DW RAMD_CALC_PAGE ; Fn 98h ;????? /* 99 */ DW SET_DISK_TYPE ; ;????? /* 9A */ DW DISK_REDIR ; ;????? /* 9B */ DW FN_NO ;GET_RAMD_NUM ; получить номер ram disk по его block id /* 9C */ DW FN_NO ; /* 9D */ DW EMM.DivMemBlocks ; разделения блока на два. /* 9E */ DW EMM.MergeMemBlocks ; слияние двух блоков /* 9F */ DW EMM.FullInit ; инициализация всей памяти, системных переменных ; Ax /* A0 */ DW PIC_FN0 ; ОТКРЫТИЕ ОКНА - Fn 0A0h /* A1 */ DW PIC_FN1 ; ВЫВЕСТИ ТОЧКУ /* A2 */ DW PIC_FN2 ; ВЫВОД ЛИНИИ COPY /* A3 */ DW PIC_FN3 ; ВЫВОД ЛИНИИ FILL /* A4 */ DW PIC_FN4 ; ВЫВОД ПАЛИТРЫ /* A5 */ DW PIC_FN5 ; УСТАНОВКА RGMOD /* A6 */ DW PIC_FN6 ; A - page_pal, E - номер палитры, B - тип палитры /* A7 */ DW PIC_FN7 ; Рисование линии одного цвета /* A8 */ DW PIC_FN8 ; Рисование разноцветной линии /* A9 */ DW PIC_FN9 ; нет /* AA */ DW PIC_FN10 ; нет /* AB */ DW PIC_FN11 ; нет /* AC */ DW PIC_FN12 ; нет /* AD */ DW PIC_FN14 ; нет /* AE */ DW PIC_FN14 ; нет /* AF */ DW PIC_FN15 ; нет ; Bx /* B0 */ DW WIN_OPEN ; открытие окна по описателю /* B1 */ DW WIN_CLOSE ; закрытие окна /* B2 */ DW WIN_COPY ; сохранение текстового окна в памяти /* B3 */ DW WIN_RESTORE ; восстановление текстового окна из памяти /* B4 */ DW WIN_GET_SYM ; взять символ /* B5 */ DW WIN_PUT_SYM ; положить символ /* B6 */ DW WIN_SET_ZG ; загрузка знакогенератора /* B7 */ DW WIN_MOVE ; переместить окно /* B8 */ DW WIN_GET_ZG ; получить знакогенератор /* B9 */ DW FN_NO /* BA */ DW FN_NO /* BB */ DW FN_NO /* BC */ DW FN_NO /* BD */ DW FN_NO /* BE */ DW FN_NO /* BF */ DW FN_NO ; Cx /* C0 */ DW EMM.GetMemSize ; получить данные об объеме памяти и кол-во своб. стр. /* C1 */ DW EMM.InitMem ; инициализация распределения памяти /* C2 */ DW EMM.GetMem ; получить блок памяти /* C3 */ DW EMM.FreeMem ; освободить блок памяти /* C4 */ DW EMM.GetMemPage ; получить номер страницы в блоке памяти /* C5 */ DW EMM.GetMemBlkPages ; получить список страниц блока памяти /* C6 */ DW EMM.GetBanksPorts ; получить адреса портов окон /* C7 */ DW EMM.GetMemPageNext ; получить следующую страницу блока /* C8 */ DW BLK_RD_WR ; функция чтения/записи в блок памяти /* C9 */ DW BLK_TO_RAMD ; назначить блок RAM-Disk-у /* CA */ DW RAMD_CLEAR ; освободить RAM-Disk /* CB */ DW RAMD_TO_DRV ; назначить RAM-Disk на дисковод /* CC */ DW FDD_TO_DRV ; назначить REAL_DRIVE на дисковод /* CD */ DW HDD_TO_DRV ; назначить HDD на дисковод /* CE */ DW GET_RAMD_ST ; получить тип назначения на RAM-Disk /* CF */ DW GET_DRV_ST ; получить тип назначения на дисковод ; Dx /* D0 */ DW FN_LIB /* D1 */ DW FN_LIB /* D2 */ DW FN_LIB /* D3 */ DW FN_LIB /* D4 */ DW FN_LIB /* D5 */ DW FN_LIB /* D6 */ DW FN_LIB /* D7 */ DW FN_LIB /* D8 */ DW FN_LIB /* D9 */ DW FN_LIB /* DA */ DW FN_LIB /* DB */ DW FN_LIB /* DC */ DW FN_LIB /* DD */ DW FN_LIB /* DE */ DW FN_LIB /* DF */ DW FN_LIB ; Ex /* E0 */ DW LP_PRINT_LINE_DIR /* E1 */ DW FN_NO /* E2 */ DW FN_NO /* E3 */ DW FN_NO /* E4 */ DW FN_NO /* E5 */ DW FN_NO /* E6 */ DW FN_NO /* E7 */ DW FN_NO /* E8 */ DW FN_SEND_BYTE ; послать байт через PC_link /* E9 */ DW FN_RESEIVE_B ; принять байт через PC_link /* EA */ DW FN_KBD_OUT ; послать байт в клавиатуру /* EB */ DW FN_NO /* EC */ DW FN_NO /* ED */ DW FN_CRIPT /* EE */ DW AY8910 /* EF */ DW FN_VERSION ; Fx /* F0 */ DW SPRINTER_1 /* F1 */ DW SPRINTER_2 /* F2 */ DW FN_SINC /* F3 */ DW SPRINTER_ALL /* F4 */ DW DCP_FN0 /* F5 */ DW CMOS_TEST /* F6 */ DW CMOS_RD /* F7 */ DW CMOS_WR /* F8 */ DW SET_ROM_PAGES /* F9 */ DW READ_PORTS ; !TODO /* FA */ DW WRITE_PORTS ; !TODO /* FB */ DW GOTO_SPEC ; Goto Spectrum! /* FC */ DW FN_NO /* FD */ DW FN_RESET /* FE */ DW FN_NO ; SAVE_AUTOSTART /* FF */ DW FN_VERSION EXP_FNS: ; Вход в функцию из DOS POP AF CALL APIfrom80toFF ; !TEST new_api CALL DOS_ON JP EXP_FNS_RET ;************************************ ; Вход в функцию по RST18 и RST8 EXP_FNS_RST18: BIT 7,C JR NZ,APIfrom80toFF ; !TEST new_api ;.APIfrom40to5F: BIT 6,C RES 6,C JP NZ,EXP_HDD_NEW SCF RET ;********************************** ;----------------------------------------------------------------------- FN_CRIPT: DEC B SCF RET NZ LD HL,(ROM_NUMBER.part1) ;rdlow-ok LD A,(ROM_NUMBER.part2) ;rdlow-ok LD BC,(BoardID.start) ;rdlow-ok LD DE,(BoardID.end) ;rdlow-ok AND A RET ; BoardID_start old address #312A ; BoardID_end old address #312D ;----------------------------------------------------------------------- ;********************************** ;!!!!! глянуть ; START_DI: ; PUSH AF ; LD A,R ; JP PE,XX_DI ; LD A,R ; XX_DI: 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 ; BIT 7,A ; JR Z,XX_DI3 ; EI ; POP AF ; PE ; RET ; XX_DI3: DI ; POP AF ; PO ; RET ;********************************** APIfrom80toFF: PUSH HL LD L,C SLA L LD H,high TAB_FNS LD C,(HL) // LD A,(HL) INC L LD H,(HL) LD L,C // LD L,A EX (SP),HL RET ;! ! ! ! ! ! ! ! ; !TODO сделать READ_PORTS: WRITE_PORTS: FN_NO: SCF RET ;! ! ! ! ! ! ! ! ; ????? может переделать вход? ; CALL from 3D13h! ; in A - page, B - new ROM-page ; out B - old ROM-page SET_ROM_PAGES: EX AF,AF' LD A,CNF_0 OUT (SYS_PORT.ON),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 ; установить порт ROM TR-DOS LD (#8200),A EX AF,AF' LD A,B LD BC,0 EX AF,AF' IN A,(C) EX AF,AF' OUT (C),A ; установить новый TR-DOS EX AF,AF' LD B,A LD A,L LD (#8000),A ; вернуть порт LD A,H LD (#8200),A ; вернуть порт LD C,SLOT2 LD A,SYS_PAGE OUT (C),A LD A,(SYS_PAGE.CONFIG_DE-#4000) OUT (C),D ; вернуть страницу OUT (SYS_PORT.ON),A AND A RET ;TAB_SIZE EQU $-TAB_FNS ;***************************************** ;***************************************** ; Функция дешифратора портов. ; HL - адрес ; DE - маска - 0 изменяемые биты, 1 неизменяемые ; B - порт ; ; ALL STACKS, DI ;***************************************** DCP_FN0: ; !FIXIT запоминать тут состояние прерываний и вырубать AND A JP Z,PORTS_INIT PUSH IX LD IX,.RET_DCP_FN0 IN A,(SLOT3) EX AF,AF' LD A,DCP_PAGE OUT (SLOT3),A JR DCP_FN0M .RET_DCP_FN0: EX AF,AF' OUT (SLOT3),A AND A POP IX ; !FIXIT восстанавливать прерывания RET ;-----------------------------------------------------------------------; ; Функция дешифратора портов. ; HL - адрес ; DE - маска - 0 изменяемые биты, 1 неизменяемые ; B - порт DCP_FN0M: LD A,L AND E LD L,A LD A,H AND D ; AND #3F 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 ; цикл .carry: ; A = 0 ; OR E ; XOR E ; LD C,A LD A,L ; забить изменяемые биты нулями AND E ; OR C LD L,A LD A,H ; замаскировать неизменяемые биты 1-ми OR D ; для прохождения переноса INC A ; увеличить адрес JR Z,.exit OR D XOR D LD C,A ; изменяемая часть LD A,H AND D ; выделить неизменяемую OR C LD H,A ; добавить изменяемую часть JR .loop .exit: JP (IX) ;-----------------------------------------------------------------------; ; RAM-Disk A, BLK - B BLK_TO_RAMD: CP SYS_PAGE.RAMD_KEYS.NUM CCF RET C PUSH HL LD L,A IN A,(SLOT2) LD C,A LD A,SYS_PAGE OUT (SLOT2),A LD A,L LD HL,SYS_PAGE.RAMD_KEYS-#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 (SLOT2),A LD A,B AND A POP HL RET BLK_BUSY: LD A,C OUT (SLOT2),A SCF POP HL RET ; RAM-Disk A RAMD_CLEAR: CP SYS_PAGE.RAMD_KEYS.NUM CCF RET C PUSH HL LD L,A IN A,(SLOT2) LD C,A LD A,SYS_PAGE OUT (SLOT2),A LD A,L LD HL,SYS_PAGE.RAMD_KEYS-#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 (SLOT2),A AND A POP HL RET ; 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 ; 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 ; HDD A, DRV - B HDD_TO_DRV: AND 0FH 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,40H LD (HL),A LD A,B OUT (SLOT2),A AND A RET ; Вход: ; A - RAM Disk ID ; Выход: ; A - Number (0..15) ; GET_RAMD_NUM: ; EX AF,AF' ; IN A,(SLOT2) ; EX AF,AF' ; LD BC,SYS_PAGE * 256 + SLOT2 ; OUT (C),B ; LD HL,SYS_PAGE.RAMD_KEYS-#4000 ; LD BC,SYS_PAGE.RAMD_KEYS.NUM ; CPIR ; EX AF,AF' ; OUT (SLOT2),A ; EX AF,AF' ; SCF ; RET PE ; DEC L ; LD A,L ; SUB low SYS_PAGE.RAMD_KEYS ; RET ; на выходе при А = 0 должен быть установлен флаг Z GET_RAMD_ST: ; DSS надеется, что эта функция не грохает DE CP SYS_PAGE.RAMD_KEYS.NUM CCF RET C PUSH BC LD HL,SYS_PAGE.RAMD_KEYS-#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 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 ;*********************************************** ; ????? чё за херня про бейсик? тут не то ниже ; ; CMOS - 35h,36h - установки бейсика ; ;*********************************************** 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: CALL CMOS_TEST JR C,CMOS_EMU_WR XWR_CMOS: LD BC,CMOS.Port.Address.Write OUT (C),D LD BC,CMOS.Port.Data.Write OUT (C),A RET CMOS_EMU_RD: PUSH DE LD C,SLOT3 IN B,(C) LD E,SYS_PAGE OUT (C),E LD E,D LD D,#FF LD A,(DE) OUT (C),B POP DE RET ; чтение из CMOS CMOS_RD: CALL CMOS_TEST JR C,CMOS_EMU_RD XRD_CMOS: LD BC,CMOS.Port.Address.Write OUT (C),D LD BC,CMOS.Port.Data.Read IN A,(C) RET CMOS_TEST: PUSH DE PUSH BC PUSH AF LD D,3FH ; !HARDCODE CALL XRD_CMOS LD E,A CPL CALL XWR_CMOS CALL XRD_CMOS CPL CP E JR NZ,CMOS_ERR LD A,E CALL XWR_CMOS POP AF POP BC POP DE AND A RET CMOS_ERR: LD A,E CALL XWR_CMOS POP AF POP BC POP DE SCF 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 ; FN_TURBO: CP 2 JR Z,.FN_TB_ONOFF CP 3 JR Z,.FN_TB_ONOFF CP #12 JR Z,.SET_FDD_720 CP #13 JR Z,.SET_FDD_1440 SCF RET ;!FIXIT меняем плотность - меняем в системной странице инфу об этом .SET_FDD_720: LD A,1 OUT (#BD),A ; !HARDCODE AND A RET ;!FIXIT меняем плотность - меняем в системной странице инфу об этом .SET_FDD_1440: LD A,#21 OUT (#BD),A ; !HARDCODE AND A RET .FN_TB_ONOFF: 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 AND #FC OR C LD E,A OUT (SYS_PORT.ON),A LD (SYS_PAGE.CONFIG_DE),DE LD A,B OUT (SLOT3),A AND A 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,(SLOT2) EX AF,AF' LD A,SYS_PAGE OUT (SLOT2),A LD H,high (SYS_PAGE.RAMD_FAT - #4000) LD L,D LD A,(HL) LD (HL),0FFH LD B,A EX AF,AF' OUT (SLOT2),A LD A,E AND A RET ; слить два блока памяти в один ; А - блок 1, B - блок 2 ; выход: А - блок EMM.MergeMemBlocks: LD E,A IN A,(SLOT2) EX AF,AF' LD A,SYS_PAGE OUT (SLOT2),A LD H,high (SYS_PAGE.RAMD_FAT - #4000) LD L,E LD C,B LD B,0 EMM_ADD_L: LD A,(HL) AND A JR Z,EMM_ADD_ERR CP 0FFH JR Z,EMM_ADD_NEXT LD L,A DJNZ EMM_ADD_L EMM_ADD_ERR: EX AF,AF' OUT (SLOT2),A SCF RET EMM_ADD_NEXT: LD A,C AND A JR Z,EMM_ADD_ERR LD (HL),A EX AF,AF' OUT (SLOT2),A AND A LD A,E RET ;