home *** CD-ROM | disk | FTP | other *** search
/ Hall of Fame / HallofFameCDROM.cdr / filedisk / asc.lzh / ASC.ASM next >
Assembly Source File  |  1987-07-25  |  35KB  |  684 lines

  1. ;ASC for the IBM Personal Computer - 1986 by Jeff Prosise
  2. ;
  3. kb_data       equ 60h                       ;keyboard data port
  4. kb_ctrl       equ 61h                       ;keyboard control port
  5. eoi           equ 20h                       ;8259 end-of-interrupt value
  6. int_ctrl_port equ 20h                       ;8259 PIC port
  7. a_key         equ 30                        ;scan code for 'A' key
  8. alt_key       equ 8                         ;shift code for Alt key
  9. ;
  10. bios_data     segment at 40h                ;BIOS data area
  11.               org 63h
  12. addr_6845     dw ?                          ;6845 Index Register address
  13. bios_data     ends
  14. ;
  15. code          segment para public 'code'
  16.               assume cs:code
  17.               org 100h
  18. begin:        jmp initialize                ;jump to initialization code
  19. ;
  20. notice             db 'Copyright 1986 Ziff-Davis Publishing Co.'
  21. notice2            db 'Programmed by Jeff Prosise '
  22. ibm_signature      db 'IBM'                 ;EGA BIOS signature
  23. adapter            db 2                     ;0 = CGA, 1 = MDA, 2 = EGA
  24. video_segment      dw 0B800h                ;video segment address
  25. video_page         db ?                     ;current video page
  26. border_attr        db 0Fh                   ;window border attribute
  27. text_attr          db 1Fh                   ;window text attribute
  28. header_attr        db 1Eh                   ;window header attribute
  29. window_row         db 1                     ;row of left corner of window
  30. window_column      db 3                     ;column of left corner of window
  31. start_value        db 0                     ;first value in ASCII table
  32. int_status         db 0                     ;status of interrupt routine
  33. cursor_mode        dw ?                     ;cursor scan line definition
  34. old_int_9h         label dword              ;old interrupt vector
  35. old_keyboard_int   dw 2 dup (?)
  36. screen_buffer      dw offset initialize     ;pointer to screen buffer area
  37. ;
  38. enable_values      db 2Ch,28h,2Dh,29h,      ;values to enable CGA display
  39.                    db 2Ah,2Eh,1Eh
  40. header_text        db ' Dec Hex Char  Dec Hex Char '       ;window header text
  41. ;
  42. ;-----------------------------------------------------------------------------
  43. ;Front-end routine for the keyboard interrupt handler.  Execution is vectored
  44. ;here whenever an interrupt 9 is generated by the PC keyboard.
  45. ;-----------------------------------------------------------------------------
  46. ascview       proc near
  47.               cmp int_status,0              ;is ASCII table already displayed?
  48.               jne short_exit                ;yes, then exit immediately
  49.               sti                           ;enable interrupts
  50.               push ax                       ;save registers
  51.               push bx
  52.               push cx
  53.               push dx
  54.               push si
  55.               push di
  56.               push ds
  57.               push es
  58.               in al,kb_data                 ;get scan code from keyboard
  59.               cmp al,a_key                  ;was the 'A' key pressed?
  60.               jne exit                      ;no, then exit to normal routine
  61.               mov ah,2                      ;get state of shift keys
  62.               int 16h
  63.               test al,alt_key               ;is the Alt key depressed?
  64.               jne asc1                      ;yes, then continue
  65. ;
  66. ;Exit is achieved thru here when execution is to be transferred to the normal
  67. ;BIOS keyboard interrupt handling routine.
  68. ;
  69. exit:         pop es                        ;restore registers
  70.               pop ds
  71.               pop di
  72.               pop si
  73.               pop dx
  74.               pop cx
  75.               pop bx
  76.               pop ax
  77. short_exit:   jmp old_int_9h                ;goto BIOS keyboard routine
  78. ;
  79. ;The key combination Alt-A was just pressed.  Reset the keyboard and issue an
  80. ;EOI to the 8259 PIC to enable hardware interrupts.
  81. ;
  82. asc1:         call kb_reset                 ;reset keyboard, end 8259 int
  83.               push cs                       ;set DS and ES to the code segment
  84.               pop ds
  85.               push cs
  86.               pop es
  87.               assume ds:code
  88. ;
  89. ;Check the current video mode to see if it's one of the 80-column text modes
  90. ;(2, 3, or 7).  If it is, then continue.  If it's not, gracefully abort this
  91. ;routine by exiting thru an IRET.
  92. ;
  93.               mov ah,15                     ;get video page and display mode
  94.               int 10h
  95.               cmp al,2                      ;video mode 2?
  96.               je asc2                       ;yes, then continue
  97.               cmp al,3                      ;mode 3?
  98.               je asc2                       ;yes, then continue
  99.               cmp al,7                      ;mode 7 (monochrome)?
  100.               je asc2                       ;yes, then continue
  101. done:         pop es                        ;restore register values for exit
  102.               pop ds
  103.               pop di
  104.               pop si
  105.               pop dx
  106.               pop cx
  107.               pop bx
  108.               pop ax
  109.               iret                          ;return to interrupted program
  110. ;
  111. ;Save the current video page number and the cursor scan line parameters,
  112. ;set the interrupt routine status flag, and blank the cursor.
  113. ;
  114. asc2:         mov video_page,bh             ;save page number
  115.               mov int_status,1              ;set interrupt routine status flag
  116.               mov ah,3                      ;get the cursor shape
  117.               int 10h
  118.               mov cursor_mode,cx            ;save it
  119.               mov ah,1                      ;hide the cursor for now
  120.               mov ch,20h
  121.               int 10h
  122. ;
  123. ;Save the contents of the portion of the screen that will underlie the window.
  124. ;
  125.               cmp adapter,0                 ;is this a CGA?
  126.               jne asc3                      ;no, then skip disable
  127.               call disable_cga              ;disable CGA video
  128. asc3:         mov di,screen_buffer          ;point DI to storage buffer
  129.               call save_screen              ;save screen contents
  130. ;
  131. ;Pop the window border onto the display by writing directly to video.  Finish
  132. ;things up by filling the blank window with the text of the ASCII table.
  133. ;
  134.               call open_window              ;pop up the window border
  135.               cmp adapter,0                 ;is this a CGA?
  136.               jne asc4                      ;no, then skip enable
  137.               call enable_cga               ;enable CGA video
  138. asc4:         call fill_window              ;write the window text
  139. ;
  140. ;The window is now displayed on the screen.  Wait for a keypress.
  141. ;
  142. asc5:         mov ah,0                      ;get a keypress
  143.               int 16h
  144.               cmp al,0                      ;is it an extended code?
  145.               je asc10                      ;yes, then jump
  146.               cmp al,27                     ;ESC key pressed?
  147.               jne asc5                      ;no, then get another keypress
  148. ;
  149. ;The ESC key has been pressed.  Restore the original contents of the screen,
  150. ;restore the cursor, reset the status flag, and exit to the application.
  151. ;
  152.               cmp adapter,0                 ;blank video if CGA installed
  153.               jne asc6
  154.               call disable_cga
  155. asc6:         mov si,screen_buffer          ;point SI to holding buffer
  156.               call restore_screen           ;restore video memory contents
  157.               cmp adapter,0                 ;enable video if necessary
  158.               jne asc7
  159.               call enable_cga
  160. asc7:         mov ah,1                      ;unblank the cursor
  161.               mov cx,cursor_mode            ;define cursor scan lines
  162.               int 10h
  163.               mov int_status,0              ;reset status flag
  164.               jmp done                      ;exit
  165. ;
  166. ;A key has been pressed that returned an extended code.
  167. ;
  168. asc10:        cmp ah,72                     ;Up-Arrow pressed?
  169.               jne asc11                     ;no, then jump to next test
  170.               call scroll_down              ;yes, then scroll down
  171.               jmp asc5                      ;return for another keypress
  172. asc11:        cmp ah,80                     ;Down-Arrow pressed?
  173.               jne asc12
  174.               call scroll_up                ;scroll window up
  175.               jmp asc5
  176. asc12:        cmp ah,73                     ;PgUp pressed?
  177.               jne asc13
  178.               call last_window_page         ;flip window page back
  179.               jmp asc5
  180. asc13:        cmp ah,81                     ;PgDn pressed?
  181.               jne asc14
  182.               call next_window_page         ;flip window page forward
  183.               jmp asc5
  184. asc14:        cmp ah,79                     ;End pressed?
  185.               jne asc15
  186.               call end_window_page          ;flip to last window page
  187.               jmp asc5
  188. asc15:        cmp ah,71                     ;Home pressed?
  189.               jne asc16                     ;no, then start again
  190.               call first_window_page        ;goto first window page
  191. asc16:        jmp asc5                      ;look for another keypress
  192. ascview       endp
  193. ;
  194. ;-----------------------------------------------------------------------------
  195. ;SAVE_SCREEN saves the contents of the screen beneath the window.
  196. ;Entry:  ES:DI - buffer address
  197. ;-----------------------------------------------------------------------------
  198. save_screen   proc near
  199.               mov dh,window_row             ;row and column of window corner
  200.               mov dl,window_column
  201.               mov bl,video_page             ;get video page in BX
  202.               xor bh,bh
  203.               push di                       ;save buffer address
  204.               call video_offset             ;get starting address of window
  205.               mov si,di                     ;transfer address to SI
  206.               pop di                        ;retrieve buffer address
  207.               push ds                       ;save DS
  208.               mov ds,video_segment          ;set DS to video segment
  209.               assume ds:nothing
  210.               mov cx,19                     ;19 lines to save
  211.               cld                           ;clear DF
  212. save1:        push cx                       ;save line counter
  213.               mov cx,30                     ;30 words per line
  214.               rep movsw                     ;transfer one line to buffer
  215.               add si,100                    ;adjust SI for next line
  216.               pop cx                        ;get line count
  217.               loop save1                    ;loop until done
  218.               pop ds                        ;restore DS
  219.               assume ds:code
  220.               ret
  221. save_screen   endp
  222. ;
  223. ;-----------------------------------------------------------------------------
  224. ;RESTORE_SCREEN restores the contents of the screen beneath the window.
  225. ;Entry:  DS:SI - buffer address
  226. ;-----------------------------------------------------------------------------
  227. restore_screen proc near
  228.               mov dh,window_row             ;row & column where window starts
  229.               mov dl,window_column
  230.               mov bl,video_page             ;get video page in BX
  231.               xor bh,bh
  232.               call video_offset             ;get window starting address
  233.               mov es,video_segment          ;set ES to video segment
  234.               mov cx,19                     ;19 lines to restore
  235.               cld                           ;clear DF
  236. restore1:     push cx                       ;save line counter
  237.               mov cx,30                     ;30 words per line
  238.               rep movsw                     ;restore one line
  239.               add di,100                    ;set DI for next line
  240.               pop cx                        ;retrieve count
  241.               loop restore1                 ;loop until done
  242.               ret
  243. restore_screen endp
  244. ;
  245. ;-----------------------------------------------------------------------------
  246. ;VIDEO_OFFSET calculates the offset address in video memory that corresponds
  247. ;to the given row, column, and video page.
  248. ;Entry:  DH,DL - row, column           | Exit:  DI - offset
  249. ;        BX    - video page            |
  250. ;-----------------------------------------------------------------------------
  251. video_offset  proc near
  252.               mov al,160                    ;row * 160
  253.               mul dh                        ;result in AX
  254.               shl dl,1                      ;column * 2
  255.               xor dh,dh                     ;byte to word in DX
  256.               add ax,dx                     ;add the two
  257.               mov di,ax                     ;save result in DI
  258.               mov ax,1000h                  ;length of one video page
  259.               mul bx                        ;page * 1000h
  260.               add di,ax                     ;complete the offset address
  261.               ret
  262. video_offset  endp
  263. ;
  264. ;-----------------------------------------------------------------------------
  265. ;DISABLE_CGA and ENABLE_CGA routines disable and enable CGA video by writing
  266. ;to the Mode Select Register at port address 3D8h.
  267. ;-----------------------------------------------------------------------------
  268. disable_cga   proc near
  269.               mov dx,3DAh                   ;load Status Register address
  270. disable1:     in al,dx                      ;get video status
  271.               test al,8                     ;vertical retrace active?
  272.               je disable1                   ;no, then wait until it is
  273.               sub dx,2                      ;load MSR address
  274.               mov al,25h                    ;value to disable video
  275.               out dx,al                     ;send it to the adapter
  276.               ret
  277. disable_cga   endp
  278. ;
  279. enable_cga    proc near
  280.               mov ah,15                     ;get current video mode
  281.               int 10h
  282.               lea bx,enable_values          ;offset of enable value table
  283.               xlat                          ;get the value to enable video
  284.               mov dx,3D8h                   ;load address of MSR
  285.               out dx,al                     ;OUT the enable value
  286.               ret
  287. enable_cga    endp
  288. ;
  289. ;-----------------------------------------------------------------------------
  290. ;KB_RESET resets the keyboard and issues an EOI to the 8259 PIC.
  291. ;-----------------------------------------------------------------------------
  292. kb_reset      proc near
  293.               in al,kb_ctrl                 ;get current control port value
  294.               mov ah,al                     ;save it in AH
  295.               or al,80h                     ;set bit 7
  296.               out kb_ctrl,al                ;send reset value
  297.               mov al,ah                     ;get original value
  298.               out kb_ctrl,al                ;send it out to enable keyboard
  299.               cli                           ;suspend interrupts
  300.               mov al,eoi                    ;get EOI value
  301.               out int_ctrl_port,al          ;send EOI to 8259
  302.               sti                           ;enable interrupts
  303.               ret
  304. kb_reset      endp
  305. ;
  306. ;-----------------------------------------------------------------------------
  307. ;BIN2ASC outputs a byte value to the screen in decimal or hexadecimal form.
  308. ;Entry:  DH,DL - row, column
  309. ;        AL    - number to output
  310. ;        BL    - divisor (10 for decimal output, 16 for hex)
  311. ;-----------------------------------------------------------------------------
  312. bin2asc       proc near
  313.               push ax                       ;save value to output
  314.               xor cx,cx                     ;zero digit counter
  315.               xor ah,ah                     ;byte to word in AX
  316. bin1:         div bl                        ;divide AX by 10 or 16
  317.               push ax                       ;save AH (remainder)
  318.               inc cx                        ;increment counter
  319.               xor ah,ah                     ;byte to word (quotient)
  320.               or al,al                      ;was the quotient zero?
  321.               jne bin1                      ;no, then go back for more
  322. bin2:         pop ax                        ;get digit to print next
  323.               mov al,ah                     ;put it in AL
  324.               or al,48                      ;convert binary to ASCII
  325.               cmp al,'9'                    ;alphanumeric hex digit?
  326.               jna bin3                      ;no, then jump ahead
  327.               add al,7                      ;yes, then more conversion needed
  328. bin3:         mov ah,text_attr              ;set text attribute for write
  329.               call output_char              ;print the digit
  330.               inc dl                        ;advance cursor
  331.               loop bin2                     ;loop until done
  332.               pop ax                        ;restore value of AX
  333.               ret
  334. bin2asc       endp
  335. ;
  336. ;-----------------------------------------------------------------------------
  337. ;OUTPUT_CHAR writes the designated character directly to video memory.
  338. ;Entry:  DH,DL - row, column
  339. ;        AH,AL - attribute, character
  340. ;-----------------------------------------------------------------------------
  341. output_char   proc near
  342.               push dx                       ;save DX and AX
  343.               push ax
  344.               mov bl,video_page             ;get page in BX
  345.               xor bh,bh
  346.               call video_offset             ;calculate address to write to
  347.               cmp adapter,0                 ;is this a CGA?
  348.               jne output3                   ;no, then skip wait loop
  349.               mov dx,3DAh                   ;get CGA Status Register address
  350. output1:      in al,dx                      ;wait until horiz. retrace done
  351.               test al,1
  352.               jne output1
  353.               cli                           ;suspend interrupts during write
  354. output2:      in al,dx                      ;wait for next horizontal retrace
  355.               test al,1
  356.               je output2
  357. output3:      pop ax                        ;get character and attribute
  358.               stosw                         ;write them to video memory
  359.               sti                           ;enable interrupts
  360.               pop dx                        ;restore DX
  361.               ret
  362. output_char   endp
  363. ;
  364. ;-----------------------------------------------------------------------------
  365. ;FILL_WINDOW writes the text of the ASCII table to the window.
  366. ;-----------------------------------------------------------------------------
  367. fill_window   proc near
  368.               mov dh,window_row             ;set DH for first text row
  369.               add dh,2
  370.               mov al,start_value            ;get first table value in AL
  371.               mov cx,16                     ;16 lines to fill
  372. fill1:        push cx                       ;save line counter
  373.               mov dl,window_column          ;specify starting column
  374.               add dl,2
  375.               call write_line               ;write first half of the line
  376.               add dl,5                      ;advance cursor for next half
  377.               add al,16                     ;adjust AL for next half
  378.               call write_line               ;write second half
  379.               sub al,15                     ;set AL for start of next line
  380.               inc dh                        ;set cursor for next row
  381.               pop cx                        ;retrieve line counter
  382.               loop fill1                    ;loop until table full
  383.               ret
  384. fill_window   endp
  385. ;
  386. ;-----------------------------------------------------------------------------
  387. ;WRITE_LINE outputs one ASCII character and its decimal and hex equivalents.
  388. ;Entry:  AL    - ASCII code for character to output
  389. ;        DH,DL - row, column to start writing at
  390. ;-----------------------------------------------------------------------------
  391. write_line    proc near
  392.               mov es,video_segment          ;set ES to video for writing
  393.               cmp al,100                    ;advance cursor if AL < 100
  394.               jae write1
  395.               inc dl
  396.               cmp al,10                     ;advance again if AL < 10
  397.               jae write1
  398.               inc dl
  399. write1:       mov bl,10                     ;set BL for decimal output
  400.               call bin2asc                  ;output decimal text
  401.               add dl,2                      ;set cursor to next field
  402.               cmp al,10h                    ;advance cursor if AL < 10h
  403.               jae write2
  404.               inc dl
  405. write2:       mov bl,16                     ;set BL for hex output
  406.               call bin2asc                  ;output hexadecimal text
  407.               add dl,2                      ;goto next field
  408.               mov ah,text_attr              ;set text attribute
  409.               call output_char              ;print the character
  410.               ret
  411. write_line    endp
  412. ;
  413. ;-----------------------------------------------------------------------------
  414. ;OPEN_WINDOW draws the window border onto the screen.  Character/attribute
  415. ;pairs are sent directly to video memory for fast display speed.
  416. ;-----------------------------------------------------------------------------
  417. open_window   proc near
  418.               mov dh,window_row             ;get coordinates of window corner
  419.               mov dl,window_column
  420.               mov es,video_segment          ;point ES to video buffer
  421.               cld                           ;clear DF for string operations
  422.               mov bl,video_page             ;get video page in BX
  423.               xor bh,bh
  424.               call video_offset             ;calculate starting address
  425. ;
  426. ;Write the top line of the window border to video.
  427. ;
  428.               mov al,218                    ;start with upper left corner
  429.               mov ah,border_attr            ;set attribute
  430.               stosw
  431.               mov cx,28                     ;do the next 28 characters
  432.               mov al,196
  433.               rep stosw
  434.               mov al,191                    ;do upper right corner
  435.               stosw
  436. ;
  437. ;Do the window header line.
  438. ;
  439.               add di,100                    ;set DI for new line
  440.               mov al,179                    ;left window border character
  441.               stosw                         ;write it
  442.               lea si,header_text            ;point SI to text of line
  443.               mov cx,28                     ;28 characters to write
  444.               mov ah,header_attr            ;use header attribute for these
  445. open1:        lodsb                         ;get the text character
  446.               stosw                         ;write char/attr pair to video
  447.               loop open1                    ;repeat for all 28
  448.               mov ah,border_attr            ;do rightmost column
  449.               mov al,179
  450.               stosw
  451. ;
  452. ;Now write the next 16 lines (no text) to the display.
  453. ;
  454.               add di,100                    ;set DI for new line
  455.               mov cx,16                     ;16 lines to do
  456. open2:        push cx                       ;save line counter
  457.               mov al,179                    ;do leftmost column
  458.               mov ah,border_attr
  459.               stosw
  460.               mov al,32                     ;do next 28 columns (blank)
  461.               mov ah,text_attr
  462.               mov cx,28
  463.               rep stosw
  464.               mov al,179                    ;do rightmost column
  465.               mov ah,border_attr
  466.               stosw
  467.               add di,100                    ;adjust DI for next line
  468.               pop cx                        ;retrieve counter
  469.               loop open2                    ;loop until finished
  470. ;
  471. ;Finish things up by writing the last line.
  472. ;
  473.               mov al,192                    ;lower left corner
  474.               stosw
  475.               mov cx,28                     ;next 28 characters
  476.               mov al,196
  477.               rep stosw
  478.               mov al,217                    ;lower right corner
  479.               stosw
  480.               ret
  481. open_window   endp
  482. ;
  483. ;-----------------------------------------------------------------------------
  484. ;SCROLL_UP scrolls the window contents up one line.
  485. ;-----------------------------------------------------------------------------
  486. scroll_up     proc near
  487.               cmp start_value,224           ;can we scroll more?
  488.               je scrup1                     ;no, then do nothing
  489.               mov ah,6                      ;use INT 10h to scroll up
  490.               mov al,1                      ;one line
  491.               call define_window            ;set CX and DX for scroll
  492.               mov bh,text_attr              ;define attribute
  493.               int 10h                       ;scroll up
  494.               inc start_value               ;adjust starting value
  495.               mov al,start_value            ;calculate new value to write
  496.               add al,15
  497.               mov dh,window_row             ;determine row to be written to
  498.               add dh,17
  499.               mov dl,window_column          ;set starting column
  500.               add dl,2
  501.               call write_line               ;write the first half of new line
  502.               add al,16                     ;adjust AL
  503.               add dl,5                      ;move cursor to next half of line
  504.               call write_line               ;write second half
  505. scrup1:       ret
  506. scroll_up     endp
  507. ;
  508. ;-----------------------------------------------------------------------------
  509. ;SCROLL_DOWN scrolls the window contents down one line.
  510. ;-----------------------------------------------------------------------------
  511. scroll_down   proc near
  512.               cmp start_value,0             ;can we scroll more?
  513.               je scrdn1                     ;no, then do nothing
  514.               mov ah,7                      ;use INT 10h to scroll down
  515.               mov al,1                      ;one line
  516.               call define_window            ;set CX and DX
  517.               mov bh,text_attr              ;set attribute
  518.               int 10h                       ;do the scroll
  519.               dec start_value               ;adjust starting value
  520.               mov al,start_value            ;new value to write
  521.               mov dh,window_row             ;determine row for write
  522.               add dh,2
  523.               mov dl,window_column          ;set starting column
  524.               add dl,2
  525.               call write_line               ;write new line at top
  526.               add al,16                     ;adjust AL
  527.               add dl,5                      ;move cursor to second half
  528.               call write_line               ;write second half of line
  529. scrdn1:       ret
  530. scroll_down   endp
  531. ;
  532. ;-----------------------------------------------------------------------------
  533. ;LAST_WINDOW_PAGE pages the window back one page.
  534. ;-----------------------------------------------------------------------------
  535. last_window_page proc near
  536.               cmp start_value,0             ;can we go back more?
  537.               je last3                      ;no, then do nothing
  538.               cmp start_value,31            ;starting value > 31?
  539.               ja last1                      ;yes, then jump
  540.               mov start_value,0             ;no, then zero value
  541.               jmp last2                     ;skip next line
  542. last1:        sub start_value,32            ;adjust START_VALUE
  543. last2:        call clear_window             ;clear interior of window
  544.               call fill_window              ;write the new table
  545. last3:        ret
  546. last_window_page endp
  547. ;
  548. ;-----------------------------------------------------------------------------
  549. ;NEXT_WINDOW_PAGE pages the window forward one page.
  550. ;-----------------------------------------------------------------------------
  551. next_window_page proc near
  552.               cmp start_value,224           ;can we go forward more?
  553.               je next3                      ;no, then do nothing
  554.               cmp start_value,193           ;starting value <193?
  555.               jb next1                      ;yes, then jump
  556.               mov start_value,224           ;set START_VALUE to maximum
  557.               jmp next2                     ;skip next line
  558. next1:        add start_value,32            ;adjust for next page
  559. next2:        call clear_window             ;clear window
  560.               call fill_window              ;write new text page
  561. next3:        ret
  562. next_window_page endp
  563. ;
  564. ;-----------------------------------------------------------------------------
  565. ;FIRST_WINDOW_PAGE flips the window contents to the first page.
  566. ;-----------------------------------------------------------------------------
  567. first_window_page proc near
  568.               cmp start_value,0             ;already at beginning?
  569.               je first1                     ;yes, then do nothing
  570.               mov start_value,0             ;zero starting value
  571.               call clear_window             ;clear window
  572.               call fill_window              ;write text to window
  573. first1:       ret
  574. first_window_page endp
  575. ;
  576. ;-----------------------------------------------------------------------------
  577. ;END_WINDOW_PAGE flips the window contents to the final page.
  578. ;-----------------------------------------------------------------------------
  579. end_window_page proc near
  580.               cmp start_value,224           ;already at end?
  581.               je end1                       ;yes, then do nothing
  582.               mov start_value,224           ;set START_VALUE to maximum
  583.               call clear_window             ;clear window
  584.               call fill_window              ;write window text
  585. end1:         ret
  586. end_window_page endp
  587. ;
  588. ;-----------------------------------------------------------------------------
  589. ;CLEAR_WINDOW clears the interior of the window.
  590. ;-----------------------------------------------------------------------------
  591. clear_window  proc near
  592.               mov ah,6                      ;use INT 10h to clear window
  593.               mov al,0                      ;code for blank function
  594.               call define_window            ;set CX and DX
  595.               mov bh,text_attr              ;set attribute for cleared area
  596.               int 10h                       ;perform the clear
  597.               ret
  598. clear_window  endp
  599. ;
  600. ;-----------------------------------------------------------------------------
  601. ;DEFINE_WINDOW sets the values of CX and DX for call to BIOS scroll functions.
  602. ;-----------------------------------------------------------------------------
  603. define_window proc near
  604.               mov ch,window_row             ;define upper left corner in CX
  605.               add ch,2
  606.               mov cl,window_column
  607.               add cl,2
  608.               mov dx,cx                     ;define lower right corner in DX
  609.               add dh,15
  610.               add dl,25
  611.               ret
  612. define_window endp
  613. ;
  614. ;-----------------------------------------------------------------------------
  615. ;INITIALIZE performs a variety of tasks to set the stage for the resident part
  616. ;of the program.
  617. ;-----------------------------------------------------------------------------
  618. initialize    proc near
  619. ;
  620. ;See if the display adapter is an EGA by looking for the EGA BIOS signature.
  621. ;
  622.               mov ax,0C000h                 ;set ES to EGA BIOS segment
  623.               mov es,ax
  624.               mov di,1Eh                    ;point DI to signature location
  625.               lea si,ibm_signature          ;point SI to 'IBM' text
  626.               mov cx,3                      ;three bytes to compare
  627.               cld                           ;clear DF
  628.               repe cmpsb                    ;check three bytes
  629.               je init1                      ;jump if EGA signature found
  630. ;
  631. ;The display adapter is not an EGA.  Determine whether it's a CGA or an MDA.
  632. ;
  633.               mov adapter,0                 ;zero ADAPTER for CGA
  634.               mov ah,15                     ;get video mode
  635.               int 10h
  636.               cmp al,7                      ;is it mode 7?
  637.               jne init1                     ;no, then it's a CGA - jump
  638.               inc adapter                   ;yes, it's an MDA - set ADAPTER
  639. ;
  640. ;If this is a monochrome system, modify color-dependent values accordingly.
  641. ;
  642. init1:        cmp al,7                      ;is current video mode 7?
  643.               je init2                      ;yes, then branch
  644.               cmp al,15                     ;is current video mode 15?
  645.               jne init3                     ;no, then skip modification code
  646. init2:        sub video_segment,800h        ;set VIDEO_SEGMENT for monochrome
  647.               mov border_attr,70h           ;change attributes for monochrome
  648.               mov text_attr,07h
  649.               mov header_attr,07h
  650. ;
  651. ;Reset the cursor to scan lines 6 and 7 (color) or 12 and 13 (monochrome).
  652. ;
  653. init3:        mov cx,0C0Dh                  ;monochrome cursor type
  654.               cmp al,7                      ;video mode 7?
  655.               je init4                      ;yes, then jump
  656.               cmp al,15                     ;video mode 15?
  657.               je init4                      ;yes, then jump
  658.               mov cx,0607h                  ;scan lines 6 and 7 for color
  659. init4:        mov ah,1                      ;set cursor type
  660.               int 10h
  661. ;
  662. ;Now save the old interrupt 9 vector and replace it with one pointing to the
  663. ;code that we will leave behind in memory.
  664. ;
  665.               mov ah,35h                    ;get current interrupt 9 vector
  666.               mov al,9
  667.               int 21h
  668.               mov old_keyboard_int,bx       ;save vector offset
  669.               mov old_keyboard_int[2],es    ;save vector segment
  670.               mov ah,25h                    ;set new vector
  671.               mov al,9
  672.               lea dx,ascview                ;point it to body of program
  673.               int 21h
  674. ;
  675. ;Exit thru INT 27h and reserve enough room beyond the actual code to store the
  676. ;contents of the area of screen that underlies the pop-up window.
  677. ;
  678.               mov dx,offset initialize+1140 ;reserve space for code and buffer
  679.               int 27h                       ;terminate-but-stay-resident
  680. initialize    endp
  681. ;
  682. code          ends
  683.               end begin
  684.