home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / assemblr / library / sampler0 / kbxdual.asm < prev    next >
Assembly Source File  |  1987-09-17  |  32KB  |  645 lines

  1. ; revised by rwt for dual-display systems, tests display type each time
  2. ; the window is activated.  Done through calls to set-display-type, which
  3. ; is a re-written portion of the initialization routine.  Also eliminated
  4. ; possibility of entering ASCII 127 (in SCR_TABLE).  
  5. ;
  6. ; All changes to the program are in UPPER-case letters.  Un-commented 
  7. ; portions are closely related to the original, commented out but 
  8. ; commented, source code.  This should work with any normal two display
  9. ; system, e.g. mono with either cga or ega.
  10. ;
  11. ;KBX.COM for the IBM Personal Computer - 1987 by Jeff Prosise
  12. ;
  13. kb_data       equ 60h                       ;keyboard data port
  14. kb_ctrl       equ 61h                       ;keyboard control port
  15. eoi           equ 20h                       ;8259 EOI value
  16. int_ctrl      equ 20h                       ;8259 port address
  17. ;
  18. bios_data     segment at 40h                ;BIOS data area
  19.               org 17h
  20. kb_status     db ?                          ;keyboard status byte
  21.               org 1Ah
  22. buffer_head   dw ?                          ;pointer to keyboard buffer head
  23. buffer_tail   dw ?                          ;pointer to keyboard buffer tail
  24.               org 80h
  25. buffer_start  dw ?                          ;starting keyboard buffer address
  26. buffer_end    dw ?                          ;ending keyboard buffer address
  27. bios_data     ends
  28. ;
  29. code          segment para public 'code'    ;code segment
  30.               assume cs:code
  31.               org 100h
  32. begin:        jmp initialize                ;goto initialization code
  33. ;
  34. copyright          db 'Copyright 1987 Ziff-Davis Publishing Co.',1Ah
  35. enable_values      db 2Ch,28h,2Dh,29h,2Ah,2Eh,1Eh
  36. screen_buffer      dw offset initialize     ;pointer to screen buffer
  37. aux_shift          db 0                     ;auxiliary keyboard status byte
  38. old_shift          db 0                     ;storage for shift status
  39. window_status      db 0                     ;window display status
  40. adapter            db 2                     ;0 = MDA, 1 = CGA, 2 = EGA
  41. video_segment      dw 0B800h                ;default video segment
  42. border_attr        db 2Fh                   ;window border attribute
  43. text_attr          db 1Bh                   ;window border attribute
  44. cursor_mode        dw 0607h                 ;default cursor shape
  45. cursor_position    dw ?                     ;saved cursor position
  46. video_page         db ?                     ;saved video page number
  47. video_offset       dw ?                     ;starting window offset address
  48. addr_6845          dw ?                     ;port address of CRTC
  49. ibm                db 'IBM'                 ;EGA ASCII signature
  50. old9h              label dword
  51. old9h_vector       dw 2 dup (?)             ;storage for interrupt 9 vector
  52. ;
  53. fill_parms    dw 1,030Fh,12
  54.               dw 2,050Fh,12
  55.               dw 2,070Fh,12
  56.               dw 2,090Fh,10
  57.               dw 17,0537h,4
  58.               dw 0,0737h,4
  59.               dw 0,0937h,3
  60. ;
  61. def_table     db 0,'1234567890-=',0
  62.               db 0,'QWERTYUIOP[]',0
  63.               db 0,'ASDFGHJKL;',39,96
  64.               db 0,0,'ZXCVBNM,./'
  65.               db 17 dup (0)
  66.               db '789-456+123',0,0
  67. ;
  68. scr_table     db 0,000,128,129,130,131,132,133,134,135,136,137,138,0
  69. ; NOTE 127 ABOVE CHANGED TO 000
  70.               db 0,139,140,141,142,143,144,145,146,147,148,149,150,0
  71.               db 0,151,152,153,154,155,156,157,158,159,160,161,162
  72.               db 0,0,163,164,165,166,167,168,0,0,0,0
  73.               db 17 dup (0)
  74.               db 201,203,187,205,204,206,185,186,200,202,188,0,0
  75. ;
  76. num_table     db 0,169,170,171,172,173,174,175,176,177,178,219,220,0
  77.               db 0,221,222,223,224,225,226,227,228,229,230,231,232,0
  78.               db 0,233,234,235,236,237,238,239,240,241,242,243,244
  79.               db 0,0,245,246,247,248,249,250,251,252,253,254
  80.               db 17 dup (0)
  81.               db 218,194,191,196,195,197,180,179,192,193,217,0,0
  82. ;
  83. ;------------------------------------------------------------------------------
  84. ;Interrupt 9 handler.  Execution comes here when a key is pressed or released.
  85. ;------------------------------------------------------------------------------
  86. new9h         proc near
  87.               sti                           ;set interrupt enable flag
  88.               push ax                       ;save AX
  89.               in al,kb_data                 ;get scan code from keyboard
  90.               cmp al,69                     ;NumLock key pressed?
  91.               je numlock_down               ;yes, then branch
  92.               cmp al,69+128                 ;NumLock key released?
  93.               je numlock_up                 ;yes, then branch
  94.               cmp al,70                     ;ScrLock key pressed?
  95.               je scrlock_down               ;yes, then branch
  96.               cmp al,70+128                 ;ScrLock key released?
  97.               je scrlock_up                 ;yes, then branch
  98.               cmp al,57                     ;spacebar pressed?
  99.               je spacebar                   ;yes, then branch
  100.               cmp aux_shift,0               ;NumLock or ScrLock depressed?
  101.               je exit                       ;no, then exit
  102.               jmp newkey                    ;yes, then branch
  103. exit:         pop ax                        ;restore AX
  104.               jmp old9h                     ;goto old interrupt handler
  105. ;
  106. ;The NumLock key was pressed.  Toggle NumLock state or set shift bit.
  107. ;
  108. numlock_down: call get_status               ;get main shift status byte
  109.               test al,12                    ;is either Ctrl or Alt pressed?
  110.               jnz exit                      ;yes, then goto normal handler
  111.               push ax                       ;save shift code
  112.               call reset_kb                 ;reset the keyboard
  113.               pop ax                        ;retrieve shift code
  114.               test al,3                     ;is either Shift key depressed?
  115.               jnz numlock1                  ;yes, then branch
  116.               or aux_shift,2                ;set NumLock shift bit
  117.               jmp end_int                   ;exit
  118. numlock1:     push ds                       ;save DS
  119.               mov ax,bios_data              ;point DS to BIOS data area
  120.               mov ds,ax
  121.               assume ds:bios_data
  122.               xor kb_status,32              ;toggle NumLock state
  123.               pop ds                        ;restore DS
  124.               assume ds:nothing
  125.               jmp end_int                   ;exit
  126. ;
  127. ;The NumLock key was released.  Clear the NumLock shift bit.
  128. ;
  129. numlock_up:   call reset_kb                 ;reset the keyboard
  130.               and aux_shift,253             ;clear shift bit
  131.               jmp end_int                   ;exit
  132. ;
  133. ;The ScrLock key was pressed.  Toggle ScrLock state or set shift bit.
  134. ;
  135. scrlock_down: call get_status               ;get main shift status byte
  136.               test al,12                    ;is either Ctrl or Alt pressed?
  137.               jnz exit                      ;yes, then goto normal handler
  138.               push ax                       ;save shift code
  139.               call reset_kb                 ;reset the keyboard
  140.               pop ax                        ;retrieve shift code
  141.               test al,3                     ;is either Shift key depressed?
  142.               jnz scrlock1                  ;yes, then branch
  143.               or aux_shift,1                ;set ScrLock shift bit
  144.               jmp end_int                   ;exit
  145. scrlock1:     push ds                       ;save DS
  146.               mov ax,bios_data              ;point DS to BIOS data area
  147.               mov ds,ax
  148.               assume ds:bios_data
  149.               xor kb_status,16              ;toggle ScrLock state
  150.               pop ds                        ;restore DS
  151.               assume ds:nothing
  152.               jmp end_int                   ;exit
  153. ;
  154. ;The ScrLock key was released.  Clear the ScrLock shift bit.
  155. ;
  156. scrlock_up:   call reset_kb                 ;reset the keyboard
  157.               and aux_shift,254             ;clear shift bit
  158. end_int:      mov al,eoi                    ;issue EOI to 8259 controller
  159.               out int_ctrl,al
  160.               pop ax                        ;clean up the stack
  161.               iret                          ;return from interrupt
  162. ;
  163. ;The spacebar was pressed.  Pop up the window if Alt is depressed.
  164. ;
  165. spacebar:     call get_status               ;get current shift status
  166.               test al,8                     ;is the Alt key depressed?
  167.               jz exit                       ;no, then exit to normal handler
  168.               call reset_kb                 ;yes, then reset keyboard
  169.               mov al,eoi                    ;issue end-of-interrupt signal
  170.               out int_ctrl,al
  171.               cmp window_status,0           ;is the window already up?
  172.               jne space1                    ;yes, then ignore keypress
  173.               push bx                       ;save BX
  174.               call kb_display               ;pop up keyboard display
  175.               pop bx                        ;restore BX
  176. space1:       pop ax                        ;clean up the stack
  177.               iret                          ;exit
  178. ;
  179. ;A key was pressed or released with NumLock or ScrLock held down.
  180. ;
  181. newkey:       push ax                       ;save scan code
  182.               call reset_kb                 ;reset keyboard
  183.               pop ax                        ;recover scan code
  184.               test al,80h                   ;is the high bit set?
  185.               jnz newkey3                   ;yes, then don't process it
  186.               push bx                       ;save BX
  187.               mov bx,offset num_table       ;point BX to NumLock key table
  188.               cmp aux_shift,1               ;ScrLock depressed?
  189.               jne newkey1                   ;no, then continue
  190.               mov bx,offset scr_table       ;yes, then adjust BX
  191. newkey1:      mov ah,al                     ;transfer scan code to AH
  192.               dec al                        ;set AL relative to zero base
  193.               xlat num_table                ;get ASCII code from table
  194.               or al,al                      ;is it zero?
  195.               je newkey2                    ;yes, then don't process this key
  196.               call insert_char              ;insert character into kb buffer
  197. newkey2:      pop bx                        ;restore BX register value
  198. newkey3:      mov al,eoi                    ;issue end-of-interrupt signal
  199.               out int_ctrl,al
  200.               pop ax                        ;restore AX and clean up the stack
  201.               iret
  202. new9h         endp
  203. ;
  204. ;------------------------------------------------------------------------------
  205. ;RESET_KB resets the keyboard.
  206. ;------------------------------------------------------------------------------
  207. reset_kb      proc near
  208.               in al,kb_ctrl                 ;get control port value
  209.               mov ah,al                     ;save it
  210.               or al,80h                     ;set high bit of control value
  211.               out kb_ctrl,al                ;send reset value
  212.               mov al,ah                     ;get original control value
  213.               out kb_ctrl,al                ;enable keyboard
  214.               ret                           ;done
  215. reset_kb      endp
  216. ;
  217. ;------------------------------------------------------------------------------
  218. ;GET_STATUS returns the main keyboard shift status byte in AL.
  219. ;------------------------------------------------------------------------------
  220. get_status    proc near
  221.               push ds                       ;save DS
  222.               mov ax,bios_data              ;point DS to BIOS data area
  223.               mov ds,ax
  224.               assume ds:bios_data
  225.               mov al,kb_status              ;get status byte in AL
  226.               pop ds                        ;restore DS
  227.               assume ds:nothing
  228.               ret                           ;exit
  229. get_status    endp
  230. ;
  231. ;------------------------------------------------------------------------------
  232. ;INSERT_CHAR inserts the character code in AX into the keyboard buffer.
  233. ;Entry:  AH,AL - scan code, ASCII code
  234. ;------------------------------------------------------------------------------
  235. insert_char   proc near
  236.               push dx                       ;save DX and DS
  237.               push ds
  238.               mov bx,bios_data              ;point DS to BIOS data area
  239.               mov ds,bx
  240.               assume ds:bios_data
  241.               mov bx,buffer_tail            ;get current buffer tail address
  242.               mov dx,bx                     ;transfer it to DX
  243.               add dx,2                      ;calculate next buffer position
  244.               cmp dx,buffer_end             ;did we overshoot the end?
  245.               jne insert1                   ;no, then continue
  246.               mov dx,buffer_start           ;yes, then wrap around
  247. insert1:      cmp dx,buffer_head            ;is the buffer full?
  248.               je insert2                    ;yes, then branch
  249.               mov [bx],ax                   ;deposit character into buffer
  250.               mov bx,dx                     ;advance buffer tail
  251.               mov buffer_tail,bx            ;record its new value
  252. insert2:      pop ds                        ;restore DS
  253.               assume ds:nothing
  254.               pop dx                        ;restore DX
  255.               ret                           ;exit
  256. insert_char   endp
  257. ;
  258. ;------------------------------------------------------------------------------
  259. ;KB_DISPLAY opens a window showing all possible key definitions.
  260. ;------------------------------------------------------------------------------
  261. kb_display    proc near
  262. ;
  263. ;Make sure current video mode is an 80-column text mode.
  264. ;
  265.               mov ah,15                     ;get current video mode
  266.               int 10h
  267.               cmp al,2                      ;video mode 2?
  268.               je kb1                        ;yes, then continue
  269.               cmp al,3                      ;video mode 3?
  270.               je kb1                        ;yes, then continue
  271.               cmp al,7                      ;video mode 7 (monochrome)?
  272.               je kb1
  273.               ret                           ;unsupported mode - terminate
  274. kb1:          mov window_status,1           ;set status flag
  275.               push cx                       ;save register values
  276.               push dx
  277.               push si
  278.               push di
  279.               push ds
  280.               push es
  281.               push cs                       ;set DS and ES to the code segment
  282.               pop ds
  283.               assume ds:code
  284.               push cs
  285. ;             pop es    ;THIS POP MOVED DOWN 3 LINES
  286. ;
  287. ;Save page number, cursor mode, and cursor position.  Then blank the cursor.
  288. ;
  289.               mov video_page,bh             ;store video page number
  290.         CALL    SET_DISPLAY_TYPE ; CHECK DISPLAY TYPE EACH TIME.
  291.         POP     ES              ; SEE 3 LINES UP
  292.               mov ah,3                      ;get current cursor mode
  293.               int 10h
  294.               mov cursor_mode,cx            ;store cursor mode
  295.               call read_cursor              ;get cursor position
  296.               mov cursor_position,ax        ;save it
  297.               mov ah,1                      ;hide the cursor
  298.               mov ch,20h
  299.               int 10h
  300. ;
  301. ;Save the portion of video memory that will be overwritten.
  302. ;
  303.               cmp adapter,1                 ;disable video if this is a CGA
  304.               jne kb2
  305.               call disable_cga
  306. kb2:          call save_screen              ;copy video memory into buffer
  307. ;
  308. ;Open the keyboard display window.
  309. ;
  310.               call open_window              ;open the window
  311.               cmp adapter,1                 ;enable CGA video
  312.               jne kb3
  313.               call enable_cga
  314. kb3:          lea si,def_table              ;point SI to default key table
  315.               call fill_window              ;draw unshifted key definitions
  316. ;
  317. ;The window is open.  Loop until the ESC key is pressed, continually monitoring
  318. ;the auxiliary shift byte to determine what key definition set to display.
  319. ;
  320. kb4:          mov ah,1                      ;check buffer for character
  321.               int 16h
  322.               jz kb5                        ;branch if buffer is empty
  323.               mov ah,0                      ;get the character
  324.               int 16h
  325.               cmp al,27                     ;is it the ESC key?
  326.               je kb7                        ;yes, then close window and exit
  327. kb5:          mov al,aux_shift              ;get auxiliary shift byte
  328.               cmp al,2                      ;is it <= 2?
  329.               jna kb6                       ;yes, then branch
  330.               mov al,2                      ;no, then set it to 2
  331. kb6:          cmp al,old_shift              ;has the shift status changed?
  332.               je kb4                        ;no, then loop back
  333.               mov old_shift,al              ;record current shift status
  334.               mov bl,83                     ;calculate table address from AL
  335.               mul bl
  336.               mov si,ax                     ;transfer it to SI
  337.               add si,offset def_table       ;complete offset address in SI
  338.               call fill_window              ;write key equivalents to window
  339.               jmp kb4                       ;go back for more
  340. ;
  341. ;The ESC key was pressed.  Close the window and exit.
  342. ;
  343. kb7:          cmp adapter,1                 ;blank CGA video
  344.               jne kb8
  345.               call disable_cga
  346. kb8:          call restore_screen           ;restore contents of video memory
  347.               cmp adapter,1                 ;enable CGA video
  348.               jne kb9
  349.               call enable_cga
  350. kb9:          mov ah,2                      ;restore cursor position
  351.               mov bh,video_page
  352.               mov dx,cursor_position
  353.               int 10h
  354.               mov ah,1                      ;unblank the cursor
  355.               mov cx,cursor_mode
  356.               int 10h
  357.               mov window_status,0           ;reset status flag
  358.               pop es                        ;restore register values
  359.               pop ds
  360.               pop di
  361.               pop si
  362.               pop dx
  363.               pop cx
  364.               ret                          ;return to calling routine
  365. kb_display    endp
  366. ;
  367. ;------------------------------------------------------------------------------
  368. ;SAVE_SCREEN saves the block of video memory that will be overwritten.
  369. ;------------------------------------------------------------------------------
  370. save_screen   proc near
  371.               mov si,182                    ;set zero page window offset in SI
  372.               mov cl,video_page             ;get video page in CX
  373.               xor ch,ch
  374.               jcxz save2                    ;branch if page zero
  375. save1:        add si,1000h                  ;add one page length
  376.               loop save1                    ;loop until offset is correct
  377. save2:        mov video_offset,si           ;save starting window address
  378.               push ds                       ;save DS
  379.               mov ds,video_segment          ;point DS to video memory
  380.               assume ds:nothing
  381.               mov di,screen_buffer          ;point ES:DI to screen buffer
  382.               mov cx,11                     ;11 lines to save
  383. save3:        push cx                       ;save line counter
  384.               mov cx,58                     ;58 characters per line
  385.               cld                           ;clear DF
  386.               rep movsw                     ;transfer one line to storage
  387.               pop cx                        ;retrieve counter
  388.               add si,44                     ;point SI to next line
  389.               loop save3                    ;loop until all lines are saved
  390.               pop ds                        ;restore DS
  391.               assume ds:code
  392.               ret
  393. save_screen   endp
  394. ;
  395. ;------------------------------------------------------------------------------
  396. ;RESTORE_SCREEN restores saved video memory.
  397. ;------------------------------------------------------------------------------
  398. restore_screen proc near
  399.               mov es,video_segment          ;point ES to video segment
  400.               mov di,video_offset           ;point DI to window area
  401.               mov si,screen_buffer          ;point DS:SI to screen buffer
  402.               mov cx,11                     ;11 lines to restore
  403. restore1:     push cx                       ;save line count
  404.               mov cx,58                     ;58 characters per line
  405.               rep movsw                     ;restore one line
  406.               pop cx                        ;retrieve count
  407.               add di,44                     ;advance DI to next line
  408.               loop restore1                 ;loop until done
  409.               ret
  410. restore_screen endp
  411. ;
  412. ;------------------------------------------------------------------------------
  413. ;DISABLE_CGA and ENABLE_CGA control CGA video output.
  414. ;------------------------------------------------------------------------------
  415. disable_cga   proc near
  416.               mov dx,3DAh                   ;Status Register port address
  417. disable1:     in al,dx                      ;read status
  418.               test al,8                     ;vertical retrace active?
  419.               jz disable1                   ;no, then wait until it is
  420.               sub dx,2                      ;point DX to MSR
  421.               mov al,25h                    ;load disable value
  422.               out dx,al                     ;disable video
  423.               ret
  424. disable_cga   endp
  425. ;
  426. enable_cga    proc near
  427.               mov ah,15                     ;get current video mode
  428.               int 10h
  429.               lea bx,enable_values          ;point BX to table of values
  430.               xlat enable_values            ;get value to enable signal
  431.               mov dx,3D8h                   ;MSR address
  432.               out dx,al                     ;enable video output
  433.               ret
  434. enable_cga    endp
  435. ;
  436. ;------------------------------------------------------------------------------
  437. ;READ_CURSOR reads the cursor position directly from the CRT Controller.
  438. ;Exit:  AH,AL - row, column
  439. ;------------------------------------------------------------------------------
  440. read_cursor   proc near
  441.               mov dx,addr_6845              ;get CRTC Address Register port
  442.               mov al,14                     ;specify register number
  443.               out dx,al
  444.               inc dx                        ;point DX to Data Register
  445.               in al,dx                      ;read high byte of cursor address
  446.               mov ah,al                     ;save it in AH
  447.               dec dx                        ;point DX back to Address Register
  448.               mov al,15                     ;specify next register number
  449.               out dx,al
  450.               inc dx                        ;point DX to Data Register
  451.               in al,dx                      ;read low byte of address
  452.               and ax,07FFh                  ;strip page bits from address
  453.               mov bl,80                     ;divide by 80
  454.               div bl
  455.               xchg ah,al                    ;swap AH and AL
  456.               ret
  457. read_cursor   endp
  458. ;
  459. ;------------------------------------------------------------------------------
  460. ;OPEN_WINDOW writes the new window to video memory.
  461. ;------------------------------------------------------------------------------
  462. open_window   proc near
  463.               mov es,video_segment          ;point ES to video memory
  464.               mov di,video_offset           ;point DI to start of window
  465.               mov al,218                    ;get first character code
  466.               mov ah,border_attr            ;and first attribute byte
  467.               stosw                         ;write
  468.               mov cx,56                     ;do the next 56 characters
  469.               mov al,196
  470.               rep stosw
  471.               mov al,191                    ;finish the first line
  472.               stosw
  473.               add di,44                     ;advance DI to next line
  474.               mov cx,9                      ;9 identical lines next
  475. open1:        push cx                       ;save line counter
  476.               mov al,179                    ;do first character
  477.               push ax                       ;save character/attribute
  478.               stosw
  479.               mov cx,56                     ;do the next 56 characters
  480.               mov al,32
  481.               mov ah,text_attr
  482.               rep stosw
  483.               pop ax                        ;retrieve character/attribute pair
  484.               stosw                         ;finish the line
  485.               add di,44                     ;advance DI to next line
  486.               pop cx                        ;retrieve line count
  487.               loop open1                    ;loop until all 9 are done
  488.               mov al,192                    ;first character on last line
  489.               stosw
  490.               mov cx,56                     ;do the next 56
  491.               mov al,196
  492.               rep stosw
  493.               mov al,217                    ;finish the last line
  494.               stosw
  495.               ret
  496. open_window   endp
  497. ;
  498. ;------------------------------------------------------------------------------
  499. ;FILL_WINDOW writes a set of key definitions to the open window.
  500. ;Entry:  DS:SI - key definition table address
  501. ;------------------------------------------------------------------------------
  502. fill_window   proc near
  503.               mov bh,video_page             ;retrieve video page number
  504.               lea di,fill_parms             ;point DI to parameter table
  505.               mov cx,7                      ;7 lines to write
  506. fill1:        push cx                       ;save counter
  507.               add si,word ptr [di]          ;adjust table index
  508.               mov dx,[di+2]                 ;set starting cursor position
  509.               mov cx,[di+4]                 ;set number of characters
  510.               call writeln                  ;write one line
  511.               add di,6                      ;advance parameter table index
  512.               pop cx                        ;retrieve count
  513.               loop fill1                    ;loop until done
  514.               ret
  515. fill_window   endp
  516. ;
  517. ;------------------------------------------------------------------------------
  518. ;WRITELN writes one line of key equivalents to the open window.
  519. ;Entry:  DS:SI - character string address
  520. ;        BH    - video page
  521. ;        CX    - number of characters
  522. ;        DH,DL - starting row and column
  523. ;------------------------------------------------------------------------------
  524. writeln       proc near
  525.               push cx                       ;save character counter
  526.               mov ah,2                      ;position the cursor
  527.               int 10h
  528.               lodsb                         ;get one character
  529.               mov ah,10                     ;print it
  530.               mov cx,1
  531.               int 10h
  532.               add dl,3                      ;advance cursor position
  533.               pop cx                        ;retrieve count
  534.               loop writeln                  ;loop until done
  535.               ret
  536. writeln       endp
  537. ;
  538. ;------------------------------------------------------------------------------
  539. ;INITIALIZE prepares the body of the program for residency.
  540. ;------------------------------------------------------------------------------
  541. ;
  542. SET_DISPLAY_TYPE    PROC NEAR   ; CHECKS DISPLAY TYPE FOR WINDOWING EACH TIME
  543.                                 ; IT IS USED, NOT JUST AT INITIALIZATION.
  544. ;
  545.         MOV     AH,15
  546.         INT     10H
  547.         CMP     AL,7
  548.         JNZ     INIT2
  549.         MOV     ADAPTER,0
  550.         MOV     VIDEO_SEGMENT,0B000H
  551.         MOV     BORDER_ATTR,70H
  552.         MOV     TEXT_ATTR,07H
  553.         MOV     CURSOR_MODE,0C0DH
  554.         JMP     INIT3
  555. INIT2:  MOV     ADAPTER,2
  556.         MOV     VIDEO_SEGMENT,0B800H
  557.         MOV     BORDER_ATTR,2FH
  558.         MOV     TEXT_ATTR,1BH
  559.         MOV     CURSOR_MODE,0607H
  560.         MOV     AX,0C000H
  561.         MOV     ES,AX
  562.         MOV     DI,1EH
  563.         LEA     SI,IBM
  564.         MOV     CX,3
  565.         CLD
  566.         REPE    CMPSB
  567.         JZ      INIT3
  568.         DEC     ADAPTER
  569. INIT3:  MOV     AX,40H
  570.         MOV     ES,AX
  571.         MOV     DI,63H
  572.         MOV     DX,ES:[DI]
  573.         MOV     ADDR_6845,DX
  574.         MOV     CX,CURSOR_MODE
  575.         MOV     AH,1
  576.         INT     10H
  577.         RET
  578. ;
  579. SET_DISPLAY_TYPE        ENDP
  580. ;
  581. ;
  582. ;initialize    proc near
  583. ;
  584. ;See if the display adapter is an EGA.
  585. ;
  586. ;              mov ax,0C000h                 ;set ES to EGA BIOS segment
  587. ;              mov es,ax
  588. ;              mov di,1Eh                    ;point DI to signature location
  589. ;              lea si,ibm                    ;point SI to 'IBM' text
  590. ;              mov cx,3                      ;three bytes to compare
  591. ;              cld                           ;clear DF
  592. ;              repe cmpsb                    ;check three bytes
  593. ;              je init1                      ;branch if signature found
  594. ;
  595. ;Determine whether adapter is a CGA or an MDA.
  596. ;
  597. ;              dec adapter                   ;decrement assumed value
  598. ;              mov ah,15                     ;get current video mode
  599. ;              int 10h
  600. ;              cmp al,7                      ;is it mode 7?
  601. ;              jne init1                     ;no, then it's a CGA
  602. ;
  603. ;The display adapter is an MDA.  Modify video attributes.
  604. ;
  605. ;              dec adapter                   ;set ADAPTER value for MDA
  606. ;              sub video_segment, 800h       ;modify video segment value
  607. ;              mov border_attr,70h           ;modify border attribute
  608. ;              mov text_attr,07h             ;modify text attribute
  609. ;              mov cursor_mode,0C0Dh         ;modify default cursor shape
  610. ;
  611. ;Reset the cursor to its default shape.
  612. ;
  613. ;init1:        mov cx,cursor_mode            ;set scan lines in CX
  614. ;              mov ah,1                      ;video function - set cursor
  615. ;              int 10h                       ;reset cursor
  616. ;
  617. ;Get and save the address of the CRT Controller.
  618. ;
  619. ;              mov ax,40h                    ;point ES to BIOS data area
  620. ;              mov es,ax
  621. ;              mov di,63h                    ;point DI to address word
  622. ;              mov dx,es:[di]                ;get CRTC address
  623. ;              mov addr_6845,dx              ;save it
  624. ;
  625. INITIALIZE      PROC    NEAR
  626. ;
  627. ;Save the old interrupt 9 vector and replace it with a new one.
  628. ;
  629.               mov ax,3509h                  ;get current interrupt 9 vector
  630.               int 21h
  631.               mov old9h_vector,bx           ;save it
  632.               mov old9h_vector[2],es
  633.               mov ah,25h                    ;then point it to NEW9H routine
  634.               lea dx,new9h
  635.               int 21h
  636. ;
  637. ;Terminate, leaving additional room for screen buffering.
  638. ;
  639.               mov dx,offset initialize+1276 ;set DX for exit
  640.               int 27h                       ;terminate-but-stay-resident
  641. initialize    endp
  642. ;
  643. code          ends
  644.               end begin
  645.