home *** CD-ROM | disk | FTP | other *** search
/ MS DOS Archives 1 / MS-DOS_Archives_Volume_One_Walnut_Creek.iso / msdos / graphics / int_70h.arc / INT70H.ASM < prev    next >
Assembly Source File  |  1988-12-07  |  27KB  |  758 lines

  1.                     PAGE 63, 132
  2.                     Title  Interupt support for the Hercules Graphics Card
  3.  
  4.  
  5. CSEG        SEGMENT
  6.             ORG  100H
  7.             ASSUME CS:CSEG, DS:CSEG, SS:CSEG
  8. START:      JMP  SET_UP
  9.  
  10. ;------------------------ routine ----------------------
  11. ROUTINE     PROC FAR
  12.             PUSHF
  13.             PUSH ES
  14.             PUSH DS
  15.             PUSH SI
  16.             PUSH DI
  17.             PUSH AX
  18.             PUSH BX
  19.             PUSH CX
  20.             PUSH DX
  21.             JMP  SKIP_DATA
  22.  
  23. ;   data section
  24.  
  25. Pos_X            DW  ?
  26. Pos_Y            DW  ?
  27. Pos_Err          DW  ?
  28.  
  29. Neg_X            DW  ?
  30. Neg_Y            DW  ?
  31. Neg_Err          DW  ?
  32.  
  33. Line_Err         DW  ?
  34.  
  35. LENGTH           DW  ?
  36. Point_Type       DB  ?
  37.  
  38. X1               DW  ?
  39. Y1               DW  ?
  40. X2               DW  ?
  41. Y2               DW  ?
  42. DeltaX           DW  ?
  43. DeltaY           DW  ?
  44. Ten              DB  0Ah
  45.  
  46. Function_Table   DW  8 DUP(0)
  47.  
  48. Active_page      DB  0
  49.  
  50. Segment_value    DW  ?
  51. Offset_Value     DW  ?
  52.  
  53.  
  54. ;
  55. ;++======================================================================++
  56. ;||                                                                      ||
  57. ;||               Draws the line given the present data                  ||
  58. ;||                                                                      ||
  59. ;++======================================================================++
  60. ;
  61. DrawIt   PROC Near
  62.          MOV  AX, 0B000h
  63.          MOV  BH, Active_page
  64.          CMP  BH, 0
  65.          JE   Pg_0d
  66.          MOV  AX, 0B800h
  67.  
  68.   Pg_0d: MOV  ES, AX
  69.  
  70.          MOV  AX, Y2              ; see which is larger. if Y1 is larger,
  71.          CMP  AX, Y1              ;   you have to swap the end points
  72.          JNL  No_Swap             ;   ( you always want to go up )
  73.  
  74.  
  75.          MOV  AX, Y1              ; put the first Y value into the AX register
  76.          MOV  BX, Y2              ; put the second Y value into the BX register
  77.          MOV  Y2, AX              ; put the first Y value into the second Y
  78.          MOV  Y1, BX              ; put the second Y value into the first Y
  79.  
  80.          MOV  AX, X1              ; same as above for the X values
  81.          MOV  BX, X2
  82.          MOV  X2, AX
  83.          MOV  X1, BX
  84.  
  85.  
  86. No_Swap: MOV  AX, X2              ; come up with the difference in X's
  87.          SUB  AX, X1
  88.          MOV  DeltaX, AX
  89.  
  90.          MOV  AX, Y2              ; come up with the difference in Y's
  91.          SUB  AX, Y1
  92.          MOV  DeltaY, AX
  93.          JNZ  Not_Horiz           ; if DeltaY is zero, the line is horizontal
  94.          JMP  Horiz
  95.  
  96. Not_Horiz:
  97.          CMP  AX, DeltaX          ; compare DeltaY to DeltaX
  98.          JNE  Not_Diag1           ; if they are equal, the slope is 1
  99.          JMP  Diag1
  100.  
  101. Not_Diag1:
  102.          XOR  AX, 0FFFFh          ; get negative DeltaY in AX
  103.          INC  AX
  104.          CMP  AX, DeltaX          ; compare negative DeltaY to DeltaX
  105.          JNE  Not_Diag2           ; if they are equal, the slope is -1
  106.          JMP  Diag2
  107.  
  108. Not_Diag2:
  109.          CMP  DeltaX, 0           ; compare DeltaX to zero
  110.          JNE  Not_Vert            ; if there is no difference in X's, it's vert
  111.          JMP  Vert
  112.  
  113. Not_Vert:
  114.          JL   Case_3_or_4         ; this line has a negative slope
  115.  
  116. Case_1_or_2:
  117.          XOR  AX, 0FFFFh          ; AX should still have -DeltaY
  118.          INC  AX                  ; so, make it positive
  119.          CMP  AX, DeltaX          ; compare this to DeltaX
  120.          JA   Case2               ; if DeltaY > DeltaX the goto Case 2
  121.  
  122.   Case1: MOV  DX, AX              ; store the negative error correction
  123.  
  124.          MOV  SI, DeltaX          ; the length of the line
  125.          SUB  AX, SI              ; Positive error = DeltaY - DeltaX
  126.          MOV  CX, AX              ; store it
  127.  
  128.          MOV  BX, X1              ; get the starting point
  129.          MOV  AX, Y1
  130.  
  131.          XOR  DI, DI              ; initialize the error register
  132.  
  133.  Plot_1: CALL Plot_pt
  134.          CMP  DI, 0               ; compare the error to zero
  135.          JL   Neg_err_1           ; if a negative error, jump pos err code
  136.          ADD  DI, CX              ; add pos error correction
  137.          INC  AX                  ; next point is "up" and to the right
  138.          INC  BX
  139.          JMP  Chk_1               ; jump neg err code
  140. Neg_err_1:
  141.          ADD  DI, DX              ; add neg error correction
  142.          INC  BX                  ; next point is to the right
  143.  
  144.   Chk_1: DEC  SI                  ; decrement counter
  145.          JNZ  Plot_1              ; check to see if you are done
  146.  
  147.          JMP  Plot_end_pts        ; go to where you will plot the end points
  148.  
  149.  
  150.  
  151.  
  152.   Case2: MOV  SI, AX              ; AX has DeltaX in it and that is the length
  153.          MOV  CX, DeltaX          ; get DeltaX for Pos err correction
  154.          SUB  AX, CX              ; DeltaY - DeltaX
  155.          MOV  DX, AX              ; store the Neg err correction
  156.  
  157.          XOR  CX, 0FFFFh          ; Pos err cor is -DeltaX
  158.          INC  CX
  159.  
  160.          MOV  BX, X1
  161.          MOV  AX, Y1
  162.  
  163.          XOR  DI, DI
  164.  
  165.  Plot_2: CALL Plot_pt
  166.          CMP  DI, 0               ; compare the error to zero
  167.          JL   Neg_err_2           ; if a negative error, jump pos err code
  168.          ADD  DI, CX              ; add pos error correction
  169.          INC  AX                  ; next point is "up" one point
  170.          JMP  Chk_2               ; jump neg err code
  171. Neg_err_2:
  172.          ADD  DI, DX              ; add neg error correction
  173.          INC  AX                  ; next point is "up" and to the right
  174.          INC  BX                  ;
  175.  
  176.   Chk_2: DEC  SI                  ; decrement counter
  177.          JNZ  Plot_2              ; check to see if you are done
  178.  
  179.          JMP  Plot_end_pts        ; go to where you will plot the end points
  180.  
  181.  
  182.  
  183.  
  184. Case_3_or_4:
  185.          MOV  AX, DeltaX          ; DeltaX is negative.  Invert it and add 1 for
  186.          XOR  AX, 0FFFFh          ;   2's compliment (leave DeltaX alone use AX)
  187.          INC  AX
  188.  
  189.  
  190.          CMP  AX, DeltaY          ; If DeltaY > DeltaX . . .
  191.          JB   Case4               ; this means that the slope is < -1
  192.  
  193.  
  194.   Case3: MOV  SI, AX              ; AX has DeltaX in it and that is the length
  195.          MOV  CX, DeltaY          ; get DeltaY for neg err correction
  196.          MOV  DX, CX              ; store it
  197.          SUB  CX, AX              ; calculate the pos err correction: Dy - Dx
  198.  
  199.          MOV  BX, X1              ; set initial values
  200.          MOV  AX, Y1
  201.  
  202.          XOR  DI, DI
  203.  
  204.  Plot_3: CALL Plot_pt
  205.          CMP  DI, 0               ; compare the error to zero
  206.          JL   Neg_err_3           ; if a negative error, jump pos err code
  207.          ADD  DI, CX              ; add pos error correction
  208.          INC  AX                  ; next point is "up" and to the left
  209.          DEC  BX
  210.          JMP  Chk_3               ; jump neg err code
  211. Neg_err_3:
  212.          ADD  DI, DX              ; add neg error correction
  213.          DEC  BX                  ; next point is "up" and to the left
  214.  
  215.   Chk_3: DEC  SI                  ; decrement counter
  216.          JNZ  Plot_3              ; check to see if you are done
  217.  
  218.          JMP  Plot_end_pts        ; go to where you will plot the end points
  219.  
  220.  
  221.  
  222.  
  223.  
  224.   Case4: MOV  SI, DeltaY          ; the length of the line
  225.          XOR  AX, 0FFFFh          ; AX had -DeltaX in it
  226.          INC  AX                  ; change it to DeltaX
  227.          MOV  CX, AX              ; set the pos err correction register ( +Dx )
  228.          ADD  AX, SI              ; calculate the neg err correction ( Dy + Dx )
  229.          MOV  DX, AX              ; store it
  230.  
  231.          MOV  BX, X1              ; set initial values
  232.          MOV  AX, Y1
  233.  
  234.          XOR  DI, DI
  235.  
  236.  Plot_4: CALL Plot_pt
  237.          CMP  DI, 0               ; compare the error to zero
  238.          JL   Neg_err_4           ; if a negative error, jump pos err code
  239.          ADD  DI, CX              ; add pos error correction
  240.          INC  AX                  ; next point is "up" one point
  241.          JMP  Chk_4               ; jump neg err code
  242. Neg_err_4:
  243.          ADD  DI, DX              ; add neg error correction
  244.          INC  AX                  ; next point is "up" and to the right
  245.          DEC  BX                  ;
  246.  
  247.   Chk_4: DEC  SI                  ; decrement counter
  248.          JNZ  Plot_4              ; check to see if you are done
  249.  
  250.          JMP  Plot_end_pts        ; go to where you will plot the end points
  251.  
  252.  
  253.  
  254.  
  255.  
  256.   Horiz: MOV  SI, DeltaX          ; set the length variable
  257.          MOV  BX, X1              ; set initial values
  258.          MOV  AX, Y1
  259.          CMP  SI, 0               ; check to see if the length var is neg
  260.          JG   Plot_H              ; if not, skip making it neg
  261.          XOR  SI, 0FFFFh          ; make SI ( = -DeltaX ) positive
  262.          INC  SI
  263.  
  264. Plot_H:  CALL Plot_pt             ; plot the point
  265.          INC  BX                  ; move one pixel right
  266.          DEC  SI                  ; decrement the counter
  267.          JNZ  Plot_H              ; if not done, go again
  268.  
  269.          JMP  Plot_end_pts        ; plot the end points of the line
  270.  
  271.  
  272.  
  273.    Vert: XOR  AX, 0FFFFh          ; AX already had -DeltaY,
  274.          INC  AX                  ;    make it DeltaY and
  275.          MOV  SI, AX              ; stick it into the length var
  276.          MOV  BX, X1              ; set initial values
  277.          MOV  AX, Y1
  278.  
  279. Plot_V:  CALL Plot_pt             ; plot the point
  280.          INC  AX                  ; move one pixel right
  281.          DEC  SI                  ; decrement the counter
  282.          JNZ  Plot_V              ; if not done, go again
  283.  
  284.          JMP  Plot_end_pts        ; plot the end points of the line
  285.  
  286.  
  287.  
  288.  
  289.   Diag1: MOV  SI, AX              ; AX still has DeltaY in it
  290.          MOV  BX, X1              ; the starting point
  291.          MOV  AX, Y1
  292.  
  293. Plot_D1: CALL Plot_pt
  294.          INC  AX                  ; next point is "up" and to the right
  295.          INC  BX
  296.          DEC  SI                  ; decrement the counter
  297.          JNZ  Plot_D1             ; if not done, go again
  298.  
  299.          JMP  Plot_end_pts
  300.  
  301.  
  302.  
  303.   Diag2: XOR  AX, 0FFFFh          ; AX has -DeltaY in it, change its sign
  304.          INC  AX
  305.          MOV  SI, AX              ; store it
  306.          MOV  BX, X1              ; initial point
  307.          MOV  AX, Y1
  308.  
  309. Plot_D2: CALL Plot_pt
  310.          INC  AX                  ; next point is "up" and to the left
  311.          DEC  BX
  312.          DEC  SI                  ; decrement counter
  313.          JNZ  Plot_D2             ; if not done, go again
  314.  
  315.  
  316.  
  317.  
  318. Plot_end_pts:
  319.          MOV  AX, Y1              ; set up for plotting the 1st end pt
  320.          MOV  BX, X1
  321.          CALL  Plot_Pt            ; plot 1st end pt
  322.  
  323.          MOV  AX, Y2              ; set up for plotting the 2nd end pt
  324.          MOV  BX, X2
  325.          CALL  Plot_Pt
  326.  
  327.          RET
  328.  
  329. DrawIt   ENDP                     ; done here
  330.  
  331.  
  332.  
  333.  
  334.  
  335.  
  336. ;
  337. ;++======================================================================++
  338. ;||                                                                      ||
  339. ;||          Plots a point at (BX,AX) if possible using Line_Type        ||
  340. ;||                                                                      ||
  341. ;++======================================================================++
  342. ;
  343.  Plot_Pt PROC Near
  344.          PUSH AX                  ; save the values of X & Y
  345.          PUSH BX
  346.          PUSH CX
  347.  
  348.          CALL AddrHGC             ; get the offset in the buffer
  349.          CMP  AX, 1000h           ; check for an error being returned from
  350.          JNE  No_Plot             ; if an error was detected, get out
  351.  
  352.          MOV  CH, 1               ; bit to or into the byte
  353.          SHL  CH, CL              ; move the bit into position
  354.          CMP  Point_Type, 2       ;
  355.          JB   Or_Point            ; if plotting a line...
  356.          JA   Del_Point           ; if erasing a line...
  357.  
  358.          XOR  ES:[BX], CH         ; xor the line
  359.          JMP  No_Plot
  360.  
  361. Or_Point:
  362.          OR   ES:[BX], CH         ; set the bit in the video buffer
  363.          JMP  No_Plot
  364.  
  365. Del_Point:
  366.          XOR  CH, 0FFFFh          ; reverse the bits
  367.          AND  ES:[BX], CH         ; erase the bit
  368.  
  369. No_Plot: POP  CX                  ; CX was altered, restore it
  370.          POP  BX                  ; get the X value back
  371.          POP  AX                  ; get the Y value back
  372.  
  373.          RET
  374.  
  375.  Plot_Pt ENDP
  376.  
  377.  
  378.  
  379.  
  380.  
  381. ;
  382. ;             in:  AX = y
  383. ;                  BX = x  <--------------------+
  384. ;                                               |
  385. ;            out:  AX = 1000 if value is OK or  x  if bad
  386. ;                  BX = byte offset in buffer
  387. ;                  CL = nuber of bits to shift left
  388. ;
  389.  
  390. AddrHGC  PROC Near
  391.  
  392.          CMP  AX, 0               ; is the y value too small?
  393.          JL   DONE                ;  if so, get out of the procedure
  394.          CMP  AX, 347             ; is the y value too large?
  395.          JG   DONE                ;  if so, get out of the procedure
  396.          CMP  BX, 0               ; is the x value too small?
  397.          JL   DONE                ;  if so, get out of the procedure
  398.          CMP  BX, 719             ; is the x value too large?
  399.          JG   DONE                ;  if not, get out
  400.  
  401.          MOV  CL, BL              ; CL = low order byte of x
  402.          SHR  AX, 1               ; AX = y / 2
  403.          RCR  BX, 1               ; BX = 8000h * (y&1) + x/2
  404.          SHR  AX, 1               ; AX = y / 4
  405.          RCR  BX, 1               ; BX = 4000h * (y&3) + x/4
  406.          SHR  BX, 1               ; BX = 2000h * (y&3) + x/8
  407.          MOV  AH, 90              ; bytes per line (decimal)
  408.          MUL  AH                  ; AX = bytes per line * (y/4)
  409.          ADD  BX, AX              ; BX = 2000h * (y&3) + x/8 +
  410.                                   ;      bytes per line * (y/4)
  411.  
  412.          AND  CL, 7               ; CL = x & 7
  413.          XOR  CL, 7               ; CL = number of bits to shift left
  414.          MOV  AX, 1000h           ; AH = unshifted bit mask
  415.  
  416. DONE:    RET
  417.  
  418. AddrHGC  ENDP
  419.  
  420.  
  421.  
  422.  
  423. ;
  424. ;++======================================================================++
  425. ;||                                                                      ||
  426. ;||                  Turns on the HERCULES graphics mode                 ||
  427. ;||                                                                      ||
  428. ;++======================================================================++
  429. ;
  430. Graphics_on  PROC Near
  431.  
  432.          MOV  AL, 02Ah            ; graphics mode (Page 0)
  433.  
  434.          AND  DH, 01              ; get visible page from the instruction byte
  435.          JZ   Pg_0g               ; if it is page 0, don't change now
  436.          MOV  AL, 0AAh            ; graphics mode (Page 1)
  437.  
  438.   Pg_0g: MOV  DX, 03B8h           ; HGC mode control reister
  439.          OUT  DX, AL              ; set to graphics mode
  440.  
  441.          MOV  AL, 03h             ; code to enable graphics
  442.          MOV  DX, 03BFh           ; HGC config switch register
  443.          OUT  DX, AL              ; enable graphics
  444.  
  445.          RET
  446.  
  447. Graphics_on  ENDP
  448.  
  449.  
  450.  
  451.  
  452. ;
  453. ;++======================================================================++
  454. ;||                                                                      ||
  455. ;||                  Turns off the HERCULES graphics mode                ||
  456. ;||                                                                      ||
  457. ;++======================================================================++
  458. ;
  459. Text_on    PROC Near
  460.  
  461.            MOV  AL, 028h            ; text mode (page 0)
  462.  
  463.            AND  DH, 01              ; get visible page from instruction byte
  464.            JZ   Pg_0                ; don't make it page 1 if page 0
  465.            MOV  AL, 0A8h            ; text mode (page 1)
  466.  
  467.      Pg_0: MOV  DX, 03B8h           ; HGC mode control reister
  468.            OUT  DX, AL              ; set to graphics mode
  469.  
  470.            MOV  AL, 03h             ; code to enable HGC
  471.            MOV  DX, 03BFh           ; HGC config switch register
  472.            OUT  DX, AL              ; enable graphics
  473.  
  474.            RET
  475.  
  476. Text_on    ENDP
  477.  
  478.  
  479.  
  480.  
  481. ;
  482. ;++======================================================================++
  483. ;||                                                                      ||
  484. ;||                   plot a point on the graphics page                  ||
  485. ;||                                                                      ||
  486. ;++======================================================================++
  487. ;
  488. Point    PROC near
  489.          AND  DH, 03                 ; mask off the type of point
  490.          MOV  Point_type, DH         ; set the variable
  491.  
  492.          MOV  CX, ES:[BX]            ; get the X value of the point
  493.          ADD  BX, 2                  ; move past the data word
  494.  
  495.          MOV  DX, ES:[BX]            ; get the Y value of the point
  496.          ADD  BX, 2                  ; move pointer past the data word
  497.  
  498.          MOV  Offset_value, BX       ; save current value
  499.  
  500.          MOV  AX, 0B000h             ; default graphics page ( page 0 )
  501.          MOV  BH, Active_page        ; get the number of the active page
  502.          CMP  BH, 0                  ; check to see if page 0 IS the active page
  503.          JE   Pg_0p                  ; if so, don't change it now
  504.          MOV  AX, 0B800h             ; if not, do change it to page 1
  505.  
  506.   Pg_0p: MOV  ES, AX                 ; plot_pt needs this
  507.  
  508.          MOV  BX, CX                 ; BX is where the procedure expects the
  509.                                      ;     X value of the point
  510.          MOV  AX, DX                 ; AX is where the procedure expects the
  511.                                      ;     Y value of the point
  512.  
  513.          CALL Plot_Pt                ; call the procedure to plot the point
  514.  
  515.          RET                         ; you're done here
  516. Point    ENDP
  517.  
  518.  
  519.  
  520.  
  521.  
  522. ;
  523. ;++======================================================================++
  524. ;||                                                                      ||
  525. ;||                    plot a line on the graphics page                  ||
  526. ;||                                                                      ||
  527. ;++======================================================================++
  528. ;
  529. Line     PROC near
  530.          MOV  CX, ES:[BX]            ; get the first end point's X value
  531.          MOV  X1, CX                 ; store the value
  532.          ADD  BX, 2                  ; mov the pointer past the word
  533.  
  534.          MOV  CX, ES:[BX]            ; get the 1st pt's Y value
  535.          MOV  Y1, CX                 ; store it
  536.          ADD  BX, 2
  537.  
  538.          MOV  CX, ES:[BX]            ; 2nd pt's X value
  539.          MOV  X2, CX
  540.          ADD  BX, 2
  541.  
  542.          MOV  CX, ES:[BX]            ; 2nd pt's Y value
  543.          MOV  Y2, CX
  544.          ADD  BX, 2
  545.  
  546.          MOV  Offset_value, BX       ; store current value of my IR
  547.  
  548.          AND  DH, 03                 ; get the line type
  549.          MOV  Point_type, DH         ;
  550.  
  551.          CALL Drawit                 ; call the procedure to draw the line
  552.  
  553.          RET                         ; you're done
  554. Line     ENDP
  555.  
  556.  
  557.  
  558.  
  559. ;
  560. ;++======================================================================++
  561. ;||                                                                      ||
  562. ;||                    set the active page variable                      ||
  563. ;||                    (needed by the plot_pt proc)                      ||
  564. ;||                                                                      ||
  565. ;++======================================================================++
  566. ;
  567. act_page PROC near
  568.          AND  DH, 01                 ; the only pages are 0 and 1 & the LSB
  569.          MOV  Active_page, DH        ;   gives the page
  570.          RET
  571. act_page ENDP
  572.  
  573.  
  574.  
  575.  
  576.  
  577. ;
  578. ;++======================================================================++
  579. ;||                                                                      ||
  580. ;||                  clears the given page (graphics)                    ||
  581. ;||                                                                      ||
  582. ;++======================================================================++
  583. ;
  584. Clear_page PROC near
  585.          MOV  AX, 0B000h          ; start of video buffer
  586.  
  587.          AND  DH, 01              ; get the active page number
  588.          JE   Clr_pg_1            ; if it is zero, you don't need to change AX
  589.          MOV  AX, 0B800h          ; second page
  590.  
  591. Clr_pg_1:MOV  ES, AX              ; set base value
  592.  
  593.          XOR  DI, DI              ; reset offset
  594.          XOR  AX, AX              ; value to put in buffer ( AX = 0 )
  595.          MOV  CX, 8000H           ; number of bytes to fill
  596.          REP  STOSW               ; repeat storing value in memory
  597.  
  598.          RET
  599. Clear_page ENDP
  600.  
  601.  
  602.  
  603. ;
  604. ;++======================================================================++
  605. ;||                                                                      ||
  606. ;||                  fills the given page (graphics)                     ||
  607. ;||                                                                      ||
  608. ;++======================================================================++
  609. ;
  610. Fill_page PROC near
  611.          MOV  CX, ES:[BX]         ; get the value to fill the buffer
  612.          ADD  BX, 2               ; increment the instruction pointer
  613.          MOV  Offset_value, BX    ; store the pointer
  614.  
  615.          MOV  AX, 0B000h          ; start of video buffer
  616.  
  617.          AND  DH, 01              ; get the active page number
  618.          JE   Fil_pg_1            ; if it is zero, you don't need to change AX
  619.          MOV  AX, 0B800h          ; second page
  620.  
  621. Fil_pg_1:MOV  ES, AX              ; set base value
  622.  
  623.          XOR  DI, DI              ; reset offset
  624.  
  625.          MOV  AX, CX              ; value to put in buffer ( AX = 0 )
  626.          MOV  CX, 8000H           ; number of bytes to fill
  627.          REP  STOSW               ; repeat storing value in memory
  628.  
  629.          RET
  630. Fill_page ENDP
  631.  
  632.  
  633.  
  634.  
  635. ;
  636. ;++======================================================================++
  637. ;||                                                                      ||
  638. ;||                   This is the error return function                  ||
  639. ;||                                                                      ||
  640. ;++======================================================================++
  641. ;
  642. Err_in_fn:  POP AX                  ; the calling value of the AX register is
  643.                                     ;    on top of the stack.  get it off.
  644.             MOV AH, 0FFh            ; signify an error return
  645.             MOV AL, DH              ; return erroneous function
  646.             JMP Err_exit            ; get out while you still can
  647.  
  648.  
  649.  
  650. ;
  651. ;++======================================================================++
  652. ;||                                                                      ||
  653. ;||                   This is the main loop of the code                  ||
  654. ;||                                                                      ||
  655. ;++======================================================================++
  656. ;
  657. SKIP_DATA:  MOV  CX, CS             ; set DS to the same as CS
  658.             MOV  DS, CX
  659.  
  660.             MOV  Segment_value, AX  ; save these important values
  661.             MOV  Offset_value,  BX
  662.  
  663.             MOV  ES, AX             ; move data segment value into ES
  664.  
  665. Go_again:   MOV  DH, ES:[BX]        ; load the function byte
  666.             INC  BX                 ; increment my program counter
  667.             MOV  Offset_value, BX   ; save program counter
  668.             CMP  DH, 0              ; compare it to 0 to see if you are done
  669.             JE   Quit_int           ; if equal, get out
  670.             CMP  DH, 80h            ; see if the function # is too high
  671.             JAE  Err_in_fn          ; if so, go tell the user
  672.             CMP  DH, 10h            ; see if the function # is too low
  673.             JB   Err_in_fn          ; if so, go tell the user
  674.  
  675.             MOV  CL, 3              ; bits to shift left (to find fn in table)
  676.             MOV  DL, DH             ;
  677.             XOR  DH, DH
  678.             MOV  SI, DX             ; copy function byte for manipulation
  679.             SHR  SI, CL             ; shift byte (divide it by 8)
  680.             AND  SI, 0Eh            ; mask off value (offset into the table)
  681.             MOV  DH, DL             ; some of the fns require DH to have the
  682.                                     ;   instruction byte
  683.  
  684.             CALL Function_table[SI] ; jump to funcion offset in the table
  685.  
  686.             MOV  BX, Segment_value  ; get the segment value
  687.             MOV  ES, BX             ; set the ES register to the proper segment
  688.  
  689.             MOV  BX, Offset_value   ; get pointer to next instruction
  690.             JMP  Go_again           ; start over
  691.  
  692.  
  693. Quit_int:   POP  AX
  694. Err_exit:   POP  BX
  695.             POP  CX
  696.             POP  DX
  697.             POP  DI
  698.             POP  SI
  699.             POP  DS
  700.             POP  ES
  701.             POPF
  702.             IRET
  703.     FINISH  EQU  $
  704. ROUTINE     ENDP
  705.  
  706. ;-----------------------  set up  -----------------------
  707. SET_UP:     LEA  BX, Function_Table         ; set up fuction offset table
  708.  
  709.             LEA  CX, Graphics_on
  710.             MOV  [BX+2], CX
  711.  
  712.             LEA  CX, Text_on
  713.             MOV  [BX+4], CX
  714.  
  715.             LEA  CX, Point
  716.             MOV  [BX+6], CX
  717.  
  718.             LEA  CX, Line
  719.             MOV  [BX+8], CX
  720.  
  721.             LEA  CX, Act_page
  722.             MOV  [BX+10], CX
  723.  
  724.             LEA  CX, Clear_page
  725.             MOV  [BX+12], CX
  726.  
  727.             LEA  CX, Fill_page
  728.             MOV  [BX+14], CX
  729.  
  730.             LEA  DX, Strt_msg
  731.             MOV  AH, 9
  732.             INT  21H
  733.  
  734.             MOV  DX, OFFSET ROUTINE        ; start of routine
  735.             MOV  AL, 70H                   ; what interupt I plan to use
  736.             MOV  AH, 25H                   ; DOS function to set the int vector
  737.             INT  21H                       ; set the vector
  738.  
  739.             LEA  DX, FINISH                ; end of resident routine
  740.             INT  27H                       ; quit and routine stays resident
  741.  
  742. strt_msg    DB   13, 10, '╒══════════════════════════════════════════╕'
  743.             DB   13, 10, '│                                          │'
  744.             DB   13, 10, '│   Hercules video support now resident.   │'
  745.             DB   13, 10, '│                                          │'
  746.             DB   13, 10, '│                 INT  70h                 │'
  747.             DB   13, 10, '│                    by                    │'
  748.             DB   13, 10, '│                                          │'
  749.             DB   13, 10, '│               Ted O''Connor               │'
  750.             DB   13, 10, '│                                          │'
  751.             DB   13, 10, '╘══════════════════════════════════════════╛'
  752.  
  753.             DB   13, 10, 10, '$'
  754.  
  755. CSEG        ENDS
  756.             END START
  757.             END
  758.