PAGE,120 TITLE ENHANCED GRAPHICS ADAPTER BIOS EXTRN CGMN:NEAR, CGDDOT:NEAR, INT_1F_1:NEAR, CGMN_FDG:NEAR EXTRN END_ADDRESS:NEAR ;---------------------------------------------------------------- ; THE BIOS ROUTINES ARE MEANT TO BE ACCESSED THROUGH : ; SOFTWARE INTERRUPTS ONLY. ANY ADDRESSES PRESENT IN : ; THE LISTINGS ARE INCLUDED ONLY FOR COMPLETENESS, : ; NOT FOR REFERENCE. APPLICATIONS WHICH REFERENCE : ; ABSOLUTE ADDRESSES WITHIN THE CODE SEGMENT : ; VIOLATE THE STRUCTURE AND DESIGN OF BIOS. : ;---------------------------------------------------------------- .LIST INCLUDE VFRONT.INC ;----- CODE SEGMENT CODE SEGMENT PUBLIC INCLUDE VPOST.INC T2 LABEL WORD DW OFFSET AH0 ; MODE SET DW OFFSET AH1 ; SET CURSOR TYPE DW OFFSET AH2 ; SET CURSOR POSITION DW OFFSET AH3 ; READ CURSOR POSITION DW OFFSET AH4 ; READ LIGHT PEN POSITION DW OFFSET AH5 ; ACTIVE DISPLAY PAGE DW OFFSET AH6 ; SCROLL DOWN DW OFFSET AH7 ; SCROLL UP DW OFFSET AH8 ; READ CHAR/ATTRIBUTE DW OFFSET AH9 ; WRITE CHAR/ATTRIBUTE DW OFFSET AHA ; WRITE CHARACTER ONLY DW OFFSET AHB ; SET COLOR PALETTE DW OFFSET AHC ; WRITE DOT DW OFFSET AHD ; READ DOT DW OFFSET AHE ; WRITE TTY DW OFFSET AHF ; CURRENT VIDEO STATE DW OFFSET AH10 ; SET PALETTE REGISTERS DW OFFSET AH11 ; CHAR GENERATOR ROUTINE DW OFFSET AH12 ; ALTERNATE SELECT DW OFFSET AH13 ; WRITE STRING T2L EQU $-T2 INCLUDE VPARMS.INC ;----- VECTOR INTO SPECIFIED FUNCTION COMBO_VIDEO PROC NEAR STI ; INTERRUPTS ON CLD ; SET DIRECTION FORWARD PUSH BP ; SAVE THE REGISTER SET PUSH ES PUSH DS PUSH DX PUSH CX PUSH BX PUSH SI PUSH DI PUSH AX ; SAVE AX VALUE MOV AL,AH ; GET INTO LOW BYTE XOR AH,AH ; ZERO TO HIGH BYTE SAL AX,1 ; * 2 FOR TABLE LOOKUP MOV SI,AX ; PUT INTO SI FOR BRANCH CMP AX,T2L ; TEST FOR WITHIN RANGE JB M2 ; BRANCH AROUND BRANCH POP AX ; RECOVER REGISTER INT 42H ; PASS UNRECOGNIZED CALL JMP V_RET ; RETURN TO CALLER M2: ASSUME DS:ABS0 CALL DDS POP AX ; RECOVER JMP WORD PTR CS:[SI + OFFSET T2] ; JMP TO AH=0 THRU AH=XX ;----- UTILITY ROUTINES ;----- SET DS TO THE DATA SEGMENT DDS PROC NEAR PUSH AX ; SAVE REGISTER SUB AX,AX MOV DS,AX POP AX ; RESTORE REGISTER RET DDS ENDP WHAT_BASE PROC NEAR ASSUME DS:ABS0 PUSH DS ; SAVE DATA SEGMENT CALL DDS ; GET LOW MEMORY SEGMENT MOV DX,ADDR_6845 ; GET CRTC ADDRESS AND DL,0F0H ; STRIP OFF LOW NIBBLE OR DL,0AH ; SET TO STATUS REGISTER POP DS RET WHAT_BASE ENDP OUT_DX PROC NEAR ; AH=INDEX,AL=DATA,DX=PORT XCHG AL,AH ; GET INDEX VALUE OUT DX,AL ; SET INDEX REG INC DX ; SET DX TO DATA REG XCHG AL,AH ; GET DATA VALUE OUT DX,AL ; SET DATA REG DEC DX ; SET DX BACK TO INDEX RET OUT_DX ENDP ;----- ROUTINE TO SOUND BEEPER BP_1 PROC NEAR OUT DX,AL RET BP_1 ENDP BEEP PROC NEAR PUSH DX MOV DX,TIMER+3 MOV AL,10110110B ; SEL TIM 2,LSB,MSB,BINARY CALL BP_1 ; WRITE THE TIMER MODE REG MOV AX,533H ; DIVISOR FOR 1000 HZ DEC DX CALL BP_1 ; WRITE TIMER 2 CNT - LSB MOV AL,AH CALL BP_1 ; WRITE TIMER 2 CNT - MSB MOV DX,PORT_B IN AL,DX ; GET SETTING OF PORT MOV AH,AL ; SAVE THAT SETTING OR AL,03 ; TURN SPEAKER ON CALL BP_1 SUB CX,CX ; SET CNT TO WAIT 500 MS G7: LOOP G7 ; DELAY BEFORE TURNING OFF DEC BL ; DELAY CNT EXPIRED? JNZ G7 ; NO-CONTINUE BEEPING SPK MOV AL,AH ; RECOVER VALUE OF PORT CALL BP_1 POP DX RET ; RETURN TO CALLER BEEP ENDP ;----- FIND THE PARAMETER TABLE VECTOR IN THE SAVE TABLE SET_BASE PROC NEAR ASSUME DS:ABS0 CALL DDS LES BX,SAVE_PTR ; GET PTR TP PTR TABLE LES BX,DWORD PTR ES:[BX] ; GET PARAMETER PTR RET SET_BASE ENDP ;----- ESTABLISH ADDRESSING TO THE CORRECT MODE TABLE ENTRY MAKE_BASE PROC NEAR ASSUME DS:ABS0 PUSH CX PUSH DX CALL SET_BASE ; GET PARM TBL PTR MOV AH,CRT_MODE TEST INFO,060H ; TEST FOR BASE CARD JZ B_M_1 ; MIN MEMORY ;----- WE HAVE A MEMORY EXPANSION OPTION HERE CMP AH,0FH JNE B_M_2 ADD BX,BASE_2 - BASE_1 JMP B_M_OUT B_M_2: CMP AH,010H JNE B_M_1 ADD BX,BASE_2 + M_TBL_LEN - BASE_1 JMP B_M_OUT B_M_1: CMP AH,03H JA B_M_3 ; SKIP ENHANCED PORTION ;----- CHECK THE SWITCH SETTING FOR ENHANCEMENT MOV AL,INFO_3 AND AL,0FH CMP AL,03H ; SECONDARY EMULATE SETTING JE BRS CMP AL,09H ; PRIMARY EMULATE SETTING JE BRS JMP B_M_3 ;----- WE WILL PERFORM ENHANCEMENT BRS: ADD BX,BASE_3 - BASE_1 ; VECTOR TO ENHANCEMENT TBL B_M_3: MOV CL,CRT_MODE SUB CH,CH JCXZ B_M_4 ;----- THIS LOOP WILL MOVE THE PTR TO THE INDIVIDUAL MODE ENTRY B_M_5: ADD BX,M_TBL_LEN ; LENGTH OF ONE MODE ENTRY LOOP B_M_5 B_M_4: B_M_OUT: POP DX POP CX RET MAKE_BASE ENDP ;----- PROGRAM THE EGA REGISTERS FROM THE PARAMETER TABLE SET_REGS PROC NEAR ASSUME DS:ABS0,ES:NOTHING ;----- PROGRAM THE SEQUENCER CALL MAKE_BASE ; GET TABLE PTR ADD BX,TFS_LEN ; MODE TO SEQUENCER PARMS MOV DH,3 MOV DL,SEQ_ADDR MOV AX,0001H ; RESET SEQUENCER CLI ; DISABLE INTERRUPTS CALL OUT_DX MOV AL,ES:[BX] ; GET SEQUENCER VALUE INC AH ; NEXT INDEX CALL OUT_DX ; SET IT D1: INC AH ; NEXT INDEX REGISTER INC BX ; NEXT TABLE ENTRY MOV AL,ES:[BX] CALL OUT_DX CMP AH,M1+1 JB D1 MOV AL,ES:[BX] INC BX MOV DL,MISC_OUTPUT OUT DX,AL MOV DL,SEQ_ADDR MOV AX,0003H CALL OUT_DX ; START SEQUENCER STI ; ENABLE INTERRUPTS ;----- PROGRAM THE CRT CONTROLLER MOV DX,ADDR_6845 ; CRTC INDEX REGISTER SUB AH,AH ; COUNTER X1: MOV AL,ES:[BX] ; GET VALUE FROM TABLE CALL OUT_DX ; SET CRTC REGISTER INC BX ; NEXT TABLE ENTRY INC AH ; NEXT INDEX VALUE CMP AH,M4 ; TEST REGISTER COUNT JB X1 ; DO THE REST MOV AX,ES:[BX][-0FH] ; GET CURSOR MODE XCHG AH,AL MOV CURSOR_MODE,AX ; SET LOW RAM VALUE ;----- PROGRAM THE ATTRIBUTE CHIP MOV SI ,BX CALL WHAT_BASE IN AL,DX MOV DL,ATTR_WRITE SUB AH,AH ; INDEX COUNTER D3: MOV AL,ES:[BX] ; GET DATA VALUE XCHG AH,AL OUT DX,AL XCHG AH,AL OUT DX,AL INC BX ; NEXT DATA VALUE INC AH ; NEXT INDEX VALUE CMP AH,M5 ; TEST REGISTER COUNT JB D3 ; DO THE REST MOV AL,0 OUT DX,AL ;----- CHECK IF PALETTE REGISTER VALUES ARE TO BE SAVED PUSH DS PUSH ES LES DI,SAVE_PTR ; GET TABLE PTR LES DI,DWORD PTR ES:[DI][4] ; GET PALETTE PTR MOV AX,ES OR AX,DI JZ SAVE_OUT ; IF ZERO, NO SAVE OCCURS ;----- STORE AWAY THE PALETTE VALUES IN RAM SAVE AREA POP DS PUSH DS MOV CX,16D REP MOVSB ; SAVE THE PALETTE REGS INC SI MOVSB ; SAVE THE OVERSCAN REG SAVE_OUT: POP ES POP DS ;----- PROGRAM THE GRAPHICS CHIPS MOV DL,GRAPH_1_POS MOV AL,0 OUT DX,AL MOV DL,GRAPH_2_POS MOV AL,1 OUT DX,AL MOV DL,GRAPH_ADDR SUB AH,AH D4: MOV AL,ES:[BX] ; PARAMETER BYTE CALL OUT_DX ; SET IT INC BX ; NEXT BYTE INC AH ; NEXT REGISTER CMP AH,M6 JB D4 ; CONTINUE RET SET_REGS ENDP ;----- MODE SET REGEN CLEAR ROUTINE BLANK PROC NEAR ; FILL REGEN WITH BLANKS ASSUME DS:ABS0,ES:NOTHING MOV AL,INFO ; SEE IF BLANK IS TO OCCUR TEST AL,080H ; MODE SET HIGH BIT JNZ OUT_1 ; SKIP BLANK FOR REGEN MOV DX,0B800H ; COLOR MODE REGEN ADDRESS MOV AL,CRT_MODE ; CURRENT MODE SET CMP AL,6 ; 0-6 ARE COLOR MODES JBE CGO MOV DX,0B000H ; MONOCHROME REGEN ADDRESS CMP AL,7 ; MONOCHROME MODE JE CGO MOV DX,0A000H ; REMAINING MODES CGO: MOV BX,0720H ; ALPHA BLANK VALUE CMP AL,4 ; ALPHAMODES 0-3 JB WW1 CMP AL,7 ; ALPHA MODE JE WW1 SUB BX,BX ; GRAPHICS BLANK VALUE WW1: SRLOAD ES ; SET THE REGEN SEGMENT MOV CX,CRT_LEN JCXZ OUT_1 MOV CX,08000H CMP DH,0A0H JE N_BA MOV CH,040H N_BA: MOV AX,BX ; BLANK VALUE SUB DI,DI ; CLEAR POINTER REP STOSW ; CLEAR THE PAGE OUT_1: RET ; RETURN TO CALLER BLANK ENDP PH_5 PROC NEAR CALL PAL_ON RET PH_5 ENDP ;----- SEE IF WE ARE TO SUPPORT 640 X 350 ON A 640 X 200 MODE BRST_DET PROC NEAR ASSUME DS:ABS0 PUSH AX PUSH DS CALL DDS MOV AL,INFO_3 POP DS AND AL,0FH CMP AL,03H ; EMULATE MODE JE B_YES CMP AL,09H ; EMULATE MODE JE B_YES POP AX CLC RET B_YES: POP AX STC RET BRST_DET ENDP ;----- MODE SET AH0: ASSUME DS:ABS0 CLI MOV WORD PTR GRX_SET, OFFSET CGDDOT MOV WORD PTR GRX_SET+2, CS STI AND INFO,11110011B ; TURN OFF RETRACE BIT ; EGA ACTIVE BIT PUSH AX ; SAVE TEST INFO,2 JZ ST_1 ; THERE IS NO MONOCHROME MOV AX,EQUIP_FLAG ; THERE IS A MONOCHROME AND AL,030H ; CHECK THE EQUIPMENT FLAG CMP AL,030H ; FOR MONOCHROME CALL JE ST_2 ; IT IS A MONOCHROME CALL ;----- FALL THROUGH => REGULAR COLOR CARD SETUP MOV ROWS,024D MOV POINTS,8 POP AX ; RECOVER OR INFO,00001000B ; EGA NOT ACTIVE CMP AL,1 JBE ST_7 ; WAIT FOR RETRACE ON CMP AL,4 ; MODES 2,3 ONLY JAE ST_7 OR INFO,00000100B ; DO RETRACE ST_7: INT 42H ; OTHER ADAPTER MODE CALL JMP V_RET ; BACK TO CALLER ;----- AT THIS POINT THERE IS NO MONOCHROME ATTACHED TO THE ADAPTER ST_1: MOV AX,EQUIP_FLAG ; TEST THE EQUIPMENT FLAG AND AL,030H ; TO SEE IF THIS IS A CMP AL,030H ; MONOCHROME SETUP CALL JNE ST_3 ; MUST BE COLOR TO CARD ;----- FALL THROUGH => REGULAR MONOCHROME CARD SETUP MOV ROWS,024D MOV POINTS,014D POP AX ; RECOVER INT 42H ; OTHER ADAPTER MODE CALL MOV CURSOR_MODE,0B0CH ; FIX PLANAR VALUE OR INFO,8 ; THE EGA IS NOT ACTIVE JMP V_RET ; BACK TO CALLER ;----- MONOCHROME SETUP TO THE ADAPTER ST_2: POP AX ; RECOVER PUSH AX ; SAVE MOV DH,3 AND AL,080H ; PICK OFF THE CLEAR BIT AND INFO,07FH ; MASK OFF THE OTHER BITS OR INFO,AL ; SAVE REGEN CLEAR BIT POP AX ; RECOVER TRUE CALL VALUE AND AL,07FH ; ALREADY DEALT WITH D7 CMP AL,0FH ; A MONOCHROME MODE JE ST_2A ; DO THIS MODE MOV AL,7 ; REGULAR MONOCHROME ST_2A: MOV CRT_MODE,AL ; SAVE MODE VALUE MOV DL,CRTC_ADDR_B ; IT IS 3-B-X MOV ADDR_6845,DX ; SAVE CRTC ADDRESS JMP QQ1 ; CONTINUE THE MODE SET ;----- COLOR SETUP TO THE ADAPTER ST_3: POP AX ; RECOVER PARAMETER VALUE PUSH AX ; SAVE IT MOV DH,3 AND AL,080H ; ISOLATE REGEN CLEAR BIT AND INFO,07FH ; PREPARE INFO BYTE OR INFO,AL ; SET IT, OR NOT POP AX ; RECOVER TRUE MODE CALL AND AL,07FH ; DONE WITH D7 MOV CRT_MODE,AL ; SAVE THIS MODE MOV DL,CRTC_ADDR ; 3-D-X MOV ADDR_6845,DX ; SAVE CRTC ADDRESS QQ1: MOV CRT_START,0 ; SAVE START ADDRESS MOV ACTIVE_PAGE,0 ; RESET PAGE VALUE TO ZERO ASSUME ES:NOTHING MOV CX,8 ; 8 PAGES OF CURSOR VALUES MOV DI,OFFSET CURSOR_POSN ; OFFSET PUSH DS ; ESTABLISH POP ES ; ADDRESSING SUB AX,AX ; 0 THOSE CURSOR LOCATIONS REP STOSW ; CLEAR OUT SAVED VALUES CALL MAKE_BASE MOV AL,ES:[BX] ; GET COLUMN COUNT SUB AH,AH ; ZERO HIGH BYTE MOV CRT_COLS,AX ; STORE COLUMN VALUE MOV AL,ES:[BX][1] ; GET ROW VALUE MOV ROWS,AL ; STORE ROW VALUE MOV AL,ES:[BX][2] ; GET THE BYTES/CHAR SUB AH,AH ; ZERO HIGH BYTE MOV POINTS,AX ; STORE BYTES/CHAR MOV AX,ES:[BX][3] ; GET PAGE SIZE MOV CRT_LEN,AX ; STORE PAGE LENGTH SUB BX,BX ; ZERO MOV AL,1 ; MONOCHROME ALPHA CHAR GEN MOV AH,CRT_MODE ; GET CURRENT MODE CMP AH,7 ; IS IT MONOCHROME JE ENTRY_2 ; 9X14 FONT CMP AH,03H JA ENTRY_1 CALL BRST_DET JC ENTRY_2 MOV AL,2 ; COLOR ALPHA CHAR GEN ENTRY_2: CALL CH_GEN ; LOAD ALPHA CHAR GEN CALL DDS MOV AH,CRT_MODE ; GET CURRENT MODE CMP AH,7 ; IS IT MONOCHROME JE FDG_IT ; 9X14 FONT JMP ENTRY_1 FDG_IT: MOV BP,OFFSET CGMN_FDG ; TABLE POINTER MOV BX,0E00H ; 14 BYTES PER CHAR FDG: PUSH CS ; GET THE ROM SEGMENT POP ES ; INTO ES MOV DX,ES:[BP] ; GET THE CHAR HEX CODE OR DX,DX ; ZERO = NO MORE CHARS JZ ENTRY_1 ; NO MORE MOV CX,1 ; DO ONE CHAR AT A TIME INC BP ; MOVE TO FIRST CODE POINT CALL DO_MAP2 ; STORE THE CODE POINT ADD BP,014D ; ADJUST BP TO NEXT CODE JMP FDG ; DO ANOTHER ENTRY_1: CALL SET_REGS CALL BLANK ; CLEAR OUT THE BUFFER CALL PH_5 ASSUME DS:ABS0 CALL DDS CMP CRT_MODE,0FH JB MS_1 MOV WORD PTR GRX_SET , OFFSET CGMN MS_1: CMP CRT_MODE,7 JA SAVE_GRPH JE SAVE_ALPH CMP CRT_MODE,3 JBE SAVE_ALPH SAVE_GRPH: LES BX,SAVE_PTR ADD BX,0CH LES BX,DWORD PTR ES:[BX] MOV AX,ES OR AX,BX JZ J4J ; JMP AH0_DONE MOV SI,07H SG_1: MOV AL,ES:[BX][SI] CMP AL,0FFH JE AH0_DONE CMP AL,CRT_MODE JE SG_2 INC SI JMP SG_1 SG_2: CLI MOV AL,BYTE PTR ES:[BX] DEC AL MOV ROWS,AL MOV AX,WORD PTR ES:[BX][1] MOV POINTS,AX MOV AX,WORD PTR ES:[BX][3] MOV WORD PTR GRX_SET,AX MOV AX,WORD PTR ES:[BX][5] MOV WORD PTR GRX_SET + 2,AX STI J4J: JMP SHORT AH0_DONE SAVE_ALPH: LES BX,SAVE_PTR ADD BX,08H LES BX,DWORD PTR ES:[BX] MOV AX,ES OR AX,BX JZ AH0_DONE MOV SI,0BH SA_1: MOV AL,ES:[BX][SI] CMP AL,0FFH JE AH0_DONE CMP AL,CRT_MODE JE SA_2 INC SI JMP SA_1 SA_2: MOV AH,ES:[BX] MOV AL,ES:[BX][1] MOV CX,ES:[BX][2] MOV DX,ES:[BX][4] MOV BP,ES:[BX][6] MOV ES,ES:[BX][8] PUSH BX MOV BX,AX MOV AX,1110H INT 10H POP BX MOV AL,ES:[BX][0AH] CMP AL,0FFH JE AH0_DONE DEC AL MOV ROWS,AL ;----- SET THE LOW RAM VALUES FOR COMPATIBILITY (3D8 AND 3D9 SAVE BYTES) AH0_DONE: CALL DDS CMP CRT_MODE,7 JA DNDCS MOV BX,OFFSET COMPAT_MODE MOV AL,CRT_MODE SUB AH,AH ADD BX,AX MOV AL,CS:[BX] MOV CRT_MODE_SET,AL MOV AL,030H CMP CRT_MODE,6 JNE DO_PAL MOV AL,03FH DO_PAL: MOV CRT_PALETTE,AL DNDCS: MOV CX,CURSOR_MODE JMP AH1 COMPAT_MODE LABEL BYTE DB 02CH,028H,02DH,029H,02AH,02EH DB 01EH,029H INCLUDE V1-5.INC INCLUDE VSCROLL.INC INCLUDE VGRW.INC ;----- SET COLOR PALETTE AHB: ASSUME DS:ABS0 CMP BYTE PTR ADDR_6845,0B4H JE M21_B ; CALL VALID ONLY FOR COLOR TEST INFO,2 ; SEE IF ITS THE OLD COLOR CARD JZ M21_A ; IF NOT, HANDLE IT HERE INT 42H ; OLD CODE CALL M21_B: JMP V_RET ; BACK TO CALLER M21_A: SUB AX,AX MOV BP,AX LES DI,SAVE_PTR ADD DI,4 LES DI,DWORD PTR ES:[DI] MOV AX,ES OR AX,DI JZ NOT4AHB INC BP NOT4AHB: CALL PAL_INIT OR BH,BH JNZ M20 ;----- HANDLE BH = 0 HERE ; ALPHA MODES => BL = OVERSCAN COLOR ; GRAPHICS => BL = OVERSCAN AND BACKGROUND COLOR ;----- MOVE INTENSITY BIT FROM D3 TO D4 FOR COMPATIBILITY MOV BH,BL MOV AL,CRT_PALETTE AND AL,0E0H AND BL,01FH OR AL,BL MOV CRT_PALETTE,AL MOV BL,BH AND BH,08H SHL BH,1 MOV CH,AL AND CH,0EFH OR CH,CH AND BL,0FH MOV BH,BL SHL BL,1 AND BL,010H AND BH,07H OR BL,BH MOV AL,CRT_MODE CMP AL,3 JBE M21 ;----- GRAPHICS MODE DONE HERE (SET PALETTE 0 AND OVERSCAN) MOV AH,0 MOV AL,BL CALL PAL_SET OR BP,BP JZ M21 MOV ES:[DI],BL ;----- ALPHA MODE DONE HERE (SET OVERSCAN REGISTER) M21: CMP CRT_MODE,3 ; CHECK FOR AN ENHANCED MODE JA SET_OVRSC ; NO CHANCE CALL BRST_DET ; SEE IF WE ARE ENHANCED JC SKIP_OVRSC ; THERE IS NO BORDER SET_OVRSC: MOV AH,011H ; OVERSCAN REGISTER MOV AL,BL CALL PAL_SET ; SET THE BORDER SKIP_OVRSC: OR BP,BP JZ M21Y MOV ES:[DI][16D],BL M21Y: MOV BL,CH AND BL,020H MOV CL,5 SHR BL,CL ;----- HANDLE BH = 1 HERE ; ALPHA MODES => NO EFFECT ; GRAPHICS => LOW BIT OF BL = 0 ; PALETTE 0 = BACKGROUND ; PALETTE 1 = GREEN ; PALETTE 2 = RED ; PALETTE 3 = BROWN ; => LOW BIT OF BL = 1 ; PALETTE 0 = BACKGROUND ; PALETTE 1 = CYAN ; PALETTE 2 = MAGENTA ; PALETTE 3 = WHITE ; M20: CMP CRT_MODE,3 JBE M80 MOV AL,CRT_PALETTE AND AL,0DFH AND BL,1 JZ M22 OR AL,020H M22: MOV CRT_PALETTE,AL AND AL,010H OR AL,2 OR BL,AL MOV AH,1 MOV AL,BL CALL PAL_SET OR BP,BP JZ M22Y MOV ES:[DI][1],BL M22Y: INC BL INC BL MOV AH,2 MOV AL,BL CALL PAL_SET OR BP,BP JZ M27Y MOV ES:[DI][2],BL M27Y: INC BL INC BL MOV AH,3 MOV AL,BL CALL PAL_SET OR BP,BP JZ M80 MOV ES:[DI][3],BL M80: CALL PAL_ON JMP V_RET INCLUDE VDOT.INC PAL_SET PROC NEAR PUSH AX CALL WHAT_BASE CLI VR: IN AL,DX TEST AL,08H ; VERTICAL RETRACE JZ VR POP AX MOV DL,ATTR_WRITE XCHG AL,AH OUT DX,AL XCHG AL,AH OUT DX,AL MOV AL,020H OUT DX,AL STI RET PAL_SET ENDP PAL_ON PROC NEAR CALL PAL_INIT MOV DL,ATTR_WRITE MOV AL,020H OUT DX,AL RET PAL_ON ENDP PAL_INIT PROC NEAR CALL WHAT_BASE IN AL,DX RET PAL_INIT ENDP ;----- SET PALETTE REGISTERS AH10: ASSUME DS:ABS0 TEST INFO,2 JNZ BM_OK ; IN MONOCHROME MODE ;----- HERE THE EGA IS IN A COLOR MODE CMP BYTE PTR ADDR_6845,0B4H JE BM_OUT BM_OK: MOV AH,AL OR AH,AH JNZ BM_1 ;----- SET INDIVIDUAL REGISTER SUB BP,BP LES DI,SAVE_PTR ADD DI,4 LES DI,DWORD PTR ES:[DI] MOV AX,ES OR AX,DI JZ TLO_1 INC BP TLO_1: CALL PAL_INIT MOV AH,BL MOV AL,BH CALL PAL_SET CALL PAL_ON OR BP,BP JZ BM_OUT MOV AL,BH SUB BH,BH ADD DI,BX MOV ES:[DI],AL BM_OUT: JMP V_RET BM_1: DEC AH JNZ BM_2 SUB BP,BP LES DI,SAVE_PTR ADD DI,4 LES DI,DWORD PTR ES:[DI] MOV AX,ES OR AX,DI JZ TLO_2 INC BP TLO_2: ;----- SET OVERSCAN REGISTER CALL PAL_INIT MOV AH,011H MOV AL,BH CALL PAL_SET CALL PAL_ON OR BP,BP JZ BM_OUT ADD DI,011H MOV ES:[DI],BH JMP V_RET BM_2: DEC AH JNZ BM_3 ;----- SET 16 PALETTE REGISTERS AND OVERSCAN REGISTER PUSH DS PUSH ES LES DI,SAVE_PTR ADD DI,4 LES DI,DWORD PTR ES:[DI] ; ES:DI PTR TO PAL SAVE AREA MOV AX,ES OR AX,DI JZ TLO_3 POP DS ; PARAMETER ES PUSH DS MOV SI,DX ; PARAMETER OFFSET MOV CX,17D REP MOVSB TLO_3: POP ES POP DS MOV BX,DX CALL PAL_INIT SUB AH,AH BM_2A: MOV AL,ES:[BX] CALL PAL_SET INC AH INC BX CMP AH,010H JB BM_2A INC AH MOV AL,ES:[BX] CALL PAL_SET CALL PAL_ON JMP V_RET BM_3: DEC AH JNZ BM_4 ;----- TOGGLE INTENSIFY/BLINKING BIT PUSH BX CALL MAKE_BASE ADD BX,010H + LN_4 MOV AL,ES:[BX] POP BX OR BL,BL JNZ BM_6 ;----- ENABLE INTENSIFY AND CRT_MODE_SET,11011111B AND AL,0F7H JMP BM_7 BM_6: DEC BL JNZ BM_7 ;----- ENABLE BLINK OR CRT_MODE_SET,020H OR AL,08H BM_7: MOV AH,P_MODE CALL PAL_SET BM_4: JMP V_RET INCLUDE VCHGEN.INC ;----- ALTERNATE SELECT AH12: ASSUME DS:ABS0 CMP BL,010H ; RETURN ACTIVE CALL JB ACT_1 JE ACT_3 CMP BL,020H ; ALTERNATE PRINT SCREEN JE ACT_2 JMP V_RET ; INVALID CALL ACT_2: ; NEW PRINT SCREEN SRLOAD DS,0 CLI MOV WORD PTR INT5_PTR, OFFSET PRINT_SCREEN MOV WORD PTR INT5_PTR+2, CS STI JMP V_RET ACT_3: MOV BH,INFO ; LOOKING FOR MONOC BIT AND BH,2 ; ISOLATE SHR BH,1 ; ADJUST MOV AL,INFO ; LOOKING FOR MEMORY AND AL,01100000B ; MEMORY BITS MOV CL,5 ; SHIFT COUNT SHR AL,CL ; ADJUST MEM VALUE MOV BL,AL ; RETURN REGISTER MOV CL,INFO_3 ; FEATURE/SWITCH MOV CH,CL ; DUPLICATE IN CH AND CL,0FH ; MASK OFF SWITCH VALUE SHR CH,1 ; MOVE FEATURE VALUE SHR CH,1 SHR CH,1 SHR CH,1 AND CH,0FH ; MASK IT POP DI POP SI POP DX ; DISCARD BX POP DX ; DISCARD CX POP DX POP DS POP ES POP BP IRET AH12_X: JMP V_RET ; RETURN TO CALLER ACT_1: STR_OUTZ: JMP V_RET ; RETURN TO CALLER ;----- WRITE STRING AH13: CMP AL,04 ; RANGE CHECK JAE STR_OUTZ ; INVALID PARAMETER JCXZ STR_OUTZ PUSH BX ; SAVE REGISTER MOV BL,BH ; GET PAGE TO LOW BYTE SUB BH,BH SAL BX,1 ; *2 FOR WORD OFFSET MOV SI,[BX + OFFSET CURSOR_POSN] ; GET CURSOR POSITION POP BX ; RESTORE PUSH SI ; CURRENT VALUE ON STACK PUSH AX MOV AX,0200H ; SET THE CURSOR POSITION INT 10H POP AX STR_1: PUSH CX PUSH BX PUSH AX XCHG AH,AL MOV AL,ES:[BP] ; GET THE CHAR TO WRITE INC BP CMP AL,0DH ; CARRIAGE RETURN JE STR_CR_LF CMP AL,0AH ; LINE FEED JE STR_CR_LF CMP AL,08H ; BACKSPACE JE STR_CR_LF CMP AL,07H ; BELL JE STR_CR_LF MOV CX,1 ; COUNT OF CHARACTERS CMP AH,2 ; CHECK WHERE ATTR IS JB DO_STR ; NOT IN THE STRING MOV BL,ES:[BP] ; GET THE ATTRIBUTE INC BP ; NEXT ITEM IN STRING DO_STR: MOV AH,09H ; WRITE THE CHAR/ATTR INT 10H INC DL ; NEXT CURSOR POSITION CMP DL,BYTE PTR CRT_COLS ; COLUMN OVERFLOW JB STR_2 ; NOT YET CMP DH,ROWS JNE STR_3 MOV AX,0E0AH INT 10H DEC DH STR_3: INC DH ; NEXT ROW SUB DL,DL ; COLUMN ZERO STR_2: MOV AX,0200H ; SET THE CURSOR INT 10H JMP SHORT STR_4 STR_CR_LF: MOV AH,0EH INT 10H MOV BL,BH SUB BH,BH SAL BX,1 ; *2 FOR WORD OFFSET MOV DX,[BX + OFFSET CURSOR_POSN] ; GET CURSOR POSITION STR_4: POP AX POP BX POP CX LOOP STR_1 POP DX ; RECOVER CURSOR POSITION ; FROM PUSH SI ABOVE CMP AL,1 JE STR_OUT CMP AL,3 JE STR_OUT MOV AX,0200H ; SET CURSOR POSITION INT 10H STR_OUT: ; ALLOW FALL THROUGH V_RET PROC NEAR ; VIDEO BIOS RETURN POP DI POP SI POP BX POP CX POP DX POP DS POP ES POP BP IRET V_RET ENDP COMBO_VIDEO ENDP INCLUDE VPRSC.INC CODE ENDS END