]> 4ch.mooo.com Git - 16.git/blobdiff - 16/keen456/KEEN4-6/ID_VW_AC.ASM
added keen 4-6 rebuild code for reference.... i need to stop doing this... xD
[16.git] / 16 / keen456 / KEEN4-6 / ID_VW_AC.ASM
diff --git a/16/keen456/KEEN4-6/ID_VW_AC.ASM b/16/keen456/KEEN4-6/ID_VW_AC.ASM
deleted file mode 100755 (executable)
index 80523b4..0000000
+++ /dev/null
@@ -1,1536 +0,0 @@
-; Reconstructed Commander Keen 4-6 Source Code\r
-; Copyright (C) 2021 K1n9_Duk3\r
-;\r
-; This file is primarily based on:\r
-; Catacomb 3-D Source Code\r
-; Copyright (C) 1993-2014 Flat Rock Software\r
-;\r
-; This program is free software; you can redistribute it and/or modify\r
-; it under the terms of the GNU General Public License as published by\r
-; the Free Software Foundation; either version 2 of the License, or\r
-; (at your option) any later version.\r
-;\r
-; This program is distributed in the hope that it will be useful,\r
-; but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-; GNU General Public License for more details.\r
-;\r
-; You should have received a copy of the GNU General Public License along\r
-; with this program; if not, write to the Free Software Foundation, Inc.,\r
-; 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
-\r
-;=================================\r
-;\r
-; CGA view manager routines\r
-;\r
-;=================================\r
-\r
-;============================================================================\r
-;\r
-; All of these routines draw into a floating virtual screen segment in main\r
-; memory.  bufferofs points to the origin of the drawing page in screenseg.\r
-; The routines that write out words must take into account buffer wrapping\r
-; and not write a word at 0xffff (which causes an exception on 386s).\r
-;\r
-; The direction flag should be clear\r
-;\r
-;============================================================================\r
-\r
-DATASEG\r
-\r
-plotpixels     db      0c0h,030h,0ch,03h\r
-colorbyte      db      000000b,01010101b,10101010b,11111111b\r
-colorword      dw      0,5555h,0aaaah,0ffffh\r
-\r
-CODESEG\r
-\r
-;============================================================================\r
-;\r
-; VW_Plot (int x,y,color)\r
-;\r
-;============================================================================\r
-\r
-\r
-PROC   VW_Plot x:WORD, y:WORD, color:WORD\r
-PUBLIC VW_Plot\r
-USES   SI,DI\r
-\r
-       mov     es,[screenseg]\r
-\r
-       mov     di,[bufferofs]\r
-       mov     bx,[y]\r
-       shl     bx,1\r
-       add     di,[ylookup+bx]\r
-       mov     bx,[x]\r
-       mov     ax,bx\r
-       shr     ax,1\r
-       shr     ax,1\r
-       add     di,ax                           ; di = byte on screen\r
-\r
-       and     bx,3\r
-       mov     ah,[plotpixels+bx]\r
-       mov     bx,[color]\r
-       mov     cl,[colorbyte+bx]\r
-       and     cl,ah\r
-       not     ah\r
-\r
-       mov     al,[es:di]\r
-       and     al,ah                           ; mask off other pixels\r
-       or      al,cl\r
-       stosb\r
-\r
-       ret\r
-\r
-ENDP\r
-\r
-\r
-;============================================================================\r
-;\r
-; VW_Vlin (int yl,yh,x,color)\r
-;\r
-;============================================================================\r
-\r
-PROC   VW_Vlin yl:WORD, yh:WORD, x:WORD, color:WORD\r
-PUBLIC VW_Vlin\r
-USES   SI,DI\r
-\r
-       mov     es,[screenseg]\r
-\r
-       mov     di,[bufferofs]\r
-       mov     bx,[yl]\r
-       shl     bx,1\r
-       add     di,[ylookup+bx]\r
-       mov     bx,[x]\r
-       mov     ax,bx\r
-       shr     ax,1\r
-       shr     ax,1\r
-       add     di,ax                           ; di = byte on screen\r
-\r
-       and     bx,3\r
-       mov     ah,[plotpixels+bx]\r
-       mov     bx,[color]\r
-       mov     bl,[colorbyte+bx]\r
-       and     bl,ah\r
-       not     ah\r
-\r
-       mov     cx,[yh]\r
-       sub     cx,[yl]\r
-       inc     cx                                      ;number of pixels to plot\r
-\r
-       mov     dx,[linewidth]\r
-\r
-@@plot:\r
-       mov     al,[es:di]\r
-       and     al,ah                           ; mask off other pixels\r
-       or      al,bl\r
-       mov [es:di],al\r
-       add     di,dx\r
-       loop    @@plot\r
-\r
-       ret\r
-\r
-       ret\r
-\r
-ENDP\r
-\r
-\r
-;============================================================================\r
-\r
-\r
-;===================\r
-;\r
-; VW_DrawTile8\r
-;\r
-; xcoord in bytes (8 pixels), ycoord in pixels\r
-; All Tile8s are in one grseg, so an offset is calculated inside it\r
-;\r
-; DONE\r
-;\r
-;===================\r
-\r
-PROC   VW_DrawTile8    xcoord:WORD, ycoord:WORD, tile:WORD\r
-PUBLIC VW_DrawTile8\r
-USES   SI,DI\r
-\r
-       mov     es,[screenseg]\r
-\r
-       mov     di,[bufferofs]\r
-       add     di,[xcoord]\r
-       mov     bx,[ycoord]\r
-       shl     bx,1\r
-       add     di,[ylookup+bx]\r
-\r
-       mov     bx,[linewidth]\r
-       sub     bx,2\r
-\r
-       mov     si,[tile]\r
-       shl     si,1\r
-       shl     si,1\r
-       shl     si,1\r
-       shl     si,1\r
-\r
-       mov     ds,[grsegs+STARTTILE8*2] ; segment for all tile8s\r
-\r
-;\r
-; start drawing\r
-;\r
-\r
-REPT   7\r
-       movsb                                           ;no word moves because of segment wrapping\r
-       movsb\r
-       add     di,bx\r
-ENDM\r
-       movsb\r
-       movsb\r
-\r
-       mov     ax,ss\r
-       mov     ds,ax                                   ;restore turbo's data segment\r
-\r
-       ret\r
-\r
-ENDP\r
-\r
-\r
-;============================================================================\r
-;\r
-; VW_MaskBlock\r
-;\r
-; Draws a masked block shape to the screen.  bufferofs is NOT accounted for.\r
-; The mask comes first, then the data.  Seperate unwound routines are used\r
-; to speed drawing.\r
-;\r
-; Mask blocks will allways be an even width because of the way IGRAB works\r
-;\r
-; DONE\r
-;\r
-;============================================================================\r
-\r
-DATASEG\r
-\r
-UNWOUNDMASKS   =       18\r
-\r
-\r
-maskroutines   dw      mask0,mask0,mask2E,mask2O,mask4E,mask4O\r
-                               dw      mask6E,mask6O,mask8E,mask8O,mask10E,mask10O\r
-                               dw      mask12E,mask12O,mask14E,mask14O,mask16E,mask16O\r
-                               dw      mask18E,mask18O\r
-\r
-\r
-routinetouse   dw      ?\r
-\r
-CODESEG\r
-\r
-PROC   VW_MaskBlock    segm:WORD, ofs:WORD, dest:WORD, wide:WORD, height:WORD, planesize:WORD\r
-PUBLIC VW_MaskBlock\r
-USES   SI,DI\r
-\r
-       mov     es,[screenseg]\r
-\r
-       mov     di,[wide]\r
-       mov     dx,[linewidth]\r
-       sub     dx,di                                   ;dx = delta to start of next line\r
-\r
-       mov     bx,[planesize]                  ; si+bx = data location\r
-\r
-       cmp     di,UNWOUNDMASKS\r
-       jbe     @@unwoundroutine\r
-\r
-;==============\r
-;\r
-; General purpose masked block drawing.  This could be optimised into\r
-; four routines to use words, but few play loop sprites should be this big!\r
-;\r
-;==============\r
-\r
-       mov     [ss:linedelta],dx\r
-       mov     ds,[segm]\r
-       mov     si,[ofs]\r
-       mov     di,[dest]\r
-       mov     dx,[height]                             ;scan lines to draw\r
-\r
-@@lineloopgen:\r
-       mov     cx,[wide]\r
-@@byteloop:\r
-       mov     al,[es:di]\r
-       and     al,[si]\r
-       or      al,[bx+si]\r
-       inc     si\r
-       stosb\r
-       loop    @@byteloop\r
-\r
-       add     di,[ss:linedelta]\r
-       dec     dx\r
-       jnz     @@lineloopgen\r
-\r
-mask0:\r
-       mov     ax,ss\r
-       mov     ds,ax\r
-       ret                                                     ;width of 0 = no drawing\r
-\r
-\r
-;=================\r
-;\r
-; use the unwound routines\r
-;\r
-;=================\r
-\r
-@@unwoundroutine:\r
-       shr     di,1                                    ;we only have even width unwound routines\r
-       mov     cx,[dest]\r
-       shr     cx,1\r
-       rcl     di,1                                    ;shift a 1 in if destination is odd\r
-       shl     di,1\r
-       mov     ax,[maskroutines+di]    ;call the right routine\r
-\r
-       mov     ds,[segm]\r
-       mov     si,[ofs]\r
-       mov     di,[dest]\r
-       mov     cx,[height]                             ;scan lines to draw\r
-\r
-       jmp ax                                          ;draw it\r
-\r
-;=================\r
-;\r
-; Horizontally unwound routines to draw certain masked blocks faster\r
-;\r
-;=================\r
-\r
-MACRO  MASKBYTE\r
-       mov     al,[es:di]\r
-       and     al,[si]\r
-       or      al,[bx+si]\r
-       inc     si\r
-       stosb\r
-ENDM\r
-\r
-MACRO  MASKWORD\r
-       mov     ax,[es:di]\r
-       and     ax,[si]\r
-       or      ax,[bx+si]\r
-       inc     si\r
-       inc     si\r
-       stosw\r
-ENDM\r
-\r
-MACRO  SPRITELOOP      addr\r
-       add     di,dx\r
-       loop    addr\r
-       mov     ax,ss\r
-       mov     ds,ax\r
-       ret\r
-ENDM\r
-\r
-\r
-EVEN\r
-mask2E:\r
-       MASKWORD\r
-       SPRITELOOP      mask2E\r
-\r
-EVEN\r
-mask2O:\r
-       MASKBYTE\r
-       MASKBYTE\r
-       SPRITELOOP      mask2O\r
-\r
-EVEN\r
-mask4E:\r
-       MASKWORD\r
-       MASKWORD\r
-       SPRITELOOP      mask4E\r
-\r
-EVEN\r
-mask4O:\r
-       MASKBYTE\r
-       MASKWORD\r
-       MASKBYTE\r
-       SPRITELOOP      mask4O\r
-\r
-EVEN\r
-mask6E:\r
-       MASKWORD\r
-       MASKWORD\r
-       MASKWORD\r
-       SPRITELOOP      mask6E\r
-\r
-EVEN\r
-mask6O:\r
-       MASKBYTE\r
-       MASKWORD\r
-       MASKWORD\r
-       MASKBYTE\r
-       SPRITELOOP      mask6O\r
-\r
-EVEN\r
-mask8E:\r
-       MASKWORD\r
-       MASKWORD\r
-       MASKWORD\r
-       MASKWORD\r
-       SPRITELOOP      mask8E\r
-\r
-EVEN\r
-mask8O:\r
-       MASKBYTE\r
-       MASKWORD\r
-       MASKWORD\r
-       MASKWORD\r
-       MASKBYTE\r
-       SPRITELOOP      mask8O\r
-\r
-EVEN\r
-mask10E:\r
-       MASKWORD\r
-       MASKWORD\r
-       MASKWORD\r
-       MASKWORD\r
-       MASKWORD\r
-       SPRITELOOP      mask10E\r
-\r
-EVEN\r
-mask10O:\r
-       MASKBYTE\r
-       MASKWORD\r
-       MASKWORD\r
-       MASKWORD\r
-       MASKWORD\r
-       MASKBYTE\r
-       SPRITELOOP      mask10O\r
-\r
-EVEN\r
-mask12E:\r
-       MASKWORD\r
-       MASKWORD\r
-       MASKWORD\r
-       MASKWORD\r
-       MASKWORD\r
-       MASKWORD\r
-       SPRITELOOP      mask12E\r
-\r
-EVEN\r
-mask12O:\r
-       MASKBYTE\r
-       MASKWORD\r
-       MASKWORD\r
-       MASKWORD\r
-       MASKWORD\r
-       MASKWORD\r
-       MASKBYTE\r
-       SPRITELOOP      mask12O\r
-\r
-EVEN\r
-mask14E:\r
-       MASKWORD\r
-       MASKWORD\r
-       MASKWORD\r
-       MASKWORD\r
-       MASKWORD\r
-       MASKWORD\r
-       MASKWORD\r
-       SPRITELOOP      mask14E\r
-\r
-EVEN\r
-mask14O:\r
-       MASKBYTE\r
-       MASKWORD\r
-       MASKWORD\r
-       MASKWORD\r
-       MASKWORD\r
-       MASKWORD\r
-       MASKWORD\r
-       MASKBYTE\r
-       SPRITELOOP      mask14O\r
-\r
-EVEN\r
-mask16E:\r
-       MASKWORD\r
-       MASKWORD\r
-       MASKWORD\r
-       MASKWORD\r
-       MASKWORD\r
-       MASKWORD\r
-       MASKWORD\r
-       MASKWORD\r
-       SPRITELOOP      mask16E\r
-\r
-EVEN\r
-mask16O:\r
-       MASKBYTE\r
-       MASKWORD\r
-       MASKWORD\r
-       MASKWORD\r
-       MASKWORD\r
-       MASKWORD\r
-       MASKWORD\r
-       MASKWORD\r
-       MASKBYTE\r
-       SPRITELOOP      mask16O\r
-\r
-EVEN\r
-mask18E:\r
-       MASKWORD\r
-       MASKWORD\r
-       MASKWORD\r
-       MASKWORD\r
-       MASKWORD\r
-       MASKWORD\r
-       MASKWORD\r
-       MASKWORD\r
-       MASKWORD\r
-       SPRITELOOP      mask18E\r
-\r
-EVEN\r
-mask18O:\r
-       MASKBYTE\r
-       MASKWORD\r
-       MASKWORD\r
-       MASKWORD\r
-       MASKWORD\r
-       MASKWORD\r
-       MASKWORD\r
-       MASKWORD\r
-       MASKWORD\r
-       MASKBYTE\r
-       SPRITELOOP      mask18O\r
-\r
-\r
-ENDP\r
-\r
-\r
-;============================================================================\r
-;\r
-; VW_InverseMask\r
-;\r
-; Draws a masked block shape to the screen.  bufferofs is NOT accounted for.\r
-; The mask comes first, then the data.\r
-;\r
-; Mask blocks will allways be an even width because of the way IGRAB works\r
-;\r
-;============================================================================\r
-\r
-PROC   VW_InverseMask  segm:WORD, ofs:WORD, dest:WORD, wide:WORD, height:WORD\r
-PUBLIC VW_InverseMask\r
-USES   SI,DI\r
-\r
-       mov     es, [screenseg]\r
-       mov     ax, [wide]\r
-       mov     dx, [linewidth]\r
-       sub     dx, ax;\r
-       mov     ds, [segm]\r
-       mov     si, [ofs]\r
-       mov     di, [dest]\r
-       mov     bx, [height]\r
-       shr     [wide], 1\r
-@@yloop:\r
-       mov     cx, [wide]\r
-@@xloop:\r
-       lodsw\r
-       not     ax\r
-       or      [es:di], ax\r
-       inc     di\r
-       inc     di\r
-       loop    @@xloop\r
-       add     di, dx\r
-       dec     bx\r
-       jnz     @@yloop\r
-\r
-       mov     ax,ss\r
-       mov     ds,ax                                   ;restore turbo's data segment\r
-\r
-       ret\r
-ENDP\r
-\r
-\r
-;============================================================================\r
-;\r
-; VW_ScreenToScreen\r
-;\r
-; Basic block copy routine.  Copies one block of screen memory to another,\r
-; bufferofs is NOT accounted for.\r
-;\r
-; DONE\r
-;\r
-;============================================================================\r
-\r
-PROC   VW_ScreenToScreen       source:WORD, dest:WORD, wide:WORD, height:WORD\r
-PUBLIC VW_ScreenToScreen\r
-USES   SI,DI\r
-\r
-       mov     bx,[linewidth]\r
-       sub     bx,[wide]\r
-\r
-       mov     ax,[screenseg]\r
-       mov     es,ax\r
-       mov     ds,ax\r
-\r
-       mov     si,[source]\r
-       mov     di,[dest]                               ;start at same place in all planes\r
-       mov     dx,[height]                             ;scan lines to draw\r
-       mov     ax,[wide]\r
-;\r
-; if the width, source, and dest are all even, use word moves\r
-; This is allways the case in the CGA refresh\r
-;\r
-       test    ax,1\r
-       jnz     @@bytelineloop\r
-       test    si,1\r
-       jnz     @@bytelineloop\r
-       test    di,1\r
-       jnz     @@bytelineloop\r
-\r
-       shr     ax,1\r
-@@wordlineloop:\r
-       mov     cx,ax\r
-       rep     movsw\r
-       add     si,bx\r
-       add     di,bx\r
-\r
-       dec     dx\r
-       jnz     @@wordlineloop\r
-\r
-       mov     ax,ss\r
-       mov     ds,ax                                   ;restore turbo's data segment\r
-\r
-       ret\r
-\r
-@@bytelineloop:\r
-       mov     cx,ax\r
-       rep     movsb\r
-       add     si,bx\r
-       add     di,bx\r
-\r
-       dec     dx\r
-       jnz     @@bytelineloop\r
-\r
-       mov     ax,ss\r
-       mov     ds,ax                                   ;restore turbo's data segment\r
-\r
-       ret\r
-\r
-ENDP\r
-\r
-\r
-;============================================================================\r
-;\r
-; VW_MemToScreen\r
-;\r
-; Basic block drawing routine. Takes a block shape at segment pointer source\r
-; of width by height data, and draws it to dest in the virtual screen,\r
-; based on linewidth.  bufferofs is NOT accounted for.\r
-; There are four drawing routines to provide the best optimized code while\r
-; accounting for odd segment wrappings due to the floating screens.\r
-;\r
-; DONE\r
-;\r
-;============================================================================\r
-\r
-DATASEG\r
-\r
-memtoscreentable       dw      eventoeven,eventoodd,oddtoeven,oddtoodd\r
-\r
-CODESEG\r
-\r
-\r
-PROC   VW_MemToScreen  source:WORD, dest:WORD, wide:WORD, height:WORD\r
-PUBLIC VW_MemToScreen\r
-USES   SI,DI\r
-\r
-       mov     es,[screenseg]\r
-\r
-       mov     bx,[linewidth]\r
-       sub     bx,[wide]\r
-\r
-       mov     ds,[source]\r
-\r
-       xor     si,si                                   ;block is segment aligned\r
-\r
-       xor     di,di\r
-       shr     [wide],1                                ;change wide to words, and see if carry is set\r
-       rcl     di,1                                    ;1 if wide is odd\r
-       mov     ax,[dest]\r
-       shr     ax,1\r
-       rcl     di,1                                    ;shift a 1 in if destination is odd\r
-       shl     di,1                                    ;to index into a word width table\r
-       mov     dx,[height]                             ;scan lines to draw\r
-       mov     ax,[wide]\r
-       jmp     [ss:memtoscreentable+di]        ;call the right routine\r
-\r
-;==============\r
-;\r
-; Copy an even width block to an even destination address\r
-;\r
-;==============\r
-\r
-eventoeven:\r
-       mov     di,[dest]                               ;start at same place in all planes\r
-EVEN\r
-@@lineloopEE:\r
-       mov     cx,ax\r
-       rep     movsw\r
-       add     di,bx\r
-       dec     dx\r
-       jnz     @@lineloopEE\r
-\r
-       mov     ax,ss\r
-       mov     ds,ax                                   ;restore turbo's data segment\r
-\r
-       ret\r
-\r
-;==============\r
-;\r
-; Copy an odd width block to an even video address\r
-;\r
-;==============\r
-\r
-oddtoeven:\r
-       mov     di,[dest]                               ;start at same place in all planes\r
-EVEN\r
-@@lineloopOE:\r
-       mov     cx,ax\r
-       rep     movsw\r
-       movsb                                           ;copy the last byte\r
-       add     di,bx\r
-       dec     dx\r
-       jnz     @@lineloopOE\r
-\r
-       mov     ax,ss\r
-       mov     ds,ax                                   ;restore turbo's data segment\r
-\r
-       ret\r
-\r
-;==============\r
-;\r
-; Copy an even width block to an odd video address\r
-;\r
-;==============\r
-\r
-eventoodd:\r
-       mov     di,[dest]                               ;start at same place in all planes\r
-       dec     ax                                              ;one word has to be handled seperately\r
-EVEN\r
-@@lineloopEO:\r
-       movsb\r
-       mov     cx,ax\r
-       rep     movsw\r
-       movsb\r
-       add     di,bx\r
-       dec     dx\r
-       jnz     @@lineloopEO\r
-\r
-       mov     ax,ss\r
-       mov     ds,ax                                   ;restore turbo's data segment\r
-\r
-       ret\r
-\r
-;==============\r
-;\r
-; Copy an odd width block to an odd video address\r
-;\r
-;==============\r
-\r
-oddtoodd:\r
-       mov     di,[dest]                               ;start at same place in all planes\r
-EVEN\r
-@@lineloopOO:\r
-       movsb\r
-       mov     cx,ax\r
-       rep     movsw\r
-       add     di,bx\r
-       dec     dx\r
-       jnz     @@lineloopOO\r
-\r
-       mov     ax,ss\r
-       mov     ds,ax                                   ;restore turbo's data segment\r
-       ret\r
-\r
-\r
-ENDP\r
-\r
-;===========================================================================\r
-;\r
-; VW_ScreenToMem\r
-;\r
-; Copies a block of video memory to main memory, in order from planes 0-3.\r
-; This could be optimized along the lines of VW_MemToScreen to take advantage\r
-; of word copies, but this is an infrequently called routine.\r
-;\r
-; DONE\r
-;\r
-;===========================================================================\r
-\r
-PROC   VW_ScreenToMem  source:WORD, dest:WORD, wide:WORD, height:WORD\r
-PUBLIC VW_ScreenToMem\r
-USES   SI,DI\r
-\r
-       mov     es,[dest]\r
-\r
-       mov     bx,[linewidth]\r
-       sub     bx,[wide]\r
-\r
-       mov     ds,[screenseg]\r
-\r
-       xor     di,di\r
-\r
-       mov     si,[source]\r
-       mov     dx,[height]                             ;scan lines to draw\r
-\r
-@@lineloop:\r
-       mov     cx,[wide]\r
-       rep     movsb\r
-\r
-       add     si,bx\r
-\r
-       dec     dx\r
-       jnz     @@lineloop\r
-\r
-       mov     ax,ss\r
-       mov     ds,ax                                   ;restore turbo's data segment\r
-\r
-       ret\r
-\r
-ENDP\r
-\r
-\r
-;===========================================================================\r
-;\r
-;                    MISC CGA ROUTINES\r
-;\r
-;===========================================================================\r
-\r
-;==============\r
-;\r
-; VW_SetScreen\r
-;\r
-; DONE\r
-;\r
-;==============\r
-\r
-PROC   VW_SetScreen  crtc:WORD\r
-PUBLIC VW_SetScreen\r
-\r
-;\r
-; for some reason, my XT's EGA card doesn't like word outs to the CRTC\r
-; index...\r
-;\r
-       cli\r
-\r
-       mov     cx,[crtc]\r
-       mov     dx,CRTC_INDEX\r
-       mov     al,0ch          ;start address high register\r
-       out     dx,al\r
-       inc     dx\r
-       mov     al,ch\r
-       out     dx,al\r
-       dec     dx\r
-       mov     al,0dh          ;start address low register\r
-       out     dx,al\r
-       mov     al,cl\r
-       inc     dx\r
-       out     dx,al\r
-\r
-       sti\r
-\r
-       ret\r
-\r
-ENDP\r
-\r
-\r
-if NUMFONT+NUMFONTM\r
-\r
-;===========================================================================\r
-;\r
-; GENERAL FONT DRAWING ROUTINES\r
-;\r
-;===========================================================================\r
-\r
-DATASEG\r
-\r
-px     dw      ?                                       ; proportional character drawing coordinates\r
-py     dw      ?\r
-pdrawmode      db      11000b          ; 8 = OR, 24 = XOR, put in GC_DATAROTATE\r
-fontcolor      db      15              ;0-15 mapmask value\r
-\r
-PUBLIC px,py,pdrawmode,fontcolor\r
-\r
-;\r
-; offsets in font structure\r
-;\r
-pcharheight    =       0               ;lines high\r
-charloc                =       2               ;pointers to every character\r
-charwidth      =       514             ;every character's width in pixels\r
-\r
-\r
-propchar       dw      ?                       ; the character number to shift\r
-stringptr      dw      ?,?\r
-\r
-fontcolormask  dw      ?                       ; font color expands into this\r
-\r
-BUFFWIDTH      =       100\r
-BUFFHEIGHT     =   32                  ; must be twice as high as font for masked fonts\r
-\r
-databuffer     db      BUFFWIDTH*BUFFHEIGHT dup (?)\r
-\r
-bufferwidth    dw      ?                                               ; bytes with valid info / line\r
-bufferheight dw        ?                                               ; number of lines currently used\r
-\r
-bufferbyte     dw      ?\r
-bufferbit      dw      ?\r
-PUBLIC bufferwidth,bufferheight,bufferbyte,bufferbit\r
-\r
-screenspot     dw      ?                                               ; where the buffer is going\r
-\r
-bufferextra    dw      ?                                               ; add at end of a line copy\r
-screenextra    dw      ?\r
-\r
-CODESEG\r
-\r
-;======================\r
-;\r
-; Macros to table shift a byte of font\r
-;\r
-;======================\r
-\r
-MACRO  SHIFTNOXOR\r
-       mov     al,[es:bx]              ; source\r
-       xor     ah,ah\r
-       shl     ax,1\r
-       mov     si,ax\r
-       mov     ax,[bp+si]              ; table shift into two bytes\r
-       or      [di],al                 ; or with first byte\r
-       inc     di\r
-       mov     [di],ah                 ; replace next byte\r
-       inc     bx                              ; next source byte\r
-ENDM\r
-\r
-MACRO  SHIFTWITHXOR\r
-       mov     al,[es:bx]              ; source\r
-       xor     ah,ah\r
-       shl     ax,1\r
-       mov     si,ax\r
-       mov     ax,[bp+si]              ; table shift into two bytes\r
-       not     ax\r
-       and     [di],al                 ; and with first byte\r
-       inc     di\r
-       mov     [di],ah                 ; replace next byte\r
-       inc     bx                              ; next source byte\r
-ENDM\r
-\r
-\r
-;=======================\r
-;\r
-; VWL_XORBuffer\r
-;\r
-; Pass buffer start in SI (somewhere in databuffer)\r
-; Draws the buffer to the screen buffer\r
-;\r
-;========================\r
-\r
-PROC   VWL_XORBuffer   NEAR\r
-USES   BP\r
-       mov     bl,[fontcolor]\r
-       xor     bh,bh\r
-       shl     bx,1\r
-       mov     ax,[colorword+bx]\r
-       mov     [fontcolormask],ax\r
-\r
-       mov     es,[screenseg]\r
-       mov     di,[screenspot]\r
-\r
-       mov     bx,[bufferwidth]                ;calculate offsets for end of each line\r
-       mov     [bufferwidth],bx\r
-\r
-       or      bx,bx\r
-       jnz     @@isthere\r
-       ret                                                     ;nothing to draw\r
-\r
-@@isthere:\r
-       test    bx,1\r
-       jnz     @@odd\r
-       jmp     @@even\r
-;\r
-; clear the last byte so word draws can be used\r
-;\r
-@@odd:\r
-       mov     al,0\r
-line   =       0\r
-REPT   BUFFHEIGHT\r
-       mov     [BYTE databuffer+BUFFWIDTH*line+bx],al\r
-line   =       line+1\r
-ENDM\r
-\r
-       inc     bx\r
-@@even:\r
-       mov     ax,[linewidth]\r
-       sub     ax,bx\r
-       mov     [screenextra],ax\r
-       mov     ax,BUFFWIDTH\r
-       sub     ax,bx\r
-       mov     [bufferextra],ax\r
-       mov     dx,bx\r
-\r
-       mov     bx,[bufferheight]               ;lines to copy\r
-       mov     bp,[fontcolormask]\r
-@@lineloop:\r
-       mov     cx,dx\r
-@@byteloop:\r
-       lodsb                                           ;get a word from the buffer\r
-       and     ax,bp\r
-       xor     [es:di],al                              ;draw it\r
-       inc     di\r
-       loop    @@byteloop\r
-\r
-       add     si,[bufferextra]\r
-       add     di,[screenextra]\r
-\r
-       dec     bx\r
-       jnz     @@lineloop\r
-\r
-       ret\r
-ENDP\r
-\r
-\r
-DATASEG\r
-\r
-;============================================================================\r
-;\r
-; NON MASKED FONT DRAWING ROUTINES\r
-;\r
-;============================================================================\r
-\r
-if numfont\r
-\r
-DATASEG\r
-\r
-shiftdrawtable dw      0,shift1wide,shift2wide,shift3wide,shift4wide\r
-                               dw              shift5wide,shift6wide\r
-\r
-CODESEG\r
-\r
-;==================\r
-;\r
-; ShiftPropChar\r
-;\r
-; Call with BX = character number (0-255)\r
-; Draws one character to the buffer at bufferbyte/bufferbit, and adjusts\r
-; them to the new position\r
-;\r
-;==================\r
-\r
-PROC   ShiftPropChar   NEAR\r
-\r
-       mov     si,[fontnumber]\r
-       shl     si,1\r
-       mov     es,[grsegs+STARTFONT*2+si]      ;segment of font to use\r
-\r
-;\r
-; find character location, width, and height\r
-;\r
-       mov     si,[es:charwidth+bx]\r
-       and     si,0ffh                                 ;SI hold width in pixels\r
-       shl     bx,1\r
-       mov     bx,[es:charloc+bx]              ;BX holds pointer to character data\r
-\r
-;\r
-; look up which shift table to use, based on bufferbit\r
-;\r
-       mov     di,[bufferbit]\r
-       shl     di,1\r
-       mov     bp,[shifttabletable+di] ;BP holds pointer to shift table\r
-\r
-       mov     di,OFFSET databuffer\r
-       add     di,[bufferbyte]                 ;DI holds pointer to buffer\r
-\r
-       mov     cx,[bufferbit]\r
-       add     cx,si                                   ;add twice because pixel == two bits\r
-       add     cx,si                                   ;new bit position\r
-       mov     ax,cx\r
-       and     ax,7\r
-       mov     [bufferbit],ax                  ;new bit position\r
-       mov     ax,cx\r
-       shr     ax,1\r
-       shr     ax,1\r
-       shr     ax,1\r
-       add     [bufferbyte],ax                 ;new byte position\r
-\r
-       add     si,3\r
-       shr     si,1\r
-       shr     si,1                                    ;bytes the character is wide\r
-       shl     si,1                    ;*2 to look up in shiftdrawtable\r
-\r
-       mov     cx,[es:pcharheight]\r
-       mov     dx,BUFFWIDTH\r
-       jmp     [ss:shiftdrawtable+si]  ;procedure to draw this width\r
-\r
-;\r
-; one byte character\r
-;\r
-shift1wide:\r
-       dec     dx\r
-EVEN\r
-@@loop1:\r
-       SHIFTNOXOR\r
-       add     di,dx                   ; next line in buffer\r
-\r
-       loop    @@loop1\r
-\r
-       ret\r
-\r
-;\r
-; two byte character\r
-;\r
-shift2wide:\r
-       dec     dx\r
-       dec     dx\r
-EVEN\r
-@@loop2:\r
-       SHIFTNOXOR\r
-       SHIFTNOXOR\r
-       add     di,dx                   ; next line in buffer\r
-\r
-       loop    @@loop2\r
-\r
-       ret\r
-\r
-;\r
-; three byte character\r
-;\r
-shift3wide:\r
-       sub     dx,3\r
-EVEN\r
-@@loop3:\r
-       SHIFTNOXOR\r
-       SHIFTNOXOR\r
-       SHIFTNOXOR\r
-       add     di,dx                   ; next line in buffer\r
-\r
-       loop    @@loop3\r
-\r
-       ret\r
-\r
-\r
-;\r
-; four byte character\r
-;\r
-shift4wide:\r
-       sub     dx,4\r
-EVEN\r
-@@loop4:\r
-       SHIFTNOXOR\r
-       SHIFTNOXOR\r
-       SHIFTNOXOR\r
-       SHIFTNOXOR\r
-       add     di,dx                   ; next line in buffer\r
-\r
-       loop    @@loop4\r
-\r
-       ret\r
-\r
-\r
-;\r
-; five byte character\r
-;\r
-shift5wide:\r
-       sub     dx,5\r
-EVEN\r
-@@loop5:\r
-       SHIFTNOXOR\r
-       SHIFTNOXOR\r
-       SHIFTNOXOR\r
-       SHIFTNOXOR\r
-       SHIFTNOXOR\r
-       add     di,dx                   ; next line in buffer\r
-\r
-       loop    @@loop5\r
-\r
-       ret\r
-\r
-;\r
-; six byte character\r
-;\r
-shift6wide:\r
-       sub     dx,6\r
-EVEN\r
-@@loop6:\r
-       SHIFTNOXOR\r
-       SHIFTNOXOR\r
-       SHIFTNOXOR\r
-       SHIFTNOXOR\r
-       SHIFTNOXOR\r
-       SHIFTNOXOR\r
-       add     di,dx                   ; next line in buffer\r
-\r
-       loop    @@loop6\r
-\r
-       ret\r
-\r
-\r
-\r
-ENDP\r
-\r
-;============================================================================\r
-\r
-;==================\r
-;\r
-; VW_DrawPropString\r
-;\r
-; Draws a C string of characters at px/py and advances px\r
-;\r
-;==================\r
-\r
-CODESEG\r
-\r
-PROC   VW_DrawPropString       string:DWORD\r
-PUBLIC VW_DrawPropString\r
-USES   SI,DI\r
-\r
-;\r
-; proportional spaceing, which clears the buffer ahead of it, so only\r
-; clear the first collumn\r
-;\r
-       mov     al,0\r
-line   =       0\r
-REPT   BUFFHEIGHT\r
-       mov     [BYTE databuffer+BUFFWIDTH*line],al\r
-line   =       line+1\r
-ENDM\r
-\r
-;\r
-; shift the characters into the buffer\r
-;\r
-@@shiftchars:\r
-       mov     ax,[px]\r
-       and     ax,3\r
-       shl     ax,1                    ;one pixel == two bits\r
-       mov     [bufferbit],ax\r
-       mov     [bufferbyte],0\r
-\r
-       mov     ax,[WORD string]\r
-       mov     [stringptr],ax\r
-       mov     ax,[WORD string+2]\r
-       mov     [stringptr+2],ax\r
-\r
-@@shiftone:\r
-       mov     es,[stringptr+2]\r
-       mov     bx,[stringptr]\r
-       inc     [stringptr]\r
-       mov     bx,[es:bx]\r
-       xor     bh,bh\r
-       or      bl,bl\r
-       jz      @@allshifted\r
-       call    ShiftPropChar\r
-       jmp     @@shiftone\r
-\r
-@@allshifted:\r
-;\r
-; calculate position to draw buffer on screen\r
-;\r
-       mov     bx,[py]\r
-       shl     bx,1\r
-       mov     di,[ylookup+bx]\r
-       add     di,[bufferofs]\r
-       add     di,[panadjust]\r
-\r
-       mov     ax,[px]\r
-       shr     ax,1\r
-       shr     ax,1            ;x location in bytes\r
-       add     di,ax\r
-       mov     [screenspot],di\r
-\r
-;\r
-; advance px\r
-;\r
-       mov     ax,[bufferbyte]\r
-       shl     ax,1\r
-       shl     ax,1\r
-       mov     bx,[bufferbit]\r
-       shr     bx,1                    ;two bits == one pixel\r
-       or      ax,bx\r
-       add     [px],ax\r
-\r
-;\r
-; draw it\r
-;\r
-       mov     ax,[bufferbyte]\r
-       test    [bufferbit],7\r
-       jz      @@go\r
-       inc     ax                              ;so the partial byte also gets drawn\r
-@@go:\r
-       mov     [bufferwidth],ax\r
-       mov     si,[fontnumber]\r
-       shl     si,1\r
-       mov     es,[grsegs+STARTFONT*2+si]\r
-       mov     ax,[es:pcharheight]\r
-       mov     [bufferheight],ax\r
-\r
-       mov     si,OFFSET databuffer\r
-       call    VWL_XORBuffer\r
-\r
-       ret\r
-\r
-ENDP\r
-\r
-endif  ;numfont\r
-\r
-;============================================================================\r
-;\r
-; MASKED FONT DRAWING ROUTINES\r
-;\r
-;============================================================================\r
-\r
-if     numfontm\r
-\r
-DATASEG\r
-\r
-mshiftdrawtable        dw      0,mshift1wide,mshift2wide,mshift3wide\r
-\r
-\r
-CODESEG\r
-\r
-;==================\r
-;\r
-; ShiftMPropChar\r
-;\r
-; Call with BX = character number (0-255)\r
-; Draws one character to the buffer at bufferbyte/bufferbit, and adjusts\r
-; them to the new position\r
-;\r
-;==================\r
-\r
-PROC   ShiftMPropChar  NEAR\r
-\r
-       mov     es,[grsegs+STARTFONTM*2]        ;segment of font to use\r
-\r
-;\r
-; find character location, width, and height\r
-;\r
-       mov     si,[es:charwidth+bx]\r
-       and     si,0ffh                                 ;SI hold width in pixels\r
-       shl     bx,1\r
-       mov     bx,[es:charloc+bx]              ;BX holds pointer to character data\r
-\r
-;\r
-; look up which shift table to use, based on bufferbit\r
-;\r
-       mov     di,[bufferbit]\r
-       shl     di,1\r
-       mov     bp,[shifttabletable+di] ;BP holds pointer to shift table\r
-\r
-       mov     di,OFFSET databuffer\r
-       add     di,[bufferbyte]                 ;DI holds pointer to buffer\r
-\r
-;\r
-; advance position by character width\r
-;\r
-       mov     cx,[bufferbit]\r
-       add     cx,si                                   ;new bit position\r
-       mov     ax,cx\r
-       and     ax,7\r
-       mov     [bufferbit],ax                  ;new bit position\r
-       mov     ax,cx\r
-       shr     ax,1\r
-       shr     ax,1\r
-       shr     ax,1\r
-       add     [bufferbyte],ax                 ;new byte position\r
-\r
-       add     si,7\r
-       shr     si,1\r
-       shr     si,1\r
-       shr     si,1                                    ;bytes the character is wide\r
-       shl     si,1                    ;*2 to look up in shiftdrawtable\r
-\r
-       mov     cx,[es:pcharheight]\r
-       mov     dx,BUFFWIDTH\r
-       jmp     [ss:mshiftdrawtable+si] ;procedure to draw this width\r
-\r
-;\r
-; one byte character\r
-;\r
-mshift1wide:\r
-       dec     dx\r
-\r
-EVEN\r
-@@loop1m:\r
-       SHIFTWITHXOR\r
-       add     di,dx                   ; next line in buffer\r
-\r
-       loop    @@loop1m\r
-\r
-       mov     cx,[es:pcharheight]\r
-\r
-EVEN\r
-@@loop1:\r
-       SHIFTNOXOR\r
-       add     di,dx                   ; next line in buffer\r
-       loop    @@loop1\r
-\r
-       ret\r
-\r
-;\r
-; two byte character\r
-;\r
-mshift2wide:\r
-       dec     dx\r
-       dec     dx\r
-EVEN\r
-@@loop2m:\r
-       SHIFTWITHXOR\r
-       SHIFTWITHXOR\r
-       add     di,dx                   ; next line in buffer\r
-\r
-       loop    @@loop2m\r
-\r
-       mov     cx,[es:pcharheight]\r
-\r
-EVEN\r
-@@loop2:\r
-       SHIFTNOXOR\r
-       SHIFTNOXOR\r
-       add     di,dx                   ; next line in buffer\r
-       loop    @@loop2\r
-\r
-       ret\r
-\r
-;\r
-; three byte character\r
-;\r
-mshift3wide:\r
-       sub     dx,3\r
-EVEN\r
-@@loop3m:\r
-       SHIFTWITHXOR\r
-       SHIFTWITHXOR\r
-       SHIFTWITHXOR\r
-       add     di,dx                   ; next line in buffer\r
-\r
-       loop    @@loop3m\r
-\r
-       mov     cx,[es:pcharheight]\r
-\r
-EVEN\r
-@@loop3:\r
-       SHIFTNOXOR\r
-       SHIFTNOXOR\r
-       SHIFTNOXOR\r
-       add     di,dx                   ; next line in buffer\r
-       loop    @@loop3\r
-\r
-       ret\r
-\r
-\r
-ENDP\r
-\r
-;============================================================================\r
-\r
-;==================\r
-;\r
-; VW_DrawMPropString\r
-;\r
-; Draws a C string of characters at px/py and advances px\r
-;\r
-;==================\r
-\r
-\r
-\r
-PROC   VW_DrawMPropString      string:DWORD\r
-PUBLIC VW_DrawMPropString\r
-USES   SI,DI\r
-\r
-;\r
-; clear out the first byte of the buffer, the rest will automatically be\r
-; cleared as characters are drawn into it\r
-;\r
-       mov     es,[grsegs+STARTFONTM*2]\r
-       mov     dx,[es:pcharheight]\r
-       mov     di,OFFSET databuffer\r
-       mov     ax,ds\r
-       mov     es,ax\r
-       mov     bx,BUFFWIDTH-1\r
-\r
-       mov     cx,dx\r
-       mov     al,0ffh\r
-@@maskfill:\r
-       stosb                           ; fill the mask part with $ff\r
-       add     di,bx\r
-       loop    @@maskfill\r
-\r
-       mov     cx,dx\r
-       xor     al,al\r
-@@datafill:\r
-       stosb                           ; fill the data part with $0\r
-       add     di,bx\r
-       loop    @@datafill\r
-\r
-;\r
-; shift the characters into the buffer\r
-;\r
-       mov     ax,[px]\r
-       and     ax,7\r
-       mov     [bufferbit],ax\r
-       mov     [bufferbyte],0\r
-\r
-       mov     ax,[WORD string]\r
-       mov     [stringptr],ax\r
-       mov     ax,[WORD string+2]\r
-       mov     [stringptr+2],ax\r
-\r
-@@shiftone:\r
-       mov     es,[stringptr+2]\r
-       mov     bx,[stringptr]\r
-       inc     [stringptr]\r
-       mov     bx,[es:bx]\r
-       xor     bh,bh\r
-       or      bl,bl\r
-       jz      @@allshifted\r
-       call    ShiftMPropChar\r
-       jmp     @@shiftone\r
-\r
-@@allshifted:\r
-;\r
-; calculate position to draw buffer on screen\r
-;\r
-       mov     bx,[py]\r
-       shl     bx,1\r
-       mov     di,[ylookup+bx]\r
-       add     di,[bufferofs]\r
-\r
-       mov     ax,[px]\r
-       shr     ax,1\r
-       shr     ax,1\r
-       shr     ax,1            ;x location in bytes\r
-       add     di,ax\r
-       mov     [screenspot],di\r
-\r
-;\r
-; advance px\r
-;\r
-       mov     ax,[bufferbyte]\r
-       shl     ax,1\r
-       shl     ax,1\r
-       shl     ax,1\r
-       or      ax,[bufferbit]\r
-       add     [px],ax\r
-\r
-;\r
-; draw it\r
-;\r
-       mov     ax,[bufferbyte]\r
-       test    [bufferbit],7\r
-       jz      @@go\r
-       inc     ax                              ;so the partial byte also gets drawn\r
-@@go:\r
-       mov     [bufferwidth],ax\r
-       mov     es,[grsegs+STARTFONTM*2]\r
-       mov     ax,[es:pcharheight]\r
-       mov     [bufferheight],ax\r
-\r
-       mov     si,OFFSET databuffer\r
-       call    BufferToScreen          ; cut out mask\r
-                                                               ; or in data\r
-       call    BufferToScreen          ; SI is still in the right position in buffer\r
-\r
-       ret\r
-\r
-ENDP\r
-\r
-endif          ; if numfontm\r
-\r
-endif          ; if fonts\r