title DOORS.ASM - Switch Color/Mono Screens On Keyboard Request ; VECTORS segment at 0h ; 8088 / 80286 Interrupt Vector Area org 9h*4 ; IBM PC Keyboard is Int 9H KB_INT_VECTOR label dword ; Double word label ; VECTORS ends ; ROM_BIOS_DATA segment at 40h ; Low Memory "BIOS" Parameters ; org 10h ; Location of EQUIP_FLAG EQUIP_FLAG dw ? ; Contains video settings ; in bits 4 and 5 ; org 17h ; Location of KB_FLAG KB_FLAG db ? ; Contains Alt (bit 3) & ; Right Shift (bit 0) States ROM_BIOS_DATA ends ; ; Initialization Routine ; CODE_SEG segment assume cs:CODE_SEG org 100h ; COM program format BEGIN: jmp SWAP_VECTORS ; Initialize vectors and attach to DOS ; ROM_KB_INT dd 0 ; Double word to save address of ; ROM-BIOS keyboard interrupt ; DOORS_INT intercepts the keyboard interrupt and switches ; screens if [Alt]-[Right Shift] combination is pressed ; DOORS_INT proc near assume ds:nothing push ds ; Push all affected registers push es push ax push bx push cx push dx push si push di ; pushf ; Push Flags for fake interrupt call call ROM_KB_INT ; to BIOS program to read keyboard ; assume ds:ROM_BIOS_DATA ; Define data segment to read mov ax,ROM_BIOS_DATA ; keyboard flag & equipment flag mov ds,ax mov al,KB_FLAG ; Get keyboard flag and al,09h ; Isolate [Alt] + [Right Shift] cmp al,09h ; Are they pressed? jne RETURN ; No, quit ; ; [Alt] + [Right Shift] are pressed -- Continue processing ; Check on video mode - quit if not monochrome, color 80x25 or BW 80x25 ; mov ah,15 ; Call Func 15 of Int 10h to int 10h ; get video state of the PC cmp al,7 ; Is screen monochrome? je SCREEN_OKAY ; Yes, go switch screens cmp al,3 ; Is screen color text? jbe CHECK_40_OR_80 ; Yes, go check for 80 or 40 char jmp RETURN ; Screen is in graphics mode, quit CHECK_40_or_80: cmp al,1 ; Is screen 40-character? jbe RETURN ; Yes, quit ; SCREEN_OKAY: ; ; Save the current cursor position ; mov ah,3 ; Call Func 3 of Int 10H mov bh,0 ; to read cursor position int 10h ; (page zero for color screen) ; ; Screen switch routine - Establish calling argument (AL) for Int 10h ; mov bx,EQUIP_FLAG ; Current equipment flag to BX mov cx,bx ; Make a copy of it in CX and cx,30h ; Extract screen information xor bx,cx ; Erase current screen information in BX or bx,20h ; Set BX to color 80x25 mov al,3 ; Set AL for color 80x25 in Int 10h cmp cx,30h ; Is current mono? je SET_MODE ; Yes, switch to color or bx,30h ; No, set BX for monochrome mov al,7 ; Set AL for monochrome in Int 10h SET_MODE: mov EQUIP_FLAG,bx ; Write BX to equipment flag xor ah,ah ; Use Func 0 of Int 10h to int 10h ; change screen parameters ; ; Restore Cursor ; mov ah,2 ; Use Func 2 of Int 10h to restore mov bh,0 ; cursor on new screen (position in DX) int 10h ; ; After screens are switched, set DS and ES registers to move screen data ; mov ax,0b000h ; Load ES with Mono Segment mov es,ax mov ax,0b800h ; Load DS with Color Segment mov ds,ax cmp cx,30h ; Did we switch from mono? jne COPY_THE_SCREEN ; Yes, move data from mono to color push ds ; No, swap ES and DS to move data push es ; from color to mono pop ds pop es COPY_THE_SCREEN: xor di,di ; Start at zero offsets xor si,si mov cx,2000 ; 2000 chars + attrs per screen cld ; Make sure move is 'forward' rep movsw ; Move Words with string instruction ; RETURN: pop di ; Restore saved registers pop si pop dx pop cx pop bx pop ax pop es pop ds iret ; Return to system DOORS_INT endp ; ; This procedure initializes the new keyboard interupt vectors ; SWAP_VECTORS proc near assume ds:VECTORS mov ax,VECTORS ; Set up the data mov ds,ax ; segment for vectors cli ; Disable interrupts mov ax,word ptr KB_INT_VECTOR ; Store addresses mov word ptr ROM_KB_INT,ax ; of BIOS program mov ax,word ptr KB_INT_VECTOR[2] mov word ptr ROM_KB_INT[2],ax mov word ptr KB_INT_VECTOR, offset DOORS_INT ; Substitute Our mov word ptr KB_INT_VECTOR[2],cs ; Program sti ; Enable interrupts mov dx,offset SWAP_VECTORS ; End of new resident ; program int 27h ; Terminate resident SWAP_VECTORS endp CODE_SEG ends end BEGIN ;