;[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) ;--------------------------------------------------------------- ; CLEAR TEXT WINDOW CLEAR LD C,BIOS.LP_CLS_WIN2 RST ToBIOS AND A RET ; ; PRINT NULL-TERMINATED CHARS STRING ; HL - STRING POINTER PCHARS LD A,(HL) INC HL OR A RET Z ;PUSH HL CALL PUTCHAR ;POP HL JP PCHARS ; PRINT CHAR ; A - CHAR PUTCHAR: CP #0D JP Z,CR_ CP #0A JP Z,LF_ CP #09 JP Z,TB_ CP #08 JP Z,BK_ ; CP #20 ; JP NC,CHAR CHAR: LD BC,1*256 + BIOS.LP_PRINT_SYM RST ToBIOS ; САЙМАН тут насильный скролл экрана если напечатал в позиции последнего символа последней строки ; push af ; ld a,e ; cp #4F ; jp nz,.exit ; ld a,d ; cp #1F ; jp nz,.exit ; ld e,0 ; ld c,#84 ; rst 8 ; call LFF ; .exit: ; pop af ; САЙМАН RET BK_: LD C,BIOS.LP_GET_PLACE ;GET CURSOR RST ToBIOS XOR A CP E JP Z,LOCATE DEC E JP LOCATE TB_: LD C,BIOS.LP_GET_PLACE ;GET CURSOR RST ToBIOS IF TABisSPACES LD B,E LD A,E AND #F8 ADD A,8 SUB B LD B,A LD C,BIOS.LP_PRINT_SYM LD A,#20 RST ToBIOS RET ELSE LD A,E ADD A,8 AND #78 LD E,A JP LOCATE ENDIF LF_: LD C,BIOS.LP_GET_PLACE ;GET CURSOR RST ToBIOS LD A,D CP #1F JP NC,LFF INC D //JP LOCATE CALL LOCATE ; !!!!! Сайман CR_: LD C,BIOS.LP_GET_PLACE ;GET CURSOR RST ToBIOS LD E,0 JP LOCATE LFF: PUSH HL ;PUSH DE LD BC,1*256 + BIOS.LP_SCROLL_UD LD DE,#0020 EI HALT DI RST ToBIOS LD DE,#1F00 ;PUSH DE CALL LOCATE LD A,#20 LD BC,#50*256 + BIOS.LP_PRINT_SYM RST ToBIOS EI ;POP DE LD DE,#1F00 CALL LOCATE POP HL RET ; ; SET CURRENT CURSOR POSITION ;=============================== ; D = Y ; E = X LOCATE: LD C,BIOS.LP_SET_PLACE RST ToBIOS RET ; GET CURRENT CURSOR POSITION ; out: ; D - Y ; E - X CURSOR: LD C,BIOS.LP_GET_PLACE RST ToBIOS RET ; READ CHAR & ATTR FROM THE SCREEN ; in: ; D - Y ; E - X ; out: ; A - CHAR ; B - ATTR RDCHAR: XOR A LD C,BIOS.WIN_GET_SYM RST ToBIOS LD A,L LD B,H AND A RET ; WRITE CHAR & ATTR TO THE SCREEN ; D - Y ; E - X ; A - CHAR ; B - ATTR ;!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 RST ToBIOS AND A RET ; COPY WINDOW FROM THE SCREEN ; D - Y ; E - X ; H - HEIGHT ; L - WIDTH ; IX - ADDRESS ; B - PAGE, IF IX > 0C000H ; FIXIT не косяк ли тут? банка должна в A' передаваться, а не B WINCOPY: AND A LD A,R ;R02 PUSH AF ;R02 XOR A EX AF,AF' ;R03 LD A,B ;R03 EX AF,AF' ;R03 LD C,BIOS.WIN_COPY DI ;R02 RST ToBIOS POP AF ;R02 RET PO ;R02 EI ;R02 RET ; RESTORE WINDOW TO THE SCREEN ; D - Y ; E - X ; H - HEIGHT ; L - WIDTH ; IX - ADDRESS ; B - PAGE, IF IX > 0C000H ; FIXIT не косяк ли тут? банка должна в A' передаваться, а не B WINREST: AND A LD A,R ;R02 PUSH AF ;R02 XOR A EX AF,AF' ;R03 LD A,B ;R03 EX AF,AF' ;R03 DI ;R02 LD C,BIOS.WIN_RESTORE RST ToBIOS POP AF ;R02 RET PO ;R02 EI ;R02 RET ; SCROLL WINDOW ; D - Y ; E - X ; H - HEIGHT ; L - WIDTH ; B - SCROLL DIRECTION ; B = 1 - SCROLL UP ; B = 2 - SCROLL DOWN ; A = 0 - CLEAR LINE SCROLL: DJNZ SCR_DW LD B,A LD C,H PUSH BC PUSH DE PUSH HL LD XH,D LD XL,E INC D DEC H LD C,BIOS.WIN_MOVE XOR A RST ToBIOS POP HL POP DE POP BC XOR A CP B RET NZ LD A,D ADD A,H DEC A ;R01 LD D,A .print: PUSH DE ;R01 CALL LOCATE LD A,#20 LD B,L LD C,BIOS.LP_PRINT_SYM RST ToBIOS POP DE ;R01 CALL LOCATE ;R01 AND A RET SCR_DW: DJNZ SCR_ERR LD B,A LD C,L PUSH BC ;R03 PUSH DE PUSH HL LD XH,D LD XL,E INC XH DEC H LD C,BIOS.WIN_MOVE XOR A RST ToBIOS POP HL POP DE POP BC ;R03 XOR A CP B JR Z,SCROLL.print ; PUSH DE ;R01 ; CALL LOCATE ; LD A,#20 ; LD B,L ; LD C,BIOS.LP_PRINT_SYM ; RST ToBIOS ; POP DE ;R01 ; CALL LOCATE ;R01 ; AND A RET SCR_ERR: LD A,DSS_Error.sys.INVALID_FUNCTION SCF RET ; SELECT SCREEN PAGE ; B - SCREEN PAGE SELPAGE ;PUSH BC LD A,(VMODE) BIT 7,A JR NZ,SEL2 PUSH BC LD C,A CALL SETVMOD.TEXT_M POP BC SEL2 ;POP BC LD A,B AND #01 OUT (SCREEN_SWITCH),A RET ; GET CURRENT VIDEO MODE ; out: ; A - MODE ; B - PAGE GETVMOD IN A,(SCREEN_SWITCH) LD B,A LD A,(VMODE) AND A RET ; SET CURRENT VIDEO MODE ; A - MODE ; B - PAGE SETVMOD: BIT 7,A LD C,A JR NZ,GRAPH .TEXT_M: LD IX,BACKTXT PUSH IX EX AF,AF' LD A,(VMODE) LD (VVMODE),A EX AF,AF' INC A DEC A JR Z,.NOMODE DEC A JR Z,.NOMODE DEC A LD HL,TAB_40x32 JP Z,T_40_32 DEC A LD HL,TAB_80x32 JP 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 JP Z,G320_56 DEC A JP 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,#81 RST #30 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 JR 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 JR 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 ;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,#FEE0 ;!HARDCODE грязный хак. кидает данные в буфер служебной страницы биоса. LD BC,ScreenDescriptorTable.Size ; БИОС при использовании IX предполагает, что он указывает ;CALL MOVBIOS ; на адрес ниже #C000 и вставляет в третью банку страницу #FE ;LD A,R IN A,(SLOT3) EX AF,AF' LD A,SYS_PAGE OUT (SLOT3),A LDIR EX AF,AF' OUT (SLOT3),A ;JP PO,.skip_EI ;EI .skip_EI: POP DE LD IX,#FEE0 ;!HARDCODE грязный хак. ;LD HL,#0000 LD C,BIOS.WIN_OPEN RST ToBIOS SAFE_PORTY ;????? - возможно, что теперь не нужно, везде с банкой 3 работают, проверить XOR A RET ; MOVBIOS: LD A,R ; IN A,(SLOT3) ; EX AF,AF' ; LD A,SYS_PAGE ; OUT (SLOT3),A ; LDIR ; EX AF,AF' ; OUT (SLOT3),A ; RET PO ; EI ; 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) ; ;....................................................................... ScreenDescriptorTable EQU $ ;80x32 TAB_80x32 DB #28,#20,#00,#00,#1B,#00,#00,#00 ;1 ;40x32 TAB_40x32 DB #28,#20,#00,#00,#3B,#00,#00,#00 ;2 ;640x256 PAGE 0 TAB_640x256_0 DB #28,#20,#00,#00,#00,#00,#00,#00 ;3 ;320x256 PAGE 0 TAB_320x256_0 DB #28,#20,#00,#00,#20,#00,#00,#00 ;4 ;640x256 PAGE 1 TAB_640x256_1 DB #28,#20,#00,#00,#40,#00,#28,#00 ;5 ;320x256 PAGE 1 TAB_320x256_1 DB #28,#20,#00,#00,#60,#00,#28,#00 ;6 ScreenDescriptorTable.Size EQU ($ - ScreenDescriptorTable)/6 ;....................................................................... ; SAVETXT PUSH AF ;;!!!!! перенесена логика супер дичайшего ускорения LD A,(VMODE) BIT 7,A JR NZ,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 (TCURS),DE POP AF LD IX,#C000 LD HL,#2050 OR A JR NZ,SVTEXT1 LD L,#28 SVTEXT1 LD (SVHL1),HL LD DE,#0000 EX AF,AF' ;R03 LD A,(BANKTBL+TXTPAGE) LD B,A EX AF,AF' ;R03 LD C,BIOS.WIN_COPY XOR A DI RST ToBIOS EI POP IX POP HL POP DE POP BC NOSAVET: POP AF RET BACKTXT PUSH AF VVMODE+1: LD A,#00 BIT 7,A JR Z,NOBACKT PUSH BC PUSH DE PUSH HL PUSH IX LD IX,#C000 SVHL1+1: LD HL,#2050 LD DE,#0000 EX AF,AF' ;R03 LD A,(BANKTBL+TXTPAGE) LD B,A EX AF,AF' ;R03 LD C,BIOS.WIN_RESTORE XOR A DI RST ToBIOS EI TCURS+1: LD DE,#0000 LD C,BIOS.LP_SET_PLACE RST ToBIOS POP IX POP HL POP DE POP BC NOBACKT: POP AF RET ; SEND A SYMBOL TO THE PRINTER ;============================== ; A - SYMBOL ;!FIXIT заменить на sp2000.inc LPT_A EQU #1B LPT_B EQU #1C PRINT: AND A LD B,A LD A,R LD A,B 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 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 (COM_A),A ;LD A,0 OUT (COM_A),A ; ????? надо ли второй раз зассылать и вообще имеет ли смысл com инитить? LD A,5 OUT (COM_A),A LD A,#62 ; bit 7 - Direction for Bufer (0), Bit 1 - Bufer Enable (1) OUT (COM_A),A RET ; САЙМАН ВЫРЕЗАЛ ;//MODULE: VIDEO ;[END]