; DISPLAY "Low-print-2." ;============================================================== ; ; Программа LOW PRINT for Sprinter-97. ; ;============================================================== ;============================================================= ; Функции Bios Sprinter-97. ; Рабочая версия 29.05.97 ;============================================================= ; LP_OPEN_WIN Открытие окна ; point 3D13h C=80h Вход: B - код окна. ; B=0 - Spectrum 32x24 B=1 - Spectrum 64x24 ; B=2 - Spectrum 40x24 B=3 - Spectrum 80x24 ; Выход: DE - размер окна ;============================================================= ; LP_PRINT_ALL Вывод символов на экран с текущего знакоместа ; point 3D13h C=81h Вход: A - символ, ; B - число выводимых символов, ; Е - атрибут символа ;============================================================= ; LP_PRINT_SYM Вывод символов на экран с текущего знакоместа ; без атрибута ; point 3D13h C=82h Вход: A - символ, ; B - число выводимых символов, ;============================================================= ; LP_PRINT_ATR Вывод атрибутов на экран с текущего знакоместа ; point 3D13h C=83h Вход: B - число выводимых символов, ; Е - атрибут символа ;============================================================= ; LP_SET_PLACE Установка текущего знакоместа ; point 3D13h C=84h Вход: E - знакоместо по горизонтали ; D - знакоместо по вертикали ;============================================================= ; LP_PRINT_LN Вывод строки символов на экран с текущего ; знакоместа ; point 3D13h C=85h Вход: HL - адрес строки ; B - число выводимых символов, ; Е - атрибут символов ;============================================================= ; LP_PRINT_LN2 Вывод строки символов на экран с текущего ; знакоместа без атрибутов ; point 3D13h C=86h Вход: HL - адрес строки ; B - число выводимых символов, ;============================================================= ; LP_PRINT_LN3 Вывод строки символов на экран с текущего ; знакоместа ; point 3D13h C=87h Вход: HL - адрес строки ; B - число выводимых символов, ; D - разделитель ; Е - атрибут символов ;============================================================= ; LP_PRINT_LN4 Вывод строки символов на экран с текущего ; знакоместа без атрибутов ; point 3D13h C=88h Вход: HL - адрес строки ; B - число выводимых символов, ; D - разделитель ;============================================================= ; LP_CLS_WIN Очистка окна экрана ; point 3D13h C=89h Вход: DE - положение окна ; B - атрибут очистки ; H - высота, L - ширина ;============================================================= MACRO CORRECT_SCR_40_FORWARD ;[x] включил 31/10/23, чисто на Хэллоууууииин EX AF,AF' JR C,.LLL INC D ; режим 40 .LLL: EX AF,AF' ENDM ; MACRO CORRECT_SCR_40_BACKWARD EX AF,AF' JR C,.LLL DEC D ; режим 40 .LLL: EX AF,AF' ENDM ; MACRO DJNZ_NEXT_HL DJNZ .LLL CALL LP_NEXT_HL .LLL: ; ENDM ;********************************* ;* LOW LEVEL PRINTER * ;* DE' - ZG * ;* HL' - PLACE ON SCR * ;* C' - ATTRIBUTES * ;* B' - COUNT SYMBS * ;* ZF - inverse * ;* AF' - страница и mode * ;********************************* ; MACRO LP_BEG_PM ; EX AF,AF' ; EXX ; IN A,(SLOT3) ; LD C,A ; IN A,(PORT_Y) ; LD B,A ; LD A,SYS_PAGE ; OUT (SLOT3),A ; LD (SYS_SP),SP ; LD SP,SYS_SP ; PUSH BC ; ; ; LD HL,(WIN_ID_0.HL) ; LD DE,(WIN_ID_0.DE) ; LD BC,(WIN_ID_0.BC) ; LD A,E ; AND A ; RRA ; OUT (PORT_Y),A ; EXX ; EX AF,AF' ; ENDM ; ; MACRO LP_END_PM ; EX AF,AF' ; EXX ; RLA ; LD E,A ; LD (WIN_ID_0.HL),HL ; место печати ; LD (WIN_ID_0.DE),DE ; LD (WIN_ID_0.BC),BC ; ; ; POP BC ; LD A,B ; OUT (PORT_Y),A ; LD A,C ; OUT (SLOT3),A ; LD SP,SYS_SP ; EXX ; EX AF,AF' ; RET ; ENDM ; ; ;------------------------------------------------------------------[#81] LP_PRINT_ALL: CALL LP_BEG_P EXX LD C,A EXX LD A,#50 OUT (SLOT3),A ; .loop: EXX LD A,D OUT (PORT_Y),A INC D .cont: LD (HL),C EXX LD A,E EXX INC L LD (HL),A DEC L CORRECT_SCR_40_FORWARD DJNZ_NEXT_HL EXX DJNZ .loop JP LP_END_P ;------------------------------------------------------------------[#81] ; ; ;------------------------------------------------------------------[#82] ; LP_PRINT_SYM: CALL LP_BEG_P EXX LD C,A EXX LD A,#50 OUT (SLOT3),A ; .loop: EXX LD A,D OUT (PORT_Y),A .cont: LD (HL),C INC D CORRECT_SCR_40_FORWARD DJNZ_NEXT_HL EXX DJNZ .loop JP LP_END_P ;------------------------------------------------------------------[#82] ; ; ;------------------------------------------------------------------[#83] LP_PRINT_ATR: CALL LP_BEG_P LD A,E EXX LD C,A EXX LD A,#50 OUT (SLOT3),A ; .loop: EXX LD A,D OUT (PORT_Y),A INC D INC L LD (HL),C DEC L CORRECT_SCR_40_FORWARD DJNZ_NEXT_HL EXX DJNZ .loop JP LP_END_P ;------------------------------------------------------------------[#83] ; ; ;------------------------------------------------------------------[#85] LP_PRINT_LINE: CALL LP_BEG_P EXX LD C,PORT_Y EXX LD A,#50 OUT (SLOT3),A ; .loop: EXX OUT (C),D INC D EXX LD A,(HL) INC HL EXX LD (HL),A EXX LD A,E EXX INC L LD (HL),A DEC L CORRECT_SCR_40_FORWARD DJNZ_NEXT_HL EXX DJNZ .loop JP LP_END_P ;------------------------------------------------------------------[#85] ; ; ;------------------------------------------------------------------[#86] LP_PRINT_LINE2: CALL LP_BEG_P EXX LD C,PORT_Y EXX LD A,#50 OUT (SLOT3),A ; .loop: LD A,(HL) INC HL EXX OUT (C),D INC D LD (HL),A CORRECT_SCR_40_FORWARD DJNZ_NEXT_HL EXX DJNZ .loop ;LD A,SYS_PAGE ;OUT (SLOT3),A JP LP_END_P ;------------------------------------------------------------------[#86] ; ; ;------------------------------------------------------------------[#87] LP_PRINT_LINE3: CALL LP_BEG_P LD A,#50 OUT (SLOT3),A ; .loop: EXX LD A,D OUT (PORT_Y),A INC D EXX LD A,(HL) INC HL CP D JR NZ,.NoEnd ; DEC HL EXX LD C,' ' JP LP_PRINT_ALL.cont ; .NoEnd: EXX LD (HL),A EXX LD A,E EXX INC L LD (HL),A DEC L CORRECT_SCR_40_FORWARD DJNZ_NEXT_HL EXX DJNZ .loop JP LP_END_P ;------------------------------------------------------------------[#87] ; ; ;------------------------------------------------------------------[#88] LP_PRINT_LINE4: CALL LP_BEG_P LD A,#50 OUT (SLOT3),A ; .loop: EXX LD A,D OUT (PORT_Y),A EXX LD A,(HL) INC HL CP D JR NZ,.NoEndSymbol ; DEC HL EXX LD C,' ' JP LP_PRINT_SYM.cont ; .NoEndSymbol: EXX LD (HL),A INC D CORRECT_SCR_40_FORWARD DJNZ_NEXT_HL EXX DJNZ .loop JP LP_END_P ;------------------------------------------------------------------[#88] ; ; ;------------------------------------------------------------------[#8B] LP_PRINT_LINE5: CALL LP_BEG_P LD A,#50 OUT (SLOT3),A EXX LD C,PORT_Y EXX ; .loop: EXX OUT (C),D EXX LD A,(HL) INC HL CP D JR Z,LP_END_P ; EXX LD (HL),A EXX LD A,E EXX INC L LD (HL),A DEC L INC D CORRECT_SCR_40_FORWARD DJNZ_NEXT_HL EXX DJNZ .loop ;JP LP_END_P ;----------------- ------------------------------------[#8B] ; ожидается, что портятся только альтернативные регистры и те, что как параметры на входе LP_END_P: LD A,SYS_PAGE OUT (SLOT3),A ; .SYS_PAGE: EX AF,AF' EXX RLA LD E,A LD (WIN_ID_0.LineAddr),HL ; место печати LD (WIN_ID_0.ColumnRGADR_TXTMode),DE LD (WIN_ID_0.reg_BC),BC CALL LP_CLOSE_PG EXX EX AF,AF' AND A RET ; .short: EX AF,AF' EXX CALL LP_CLOSE_PG EXX EX AF,AF' AND A RET ;------------------------------------------------------------------[#8C] LP_PRINT_LINE6: CALL LP_BEG_P LD A,#50 OUT (SLOT3),A EXX LD C,PORT_Y EXX ; .loop: EXX OUT (C),D EXX LD A,(HL) INC HL CP D JR Z,LP_END_P ; EXX LD (HL),A INC D CORRECT_SCR_40_FORWARD DJNZ_NEXT_HL EXX DJNZ .loop JP LP_END_P ;------------------------------------------------------------------[#8C] ; ; ;------------------------------------------------------------------[#84] ; портятся только альтернативные регистры и те, что как параметры на входе LP_SET_PLACE: CALL LP_BEG_P CALL LP_SET_CUR JP LP_END_P.SYS_PAGE ;------------------------------------------------------------------[#84] ; ; ;------------------------------------------------------------------[#8E] LP_GET_PLACE: CALL LP_BEG_P LD A,(WIN_ID_0.H_BEG) NEG EXX ADD A,D EXX LD E,A LD A,(WIN_ID_0.V_BEG) NEG EXX ADD A,L DEC A EXX RRCA RRCA AND %0011'1111 LD D,A ; режим txt 40 EX AF,AF' JR C,.no_txt40 SRL E AND A .no_txt40: EX AF,AF' JP LP_END_P.short ;------------------------------------------------------------------[#8E] ; ; ;-------------------------------------------------------------[#89, #8D] ;--------------------------------------------------------[#8D] LP_CLS_WIN2: LD C,A JR LP_CLS_WIN.START ;--------------------------------------------------------[#8D] ;--------------------------------------------------------[#89] LP_CLS_WIN: LD C,' ' ;---------------- -----------------------------[#89] .START: CALL LP_BEG_P CALL .CLS JP LP_END_P.SYS_PAGE ; .CLS: LD (SYS_PAGE.SYS_WORK1),BC ; сохранить цвет ; !TODO использовать переменные окна PUSH DE ; !TODO проверка на превышение размера окна - но сейчас эти процедуры для полного экрана ; EXX ; LD A,B ; EXX ; CP L ; JR NC,.loop1 ; LD L,A ; .loop1: CALL LP_SET_CUR PUSH DE EXX LD BC,(SYS_PAGE.SYS_WORK1) ; !TODO использовать переменные окна EXX LD B,L LD A,#50 OUT (SLOT3),A ; .loop2: EXX LD A,D OUT (PORT_Y),A LD (HL),C INC L LD (HL),B DEC L INC D CORRECT_SCR_40_FORWARD EXX DJNZ .loop2 ; LD A,SYS_PAGE OUT (SLOT3),A POP DE INC D DEC H JR NZ,.loop1 ; POP DE JP LP_SET_CUR ;-------------------------------------------------------------[#89, #8D] ; ; ;------------------------------------------------------------------[#B8] ; DE - адрес куда переслать фонт WIN_GET_ZG: LD HL,ZG_ADDRESS LD BC,ZG_SIZE LDIR AND A RET ;------------------------------------------------------------------[#B8] ; ; ;------------------------------------------------------------------[#B6] WIN_SET_ZG: EX AF,AF' ; LP_SET_ZG: EXX CALL LP_OPEN_PG CALL .SET CALL LP_CLOSE_PG EXX EX AF,AF' AND A RET ; .SET: IN A,(SLOT1) ;LP_SET_ZG1 LD (SYS_PAGE.COPY_SLOT1),A LD A,SHARED_PAGE OUT (SLOT1),A EXX LD BC,Port_All_Mode IN A,(C) LD (SYS_PAGE.SYS_WORK1),A AND #FE ; Spectrum Screen on, accelerator and keyboard interrupt off OUT (C),A EX AF,AF' LD B,A AND #0F ADD A,A OUT (PORT_Y),A LD A,B ; %xx00'0000 RRCA ; %0xx0'0000 RRCA ; %00xx'0000 RRCA ; %000x'x000 AND %0001'1000 OR %0100'0000 LD H,A LD L,0 LD BC,ZG_SIZE EX DE,HL ;[ ] 11/02/2024 установка шрифта более гибкая без заплётов LD A,H SUB #C0 JR NC,.change ; LDIR .cont: EX DE,HL LD A,H RRCA RRCA RRCA DEC A AND 3 ADD A,#58 LD H,A ; .loop: LD (HL),L INC L JR NZ,.loop ; LD A,(SYS_PAGE.SYS_WORK1) LD BC,Port_All_Mode OUT (C),A EXX EX AF,AF' LD A,(SYS_PAGE.COPY_SLOT1) OUT (SLOT1),A RET ; ;[ ] 11/02/2024 установка шрифта более гибкая без заплётов .change: LD A,(SYS_PAGE.COPY_SLOT3) OUT (SLOT3),A LDIR LD A,SYS_PAGE OUT (SLOT3),A JR .cont ;------------------------------------------------------------------[#B6] ; ;******************************************************* ; ; WIN_MAP_SC - карта экрана ; 0 - hor size ; 1 - ver size ; 2 - hor place ; 3 - ver place ; определение size LP_SIZE: CALL LP_OPEN_PG LD DE,(WIN_ID_0.USER.SIZE_H) LD A,(WIN_ID_0.USER.MODE) AND %0010'0000 CALL LP_CLOSE_PG RET NZ ; txt 40 SLA E RET ; ; ожидается, что портятся только альтернативные регистры и те, что как параметры на входе ; установить курсор: ; D - номер символа по вертикали ; E - номер символа по горизонтали LP_SET_CUR: ; LP_AT_D: LD A,(WIN_ID_0.USER.SIZE_V) EXX LD L,A EXX LD A,D EXX .loop_x: SUB L JR NC,.loop_x ; ADD A,L ADD A,A ADD A,A LD L,A ; LD A,(WIN_ID_0.V_BEG) ADD A,L LD L,A INC L LD H,#C3 ;!HARDCODE начало описателей в SLOT3 EXX ;RET ; ;LP_TAB_E: LD A,(WIN_ID_0.SIZE_REL) EXX LD D,A EXX LD A,E EXX .loop_y: SUB D JR NC,.loop_y JR Z,.loop_y ; NEG LD B,A ; сохранить сколько осталось символов в строке NEG ADD A,D LD D,A ; EX AF,AF' JR C,.LLL SLA D ; режим txt 40. не должно ставить CF .LLL: EX AF,AF' .skip_Dx2: LD A,(WIN_ID_0.H_BEG) ADD A,D LD D,A EXX RET ;************************************************************* ; вычисление нового места LP_NEXT_HL: LD A,SYS_PAGE OUT (SLOT3),A LD A,4 ;!HARDCODE длина одного описателя квадратика ADD L LD L,A LD A,(WIN_ID_0.V_END) CP L JR C,.end_line ; .no_end_line: LD A,(WIN_ID_0.H_BEG) LD D,A LD A,(WIN_ID_0.SIZE_REL) LD B,A LD A,#50 OUT (SLOT3),A RET ; .end_line: LD HL,(WIN_ID_0.V_BEG) INC L LD H,#C3 ;!HARDCODE начало описателей в SLOT3 JP .no_end_line ; !ожидается, что портятся только альтернативные регистры и те, что как параметры на входе LP_BEG_P: EX AF,AF' EXX CALL LP_OPEN_PG LD HL,(WIN_ID_0.LineAddr) LD DE,(WIN_ID_0.ColumnRGADR_TXTMode) LD BC,(WIN_ID_0.reg_BC) LD A,E AND A RRA ;OUT (PORT_Y),A EXX EX AF,AF' RET ; LP_INI_P: EX AF,AF' EXX CALL LP_OPEN_PG LD A,(WIN_ID_0.USER.MODE) CP #C0 JR NC,.NO_ZG ; открытие бордера... LD A,(WIN_ID_0.USER.MODE_S) AND %0000'0001 JR NZ,.NO_ZG ; открытие Spectrum-Screen ; LD A,(WIN_ID_0.USER.MODE) BIT 4,A JR Z,.NO_ZG ; открытие графического экрана ;LD DE,(SYS_PAGE.WIN_ZG) ; знакогенератор LD DE,ZG_ADDRESS ; знакогенератор EXX EX AF,AF' CALL WIN_SET_ZG.SET ;LP_SET_ZG1 ;!TODO стоит ли каждый раз закидывать шрифт? EX AF,AF' EXX .NO_ZG: LD A,(WIN_ID_0.H_BEG) LD D,A LD A,(WIN_ID_0.V_BEG) LD L,A INC L LD H,#C3 AND A LD A,(WIN_ID_0.USER.MODE) BIT 5,A LD A,(WIN_ID_0.USER.SIZE_H) JR NZ,.TXT_40 ; TXT_80 ADD A,A SCF .TXT_40: LD B,A LD (WIN_ID_0.SIZE_REL),A EX AF,AF' EXX JP LP_END_P ;******************************************************** ; ;------------------------------------------------------------------[#80] LP_OPEN_S: LD A,B ADD A,A CP LP_SC_TAB.SIZE CCF RET C PUSH HL LD HL,LP_SC_TAB ADD A,L LD L,A JR NC,.no_inc INC H .no_inc: LD A,(HL) INC HL LD H,(HL) LD L,A EX (SP),HL RET ; LP_SC_TAB: DW LP_SET_32 ; 0 - спектрумовское окно 32x24 DW LP_SET_64 ; 1 - текстовое окно 64x24 DW LP_SET_40 ; 2 - текстовое окно 40x32 DW LP_SET_80 ; 3 - текстовое окно 80x32 DW LP_SET_32.X ; 4 - спектрумовское окно, HL - положение окна DW LP_SET_64.X ; 5 - текстовое окно 64x24, HL - положение окна DW LP_SET_40.X ; 6 - текстовое окно 40x32, HL - положение окна DW LP_SET_80.X ; 7 - текстовое окно 80x32, HL - положение окна DW PIC_SET_S1 ; 8 - графическое окно 0, HL - положение окна DW PIC_SET_S2 ; 9 - графическое окно 1, HL - положение окна ;DW LP_SET_MNU ; 10 - ;!TODO .SIZE: EQU $-LP_SC_TAB ; !TODO ; LP_SET_MNU: ; LD IX,LP_SCR_MNU ; JP PIC_FN0_OpenWin LP_SET_32: LD HL,#4104 .X: LD IX,LP_SCR_32 JP PIC_FN0_OpenWin LP_SET_64: LD HL,#4104 .X: LD IX,LP_SCR_64 JP PIC_FN0_OpenWin LP_SET_40: LD HL,#4000 .X: LD IX,LP_SCR_40 JP PIC_FN0_OpenWin LP_SET_80: LD HL,#4000 .X: LD IX,LP_SCR_80 JP PIC_FN0_OpenWin PIC_SET_S1: LD IX,PIC_320X256_1 JP PIC_FN0_OpenWin PIC_SET_S2: LD IX,PIC_320X256_2 JP PIC_FN0_OpenWin ;------------------------------------------------------------------[#80] ; ;------------------------------------------------------------------[#B1] ; !TODO WIN_CLOSE: SCF RET ;------------------------------------------------------------------[#B1] ; ; ;------------------------------------------------------------------[#B0] ; IX - описатель окна WIN_OPEN.SCR1: LD E,1 ; E - bit0 - номер экрана WIN_OPEN: CALL .Prepare LD L,(IX + Window_Variables.USER.PLACE_H) LD H,(IX + Window_Variables.USER.PLACE_V) JP WIN_OPEN_W1 ; .Prepare: CALL LP_OPEN_PG PUSH HL PUSH DE ;LD (SYS_PAGE.WIN_MAP_SC),IX ; карта окна ;LD HL,(SYS_PAGE.WIN_MAP_SC) PUSH IX POP HL LD DE,WIN_ID_0 LD BC,Window_UserVars LDIR LD IX,WIN_ID_0 POP DE POP HL LD (IX + Window_Variables.MODE_E),E RET ;------------------------------------------------------------------[#B0] ; ; ;------------------------------------------------------------------[#A0] ; HL = X + Y*64 + #4000 + #1000*RGMOD. место на экране по знакоместам ; IX - описатель окна ; E - bit0: номер экрана ;LP_SET_MODE: PIC_FN0_OpenWin: ; финт для совместимости со старыми прогами, где передавались другие параметры LD A,H AND %00001'0000 ; переместить бит 4 в регистр E XOR E LD E,A ; LD A,L AND #3F ADD HL,HL ADD HL,HL LD L,A ; LD A,H AND #3F LD H,A CALL WIN_OPEN.Prepare LD (IX + Window_Variables.USER.PLACE_H),L LD (IX + Window_Variables.USER.PLACE_V),H ; WIN_OPEN_W1: LD A,L ADD A,A INC A ; вычисление PORT_Y BIT 4,E JR NZ,.NO_OR OR #80 ; если вывод на второй экран .NO_OR: LD (IX+Window_Variables.H_BEG),A LD D,A LD A,(IX+Window_Variables.USER.SIZE_H) ADD A,A ADD A,D LD (IX+Window_Variables.H_END),A ;LD (SYS_PAGE.WIN_MODE_SC),DE ; место по горизонтали и страница моды LD A,H AND #3F ADD A,A ADD A,A LD L,A LD H,A ;LD (SYS_PAGE.WIN_MODE_SH),HL ; место по вертикали с адресом LD (IX+Window_Variables.V_BEG),A LD A,(IX+Window_Variables.USER.SIZE_V) ADD A,A ADD A,A ADD A,L LD (IX+Window_Variables.V_END),A ; ;LD L,(IX+Window_Variables.V_BEG) LD L,H LD H,#C3 LD B,(IX+Window_Variables.USER.SIZE_V) ; размер по вертикали LD (IX+Window_Variables.WORK_1),0 LD A,(IX+Window_Variables.USER.MODE) ; знакогенератор плюс режим LD (IX+Window_Variables.WORK_2),A BIT 4,A JR NZ,.LOOP ; переход, если текстовый режим ; AND #F0 LD C,A LD A,(IX+Window_Variables.USER.GR_X) RRCA RRCA RRCA LD D,A AND #0F OR C LD (IX+Window_Variables.WORK_2),A ; LD A,D AND #E0 LD C,A LD A,(IX+Window_Variables.USER.GR_Y) AND #1F OR C RLCA RLCA RLCA LD (IX+Window_Variables.WORK_1),A .LOOP: LD D,(IX+Window_Variables.H_BEG) ; D - начало строки (PORT_Y) LD C,(IX+Window_Variables.USER.SIZE_H) ; размер по горизонтали LD A,(IX+Window_Variables.USER.MODE) ; знакогенератор плюс режим PUSH BC CALL LP_MODE_LINE POP BC INC L INC L INC L INC L DJNZ .LOOP ; LD A,(IX+Window_Variables.MODE_E) AND 1 OUT (SCREEN_SWITCH),A ;LD A,(IX+Window_Variables.MODE) ;BIT 4,A CALL LP_CLOSE_PG ;RET Z CALL LP_INI_P ;LD A,(SYS_PAGE.WIN_MODE_SC) ;OUT (RGMOD),A ; нигде не было описано CALL LP_SIZE ; DE - размеры окна ; XOR A ;!TODO номер окна RET ; ; Установка режима на линии LP_MODE_LINE: BIT 0,(IX+Window_Variables.USER.MODE_S) JP NZ,.Spectrum ; идти на спектрум BIT 4,A JP Z,.Graphic ; идти на графику! DEC D ; текстовый режим. EX AF,AF' LD A,#50 OUT (SLOT3),A LD A,L ; вертикальное положение CP #80 JR NC,.Exit_txt ; CALL .RECURSE JR NC,.Exit_txt ; CALL .CALC_C ; .loop_txt_scr: EX AF,AF' LD A,D OUT (PORT_Y),A EX AF,AF' LD (HL),A ; режим INC D EX AF,AF' LD A,D OUT (PORT_Y),A EX AF,AF' LD (HL),A ; режим INC D DEC C JR NZ,.loop_txt_scr ; EX AF,AF' .Exit_txt: LD A,SYS_PAGE OUT (SLOT3),A EX AF,AF' RET ; ; Spectrum mode .Spectrum: LD A,(IX+Window_Variables.WORK_2) LD B,(IX+Window_Variables.WORK_1) DEC D EX AF,AF' LD A,#50 OUT (SLOT3),A LD A,L ; вертикальное положение CP #80 JR NC,.Exit_zx_scr ; CALL .RECURSE JR NC,.Exit_zx_scr ; CALL .CALC_C ; .loop_zx_scr: EX AF,AF' LD A,D OUT (PORT_Y),A EX AF,AF' LD (HL),A ; режим ; INC L LD (HL),B INC L LD (HL),B DEC L DEC L ; INC D BIT 4,A JR NZ,.no_inc_B_zx ; INC B .no_inc_B_zx: EX AF,AF' LD A,D OUT (PORT_Y),A EX AF,AF' ; LD (HL),A ; режим INC L LD (HL),B INC L LD (HL),B DEC L DEC L ; INC D INC B JR NZ,.NO_ADD_40 ; ADD A,#40 .NO_ADD_40: DEC C JR NZ,.loop_zx_scr EX AF,AF' ; .Exit_zx_scr: LD A,SYS_PAGE OUT (SLOT3),A EX AF,AF' LD (IX+Window_Variables.WORK_1),B LD (IX+Window_Variables.WORK_2),A RET ; ; Graphic Mode .Graphic: LD A,(IX+Window_Variables.WORK_1) LD B,(IX+Window_Variables.WORK_2) DEC D EX AF,AF' LD A,#50 OUT (SLOT3),A LD A,L ; вертикальное положение CP #80 JR NC,.Exit2_GFX_scr ; CALL .RECURSE JR NC,.Exit2_GFX_scr ; CALL .CALC_C ; BIT 5,B JR Z,.GFX_640_Loop ; ; GFX 320 .loop_GFX_scr: EX AF,AF' LD A,D OUT (PORT_Y),A EX AF,AF' LD (HL),B ; mode 0 INC L LD (HL),A ; mode 1 INC L LD (HL),0 ; mode 2 DEC L DEC L INC D ; ;EX AF,AF' ;LD A,D ;OUT (PORT_Y),A ;EX AF,AF' ;LD (HL),B ; режим ;INC L ;LD (HL),A ; режим 2 ;DEC L ; INC D INC A LD E,A AND 7 JR NZ,.NO_INC_B_320 ; LD A,E SUB 8 LD E,A INC B .NO_INC_B_320: LD A,E DEC C JR NZ,.loop_GFX_scr ; .Exit_GFX_scr: EX AF,AF' .Exit2_GFX_scr: LD A,SYS_PAGE OUT (SLOT3),A EX AF,AF' LD A,(IX+Window_Variables.WORK_1) ADD A,8 LD (IX+Window_Variables.WORK_1),A RET ; ; GFX 640 .GFX_640_Loop: EX AF,AF' LD A,D OUT (PORT_Y),A EX AF,AF' LD (HL),B ; mode 0 INC L LD (HL),A ; mode 1 INC L LD (HL),0 ; mode 2 ; INC D EX AF,AF' LD A,D OUT (PORT_Y),A EX AF,AF' LD (HL),0 ; mode 2 DEC L LD (HL),A ; mode 1 DEC L LD (HL),B ; mode 0 ; INC D INC A LD E,A AND 7 JR NZ,.NO_INC_B_640 ; LD A,E SUB 8 LD E,A INC B .NO_INC_B_640: LD A,E DEC C JR NZ,.GFX_640_Loop JP .Exit_GFX_scr ; .RECURSE: LD A,D ; горизонтальное положение AND #7F SUB 80 RET C SUB 48 NEG LD E,A ; запомнить ADD A,D LD D,A ; новое положение LD A,E ; восстановить RRA AND #3F SUB C RET NC NEG LD C,A ; новое значение C JR .RECURSE ; .CALC_C: NEG RRA AND #3F CP C JR NC,.NoChangeC LD C,A .NoChangeC: EX AF,AF' INC D RET ;***************************************************************** LP_SCROLL_UD: DEC B JR Z,LP_SCROLL_UP DEC B JR Z,LP_SCROLL_DN SCF RET ; Вход: ; D - верхняя строка ( от 0 ) ; E - число скроллируемых строк LP_SCROLL_UP: DEC E RET Z CALL LP_OPEN_PG ; LD B,E LD E,0 ; всю строку окна скроллим CALL .RUN JP LP_CLOSE_PG ; ; .RUN: CALL LP_SET_CUR ; вычислить переменные для строки PUSH IX LD IX,(WIN_ID_0.USER.SIZE_H) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!TODO ; отличие от LP_SCROLL_DN LD A,(WIN_ID_0.V_END) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; LD C,A LD A,#50 OUT (SLOT3),A ; открыть страницу для переноса ; .loop2: EXX PUSH HL EXX POP HL ; LD E,L LD D,H ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!TODO ; отличие от LP_SCROLL_DN LD A,4 ADD L LD L,A ; LD A,C ; LD A,(WIN_ID_0.V_END) CP L JR C,.exit ; если конец, то выход ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; PUSH BC LD A,L EXX LD L,A EXX ;XH LD A,XL ; WIN_ID_0.USER.SIZE_H ; LD A,SYS_PAGE ; OUT (SLOT3),A ; LD A,(WIN_ID_0.USER.SIZE_H) ADD A,A ; число байт в строке для переноса ADD A,A LD C,A LD B,0 ; LD A,#50 ; OUT (SLOT3),A ; открыть страницу для переноса ; EXX LD A,D ; получить порт начала строки EXX .loop1: OUT (PORT_Y),A INC A ; следующее значение порта LDI LDD ; OUT (PORT_Y),A INC A ; следующее значение порта LDI LDD JP PE,.loop1 ; POP BC DJNZ .loop2 .exit: POP IX RET ; Вход : ; D - верхняя строка ( от 0 ) ; E - число скроллируемых строк LP_SCROLL_DN: DEC E RET Z CALL LP_OPEN_PG ; LD B,E LD E,0 LD A,D ADD A,B LD D,A CALL .RUN .EXIT: JP LP_CLOSE_PG ; ; .RUN: CALL LP_SET_CUR PUSH IX LD IX,(WIN_ID_0.USER.SIZE_H) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!TODO ; отличие от LP_SCROLL_UD LD A,(WIN_ID_0.V_BEG) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; LD C,A LD A,#50 OUT (SLOT3),A ; открыть страницу для переноса ; .loop2: EXX PUSH HL EXX POP HL ; LD E,L LD D,H ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;!TODO ; отличие от LP_SCROLL_UD LD A,L SUB 4 LD L,A ; LD A,C CP L ; .CONT: L >= A JR Z,.CONT JR NC,.exit ; если конец, то выход ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; .CONT: PUSH BC LD A,L EXX LD L,A EXX ; LD A,XL ; WIN_ID_0.USER.SIZE_H ; LD A,SYS_PAGE ; OUT (SLOT3),A ; LD A,(WIN_ID_0.USER.SIZE_H) ADD A,A ; число байт в строке для переноса ADD A,A LD C,A LD B,0 ; LD A,#50 ; OUT (SLOT3),A ; открыть страницу для переноса ; EXX LD A,D ; получить порт начала строки EXX .loop1: OUT (PORT_Y),A INC A ; следующее значение порта LDI LDD ; OUT (PORT_Y),A INC A ; следующее значение порта LDI LDD JP PE,.loop1 ; POP BC DJNZ .loop2 .exit: POP IX RET ; DE - место символа в окне ; А - номер окна ; выход: HL - символ/атрибут B - знакогенератор WIN_GET_SYM: AND A SCF RET NZ ; CALL LP_BEG_P CALL LP_SET_CUR LD A,#50 OUT (SLOT3),A ; EXX LD A,D OUT (PORT_Y),A LD A,(HL) EXX LD L,A EXX INC L LD A,(HL) EXX LD H,A EXX DEC L DEC L LD A,(HL) INC L EXX LD B,A JP LP_END_P ;RET ; DE - место символа в окне ; А - номер окна ; HL - символ/атрибут ; B - знакогенератор WIN_PUT_SYM: AND A SCF RET NZ ; CALL LP_BEG_P CALL LP_SET_CUR LD A,#50 OUT (SLOT3),A ; EXX LD A,D OUT (PORT_Y),A EXX ; [ ] 31/03/2025 если B=0, то кладём только символ ; если B=1, то кладём символ с атрибутом ; символ ; LD A,L ; EXX ; LD (HL),A ; INC L ; EXX ; ; атрибут ; LD A,H ; EXX ; LD (HL),A ; DEC L ; DEC L ; EXX ; ; шрифт ; LD A,B ; EXX ; LD (HL),A ; INC L ; EXX ; JP LP_END_P ; ; шрифт LD A,B OR A JR Z,.onlySymbol DEC B JR Z,.noChangeZG ; EXX DEC L LD (HL),A INC L EXX ; атрибут .noChangeZG: LD A,H EXX INC L LD (HL),A DEC L EXX ; символ .onlySymbol: LD A,L EXX LD (HL),A EXX JP LP_END_P ; HL - размер окна ; DE - положение окна ; A - номер окна ; IX - новое положение окна WIN_MOVE: AND A SCF RET NZ PUSH IX PUSH HL LD B,SHARED_PAGE LD IX,SLOT3.MEM_ADDR CALL WIN_COPY_WIN1 POP HL POP DE LD B,SHARED_PAGE LD IX,SLOT3.MEM_ADDR CALL WIN_RESTORE.Start AND A RET ; HL - размер сохраняемого окна ; DE - место сохраняемого окна ; IX - адрес сохраняемого окна, в странице 4000h ; А - номер окна, B - страница WIN_COPY: AND A SCF RET NZ WIN_COPY_WIN1: CALL LP_BEG_P IN A,(SLOT1) PUSH AF ; CALL LP_SET_CUR LD (SYS_PAGE.SYS_WORK1),SP LD A,B OUT (SLOT3),A LD A,#50 OUT (SLOT1),A ; EXX RES 7,H LD C,D EXX ; .COPY_loop2: LD A,L EXX LD B,A ADD A,A ADD A,XL LD XL,A JR NC,.NO_INC_XH ; INC XH .NO_INC_XH: LD SP,IX LD A,C ADD A,B .COPY_loop: DEC A OUT (PORT_Y),A LD E,(HL) INC L LD D,(HL) DEC L PUSH DE DJNZ .COPY_loop ; INC HL INC HL INC HL INC HL EXX DEC H JR NZ,.COPY_loop2 ; LD A,SYS_PAGE OUT (SLOT3),A LD SP,(SYS_PAGE.SYS_WORK1) ; POP AF OUT (SLOT1),A JP LP_END_P.short ; ; HL - размер сохраняемого окна ; DE - место сохраняемого окна ; IX - адрес данных восстанавливаемого окна WIN_RESTORE: AND A SCF RET NZ .Start: CALL LP_BEG_P ; IN A,(SLOT1) PUSH AF ; CALL LP_SET_CUR ; LD (SYS_PAGE.SYS_WORK1),SP LD SP,IX ; LD A,B OUT (SLOT3),A LD A,#50 OUT (SLOT1),A ; EXX RES 7,H LD C,D EXX .L2: LD A,L EXX LD B,A LD A,C .L1: OUT (PORT_Y),A INC A POP DE LD (HL),E INC L LD (HL),D DEC L DJNZ .L1 ; INC HL INC HL INC HL INC HL EXX DEC H JR NZ,.L2 LD A,SYS_PAGE OUT (SLOT3),A LD SP,(SYS_PAGE.SYS_WORK1) POP AF OUT (SLOT1),A JP LP_END_P.short ;======================================================================; ; Печать с управляющими символами в консоль ;------------------------------------------------------------------[#E0] LP_PR_LINE_DIR: ;>------------------------------------------------[BELL] .BELL: EXX PUSH HL PUSH BC ; LD DE,1200 LD HL,4 CALL BEEP ; POP BC POP HL EXX JR .loop ;-------------------------------------------------[BELL] ;>------------------------------------------------[Backspace] .BACK: LD A,(WIN_ID_0.H_BEG) CP D JR Z,.loop INC B DEC D CORRECT_SCR_40_BACKWARD JP .loop ;>------------------------------------------------[Backspace] ; .EXIT_SpecSymbol: DEC HL CALL LP_END_P POP IX SCF RET ; .EXIT: POP IX JP LP_END_P ;;;;;;;;;;;;;;;;; ; A - атрибуты выводимого символа если CF' ; A' - если !=0 то без скролла ; CF - XY-mode ; DE - место символа в окне, если CF=1 ; HL - адрес с выводимой строкой ; B - цвет консоли (используется при скролле и очистке окна) ; IY - два спец.символа для выхода с CF=1. Должны быть равны 0, если не нужны ; CF' - выводить символ с атрибутами ;;;;;;;;;;;;;;;;; .START: PUSH IX LD XL,A ; атрибуты выводимого символа ; EX AF,AF' PUSH AF ; attr-mode EX AF,AF' ; IN A,(SLOT3) LD C,A CALL LP_BEG_P CALL C,LP_SET_CUR ; mode for DE LD A,B ; далее рег B свободен, можно задействовать LD (SYS_PAGE.SYS_WORK2),A ; цвет консоли POP AF ; attr-mode, scroll on/off LD B,A ; scroll on/off EXX RL C ; C' - attr-mode. выводить атрибут .loop: LD A,D OUT (PORT_Y),A EXX LD A,C OUT (SLOT3),A ; LD A,(HL) LD XH,A INC HL AND A JR Z,.EXIT CP YH JR Z,.EXIT_SpecSymbol CP YL JR Z,.EXIT_SpecSymbol ; EXX ; печатаемые символы CP 14 JR NC,.print CP 7 JR C,.print ; управляющие символы LD A,SYS_PAGE OUT (SLOT3),A LD A,XH ; SUB 7 JR Z,.BELL ; A = 07 "BELL" DEC A JR Z,.BACK ; A = 08 "Backspace" DEC A JR Z,.TAB ; A = 09 "TAB" DEC A JR Z,.LineFeed ; А = 10 "Line Feed" DEC A JR Z,.VertTab ; А = 11 "Vertical Tabulation" DEC A JR Z,.CLS ; А = 12 "Form feed" - разрыв страницы, начало нового листа, может работать как VT ;DEC A ;JR Z,.CR ; А = 13 "Carriage Return" ;>------------------------------------------------[CR] .CR: LD A,(WIN_ID_0.H_BEG) LD D,A LD A,(WIN_ID_0.SIZE_REL) LD B,A JP .loop ;-------------------------------------------------[CR] ;>------------------------------------------------[PRINT] .print: LD A,#50 OUT (SLOT3),A LD A,XH LD (HL),A ; выводить атрибут RR C ; C' - attr flag JR NC,.NoPutAttr ; INC L LD A,XL LD (HL),A DEC L .NoPutAttr: RL C ; C' - attr flag INC D .next_full: CORRECT_SCR_40_FORWARD .next: DJNZ .loop CALL LP_NEXT_HL_DIR JP .loop ;-------------------------------------------------[PRINT] ;>------------------------------------------------[TAB] .TAB: LD A,(WIN_ID_0.H_BEG) SUB D NEG AND %0000'0111 NEG ADD A,8 CP B JR C,.keep_A ; LD A,B DEC A .keep_A: ;NEG PUSH BC ; save C' - attr flag LD C,A EX AF,AF' JR C,.LLL ; EX AF,AF' ADD A,A ; режим 40 EX AF,AF' .LLL: EX AF,AF' ; .tabNxt: ADD A,D LD D,A LD A,B SUB C ; set XL POP BC ; restore C' - attr flag LD B,A JP .loop ; ;-------------------------------------------------[TAB] ;>------------------------------------------------[Line Feed] .VertTab: ; .LineFeed: LD A,4 ;!HARDCODE длина одного описателя квадратика ADD L LD L,A ; LD A,(WIN_ID_0.V_END) CP L CALL C,LP_NEXT_HL_DIR.end_line JP .loop ;-------------------------------------------------[Line Feed] ;>------------------------------------------------[Form feed] .CLS: PUSH BC ; C' - attr flag EXX PUSH BC PUSH HL PUSH DE ; LD A,(SYS_PAGE.SYS_WORK2) ; цвет консоли LD B,A LD DE,0 LD HL,(WIN_ID_0.USER.SIZE_H) ; get WIN XY LD A,(WIN_ID_0.SIZE_REL) LD L,A LD C," " CALL LP_CLS_WIN.CLS ; POP DE POP HL POP BC EXX LD A,B POP BC ; C' - attr flag LD B,A JP .loop ;-------------------------------------------------[Form feed] ;------------------------------------------------------------------[#E0] ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; LP_NEXT_HL_DIR: LD A,SYS_PAGE OUT (SLOT3),A LD A,4 ;!HARDCODE длина одного описателя квадратика ADD L LD L,A LD A,(WIN_ID_0.V_END) CP L CALL C,.end_line ; .no_end_line: LD A,(WIN_ID_0.H_BEG) LD D,A LD A,(WIN_ID_0.SIZE_REL) LD B,A RET ; .end_line: LD A,L SUB 4 ;!HARDCODE длина одного описателя квадратика LD L,A ; игнорим скрролл или нет? EXX LD A,B EXX AND A RET NZ ; ZF=0 игнор скролла ; PUSH HL DEC L PUSH BC PUSH DE EXX PUSH BC PUSH HL PUSH DE LD A,(WIN_ID_0.V_BEG) LD D,A LD A,(WIN_ID_0.USER.SIZE_V) LD B,A LD E,0 ; всю строку окна скроллим CALL LP_SCROLL_UP.RUN ; LD A,SYS_PAGE OUT (SLOT3),A LD C," " LD A,(SYS_PAGE.SYS_WORK2) ; цвет консоли LD B,A LD A,(WIN_ID_0.USER.SIZE_V) DEC A LD D,A LD E,0 LD HL,(WIN_ID_0.SIZE_REL) LD H,1 LD C," " CALL LP_CLS_WIN.CLS ; POP DE POP HL POP BC EXX POP DE POP BC POP HL RET ; ; LD HL,(WIN_ID_0.V_END) ; DEC L ; DEC L ; DEC L ; LD H,#C3 ; ; ; LD A,(WIN_ID_0.H_BEG) ; LD D,A ; ; ; LD A,#50 ; OUT (SLOT3),A ; ; ; EXX ; LD A,(WIN_ID_0.SIZE_REL) ; LD B,A ; .loop_cl_line: EXX ; LD A,D ; OUT (PORT_Y),A ; LD (HL),C ; INC D ; CORRECT_SCR_40_FORWARD ; EXX ; DJNZ .loop_cl_line ; LD A,SYS_PAGE ; OUT (SLOT3),A ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; LP_OPEN_PG: IN A,(SLOT3) LD C,A LD A,SYS_PAGE OUT (SLOT3),A ; LD A,C LD (SYS_PAGE.COPY_SLOT3),A IN A,(PORT_Y) LD (SYS_PAGE.COPY_RGADR),A RET ; ; не должна влиять на флаги и трогать регистры кроме A LP_CLOSE_PG: LD A,(SYS_PAGE.COPY_RGADR) OUT (PORT_Y),A LD A,(SYS_PAGE.COPY_SLOT3) OUT (SLOT3),A RET /* ;!TODO старая LP_SET_MODE - расковырять старый LP_SCR_MNU MODULE EXPERIMENT ; byte 1 ; 0..4 - VIDEO_PAGE ; 5 - mode 42/84 ; 0 - 42,1 - 84 ; 6 - next line ; 7 - end table ; byte 2 - number of places ; byte 3..4 - adress places/ ; 4000-5FFF - Spectrum modes/ C000-FFFF - Graf mode ; MACRO LP_S PG,XX,ADR DB PG,XX DW ADR ENDM MACRO LP_OPEN_PG IN A,(SLOT3) LD C,A LD A,SYS_PAGE OUT (SLOT3),A ; LD A,C LD (SYS_PAGE.COPY_SLOT3),A IN A,(PORT_Y) LD (SYS_PAGE.COPY_RGADR),A ENDM ; MACRO LP_CLOSE_PG LD A,(SYS_PAGE.COPY_RGADR) OUT (PORT_Y),A LD A,(SYS_PAGE.COPY_SLOT3) OUT (SLOT3),A ENDM ; ;--------------------------------------- GR_BIT_END: EQU 7 S_BIT_END: EQU 7 S_BIT_LIN: EQU 6 S_BIT_MOD: EQU 5 BIT_1440: EQU 1 BIT_MASK_1440: EQU %00000010 MODE_PAGE: EQU #FC ;--------------------------------------- ;DS (($/4)*4+4-$) ALIGN 4 LP_SCR_MNU: LP_S #40,14,#40E7 LP_S #40,14,#4807 LP_S #40,14,#4827 LP_S #40,14,#4847 LP_S #40,14,#4867 LP_S #40,14,#4887 LP_S #40,14,#48A7 LP_S #40,14,#48C7 LP_S #40,14,#48E7 DB #FF,0,0,0 ; LP_SCR_80: ; DB 40,32,0,0,#1B,0,0,0 ; DB 0,0,0,0,0,0,0,0 ; LP_S %0110'0010,40,#4000 ; LP_S %0110'0010,40,#4028 ; LP_S %0110'0010,40,#4050 ; LP_S %0110'0010,40,#4078 ; LP_S %0110'0010,40,#40A0 ; LP_S %0110'0010,40,#40C8 ; ; LP_S %0110'0010,40,#4800 ; LP_S %0110'0010,40,#4828 ; LP_S %0110'0010,40,#4850 ; LP_S %0110'0010,40,#4878 ; LP_S %0110'0010,40,#48A0 ; LP_S %0110'0010,40,#48C8 ; ; LP_S %0110'0010,40,#5000 ; LP_S %0110'0010,40,#5028 ; LP_S %0110'0010,40,#5050 ; LP_S %0110'0010,40,#5078 ; LP_S %0110'0010,40,#50A0 ; LP_S %0110'0010,40,#50C8 ; ; LP_S %0110'0100,40,#4000 ; LP_S %0110'0100,40,#4028 ; LP_S %0110'0100,40,#4050 ; LP_S %0110'0100,40,#4078 ; LP_S %0110'0100,40,#40A0 ; LP_S %0110'0100,40,#40C8 ; ; LP_S %0110'0100,40,#4800 ; LP_S %0110'0100,40,#4828 ; LP_S %0110'0100,40,#4850 ; LP_S %0110'0100,40,#4878 ; LP_S %0110'0100,40,#48A0 ; LP_S %0110'0100,40,#48C8 ; ; LP_S %0110'0100,40,#5000 ; LP_S %0110'0100,40,#5028 ; ; DEFB #FF,0,0,0 ; ; LP_SCR_40: ; DB 40,32,0,0,7BH,0,0,0 ; DB 0,0,0,0,0,0,0,0 ; ; LP_S 01000100B,40,5050H ; LP_S 01000100B,40,5078H ; LP_S 01000100B,40,50A0H ; LP_S 01000100B,40,50C8H ; ; LP_S 01000110B,40,4000H ; LP_S 01000110B,40,4028H ; LP_S 01000110B,40,4050H ; LP_S 01000110B,40,4078H ; LP_S 01000110B,40,40A0H ; LP_S 01000110B,40,40C8H ; ; LP_S 01000110B,40,4800H ; LP_S 01000110B,40,4828H ; LP_S 01000110B,40,4850H ; LP_S 01000110B,40,4878H ; LP_S 01000110B,40,48A0H ; LP_S 01000110B,40,48C8H ; ; LP_S 01000110B,40,5000H ; LP_S 01000110B,40,5028H ; LP_S 01000110B,40,5050H ; LP_S 01000110B,40,5078H ; LP_S 01000110B,40,50A0H ; LP_S 01000110B,40,50C8H ; ; LP_S 01001000B,40,4000H ; LP_S 01001000B,40,4028H ; LP_S 01001000B,40,4050H ; LP_S 01001000B,40,4078H ; LP_S 01001000B,40,40A0H ; LP_S 01001000B,40,40C8H ; ; LP_S 01001000B,40,4800H ; LP_S 01001000B,40,4828H ; LP_S 01001000B,40,4850H ; LP_S 01001000B,40,4878H ; ; DEFB 0FFh,0,0,0 ; ; LP_SCR_32: ; DB 32,24,4,4,30H,1,0,0 ; DB 0,0,0,0,0,0,0,0 ; ; LP_S 040h,32,04000H ; LP_S 040h,32,04020H ; LP_S 040h,32,04040H ; LP_S 040h,32,04060H ; LP_S 040h,32,04080H ; LP_S 040h,32,040A0H ; LP_S 040h,32,040C0H ; LP_S 040h,32,040E0H ; ; LP_S 040h,32,04800H ; LP_S 040h,32,04820H ; LP_S 040h,32,04840H ; LP_S 040h,32,04860H ; LP_S 040h,32,04880H ; LP_S 040h,32,048A0H ; LP_S 040h,32,048C0H ; LP_S 040h,32,048E0H ; ; LP_S 040h,32,05000H ; LP_S 040h,32,05020H ; LP_S 040h,32,05040H ; LP_S 040h,32,05060H ; LP_S 040h,32,05080H ; LP_S 040h,32,050A0H ; LP_S 040h,32,050C0H ; LP_S 040h,32,050E0H ; ; LP_S 0FFh,0,0 ; ; LP_SCR_64: ; DB 32,24,4,4,9BH,0,0,0 ; DB 0,0,0,0,0,0,0,0 ; ; LP_S 06Ah,32,04000H ; LP_S 06Ah,32,04020H ; LP_S 06Ah,32,04040H ; LP_S 06Ah,32,04060H ; LP_S 06Ah,32,04080H ; LP_S 06Ah,32,040A0H ; LP_S 06Ah,32,040C0H ; LP_S 06Ah,32,040E0H ; ; LP_S 06Ah,32,04800H ; LP_S 06Ah,32,04820H ; LP_S 06Ah,32,04840H ; LP_S 06Ah,32,04860H ; LP_S 06Ah,32,04880H ; LP_S 06Ah,32,048A0H ; LP_S 06Ah,32,048C0H ; LP_S 06Ah,32,048E0H ; ; LP_S 06Ah,32,05000H ; LP_S 06Ah,32,05020H ; LP_S 06Ah,32,05040H ; LP_S 06Ah,32,05060H ; LP_S 06Ah,32,05080H ; LP_S 06Ah,32,050A0H ; LP_S 06Ah,32,050C0H ; LP_S 06Ah,32,050E0H ; ; LP_S 0FFh,0,0 @LP_SET_MNU: LD IX,LP_SCR_MNU ;JR LP_SET_MODE ; HL - смещение от начала экрана ; = hor_sh + vert_sh * 64 + 4000H ; IX - экранная таблица LP_SET_MODE: LP_OPEN_PG LD (SYS_PAGE.WIN_MAP_SC),IX LD (SYS_PAGE.WIN_MODE_SH),HL LD (SYS_PAGE.WIN_MODE_SC),DE LD HL,(SYS_PAGE.WIN_MAP_SC) LD DE,SYS_PAGE.WIN_MAP_IX .LP_SET_COPY: LD BC,4 LDIR BIT S_BIT_END,(HL) JR Z,.LP_SET_COPY LD BC,4 LDIR LD HL,SYS_PAGE.WIN_MAP_IX LD (SYS_PAGE.WIN_MAP_SC),HL .LP_SET_MODE_INT: LD IX,(SYS_PAGE.WIN_MAP_SC) LD HL,(SYS_PAGE.WIN_MODE_SH) CALL LP_SET_MODE1 LD DE,(SYS_PAGE.WIN_MODE_SC) LP_CLOSE_PG PUSH DE CALL LP_INI_P POP DE LD A,E OUT (RGMOD),A CALL LP_SIZE RET LP_SET_MODE1: AND A BIT S_BIT_END,(IX) ; проверка конца данных RET NZ PUSH HL IN A,(RGADR) PUSH AF LD A,H CP #48 CCF LD A,#16 ADC A,0 OUT (RGADR),A .LP_SET_LOOP: CALL LP_MODE_LINE INC IX INC IX INC IX INC IX BIT S_BIT_LIN,(IX) JR Z,.LP_SET_LOOP POP AF OUT (RGADR),A POP HL LD BC,#40 ADD HL,BC JR LP_SET_MODE1 ;******************************************************** ; Вычисление значения MODE из экранной таблицы. ; IX - текущее положение в таблице. LP_MODE_LINE: BIT 3,H RET NZ IN A,(SLOT1) LD (SYS_PAGE.SYS_WORK1),A IN A,(RGADR) AND 1 OR MODE_PAGE OUT (SLOT1),A LD A,(IX) LD B,A RRCA AND #0F LD C,A LD A,B AND #20 XOR #30 OR C LD C,A LD A,(IX+3) RLC A RLC A RLC A AND #C0 OR C LD D,A ; Первый байт MODE LD E,(IX+2) ; Второй байт.. LD B,(IX+1) ; число знакомест LD A,L AND #3F SUB 40 JR NC,.LP_NO_SET_MD NEG CP B JR NC,.LP_MD_NO_B LD B,A .LP_MD_NO_B: .LP_MD_LOOP: SET 4,H LD (HL),E RES 4,H LD (HL),D INC E INC L DJNZ .LP_MD_LOOP .LP_MD_END: LD A,(SYS_PAGE.SYS_WORK1) OUT (SLOT1),A RET .LP_NO_SET_MD: LD A,C .LP_MD_LOOP2: INC E INC L BIT 5,H JR Z,.LP_MD_LOOP DJNZ .LP_MD_LOOP2 JR .LP_MD_END ; вычисление нового места LP_TAB_HL: LD HL,(SYS_PAGE.WIN_TAB_SC) ; загрузить текущее положение в таблице SCR LD A,(HL) ; загрузить флаги таблицы BIT S_BIT_END,A ; флаг конца JR Z,LP_TAB_H1 ; если 0 - не конец LP_TAB_H2: LD HL,(SYS_PAGE.WIN_MAP_SC) ; загрузить начальное положение в таблице SCR LP_TAB_H3: LD A,(HL) ; и новые флаги LP_TAB_H1: CALL .LP_PG1 ; переключить страницу INC HL ; (HL) - новое число символов BIT S_BIT_MOD,A ; бит 42/84 LD A,(HL) ; загрузить число символов JR Z,.LP_NO_MUL ; если 84, то не нужно умножение на 2 ADD A,A ; A=A*2 .LP_NO_MUL: LD B,A ; число символов в B INC HL ; загрузка нового HL LD A,(HL) INC HL INC HL LD (SYS_PAGE.WIN_TAB_SC),HL ; с сохранением следующего положения в таблице SCR DEC HL LD H,(HL) ; положение на экране LD L,A LD A,H RRCA ; вычислить положение RRCA ; аттрибута RRCA AND 3 OR H OR #18 LD C,A RET .LP_PG1: AND #1F ; переключать только страницы ОЗУ Spectrum mode OUT (RGADR),A LD E,(HL) ; значение битов и флагов BIT S_BIT_MOD,E ; бит 42/84 JR Z,.LP_N_84 ; если 42 то не устанавливать CF SCF ; 84 mode .LP_N_84: EX AF,AF' ; спрятать флаги и значение для вывода в порт LD A,E ; в A должен быть байт с флагами RET ; program init registers ; for low printer & save LP_INI_P: EXX LP_OPEN_PG LD DE,(SYS_PAGE.WIN_ZG) LD B,0 CALL LP_TAB_H2 EXX ; program save registers ; for low printer LP_END_P: EX AF,AF' EXX RLA LD E,A LD (SYS_PAGE.WIN_SAV_HL),HL LD (SYS_PAGE.WIN_SAV_DE),DE LD (SYS_PAGE.WIN_SAV_BC),BC LP_CLOSE_PG EXX EX AF,AF' RET ; определение size LP_SIZE: LP_OPEN_PG EXX XOR A LD HL,(SYS_PAGE.WIN_MAP_SC) ; начало карты scr CALL .LP_LN2 ; сканировать до EXX ; конца NEG ; получить число LD D,A ; строк в D LD E,0 EXX ;LD A,3 ; число символов LD HL,(SYS_PAGE.WIN_MAP_SC) ; по 3-йе строке ;CALL LP_LN2 ; настройка .LOOP: CALL LP_TAB_H3 ; данные LD A,B EXX ADD A,E LD E,A EXX LD HL,(SYS_PAGE.WIN_TAB_SC) ; данные экрана BIT S_BIT_LIN,(HL) JR Z,.LOOP ;BIT S_BIT_MOD,(HL) EXX ;XOR A ;OUT (RGADR),A LP_CLOSE_PG RET ; .LP_LN0: DEC A RET Z .LP_LN1: INC HL INC HL INC HL INC HL .LP_LN2: BIT S_BIT_LIN,(HL) JR Z,.LP_LN1 BIT S_BIT_END,(HL) JR Z,.LP_LN0 RET ENDMODULE */