home *** CD-ROM | disk | FTP | other *** search
/ The Unsorted BBS Collection / thegreatunsorted.tar / thegreatunsorted / misc / ega.asm < prev    next >
Assembly Source File  |  1990-03-30  |  71KB  |  1,806 lines

  1.     Page    58,132
  2.     Title    EGA.ASM     Apple EGA Video Routines
  3. ;******************************************************************************
  4. ;
  5. ;   Name:    EGA.ASM     Apple EGA Video Routines
  6. ;
  7. ;   Group:    Emulator
  8. ;
  9. ;   Revision:    1.00
  10. ;
  11. ;   Date:    January 30, 1988
  12. ;
  13. ;   Author:    Randy W. Spurlock
  14. ;
  15. ;******************************************************************************
  16. ;
  17. ;  Module Functional Description:
  18. ;
  19. ;        This module contains all the code for the Apple
  20. ;    EGA video routines.
  21. ;
  22. ;******************************************************************************
  23. ;
  24. ;  Changes:
  25. ;
  26. ;    DATE     REVISION                DESCRIPTION
  27. ;  --------   --------    -------------------------------------------------------
  28. ;   1/30/88    1.00    Original
  29. ;
  30. ;******************************************************************************
  31.     Page
  32. ;
  33. ;  Public Declarations
  34. ;
  35.     Public    EGA_Text_1        ; Low resolution/text page 1 write
  36.     Public    EGA_Text_2        ; Low resolution/text page 2 write
  37.     Public    EGA_Graph_1        ; High resolution page 1 write
  38.     Public    EGA_Graph_2        ; High resolution page 2 write
  39.     Public    EGA_Text_Off        ; Text mode off (Graphics)
  40.     Public    EGA_Text_On        ; Text mode on (Text)
  41.     Public    EGA_Mixed_Off        ; Mixed off (Text / Graphics)
  42.     Public    EGA_Mixed_On        ; Mixed on (Text & Graphics)
  43.     Public    EGA_Page_1        ; Select video page 1 (Text & Graphics)
  44.     Public    EGA_Page_2        ; Select video page 2 (Text & Graphics)
  45.     Public    EGA_Low_Res        ; Select low resolution (Graphics)
  46.     Public    EGA_High_Res        ; Select high resolution (Graphics)
  47.     Public    EGA_Restore        ; EGA restore screen routine
  48.     Public    EGA_Setup        ; EGA graphics setup routine
  49.     Public    Update_Toggle        ; Update mode toggle routine
  50. ;
  51. ;  External Declarations
  52. ;
  53.     Extrn    Cursor_Off:Near     ; Turn cursor off routine    (VIDEO)
  54.     Extrn    Cursor_On:Near        ; Turn cursor on routine    (VIDEO)
  55.     Extrn    Blink_Off:Near        ; Turn blink off routine    (VIDEO)
  56.     Extrn    Blink_On:Near        ; Turn blink on routine     (VIDEO)
  57.     Extrn    Set_Address:Near    ; Set video address routine    (VIDEO)
  58.     Extrn    Set_LED:Near        ; Set LED status routine     (KEYBOARD)
  59.     Extrn    Text_Address:Word    ; Text address mapping table    (VIDEO)
  60.     Extrn    Macro_Table:Word    ; Text macro table        (VIDEO)
  61.     Extrn    Char_Table:Word     ; Text character mapping table    (VIDEO)
  62.     Extrn    EGA_Address:Word    ; EGA graphics address table    (VIDEO)
  63.     Extrn    EGA_Slice:Word        ; EGA graphics macro/slice table(VIDEO)
  64.     Extrn    Reverse_Table:Byte    ; Bit reversal table        (VIDEO)
  65.     Extrn    EGA_Shift:Byte        ; EGA bit shift table        (VIDEO)
  66.     Extrn    Text_CGA:Byte        ; CGA display text color table    (VIDEO)
  67.     Extrn    Text_EGA:Byte        ; EGA display text color table    (VIDEO)
  68.     Extrn    Low_CGA:Byte        ; CGA display low res. table    (VIDEO)
  69.     Extrn    Low_EGA:Byte        ; EGA display low res. table    (VIDEO)
  70.     Extrn    High_CGA:Byte        ; CGA display high res. table    (VIDEO)
  71.     Extrn    High_EGA:Byte        ; EGA display high res. table    (VIDEO)
  72.     Extrn    Key_Status:Byte     ; Keyboard status byte         (KEYBOARD)
  73.     Extrn    Last_Key:Byte        ; Last keyboard scan code    (KEYBOARD)
  74.     Extrn    System_Flag:Byte    ; Apple emulator system flag byte(DATA)
  75.     Extrn    Video_Flag:Byte     ; Video system flag byte     (DATA)
  76. ;
  77. ;  LOCAL Equates
  78. ;
  79. TEXT_PAGE_1    Equ    04h        ; Starting text page 1 page value
  80. TEXT_PAGE_2    Equ    08h        ; Starting text page 2 page value
  81. GRAPH_PAGE_1    Equ    20h        ; Starting graphics page 1 page value
  82. GRAPH_PAGE_2    Equ    40h        ; Starting graphics page 2 page value
  83. TEXT_ADDRESS_1    Equ    0400h        ; Starting text page 1 address value
  84. TEXT_ADDRESS_2    Equ    0800h        ; Starting text page 2 address value
  85. GRAPH_ADDRESS_1 Equ    2000h        ; Starting graphics page 1 address value
  86. GRAPH_ADDRESS_2 Equ    4000h        ; Starting graphics page 2 address value
  87. BASE_TEXT    Equ    0000h        ; Base text video memory address
  88. BASE_GRAPHIC    Equ    4000h        ; Base graphics video memory address
  89. BASE_GRAPHIC_1    Equ    4000h        ; Base high res. page 1 memory address
  90. BASE_GRAPHIC_2    Equ    6000h        ; Base high res. page 2 memory address
  91. BLOCK_CHAR    Equ    0DFh        ; Low resolution block character value
  92. SLICE_COUNT    Equ    08h        ; Slice count value (8 = 192 Lines)
  93. MACRO_COUNT    Equ    08h        ; Macro count value (8 = 24 Rows)
  94. ROW_COUNT    Equ    03h        ; Row count value (3 = 3 Rows)
  95. CHAR_COUNT    Equ    28h        ; Character column count (40 Bytes)
  96. BYTE_COUNT    Equ    05h        ; Graphics byte count (5 = 40 Bytes)
  97. MACRO_OFFSET    Equ    08h        ; Macro offset value (Screen holes [8])
  98. NEXT_OFFSET    Equ    50h        ; Next row offset value (80)
  99. ROW_OFFSET    Equ    0230h        ; Row offset value (7 * 40 * 2)
  100. NEXT_SLICE    Equ    28h        ; Next slice offset value (40)
  101. NEXT_MACRO    Equ    0140h        ; Next macro set offset value (Graphics)
  102. NEXT_ROW    Equ    09DDh        ; Next row offset value (Graphics)
  103. TEXT_MASK    Equ    07FFh        ; Text destination mask value
  104. TEXT_MODE    Equ    00h        ; Text mode value (40 x 25)
  105. GRAPH_MODE    Equ    0Dh        ; Graphics mode value (320 x 200)
  106. COLOR_MASK    Equ    007Fh        ; Color bit mask value
  107. DATA_MASK    Equ    0FE00h        ; Data mask initial value
  108. ADDRESS_MASK    Equ    07h        ; Address bits mask value (Mod 8)
  109. ODD_COLUMN    Equ    0001h        ; Odd column test mask value
  110. BYTE_OFFSET    Equ    02h        ; Byte offset value
  111. SEQ_INDEX    Equ    3C4h        ; Sequencer index port address
  112. CRT_INDEX    Equ    3D4h        ; CRT ctrl. index port address
  113. GRA_INDEX    Equ    3CEh        ; Graphics ctrl. index port address
  114. ATR_INDEX    Equ    3C0h        ; Attribute ctrl. index port address
  115. TEXT_MAP    Equ    0606h        ; Text map at 0A000h value
  116. NO_CLEAR    Equ    80h        ; Don't clear regen buffer flag bit
  117. FILL_PATTERN    Equ    55h        ; Video memory fill pattern byte
  118. FILL_SIZE    Equ    4000h        ; Video memory fill size (16384 Bytes)
  119. CLEAR        Equ    0000h        ; Page counter clear value (0)
  120. LIMIT        Equ    0AAAh        ; Page count limit value (.333 Screen)
  121. SEQ_INDEX    Equ    3C4h        ; Sequencer index port address
  122. MAP_MASK    Equ    02h        ; Map mask register index value
  123. PLANE_0     Equ    01h        ; Plane 0 map mask value
  124. PLANE_1     Equ    02h        ; Plane 1 map mask value
  125. PLANE_2     Equ    04h        ; Plane 2 map mask value
  126. PLANE_3     Equ    08h        ; Plane 3 map mask value
  127. GRA_INDEX    Equ    3CEh        ; Graphics controller index port address
  128. READ_MAP    Equ    04h        ; Read map select register index value
  129. READ_0        Equ    00h        ; Plane 0 read value
  130. READ_1        Equ    01h        ; Plane 1 read value
  131. READ_2        Equ    02h        ; Plane 2 read value
  132. READ_3        Equ    03h        ; Plane 3 read value
  133. ;
  134. ;  Define any include files needed
  135. ;
  136.     Include     Macros.inc    ; Include the macro definitions
  137.     Include     Equates.inc    ; Include the equate definitions
  138.     .286c                ; Include 80286 instructions
  139.     Page
  140. ;
  141. ;  Define the emulator code segment
  142. ;
  143. Emulate Segment Word Public 'EMULATE'   ; Emulator code segment
  144.     Assume    cs:Emulate, ds:Nothing, es:Nothing
  145.     Subttl    EGA_Text_1    Low Resolution/Text Page 1 Write
  146.     Page    +
  147. ;******************************************************************************
  148. ;
  149. ;    EGA_Text_1(Effective_Address, Value)
  150. ;
  151. ;        Write the memory location value (Byte)
  152. ;        If this is a text mode and page 1
  153. ;            Save the required registers
  154. ;            Save the character table index value
  155. ;            Calculate macro line and offset values
  156. ;            Load offset value from offset table
  157. ;            If this is NOT a screen hole
  158. ;                Load macro line value from macro table
  159. ;                Compute the actual screen address
  160. ;                Lookup the character/attribute values
  161. ;                Store the character to the screen
  162. ;            Endif this is a screen hole
  163. ;            Restore the required registers
  164. ;        Else this is a graphics mode
  165. ;            If this is low resolution graphics mode page 1
  166. ;                Save the required registers
  167. ;                Save the graphics byte index value
  168. ;                Calculate macro line and offset values
  169. ;                Load offset value from offset table
  170. ;                If this is NOT a screen hole
  171. ;                    Load macro line value from macro table
  172. ;                    Compute the actual screen address
  173. ;                    Lookup the graphics mapping value
  174. ;                    Force character code to a half block
  175. ;                    Store the character to the screen
  176. ;                Endif this is a screen hole
  177. ;                Restore the required registers
  178. ;        Endif for mode value
  179. ;        Return to the caller
  180. ;
  181. ;    Registers on Entry:
  182. ;
  183. ;        AL    - Memory value
  184. ;        DS:DI - 65C02 Effective address
  185. ;        ES    - Video memory segment
  186. ;
  187. ;    Registers on Exit:
  188. ;
  189. ;        AX    - Destroyed
  190. ;        DI    - Destroyed
  191. ;        BP    - Destroyed
  192. ;
  193. ;******************************************************************************
  194.         Even            ; Force procedure to even address
  195. EGA_Text_1    Proc    Near        ; Low res/text page 1 write procedure
  196.     mov    ds:[di],al        ; Write the memory location
  197.     test    cs:[Video_Flag],VIDEO_MODE+PAGE_NUMBER
  198.     jnz    Low_Check_1        ; Jump if NOT text mode page 1
  199.     Save    bx            ; Save the required registers
  200.     xor    ah,ah            ; Convert character to full word
  201.     shl    ax,1            ; Convert character to table index
  202.     mov    bp,ax            ; Save character table index in BP
  203.     mov    ax,di            ; Get the effective memory address
  204.     sub    ah,TEXT_PAGE_1        ; Subtract off the starting value
  205.     shl    ax,1            ; Move macro number into AH register
  206.     xor    bh,bh            ; Setup to index through video tables
  207.     mov    bl,al            ; Convert offset into table index
  208.     mov    di,cs:[bx+Text_Address] ; Get the text offset table value
  209.     inc    di            ; Increment for screen hole check
  210.     js    Text_1_Hole        ; Jump if this is a screen hole
  211.     mov    bl,ah            ; Get macro number into BL register
  212.     shl    bx,1            ; Convert macro number into table index
  213.     add    di,cs:[bx+Macro_Table]    ; Compute the actual screen address
  214.     mov    ax,cs:[bp+Char_Table]    ; Lookup the correct character value
  215.     stosw                ; Store character value onto screen
  216. Text_1_Hole:
  217.     Restore bx            ; Restore the required registers
  218. Text_Done_1:
  219.     ret                ; Return to the caller
  220. Low_Check_1:
  221.     test    cs:[Video_Flag],RESOLUTION+PAGE_NUMBER
  222.     jnz    Low_Done_1        ; Jump if NOT low resolution page 1
  223.     Save    bx            ; Save the required registers
  224.     mov    ah,al            ; Move graphics byte to AH register
  225.     mov    bp,ax            ; Save graphices byte value in BP
  226.     mov    ax,di            ; Get the effective memory address
  227.     sub    ah,TEXT_PAGE_1        ; Subtract off the starting value
  228.     shl    ax,1            ; Move macro number in AH register
  229.     xor    bh,bh            ; Setup to index through video tables
  230.     mov    bl,al            ; Convert offset into table index
  231.     mov    di,cs:[bx+Text_Address] ; Get the text offset table value
  232.     inc    di            ; Increment for screen hole check
  233.     js    Low_1_Hole        ; Jump if this is a screen hole
  234.     mov    bl,ah            ; Get macro number into BL register
  235.     shl    bx,1            ; Convert macro number into table index
  236.     add    di,cs:[bx+Macro_Table]    ; Compute the actual screen offset
  237.     mov    ax,bp            ; Restore the graphics byte value
  238.     mov    al,BLOCK_CHAR        ; Force character to block character
  239.     stosw                ; Store graphics value onto screen
  240. Low_1_Hole:
  241.     Restore bx            ; Restore the required registers
  242. Low_Done_1:
  243.     ret                ; Return to the caller
  244. EGA_Text_1    Endp            ; End of the EGA_Text_1 procedure
  245.     Subttl    EGA_Text_2    Low Resolution/Text Page 2 Write
  246.     Page    +
  247. ;******************************************************************************
  248. ;
  249. ;    EGA_Text_2(Effective_Address, Value)
  250. ;
  251. ;        Write the memory location value (Byte)
  252. ;        If this is a text mode and page 2
  253. ;            Save the required registers
  254. ;            Save the character table index value
  255. ;            Calculate macro line and offset values
  256. ;            Load offset value from offset table
  257. ;            If this is NOT a screen hole
  258. ;                Load macro line value from macro table
  259. ;                Compute the actual screen address
  260. ;                Lookup the character/attribute values
  261. ;                Store the character to the screen
  262. ;            Endif this is a screen hole
  263. ;            Restore the required registers
  264. ;        Else this is a graphics mode
  265. ;            If this is low resolution graphics mode page 2
  266. ;                Save the required registers
  267. ;                Save the graphics byte index value
  268. ;                Calculate macro line and offset values
  269. ;                Load offset value from offset table
  270. ;                If this is NOT a screen hole
  271. ;                    Load macro line value from macro table
  272. ;                    Compute the actual screen address
  273. ;                    Lookup the graphics mapping value
  274. ;                    Force character code to a half block
  275. ;                    Store the character to the screen
  276. ;                Endif this is a screen hole
  277. ;                Restore the required registers
  278. ;        Endif for mode value
  279. ;        Return to the caller
  280. ;
  281. ;    Registers on Entry:
  282. ;
  283. ;        AL    - Memory value
  284. ;        DS:DI - 65C02 Effective address
  285. ;        ES    - Video memory segment
  286. ;
  287. ;    Registers on Exit:
  288. ;
  289. ;        AX    - Destroyed
  290. ;        DI    - Destroyed
  291. ;        BP    - Destroyed
  292. ;
  293. ;******************************************************************************
  294.         Even            ; Force procedure to even address
  295. EGA_Text_2    Proc    Near        ; Low res/text page 2 write procedure
  296.     mov    ds:[di],al        ; Write the memory location
  297.     test    cs:[Video_Flag],VIDEO_MODE+PAGE_INV
  298.     jnz    Low_Check_2        ; Jump if NOT text mode page 2
  299.     Save    bx            ; Save the required registers
  300.     xor    ah,ah            ; Convert character to full word
  301.     shl    ax,1            ; Convert character to table index
  302.     mov    bp,ax            ; Save character table index in BP
  303.     mov    ax,di            ; Get the effective memory address
  304.     sub    ah,TEXT_PAGE_2        ; Subtract off the starting value
  305.     shl    ax,1            ; Move macro number into AH register
  306.     xor    bh,bh            ; Setup to index through video tables
  307.     mov    bl,al            ; Convert offset into table index
  308.     mov    di,cs:[bx+Text_Address] ; Get the text offset table value
  309.     inc    di            ; Increment for screen hole check
  310.     js    Text_2_Hole        ; Jump if this is a screen hole
  311.     mov    bl,ah            ; Get macro number into BL register
  312.     shl    bx,1            ; Convert macro number into table index
  313.     add    di,cs:[bx+Macro_Table]    ; Compute the actual screen address
  314.     mov    ax,cs:[bp+Char_Table]    ; Lookup the correct character value
  315.     stosw                ; Store character value onto screen
  316. Text_2_Hole:
  317.     Restore bx            ; Restore the required registers
  318. Text_Done_2:
  319.     ret                ; Return to the caller
  320. Low_Check_2:
  321.     test    cs:[Video_Flag],RESOLUTION+PAGE_INV
  322.     jnz    Low_Done_2        ; Jump if NOT low resolution page 2
  323.     Save    bx            ; Save the required registers
  324.     mov    ah,al            ; Move graphics byte to AH register
  325.     mov    bp,ax            ; Save graphices byte value in BP
  326.     mov    ax,di            ; Get the effective memory address
  327.     sub    ah,TEXT_PAGE_2        ; Subtract off the starting value
  328.     shl    ax,1            ; Move macro number in AH register
  329.     xor    bh,bh            ; Setup to index through video tables
  330.     mov    bl,al            ; Convert offset into table index
  331.     mov    di,cs:[bx+Text_Address] ; Get the text offset table value
  332.     inc    di            ; Increment for screen hole check
  333.     js    Low_2_Hole        ; Jump if this is a screen hole
  334.     mov    bl,ah            ; Get macro number into BL register
  335.     shl    bx,1            ; Convert macro number into table index
  336.     add    di,cs:[bx+Macro_Table]    ; Compute the actual screen offset
  337.     mov    ax,bp            ; Restore the graphics byte value
  338.     mov    al,BLOCK_CHAR        ; Force character to block character
  339.     stosw                ; Store graphics value onto screen
  340. Low_2_Hole:
  341.     Restore bx            ; Restore the required registers
  342. Low_Done_2:
  343.     ret                ; Return to the caller
  344. EGA_Text_2    Endp            ; End of the EGA_Text_2 procedure
  345.     Subttl    EGA_Graph_1    High Resolution Graphics Page 1 Write
  346.     Page    +
  347. ;******************************************************************************
  348. ;
  349. ;    EGA_Graph_1(Effective_Address, Value)
  350. ;
  351. ;        Write the memory location value (Byte)
  352. ;        If this is a graphics mode and update required
  353. ;            Save the required registers
  354. ;            Get the base video memory address
  355. ;            Save the bit value table index value
  356. ;            Calculate macro/slice and offset values
  357. ;            Load offset value from offset table
  358. ;            If this is NOT a screen hole
  359. ;                Load macro/slice value from macro/slice table
  360. ;                Compute the actual screen address
  361. ;                If data value is non-zero
  362. ;                    Lookup the reverse bit value
  363. ;                    Lookup the shift value
  364. ;                    Setup to read/write to plane 0
  365. ;                    Get the data mask value
  366. ;                    Shift the data mask into position
  367. ;                    Update the screen data bytes
  368. ;                    Setup to read/write to plane 2
  369. ;                    Get the data mask value
  370. ;                    Update the screen data bytes
  371. ;                Else data is zero (Clear request)
  372. ;                    Setup to read/write to plane 0
  373. ;                    Get the data mask value
  374. ;                    Shift the data mask into position
  375. ;                    Update the screen data bytes (Mask bits)
  376. ;                Endif for special data values
  377. ;            Endif this is a screen hole
  378. ;            Restore the required registers
  379. ;        Endif this is NOT a graphics mode
  380. ;        Return to the caller
  381. ;
  382. ;    Registers on Entry:
  383. ;
  384. ;        AL    - Memory value
  385. ;        DS:DI - 65C02 Effective address
  386. ;        ES    - Video memory segment
  387. ;
  388. ;    Registers on Exit:
  389. ;
  390. ;        AX    - Destroyed
  391. ;        DI    - Destroyed
  392. ;        BP    - Destroyed
  393. ;
  394. ;******************************************************************************
  395.         Even            ; Force procedure to even address
  396. EGA_Graph_1    Proc    Near        ; High res page 1 write procedure
  397.     mov    ds:[di],al        ; Write the memory location
  398.     mov    ah,VIDEO_INV+RES_INV    ; Default to special type update
  399.     mov    bp,BASE_GRAPHIC_1    ; Get high res. page 1 memory address
  400.     test    cs:[Key_Status],TYPE_SPECIAL
  401.     jnz    EGA_Check_1        ; Jump if this is special update type
  402.     or    ah,PAGE_NUMBER        ; Setup for standard update check
  403.     mov    bp,BASE_GRAPHIC     ; Get graphics base memory address
  404. EGA_Check_1:
  405.     test    cs:[Video_Flag],ah    ; Check for a video update needed
  406.     jnz    Low_Done_2        ; Jump if an update is NOT needed
  407.     Save    bx,cx,dx,si        ; Save the required registers
  408.     mov    si,bp            ; Get correct graphics base memory
  409.     mov    dl,al            ; Get copy of memory value into DL
  410.     sar    dl,7            ; Convert DL into plane 2 value
  411.     and    ax,COLOR_MASK        ; Mask off all but the color bits
  412.     mov    bp,ax            ; Save bit value table index in BP
  413.     mov    ax,di            ; Get the effective memory address
  414.     and    di,ADDRESS_MASK     ; Mask all but required address bits
  415.     sub    ah,GRAPH_PAGE_1     ; Subtract off the starting value
  416.     shl    ax,1            ; Move macro/slice number to AH register
  417.     xor    bx,bx            ; Setup to index through video tables
  418.     xchg    al,bl            ; Convert offset into table index
  419.     mov    bx,cs:[bx+EGA_Address]    ; Get the graphics offset table value
  420.     inc    bx            ; Increment for screen hole check
  421.     js    Graph_Exit_1        ; Jump if this is a screen hole
  422.     xchg    ax,bx            ; Save offset value in AX register
  423.     xchg    bl,bh            ; Get macro/slice number to BL register
  424.     shl    bx,1            ; Convert macro/slice into table index
  425.     add    ax,cs:[bx+EGA_Slice]    ; Compute the actual screen offset
  426.     add    si,ax            ; Compute the actual screen address
  427.     or    bp,bp            ; Check for zero data bits
  428.     jz    Graph_1_Clear        ; Jump if this is a clear request
  429.     mov    bl,cs:[bp+Reverse_Table]; Lookup the reverse bit value
  430.     mov    bh,dl            ; Move plane 2 value into BH register
  431.     mov    cl,cs:[di+EGA_Shift]    ; Get the shift count value
  432.     mov    dx,SEQ_INDEX        ; Get sequencer index port address
  433.     mov    ax,PLANE_0 Shl 8 + MAP_MASK
  434.     out    dx,ax            ; Setup to write to plane 0
  435.     mov    dx,GRA_INDEX        ; Get graphics ctrl. index port address
  436.     mov    ax,READ_0 Shl 8 + READ_MAP
  437.     out    dx,ax            ; Setup to read from plane 0
  438.     mov    ax,DATA_MASK        ; Get the initial data mask value
  439.     shr    ax,cl            ; Shift data mask into position
  440.     not    ax            ; Invert the mask polarity
  441.     mov    di,ax            ; Save a copy of the mask value
  442.     and    ah,es:[si]        ; Mask off first 8 data bits to replace
  443.     and    al,es:[si+1]        ; Mask off second 8 data bits to replace
  444.     mov    dh,bl            ; Get the new plane 0 data bits value
  445.     xor    dl,dl            ; Convert data bits to full word
  446.     shr    dx,cl            ; Shift data bits into position
  447.     or    ax,dx            ; Logically OR in the new data bits
  448.     mov    es:[si],ah        ; Update first 8 screen data bits
  449.     mov    es:[si+1],al        ; Update second 8 screen data bits
  450.     mov    dx,SEQ_INDEX        ; Get sequencer index port address
  451.     mov    ax,PLANE_2 Shl 8 + MAP_MASK
  452.     out    dx,ax            ; Setup to write to plane 2
  453.     mov    dx,GRA_INDEX        ; Get graphics ctrl. index port address
  454.     mov    ax,READ_2 Shl 8 + READ_MAP
  455.     out    dx,ax            ; Setup to read from plane 2
  456.     mov    ax,di            ; Restore the shifted mask value
  457.     and    ah,es:[si]        ; Mask off first 8 data bits to replace
  458.     and    al,es:[si+1]        ; Mask off second 8 data bits to replace
  459.     mov    dh,bh            ; Get the new plane 3 data bits value
  460.     xor    dl,dl            ; Convert data bits to full word
  461.     shr    dx,cl            ; Shift data bits into position
  462.     or    ax,dx            ; Logically OR in the new data bits
  463.     mov    es:[si],ah        ; Update first 8 screen data bits
  464.     mov    es:[si+1],al        ; Update second 8 screen data bits
  465. Graph_Exit_1:
  466.     Restore bx,cx,dx,si        ; Restore the required registers
  467. Graph_Done_1:
  468.     ret                ; Return to the caller
  469. Graph_1_Clear:
  470.     mov    cl,cs:[di+EGA_Shift]    ; Get the shift count value
  471.     mov    dx,SEQ_INDEX        ; Get sequencer index port address
  472.     mov    ax,PLANE_0 Shl 8 + MAP_MASK
  473.     out    dx,ax            ; Setup to write to plane 0
  474.     mov    dx,GRA_INDEX        ; Get graphics ctrl. index port address
  475.     mov    ax,READ_0 Shl 8 + READ_MAP
  476.     out    dx,ax            ; Setup to read from plane 0
  477.     mov    ax,DATA_MASK        ; Get the initial data mask value
  478.     shr    ax,cl            ; Shift data mask into position
  479.     not    ax            ; Invert the mask polarity
  480.     mov    di,ax            ; Save a copy of the mask value
  481.     and    es:[si],ah        ; Mask off first 8 data bits
  482.     and    es:[si+1],al        ; Mask off second 8 data bits
  483.     Restore bx,cx,dx,si        ; Restore the required registers
  484.     ret                ; Return to the caller
  485. EGA_Graph_1    Endp            ; End of the EGA_Graph_1 procedure
  486.     Subttl    EGA_Graph_2    High Resolution Graphics Page 2 Write
  487.     Page    +
  488. ;******************************************************************************
  489. ;
  490. ;    EGA_Graph_2(Effective_Address, Value)
  491. ;
  492. ;        Write the memory location value (Byte)
  493. ;        If this is a graphics mode and update required
  494. ;            Save the required registers
  495. ;            Get the base video memory address
  496. ;            Save the bit value table index value
  497. ;            Calculate macro/slice and offset values
  498. ;            Load offset value from offset table
  499. ;            If this is NOT a screen hole
  500. ;                Load macro/slice value from macro/slice table
  501. ;                Compute the actual screen address
  502. ;                If data value is non-zero
  503. ;                    Lookup the reverse bit value
  504. ;                    Lookup the shift value
  505. ;                    Setup to read/write to plane 0
  506. ;                    Get the data mask value
  507. ;                    Shift the data mask into position
  508. ;                    Update the screen data bytes
  509. ;                    Setup to read/write to plane 2
  510. ;                    Get the data mask value
  511. ;                    Update the screen data bytes
  512. ;                Else data is zero (Clear request)
  513. ;                    Setup to read/write to plane 0
  514. ;                    Get the data mask value
  515. ;                    Shift the data mask into position
  516. ;                    Update the screen data bytes (Mask bits)
  517. ;                Endif for special data values
  518. ;            Endif this is a screen hole
  519. ;            Restore the required registers
  520. ;        Endif this is NOT a graphics mode
  521. ;        Return to the caller
  522. ;
  523. ;    Registers on Entry:
  524. ;
  525. ;        AL    - Memory value
  526. ;        DS:DI - 65C02 Effective address
  527. ;        ES    - Video memory segment
  528. ;
  529. ;    Registers on Exit:
  530. ;
  531. ;        AX    - Destroyed
  532. ;        DI    - Destroyed
  533. ;        BP    - Destroyed
  534. ;
  535. ;******************************************************************************
  536.         Even            ; Force procedure to even address
  537. EGA_Graph_2    Proc    Near        ; High res page 2 write procedure
  538.     mov    ds:[di],al        ; Write the memory location
  539.     mov    ah,VIDEO_INV+RES_INV    ; Default to special type update
  540.     mov    bp,BASE_GRAPHIC_2    ; Get high res. page 2 memory address
  541.     test    cs:[Key_Status],TYPE_SPECIAL
  542.     jnz    EGA_Check_2        ; Jump if this is special update type
  543.     or    ah,PAGE_INV        ; Setup for standard update check
  544.     mov    bp,BASE_GRAPHIC     ; Get graphics base memory address
  545. EGA_Check_2:
  546.     test    cs:[Video_Flag],ah    ; Check for a video update needed
  547.     jnz    Graph_Done_1        ; Jump if NOT high res. mode page 2
  548.     Save    bx,cx,dx,si        ; Save the required registers
  549.     mov    si,bp            ; Get correct graphics base memory
  550.     mov    dl,al            ; Get copy of memory value into DL
  551.     sar    dl,7            ; Convert DL into plane 2 value
  552.     and    ax,COLOR_MASK        ; Mask off all but the color bits
  553.     mov    bp,ax            ; Save bit value table index in BP
  554.     mov    ax,di            ; Get the effective memory address
  555.     and    di,ADDRESS_MASK     ; Mask all but required address bits
  556.     sub    ah,GRAPH_PAGE_2     ; Subtract off the starting value
  557.     shl    ax,1            ; Move macro/slice number to AH register
  558.     xor    bx,bx            ; Setup to index through video tables
  559.     xchg    al,bl            ; Convert offset into table index
  560.     mov    bx,cs:[bx+EGA_Address]    ; Get the graphics offset table value
  561.     inc    bx            ; Increment for screen hole check
  562.     js    Graph_Exit_2        ; Jump if this is a screen hole
  563.     xchg    ax,bx            ; Save offset value in AX register
  564.     xchg    bl,bh            ; Get macro/slice number to BL register
  565.     shl    bx,1            ; Convert macro/slice into table index
  566.     add    ax,cs:[bx+EGA_Slice]    ; Compute the actual screen offset
  567.     add    si,ax            ; Compute the actual screen address
  568.     or    bp,bp            ; Check for zero data bits
  569.     jz    Graph_2_Clear        ; Jump if this is a clear request
  570.     mov    bl,cs:[bp+Reverse_Table]; Lookup the reverse bit value
  571.     mov    bh,dl            ; Move plane 2 value into BH register
  572.     mov    cl,cs:[di+EGA_Shift]    ; Get the shift count value
  573.     mov    dx,SEQ_INDEX        ; Get sequencer index port address
  574.     mov    ax,PLANE_0 Shl 8 + MAP_MASK
  575.     out    dx,ax            ; Setup to write to plane 0
  576.     mov    dx,GRA_INDEX        ; Get graphics ctrl. index port address
  577.     mov    ax,READ_0 Shl 8 + READ_MAP
  578.     out    dx,ax            ; Setup to read from plane 0
  579.     mov    ax,DATA_MASK        ; Get the initial data mask value
  580.     shr    ax,cl            ; Shift data mask into position
  581.     not    ax            ; Invert the mask polarity
  582.     mov    di,ax            ; Save a copy of the mask value
  583.     and    ah,es:[si]        ; Mask off first 8 data bits to replace
  584.     and    al,es:[si+1]        ; Mask off second 8 data bits to replace
  585.     mov    dh,bl            ; Get the new plane 0 data bits value
  586.     xor    dl,dl            ; Convert data bits to full word
  587.     shr    dx,cl            ; Shift data bits into position
  588.     or    ax,dx            ; Logically OR in the new data bits
  589.     mov    es:[si],ah        ; Update first 8 screen data bits
  590.     mov    es:[si+1],al        ; Update second 8 screen data bits
  591.     mov    dx,SEQ_INDEX        ; Get sequencer index port address
  592.     mov    ax,PLANE_2 Shl 8 + MAP_MASK
  593.     out    dx,ax            ; Setup to write to plane 2
  594.     mov    dx,GRA_INDEX        ; Get graphics ctrl. index port address
  595.     mov    ax,READ_2 Shl 8 + READ_MAP
  596.     out    dx,ax            ; Setup to read from plane 2
  597.     mov    ax,di            ; Restore the shifted mask value
  598.     and    ah,es:[si]        ; Mask off first 8 data bits to replace
  599.     and    al,es:[si+1]        ; Mask off second 8 data bits to replace
  600.     mov    dh,bh            ; Get the new plane 3 data bits value
  601.     xor    dl,dl            ; Convert data bits to full word
  602.     shr    dx,cl            ; Shift data bits into position
  603.     or    ax,dx            ; Logically OR in the new data bits
  604.     mov    es:[si],ah        ; Update first 8 screen data bits
  605.     mov    es:[si+1],al        ; Update second 8 screen data bits
  606. Graph_Exit_2:
  607.     Restore bx,cx,dx,si        ; Restore the required registers
  608. Graph_Done_2:
  609.     ret                ; Return to the caller
  610. Graph_2_Clear:
  611.     mov    cl,cs:[di+EGA_Shift]    ; Get the shift count value
  612.     mov    dx,SEQ_INDEX        ; Get sequencer index port address
  613.     mov    ax,PLANE_0 Shl 8 + MAP_MASK
  614.     out    dx,ax            ; Setup to write to plane 0
  615.     mov    dx,GRA_INDEX        ; Get graphics ctrl. index port address
  616.     mov    ax,READ_0 Shl 8 + READ_MAP
  617.     out    dx,ax            ; Setup to read from plane 0
  618.     mov    ax,DATA_MASK        ; Get the initial data mask value
  619.     shr    ax,cl            ; Shift data mask into position
  620.     not    ax            ; Invert the mask polarity
  621.     mov    di,ax            ; Save a copy of the mask value
  622.     and    es:[si],ah        ; Mask off first 8 data bits
  623.     and    es:[si+1],al        ; Mask off second 8 data bits
  624.     Restore bx,cx,dx,si        ; Restore the required registers
  625.     ret                ; Return to the caller
  626. EGA_Graph_2    Endp            ; End of the EGA_Graph_2 procedure
  627.     Subttl    EGA_Text_Off    Text Off Routine (Graphics)
  628.     Page    +
  629. ;******************************************************************************
  630. ;
  631. ;    EGA_Text_Off(RAM_Space, Video_Segment)
  632. ;
  633. ;        If currently in a text mode
  634. ;            Reset the text mode flag bit (Graphics)
  635. ;            If in high resolution graphics mode
  636. ;                Set graphics mode D (320 x 200)
  637. ;            Endif for high resolution graphics mode
  638. ;            Call routine to program the colors
  639. ;            Call routine to enable intensity (No blink)
  640. ;            Call routine to restore graphics screen
  641. ;        Endif for text mode
  642. ;        Return to the caller
  643. ;
  644. ;    Registers on Entry:
  645. ;
  646. ;        DS    - 65C02 RAM space
  647. ;        ES    - Video memory segment
  648. ;
  649. ;    Registers on Exit:
  650. ;
  651. ;        AX    - Destroyed
  652. ;        BP    - Destroyed
  653. ;
  654. ;******************************************************************************
  655.         Even            ; Force procedure to even address
  656. EGA_Text_Off    Proc    Near        ; Text off (Graphics) procedure
  657.     test    cs:[Video_Flag],VIDEO_MODE
  658.     jnz    Text_Off_Done        ; Jump if this is NOT a text mode
  659.     or    cs:[Video_Flag],VIDEO_MODE
  660.     and    cs:[Video_Flag],Not VIDEO_INV
  661.     test    cs:[Video_Flag],RESOLUTION
  662.     jz    Do_Graphic        ; Jump if low resolution graphics
  663. Do_EGA_High:
  664.     mov    ah,SET_MODE        ; Get set mode video sub-function code
  665.     mov    al,GRAPH_MODE + NO_CLEAR; Get the 320x200 graphics mode value
  666.     int    VIDEO            ; Set video mode to 320x200 graphics
  667. Do_Graphic:
  668.     call    Color_Program        ; Call routine to program the colors
  669.     call    Blink_Off        ; Call routine to turn blink off
  670.     call    Graphic_Restore     ; Call routine to restore graphics
  671. Text_Off_Done:
  672.     ret                ; Return to the caller
  673. EGA_Text_Off    Endp            ; End of the EGA_Text_Off procedure
  674.     Subttl    EGA_Text_On    Text On Routine (Text)
  675.     Page    +
  676. ;******************************************************************************
  677. ;
  678. ;    EGA_Text_On(RAM_Space, Video_Segment)
  679. ;
  680. ;        If currently in a graphics mode
  681. ;            Reset the graphics mode flag bit (Text)
  682. ;            If in high resolution graphics mode
  683. ;                Set text mode 0 (40x25)
  684. ;                Set video memory address to 0A000h
  685. ;                Call routine to turn off cursor
  686. ;            Endif
  687. ;            Call routine to program the colors
  688. ;            Call routine to enable blink (No intensity)
  689. ;            Call routine to restore text screen
  690. ;        Endif
  691. ;        Return to the caller
  692. ;
  693. ;    Registers on Entry:
  694. ;
  695. ;        DS    - 65C02 RAM space
  696. ;        ES    - Video memory segment
  697. ;
  698. ;    Registers on Exit:
  699. ;
  700. ;        AX    - Destroyed
  701. ;        BP    - Destroyed
  702. ;
  703. ;******************************************************************************
  704.         Even            ; Force procedure to even address
  705. EGA_Text_On    Proc    Near        ; Text on (Text) procedure
  706.     test    cs:[Video_Flag],VIDEO_MODE
  707.     jz    Text_On_Done        ; Jump if this is a text mode
  708.     and    cs:[Video_Flag],Not VIDEO_MODE
  709.     or    cs:[Video_Flag],VIDEO_INV
  710.     test    cs:[Video_Flag],RESOLUTION
  711.     jz    Do_Text         ; Jump if low resolution graphics
  712.     mov    ah,SET_MODE        ; Get set mode video sub-function code
  713.     mov    al,TEXT_MODE + NO_CLEAR ; Get the 40x25 text mode value
  714.     int    VIDEO            ; Set video mode to 40x25 text mode
  715.     Save    dx            ; Save the required registers
  716.     mov    dx,GRA_INDEX        ; Get graphics controller index port
  717.     mov    ax,TEXT_MAP        ; Get the text memory mapping value
  718.     out    dx,ax            ; Set text memory to 0A000h
  719.     Restore dx            ; Restore the required registers
  720.     call    Cursor_Off        ; Call routine to turn cursor off
  721. Do_Text:
  722.     call    Color_Program        ; Call routine to program the colors
  723.     call    Blink_On        ; Call routine to turn blink on
  724.     call    Text_Restore        ; Call routine to restore text
  725. Text_On_Done:
  726.     ret                ; Return to the caller
  727. EGA_Text_On    Endp            ; End of the EGA_Text_On procedure
  728.     Subttl    EGA_Mixed_Off    Mixed Off Routine (Text/Graphics)
  729.     Page    +
  730. ;******************************************************************************
  731. ;
  732. ;    EGA_Mixed_Off()
  733. ;
  734. ;        If this is mixed mode
  735. ;            Reset mixed mode flag bit
  736. ;            If this is a graphics mode
  737. ;                Call routine to restore graphics screen
  738. ;            Endif
  739. ;        Endif this is mixed mode
  740. ;        Return to the caller
  741. ;
  742. ;    Registers on Entry:
  743. ;
  744. ;        None
  745. ;
  746. ;    Registers on Exit:
  747. ;
  748. ;        AX    - Destroyed
  749. ;
  750. ;******************************************************************************
  751.         Even            ; Force procedure to even address
  752. EGA_Mixed_Off    Proc    Near        ; Mixed off (Text/Graphics) procedure
  753.     mov    al,cs:[Video_Flag]    ; Get the video flag word
  754.     test    al,MIXED_MODE        ; Check for mixed mode already selected
  755.     jz    Mixed_On_Done        ; Jump if this IS mixed mode already
  756.     and    cs:[Video_Flag],Not MIXED_MODE
  757.     or    cs:[Video_Flag],MIXED_INV
  758.     test    al,VIDEO_MODE        ; Check the video mode flag bit
  759.     jz    Mixed_Off_Done        ; Jump if this is NOT a graphics mode
  760.     call    Graphic_Restore     ; Call routine to restore graphics
  761. Mixed_Off_Done:
  762.     ret                ; Return to the caller
  763. EGA_Mixed_Off    Endp            ; End of the EGA_Mixed_Off procedure
  764.     Subttl    EGA_Mixed_On    Mixed On Routine (Text & Graphics)
  765.     Page    +
  766. ;******************************************************************************
  767. ;
  768. ;    EGA_Mixed_On()
  769. ;
  770. ;        If this is NOT mixed mode
  771. ;            Set mixed mode flag bit
  772. ;            If this is a graphics mode
  773. ;                Call routine to update mixed screen
  774. ;            Endif
  775. ;        Endif this is NOT mixed mode
  776. ;        Return to the caller
  777. ;
  778. ;    Registers on Entry:
  779. ;
  780. ;        None
  781. ;
  782. ;    Registers on Exit:
  783. ;
  784. ;        AX    - Destroyed
  785. ;
  786. ;******************************************************************************
  787.         Even            ; Force procedure to even address
  788. EGA_Mixed_On    Proc    Near        ; Mixed on (Text & Graphics) procedure
  789.     mov    al,cs:[Video_Flag]    ; Get the video flag word
  790.     test    al,MIXED_MODE        ; Check for mixed mode already selected
  791.     jnz    Mixed_On_Done        ; Jump if this IS mixed mode already
  792.     or    cs:[Video_Flag],MIXED_MODE
  793.     and    cs:[Video_Flag],Not MIXED_INV
  794.     test    al,VIDEO_MODE        ; Check the video mode flag bit
  795.     jz    Mixed_On_Done        ; Jump if this is NOT a graphics mode
  796.     call    Mixed_Update        ; Call routine to update mixed screen
  797. Mixed_On_Done:
  798.     ret                ; Return to the caller
  799. EGA_Mixed_On    Endp            ; End of the EGA_Mixed_On procedure
  800.     Subttl    EGA_Page_1    Select Page 1 Routine
  801.     Page    +
  802. ;******************************************************************************
  803. ;
  804. ;    EGA_Page_1(RAM_Space, Video_Segment)
  805. ;
  806. ;        If this is NOT page 1
  807. ;            Reset page number flag bit (Page 1)
  808. ;            If this is a text mode
  809. ;                Call routine to restore text screen
  810. ;            Else this is a graphics mode
  811. ;                If in high resolution graphics mode
  812. ;                    If special update type in effect
  813. ;                        Get high res. page 1 address
  814. ;                        Call routine to set address
  815. ;                    Else standard update type
  816. ;                        Call restore graphics screen
  817. ;                    Endif for update type
  818. ;                Else in low resolution graphics mode
  819. ;                    Call routine to restore graphics screen
  820. ;                Endif for graphics mode
  821. ;            Endif for mode type
  822. ;        Endif this is NOT page 1
  823. ;        Return to the caller
  824. ;
  825. ;    Registers on Entry:
  826. ;
  827. ;        DS    - 65C02 RAM space
  828. ;        ES    - Video memory segment
  829. ;
  830. ;    Registers on Exit:
  831. ;
  832. ;        AX    - Destroyed
  833. ;        BP    - Destroyed
  834. ;
  835. ;******************************************************************************
  836.         Even            ; Force procedure to even address
  837. EGA_Page_1    Proc    Near        ; Select video page 1 procedure
  838.     mov    al,cs:[Video_Flag]    ; Get the video flag word
  839.     test    al,PAGE_NUMBER        ; Check for page 1 already selected
  840.     jz    Page_1_Done        ; Jump if this IS page 1 already
  841.     and    cs:[Video_Flag],Not PAGE_NUMBER
  842.     or    cs:[Video_Flag],PAGE_INV
  843.     test    al,VIDEO_MODE        ; Check the video mode flag bit
  844.     jnz    Graphics_1        ; Jump if this is a graphics mode
  845.     call    Text_Restore        ; Call routine to restore text screen
  846.     jmp    Short Page_1_Done    ; Go return to the caller
  847. Graphics_1:
  848.     test    cs:[Video_Flag],RESOLUTION
  849.     jz    Do_Standard_1        ; Jump if low resolution graphics
  850.     test    cs:[Key_Status],TYPE_SPECIAL
  851.     jz    Do_Standard_1        ; Jump if standard update type
  852. Do_Special_1:
  853.     mov    bp,BASE_GRAPHIC_1    ; Get high resolution page 1 address
  854.     call    Set_Address        ; Call routine to set video address
  855.     jmp    Short Page_1_Done    ; Go return to the caller
  856. Do_Standard_1:
  857.     call    Graphic_Restore     ; Call routine to restore graphics
  858. Page_1_Done:
  859.     ret                ; Return to the caller
  860. EGA_Page_1    Endp            ; End of the EGA_Page_1 procedure
  861.     Subttl    EGA_Page_2    Select Page 2 Routine
  862.     Page    +
  863. ;******************************************************************************
  864. ;
  865. ;    EGA_Page_2(RAM_Space, Video_Segment)
  866. ;
  867. ;        If this is NOT page 2
  868. ;            Set page number flag bit (Page 2)
  869. ;            If this is a text mode
  870. ;                Call routine to restore text screen
  871. ;            Else this is a graphics mode
  872. ;                If in high resolution graphics mode
  873. ;                    If special update type in effect
  874. ;                        Get high res. page 2 address
  875. ;                        Call routine to set address
  876. ;                    Else standard update type
  877. ;                        Call restore graphics screen
  878. ;                    Endif for update type
  879. ;                Else in low resolution graphics mode
  880. ;                    Call routine to restore graphics screen
  881. ;                Endif for graphics mode
  882. ;            Endif for mode type
  883. ;        Endif this is NOT page 2
  884. ;        Return to the caller
  885. ;
  886. ;    Registers on Entry:
  887. ;
  888. ;        DS    - 65C02 RAM space
  889. ;        ES    - Video memory segment
  890. ;
  891. ;    Registers on Exit:
  892. ;
  893. ;        AX    - Destroyed
  894. ;        BP    - Destroyed
  895. ;
  896. ;******************************************************************************
  897.         Even            ; Force procedure to even address
  898. EGA_Page_2    Proc    Near        ; Select video page 2 procedure
  899.     mov    al,cs:[Video_Flag]    ; Get the video flag word
  900.     test    al,PAGE_NUMBER        ; Check for page 2 already selected
  901.     jnz    Page_2_Done        ; Jump if this IS page 2 already
  902.     or    cs:[Video_Flag],PAGE_NUMBER
  903.     and    cs:[Video_Flag],Not PAGE_INV
  904.     test    al,VIDEO_MODE        ; Check the video mode flag bit
  905.     jnz    Graphics_2        ; Jump if this is a graphics mode
  906.     call    Text_Restore        ; Call routine to restore text screen
  907.     jmp    Short Page_2_Done    ; Go return to the caller
  908. Graphics_2:
  909.     test    cs:[Video_Flag],RESOLUTION
  910.     jz    Do_Standard_2        ; Jump if low resolution graphics
  911.     test    cs:[Key_Status],TYPE_SPECIAL
  912.     jz    Do_Standard_2        ; Jump if standard update type
  913. Do_Special_2:
  914.     mov    bp,BASE_GRAPHIC_2    ; Get high resolution page 1 address
  915.     call    Set_Address        ; Call routine to set video address
  916.     jmp    Short Page_2_Done    ; Go return to the caller
  917. Do_Standard_2:
  918.     call    Graphic_Restore     ; Call routine to restore graphics
  919. Page_2_Done:
  920.     ret                ; Return to the caller
  921. EGA_Page_2    Endp            ; End of the EGA_Page_2 procedure
  922.     Subttl    EGA_Low_Res    Select Low Resolution Routine
  923.     Page    +
  924. ;******************************************************************************
  925. ;
  926. ;    EGA_Low_Res()
  927. ;
  928. ;        If this is NOT low resolution mode
  929. ;            Set low resolution mode flag bit
  930. ;            If this is a graphics mode
  931. ;                Set text mode 0 (40x25)
  932. ;                Set video memory address to 0A000h
  933. ;                Call routine to program the colors
  934. ;                Call routine to turn off cursor
  935. ;                Call routine to enable intensity (No blink)
  936. ;                Call routine to restore graphics
  937. ;            Endif
  938. ;        Endif this is NOT low resolution mode
  939. ;        Return to the caller
  940. ;
  941. ;    Registers on Entry:
  942. ;
  943. ;        None
  944. ;
  945. ;    Registers on Exit:
  946. ;
  947. ;        AX    - Destroyed
  948. ;
  949. ;******************************************************************************
  950.         Even            ; Force procedure to even address
  951. EGA_Low_Res    Proc    Near        ; Select low resolution procedure
  952.     mov    al,cs:[Video_Flag]    ; Get the video flag byte
  953.     test    al,RESOLUTION        ; Check for low resolution mode
  954.     jz    Low_Res_Done        ; Jump if this IS low resolution
  955.     and    cs:[Video_Flag],Not RESOLUTION
  956.     or    cs:[Video_Flag],RES_INV
  957.     test    al,VIDEO_MODE        ; Check the video mode flag bit
  958.     jz    Low_Res_Done        ; Jump if this is NOT a graphics mode
  959.     mov    ah,SET_MODE        ; Get set mode video sub-function code
  960.     mov    al,TEXT_MODE + NO_CLEAR ; Get the 40x25 text mode value
  961.     int    VIDEO            ; Set video mode to 40x25 text mode
  962.     Save    dx            ; Save the required registers
  963.     mov    dx,GRA_INDEX        ; Get graphics controller index port
  964.     mov    ax,TEXT_MAP        ; Get the text memory mapping value
  965.     out    dx,ax            ; Set text memory to 0A000h
  966.     Restore dx            ; Restore the required registers
  967.     call    Color_Program        ; Call routine to program the colors
  968.     call    Cursor_Off        ; Call routine to turn cursor off
  969.     call    Blink_Off        ; Call routine to turn blink off
  970.     call    Graphic_Restore     ; Call routine to restore graphics
  971. Low_Res_Done:
  972.     ret                ; Return to the caller
  973. EGA_Low_Res    Endp            ; End of the EGA_Low_Res procedure
  974.     Subttl    EGA_High_Res    Select High Resolution Routine
  975.     Page    +
  976. ;******************************************************************************
  977. ;
  978. ;    EGA_High_Res()
  979. ;
  980. ;        If this is NOT high resolution mode
  981. ;            Set high resolution mode flag bit
  982. ;            If this is a graphics mode
  983. ;                Set graphics mode D (320 x 200)
  984. ;                Call routine to program the colors
  985. ;                Call routine to restore graphics
  986. ;            Endif
  987. ;        Endif this is NOT high resolution mode
  988. ;        Return to the caller
  989. ;
  990. ;    Registers on Entry:
  991. ;
  992. ;        None
  993. ;
  994. ;    Registers on Exit:
  995. ;
  996. ;        AX    - Destroyed
  997. ;
  998. ;******************************************************************************
  999.         Even            ; Force procedure to even address
  1000. EGA_High_Res    Proc    Near        ; Select high resolution procedure
  1001.     mov    al,cs:[Video_Flag]    ; Get the video flag byte
  1002.     test    al,RESOLUTION        ; Check for high resolution mode
  1003.     jnz    High_Res_Done        ; Jump if this IS high resolution
  1004.     or    cs:[Video_Flag],RESOLUTION
  1005.     and    cs:[Video_Flag],Not RES_INV
  1006.     test    al,VIDEO_MODE        ; Check the video mode flag bit
  1007.     jz    High_Res_Done        ; Jump if this is NOT a graphics mode
  1008.     mov    ah,SET_MODE        ; Get set mode video sub-function code
  1009.     mov    al,GRAPH_MODE + NO_CLEAR; Get the 320x200 graphics mode value
  1010.     int    VIDEO            ; Set video mode to 320x200 graphics
  1011.     call    Color_Program        ; Call routine to program the colors
  1012.     call    Graphic_Restore     ; Call routine to restore graphics
  1013. High_Res_Done:
  1014.     ret                ; Return to the caller
  1015. EGA_High_Res    Endp            ; End of the EGA_High_Res procedure
  1016.     Subttl    Text_Restore    Restore Text Screen Routine
  1017.     Page    +
  1018. ;******************************************************************************
  1019. ;
  1020. ;    Text_Restore(RAM_Space, Video_Segment)
  1021. ;
  1022. ;        Save the required registers
  1023. ;        Set source index to page 1 memory (0400h)
  1024. ;        If page 2 is selected
  1025. ;            Set source index to page 2 memory (0800h)
  1026. ;        Endif
  1027. ;        Set destination index to text video memory (BASE_TEXT)
  1028. ;        Call routine to restore the text memory
  1029. ;        Setup base address to text video memory (BASE_TEXT)
  1030. ;        Call routine to set base video address
  1031. ;        Restore the required registers
  1032. ;        Return to the caller
  1033. ;
  1034. ;    Registers on Entry:
  1035. ;
  1036. ;        DS    - 65C02 RAM space
  1037. ;        ES    - Video memory segment
  1038. ;
  1039. ;    Registers on Exit:
  1040. ;
  1041. ;        AX    - Destroyed
  1042. ;        BP    - Destroyed
  1043. ;
  1044. ;******************************************************************************
  1045.         Even            ; Force procedure to even address
  1046. Text_Restore    Proc    Near        ; Restore text screen procedure
  1047.     Save    bx,cx,dx,si,di        ; Save the required registers
  1048.     mov    si,TEXT_ADDRESS_1    ; Setup source index for page 1
  1049.     test    cs:[Video_Flag],PAGE_NUMBER
  1050.     jz    Do_Restore        ; Jump if this really is page 1
  1051.     mov    si,TEXT_ADDRESS_2    ; Setup base address for page 2
  1052. Do_Restore:
  1053.     mov    di,BASE_TEXT        ; Setup destination index
  1054.     mov    bp,TEXT_MASK        ; Setup destination mask value
  1055.     call    Restore_Text        ; Call routine to restore text page 1
  1056. Text_Set:
  1057.     mov    bp,BASE_TEXT Shr 1    ; Setup base text video address
  1058.     call    Set_Address        ; Call routine to set base address
  1059.     Restore bx,cx,dx,si,di        ; Restore the required registers
  1060.     ret                ; Return to the caller
  1061. Text_Restore    Endp            ; End of the Text_Restore procedure
  1062.     Subttl    Restore_Text    Restore Text Memory Routine
  1063.     Page    +
  1064. ;******************************************************************************
  1065. ;
  1066. ;    Restore_Text(RAM_Space, Video_Segment, Source, Destination, Mask)
  1067. ;
  1068. ;        Set Macro_Counter to 8 (Restore 8 macro lines [24 rows])
  1069. ;        While Macro_Counter > 0
  1070. ;            Set Row_Counter to 3 (Restore 3 rows)
  1071. ;            While Row_Counter > 0
  1072. ;                Set Character_Counter to 40 (Restore 40 columns)
  1073. ;                While Character_Counter > 0
  1074. ;                    Load a character code from memory
  1075. ;                    Lookup the character/attribute value
  1076. ;                    Store character/attribute to memory
  1077. ;                    Decrement the Character_Counter
  1078. ;                Endwhile for Character_Count
  1079. ;                Increment destination index by ROW_OFFSET (8)
  1080. ;                Mask off all but valid destination address bits
  1081. ;            Endwhile for Row_Counter
  1082. ;            Increment source index by MACRO_OFFSET (8)
  1083. ;        Endwhile for Macro_Counter
  1084. ;        Return to the caller
  1085. ;
  1086. ;    Registers on Entry:
  1087. ;
  1088. ;        DS:SI - 65C02 RAM space source index
  1089. ;        ES:DI - Video memory segment destination index
  1090. ;        BP    - Destination index address mask
  1091. ;
  1092. ;    Registers on Exit:
  1093. ;
  1094. ;        AX-DX - Destroyed
  1095. ;
  1096. ;******************************************************************************
  1097.         Even            ; Force procedure to even address
  1098. Restore_Text    Proc    Near        ; Restore text memory procedure
  1099.     mov    dh,MACRO_COUNT        ; Setup the macro count (8 = 24 Rows)
  1100. Macro_Loop:
  1101.     mov    dl,ROW_COUNT        ; Setup the row count (3 Rows)
  1102.     Save    di            ; Save the destination index value
  1103. Row_Loop:
  1104.     mov    cx,CHAR_COUNT        ; Setup the character count (40 Columns)
  1105. Char_Loop:
  1106.     lodsb                ; Load the character code from memory
  1107.     xor    ah,ah            ; Convert character code to full word
  1108.     shl    ax,1            ; Convert character code to table index
  1109.     mov    bx,ax            ; Setup to translate the character
  1110.     mov    ax,cs:[bx + Char_Table] ; Lookup the correct character value
  1111.     stosw                ; Store the character code to memory
  1112.     loop    Char_Loop        ; Loop till all columns are moved
  1113.     add    di,ROW_OFFSET        ; Increment destination address value
  1114.     and    di,bp            ; Mask off all but valid address bits
  1115.     dec    dl            ; Decrement the row counter value
  1116.     jnz    Row_Loop        ; Jump if more rows to move
  1117.     add    si,MACRO_OFFSET     ; Increment source address value
  1118.     Restore di            ; Restore the destination index value
  1119.     add    di,NEXT_OFFSET        ; Increment destination address value
  1120.     dec    dh            ; Decrement the macro counter value
  1121.     jnz    Macro_Loop        ; Jump if more macro lines to moves
  1122.     ret                ; Return to the caller
  1123. Restore_Text    Endp            ; End of the Restore_Text procedure
  1124.     Subttl    Graphic_Restore Restore Graphic Screen Routine
  1125.     Page    +
  1126. ;******************************************************************************
  1127. ;
  1128. ;    Graphic_Restore(RAM_Space, Video_Segment)
  1129. ;
  1130. ;        Save the required registers
  1131. ;        If in low resolution graphics mode
  1132. ;            Set source index to page 1 memory (0400h)
  1133. ;            If page 2 is selected
  1134. ;                Set source index to page 2 memory (0800h)
  1135. ;            Endif
  1136. ;            Call routine to restore low resolution memory
  1137. ;            Setup base address to text memory (BASE_TEXT)
  1138. ;        Else in high resolution graphics mode
  1139. ;            If special update type selected
  1140. ;                Set source index to page 1 (2000h)
  1141. ;                Set destination to high res. page 1
  1142. ;                Call routine to restore graphics screen
  1143. ;                Set source index to page 2 (4000h)
  1144. ;                Set destination to high res. page 2
  1145. ;                Call routine to restore graphics screen
  1146. ;                Set address to graphics page 1
  1147. ;                If page 2 is selected
  1148. ;                    Set address to graphics page 2
  1149. ;                Endif
  1150. ;            Else standard update type selected
  1151. ;                Set source index to page 1 (2000h)
  1152. ;                If page 2 is selected
  1153. ;                    Set source index to page 2 (4000h)
  1154. ;                Endif
  1155. ;                Set destination to graphics video memory
  1156. ;                Call routine to restore graphics screen
  1157. ;                Setup address to graphics memory (BASE_GRAPHIC)
  1158. ;            Endif for special update
  1159. ;        Endif for type of graphics mode
  1160. ;        Call routine to set base video address
  1161. ;        Restore the required registers
  1162. ;        Return to the caller
  1163. ;
  1164. ;    Registers on Entry:
  1165. ;
  1166. ;        DS    - 65C02 RAM space
  1167. ;        ES    - Video memory segment
  1168. ;
  1169. ;    Registers on Exit:
  1170. ;
  1171. ;        AX    - Destroyed
  1172. ;        BP    - Destroyed
  1173. ;
  1174. ;******************************************************************************
  1175.         Even            ; Force procedure to even address
  1176. Graphic_Restore Proc    Near        ; Restore graphic screen procedure
  1177.     Save    bx,cx,dx,si,di        ; Save the required registers
  1178.     test    cs:[Video_Flag],RESOLUTION
  1179.     jz    Low_Restore        ; Jump if this is low resolution
  1180. High_Restore:
  1181.     test    cs:[Key_Status],TYPE_SPECIAL
  1182.     jz    Do_Standard        ; Jump if standard update type
  1183. Do_Special:
  1184.     mov    si,GRAPH_ADDRESS_1    ; Setup base address for page 1
  1185.     mov    di,BASE_GRAPHIC_1    ; Setup for page 1 video restore
  1186.     call    Restore_High        ; Call routine to restore page 1
  1187.     mov    si,GRAPH_ADDRESS_2    ; Setup base address for page 2
  1188.     mov    di,BASE_GRAPHIC_2    ; Setup for page 2 video restore
  1189.     call    Restore_High        ; Call routine to restore page 2
  1190.     mov    bp,BASE_GRAPHIC_1    ; Default to high resolution page 1
  1191.     test    cs:[Video_Flag],PAGE_NUMBER
  1192.     jz    Graphic_Set        ; Jump if this really is page 1
  1193.     mov    bp,BASE_GRAPHIC_2    ; Setup base address for page 2
  1194.     jmp    Short Graphic_Set    ; Go set the video address
  1195. Do_Standard:
  1196.     mov    si,GRAPH_ADDRESS_1    ; Setup source index for page 1
  1197.     test    cs:[Video_Flag],PAGE_NUMBER
  1198.     jz    Do_High         ; Jump if this really is page 1
  1199.     mov    si,GRAPH_ADDRESS_2    ; Setup base address for page 2
  1200. Do_High:
  1201.     mov    di,BASE_GRAPHIC     ; Default to page 1 video restore
  1202.     call    Restore_High        ; Call routine to restore high res.
  1203.     mov    bp,BASE_GRAPHIC     ; Default to page 1 video address
  1204.     jmp    Short Graphic_Set    ; Go setup the base address value
  1205. Low_Restore:
  1206.     mov    si,TEXT_ADDRESS_1    ; Setup source index for page 1
  1207.     test    cs:[Video_Flag],PAGE_NUMBER
  1208.     jz    Do_Low            ; Jump if this really is page 1
  1209.     mov    si,TEXT_ADDRESS_2    ; Setup base address for page 2
  1210. Do_Low:
  1211.     mov    di,BASE_TEXT        ; Setup destination index
  1212.     mov    bp,TEXT_MASK        ; Setup destination mask value
  1213.     call    Restore_Low        ; Call routine to restore low page 1
  1214.     mov    bp,BASE_TEXT Shr 1    ; Get base text video address
  1215. Graphic_Set:
  1216.     call    Set_Address        ; Call routine to set base address
  1217. Graphic_Done:
  1218.     Restore bx,cx,dx,si,di        ; Restore the required registers
  1219.     ret                ; Return to the caller
  1220. Graphic_Restore Endp            ; End of the Graphic_Restore procedure
  1221.     Subttl    Restore_Low    Restore Low Resolution Memory Routine
  1222.     Page    +
  1223. ;******************************************************************************
  1224. ;
  1225. ;    Restore_Low(RAM_Space, Video_Segment, Source, Destination, Mask)
  1226. ;
  1227. ;        Set Macro_Counter to 8 (Restore 8 macro lines [24 rows])
  1228. ;        While Macro_Counter > 0
  1229. ;            Set Row_Counter to 3 (Restore 3 rows)
  1230. ;            While Row_Counter > 0
  1231. ;                Set Character_Counter to 40 (Restore 40 columns)
  1232. ;                While Character_Counter > 0
  1233. ;                    Load a graphics byte from memory
  1234. ;                    Force character code to half block value
  1235. ;                    Store character/attribute to memory
  1236. ;                    Decrement the Character_Counter
  1237. ;                Endwhile for Character_Count
  1238. ;                Increment destination index by ROW_OFFSET (8)
  1239. ;                Mask off all but valid destination address bits
  1240. ;            Endwhile for Row_Counter
  1241. ;            Increment source index by MACRO_OFFSET (8)
  1242. ;        Endwhile for Macro_Counter
  1243. ;        Return to the caller
  1244. ;
  1245. ;    Registers on Entry:
  1246. ;
  1247. ;        DS:SI - 65C02 RAM space source index
  1248. ;        ES:DI - Video memory segment destination index
  1249. ;        BP    - Destination index address mask
  1250. ;
  1251. ;    Registers on Exit:
  1252. ;
  1253. ;        AX-DX - Destroyed
  1254. ;
  1255. ;******************************************************************************
  1256.         Even            ; Force procedure to even address
  1257. Restore_Low    Proc    Near        ; Restore low res. memory procedure
  1258.     mov    dh,MACRO_COUNT        ; Setup the macro count (8 = 24 Rows)
  1259. Loop_Macro:
  1260.     mov    dl,ROW_COUNT        ; Setup the row count (3 Rows)
  1261.     Save    di            ; Save the destination index value
  1262. Loop_Row:
  1263.     mov    cx,CHAR_COUNT        ; Setup the character count (40 Columns)
  1264. Loop_Byte:
  1265.     lodsb                ; Load the graphics byte from memory
  1266.     mov    ah,al            ; Move graphics byte to AH register
  1267.     mov    al,BLOCK_CHAR        ; Force block character code value
  1268.     stosw                ; Store the character code to memory
  1269.     loop    Loop_Byte        ; Loop till all columns are moved
  1270.     add    di,ROW_OFFSET        ; Increment destination address value
  1271.     and    di,bp            ; Mask off all but valid address bits
  1272.     dec    dl            ; Decrement the row counter value
  1273.     jnz    Loop_Row        ; Jump if more rows to move
  1274.     add    si,MACRO_OFFSET     ; Increment source address value
  1275.     Restore di            ; Restore the destination index value
  1276.     add    di,NEXT_OFFSET        ; Increment destination address value
  1277.     dec    dh            ; Decrement the macro counter value
  1278.     jnz    Loop_Macro        ; Jump if more macro lines to moves
  1279.     ret                ; Return to the caller
  1280. Restore_Low    Endp            ; End of the Restore_Low procedure
  1281.     Subttl    Restore_High    Restore High Resolution Memory Routine
  1282.     Page    +
  1283. ;******************************************************************************
  1284. ;
  1285. ;    Restore_High(RAM_Space, Video_Segment, Source, Destination)
  1286. ;
  1287. ;        Setup to write to plane 0
  1288. ;        Set Slice_Counter to 8 (Restore 8 slices [192 lines])
  1289. ;        While Slice_Counter > 0
  1290. ;            Set Macro_Counter to 8 (Restore 8 macro lines [24 rows])
  1291. ;            While Macro_Counter > 0
  1292. ;                Set Row_Counter to 3 (Restore 3 rows)
  1293. ;                While Row_Counter > 0
  1294. ;                    Set Byte_Counter to 5 (40 Bytes)
  1295. ;                    While Byte_Counter > 0
  1296. ;                        Set Repeat_Count to 8
  1297. ;                        Setup to plane 0
  1298. ;                        While Repeat_Count > 0
  1299. ;                            Get next graphics byte
  1300. ;                            Lookup reverse bit value
  1301. ;                            Lookup the shift value
  1302. ;                            Get data mask value
  1303. ;                            Combine previous bits
  1304. ;                            Shift mask into position
  1305. ;                            Update screen data bytes
  1306. ;                        Endwhile for Repeat_Count
  1307. ;                        Set Repeat_Count to 8
  1308. ;                        Setup to plane 2
  1309. ;                        While Repeat_Count > 0
  1310. ;                            Get next graphics byte
  1311. ;                            Lookup reverse bit value
  1312. ;                            Lookup the shift value
  1313. ;                            Get data mask value
  1314. ;                            Combine previous bits
  1315. ;                            Shift mask into position
  1316. ;                            Update screen data bytes
  1317. ;                        Endwhile for Repeat_Count
  1318. ;                    Endwhile for Byte_Count
  1319. ;                Increment destination index by NEXT_ROW (2525)
  1320. ;                Endwhile for Row_Counter
  1321. ;                Increment source index by NEXT_MACRO (320)
  1322. ;            Endwhile for Macro_Counter
  1323. ;            Increment destination index by NEXT_SLICE (40)
  1324. ;        Endwhile for Slice_Counter
  1325. ;        Return to the caller
  1326. ;
  1327. ;    Registers on Entry:
  1328. ;
  1329. ;        DS:SI - 65C02 RAM space source index
  1330. ;        ES:DI - Video memory segment destination index
  1331. ;
  1332. ;    Registers on Exit:
  1333. ;
  1334. ;        AX-DX - Destroyed
  1335. ;
  1336. ;******************************************************************************
  1337.         Even            ; Force procedure to even address
  1338. Restore_High    Proc    Near        ; Restore high res. memory procedure
  1339.     mov    dx,SEQ_INDEX        ; Get sequencer index port address
  1340.     mov    ax,PLANE_0 Shl 8 + MAP_MASK
  1341.     out    dx,ax            ; Setup to write to plane 0
  1342.     Save    si,di            ; Save source and destination
  1343.     mov    ch,SLICE_COUNT        ; Setup the slice count (8 = 192 Lines)
  1344. Slice_0_Next:
  1345.     mov    dh,MACRO_COUNT        ; Setup the macro count (8 = 24 Rows)
  1346.     Save    di            ; Save the destination index value
  1347. Macro_0_Next:
  1348.     mov    dl,ROW_COUNT        ; Setup the row count (3 Rows)
  1349.     Save    di            ; Save the destination index value
  1350. Row_0_Next:
  1351.     mov    cl,BYTE_COUNT        ; Setup graphics count (10 = 40 Bytes)
  1352. Byte_0_Next:
  1353.     lodsb                ; Get the next graphics data byte
  1354.     mov    bl,al            ; Move data byte into BL register
  1355.     and    bx,COLOR_MASK        ; Mask off all but the color bits
  1356.     mov    ah,cs:[bx+Reverse_Table]; Reverse the graphics data bits
  1357.     shr    ah,1            ; Shift data bits into position
  1358.     lodsb                ; Get the next graphics data byte
  1359.     mov    bl,al            ; Move data byte into BL register
  1360.     and    bx,COLOR_MASK        ; Mask off all but the color bits
  1361.     mov    al,cs:[bx+Reverse_Table]; Reverse the graphics data bits
  1362.     shl    ax,1            ; Shift data bits into position
  1363.     xchg    al,ah            ; Put bytes into correct order
  1364.     stosb                ; Store data bytes to screen memory
  1365.     shr    ah,2            ; Shift data bits into position
  1366.     lodsb                ; Get the next graphics data byte
  1367.     mov    bl,al            ; Move data byte into BL register
  1368.     and    bx,COLOR_MASK        ; Mask off all but the color bits
  1369.     mov    al,cs:[bx+Reverse_Table]; Reverse the graphics data bits
  1370.     shl    ax,2            ; Shift data bits into position
  1371.     xchg    al,ah            ; Put bytes into correct order
  1372.     stosb                ; Store data bytes to screen memory
  1373.     shr    ah,3            ; Shift data bits into position
  1374.     lodsb                ; Get the next graphics data byte
  1375.     mov    bl,al            ; Move data byte into BL register
  1376.     and    bx,COLOR_MASK        ; Mask off all but the color bits
  1377.     mov    al,cs:[bx+Reverse_Table]; Reverse the graphics data bits
  1378.     shl    ax,3            ; Shift data bits into position
  1379.     xchg    al,ah            ; Put bytes into correct order
  1380.     stosb                ; Store data bytes to screen memory
  1381.     shr    ah,4            ; Shift data bits into position
  1382.     lodsb                ; Get the next graphics data byte
  1383.     mov    bl,al            ; Move data byte into BL register
  1384.     and    bx,COLOR_MASK        ; Mask off all but the color bits
  1385.     mov    al,cs:[bx+Reverse_Table]; Reverse the graphics data bits
  1386.     shl    ax,4            ; Shift data bits into position
  1387.     xchg    al,ah            ; Put bytes into correct order
  1388.     stosb                ; Store data bytes to screen memory
  1389.     shr    ah,5            ; Shift data bits into position
  1390.     lodsb                ; Get the next graphics data byte
  1391.     mov    bl,al            ; Move data byte into BL register
  1392.     and    bx,COLOR_MASK        ; Mask off all but the color bits
  1393.     mov    al,cs:[bx+Reverse_Table]; Reverse the graphics data bits
  1394.     shl    ax,5            ; Shift data bits into position
  1395.     xchg    al,ah            ; Put bytes into correct order
  1396.     stosb                ; Store data bytes to screen memory
  1397.     shr    ah,6            ; Shift data bits into position
  1398.     lodsb                ; Get the next graphics data byte
  1399.     mov    bl,al            ; Move data byte into BL register
  1400.     and    bx,COLOR_MASK        ; Mask off all but the color bits
  1401.     mov    al,cs:[bx+Reverse_Table]; Reverse the graphics data bits
  1402.     shl    ax,6            ; Shift data bits into position
  1403.     xchg    al,ah            ; Put bytes into correct order
  1404.     stosb                ; Store data bytes to screen memory
  1405.     shr    ah,7            ; Shift data bits into position
  1406.     lodsb                ; Get the next graphics data byte
  1407.     mov    bl,al            ; Move data byte into BL register
  1408.     and    bx,COLOR_MASK        ; Mask off all but the color bits
  1409.     mov    al,cs:[bx+Reverse_Table]; Reverse the graphics data bits
  1410.     shl    ax,7            ; Shift data bits into position
  1411.     xchg    al,ah            ; Put bytes into correct order
  1412.     stosb                ; Store data bytes to screen memory
  1413.     dec    cl            ; Decrement the graphics byte counter
  1414.     jz    Byte_0_Done        ; Jump if all bytes have been moved
  1415.     jmp    Byte_0_Next        ; Go process more graphics bytes
  1416. Byte_0_Done:
  1417.     add    di,NEXT_ROW        ; Increment to the next graphics row
  1418.     dec    dl            ; Decrement the row counter
  1419.     jz    Row_0_Done        ; Jump if all rows have been moved
  1420.     jmp    Row_0_Next        ; Go process more graphics rows
  1421. Row_0_Done:
  1422.     add    si,MACRO_OFFSET     ; Increment source address value
  1423.     Restore di            ; Restore the destination index value
  1424.     add    di,NEXT_MACRO        ; Increment to the next macro line
  1425.     dec    dh            ; Decrement the macro counter value
  1426.     jz    Macro_0_Done        ; Jump if all macro lines are moved
  1427.     jmp    Macro_0_Next        ; Go process more macro lines
  1428. Macro_0_Done:
  1429.     Restore di            ; Restore the destination index value
  1430.     add    di,NEXT_SLICE        ; Increment to the next slice line
  1431.     dec    ch            ; Decrement the slice counter value
  1432.     jz    Restore_2        ; Jump if restore of plane 0 is complete
  1433.     jmp    Slice_0_Next        ; Go process more slice sets
  1434. Restore_2:
  1435.     mov    dx,SEQ_INDEX        ; Get sequencer index port address
  1436.     mov    ax,PLANE_2 Shl 8 + MAP_MASK
  1437.     out    dx,ax            ; Setup to write to plane 2
  1438.     Restore si,di            ; Restore source and destination
  1439.     mov    ch,SLICE_COUNT        ; Setup the slice count (8 = 192 Lines)
  1440. Slice_2_Next:
  1441.     mov    dh,MACRO_COUNT        ; Setup the macro count (8 = 24 Rows)
  1442.     Save    di            ; Save the destination index value
  1443. Macro_2_Next:
  1444.     mov    dl,ROW_COUNT        ; Setup the row count (3 Rows)
  1445.     Save    di            ; Save the destination index value
  1446. Row_2_Next:
  1447.     mov    cl,BYTE_COUNT        ; Setup graphics count (10 = 40 Bytes)
  1448. Byte_2_Next:
  1449.     lodsb                ; Get the next graphics data byte
  1450.     sar    al,7            ; Convert data byte into plane 2 value
  1451.     mov    ah,al            ; Move data byte into AH register
  1452.     shr    ah,1            ; Shift data bits into position
  1453.     lodsb                ; Get the next graphics data byte
  1454.     sar    al,7            ; Convert data byte into plane 2 value
  1455.     shl    ax,1            ; Shift data bits into position
  1456.     xchg    al,ah            ; Put bytes into correct order
  1457.     stosb                ; Store data bytes to screen memory
  1458.     shr    ah,2            ; Shift data bits into position
  1459.     lodsb                ; Get the next graphics data byte
  1460.     sar    al,7            ; Convert data byte into plane 2 value
  1461.     shl    ax,2            ; Shift data bits into position
  1462.     xchg    al,ah            ; Put bytes into correct order
  1463.     stosb                ; Store data bytes to screen memory
  1464.     shr    ah,3            ; Shift data bits into position
  1465.     lodsb                ; Get the next graphics data byte
  1466.     sar    al,7            ; Convert data byte into plane 2 value
  1467.     shl    ax,3            ; Shift data bits into position
  1468.     xchg    al,ah            ; Put bytes into correct order
  1469.     stosb                ; Store data bytes to screen memory
  1470.     shr    ah,4            ; Shift data bits into position
  1471.     lodsb                ; Get the next graphics data byte
  1472.     sar    al,7            ; Convert data byte into plane 2 value
  1473.     shl    ax,4            ; Shift data bits into position
  1474.     xchg    al,ah            ; Put bytes into correct order
  1475.     stosb                ; Store data bytes to screen memory
  1476.     shr    ah,5            ; Shift data bits into position
  1477.     lodsb                ; Get the next graphics data byte
  1478.     sar    al,7            ; Convert data byte into plane 2 value
  1479.     shl    ax,5            ; Shift data bits into position
  1480.     xchg    al,ah            ; Put bytes into correct order
  1481.     stosb                ; Store data bytes to screen memory
  1482.     shr    ah,6            ; Shift data bits into position
  1483.     lodsb                ; Get the next graphics data byte
  1484.     sar    al,7            ; Convert data byte into plane 2 value
  1485.     shl    ax,6            ; Shift data bits into position
  1486.     xchg    al,ah            ; Put bytes into correct order
  1487.     stosb                ; Store data bytes to screen memory
  1488.     shr    ah,7            ; Shift data bits into position
  1489.     lodsb                ; Get the next graphics data byte
  1490.     sar    al,7            ; Convert data byte into plane 2 value
  1491.     shl    ax,7            ; Shift data bits into position
  1492.     xchg    al,ah            ; Put bytes into correct order
  1493.     stosb                ; Store data bytes to screen memory
  1494.     dec    cl            ; Decrement the graphics byte counter
  1495.     jz    Byte_2_Done        ; Jump if all bytes have been moved
  1496.     jmp    Byte_2_Next        ; Go process more graphics bytes
  1497. Byte_2_Done:
  1498.     add    di,NEXT_ROW        ; Increment to the next graphics row
  1499.     dec    dl            ; Decrement the row counter
  1500.     jz    Row_2_Done        ; Jump if all rows have been moved
  1501.     jmp    Row_2_Next        ; Go process more graphics rows
  1502. Row_2_Done:
  1503.     add    si,MACRO_OFFSET     ; Increment source address value
  1504.     Restore di            ; Restore the destination index value
  1505.     add    di,NEXT_MACRO        ; Increment to the next macro line
  1506.     dec    dh            ; Decrement the macro counter value
  1507.     jz    Macro_2_Done        ; Jump if all macro lines are moved
  1508.     jmp    Macro_2_Next        ; Go process more macro lines
  1509. Macro_2_Done:
  1510.     Restore di            ; Restore the destination index value
  1511.     add    di,NEXT_SLICE        ; Increment to the next slice line
  1512.     dec    ch            ; Decrement the slice counter value
  1513.     jz    Restore_Done        ; Jump if restore is complete
  1514.     jmp    Slice_2_Next        ; Go process more slice sets
  1515. Restore_Done:
  1516.     ret                ; Return to the caller
  1517. Restore_High    Endp            ; End of the Restore_High procedure
  1518.     Subttl    Mixed_Update    Mixed Mode Update Routine
  1519.     Page    +
  1520. ;******************************************************************************
  1521. ;
  1522. ;    Mixed_Update()
  1523. ;
  1524. ;
  1525. ;        Return to the caller
  1526. ;
  1527. ;    Registers on Entry:
  1528. ;
  1529. ;        None
  1530. ;
  1531. ;    Registers on Exit:
  1532. ;
  1533. ;        None
  1534. ;
  1535. ;******************************************************************************
  1536.         Even            ; Force procedure to even address
  1537. Mixed_Update    Proc    Near        ; Mixed screen update procedure
  1538.  
  1539.     ret                ; Return to the caller
  1540. Mixed_Update    Endp            ; End of the Mixed_Update procedure
  1541.     Subttl    Color_Program    Program the Colors Routine
  1542.     Page    +
  1543. ;******************************************************************************
  1544. ;
  1545. ;    Color_Program()
  1546. ;
  1547. ;        Save the required registers
  1548. ;        If this is a text mode
  1549. ;            Setup to program colors for text (High res. display)
  1550. ;            If a low resolution display attached
  1551. ;                Setup colors for text (Low res. display)
  1552. ;            Endif
  1553. ;        Else this is a graphics mode
  1554. ;            If this is low resolution graphics
  1555. ;                Setup colors for low res. (High res. display)
  1556. ;                If a low resolution display attached
  1557. ;                    Setup for low res. (Low res. display)
  1558. ;                Endif
  1559. ;            Else this is high resolution graphics
  1560. ;                Setup colors for high res. (High res. display)
  1561. ;                If a low resolution display attached
  1562. ;                    Setup for high res. (Low res. display)
  1563. ;                Endif
  1564. ;            Endif for graphics mode
  1565. ;        Endif for video mode
  1566. ;        Program the color palette with new colors
  1567. ;        Restore the required registers
  1568. ;        Return to the caller
  1569. ;
  1570. ;    Registers on Entry:
  1571. ;
  1572. ;        None
  1573. ;
  1574. ;    Registers on Exit:
  1575. ;
  1576. ;        None
  1577. ;
  1578. ;******************************************************************************
  1579.         Even            ; Force procedure to even address
  1580. Color_Program    Proc    Near        ; Program the colors procedure
  1581.     Save    ax,dx,es        ; Save the required registers
  1582.     mov    al,cs:[Video_Flag]    ; Get the video system flag byte
  1583.     mov    ah,cs:[System_Flag]    ; Get the Apple system flag byte
  1584.     test    al,VIDEO_MODE        ; Check for a text or graphics mode
  1585.     jnz    Color_Graphics        ; Jump if this is a graphics mode
  1586. Color_Text:
  1587.     lea    dx,cs:[Text_EGA]    ; Setup for EGA display text colors
  1588.     test    ah,EGA_DISPLAY        ; Check for an EGA type display
  1589.     jnz    Color_Set        ; Jump if this is an EGA type display
  1590.     lea    dx,cs:[Text_CGA]    ; Setup for CGA display text colors
  1591.     jmp    Short Color_Set     ; Go set all of the color values
  1592. Color_Graphics:
  1593.     test    al,RESOLUTION        ; Check for low or high resolution
  1594.     jnz    Color_High        ; Jump if this is high resolution
  1595. Color_Low:
  1596.     lea    dx,cs:[Low_EGA]     ; Setup for EGA display low res. colors
  1597.     test    ah,EGA_DISPLAY        ; Check for an EGA type display
  1598.     jnz    Color_Set        ; Jump if this is an EGA type display
  1599.     lea    dx,cs:[Low_CGA]     ; Setup for CGA display low res. colors
  1600.     jmp    Short Color_Set     ; Go set all of the color values
  1601. Color_High:
  1602.     lea    dx,cs:[High_EGA]    ; Setup for EGA display high res. colors
  1603.     test    ah,EGA_DISPLAY        ; Check for an EGA type display
  1604.     jnz    Color_Set        ; Jump if this is an EGA type display
  1605.     lea    dx,cs:[High_CGA]    ; Setup for CGA display high res. colors
  1606. Color_Set:
  1607.     mov    ax,cs            ; Get the current CS register value
  1608.     mov    es,ax            ; Setup ES to the current CS value
  1609.     mov    ah,SET_PALETTE        ; Get the set palette function code
  1610.     mov    al,SET_ALL        ; Get set all sub-function code
  1611.     int    VIDEO            ; Program all of the color values
  1612. Color_Done:
  1613.     Restore ax,dx,es        ; Restore the required registers
  1614.     ret                ; Return to the caller
  1615. Color_Program    Endp            ; End of the Color_Program procedure
  1616.     Subttl    EGA_Restore    Restore Screen Routine
  1617.     Page    +
  1618. ;******************************************************************************
  1619. ;
  1620. ;    EGA_Restore(Video_Segment)
  1621. ;
  1622. ;        If this is text mode
  1623. ;            Set text mode 0 (40x25)
  1624. ;            Set video memory address to 0A000h
  1625. ;            Call routine to turn off cursor
  1626. ;            Call routine to enable blink (No intensity)
  1627. ;            Call the text restore routine
  1628. ;        Else this is a graphics mode
  1629. ;            If this is high resolution graphics
  1630. ;                Set graphics mode D (320 x 200)
  1631. ;                    If special update type in effect
  1632. ;                        If page 1 is selected
  1633. ;                            Get page 1 address
  1634. ;                        Else page 2 is selected
  1635. ;                            Get page 2 address
  1636. ;                        Endif for page number
  1637. ;                        Call routine to set address
  1638. ;                    Else standard update type
  1639. ;                        Call routine to restore graphics
  1640. ;                    Endif for update type
  1641. ;            Else this is low resolution graphics
  1642. ;                Set text mode 0 (40x25)
  1643. ;                Set video memory address to 0A000h
  1644. ;                Call routine to turn off cursor
  1645. ;                Call routine to enable intensity (No blink)
  1646. ;                Call the graphics restore routine
  1647. ;            Endif for graphics resolution
  1648. ;        Endif for video mode
  1649. ;        Call routine to program the colors
  1650. ;        Return to the caller
  1651. ;
  1652. ;    Registers on Entry:
  1653. ;
  1654. ;        ES    - Video segment
  1655. ;
  1656. ;    Registers on Exit:
  1657. ;
  1658. ;        AX    - Destroyed
  1659. ;
  1660. ;******************************************************************************
  1661.         Even            ; Force procedure to even address
  1662. EGA_Restore    Proc    Near        ; Restore screen procedure
  1663.     test    cs:[Video_Flag],VIDEO_MODE
  1664.     jnz    Mode_Graphics        ; Jump if this is a graphics mode
  1665. Mode_Text:
  1666.     mov    ah,SET_MODE        ; Get set mode video sub-function code
  1667.     mov    al,TEXT_MODE + NO_CLEAR ; Get the 40x25 text mode value
  1668.     int    VIDEO            ; Set video mode to 40x25 text mode
  1669.     Save    dx            ; Save the required registers
  1670.     mov    dx,GRA_INDEX        ; Get graphics controller index port
  1671.     mov    ax,TEXT_MAP        ; Get the text memory mapping value
  1672.     out    dx,ax            ; Set text memory to 0A000h
  1673.     Restore dx            ; Restore the required registers
  1674.     call    Cursor_Off        ; Call routine to turn cursor off
  1675.     call    Blink_On        ; Call routine to turn blink on
  1676.     call    Text_Restore        ; Call routine to restore text screen
  1677.     jmp    Short EGA_Done        ; Go return to the caller
  1678. Mode_Graphics:
  1679.     test    cs:[Video_Flag],RESOLUTION
  1680.     jnz    EGA_High
  1681. EGA_Low:
  1682.     mov    ah,SET_MODE        ; Get set mode video sub-function code
  1683.     mov    al,TEXT_MODE + NO_CLEAR ; Get the 40x25 text mode value
  1684.     int    VIDEO            ; Set video mode to 40x25 text mode
  1685.     Save    dx            ; Save the required registers
  1686.     mov    dx,GRA_INDEX        ; Get graphics controller index port
  1687.     mov    ax,TEXT_MAP        ; Get the text memory mapping value
  1688.     out    dx,ax            ; Set text memory to 0A000h
  1689.     Restore dx            ; Restore the required registers
  1690.     call    Cursor_Off        ; Call routine to turn cursor off
  1691.     call    Blink_Off        ; Call routine to turn blink off
  1692.     jmp    Short Do_EGA_Std    ; Go finish the EGA restore
  1693. EGA_High:
  1694.     mov    ah,SET_MODE        ; Get set mode video sub-function code
  1695.     mov    al,GRAPH_MODE + NO_CLEAR; Get the 320x200 graphics mode value
  1696.     int    VIDEO            ; Set video mode to 320x200 graphics
  1697.     test    cs:[Key_Status],TYPE_SPECIAL
  1698.     jz    Do_EGA_Std        ; Jump if standard update type
  1699. Do_EGA_Spc:
  1700.     mov    bp,BASE_GRAPHIC_1    ; Default to high resolution page 1
  1701.     test    cs:[Video_Flag],PAGE_NUMBER
  1702.     jz    Do_EGA_Set        ; Jump if this is page 1
  1703.     mov    bp,BASE_GRAPHIC_2    ; Setup for high resolution page 2
  1704. Do_EGA_Set:
  1705.     call    Set_Address        ; Call routine to set video address
  1706.     jmp    Short EGA_Done        ; Go return to the caller
  1707. Do_EGA_Std:
  1708.     call    Graphic_Restore     ; Call graphics screen restore routine
  1709. EGA_Done:
  1710.     call    Color_Program        ; Call routine to program the colors
  1711.     ret                ; Return to the caller
  1712. EGA_Restore    Endp            ; End of the EGA_Restore procedure
  1713.     Subttl    EGA_Setup    EGA Graphics Setup Routine
  1714.     Page    +
  1715. ;******************************************************************************
  1716. ;
  1717. ;    EGA_Setup(Video_Segment)
  1718. ;
  1719. ;        Save the required registers
  1720. ;        Set graphics mode D (320 x 200)
  1721. ;        Get graphics video memory base address
  1722. ;        Setup to write to plane 1
  1723. ;        Get the fill pattern byte value (55h)
  1724. ;        Get the fill size (16384 Bytes)
  1725. ;        Fill video memory with the fill pattern
  1726. ;        Restore the required registers
  1727. ;        Return to the caller
  1728. ;
  1729. ;    Registers on Entry:
  1730. ;
  1731. ;        ES    - Video segment
  1732. ;
  1733. ;    Registers on Exit:
  1734. ;
  1735. ;        None
  1736. ;
  1737. ;******************************************************************************
  1738.         Even            ; Force procedure to even address
  1739. EGA_Setup    Proc    Near        ; EGA graphics setup procedure
  1740.     Save    ax,cx,dx,di        ; Save the required registers
  1741.     mov    ah,SET_MODE        ; Get set mode video sub-function code
  1742.     mov    al,GRAPH_MODE        ; Get the 320x200 graphics mode value
  1743.     int    VIDEO            ; Set video mode to 320x200 graphics
  1744.     mov    di,BASE_GRAPHIC     ; Get graphics base memory address
  1745.     mov    dx,SEQ_INDEX        ; Get sequencer index port address
  1746.     mov    ax,PLANE_1 Shl 8 + MAP_MASK
  1747.     out    dx,ax            ; Setup to write to plane 1
  1748.     mov    al,FILL_PATTERN     ; Get the fill pattern byte value (55h)
  1749.     mov    cx,FILL_SIZE        ; Get the fill size (16384 Bytes)
  1750.     rep    stosb            ; Move fill pattern to video memory
  1751. Setup_Done:
  1752.     Restore ax,cx,dx,di        ; Restore the required registers
  1753.     ret                ; Return to the caller
  1754. EGA_Setup    Endp            ; End of the EGA_Setup procedure
  1755.     Subttl    Update_Toggle    Graphics Update Mode Toggle Routine
  1756.     Page    +
  1757. ;******************************************************************************
  1758. ;
  1759. ;    Update_Toggle()
  1760. ;
  1761. ;        If the last scan code does NOT match (NOT a repeat)
  1762. ;            If this is a make code
  1763. ;                If this is an EGA style adapter
  1764. ;                    Toggle the update mode bit
  1765. ;                    If this is a high-res. graphics mode
  1766. ;                        Call routine to update graphics
  1767. ;                    Endif for graphics mode
  1768. ;                Endif this is a CGA style adapter
  1769. ;            Endif this is a break code
  1770. ;        Endif this key is repeating
  1771. ;        Call routine to update the LED status
  1772. ;        Return to the caller
  1773. ;
  1774. ;    Registers on Entry:
  1775. ;
  1776. ;        None
  1777. ;
  1778. ;    Registers on Exit:
  1779. ;
  1780. ;        None
  1781. ;
  1782. ;******************************************************************************
  1783.         Even            ; Force procedure to even address
  1784. Update_Toggle    Proc    Near        ; Graphics update mode toggle procedure
  1785.     cmp    ah,cs:[Last_Key]    ; Check for a repeat scan code
  1786.     je    Update_Done        ; Jump if this key is repeating
  1787.     or    ah,ah            ; Check for a make or break code
  1788.     js    Update_Done        ; Jump if this is a break code
  1789.     test    cs:[System_Flag],EGA_TYPE
  1790.     jz    Update_Done        ; Jump if NOT an EGA style adapter
  1791.     xor    cs:[Key_Status],TYPE_SPECIAL
  1792.     test    cs:[Video_Flag],VIDEO_INV+RES_INV
  1793.     jnz    Update_Done        ; Jump if NOT high-res. graphics mode
  1794.     call    Graphic_Restore     ; Call routine to restore graphics
  1795. Update_Done:
  1796.     call    Set_LED         ; Call routine to update LED status
  1797.     ret                ; Return to the caller
  1798. Update_Toggle    Endp            ; End of the Update_Toggle procedure
  1799. ;******************************************************************************
  1800. ;
  1801. ;    Define the end of the Emulator Code Segment
  1802. ;
  1803. ;******************************************************************************
  1804. Emulate Ends
  1805.     End                ; End of the EGA module
  1806.