;[BEGIN] ;//MODULE: VIDEO ;//CREATE: 19-05-1998 AUTHOR: Denis Parinov ;//UPDATE: 24-10-1999 DNS Restore module ;--------------------------------------------------------------- ;Rev Date Name Description ;--------------------------------------------------------------- ;R02 07-11-2002 DNS CORRECT FN. WINCOPY & WINREST, ADD "DI+EI" ;R01 07-11-2002 DNS FIX BUG WITH SCROLLUP FN. (A=0) ;--------------------------------------------------------------- ;///////////////////////////////////////////////////////////////////// ; Функция #56. Очистить окно. ; ; вход: D - строка левого верхнего угла окна ; E - столбец левого верхнего угла окна ; H - высота окна ; L - ширина окна ; A - символ заполнитель ; B - атрибут заполнитель ; выход: нет ;///////////////////////////////////////////////////////////////////// CLEAR: LD C,BIOS.LP_CLS_WIN2 JP ToBIOS ;AND A ;RET ; ;///////////////////////////////////////////////////////////////////// ; Функция #5C. Вывод строки на экран. ; ; вход: HL - указатель на строку символов ; выход: HL - указатель на следующую строку символов ; PRINT NULL-TERMINATED CHARS STRING ;///////////////////////////////////////////////////////////////////// PCHARS: LD A,(HL) INC HL OR A RET Z CALL PUTCHAR JP PCHARS ;///////////////////////////////////////////////////////////////////// ; Функция #5B. Вывод символа на экран в тек. позиции. ; ; вход: A - символ ; выход: нет ;///////////////////////////////////////////////////////////////////// PUTCHAR: ;CALL .NO_SCROLL CP #0E JR C,.control_characters ; LD BC,1*256 + BIOS.LP_PRINT_SYM ;[x] CR+LF+SCROLL RST ToBIOS ; ; проверка на переход курсора в самое начало (X:Y == 0:0) CALL CURSOR LD A,D OR E RET NZ ; .LFF: PUSH HL LD BC,1*256 + BIOS.LP_SCROLL_UD LD DE,#0020 RST ToBIOS LD DE,#1F00 CALL LOCATE LD A,' ' LD BC,#50*256 + BIOS.LP_PRINT_SYM RST ToBIOS LD DE,#1F00 CALL LOCATE POP HL RET .TB_: CALL CURSOR IF TABisSPACES LD B,E LD A,E AND #F8 ADD A,8 SUB B LD B,A LD A,' ' LD C,BIOS.LP_PRINT_SYM JP ToBIOS ELSE LD A,E ADD A,8 AND #78 ;????? глянуть, что будет если координаты курсора в конце строки почти LD E,A JP LOCATE ENDIF .BK_: CALL CURSOR XOR A CP E RET Z DEC E JP LOCATE .LF_: CALL CURSOR LD A,D CP #1F JR NC,.LFF INC D IFN EnoughtOnly_LF JP LOCATE ELSE CALL LOCATE ; !!!! НЕ разрывать LF_ и CR_ !!!! ENDIF .CR_: CALL CURSOR LD E,0 JP LOCATE ; [x] Beep in PChars/PUTCHAR .BELL: LD DE,1200 PUSH HL LD HL,4 CALL BEEP POP HL RET ; ; [x] -bug with Vasil's version of cursor .NO_SCROLL: CP #0E JR C,.control_characters ._CHAR: LD BC,1*256 + BIOS.LP_PRINT_SYM JP ToBIOS ; .control_characters: CP #0D JR Z,.CR_ CP #0A JR Z,.LF_ CP #09 JR Z,.TB_ CP #08 JR Z,.BK_ CP #07 JR Z,.BELL ; [x] Beep in PChars/PUTCHAR RET ;-----[] ; ; ;///////////////////////////////////////////////////////////////////// ; Функция #52. Установить положение курсора. ; ; вход: D - строка курсора ; E - колонка курсора ; выход: нет ;///////////////////////////////////////////////////////////////////// LOCATE: LD C,BIOS.LP_SET_PLACE JP ToBIOS ;///////////////////////////////////////////////////////////////////// ; Функция #53. Узнать положение курсора. ; ; вход: нет ; выход: D - строка курсора ; E - колонка курсора ;///////////////////////////////////////////////////////////////////// CURSOR: LD C,BIOS.LP_GET_PLACE JP ToBIOS ;///////////////////////////////////////////////////////////////////// ; Функция #57. Прочитать символ с экрана. ; ; вход: D - строка ; E - колонка ; выход: A - символ ; B - атрибут ;///////////////////////////////////////////////////////////////////// RDCHAR: XOR A LD C,BIOS.WIN_GET_SYM RST ToBIOS LD A,L LD B,H ;AND A RET ;///////////////////////////////////////////////////////////////////// ; Функция #58. Вывести символ на экран. ; Управляющие символы выводятся как обычные символы. ; ; вход: D - строка ; E - колонка ; A - символ ; B - атрибут ; выход: нет ;!FIXIT slow как без WIN_GET_SYM тут обойтись? ;///////////////////////////////////////////////////////////////////// WRCHAR: LD C,A PUSH BC PUSH DE XOR A LD C,BIOS.WIN_GET_SYM RST ToBIOS POP DE POP HL XOR A LD C,BIOS.WIN_PUT_SYM JP ToBIOS ;AND A ;RET ;///////////////////////////////////////////////////////////////////// ; Функция #59. Сохранить окно экрана. ; ; вход: D - строка ; E - колонка левого верхнего угла окна ; H - высота окна ; L - ширина окна ; B - страница буфера, если IX >= #C000 ; IX - адрес буфера ; выход: нет ;///////////////////////////////////////////////////////////////////// WINCOPY: AND A LD A,R ;R02 PUSH AF ;R02 XOR A LD C,BIOS.WIN_COPY DI ;R02 RST ToBIOS POP AF ;R02 RET PO ;R02 EI ;R02 RET ;///////////////////////////////////////////////////////////////////// ; Функция #5A. Восстановить окно экрана. ; ; вход: D - строка ; E - колонка левого верхнего угла окна ; H - высота окна ; L - ширина окна ; B - страница буфера, если IX >= #C000 ; IX - адрес буфера ; выход: нет ;///////////////////////////////////////////////////////////////////// WINREST: AND A LD A,R ;R02 PUSH AF ;R02 XOR A DI ;R02 LD C,BIOS.WIN_RESTORE RST ToBIOS POP AF ;R02 RET PO ;R02 EI ;R02 RET ;///////////////////////////////////////////////////////////////////// ; Функция #55. Скроллинг экрана. ; ; вход: D - строка левого верхнего угла окна ; E - колонка левого верхнего угла окна ; H - высота окна ; L - ширина окна ; B = 1 - прокрутка вверх ; B = 2 - прокрутка вниз ; A = 0 - очищать строку ; выход: нет ;///////////////////////////////////////////////////////////////////// SCROLL: DJNZ .SCR_DW ;!TODO заменить на BIOS.LP_SCROLL_UD и посмотреть, что шустрее ;[x] 04/04/23 ;LD B,A ;LD C,H ;PUSH BC PUSH AF ; PUSH DE PUSH HL LD XH,D LD XL,E INC D DEC H LD C,BIOS.WIN_MOVE ;[x] 29/9/23 LD A,R PUSH AF ; XOR A DI ;[x] 29/9/23 RST ToBIOS ;[x] 29/9/23 POP AF JP PO,.skip_EI EI .skip_EI: POP HL POP DE ;[x] 04/04/23 ;POP BC POP AF ;XOR A ;CP B AND A ; RET NZ LD A,D ADD A,H DEC A ;R01 LD D,A .print: PUSH DE ;R01 CALL LOCATE LD A,' ' LD B,L LD C,BIOS.LP_PRINT_SYM RST ToBIOS POP DE ;R01 JP LOCATE ;R01 ;AND A ;RET .SCR_DW: DJNZ .SCR_ERR ;[x] 04/04/23 ;LD B,A ;LD C,H ;PUSH BC PUSH AF ; PUSH DE PUSH HL LD XH,D LD XL,E INC XH DEC H LD C,BIOS.WIN_MOVE ;[x] 29/9/23 LD A,R PUSH AF ; XOR A DI ;[x] 29/9/23 RST ToBIOS ; [x] 29/9/23 POP AF JP PO,.skip2_EI: EI .skip2_EI: POP HL POP DE ;[x] 29/9/23 ;POP BC POP AF ;XOR A ;CP B AND A ; RET NZ JP SCROLL.print .SCR_ERR: LD A,DSS_Error.sys.INVALID_FUNCTION SCF RET ;///////////////////////////////////////////////////////////////////// ; Функция #54. Выбрать активную страницу экрана. ; ; вход: B - страница экрана 0/1 ; выход: A - код ошибки, если CF=1 ;///////////////////////////////////////////////////////////////////// SELPAGE: LD A,(VMODE) ;BIT 7,A CP %1000'0000 JR NC,.SEL2 PUSH BC LD C,A CALL SETVMOD.TEXT_M POP BC .SEL2: LD A,B AND #01 OUT (SCREEN_SWITCH),A RET ;///////////////////////////////////////////////////////////////////// ; Функция #51. Получить текущий режим экрана. ; ; вход: нет ; выход: A - текущий режим экрана ; B - страница экрана 0/1 ;///////////////////////////////////////////////////////////////////// GETVMOD: IN A,(SCREEN_SWITCH) LD B,A LD A,(VMODE) AND A RET ;///////////////////////////////////////////////////////////////////// ; Функция #50. Выбор режима экрана. ; ; вход: A - режим экрана ; #02 - текстовый 40x32x16 цветов ; #03 - текстовый 80x32x16 цветов ; #81 - графический 320x256x256 цветов ; #82 - графический 640x256x16 цветов ; B - страница экрана 0/1 ; выход: A - код ошибки, если CF=1 ;///////////////////////////////////////////////////////////////////// SETVMOD:; CP %1000'0000 LD C,A JR NC,GRAPH .TEXT_M: LD IX,BACKTXT PUSH IX EX AF,AF' LD A,(VMODE) LD (BACKTXT.VMODE),A EX AF,AF' OR A JR Z,.NOMODE DEC A JR Z,.NOMODE DEC A LD HL,TAB_40x32 JR Z,T_40_32 DEC A LD HL,TAB_80x32 JR Z,T_80_32 .NOMODE: POP IX LD A,DSS_Error.sys.INVALID_VIDEO_MODE SCF RET ; Установка граф. режимов GRAPH: CALL SAVETXT AND #7F JR Z,G320_16 ; !TODO ? - пока отрабатывает как ошибка DEC A JR Z,G320_56 DEC A JR Z,G640_16 ; DEC A ; JP Z,G640_56 ; !TODO ? - пока отрабатывает как ошибка G320_16: LD A,DSS_Error.sys.INVALID_VIDEO_MODE SCF RET T_80_32: T_40_32: PUSH BC ; LD HL,TAB2 LD A,B RLCA RLCA RLCA RLCA OR B AND #11 XOR #10 LD E,A GRAPH_NEXT: CALL SETMODE POP BC LD A,C LD (VMODE),A LD A,B AND #01 OUT (SCREEN_SWITCH),A LD A,(VMODE) LD C,Dss.Mouse.SetVideoMode RST ToDSS.Mouse SAFE_PORTY XOR A RET ; T_80_32 PUSH BC ; LD HL,TAB1 ; LD A,B ; RLCA ; RLCA ; RLCA ; RLCA ; OR B ; AND #11 ; XOR #10 ; LD E,A ; CALL SETMODE ; POP BC ; LD A,C ; LD (VMODE),A ; LD A,B ; AND #01 ; OUT (SCREEN_SWITCH),A ; LD A,(VMODE) ; LD C,#81 ; RST #30 ; SAFE_PORTY ; XOR A ; RET G320_56 PUSH BC LD HL,TAB_320x256_0 LD E,#11 CALL SETMODE LD HL,TAB_320x256_1 LD E,#00 JP GRAPH_NEXT ; CALL SETMODE ; POP BC ; LD A,C ; LD (VMODE),A ; LD A,B ; AND #01 ; OUT (SCREEN_SWITCH),A ; LD A,(VMODE) ; LD C,#81 ; RST #30 ; SAFE_PORTY ; XOR A ; RET G640_16 PUSH BC LD HL,TAB_640x256_0 LD E,#11 CALL SETMODE LD HL,TAB_640x256_1 LD E,#00 JP GRAPH_NEXT ; CALL SETMODE ; POP BC ; LD A,C ; LD (VMODE),A ; LD A,B ; AND #01 ; OUT (SCREEN_SWITCH),A ; LD A,(VMODE) ; LD C,#81 ; RST #30 ; SAFE_PORTY ; XOR A ; RET VMODE: DB #03 ;----------------------------------------------------------------------- ; Открыть окно ; вход: hl=описатель окна ; e=флаги окна ; ;02h - TEXT 40 x 32 (16 colors) ;03h - TEXT 80 x 32 (16 colors) ;80h - GRAF 320 x 256 (16 colors) ;81h - GRAF 320 x 256 (256 colors) ;82h - GRAF 640 x 256 (16 colors) ;83h - GRAF 640 x 256 (256 colors) UNUSED ;----------------------------------------------------------------------- SETMODE: PUSH DE LD DE,SYS_PAGE.SHARED_BUFFER_32b ; грязный хак. кидает данные в буфер служебной страницы биоса. LD BC,ScreenDescriptorTable.Size ; БИОС при использовании IX предполагает, что он указывает IN A,(SLOT3) ; на адрес ниже #C000 и вставляет в третью банку страницу #FE EX AF,AF' LD A,SYS_PAGE OUT (SLOT3),A LDIR EX AF,AF' OUT (SLOT3),A .skip_EI: POP DE LD IX,SYS_PAGE.SHARED_BUFFER_32b ; грязный хак. LD C,BIOS.WIN_OPEN RST ToBIOS SAFE_PORTY XOR A RET ;IX+0 ;HORIZONTAL ;IX+1 ;VERTICAL ;IX+2 ;X - COORD ;IX+3 ;Y - COORD ;IX+4 ;MODE ;IX+5 ;EXT MODE ;IX+6 ;VIDEO RAM X OFFSET (SIGNPLACES) ;IX+7 ;VIDEO RAM Y OFFSET (SIGNPLACES) ; ;....................................................................... ;+0 X размер окна в знакоместах ;+1 Y размер окна в знакоместах ;+2 X полож. окна на экране ;+3 Y полож. окна на экране ;+4 режим знакоместа ;+5 доп. режим знакоместа (bit0=1 спек. адресация экрана) ;+6 X полож. в поле графики (в знакоместах) ;+7 Y полож. в поле графики (в знакоместах) ScreenDescriptorTable EQU $ ; 80x32. текстовое, знакоместо 16x8, #0B - номер знакоген. TAB_80x32 DB #28,#20,#00,#00,#1B,#00,#00,#00 ;1 ; 40x32. текстовое, знакоместо 8x8, #0B - номер знакоген. TAB_40x32 DB #28,#20,#00,#00,#3B,#00,#00,#00 ;2 ; 640x256. графическое, 0-й экран TAB_640x256_0 DB #28,#20,#00,#00,#00,#00,#00,#00 ;3 ; 320x256. графическое, 0-й экран TAB_320x256_0 DB #28,#20,#00,#00,#20,#00,#00,#00 ;4 ; 640x256. графическое, 1-й экран TAB_640x256_1 DB #28,#20,#00,#00,#40,#00,#28,#00 ;5 ; 320x256. графическое, 1-й экран TAB_320x256_1 DB #28,#20,#00,#00,#60,#00,#28,#00 ;6 ScreenDescriptorTable.Size EQU ($ - ScreenDescriptorTable)/6 ;....................................................................... ; ;---------------------------------------------------------------------- ; Сохранить экран текст. режима. ; Для буфера экрана исп. 2-я банка расширения ДОС. SAVETXT: PUSH AF LD A,(VMODE) ;BIT 7,A CP %1000'0000 JR NC,.NOSAVET SUB #02 JR C,.NOSAVET ; PUSH BC PUSH DE PUSH HL PUSH IX ; PUSH AF LD C,BIOS.LP_GET_PLACE RST ToBIOS LD (BACKTXT.CURS),DE POP AF LD IX,#C000 LD HL,#2050 OR A JR NZ,.SVTEXT1 LD L,#28 .SVTEXT1: LD (BACKTXT.WinMax),HL LD DE,#0000 LD A,(BANKTBL+TXTPAGE) LD B,A LD C,BIOS.WIN_COPY ;[x] 29/9/23 LD A,R PUSH AF ; XOR A DI RST ToBIOS ;[x] 29/9/23 POP AF JP PO,.skip_EI EI .skip_EI: ; POP IX POP HL POP DE POP BC .NOSAVET: POP AF RET ;---------------------------------------------------------------------- BACKTXT: PUSH AF .VMODE+1: LD A,#00 ;BIT 7,A CP %1000'0000 JR C,NOBACKT ; PUSH BC PUSH DE PUSH HL PUSH IX LD IX,#C000 .WinMax+1: LD HL,#2050 LD DE,#0000 LD A,(BANKTBL+TXTPAGE) LD B,A LD C,BIOS.WIN_RESTORE ;[x] 29/9/23 LD A,R PUSH AF ; XOR A DI RST ToBIOS ;[x] 29/9/23 POP AF JP PO,.no_ei EI .no_ei: ; .CURS+1: LD DE,#0000 CALL LOCATE POP IX POP HL POP DE POP BC NOBACKT: POP AF RET ;///////////////////////////////////////////////////////////////////// ; Функция #5F. Вывод символа на принтер без ожидания. ; ; Интерпретация байта состояния принтера: ; 0..2 - не используются, обычно уст. в "1" ; 3 - ошибка принтера - есть/нет (1/0) ; 4 - принтер подключен/не подключен (1/0) ; 5 - бумаги нет/есть (1/0) ; 6 - принтер готов/выводит очередной символ (1/0) ; 7 - принтер свободен/занят (1/0) ; ; вход: A - символ ; выход: B - символ ; CF - ошибка, A=байт состояния (биты 7..3) ;///////////////////////////////////////////////////////////////////// ;!FIXIT заменить на sp2000.inc LPT_A EQU #1B LPT_B EQU #1C PRINT: AND A LD B,A ; сохраняем символ ; LD A,R DI PUSH AF ; XOR A OUT (LPT_A),A LD A,#10 OUT (LPT_A),A XOR A OUT (LPT_A),A IN A,(LPT_A) ; IN (1Bh): bit 5 - busy, Bit 3 - Ack LD C,A BIT 5,A ; IN (19h): bit 5 - Paper Enable, Bit 3 - Select JR NZ,LPTBUSY AND %11011000 JR Z,LPTBUSY LD A,B ; восстанавливаем символ OUT (LPT_B),A POP AF RET PO EI RET LPTBUSY: POP AF LD A,C SCF RET PO EI RET ; B - SYMBOL ; CF = 1 - PRINTER BUSY ;!FIXIT заменить на sp2000.inc LPT1_C EQU #1D LPT2_D EQU #1E LPT2_C EQU #1F PRINT_INIT: DI LD A,#CF ; port #1F только чеpез LD BC,1F : Out (BC),reg (в альтере идёт перехват этого порта проца, если он в команде явно указан) LD BC,LPT2_C OUT (C),A ;[x] 29/9/23 ;LD A,#63 LD A,63 ; OUT (C),A LD A,#C0 ; Bit 7 - Select (1), Bit 6 - Auto_Line_Feed (1) OUT (LPT2_D),A LD A,#0F ; Init printer port for Out OUT (LPT1_C),A ; клава XOR A ;LD A,0 OUT (Z84.SIO.Ch_A.Ctrl),A ;[x] 29/9/23 INC A OUT (Z84.SIO.Ch_A.Ctrl),A DEC A ; OUT (Z84.SIO.Ch_A.Ctrl),A LD A,5 OUT (Z84.SIO.Ch_A.Ctrl),A LD A,#62 ; bit 7 - Direction for Bufer (0), Bit 1 - Bufer Enable (1) OUT (Z84.SIO.Ch_A.Ctrl),A RET ;//MODULE: VIDEO ;[END]