]> 4ch.mooo.com Git - 16.git/commitdiff
wwww
authorsparky4 <sparky4@cock.li>
Mon, 23 Nov 2015 22:22:28 +0000 (16:22 -0600)
committersparky4 <sparky4@cock.li>
Mon, 23 Nov 2015 22:22:28 +0000 (16:22 -0600)
16 files changed:
src/lib/modex/c_utils.asm [new file with mode: 0755]
src/lib/modex/c_utils.h [new file with mode: 0755]
src/lib/modex/c_utils.lst [new file with mode: 0755]
src/lib/modex/c_utils.sbr [new file with mode: 0755]
src/lib/modex/makefile [new file with mode: 0755]
src/lib/modex/modex.asm
src/lib/modex/modex.h
src/lib/modex/utls-asm.bat [new file with mode: 0755]
src/lib/modex/w.sh [new file with mode: 0755]
src/lib/modex/x.exe [new file with mode: 0755]
src/lib/modex/x_demo.c [new file with mode: 0755]
src/lib/modex/x_demo.dsk [new file with mode: 0755]
src/lib/modex/x_demo.exe [moved from x-demo.exe with 86% similarity]
src/lib/modex/x_demo.prj [new file with mode: 0755]
x-demo.smp [moved from xdemo.smp with 100% similarity]
x_demo.exe [new file with mode: 0755]

diff --git a/src/lib/modex/c_utils.asm b/src/lib/modex/c_utils.asm
new file mode 100755 (executable)
index 0000000..0118201
--- /dev/null
@@ -0,0 +1,456 @@
+;=======================================================\r
+;===  C_UTILS.ASM  - Asm Utilities for C/C++         ===\r
+;=======================================================\r
+\r
+       PAGE    255, 132\r
+\r
+       .MODEL Huge\r
+;      .286\r
+\r
+       ; ==== MACROS ====\r
+\r
+       ; macros to PUSH and POP multiple registers\r
+\r
+; PUSHx MACRO R1, R2, R3, R4;, R5, R6, R7, R8\r
+;      IFNB <R1>\r
+;              push    R1                              ; Save R1\r
+;              PUSHx   R2, R3, R4;, R5, R6, R7, R8\r
+;      ENDIF\r
+; ENDM\r
+;\r
+; POPx MACRO R1, R2, R3, R4;, R5, R6, R7, R8\r
+;      IFNB <R1>\r
+;              pop             R1                              ; Restore R1\r
+;              POPx    R2, R3, R4;, R5, R6, R7, R8\r
+;      ENDIF\r
+; ENDM\r
+\r
+       ; Macro to Clear a Register to 0\r
+\r
+CLR MACRO Register\r
+       xor             Register, Register              ; Set Register = 0\r
+ENDM\r
+\r
+       ; Macros to Decrement Counter & Jump on Condition\r
+\r
+LOOPx MACRO Register, Destination\r
+       dec             Register                                ; Counter--\r
+       jnz             Destination                             ; Jump if not 0\r
+ENDM\r
+\r
+LOOPjz MACRO Register, Destination\r
+       dec             Register                                ; Counter--\r
+       jz              Destination                             ; Jump if 0\r
+ENDM\r
+\r
+\r
+       ; ==== General Constants ====\r
+\r
+       False   EQU     0\r
+       True    EQU     -1\r
+       nil             EQU 0\r
+\r
+       b               EQU     BYTE PTR\r
+       w               EQU     WORD PTR\r
+       d               EQU     DWORD PTR\r
+       o               EQU     OFFSET\r
+       f               EQU FAR PTR\r
+       s               EQU     SHORT\r
+       ?x4             EQU <?,?,?,?>\r
+       ?x3             EQU <?,?,?>\r
+       ?x2             EQU <?,?>\r
+       ?x1             EQU <?>\r
+\r
+\r
+       .Data\r
+\r
+       EVEN\r
+\r
+RND_Seed       DW      7397, 29447, 802\r
+RND_Mult       DW      179, 183, 182\r
+RND_ModV       DW      32771, 32779, 32783\r
+\r
+CR_LF          DB      13, 10                  ; the CRLF data\r
+\r
+       .Code\r
+\r
+;===========================================\r
+;void far pascal dos_print  (far char *Text)\r
+;===========================================\r
+;\r
+; - Print Text Directly to DOS console w/ CR/LF\r
+;\r
+\r
+       PUBLIC  DOS_PRINT\r
+\r
+DP_Stack       STRUC\r
+                               DW      ?x1     ; DI, SI, DS, BP\r
+                               DW      ?x1     ; DI, SI, DS, BP\r
+                               DW      ?x1     ; DI, SI, DS, BP\r
+                               DW      ?x1     ; DI, SI, DS, BP\r
+                               DD      ?       ; Caller\r
+       DP_Text         DD      ?       ; Far Address of Text to print\r
+DP_Stack       ENDS\r
+\r
+\r
+DOS_PRINT       PROC    FAR\r
+\r
+       ;PUSHx  BP, DS, SI, DI          ; Preserve Important Registers\r
+       push bp\r
+       push ds\r
+       push si\r
+       push di\r
+       mov             BP, SP                          ; Set up Stack Frame\r
+\r
+       lds     DX, [BP].DP_Text        ; Get Addr of Text$ descriptor\r
+\r
+       ; Compute Length of string\r
+\r
+       CLR             CX                                      ; Length = 0\r
+       mov             SI, DX                          ; DS:SI = String data\r
+\r
+@@DP_Scan_it:\r
+\r
+       cmp             b [SI], 0                       ; Null Byte found?\r
+       je              @@DP_Got_Len            ; exit loop if so\r
+\r
+       inc             CX                                      ; Len++\r
+       inc             SI                                      ; Point to next char\r
+       jmp             s @@DP_Scan_it          ; check again...\r
+\r
+@@DP_Got_len:\r
+\r
+       jcxz    @No_Print                       ; Don't Print if empty\r
+\r
+       mov             BX, 1                           ; 1= DOS Handle for Display\r
+       mov             AH, 40h                         ; Write Text Function\r
+       int             21h                                     ; Call DOS to do it\r
+\r
+@No_Print:\r
+       mov             AX, SEG DGROUP          ; Restore DGroup\r
+       mov             DS, AX\r
+\r
+       mov             DX, o CR_LF                     ; Get Addr of CR/LF pair\r
+       mov             CX, 2                           ; 2 Characters to Write\r
+       mov             BX, 1                           ; 1= DOS Handle for Display\r
+\r
+       mov             AH, 40h                         ; Write Text Function\r
+       int             21h                                     ; Call DOS to do it\r
+\r
+       cld                                                     ; Reset Direction Flag\r
+       ;POPx   DI, SI, DS, BP          ; Restore Saved Registers\r
+       pop di\r
+       pop si\r
+       pop ds\r
+       pop bp\r
+       ret             4                                       ; Exit & Clean Up Stack\r
+\r
+DOS_PRINT       ENDP\r
+\r
+\r
+;===========================================\r
+;void far pascal dos_prints (char far *Text)\r
+;===========================================\r
+;\r
+; Print Text Directly to DOS console\r
+; without a trailing CR/LF\r
+;\r
+\r
+       PUBLIC  DOS_PRINTS\r
+\r
+DOS_PRINTS      PROC    FAR\r
+\r
+       ;PUSHx  BP, DS, SI, DI          ; Preserve Important Registers\r
+       push bp\r
+       push ds\r
+       push si\r
+       push di\r
+       mov             BP, SP                          ; Set up Stack Frame\r
+\r
+       lds     DX, [BP].DP_Text        ; Get Addr of Text$ descriptor\r
+\r
+       ; Compute Length of string\r
+\r
+       CLR             CX                                      ; Length = 0\r
+       mov             SI, DX                          ; DS:SI = String data\r
+\r
+@@DPS_Scan_it:\r
+\r
+       cmp             b [SI], 0                       ; Null Byte found?\r
+       je              @@DPS_Got_Len           ; exit loop if so\r
+\r
+       inc             CX                                      ; Len++\r
+       inc             SI                                      ; Point to next char\r
+       jmp             s @@DPS_Scan_it         ; check again...\r
+\r
+@@DPS_Got_len:\r
+\r
+       jcxz    @DPS_Exit                       ; Don't Print if empty\r
+\r
+       mov             BX, 1                           ; 1= DOS Handle for Display\r
+       mov             AH, 40h                         ; Write Text Function\r
+       int             21h                                     ; Call DOS to do it\r
+\r
+@DPS_Exit:\r
+       cld                                                     ; Reset Direction Flag\r
+       ;POPx   DI, SI, DS, BP          ; Restore Saved Registers\r
+       pop di\r
+       pop si\r
+       pop ds\r
+       pop bp\r
+       ret             2                                       ; Exit & Clean Up Stack\r
+\r
+DOS_PRINTS      ENDP\r
+\r
+\r
+;=========================================\r
+;void far pascal set_video_mode (int Mode)\r
+;=========================================\r
+;\r
+; Sets the Video Mode through the BIOS\r
+;\r
+\r
+       PUBLIC  SET_VIDEO_MODE\r
+\r
+SVM_Stack      STRUC\r
+                               DW      ?x1     ; DI, SI, DS, BP\r
+                               DW      ?x1     ; DI, SI, DS, BP\r
+                               DW      ?x1     ; DI, SI, DS, BP\r
+                               DW      ?x1     ; DI, SI, DS, BP\r
+                               DD      ?       ; Caller\r
+       SVM_Mode        DB      ?,? ; Desired Video Mode\r
+SVM_Stack      ENDS\r
+\r
+\r
+SET_VIDEO_MODE PROC    FAR\r
+\r
+       ;PUSHx  BP, DS, SI, DI          ; Preserve Important Registers\r
+       push bp\r
+       push ds\r
+       push si\r
+       push di\r
+       mov             BP, SP                          ; Set up Stack Frame\r
+\r
+       CLR             AH                                      ; Function 0\r
+       mov             AL, [BP].SVM_Mode       ; Get Mode #\r
+\r
+       int             10H                                     ; Change Video Modes\r
+\r
+@SVM_Exit:\r
+       ;POPx   DI, SI, DS, BP          ; Restore Saved Registers\r
+       pop di\r
+       pop si\r
+       pop ds\r
+       pop bp\r
+       ret             2                                       ; Exit & Clean Up Stack\r
+\r
+SET_VIDEO_MODE ENDP\r
+\r
+\r
+;===================================\r
+;int far pascal scan_keyboard (void)\r
+;===================================\r
+;\r
+; Function to scan keyboard for a pressed key\r
+;\r
+\r
+       PUBLIC  SCAN_KEYBOARD\r
+\r
+SCAN_KEYBOARD  PROC    FAR\r
+\r
+       ;PUSHx  BP, DS, SI, DI          ; Preserve Important Registers\r
+       push bp\r
+       push ds\r
+       push si\r
+       push di\r
+\r
+       mov             AH, 01H                         ; Function #1\r
+       INT             16H                                     ; Call Keyboard Driver\r
+       JZ              @SK_NO_KEY                      ; Exit if Zero flag set\r
+\r
+       mov             AH,     00H                             ; Remove Key from Buffer\r
+       INT             16H                                     ; Get Keycode in AX\r
+\r
+       OR              AL, AL                          ; Low Byte Set (Ascii?)\r
+       JZ              @SK_Exit                        ; if not, it's a F-Key\r
+\r
+       CLR             AH                                      ; Clear ScanCode if Ascii\r
+       JMP             s @SK_Exit                      ; Return Key in AX\r
+\r
+@SK_NO_KEY:\r
+       CLR             AX                                      ; Return Nil (no Keypress)\r
+\r
+@SK_Exit:\r
+       cld                                                     ; Reset Direction Flag\r
+       ;POPx   DI, SI, DS, BP          ; Restore Saved Registers\r
+       pop di\r
+       pop si\r
+       pop ds\r
+       pop bp\r
+       ret                                                     ; Exit & Clean Up Stack\r
+\r
+SCAN_KEYBOARD  ENDP\r
+\r
+\r
+;========================================\r
+;int far pascal random_int (int MaxValue)\r
+;========================================\r
+;\r
+; Returns a pseudo-random number in the range of (0.. MaxInt-1)\r
+;\r
+\r
+\r
+       PUBLIC  RANDOM_INT\r
+\r
+RI_Stack       STRUC\r
+                               DW      ?       ; BP\r
+                               DD      ?       ; Caller\r
+       RI_MaxVal       DW      ?       ; Maximum Value to Return + 1\r
+RI_Stack       ENDS\r
+\r
+\r
+RANDOM_INT     PROC    FAR\r
+\r
+       push    BP                                      ; Preserve Important Registers\r
+       mov             BP, SP                          ; Set up Stack Frame\r
+\r
+       CLR             BX                                      ; BX is the data index\r
+       CLR             CX                              ; CX is the accumulator\r
+\r
+REPT 3\r
+       mov             AX, RND_Seed[BX]        ; load the initial seed\r
+       mul             RND_Mult[BX]            ; multiply it\r
+       div             RND_ModV[BX]            ; and obtain the Mod value\r
+       mov             RND_Seed[BX], DX        ; save that for the next time\r
+\r
+       add             CX, DX                          ; add it into the accumulator\r
+       inc             BX\r
+       inc             BX                      ; point to the next set of values\r
+ENDM\r
+\r
+       mov             AX, CX                          ; AX = Random #\r
+       CLR             DX                                      ; DX = 0\r
+       div             [BP].RI_MaxVal          ; DX = DX:AX / MAxVal Remainder\r
+\r
+       mov             AX, DX\r
+\r
+       pop             BP                                      ; Restore BP\r
+       ret             2                               ; back to BASIC with AX holding the result\r
+\r
+RANDOM_INT     ENDP\r
+\r
+\r
+;==================================\r
+;void far pascal init_random (void)\r
+;==================================\r
+;\r
+; Scrambles the psuedo-random number sequence\r
+; (XOR's the seed value with the timer)\r
+;\r
+\r
+       PUBLIC  INIT_RANDOM\r
+\r
+INIT_RANDOM    PROC    FAR\r
+\r
+       CLR             AX                                      ; Segment = 0000\r
+       mov             ES, AX\r
+       mov             AX, ES:[046Ch]      ; Get Timer Lo Word\r
+\r
+       xor             RND_Seed, AX            ; Scramble 1st Seed\r
+\r
+       ret                                                     ; Exit & Clean Up Stack\r
+\r
+INIT_RANDOM    ENDP\r
+\r
+;=========================================\r
+;int far pascal int_sqr (int X, int Round)\r
+;=========================================\r
+;\r
+; Returns the Integer Square Root of (X)\r
+; Round allows the return value to be rounded to the\r
+; nearest integer value by passing 0x80.  Passing 0\r
+; return the Integer Portion only.  The rounding amound is\r
+; a number from 0 to 1 multiplied by 256, thus\r
+; 0.5 * 0x100 = 0x80!\r
+;\r
+\r
+ISQ_Stack      STRUC\r
+                                       DW      ?,?     ; BP, DI\r
+                                       DD      ?       ; Caller\r
+       ISQ_Round               DW      ?       ; Amount to Round Result * 256\r
+       ISQ_X                   DW      ?       ; "X"\r
+ISQ_Stack      ENDS\r
+\r
+       PUBLIC  INT_SQR\r
+\r
+INT_SQR                PROC    FAR\r
+\r
+    ;PUSHx   BP, DI                            ; Save BP\r
+       push bp\r
+       push di\r
+    mov     BP, SP                             ; Set up Stack Frame\r
+\r
+       xor     AX, AX                          ; {xor eax,eax}\r
+       xor     DX, DX                          ; {xor edx,edx}\r
+       mov     DI, [BP].ISQ_X          ; {mov edi,x}\r
+\r
+       mov     CX, 16                          ; {mov cx, 32}\r
+\r
+@ISQ_L:\r
+\r
+       shl     DI, 1                           ; {shl edi,1}\r
+       rcl     DX, 1                           ; {rcl edx,1}\r
+       shl     DI, 1                           ; {shl edi,1}\r
+       rcl     DX, 1                           ; {rcl edx,1}\r
+       shl     AX, 1                           ; {shl eax,1}\r
+       mov     BX, AX                          ; {mov ebx,eax}\r
+       shl     BX, 1                           ; {shl ebx,1}\r
+       inc     BX                                      ; {inc ebx}\r
+       cmp     DX, BX                          ; {cmp edx,ebx}\r
+       jl              @ISQ_S\r
+\r
+       sub     DX, BX                          ; {sub edx,ebx}\r
+       inc     AX                                      ; {inc eax}\r
+\r
+@ISQ_S:\r
+       loop    @ISQ_L\r
+\r
+       add     ax, [BP].ISQ_Round      ; {add eax,$00008000}\r
+                                                               ; {*round* result in hi word: ie. +0.5}\r
+       shr     ax, 1                           ; {shr eax,16}  {to ax (result)}\r
+       shr     ax, 1                           ; {shr eax,16}  {to ax (result)}\r
+       shr     ax, 1                           ; {shr eax,16}  {to ax (result)}\r
+       shr     ax, 1                           ; {shr eax,16}  {to ax (result)}\r
+       shr     ax, 1                           ; {shr eax,16}  {to ax (result)}\r
+       shr     ax, 1                           ; {shr eax,16}  {to ax (result)}\r
+       shr     ax, 1                           ; {shr eax,16}  {to ax (result)}\r
+       shr     ax, 1                           ; {shr eax,16}  {to ax (result)}\r
+\r
+       ;POPx   DI, BP                          ; Restore Registers\r
+       pop di\r
+       pop bp\r
+       ret             4                                       ; Exit\r
+\r
+INT_SQR                ENDP\r
+\r
+;=================================\r
+;int far pascal timer_count (void)\r
+;=================================\r
+;\r
+; Returns the current timer value as an integer/long integer\r
+;\r
+\r
+       PUBLIC  TIMER_COUNT\r
+\r
+TIMER_COUNT      PROC    FAR\r
+\r
+       CLR             AX                                      ; Segment = 0000\r
+       mov             ES, AX\r
+       mov             AX, ES:[046Ch]      ; Get Timer Lo Word\r
+       mov             DX, ES:[046Eh]          ; Get Timer Hi Word\r
+       ret                                                     ; Exit & Clean Up Stack\r
+\r
+TIMER_COUNT      ENDP\r
+\r
+\r
+       END\r
diff --git a/src/lib/modex/c_utils.h b/src/lib/modex/c_utils.h
new file mode 100755 (executable)
index 0000000..9be6ba2
--- /dev/null
@@ -0,0 +1,117 @@
+\r
+#ifndef __C_UTILS_H\r
+#define __C_UTILS_H\r
+\r
+\r
+       /* Misc Constants */\r
+\r
+#define True     -1\r
+#define False    0\r
+#define nil      0\r
+\r
+       /* Color Constants */\r
+\r
+#define c_BLACK   0\r
+#define c_BLUE    1\r
+#define c_GREEN   2\r
+#define c_CYAN    3\r
+#define c_RED     4\r
+#define c_PURPLE  5\r
+#define c_BROWN   6\r
+#define c_WHITE   7\r
+#define c_GREY    8\r
+#define c_bBLUE   9\r
+#define c_bGREEN  10\r
+#define c_bCYAN   11\r
+#define c_bRED    12\r
+#define c_bPURPLE 13\r
+#define c_YELLOW  14\r
+#define c_bWHITE  15\r
+#define c_BRIGHT  16\r
+\r
+\r
+#define Ky_F1     0x3B00\r
+#define Ky_F2     0x3C00\r
+#define Ky_F3     0x3D00\r
+#define Ky_F4     0x3E00\r
+#define Ky_F5     0x3F00\r
+#define Ky_F6     0x4000\r
+#define Ky_F7     0x4100\r
+#define Ky_F8     0x4200\r
+#define Ky_F9     0x4300\r
+#define Ky_F10    0x4400\r
+\r
+#define Ky_Up     0x4800\r
+#define Ky_Left   0x4B00\r
+#define Ky_Right  0x4D00\r
+#define Ky_Down   0x5000\r
+#define Ky_SUp    0xC800\r
+#define Ky_SLeft  0xCB00\r
+#define Ky_SRight 0xCD00\r
+#define Ky_SDown  0xD000\r
+\r
+#define Ky_Home   0x4700\r
+#define Ky_End    0x4F00\r
+#define Ky_PgUp   0x4900\r
+#define Ky_PgDn   0x5100\r
+#define Ky_SHome  0xC700\r
+#define Ky_SEnd   0xCF00\r
+#define Ky_SPgUp  0xC900\r
+#define Ky_SPgDn  0xD100\r
+\r
+#define Ky_Ins    0x5200\r
+#define Ky_Del    0x5300\r
+#define Ky_SIns   0xC200\r
+#define Ky_SDel   0xC300\r
+\r
+#define Ky_Tab    0x0009\r
+#define Ky_RvsTab 0x8F00\r
+#define Ky_STab   0x8F00\r
+\r
+#define Ky_BS     0x0008\r
+#define Ky_CR     0x000D\r
+#define Ky_ESC    0x001B\r
+#define Ky_Clr    0x007F\r
+\r
+#define Ky_Plus   0x002D\r
+#define Ky_Minus  0x002B\r
+\r
+#define Ky_AltA   0x1E00\r
+#define Ky_AltB   0x3000\r
+#define Ky_AltC   0x2E00\r
+#define Ky_AltD   0x2000\r
+#define Ky_AltE   0x1200\r
+#define Ky_AltF   0x2100\r
+#define Ky_AltG   0x2200\r
+#define Ky_AltH   0x2300\r
+#define Ky_AltI   0x1700\r
+#define Ky_AltJ   0x2400\r
+#define Ky_AltK   0x2500\r
+#define Ky_AltL   0x2600\r
+#define Ky_AltM   0x3200\r
+#define Ky_AltN   0x3100\r
+#define Ky_AltO   0x1800\r
+#define Ky_AltP   0x1900\r
+#define Ky_AltQ   0x1000\r
+#define Ky_AltR   0x1300\r
+#define Ky_AltS   0x1F00\r
+#define Ky_AltT   0x1400\r
+#define Ky_AltU   0x1600\r
+#define Ky_AltV   0x2F00\r
+#define Ky_AltW   0x1100\r
+#define Ky_AltX   0x2D00\r
+#define Ky_AltY   0x1500\r
+#define Ky_AltZ   0x2C00\r
+\r
+       /* .ASM Functions From C_UTILS.ASM */\r
+\r
+void far pascal dos_print (char far *Text);\r
+void far pascal dos_prints (char far *Text);\r
+void far pascal set_video_mode (int Mode);\r
+int  far pascal scan_keyboard (void);\r
+int  far pascal random_int (int MaxValue);\r
+void far pascal init_random (void);\r
+int  far pascal int_sqr (int X, int Round);\r
+int  far pascal timer_count (void);\r
+\r
+#endif\r
diff --git a/src/lib/modex/c_utils.lst b/src/lib/modex/c_utils.lst
new file mode 100755 (executable)
index 0000000..f9664ba
--- /dev/null
@@ -0,0 +1,597 @@
+Microsoft (R) Macro Assembler Version 6.11                 07/03/14 12:38:18\r
+c_utils.asm                                                 Page 1 - 1\r
+\r
+\r
+                               ;=======================================================\r
+                               ;===  C_UTILS.ASM  - Asm Utilities for C/C++         ===\r
+                               ;=======================================================\r
+\r
+                                       PAGE    255, 132\r
+\r
+                                       .MODEL Medium\r
+                                       .286\r
+\r
+                                       ; ==== MACROS ====\r
+\r
+                                       ; macros to PUSH and POP multiple registers\r
+\r
+                               PUSHx MACRO R1, R2, R3, R4, R5, R6, R7, R8\r
+                                       IFNB <R1>\r
+                                               push    R1                              ; Save R1\r
+                                               PUSHx   R2, R3, R4, R5, R6, R7, R8\r
+                                       ENDIF\r
+                               ENDM\r
+\r
+                               POPx MACRO R1, R2, R3, R4, R5, R6, R7, R8\r
+                                       IFNB <R1>\r
+                                               pop             R1                              ; Restore R1\r
+                                               POPx    R2, R3, R4, R5, R6, R7, R8\r
+                                       ENDIF\r
+                               ENDM\r
+\r
+                                       ; Macro to Clear a Register to 0\r
+\r
+                               CLR MACRO Register\r
+                                       xor             Register, Register              ; Set Register = 0\r
+                               ENDM\r
+\r
+                                       ; Macros to Decrement Counter & Jump on Condition\r
+\r
+                               LOOPx MACRO Register, Destination\r
+                                       dec             Register                                ; Counter--\r
+                                       jnz             Destination                             ; Jump if not 0\r
+                               ENDM\r
+\r
+                               LOOPjz MACRO Register, Destination\r
+                                       dec             Register                                ; Counter--\r
+                                       jz              Destination                             ; Jump if 0\r
+                               ENDM\r
+\r
+\r
+                                       ; ==== General Constants ====\r
+\r
+ = 0000                                        False   EQU     0\r
+ =-0001                                        True    EQU     -1\r
+ = 0000                                        nil             EQU 0\r
+\r
+ = BYTE PTR                            b               EQU     BYTE PTR\r
+ = WORD PTR                            w               EQU     WORD PTR\r
+ = DWORD PTR                           d               EQU     DWORD PTR\r
+ = OFFSET                              o               EQU     OFFSET\r
+ = FAR PTR                             f               EQU FAR PTR\r
+ = SHORT                               s               EQU     SHORT\r
+ = ?,?,?,?                             ?x4             EQU <?,?,?,?>\r
+ = ?,?,?                               ?x3             EQU <?,?,?>\r
+\r
+\r
+ 0000                                  .Data\r
+\r
+                                       EVEN\r
+\r
+ 0000 1CE5 7307 0322           RND_Seed        DW      7397, 29447, 802\r
+ 0006 00B3 00B7 00B6           RND_Mult        DW      179, 183, 182\r
+ 000C 8003 800B 800F           RND_ModV        DW      32771, 32779, 32783\r
+\r
+ 0012 0D 0A                    CR_LF           DB      13, 10                  ; the CRLF data\r
+\r
+ 0000                                  .Code\r
+\r
+                               ;===========================================\r
+                               ;void far pascal dos_print  (far char *Text)\r
+                               ;===========================================\r
+                               ;\r
+                               ; - Print Text Directly to DOS console w/ CR/LF\r
+                               ;\r
+\r
+                                       PUBLIC  DOS_PRINT\r
+\r
+ 0010                          DP_Stack        STRUC\r
+ 0000  0000 0000 0000                                          DW      ?x4     ; DI, SI, DS, BP\r
+       0000\r
+ 0008  00000000                                                        DD      ?       ; Caller\r
+ 000C  00000000                                DP_Text         DD      ?       ; Far Address of Text to print\r
+                               DP_Stack        ENDS\r
+\r
+\r
+ 0000                          DOS_PRINT        PROC    FAR\r
+                                                          \r
+                                       PUSHx   BP, DS, SI, DI          ; Preserve Important Registers\r
+ 0000  55                   1                  push    BP                              ; Save R1\r
+ 0001  1E                   2                  push    DS                              ; Save R1\r
+ 0002  56                   3                  push    SI                              ; Save R1\r
+ 0003  57                   4                  push    DI                              ; Save R1\r
+ 0004  8B EC                           mov             BP, SP                          ; Set up Stack Frame\r
+\r
+ 0006  C5 56 0C                                lds     DX, [BP].DP_Text        ; Get Addr of Text$ descriptor\r
+\r
+                                       ; Compute Length of string\r
+\r
+                                       CLR             CX                                      ; Length = 0\r
+ 0009  33 C9                1          xor             CX, CX          ; Set Register = 0\r
+ 000B  8B F2                           mov             SI, DX                          ; DS:SI = String data\r
+\r
+ 000D                          @@DP_Scan_it:\r
+                                       \r
+ 000D  80 3C 00                                cmp             b [SI], 0                       ; Null Byte found?\r
+ 0010  74 04                           je              @@DP_Got_Len            ; exit loop if so\r
+\r
+ 0012  41                              inc             CX                                      ; Len++\r
+ 0013  46                              inc             SI                                      ; Point to next char\r
+ 0014  EB F7                           jmp             s @@DP_Scan_it          ; check again...\r
+\r
+ 0016                          @@DP_Got_len:\r
+\r
+ 0016  E3 07                           jcxz    @No_Print                       ; Don't Print if empty\r
+\r
+ 0018  BB 0001                         mov             BX, 1                           ; 1= DOS Handle for Display\r
+ 001B  B4 40                           mov             AH, 40h                         ; Write Text Function\r
+ 001D  CD 21                           int             21h                                     ; Call DOS to do it\r
+\r
+ 001F                          @No_Print:\r
+ 001F  B8 ---- R                       mov             AX, SEG DGROUP          ; Restore DGroup\r
+ 0022  8E D8                           mov             DS, AX\r
+\r
+ 0024  BA 0012 R                       mov             DX, o CR_LF                     ; Get Addr of CR/LF pair\r
+ 0027  B9 0002                         mov             CX, 2                           ; 2 Characters to Write         \r
+ 002A  BB 0001                         mov             BX, 1                           ; 1= DOS Handle for Display\r
+\r
+ 002D  B4 40                           mov             AH, 40h                         ; Write Text Function\r
+ 002F  CD 21                           int             21h                                     ; Call DOS to do it\r
+\r
+ 0031  FC                              cld                                                     ; Reset Direction Flag          \r
+                                       POPx    DI, SI, DS, BP          ; Restore Saved Registers\r
+ 0032  5F                   1                  pop             DI                              ; Restore R1\r
+ 0033  5E                   2                  pop             SI                              ; Restore R1\r
+ 0034  1F                   3                  pop             DS                              ; Restore R1\r
+ 0035  5D                   4                  pop             BP                              ; Restore R1\r
+ 0036  CA 0004                         ret             4                                       ; Exit & Clean Up Stack\r
+\r
+ 0039                          DOS_PRINT        ENDP\r
+\r
+\r
+                               ;===========================================\r
+                               ;void far pascal dos_prints (char far *Text)\r
+                               ;===========================================\r
+                               ; \r
+                               ; Print Text Directly to DOS console \r
+                               ; without a trailing CR/LF\r
+                               ;\r
+\r
+                                       PUBLIC  DOS_PRINTS\r
+\r
+ 0039                          DOS_PRINTS       PROC    FAR\r
+\r
+                                       PUSHx   BP, DS, SI, DI          ; Preserve Important Registers\r
+ 0039  55                   1                  push    BP                              ; Save R1\r
+ 003A  1E                   2                  push    DS                              ; Save R1\r
+ 003B  56                   3                  push    SI                              ; Save R1\r
+ 003C  57                   4                  push    DI                              ; Save R1\r
+ 003D  8B EC                           mov             BP, SP                          ; Set up Stack Frame\r
+\r
+ 003F  C5 56 0C                                lds     DX, [BP].DP_Text        ; Get Addr of Text$ descriptor\r
+\r
+                                       ; Compute Length of string\r
+\r
+                                       CLR             CX                                      ; Length = 0\r
+ 0042  33 C9                1          xor             CX, CX          ; Set Register = 0\r
+ 0044  8B F2                           mov             SI, DX                          ; DS:SI = String data\r
+\r
+ 0046                          @@DPS_Scan_it:\r
+                                       \r
+ 0046  80 3C 00                                cmp             b [SI], 0                       ; Null Byte found?\r
+ 0049  74 04                           je              @@DPS_Got_Len           ; exit loop if so\r
+\r
+ 004B  41                              inc             CX                                      ; Len++\r
+ 004C  46                              inc             SI                                      ; Point to next char\r
+ 004D  EB F7                           jmp             s @@DPS_Scan_it         ; check again...\r
+\r
+ 004F                          @@DPS_Got_len:\r
+\r
+ 004F  E3 07                           jcxz    @DPS_Exit                       ; Don't Print if empty\r
+\r
+ 0051  BB 0001                         mov             BX, 1                           ; 1= DOS Handle for Display\r
+ 0054  B4 40                           mov             AH, 40h                         ; Write Text Function\r
+ 0056  CD 21                           int             21h                                     ; Call DOS to do it\r
+\r
+ 0058                          @DPS_Exit:\r
+ 0058  FC                              cld                                                     ; Reset Direction Flag          \r
+                                       POPx    DI, SI, DS, BP          ; Restore Saved Registers\r
+ 0059  5F                   1                  pop             DI                              ; Restore R1\r
+ 005A  5E                   2                  pop             SI                              ; Restore R1\r
+ 005B  1F                   3                  pop             DS                              ; Restore R1\r
+ 005C  5D                   4                  pop             BP                              ; Restore R1\r
+ 005D  CA 0002                         ret             2                                       ; Exit & Clean Up Stack\r
+\r
+ 0060                          DOS_PRINTS       ENDP\r
+\r
+\r
+                               ;=========================================\r
+                               ;void far pascal set_video_mode (int Mode)\r
+                               ;=========================================\r
+                               ;\r
+                               ; Sets the Video Mode through the BIOS\r
+                               ;\r
+\r
+                                       PUBLIC  SET_VIDEO_MODE\r
+\r
+ 000E                          SVM_Stack       STRUC\r
+ 0000  0000 0000 0000                                          DW      ?x4     ; DI, SI, DS, BP\r
+       0000\r
+ 0008  00000000                                                        DD      ?       ; Caller\r
+ 000C  00 00                           SVM_Mode        DB      ?,? ; Desired Video Mode\r
+                               SVM_Stack       ENDS\r
+\r
+\r
+ 0060                          SET_VIDEO_MODE  PROC    FAR\r
+\r
+                                       PUSHx   BP, DS, SI, DI          ; Preserve Important Registers\r
+ 0060  55                   1                  push    BP                              ; Save R1\r
+ 0061  1E                   2                  push    DS                              ; Save R1\r
+ 0062  56                   3                  push    SI                              ; Save R1\r
+ 0063  57                   4                  push    DI                              ; Save R1\r
+ 0064  8B EC                           mov             BP, SP                          ; Set up Stack Frame\r
+\r
+                                       CLR             AH                                      ; Function 0\r
+ 0066  32 E4                1          xor             AH, AH          ; Set Register = 0\r
+ 0068  8A 46 0C                                mov             AL, [BP].SVM_Mode       ; Get Mode #\r
+\r
+ 006B  CD 10                           int             10H                                     ; Change Video Modes\r
+\r
+ 006D                          @SVM_Exit:\r
+                                       POPx    DI, SI, DS, BP          ; Restore Saved Registers\r
+ 006D  5F                   1                  pop             DI                              ; Restore R1\r
+ 006E  5E                   2                  pop             SI                              ; Restore R1\r
+ 006F  1F                   3                  pop             DS                              ; Restore R1\r
+ 0070  5D                   4                  pop             BP                              ; Restore R1\r
+ 0071  CA 0002                         ret             2                                       ; Exit & Clean Up Stack\r
+\r
+ 0074                          SET_VIDEO_MODE  ENDP\r
+\r
+\r
+                               ;===================================\r
+                               ;int far pascal scan_keyboard (void)\r
+                               ;===================================\r
+                               ;\r
+                               ; Function to scan keyboard for a pressed key\r
+                               ;\r
+\r
+                                       PUBLIC  SCAN_KEYBOARD\r
+\r
+ 0074                          SCAN_KEYBOARD   PROC    FAR\r
+\r
+                                       PUSHx   BP, DS, SI, DI          ; Preserve Important Registers\r
+ 0074  55                   1                  push    BP                              ; Save R1\r
+\fMicrosoft (R) Macro Assembler Version 6.11                07/03/14 12:38:18\r
+c_utils.asm                                                 Page 2 - 1\r
+\r
+\r
+ 0075  1E                   2                  push    DS                              ; Save R1\r
+ 0076  56                   3                  push    SI                              ; Save R1\r
+ 0077  57                   4                  push    DI                              ; Save R1\r
+\r
+ 0078  B4 01                           mov             AH, 01H                         ; Function #1\r
+ 007A  CD 16                           INT             16H                                     ; Call Keyboard Driver\r
+ 007C  74 0C                           JZ              @SK_NO_KEY                      ; Exit if Zero flag set\r
+\r
+ 007E  B4 00                           mov             AH,     00H                             ; Remove Key from Buffer\r
+ 0080  CD 16                           INT             16H                                     ; Get Keycode in AX\r
+\r
+ 0082  0A C0                           OR              AL, AL                          ; Low Byte Set (Ascii?)\r
+ 0084  74 06                           JZ              @SK_Exit                        ; if not, it's a F-Key\r
+\r
+                                       CLR             AH                                      ; Clear ScanCode if Ascii\r
+ 0086  32 E4                1          xor             AH, AH          ; Set Register = 0\r
+ 0088  EB 02                           JMP             s @SK_Exit                      ; Return Key in AX\r
+\r
+ 008A                          @SK_NO_KEY:\r
+                                       CLR             AX                                      ; Return Nil (no Keypress)\r
+ 008A  33 C0                1          xor             AX, AX          ; Set Register = 0\r
+\r
+ 008C                          @SK_Exit:\r
+ 008C  FC                              cld                                                     ; Reset Direction Flag          \r
+                                       POPx    DI, SI, DS, BP          ; Restore Saved Registers\r
+ 008D  5F                   1                  pop             DI                              ; Restore R1\r
+ 008E  5E                   2                  pop             SI                              ; Restore R1\r
+ 008F  1F                   3                  pop             DS                              ; Restore R1\r
+ 0090  5D                   4                  pop             BP                              ; Restore R1\r
+ 0091  CB                              ret                                                     ; Exit & Clean Up Stack\r
+\r
+ 0092                          SCAN_KEYBOARD   ENDP\r
+\r
+\r
+                               ;========================================\r
+                               ;int far pascal random_int (int MaxValue)\r
+                               ;========================================\r
+                               ;\r
+                               ; Returns a pseudo-random number in the range of (0.. MaxInt-1)\r
+                               ;\r
+\r
+\r
+                                       PUBLIC  RANDOM_INT\r
+\r
+ 0008                          RI_Stack        STRUC\r
+ 0000  0000                                                    DW      ?       ; BP\r
+ 0002  00000000                                                        DD      ?       ; Caller\r
+ 0006  0000                            RI_MaxVal       DW      ?       ; Maximum Value to Return + 1\r
+                               RI_Stack        ENDS\r
+\r
+\r
+ 0092                          RANDOM_INT      PROC    FAR\r
+\r
+ 0092  55                              push    BP                                      ; Preserve Important Registers\r
+ 0093  8B EC                           mov             BP, SP                          ; Set up Stack Frame\r
+\r
+                                       CLR             BX                                      ; BX is the data index\r
+ 0095  33 DB                1          xor             BX, BX          ; Set Register = 0\r
+                                       CLR             CX                              ; CX is the accumulator\r
+ 0097  33 C9                1          xor             CX, CX          ; Set Register = 0\r
+\r
+                               REPT 3\r
+                                       mov             AX, RND_Seed[BX]        ; load the initial seed\r
+                                       mul             RND_Mult[BX]            ; multiply it\r
+                                       div             RND_ModV[BX]            ; and obtain the Mod value\r
+                                       mov             RND_Seed[BX], DX        ; save that for the next time\r
+\r
+                                       add             CX, DX                          ; add it into the accumulator\r
+                                       inc             BX\r
+                                       inc             BX                      ; point to the next set of values\r
+                               ENDM\r
+ 0099  8B 87 0000 R         1          mov             AX, RND_Seed[BX]        ; load the initial seed\r
+ 009D  F7 A7 0006 R         1          mul             RND_Mult[BX]            ; multiply it\r
+ 00A1  F7 B7 000C R         1          div             RND_ModV[BX]            ; and obtain the Mod value\r
+ 00A5  89 97 0000 R         1          mov             RND_Seed[BX], DX        ; save that for the next time\r
+ 00A9  03 CA                1          add             CX, DX                          ; add it into the accumulator\r
+ 00AB  43                   1          inc             BX\r
+ 00AC  43                   1          inc             BX                      ; point to the next set of values\r
+ 00AD  8B 87 0000 R         1          mov             AX, RND_Seed[BX]        ; load the initial seed\r
+ 00B1  F7 A7 0006 R         1          mul             RND_Mult[BX]            ; multiply it\r
+ 00B5  F7 B7 000C R         1          div             RND_ModV[BX]            ; and obtain the Mod value\r
+ 00B9  89 97 0000 R         1          mov             RND_Seed[BX], DX        ; save that for the next time\r
+ 00BD  03 CA                1          add             CX, DX                          ; add it into the accumulator\r
+ 00BF  43                   1          inc             BX\r
+ 00C0  43                   1          inc             BX                      ; point to the next set of values\r
+ 00C1  8B 87 0000 R         1          mov             AX, RND_Seed[BX]        ; load the initial seed\r
+ 00C5  F7 A7 0006 R         1          mul             RND_Mult[BX]            ; multiply it\r
+ 00C9  F7 B7 000C R         1          div             RND_ModV[BX]            ; and obtain the Mod value\r
+ 00CD  89 97 0000 R         1          mov             RND_Seed[BX], DX        ; save that for the next time\r
+ 00D1  03 CA                1          add             CX, DX                          ; add it into the accumulator\r
+ 00D3  43                   1          inc             BX\r
+ 00D4  43                   1          inc             BX                      ; point to the next set of values\r
+\r
+ 00D5  8B C1                           mov             AX, CX                          ; AX = Random #\r
+                                       CLR             DX                                      ; DX = 0\r
+ 00D7  33 D2                1          xor             DX, DX          ; Set Register = 0\r
+ 00D9  F7 76 06                                div             [BP].RI_MaxVal          ; DX = DX:AX / MAxVal Remainder\r
+\r
+ 00DC  8B C2                           mov             AX, DX\r
+\r
+ 00DE  5D                              pop             BP                                      ; Restore BP\r
+ 00DF  CA 0002                         ret             2                               ; back to BASIC with AX holding the result\r
+\r
+ 00E2                          RANDOM_INT      ENDP\r
+\r
+\r
+                               ;==================================\r
+                               ;void far pascal init_random (void)\r
+                               ;==================================\r
+                               ;\r
+                               ; Scrambles the psuedo-random number sequence\r
+                               ; (XOR's the seed value with the timer)\r
+                               ;\r
+\r
+                                       PUBLIC  INIT_RANDOM\r
+\r
+ 00E2                          INIT_RANDOM     PROC    FAR\r
+\r
+                                       CLR             AX                                      ; Segment = 0000\r
+ 00E2  33 C0                1          xor             AX, AX          ; Set Register = 0\r
+ 00E4  8E C0                           mov             ES, AX\r
+ 00E6  26: A1 046C                     mov             AX, ES:[046Ch]      ; Get Timer Lo Word\r
+\r
+ 00EA  31 06 0000 R                    xor             RND_Seed, AX            ; Scramble 1st Seed\r
+\r
+ 00EE  CB                              ret                                                     ; Exit & Clean Up Stack\r
+\r
+ 00EF                          INIT_RANDOM     ENDP\r
+\r
+                               ;=========================================\r
+                               ;int far pascal int_sqr (int X, int Round)\r
+                               ;=========================================\r
+                               ;\r
+                               ; Returns the Integer Square Root of (X)\r
+                               ; Round allows the return value to be rounded to the \r
+                               ; nearest integer value by passing 0x80.  Passing 0\r
+                               ; return the Integer Portion only.  The rounding amound is\r
+                               ; a number from 0 to 1 multiplied by 256, thus \r
+                               ; 0.5 * 0x100 = 0x80!\r
+                               ;\r
+\r
+ 000C                          ISQ_Stack       STRUC\r
+ 0000  0000 0000                                                       DW      ?,?     ; BP, DI\r
+ 0004  00000000                                                                DD      ?       ; Caller\r
+ 0008  0000                            ISQ_Round               DW      ?       ; Amount to Round Result * 256\r
+ 000A  0000                            ISQ_X                   DW      ?       ; "X"\r
+                               ISQ_Stack       ENDS\r
+\r
+                                       PUBLIC  INT_SQR\r
+\r
+ 00EF                          INT_SQR         PROC    FAR\r
+\r
+                                   PUSHx   BP, DI                              ; Save BP\r
+ 00EF  55                   1                  push    BP                              ; Save R1\r
+ 00F0  57                   2                  push    DI                              ; Save R1\r
+ 00F1  8B EC                       mov     BP, SP                              ; Set up Stack Frame\r
+\r
+ 00F3  33 C0                           xor     AX, AX                          ; {xor eax,eax}\r
+ 00F5  33 D2                           xor     DX, DX                          ; {xor edx,edx}\r
+ 00F7  8B 7E 0A                                mov     DI, [BP].ISQ_X          ; {mov edi,x}\r
+\r
+ 00FA  B9 0010                         mov     CX, 16                          ; {mov cx, 32}\r
+\r
+ 00FD                          @ISQ_L:\r
+\r
+ 00FD  D1 E7                           shl     DI, 1                           ; {shl edi,1}\r
+ 00FF  D1 D2                           rcl     DX, 1                           ; {rcl edx,1}\r
+ 0101  D1 E7                           shl     DI, 1                           ; {shl edi,1}\r
+ 0103  D1 D2                           rcl     DX, 1                           ; {rcl edx,1}\r
+ 0105  D1 E0                           shl     AX, 1                           ; {shl eax,1}\r
+ 0107  8B D8                           mov     BX, AX                          ; {mov ebx,eax}\r
+ 0109  D1 E3                           shl     BX, 1                           ; {shl ebx,1}\r
+ 010B  43                              inc     BX                                      ; {inc ebx}\r
+ 010C  3B D3                           cmp     DX, BX                          ; {cmp edx,ebx}\r
+ 010E  7C 03                           jl              @ISQ_S\r
+\r
+ 0110  2B D3                           sub     DX, BX                          ; {sub edx,ebx}\r
+ 0112  40                              inc     AX                                      ; {inc eax}\r
+\r
+ 0113                          @ISQ_S: \r
+ 0113  E2 E8                           loop    @ISQ_L\r
+\r
+ 0115  03 46 08                                add     ax, [BP].ISQ_Round      ; {add eax,$00008000}  \r
+                                                                                               ; {*round* result in hi word: ie. +0\r
+                               .5}\r
+ 0118  C1 E8 08                                shr     ax, 8                           ; {shr eax,16}  {to ax (result)}\r
+\r
+                                       POPx    DI, BP                          ; Restore Registers     \r
+ 011B  5F                   1                  pop             DI                              ; Restore R1\r
+ 011C  5D                   2                  pop             BP                              ; Restore R1\r
+ 011D  CA 0004                         ret             4                                       ; Exit\r
+\r
+ 0120                          INT_SQR         ENDP\r
+\r
+                               ;=================================\r
+                               ;int far pascal timer_count (void)\r
+                               ;=================================\r
+                               ;\r
+                               ; Returns the current timer value as an integer/long integer\r
+                               ;\r
+\r
+                                       PUBLIC  TIMER_COUNT\r
+\r
+ 0120                          TIMER_COUNT      PROC    FAR\r
+\r
+                                       CLR             AX                                      ; Segment = 0000\r
+ 0120  33 C0                1          xor             AX, AX          ; Set Register = 0\r
+ 0122  8E C0                           mov             ES, AX\r
+ 0124  26: A1 046C                     mov             AX, ES:[046Ch]      ; Get Timer Lo Word\r
+ 0128  26: 8B 16 046E                  mov             DX, ES:[046Eh]          ; Get Timer Hi Word\r
+ 012D  CB                              ret                                                     ; Exit & Clean Up Stack\r
+\r
+ 012E                          TIMER_COUNT      ENDP\r
+\r
+\r
+                                       END\r
+\fMicrosoft (R) Macro Assembler Version 6.11                07/03/14 12:38:18\r
+c_utils.asm                                                 Symbols 3 - 1\r
+\r
+\r
+\r
+\r
+Macros:\r
+\r
+                N a m e                 Type\r
+\r
+CLR  . . . . . . . . . . . . . .       Proc\r
+LOOPjz . . . . . . . . . . . . .       Proc\r
+LOOPx  . . . . . . . . . . . . .       Proc\r
+POPx . . . . . . . . . . . . . .       Proc\r
+PUSHx  . . . . . . . . . . . . .       Proc\r
+\fMicrosoft (R) Macro Assembler Version 6.11                07/03/14 12:38:18\r
+c_utils.asm                                                 Symbols 4 - 1\r
+\r
+\r
+\r
+\r
+Structures and Unions:\r
+\r
+                N a m e                  Size\r
+                                         Offset      Type\r
+\r
+DP_Stack . . . . . . . . . . . .        0010\r
+  DP_Text  . . . . . . . . . . .        000C        DWord\r
+ISQ_Stack  . . . . . . . . . . .        000C\r
+  ISQ_Round  . . . . . . . . . .        0008        Word\r
+  ISQ_X  . . . . . . . . . . . .        000A        Word\r
+RI_Stack . . . . . . . . . . . .        0008\r
+  RI_MaxVal  . . . . . . . . . .        0006        Word\r
+SVM_Stack  . . . . . . . . . . .        000E\r
+  SVM_Mode . . . . . . . . . . .        000C        Byte\r
+\fMicrosoft (R) Macro Assembler Version 6.11                07/03/14 12:38:18\r
+c_utils.asm                                                 Symbols 5 - 1\r
+\r
+\r
+\r
+\r
+Segments and Groups:\r
+\r
+                N a m e                 Size     Length   Align   Combine Class\r
+\r
+C_UTILS_TEXT . . . . . . . . . .       16 Bit   012E     Word    Public  'CODE'        \r
+DGROUP . . . . . . . . . . . . .       GROUP\r
+_DATA  . . . . . . . . . . . . .       16 Bit   0014     Word    Public  'DATA'        \r
+\fMicrosoft (R) Macro Assembler Version 6.11                07/03/14 12:38:18\r
+c_utils.asm                                                 Symbols 6 - 1\r
+\r
+\r
+\r
+\r
+Procedures,  parameters and locals:\r
+\r
+                N a m e                 Type     Value    Attr\r
+\r
+DOS_PRINTS . . . . . . . . . . .       P Far    0039     C_UTILS_TEXT  Length= 0027 Public\r
+DOS_PRINT  . . . . . . . . . . .       P Far    0000     C_UTILS_TEXT  Length= 0039 Public\r
+INIT_RANDOM  . . . . . . . . . .       P Far    00E2     C_UTILS_TEXT  Length= 000D Public\r
+INT_SQR  . . . . . . . . . . . .       P Far    00EF     C_UTILS_TEXT  Length= 0031 Public\r
+RANDOM_INT . . . . . . . . . . .       P Far    0092     C_UTILS_TEXT  Length= 0050 Public\r
+SCAN_KEYBOARD  . . . . . . . . .       P Far    0074     C_UTILS_TEXT  Length= 001E Public\r
+SET_VIDEO_MODE . . . . . . . . .       P Far    0060     C_UTILS_TEXT  Length= 0014 Public\r
+TIMER_COUNT  . . . . . . . . . .       P Far    0120     C_UTILS_TEXT  Length= 000E Public\r
+\fMicrosoft (R) Macro Assembler Version 6.11                07/03/14 12:38:18\r
+c_utils.asm                                                 Symbols 7 - 1\r
+\r
+\r
+\r
+\r
+Symbols:\r
+\r
+                N a m e                 Type     Value    Attr\r
+\r
+?x3  . . . . . . . . . . . . . .       Text     ?,?,?\r
+?x4  . . . . . . . . . . . . . .       Text     ?,?,?,?\r
+@@DPS_Got_len  . . . . . . . . .       L Near   004F     C_UTILS_TEXT  \r
+@@DPS_Scan_it  . . . . . . . . .       L Near   0046     C_UTILS_TEXT  \r
+@@DP_Got_len . . . . . . . . . .       L Near   0016     C_UTILS_TEXT  \r
+@@DP_Scan_it . . . . . . . . . .       L Near   000D     C_UTILS_TEXT  \r
+@CodeSize  . . . . . . . . . . .       Number   0001h   \r
+@DPS_Exit  . . . . . . . . . . .       L Near   0058     C_UTILS_TEXT  \r
+@DataSize  . . . . . . . . . . .       Number   0000h   \r
+@ISQ_L . . . . . . . . . . . . .       L Near   00FD     C_UTILS_TEXT  \r
+@ISQ_S . . . . . . . . . . . . .       L Near   0113     C_UTILS_TEXT  \r
+@Interface . . . . . . . . . . .       Number   0000h   \r
+@Model . . . . . . . . . . . . .       Number   0004h   \r
+@No_Print  . . . . . . . . . . .       L Near   001F     C_UTILS_TEXT  \r
+@SK_Exit . . . . . . . . . . . .       L Near   008C     C_UTILS_TEXT  \r
+@SK_NO_KEY . . . . . . . . . . .       L Near   008A     C_UTILS_TEXT  \r
+@SVM_Exit  . . . . . . . . . . .       L Near   006D     C_UTILS_TEXT  \r
+@code  . . . . . . . . . . . . .       Text     C_UTILS_TEXT\r
+@data  . . . . . . . . . . . . .       Text     DGROUP\r
+@fardata?  . . . . . . . . . . .       Text     FAR_BSS\r
+@fardata . . . . . . . . . . . .       Text     FAR_DATA\r
+@stack . . . . . . . . . . . . .       Text     DGROUP\r
+CR_LF  . . . . . . . . . . . . .       Byte     0012     _DATA \r
+False  . . . . . . . . . . . . .       Number   0000h   \r
+RND_ModV . . . . . . . . . . . .       Word     000C     _DATA \r
+RND_Mult . . . . . . . . . . . .       Word     0006     _DATA \r
+RND_Seed . . . . . . . . . . . .       Word     0000     _DATA \r
+True . . . . . . . . . . . . . .       Number   -0001h   \r
+b  . . . . . . . . . . . . . . .       Text     BYTE PTR\r
+d  . . . . . . . . . . . . . . .       Text     DWORD PTR\r
+f  . . . . . . . . . . . . . . .       Text     FAR PTR\r
+nil  . . . . . . . . . . . . . .       Number   0000h   \r
+o  . . . . . . . . . . . . . . .       Text     OFFSET\r
+s  . . . . . . . . . . . . . . .       Text     SHORT\r
+w  . . . . . . . . . . . . . . .       Text     WORD PTR\r
+\r
+          0 Warnings\r
+          0 Errors\r
diff --git a/src/lib/modex/c_utils.sbr b/src/lib/modex/c_utils.sbr
new file mode 100755 (executable)
index 0000000..0301171
Binary files /dev/null and b/src/lib/modex/c_utils.sbr differ
diff --git a/src/lib/modex/makefile b/src/lib/modex/makefile
new file mode 100755 (executable)
index 0000000..fdf9d91
--- /dev/null
@@ -0,0 +1,30 @@
+!ifdef __LINUX__
+REMOVECOMMAND=rm -f
+COPYCOMMAND=cp -f
+DIRSEP=/
+OBJ=o
+!else
+REMOVECOMMAND=del
+COPYCOMMAND=copy /y
+DIRSEP=\
+OBJ=obj
+!endif
+
+CFLAGS=-d2 -0 -mc
+
+all: x_demo.exe
+
+x_demo.exe: x_demo.$(OBJ) modex.$(OBJ) c_utils.$(OBJ)
+       wcl $(CFLAGS) x_demo.$(OBJ) modex.$(OBJ) c_utils.$(OBJ)
+x_demo.$(OBJ): x_demo.c
+       wcl -c $(CFLAGS) x_demo.c
+
+c_utils.$(OBJ): c_utils.asm
+       wcl -c $(CFLAGS) c_utils.asm
+modex.$(OBJ): modex.asm
+       wcl -c $(CFLAGS) modex.asm
+
+clean: .symbolic
+       @$(REMOVECOMMAND) x-demo.exe
+       @$(REMOVECOMMAND) *.$(OBJ)
+       @$(REMOVECOMMAND) *.err
index 2985fd80def58c8de0feac946d8035da15985a9c..f2b1b5124db8b7d4f6132f68af8e718700e30f6d 100755 (executable)
 ;          READ_DAC_REGISTERS.  Expanded CLR Macro\r
 ;          to handle multiple registers\r
 ;\r
\r
+\r
     PAGE    255, 132\r
\r
-    .MODEL Medium\r
-    .286\r
\r
+\r
+    .MODEL Huge\r
+    ;.286\r
+\r
     ; ===== MACROS =====\r
\r
+\r
     ; Macro to OUT a 16 bit value to an I/O port\r
\r
+\r
 OUT_16 MACRO Register, Value\r
     IFDIFI <Register>, <DX>         ; If DX not setup\r
         MOV     DX, Register        ; then Select Register\r
@@ -101,9 +101,9 @@ OUT_16 MACRO Register, Value
     ENDIF\r
         OUT     DX, AX              ; Set I/O Register(s)\r
 ENDM\r
\r
+\r
     ; Macro to OUT a 8 bit value to an I/O Port\r
\r
+\r
 OUT_8 MACRO Register, Value\r
     IFDIFI <Register>, <DX>         ; If DX not setup\r
         MOV     DX, Register        ; then Select Register\r
@@ -113,64 +113,63 @@ OUT_8 MACRO Register, Value
     ENDIF\r
         OUT     DX, AL              ; Set I/O Register\r
 ENDM\r
\r
+\r
     ; macros to PUSH and POP multiple registers\r
\r
-PUSHx MACRO R1, R2, R3, R4, R5, R6, R7, R8\r
-    IFNB <R1>\r
-        PUSH    R1              ; Save R1\r
-        PUSHx   R2, R3, R4, R5, R6, R7, R8\r
-    ENDIF\r
-ENDM\r
\r
-POPx MACRO R1, R2, R3, R4, R5, R6, R7, R8\r
-    IFNB <R1>\r
-        POP     R1              ; Restore R1\r
-        POPx    R2, R3, R4, R5, R6, R7, R8\r
-    ENDIF\r
-ENDM\r
\r
+\r
+PUSHx MACRO R1, R2, R3, R4, R5, R6, R7, R8\r
+    IFNB <R1>\r
+        PUSH    R1              ; Save R1\r
+        PUSHx   R2, R3, R4, R5, R6, R7, R8\r
+    ENDIF\r
+ENDM\r
+;\r
+POPx MACRO R1, R2, R3, R4, R5, R6, R7, R8\r
+    IFNB <R1>\r
+        POP     R1              ; Restore R1\r
+        POPx    R2, R3, R4, R5, R6, R7, R8\r
+    ENDIF\r
+ENDM\r
+\r
     ; Macro to Clear Registers to 0\r
\r
-CLR MACRO Register, R2, R3, R4, R5, R6\r
-    IFNB <Register>\r
-        XOR     Register, Register      ; Set Register = 0\r
-        CLR R2, R3, R4, R5, R6\r
-    ENDIF\r
-ENDM\r
\r
+\r
+; CLR MACRO Register, R2, R3, R4;, R5, R6\r
+    IFNB <Register>\r
+        XOR     Register, Register      ; Set Register = 0\r
+;         CLR R2, R3, R4;, R5, R6\r
+    ENDIF\r
+ENDM\r
+\r
     ; Macros to Decrement Counter & Jump on Condition\r
\r
+\r
 LOOPx MACRO Register, Destination\r
     DEC     Register                ; Counter--\r
     JNZ     Destination             ; Jump if not 0\r
 ENDM\r
\r
+\r
 LOOPjz MACRO Register, Destination\r
     DEC     Register                ; Counter--\r
     JZ      Destination             ; Jump if 0\r
 ENDM\r
\r
\r
+\r
+\r
     ; ===== General Constants =====\r
\r
+\r
     False   EQU 0\r
     True    EQU -1\r
     nil     EQU 0\r
\r
+\r
     b       EQU BYTE PTR\r
     w       EQU WORD PTR\r
     d       EQU DWORD PTR\r
     o       EQU OFFSET\r
     f       EQU FAR PTR\r
     s       EQU SHORT\r
-    ?x4     EQU <?,?,?,?>\r
-    ?x3     EQU <?,?,?>\r
\r
+    ?x1     EQU <?>\r
+\r
     ; ===== VGA Register Values =====\r
\r
+\r
     VGA_Segment     EQU 0A000h  ; Vga Memory Segment\r
\r
+\r
     ATTRIB_Ctrl     EQU 03C0h   ; VGA Attribute Controller\r
     GC_Index        EQU 03CEh   ; VGA Graphics Controller\r
     SC_Index        EQU 03C4h   ; VGA Sequencer Controller\r
@@ -179,43 +178,43 @@ ENDM
     CRTC_Data       EQU 03D5h   ; VGA CRT Controller Data\r
     MISC_OUTPUT     EQU 03C2h   ; VGA Misc Register\r
     INPUT_1         EQU 03DAh   ; Input Status #1 Register\r
\r
+\r
     DAC_WRITE_ADDR  EQU 03C8h   ; VGA DAC Write Addr Register\r
     DAC_READ_ADDR   EQU 03C7h   ; VGA DAC Read Addr Register\r
     PEL_DATA_REG    EQU 03C9h   ; VGA DAC/PEL data Register R/W\r
\r
+\r
     PIXEL_PAN_REG   EQU 033h    ; Attrib Index: Pixel Pan Reg\r
     MAP_MASK        EQU 002h    ; Sequ Index: Write Map Mask reg\r
     READ_MAP        EQU 004h    ; GC Index: Read Map Register\r
     START_DISP_HI   EQU 00Ch    ; CRTC Index: Display Start Hi\r
     START_DISP_LO   EQU 00Dh    ; CRTC Index: Display Start Lo\r
\r
+\r
     MAP_MASK_PLANE1 EQU 00102h  ; Map Register + Plane 1\r
     MAP_MASK_PLANE2 EQU 01102h  ; Map Register + Plane 1\r
     ALL_PLANES_ON   EQU 00F02h  ; Map Register + All Bit Planes\r
\r
+\r
     CHAIN4_OFF      EQU 00604h  ; Chain 4 mode Off\r
     ASYNC_RESET     EQU 00100h  ; (A)synchronous Reset\r
     SEQU_RESTART    EQU 00300h  ; Sequencer Restart\r
\r
+\r
     LATCHES_ON      EQU 00008h  ; Bit Mask + Data from Latches\r
     LATCHES_OFF     EQU 0FF08h  ; Bit Mask + Data from CPU\r
\r
+\r
     VERT_RETRACE    EQU 08h     ; INPUT_1: Vertical Retrace Bit\r
     PLANE_BITS      EQU 03h     ; Bits 0-1 of Xpos = Plane #\r
     ALL_PLANES      EQU 0Fh     ; All Bit Planes Selected\r
     CHAR_BITS       EQU 0Fh     ; Bits 0-3 of Character Data\r
\r
+\r
     GET_CHAR_PTR    EQU 01130h  ; VGA BIOS Func: Get Char Set\r
     ROM_8x8_Lo      EQU 03h     ; ROM 8x8 Char Set Lo Pointer\r
     ROM_8x8_Hi      EQU 04h     ; ROM 8x8 Char Set Hi Pointer\r
\r
+\r
     ; Constants Specific for these routines\r
\r
+\r
     NUM_MODES       EQU 8       ; # of Mode X Variations\r
\r
+\r
     ; Specific Mode Data Table format...\r
\r
+\r
 Mode_Data_Table STRUC\r
     M_MiscR         DB  ?       ; Value of MISC_OUTPUT register\r
     M_Pages         DB  ?       ; Maximum Possible # of pages\r
@@ -225,69 +224,69 @@ Mode_Data_Table STRUC
     M_YMax          DW  ?       ; Maximum Possible Y Size\r
     M_CRTC          DW  ?       ; Table of CRTC register values\r
 Mode_Data_Table ENDS\r
\r
+\r
     ; ===== DGROUP STORAGE NEEDED (42 BYTES) =====\r
\r
+\r
     .DATA?\r
\r
+\r
 SCREEN_WIDTH    DW  0       ; Width of a line in Bytes\r
 SCREEN_HEIGHT   DW  0       ; Vertical Height in Pixels\r
\r
+\r
 LAST_PAGE       DW  0       ; # of Display Pages\r
 PAGE_ADDR       DW  4 DUP (0)   ; Offsets to start of each page\r
\r
+\r
 PAGE_SIZE       DW  0       ; Size of Page in Addr Bytes\r
\r
+\r
 DISPLAY_PAGE    DW  0       ; Page # currently displayed\r
 ACTIVE_PAGE     DW  0       ; Page # currently active\r
\r
+\r
 CURRENT_PAGE    DW  0       ; Offset of current Page\r
 CURRENT_SEGMENT DW  0       ; Segment of VGA memory\r
\r
+\r
 CURRENT_XOFFSET DW  0       ; Current Display X Offset\r
 CURRENT_YOFFSET DW  0       ; Current Display Y Offset\r
\r
+\r
 CURRENT_MOFFSET DW  0       ; Current Start Offset\r
\r
+\r
 MAX_XOFFSET     DW  0       ; Current Display X Offset\r
 MAX_YOFFSET     DW  0       ; Current Display Y Offset\r
\r
+\r
 CHARSET_LOW     DW  0, 0    ; Far Ptr to Char Set: 0-127\r
 CHARSET_HI      DW  0, 0    ; Far Ptr to Char Set: 128-255\r
\r
+\r
     .CODE\r
\r
+\r
     ; ===== DATA TABLES =====\r
\r
+\r
     ; Data Tables, Put in Code Segment for Easy Access\r
     ; (Like when all the other Segment Registers are in\r
     ; use!!) and reduced DGROUP requirements...\r
\r
+\r
     ; Bit Mask Tables for Left/Right/Character Masks\r
\r
+\r
 Left_Clip_Mask      DB  0FH, 0EH, 0CH, 08H\r
\r
+\r
 Right_Clip_Mask     DB  01H, 03H, 07H, 0FH\r
\r
+\r
     ; Bit Patterns for converting character fonts\r
\r
+\r
 Char_Plane_Data     DB  00H,08H,04H,0CH,02H,0AH,06H,0EH\r
                     DB  01H,09H,05H,0DH,03H,0BH,07H,0FH\r
\r
+\r
         ; CRTC Register Values for Various Configurations\r
\r
+\r
 MODE_Single_Line:       ; CRTC Setup Data for 400/480 Line modes\r
         DW  04009H      ; Cell Height (1 Scan Line)\r
         DW  00014H      ; Dword Mode off\r
         DW  0E317H      ; turn on Byte Mode\r
         DW  nil         ; End of CRTC Data for 400/480 Line Mode\r
\r
+\r
 MODE_Double_Line:       ; CRTC Setup Data for 200/240 Line modes\r
         DW  04109H      ; Cell Height (2 Scan Lines)\r
         DW  00014H      ; Dword Mode off\r
         DW  0E317H      ; turn on Byte Mode\r
         DW  nil         ; End of CRTC Data for 200/240 Line Mode\r
\r
+\r
 MODE_320_Wide:          ; CRTC Setup Data for 320 Horz Pixels\r
         DW  05F00H      ; Horz total\r
         DW  04F01H      ; Horz Displayed\r
@@ -296,7 +295,7 @@ MODE_320_Wide:          ; CRTC Setup Data for 320 Horz Pixels
         DW  05404H      ; Start H Sync\r
         DW  08005H      ; End H Sync\r
         DW  nil         ; End of CRTC Data for 320 Horz pixels\r
\r
+\r
 MODE_360_Wide:          ; CRTC Setup Data for 360 Horz Pixels\r
         DW  06B00H      ; Horz total\r
         DW  05901H      ; Horz Displayed\r
@@ -305,7 +304,7 @@ MODE_360_Wide:          ; CRTC Setup Data for 360 Horz Pixels
         DW  05E04H      ; Start H Sync\r
         DW  08A05H      ; End H Sync\r
         DW  nil         ; End of CRTC Data for 360 Horz pixels\r
\r
+\r
 MODE_200_Tall:\r
 MODE_400_Tall:          ; CRTC Setup Data for 200/400 Line modes\r
         DW  0BF06H      ; Vertical Total\r
@@ -316,7 +315,7 @@ MODE_400_Tall:          ; CRTC Setup Data for 200/400 Line modes
         DW  09615H      ; V Blank Start\r
         DW  0B916H      ; V Blank End\r
         DW  nil         ; End of CRTC Data for 200/400 Lines\r
\r
+\r
 MODE_240_Tall:\r
 MODE_480_Tall:          ; CRTC Setup Data for 240/480 Line modes\r
         DW  00D06H      ; Vertical Total\r
@@ -327,100 +326,100 @@ MODE_480_Tall:          ; CRTC Setup Data for 240/480 Line modes
         DW  0E715H      ; V Blank Start\r
         DW  00616H      ; V Blank End\r
         DW  nil         ; End of CRTC Data for 240/480 Lines\r
\r
+\r
         ; Table of Display Mode Tables\r
\r
+\r
 MODE_TABLE:\r
         DW  o MODE_320x200, o MODE_320x400\r
         DW  o MODE_360x200, o MODE_360x400\r
         DW  o MODE_320x240, o MODE_320x480\r
         DW  o MODE_360x240, o MODE_360x480\r
\r
+\r
         ; Table of Display Mode Components\r
\r
+\r
 MODE_320x200:           ; Data for 320 by 200 Pixels\r
\r
+\r
         DB  063h        ; 400 scan Lines & 25 Mhz Clock\r
         DB  4           ; Maximum of 4 Pages\r
         DW  320, 200    ; Displayed Pixels (X,Y)\r
         DW  1302, 816   ; Max Possible X and Y Sizes\r
\r
+\r
         DW  o MODE_320_Wide, o MODE_200_Tall\r
         DW  o MODE_Double_Line, nil\r
\r
+\r
 MODE_320x400:           ; Data for 320 by 400 Pixels\r
\r
+\r
         DB  063h        ; 400 scan Lines & 25 Mhz Clock\r
         DB  2           ; Maximum of 2 Pages\r
         DW  320, 400    ; Displayed Pixels X,Y\r
         DW  648, 816    ; Max Possible X and Y Sizes\r
\r
+\r
         DW  o MODE_320_Wide, o MODE_400_Tall\r
         DW  o MODE_Single_Line, nil\r
\r
+\r
 MODE_360x240:           ; Data for 360 by 240 Pixels\r
\r
+\r
         DB  0E7h        ; 480 scan Lines & 28 Mhz Clock\r
         DB  3           ; Maximum of 3 Pages\r
         DW  360, 240    ; Displayed Pixels X,Y\r
         DW  1092, 728   ; Max Possible X and Y Sizes\r
\r
+\r
         DW  o MODE_360_Wide, o MODE_240_Tall\r
         DW  o MODE_Double_Line , nil\r
\r
+\r
 MODE_360x480:           ; Data for 360 by 480 Pixels\r
\r
+\r
         DB  0E7h        ; 480 scan Lines & 28 Mhz Clock\r
         DB  1           ; Only 1 Page Possible\r
         DW  360, 480    ; Displayed Pixels X,Y\r
         DW  544, 728    ; Max Possible X and Y Sizes\r
\r
+\r
         DW  o MODE_360_Wide, o MODE_480_Tall\r
         DW  o MODE_Single_Line , nil\r
\r
+\r
 MODE_320x240:           ; Data for 320 by 240 Pixels\r
\r
+\r
         DB  0E3h        ; 480 scan Lines & 25 Mhz Clock\r
         DB  3           ; Maximum of 3 Pages\r
         DW  320, 240    ; Displayed Pixels X,Y\r
         DW  1088, 818   ; Max Possible X and Y Sizes\r
\r
+\r
         DW  o MODE_320_Wide, o MODE_240_Tall\r
         DW  o MODE_Double_Line, nil\r
\r
+\r
 MODE_320x480:           ; Data for 320 by 480 Pixels\r
\r
+\r
         DB  0E3h        ; 480 scan Lines & 25 Mhz Clock\r
         DB  1           ; Only 1 Page Possible\r
         DW  320, 480    ; Displayed Pixels X,Y\r
         DW  540, 818    ; Max Possible X and Y Sizes\r
\r
+\r
         DW  o MODE_320_WIDE, o MODE_480_Tall\r
         DW  o MODE_Single_Line, nil\r
\r
+\r
 MODE_360x200:           ; Data for 360 by 200 Pixels\r
\r
+\r
         DB  067h        ; 400 scan Lines & 28 Mhz Clock\r
         DB  3           ; Maximum of 3 Pages\r
         DW  360, 200    ; Displayed Pixels (X,Y)\r
         DW  1302, 728   ; Max Possible X and Y Sizes\r
\r
+\r
         DW  o MODE_360_Wide, MODE_200_Tall\r
         DW  o MODE_Double_Line, nil\r
\r
+\r
 MODE_360x400:           ; Data for 360 by 400 Pixels\r
\r
+\r
         DB  067h        ; 400 scan Lines & 28 Mhz Clock\r
         DB  1           ; Maximum of 1 Pages\r
         DW  360, 400    ; Displayed Pixels X,Y\r
         DW  648, 816    ; Max Possible X and Y Sizes\r
\r
+\r
         DW  o MODE_360_Wide, MODE_400_Tall\r
         DW  o MODE_Single_Line, nil\r
\r
\r
+\r
+\r
     ; ===== MODE X SETUP ROUTINES =====\r
\r
+\r
 ;======================================================\r
 ;SET_VGA_MODEX% (ModeType%, MaxXPos%, MaxYpos%, Pages%)\r
 ;======================================================\r
@@ -445,118 +444,149 @@ MODE_360x400:           ; Data for 360 by 400 Pixels
 ;        MaxYpos = The Desired Virtual Screen Height\r
 ;        Pages   = The Desired # of Video Pages\r
 ;\r
-; EXIT:  AX = Success Flag:   0 = Failure / -1= Success\r
+; EXIT:  AX = Success Flag:   >0 = Failure / 0 = Success\r
 ;\r
\r
+\r
 SVM_STACK   STRUC\r
     SVM_Table   DW  ?   ; Offset of Mode Info Table\r
-                DW  ?x4 ; DI, SI, DS, BP\r
+                DW  ?x1 ; DI, SI, DS, BP\r
+                DW  ?x1 ; DI, SI, DS, BP\r
+                DW  ?x1 ; DI, SI, DS, BP\r
+                DW  ?x1 ; DI, SI, DS, BP\r
                 DD  ?   ; Caller\r
     SVM_Pages   DW  ?   ; # of Screen Pages desired\r
     SVM_Ysize   DW  ?   ; Vertical Screen Size Desired\r
     SVM_Xsize   DW  ?   ; Horizontal Screen Size Desired\r
     SVM_Mode    DW  ?   ; Display Resolution Desired\r
 SVM_STACK   ENDS\r
\r
+\r
     PUBLIC  SET_VGA_MODEX\r
\r
+\r
 SET_VGA_MODEX   PROC    FAR\r
\r
-    PUSHx   BP, DS, SI, DI      ; Preserve Important Registers\r
+\r
+    ;PUSHx   BP, DS, SI, DI      ; Preserve Important Registers\r
+    push       bp\r
+       push    ds\r
+       push    si\r
+       push    di\r
     SUB     SP, 2               ; Allocate workspace\r
     MOV     BP, SP              ; Set up Stack Frame\r
\r
+\r
     ; Check Legality of Mode Request....\r
\r
+\r
     MOV     BX, [BP].SVM_Mode   ; Get Requested Mode #\r
     CMP     BX, NUM_MODES       ; Is it 0..7?\r
-    JAE     @SVM_BadModeSetup   ; If Not, Error out\r
\r
+    JAE     @SVM_BadModeSetup1   ; If Not, Error out\r
+\r
     SHL     BX, 1                   ; Scale BX\r
     MOV     SI, w MODE_TABLE[BX]    ; CS:SI -> Mode Info\r
     MOV     [BP].SVM_Table, SI      ; Save ptr for later use\r
\r
+\r
     ; Check # of Requested Display Pages\r
\r
+\r
     MOV     CX, [BP].SVM_Pages  ; Get # of Requested Pages\r
-    CLR     CH                  ; Set Hi Word = 0!\r
+    ;CLR       CH                  ; Set Hi Word = 0!\r
+    mov        ch,0                  ; Set Hi Word = 0!\r
     CMP     CL, CS:[SI].M_Pages ; Check # Pages for mode\r
-    JA      @SVM_BadModeSetup   ; Report Error if too Many Pages\r
-    JCXZ    @SVM_BadModeSetup   ; Report Error if 0 Pages\r
\r
+    JA      @SVM_BadModeSetup2   ; Report Error if too Many Pages\r
+    JCXZ    @SVM_BadModeSetup3   ; Report Error if 0 Pages\r
+\r
     ; Check Validity of X Size\r
\r
+\r
     AND     [BP].SVM_XSize, 0FFF8h  ; X size Mod 8 Must = 0\r
\r
+\r
     MOV     AX, [BP].SVM_XSize  ; Get Logical Screen Width\r
     CMP     AX, CS:[SI].M_XSize ; Check against Displayed X\r
-    JB      @SVM_BadModeSetup   ; Report Error if too small\r
+    JB      @SVM_BadModeSetup4   ; Report Error if too small\r
     CMP     AX, CS:[SI].M_XMax  ; Check against Max X\r
-    JA      @SVM_BadModeSetup   ; Report Error if too big\r
\r
+    JA      @SVM_BadModeSetup5   ; Report Error if too big\r
+\r
     ; Check Validity of Y Size\r
\r
+\r
     MOV     BX, [BP].SVM_YSize  ; Get Logical Screen Height\r
     CMP     BX, CS:[SI].M_YSize ; Check against Displayed Y\r
-    JB      @SVM_BadModeSetup   ; Report Error if too small\r
+    JB      @SVM_BadModeSetup6   ; Report Error if too small\r
     CMP     BX, CS:[SI].M_YMax  ; Check against Max Y\r
-    JA      @SVM_BadModeSetup   ; Report Error if too big\r
\r
+    JA      @SVM_BadModeSetup7   ; Report Error if too big\r
+\r
     ; Enough memory to Fit it all?\r
\r
-    SHR     AX, 2               ; # of Bytes:Line = XSize/4\r
+\r
+    SHR     AX, 1               ; # of Bytes:Line = XSize/4\r
+    SHR     AX, 1               ; # of Bytes:Line = XSize/4\r
     MUL     CX                  ; AX = Bytes/Line * Pages\r
     MUL     BX                  ; DX:AX = Total VGA mem needed\r
     JNO     @SVM_Continue       ; Exit if Total Size > 256K\r
\r
+\r
     DEC     DX                  ; Was it Exactly 256K???\r
     OR      DX, AX              ; (DX = 1, AX = 0000)\r
     JZ      @SVM_Continue       ; if so, it's valid...\r
\r
+\r
+       jmp      @SVM_Continue;0000\r
+\r
 @SVM_BadModeSetup:\r
\r
-    CLR     AX                  ; Return Value = False\r
+    mov ax,8                  ; Return Value = False\r
+    JMP     @SVM_Exit           ; Normal Exit\r
+@SVM_BadModeSetup1:\r
+    mov ax,1                  ; Return Value = False\r
+    JMP     @SVM_Exit           ; Normal Exit\r
+@SVM_BadModeSetup2:\r
+    mov ax,2                  ; Return Value = False\r
+    JMP     @SVM_Exit           ; Normal Exit\r
+@SVM_BadModeSetup3:\r
+    mov ax,3                  ; Return Value = False\r
+    JMP     @SVM_Exit           ; Normal Exit\r
+@SVM_BadModeSetup4:\r
+    mov ax,4                  ; Return Value = False\r
+    JMP     @SVM_Exit           ; Normal Exit\r
+@SVM_BadModeSetup5:\r
+    mov ax,5                  ; Return Value = False\r
+    JMP     @SVM_Exit           ; Normal Exit\r
+@SVM_BadModeSetup6:\r
+    mov ax,6                  ; Return Value = False\r
+    JMP     @SVM_Exit           ; Normal Exit\r
+@SVM_BadModeSetup7:\r
+    mov ax,7                  ; Return Value = False\r
     JMP     @SVM_Exit           ; Normal Exit\r
\r
+\r
 @SVM_Continue:\r
\r
+\r
     MOV     AX, 13H             ; Start with Mode 13H\r
     INT     10H                 ; Let BIOS Set Mode\r
\r
+\r
     OUT_16  SC_INDEX, CHAIN4_OFF            ; Disable Chain 4 Mode\r
     OUT_16  SC_INDEX, ASYNC_RESET           ; (A)synchronous Reset\r
     OUT_8   MISC_OUTPUT, CS:[SI].M_MiscR    ; Set New Timing/Size\r
     OUT_16  SC_INDEX, SEQU_RESTART          ; Restart Sequencer ...\r
\r
+\r
     OUT_8   CRTC_INDEX, 11H     ; Select Vert Retrace End Register\r
     INC     DX                  ; Point to Data\r
     IN      AL, DX              ; Get Value, Bit 7 = Protect\r
     AND     AL, 7FH             ; Mask out Write Protect\r
     OUT     DX, AL              ; And send it back\r
\r
+\r
     MOV     DX, CRTC_INDEX      ; Vga Crtc Registers\r
     ADD     SI, M_CRTC          ; SI -> CRTC Parameter Data\r
\r
+\r
     ; Load Tables of CRTC Parameters from List of Tables\r
\r
+\r
 @SVM_Setup_Table:\r
\r
+\r
     MOV     DI, CS:[SI]         ; Get Pointer to CRTC Data Tbl\r
     ADD     SI, 2               ; Point to next Ptr Entry\r
     OR      DI, DI              ; A nil Ptr means that we have\r
     JZ      @SVM_Set_Data       ; finished CRTC programming\r
\r
+\r
 @SVM_Setup_CRTC:\r
     MOV     AX, CS:[DI]         ; Get CRTC Data from Table\r
     ADD     DI, 2               ; Advance Pointer\r
     OR      AX, AX              ; At End of Data Table?\r
     JZ      @SVM_Setup_Table    ; If so, Exit & get next Table\r
\r
+\r
     OUT     DX, AX              ; Reprogram VGA CRTC reg\r
     JMP     s @SVM_Setup_CRTC   ; Process Next Table Entry\r
\r
+\r
     ; Initialize Page & Scroll info, DI = 0\r
\r
+\r
 @SVM_Set_Data:\r
     MOV     DISPLAY_PAGE, DI    ; Display Page = 0\r
     MOV     ACTIVE_PAGE, DI     ; Active Page = 0\r
@@ -564,88 +594,93 @@ SET_VGA_MODEX   PROC    FAR
     MOV     CURRENT_XOFFSET, DI ; Horz Scroll Index = 0\r
     MOV     CURRENT_YOFFSET, DI ; Vert Scroll Index = 0\r
     MOV     CURRENT_MOFFSET, DI ; Memory Scroll Index = 0\r
\r
+\r
     MOV     AX, VGA_SEGMENT     ; Segment for VGA memory\r
     MOV     CURRENT_SEGMENT, AX ; Save for Future LES's\r
\r
+\r
     ; Set Logical Screen Width, X Scroll and Our Data\r
\r
+\r
     MOV     SI, [BP].SVM_Table  ; Get Saved Ptr to Mode Info\r
     MOV     AX, [BP].SVM_Xsize  ; Get Display Width\r
\r
+\r
     MOV     CX, AX              ; CX = Logical Width\r
     SUB     CX, CS:[SI].M_XSize ; CX = Max X Scroll Value\r
     MOV     MAX_XOFFSET, CX     ; Set Maximum X Scroll\r
\r
-    SHR     AX, 2               ; Bytes = Pixels / 4\r
+\r
+    SHR     AX, 1               ; Bytes = Pixels / 4\r
+    SHR     AX, 1               ; Bytes = Pixels / 4\r
     MOV     SCREEN_WIDTH, AX    ; Save Width in Pixels\r
\r
+\r
     SHR     AX, 1               ; Offset Value = Bytes / 2\r
     MOV     AH, 13h             ; CRTC Offset Register Index\r
     XCHG    AL, AH              ; Switch format for OUT\r
     OUT     DX, AX              ; Set VGA CRTC Offset Reg\r
\r
+\r
     ; Setup Data table, Y Scroll, Misc for Other Routines\r
\r
+\r
     MOV     AX, [BP].SVM_Ysize  ; Get Logical Screen Height\r
\r
+\r
     MOV     CX, AX              ; CX = Logical Height\r
     SUB     BX, CS:[SI].M_YSize ; CX = Max Y Scroll Value\r
     MOV     MAX_YOFFSET, CX     ; Set Maximum Y Scroll\r
\r
+\r
     MOV     SCREEN_HEIGHT, AX   ; Save Height in Pixels\r
     MUL     SCREEN_WIDTH        ; AX = Page Size in Bytes,\r
     MOV     PAGE_SIZE, AX       ; Save Page Size\r
\r
+\r
     MOV     CX, [BP].SVM_Pages  ; Get # of Pages\r
     MOV     LAST_PAGE, CX       ; Save # of Pages\r
\r
-    CLR     BX                  ; Page # = 0\r
+\r
+    mov bx,0                  ; Page # = 0\r
     MOV     DX, BX              ; Page 0 Offset = 0\r
\r
+\r
 @SVM_Set_Pages:\r
\r
+\r
     MOV     PAGE_ADDR[BX], DX   ; Set Page #(BX) Offset\r
     ADD     BX, 2               ; Page#++\r
     ADD     DX, AX              ; Compute Addr of Next Page\r
     LOOPx   CX, @SVM_Set_Pages  ; Loop until all Pages Set\r
\r
+\r
     ; Clear VGA Memory\r
\r
+\r
     OUT_16  SC_INDEX, ALL_PLANES_ON ; Select All Planes\r
     LES     DI, d CURRENT_PAGE      ; -> Start of VGA memory\r
\r
-    CLR     AX                  ; AX = 0\r
+\r
+    mov ax,0                  ; AX = 0\r
     CLD                         ; Block Xfer Forwards\r
     MOV     CX, 8000H           ; 32K * 4 * 2 = 256K\r
     REP     STOSW               ; Clear dat memory!\r
\r
+\r
     ; Setup Font Pointers\r
\r
+\r
     MOV     BH, ROM_8x8_Lo      ; Ask for 8x8 Font, 0-127\r
     MOV     AX, GET_CHAR_PTR    ; Service to Get Pointer\r
     INT     10h                 ; Call VGA BIOS\r
\r
+\r
     MOV     CHARSET_LOW, BP     ; Save Char Set Offset\r
     MOV     CHARSET_LOW+2, ES   ; Save Char Set Segment\r
\r
+\r
     MOV     BH, ROM_8x8_Hi      ; Ask for 8x8 Font, 128-255\r
     MOV     AX, GET_CHAR_PTR    ; Service to Get Pointer\r
     INT     10h                 ; Call VGA BIOS\r
\r
+\r
     MOV     CHARSET_HI, BP      ; Save Char Set Offset\r
     MOV     CHARSET_HI+2, ES    ; Save Char Set Segment\r
\r
+\r
     MOV     AX, True            ; Return Success Code\r
\r
+\r
 @SVM_EXIT:\r
     ADD     SP, 2               ; Deallocate workspace\r
-    POPx    DI, SI, DS, BP      ; Restore Saved Registers\r
+    ;POPx    DI, SI, DS, BP      ; Restore Saved Registers\r
+    pop        di\r
+       pop     si\r
+       pop     ds\r
+       pop     bp\r
     RET     8                   ; Exit & Clean Up Stack\r
\r
+\r
 SET_VGA_MODEX   ENDP\r
\r
\r
+\r
+\r
 ;==================\r
 ;SET_MODEX% (Mode%)\r
 ;==================\r
@@ -657,47 +692,51 @@ SET_VGA_MODEX   ENDP
 ;\r
 ; EXIT:  AX = Success Flag:   0 = Failure / -1= Success\r
 ;\r
\r
+\r
 SM_STACK    STRUC\r
                 DW  ?,? ; BP, SI\r
                 DD  ?   ; Caller\r
     SM_Mode     DW  ?   ; Desired Screen Resolution\r
 SM_STACK    ENDS\r
\r
+\r
     PUBLIC  SET_MODEX\r
\r
+\r
 SET_MODEX   PROC    FAR\r
\r
-    PUSHx   BP, SI              ; Preserve Important registers\r
+\r
+    ;PUSHx   BP, SI              ; Preserve Important registers\r
+    push       bp\r
+       push    si\r
     MOV     BP, SP              ; Set up Stack Frame\r
\r
-    CLR     AX                  ; Assume Failure\r
+\r
+    mov ax,0                  ; Assume Failure\r
     MOV     BX, [BP].SM_Mode    ; Get Desired Mode #\r
     CMP     BX, NUM_MODES       ; Is it a Valid Mode #?\r
     JAE     @SMX_Exit           ; If Not, don't Bother\r
\r
+\r
     PUSH    BX                  ; Push Mode Parameter\r
\r
+\r
     SHL     BX, 1                   ; Scale BX to word Index\r
     MOV     SI, w MODE_TABLE[BX]    ; CS:SI -> Mode Info\r
\r
+\r
     PUSH    CS:[SI].M_XSize     ; Push Default X Size\r
     PUSH    CS:[SI].M_Ysize     ; Push Default Y size\r
     MOV     AL, CS:[SI].M_Pages ; Get Default # of Pages\r
-    CLR     AH                  ; Hi Byte = 0\r
+    mov ah,0                  ; Hi Byte = 0\r
     PUSH    AX                  ; Push # Pages\r
\r
+\r
     CALL    f SET_VGA_MODEX     ; Set up Mode X!\r
\r
+\r
 @SMX_Exit:\r
-    POPx    SI, BP              ; Restore Registers\r
+    ;POPx    SI, BP              ; Restore Registers\r
+       pop     si\r
+       pop     bp\r
     RET     2                   ; Exit & Clean Up Stack\r
\r
+\r
 SET_MODEX   ENDP\r
\r
\r
+\r
+\r
     ; ===== BASIC GRAPHICS PRIMITIVES =====\r
\r
+\r
 ;============================\r
 ;CLEAR_VGA_SCREEN (ColorNum%)\r
 ;============================\r
@@ -708,37 +747,41 @@ SET_MODEX   ENDP
 ;\r
 ; EXIT:  No meaningful values returned\r
 ;\r
\r
+\r
 CVS_STACK   STRUC\r
                 DW  ?,? ; DI, BP\r
                 DD  ?   ; Caller\r
     CVS_COLOR   DB  ?,? ; Color to Set Screen to\r
 CVS_STACK   ENDS\r
\r
+\r
     PUBLIC  CLEAR_VGA_SCREEN\r
\r
+\r
 CLEAR_VGA_SCREEN    PROC    FAR\r
\r
-    PUSHx   BP, DI              ; Preserve Important Registers\r
+\r
+    ;PUSHx   BP, DI              ; Preserve Important Registers\r
+    push       bp\r
+       push    di\r
     MOV     BP, SP              ; Set up Stack Frame\r
\r
+\r
     OUT_16  SC_INDEX, ALL_PLANES_ON ; Select All Planes\r
     LES     DI, d CURRENT_PAGE      ; Point to Active VGA Page\r
\r
+\r
     MOV     AL, [BP].CVS_COLOR  ; Get Color\r
     MOV     AH, AL              ; Copy for Word Write\r
     CLD                         ; Block fill Forwards\r
\r
+\r
     MOV     CX, PAGE_SIZE       ; Get Size of Page\r
     SHR     CX, 1               ; Divide by 2 for Words\r
     REP     STOSW               ; Block Fill VGA memory\r
\r
-    POPx    DI, BP              ; Restore Saved Registers\r
+\r
+    ;POPx    DI, BP              ; Restore Saved Registers\r
+    pop        di\r
+       pop     bp\r
     RET     2                   ; Exit & Clean Up Stack\r
\r
+\r
 CLEAR_VGA_SCREEN    ENDP\r
\r
\r
+\r
+\r
 ;===================================\r
 ;SET_POINT (Xpos%, Ypos%, ColorNum%)\r
 ;===================================\r
@@ -751,7 +794,7 @@ CLEAR_VGA_SCREEN    ENDP
 ;\r
 ; EXIT:  No meaningful values returned\r
 ;\r
\r
+\r
 SP_STACK    STRUC\r
                 DW  ?,? ; BP, DI\r
                 DD  ?   ; Caller\r
@@ -759,38 +802,43 @@ SP_STACK    STRUC
     SETP_Ypos   DW  ?   ; Y pos of Point to Plot\r
     SETP_Xpos   DW  ?   ; X pos of Point to Plot\r
 SP_STACK    ENDS\r
\r
+\r
         PUBLIC SET_POINT\r
\r
+\r
 SET_POINT   PROC    FAR\r
\r
-    PUSHx   BP, DI              ; Preserve Registers\r
+\r
+    ;PUSHx   BP, DI              ; Preserve Registers\r
+    push       bp\r
+       push    di\r
     MOV     BP, SP              ; Set up Stack Frame\r
\r
+\r
     LES     DI, d CURRENT_PAGE  ; Point to Active VGA Page\r
\r
+\r
     MOV     AX, [BP].SETP_Ypos  ; Get Line # of Pixel\r
     MUL     SCREEN_WIDTH        ; Get Offset to Start of Line\r
\r
+\r
     MOV     BX, [BP].SETP_Xpos  ; Get Xpos\r
     MOV     CX, BX              ; Copy to extract Plane # from\r
-    SHR     BX, 2               ; X offset (Bytes) = Xpos/4\r
+    SHR     BX, 1               ; X offset (Bytes) = Xpos/4\r
+    SHR     BX, 1               ; X offset (Bytes) = Xpos/4\r
     ADD     BX, AX              ; Offset = Width*Ypos + Xpos/4\r
\r
+\r
     MOV     AX, MAP_MASK_PLANE1 ; Map Mask & Plane Select Register\r
     AND     CL, PLANE_BITS      ; Get Plane Bits\r
     SHL     AH, CL              ; Get Plane Select Value\r
     OUT_16  SC_Index, AX        ; Select Plane\r
\r
+\r
     MOV     AL,[BP].SETP_Color  ; Get Pixel Color\r
     MOV     ES:[DI+BX], AL      ; Draw Pixel\r
\r
-    POPx    DI, BP              ; Restore Saved Registers\r
+\r
+    ;POPx    DI, BP              ; Restore Saved Registers\r
+    pop        di\r
+       pop     bp\r
     RET     6                   ; Exit and Clean up Stack\r
\r
+\r
 SET_POINT        ENDP\r
\r
\r
+\r
+\r
 ;==========================\r
 ;READ_POINT% (Xpos%, Ypos%)\r
 ;==========================\r
@@ -802,45 +850,50 @@ SET_POINT        ENDP
 ;\r
 ; EXIT:  AX   = Color of Pixel at (Xpos, Ypos)\r
 ;\r
\r
+\r
 RP_STACK    STRUC\r
             DW  ?,? ; BP, DI\r
             DD  ?   ; Caller\r
     RP_Ypos DW  ?   ; Y pos of Point to Read\r
     RP_Xpos DW  ?   ; X pos of Point to Read\r
 RP_STACK    ENDS\r
\r
+\r
         PUBLIC  READ_POINT\r
\r
+\r
 READ_POINT      PROC    FAR\r
\r
-    PUSHx   BP, DI              ; Preserve Registers\r
+\r
+    ;PUSHx   BP, DI              ; Preserve Registers\r
+    push       bp\r
+       push    di\r
     MOV     BP, SP              ; Set up Stack Frame\r
\r
+\r
     LES     DI, d CURRENT_PAGE  ; Point to Active VGA Page\r
\r
+\r
     MOV     AX, [BP].RP_Ypos    ; Get Line # of Pixel\r
     MUL     SCREEN_WIDTH        ; Get Offset to Start of Line\r
\r
+\r
     MOV     BX, [BP].RP_Xpos    ; Get Xpos\r
     MOV     CX, BX\r
-    SHR     BX, 2               ; X offset (Bytes) = Xpos/4\r
+    SHR     BX, 1               ; X offset (Bytes) = Xpos/4\r
+    SHR     BX, 1               ; X offset (Bytes) = Xpos/4\r
     ADD     BX, AX              ; Offset = Width*Ypos + Xpos/4\r
\r
+\r
     MOV     AL, READ_MAP        ; GC Read Mask Register\r
     MOV     AH, CL              ; Get Xpos\r
     AND     AH, PLANE_BITS      ; & mask out Plane #\r
     OUT_16  GC_INDEX, AX        ; Select Plane to read in\r
\r
-    CLR     AH                  ; Clear Return Value Hi byte\r
+\r
+    mov ah,0                  ; Clear Return Value Hi byte\r
     MOV     AL, ES:[DI+BX]      ; Get Color of Pixel\r
\r
-    POPx    DI, BP              ; Restore Saved Registers\r
+\r
+    ;POPx    DI, BP              ; Restore Saved Registers\r
+    pop        di\r
+       pop     bp\r
     RET     4                   ; Exit and Clean up Stack\r
\r
+\r
 READ_POINT        ENDP\r
\r
\r
+\r
+\r
 ;======================================================\r
 ;FILL_BLOCK (Xpos1%, Ypos1%, Xpos2%, Ypos2%, ColorNum%)\r
 ;======================================================\r
@@ -855,9 +908,12 @@ READ_POINT        ENDP
 ;\r
 ; EXIT:  No meaningful values returned\r
 ;\r
\r
+\r
 FB_STACK    STRUC\r
-                DW  ?x4 ; DS, DI, SI, BP\r
+                DW  ?x1 ; DS, DI, SI, BP\r
+                DW  ?x1 ; DS, DI, SI, BP\r
+                DW  ?x1 ; DS, DI, SI, BP\r
+                DW  ?x1 ; DS, DI, SI, BP\r
                 DD  ?   ; Caller\r
     FB_Color    DB  ?,? ; Fill Color\r
     FB_Ypos2    DW  ?   ; Y pos of Lower Right Pixel\r
@@ -865,154 +921,160 @@ FB_STACK    STRUC
     FB_Ypos1    DW  ?   ; Y pos of Upper Left Pixel\r
     FB_Xpos1    DW  ?   ; X pos of Upper Left Pixel\r
 FB_STACK    ENDS\r
\r
+\r
         PUBLIC    FILL_BLOCK\r
\r
+\r
 FILL_BLOCK  PROC    FAR\r
\r
-    PUSHx   BP, DS, SI, DI      ; Preserve Important Registers\r
+\r
+    ;PUSHx   BP, DS, SI, DI      ; Preserve Important Registers\r
+    push       bp\r
+       push    ds\r
+       push    si\r
+       push    di\r
     MOV     BP, SP              ; Set up Stack Frame\r
\r
+\r
     LES     DI, d CURRENT_PAGE  ; Point to Active VGA Page\r
     CLD                         ; Direction Flag = Forward\r
\r
+\r
     OUT_8   SC_INDEX, MAP_MASK  ; Set up for Plane Select\r
\r
+\r
     ; Validate Pixel Coordinates\r
     ; If necessary, Swap so X1 <= X2, Y1 <= Y2\r
\r
+\r
     MOV     AX, [BP].FB_Ypos1   ; AX = Y1   is Y1< Y2?\r
     MOV     BX, [BP].FB_Ypos2   ; BX = Y2\r
     CMP     AX, BX\r
     JLE     @FB_NOSWAP1\r
\r
+\r
     MOV     [BP].FB_Ypos1, BX   ; Swap Y1 and Y2 and save Y1\r
     XCHG    AX, BX              ; on stack for future use\r
\r
+\r
 @FB_NOSWAP1:\r
     SUB     BX, AX              ; Get Y width\r
     INC     BX                  ; Add 1 to avoid 0 value\r
     MOV     [BP].FB_Ypos2, BX   ; Save in Ypos2\r
\r
+\r
     MUL     SCREEN_WIDTH        ; Mul Y1 by Bytes per Line\r
     ADD     DI, AX              ; DI = Start of Line Y1\r
\r
+\r
     MOV     AX, [BP].FB_Xpos1   ; Check X1 <= X2\r
     MOV     BX, [BP].FB_Xpos2   ;\r
     CMP     AX, BX\r
     JLE     @FB_NOSWAP2         ; Skip Ahead if Ok\r
\r
+\r
     MOV     [BP].FB_Xpos2, AX   ; Swap X1 AND X2 and save X2\r
     XCHG    AX, BX              ; on stack for future use\r
\r
+\r
     ; All our Input Values are in order, Now determine\r
     ; How many full "bands" 4 pixels wide (aligned) there\r
     ; are, and if there are partial bands (<4 pixels) on\r
     ; the left and right edges.\r
\r
+\r
 @FB_NOSWAP2:\r
     MOV     DX, AX              ; DX = X1 (Pixel Position)\r
-    SHR     DX, 2               ; DX/4 = Bytes into Line\r
+    SHR     DX, 1               ; DX/4 = Bytes into Line\r
+    SHR     DX, 1               ; DX/4 = Bytes into Line\r
     ADD     DI, DX              ; DI = Addr of Upper-Left Corner\r
\r
+\r
     MOV     CX, BX              ; CX = X2 (Pixel Position)\r
-    SHR     CX, 2               ; CX/4 = Bytes into Line\r
\r
+    SHR     CX, 1               ; CX/4 = Bytes into Line\r
+    SHR     CX, 1               ; CX/4 = Bytes into Line\r
+\r
     CMP     DX, CX              ; Start and end in same band?\r
     JNE     @FB_NORMAL          ; if not, check for l & r edges\r
     JMP     @FB_ONE_BAND_ONLY   ; if so, then special processing\r
\r
+\r
 @FB_NORMAL:\r
     SUB     CX, DX              ; CX = # bands -1\r
     MOV     SI, AX              ; SI = PLANE#(X1)\r
     AND     SI, PLANE_BITS      ; if Left edge is aligned then\r
     JZ      @FB_L_PLANE_FLUSH   ; no special processing..\r
\r
+\r
     ; Draw "Left Edge" vertical strip of 1-3 pixels...\r
\r
+\r
     OUT_8   SC_Data, Left_Clip_Mask[SI] ; Set Left Edge Plane Mask\r
\r
+\r
     MOV     SI, DI              ; SI = Copy of Start Addr (UL)\r
\r
+\r
     MOV     DX, [BP].FB_Ypos2   ; Get # of Lines to draw\r
     MOV     AL, [BP].FB_Color   ; Get Fill Color\r
     MOV     BX, SCREEN_WIDTH    ; Get Vertical increment Value\r
\r
+\r
 @FB_LEFT_LOOP:\r
     MOV     ES:[SI], AL         ; Fill in Left Edge Pixels\r
     ADD     SI, BX              ; Point to Next Line (Below)\r
     LOOPjz  DX, @FB_LEFT_CONT   ; Exit loop if all Lines Drawn\r
\r
+\r
     MOV     ES:[SI], AL         ; Fill in Left Edge Pixels\r
     ADD     SI, BX              ; Point to Next Line (Below)\r
     LOOPx   DX, @FB_LEFT_LOOP   ; loop until left strip is drawn\r
\r
+\r
 @FB_LEFT_CONT:\r
\r
+\r
     INC     DI                  ; Point to Middle (or Right) Block\r
     DEC     CX                  ; Reset CX instead of JMP @FB_RIGHT\r
\r
+\r
 @FB_L_PLANE_FLUSH:\r
     INC     CX                  ; Add in Left band to middle block\r
\r
+\r
     ; DI = Addr of 1st middle Pixel (band) to fill\r
     ; CX = # of Bands to fill -1\r
\r
+\r
 @FB_RIGHT:\r
     MOV     SI, [BP].FB_Xpos2   ; Get Xpos2\r
     AND     SI, PLANE_BITS      ; Get Plane values\r
     CMP     SI, 0003            ; Plane = 3?\r
     JE      @FB_R_EDGE_FLUSH    ; Hey, add to middle\r
\r
+\r
     ; Draw "Right Edge" vertical strip of 1-3 pixels...\r
\r
+\r
     OUT_8   SC_Data, Right_Clip_Mask[SI]    ; Right Edge Plane Mask\r
\r
+\r
     MOV     SI, DI              ; Get Addr of Left Edge\r
     ADD     SI, CX              ; Add Width-1 (Bands)\r
     DEC     SI                  ; To point to top of Right Edge\r
\r
+\r
     MOV     DX, [BP].FB_Ypos2   ; Get # of Lines to draw\r
     MOV     AL, [BP].FB_Color   ; Get Fill Color\r
     MOV     BX, SCREEN_WIDTH    ; Get Vertical increment Value\r
\r
+\r
 @FB_RIGHT_LOOP:\r
     MOV     ES:[SI], AL         ; Fill in Right Edge Pixels\r
     ADD     SI, BX              ; Point to Next Line (Below)\r
     LOOPjz  DX, @FB_RIGHT_CONT  ; Exit loop if all Lines Drawn\r
\r
+\r
     MOV     ES:[SI], AL         ; Fill in Right Edge Pixels\r
     ADD     SI, BX              ; Point to Next Line (Below)\r
     LOOPx   DX, @FB_RIGHT_LOOP  ; loop until left strip is drawn\r
\r
+\r
 @FB_RIGHT_CONT:\r
\r
+\r
     DEC     CX                  ; Minus 1 for Middle bands\r
     JZ      @FB_EXIT            ; Uh.. no Middle bands...\r
\r
+\r
 @FB_R_EDGE_FLUSH:\r
\r
+\r
     ; DI = Addr of Upper Left block to fill\r
     ; CX = # of Bands to fill in (width)\r
\r
+\r
     OUT_8   SC_Data, ALL_PLANES ; Write to All Planes\r
\r
+\r
     MOV     DX, SCREEN_WIDTH    ; DX = DI Increment\r
     SUB     DX, CX              ;  = Screen_Width-# Planes Filled\r
\r
+\r
     MOV     BX, CX              ; BX = Quick Refill for CX\r
     MOV     SI, [BP].FB_Ypos2   ; SI = # of Line to Fill\r
     MOV     AL, [BP].FB_Color   ; Get Fill Color\r
\r
+\r
 @FB_MIDDLE_LOOP:\r
     REP     STOSB               ; Fill in entire line\r
\r
+\r
     MOV     CX, BX              ; Recharge CX (Line Width)\r
     ADD     DI, DX              ; Point to start of Next Line\r
     LOOPx   SI, @FB_MIDDLE_LOOP ; Loop until all lines drawn\r
\r
+\r
     JMP     s @FB_EXIT          ; Outa here\r
\r
+\r
 @FB_ONE_BAND_ONLY:\r
     MOV     SI, AX                  ; Get Left Clip Mask, Save X1\r
     AND     SI, PLANE_BITS          ; Mask out Row #\r
@@ -1020,29 +1082,33 @@ FILL_BLOCK  PROC    FAR
     MOV     SI, BX                  ; Get Right Clip Mask, Save X2\r
     AND     SI, PLANE_BITS          ; Mask out Row #\r
     AND     AL, Right_Clip_Mask[SI] ; Get Right Edge Mask byte\r
\r
+\r
     OUT_8   SC_Data, AL         ; Clip For Left & Right Masks\r
\r
+\r
     MOV     CX, [BP].FB_Ypos2   ; Get # of Lines to draw\r
     MOV     AL, [BP].FB_Color   ; Get Fill Color\r
     MOV     BX, SCREEN_WIDTH    ; Get Vertical increment Value\r
\r
+\r
 @FB_ONE_LOOP:\r
     MOV     ES:[DI], AL         ; Fill in Pixels\r
     ADD     DI, BX              ; Point to Next Line (Below)\r
     LOOPjz  CX, @FB_EXIT        ; Exit loop if all Lines Drawn\r
\r
+\r
     MOV     ES:[DI], AL         ; Fill in Pixels\r
     ADD     DI, BX              ; Point to Next Line (Below)\r
     LOOPx   CX, @FB_ONE_LOOP    ; loop until left strip is drawn\r
\r
+\r
 @FB_EXIT:\r
-    POPx    DI, SI, DS, BP      ; Restore Saved Registers\r
+    ;POPx    DI, SI, DS, BP      ; Restore Saved Registers\r
+    pop        di\r
+       pop     si\r
+       pop     ds\r
+       pop     bp\r
     RET     10                  ; Exit and Clean up Stack\r
\r
+\r
 FILL_BLOCK   ENDP\r
\r
\r
+\r
+\r
 ;=====================================================\r
 ;DRAW_LINE (Xpos1%, Ypos1%, Xpos2%, Ypos2%, ColorNum%)\r
 ;=====================================================\r
@@ -1057,9 +1123,11 @@ FILL_BLOCK   ENDP
 ;\r
 ; EXIT:  No meaningful values returned\r
 ;\r
\r
+\r
 DL_STACK    STRUC\r
-                DW  ?x3 ; DI, SI, BP\r
+                DW  ?x1 ; DI, SI, BP\r
+                DW  ?x1 ; DI, SI, BP\r
+                DW  ?x1 ; DI, SI, BP\r
                 DD  ?   ; Caller\r
     DL_ColorF   DB  ?,? ; Line Draw Color\r
     DL_Ypos2    DW  ?   ; Y pos of last point\r
@@ -1067,249 +1135,256 @@ DL_STACK    STRUC
     DL_Ypos1    DW  ?   ; Y pos of first point\r
     DL_Xpos1    DW  ?   ; X pos of first point\r
 DL_STACK    ENDS\r
\r
+\r
         PUBLIC DRAW_LINE\r
\r
+\r
 DRAW_LINE   PROC    FAR\r
\r
-    PUSHx   BP, SI, DI          ; Preserve Important Registers\r
+\r
+    ;PUSHx   BP, SI, DI          ; Preserve Important Registers\r
+    push       bp\r
+       push    si\r
+       push    di\r
     MOV     BP, SP              ; Set up Stack Frame\r
     CLD                         ; Direction Flag = Forward\r
\r
+\r
     OUT_8   SC_INDEX, MAP_MASK  ; Set up for Plane Select\r
     MOV     CH, [BP].DL_ColorF  ; Save Line Color in CH\r
\r
+\r
     ; Check Line Type\r
\r
+\r
     MOV     SI, [BP].DL_Xpos1   ; AX = X1   is X1< X2?\r
     MOV     DI, [BP].DL_Xpos2   ; DX = X2\r
     CMP     SI, DI              ; Is X1 < X2\r
     JE      @DL_VLINE           ; If X1=X2, Draw Vertical Line\r
     JL      @DL_NOSWAP1         ; If X1 < X2, don't swap\r
\r
+\r
     XCHG    SI, DI              ; X2 IS > X1, SO SWAP THEM\r
\r
+\r
 @DL_NOSWAP1:\r
\r
+\r
     ; SI = X1, DI = X2\r
\r
+\r
     MOV     AX, [BP].DL_Ypos1   ; AX = Y1   is Y1 <> Y2?\r
     CMP     AX, [BP].DL_Ypos2   ; Y1 = Y2?\r
     JE      @DL_HORZ            ; If so, Draw a Horizontal Line\r
\r
+\r
     JMP     @DL_BREZHAM         ; Diagonal line... go do it...\r
\r
+\r
     ; This Code draws a Horizontal Line in Mode X where:\r
     ; SI = X1, DI = X2, and AX = Y1/Y2\r
\r
+\r
 @DL_HORZ:\r
\r
+\r
     MUL     SCREEN_WIDTH        ; Offset = Ypos * Screen_Width\r
     MOV     DX, AX              ; CX = Line offset into Page\r
\r
+\r
     MOV     AX, SI                  ; Get Left edge, Save X1\r
     AND     SI, PLANE_BITS          ; Mask out Row #\r
     MOV     BL, Left_Clip_Mask[SI]  ; Get Left Edge Mask\r
     MOV     CX, DI                  ; Get Right edge, Save X2\r
     AND     DI, PLANE_BITS          ; Mask out Row #\r
     MOV     BH, Right_Clip_Mask[DI] ; Get Right Edge Mask byte\r
\r
-    SHR     AX, 2               ; Get X1 Byte # (=X1/4)\r
-    SHR     CX, 2               ; Get X2 Byte # (=X2/4)\r
\r
+\r
+    SHR     AX, 1               ; Get X1 Byte # (=X1/4)\r
+    SHR     CX, 1               ; Get X2 Byte # (=X2/4)\r
+    SHR     AX, 1               ; Get X1 Byte # (=X1/4)\r
+    SHR     CX, 1               ; Get X2 Byte # (=X2/4)\r
+\r
     LES     DI, d CURRENT_PAGE  ; Point to Active VGA Page\r
     ADD     DI, DX              ; Point to Start of Line\r
     ADD     DI, AX              ; Point to Pixel X1\r
\r
+\r
     SUB     CX, AX              ; CX = # Of Bands (-1) to set\r
     JNZ     @DL_LONGLN          ; jump if longer than one segment\r
\r
+\r
     AND     BL, BH              ; otherwise, merge clip masks\r
\r
+\r
 @DL_LONGLN:\r
\r
+\r
     OUT_8   SC_Data, BL         ; Set the Left Clip Mask\r
\r
+\r
     MOV     AL, [BP].DL_ColorF  ; Get Line Color\r
     MOV     BL, AL              ; BL = Copy of Line Color\r
     STOSB                       ; Set Left (1-4) Pixels\r
\r
+\r
     JCXZ    @DL_EXIT            ; Done if only one Line Segment\r
\r
+\r
     DEC     CX                  ; CX = # of Middle Segments\r
     JZ      @DL_XRSEG           ; If no middle segments....\r
\r
+\r
     ; Draw Middle Segments\r
\r
+\r
     OUT_8   DX, ALL_PLANES      ; Write to ALL Planes\r
\r
+\r
     MOV     AL, BL              ; Get Color from BL\r
     REP     STOSB               ; Draw Middle (4 Pixel) Segments\r
\r
+\r
 @DL_XRSEG:\r
     OUT_8   DX, BH              ; Select Planes for Right Clip Mask\r
     MOV     AL, BL              ; Get Color Value\r
     STOSB                       ; Draw Right (1-4) Pixels\r
\r
+\r
     JMP     s @DL_EXIT          ; We Are Done...\r
\r
\r
+\r
+\r
     ; This Code Draws A Vertical Line.  On entry:\r
     ; CH = Line Color, SI & DI = X1\r
\r
+\r
 @DL_VLINE:\r
\r
+\r
     MOV     AX, [BP].DL_Ypos1   ; AX = Y1\r
     MOV     SI, [BP].DL_Ypos2   ; SI = Y2\r
     CMP     AX, SI              ; Is Y1 < Y2?\r
     JLE     @DL_NOSWAP2         ; if so, Don't Swap them\r
\r
+\r
     XCHG    AX, SI              ; Ok, NOW Y1 < Y2\r
\r
+\r
 @DL_NOSWAP2:\r
\r
+\r
     SUB     SI, AX              ; SI = Line Height (Y2-Y1+1)\r
     INC     SI\r
\r
+\r
     ; AX = Y1, DI = X1, Get offset into Page into AX\r
\r
+\r
     MUL     SCREEN_WIDTH        ; Offset = Y1 (AX) * Screen Width\r
     MOV     DX, DI              ; Copy Xpos into DX\r
-    SHR     DI, 2               ; DI = Xpos/4\r
+    SHR     DI, 1               ; DI = Xpos/4\r
+    SHR     DI, 1               ; DI = Xpos/4\r
     ADD     AX, DI              ; DI = Xpos/4 + ScreenWidth * Y1\r
\r
+\r
     LES     DI, d CURRENT_PAGE  ; Point to Active VGA Page\r
     ADD     DI, AX              ; Point to Pixel X1, Y1\r
\r
+\r
     ;Select Plane\r
\r
+\r
     MOV     CL, DL              ; CL = Save X1\r
     AND     CL, PLANE_BITS      ; Get X1 MOD 4 (Plane #)\r
     MOV     AX, MAP_MASK_PLANE1 ; Code to set Plane #1\r
     SHL     AH, CL              ; Change to Correct Plane #\r
     OUT_16  SC_Index, AX        ; Select Plane\r
\r
+\r
     MOV     AL, CH              ; Get Saved Color\r
     MOV     BX, SCREEN_WIDTH    ; Get Offset to Advance Line By\r
\r
+\r
 @DL_VLoop:\r
     MOV     ES:[DI], AL         ; Draw Single Pixel\r
     ADD     DI, BX              ; Point to Next Line\r
     LOOPjz  SI, @DL_EXIT        ; Lines--, Exit if done\r
\r
+\r
     MOV     ES:[DI], AL         ; Draw Single Pixel\r
     ADD     DI, BX              ; Point to Next Line\r
     LOOPx   SI, @DL_VLoop       ; Lines--, Loop until Done\r
\r
+\r
 @DL_EXIT:\r
\r
+\r
     JMP     @DL_EXIT2           ; Done!\r
\r
+\r
     ; This code Draws a diagonal line in Mode X\r
\r
+\r
 @DL_BREZHAM:\r
     LES     DI, d CURRENT_PAGE  ; Point to Active VGA Page\r
\r
+\r
     MOV     AX, [BP].DL_Ypos1   ; get Y1 value\r
     MOV     BX, [BP].DL_Ypos2   ; get Y2 value\r
     MOV     CX, [BP].DL_Xpos1   ; Get Starting Xpos\r
\r
+\r
     CMP     BX, AX              ; Y2-Y1 is?\r
     JNC     @DL_DeltaYOK        ; if Y2>=Y1 then goto...\r
\r
+\r
     XCHG    BX, AX              ; Swap em...\r
     MOV     CX, [BP].DL_Xpos2   ; Get New Starting Xpos\r
\r
+\r
 @DL_DeltaYOK:\r
     MUL     SCREEN_WIDTH        ; Offset = SCREEN_WIDTH * Y1\r
\r
+\r
     ADD     DI, AX              ; DI -> Start of Line Y1 on Page\r
     MOV     AX, CX              ; AX = Xpos (X1)\r
-    SHR     AX, 2               ; /4 = Byte Offset into Line\r
+    SHR     AX, 1               ; /4 = Byte Offset into Line\r
+    SHR     AX, 1               ; /4 = Byte Offset into Line\r
     ADD     DI, AX              ; DI = Starting pos (X1,Y1)\r
\r
+\r
     MOV     AL, 11h             ; Staring Mask\r
     AND     CL, PLANE_BITS      ; Get Plane #\r
     SHL     AL, CL              ; and shift into place\r
     MOV     AH, [BP].DL_ColorF  ; Color in Hi Bytes\r
\r
+\r
     PUSH    AX                  ; Save Mask,Color...\r
\r
+\r
     MOV     AH, AL              ; Plane # in AH\r
     MOV     AL, MAP_MASK        ; Select Plane Register\r
     OUT_16  SC_Index, AX        ; Select initial plane\r
\r
+\r
     MOV     AX, [BP].DL_Xpos1   ; get X1 value\r
     MOV     BX, [BP].DL_Ypos1   ; get Y1 value\r
     MOV     CX, [BP].DL_Xpos2   ; get X2 value\r
     MOV     DX, [BP].DL_Ypos2   ; get Y2 value\r
\r
+\r
     MOV     BP, SCREEN_WIDTH    ; Use BP for Line width to\r
                                 ; to avoid extra memory access\r
\r
+\r
     SUB     DX, BX              ; figure Delta_Y\r
     JNC     @DL_DeltaYOK2       ; jump if Y2 >= Y1\r
\r
+\r
     ADD     BX, DX              ; put Y2 into Y1\r
     NEG     DX                  ; abs(Delta_Y)\r
     XCHG    AX, CX              ; and exchange X1 and X2\r
\r
+\r
 @DL_DeltaYOK2:\r
     MOV     BX, 08000H          ; seed for fraction accumulator\r
\r
+\r
     SUB     CX, AX              ; figure Delta_X\r
     JC      @DL_DrawLeft        ; if negative, go left\r
\r
+\r
     JMP     @DL_DrawRight       ; Draw Line that slopes right\r
\r
+\r
 @DL_DrawLeft:\r
\r
+\r
     NEG     CX                  ; abs(Delta_X)\r
\r
+\r
     CMP     CX, DX              ; is Delta_X < Delta_Y?\r
     JB      @DL_SteepLeft       ; yes, so go do steep line\r
                                 ; (Delta_Y iterations)\r
\r
+\r
     ; Draw a Shallow line to the left in Mode X\r
\r
+\r
 @DL_ShallowLeft:\r
-    CLR     AX                  ; zero low word of Delta_Y * 10000h\r
+    mov ax,0                  ; zero low word of Delta_Y * 10000h\r
     SUB     AX, DX              ; DX:AX <- DX * 0FFFFh\r
     SBB     DX, 0               ; include carry\r
     DIV     CX                  ; divide by Delta_X\r
\r
+\r
     MOV     SI, BX              ; SI = Accumulator\r
     MOV     BX, AX              ; BX = Add fraction\r
     POP     AX                  ; Get Color, Bit mask\r
     MOV     DX, SC_Data         ; Sequence controller data register\r
     INC     CX                  ; Inc Delta_X so we can unroll loop\r
\r
+\r
     ; Loop (x2) to Draw Pixels, Move Left, and Maybe Down...\r
\r
+\r
 @DL_SLLLoop:\r
     MOV     ES:[DI], AH         ; set first pixel, plane data set up\r
     LOOPjz  CX, @DL_SLLExit     ; Delta_X--, Exit if done\r
\r
+\r
     ADD     SI, BX              ; add numerator to accumulator\r
     JNC     @DL_SLLL2nc         ; move down on carry\r
\r
+\r
     ADD     DI, BP              ; Move Down one line...\r
\r
+\r
 @DL_SLLL2nc:\r
     DEC     DI                  ; Left one addr\r
     ROR     AL, 1               ; Move Left one plane, back on 0 1 2\r
     CMP     AL, 87h             ; wrap?, if AL <88 then Carry set\r
     ADC     DI, 0               ; Adjust Address: DI = DI + Carry\r
     OUT     DX, AL              ; Set up New Bit Plane mask\r
\r
+\r
     MOV     ES:[DI], AH         ; set pixel\r
     LOOPjz  CX, @DL_SLLExit     ; Delta_X--, Exit if done\r
\r
+\r
     ADD     SI, BX              ; add numerator to accumulator,\r
     JNC     @DL_SLLL3nc         ; move down on carry\r
\r
+\r
     ADD     DI, BP              ; Move Down one line...\r
\r
+\r
 @DL_SLLL3nc:                    ; Now move left a pixel...\r
     DEC     DI                  ; Left one addr\r
     ROR     AL, 1               ; Move Left one plane, back on 0 1 2\r
@@ -1317,171 +1392,174 @@ DRAW_LINE   PROC    FAR
     ADC     DI, 0               ; Adjust Address: DI = DI + Carry\r
     OUT     DX, AL              ; Set up New Bit Plane mask\r
     JMP     s @DL_SLLLoop       ; loop until done\r
\r
+\r
 @DL_SLLExit:\r
     JMP     @DL_EXIT2           ; and exit\r
\r
+\r
     ; Draw a steep line to the left in Mode X\r
\r
+\r
 @DL_SteepLeft:\r
-    CLR     AX                  ; zero low word of Delta_Y * 10000h\r
+    mov ax,0                  ; zero low word of Delta_Y * 10000h\r
     XCHG    DX, CX              ; Delta_Y switched with Delta_X\r
     DIV     CX                  ; divide by Delta_Y\r
\r
+\r
     MOV     SI, BX              ; SI = Accumulator\r
     MOV     BX, AX              ; BX = Add Fraction\r
     POP     AX                  ; Get Color, Bit mask\r
     MOV     DX, SC_Data         ; Sequence controller data register\r
     INC     CX                  ; Inc Delta_Y so we can unroll loop\r
\r
+\r
     ; Loop (x2) to Draw Pixels, Move Down, and Maybe left\r
\r
+\r
 @DL_STLLoop:\r
\r
+\r
     MOV     ES:[DI], AH         ; set first pixel\r
     LOOPjz  CX, @DL_STLExit     ; Delta_Y--, Exit if done\r
\r
+\r
     ADD     SI, BX              ; add numerator to accumulator\r
     JNC     @DL_STLnc2          ; No carry, just move down!\r
\r
+\r
     DEC     DI                  ; Move Left one addr\r
     ROR     AL, 1               ; Move Left one plane, back on 0 1 2\r
     CMP     AL, 87h             ; Wrap?, if AL <88 then Carry set\r
     ADC     DI, 0               ; Adjust Address: DI = DI + Carry\r
     OUT     DX, AL              ; Set up New Bit Plane mask\r
\r
+\r
 @DL_STLnc2:\r
     ADD     DI, BP              ; advance to next line.\r
\r
+\r
     MOV     ES:[DI], AH         ; set pixel\r
     LOOPjz  CX, @DL_STLExit     ; Delta_Y--, Exit if done\r
\r
+\r
     ADD     SI, BX              ; add numerator to accumulator\r
     JNC     @DL_STLnc3          ; No carry, just move down!\r
\r
+\r
     DEC     DI                  ; Move Left one addr\r
     ROR     AL, 1               ; Move Left one plane, back on 0 1 2\r
     CMP     AL, 87h             ; Wrap?, if AL <88 then Carry set\r
     ADC     DI, 0               ; Adjust Address: DI = DI + Carry\r
     OUT     DX, AL              ; Set up New Bit Plane mask\r
\r
+\r
 @DL_STLnc3:\r
     ADD     DI, BP              ; advance to next line.\r
     JMP     s @DL_STLLoop       ; Loop until done\r
\r
+\r
 @DL_STLExit:\r
     JMP     @DL_EXIT2           ; and exit\r
\r
+\r
     ; Draw a line that goes to the Right...\r
\r
+\r
 @DL_DrawRight:\r
     CMP     CX, DX              ; is Delta_X < Delta_Y?\r
     JB      @DL_SteepRight      ; yes, so go do steep line\r
                                 ; (Delta_Y iterations)\r
\r
+\r
     ; Draw a Shallow line to the Right in Mode X\r
\r
+\r
 @DL_ShallowRight:\r
-    CLR     AX                  ; zero low word of Delta_Y * 10000h\r
+    mov ax,0                  ; zero low word of Delta_Y * 10000h\r
     SUB     AX, DX              ; DX:AX <- DX * 0FFFFh\r
     SBB     DX, 0               ; include carry\r
     DIV     CX                  ; divide by Delta_X\r
\r
+\r
     MOV     SI, BX              ; SI = Accumulator\r
     MOV     BX, AX              ; BX = Add Fraction\r
     POP     AX                  ; Get Color, Bit mask\r
     MOV     DX, SC_Data         ; Sequence controller data register\r
     INC     CX                  ; Inc Delta_X so we can unroll loop\r
\r
+\r
     ; Loop (x2) to Draw Pixels, Move Right, and Maybe Down...\r
\r
+\r
 @DL_SLRLoop:\r
     MOV     ES:[DI], AH         ; set first pixel, mask is set up\r
     LOOPjz  CX, @DL_SLRExit     ; Delta_X--, Exit if done..\r
\r
+\r
     ADD     SI, BX              ; add numerator to accumulator\r
     JNC     @DL_SLR2nc          ; don't move down if carry not set\r
\r
+\r
     ADD     DI, BP              ; Move Down one line...\r
\r
+\r
 @DL_SLR2nc:                     ; Now move right a pixel...\r
     ROL     AL, 1               ; Move Right one addr if Plane = 0\r
     CMP     AL, 12h             ; Wrap? if AL >12 then Carry not set\r
     ADC     DI, 0               ; Adjust Address: DI = DI + Carry\r
     OUT     DX, AL              ; Set up New Bit Plane mask\r
\r
+\r
     MOV     ES:[DI], AH         ; set pixel\r
     LOOPjz  CX, @DL_SLRExit     ; Delta_X--, Exit if done..\r
\r
+\r
     ADD     SI, BX              ; add numerator to accumulator\r
     JNC     @DL_SLR3nc          ; don't move down if carry not set\r
\r
+\r
     ADD     DI, BP              ; Move Down one line...\r
\r
+\r
 @DL_SLR3nc:\r
     ROL     AL, 1               ; Move Right one addr if Plane = 0\r
     CMP     AL, 12h             ; Wrap? if AL >12 then Carry not set\r
     ADC     DI, 0               ; Adjust Address: DI = DI + Carry\r
     OUT     DX, AL              ; Set up New Bit Plane mask\r
     JMP     s @DL_SLRLoop       ; loop till done\r
\r
+\r
 @DL_SLRExit:\r
     JMP     @DL_EXIT2           ; and exit\r
\r
+\r
     ; Draw a Steep line to the Right in Mode X\r
\r
+\r
 @DL_SteepRight:\r
-    CLR     AX                  ; zero low word of Delta_Y * 10000h\r
+    mov ax,0                  ; zero low word of Delta_Y * 10000h\r
     XCHG    DX, CX              ; Delta_Y switched with Delta_X\r
     DIV     CX                  ; divide by Delta_Y\r
\r
+\r
     MOV     SI, BX              ; SI = Accumulator\r
     MOV     BX, AX              ; BX = Add Fraction\r
     POP     AX                  ; Get Color, Bit mask\r
     MOV     DX, SC_Data         ; Sequence controller data register\r
     INC     CX                  ; Inc Delta_Y so we can unroll loop\r
\r
+\r
     ; Loop (x2) to Draw Pixels, Move Down, and Maybe Right\r
\r
+\r
 @STRLoop:\r
     MOV     ES:[DI], AH         ; set first pixel, mask is set up\r
     LOOPjz  CX, @DL_EXIT2       ; Delta_Y--, Exit if Done\r
\r
+\r
     ADD     SI, BX              ; add numerator to accumulator\r
     JNC     @STRnc2             ; if no carry then just go down...\r
\r
+\r
     ROL     AL, 1               ; Move Right one addr if Plane = 0\r
     CMP     AL, 12h             ; Wrap? if AL >12 then Carry not set\r
     ADC     DI, 0               ; Adjust Address: DI = DI + Carry\r
     OUT     DX, AL              ; Set up New Bit Plane mask\r
\r
+\r
 @STRnc2:\r
     ADD     DI, BP              ; advance to next line.\r
\r
+\r
     MOV     ES:[DI], AH         ; set pixel\r
     LOOPjz  CX, @DL_EXIT2       ; Delta_Y--, Exit if Done\r
\r
+\r
     ADD     SI, BX              ; add numerator to accumulator\r
     JNC     @STRnc3             ; if no carry then just go down...\r
\r
+\r
     ROL     AL, 1               ; Move Right one addr if Plane = 0\r
     CMP     AL, 12h             ; Wrap? if AL >12 then Carry not set\r
     ADC     DI, 0               ; Adjust Address: DI = DI + Carry\r
     OUT     DX, AL              ; Set up New Bit Plane mask\r
\r
+\r
 @STRnc3:\r
     ADD     DI, BP              ; advance to next line.\r
     JMP     s @STRLoop          ; loop till done\r
\r
+\r
 @DL_EXIT2:\r
-    POPx    DI, SI, BP          ; Restore Saved Registers\r
+    ;POPx    DI, SI, BP          ; Restore Saved Registers\r
+    pop        di\r
+       pop     si\r
+       pop     bp\r
     RET     10                  ; Exit and Clean up Stack\r
\r
+\r
 DRAW_LINE        ENDP\r
\r
\r
+\r
+\r
     ; ===== DAC COLOR REGISTER ROUTINES =====\r
\r
+\r
 ;=================================================\r
 ;SET_DAC_REGISTER (Register%, Red%, Green%, Blue%)\r
 ;=================================================\r
@@ -1495,7 +1573,7 @@ DRAW_LINE        ENDP
 ;\r
 ; EXIT:  No meaningful values returned\r
 ;\r
\r
+\r
 SDR_STACK   STRUC\r
                     DW  ?   ; BP\r
                     DD  ?   ; Caller\r
@@ -1504,28 +1582,28 @@ SDR_STACK   STRUC
     SDR_Red         DB  ?,? ; Red Data Value\r
     SDR_Register    DB  ?,? ; Palette Register #\r
 SDR_STACK   ENDS\r
\r
+\r
     PUBLIC  SET_DAC_REGISTER\r
\r
+\r
 SET_DAC_REGISTER    PROC    FAR\r
\r
+\r
     PUSH    BP                  ; Save BP\r
     MOV     BP, SP              ; Set up Stack Frame\r
\r
+\r
     ; Select which DAC Register to modify\r
\r
+\r
     OUT_8   DAC_WRITE_ADDR, [BP].SDR_Register\r
\r
+\r
     MOV     DX, PEL_DATA_REG    ; Dac Data Register\r
     OUT_8   DX, [BP].SDR_Red    ; Set Red Intensity\r
     OUT_8   DX, [BP].SDR_Green  ; Set Green Intensity\r
     OUT_8   DX, [BP].SDR_Blue   ; Set Blue Intensity\r
\r
+\r
     POP     BP                  ; Restore Registers\r
     RET     8                   ; Exit & Clean Up Stack\r
\r
+\r
 SET_DAC_REGISTER    ENDP\r
\r
+\r
 ;====================================================\r
 ;GET_DAC_REGISTER (Register%, &Red%, &Green%, &Blue%)\r
 ;====================================================\r
@@ -1541,7 +1619,7 @@ SET_DAC_REGISTER    ENDP
 ;        Green, and Blue are set to the values\r
 ;        taken from the specified DAC register.\r
 ;\r
\r
+\r
 GDR_STACK   STRUC\r
                     DW  ?   ; BP\r
                     DD  ?   ; Caller\r
@@ -1550,39 +1628,39 @@ GDR_STACK   STRUC
     GDR_Red         DW  ?   ; Addr of Red Data Value in DS\r
     GDR_Register    DB  ?,? ; Palette Register #\r
 GDR_STACK   ENDS\r
\r
+\r
     PUBLIC  GET_DAC_REGISTER\r
\r
+\r
 GET_DAC_REGISTER    PROC    FAR\r
\r
+\r
     PUSH    BP                  ; Save BP\r
     MOV     BP, SP              ; Set up Stack Frame\r
\r
+\r
     ; Select which DAC Register to read in\r
\r
+\r
     OUT_8   DAC_READ_ADDR, [BP].GDR_Register\r
\r
+\r
     MOV     DX, PEL_DATA_REG    ; Dac Data Register\r
-    CLR     AX                  ; Clear AX\r
\r
+    mov ax,0                  ; Clear AX\r
+\r
     IN      AL, DX              ; Read Red Value\r
     MOV     BX, [BP].GDR_Red    ; Get Address of Red%\r
     MOV     [BX], AX            ; *Red% = AX\r
\r
+\r
     IN      AL, DX              ; Read Green Value\r
     MOV     BX, [BP].GDR_Green  ; Get Address of Green%\r
     MOV     [BX], AX            ; *Green% = AX\r
\r
+\r
     IN      AL, DX              ; Read Blue Value\r
     MOV     BX, [BP].GDR_Blue   ; Get Address of Blue%\r
     MOV     [BX], AX            ; *Blue% = AX\r
\r
+\r
     POP     BP                  ; Restore Registers\r
     RET     8                   ; Exit & Clean Up Stack\r
\r
+\r
 GET_DAC_REGISTER    ENDP\r
\r
\r
+\r
+\r
 ;===========================================================\r
 ;LOAD_DAC_REGISTERS (SEG PalData, StartReg%, EndReg%, Sync%)\r
 ;===========================================================\r
@@ -1599,40 +1677,45 @@ GET_DAC_REGISTER    ENDP
 ; NOTES: PalData is a linear array of 3 byte Palette values\r
 ;        in the order: Red  (0-63), Green (0-63), Blue (0-63)\r
 ;\r
\r
+\r
 LDR_STACK   STRUC\r
-                    DW  ?x3 ; BP, DS, SI\r
+                    DW  ?x1 ; BP, DS, SI\r
+                    DW  ?x1 ; BP, DS, SI\r
+                    DW  ?x1 ; BP, DS, SI\r
                     DD  ?   ; Caller\r
     LDR_Sync        DW  ?   ; Vertical Sync Flag\r
     LDR_EndReg      DB  ?,? ; Last Register #\r
     LDR_StartReg    DB  ?,? ; First Register #\r
     LDR_PalData     DD  ?   ; Far Ptr to Palette Data\r
 LDR_STACK   ENDS\r
\r
+\r
     PUBLIC  LOAD_DAC_REGISTERS\r
\r
+\r
 LOAD_DAC_REGISTERS  PROC    FAR\r
\r
-    PUSHx   BP, DS, SI          ; Save Registers\r
+\r
+    ;PUSHx   BP, DS, SI          ; Save Registers\r
+    push       bp\r
+       push    ds\r
+       push    si\r
     mov     BP, SP              ; Set up Stack Frame\r
\r
+\r
     mov     AX, [BP].LDR_Sync   ; Get Vertical Sync Flag\r
     or      AX, AX              ; is Sync Flag = 0?\r
     jz      @LDR_Load           ; if so, skip call\r
\r
+\r
     call    f SYNC_DISPLAY      ; wait for vsync\r
\r
+\r
     ; Determine register #'s, size to copy, etc\r
\r
+\r
 @LDR_Load:\r
\r
+\r
     lds     SI, [BP].LDR_PalData    ; DS:SI -> Palette Data\r
     mov     DX, DAC_WRITE_ADDR      ; DAC register # selector\r
\r
-    CLR     AX, BX                  ; Clear for byte loads\r
+\r
+    mov ax,0, BX                  ; Clear for byte loads\r
     mov     AL, [BP].LDR_StartReg   ; Get Start Register\r
     mov     BL, [BP].LDR_EndReg     ; Get End Register\r
\r
+\r
     sub     BX, AX              ; BX = # of DAC registers -1\r
     inc     BX                  ; BX = # of DAC registers\r
     mov     CX, BX              ; CX = # of DAC registers\r
@@ -1640,19 +1723,22 @@ LOAD_DAC_REGISTERS  PROC    FAR
     add     CX, BX              ; CX =  "   " * 3\r
     cld                         ; Block OUTs forward\r
     out     DX, AL              ; set up correct register #\r
\r
+\r
     ; Load a block of DAC Registers\r
\r
+\r
     mov     DX, PEL_DATA_REG    ; Dac Data Register\r
\r
-    rep     outsb               ; block set DAC registers\r
\r
-    POPx    SI, DS, BP          ; Restore Registers\r
+\r
+    ;rep     outsb               ; block set DAC registers\r
+\r
+    ;POPx    SI, DS, BP          ; Restore Registers\r
+       pop     si\r
+       pop     ds\r
+       pop     bp\r
     ret     10                  ; Exit & Clean Up Stack\r
\r
+\r
 LOAD_DAC_REGISTERS  ENDP\r
\r
\r
+\r
+\r
 ;====================================================\r
 ;READ_DAC_REGISTERS (SEG PalData, StartReg%, EndReg%)\r
 ;====================================================\r
@@ -1668,53 +1754,61 @@ LOAD_DAC_REGISTERS  ENDP
 ; NOTES: PalData is a linear array of 3 byte Palette values\r
 ;        in the order: Red  (0-63), Green (0-63), Blue (0-63)\r
 ;\r
\r
+\r
 RDR_STACK   STRUC\r
-                    DW  ?x3 ; BP, ES, DI\r
+                    DW  ?x1 ; BP, ES, DI\r
+                    DW  ?x1 ; BP, ES, DI\r
+                    DW  ?x1 ; BP, ES, DI\r
                     DD  ?   ; Caller\r
     RDR_EndReg      DB  ?,? ; Last Register #\r
     RDR_StartReg    DB  ?,? ; First Register #\r
     RDR_PalData     DD  ?   ; Far Ptr to Palette Data\r
 RDR_STACK   ENDS\r
\r
+\r
     PUBLIC  READ_DAC_REGISTERS\r
\r
+\r
 READ_DAC_REGISTERS  PROC    FAR\r
\r
-    PUSHx   BP, ES, DI          ; Save Registers\r
+\r
+    ;PUSHx   BP, ES, DI          ; Save Registers\r
+    push       bp\r
+       push    es\r
+       push    di\r
     mov     BP, SP              ; Set up Stack Frame\r
\r
+\r
     ; Determine register #'s, size to copy, etc\r
\r
+\r
     les     DI, [BP].RDR_PalData    ; ES:DI -> Palette Buffer\r
     mov     DX, DAC_READ_ADDR       ; DAC register # selector\r
\r
-    CLR     AX, BX                  ; Clear for byte loads\r
+\r
+    mov ax,0, BX                  ; Clear for byte loads\r
     mov     AL, [BP].RDR_StartReg   ; Get Start Register\r
     mov     BL, [BP].RDR_EndReg     ; Get End Register\r
\r
+\r
     sub     BX, AX              ; BX = # of DAC registers -1\r
     inc     BX                  ; BX = # of DAC registers\r
     mov     CX, BX              ; CX = # of DAC registers\r
     add     CX, BX              ; CX =  "   " * 2\r
     add     CX, BX              ; CX =  "   " * 3\r
     cld                         ; Block INs forward\r
\r
+\r
     ; Read a block of DAC Registers\r
\r
+\r
     out     DX, AL              ; set up correct register #\r
     mov     DX, PEL_DATA_REG    ; Dac Data Register\r
\r
-    rep     insb                ; block read DAC registers\r
\r
-    POPx    DI, ES, BP          ; Restore Registers\r
+\r
+    ;rep     insb                ; block read DAC registers\r
+\r
+    ;POPx    DI, ES, BP          ; Restore Registers\r
+    pop        di\r
+       pop     es\r
+       pop     bp\r
     ret     8                   ; Exit & Clean Up Stack\r
\r
+\r
 READ_DAC_REGISTERS  ENDP\r
\r
\r
+\r
+\r
     ; ===== PAGE FLIPPING AND SCROLLING ROUTINES =====\r
\r
+\r
 ;=========================\r
 ;SET_ACTIVE_PAGE (PageNo%)\r
 ;=========================\r
@@ -1726,38 +1820,38 @@ READ_DAC_REGISTERS  ENDP
 ;\r
 ; EXIT:  No meaningful values returned\r
 ;\r
\r
+\r
 SAP_STACK   STRUC\r
                 DW  ?   ; BP\r
                 DD  ?   ; Caller\r
     SAP_Page    DW  ?   ; Page # for Drawing\r
 SAP_STACK   ENDS\r
\r
+\r
     PUBLIC  SET_ACTIVE_PAGE\r
\r
+\r
 SET_ACTIVE_PAGE PROC    FAR\r
\r
+\r
     PUSH    BP                  ; Preserve Registers\r
     MOV     BP, SP              ; Set up Stack Frame\r
\r
+\r
     MOV     BX, [BP].SAP_Page   ; Get Desired Page #\r
     CMP     BX, LAST_PAGE       ; Is Page # Valid?\r
     JAE     @SAP_Exit           ; IF Not, Do Nothing\r
\r
+\r
     MOV     ACTIVE_PAGE, BX     ; Set Active Page #\r
\r
+\r
     SHL     BX, 1               ; Scale Page # to Word\r
     MOV     AX, PAGE_ADDR[BX]   ; Get offset to Page\r
\r
+\r
     MOV     CURRENT_PAGE, AX    ; And set for future LES's\r
\r
+\r
 @SAP_Exit:\r
     POP     BP                  ; Restore Registers\r
     RET     2                   ; Exit and Clean up Stack\r
\r
+\r
 SET_ACTIVE_PAGE ENDP\r
\r
\r
+\r
+\r
 ;================\r
 ;GET_ACTIVE_PAGE%\r
 ;================\r
@@ -1768,17 +1862,17 @@ SET_ACTIVE_PAGE ENDP
 ;\r
 ; EXIT:  AX = Current Video Page used for Drawing\r
 ;\r
\r
+\r
     PUBLIC  GET_ACTIVE_PAGE\r
\r
+\r
 GET_ACTIVE_PAGE PROC    FAR\r
\r
+\r
     MOV     AX, ACTIVE_PAGE     ; Get Active Page #\r
     RET                         ; Exit and Clean up Stack\r
\r
+\r
 GET_ACTIVE_PAGE ENDP\r
\r
\r
+\r
+\r
 ;===============================\r
 ;SET_DISPLAY_PAGE (DisplayPage%)\r
 ;===============================\r
@@ -1792,70 +1886,70 @@ GET_ACTIVE_PAGE ENDP
 ;\r
 ; EXIT:  No meaningful values returned\r
 ;\r
\r
+\r
 SDP_STACK   STRUC\r
                 DW  ?       ; BP\r
                 DD  ?       ; Caller\r
     SDP_Page    DW  ?       ; Page # to Display...\r
 SDP_STACK   ENDS\r
\r
+\r
     PUBLIC  SET_DISPLAY_PAGE\r
\r
+\r
 SET_DISPLAY_PAGE    PROC    FAR\r
\r
+\r
     PUSH    BP                  ; Preserve Registers\r
     MOV     BP, SP              ; Set up Stack Frame\r
\r
+\r
     MOV     BX, [BP].SDP_Page   ; Get Desired Page #\r
     CMP     BX, LAST_PAGE       ; Is Page # Valid?\r
     JAE     @SDP_Exit           ; IF Not, Do Nothing\r
\r
+\r
     MOV     DISPLAY_PAGE, BX    ; Set Display Page #\r
\r
+\r
     SHL     BX, 1               ; Scale Page # to Word\r
     MOV     CX, PAGE_ADDR[BX]   ; Get offset in memory to Page\r
     ADD     CX, CURRENT_MOFFSET ; Adjust for any scrolling\r
\r
+\r
     ; Wait if we are currently in a Vertical Retrace\r
\r
+\r
     MOV     DX, INPUT_1         ; Input Status #1 Register\r
\r
+\r
 @DP_WAIT0:\r
     IN      AL, DX              ; Get VGA status\r
     AND     AL, VERT_RETRACE    ; In Display mode yet?\r
     JNZ     @DP_WAIT0           ; If Not, wait for it\r
\r
+\r
     ; Set the Start Display Address to the new page\r
\r
+\r
     MOV     DX, CRTC_Index      ; We Change the VGA Sequencer\r
\r
+\r
     MOV     AL, START_DISP_LO   ; Display Start Low Register\r
     MOV     AH, CL              ; Low 8 Bits of Start Addr\r
     OUT     DX, AX              ; Set Display Addr Low\r
\r
+\r
     MOV     AL, START_DISP_HI   ; Display Start High Register\r
     MOV     AH, CH              ; High 8 Bits of Start Addr\r
     OUT     DX, AX              ; Set Display Addr High\r
\r
+\r
     ; Wait for a Vertical Retrace to smooth out things\r
\r
+\r
     MOV     DX, INPUT_1         ; Input Status #1 Register\r
\r
+\r
 @DP_WAIT1:\r
     IN      AL, DX              ; Get VGA status\r
     AND     AL, VERT_RETRACE    ; Vertical Retrace Start?\r
     JZ      @DP_WAIT1           ; If Not, wait for it\r
\r
+\r
     ; Now Set Display Starting Address\r
\r
\r
+\r
+\r
 @SDP_Exit:\r
     POP     BP                  ; Restore Registers\r
     RET     2                   ; Exit and Clean up Stack\r
\r
+\r
 SET_DISPLAY_PAGE    ENDP\r
\r
\r
+\r
+\r
 ;=================\r
 ;GET_DISPLAY_PAGE%\r
 ;=================\r
@@ -1866,17 +1960,17 @@ SET_DISPLAY_PAGE    ENDP
 ;\r
 ; EXIT:  AX = Current Video Page being displayed\r
 ;\r
\r
+\r
     PUBLIC  GET_DISPLAY_PAGE\r
\r
+\r
 GET_DISPLAY_PAGE    PROC    FAR\r
\r
+\r
     MOV     AX, DISPLAY_PAGE    ; Get Display Page #\r
     RET                         ; Exit & Clean Up Stack\r
\r
+\r
 GET_DISPLAY_PAGE    ENDP\r
\r
\r
+\r
+\r
 ;=======================================\r
 ;SET_WINDOW (DisplayPage%, Xpos%, Ypos%)\r
 ;=======================================\r
@@ -1894,7 +1988,7 @@ GET_DISPLAY_PAGE    ENDP
 ;\r
 ; EXIT:  No meaningful values returned\r
 ;\r
\r
+\r
 SW_STACK    STRUC\r
                 DW  ?   ; BP\r
                 DD  ?   ; Caller\r
@@ -1902,86 +1996,87 @@ SW_STACK    STRUC
     SW_Xpos     DW  ?   ; X pos of UL Screen Corner\r
     SW_Page     DW  ?   ; (new) Display Page\r
 SW_STACK    ENDS\r
\r
+\r
         PUBLIC SET_WINDOW\r
\r
+\r
 SET_WINDOW  PROC    FAR\r
\r
+\r
     PUSH    BP                  ; Preserve Registers\r
     MOV     BP, SP              ; Set up Stack Frame\r
\r
+\r
     ; Check if our Scroll Offsets are Valid\r
\r
+\r
     MOV     BX, [BP].SW_Page    ; Get Desired Page #\r
     CMP     BX, LAST_PAGE       ; Is Page # Valid?\r
     JAE     @SW_Exit            ; IF Not, Do Nothing\r
\r
+\r
     MOV     AX, [BP].SW_Ypos    ; Get Desired Y Offset\r
     CMP     AX, MAX_YOFFSET     ; Is it Within Limits?\r
     JA      @SW_Exit            ; if not, exit\r
\r
+\r
     MOV     CX, [BP].SW_Xpos    ; Get Desired X Offset\r
     CMP     CX, MAX_XOFFSET     ; Is it Within Limits?\r
     JA      @SW_Exit            ; if not, exit\r
\r
+\r
     ; Compute proper Display start address to use\r
\r
+\r
     MUL     SCREEN_WIDTH        ; AX = YOffset * Line Width\r
-    SHR     CX, 2               ; CX / 4 = Bytes into Line\r
+    SHR     CX, 1               ; CX / 4 = Bytes into Line\r
+    SHR     CX, 1               ; CX / 4 = Bytes into Line\r
     ADD     AX, CX              ; AX = Offset of Upper Left Pixel\r
\r
+\r
     MOV     CURRENT_MOFFSET, AX ; Save Offset Info\r
\r
+\r
     MOV     DISPLAY_PAGE, BX    ; Set Current Page #\r
     SHL     BX, 1               ; Scale Page # to Word\r
     ADD     AX, PAGE_ADDR[BX]   ; Get offset in VGA to Page\r
     MOV     BX, AX              ; BX = Desired Display Start\r
\r
+\r
     MOV     DX, INPUT_1         ; Input Status #1 Register\r
\r
+\r
     ; Wait if we are currently in a Vertical Retrace\r
\r
+\r
 @SW_WAIT0:\r
     IN      AL, DX              ; Get VGA status\r
     AND     AL, VERT_RETRACE    ; In Display mode yet?\r
     JNZ     @SW_WAIT0           ; If Not, wait for it\r
\r
+\r
     ; Set the Start Display Address to the new window\r
\r
+\r
     MOV     DX, CRTC_Index      ; We Change the VGA Sequencer\r
     MOV     AL, START_DISP_LO   ; Display Start Low Register\r
     MOV     AH, BL              ; Low 8 Bits of Start Addr\r
     OUT     DX, AX              ; Set Display Addr Low\r
\r
+\r
     MOV     AL, START_DISP_HI   ; Display Start High Register\r
     MOV     AH, BH              ; High 8 Bits of Start Addr\r
     OUT     DX, AX              ; Set Display Addr High\r
\r
+\r
     ; Wait for a Vertical Retrace to smooth out things\r
\r
+\r
     MOV     DX, INPUT_1         ; Input Status #1 Register\r
\r
+\r
 @SW_WAIT1:\r
     IN      AL, DX              ; Get VGA status\r
     AND     AL, VERT_RETRACE    ; Vertical Retrace Start?\r
     JZ      @SW_WAIT1           ; If Not, wait for it\r
\r
+\r
     ; Now Set the Horizontal Pixel Pan values\r
\r
+\r
     OUT_8   ATTRIB_Ctrl, PIXEL_PAN_REG  ; Select Pixel Pan Register\r
\r
+\r
     MOV     AX, [BP].SW_Xpos    ; Get Desired X Offset\r
     AND     AL, 03              ; Get # of Pixels to Pan (0-3)\r
     SHL     AL, 1               ; Shift for 256 Color Mode\r
     OUT     DX, AL              ; Fine tune the display!\r
\r
+\r
 @SW_Exit:\r
     POP     BP                  ; Restore Saved Registers\r
     RET     6                   ; Exit and Clean up Stack\r
\r
+\r
 SET_WINDOW        ENDP\r
\r
\r
+\r
+\r
 ;=============\r
 ;GET_X_OFFSET%\r
 ;=============\r
@@ -1993,17 +2088,17 @@ SET_WINDOW        ENDP
 ;\r
 ; EXIT:  AX = Current Horizontal Scroll Offset\r
 ;\r
\r
+\r
     PUBLIC  GET_X_OFFSET\r
\r
+\r
 GET_X_OFFSET    PROC    FAR\r
\r
+\r
     MOV     AX, CURRENT_XOFFSET ; Get current horz offset\r
     RET                         ; Exit & Clean Up Stack\r
\r
+\r
 GET_X_OFFSET    ENDP\r
\r
\r
+\r
+\r
 ;=============\r
 ;GET_Y_OFFSET%\r
 ;=============\r
@@ -2015,17 +2110,17 @@ GET_X_OFFSET    ENDP
 ;\r
 ; EXIT:  AX = Current Vertical Scroll Offset\r
 ;\r
\r
+\r
     PUBLIC  GET_Y_OFFSET\r
\r
+\r
 GET_Y_OFFSET    PROC    FAR\r
\r
+\r
     MOV     AX, CURRENT_YOFFSET ; Get current vertical offset\r
     RET                         ; Exit & Clean Up Stack\r
\r
+\r
 GET_Y_OFFSET    ENDP\r
\r
\r
+\r
+\r
 ;============\r
 ;SYNC_DISPLAY\r
 ;============\r
@@ -2036,34 +2131,34 @@ GET_Y_OFFSET    ENDP
 ;\r
 ; EXIT:  No meaningful values returned\r
 ;\r
\r
+\r
     PUBLIC  SYNC_DISPLAY\r
\r
+\r
 SYNC_DISPLAY    PROC    FAR\r
\r
+\r
     MOV     DX, INPUT_1         ; Input Status #1 Register\r
\r
+\r
     ; Wait for any current retrace to end\r
\r
+\r
 @SD_WAIT0:\r
     IN      AL, DX              ; Get VGA status\r
     AND     AL, VERT_RETRACE    ; In Display mode yet?\r
     JNZ     @SD_WAIT0           ; If Not, wait for it\r
\r
+\r
     ; Wait for the start of the next vertical retrace\r
\r
+\r
 @SD_WAIT1:\r
     IN      AL, DX              ; Get VGA status\r
     AND     AL, VERT_RETRACE    ; Vertical Retrace Start?\r
     JZ      @SD_WAIT1           ; If Not, wait for it\r
\r
+\r
     RET                         ; Exit & Clean Up Stack\r
\r
+\r
 SYNC_DISPLAY    ENDP\r
\r
\r
+\r
+\r
     ; ===== TEXT DISPLAY ROUTINES =====\r
\r
+\r
 ;==================================================\r
 ;GPRINTC (CharNum%, Xpos%, Ypos%, ColorF%, ColorB%)\r
 ;==================================================\r
@@ -2080,13 +2175,16 @@ SYNC_DISPLAY    ENDP
 ;\r
 ; EXIT:  No meaningful values returned\r
 ;\r
\r
+\r
 GPC_STACK   STRUC\r
     GPC_Width   DW  ?   ; Screen Width-1\r
     GPC_Lines   DB  ?,? ; Scan lines to Decode\r
     GPC_T_SETS  DW  ?   ; Saved Charset Segment\r
     GPC_T_SETO  DW  ?   ; Saved Charset Offset\r
-                DW  ?x4 ; DI, SI, DS, BP\r
+                DW  ?x1 ; DI, SI, DS, BP\r
+                DW  ?x1 ; DS, DI, SI, BP\r
+                DW  ?x1 ; DS, DI, SI, BP\r
+                DW  ?x1 ; DS, DI, SI, BP\r
                 DD  ?   ; Caller\r
     GPC_ColorB  DB  ?,? ; Background Color\r
     GPC_ColorF  DB  ?,? ; Text Color\r
@@ -2094,171 +2192,189 @@ GPC_STACK   STRUC
     GPC_Xpos    DW  ?   ; X position to Print at\r
     GPC_Char    DB  ?,? ; Character to Print\r
 GPC_STACK   ENDS\r
\r
+\r
         PUBLIC GPRINTC\r
\r
+\r
 GPRINTC     PROC    FAR\r
\r
-    PUSHx   BP, DS, SI, DI      ; Preserve Important Registers\r
+\r
+    ;PUSHx   BP, DS, SI, DI      ; Preserve Important Registers\r
+    push       bp\r
+       push    ds\r
+       push    si\r
+       push    di\r
     SUB     SP, 8               ; Allocate WorkSpace on Stack\r
     MOV     BP, SP              ; Set up Stack Frame\r
\r
+\r
     LES     DI, d CURRENT_PAGE  ; Point to Active VGA Page\r
\r
+\r
     MOV     AX, SCREEN_WIDTH    ; Get Logical Line Width\r
     MOV     BX, AX              ; BX = Screen Width\r
     DEC     BX                  ;    = Screen Width-1\r
     MOV     [BP].GPC_Width, BX  ; Save for later use\r
\r
+\r
     MUL     [BP].GPC_Ypos       ; Start of Line = Ypos * Width\r
     ADD     DI, AX              ; DI -> Start of Line Ypos\r
\r
+\r
     MOV     AX, [BP].GPC_Xpos   ; Get Xpos of Character\r
     MOV     CX, AX              ; Save Copy of Xpos\r
-    SHR     AX, 2               ; Bytes into Line = Xpos/4\r
+    SHR     AX, 1               ; Bytes into Line = Xpos/4\r
+    SHR     AX, 1               ; Bytes into Line = Xpos/4\r
     ADD     DI, AX              ; DI -> (Xpos, Ypos)\r
\r
+\r
     ;Get Source ADDR of Character Bit Map  & Save\r
\r
+\r
     MOV     AL, [BP].GPC_Char   ; Get Character #\r
     TEST    AL, 080h            ; Is Hi Bit Set?\r
     JZ      @GPC_LowChar        ; Nope, use low char set ptr\r
\r
+\r
     AND     AL, 07Fh            ; Mask Out Hi Bit\r
     MOV     BX, CHARSET_HI      ; BX = Char Set Ptr:Offset\r
     MOV     DX, CHARSET_HI+2    ; DX = Char Set Ptr:Segment\r
     JMP     s @GPC_Set_Char     ; Go Setup Character Ptr\r
\r
+\r
 @GPC_LowChar:\r
\r
+\r
     MOV     BX, CHARSET_LOW     ; BX = Char Set Ptr:Offset\r
     MOV     DX, CHARSET_LOW+2   ; DX = Char Set Ptr:Segment\r
\r
+\r
 @GPC_Set_Char:\r
     MOV     [BP].GPC_T_SETS, DX ; Save Segment on Stack\r
\r
+\r
     MOV     AH, 0               ; Valid #'s are 0..127\r
-    SHL     AX, 3               ; * 8 Bytes Per Bitmap\r
+    SHL     AX, 1               ; * 8 Bytes Per Bitmap\r
+    SHL     AX, 1               ; * 8 Bytes Per Bitmap\r
+    SHL     AX, 1               ; * 8 Bytes Per Bitmap\r
     ADD     BX, AX              ; BX = Offset of Selected char\r
     MOV     [BP].GPC_T_SETO, BX ; Save Offset on Stack\r
\r
+\r
     AND     CX, PLANE_BITS      ; Get Plane #\r
     MOV     CH, ALL_PLANES      ; Get Initial Plane mask\r
     SHL     CH, CL              ; And shift into position\r
     AND     CH, ALL_PLANES      ; And mask to lower nibble\r
\r
+\r
     MOV     AL, 04              ; 4-Plane # = # of initial\r
     SUB     AL, CL              ; shifts to align bit mask\r
     MOV     CL, AL              ; Shift Count for SHL\r
\r
+\r
     ;Get segment of character map\r
\r
+\r
     OUT_8   SC_Index, MAP_MASK  ; Setup Plane selections\r
     INC     DX                  ; DX -> SC_Data\r
\r
+\r
     MOV     AL, 08              ; 8 Lines to Process\r
     MOV     [BP].GPC_Lines, AL  ; Save on Stack\r
\r
+\r
     MOV     DS, [BP].GPC_T_SETS ; Point to character set\r
\r
+\r
 @GPC_DECODE_CHAR_BYTE:\r
\r
+\r
     MOV     SI, [BP].GPC_T_SETO ; Get DS:SI = String\r
\r
+\r
     MOV     BH, [SI]            ; Get Bit Map\r
     INC     SI                  ; Point to Next Line\r
     MOV     [BP].GPC_T_SETO, SI ; And save new Pointer...\r
\r
-    CLR     AX                  ; Clear AX\r
\r
-    CLR     BL                      ; Clear BL\r
+\r
+    mov ax,0                  ; Clear AX\r
+\r
+    ;mov bl,0                      ; Clear BL\r
+    mov bl,0\r
     ROL     BX, CL                  ; BL holds left edge bits\r
     MOV     SI, BX                  ; Use as Table Index\r
     AND     SI, CHAR_BITS           ; Get Low Bits\r
     MOV     AL, Char_Plane_Data[SI] ; Get Mask in AL\r
     JZ      @GPC_NO_LEFT1BITS       ; Skip if No Pixels to set\r
\r
+\r
     MOV     AH, [BP].GPC_ColorF ; Get Foreground Color\r
     OUT     DX, AL              ; Set up Screen Mask\r
     MOV     ES:[DI], AH         ; Write Foreground color\r
\r
+\r
 @GPC_NO_LEFT1BITS:\r
     XOR     AL, CH              ; Invert mask for Background\r
     JZ      @GPC_NO_LEFT0BITS   ; Hey, no need for this\r
\r
+\r
     MOV     AH, [BP].GPC_ColorB ; Get background Color\r
     OUT     DX, AL              ; Set up Screen Mask\r
     MOV     ES:[DI], AH         ; Write Foreground color\r
\r
+\r
     ;Now Do Middle/Last Band\r
\r
+\r
 @GPC_NO_LEFT0BITS:\r
     INC     DI                  ; Point to next Byte\r
-    ROL     BX, 4               ; Shift 4 bits\r
\r
+    ROL     BX, 1               ; Shift 4 bits\r
+    ROL     BX, 1               ; Shift 4 bits\r
+    ROL     BX, 1               ; Shift 4 bits\r
+    ROL     BX, 1               ; Shift 4 bits\r
+\r
     MOV     SI, BX                  ; Make Lookup Pointer\r
     AND     SI, CHAR_BITS           ; Get Low Bits\r
     MOV     AL, Char_Plane_Data[SI] ; Get Mask in AL\r
     JZ      @GPC_NO_MIDDLE1BITS     ; Skip if no pixels to set\r
\r
+\r
     MOV     AH, [BP].GPC_ColorF ; Get Foreground Color\r
     OUT     DX, AL              ; Set up Screen Mask\r
     MOV     ES:[DI], AH         ; Write Foreground color\r
\r
+\r
 @GPC_NO_MIDDLE1BITS:\r
     XOR     AL, ALL_PLANES      ; Invert mask for Background\r
     JZ      @GPC_NO_MIDDLE0BITS ; Hey, no need for this\r
\r
+\r
     MOV     AH, [BP].GPC_ColorB ; Get background Color\r
     OUT     DX, AL              ; Set up Screen Mask\r
     MOV     ES:[DI], AH         ; Write Foreground color\r
\r
+\r
 @GPC_NO_MIDDLE0BITS:\r
     XOR     CH, ALL_PLANES      ; Invert Clip Mask\r
     CMP     CL, 4               ; Aligned by 4?\r
     JZ      @GPC_NEXT_LINE      ; If so, Exit now..\r
\r
+\r
     INC     DI                  ; Point to next Byte\r
-    ROL     BX, 4               ; Shift 4 bits\r
\r
+    ROL     BX, 1               ; Shift 4 bits\r
+    ROL     BX, 1               ; Shift 4 bits\r
+    ROL     BX, 1               ; Shift 4 bits\r
+    ROL     BX, 1               ; Shift 4 bits\r
+\r
     MOV     SI, BX                  ; Make Lookup Pointer\r
     AND     SI, CHAR_BITS           ; Get Low Bits\r
     MOV     AL, Char_Plane_Data[SI] ; Get Mask in AL\r
     JZ      @GPC_NO_RIGHT1BITS      ; Skip if No Pixels to set\r
\r
+\r
     MOV     AH, [BP].GPC_ColorF ; Get Foreground Color\r
     OUT     DX, AL              ; Set up Screen Mask\r
     MOV     ES:[DI], AH         ; Write Foreground color\r
\r
+\r
 @GPC_NO_RIGHT1BITS:\r
\r
+\r
     XOR     AL, CH              ; Invert mask for Background\r
     JZ      @GPC_NO_RIGHT0BITS  ; Hey, no need for this\r
\r
+\r
     MOV     AH, [BP].GPC_ColorB ; Get background Color\r
     OUT     DX, AL              ; Set up Screen Mask\r
     MOV     ES:[DI], AH         ; Write Foreground color\r
\r
+\r
 @GPC_NO_RIGHT0BITS:\r
     DEC     DI                  ; Adjust for Next Line Advance\r
\r
+\r
 @GPC_NEXT_LINE:\r
     ADD     DI, [BP].GPC_Width  ; Point to Next Line\r
     XOR     CH, CHAR_BITS       ; Flip the Clip mask back\r
\r
+\r
     DEC     [BP].GPC_Lines      ; Count Down Lines\r
     JZ      @GPC_EXIT           ; Ok... Done!\r
\r
+\r
     JMP     @GPC_DECODE_CHAR_BYTE   ; Again! Hey!\r
\r
+\r
 @GPC_EXIT:\r
     ADD     SP, 08              ; Deallocate stack workspace\r
-    POPx    DI, SI, DS, BP      ; Restore Saved Registers\r
+    ;POPx    DI, SI, DS, BP      ; Restore Saved Registers\r
+    pop        di\r
+       pop     si\r
+       pop     ds\r
+       pop     bp\r
     RET     10                  ; Exit and Clean up Stack\r
\r
+\r
 GPRINTC  ENDP\r
\r
\r
+\r
+\r
 ;==========================================\r
 ;TGPRINTC (CharNum%, Xpos%, Ypos%, ColorF%)\r
 ;==========================================\r
@@ -2273,158 +2389,178 @@ GPRINTC  ENDP
 ;\r
 ; EXIT:  No meaningful values returned\r
 ;\r
\r
+\r
 TGP_STACK   STRUC\r
     TGP_Width   DW  ?   ; Screen Width-1\r
     TGP_Lines   DB  ?,? ; Scan lines to Decode\r
     TGP_T_SETS  DW  ?   ; Saved Charset Segment\r
     TGP_T_SETO  DW  ?   ; Saved Charset Offset\r
-                DW  ?x4 ; DI, SI, DS, BP\r
+                DW  ?x1 ; DI, SI, DS, BP\r
+                DW  ?x1 ; DS, DI, SI, BP\r
+                DW  ?x1 ; DS, DI, SI, BP\r
+                DW  ?x1 ; DS, DI, SI, BP\r
                 DD  ?   ; Caller\r
     TGP_ColorF  DB  ?,? ; Text Color\r
     TGP_Ypos    DW  ?   ; Y Position to Print at\r
     TGP_Xpos    DW  ?   ; X position to Print at\r
     TGP_Char    DB  ?,? ; Character to Print\r
 TGP_STACK   ENDS\r
\r
+\r
         PUBLIC TGPRINTC\r
\r
+\r
 TGPRINTC    PROC    FAR\r
\r
-    PUSHx   BP, DS, SI, DI      ; Preserve Important Registers\r
+\r
+    ;PUSHx   BP, DS, SI, DI      ; Preserve Important Registers\r
+    push       bp\r
+       push    ds\r
+       push    si\r
+       push    di\r
     SUB     SP, 8               ; Allocate WorkSpace on Stack\r
     MOV     BP, SP              ; Set up Stack Frame\r
\r
+\r
     LES     DI, d CURRENT_PAGE  ; Point to Active VGA Page\r
\r
+\r
     MOV     AX, SCREEN_WIDTH    ; Get Logical Line Width\r
     MOV     BX, AX              ; BX = Screen Width\r
     DEC     BX                  ;    = Screen Width-1\r
     MOV     [BP].TGP_Width, BX  ; Save for later use\r
\r
+\r
     MUL     [BP].TGP_Ypos       ; Start of Line = Ypos * Width\r
     ADD     DI, AX              ; DI -> Start of Line Ypos\r
\r
+\r
     MOV     AX, [BP].TGP_Xpos   ; Get Xpos of Character\r
     MOV     CX, AX              ; Save Copy of Xpos\r
-    SHR     AX, 2               ; Bytes into Line = Xpos/4\r
+    SHR     AX, 1               ; Bytes into Line = Xpos/4\r
+    SHR     AX, 1               ; Bytes into Line = Xpos/4\r
     ADD     DI, AX              ; DI -> (Xpos, Ypos)\r
\r
+\r
     ;Get Source ADDR of Character Bit Map  & Save\r
\r
+\r
     MOV     AL, [BP].TGP_Char   ; Get Character #\r
     TEST    AL, 080h            ; Is Hi Bit Set?\r
     JZ      @TGP_LowChar        ; Nope, use low char set ptr\r
\r
+\r
     AND     AL, 07Fh            ; Mask Out Hi Bit\r
     MOV     BX, CHARSET_HI      ; BX = Char Set Ptr:Offset\r
     MOV     DX, CHARSET_HI+2    ; DX = Char Set Ptr:Segment\r
     JMP     s @TGP_Set_Char     ; Go Setup Character Ptr\r
\r
+\r
 @TGP_LowChar:\r
\r
+\r
     MOV     BX, CHARSET_LOW     ; BX = Char Set Ptr:Offset\r
     MOV     DX, CHARSET_LOW+2   ; DX = Char Set Ptr:Segment\r
\r
+\r
 @TGP_Set_Char:\r
     MOV     [BP].TGP_T_SETS, DX ; Save Segment on Stack\r
\r
+\r
     MOV     AH, 0               ; Valid #'s are 0..127\r
-    SHL     AX, 3               ; * 8 Bytes Per Bitmap\r
+    SHL     AX, 1               ; * 8 Bytes Per Bitmap\r
+    SHL     AX, 1               ; * 8 Bytes Per Bitmap\r
+    SHL     AX, 1               ; * 8 Bytes Per Bitmap\r
     ADD     BX, AX              ; BX = Offset of Selected char\r
     MOV     [BP].TGP_T_SETO, BX ; Save Offset on Stack\r
\r
+\r
     AND     CX, PLANE_BITS      ; Get Plane #\r
     MOV     CH, ALL_PLANES      ; Get Initial Plane mask\r
     SHL     CH, CL              ; And shift into position\r
     AND     CH, ALL_PLANES      ; And mask to lower nibble\r
\r
+\r
     MOV     AL, 04              ; 4-Plane # = # of initial\r
     SUB     AL, CL              ; shifts to align bit mask\r
     MOV     CL, AL              ; Shift Count for SHL\r
\r
+\r
     ;Get segment of character map\r
\r
+\r
     OUT_8   SC_Index, MAP_MASK  ; Setup Plane selections\r
     INC     DX                  ; DX -> SC_Data\r
\r
+\r
     MOV     AL, 08              ; 8 Lines to Process\r
     MOV     [BP].TGP_Lines, AL  ; Save on Stack\r
\r
+\r
     MOV     DS, [BP].TGP_T_SETS ; Point to character set\r
\r
+\r
 @TGP_DECODE_CHAR_BYTE:\r
\r
+\r
     MOV     SI, [BP].TGP_T_SETO ; Get DS:SI = String\r
\r
+\r
     MOV     BH, [SI]            ; Get Bit Map\r
     INC     SI                  ; Point to Next Line\r
     MOV     [BP].TGP_T_SETO, SI ; And save new Pointer...\r
\r
+\r
     MOV     AH, [BP].TGP_ColorF ; Get Foreground Color\r
\r
-    CLR     BL                      ; Clear BL\r
+\r
+    mov bl,0                      ; Clear BL\r
     ROL     BX, CL                  ; BL holds left edge bits\r
     MOV     SI, BX                  ; Use as Table Index\r
     AND     SI, CHAR_BITS           ; Get Low Bits\r
     MOV     AL, Char_Plane_Data[SI] ; Get Mask in AL\r
     JZ      @TGP_NO_LEFT1BITS       ; Skip if No Pixels to set\r
\r
+\r
     OUT     DX, AL              ; Set up Screen Mask\r
     MOV     ES:[DI], AH         ; Write Foreground color\r
\r
+\r
     ;Now Do Middle/Last Band\r
\r
+\r
 @TGP_NO_LEFT1BITS:\r
\r
+\r
     INC     DI                  ; Point to next Byte\r
-    ROL     BX, 4               ; Shift 4 bits\r
\r
+    ROL     BX, 1               ; Shift 4 bits\r
+    ROL     BX, 1               ; Shift 4 bits\r
+    ROL     BX, 1               ; Shift 4 bits\r
+    ROL     BX, 1               ; Shift 4 bits\r
+\r
     MOV     SI, BX                  ; Make Lookup Pointer\r
     AND     SI, CHAR_BITS           ; Get Low Bits\r
     MOV     AL, Char_Plane_Data[SI] ; Get Mask in AL\r
     JZ      @TGP_NO_MIDDLE1BITS     ; Skip if no pixels to set\r
\r
+\r
     OUT     DX, AL              ; Set up Screen Mask\r
     MOV     ES:[DI], AH         ; Write Foreground color\r
\r
+\r
 @TGP_NO_MIDDLE1BITS:\r
     XOR     CH, ALL_PLANES      ; Invert Clip Mask\r
     CMP     CL, 4               ; Aligned by 4?\r
     JZ      @TGP_NEXT_LINE      ; If so, Exit now..\r
\r
+\r
     INC     DI                  ; Point to next Byte\r
-    ROL     BX, 4               ; Shift 4 bits\r
\r
+    ROL     BX, 1               ; Shift 4 bits\r
+    ROL     BX, 1               ; Shift 4 bits\r
+    ROL     BX, 1               ; Shift 4 bits\r
+    ROL     BX, 1               ; Shift 4 bits\r
+\r
     MOV     SI, BX                  ; Make Lookup Pointer\r
     AND     SI, CHAR_BITS           ; Get Low Bits\r
     MOV     AL, Char_Plane_Data[SI] ; Get Mask in AL\r
     JZ      @TGP_NO_RIGHT1BITS      ; Skip if No Pixels to set\r
\r
+\r
     OUT     DX, AL              ; Set up Screen Mask\r
     MOV     ES:[DI], AH         ; Write Foreground color\r
\r
+\r
 @TGP_NO_RIGHT1BITS:\r
\r
+\r
     DEC     DI                  ; Adjust for Next Line Advance\r
\r
+\r
 @TGP_NEXT_LINE:\r
     ADD     DI, [BP].TGP_Width  ; Point to Next Line\r
     XOR     CH, CHAR_BITS       ; Flip the Clip mask back\r
\r
+\r
     DEC     [BP].TGP_Lines      ; Count Down Lines\r
     JZ      @TGP_EXIT           ; Ok... Done!\r
\r
+\r
     JMP     @TGP_DECODE_CHAR_BYTE   ; Again! Hey!\r
\r
+\r
 @TGP_EXIT:\r
     ADD     SP, 08              ; Deallocate stack workspace\r
-    POPx    DI, SI, DS, BP      ; Restore Saved Registers\r
+    ;POPx    DI, SI, DS, BP      ; Restore Saved Registers\r
+    pop        di\r
+       pop     si\r
+       pop     ds\r
+       pop     bp\r
     RET     8                   ; Exit and Clean up Stack\r
\r
+\r
 TGPRINTC    ENDP\r
\r
\r
+\r
+\r
 ;===============================================================\r
 ;PRINT_STR (SEG String, MaxLen%, Xpos%, Ypos%, ColorF%, ColorB%)\r
 ;===============================================================\r
@@ -2441,9 +2577,12 @@ TGPRINTC    ENDP
 ;\r
 ; EXIT:  No meaningful values returned\r
 ;\r
\r
+\r
 PS_STACK    STRUC\r
-                DW  ?x4 ; DI, SI, DS, BP\r
+                DW  ?x1 ; DI, SI, DS, BP\r
+                DW  ?x1 ; DI, SI, DS, BP\r
+                DW  ?x1 ; DS, DI, SI, BP\r
+                DW  ?x1 ; DS, DI, SI, BP\r
                 DD  ?   ; Caller\r
     PS_ColorB   DW  ?   ; Background Color\r
     PS_ColorF   DW  ?   ; Text Color\r
@@ -2452,54 +2591,62 @@ PS_STACK    STRUC
     PS_Len      DW  ?   ; Maximum Length of string to print\r
     PS_Text     DW  ?,? ; Far Ptr to Text String\r
 PS_STACK    ENDS\r
\r
+\r
         PUBLIC  PRINT_STR\r
\r
+\r
 PRINT_STR   PROC    FAR\r
\r
-    PUSHx   BP, DS, SI, DI      ; Preserve Important Registers\r
+\r
+    ;PUSHx   BP, DS, SI, DI      ; Preserve Important Registers\r
+    push       bp\r
+       push    ds\r
+       push    si\r
+       push    di\r
     MOV     BP, SP              ; Set up Stack Frame\r
\r
+\r
 @PS_Print_It:\r
\r
+\r
     MOV     CX, [BP].PS_Len     ; Get Remaining text Length\r
     JCXZ    @PS_Exit            ; Exit when out of text\r
\r
+\r
     LES     DI, d [BP].PS_Text  ; ES:DI -> Current Char in Text\r
     MOV     AL, ES:[DI]         ; AL = Text Character\r
     AND     AX, 00FFh           ; Clear High Word\r
     JZ      @PS_Exit            ; Exit if null character\r
\r
+\r
     DEC     [BP].PS_Len         ; Remaining Text length--\r
     INC     [BP].PS_Text        ; Point to Next text char\r
\r
+\r
     ; Set up Call to GPRINTC\r
\r
+\r
     PUSH    AX                  ; Set Character Parameter\r
     MOV     BX, [BP].PS_Xpos    ; Get Xpos\r
     PUSH    BX                  ; Set Xpos Parameter\r
     ADD     BX, 8               ; Advance 1 Char to Right\r
     MOV     [BP].PS_Xpos, BX    ; Save for next time through\r
\r
+\r
     MOV     BX, [BP].PS_Ypos    ; Get Ypos\r
     PUSH    BX                  ; Set Ypos Parameter\r
\r
+\r
     MOV     BX, [BP].PS_ColorF  ; Get Text Color\r
     PUSH    BX                  ; Set ColorF Parameter\r
\r
+\r
     MOV     BX, [BP].PS_ColorB  ; Get Background Color\r
     PUSH    BX                  ; Set ColorB Parameter\r
\r
+\r
     CALL    f GPRINTC           ; Print Character!\r
     JMP     s @PS_Print_It      ; Process next character\r
\r
+\r
 @PS_Exit:\r
-    POPx    DI, SI, DS, BP      ; Restore Saved Registers\r
+    ;POPx    DI, SI, DS, BP      ; Restore Saved Registers\r
+    pop        di\r
+       pop     si\r
+       pop     ds\r
+       pop     bp\r
     RET     14                  ; Exit and Clean up Stack\r
\r
+\r
 PRINT_STR  ENDP\r
\r
\r
+\r
+\r
 ;================================================================\r
 ;TPRINT_STR (SEG String, MaxLen%, Xpos%, Ypos%, ColorF%, ColorB%)\r
 ;================================================================\r
@@ -2515,9 +2662,12 @@ PRINT_STR  ENDP
 ;\r
 ; EXIT:  No meaningful values returned\r
 ;\r
\r
+\r
 TPS_STACK   STRUC\r
-                DW  ?x4 ; DI, SI, DS, BP\r
+                DW  ?x1 ; DI, SI, DS, BP\r
+                DW  ?x1 ; DI, SI, DS, BP\r
+                DW  ?x1 ; DS, DI, SI, BP\r
+                DW  ?x1 ; DS, DI, SI, BP\r
                 DD  ?   ; Caller\r
     TPS_ColorF  DW  ?   ; Text Color\r
     TPS_Ypos    DW  ?   ; Y Position to Print at\r
@@ -2525,51 +2675,59 @@ TPS_STACK   STRUC
     TPS_Len     DW  ?   ; Maximum Length of string to print\r
     TPS_Text    DW  ?,? ; Far Ptr to Text String\r
 TPS_STACK   ENDS\r
\r
+\r
         PUBLIC  TPRINT_STR\r
\r
+\r
 TPRINT_STR  PROC    FAR\r
\r
-    PUSHx   BP, DS, SI, DI      ; Preserve Important Registers\r
+\r
+    ;PUSHx   BP, DS, SI, DI      ; Preserve Important Registers\r
+    push       bp\r
+       push    ds\r
+       push    si\r
+       push    di\r
     MOV     BP, SP              ; Set up Stack Frame\r
\r
+\r
 @TPS_Print_It:\r
\r
+\r
     MOV     CX, [BP].TPS_Len    ; Get Remaining text Length\r
     JCXZ    @TPS_Exit           ; Exit when out of text\r
\r
+\r
     LES     DI, d [BP].TPS_Text ; ES:DI -> Current Char in Text\r
     MOV     AL, ES:[DI]         ; AL = Text Character\r
     AND     AX, 00FFh           ; Clear High Word\r
     JZ      @TPS_Exit           ; Exit if null character\r
\r
+\r
     DEC     [BP].TPS_Len        ; Remaining Text length--\r
     INC     [BP].TPS_Text       ; Point to Next text char\r
\r
+\r
     ; Set up Call to TGPRINTC\r
\r
+\r
     PUSH    AX                  ; Set Character Parameter\r
     MOV     BX, [BP].TPS_Xpos   ; Get Xpos\r
     PUSH    BX                  ; Set Xpos Parameter\r
     ADD     BX, 8               ; Advance 1 Char to Right\r
     MOV     [BP].TPS_Xpos, BX   ; Save for next time through\r
\r
+\r
     MOV     BX, [BP].TPS_Ypos   ; Get Ypos\r
     PUSH    BX                  ; Set Ypos Parameter\r
\r
+\r
     MOV     BX, [BP].TPS_ColorF ; Get Text Color\r
     PUSH    BX                  ; Set ColorF Parameter\r
\r
+\r
     CALL    f TGPRINTC          ; Print Character!\r
     JMP     s @TPS_Print_It     ; Process next character\r
\r
+\r
 @TPS_Exit:\r
-    POPx    DI, SI, DS, BP      ; Restore Saved Registers\r
+    ;POPx    DI, SI, DS, BP      ; Restore Saved Registers\r
+    pop        di\r
+       pop     si\r
+       pop     ds\r
+       pop     bp\r
     RET     12                  ; Exit and Clean up Stack\r
\r
+\r
 TPRINT_STR  ENDP\r
\r
\r
+\r
+\r
 ;===========================================\r
 ;SET_DISPLAY_FONT(SEG FontData, FontNumber%)\r
 ;===========================================\r
@@ -2584,41 +2742,41 @@ TPRINT_STR  ENDP
 ;\r
 ; EXIT:  No meaningful values returned\r
 ;\r
\r
+\r
 SDF_STACK   STRUC\r
                 DW  ?   ; BP\r
                 DD  ?   ; Caller\r
     SDF_Which   DW  ?   ; Hi Table/Low Table Flag\r
     SDF_Font    DD  ?   ; Far Ptr to Font Table\r
 SDF_STACK   ENDS\r
\r
+\r
     PUBLIC  SET_DISPLAY_FONT\r
\r
+\r
 SET_DISPLAY_FONT    PROC    FAR\r
\r
+\r
     PUSH    BP                  ; Preserve Registers\r
     MOV     BP, SP              ; Set up Stack Frame\r
\r
+\r
     LES     DI, [BP].SDF_Font   ; Get Far Ptr to Font\r
\r
+\r
     MOV     SI, o CHARSET_LOW   ; Assume Lower 128 chars\r
     TEST    [BP].SDF_Which, 1   ; Font #1 selected?\r
     JZ      @SDF_Set_Font       ; If not, skip ahead\r
\r
+\r
     MOV     SI, o CHARSET_HI    ; Ah, really it's 128-255\r
\r
+\r
 @SDF_Set_Font:\r
     MOV     [SI], DI            ; Set Font Pointer Offset\r
     MOV     [SI+2], ES          ; Set Font Pointer Segment\r
\r
+\r
     POP     BP                  ; Restore Registers\r
     RET     6                   ; We are Done.. Outa here\r
\r
+\r
 SET_DISPLAY_FONT    ENDP\r
\r
\r
+\r
+\r
     ; ===== BITMAP (SPRITE) DISPLAY ROUTINES =====\r
\r
+\r
 ;======================================================\r
 ;DRAW_BITMAP (SEG Image, Xpos%, Ypos%, Width%, Height%)\r
 ;======================================================\r
@@ -2637,14 +2795,17 @@ SET_DISPLAY_FONT    ENDP
 ;\r
 ; EXIT:  No meaningful values returned\r
 ;\r
\r
+\r
 DB_STACK    STRUC\r
     DB_LineO    DW  ?   ; Offset to Next Line\r
     DB_PixCount DW  ?   ; (Minimum) # of Pixels/Line\r
     DB_Start    DW  ?   ; Addr of Upper Left Pixel\r
     DB_PixSkew  DW  ?   ; # of bytes to Adjust EOL\r
     DB_SkewFlag DW  ?   ; Extra Pix on Plane Flag\r
-                DW  ?x4 ; DI, SI, DS, BP\r
+                DW  ?x1 ; DI, SI, DS, BP\r
+                DW  ?x1 ; DI, SI, DS, BP\r
+                DW  ?x1 ; DS, DI, SI, BP\r
+                DW  ?x1 ; DS, DI, SI, BP\r
                 DD  ?   ; Caller\r
     DB_Height   DW  ?   ; Height of Bitmap in Pixels\r
     DB_Width    DW  ?   ; Width of Bitmap in Pixels\r
@@ -2652,65 +2813,71 @@ DB_STACK    STRUC
     DB_Xpos     DW  ?   ; X position to Draw Bitmap at\r
     DB_Image    DD  ?   ; Far Pointer to Graphics Bitmap\r
 DB_STACK    ENDS\r
\r
+\r
         PUBLIC    DRAW_BITMAP\r
\r
+\r
 DRAW_BITMAP PROC    FAR\r
\r
-    PUSHx   BP, DS, SI, DI      ; Preserve Important Registers\r
+\r
+    ;PUSHx   BP, DS, SI, DI      ; Preserve Important Registers\r
+    push       bp\r
+       push    ds\r
+       push    si\r
+       push    di\r
     SUB     SP, 10              ; Allocate workspace\r
     MOV     BP, SP              ; Set up Stack Frame\r
\r
+\r
     LES     DI, d CURRENT_PAGE  ; Point to Active VGA Page\r
     CLD                         ; Direction Flag = Forward\r
\r
+\r
     MOV     AX, [BP].DB_Ypos    ; Get UL Corner Ypos\r
     MUL     SCREEN_WIDTH        ; AX = Offset to Line Ypos\r
\r
+\r
     MOV     BX, [BP].DB_Xpos    ; Get UL Corner Xpos\r
     MOV     CL, BL              ; Save Plane # in CL\r
-    SHR     BX, 2               ; Xpos/4 = Offset Into Line\r
\r
+    SHR     BX, 1               ; Xpos/4 = Offset Into Line\r
+    SHR     BX, 1               ; Xpos/4 = Offset Into Line\r
+\r
     ADD     DI, AX              ; ES:DI -> Start of Line\r
     ADD     DI, BX              ; ES:DI -> Upper Left Pixel\r
     MOV     [BP].DB_Start, DI   ; Save Starting Addr\r
\r
+\r
     ; Compute line to line offset\r
\r
+\r
     MOV     BX, [BP].DB_Width   ; Get Width of Image\r
     MOV     DX, BX              ; Save Copy in DX\r
-    SHR     BX, 2               ; /4 = width in bands\r
+    SHR     BX, 1               ; /4 = width in bands\r
+    SHR     BX, 1               ; /4 = width in bands\r
     MOV     AX, SCREEN_WIDTH    ; Get Screen Width\r
     SUB     AX, BX              ; - (Bitmap Width/4)\r
\r
+\r
     MOV     [BP].DB_LineO, AX       ; Save Line Width offset\r
     MOV     [BP].DB_PixCount, BX    ; Minimum # pix to copy\r
\r
+\r
     AND     DX, PLANE_BITS          ; Get "partial band" size (0-3)\r
     MOV     [BP].DB_PixSkew, DX     ; Also End of Line Skew\r
     MOV     [BP].DB_SkewFlag, DX    ; Save as Flag/Count\r
\r
+\r
     AND     CX, PLANE_BITS      ; CL = Starting Plane #\r
     MOV     AX, MAP_MASK_PLANE2 ; Plane Mask & Plane Select\r
     SHL     AH, CL              ; Select correct Plane\r
     OUT_16  SC_Index, AX        ; Select Plane...\r
     MOV     BH, AH              ; BH = Saved Plane Mask\r
     MOV     BL, 4               ; BL = Planes to Copy\r
\r
+\r
 @DB_COPY_PLANE:\r
\r
+\r
     LDS     SI, [BP].DB_Image   ; DS:SI-> Source Image\r
     MOV     DX, [BP].DB_Height  ; # of Lines to Copy\r
     MOV     DI, [BP].DB_Start   ; ES:DI-> Dest pos\r
\r
+\r
 @DB_COPY_LINE:\r
     MOV     CX, [BP].DB_PixCount    ; Min # to copy\r
\r
+\r
     TEST    CL, 0FCh            ; 16+PixWide?\r
     JZ      @DB_COPY_REMAINDER  ; Nope...\r
\r
+\r
     ; Pixel Copy loop has been unrolled to x4\r
\r
+\r
 @DB_COPY_LOOP:\r
     MOVSB                       ; Copy Bitmap Pixel\r
     ADD     SI, 3               ; Skip to Next Byte in same plane\r
@@ -2720,60 +2887,64 @@ DRAW_BITMAP PROC    FAR
     ADD     SI, 3               ; Skip to Next Byte in same plane\r
     MOVSB                       ; Copy Bitmap Pixel\r
     ADD     SI, 3               ; Skip to Next Byte in same plane\r
\r
+\r
     SUB     CL, 4               ; Pixels to Copy=-4\r
     TEST    CL, 0FCh            ; 4+ Pixels Left?\r
     JNZ     @DB_COPY_LOOP       ; if so, do another block\r
\r
+\r
 @DB_COPY_REMAINDER:\r
     JCXZ    @DB_NEXT_LINE       ; Any Pixels left on line\r
\r
+\r
 @DB_COPY2:\r
     MOVSB                       ; Copy Bitmap Pixel\r
     ADD     SI,3                ; Skip to Next Byte in same plane\r
     LOOPx   CX, @DB_COPY2       ; Pixels to Copy--, Loop until done\r
\r
+\r
 @DB_NEXT_LINE:\r
\r
+\r
     ; any Partial Pixels? (some planes only)\r
\r
+\r
     OR      CX, [BP].DB_SkewFlag    ; Get Skew Count\r
     JZ      @DB_NEXT2               ; if no partial pixels\r
\r
+\r
     MOVSB                       ; Copy Bitmap Pixel\r
     DEC     DI                  ; Back up to align\r
     DEC     SI                  ; Back up to align\r
\r
+\r
 @DB_NEXT2:\r
     ADD     SI, [BP].DB_PixSkew ; Adjust Skew\r
     ADD     DI, [BP].DB_LineO   ; Set to Next Display Line\r
     LOOPx   DX, @DB_COPY_LINE   ; Lines to Copy--, Loop if more\r
\r
+\r
     ; Copy Next Plane....\r
\r
+\r
     DEC     BL                  ; Planes to Go--\r
     JZ      @DB_Exit            ; Hey! We are done\r
\r
+\r
     ROL     BH, 1               ; Next Plane in line...\r
     OUT_8   SC_Data, BH         ; Select Plane\r
\r
+\r
     CMP     AL, 12h             ; Carry Set if AL=11h\r
     ADC     [BP].DB_Start, 0    ; Screen Addr =+Carry\r
     INC     w [BP].DB_Image     ; Start @ Next Byte\r
\r
+\r
     SUB     [BP].DB_SkewFlag, 1 ; Reduce Planes to Skew\r
     ADC     [BP].DB_SkewFlag, 0 ; Back to 0 if it was -1\r
\r
+\r
     JMP     s @DB_COPY_PLANE    ; Go Copy the Next Plane\r
\r
+\r
 @DB_Exit:\r
     ADD     SP, 10              ; Deallocate workspace\r
-    POPx    DI, SI, DS, BP      ; Restore Saved Registers\r
+    ;POPx    DI, SI, DS, BP      ; Restore Saved Registers\r
+    pop        di\r
+       pop     si\r
+       pop     ds\r
+       pop     bp\r
     RET     12                  ; Exit and Clean up Stack\r
\r
+\r
 DRAW_BITMAP   ENDP\r
\r
\r
+\r
+\r
 ;=======================================================\r
 ;TDRAW_BITMAP (SEG Image, Xpos%, Ypos%, Width%, Height%)\r
 ;=======================================================\r
@@ -2793,14 +2964,17 @@ DRAW_BITMAP   ENDP
 ;\r
 ; EXIT:  No meaningful values returned\r
 ;\r
\r
+\r
 TB_STACK    STRUC\r
     TB_LineO    DW  ?   ; Offset to Next Line\r
     TB_PixCount DW  ?   ; (Minimum) # of Pixels/Line\r
     TB_Start    DW  ?   ; Addr of Upper Left Pixel\r
     TB_PixSkew  DW  ?   ; # of bytes to Adjust EOL\r
     TB_SkewFlag DW  ?   ; Extra Pix on Plane Flag\r
-                DW  ?x4 ; DI, SI, DS, BP\r
+                DW  ?x1 ; DI, SI, DS, BP\r
+                DW  ?x1 ; DI, SI, DS, BP\r
+                DW  ?x1 ; DS, DI, SI, BP\r
+                DW  ?x1 ; DS, DI, SI, BP\r
                 DD  ?   ; Caller\r
     TB_Height   DW  ?   ; Height of Bitmap in Pixels\r
     TB_Width    DW  ?   ; Width of Bitmap in Pixels\r
@@ -2808,163 +2982,173 @@ TB_STACK    STRUC
     TB_Xpos     DW  ?   ; X position to Draw Bitmap at\r
     TB_Image    DD  ?   ; Far Pointer to Graphics Bitmap\r
 TB_STACK    ENDS\r
\r
+\r
         PUBLIC    TDRAW_BITMAP\r
\r
+\r
 TDRAW_BITMAP    PROC    FAR\r
\r
-    PUSHx   BP, DS, SI, DI      ; Preserve Important Registers\r
+\r
+    ;PUSHx   BP, DS, SI, DI      ; Preserve Important Registers\r
+    push       bp\r
+       push    ds\r
+       push    si\r
+       push    di\r
     SUB     SP, 10              ; Allocate workspace\r
     MOV     BP, SP              ; Set up Stack Frame\r
\r
+\r
     LES     DI, d CURRENT_PAGE  ; Point to Active VGA Page\r
     CLD                         ; Direction Flag = Forward\r
\r
+\r
     MOV     AX, [BP].TB_Ypos    ; Get UL Corner Ypos\r
     MUL     SCREEN_WIDTH        ; AX = Offset to Line Ypos\r
\r
+\r
     MOV     BX, [BP].TB_Xpos    ; Get UL Corner Xpos\r
     MOV     CL, BL              ; Save Plane # in CL\r
-    SHR     BX, 2               ; Xpos/4 = Offset Into Line\r
\r
+    SHR     BX, 1               ; Xpos/4 = Offset Into Line\r
+    SHR     BX, 1               ; Xpos/4 = Offset Into Line\r
+\r
     ADD     DI, AX              ; ES:DI -> Start of Line\r
     ADD     DI, BX              ; ES:DI -> Upper Left Pixel\r
     MOV     [BP].TB_Start, DI   ; Save Starting Addr\r
\r
+\r
     ; Compute line to line offset\r
\r
+\r
     MOV     BX, [BP].TB_Width   ; Get Width of Image\r
     MOV     DX, BX              ; Save Copy in DX\r
-    SHR     BX, 2               ; /4 = width in bands\r
+    SHR     BX, 1               ; /4 = width in bands\r
+    SHR     BX, 1               ; /4 = width in bands\r
     MOV     AX, SCREEN_WIDTH    ; Get Screen Width\r
     SUB     AX, BX              ; - (Bitmap Width/4)\r
\r
+\r
     MOV     [BP].TB_LineO, AX       ; Save Line Width offset\r
     MOV     [BP].TB_PixCount, BX    ; Minimum # pix to copy\r
\r
+\r
     AND     DX, PLANE_BITS          ; Get "partial band" size (0-3)\r
     MOV     [BP].TB_PixSkew, DX     ; Also End of Line Skew\r
     MOV     [BP].TB_SkewFlag, DX    ; Save as Flag/Count\r
\r
+\r
     AND     CX, PLANE_BITS      ; CL = Starting Plane #\r
     MOV     AX, MAP_MASK_PLANE2 ; Plane Mask & Plane Select\r
     SHL     AH, CL              ; Select correct Plane\r
     OUT_16  SC_Index, AX        ; Select Plane...\r
     MOV     BH, AH              ; BH = Saved Plane Mask\r
     MOV     BL, 4               ; BL = Planes to Copy\r
\r
+\r
 @TB_COPY_PLANE:\r
\r
+\r
     LDS     SI, [BP].TB_Image   ; DS:SI-> Source Image\r
     MOV     DX, [BP].TB_Height  ; # of Lines to Copy\r
     MOV     DI, [BP].TB_Start   ; ES:DI-> Dest pos\r
\r
+\r
     ; Here AH is set with the value to be considered\r
     ; "Transparent".  It can be changed!\r
\r
+\r
     MOV     AH, 0               ; Value to Detect 0\r
\r
+\r
 @TB_COPY_LINE:\r
     MOV     CX, [BP].TB_PixCount    ; Min # to copy\r
\r
+\r
     TEST    CL, 0FCh            ; 16+PixWide?\r
     JZ      @TB_COPY_REMAINDER  ; Nope...\r
\r
+\r
     ; Pixel Copy loop has been unrolled to x4\r
\r
+\r
 @TB_COPY_LOOP:\r
     LODSB                       ; Get Pixel Value in AL\r
     ADD     SI, 3               ; Skip to Next Byte in same plane\r
     CMP     AL, AH              ; It is "Transparent"?\r
     JE      @TB_SKIP_01         ; Skip ahead if so\r
     MOV     ES:[DI], AL         ; Copy Pixel to VGA screen\r
\r
+\r
 @TB_SKIP_01:\r
     LODSB                       ; Get Pixel Value in AL\r
     ADD     SI, 3               ; Skip to Next Byte in same plane\r
     CMP     AL, AH              ; It is "Transparent"?\r
     JE      @TB_SKIP_02         ; Skip ahead if so\r
     MOV     ES:[DI+1], AL       ; Copy Pixel to VGA screen\r
\r
+\r
 @TB_SKIP_02:\r
     LODSB                       ; Get Pixel Value in AL\r
     ADD     SI, 3               ; Skip to Next Byte in same plane\r
     CMP     AL, AH              ; It is "Transparent"?\r
     JE      @TB_SKIP_03         ; Skip ahead if so\r
     MOV     ES:[DI+2], AL       ; Copy Pixel to VGA screen\r
\r
+\r
 @TB_SKIP_03:\r
     LODSB                       ; Get Pixel Value in AL\r
     ADD     SI, 3               ; Skip to Next Byte in same plane\r
     CMP     AL, AH              ; It is "Transparent"?\r
     JE      @TB_SKIP_04         ; Skip ahead if so\r
     MOV     ES:[DI+3], AL       ; Copy Pixel to VGA screen\r
\r
+\r
 @TB_SKIP_04:\r
     ADD     DI, 4               ; Adjust Pixel Write Location\r
     SUB     CL, 4               ; Pixels to Copy=-4\r
     TEST    CL, 0FCh            ; 4+ Pixels Left?\r
     JNZ     @TB_COPY_LOOP       ; if so, do another block\r
\r
+\r
 @TB_COPY_REMAINDER:\r
     JCXZ    @TB_NEXT_LINE       ; Any Pixels left on line\r
\r
+\r
 @TB_COPY2:\r
     LODSB                       ; Get Pixel Value in AL\r
     ADD     SI, 3               ; Skip to Next Byte in same plane\r
     CMP     AL, AH              ; It is "Transparent"?\r
     JE      @TB_SKIP_05         ; Skip ahead if so\r
     MOV     ES:[DI], AL         ; Copy Pixel to VGA screen\r
\r
+\r
 @TB_SKIP_05:\r
     INC     DI                  ; Advance Dest Addr\r
     LOOPx   CX, @TB_COPY2       ; Pixels to Copy--, Loop until done\r
\r
+\r
 @TB_NEXT_LINE:\r
\r
+\r
     ; any Partial Pixels? (some planes only)\r
\r
+\r
     OR      CX, [BP].TB_SkewFlag    ; Get Skew Count\r
     JZ      @TB_NEXT2               ; if no partial pixels\r
\r
+\r
     LODSB                       ; Get Pixel Value in AL\r
     DEC     SI                  ; Backup to Align\r
     CMP     AL, AH              ; It is "Transparent"?\r
     JE      @TB_NEXT2           ; Skip ahead if so\r
     MOV     ES:[DI], AL         ; Copy Pixel to VGA screen\r
\r
+\r
 @TB_NEXT2:\r
     ADD     SI, [BP].TB_PixSkew ; Adjust Skew\r
     ADD     DI, [BP].TB_LineO   ; Set to Next Display Line\r
     LOOPx   DX, @TB_COPY_LINE   ; Lines to Copy--, Loop if More\r
\r
+\r
     ;Copy Next Plane....\r
\r
+\r
     DEC     BL                  ; Planes to Go--\r
     JZ      @TB_Exit            ; Hey! We are done\r
\r
+\r
     ROL     BH, 1               ; Next Plane in line...\r
     OUT_8   SC_Data, BH         ; Select Plane\r
\r
+\r
     CMP     AL, 12h             ; Carry Set if AL=11h\r
     ADC     [BP].TB_Start, 0    ; Screen Addr =+Carry\r
     INC     w [BP].TB_Image     ; Start @ Next Byte\r
\r
+\r
     SUB     [BP].TB_SkewFlag, 1 ; Reduce Planes to Skew\r
     ADC     [BP].TB_SkewFlag, 0 ; Back to 0 if it was -1\r
\r
+\r
     JMP     @TB_COPY_PLANE      ; Go Copy the next Plane\r
\r
+\r
 @TB_Exit:\r
     ADD     SP, 10              ; Deallocate workspace\r
-    POPx    DI, SI, DS, BP      ; Restore Saved Registers\r
+    ;POPx    DI, SI, DS, BP      ; Restore Saved Registers\r
+    pop        di\r
+       pop     si\r
+       pop     ds\r
+       pop     bp\r
     RET     12                  ; Exit and Clean up Stack\r
\r
+\r
 TDRAW_BITMAP    ENDP\r
\r
\r
+\r
+\r
     ; ==== VIDEO MEMORY to VIDEO MEMORY COPY ROUTINES =====\r
\r
+\r
 ;==================================\r
 ;COPY_PAGE (SourcePage%, DestPage%)\r
 ;==================================\r
@@ -2976,70 +3160,81 @@ TDRAW_BITMAP    ENDP
 ;\r
 ; EXIT:  No meaningful values returned\r
 ;\r
\r
+\r
 CP_STACK    STRUC\r
-                DW  ?x4 ; DI, SI, DS, BP\r
+                DW  ?x1 ; DI, SI, DS, BP\r
+                DW  ?x1 ; DI, SI, DS, BP\r
+                DW  ?x1 ; DS, DI, SI, BP\r
+                DW  ?x1 ; DS, DI, SI, BP\r
                 DD  ?   ; Caller\r
     CP_DestP    DW  ?   ; Page to hold copied image\r
     CP_SourceP  DW  ?   ; Page to Make copy from\r
 CP_STACK    ENDS\r
\r
+\r
         PUBLIC    COPY_PAGE\r
\r
+\r
 COPY_PAGE   PROC    FAR\r
\r
-    PUSHx   BP, DS, SI, DI      ; Preserve Important Registers\r
+\r
+    ;PUSHx   BP, DS, SI, DI      ; Preserve Important Registers\r
+    push       bp\r
+       push    ds\r
+       push    si\r
+       push    di\r
     MOV     BP, SP              ; Set up Stack Frame\r
     CLD                         ; Block Xfer Forwards\r
\r
+\r
     ; Make sure Page #'s are valid\r
\r
+\r
     MOV     AX, [BP].CP_SourceP ; Get Source Page #\r
     CMP     AX, LAST_PAGE       ; is it > Max Page #?\r
     JAE     @CP_Exit            ; if so, abort\r
\r
+\r
     MOV     BX, [BP].CP_DestP   ; Get Destination Page #\r
     CMP     BX, LAST_PAGE       ; is it > Max Page #?\r
     JAE     @CP_Exit            ; if so, abort\r
\r
+\r
     CMP     AX, BX              ; Pages #'s the same?\r
     JE      @CP_Exit            ; if so, abort\r
\r
+\r
     ; Setup DS:SI and ES:DI to Video Pages\r
\r
+\r
     SHL     BX, 1               ; Scale index to Word\r
     MOV     DI, PAGE_ADDR[BX]   ; Offset to Dest Page\r
\r
+\r
     MOV     BX, AX              ; Index to Source page\r
     SHL     BX, 1               ; Scale index to Word\r
     MOV     SI, PAGE_ADDR[BX]   ; Offset to Source Page\r
\r
+\r
     MOV     CX, PAGE_SIZE       ; Get size of Page\r
     MOV     AX, CURRENT_SEGMENT ; Get Video Mem Segment\r
     MOV     ES, AX              ; ES:DI -> Dest Page\r
     MOV     DS, AX              ; DS:SI -> Source Page\r
\r
+\r
     ; Setup VGA registers for Mem to Mem copy\r
\r
+\r
     OUT_16  GC_Index, LATCHES_ON    ; Data from Latches = on\r
     OUT_16  SC_Index, ALL_PLANES_ON ; Copy all Planes\r
\r
+\r
     ; Note.. Do *NOT* use MOVSW or MOVSD - they will\r
     ; Screw with the latches which are 8 bits x 4\r
\r
+\r
     REP     MOVSB               ; Copy entire Page!\r
\r
+\r
     ; Reset VGA for normal memory access\r
\r
+\r
     OUT_16  GC_Index, LATCHES_OFF   ; Data from Latches = off\r
\r
+\r
 @CP_Exit:\r
-    POPx    DI, SI, DS, BP      ; Restore Saved Registers\r
+    ;POPx    DI, SI, DS, BP      ; Restore Saved Registers\r
+    pop        di\r
+       pop     si\r
+       pop     ds\r
+       pop     bp\r
     RET     4                   ; Exit and Clean up Stack\r
\r
+\r
 COPY_PAGE   ENDP\r
\r
\r
+\r
+\r
 ;==========================================================================\r
 ;COPY_BITMAP (SourcePage%, X1%, Y1%, X2%, Y2%, DestPage%, DestX1%, DestY1%)\r
 ;==========================================================================\r
@@ -3065,11 +3260,14 @@ COPY_PAGE   ENDP
 ;\r
 ; EXIT:  AX = Success Flag:   0 = Failure / -1= Success\r
 ;\r
\r
+\r
 CB_STACK    STRUC\r
     CB_Height   DW  ?   ; Height of Image in Lines\r
     CB_Width    DW  ?   ; Width of Image in "bands"\r
-                DW  ?x4 ; DI, SI, DS, BP\r
+                DW  ?x1 ; DI, SI, DS, BP\r
+                DW  ?x1 ; DI, SI, DS, BP\r
+                DW  ?x1 ; DS, DI, SI, BP\r
+                DW  ?x1 ; DS, DI, SI, BP\r
                 DD  ?   ; Caller\r
     CB_DestY1   DW  ?   ; Destination Ypos\r
     CB_DestX1   DW  ?   ; Destination Xpos\r
@@ -3080,64 +3278,71 @@ CB_STACK    STRUC
     CB_X1       DW  ?   ; UL Xpos of Image\r
     CB_SourceP  DW  ?   ; Page containing Source Bitmap\r
 CB_STACK    ENDS\r
\r
+\r
         PUBLIC    COPY_BITMAP\r
\r
+\r
 COPY_BITMAP PROC    FAR\r
\r
-    PUSHx   BP, DS, SI, DI      ; Preserve Important Registers\r
+\r
+    ;PUSHx   BP, DS, SI, DI      ; Preserve Important Registers\r
+    push       bp\r
+       push    ds\r
+       push    si\r
+       push    di\r
     SUB     SP, 4               ; Allocate WorkSpace on Stack\r
     MOV     BP, SP              ; Set up Stack Frame\r
\r
+\r
     ; Prep Registers (and keep jumps short!)\r
\r
+\r
     MOV     ES, CURRENT_SEGMENT ; ES -> VGA Ram\r
     CLD                         ; Block Xfer Forwards\r
\r
+\r
     ; Make sure Parameters are valid\r
\r
+\r
     MOV     BX, [BP].CB_SourceP ; Get Source Page #\r
     CMP     BX, LAST_PAGE       ; is it > Max Page #?\r
     JAE     @CB_Abort           ; if so, abort\r
\r
+\r
     MOV     CX, [BP].CB_DestP   ; Get Destination Page #\r
     CMP     CX, LAST_PAGE       ; is it > Max Page #?\r
     JAE     @CB_Abort           ; if so, abort\r
\r
+\r
     MOV     AX, [BP].CB_X1      ; Get Source X1\r
     XOR     AX, [BP].CB_DestX1  ; Compare Bits 0-1\r
     AND     AX, PLANE_BITS      ; Check Plane Bits\r
     JNZ     @CB_Abort           ; They should cancel out\r
\r
+\r
     ; Setup for Copy processing\r
\r
+\r
     OUT_8   SC_INDEX, MAP_MASK      ; Set up for Plane Select\r
     OUT_16  GC_Index, LATCHES_ON    ; Data from Latches = on\r
\r
+\r
     ; Compute Info About Images, Setup ES:SI & ES:DI\r
\r
+\r
     MOV     AX, [BP].CB_Y2      ; Height of Bitmap in lines\r
     SUB     AX, [BP].CB_Y1      ; is Y2 - Y1 + 1\r
     INC     AX                  ; (add 1 since were not 0 based)\r
     MOV     [BP].CB_Height, AX  ; Save on Stack for later use\r
\r
+\r
     MOV     AX, [BP].CB_X2      ; Get # of "Bands" of 4 Pixels\r
     MOV     DX, [BP].CB_X1      ; the Bitmap Occupies as X2-X1\r
-    SHR     AX, 2               ; Get X2 Band (X2 / 4)\r
-    SHR     DX, 2               ; Get X1 Band (X1 / 4)\r
+    SHR     AX, 1               ; Get X2 Band (X2 / 4)\r
+    SHR     DX, 1               ; Get X1 Band (X1 / 4)\r
+    SHR     AX, 1               ; Get X2 Band (X2 / 4)\r
+    SHR     DX, 1               ; Get X1 Band (X1 / 4)\r
     SUB     AX, DX              ; AX = # of Bands - 1\r
     INC     AX                  ; AX = # of Bands\r
     MOV     [BP].CB_Width, AX   ; Save on Stack for later use\r
\r
+\r
     SHL     BX, 1               ; Scale Source Page to Word\r
     MOV     SI, PAGE_ADDR[BX]   ; SI = Offset of Source Page\r
     MOV     AX, [BP].CB_Y1      ; Get Source Y1 Line\r
     MUL     SCREEN_WIDTH        ; AX = Offset to Line Y1\r
     ADD     SI, AX              ; SI = Offset to Line Y1\r
     MOV     AX, [BP].CB_X1      ; Get Source X1\r
-    SHR     AX, 2               ; X1 / 4 = Byte offset\r
+    SHR     AX, 1               ; X1 / 4 = Byte offset\r
+    SHR     AX, 1               ; X1 / 4 = Byte offset\r
     ADD     SI, AX              ; SI = Byte Offset to (X1,Y1)\r
\r
+\r
     MOV     BX, CX              ; Dest Page Index to BX\r
     SHL     BX, 1               ; Scale Source Page to Word\r
     MOV     DI, PAGE_ADDR[BX]   ; DI = Offset of Dest Page\r
@@ -3145,24 +3350,25 @@ COPY_BITMAP PROC    FAR
     MUL     SCREEN_WIDTH        ; AX = Offset to Line Y1\r
     ADD     DI, AX              ; DI = Offset to Line Y1\r
     MOV     AX, [BP].CB_DestX1  ; Get Dest X1\r
-    SHR     AX, 2               ; X1 / 4 = Byte offset\r
+    SHR     AX, 1              ; X1 / 4 = Byte offset\r
+    SHR     AX, 1               ; X1 / 4 = Byte offset\r
     ADD     DI, AX              ; DI = Byte Offset to (D-X1,D-Y1)\r
\r
+\r
     MOV     CX, [BP].CB_Width   ; CX = Width of Image (Bands)\r
     DEC     CX                  ; CX = 1?\r
     JE      @CB_Only_One_Band   ; 0 Means Image Width of 1 Band\r
\r
+\r
     MOV     BX, [BP].CB_X1      ; Get Source X1\r
     AND     BX, PLANE_BITS      ; Aligned? (bits 0-1 = 00?)\r
     JZ      @CB_Check_Right     ; if so, check right alignment\r
     JNZ     @CB_Left_Band       ; not aligned? well..\r
\r
+\r
 @CB_Abort:\r
-    CLR     AX                  ; Return False (Failure)\r
+    mov ax,0                  ; Return False (Failure)\r
     JMP     @CB_Exit            ; and Finish Up\r
\r
+\r
     ; Copy when Left & Right Clip Masks overlap...\r
\r
+\r
 @CB_Only_One_Band:\r
     MOV     BX, [BP].CB_X1          ; Get Left Clip Mask\r
     AND     BX, PLANE_BITS          ; Mask out Row #\r
@@ -3170,126 +3376,130 @@ COPY_BITMAP PROC    FAR
     MOV     BX, [BP].CB_X2          ; Get Right Clip Mask\r
     AND     BX, PLANE_BITS          ; Mask out Row #\r
     AND     AL, Right_Clip_Mask[BX] ; Get Right Edge Mask byte\r
\r
+\r
     OUT_8   SC_Data, AL         ; Clip For Left & Right Masks\r
\r
+\r
     MOV     CX, [BP].CB_Height  ; CX = # of Lines to Copy\r
     MOV     DX, SCREEN_WIDTH    ; DX = Width of Screen\r
-    CLR     BX                  ; BX = Offset into Image\r
\r
+    mov bx,0                  ; BX = Offset into Image\r
+\r
 @CB_One_Loop:\r
     MOV     AL, ES:[SI+BX]      ; Load Latches\r
     MOV     ES:[DI+BX], AL      ; Unload Latches\r
     ADD     BX, DX              ; Advance Offset to Next Line\r
     LOOPjz  CX, @CB_One_Done    ; Exit Loop if Finished\r
\r
+\r
     MOV     AL, ES:[SI+BX]      ; Load Latches\r
     MOV     ES:[DI+BX], AL      ; Unload Latches\r
     ADD     BX, DX              ; Advance Offset to Next Line\r
     LOOPx   CX, @CB_One_Loop    ; Loop until Finished\r
\r
+\r
 @CB_One_Done:\r
     JMP     @CB_Finish          ; Outa Here!\r
\r
+\r
     ; Copy Left Edge of Bitmap\r
\r
+\r
 @CB_Left_Band:\r
\r
+\r
     OUT_8   SC_Data, Left_Clip_Mask[BX] ; Set Left Edge Plane Mask\r
\r
+\r
     MOV     CX, [BP].CB_Height  ; CX = # of Lines to Copy\r
     MOV     DX, SCREEN_WIDTH    ; DX = Width of Screen\r
-    CLR     BX                  ; BX = Offset into Image\r
\r
+    mov bx,0                  ; BX = Offset into Image\r
+\r
 @CB_Left_Loop:\r
     MOV     AL, ES:[SI+BX]      ; Load Latches\r
     MOV     ES:[DI+BX], AL      ; Unload Latches\r
     ADD     BX, DX              ; Advance Offset to Next Line\r
     LOOPjz  CX, @CB_Left_Done   ; Exit Loop if Finished\r
\r
+\r
     MOV     AL, ES:[SI+BX]      ; Load Latches\r
     MOV     ES:[DI+BX], AL      ; Unload Latches\r
     ADD     BX, DX              ; Advance Offset to Next Line\r
     LOOPx   CX, @CB_Left_Loop   ; Loop until Finished\r
\r
+\r
 @CB_Left_Done:\r
     INC     DI                  ; Move Dest Over 1 band\r
     INC     SI                  ; Move Source Over 1 band\r
     DEC     [BP].CB_Width       ; Band Width--\r
\r
+\r
     ; Determine if Right Edge of Bitmap needs special copy\r
\r
+\r
 @CB_Check_Right:\r
     MOV     BX, [BP].CB_X2      ; Get Source X2\r
     AND     BX, PLANE_BITS      ; Aligned? (bits 0-1 = 11?)\r
     CMP     BL, 03h             ; Plane = 3?\r
     JE      @CB_Copy_Middle     ; Copy the Middle then!\r
\r
+\r
     ; Copy Right Edge of Bitmap\r
\r
+\r
 @CB_Right_Band:\r
\r
+\r
     OUT_8   SC_Data, Right_Clip_Mask[BX]    ; Set Right Edge Plane Mask\r
\r
+\r
     DEC     [BP].CB_Width       ; Band Width--\r
     MOV     CX, [BP].CB_Height  ; CX = # of Lines to Copy\r
     MOV     DX, SCREEN_WIDTH    ; DX = Width of Screen\r
     MOV     BX, [BP].CB_Width   ; BX = Offset to Right Edge\r
\r
+\r
 @CB_Right_Loop:\r
     MOV     AL, ES:[SI+BX]      ; Load Latches\r
     MOV     ES:[DI+BX], AL      ; Unload Latches\r
     ADD     BX, DX              ; Advance Offset to Next Line\r
     LOOPjz  CX, @CB_Right_Done  ; Exit Loop if Finished\r
\r
+\r
     MOV     AL, ES:[SI+BX]      ; Load Latches\r
     MOV     ES:[DI+BX], AL      ; Unload Latches\r
     ADD     BX, DX              ; Advance Offset to Next Line\r
     LOOPx   CX, @CB_Right_Loop  ; Loop until Finished\r
\r
+\r
 @CB_Right_Done:\r
\r
+\r
     ; Copy the Main Block of the Bitmap\r
\r
+\r
 @CB_Copy_Middle:\r
\r
+\r
     MOV     CX, [BP].CB_Width   ; Get Width Remaining\r
     JCXZ    @CB_Finish          ; Exit if Done\r
\r
+\r
     OUT_8   SC_Data, ALL_PLANES ; Copy all Planes\r
\r
+\r
     MOV     DX, SCREEN_WIDTH    ; Get Width of Screen minus\r
     SUB     DX, CX              ; Image width (for Adjustment)\r
     MOV     AX, [BP].CB_Height  ; AX = # of Lines to Copy\r
     MOV     BX, CX              ; BX = Quick REP reload count\r
     MOV     CX, ES              ; Move VGA Segment\r
     MOV     DS, CX              ; Into DS\r
\r
+\r
     ; Actual Copy Loop.  REP MOVSB does the work\r
\r
+\r
 @CB_Middle_Copy:\r
     MOV     CX, BX              ; Recharge Rep Count\r
     REP     MOVSB               ; Move Bands\r
     LOOPjz  AX, @CB_Finish      ; Exit Loop if Finished\r
\r
+\r
     ADD     SI, DX              ; Adjust DS:SI to Next Line\r
     ADD     DI, DX              ; Adjust ES:DI to Next Line\r
\r
+\r
     MOV     CX, BX              ; Recharge Rep Count\r
     REP     MOVSB               ; Move Bands\r
\r
+\r
     ADD     SI, DX              ; Adjust DS:SI to Next Line\r
     ADD     DI, DX              ; Adjust ES:DI to Next Line\r
     LOOPx   AX, @CB_Middle_Copy ; Copy Lines until Done\r
\r
+\r
 @CB_Finish:\r
     OUT_16  GC_Index, LATCHES_OFF   ; Data from Latches = on\r
\r
+\r
 @CB_Exit:\r
     ADD     SP, 04              ; Deallocate stack workspace\r
-    POPx    DI, SI, DS, BP      ; Restore Saved Registers\r
+    ;POPx    DI, SI, DS, BP      ; Restore Saved Registers\r
+    pop        di\r
+       pop     si\r
+       pop     ds\r
+       pop     bp\r
     RET     16                  ; Exit and Clean up Stack\r
\r
+\r
 COPY_BITMAP ENDP\r
\r
+\r
     END                         ; End of Code Segment\r
index 7de25a6318f420f3639d926f7f03b4eba75945dc..1381abb6696bd66bd5820eee902e75d981b8284c 100755 (executable)
@@ -1,9 +1,9 @@
\r
+\r
 #ifndef __MODEX_H\r
 #define __MODEX_H\r
\r
+\r
     /* ===== SCREEN RESOLUTIONS ===== */\r
\r
+\r
 #define Mode_320x200  0\r
 #define Mode_320x400  1\r
 #define Mode_360x200  2\r
 #define Mode_320x480  5\r
 #define Mode_360x240  6\r
 #define Mode_360x480  7\r
\r
+\r
     /* ===== MODE X SETUP ROUTINES ===== */\r
\r
+\r
 int far pascal set_vga_modex (int Mode, int MaxXpos, int MaxYpos, int Pages);\r
 int far pascal set_modex (int Mode);\r
\r
+\r
     /* ===== BASIC GRAPHICS PRIMITIVES ===== */\r
\r
+\r
 void far pascal clear_vga_screen (int Color);\r
 void far pascal set_point (int Xpos, int Ypos, int Color);\r
 int  far pascal read_point (int Xpos, int Ypos);\r
@@ -27,18 +27,18 @@ void far pascal fill_block (int Xpos1, int Ypos1, int Xpos2, int Ypos2,
                             int Color);\r
 void far pascal draw_line (int Xpos1, int Ypos1, int Xpos2, int Ypos2,\r
                            int Color);\r
\r
+\r
     /* ===== DAC COLOR REGISTER ROUTINES ===== */\r
\r
+\r
 void far pascal set_dac_register (int RegNo, int Red, int Green, int Blue);\r
 void far pascal get_dac_register (int RegNo, int* Red, int* Green, int* Blue);\r
 void far pascal load_dac_registers (char far *PalData, int StartReg,\r
                                     int EndReg, int VSync);\r
 void far pascal readd_dac_registers (char far *PalData, int StartReg,\r
                                     int EndReg);\r
\r
+\r
     /* ===== PAGE FLIPPING AND SCROLLING ROUTINES ===== */\r
\r
+\r
 void far pascal set_active_page (int PageNo);\r
 int  far pascal get_active_page (void);\r
 void far pascal set_display_page (int PageNo);\r
@@ -47,9 +47,9 @@ void far pascal set_window (int DisplayPage, int XOffset, int YOffset);
 int  far pascal get_x_offset (void);\r
 int  far pascal get_y_offset (void);\r
 void far pascal sync_display (void);\r
\r
+\r
     /* ===== TEXT DISPLAY ROUTINES ===== */\r
\r
+\r
 void far pascal gprintc (int CharNum, int Xpos, int Ypos, int ColorF,\r
                          int ColorB);\r
 void far pascal tgprintc (int CharNum, int Xpos, int Ypos, int ColorF);\r
@@ -58,19 +58,19 @@ void far pascal print_str (char far *Text, int MaxLen, int Xpos, int Ypos,
 void far pascal tprint_str (char far *Text, int MaxLen, int Xpos, int Ypos,\r
                             int ColorF);\r
 void far pascal set_display_font (char far *FontData, int FontNumber);\r
\r
+\r
     /* ===== BITMAP (SPRITE) DISPLAY ROUTINES ===== */\r
\r
+\r
 void far pascal draw_bitmap (char far *Image, int Xpos, int Ypos,\r
                              int Width, int Height);\r
 void far pascal tdraw_bitmap (char far *Image, int Xpos, int Ypos,\r
                               int Width, int Height);\r
\r
+\r
     /* ==== VIDEO MEMORY to VIDEO MEMORY COPY ROUTINES ===== */\r
\r
+\r
 void far pascal copy_page (int SourcePage, int DestPage);\r
 void far pascal copy_bitmap (int SourcePage, int X1, int Y1, int X2, int Y2,\r
                              int DestPage, int DestX1, int DestY1);\r
\r
\r
+\r
+\r
 #endif\r
diff --git a/src/lib/modex/utls-asm.bat b/src/lib/modex/utls-asm.bat
new file mode 100755 (executable)
index 0000000..d996978
--- /dev/null
@@ -0,0 +1 @@
+MASM c_utils, c_utils, c_utils, nul;
\ No newline at end of file
diff --git a/src/lib/modex/w.sh b/src/lib/modex/w.sh
new file mode 100755 (executable)
index 0000000..4483916
--- /dev/null
@@ -0,0 +1,3 @@
+#! /bin/bash
+wmake clean;wmake
+cp x_demo.exe ../../../
diff --git a/src/lib/modex/x.exe b/src/lib/modex/x.exe
new file mode 100755 (executable)
index 0000000..7742d14
Binary files /dev/null and b/src/lib/modex/x.exe differ
diff --git a/src/lib/modex/x_demo.c b/src/lib/modex/x_demo.c
new file mode 100755 (executable)
index 0000000..dfe9a3e
--- /dev/null
@@ -0,0 +1,786 @@
+/* X-DEMO.C - a Mode "X" Demo      */\r
+/* By Matt Pritchard, 14 Apr, 1993 */\r
+\r
+#include <stdlib.h>\r
+#include <stdio.h>\r
+\r
+#include "modex.h"\r
+#include "c_utils.h"\r
+\r
+#define MAX_SHAPES  32\r
+#define MAX_SPRITES 64\r
+\r
+       /* routines in this file */\r
+\r
+void demo_res (int, int, int);\r
+int  get_key (void);\r
+void error_out (char*);\r
+void load_shapes (void);\r
+int  int_sqrt (int, int);\r
+void page_demo (void);\r
+\r
+       /* Structures for Sprites */\r
+\r
+struct Shape\r
+{\r
+       unsigned char Image[512];\r
+       int           X_Width;\r
+       int                       Y_Width;\r
+}   Img [MAX_SHAPES];\r
+\r
+struct Sprite\r
+{\r
+       int     X_pos;\r
+       int     Y_pos;\r
+       int X_Dir;\r
+       int Y_Dir;\r
+       int     Shape;\r
+       int     Last_X [2];\r
+       int Last_Y [2];\r
+}   Obj [MAX_SPRITES];\r
+\r
+\r
+       /* MAIN */\r
+\r
+\r
+int main(int argc, char *argv[])\r
+{\r
+\r
+   /*  if (argc > 0)\r
+       {\r
+               while (argc > 0)\r
+               {\r
+                       dos_print ("Unknown Argument: ");\r
+                       dos_print (makefp argv[argc]);\r
+                       argc--;\r
+               }\r
+               return (0);\r
+\r
+       }\r
+        */\r
+\r
+       init_random ();\r
+\r
+       load_shapes ();\r
+\r
+       demo_res ( Mode_320x200, 320, 200 );\r
+       demo_res ( Mode_320x400, 320, 400 );\r
+\r
+       demo_res ( Mode_360x200, 360, 200 );\r
+       demo_res ( Mode_360x400, 360, 400 );\r
+\r
+       demo_res ( Mode_320x240, 320, 240 );\r
+       demo_res ( Mode_320x480, 320, 480 );\r
+\r
+       demo_res ( Mode_360x240, 360, 240 );\r
+       demo_res ( Mode_360x480, 360, 480 );\r
+\r
+       page_demo ();\r
+\r
+       set_video_mode (3);\r
+       dos_print ("This Mode X Demo is Finished");\r
+       return (0);\r
+\r
+}\r
+\r
+\r
+       /* Demonstrate a given resolution */\r
+\r
+\r
+void demo_res (int Screen_Mode, int X_max, int Y_max)\r
+{\r
+\r
+char   *Error1 = "Failure while calling SET_MODEX";\r
+char   *Error2 = "Failure during READ_PIXEL test";\r
+\r
+char   *Abort_Msg = "Demo aborted by User";\r
+\r
+char   *Demo_Msg = " This is a MODE X demo ";\r
+char   *Scrn_Msg = "Screen Resolution is     by    ";\r
+char   *Cont_Msg = "Press <ANY KEY> to Continue";\r
+\r
+char    *Line_Msg = "LINE TEST";\r
+char   *Fill_Msg = "FILL TEST";\r
+char   *Pixel_Msg = "PIXEL TEST";\r
+\r
+char   Text[10];\r
+\r
+int            x1, y1, x2, y2 = 0;\r
+int            x, y, z = 0;\r
+int            X_Center, gap = 0;\r
+\r
+\r
+       if (set_modex (Screen_Mode) == 0)\r
+       {\r
+               error_out (Error1);\r
+       }\r
+\r
+       X_Center = X_max / 2;\r
+\r
+       x1 = 10;\r
+       y1 = 10;\r
+       x2 = X_max - 1;\r
+       y2 = Y_max - 1;\r
+\r
+       for (z = 0; z <= 3; z++)\r
+       {\r
+               y = 31 - z -z;\r
+               draw_line (x1+z, y1+z, x2-z, y1+z, y);\r
+               draw_line (x1+z, y1+z, x1+z, y2-z, y);\r
+               draw_line (x1+z, y2-z, x2-z, y2-z, y);\r
+               draw_line (x2-z, y1+z, x2-z, y2-z, y);\r
+       }\r
+\r
+       for (x = 0; x < (X_max / 10); x++)\r
+       {\r
+               tgprintc (48 + ((x+1) % 10), x*10+1, 1, 9 + ((x/8) % 7) );\r
+               draw_line (x*10+9, 0, x*10+9, 3, c_bWHITE);\r
+       }\r
+\r
+       for (y = 0; y < (Y_max / 10); y++)\r
+       {\r
+               tgprintc (48 + ((y+1) % 10), 1, y*10+1, 9 + ((y/10) % 7) );\r
+               draw_line (0, y*10+9, 3, y*10+9, c_bWHITE);\r
+       }\r
+\r
+       for (x = 0; x <= 63; x++)\r
+       {\r
+               z = 15 + (x * 3 / 4);\r
+               set_dac_register (64+x, z, z, z);\r
+               set_dac_register (128+x, 0, z, z);\r
+\r
+               draw_line (103-x, 60, 40+x, 123, 64+x);\r
+               draw_line (40, 60+x, 103, 123-x, 128+x);\r
+\r
+       }\r
+\r
+       tprint_str (Line_Msg, 9, 37, 130, c_BLUE);\r
+\r
+       y = 60;\r
+       gap = 0;\r
+       for (x = 0; x <= 9; x++)\r
+       {\r
+               fill_block (120, y, 120+x, y+gap, 64+x);\r
+               fill_block (140 - (15-x), y, 150+x, y+gap, 230+x);\r
+               fill_block (170 - (15-x), y, 170, y+gap, 128+x);\r
+               y = y + gap + 2;\r
+               gap++;\r
+       }\r
+\r
+       tprint_str (Fill_Msg, 9, 110, 46, c_GREEN);\r
+\r
+       for (x = 190; x <= 250; x+=2)\r
+       {\r
+               for (y = 60; y <= 122; y+=2)\r
+               {\r
+                       z = (x+x+y+y) & 0xff;\r
+                       set_point (x, y, z);\r
+               }\r
+       }\r
+\r
+       tprint_str (Pixel_Msg, 10, 182, 130, c_RED);\r
+\r
+       for (x = 190; x <= 250; x+=2)\r
+       {\r
+               for (y = 60; y <= 122; y+=2)\r
+               {\r
+                       z = (x+x+y+y) & 0xff;\r
+                       if (read_point(x, y) != z)\r
+                       {\r
+                               error_out (Error2);\r
+                       }\r
+               }\r
+       }\r
+\r
+       print_str (Demo_Msg, 23, X_Center - 92, 20, c_bRED, c_BLUE);\r
+\r
+       x = X_Center - 124;\r
+       print_str (Scrn_Msg, 28, x, 30, c_bGREEN, c_BLACK);\r
+\r
+       sprintf (Text, "%3d", X_max);\r
+       print_str (Text, 3, x+168, 30, c_bPURPLE, c_BLACK);\r
+\r
+       sprintf (Text, "%3d", Y_max);\r
+       print_str (Text, 3, x + 224, 30, c_bWHITE, c_BLACK);\r
+\r
+       for (x = 0; x <= 15; x++)\r
+       {\r
+               set_dac_register (230+x, 63-x*4, 0, 15+x*3);\r
+               draw_line (30+x, Y_max-6-x, X_max-20-x, Y_max-6-x, 230+x);\r
+       }\r
+\r
+       tprint_str (Cont_Msg, 27, X_Center - 103, Y_max-18, c_YELLOW);\r
+\r
+       if (get_key () == Ky_ESC)\r
+       {\r
+               error_out (Abort_Msg);\r
+       }\r
+\r
+       return ;\r
+\r
+}\r
+\r
+\r
+       /* Wait for a Keystroke */\r
+\r
+\r
+int get_key(void)\r
+{\r
+\r
+int    c = 0;\r
+\r
+       while (c == 0)\r
+       {\r
+               c = scan_keyboard ();\r
+       }\r
+\r
+       return (c);\r
+\r
+}\r
+\r
+\r
+       /* Error Handling Routine */\r
+\r
+\r
+void error_out (char * text)\r
+{\r
+\r
+       set_video_mode (3);\r
+       dos_print (text);\r
+       exit (EXIT_SUCCESS);\r
+\r
+}\r
+\r
+\r
+       /* Routine to generate random sprites */\r
+\r
+\r
+void load_shapes ()\r
+{\r
+\r
+unsigned char  Grid[33][33];\r
+\r
+char   *Error1 = "Bad Shape Selected Error";\r
+\r
+int            Shape;\r
+int            x, y, z;\r
+int            Style, Color;\r
+int            X_Width, Y_Width, Center, S_Width;\r
+int            Hollow_X, Hollow_Y;\r
+\r
+       for (Shape = 0; Shape < MAX_SHAPES; Shape++)\r
+       {\r
+               for (y = 0; y <= 32; y++)\r
+               {\r
+                       for (x = 0; x <= 32; x++)\r
+                       {\r
+                               Grid[x][y] = c_BLACK;\r
+                       }\r
+               }\r
+\r
+               Style = random_int (6);\r
+               Color = 1 + random_int (15);\r
+\r
+               switch (Style)\r
+\r
+               {\r
+                               /* SOLID BOXES */\r
+\r
+                       case 0:\r
+\r
+                       {\r
+                               do\r
+                               {\r
+                                       X_Width = 3 + random_int(30);\r
+                                       Y_Width = 3 + random_int(30);\r
+\r
+                               } while ( (X_Width * Y_Width) >= 512);\r
+\r
+                               for (x = 1; x <= X_Width; x++)\r
+                               {\r
+                                       for (y = 1; y <= Y_Width; y++)\r
+                                       {\r
+                                          Grid[x][y] = Color;\r
+                                       }\r
+                               }\r
+\r
+                               break;\r
+\r
+                       }\r
+                               /* HOLLOW BOXES */\r
+\r
+                       case 1:\r
+\r
+                       {\r
+                               do {\r
+                                       X_Width = 6 + random_int(27);\r
+                                       Y_Width = 6 + random_int(27);\r
+                               } while ( (X_Width * Y_Width) >= 512);\r
+\r
+                               for (y = 1; y <= Y_Width; y++)\r
+                               {\r
+                                       for (x = 1; x <= X_Width; x++)\r
+                                       {\r
+                                               Grid[x][y] = Color;\r
+                                       }\r
+                               }\r
+\r
+                               Hollow_X = 1 + random_int ((X_Width / 2) -1);\r
+                               Hollow_Y = 1 + random_int ((Y_Width / 2) -1);\r
+\r
+                               for (y = Hollow_Y+1; y <= Y_Width-Hollow_Y; y++)\r
+                               {\r
+                                       for (x = Hollow_X+1; x <= X_Width-Hollow_X; x++)\r
+                                       {\r
+                                               Grid[x][y] = c_BLACK;\r
+                                       }\r
+                               }\r
+\r
+                               break;\r
+\r
+                       }\r
+\r
+                               /* SOLID DIAMOND */\r
+\r
+                       case 2:\r
+\r
+                       {\r
+\r
+                               X_Width = 3 + 2 * random_int(10);\r
+                               Y_Width = X_Width;\r
+                               Center = X_Width / 2;\r
+\r
+                               for (y = 0; y <= Center; y++)\r
+                               {\r
+                                       for (x = 0; x <= y; x++)\r
+                                       {\r
+                                               Grid [Center-x+1][y+1] = Color;\r
+                                               Grid [Center+x+1][y+1] = Color;\r
+                                               Grid [Center-x+1][Y_Width-y] = Color;\r
+                                               Grid [Center+x+1][Y_Width-y] = Color;\r
+                                       }\r
+                               }\r
+\r
+                               break;\r
+\r
+                       }\r
+\r
+                               /* HOLLOW DIAMOND */\r
+\r
+                       case 3:\r
+\r
+                       {\r
+\r
+                               X_Width = 3 + 2 * random_int(10);\r
+                               Y_Width = X_Width;\r
+                               Center = X_Width / 2;\r
+                               S_Width = random_int (Center);\r
+\r
+                               for (y = 0; y <= Center; y++)\r
+                               {\r
+                                       for (x = 0; x <= y; x++)\r
+                                       {\r
+                                               if ( x+(Center-y) >= S_Width )\r
+                                               {\r
+                                                       Grid [Center-x+1][y+1] = Color;\r
+                                                       Grid [Center+x+1][y+1] = Color;\r
+                                                       Grid [Center-x+1][Y_Width-y] = Color;\r
+                                                       Grid [Center+x+1][Y_Width-y] = Color;\r
+                                               }\r
+                                       }\r
+                               }\r
+\r
+                               break;\r
+\r
+                       }\r
+\r
+                               /* BALL */\r
+\r
+                       case 4:\r
+\r
+                       {\r
+\r
+                               X_Width = 7 + 2 * random_int (8);\r
+                               Y_Width = X_Width;\r
+                               Center  = 1 + X_Width / 2;\r
+\r
+                               for (y = 1; y <= Y_Width; y++)\r
+                               {\r
+                                       for (x = 1; x <= X_Width; x++)\r
+                                       {\r
+                                               z = int_sqrt(Center-x, Center-y);\r
+                                               if (z < Center)\r
+                                               {\r
+                                                       Grid[x][y] = 150 + Color * 2 + z * 3;\r
+                                               }\r
+                                       }\r
+                               }\r
+\r
+                               break;\r
+                       }\r
+\r
+                               /* HOLLOW BALLS */\r
+\r
+                       case 5:\r
+\r
+                       {\r
+                               X_Width = 7 + 2 * random_int (8);\r
+                               Y_Width = X_Width;\r
+                               Center  = 1 + X_Width / 2;\r
+                               S_Width = random_int (X_Width);\r
+\r
+                               for (y = 1; y <= Y_Width; y++)\r
+                               {\r
+                                       for (x = 1; x <= X_Width; x++)\r
+                                       {\r
+                                               z = int_sqrt(Center-x, Center-y);\r
+                                               if ( (z < Center) && (z >= S_Width) )\r
+                                               {\r
+                                                       Grid[x][y] = 150 + Color * 2 + z * 3;\r
+                                               }\r
+                                       }\r
+                               }\r
+\r
+\r
+                               break;\r
+                       }\r
+\r
+                       default:\r
+\r
+                       {\r
+                               error_out (Error1);\r
+                               break;\r
+\r
+                       }\r
+\r
+               }\r
+\r
+               z = 0;\r
+               for (y = 1; y <= Y_Width; y++)\r
+               {\r
+                       for (x = 1; x <= X_Width; x++)\r
+                       {\r
+                               Img[Shape].Image[z] = Grid[x][y];\r
+                               z++;\r
+                       }\r
+               }\r
+\r
+               Img[Shape].X_Width = X_Width;\r
+               Img[Shape].Y_Width = Y_Width;\r
+\r
+       }\r
+\r
+       return;\r
+}\r
+\r
+\r
+       /* Quickie Psuedo Integer Square Root Routine */\r
+\r
+\r
+int int_sqrt ( int x, int y )\r
+{\r
+\r
+int    Sqr_Table[12] = {1, 4, 9, 6, 25, 36, 49, 64, 81, 100, 121, 144};\r
+\r
+int    r, d;\r
+\r
+       d = (x * x) + (y * y);\r
+       r = 0;\r
+\r
+       while ( d >= Sqr_Table[r] )\r
+       {\r
+               r++;\r
+       }\r
+\r
+       return (r);\r
+\r
+}\r
+\r
+\r
+       /* The Bit Sprite Demo */\r
+\r
+\r
+void page_demo ()\r
+{\r
+\r
+char   *Error1 = "Failure during SET_VGA_MODEX (0, 320, 200, 2) call";\r
+\r
+int            Last_Objects[2], Visible_Objects;\r
+\r
+int            Screen_X = 384;\r
+int            Screen_Y = 224;\r
+\r
+int            x, y, z;\r
+int            c, dc;\r
+int            x1, y1, x2, y2;\r
+\r
+int            Sprite_X, Sprite_Y;\r
+int            Current_Page;\r
+int            New_X, New_Y;\r
+\r
+int            View_X, View_Y, View_Max, View_Cnt, View_XD, View_YD;\r
+int            Set_Color, Prev_Color, S_Dir, P_Dir;\r
+\r
+int            Demo_Running = True;\r
+int            redo, code;\r
+\r
+int pee;\r
+pee = set_vga_modex(Mode_320x200, Screen_X, Screen_Y, 3);\r
+       if ( pee > 0)\r
+       {\r
+               set_video_mode (3);\r
+               dos_print (Error1);\r
+               fprintf(stdout, "return value is %d\n", pee);\r
+               //error_out (Error1);\r
+               exit (EXIT_SUCCESS);\r
+       }\r
+\r
+       set_active_page (0);\r
+       clear_vga_screen (c_BLACK);\r
+\r
+       print_str ("This is a Test of the Following Functions:", 99, 10, 9, c_bWHITE, c_BLACK);\r
+\r
+       draw_line (10, 18, 350, 18, c_YELLOW);\r
+       print_str ("SET_ACTIVE_PAGE", 99, 10, 20, c_bBLUE, c_BLACK);\r
+       print_str ("SET_DISPLAY_PAGE", 99, 10, 30, c_GREEN, c_BLACK);\r
+       print_str ("SET_DAC_REGISTER", 99, 10, 40, c_RED, c_BLACK);\r
+       print_str ("CLEAR_VGA_SCREEN", 99, 10, 50, c_CYAN, c_BLACK);\r
+\r
+       print_str ("TDRAW_BITMAP", 99, 10, 60, c_PURPLE, c_BLACK);\r
+       print_str ("COPY_PAGE", 99, 10, 70, c_GREEN, c_BLACK);\r
+       print_str ("COPY_BITMAP", 99, 10, 80, c_CYAN, c_BLACK);\r
+\r
+       print_str ("GPRINTC", 99, 10, 90, c_BLUE, c_BLACK);\r
+       print_str ("TGPRINTC", 99, 10, 100, c_GREEN, c_BLACK);\r
+       print_str ("SET_WINDOW", 99, 10, 110, c_RED, c_BLACK);\r
+\r
+       print_str ("VIRTUAL SCREEN SIZES", 20, 190, 20, c_bBLUE, c_BLACK);\r
+       print_str ("    SMOOTH SCROLLING", 20, 190, 30, c_GREEN, c_BLACK);\r
+       print_str ("    SPRITE ANIMATION", 20, 190, 40, c_CYAN, c_BLACK);\r
+       print_str ("       PAGE FLIPPING", 20, 190, 50, c_RED, c_BLACK);\r
+       print_str ("       COLOR CYCLING", 20, 190, 60, c_PURPLE, c_BLACK);\r
+\r
+       for (x = 0; x <=60; x++)\r
+       {\r
+               set_dac_register (50 + x, 3 + x, 0, 60 - x);\r
+               set_dac_register (150 + x, 3 + x, 0, 60 - x);\r
+       }\r
+\r
+       c = 0;\r
+       dc = 1;\r
+       for (x = 0; x <= (Screen_X / 2); x++)\r
+       {\r
+               draw_line (Screen_X / 2 - 1, Screen_Y / 4, x, Screen_Y - 1, c + 50);\r
+               draw_line (Screen_X / 2, Screen_Y / 4, Screen_X - x - 1, Screen_Y - 1, c + 50);\r
+               c+= dc;\r
+               if ((c == 0) || (c == 60) ) { dc = -dc;}\r
+       }\r
+\r
+       tprint_str ("Press <ANY KEY> to Continue", 99, 72, 190, c_bWHITE);\r
+       tprint_str ("< > = Faster   < > = Slower", 99, 72, 204, c_bGREEN);\r
+       tprint_str ("< > = Fewer Shapes  < > = More Shapes", 99, 32, 218, c_bCYAN);\r
+\r
+       tgprintc (43, 80, 204, c_YELLOW);\r
+       tgprintc (45, 200, 204, c_YELLOW);\r
+\r
+       tgprintc (25, 40, 218, c_YELLOW);\r
+       tgprintc (24, 200, 218, c_YELLOW);\r
+\r
+       copy_page (0, 1);\r
+       copy_page (0, 2);\r
+\r
+       for (x = 0; x < MAX_SPRITES; x++)\r
+       {\r
+               do {\r
+                       Obj[x].X_Dir = random_int(7) - 3;\r
+                       Obj[x].Y_Dir = random_int(7) - 3;\r
+               } while ( (Obj[x].X_Dir == 0) && (Obj[x].Y_Dir == 0) );\r
+\r
+               Obj[x].Shape = x % MAX_SHAPES;\r
+\r
+               Sprite_X = Img[Obj[x].Shape].X_Width;\r
+               Sprite_Y = Img[Obj[x].Shape].Y_Width;\r
+\r
+               Obj[x].X_pos = 1 + random_int(Screen_X - Sprite_X - 2);\r
+               Obj[x].Y_pos = 1 + random_int(Screen_Y - Sprite_Y - 2);\r
+\r
+               Obj[x].Last_X[0] = Obj[x].X_pos;\r
+               Obj[x].Last_X[1] = Obj[x].X_pos;\r
+               Obj[x].Last_Y[0] = Obj[x].Y_pos;\r
+               Obj[x].Last_Y[1] = Obj[x].Y_pos;\r
+\r
+       }\r
+\r
+       Current_Page = 0;\r
+\r
+       View_X = 0;\r
+       View_Y = 0;\r
+       View_Max = 3;\r
+       View_Cnt = 0;\r
+       View_XD = 1;\r
+       View_YD = 1;\r
+\r
+       Set_Color = 3;\r
+       S_Dir = 1;\r
+       Prev_Color = 0;\r
+       P_Dir = 1;\r
+\r
+       Visible_Objects = MAX_SPRITES / 2;\r
+       Last_Objects[0] = 0;\r
+       Last_Objects[1] = 0;\r
+\r
+       while (Demo_Running)\r
+       {\r
+\r
+               set_active_page (Current_Page);\r
+\r
+                       /* Erase Old Images */\r
+\r
+               for (x = 0; x <= Last_Objects[Current_Page]; x++)\r
+               {\r
+                       z = 2;\r
+                       y = Obj[x].Shape;\r
+                       x1 = Obj[x].Last_X[Current_Page];\r
+                       y1 = Obj[x].Last_Y[Current_Page];\r
+                       x2 = x1 + Img[y].X_Width -1;\r
+                       y2 = y1 + Img[y].Y_Width -1;\r
+\r
+                       x1 = x1 & 0xfffc;\r
+                       x2 = x2 | 0x0003;\r
+\r
+                       copy_bitmap (z, x1, y1, x2, y2, Current_Page, x1, y1);\r
+               }\r
+\r
+                       /* Draw new images */\r
+\r
+               for (x = 0; x <= Visible_Objects; x++)\r
+               {\r
+                       Sprite_X = Img[Obj[x].Shape].X_Width;\r
+                       Sprite_Y = Img[Obj[x].Shape].Y_Width;\r
+\r
+                       /*  Move Sprite */\r
+\r
+                       do\r
+                       {\r
+                               redo = False;\r
+                               New_X = Obj[x].X_pos + Obj[x].X_Dir;\r
+\r
+                               if (( New_X < 0 ) || (New_X + Sprite_X > Screen_X) )\r
+                               {\r
+                                       Obj[x].X_Dir = -Obj[x].X_Dir;\r
+                                       if (random_int(20) == 1)\r
+                                       {\r
+                                               do\r
+                                               {\r
+                                                       Obj[x].X_Dir = random_int(7) - 3;\r
+                                                       Obj[x].Y_Dir = random_int(7) - 3;\r
+                                               } while ( (Obj[x].X_Dir == 0) && (Obj[x].Y_Dir == 0) );\r
+                                               redo = True;\r
+                                       }\r
+                               }\r
+                       } while (redo);\r
+                       Obj[x].X_pos = Obj[x].X_pos + Obj[x].X_Dir;\r
+\r
+\r
+                       do\r
+                       {\r
+                               redo = False;\r
+                               New_Y = Obj[x].Y_pos + Obj[x].Y_Dir;\r
+\r
+                               if ( (New_Y < 0) || (New_Y + Sprite_Y > Screen_Y) )\r
+                               {\r
+                                       Obj[x].Y_Dir = -Obj[x].Y_Dir;\r
+                                       if (random_int(20) == 1)\r
+                                       {\r
+                                               do\r
+                                               {\r
+                                                       Obj[x].X_Dir = random_int(7) - 3;\r
+                                                       Obj[x].Y_Dir = random_int(7) - 3;\r
+                                               } while ( (Obj[x].X_Dir == 0) && (Obj[x].Y_Dir == 0) );\r
+                                               redo = True;\r
+                                       }\r
+                               }\r
+                       } while (redo);\r
+\r
+                       Obj[x].Y_pos = Obj[x].Y_pos + Obj[x].Y_Dir;\r
+\r
+                       /* Draw Sprite */\r
+\r
+                       tdraw_bitmap ((char far*) &Img[Obj[x].Shape], Obj[x].X_pos, Obj[x].Y_pos, Sprite_X, Sprite_Y);\r
+\r
+                       Obj[x].Last_X[Current_Page] = Obj[x].X_pos;\r
+                       Obj[x].Last_Y[Current_Page] = Obj[x].Y_pos;\r
+\r
+               }\r
+\r
+               Last_Objects[Current_Page] = Visible_Objects;\r
+\r
+\r
+               /* Pan Screen Back & Forth */\r
+\r
+               View_Cnt++;\r
+               if (View_Cnt >= View_Max)\r
+               {\r
+                       View_X+= View_XD;\r
+                       if ( (View_X == 0) || (View_X == 39) ) {View_XD = -View_XD;}\r
+                       if (View_XD < 0)\r
+                       {\r
+                               View_Y+= View_YD;\r
+                               if ( (View_Y == 0) || (View_Y == 39) ) {View_YD = -View_YD;}\r
+                       }\r
+\r
+                       set_window (Current_Page, View_X, View_Y);\r
+\r
+                       View_Cnt = 0;\r
+               }\r
+               else\r
+               {\r
+                       set_display_page (Current_Page);\r
+               }\r
+\r
+               /* Cycle Colors */\r
+\r
+               set_dac_register (50 + Prev_Color, 3 + Prev_Color, 0, 60 - Prev_Color);\r
+               set_dac_register (50 + Set_Color, Set_Color, 10, 63 - Set_Color);\r
+\r
+               set_dac_register (150 + Prev_Color, 3 + Prev_Color, 0, 60 - Prev_Color);\r
+               set_dac_register (150 + Set_Color, 63, 63, Set_Color);\r
+\r
+               Set_Color+= S_Dir;\r
+               if ( (Set_Color == 60) || (Set_Color == 0) ) {S_Dir = -S_Dir;}\r
+\r
+               Prev_Color+= P_Dir;\r
+               if ( (Prev_Color == 60) || (Prev_Color == 0) ) {P_Dir = -P_Dir;}\r
+\r
+               /* Check for Keystroke */\r
+\r
+               Current_Page = Current_Page ^ 0x01;\r
+\r
+               code = scan_keyboard ();\r
+\r
+               if (code == Ky_ESC) {Demo_Running = False;}\r
+\r
+               if (code == Ky_Plus)\r
+               {\r
+                       if (View_Max < 12) {View_Max++;}\r
+               }\r
+\r
+               if (code == Ky_Minus)\r
+               {\r
+                       if (View_Max > 1) {View_Max--;}\r
+                       if (View_Cnt >= View_Max) {View_Cnt = 0;}\r
+               }\r
+\r
+               if (code == Ky_Up)\r
+               {\r
+                       if (Visible_Objects < MAX_SPRITES-1) {Visible_Objects++;}\r
+               }\r
+\r
+               if (code == Ky_Down)\r
+               {\r
+                       if (Visible_Objects > 0) {Visible_Objects--;}\r
+               }\r
+\r
+       }\r
+\r
+}\r
diff --git a/src/lib/modex/x_demo.dsk b/src/lib/modex/x_demo.dsk
new file mode 100755 (executable)
index 0000000..5573e71
Binary files /dev/null and b/src/lib/modex/x_demo.dsk differ
similarity index 86%
rename from x-demo.exe
rename to src/lib/modex/x_demo.exe
index b4fee9143d4174b8284b8a72f43c7593c13fc714..75369abaeac5b4ea65201db3e49bc84a54e7aca8 100755 (executable)
Binary files a/x-demo.exe and b/src/lib/modex/x_demo.exe differ
diff --git a/src/lib/modex/x_demo.prj b/src/lib/modex/x_demo.prj
new file mode 100755 (executable)
index 0000000..b3f307e
Binary files /dev/null and b/src/lib/modex/x_demo.prj differ
similarity index 100%
rename from xdemo.smp
rename to x-demo.smp
diff --git a/x_demo.exe b/x_demo.exe
new file mode 100755 (executable)
index 0000000..75369ab
Binary files /dev/null and b/x_demo.exe differ