home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS 1992 September / Simtel20_Sept92.cdr / msdos / screen / screen.asm < prev    next >
Assembly Source File  |  1992-09-08  |  15KB  |  493 lines

  1. page    64,132
  2. title    screen - IBM Display Enhancement  Dec 1983
  3. .radix 10
  4. ;***************************************************************
  5. ; Typed in by Greg Glass - gjg@cmu-cs-cad from Byte - Nov. 1983
  6. ; NOTE: if you have a color card this will shift over to it
  7. ;    (even if the monitor is turned off)
  8. ;      hit Alt F7 to switch to the Mono monitor.
  9. ;   To build this program:
  10. ;    1>  masm screen;    /* assemble the code */
  11. ;    2>  link screen;    /* link it - will get no stack seg. message */
  12. ;    3>  exe2bin screen      /* convert the format */
  13. ;    4>  rename screen.bin screen.com   /* make the new format executable*/
  14. ;    5>  del screen.exe    /* don't need this anymore */
  15. ;
  16. ;  To use program:  just run it or place in autoexec.bat
  17. ;
  18. ;  COMMANDS:
  19. ;    <alt>F1  - increment the text color
  20. ;    <alt>F3  - increment the background color
  21. ;    <alt>F5 -  toggle modes co80/co40
  22. ;    <alt>F7 -  toggle between color and mono display
  23. ;    <alt>F9 -  redraw display - reset colors
  24. ;***************************************************************
  25.  
  26. ;***************************************************************
  27. ;
  28. ;  Define interrupt vectors for both keyboard interrupt 16H and
  29. ;    screen interrupt 10H.  Both in segment 0.
  30. ;
  31. ;***************************************************************
  32.  
  33. keyvect    segment    at 0        ; define keyboard interrupt vector
  34.     org    16h*4
  35. KEYINT    label    dword
  36. keyvect    ends
  37.  
  38. scrvect    segment    at 0        ; define screen interrupt vector
  39.     org    10h*4
  40. SCRINT    label    dword
  41. scrvect    ends
  42.  
  43. ;***************************************************************
  44. ;
  45. ;    define constants
  46. ;
  47. ;***************************************************************
  48.  
  49. bw_val       equ    07h        ; standard b&w attibute sent to monitor
  50. equip_flag equ    410h        ; area in RAM that contains equipment status
  51. chk_mode   equ    15        ; screen interrupt function to check mode
  52. mono_mode  equ    7        ; screen mode of 7 indicates monochrome
  53. color_adpt equ    3        ;modes from 0 to 3 are non-graphics color
  54.  
  55. ;***************************************************************
  56. ;
  57. ;    start code area
  58. ;
  59. ;***************************************************************
  60.  
  61. code    segment para
  62.     assume    cs:code
  63.     org    100h        ; start code offset 100h from starting segment
  64.                 ; (this leaves room for DOS's work areas)
  65.  
  66. KEY    proc    far
  67. START:
  68.     ; Initialization code...used only once, on system startup
  69.  
  70.     jmp    init_code    ; call initialization routine
  71. even
  72.     validchk db 'FCP!'    ; used by INSTALL to check for valid SCREEN
  73.                 ; program
  74.  
  75. ;***************************************************************
  76. ;
  77. ;    Define storage areas and data structures
  78. ;
  79. ;***************************************************************
  80.  
  81.     ; define keystroke scan codes for the five SCREEN functions
  82.  
  83. fore_inc  dw    6800h        ; foreground increment
  84. back_inc  dw    6a00h        ; background increment
  85. c80_40    dw    6c00h        ; 80x25 to 40x25 flip-flop key
  86. col_mon   dw    6e00h        ; color/mono flip-flop key
  87. repaint   dw    7000h        ; repaint screen using current mode
  88.  
  89. cur_mode  dw    col80_area    ; Initialize starting mode
  90. mono_set  dw    mono_area    ; pointer to monochrome area
  91. color_set dw    col80_area    ; pointer to "active" color area
  92.  
  93. scrn_attr db    70h        ; current screen attribute
  94. scrn_mode db    255        ; saves current screen mode
  95.  
  96.     ; define structure used to contain information about 40 and 80
  97.     ; column color modes as well as monochrome mode.
  98.  
  99. s    struc
  100.     corner    dw    0    ; defines COL/ROW count of characters for mon
  101.     bf    dw    0    ; Colors of fore and back
  102.     equip    dw    0    ; equipment settings
  103.     mode    dw    0    ; AX value for setting mode of monitor
  104. s    ends
  105.  
  106.     ; Now, set up three screen structures with default conditions
  107.  
  108. col80_area    s    <5019h,0107h,20h,3>    ; 80x25, white FORE blue BACK
  109.  
  110. col40_area    s    <2819h,0107h,10h,1>    ; 40x25, Brown FORE black BACK
  111.  
  112. mono_area    s    <5019h,0007h,30h,7>    ; monochrome, reverse video
  113.  
  114. ;NOTE:    The standard BIOS ROM KEYBOARD interrupt routine is
  115. ;    executed as a subroutine ( using CALL DWORD PTR) if
  116. ;    the interrupt was invoked to return a keystroke.  Any 
  117. ;    other execution KEYBOARD_IO can be called as a simple
  118. ;    inline FAR JMP instruction.  NOTE: the CALL instruction
  119. ;    (see just after INT_LOOP label below) uses the 
  120. ;    address stored here at KEY_CALL to KEYBOARD_IO.
  121.  
  122. KEY_CALL :
  123.     db    0eah        ; far JMP address to KEYBOARD interrupt
  124.     dw    0,0        ;
  125.  
  126. ;***************************************************************
  127. ;
  128. ;    procedure KEY_RTNE - Intercepts keyboard interrupt and
  129. ;    determines if the keystroke is one of the five SCREEN ones.
  130. ;
  131. ;***************************************************************
  132.  
  133. KEY_RTNE:
  134.     assume    ds:code
  135.     sti            ; turn on interrupts
  136.     cmp    ah,0        ; call as subroutine if keyfetch
  137.     jne    KEY_CALL    ; jump to KEYBOARD_IO if not
  138.     push    ds        ; save ds and bx from destruction
  139.     push    bx        ;
  140.     push    cx
  141.     push    dx
  142.     push    es
  143.     push    di
  144.     mov    bx,cs        ; move cs segment into ds
  145.     mov    ds,bx        ;
  146.  
  147. INT_LOOP:
  148.     pushf            ; IBM keyboard proc exports interrupt call
  149.     mov    bx,offset KEY_CALL + 1    ;Get address to ROM code for keyboard
  150.     call    dword ptr[bx]    ; call keyboard routine
  151.     mov    bx, cur_mode    ; get current mode address
  152.     cmp    ax, col_mon    ; see if COLOR<->MONO flip-flop key
  153.     jne    TEST_FORE    ; exit if not
  154.     ; otherwise, flip-flop screen mode
  155.     cmp    bx, mono_set    ; are we looking at monochrome?
  156.     je    set_color    ; swap in color if yes
  157.     cmp    mono_set,0    ; see if monochrome monitor enabled
  158.     je    next_key    ; ignore command if not
  159.     mov    bx,mono_set    ; otherwise set up monochrome
  160.     jmp    short DO_CHG    ;
  161.  
  162. SET_COLOR:
  163.     cmp    color_set,0    ; see if COLOR monitor enabled
  164.     je    NEXT_KEY    ; skip if not
  165.     mov    bx,color_set    ; set up for color
  166.  
  167. DO_CHG:
  168.     call    SCREEN_CHG    ; implement screen change
  169.  
  170. NEXT_KEY:
  171.     mov    ah,0        ; set up to fetch keystroke
  172.     jmp    INT_LOOP    ; fetch next key input
  173.  
  174. TEST_FORE:
  175.     push    ax        ; save registers.
  176.     push    bx        ; see if in graphics mode
  177.     mov    ah,chk_mode    ;
  178.     int    10h        ;
  179.     pop    bx        ; restore bx register
  180.     cmp    al,color_adpt    ; if between 0 and 3, not graphics mode
  181.     jle    NOT_GRAF    ;
  182.     cmp    al,mono_mode    ; monochrome mode
  183.     jge    NOT_GRAF    ; restore stack
  184.     pop    ax        ; if color-graphics mode, do not change
  185.     jmp    DONE        ; modes
  186.  
  187. NOT_GRAF:
  188.     pop    ax        ; restore ax
  189.     cmp    ax,fore_inc    ; is this key to increment FORE ?
  190.     jne    TEST_BACK    ; skip if not
  191.     cmp    bx,color_set    ; see if currently using color
  192.     jne    BW_FLOP        ; if not, go deal with B & W
  193.     mov    ax,[bx].bf    ; gets BACK in al, FORE in ah
  194.  
  195. EQ_FORE:
  196.     inc    al        ; increment FOREGROUND color
  197.     and    al,7        ; keep it within bounds (chg. for more colors)
  198.     cmp    al,ah        ; see if same as background
  199.     je    EQ_FORE        ; increment againt if yes
  200.     mov    [bx].bf,ax    ; save back to structure
  201.     jmp    DO_CHG        ; redraw display
  202.  
  203. TEST_BACK:
  204.     cmp    ax,back_inc    ; is this key to increment BACK?
  205.     jne    TEST_REPAINT    ; skip if not
  206.     cmp    bx,color_set    ; see if currently using color
  207.     jne    BW_FLOP        ; if not, go deal with B&W
  208.     mov    ax,[bx].bf    ; gets BACK in al, FORE in ah
  209.  
  210. EQ_BACK:
  211.     inc    ah        ; increment background color
  212.     and    ah,7        ; keep in bounds
  213.     cmp    ah,al        ; see if same as foreground
  214.     je    EQ_BACK        ; increment again if yes
  215.     mov    [bx].bf,ax    ; save back to structure
  216.     jmp    DO_CHG        ; redraw the screen
  217.  
  218. BW_FLOP:        ; flip-flop B&W screen
  219.     mov    ax,[bx].bf    ; BACK in ah, FORE in al
  220.     xchg    ah,al        ; swap
  221.     mov    [bx].bf,ax    ; save back to structure
  222.     jmp    DO_CHG        ; redraw the screen
  223.  
  224. TEST_REPAINT:
  225.     cmp    ax,repaint    ; is this the key to redraw the screen ?
  226.     je    DO_CHG        ; if yes then repaint
  227.  
  228. TEST_80_40:
  229.     cmp    ax,c80_40    ; is this the key to flop 80 / 40 ?
  230.     jne    DONE        ; exit if not
  231.     cmp    bx,offset col40_area    ; is current pointer area 40x25 ?
  232.     jne    TST80        ; skip if not
  233.     mov    bx,offset col80_area    ; otherwise flip to 80x25
  234.     jmp    short SAVE_COL    ; save to color_set
  235.  
  236. TST80:
  237.     cmp    bx,offset col80_area    ; is current 80x25 color ?
  238.     jne    NEXT_KEY        ; ignore key if not
  239.     mov    bx,offset col40_area    ;
  240.  
  241. SAVE_COL:
  242.     mov    color_set,bx    ; sat to color_set
  243.     jmp    SET_COLOR    ; implement
  244.  
  245. DONE:
  246.     pop    di
  247.     pop    es
  248.     pop    dx
  249.     pop    cx
  250.     pop    bx
  251.     pop    ds
  252.     iret            ; return from interrupt
  253.  
  254. KEY endp        ; done with main routine !
  255.  
  256. ;***************************************************************
  257. ;
  258. ;    SCREEN_CHG - Changes current monitor screen mode
  259. ;
  260. ;      Inputs: bx points to current monitor structure
  261. ;
  262. ;***************************************************************
  263.  
  264. SCREEN_CHG    proc    near
  265.     mov    ax,0        ; get segment address to equip_flag
  266.     mov    es,ax        ;   in RAM memory
  267.     mov    ax,es:equip_flag ; get set of equip flag
  268.     and    al,0CFh        ; get rid of current monitor flag
  269.     or    ax,[bx].equip    ; set up new monitor flag
  270.     mov    es:equip_flag,ax ; save back in RAM
  271.     mov    cur_mode,bx    ; indicate new mode
  272.  
  273.     ;  now, set up attribute for background and foreground
  274.  
  275.     mov    dx,[bx].bf    ; get both FORE and BACK in dx
  276.     mov    cl,4        ; shift count
  277.     shl    dh,cl        ; shift BACK into upper nibble
  278.     or    dh,dl        ; move FORE into lower nibble
  279.     mov    scrn_attr,dh    ; save result
  280.  
  281.     ;  see if we need to reset monitor (switching to new monitor?)
  282.  
  283.     mov    ax,[bx].mode    ; get mode
  284.     cmp    al,scrn_mode    ; compare with current mode
  285.     je    SET_ATTR    ; skip if same
  286.     mov    scrn_mode,al    ; otherwise, save current mode
  287.     int    10h        ; and reset to new monitor
  288.  
  289. SET_ATTR:    ; change attributes of current screen
  290.     call    CH_ATTR        ; changes attributes
  291.     ret
  292.  
  293. SCREEN_CHG    endp
  294.  
  295. ;***************************************************************
  296. ;
  297. ;    CH_ATTR - repaints acctive screen so that every character on
  298. ;        current screen is displayed with the new attributes
  299. ;
  300. ;    Inputs: bx points to current monitor structure
  301. ;
  302. ;***************************************************************
  303.  
  304. CH_ATTR    proc    near
  305.     ; see if we need to draw in border for color mode
  306.     cmp    bx,offset mono_set    ; in color?
  307.     je    NO_BORDER        ; do not worry about border if not
  308.     push    ax            ; save registers
  309.     push    bx            ;
  310.     mov    bx,[bx].bf        ; get background color in bx
  311.     mov    bl,bh            ;
  312.     mov    bh,0            ; select border color
  313.     mov    ah,11            ; interface to set color palette
  314.     int    10h
  315.     pop    bx            ; restore registers
  316.     pop    ax
  317.  
  318. NO_BORDER:
  319.     mov    ax,[bx].corner        ; get COL and ROW for current
  320.     mov    cornr,ax        ; save in temporary
  321.     mov    ah,chk_mode        ; get page number
  322.     int    10h            ;
  323.     ; bh contains active page
  324.     mov    ah,3            ; save current cursor posn
  325.     int    10h
  326.     push    dx            ; save position in stack
  327.     xor    dx,dx            ; load dx with 0
  328.     mov    cx,1            ; set up replication count
  329.     mov    bl,scrn_attr        ; get current attribute
  330.  
  331. REP_ATTR:
  332.     mov    ah,2            ; set cursor position
  333.     int    10h
  334.     mov    ah,8            ; read next character
  335.     int    10h
  336.     ; ah contains current character attribute
  337.     and    ah,88h            ; get intensity bit
  338.     and     bl,77h            ; make sore attribute intensity off
  339.     or    bl,ah            ; combine to get current attribute
  340.     mov    ah,9            ; write out char with new attribute
  341.     int    10h            ;
  342.     inc    dl            ;
  343.     cmp    dl,tcol            ; are we done with this column?
  344.     jle    REP_ATTR
  345.     xor    dl,dl            ; otherwise zero out DL
  346.     inc    dh            ; move to next row
  347.     cmp    dh,trow            ; done with screen ?
  348.     jle    REP_ATTR        ; loop until done
  349.  
  350.     pop    dx            ; restore original cursor position
  351.     mov    ah,2
  352.     int    10h
  353.     ret
  354.  
  355.     cornr    label    word
  356.     trow    db    0    ; temporary store for ROW
  357.     tcol    db    0    ; temp store for COL
  358.  
  359. CH_ATTR    endp
  360.  
  361. ;***************************************************************
  362. ;
  363. ;    SCR_RTNE - Replaces SCREEN interrupt so that it can intercept
  364. ;        B&W character writes and change attributes
  365. ;
  366. ;***************************************************************
  367.  
  368. SCR_RTNE proc    near
  369.     assume    ds: code
  370.     sti
  371.     push    ds        ; save data segment register
  372.     push    cs        ; move CS segment into DS
  373.     pop    ds        ;     this is a funny way to do that (gjg)
  374.     cmp    ah,6        ; Spot SCROLL UP and SCROLL DOWN calls
  375.     jl    NORMAL_SCR    ;
  376.     cmp    ah,6
  377.     jg    NOT_SCROLL    ;
  378.  
  379. SCROLL:
  380.     call    GET_CH        ; for scrolling, update attribute
  381.     jmp    NORMAL_SCR    ; now, execute scroll
  382.  
  383. NOT_SCROLL:
  384.     cmp    ah,9        ; check for "WRITE ATTRIBUTE/CHAR" cmd
  385.     jne    NORMAL_SCR    ; send out any other command as normal
  386.     xchg    bh,bl        ; get attribute for command
  387.     call    GET_CH        ; update attribute for command
  388.     xchg    bh,bl        ; move attribute back to bh for cmd
  389.  
  390. NORMAL_SCR:
  391.     pop    ds        ; restore ds segment register
  392.     ;
  393.     ; NOTE:    We are now ready to invoke the BIOS screen interrupt.
  394.     ;    Since the ROM code includes an IRET interrupt return call,
  395.     ;    all we need to do is to jump to the start of the ROM code
  396.     ;    and all will be well.  Since the initialization code set
  397.     ;    up the address to the screen interrupt code below, we can
  398.     ;    set up a forced jump to that address.
  399.  
  400. JMP_SCR:            ; Address to SCREEN interrupt
  401.     db    0EAh        ; force a FAR JMP but do not set up dest-
  402.     dw    0,0        ;   ination address at assembly time.
  403.                 ;   (INIT routine will set this address)
  404.  
  405. SCR_RTNE  endp
  406.  
  407.  
  408. ;***************************************************************
  409. ;
  410. ;    GET_CH - subroutine replaces B&W character with current replacement
  411. ;            attributes and allows for intensity bit setting
  412. ;
  413. ;        Inputs : bh contains attribute to be modified
  414. ;
  415. ;***************************************************************
  416.  
  417. GET_CH    proc    near
  418.     mov    savech,bh    ; save character
  419.     and    bh,77h        ; Remove intensity and blink bits
  420.     cmp    bh,bw_val    ; see if currently defined B&W value
  421.     mov    bh,savech    ; otherwise, modify to current attribute
  422.     jne    OUT        ; exit if not
  423.     and    bh,88h        ; get rid of B&W part
  424.     or    bh,scrn_attr    ; move in current attribute part
  425.  
  426. OUT:
  427.     ret            ; done
  428.  
  429.     savech    db    0    ; temporary character store
  430. GET_CH    endp
  431.  
  432. LASTONE:    ; all code after this label is freed to DOS use after
  433.         ; initialization of the program.
  434.  
  435. ;***************************************************************
  436. ;
  437. ;    INIT_CODE - Code to load and initialize the SCREEN program..
  438. ;        sets up DOS to keep all code before "LASTONE" label
  439. ;        safe from overlaying during system operation.
  440. ;
  441. ;***************************************************************
  442.  
  443. COPYRT:    db  'SCREEN  Version 1.20  Copyright 1983 Tim Field',13,10,'$'
  444.  
  445. INIT_CODE proc  near
  446.  
  447.     ; Initialize KEYBOARD intercept code
  448.  
  449.     assume    es:keyvect        ;'vectors' is interrupt segment 0
  450.     
  451.     mov    ax,keyvect        ; get address to interrupt vector
  452.     mov    es,ax            ; save in es
  453.     mov    ax,es:keyint        ; get address to interrupt
  454.     mov    bx,offset key_call+1    ; address to place to save vector
  455.     mov    [bx],ax            ; save interrupt address
  456.     mov    ax,es:keyint[2]        ; get interrupt segment for rtne
  457.     mov    [bx+2],ax        ; save it too
  458.     mov    es:keyint,offset key_rtne ; now replace with own address
  459.     mov    ax,cs            ; save segment in interrupt vector
  460.     mov    es:keyint[2],ax        ;
  461.  
  462.     ; initialize SCREEN intercept code
  463.     assume    es:scrvect        ;'vectors' is interrupt segment 0
  464.  
  465.     mov    ax,scrvect        ; get address to interrupt vector
  466.     mov    es,ax            ; save in es
  467.     mov    ax,es:scrint        ; get address to interrupt
  468.     mov    bx,offset jmp_scr+1    ; address to place to save vector
  469.     mov    [bx],ax            ; save interrupt address
  470.     mov    ax,es:scrint[2]        ; get interrupt segment for rtne
  471.     mov    [bx+2],ax        ; save it too
  472.     mov    es:scrint,offset scr_rtne ; now replace with own address
  473.     mov    ax,cs            ; save segment in interrupt vector
  474.     mov    es:scrint[2],ax        ;
  475.  
  476.     ; Initialize screen
  477.     mov    bx,cur_mode        ; set up initial mode
  478.     call    SCREEN_CHG        ; initialize
  479.  
  480.     ; Now print out acknowledgement to user monitor and exit
  481.  
  482.     mov    ax,cs            ; set up segment to routine
  483.     mov    ds,ax
  484.     mov    dx,offset copyrt    ; now print out copyright message
  485.     mov    ah,9            ; DOS function to print string
  486.     int    21h            ; execute function interrupt
  487.     mov    dx,offset lastone    ; save all code up to "LASTONE" label
  488.     int    27h            ; no return needed
  489.  
  490. INIT_CODE endp
  491. code ends
  492. end start
  493.