home *** CD-ROM | disk | FTP | other *** search
- page 64,132
- title screen - IBM Display Enhancement Dec 1983
- .radix 10
- ;***************************************************************
- ; Typed in by Greg Glass - gjg@cmu-cs-cad from Byte - Nov. 1983
- ; NOTE: if you have a color card this will shift over to it
- ; (even if the monitor is turned off)
- ; hit Alt F7 to switch to the Mono monitor.
- ; To build this program:
- ; 1> masm screen; /* assemble the code */
- ; 2> link screen; /* link it - will get no stack seg. message */
- ; 3> exe2bin screen /* convert the format */
- ; 4> rename screen.bin screen.com /* make the new format executable*/
- ; 5> del screen.exe /* don't need this anymore */
- ;
- ; To use program: just run it or place in autoexec.bat
- ;
- ; COMMANDS:
- ; <alt>F1 - increment the text color
- ; <alt>F3 - increment the background color
- ; <alt>F5 - toggle modes co80/co40
- ; <alt>F7 - toggle between color and mono display
- ; <alt>F9 - redraw display - reset colors
- ;***************************************************************
-
- ;***************************************************************
- ;
- ; Define interrupt vectors for both keyboard interrupt 16H and
- ; screen interrupt 10H. Both in segment 0.
- ;
- ;***************************************************************
-
- keyvect segment at 0 ; define keyboard interrupt vector
- org 16h*4
- KEYINT label dword
- keyvect ends
-
- scrvect segment at 0 ; define screen interrupt vector
- org 10h*4
- SCRINT label dword
- scrvect ends
-
- ;***************************************************************
- ;
- ; define constants
- ;
- ;***************************************************************
-
- bw_val equ 07h ; standard b&w attibute sent to monitor
- equip_flag equ 410h ; area in RAM that contains equipment status
- chk_mode equ 15 ; screen interrupt function to check mode
- mono_mode equ 7 ; screen mode of 7 indicates monochrome
- color_adpt equ 3 ;modes from 0 to 3 are non-graphics color
-
- ;***************************************************************
- ;
- ; start code area
- ;
- ;***************************************************************
-
- code segment para
- assume cs:code
- org 100h ; start code offset 100h from starting segment
- ; (this leaves room for DOS's work areas)
-
- KEY proc far
- START:
- ; Initialization code...used only once, on system startup
-
- jmp init_code ; call initialization routine
- even
- validchk db 'FCP!' ; used by INSTALL to check for valid SCREEN
- ; program
-
- ;***************************************************************
- ;
- ; Define storage areas and data structures
- ;
- ;***************************************************************
-
- ; define keystroke scan codes for the five SCREEN functions
-
- fore_inc dw 6800h ; foreground increment
- back_inc dw 6a00h ; background increment
- c80_40 dw 6c00h ; 80x25 to 40x25 flip-flop key
- col_mon dw 6e00h ; color/mono flip-flop key
- repaint dw 7000h ; repaint screen using current mode
-
- cur_mode dw col80_area ; Initialize starting mode
- mono_set dw mono_area ; pointer to monochrome area
- color_set dw col80_area ; pointer to "active" color area
-
- scrn_attr db 70h ; current screen attribute
- scrn_mode db 255 ; saves current screen mode
-
- ; define structure used to contain information about 40 and 80
- ; column color modes as well as monochrome mode.
-
- s struc
- corner dw 0 ; defines COL/ROW count of characters for mon
- bf dw 0 ; Colors of fore and back
- equip dw 0 ; equipment settings
- mode dw 0 ; AX value for setting mode of monitor
- s ends
-
- ; Now, set up three screen structures with default conditions
-
- col80_area s <5019h,0107h,20h,3> ; 80x25, white FORE blue BACK
-
- col40_area s <2819h,0107h,10h,1> ; 40x25, Brown FORE black BACK
-
- mono_area s <5019h,0007h,30h,7> ; monochrome, reverse video
-
- ;NOTE: The standard BIOS ROM KEYBOARD interrupt routine is
- ; executed as a subroutine ( using CALL DWORD PTR) if
- ; the interrupt was invoked to return a keystroke. Any
- ; other execution KEYBOARD_IO can be called as a simple
- ; inline FAR JMP instruction. NOTE: the CALL instruction
- ; (see just after INT_LOOP label below) uses the
- ; address stored here at KEY_CALL to KEYBOARD_IO.
-
- KEY_CALL :
- db 0eah ; far JMP address to KEYBOARD interrupt
- dw 0,0 ;
-
- ;***************************************************************
- ;
- ; procedure KEY_RTNE - Intercepts keyboard interrupt and
- ; determines if the keystroke is one of the five SCREEN ones.
- ;
- ;***************************************************************
-
- KEY_RTNE:
- assume ds:code
- sti ; turn on interrupts
- cmp ah,0 ; call as subroutine if keyfetch
- jne KEY_CALL ; jump to KEYBOARD_IO if not
- push ds ; save ds and bx from destruction
- push bx ;
- push cx
- push dx
- push es
- push di
- mov bx,cs ; move cs segment into ds
- mov ds,bx ;
-
- INT_LOOP:
- pushf ; IBM keyboard proc exports interrupt call
- mov bx,offset KEY_CALL + 1 ;Get address to ROM code for keyboard
- call dword ptr[bx] ; call keyboard routine
- mov bx, cur_mode ; get current mode address
- cmp ax, col_mon ; see if COLOR<->MONO flip-flop key
- jne TEST_FORE ; exit if not
- ; otherwise, flip-flop screen mode
- cmp bx, mono_set ; are we looking at monochrome?
- je set_color ; swap in color if yes
- cmp mono_set,0 ; see if monochrome monitor enabled
- je next_key ; ignore command if not
- mov bx,mono_set ; otherwise set up monochrome
- jmp short DO_CHG ;
-
- SET_COLOR:
- cmp color_set,0 ; see if COLOR monitor enabled
- je NEXT_KEY ; skip if not
- mov bx,color_set ; set up for color
-
- DO_CHG:
- call SCREEN_CHG ; implement screen change
-
- NEXT_KEY:
- mov ah,0 ; set up to fetch keystroke
- jmp INT_LOOP ; fetch next key input
-
- TEST_FORE:
- push ax ; save registers.
- push bx ; see if in graphics mode
- mov ah,chk_mode ;
- int 10h ;
- pop bx ; restore bx register
- cmp al,color_adpt ; if between 0 and 3, not graphics mode
- jle NOT_GRAF ;
- cmp al,mono_mode ; monochrome mode
- jge NOT_GRAF ; restore stack
- pop ax ; if color-graphics mode, do not change
- jmp DONE ; modes
-
- NOT_GRAF:
- pop ax ; restore ax
- cmp ax,fore_inc ; is this key to increment FORE ?
- jne TEST_BACK ; skip if not
- cmp bx,color_set ; see if currently using color
- jne BW_FLOP ; if not, go deal with B & W
- mov ax,[bx].bf ; gets BACK in al, FORE in ah
-
- EQ_FORE:
- inc al ; increment FOREGROUND color
- and al,7 ; keep it within bounds (chg. for more colors)
- cmp al,ah ; see if same as background
- je EQ_FORE ; increment againt if yes
- mov [bx].bf,ax ; save back to structure
- jmp DO_CHG ; redraw display
-
- TEST_BACK:
- cmp ax,back_inc ; is this key to increment BACK?
- jne TEST_REPAINT ; skip if not
- cmp bx,color_set ; see if currently using color
- jne BW_FLOP ; if not, go deal with B&W
- mov ax,[bx].bf ; gets BACK in al, FORE in ah
-
- EQ_BACK:
- inc ah ; increment background color
- and ah,7 ; keep in bounds
- cmp ah,al ; see if same as foreground
- je EQ_BACK ; increment again if yes
- mov [bx].bf,ax ; save back to structure
- jmp DO_CHG ; redraw the screen
-
- BW_FLOP: ; flip-flop B&W screen
- mov ax,[bx].bf ; BACK in ah, FORE in al
- xchg ah,al ; swap
- mov [bx].bf,ax ; save back to structure
- jmp DO_CHG ; redraw the screen
-
- TEST_REPAINT:
- cmp ax,repaint ; is this the key to redraw the screen ?
- je DO_CHG ; if yes then repaint
-
- TEST_80_40:
- cmp ax,c80_40 ; is this the key to flop 80 / 40 ?
- jne DONE ; exit if not
- cmp bx,offset col40_area ; is current pointer area 40x25 ?
- jne TST80 ; skip if not
- mov bx,offset col80_area ; otherwise flip to 80x25
- jmp short SAVE_COL ; save to color_set
-
- TST80:
- cmp bx,offset col80_area ; is current 80x25 color ?
- jne NEXT_KEY ; ignore key if not
- mov bx,offset col40_area ;
-
- SAVE_COL:
- mov color_set,bx ; sat to color_set
- jmp SET_COLOR ; implement
-
- DONE:
- pop di
- pop es
- pop dx
- pop cx
- pop bx
- pop ds
- iret ; return from interrupt
-
- KEY endp ; done with main routine !
-
- ;***************************************************************
- ;
- ; SCREEN_CHG - Changes current monitor screen mode
- ;
- ; Inputs: bx points to current monitor structure
- ;
- ;***************************************************************
-
- SCREEN_CHG proc near
- mov ax,0 ; get segment address to equip_flag
- mov es,ax ; in RAM memory
- mov ax,es:equip_flag ; get set of equip flag
- and al,0CFh ; get rid of current monitor flag
- or ax,[bx].equip ; set up new monitor flag
- mov es:equip_flag,ax ; save back in RAM
- mov cur_mode,bx ; indicate new mode
-
- ; now, set up attribute for background and foreground
-
- mov dx,[bx].bf ; get both FORE and BACK in dx
- mov cl,4 ; shift count
- shl dh,cl ; shift BACK into upper nibble
- or dh,dl ; move FORE into lower nibble
- mov scrn_attr,dh ; save result
-
- ; see if we need to reset monitor (switching to new monitor?)
-
- mov ax,[bx].mode ; get mode
- cmp al,scrn_mode ; compare with current mode
- je SET_ATTR ; skip if same
- mov scrn_mode,al ; otherwise, save current mode
- int 10h ; and reset to new monitor
-
- SET_ATTR: ; change attributes of current screen
- call CH_ATTR ; changes attributes
- ret
-
- SCREEN_CHG endp
-
- ;***************************************************************
- ;
- ; CH_ATTR - repaints acctive screen so that every character on
- ; current screen is displayed with the new attributes
- ;
- ; Inputs: bx points to current monitor structure
- ;
- ;***************************************************************
-
- CH_ATTR proc near
- ; see if we need to draw in border for color mode
- cmp bx,offset mono_set ; in color?
- je NO_BORDER ; do not worry about border if not
- push ax ; save registers
- push bx ;
- mov bx,[bx].bf ; get background color in bx
- mov bl,bh ;
- mov bh,0 ; select border color
- mov ah,11 ; interface to set color palette
- int 10h
- pop bx ; restore registers
- pop ax
-
- NO_BORDER:
- mov ax,[bx].corner ; get COL and ROW for current
- mov cornr,ax ; save in temporary
- mov ah,chk_mode ; get page number
- int 10h ;
- ; bh contains active page
- mov ah,3 ; save current cursor posn
- int 10h
- push dx ; save position in stack
- xor dx,dx ; load dx with 0
- mov cx,1 ; set up replication count
- mov bl,scrn_attr ; get current attribute
-
- REP_ATTR:
- mov ah,2 ; set cursor position
- int 10h
- mov ah,8 ; read next character
- int 10h
- ; ah contains current character attribute
- and ah,88h ; get intensity bit
- and bl,77h ; make sore attribute intensity off
- or bl,ah ; combine to get current attribute
- mov ah,9 ; write out char with new attribute
- int 10h ;
- inc dl ;
- cmp dl,tcol ; are we done with this column?
- jle REP_ATTR
- xor dl,dl ; otherwise zero out DL
- inc dh ; move to next row
- cmp dh,trow ; done with screen ?
- jle REP_ATTR ; loop until done
-
- pop dx ; restore original cursor position
- mov ah,2
- int 10h
- ret
-
- cornr label word
- trow db 0 ; temporary store for ROW
- tcol db 0 ; temp store for COL
-
- CH_ATTR endp
-
- ;***************************************************************
- ;
- ; SCR_RTNE - Replaces SCREEN interrupt so that it can intercept
- ; B&W character writes and change attributes
- ;
- ;***************************************************************
-
- SCR_RTNE proc near
- assume ds: code
- sti
- push ds ; save data segment register
- push cs ; move CS segment into DS
- pop ds ; this is a funny way to do that (gjg)
- cmp ah,6 ; Spot SCROLL UP and SCROLL DOWN calls
- jl NORMAL_SCR ;
- cmp ah,6
- jg NOT_SCROLL ;
-
- SCROLL:
- call GET_CH ; for scrolling, update attribute
- jmp NORMAL_SCR ; now, execute scroll
-
- NOT_SCROLL:
- cmp ah,9 ; check for "WRITE ATTRIBUTE/CHAR" cmd
- jne NORMAL_SCR ; send out any other command as normal
- xchg bh,bl ; get attribute for command
- call GET_CH ; update attribute for command
- xchg bh,bl ; move attribute back to bh for cmd
-
- NORMAL_SCR:
- pop ds ; restore ds segment register
- ;
- ; NOTE: We are now ready to invoke the BIOS screen interrupt.
- ; Since the ROM code includes an IRET interrupt return call,
- ; all we need to do is to jump to the start of the ROM code
- ; and all will be well. Since the initialization code set
- ; up the address to the screen interrupt code below, we can
- ; set up a forced jump to that address.
-
- JMP_SCR: ; Address to SCREEN interrupt
- db 0EAh ; force a FAR JMP but do not set up dest-
- dw 0,0 ; ination address at assembly time.
- ; (INIT routine will set this address)
-
- SCR_RTNE endp
-
-
- ;***************************************************************
- ;
- ; GET_CH - subroutine replaces B&W character with current replacement
- ; attributes and allows for intensity bit setting
- ;
- ; Inputs : bh contains attribute to be modified
- ;
- ;***************************************************************
-
- GET_CH proc near
- mov savech,bh ; save character
- and bh,77h ; Remove intensity and blink bits
- cmp bh,bw_val ; see if currently defined B&W value
- mov bh,savech ; otherwise, modify to current attribute
- jne OUT ; exit if not
- and bh,88h ; get rid of B&W part
- or bh,scrn_attr ; move in current attribute part
-
- OUT:
- ret ; done
-
- savech db 0 ; temporary character store
- GET_CH endp
-
- LASTONE: ; all code after this label is freed to DOS use after
- ; initialization of the program.
-
- ;***************************************************************
- ;
- ; INIT_CODE - Code to load and initialize the SCREEN program..
- ; sets up DOS to keep all code before "LASTONE" label
- ; safe from overlaying during system operation.
- ;
- ;***************************************************************
-
- COPYRT: db 'SCREEN Version 1.20 Copyright 1983 Tim Field',13,10,'$'
-
- INIT_CODE proc near
-
- ; Initialize KEYBOARD intercept code
-
- assume es:keyvect ;'vectors' is interrupt segment 0
-
- mov ax,keyvect ; get address to interrupt vector
- mov es,ax ; save in es
- mov ax,es:keyint ; get address to interrupt
- mov bx,offset key_call+1 ; address to place to save vector
- mov [bx],ax ; save interrupt address
- mov ax,es:keyint[2] ; get interrupt segment for rtne
- mov [bx+2],ax ; save it too
- mov es:keyint,offset key_rtne ; now replace with own address
- mov ax,cs ; save segment in interrupt vector
- mov es:keyint[2],ax ;
-
- ; initialize SCREEN intercept code
- assume es:scrvect ;'vectors' is interrupt segment 0
-
- mov ax,scrvect ; get address to interrupt vector
- mov es,ax ; save in es
- mov ax,es:scrint ; get address to interrupt
- mov bx,offset jmp_scr+1 ; address to place to save vector
- mov [bx],ax ; save interrupt address
- mov ax,es:scrint[2] ; get interrupt segment for rtne
- mov [bx+2],ax ; save it too
- mov es:scrint,offset scr_rtne ; now replace with own address
- mov ax,cs ; save segment in interrupt vector
- mov es:scrint[2],ax ;
-
- ; Initialize screen
- mov bx,cur_mode ; set up initial mode
- call SCREEN_CHG ; initialize
-
- ; Now print out acknowledgement to user monitor and exit
-
- mov ax,cs ; set up segment to routine
- mov ds,ax
- mov dx,offset copyrt ; now print out copyright message
- mov ah,9 ; DOS function to print string
- int 21h ; execute function interrupt
- mov dx,offset lastone ; save all code up to "LASTONE" label
- int 27h ; no return needed
-
- INIT_CODE endp
- code ends
- end start
-