home *** CD-ROM | disk | FTP | other *** search
Text File | 2013-11-08 | 639.1 KB | 19,837 lines |
- \SAMPCODE
- \SAMPCODE\MOUSE
- \SAMPCODE\MOUSE\LIB
- \SAMPCODE\MOUSE\LIB\EGA
- \SAMPCODE\MOUSE\LIB\EGA\DEMO
- \SAMPCODE\MOUSE\LIB\EGA\DEMO\LMCEGA.C
-
- /*----------------------------------------------------------------------*/
- /* REFERENCE -- Test of cegal() IN lmcega.c */
- /* */
- /* This program tests the function cegal(), which is an interface */
- /* between large model MSC 3.0 (or higher) 'C' programs, and the EGA */
- /* Register Interface. */
- /* */
- /* To create lmcega.exe: */
- /* MSC /AL /Ze /w0 LMCEGA; */
- /* LINK LMCEGA,,,..\EGA; */
- /* or: */
- /* MAKE LMCEGA.MAK */
- /*----------------------------------------------------------------------*/
- #include <stdio.h>
- #include <dos.h>
-
- #define ega(a,b,c,d,e) cegal(a,b,c,d,e)
- #define FALSE 0
- #define NOT !
- #define TRUE NOT FALSE
-
-
- main()
- {
- int ah, bx, cx, dx, es;
- char buf[2];
- char far *ver_fptr;
-
- ah = 0xfa;
- bx = 0;
-
- ega(&ah, &bx, &cx, &dx, &es);
-
- if (!bx)
- {
- printf("\nEGA Driver not found");
- return;
- }
- printf("\nEGA Driver found, version ");
- ver_fptr = (((long) es) << 16) + bx;
- printf("%1d.%2d", *ver_fptr, ver_fptr[1]);
-
- printf("\nRead/Write Range functions (F2, F3) ");
- if (test_range()) printf("PASSED");
- else printf("FAILED");
- printf("\n\n\n");
- }
-
-
- test_range()
- {
- int ah, bx, cx, dx, es;
- int *bxp;
- static char org_buf[2] = {0xAA, 0xAA};
- static char wr_buf[2] = {0xBB, 0xBB};
- static char rd_buf[2] = {0xCC, 0xCC};
- int old_map_mask;
- int old_misc_reg;
-
- /* read the cursor location high and low registers */
-
- ah = 0xF2; /* read range */
- cx = 0x0e00; /* start at reg 14 */
- cx |= 0x0002; /* 2 reg to read */
- dx = 0x0000; /* crt controller */
- es = getds(); /* current data segment */
-
- ega(&ah, org_buf, &cx, &dx, &es);
-
- wr_buf[0] = 0xee;
- wr_buf[1] = 0xff;
-
- ah = 0xF3; /* write range */
- cx = 0x0e02; /* start at e, write 2 */
- dx = 0; /* crt controller */
- es = getds();
-
- ega(&ah, wr_buf, &cx, &dx, &es);
-
- ah = 0xF2; /* read range */
- cx = 0x0e02; /* start at e , read 2 */
- dx = 0;
- es = getds();
-
- ega(&ah, rd_buf, &cx, &dx, &es);
-
- /* restore original values */
-
- ah = 0xF3; /* write range */
- cx = 0x0e02; /* start at e, write 2 */
- dx = 0; /* crt controller */
- es = getds();
- ega(&ah, org_buf, &cx, &dx, &es);
-
- if (rd_buf[0] != wr_buf[0])
- return FALSE;
- if (rd_buf[1] != wr_buf[1])
- return FALSE;
-
- return TRUE;
- }
-
-
- getds()
- /*----------------------------------------------------------------------*/
- /* METHOD -- Returns the current data segment. */
- /*----------------------------------------------------------------------*/
- /* RETURNS -- Current code segment. */
- /*----------------------------------------------------------------------*/
- /* GLOBAL EFFECTS -- none. */
- /*----------------------------------------------------------------------*/
- /* REVISION 1.00 is: Original version. */
- /*----------------------------------------------------------------------*/
- {
- struct SREGS segregs;
-
- segread(&segregs);
- return segregs.ds;
- }
-
- \SAMPCODE\MOUSE\LIB\EGA\DEMO\MMCEGA.C
-
- /*----------------------------------------------------------------------*/
- /* REFERENCE -- Test of cegam() IN mmcega.c */
- /* */
- /* This program tests the function cegam(), which is an interface */
- /* between medium model MSC 3.0 (or higher) 'C' programs, and the EGA */
- /* Register Interface. */
- /* */
- /* To create mmcega.exe: */
- /* MSC /AM MMCEGA; */
- /* LINK MMCEGA,,,..\EGA */
- /* or: */
- /* MAKE MMCEGA.MAK */
- /*----------------------------------------------------------------------*/
- #include <stdio.h>
- #include <dos.h>
-
- #define ega(a,b,c,d,e) cegam(a,b,c,d,e)
- #define FALSE 0
- #define NOT !
- #define TRUE NOT FALSE
-
-
- main()
- {
- int ah, bx, cx, dx, es;
- char buf[2];
-
- ah = 0xfa;
- bx = 0;
-
- ega(&ah, &bx, &cx, &dx, &es);
-
- if (!bx)
- {
- printf("\nEGA Driver not found");
- return;
- }
- printf("\nEGA Driver found, version ");
- movedata(es, bx, getds(), buf, 2);
-
- printf("%1d.%2d", buf[0], buf[1]);
-
- printf("\nRead/Write Range functions (F2, F3) ");
- if (test_range()) printf("PASSED");
- else printf("FAILED");
- printf("\n\n\n");
- }
-
-
- test_range()
- {
- int ah, bx, cx, dx, es;
- int *bxp;
- static char org_buf[2] = {0xAA, 0xAA};
- static char wr_buf[2] = {0xBB, 0xBB};
- static char rd_buf[2] = {0xCC, 0xCC};
- int old_map_mask;
- int old_misc_reg;
-
- /* read the cursor location high and low registers */
-
- ah = 0xF2; /* read range */
- cx = 0x0e00; /* start at reg 14 */
- cx |= 0x0002; /* 2 reg to read */
- dx = 0x0000; /* crt controller */
- es = getds(); /* current data segment */
-
- ega(&ah, org_buf, &cx, &dx, &es);
-
- wr_buf[0] = 0xee;
- wr_buf[1] = 0xff;
-
- ah = 0xF3; /* write range */
- cx = 0x0e02; /* start at e, write 2 */
- dx = 0; /* crt controller */
- es = getds();
-
- ega(&ah, wr_buf, &cx, &dx, &es);
-
- ah = 0xF2; /* read range */
- cx = 0x0e02; /* start at e , read 2 */
- dx = 0;
- es = getds();
-
- ega(&ah, rd_buf, &cx, &dx, &es);
-
- /* restore original values */
-
- ah = 0xF3; /* write range */
- cx = 0x0e02; /* start at e, write 2 */
- dx = 0; /* crt controller */
- es = getds();
- ega(&ah, org_buf, &cx, &dx, &es);
-
- if (rd_buf[0] != wr_buf[0])
- return FALSE;
- if (rd_buf[1] != wr_buf[1])
- return FALSE;
-
- return TRUE;
- }
-
-
- getds()
- /*----------------------------------------------------------------------*/
- /* METHOD -- Returns the current data segment. */
- /*----------------------------------------------------------------------*/
- /* RETURNS -- Current code segment. */
- /*----------------------------------------------------------------------*/
- /* GLOBAL EFFECTS -- none. */
- /*----------------------------------------------------------------------*/
- /* REVISION 1.00 is: Original version. */
- /*----------------------------------------------------------------------*/
- {
- struct SREGS segregs;
-
- segread(&segregs);
- return segregs.ds;
- }
-
- \SAMPCODE\MOUSE\LIB\EGA\DEMO\SMCEGA.C
-
- /*----------------------------------------------------------------------*/
- /* REFERENCE -- Test of cegas() IN smcega.c */
- /* */
- /* This program tests the function cegas(), which is an interface */
- /* between small model MSC 3.0 (or higher) 'C' programs, and the EGA */
- /* Register Interface. */
- /* */
- /* To create smcega.exe: */
- /* MSC SMCEGA; */
- /* LINK SMCEGA,,,..\EGA; */
- /* or: */
- /* MAKE SMCEGA.MAK */
- /*----------------------------------------------------------------------*/
- #include <stdio.h>
- #include <dos.h>
-
- #define ega(a,b,c,d,e) cegas(a,b,c,d,e)
- #define FALSE 0
- #define NOT !
- #define TRUE NOT FALSE
-
-
- main()
- {
- int ah, bx, cx, dx, es;
- char buf[2];
-
- ah = 0xfa;
- bx = 0;
-
- ega(&ah, &bx, &cx, &dx, &es);
-
- if (!bx)
- {
- printf("\nEGA Driver not found");
- return;
- }
- printf("\nEGA Driver found, version ");
- movedata(es, bx, getds(), buf, 2);
-
- printf("%1d.%2d", buf[0], buf[1]);
-
- printf("\nRead/Write Range functions (F2, F3) ");
- if (test_range()) printf("PASSED");
- else printf("FAILED");
- printf("\n\n\n");
- }
-
-
- test_range()
- {
- int ah, bx, cx, dx, es;
- int *bxp;
- static char org_buf[2] = {0xAA, 0xAA};
- static char wr_buf[2] = {0xBB, 0xBB};
- static char rd_buf[2] = {0xCC, 0xCC};
- int old_map_mask;
- int old_misc_reg;
-
- /* read the cursor location high and low registers */
-
- ah = 0xF2; /* read range */
- cx = 0x0e00; /* start at reg 14 */
- cx |= 0x0002; /* 2 reg to read */
- dx = 0x0000; /* crt controller */
- es = getds(); /* current data segment */
-
- ega(&ah, org_buf, &cx, &dx, &es);
-
- wr_buf[0] = 0xee;
- wr_buf[1] = 0xff;
-
- ah = 0xF3; /* write range */
- cx = 0x0e02; /* start at e, write 2 */
- dx = 0; /* crt controller */
- es = getds();
-
- ega(&ah, wr_buf, &cx, &dx, &es);
-
- ah = 0xF2; /* read range */
- cx = 0x0e02; /* start at e , read 2 */
- dx = 0;
- es = getds();
-
- ega(&ah, rd_buf, &cx, &dx, &es);
-
- /* restore original values */
-
- ah = 0xF3; /* write range */
- cx = 0x0e02; /* start at e, write 2 */
- dx = 0; /* crt controller */
- es = getds();
- ega(&ah, org_buf, &cx, &dx, &es);
-
- if (rd_buf[0] != wr_buf[0])
- return FALSE;
- if (rd_buf[1] != wr_buf[1])
- return FALSE;
-
- return TRUE;
- }
-
-
- getds()
- /*----------------------------------------------------------------------*/
- /* METHOD -- Returns the current data segment. */
- /*----------------------------------------------------------------------*/
- /* RETURNS -- Current code segment. */
- /*----------------------------------------------------------------------*/
- /* GLOBAL EFFECTS -- none. */
- /*----------------------------------------------------------------------*/
- /* REVISION 1.00 is: Original version. */
- /*----------------------------------------------------------------------*/
- {
- struct SREGS segregs;
-
- segread(&segregs);
- return segregs.ds;
- }
-
- \SAMPCODE\MOUSE\LIB\EGA\DEMO\QBEGA.BAS
-
- '
- ' Test of function ega() and egas() in ega.lib. Tests all of the parameters
- ' passed to these two functions.
- '
- ' To make qbega.exe: QB QBEGA;
- ' LINK QBEGA,,,EGA;
- '
- '
-
- ' Interrogate the driver, get the version number.
- '
- '
- e1% = &h00fa
- e2% = 0
- e3% = 0
- e4% = 0
- e5% = 0
-
- call ega(e1%, e2%, e3%, e4%, e5%)
-
- if (e2% <> 0) then 100
- print "Mouse Driver not found"
- end
- 100 print "Mouse Driver found, version ";
- def seg = e5%
- majver = peek(e2%)
- minver = peek(e2%+1)
- def seg
- print " = ";
- print using "#";majver;
- print ".";
- print using "##";minver
- print
- def seg
-
-
- ' Test the read and write register range functions F2 and F3. Save old value
- ' write new value, read value, restore original value, if value read was not
- ' the value written, then something is wrong.
- '
-
- print "Read/Write Range functions (F2, F3) ";
-
- nvals = 2
- nints = int (nvals/2) + 1
- start = &h0e
-
- dim orbuf%(1)
- dim rdbuf%(1)
- dim wrbuf%(1)
-
- orbuf%(0) = &haaaa
- rdbuf%(0) = &hbbbb
- wrbuf%(0) = &hcccc
- '
- e1% = &hF2 ' read range
- e3% = start * 256 + nvals ' start reg & num regs
- e4% = 0 ' crt controller
- e5% = 0 ' dummy arg
-
- call ega(e1%, orbuf%(0), e3%, e4%, e5%)
-
- wrbuf%(0) = &heeff
- e1% = &hF3 ' write range
- call ega(e1%, wrbuf%(0), e3%, e4%, e5%)
-
-
- e1% = &hF2 ' read range
- call ega(e1%, rdbuf%(0), e3%, e4%, e5%)
-
- e1% = &hF3 ' write range
- call ega(e1%, orbuf%(0), e3%, e4%, e5%)
-
- if (rdbuf%(0) <> wrbuf%(0)) then print "FAILED" else print "PASSED"
-
-
- '
- ' Now test segment:offset calls
- '
- print
- print
- print "Testing calls with segment:offset, using CALLS and EGAS"
- print
-
- e1% = &h00fa
- e2% = 0
- e3% = 0
- e4% = 0
- e5% = 0
-
- calls egas(e1%, e2%, e3%, e4%, e5%)
-
- if (e2% <> 0) then 200
- print "Mouse Driver not found"
- end
- 200 print "Mouse Driver found, version ";
- def seg = e5%
- majver = peek(e2%)
- minver = peek(e2%+1)
- def seg
- print " = ";
- print using "#";majver;
- print ".";
- print using "##";minver
- print
- def seg
-
- print "Read/Write Range functions (F2, F3) ";
- ' read the cursor location high and low registers
-
-
- nvals = 2
- nints = int (nvals/2) + 1
- start = &h0e
-
- orbuf%(0) = &haaaa
- rdbuf%(0) = &hbbbb
- wrbuf%(0) = &hcccc
- '
- e1% = &hF2 ' read range
- e3% = start * 256 + nvals ' start reg & num regs
- e4% = 0 ' crt controller
- e5% = 0 ' dummy arg
-
- calls egas(e1%, orbuf%(0), e3%, e4%, e5%)
-
- wrbuf%(0) = &heeff
- e1% = &hF3 ' write range
- calls egas(e1%, wrbuf%(0), e3%, e4%, e5%)
-
-
- e1% = &hF2 ' read range
- calls egas(e1%, rdbuf%(0), e3%, e4%, e5%)
-
- e1% = &hF3 ' write range
- calls egas(e1%, orbuf%(0), e3%, e4%, e5%)
-
- if (rdbuf%(0) <> wrbuf%(0)) then print "FAILED" else print "PASSED"
- print
-
- ' Thats all
-
- end
-
- \SAMPCODE\MOUSE\LIB\EGA\DEMO\LMCEGA.MAK
-
- lmcega.obj: lmcega.c
- msc /AL /Ze lmcega;
-
- lmcega.exe: lmcega.obj
- link lmcega,,,..\ega;
-
- \SAMPCODE\MOUSE\LIB\EGA\DEMO\QBEGA.MAK
-
- QBEGA.OBJ: QBEGA.BAS
- QB QBEGA /O;
-
- QBEGA.EXE: QBEGA.OBJ
- LINK QBEGA,,,BCOM20+..\EGA;
-
- \SAMPCODE\MOUSE\LIB\EGA\DEMO\SMCEGA.MAK
-
- smcega.obj: smcega.c
- msc smcega;
-
- smcega.exe: smcega.obj
- link smcega,,,..\ega;
-
- \SAMPCODE\MOUSE\LIB\EGA\EXAMPLES
- \SAMPCODE\MOUSE\LIB\EGA\EXAMPLES\F0EXAMP.ASM
-
- ; The following example saves the contents of the Sequencer Map Mask register
- ; in "myvalue".
-
- myvalue db ?
-
- mov ah, 0f0h ; f0 = read one register
- mov bx, 0002h ; bh = 0
- ; bl = map mask index
- mov dx, 0008h ; dx = sequencer
- int 10h ; get it!
- mov myvalue, bl ; save it!
-
-
- ;---------------------------------------------------------------------
-
-
- ; The following example saves the contents of the Miscellaneous Output
- ; register in "myvalue".
-
- myvalue db ?
-
- mov ah, 0f0h ; f0 = read one register
- mov dx, 0020h ; dx = miscellaneous output register
- int 10h ; get it!
- mov myvalue, bl ; save it!
-
- \SAMPCODE\MOUSE\LIB\EGA\EXAMPLES\F1EXAMP.ASM
-
- ; The following example writes the contents of "myvalue" into the CRT
- ; Controller Cursor Start register.
-
- myvalue db 3h
-
- mov ah, 0f1h ; f1 = write one register
- mov bh, myvalue ; bh = data from myvalue
- mov bl, 000ah ; bl = cursor start index
- mov dx, 0000h ; dx = crt controller
- int 10h ; write it!
-
-
- ;---------------------------------------------------------------------
-
-
- ; The following example writes the contents of "myvalue" into the Feature
- ; Control register.
-
- myvalue db 2h
-
- mov ah, 0f1h ; f1 = write one register
- mov bl, myvalue ; bl = data from myvalue
- mov dx, 0028h ; dx = feature control register
- int 10h ; write it!
-
- \SAMPCODE\MOUSE\LIB\EGA\EXAMPLES\F2EXAMP.ASM
-
- ; The following example saves the contents of the Attribute Controller
- ; Palette registers in "paltable".
-
- paltable db 16 dup (?)
-
- mov ax, ds ; assume paltable in data segment
- mov es, ax ; es = data segment
- mov bx, offset paltable ; es:bx = paltable address
- mov ah, 0f2h ; f2 = read register range
- mov cx, 0010h ; ch = start index of 0
- ; cl = 16 registers to read
- mov dx, 0018h ; dx = attribute controller
- int 10h ; read them!
-
- \SAMPCODE\MOUSE\LIB\EGA\EXAMPLES\F3EXAMP.ASM
-
- ; The following example writes the contents of "cursloc" into the CRT
- ; Controller Cursor Location High and Cursor Location Low registers.
-
- cursloc db 01h, 00h
-
- mov ax, ds ; assume cursloc in data segment
- mov es, ax ; es = data segment
- mov bx, offset cursloc ; es:bx = cursloc address
- mov ah, 0f3h ; f2 = write register range
- mov cx, 0e02h ; ch = start index of 14
- ; cl = 2 registers to write
- mov dx, 0000h ; dx = crt controller
- int 10h ; write them!
-
- \SAMPCODE\MOUSE\LIB\EGA\EXAMPLES\F4EXAMP.ASM
-
- ; The following example saves the contents of the Miscellaneous Output
- ; register, Sequencer Memory Mode register, and CRT Controller Mode Control
- ; register in "results".
-
- outvals dw 0020h ; miscellaneous output register
- db 0 ; 0 for single registers
- db ? ; returned value
-
- dw 0008h ; sequencer
- db 04h ; memory mode register index
- db ? ; returned value
-
- dw 0000h ; crt controller
- db 17h ; mode control register index
- db ? ; returned value
-
- results db 3 dup (?)
-
- mov ax, ds ; assume outvals in data segment
- mov es, ax ; es = data segment
- mov bx, offset outvals ; es:bx = outvals address
- mov ah, 0f4h ; f4 = read register set
- mov cx, 3 ; number of entries in outvals
- int 10h ; get values into outvals!
- mov si, 3 ; move the returned values from
- add si, offset outvals ; outvals
- mov di, offset results ; to results
- mov cx, 3 ; 3 values to move
-
- movloop:
- mov ax, [si] ; move one value from outvals
- mov [di], ax ; to results
- add si, 4 ; skip to next source byte
- inc di ; point to next destination byte
- loop movloop
-
- \SAMPCODE\MOUSE\LIB\EGA\EXAMPLES\F5EXAMP.ASM
-
- ; The following example writes the contents of "outvals" to the Miscellaneous
- ; Output register, Sequencer Memory Mode register, and CRT Controller Mode
- ; Control register.
-
- outvals dw 0020h ; miscellaneous output register
- db 0 ; 0 for single registers
- db 0a7h ; output value
-
- dw 0008h ; sequencer
- db 04h ; memory mode register index
- db 03h ; output value
-
- dw 0000h ; crt controller
- db 17h ; mode control register index
- db 0a3h ; output value
-
- mov ax, ds ; assume outvals in data segment
- mov es, ax ; es = data segment
- mov bx, offset outvals ; es:bx = outvals address
- mov ah, 0f5h ; f5 = write register set
- mov cx, 3 ; number of entries in outvals
- int 10h ; write the registers!
-
- \SAMPCODE\MOUSE\LIB\EGA\EXAMPLES\F6EXAMP.ASM
-
- ; The following example restores the default settings of the EGA registers.
-
- mov ah, 0f6h ; f6 = revert to default registers
- int 10h ; do it now!
-
- \SAMPCODE\MOUSE\LIB\EGA\EXAMPLES\F7EXAMP.ASM
-
- ; The following example defnes default values for the Attribute Controller.
-
- attrdflt db 00h, 01h, 02h, 03h, 04h, 05h, 06h, 07h
- db 10h, 11h, 12h, 13h, 14h, 15h, 16h, 17h
- db 08h, 00h, 0fh, 00h
-
- mov ax, ds ; assume attrdflt in data segment
- mov es, ax ; es = data segment
- mov bx, offset attrdflt ; es:bx = attrdflt address
- mov ah, 0f7h ; f7 = define default register table
- mov dx, 0018h ; dx = attribute controller
- int 10h ; do it!
-
-
- ;---------------------------------------------------------------------------
-
-
- ; The following example defines a default value for the Feature Control
- ; register.
-
- featdflt db 00h
-
- mov ax, ds ; assume featdflt in data segment
- mov es, ax ; es = data segment
- mov bx, offset attrdflt ; es:bx = featdflt address
- mov ah, 0f7h ; f7 = define default register table
- mov dx, 0028h ; dx = feature control register
- int 10h ; do it!
-
- \SAMPCODE\MOUSE\LIB\EGA\EXAMPLES\FAEXAMP.ASM
-
- ; The following example interrogates the mouse driver and displays the
- ; results.
-
- gotmsg db "mouse driver found", 0dh, 0ah, 24h
- nopmsg db "mouse drive not found", 0dh, 0ah, 24h
- revmsg db "revision $"
- crlf db 0dh, 0ah, 24h
-
- ten db 10
-
- mov bx, 0 ; must be 0 for this call
- mov ah, 0fah ; fa = interrogate driver
- int 10h ; interrogate!
- or bx, bx ; bx = 0 ?
- jnz found ; branch if driver present
- mov dx, offset nopmsg ; assume nopmsg in data segment
- mov ah, 09h ; 9 = print string
- int 21h ; output not found message
- jmp continue ; that's all for now
-
- found: mov dx, offset gotmsg ; assume gotmsg in data segment
- mov ah, 09h ; 9 = print string
- int 21h ; output found message
- mov dx, offset revmsg ; assume revmsg in data segment
- mov ah, 09h ; 9 = print string
- int 21h ; output "revision"
- mov dl, es:[bx] ; dl = major release number
- add dl, "0" ; convert to ascii
- mov ah, 2 ; 2 = display character
- int 21h ; output major release number
- mov dl, "." ; dl = "."
- mov ah, 2 ; 2 = display character
- int 21h ; output a period
- mov al, es:[bx+1] ; al = minor release number
- xor ah, ah ; ah = 0
- idiv ten ; al = 10ths, ah = 100ths
- mov bx, ax ; save ax in bx
- mov dl, al ; dl = 10ths
- add dl, "0" ; convert to ascii
- mov ah, 2 ; 2 = display character
- int 21h ; output minor release 10ths
- mov dl, bh ; dl = 100ths
- add dl, "0" ; convert to ascii
- mov ah, 2 ; 2 = display character
- int 21h ; output minor release 100ths
- mov dx, offset crlf ; assume crlf in data segment
- mov ah, 09h ; 9 = print string
- int 21h ; output end of line
-
- continue: ; the end
-
- \SAMPCODE\MOUSE\LIB\MOUSE
- \SAMPCODE\MOUSE\LIB\MOUSE\DEMO
- \SAMPCODE\MOUSE\LIB\MOUSE\DEMO\CMCMOUSE.C
-
- /*----------------------------------------------------------------------*/
- /* REFERENCE -- Compact model mouse drive interface test IN cmcmouse.c */
- /* */
- /* To create cmcmouse.exe: */
- /* MSC CMCMOUSE; */
- /* LINK CMCMOUSE+SUBS,,,..\MOUSE */
- /* or: */
- /* MAKE CMCMOUSE.MAK */
- /* */
- /*----------------------------------------------------------------------*/
- #include <stdio.h>
- #include <dos.h>
-
- #define mouse(a, b, c, d) cmousec(a, b, c, d)
-
- #define M_RESET 0
- #define M_SHOW_CURS 1
- #define M_HIDE_CURS 2
- #define M_GET_STATUS 3
- #define M_SET_CURS 4
- #define M_GET_PRESS 5
- #define M_GET_REL 6
- #define M_SET_MAX_POS 7
- #define M_SET_MIN_POS 8
- #define M_SET_G_CURS 9
- #define M_SET_T_CURS 10
- #define M_READ_COUNT 11
- #define M_USER_SUB 12
- #define M_LPEN_ON 13
- #define M_LPEN_OFF 14
- #define M_MICK_2_PIX 15
- #define M_COND_OFF 16
- #define M_D_SPEED 19
-
- #define XMAX 640
- #define YMAX 200
-
-
- main()
- {
- int m1, m2, m3, m4, m5;
- int t, b, l, r;
- int bounds[4];
- int *bptr=bounds;
-
- cls();
- chkdrv();
-
- m1 = M_RESET;
- mouse(&m1, &m2, &m3, &m4);
- if (m1)
- {
- printf("\nMouse driver installed, %d button mouse", m2);
- }
- else
- {
- printf("\nMouse driver not installed, exiting.");
- return;
- }
-
- test_graphics_cursor();
-
- m1 = M_SET_CURS;
- m3 = XMAX;
- m4 = YMAX/2;
- mouse(&m1, &m2, &m3, &m4);
-
- m1 = M_SHOW_CURS;
- mouse(&m1, &m2, &m3, &m4);
-
- printf("\nCursor should appear at end of middle line (press a key)...");
- getch();
-
- t = 0; b = YMAX; l = 0; r = XMAX;
- do
- {
- circle(t, b, l, r);
- t += 8;
- b -= 8;
- l += 8;
- r -= 8;
- }
- while (t <= b);
-
- m1 = M_HIDE_CURS;
- mouse(&m1, &m2, &m3, &m4);
- cls();
- m1 = M_SHOW_CURS;
- mouse(&m1, &m2, &m3, &m4);
-
- printf("+----------------------------------------------------+\n");
- printf("| Test of conditional off function call. Move the |\n");
- printf("| cursor around, and verify that it disappears in |\n");
- printf("| the area bounded by the dashed line. |\n");
- printf("| |\n");
- printf("| Press any key to redisplay the cursor. |\n");
- printf("| |\n");
- printf("| Press ESCape when verified. |\n");
- printf("+----------------------------------------------------+\n");
-
- do
- {
- m1 = M_SET_CURS;
- m3 = XMAX;
- m4 = YMAX/2;
- mouse(&m1, &m2, &m3, &m4);
-
- m1 = M_SHOW_CURS;
- mouse(&m1, &m2, &m3, &m4);
-
- m1 = M_COND_OFF;
- bounds[0] = 0;
- bounds[1] = 0;
- bounds[2] = 424;
- bounds[3] = 64;
- mouse(&m1, &m2, &m3, &bptr);
- } while (getch() != 0x1B);
-
- m1 = M_SHOW_CURS;
- mouse(&m1, &m2, &m3, &m4);
-
- read_pos();
-
- printf("\n\n\nPress a key to terminate this program");
- getch();
- m1 = M_RESET;
- mouse(&m1, &m2, &m3, &m4);
- }
-
-
- chkdrv()
- {
- union REGS inregs, outregs;
- struct SREGS segregs;
- long address;
- unsigned char first_byte;
-
- inregs.x.ax = 0x3533;
- intdosx ( &inregs, &outregs, &segregs );
-
- address = (((long) segregs.es) << 16) + (long) outregs.x.bx;
- first_byte = * (long far *) address;
-
- if ((address == 0) || (first_byte == 0xcf)) {
- printf("Mouse driver NOT installed");
- exit();
- }
- }
-
-
- cls()
- {
- union REGS inregs, outregs;
-
- inregs.x.ax = 0x0600;
- inregs.h.bh = 7;
- inregs.x.cx = 0;
- inregs.x.dx = 0x184f;
- int86(0x10, &inregs, &outregs);
- inregs.x.ax = 0x0200;
- inregs.h.bh = 0;
- inregs.x.dx = 0;
- int86(0x10, &inregs, &outregs);
- }
-
-
- #define VWAIT 100
- #define HWAIT 50
-
- circle (t, b, l, r)
- int t, b, l, r;
- {
- int m1, m2, m3, m4, i;
-
- m1 = M_SET_CURS;
- m4 = t;
-
- for (m3 = l; m3 < r; m3++)
- {
- for (i=0; i < HWAIT; i++);
- mouse(&m1, &m2, &m3, &m4);
- }
-
- for (m4 = t; m4 < b; m4++)
- {
- for (i=0; i < VWAIT; i++);
- mouse(&m1, &m2, &m3, &m4);
- }
-
- for (; m3 >= l; m3--)
- {
- for (i=0; i < HWAIT; i++);
- mouse(&m1, &m2, &m3, &m4);
- }
-
- for (; m4 >= t; m4--)
- {
- for (i=0; i < VWAIT; i++);
- mouse(&m1, &m2, &m3, &m4);
- }
- }
-
-
- read_pos()
- {
- int m1, m2, m3, m4;
-
- m1 = M_HIDE_CURS;
- mouse(&m1, &m2, &m3, &m4);
- cls();
- m1 = M_SHOW_CURS;
- mouse(&m1, &m2, &m3, &m4);
-
- printf("\nMove mouse to the UPPER LEFT corner, RELEASE both buttons");
- printf("\nand then press Enter: ");
- while(getch() != 0x0d)
- ;
- m1 = M_GET_STATUS;
- mouse(&m1, &m2, &m3, &m4);
- if (m2 != 0) printf("\nBUTTON INFO WRONG.");
- if (m3 != 0) printf("\nX VALUE WRONG, EXPECT 0, READ %d", m3);
- if (m4 != 0) printf("\nY VALUE WRONG, EXPECT 0, READ %d", m4);
-
- printf("\nMove mouse to the BOTTOM RIGHT corner, PRESS both buttons");
- printf("\nand then press Enter: ");
- while(getch() != 0x0d)
- ;
- m1 = M_GET_STATUS;
- mouse(&m1, &m2, &m3, &m4);
- if (m2 != 3) printf("\nBUTTON INFO WRONG.");
- if (m3 != 632) printf("\nX VALUE WRONG, EXPECT 632, READ %d", m3);
- if (m4 != 192) printf("\nY VALUE WRONG, EXPECT 192, READ %d", m4);
- }
-
-
- test_graphics_cursor()
- {
- static int cursor[32] =
- {
- /* SCREEN MASK FOR POINTING HAND */
-
- 0xE1FF, 0xE1FF, 0xE1FF, 0xE1FF, 0xE1FF, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
-
- /* CURSOR MASK FOR POINTING HAND */
-
- 0x1E00, 0x1200, 0x1200, 0x1200, 0x1200, 0x13FF, 0x1249, 0x1249,
- 0xF249, 0x9001, 0x9001, 0x9001, 0x8001, 0x8001, 0x8001, 0xFFFF
- };
-
- int *cptr=cursor;
-
- int m1, m2, m3, m4;
-
- video_mode(6); /* 640 X 200 B&W */
-
- m1 = 9;
- m2 = 0;
- m3 = 0;
- mouse(&m1, &m2, &m3, &cptr);
- m1 = 1;
- mouse(&m1, &m2, &m3, &m4);
-
- printf("\ncursor should now be a pointing hand.");
- printf("\nMove around, press Enter when done...");
- getch();
- video_mode(3);
- }
-
-
- video_mode(mode)
- int mode;
- {
- union REGS inregs, outregs;
-
- inregs.h.ah = 0;
- inregs.h.al = mode;
- int86(0x10, &inregs, &outregs);
- }
-
- \SAMPCODE\MOUSE\LIB\MOUSE\DEMO\LMCMOUSE.C
-
- /*----------------------------------------------------------------------*/
- /* REFERENCE -- Large model mouse drive interface test IN lmcmouse.c */
- /* */
- /* To create lmcmouse.exe: */
- /* MSC LMCMOUSE; */
- /* LINK LMCMOUSE+SUBS,,,..\MOUSE */
- /* or: */
- /* MAKE LMCMOUSE.MAK */
- /* */
- /*----------------------------------------------------------------------*/
- #include <stdio.h>
- #include <dos.h>
-
- #define mouse(a, b, c, d) cmousel(a, b, c, d)
-
- #define M_RESET 0
- #define M_SHOW_CURS 1
- #define M_HIDE_CURS 2
- #define M_GET_STATUS 3
- #define M_SET_CURS 4
- #define M_GET_PRESS 5
- #define M_GET_REL 6
- #define M_SET_MAX_POS 7
- #define M_SET_MIN_POS 8
- #define M_SET_G_CURS 9
- #define M_SET_T_CURS 10
- #define M_READ_COUNT 11
- #define M_USER_SUB 12
- #define M_LPEN_ON 13
- #define M_LPEN_OFF 14
- #define M_MICK_2_PIX 15
- #define M_COND_OFF 16
- #define M_D_SPEED 19
-
- #define XMAX 640
- #define YMAX 200
-
-
- main()
- {
- int m1, m2, m3, m4, m5;
- int t, b, l, r;
- int bounds[4];
- int *bptr=bounds;
-
- cls();
- chkdrv();
-
- m1 = M_RESET;
- mouse(&m1, &m2, &m3, &m4);
- if (m1)
- {
- printf("\nMouse driver installed, %d button mouse", m2);
- }
- else
- {
- printf("\nMouse driver not installed, exiting.");
- return;
- }
-
- test_graphics_cursor();
-
- m1 = M_SET_CURS;
- m3 = XMAX;
- m4 = YMAX/2;
- mouse(&m1, &m2, &m3, &m4);
-
- m1 = M_SHOW_CURS;
- mouse(&m1, &m2, &m3, &m4);
-
- printf("\nCursor should appear at end of middle line (press a key)...");
- getch();
-
- t = 0; b = YMAX; l = 0; r = XMAX;
- do
- {
- circle(t, b, l, r);
- t += 8;
- b -= 8;
- l += 8;
- r -= 8;
- }
- while (t <= b);
-
- m1 = M_HIDE_CURS;
- mouse(&m1, &m2, &m3, &m4);
- cls();
- m1 = M_SHOW_CURS;
- mouse(&m1, &m2, &m3, &m4);
-
- printf("+----------------------------------------------------+\n");
- printf("| Test of conditional off function call. Move the |\n");
- printf("| cursor around, and verify that it disappears in |\n");
- printf("| the area bounded by the dashed line. |\n");
- printf("| |\n");
- printf("| Press any key to redisplay the cursor. |\n");
- printf("| |\n");
- printf("| Press ESCape when verified. |\n");
- printf("+----------------------------------------------------+\n");
-
- do
- {
- m1 = M_SET_CURS;
- m3 = XMAX;
- m4 = YMAX/2;
- mouse(&m1, &m2, &m3, &m4);
-
- m1 = M_SHOW_CURS;
- mouse(&m1, &m2, &m3, &m4);
-
- m1 = M_COND_OFF;
- bounds[0] = 0;
- bounds[1] = 0;
- bounds[2] = 424;
- bounds[3] = 64;
- mouse(&m1, &m2, &m3, &bptr);
- } while (getch() != 0x1B);
-
- m1 = M_SHOW_CURS;
- mouse(&m1, &m2, &m3, &m4);
-
- read_pos();
-
- printf("\n\n\nPress a key to terminate this program");
- getch();
- m1 = M_RESET;
- mouse(&m1, &m2, &m3, &m4);
- }
-
-
- chkdrv()
- {
- union REGS inregs, outregs;
- struct SREGS segregs;
- long address;
- unsigned char first_byte;
-
- inregs.x.ax = 0x3533;
- intdosx ( &inregs, &outregs, &segregs );
-
- address = (((long) segregs.es) << 16) + (long) outregs.x.bx;
- first_byte = * (long far *) address;
-
- if ((address == 0) || (first_byte == 0xcf)) {
- printf("Mouse driver NOT installed");
- exit();
- }
- }
-
-
- cls()
- {
- union REGS inregs, outregs;
-
- inregs.x.ax = 0x0600;
- inregs.h.bh = 7;
- inregs.x.cx = 0;
- inregs.x.dx = 0x184f;
- int86(0x10, &inregs, &outregs);
- inregs.x.ax = 0x0200;
- inregs.h.bh = 0;
- inregs.x.dx = 0;
- int86(0x10, &inregs, &outregs);
- }
-
-
- #define VWAIT 100
- #define HWAIT 50
-
- circle (t, b, l, r)
- int t, b, l, r;
- {
- int m1, m2, m3, m4, i;
-
- m1 = M_SET_CURS;
- m4 = t;
-
- for (m3 = l; m3 < r; m3++)
- {
- for (i=0; i < HWAIT; i++);
- mouse(&m1, &m2, &m3, &m4);
- }
-
- for (m4 = t; m4 < b; m4++)
- {
- for (i=0; i < VWAIT; i++);
- mouse(&m1, &m2, &m3, &m4);
- }
-
- for (; m3 >= l; m3--)
- {
- for (i=0; i < HWAIT; i++);
- mouse(&m1, &m2, &m3, &m4);
- }
-
- for (; m4 >= t; m4--)
- {
- for (i=0; i < VWAIT; i++);
- mouse(&m1, &m2, &m3, &m4);
- }
- }
-
-
- read_pos()
- {
- int m1, m2, m3, m4;
-
- m1 = M_HIDE_CURS;
- mouse(&m1, &m2, &m3, &m4);
- cls();
- m1 = M_SHOW_CURS;
- mouse(&m1, &m2, &m3, &m4);
-
- printf("\nMove mouse to the UPPER LEFT corner, RELEASE both buttons");
- printf("\nand then press Enter: ");
- while(getch() != 0x0d)
- ;
- m1 = M_GET_STATUS;
- mouse(&m1, &m2, &m3, &m4);
- if (m2 != 0) printf("\nBUTTON INFO WRONG.");
- if (m3 != 0) printf("\nX VALUE WRONG, EXPECT 0, READ %d", m3);
- if (m4 != 0) printf("\nY VALUE WRONG, EXPECT 0, READ %d", m4);
-
- printf("\nMove mouse to the BOTTOM RIGHT corner, PRESS both buttons");
- printf("\nand then press Enter: ");
- while(getch() != 0x0d)
- ;
- m1 = M_GET_STATUS;
- mouse(&m1, &m2, &m3, &m4);
- if (m2 != 3) printf("\nBUTTON INFO WRONG.");
- if (m3 != 632) printf("\nX VALUE WRONG, EXPECT 632, READ %d", m3);
- if (m4 != 192) printf("\nY VALUE WRONG, EXPECT 192, READ %d", m4);
- }
-
-
- test_graphics_cursor()
- {
- static int cursor[32] =
- {
- /* SCREEN MASK FOR POINTING HAND */
-
- 0xE1FF, 0xE1FF, 0xE1FF, 0xE1FF, 0xE1FF, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
-
- /* CURSOR MASK FOR POINTING HAND */
-
- 0x1E00, 0x1200, 0x1200, 0x1200, 0x1200, 0x13FF, 0x1249, 0x1249,
- 0xF249, 0x9001, 0x9001, 0x9001, 0x8001, 0x8001, 0x8001, 0xFFFF
- };
-
- int *cptr=cursor;
-
- int m1, m2, m3, m4;
-
- video_mode(6); /* 640 X 200 B&W */
-
- m1 = 9;
- m2 = 0;
- m3 = 0;
- mouse(&m1, &m2, &m3, &cptr);
- m1 = 1;
- mouse(&m1, &m2, &m3, &m4);
-
- printf("\ncursor should now be a pointing hand.");
- printf("\nMove around, press Enter when done...");
- getch();
- video_mode(3);
- }
-
-
- video_mode(mode)
- int mode;
- {
- union REGS inregs, outregs;
-
- inregs.h.ah = 0;
- inregs.h.al = mode;
- int86(0x10, &inregs, &outregs);
- }
-
- \SAMPCODE\MOUSE\LIB\MOUSE\DEMO\MMCMOUSE.C
-
- /*----------------------------------------------------------------------*/
- /* REFERENCE -- Medium model mouse drive interface test IN mmcmouse.c */
- /* */
- /* To create mmcmouse.exe: */
- /* MSC MMCMOUSE; */
- /* LINK MMCMOUSE+SUBS,,,..\MOUSE */
- /* or: */
- /* MAKE MMCMOUSE.MAK */
- /* */
- /*----------------------------------------------------------------------*/
- #include <stdio.h>
- #include <dos.h>
-
- #define mouse(a, b, c, d) cmousem(a, b, c, d)
-
- #define M_RESET 0
- #define M_SHOW_CURS 1
- #define M_HIDE_CURS 2
- #define M_GET_STATUS 3
- #define M_SET_CURS 4
- #define M_GET_PRESS 5
- #define M_GET_REL 6
- #define M_SET_MAX_POS 7
- #define M_SET_MIN_POS 8
- #define M_SET_G_CURS 9
- #define M_SET_T_CURS 10
- #define M_READ_COUNT 11
- #define M_USER_SUB 12
- #define M_LPEN_ON 13
- #define M_LPEN_OFF 14
- #define M_MICK_2_PIX 15
- #define M_COND_OFF 16
- #define M_D_SPEED 19
-
- #define XMAX 640
- #define YMAX 200
-
-
- main()
- {
- int m1, m2, m3, m4, m5;
- int t, b, l, r;
- int bounds[4];
- int *bptr=bounds;
-
- cls();
- chkdrv();
-
- m1 = M_RESET;
- mouse(&m1, &m2, &m3, &m4);
- if (m1)
- {
- printf("\nMouse driver installed, %d button mouse", m2);
- }
- else
- {
- printf("\nMouse driver not installed, exiting.");
- return;
- }
-
- test_graphics_cursor();
-
- m1 = M_SET_CURS;
- m3 = XMAX;
- m4 = YMAX/2;
- mouse(&m1, &m2, &m3, &m4);
-
- m1 = M_SHOW_CURS;
- mouse(&m1, &m2, &m3, &m4);
-
- printf("\nCursor should appear at end of middle line (press a key)...");
- getch();
-
- t = 0; b = YMAX; l = 0; r = XMAX;
- do
- {
- circle(t, b, l, r);
- t += 8;
- b -= 8;
- l += 8;
- r -= 8;
- }
- while (t <= b);
-
- m1 = M_HIDE_CURS;
- mouse(&m1, &m2, &m3, &m4);
- cls();
- m1 = M_SHOW_CURS;
- mouse(&m1, &m2, &m3, &m4);
-
- printf("+----------------------------------------------------+\n");
- printf("| Test of conditional off function call. Move the |\n");
- printf("| cursor around, and verify that it disappears in |\n");
- printf("| the area bounded by the dashed line. |\n");
- printf("| |\n");
- printf("| Press any key to redisplay the cursor. |\n");
- printf("| |\n");
- printf("| Press ESCape when verified. |\n");
- printf("+----------------------------------------------------+\n");
-
- do
- {
- m1 = M_SET_CURS;
- m3 = XMAX;
- m4 = YMAX/2;
- mouse(&m1, &m2, &m3, &m4);
-
- m1 = M_SHOW_CURS;
- mouse(&m1, &m2, &m3, &m4);
-
- m1 = M_COND_OFF;
- bounds[0] = 0;
- bounds[1] = 0;
- bounds[2] = 424;
- bounds[3] = 64;
- mouse(&m1, &m2, &m3, &bptr);
- } while (getch() != 0x1B);
-
- m1 = M_SHOW_CURS;
- mouse(&m1, &m2, &m3, &m4);
-
- read_pos();
-
- printf("\n\n\nPress a key to terminate this program");
- getch();
- m1 = M_RESET;
- mouse(&m1, &m2, &m3, &m4);
- }
-
-
- chkdrv()
- {
- union REGS inregs, outregs;
- struct SREGS segregs;
- long address;
- unsigned char first_byte;
-
- inregs.x.ax = 0x3533;
- intdosx ( &inregs, &outregs, &segregs );
-
- address = (((long) segregs.es) << 16) + (long) outregs.x.bx;
- first_byte = * (long far *) address;
-
- if ((address == 0) || (first_byte == 0xcf)) {
- printf("Mouse driver NOT installed");
- exit();
- }
- }
-
-
- cls()
- {
- union REGS inregs, outregs;
-
- inregs.x.ax = 0x0600;
- inregs.h.bh = 7;
- inregs.x.cx = 0;
- inregs.x.dx = 0x184f;
- int86(0x10, &inregs, &outregs);
- inregs.x.ax = 0x0200;
- inregs.h.bh = 0;
- inregs.x.dx = 0;
- int86(0x10, &inregs, &outregs);
- }
-
-
- #define VWAIT 100
- #define HWAIT 50
-
- circle (t, b, l, r)
- int t, b, l, r;
- {
- int m1, m2, m3, m4, i;
-
- m1 = M_SET_CURS;
- m4 = t;
-
- for (m3 = l; m3 < r; m3++)
- {
- for (i=0; i < HWAIT; i++);
- mouse(&m1, &m2, &m3, &m4);
- }
-
- for (m4 = t; m4 < b; m4++)
- {
- for (i=0; i < VWAIT; i++);
- mouse(&m1, &m2, &m3, &m4);
- }
-
- for (; m3 >= l; m3--)
- {
- for (i=0; i < HWAIT; i++);
- mouse(&m1, &m2, &m3, &m4);
- }
-
- for (; m4 >= t; m4--)
- {
- for (i=0; i < VWAIT; i++);
- mouse(&m1, &m2, &m3, &m4);
- }
- }
-
-
- read_pos()
- {
- int m1, m2, m3, m4;
-
- m1 = M_HIDE_CURS;
- mouse(&m1, &m2, &m3, &m4);
- cls();
- m1 = M_SHOW_CURS;
- mouse(&m1, &m2, &m3, &m4);
-
- printf("\nMove mouse to the UPPER LEFT corner, RELEASE both buttons");
- printf("\nand then press Enter: ");
- while(getch() != 0x0d)
- ;
- m1 = M_GET_STATUS;
- mouse(&m1, &m2, &m3, &m4);
- if (m2 != 0) printf("\nBUTTON INFO WRONG.");
- if (m3 != 0) printf("\nX VALUE WRONG, EXPECT 0, READ %d", m3);
- if (m4 != 0) printf("\nY VALUE WRONG, EXPECT 0, READ %d", m4);
-
- printf("\nMove mouse to the BOTTOM RIGHT corner, PRESS both buttons");
- printf("\nand then press Enter: ");
- while(getch() != 0x0d)
- ;
- m1 = M_GET_STATUS;
- mouse(&m1, &m2, &m3, &m4);
- if (m2 != 3) printf("\nBUTTON INFO WRONG.");
- if (m3 != 632) printf("\nX VALUE WRONG, EXPECT 632, READ %d", m3);
- if (m4 != 192) printf("\nY VALUE WRONG, EXPECT 192, READ %d", m4);
- }
-
-
- test_graphics_cursor()
- {
- static int cursor[32] =
- {
- /* SCREEN MASK FOR POINTING HAND */
-
- 0xE1FF, 0xE1FF, 0xE1FF, 0xE1FF, 0xE1FF, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
-
- /* CURSOR MASK FOR POINTING HAND */
-
- 0x1E00, 0x1200, 0x1200, 0x1200, 0x1200, 0x13FF, 0x1249, 0x1249,
- 0xF249, 0x9001, 0x9001, 0x9001, 0x8001, 0x8001, 0x8001, 0xFFFF
- };
-
- int *cptr=cursor;
-
- int m1, m2, m3, m4;
-
- video_mode(6); /* 640 X 200 B&W */
-
- m1 = 9;
- m2 = 0;
- m3 = 0;
- mouse(&m1, &m2, &m3, &cptr);
- m1 = 1;
- mouse(&m1, &m2, &m3, &m4);
-
- printf("\ncursor should now be a pointing hand.");
- printf("\nMove around, press Enter when done...");
- getch();
- video_mode(3);
- }
-
-
- video_mode(mode)
- int mode;
- {
- union REGS inregs, outregs;
-
- inregs.h.ah = 0;
- inregs.h.al = mode;
- int86(0x10, &inregs, &outregs);
- }
-
- \SAMPCODE\MOUSE\LIB\MOUSE\DEMO\SMCMOUSE.C
-
- /*----------------------------------------------------------------------*/
- /* REFERENCE -- Small model mouse drive interface test IN smcmouse.c */
- /* */
- /* To create smcmouse.exe: */
- /* MSC SMCMOUSE; */
- /* LINK SMCMOUSE+SUBS,,,..\MOUSE */
- /* or: */
- /* MAKE SMCMOUSE.MAK */
- /* */
- /*----------------------------------------------------------------------*/
- #include <stdio.h>
- #include <dos.h>
-
- #define mouse(a, b, c, d) cmouses(a, b, c, d)
-
- #define M_RESET 0
- #define M_SHOW_CURS 1
- #define M_HIDE_CURS 2
- #define M_GET_STATUS 3
- #define M_SET_CURS 4
- #define M_GET_PRESS 5
- #define M_GET_REL 6
- #define M_SET_MAX_POS 7
- #define M_SET_MIN_POS 8
- #define M_SET_G_CURS 9
- #define M_SET_T_CURS 10
- #define M_READ_COUNT 11
- #define M_USER_SUB 12
- #define M_LPEN_ON 13
- #define M_LPEN_OFF 14
- #define M_MICK_2_PIX 15
- #define M_COND_OFF 16
- #define M_D_SPEED 19
-
- #define XMAX 640
- #define YMAX 200
-
-
- main()
- {
- int m1, m2, m3, m4, m5;
- int t, b, l, r;
- int bounds[4];
- int *bptr=bounds;
-
- cls();
- chkdrv();
-
- m1 = M_RESET;
- mouse(&m1, &m2, &m3, &m4);
- if (m1)
- {
- printf("\nMouse driver installed, %d button mouse", m2);
- }
- else
- {
- printf("\nMouse driver not installed, exiting.");
- return;
- }
-
- test_graphics_cursor();
-
- m1 = M_SET_CURS;
- m3 = XMAX;
- m4 = YMAX/2;
- mouse(&m1, &m2, &m3, &m4);
-
- m1 = M_SHOW_CURS;
- mouse(&m1, &m2, &m3, &m4);
-
- printf("\nCursor should appear at end of middle line (press a key)...");
- getch();
-
- t = 0; b = YMAX; l = 0; r = XMAX;
- do
- {
- circle(t, b, l, r);
- t += 8;
- b -= 8;
- l += 8;
- r -= 8;
- }
- while (t <= b);
-
- m1 = M_HIDE_CURS;
- mouse(&m1, &m2, &m3, &m4);
- cls();
- m1 = M_SHOW_CURS;
- mouse(&m1, &m2, &m3, &m4);
-
- printf("+----------------------------------------------------+\n");
- printf("| Test of conditional off function call. Move the |\n");
- printf("| cursor around, and verify that it disappears in |\n");
- printf("| the area bounded by the dashed line. |\n");
- printf("| |\n");
- printf("| Press any key to redisplay the cursor. |\n");
- printf("| |\n");
- printf("| Press ESCape when verified. |\n");
- printf("+----------------------------------------------------+\n");
-
- do
- {
- m1 = M_SET_CURS;
- m3 = XMAX;
- m4 = YMAX/2;
- mouse(&m1, &m2, &m3, &m4);
-
- m1 = M_SHOW_CURS;
- mouse(&m1, &m2, &m3, &m4);
-
- m1 = M_COND_OFF;
- bounds[0] = 0;
- bounds[1] = 0;
- bounds[2] = 424;
- bounds[3] = 64;
- mouse(&m1, &m2, &m3, &bptr);
- } while (getch() != 0x1B);
-
- m1 = M_SHOW_CURS;
- mouse(&m1, &m2, &m3, &m4);
-
- read_pos();
-
- printf("\n\n\nPress a key to terminate this program");
- getch();
- m1 = M_RESET;
- mouse(&m1, &m2, &m3, &m4);
- }
-
-
- chkdrv()
- {
- union REGS inregs, outregs;
- struct SREGS segregs;
- long address;
- unsigned char first_byte;
-
- inregs.x.ax = 0x3533;
- intdosx ( &inregs, &outregs, &segregs );
-
- address = (((long) segregs.es) << 16) + (long) outregs.x.bx;
- first_byte = * (long far *) address;
-
- if ((address == 0) || (first_byte == 0xcf)) {
- printf("Mouse driver NOT installed");
- exit();
- }
- }
-
-
- cls()
- {
- union REGS inregs, outregs;
-
- inregs.x.ax = 0x0600;
- inregs.h.bh = 7;
- inregs.x.cx = 0;
- inregs.x.dx = 0x184f;
- int86(0x10, &inregs, &outregs);
- inregs.x.ax = 0x0200;
- inregs.h.bh = 0;
- inregs.x.dx = 0;
- int86(0x10, &inregs, &outregs);
- }
-
-
- #define VWAIT 100
- #define HWAIT 50
-
- circle (t, b, l, r)
- int t, b, l, r;
- {
- int m1, m2, m3, m4, i;
-
- m1 = M_SET_CURS;
- m4 = t;
-
- for (m3 = l; m3 < r; m3++)
- {
- for (i=0; i < HWAIT; i++);
- mouse(&m1, &m2, &m3, &m4);
- }
-
- for (m4 = t; m4 < b; m4++)
- {
- for (i=0; i < VWAIT; i++);
- mouse(&m1, &m2, &m3, &m4);
- }
-
- for (; m3 >= l; m3--)
- {
- for (i=0; i < HWAIT; i++);
- mouse(&m1, &m2, &m3, &m4);
- }
-
- for (; m4 >= t; m4--)
- {
- for (i=0; i < VWAIT; i++);
- mouse(&m1, &m2, &m3, &m4);
- }
- }
-
-
- read_pos()
- {
- int m1, m2, m3, m4;
-
- m1 = M_HIDE_CURS;
- mouse(&m1, &m2, &m3, &m4);
- cls();
- m1 = M_SHOW_CURS;
- mouse(&m1, &m2, &m3, &m4);
-
- printf("\nMove mouse to the UPPER LEFT corner, RELEASE both buttons");
- printf("\nand then press Enter: ");
- while(getch() != 0x0d)
- ;
- m1 = M_GET_STATUS;
- mouse(&m1, &m2, &m3, &m4);
- if (m2 != 0) printf("\nBUTTON INFO WRONG.");
- if (m3 != 0) printf("\nX VALUE WRONG, EXPECT 0, READ %d", m3);
- if (m4 != 0) printf("\nY VALUE WRONG, EXPECT 0, READ %d", m4);
-
- printf("\nMove mouse to the BOTTOM RIGHT corner, PRESS both buttons");
- printf("\nand then press Enter: ");
- while(getch() != 0x0d)
- ;
- m1 = M_GET_STATUS;
- mouse(&m1, &m2, &m3, &m4);
- if (m2 != 3) printf("\nBUTTON INFO WRONG.");
- if (m3 != 632) printf("\nX VALUE WRONG, EXPECT 632, READ %d", m3);
- if (m4 != 192) printf("\nY VALUE WRONG, EXPECT 192, READ %d", m4);
- }
-
-
- test_graphics_cursor()
- {
- static int cursor[32] =
- {
- /* SCREEN MASK FOR POINTING HAND */
-
- 0xE1FF, 0xE1FF, 0xE1FF, 0xE1FF, 0xE1FF, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
-
- /* CURSOR MASK FOR POINTING HAND */
-
- 0x1E00, 0x1200, 0x1200, 0x1200, 0x1200, 0x13FF, 0x1249, 0x1249,
- 0xF249, 0x9001, 0x9001, 0x9001, 0x8001, 0x8001, 0x8001, 0xFFFF
- };
-
- int *cptr=cursor;
-
- int m1, m2, m3, m4;
-
- video_mode(6); /* 640 X 200 B&W */
-
- m1 = 9;
- m2 = 0;
- m3 = 0;
- mouse(&m1, &m2, &m3, &cptr);
- m1 = 1;
- mouse(&m1, &m2, &m3, &m4);
-
- printf("\ncursor should now be a pointing hand.");
- printf("\nMove around, press Enter when done...");
- getch();
- video_mode(3);
- }
-
-
- video_mode(mode)
- int mode;
- {
- union REGS inregs, outregs;
-
- inregs.h.ah = 0;
- inregs.h.al = mode;
- int86(0x10, &inregs, &outregs);
- }
-
- \SAMPCODE\MOUSE\LIB\MOUSE\DEMO\SUBS.ASM
-
- ;
- ;
- ; This is the subroutine for mouse.lib test in FORTRAN
- ; and Pascal examples. Procedure graf sets the screen
- ; video mode into hi-res graphics.
- ;
- ;
- ;
- mdata segment byte public 'data'
-
- msg db "Mouse Driver NOT installed","$"
-
- mdata ends
-
-
-
-
- mcode segment para public 'CODE'
- assume cs:mcode
- ;
- public graf
- ;
- graf proc far
- push bp
- mov ax, 06h ;change to graphics
- int 10h ;mode by calling
- pop bp ;int 10 service
- ret
- graf endp
- ;
- ;
- ;
- public chkdrv
- ;
- chkdrv proc far
- push bp
- push es
-
- mov ax, 03533h ;get int 33h
- int 21h ;by calling int 21
- mov ax, es ;check segment and
- or ax, bx ;offset of int 33
- jnz back ;vector if 0 or IRET
- mov bl, es:[bx] ;mouse driver not installed
- cmp bl, 0cfh
- jne back ;exit
-
- mov ax,seg mdata ;set up DS to
- mov ds,ax ;point to data seg
- mov dx, offset msg ;get message
- mov ah, 09h ;out to screen
- int 21h
- pop es
- pop bp
- mov ax,04c00h ;function code for
- int 21h ;end process
-
- back:
- pop es
- pop bp
- ret
- chkdrv endp
- ;
- mcode ends
- end
-
- \SAMPCODE\MOUSE\LIB\MOUSE\DEMO\PDEMO.PAS
-
- program mtest(output);
-
- procedure mouses(vars m1,m2,m3,m4:word);extern;
- procedure chkdrv;extern;
- procedure graf;extern;
-
- var
- m1,m2,m3,m4:word;
- Cursor : array [0..31]of word;
- bound : array [0..3] of word;
- ptradd : array [1..2] of word;
- i, j : integer;
-
- begin
-
- for i := 0 to 15 do cursor[i] := 16#ffff;
- Cursor[16] := 16#8000;
- Cursor[17] := 16#E000;
- Cursor[18] := 16#F800;
- Cursor[19] := 16#FE00; {initialize curosr array}
- Cursor[20] := 16#D800;
- Cursor[21] := 16#0C00;
- Cursor[22] := 16#0600;
- Cursor[23] := 16#0300;
- for j := 24 to 31 do Cursor[j] := 16#0000;
-
- chkdrv; {Check for mouse }
- { driver installation}
- m1:=0; {Function call 0 }
- mouses(m1,m2,m3,m4); {initialize mouse }
- if ( m1 = 0 ) then {No, output message }
- writeln('Microsoft mouse NOT found')
- else
- begin {Yes, demo function 9}
- { and funciton 16 }
- graf; {set to graphics mode}
-
- m1:=9; {Function call 9 }
- m2:=1; { set graphics cursor}
- m3:=1;
- ptradd[1] := (ads Cursor).r; {offset of the array}
- ptradd[2] := (ads Cursor).s; {segment of the array}
- mouses(m1,m2,m3,ptradd[1]);
-
- writeln('Mouse cursor will disappear within this area.');
- writeln('Press the right mouse button to EXIT.........');
-
- m1:=1; {Function call 1 }
- mouses(m1,m2,m3,m4); { show mouse cursor }
-
- m1 := 16; {Function call 16 }
- bound[0] := 0; {left x coordinate }
- bound[1] := 0; {upper y coordinate }
- bound[2] := 390; {right x coordinate }
- bound[3] := 25; {lower y coordinate }
- ptradd[1] := (ads bound).r; {offset of the array}
- ptradd[2] := (ads bound).s; {segment of the array}
- mouses(m1,m2,m3,ptradd[1]);
-
- m2 := 999; {dummy value for loop}
- repeat {until . }
- m1 := 3; {Function call 3, get}
- mouses( m1, m2, m3, m4 ); {current mouse status}
- until m2 = 2; {left button pressed }
-
- end
- end.
-
-
- \SAMPCODE\MOUSE\LIB\MOUSE\DEMO\BDEMO.BAS
-
- ' Mouse library call test in Quick Basic V2.0
-
- DIM cursor% (32), cond% (4)
-
- cursor%(1) =&hf87f ' initilize data for function call #9
- cursor%(2) =&h0741
- cursor%(3) =&hcf9f
- cursor%(4) =&h9fc7
- cursor%(5) =&h0f81
- cursor%(6) =&h77be
- cursor%(7) =&h0fce
- cursor%(8) =&h8fdf
- cursor%(9) =&hbfe3
- cursor%(10)=&h9ff9
- cursor%(11)=&hc3f9
- cursor%(12)=&hfc01
- cursor%(13)=&hf7fe
- cursor%(14)=&h0ffe
- cursor%(15)=&hf87e
- cursor%(16)=&hff83
- cursor%(17)=&h0780
- cursor%(18)=&hf8be
- cursor%(19)=&h3060
- cursor%(20)=&h6038
- cursor%(21)=&hf07e
- cursor%(22)=&h8841
- cursor%(23)=&hf031
- cursor%(24)=&h7020
- cursor%(25)=&h401c
- cursor%(26)=&h6006
- cursor%(27)=&h3c06
- cursor%(28)=&h03fe
- cursor%(29)=&h0001
- cursor%(30)=&hf001
- cursor%(31)=&h0781
- cursor%(32)=&h007c
-
-
- call chkdrv ' Check for driver install
-
- m1%=0 ' Function 0
- call mouse(m1%,m2%,m3%,m4%) ' initialize mouse
- if ( M1% = 0 ) then
- print "Microsoft Mouse not found"
- end
- end if
-
- screen 2 ' Grahpics screen mode
-
- m1%=9 ' Function call 9
- m2%=1
- m3%=1
- m4%=VARPTR(cursor%(1)) ' Pointer to currsor array
- call mouse(m1%, m2%, m3%, m4%)
-
- print "Mouse cursor will disappear within this area."
- print "Press right button to EXIT..................."
-
- m1% = 1
- call mouse(m1%,m2%,m3%,m4%)
-
- m1%=16
- cond%(1) = 0
- cond%(2) = 0
- cond%(3) = 390
- cond%(4) = 25
- m4%=VARPTR(cond%(1))
- call mouse(m1%,m2%,m3%,m4%)
-
- m2% = 99
- while ( m2% <> 2 )
- m1% = 3
- call mouse(m1%,m2%,m3%,m4%)
- wend
-
- screen 0
-
- end
-
- \SAMPCODE\MOUSE\LIB\MOUSE\DEMO\IBMOUSE.BAS
-
- 1000 ' REFERENCE test of mouse/interpretive BASIC interface IN ibmouse.ba
- 1010 '
- 1020 ' This program is intended to test the parameter passing from interpret
- 1030 ' BASIC to the mouse driver.
- 1040 '
- 1050 ' Note: This program is written for interpretive BASIC. Do not attemp
- 1060 ' attempt to run it using compiled BASIC.
- 1070 '
- 1080 DEF SEG = 0
- 1090 MSEG = 256*PEEK(51*4+3)+PEEK(51*4+2)
- 1100 MOUSE = 256*PEEK(51*4+1)+PEEK(51*4)+2
- 1110 IF MSEG OR (MOUSE-2) THEN 1130
- 1120 PRINT "Mouse Driver not found" : END
- 1130 DEF SEG=MSEG
- 1140 IF PEEK (MOUSE-2) = 207, THEN 1120 '207 is iret
- 1150 '
- 1160 CLS
- 1170 '
- 1180 M1% = 0 ' Reset the mouse
- 1190 CALL MOUSE(M1%, M2%, M3%, M4%)
- 1200 IF NOT (M1%) THEN PRINT "Mouse not installed." : END
- 1210 '
- 1220 M1% = 1 ' Show the mouse curs
- 1230 CALL MOUSE(M1%, M2%, M3%, M4%)
- 1240 PRINT "Mouse cursor should now be visible..."
- 1250 '
- 1260 M1% = 4
- 1270 FOR M4% = 0 TO 200 STEP 8
- 1280 FOR M3% = 0 TO 640 STEP 2
- 1290 CALL MOUSE(M1%, M2%, M3%, M4%)
- 1300 NEXT
- 1310 NEXT
- 1320 '
- 1330 M1%=4 ' Move the mouse
- 1340 M3%=320 ' cursor to the
- 1350 M4%=100 ' center of the
- 1360 CALL MOUSE (M1%, M2%, M3%, M4%) ' screen
- 1370 '
- 1380 M1% = 0 ' Reset the mouse
- 1390 CALL MOUSE(M1%, M2%, M3%, M4%)
- 1400 END
-
- \SAMPCODE\MOUSE\LIB\MOUSE\DEMO\QBDEMO.BAS
-
- ' Mouse library call test in Quick Basic V2.0
-
- call chkdrv
-
- screen 0
-
- m1%=0 ' Function 0
- call mouse(m1%,m2%,m3%,m4%)
- if ( M1% = 0 ) then
- print "Microsoft Mouse NOT found"
- end
- end if
-
- m1%=4 ' Function 4
- m3%=200
- m4%=100
- call mouse(m1%,m2%,m3%,m4%)
-
- m1%=7 ' Function 7
- m3%=150
- m4%=450
- call mouse(m1%,m2%,m3%,m4%)
-
- m1%=8 ' Function 8
- m3%=50
- m4%=150
- call mouse(m1%,m2%,m3%,m4%)
-
- screen 2
-
- print "graphics cursor, bounded in center screen"
- print "Press left button to EXIT."
-
- m1% = 1
- call mouse(m1%,m2%,m3%,m4%)
-
- m2% = 99
- while ( m2% <> 1 )
- m1% = 3
- call mouse(m1%,m2%,m3%,m4%)
- wend
-
- screen 0
-
- end
-
- \SAMPCODE\MOUSE\LIB\MOUSE\DEMO\QBMOUSE.BAS
-
- ' REFERENCE test of mouse() in mouse.lib IN qbmouse.bas
- '
- ' This program is intended to test the parameter passing from
- ' QucikBASIC through the mouse library function mouse(), to
- ' the mouse driver.
- '
- ' To create qbmouse.exe:
- '
- ' QB QBMOUSE;
- ' LINK QBMOUSE+SUBS,,,BCOM20+MOUSE.LIB
- '
- ' Note: This program is written in QuickBASIC (compiled). Do not
- ' attempt to run it under interepted BASIC, since the mouse() functio
- ' is not available.
- '
-
- DIM BOUNDS%(4)
-
- CALL CHKDRV ' Make sure mouse driver exis
- SCREEN 2 ' 640x200 display (CGA mode 6
- CLS ' Clear the screen
-
- M1% = 0 ' Reset the mouse
- CALL MOUSE(M1%, M2%, M3%, M4%)
-
- M1% = 1 ' Show the mouse cursor
- CALL MOUSE(M1%, M2%, M3%, M4%)
-
- PRINT "Mouse cursor should now be sweeping the screen."
- M1% = 4
- FOR M3% = 0 TO 640 STEP 8
- FOR M4% = 0 TO 200 STEP 4
- CALL MOUSE(M1%, M2%, M3%, M4%) ' Set mouse cursor position
- NEXT
- NEXT
-
- M1% = 2 ' Hide the mouse cursor
- CALL MOUSE(M1%, M2%, M3%, M4%)
- CLS
-
- PRINT "╔════════════════════════════════════════════════╗"
- PRINT "║ Function 16 test. Cursor should disappear ║"
- PRINT "║ when moved over double line. ║"
- PRINT "║ ║"
- PRINT "║ Type any key to make cursor reappear. ║"
- PRINT "║ ║"
- PRINT "║ Type ESCape to exit. ║"
- PRINT "╚════════════════════════════════════════════════╝"
-
- 100 M1%= 4 ' Position mouse cursor
- M3% = 320 ' in center of screen
- M4% = 100
- CALL MOUSE(M1%, M2%, M3%, M4%)
-
- M1% = 1 ' Show mouse cursor
- CALL MOUSE(M1%, M2%, M3%, M4%)
- '
- M1% = 16
- BOUNDS%(0) = 0 ' Exclude mouse cursor from
- BOUNDS%(1) = 0 ' the rectangle with corners
- BOUNDS%(2) = 392 ' at (0,0), (0,56), (392,0),
- BOUNDS%(3) = 56 ' and (392,56)
- M4% = VARPTR(BOUNDS%(0)) ' M4% = array address
- CALL MOUSE(M1%, M2%, M3%, M4%)
-
- 200 A$ = INKEY$
- IF A$ = "" THEN 200
- IF A$ <> "" THEN 100
-
- M1% = 2 ' Make sure the mouse cursor
- CALL MOUSE(M1%, M2%, M3%, M4%) ' is hidden
- CLS
-
- PRINT "Move the mouse cursor to the UPPER LEFT corner of the screen."
- PRINT "RELEASE both mouse buttons, and then press ESCape."
- M1% = 1 ' Make sure the mouse cursor
- CALL MOUSE(M1%, M2%, M3%, M4%) ' is displayed
- CALL MOUSE(M1%, M2%, M3%, M4%)
- 300 A$ = INKEY$
- IF A$ <> "" THEN 300
- M1% = 3 ' Get mouse position and
- CALL MOUSE(M1%, M2%, M3%, M4%) ' button status
- M1% = 2 ' Make sure the mouse cursor
- CALL MOUSE(M1%, M2%, M3%, M4%) ' is hidden
- IF (M2% <> 0) THEN PRINT "Mouse button information error"
- IF (M3% <> 0) THEN PRINT "Mouse x coordinate position error ";M3%
- IF (M4% <> 0) THEN PRINT "Mouse y coordinate position error ";M4%
- M1% = 1 ' Make sure the mouse cursor
- CALL MOUSE(M1%, M2%, M3%, M4%) ' is displayed
-
- M1% = 2 ' Make sure the mouse cursor
- CALL MOUSE(M1%, M2%, M3%, M4%) ' is hidden
- PRINT "Move the mouse cursor to the LOWER RIGHT corner of the screen.
- PRINT "HOLD DOWN both mouse buttons, and then press ESCape."
- M1% = 1 ' Make sure the mouse cursor
- CALL MOUSE(M1%, M2%, M3%, M4%) ' is displayed
- 400 A$ = INKEY$
- IF A$ <> "" THEN 400
- M1% = 3 ' Get mouse position and
- CALL MOUSE(M1%, M2%, M3%, M4%) ' button status
- M1% = 2 ' Make sure the mouse cursor
- CALL MOUSE(M1%, M2%, M3%, M4%) ' is hidden
- IF (M2% <> 3) THEN PRINT "Mouse button information error"
- IF (M3% <> 639) THEN PRINT "Mouse x coordinate position error ";M3%
- IF (M4% <> 199) THEN PRINT "Mouse y coordinate position error ";M4%
- M1% = 1 ' Make sure the mouse cursor
- CALL MOUSE(M1%, M2%, M3%, M4%) ' is displayed
-
- PRINT
- PRINT "Press any key to terminate."
- 500 A$ = INKEY$
- IF A$ ="" THEN 500
- M1% = 0 ' Reset the mouse
- CALL MOUSE(M1%, M2%, M3%, M4%)
-
- END
-
- \SAMPCODE\MOUSE\LIB\MOUSE\DEMO\FDEMO.FOR
-
- PROGRAM MTEST
-
- C
- C -- Mouse Library function calls demo in MS FORTRAN V3.31
- C
-
- C -- mouse parameters --
- INTEGER*2 M1, M2, M3, M4, M5
- INTEGER*2 MCURSOR(32), BOUND(4)
- INTEGER*2 ARRLOC(2)
- INTEGER*4 ARRADDS
- EXTERNAL CHKDRV, GRAF
- EQUIVALENCE (ARRLOC(1),ARRADDS)
-
- C -- initialize data for function call 9 --
- C Mouse call #9 needs 2 byte integer input, in V3.31
- C use INT2 function.
-
- DO 50 I = 1, 16
- 50 MCURSOR (I) = INT2(#ffff)
-
- MCURSOR(17) = INT2(#0780)
- MCURSOR(18) = INT2(#b8b8)
- MCURSOR(19) = INT2(#3060)
- MCURSOR(20) = INT2(#6038)
- MCURSOR(21) = INT2(#f07e)
- MCURSOR(22) = INT2(#8841)
- MCURSOR(23) = INT2(#f031)
- MCURSOR(24) = INT2(#7020)
- MCURSOR(25) = INT2(#401c)
- MCURSOR(26) = INT2(#6006)
- MCURSOR(27) = INT2(#3c06)
- MCURSOR(28) = INT2(#03fe)
- MCURSOR(29) = INT2(#0001)
- MCURSOR(30) = INT2(#f001)
- MCURSOR(31) = INT2(#0301)
- MCURSOR(32) = INT2(#007c)
-
- C -- Chech for mouse and driver installation --
- CALL CHKDRV
-
- M1 = 0
- CALL MOUSES(M1, M2, M3, M4)
-
- IF ( M1 .EQ. 0 ) THEN
- WRITE(*,*)' Microsoft mouse NOT found'
- STOP
- ENDIF
-
-
- WRITE(*,*) ' Enter "c" to continue'
- 100 READ (*,200) CH
- 200 FORMAT(A)
- IF ( CH .NE. 'c' ) GOTO 100
-
- C -- Change to graphics mode --
- CALL GRAF
-
- C -- Function 9 Graphics Cursor --
- M1 = 9
- M2 = 1
- M3 = 1
- ARRADDS = LOCFAR(MCURSOR)
- CALL MOUSES(M1, M2, M3, ARRLOC(1))
-
- M1 = 1
- CALL MOUSES(M1, M2, M3, M4)
-
- C -- Function 16 Conditional Off --
- M1 = 16
- BOUND(1) = 0
- BOUND(2) = 0
- BOUND(3) = 50
- BOUND(4) = 300
- ARRADDS = LOCFAR(BOUND)
- CALL MOUSES(M1, M2, M3, ARRLOC(1))
-
-
- WRITE(*,*) ' ENTER "q" TO CONTINUE'
- 300 READ (*,200) CH
- IF ( CH .NE. 'q' ) GOTO 300
-
- STOP
- END
-
-
- \SAMPCODE\MOUSE\LIB\MOUSE\DEMO\FORMOUSE.FOR
-
- C----------------------------------------------------------------------
- C
- C This program tests the 4 parameter mouse driver interface function
- C
- C To Run :
- C FOR1 FORMOUSE;
- C PAS1;
- C LINK FORMOUSE+SUBS,,,MOUSE
- C OR
- C MAKE FORMOUSE.MAK
- C
- C----------------------------------------------------------------------
- INTEGER*2 M1, M2, M3, M4
- INTEGER*2 PTRADD(2), BOUND(4)
- INTEGER*4 PTR
- EXTERNAL CHKDRV, GRAF
- EQUIVALENCE (PTRADD(1), PTR)
-
- CALL CHKDRV
-
- M1 = 0
- CALL MOUSES(M1, M2, M3, M4)
- IF (M1 .NE. 0) GOTO 100
- WRITE (*, 800) ' Mouse Driver not installed'
- GOTO 99999
-
- 100 CALL GRAF
-
- M1 = 1
- CALL MOUSES(M1, M2, M3, M4)
-
- WRITE (*, 800) ' mouse cursor should be sweeping the screen'
-
- M1 = 4
- DO 210 M3 = 0, 640, 16
- DO 200 M4 = 0, 200, 2
- CALL MOUSES(M1, M2, M3, M4)
- 200 CONTINUE
- 210 CONTINUE
-
- CALL GRAF
-
- WRITE(*,800)'++-----------------------------------------------+'
- WRITE(*,800)' | Function 16 test. Cursor should disappear |'
- WRITE(*,800)' | when moved over DOTTED line. |'
- WRITE(*,800)' | Cursor should appear in center of screen |'
- WRITE(*,800)' | |'
- WRITE(*,800)' | Type ENTER to make cursor reappear. |'
- WRITE(*,800)' | Type C (Upper Case) and ENTER to continue. |'
- WRITE(*,800)' +-----------------------------------------------+'
-
- 300 M1 = 4
- M3 = 320
- M4 = 100
- CALL MOUSES(M1, M2, M3, M4)
-
- M1 = 1
- CALL MOUSES(M1, M2, M3, M4)
-
- M1 = 16
- BOUND(1) = 0
- BOUND(2) = 0
- BOUND(3) = 384
- BOUND(4) = 56
- PTR = LOCFAR(BOUND)
- CALL MOUSES(M1, M2, M3, PTRADD(1))
-
- 400 READ (*,800) CH
- IF (CH .NE. 'C') GOTO 300
-
- C Test buttons and mouse position
-
- CALL GRAF
-
- WRITE (*,800) ' Move mouse to UPPER LEFT corner.'
- WRITE (*,800) ' PRESS both buttons, press C and ENTER'
- M1 = 1
- CALL MOUSES(M1, M2, M3, M4)
- 500 READ (*,800) CH
- IF (CH .NE. 'C') GOTO 500
- M1 = 3
- M2 = 9999
- M3 = 9999
- M4 = 9999
- CALL MOUSES(M1, M2, M3, M4)
- M1 = 2
- CALL MOUSES(M1, M2, M3, M4)
- IF (M2 .NE. 3) WRITE(*, 700) ' BUTTON INFO ERROR : ',M2
- IF (M3 .NE. 0) WRITE(*, 700) ' X COORD ERROR : ',M3
- IF (M4 .NE. 0) WRITE(*, 700) ' Y COORD ERROR : ',M4
- M1 = 1
- CALL MOUSES(M1, M2, M3, M4)
-
-
- M1 = 2
- CALL MOUSE(M1, M2, M3, M4)
- WRITE (*,800) ' Move mouse to LOWER RIGHT corner.'
- WRITE (*,800) ' RELEASE both buttons, then press C then ENTER'
- M1 = 1
- CALL MOUSES(M1, M2, M3, M4)
- 600 READ (*,800) CH
- IF (CH .NE. 'C') GOTO 600
- M1 = 3
- M3 = 9999
- M4 = 9999
- CALL MOUSES(M1, M2, M3, M4)
- M1 = 2
- CALL MOUSES(M1, M2, M3, M4)
- IF (M2 .NE. 0) WRITE(*, 700) ' BUTTON INFO ERROR : ',M2
- IF (M3 .NE. 639) WRITE(*, 700) ' X COORD ERROR : ',M3
- IF (M4 .NE. 199) WRITE(*, 700) ' Y COORD ERROR : ',M4
- M1 = 1
- CALL MOUSES(M1, M2, M3, M4)
-
-
- 700 FORMAT (A, I4)
-
- 800 FORMAT(A)
-
- STOP
- 99999 END
-
- \SAMPCODE\MOUSE\LIB\MOUSE\DEMO\BDEMO.MAK
-
- bdemo.obj: bdemo.bas
- qb bdemo;
-
- bdemo.exe: bdemo.obj subs.obj
- link bdemo subs,,,..\mouse;
-
- \SAMPCODE\MOUSE\LIB\MOUSE\DEMO\CMCMOUSE.MAK
-
- cmcmouse.obj: cmcmouse.c
- msc /AC cmcmouse;
-
- cmcmouse.exe: cmcmouse.obj
- link cmcmouse+subs,,,..\mouse
-
- \SAMPCODE\MOUSE\LIB\MOUSE\DEMO\FDEMO.MAK
-
- fdemo.obj: fdemo.for
- for1 fdemo;
- pas2
-
- fdemo.exe: fdemo.obj subs.obj
- link fdemo subs,,,..\mouse;
-
- \SAMPCODE\MOUSE\LIB\MOUSE\DEMO\FORMOUSE.MAK
-
- formouse.obj: formouse.for
- for1 formouse;
- pas2
-
- formouse.exe: formouse.obj
- link formouse subs,,,..\mouse;
-
- \SAMPCODE\MOUSE\LIB\MOUSE\DEMO\LMCMOUSE.MAK
-
- lmcmouse.obj: lmcmouse.c
- msc /AL lmcmouse;
-
- lmcmouse.exe: lmcmouse.obj
- link lmcmouse+subs,,,..\mouse
-
- \SAMPCODE\MOUSE\LIB\MOUSE\DEMO\MMCMOUSE.MAK
-
- mmcmouse.obj: mmcmouse.c
- msc /AM mmcmouse;
-
- mmcmouse.exe: mmcmouse.obj
- link mmcmouse+subs,,,..\mouse
-
- \SAMPCODE\MOUSE\LIB\MOUSE\DEMO\PDEMO.MAK
-
- pdemo.obj: pdemo.pas
- pas1 pdemo;
- pas2
-
- pdemo.exe: pdemo.obj subs.obj
- link pdemo subs,,,..\mouse;
-
- \SAMPCODE\MOUSE\LIB\MOUSE\DEMO\QBDEMO.MAK
-
- QBMOUSE.OBJ: QBDEMO.BAS
- QB QBDEMO /O;
-
- QBDEMO.EXE: QBDEMO.OBJ
- LINK QBDEMO+SUBS,,,BCOM20+..\MOUSE
-
- \SAMPCODE\MOUSE\LIB\MOUSE\DEMO\QBMOUSE.MAK
-
- QBMOUSE.OBJ: QBMOUSE.BAS
- QB QBMOUSE /O;
-
- QBMOUSE.EXE: QBMOUSE.OBJ
- LINK QBMOUSE+SUBS,,,BCOM20+..\MOUSE
-
- \SAMPCODE\MOUSE\LIB\MOUSE\DEMO\SMCMOUSE.MAK
-
- smcmouse.obj: smcmouse.c
- msc smcmouse;
-
- smcmouse.exe: smcmouse.obj
- link smcmouse+subs,,,..\mouse
-
- \SAMPCODE\MOUSE\LIB\MOUSE\EXAMPLES
- \SAMPCODE\MOUSE\LIB\MOUSE\EXAMPLES\MSCEXAMP.C
-
- /* Mouse Function Calls and Microsoft C
-
- To Run : MSC MSCEXAMP;
- LINK MSCEXAMP,,,MOUSE;
- or
- MAKE MSCEXAMP.MAK
-
- */
-
- #include <stdio.h>
- #include <dos.h>
-
- void chkdrv();
- void graf();
-
- main()
- {
- int m1, m2, m3, m4;
-
- chkdrv(); /* check for mouse driver */
-
- m1 = 0; /* initialize mouse */
- cmouses( &m1, &m2, &m3, &m4);
-
- if ( m1 = 0 ) {
- printf("Microsoft Mouse NOT found");
- exit (-1); /* exit, if mouse not found */
- }
-
- m1 = 4; /* function call 4 */
- m3 = 200; /* set mouse pisition at */
- m4 = 100; /* center of the screen */
- cmouses( &m1, &m2, &m3, &m4);
-
- m1 = 7; /* function call 7 */
- m3 = 150; /* minimum horizontal value */
- m4 = 450; /* maximum horizontal value */
- cmouses( &m1, &m2, &m3, &m4);
-
- m1 = 8; /* function call 8 */
- m3 = 50; /* minimum vertical value */
- m4 = 150; /* maximum vertical value */
- cmouses( &m1, &m2, &m3, &m4);
-
- graf();
-
- printf("Graphics cursor limited to center of the screen.\n");
- printf("Press the left button to EXIT.");
-
- m1 = 1; /* function 1, show cursor */
- cmouses( &m1, &m2, &m3, &m4);
-
- m2 = 0; /* loop until left mouse */
- while ( m2 != 1 ) { /* button is pressed */
- m1 = 3;
- cmouses( &m1, &m2, &m3, &m4 );
- }
-
- m1 = 2; /* function 2, show cursor */
- cmouses( &m1, &m2, &m3, &m4);
-
- }
-
-
- void chkdrv()
- {
- union REGS inregs, outregs;
- struct SREGS segregs;
- long address;
- unsigned char first_byte;
-
- inregs.x.ax = 0x3533;
- intdosx ( &inregs, &outregs, &segregs );
-
- address = (((long) segregs.es) << 16) + (long) outregs.x.bx;
- first_byte = * (long far *) address;
-
- if ((address == 0) || (first_byte == 0xcf)) {
- printf("Mouse driver NOT installed");
- exit();
- }
-
- }
-
-
- void graf()
- {
- union REGS cpuregs;
-
- cpuregs.x.ax = 0x0006;
- int86 ( 0x10, &cpuregs, &cpuregs );
- }
-
- \SAMPCODE\MOUSE\LIB\MOUSE\EXAMPLES\ASMEXAMP.ASM
-
- ; Mouse Function Calls and Microsoft Assembler
- ;
- ; To Run : MASM ASMEXAMP;
- ; LINK ASMEXAMP;
- ;
- ; MAKE ASMEXAMP.MAK
- ;
- ;
-
-
- stack segment stack 'stack'
- db 256 dup(?)
- stack ends
- ;
- data segment public 'data'
- msg1 db "Microsoft Mouse NOT found","$"
- msg2 db "Graphics cursor limit at center of the screen",
- db "Press the left mouse button to EXIT","$"
- data ends
- ;
- code segment public 'code'
- assume cs:code, ds:data, es:data; ss:stack
- start:
- push bp
- mov bp,sp
- mov ax,seg data ;Set DS to the
- mov ds,ax ; data segment
-
- push es ;Save PSP segment address
- mov ax, 03533h ;Get int 33h vector
- int 21h ; by calling int 21
- mov ax, es ;Check segment and
- or ax, bx ;offset of int 33
- jnz begin ;vector. If 0 or pointing to
- mov bl, es:[bx] ;an IRET driver not install
- cmp bl, 0cfh
- jne begin ;Exit
-
- mov dx, offset msg1 ;Get not found message offset
- mov ah, 09h ;Output message to screen
- int 21h
- pop es
- jmp short exit ;Exit
-
- begin:
- mov ax,0 ;Initialize mouse
- int 33h
- cmp ax,0 ;Is mouse installed?
- jz exit ;No, exit
- mov ax,0006h ;Set up for 640x200 resolutio
- int 10h ;graphics mode (CGA-mode 6)
- mov ax, 4 ;Function 4 (set cursor posit
- mov cx, 200 ;M3 = 200
- mov dx, 100 ;M4 = 100
- int 33h
- mov ax, 7 ;Function 7
- mov cx, 150 ;M3 = 150
- mov dx, 450 ;M4 = 450
- int 33h
- mov ax, 8 ;Function 8
- mov cx, 50 ;M3 = 50
- mov dx, 150 ;M4 = 150
- int 33h
- mov ax,1 ;Shoe the mouse cursor
- int 33h
-
- mov dx, offset msg2 ;Get exit message
- mov ah, 09h ;Output message to screen
- int 21h
- xor ax, ax
-
- around:
- mov ax,3 ;Get mouse status
- int 33h
- cmp bx,0001h ;Left button pressed ?
- jne around ;Branch if left button NOT pr
-
- mov ax,0
- int 33h ;Reset mouse
- mov ax,0003h ;Set up 80x25 character text
- int 10h
- exit:
- mov sp,bp
- pop bp
- mov ax,04c00h ;Terminate
- int 21h
- ;
- code ends
- end start
-
- \SAMPCODE\MOUSE\LIB\MOUSE\EXAMPLES\SUBS.ASM
-
- ;
- ;
- ; This is the subroutine for mouse.lib test in FORTRAN
- ; and Pascal examples. Procedure graf sets the screen
- ; video mode into hi-res graphics.
- ;
- ;
- ;
- mdata segment byte public 'data'
-
- msg db "Mouse Driver NOT installed","$"
-
- mdata ends
-
-
-
-
- mcode segment para public 'CODE'
- assume cs:mcode
- ;
- public graf
- ;
- graf proc far
- push bp
- mov ax, 06h ;change to graphics
- int 10h ;mode by calling
- pop bp ;int 10 service
- ret
- graf endp
- ;
- ;
- ;
- public chkdrv
- ;
- chkdrv proc far
- push bp
- push es
-
- mov ax, 03533h ;get int 33h
- int 21h ;by calling int 21
- mov ax, es ;check segment and
- or ax, bx ;offset of int 33
- jnz back ;vector if 0 or IRET
- mov bl, es:[bx] ;mouse driver not installed
- cmp bl, 0cfh
- jne back ;exit
-
- mov ax,seg mdata ;set up DS to
- mov ds,ax ;point to data seg
- mov dx, offset msg ;get message
- mov ah, 09h ;out to screen
- int 21h
- pop es
- pop bp
- mov ax,04c00h ;function code for
- int 21h ;end process
-
- back:
- pop es
- pop bp
- ret
- chkdrv endp
- ;
- mcode ends
- end
-
- \SAMPCODE\MOUSE\LIB\MOUSE\EXAMPLES\PASEXAMP.PAS
-
- { Mouse Function Calls and Microsoft Pascal }
- { }
- { To Run : PAS1 PASEXAMP; }
- { PAS2 }
- { LINK PASEXAMP+SUBS,,,MOUSE; }
- { or }
- { MAKE PASEXAMP.MAK }
- { }
-
- program mtest (output);
-
- procedure mouses(vars m1, m2, m3, m4:word);extern;
- procedure chkdrv;extern;
- procedure graf;extern;
-
- var
- m1, m2, m3, m4: word;
-
- begin {demo}
-
- chkdrv; {check mouse driver, if not }
- {installed, Exit. }
- m1:=0; {installed, initialize mouse}
- mouses( m1, m2, m3, m4);
- if ( m1 = 0 ) then
- writeln('Microsoft Mouse NOT found')
- else
- begin
-
- m1 := 4; {function call 4, set mouse }
- m3 := 200; {horizontal position }
- m4 := 100; {vertical position }
- mouses( m1, m2, m3, m4 );
-
-
- m1 := 7; {function call 4, set mouse }
- m3 := 150; {minimum horizontal position}
- m4 := 450; {maximum horizontal position}
- mouses( m1, m2, m3, m4 );
-
-
- m1 := 8; {function call 4, set mouse }
- m3 := 50; {minimum vertical position }
- m4 := 150; {maximum vertical position }
- mouses( m1, m2, m3, m4 );
-
- graf; {change into graphics mode }
-
- writeln('Graphics cursor limited to center of the screen.');
- writeln('Press the left mouse button to EXIT.');
-
- m1:=1; {function call 1 }
- mouses( m1, m2, m3, m4 );{show mouse cursor }
-
- m2 := 999; {dummy value for loop }
- repeat {until .... }
- m1 := 3; {function call 3 }
- mouses( m1, m2, m3, m4 ); {get current mouse status}
- until m2 = 1; {left mouse button pressed }
-
- end
-
- end. {demo}
-
- \SAMPCODE\MOUSE\LIB\MOUSE\EXAMPLES\QBEXAMP.BAS
-
- ' Mouse Function Calls and Microsoft QuickBASIC
- '
- ' To Run : QB QBEXAMP;
- ' LINK QBEXAMP+SUBS,,,MOUSE;
- ' or
- ' MAKE QBEXAMP.MAK
- '
- '
- ' Mouse library call test in Quick Basic V2.0
-
- call chkdrv
-
- screen 0
-
- m1%=0 ' Function 0
- call mouse(m1%,m2%,m3%,m4%)
- if ( M1% = 0 ) then
- print "Microsoft Mouse NOT found"
- end
- end if
-
- m1%=4 ' Function 4
- m3%=200
- m4%=100
- call mouse(m1%,m2%,m3%,m4%)
-
- m1%=7 ' Function 7
- m3%=150
- m4%=450
- call mouse(m1%,m2%,m3%,m4%)
-
- m1%=8 ' Function 8
- m3%=50
- m4%=150
- call mouse(m1%,m2%,m3%,m4%)
-
- screen 2
-
- print "graphics cursor, bounded in center screen"
- print "Press left button to EXIT."
-
- m1% = 1
- call mouse(m1%,m2%,m3%,m4%)
-
- m2% = 99
- while ( m2% <> 1 )
- m1% = 3
- call mouse(m1%,m2%,m3%,m4%)
- wend
-
- screen 0
-
- end
-
- \SAMPCODE\MOUSE\LIB\MOUSE\EXAMPLES\FOREXAMP.FOR
-
- C Mouse Function Calls and Microsoft FORTRAN
- C
- C To Run : FOR1 FOREXAMP;
- C PAS2
- C LINK FOREXAMP+SUBS,,,MOUSE;
- C or
- C MAKE FOREXAMP.MAK
- C
-
- PROGRAM MTEST
-
- C
- C -- Mouse Library calls test in MS FORTRAN V3.31 --
- C
-
- INTEGER*2 M1, M2, M3, M4
- EXTERNAL GRAF, CHKDRV
-
-
- C -- Call driver checking routine --
- CALL CHKDRV()
-
- C -- Mouse init call --
- M1 = 0
- CALL MOUSES(M1, M2, M3, M4)
- IF ( M1 .EQ. 0 ) THEN
- WRITE(*,*)' Microsoft Mouse NOT found'
- STOP
- ENDIF
-
- C -- Place Cursor in the center of the screen --
- M1 = 4
- M3 = 200
- M4 = 100
- CALL MOUSES(M1, M2, M3, M4)
-
- C -- Set minimum and maximum horizontal position --
- M1 = 7
- M3 = 150
- M4 = 450
- CALL MOUSES(M1, M2, M3, M4)
-
- C -- Set minimum and maximum vertical position --
- M1 = 8
- M3 = 50
- M4 = 150
- CALL MOUSES(M1, M2, M3, M4)
-
- CALL GRAF()
-
- WRITE(*,*) ' Graphics cursor limited to the screen center.'
- WRITE(*,*) ' Press the left mouse button to EXIT.'
-
- M1 = 1
- CALL MOUSES(M1, M2, M3, M4)
-
-
- C -- Loop for left moue button pressed --
- M2 = 9999
- 100 M1 = 3
- CALL MOUSES(M1, M2, M3, M4)
- IF ( M2 .NE. 1 ) GOTO 100
-
- STOP
- END
-
- \SAMPCODE\MOUSE\SOURCES
- \SAMPCODE\MOUSE\SOURCES\COLOR.DEF
-
- ; SAMPLE Microsoft Mouse COLOR MENU
- ;
- ; This menu displays the color options available for the
- ; Microsoft Mouse Menus.
- ;
- ;
- BEGIN lb
- ;
- lb: execute popmen
- nul: nothing
- ;
- popmen: POPUP 2,1,NORMAL
- text "╔QUIT════════════════════════════════════════════════════════════╗"
- text "║ 000 016 032 048 064 080 096 112 128 144 160 176 192 208 224 240║"
- text "║ 001 017 033 049 065 081 097 113 129 145 161 177 193 209 225 241║"
- text "║ 002 018 034 050 066 082 098 114 130 146 162 178 194 210 226 242║"
- text "║ 003 019 035 051 067 083 099 115 131 147 163 179 195 211 227 243║"
- text "║ 004 020 036 052 068 084 100 116 132 148 164 180 196 212 228 244║"
- text "║ 005 021 037 053 069 085 101 117 133 149 165 181 197 213 229 245║"
- text "║ 006 022 038 054 070 086 102 118 134 150 166 182 198 214 230 246║"
- text "║ 007 023 039 055 071 087 103 119 135 151 167 183 199 215 231 247║"
- text "║ 008 024 040 056 072 088 104 120 136 152 168 184 200 216 232 248║"
- text "║ 009 025 041 057 073 089 105 121 137 153 169 185 201 217 233 249║"
- text "║ 010 026 042 058 074 090 106 122 138 154 170 186 202 218 234 250║"
- text "║ 011 027 043 059 075 091 107 123 139 155 171 187 203 219 235 251║"
- text "║ 012 028 044 060 076 092 108 124 140 156 172 188 204 220 236 252║"
- text "║ 013 029 045 061 077 093 109 125 141 157 173 189 205 221 237 253║"
- text "║ 014 030 046 062 078 094 110 126 142 158 174 190 206 222 238 254║"
- text "║ 015 031 047 063 079 095 111 127 143 159 175 191 207 223 239 255║"
- text "╚════════════════════════════════════════════════════════════════╝"
- ;
- SELECT 1,2,4,nul
- SELECT 1,6,4,lb
- SELECT 1,10,4,lb
- SELECT 1,14,4,lb
- SELECT 1,18,4,lb
- SELECT 1,22,4,lb
- SELECT 1,26,4,lb
- SELECT 1,30,4,lb
- SELECT 1,34,4,lb
- SELECT 1,38,4,lb
- SELECT 1,42,4,lb
- SELECT 1,46,4,lb
- SELECT 1,50,4,lb
- SELECT 1,54,4,lb
- SELECT 1,58,4,lb
- SELECT 1,62,4,lb
- SELECT 2,2,4,lb
- SELECT 3,2,4,m001
- SELECT 4,2,4,m002
- SELECT 5,2,4,m003
- SELECT 6,2,4,m004
- SELECT 7,2,4,m005
- SELECT 8,2,4,m006
- SELECT 9,2,4,m007
- SELECT 10,2,4,m008
- SELECT 11,2,4,m009
- SELECT 12,2,4,m010
- SELECT 13,2,4,m011
- SELECT 14,2,4,m012
- SELECT 15,2,4,m013
- SELECT 16,2,4,m014
- SELECT 17,2,4,m015
- SELECT 2,6,4,m016
- SELECT 3,6,4,m017
- SELECT 4,6,4,m018
- SELECT 5,6,4,m019
- SELECT 6,6,4,m020
- SELECT 7,6,4,m021
- SELECT 8,6,4,m022
- SELECT 9,6,4,m023
- SELECT 10,6,4,m024
- SELECT 11,6,4,m025
- SELECT 12,6,4,m026
- SELECT 13,6,4,m027
- SELECT 14,6,4,m028
- SELECT 15,6,4,m029
- SELECT 16,6,4,m030
- SELECT 17,6,4,m031
- SELECT 2,10,4,m032
- SELECT 3,10,4,m033
- SELECT 4,10,4,m034
- SELECT 5,10,4,m035
- SELECT 6,10,4,m036
- SELECT 7,10,4,m037
- SELECT 8,10,4,m038
- SELECT 9,10,4,m039
- SELECT 10,10,4,m040
- SELECT 11,10,4,m041
- SELECT 12,10,4,m042
- SELECT 13,10,4,m043
- SELECT 14,10,4,m044
- SELECT 15,10,4,m045
- SELECT 16,10,4,m046
- SELECT 17,10,4,m047
- SELECT 2,14,4,m048
- SELECT 3,14,4,m049
- SELECT 4,14,4,m050
- SELECT 5,14,4,m051
- SELECT 6,14,4,m052
- SELECT 7,14,4,m053
- SELECT 8,14,4,m054
- SELECT 9,14,4,m055
- SELECT 10,14,4,m056
- SELECT 11,14,4,m057
- SELECT 12,14,4,m058
- SELECT 13,14,4,m059
- SELECT 14,14,4,m060
- SELECT 15,14,4,m061
- SELECT 16,14,4,m062
- SELECT 17,14,4,m063
- SELECT 2,18,4,m064
- SELECT 3,18,4,m065
- SELECT 4,18,4,m066
- SELECT 5,18,4,m067
- SELECT 6,18,4,m068
- SELECT 7,18,4,m069
- SELECT 8,18,4,m070
- SELECT 9,18,4,m071
- SELECT 10,18,4,m072
- SELECT 11,18,4,m073
- SELECT 12,18,4,m074
- SELECT 13,18,4,m075
- SELECT 14,18,4,m076
- SELECT 15,18,4,m077
- SELECT 16,18,4,m078
- SELECT 17,18,4,m079
- SELECT 2,22,4,m080
- SELECT 3,22,4,m081
- SELECT 4,22,4,m082
- SELECT 5,22,4,m083
- SELECT 6,22,4,m084
- SELECT 7,22,4,m085
- SELECT 8,22,4,m086
- SELECT 9,22,4,m087
- SELECT 10,22,4,m088
- SELECT 11,22,4,m089
- SELECT 12,22,4,m090
- SELECT 13,22,4,m091
- SELECT 14,22,4,m092
- SELECT 15,22,4,m093
- SELECT 16,22,4,m094
- SELECT 17,22,4,m095
- SELECT 2,26,4,m096
- SELECT 3,26,4,m097
- SELECT 4,26,4,m098
- SELECT 5,26,4,m099
- SELECT 6,26,4,m100
- SELECT 7,26,4,m101
- SELECT 8,26,4,m102
- SELECT 9,26,4,m103
- SELECT 10,26,4,m104
- SELECT 11,26,4,m105
- SELECT 12,26,4,m106
- SELECT 13,26,4,m107
- SELECT 14,26,4,m108
- SELECT 15,26,4,m109
- SELECT 16,26,4,m110
- SELECT 17,26,4,m111
- SELECT 2,30,4,m112
- SELECT 3,30,4,m113
- SELECT 4,30,4,m114
- SELECT 5,30,4,m115
- SELECT 6,30,4,m116
- SELECT 7,30,4,m117
- SELECT 8,30,4,m118
- SELECT 9,30,4,m119
- SELECT 10,30,4,m120
- SELECT 11,30,4,m121
- SELECT 12,30,4,m122
- SELECT 13,30,4,m123
- SELECT 14,30,4,m124
- SELECT 15,30,4,m125
- SELECT 16,30,4,m126
- SELECT 17,30,4,m127
- SELECT 2,34,4,m128
- SELECT 3,34,4,m129
- SELECT 4,34,4,m130
- SELECT 5,34,4,m131
- SELECT 6,34,4,m132
- SELECT 7,34,4,m133
- SELECT 8,34,4,m134
- SELECT 9,34,4,m135
- SELECT 10,34,4,m136
- SELECT 11,34,4,m137
- SELECT 12,34,4,m138
- SELECT 13,34,4,m139
- SELECT 14,34,4,m140
- SELECT 15,34,4,m141
- SELECT 16,34,4,m142
- SELECT 17,34,4,m143
- SELECT 2,38,4,m144
- SELECT 3,38,4,m145
- SELECT 4,38,4,m146
- SELECT 5,38,4,m147
- SELECT 6,38,4,m148
- SELECT 7,38,4,m149
- SELECT 8,38,4,m150
- SELECT 9,38,4,m151
- SELECT 10,38,4,m152
- SELECT 11,38,4,m153
- SELECT 12,38,4,m154
- SELECT 13,38,4,m155
- SELECT 14,38,4,m156
- SELECT 15,38,4,m157
- SELECT 16,38,4,m158
- SELECT 17,38,4,m159
- SELECT 2,42,4,m160
- SELECT 3,42,4,m161
- SELECT 4,42,4,m162
- SELECT 5,42,4,m163
- SELECT 6,42,4,m164
- SELECT 7,42,4,m165
- SELECT 8,42,4,m166
- SELECT 9,42,4,m167
- SELECT 10,42,4,m168
- SELECT 11,42,4,m169
- SELECT 12,42,4,m170
- SELECT 13,42,4,m171
- SELECT 14,42,4,m172
- SELECT 15,42,4,m173
- SELECT 16,42,4,m174
- SELECT 17,42,4,m175
- SELECT 2,46,4,m176
- SELECT 3,46,4,m177
- SELECT 4,46,4,m178
- SELECT 5,46,4,m179
- SELECT 6,46,4,m180
- SELECT 7,46,4,m181
- SELECT 8,46,4,m182
- SELECT 9,46,4,m183
- SELECT 10,46,4,m184
- SELECT 11,46,4,m185
- SELECT 12,46,4,m186
- SELECT 13,46,4,m187
- SELECT 14,46,4,m188
- SELECT 15,46,4,m189
- SELECT 16,46,4,m190
- SELECT 17,46,4,m191
- SELECT 2,50,4,m192
- SELECT 3,50,4,m193
- SELECT 4,50,4,m194
- SELECT 5,50,4,m195
- SELECT 6,50,4,m196
- SELECT 7,50,4,m197
- SELECT 8,50,4,m198
- SELECT 9,50,4,m199
- SELECT 10,50,4,m200
- SELECT 11,50,4,m201
- SELECT 12,50,4,m202
- SELECT 13,50,4,m203
- SELECT 14,50,4,m204
- SELECT 15,50,4,m205
- SELECT 16,50,4,m206
- SELECT 17,50,4,m207
- SELECT 2,54,4,m208
- SELECT 3,54,4,m209
- SELECT 4,54,4,m210
- SELECT 5,54,4,m211
- SELECT 6,54,4,m212
- SELECT 7,54,4,m213
- SELECT 8,54,4,m214
- SELECT 9,54,4,m215
- SELECT 10,54,4,m216
- SELECT 11,54,4,m217
- SELECT 12,54,4,m218
- SELECT 13,54,4,m219
- SELECT 14,54,4,m220
- SELECT 15,54,4,m221
- SELECT 16,54,4,m222
- SELECT 17,54,4,m223
- SELECT 2,58,4,m224
- SELECT 3,58,4,m225
- SELECT 4,58,4,m226
- SELECT 5,58,4,m227
- SELECT 6,58,4,m228
- SELECT 7,58,4,m229
- SELECT 8,58,4,m230
- SELECT 9,58,4,m231
- SELECT 10,58,4,m232
- SELECT 11,58,4,m233
- SELECT 12,58,4,m234
- SELECT 13,58,4,m235
- SELECT 14,58,4,m236
- SELECT 15,58,4,m237
- SELECT 16,58,4,m238
- SELECT 17,58,4,m239
- SELECT 2,62,4,m240
- SELECT 3,62,4,m241
- SELECT 4,62,4,m242
- SELECT 5,62,4,m243
- SELECT 6,62,4,m244
- SELECT 7,62,4,m245
- SELECT 8,62,4,m246
- SELECT 9,62,4,m247
- SELECT 10,62,4,m248
- SELECT 11,62,4,m249
- SELECT 12,62,4,m250
- SELECT 13,62,4,m251
- SELECT 14,62,4,m252
- SELECT 15,62,4,m253
- SELECT 16,62,4,m254
- SELECT 17,62,4,m255
- PEND
- ;
- m001: MENU "001",10,35,001
- option "Blue\Black",lb
- MEND
- ;
- m002: MENU "002",10,35,002
- option "Green\Black",lb
- MEND
- ;
- m003: MENU "003",10,35,003
- option "Cyan\Black",lb
- MEND
- ;
- m004: MENU "004",10,35,004
- option "Red\Black",lb
- MEND
- ;
- m005: MENU "005",10,35,005
- option "Magenta\Black",lb
- MEND
- ;
- m006: MENU "006",10,35,006
- option "Brown \Black",lb
- MEND
- ;
- m007: MENU "007",10,35,007
- option "White\Black",lb
- MEND
- ;
- m008: MENU "008",10,35,008
- option "Gray\Black",lb
- MEND
- ;
- m009: MENU "009",10,35,009
- option "Lt. Blue\Black",lb
- MEND
- ;
- m010: MENU "010",10,35,010
- option "Lt. Green\Black",lb
- MEND
- ;
- m011: MENU "011",10,35,011
- option "Lt. Cyan\Black",lb
- MEND
- ;
- m012: MENU "012",10,35,012
- option "Lt. Red\Black",lb
- MEND
- ;
- m013: MENU "013",10,35,013
- option "Lt. Magenta\Black",lb
- MEND
- ;
- m014: MENU "014",10,35,014
- option "Yellow\Black",lb
- MEND
- ;
- m015: MENU "015",10,35,015
- option "Hi-int. White\Black",lb
- MEND
- ;
- m016: MENU "016",10,35,016
- option "Black\Blue",lb
- MEND
- ;
- m017: MENU "017",10,35,017
- option "Blue\Blue",lb
- MEND
- ;
- m018: MENU "018",10,35,018
- option "Green\Blue",lb
- MEND
- ;
- m019: MENU "019",10,35,019
- option "Cyan\Blue",lb
- MEND
- ;
- m020: MENU "020",10,35,020
- option "Red\Blue",lb
- MEND
- ;
- m021: MENU "021",10,35,021
- option "Magenta\Blue",lb
- MEND
- ;
- m022: MENU "022",10,35,022
- option "Brown\Blue",lb
- MEND
- ;
- m023: MENU "023",10,35,023
- option "White\Blue",lb
- MEND
- ;
- m024: MENU "024",10,35,024
- option "Gray\Blue",lb
- MEND
- ;
- m025: MENU "025",10,35,025
- option "Lt. Blue\Blue",lb
- MEND
- ;
- m026: MENU "026",10,35,026
- option "Lt. Green\Blue",lb
- MEND
- ;
- m027: MENU "027",10,35,027
- option "Lt. Cyan\Blue",lb
- MEND
- ;
- m028: MENU "028",10,35,028
- option "Lt. Red\Blue",lb
- MEND
- ;
- m029: MENU "029",10,35,029
- option "Lt. Magenta\Blue",lb
- MEND
- ;
- m030: MENU "030",10,35,030
- option "Yellow\Blue",lb
- MEND
- ;
- m031: MENU "031",10,35,031
- option "Hi-int. White\Blue",lb
- MEND
- ;
- m032: MENU "032",10,35,032
- option "Black\Green",lb
- MEND
- ;
- m033: MENU "033",10,35,033
- option "Blue\Green",lb
- MEND
- ;
- m034: MENU "034",10,35,034
- option "Green\Green",lb
- MEND
- ;
- m035: MENU "035",10,35,035
- option "Cyan\Green",lb
- MEND
- ;
- m036: MENU "036",10,35,036
- option "Red\Green",lb
- MEND
- ;
- m037: MENU "037",10,35,037
- option "Magenta\Green",lb
- MEND
- ;
- m038: MENU "038",10,35,038
- option "Brown\Green",lb
- MEND
- ;
- m039: MENU "039",10,35,039
- option "White\Green",lb
- MEND
- ;
- m040: MENU "040",10,35,040
- option "Gray\Green",lb
- MEND
- ;
- m041: MENU "041",10,35,041
- option "Lt. Blue\Green",lb
- MEND
- ;
- m042: MENU "042",10,35,042
- option "Lt. Green\Green",lb
- MEND
- ;
- m043: MENU "043",10,35,043
- option "Lt. Cyan\Green",lb
- MEND
- ;
- m044: MENU "044",10,35,044
- option "Lt. Red\Green",lb
- MEND
- ;
- m045: MENU "045",10,35,045
- option "Lt. Magenta\Green",lb
- MEND
- ;
- m046: MENU "046",10,35,046
- option "Yellow\Green",lb
- MEND
- ;
- m047: MENU "047",10,35,047
- option "Hi-int. White\Green",lb
- MEND
- ;
- m048: MENU "048",10,35,048
- option "Black\Cyan",lb
- MEND
- ;
- m049: MENU "049",10,35,049
- option "Blue\Cyan",lb
- MEND
- ;
- m050: MENU "050",10,35,050
- option "Green\Cyan",lb
- MEND
- ;
- m051: MENU "051",10,35,051
- option "Cyan\Cyan",lb
- MEND
- ;
- m052: MENU "052",10,35,052
- option "Red\Cyan",lb
- MEND
- ;
- m053: MENU "053",10,35,053
- option "Magenta\Cyan",lb
- MEND
- ;
- m054: MENU "054",10,35,054
- option "Brown\Cyan",lb
- MEND
- ;
- m055: MENU "055",10,35,055
- option "White\Cyan",lb
- MEND
- ;
- m056: MENU "056",10,35,056
- option "Gray\Cyan",lb
- MEND
- ;
- m057: MENU "057",10,35,057
- option "Lt. Blue\Cyan",lb
- MEND
- ;
- m058: MENU "058",10,35,058
- option "Lt. Green\Cyan",lb
- MEND
- ;
- m059: MENU "059",10,35,059
- option "Lt. Cyan\Cyan",lb
- MEND
- ;
- m060: MENU "060",10,35,060
- option "Lt. Red\Cyan",lb
- MEND
- ;
- m061: MENU "061",10,35,061
- option "Lt. Magenta\Cyan",lb
- MEND
- ;
- m062: MENU "062",10,35,062
- option "Yellow\Cyan",lb
- MEND
- ;
- m063: MENU "063",10,35,063
- option "Hi-int. White\Cyan",lb
- MEND
- ;
- m064: MENU "064",10,35,064
- option "Black\Red",lb
- MEND
- ;
- m065: MENU "065",10,35,065
- option "Blue\Red",lb
- MEND
- ;
- m066: MENU "066",10,35,066
- option "Green\Red",lb
- MEND
- ;
- m067: MENU "067",10,35,067
- option "Cyan\Red",lb
- MEND
- ;
- m068: MENU "068",10,35,068
- option "Red\Red",lb
- MEND
- ;
- m069: MENU "069",10,35,069
- option "Magenta\Red",lb
- MEND
- ;
- m070: MENU "070",10,35,070
- option "Brown\Red",lb
- MEND
- ;
- m071: MENU "071",10,35,071
- option "White\Red",lb
- MEND
- ;
- m072: MENU "072",10,35,072
- option "Gray\Red",lb
- MEND
- ;
- m073: MENU "073",10,35,073
- option "Lt. Blue\Red",lb
- MEND
- ;
- m074: MENU "074",10,35,074
- option "Lt. Green\Red",lb
- MEND
- ;
- m075: MENU "075",10,35,075
- option "Lt. Cyan\Red",lb
- MEND
- ;
- m076: MENU "076",10,35,076
- option "Lt. Red\Red",lb
- MEND
- ;
- m077: MENU "077",10,35,077
- option "Lt. Magenta\Red",lb
- MEND
- ;
- m078: MENU "078",10,35,078
- option "Yellow\Red",lb
- MEND
- ;
- m079: MENU "079",10,35,079
- option "Hi-int. White\Red",lb
- MEND
- ;
- m080: MENU "080",10,35,080
- option "Black\Magenta",lb
- MEND
- ;
- m081: MENU "081",10,35,081
- option "Blue\Magenta",lb
- MEND
- ;
- m082: MENU "082",10,35,082
- option "Green\Magenta",lb
- MEND
- ;
- m083: MENU "083",10,35,083
- option "Cyan\Magenta",lb
- MEND
- ;
- m084: MENU "084",10,35,084
- option "Red\Magenta",lb
- MEND
- ;
- m085: MENU "085",10,35,085
- option "Magenta\Magenta",lb
- MEND
- ;
- m086: MENU "086",10,35,086
- option "Brown\Magenta",lb
- MEND
- ;
- m087: MENU "087",10,35,087
- option "White\Magenta",lb
- MEND
- ;
- m088: MENU "088",10,35,088
- option "Gray\Magenta",lb
- MEND
- ;
- m089: MENU "089",10,35,089
- option "Lt. Blue\Magenta",lb
- MEND
- ;
- m090: MENU "090",10,35,090
- option "Lt. Green\Magenta",lb
- MEND
- ;
- m091: MENU "091",10,35,091
- option "Lt. Cyan\Magenta",lb
- MEND
- ;
- m092: MENU "092",10,35,092
- option "Lt. Red\Magenta",lb
- MEND
- ;
- m093: MENU "093",10,35,093
- option "Lt. Magenta\Magenta",lb
- MEND
- ;
- m094: MENU "094",10,35,094
- option "Yellow\Magenta",lb
- MEND
- ;
- m095: MENU "095",10,35,095
- option "Hi-int. White\Magenta",lb
- MEND
- ;
- m096: MENU "096",10,35,096
- option "Black\Brown",lb
- MEND
- ;
- m097: MENU "097",10,35,097
- option "Blue\Brown",lb
- MEND
- ;
- m098: MENU "098",10,35,098
- option "Green\Brown",lb
- MEND
- ;
- m099: MENU "099",10,35,099
- option "Cyan\Brown",lb
- MEND
- ;
- m100: MENU "100",10,35,100
- option "Red\Brown",lb
- MEND
- ;
- m101: MENU "101",10,35,101
- option "Magenta\Brown",lb
- MEND
- ;
- m102: MENU "102",10,35,102
- option "Brown\Brown",lb
- MEND
- ;
- m103: MENU "103",10,35,103
- option "White\Brown",lb
- MEND
- ;
- m104: MENU "104",10,35,104
- option "Gray\Brown",lb
- MEND
- ;
- m105: MENU "105",10,35,105
- option "Lt. Blue\Brown",lb
- MEND
- ;
- m106: MENU "106",10,35,106
- option "Lt. Green\Brown",lb
- MEND
- ;
- m107: MENU "107",10,35,107
- option "Lt. Cyan\Brown",lb
- MEND
- ;
- m108: MENU "108",10,35,108
- option "Lt. Red\Brown",lb
- MEND
- ;
- m109: MENU "109",10,35,109
- option "Lt. Magenta\Brown",lb
- MEND
- ;
- m110: MENU "110",10,35,110
- option "Yellow\Brown",lb
- MEND
- ;
- m111: MENU "111",10,35,111
- option "Hi-int. White\Brown",lb
- MEND
- ;
- m112: MENU "112",10,35,112
- option "Black\White",lb
- MEND
- ;
- m113: MENU "113",10,35,113
- option "Blue\White",lb
- MEND
- ;
- m114: MENU "114",10,35,114
- option "Green\White",lb
- MEND
- ;
- m115: MENU "115",10,35,115
- option "Cyan\White",lb
- MEND
- ;
- m116: MENU "116",10,35,116
- option "Red\White",lb
- MEND
- ;
- m117: MENU "117",10,35,117
- option "Magenta\White",lb
- MEND
- ;
- m118: MENU "118",10,35,118
- option "Brown\White",lb
- MEND
- ;
- m119: MENU "119",10,35,119
- option "White\White",lb
- MEND
- ;
- m120: MENU "120",10,35,120
- option "Gray\White",lb
- MEND
- ;
- m121: MENU "121",10,35,121
- option "Lt. Blue\White",lb
- MEND
- ;
- m122: MENU "122",10,35,122
- option "Lt. Green\White",lb
- MEND
- ;
- m123: MENU "123",10,35,123
- option "Lt. Cyan\White",lb
- MEND
- ;
- m124: MENU "124",10,35,124
- option "Lt. Red\White",lb
- MEND
- ;
- m125: MENU "125",10,35,125
- option "Lt. Magenta\White",lb
- MEND
- ;
- m126: MENU "126",10,35,126
- option "Yellow\White",lb
- MEND
- ;
- m127: MENU "127",10,35,127
- option "Hi-int White\White",lb
- MEND
- ;
- m128: MENU "128",10,35,128
- option "Black\Gray",lb
- MEND
- ;
- m129: MENU "129",10,35,129
- option "Blue\Gray",lb
- MEND
- ;
- m130: MENU "130",10,35,130
- option "Green\Gray",lb
- MEND
- ;
- m131: MENU "131",10,35,131
- option "Cyan\Gray",lb
- MEND
- ;
- m132: MENU "132",10,35,132
- option "Red\Gray",lb
- MEND
- ;
- m133: MENU "133",10,35,133
- option "Magenta\Gray",lb
- MEND
- ;
- m134: MENU "134",10,35,134
- option "Brown\Gray",lb
- MEND
- ;
- m135: MENU "135",10,35,135
- option "White\Gray",lb
- MEND
- ;
- m136: MENU "136",10,35,136
- option "Gray\Gray",lb
- MEND
- ;
- m137: MENU "137",10,35,137
- option "Lt. Blue\Gray",lb
- MEND
- ;
- m138: MENU "138",10,35,138
- option "Lt. Green\Gray",lb
- MEND
- ;
- m139: MENU "139",10,35,139
- option "Lt. Cyan\Gray",lb
- MEND
- ;
- m140: MENU "140",10,35,140
- option "Lt. Red\Gray",lb
- MEND
- ;
- m141: MENU "141",10,35,141
- option "Lt. Magenta\Gray",lb
- MEND
- ;
- m142: MENU "142",10,35,142
- option "Yellow\Gray",lb
- MEND
- ;
- m143: MENU "143",10,35,143
- option "Hi-int. White\Gray",lb
- MEND
- ;
- m144: MENU "144",10,35,144
- option "Black\Lt. Blue",lb
- MEND
- ;
- m145: MENU "145",10,35,145
- option "Blue\Lt. Blue",lb
- MEND
- ;
- m146: MENU "146",10,35,146
- option "Green\Lt. Blue",lb
- MEND
- ;
- m147: MENU "147",10,35,147
- option "Cyan\Lt. Blue",lb
- MEND
- ;
- m148: MENU "148",10,35,148
- option "Red\Lt. Blue",lb
- MEND
- ;
- m149: MENU "149",10,35,149
- option "Magenta\Lt. Blue",lb
- MEND
- ;
- m150: MENU "150",10,35,150
- option "Brown\Lt. Blue",lb
- MEND
- ;
- m151: MENU "151",10,35,151
- option "White\Lt. Blue",lb
- MEND
- ;
- m152: MENU "152",10,35,152
- option "Gray\Lt. Blue",lb
- MEND
- ;
- m153: MENU "153",10,35,153
- option "Lt. Blue\Lt. Blue",lb
- MEND
- ;
- m154: MENU "154",10,35,154
- option "Lt. Green\Lt. Blue",lb
- MEND
- ;
- m155: MENU "155",10,35,155
- option "Lt. Cyan\Lt. Blue",lb
- MEND
- ;
- m156: MENU "156",10,35,156
- option "Lt. Red\Lt. Blue",lb
- MEND
- ;
- m157: MENU "157",10,35,157
- option "Lt. Magenta\Lt. Blue",lb
- MEND
- ;
- m158: MENU "158",10,35,158
- option "Yellow\Lt. Blue",lb
- MEND
- ;
- m159: MENU "159",10,35,159
- option "Hi-int. White\Lt. Blue",lb
- MEND
- ;
- m160: MENU "160",10,35,160
- option "Black\Lt. Green",lb
- MEND
- ;
- m161: MENU "161",10,35,161
- option "Blue\Lt. Green",lb
- MEND
- ;
- m162: MENU "162",10,35,162
- option "Green\Lt. Green",lb
- MEND
- ;
- m163: MENU "163",10,35,163
- option "Cyan\Lt. Green",lb
- MEND
- ;
- m164: MENU "164",10,35,164
- option "Red\Lt. Green",lb
- MEND
- ;
- m165: MENU "165",10,35,165
- option "Magenta\Lt. Green",lb
- MEND
- ;
- m166: MENU "166",10,35,166
- option "Brown\Lt. Green",lb
- MEND
- ;
- m167: MENU "167",10,35,167
- option "White\Lt. Green",lb
- MEND
- ;
- m168: MENU "168",10,35,168
- option "Gray\Lt. Green",lb
- MEND
- ;
- m169: MENU "169",10,35,169
- option "Lt. Blue\Lt. Green",lb
- MEND
- ;
- m170: MENU "170",10,35,170
- option "Lt. Green\Lt. Green",lb
- MEND
- ;
- m171: MENU "171",10,35,171
- option "Lt. Cyan\Lt. Green",lb
- MEND
- ;
- m172: MENU "172",10,35,172
- option "Lt. Red\Lt. Green",lb
- MEND
- ;
- m173: MENU "173",10,35,173
- option "Lt. Magenta\Lt. Green",lb
- MEND
- ;
- m174: MENU "174",10,35,174
- option "Yellow\Lt. Green",lb
- MEND
- ;
- m175: MENU "175",10,35,175
- option "Hi-int. White\Lt. Green",lb
- MEND
- ;
- m176: MENU "176",10,35,176
- option "Black\Lt. Cyan",lb
- MEND
- ;
- m177: MENU "177",10,35,177
- option "Blue\Lt. Cyan",lb
- MEND
- ;
- m178: MENU "178",10,35,178
- option "Green\Lt. Cyan",lb
- MEND
- ;
- m179: MENU "179",10,35,179
- option "Cyan\Lt. Cyan",lb
- MEND
- ;
- m180: MENU "180",10,35,180
- option "Red\Lt. Cyan",lb
- MEND
- ;
- m181: MENU "181",10,35,181
- option "Magenta\Lt. Cyan",lb
- MEND
- ;
- m182: MENU "182",10,35,182
- option "Brown\Lt. Cyan",lb
- MEND
- ;
- m183: MENU "183",10,35,183
- option "White\Lt. Cyan",lb
- MEND
- ;
- m184: MENU "184",10,35,184
- option "Gray\Lt. Cyan",lb
- MEND
- ;
- m185: MENU "185",10,35,185
- option "Lt. Blue\Lt. Cyan",lb
- MEND
- ;
- m186: MENU "186",10,35,186
- option "Lt. Green\Lt. Cyan",lb
- MEND
- ;
- m187: MENU "187",10,35,187
- option "Lt. Cyan\Lt. Cyan",lb
- MEND
- ;
- m188: MENU "188",10,35,188
- option "Lt. Red\Lt. Cyan",lb
- MEND
- ;
- m189: MENU "189",10,35,189
- option "Lt. Magenta\Lt. Cyan",lb
- MEND
- ;
- m190: MENU "190",10,35,190
- option "Yellow\Lt. Cyan",lb
- MEND
- ;
- m191: MENU "191",10,35,191
- option "Hi-int. White\Lt. Cyan",lb
- MEND
- ;
- m192: MENU "192",10,35,192
- option "Black\Lt. Red",lb
- MEND
- ;
- m193: MENU "193",10,35,193
- option "Blue\Lt. Red",lb
- MEND
- ;
- m194: MENU "194",10,35,194
- option "Green\Lt. Red",lb
- MEND
- ;
- m195: MENU "195",10,35,195
- option "Cyan\Lt. Red",lb
- MEND
- ;
- m196: MENU "196",10,35,196
- option "Red\Lt. Red",lb
- MEND
- ;
- m197: MENU "197",10,35,197
- option "Magenta\Lt. Red",lb
- MEND
- ;
- m198: MENU "198",10,35,198
- option "Brown\Lt. Red",lb
- MEND
- ;
- m199: MENU "199",10,35,199
- option "White\Lt. Red",lb
- MEND
- ;
- m200: MENU "200",10,35,200
- option "Gray\Lt. Red",lb
- MEND
- ;
- m201: MENU "201",10,35,201
- option "Lt. Blue\Lt. Red",lb
- MEND
- ;
- m202: MENU "202",10,35,202
- option "Lt. Green\Lt. Red",lb
- MEND
- ;
- m203: MENU "203",10,35,203
- option "Lt. Cyan\Lt. Red",lb
- MEND
- ;
- m204: MENU "204",10,35,204
- option "Lt. Red\Lt. Red",lb
- MEND
- ;
- m205: MENU "205",10,35,205
- option "Lt. Magenta\Lt. Red",lb
- MEND
- ;
- m206: MENU "206",10,35,206
- option "Yellow\Lt. Red",lb
- MEND
- ;
- m207: MENU "207",10,35,207
- option "Hi-int. White\Lt. Red",lb
- MEND
- ;
- m208: MENU "208",10,35,208
- option "Black\Lt. Magenta",lb
- MEND
- ;
- m209: MENU "209",10,35,209
- option "Blue\Lt. Magenta",lb
- MEND
- ;
- m210: MENU "210",10,35,210
- option "Green\Lt. Magenta",lb
- MEND
- ;
- m211: MENU "211",10,35,211
- option "Cyan\Lt. Magenta",lb
- MEND
- ;
- m212: MENU "212",10,35,212
- option "Red\Lt. Magenta",lb
- MEND
- ;
- m213: MENU "213",10,35,213
- option "Magenta\Lt. Magenta",lb
- MEND
- ;
- m214: MENU "214",10,35,214
- option "Brown\Lt. Magenta",lb
- MEND
- ;
- m215: MENU "215",10,35,215
- option "White\Lt. Magenta",lb
- MEND
- ;
- m216: MENU "216",10,35,216
- option "Gray\Lt. Magenta",lb
- MEND
- ;
- m217: MENU "217",10,35,217
- option "Lt. Blue\Lt. Magenta",lb
- MEND
- ;
- m218: MENU "218",10,35,218
- option "Lt. Green\Lt. Magenta",lb
- MEND
- ;
- m219: MENU "219",10,35,219
- option "Lt. Cyan\Lt. Magenta",lb
- MEND
- ;
- m220: MENU "220",10,35,220
- option "Lt. Red\Lt. Magenta",lb
- MEND
- ;
- m221: MENU "221",10,35,221
- option "Lt. Magenta\Lt. Magenta",lb
- MEND
- ;
- m222: MENU "222",10,35,222
- option "Yellow\Lt. Magenta",lb
- MEND
- ;
- m223: MENU "223",10,35,223
- option "Hi-int. White\Lt. Magenta",lb
- MEND
- ;
- m224: MENU "224",10,35,224
- option "Black\Yellow",lb
- MEND
- ;
- m225: MENU "225",10,35,225
- option "Blue\Yellow",lb
- MEND
- ;
- m226: MENU "226",10,35,226
- option "Green\Yellow",lb
- MEND
- ;
- m227: MENU "227",10,35,227
- option "Cyan\Yellow",lb
- MEND
- ;
- m228: MENU "228",10,35,228
- option "Red\Yellow",lb
- MEND
- ;
- m229: MENU "229",10,35,229
- option "Magenta\Yellow",lb
- MEND
- ;
- m230: MENU "230",10,35,230
- option "Brown\Yellow",lb
- MEND
- ;
- m231: MENU "231",10,35,231
- option "White\Yellow",lb
- MEND
- ;
- m232: MENU "232",10,35,232
- option "Gray\Yellow",lb
- MEND
- ;
- m233: MENU "233",10,35,233
- option "Lt. Blue\Yellow",lb
- MEND
- ;
- m234: MENU "234",10,35,234
- option "Lt. Green\Yellow",lb
- MEND
- ;
- m235: MENU "235",10,35,235
- option "Lt. Cyan\Yellow",lb
- MEND
- ;
- m236: MENU "236",10,35,236
- option "Lt. Red\Yellow",lb
- MEND
- ;
- m237: MENU "237",10,35,237
- option "Lt. Magenta\Yellow",lb
- MEND
- ;
- m238: MENU "238",10,35,238
- option "Yellow\Yellow",lb
- MEND
- ;
- m239: MENU "239",10,35,239
- option "Hi-int. White\Yellow",lb
- MEND
- ;
- m240: MENU "240",10,35,240
- option "Black\Hi-int. White",lb
- MEND
- ;
- m241: MENU "241",10,35,241
- option "Blue\Hi-int. White",lb
- MEND
- ;
- m242: MENU "242",10,35,242
- option "Green\Hi-int. White",lb
- MEND
- ;
- m243: MENU "243",10,35,243
- option "Cyan\Hi-int. White",lb
- MEND
- ;
- m244: MENU "244",10,35,244
- option "Red\Hi-int. White",lb
- MEND
- ;
- m245: MENU "245",10,35,245
- option "Magenta\Hi-int. White",lb
- MEND
- ;
- m246: MENU "246",10,35,246
- option "Brown\Hi-int. White",lb
- MEND
- ;
- m247: MENU "247",10,35,247
- option "White\Hi-int. White",lb
- MEND
- ;
- m248: MENU "248",10,35,248
- option "Gray\Hi-int. White",lb
- MEND
- ;
- m249: MENU "249",10,35,249
- option "Lt. Blue\Hi-int. White",lb
- MEND
- ;
- m250: MENU "250",10,35,250
- option "Lt. Green\Hi-int. White",lb
- MEND
- ;
- m251: MENU "251",10,35,251
- option "Lt. Cyan\Hi-int. White",lb
- MEND
- ;
- m252: MENU "252",10,35,252
- option "Lt. Red\Hi-int. White",lb
- MEND
- ;
- m253: MENU "253",10,35,253
- option "Lt. Magenta\Hi-int. White",lb
- MEND
- ;
- m254: MENU "254",10,35,254
- option "Yellow\Hi-int. White",lb
- MEND
- ;
- m255: MENU "255",10,35,255
- option "Hi-int. White\Hi-int. White",lb
- MEND
- ;
-
- \SAMPCODE\MOUSE\SOURCES\DROP.DEF
-
- ; SAMPLE Microsoft Mouse 'DROP' MENU
- ;
- ; Note: Please review the comments below before you compile
- ; and use this source file as a mouse menu.
-
- ; The DROP mouse menu demonstrates how to create 'drop-
- ; down' menus.
- ;
- ; Clicking a mouse button when the cursor is on the main
- ; menu (drop1) will display a drop-down menu (except in the
- ; case of the 'CLR SCRN' field, which will cause a screen-
- ; clear command to be executed).
- ;
- ; Clicking a mouse button when the cursor is on the top
- ; entry of a drop-down menu will redisplay the main menu.
- ;
- ; Since the entire area underneath the main menu will be
- ; written over by each drop-down menu, you should use a
- ; BLACK background for this type of mouse menu.
- ;
- ; When you choose a drop-down menu, the initial position of
- ; the cursor is always the upper-left corner of the area
- ; defined by the set of SELECT statements associated with
- ; the menu.
- ;
- ;
- BEGIN lb
- ;
- lb: execute drop1
- rb: execute drop2
- bb: execute drop3
- nul: nothing
- ;
- drop1: POPUP 1,40,NORMAL
- text "╔══════════╤══════════╤══════════╗"
- text "║ CLR SCRN │ LIST DIR │ CH DRIVE ║"
- text "╚══════════╧══════════╧══════════╝"
- select 2,2,10,cls
- select 2,13,10,rb
- select 2,24,10,bb
- PEND
- ;
- cls: type "cls",enter
- ;
- drop2: POPUP 1,40,NORMAL
- text "╔══════════╦══════════╦══════════╗"
- text "║ CLR SCRN ║ LIST DIR ║ CH DRIVE ║"
- text "╚══════════╬══════════╬══════════╝"
- text " ║ dir ║"
- text " ║ *.bat ║"
- text " ║ *.com ║"
- text " ║ *.doc ║"
- text " ║ *.exe ║"
- text " ║ *.sys ║"
- text " ║ CANCEL ║"
- text " ╚══════════╝"
- select 2,13,10,lb
- select 3,13,10,rb
- select 4,13,10,dir
- select 5,13,10,dirb
- select 6,13,10,dirc
- select 7,13,10,dird
- select 8,13,10,dire
- select 9,13,10,dirs
- select 10,13,10,nul
- PEND
- ;
- dir: type "dir",enter
- dirb: type "dir *.bat",enter
- dirc: type "dir *.com",enter
- dird: type "dir *.doc",enter
- dire: type "dir *.exe",enter
- dirs: type "dir *.sys",enter
- ;
- drop3: POPUP 1,40,NORMAL
- text "╔══════════╤══════════╦══════════╗"
- text "║ CLR SCRN │ LIST DIR ║ CH DRIVE ║"
- text "╚══════════╧══════════╬══════════╣"
- text " ║ A: ║"
- text " ║ B: ║"
- text " ║ C: ║"
- text " ║ CANCEL ║"
- text " ╚══════════╝"
- select 2,24,10,lb
- select 3,24,10,bb
- select 4,24,10,a
- select 5,24,10,b
- select 6,24,10,c
- select 7,24,10,nul
- PEND
- ;
- a: type "A:",enter,"cls",enter,enter
- b: type "B:",enter,"cls",enter,enter
- c: type "C:",enter,"cls",enter,enter
- ;
-
- \SAMPCODE\MOUSE\SOURCES\EXECUTE1.DEF
-
- ; SAMPLE Microsoft Mouse `EXECUTE1' MENU
- ;
- ; NOTE: Please review the comments below before you compile
- ; and use this source file as a mouse menu.
- ;
- ; The EXECUTE1 menu provides an example of the functional
- ; limitations of the Microsoft Mouse EXECUTE statement.
- ;
- ; This example calls a label from a menu (menu1), where the
- ; label (run:) specifies that two commands be executed (cls
- ; & menu2). The label 'cls:' causes a 'cls<return>'
- ; sequence to be sent to the keyboard buffer, after which
- ; 'menu2:'is run.
- ;
- ; Running the menu appears to yield the opposite order of
- ; operations. That is, the 'cls<enter>' command is executed
- ; AFTER 'menu2:' terminates. The keystrokes 'cls<enter>'
- ; are sent to the keyboard buffer BEFORE 'menu2:' is
- ; executed, but since the menu has not relinquished control
- ; to DOS, they are not immediately acted upon.
- ;
- ; Note: See the file EXECUTE2.DEF for a related example.
- ;
- ;
- BEGIN lb
-
- lb: execute menu1
-
- menu1: MENU " sample 'execute' function menu (1)",1,40,NORMAL
- option " clear the screen, and run menu2 ",run
- MEND
- ;
- run: execute cls,menu2
- ;
- menu2: MENU " sample 'execute' function menu (2)",1,40,NORMAL
- option " do nothing ",nul
- MEND
- ;
- cls: type "cls",enter
- nul: nothing
- ;
-
- \SAMPCODE\MOUSE\SOURCES\EXECUTE2.DEF
-
- ; SAMPLE Microsoft Mouse `EXECUTE2' MENU
- ;
- ; NOTE: Review the comments below before you compile
- ; and use this source file as a mouse menu.
- ;
- ; The EXECUTE2 menu provides an example of 'semi-automatic'
- ; mouse menu activation. It demonstrates how you can
- ; achieve subtle interaction between certain types of mouse
- ; menu 'event trapping' (especially with mouse motion/MATCH
- ; statement trapping). This menu runs at the DOS level.
- ; The comments included in the source code explain the
- ; necessary complexity of the menu.
-
- ; EXECUTE2 has two levels of menus. The first menu is
- ; activated by clicking a mouse button, and sets up the
- ; conditions for entry into the second menu (horizontal
- ; mouse motion combined with particular screen display
- ; conditions). Exiting the second menu ensures that the
- ; proper conditions are set up for the first menu.
- ;
- ; The major reason for this menu's complexity is the speed
- ; at which mouse motion trapping occurs. If the entry and
- ; exit conditions around the second menu are cut down, the
- ; second menu may become active before the DOS 'cls'
- ; statement is COMPLETELY processed. In addition, mouse
- ; motion in conjunction with a mouse button click within the
- ; second menu could cause the second menu to be redisplayed
- ; (this would occur if the 'cln:' "ASSIGN" statement was
- ; EXECUTED upon exiting menu2).
- ;
- ; When working with menus with this style of user
- ; interaction, ALL input and output conditions must be
- ; thoroughly analyzed and accommodated. Otherwise, the
- ; intended entry conditions may be violated.
- ;
- ;
- BEGIN lb,nul,nul,nul,nul,nul,nul,32,16 ;left button is the only
- ;entry into the initial menu
- ;
- lb: execute menu1
- ;
- menu1: MENU " sample 'match' function menu (1)",1,40,NORMAL
- option " clear the screen, and run menu2 ",set
- MEND
- ;
- set: execute cls,asn,nul ;'cls:' clears the screen
- ;'asn:' reassigns the menu
- ; entry to allow horizontal
- ; mouse motion to trigger the
- ; second menu.
- ;'nul:' is a "do nothing"
- ;
- cls: type "cls",enter
- asn: ASSIGN lb,nul,nul,chk,chk,nul,nul,32,16
- nul: nothing
- ;
- chk: MATCH 2,0,NORMAL,32,res,nul ;When horizontal mouse motion
- ; is detected, this statement
- ; looks for a SPACE character
- ; at the left margin of the
- ; second line of the display,
- ; indicating that the DOS 'cls'
- ; command is complete...
- ;
- res: EXECUTE clr,menu2 ;When 'chk:' is satisfied, this
- ; will cause the horizontal
- ; motion sensitivity to be
- ; low, and reassigns all motion
- ; trapping to a 'do nothing'
- ; state, disallowing REENTRY
- ; into the second menu (menu2).
- ;
- clr: ASSIGN lb,nul,nul,nul,nul,nul,nul,5000,16
- menu2: MENU " sample 'execute' function menu (2)",1,40,NORMAL
- option " do nothing ",org
- option " do nothing ",org
- MEND
- ;
- org: execute cln,zip ;This will reset the menu
- ; parameters to the original
- ; state at menu load-time,
- ; and makes sure that there
- ; is something other than
- ; a SPACE at the left margin
- ; of line 2 of the display
- ; (depending on the DOS
- ; PROMPT configuration)
- ; - this will disallow early
- ; entry into 'menu2' after
- ; subsequent entry into
- ; menu1.
- ;
- cln: ASSIGN lb,nul,nul,nul,nul,nul,nul,32,16
- zip: type enter
- ;
-
- \SAMPCODE\MOUSE\SOURCES\KBD.DEF
-
- ; SAMPLE Microsoft Mouse `KEYBOARD EMULATION' MENU
- ;
- ; NOTE: Please review the comments below before you compile
- ; and use this source file as a mouse menu.
- ;
- ; This menu is designed to provide a partial keyboard
- ; emulation. Not all usable keystrokes are emulated.
- ; The <ALT> and <SHIFT> function keys are not implemented.
- ; <CTRL> plus PrtSc, Home, the left or right cursor key,
- ; End, and PgDn are not implemented. <ALT> plus 1 through
- ; 9, -, =, and uppercase ASCII are also not implemented.
- ;
- ; Most of the SELECT statements (except in the
- ; case of the function keys) work from single screen
- ; locations. You can modify the third SELECT parameter to
- ; specify wider selection fields. However, make sure each
- ; screen position does not have more than one SELECT
- ; statement defining it.
-
- ; This menu is displayed when you click a mouse button.
- ; Double clicking a menu item puts the selected character
- ; into the keyboard buffer, then reactivates the menu.
-
- ; Please note that the 'control character' menu shown below
- ; will send ANY ASCII control code to the console. Use of
- ; some codes under certain programs may cause operational
- ; difficulties. In particular, use the 'SUB' code
- ; carefully. SUB is the normal 'end-of-file' marker, or
- ; 'control-Z.' Sending this code to the console (display)
- ; within an application that is performing stream I/O to the
- ; standard output device (CON or 'stdout') may terminate
- ; communications.
- ;
- ; This menu has been provided for illustrative purposes,
- ; and is not intended as a replacement for the keyboard.
- ; It is not efficient for typing anything but the simplest
- ; character sequences.
- ;
- ;
- BEGIN nulx,ctrl,nula
-
- nulx: execute kpop ;run the 'keyboard' menu if the
- ;left button was clicked
- ctrl: execute cpop ;run the 'control keys' menu if
- ;the right button was clicked
- nula: execute gpop ;run the 'graphics' character menu
- ;if both buttons were clicked.
-
- kpop: POPUP 2,40,NORMAL ;this is the 'keyboard' menu
- text "╔════╦════╤════╦═══════╦═══╦════╗"
- text "║quit║Ctrl│Symb║ Enter ║Ins║Del ║"
- text "╠═╤═╤╩╤═╤═╪═╤═╤╩╤═╤═╤═╤╩╤═╤╩╤═╤═╣"
- text "║@│A│B│C│D│E│F│G│H│I│J│K│L│M│N│O║"
- text "║P│Q│R│S│T│U│V│W│X│Y│Z│[│\│^│]│^║"
- text "║`│a│b│c│d│e│f│g│h│i│j│k│l│m│n│o║"
- text "║p│q│r│s│t│u│v│w│x│y│z│{│|│}│~│·║"
- text "║─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴╔╧═╧═╣"
- text "║ spacebar ║ BS ║"
- text "║─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬╚╤═╤═╣"
- text "║ │!│ │#│$│%│&│'│(│)│*│+│,│-│.│/║"
- text "║0│1│2│3│4│5│6│7│8│9│:│;│<│=│>│?║"
- text "║═╧═╧═╧═╧═╧═╧═╧═╧═╧═╧═╧═╧═╧═╧═╧═╣"
- text "║ h p │ f1 f2 f3 f4 f5 ║"
- text "║ · │ f6 f8 f8 f9 f10 ║"
- text "║ e d ╔═══════════════════════╝"
- text "╚═══════╝"
- ;here are the SELECT statements
- ;for the 'keyboard' menu.
- select 2,2,1,quit
- select 2,3,1,quit
- select 2,4,1,quit
- select 2,5,1,quit
- select 2,6,1,nulx
- select 2,7,1,ctrl
- select 2,8,1,ctrl
- select 2,9,1,ctrl
- select 2,10,1,ctrl
- select 2,11,1,nulx
- select 2,12,1,nula
- select 2,13,1,nula
- select 2,14,1,nula
- select 2,15,1,nula
- select 2,16,1,nulx
- select 2,17,1,x13
- select 2,18,1,x13
- select 2,19,1,x13
- select 2,20,1,x13
- select 2,21,1,x13
- select 2,22,1,x13
- select 2,23,1,x13
- select 2,24,1,nulx
- select 2,25,1,ins
- select 2,26,1,ins
- select 2,27,1,ins
- select 2,28,1,nulx
- select 2,29,1,del
- select 2,30,1,del
- select 2,31,1,del
- select 2,32,1,nulx
- select 3,2,1,nulx
- select 3,3,1,nulx
- select 3,4,1,nulx
- select 3,5,1,nulx
- select 3,6,1,nulx
- select 3,7,1,nulx
- select 3,8,1,nulx
- select 3,9,1,nulx
- select 3,10,1,nulx
- select 3,11,1,nulx
- select 3,12,1,nulx
- select 3,13,1,nulx
- select 3,14,1,nulx
- select 3,15,1,nulx
- select 3,16,1,nulx
- select 3,17,1,nulx
- select 3,18,1,nulx
- select 3,19,1,nulx
- select 3,20,1,nulx
- select 3,21,1,nulx
- select 3,22,1,nulx
- select 3,23,1,nulx
- select 3,24,1,nulx
- select 3,25,1,nulx
- select 3,26,1,nulx
- select 3,27,1,nulx
- select 3,28,1,nulx
- select 3,29,1,nulx
- select 3,30,1,nulx
- select 3,31,1,nulx
- select 3,32,1,nulx
- select 4,2,1,x64
- select 4,3,1,nulx
- select 4,4,1,x65
- select 4,5,1,nulx
- select 4,6,1,x66
- select 4,7,1,nulx
- select 4,8,1,x67
- select 4,9,1,nulx
- select 4,10,1,x68
- select 4,11,1,nulx
- select 4,12,1,x69
- select 4,13,1,nulx
- select 4,14,1,x70
- select 4,15,1,nulx
- select 4,16,1,x71
- select 4,17,1,nulx
- select 4,18,1,x72
- select 4,19,1,nulx
- select 4,20,1,x73
- select 4,21,1,nulx
- select 4,22,1,x74
- select 4,23,1,nulx
- select 4,24,1,x75
- select 4,25,1,nulx
- select 4,26,1,x76
- select 4,27,1,nulx
- select 4,28,1,x77
- select 4,29,1,nulx
- select 4,30,1,x78
- select 4,31,1,nulx
- select 4,32,1,x79
- select 5,2,1,x80
- select 5,3,1,nulx
- select 5,4,1,x81
- select 5,5,1,nulx
- select 5,6,1,x82
- select 5,7,1,nulx
- select 5,8,1,x83
- select 5,9,1,nulx
- select 5,10,1,x84
- select 5,11,1,nulx
- select 5,12,1,x85
- select 5,13,1,nulx
- select 5,14,1,x86
- select 5,15,1,nulx
- select 5,16,1,x87
- select 5,17,1,nulx
- select 5,18,1,x88
- select 5,19,1,nulx
- select 5,20,1,x89
- select 5,21,1,nulx
- select 5,22,1,x90
- select 5,23,1,nulx
- select 5,24,1,x91
- select 5,25,1,nulx
- select 5,26,1,x92
- select 5,27,1,nulx
- select 5,28,1,x93
- select 5,29,1,nulx
- select 5,30,1,x94
- select 5,31,1,nulx
- select 5,32,1,x95
- select 6,2,1,x96
- select 6,3,1,nulx
- select 6,4,1,x97
- select 6,5,1,nulx
- select 6,6,1,x98
- select 6,7,1,nulx
- select 6,8,1,x99
- select 6,9,1,nulx
- select 6,10,1,x100
- select 6,11,1,nulx
- select 6,12,1,x101
- select 6,13,1,nulx
- select 6,14,1,x102
- select 6,15,1,nulx
- select 6,16,1,x103
- select 6,17,1,nulx
- select 6,18,1,x104
- select 6,19,1,nulx
- select 6,20,1,x105
- select 6,21,1,nulx
- select 6,22,1,x106
- select 6,23,1,nulx
- select 6,24,1,x107
- select 6,25,1,nulx
- select 6,26,1,x108
- select 6,27,1,nulx
- select 6,28,1,x109
- select 6,29,1,nulx
- select 6,30,1,x110
- select 6,31,1,nulx
- select 6,32,1,x111
- select 7,2,1,x112
- select 7,3,1,nulx
- select 7,4,1,x113
- select 7,5,1,nulx
- select 7,6,1,x114
- select 7,7,1,nulx
- select 7,8,1,x115
- select 7,9,1,nulx
- select 7,10,1,x116
- select 7,11,1,nulx
- select 7,12,1,x117
- select 7,13,1,nulx
- select 7,14,1,x118
- select 7,15,1,nulx
- select 7,16,1,x119
- select 7,17,1,nulx
- select 7,18,1,x120
- select 7,19,1,nulx
- select 7,20,1,x121
- select 7,21,1,nulx
- select 7,22,1,x122
- select 7,23,1,nulx
- select 7,24,1,x123
- select 7,25,1,nulx
- select 7,26,1,x124
- select 7,27,1,nulx
- select 7,28,1,x125
- select 7,29,1,nulx
- select 7,30,1,x126
- select 7,31,1,nulx
- select 7,32,1,x127
- select 8,2,1,nulx
- select 8,3,1,nulx
- select 8,4,1,nulx
- select 8,5,1,nulx
- select 8,6,1,nulx
- select 8,7,1,nulx
- select 8,8,1,nulx
- select 8,9,1,nulx
- select 8,10,1,nulx
- select 8,11,1,nulx
- select 8,12,1,nulx
- select 8,13,1,nulx
- select 8,14,1,nulx
- select 8,15,1,nulx
- select 8,16,1,nulx
- select 8,17,1,nulx
- select 8,18,1,nulx
- select 8,19,1,nulx
- select 8,20,1,nulx
- select 8,21,1,nulx
- select 8,22,1,nulx
- select 8,23,1,nulx
- select 8,24,1,nulx
- select 8,25,1,nulx
- select 8,26,1,nulx
- select 8,27,1,nulx
- select 8,28,1,nulx
- select 8,29,1,nulx
- select 8,30,1,nulx
- select 8,31,1,nulx
- select 8,32,1,nulx
- select 9,2,1,x32
- select 9,3,1,x32
- select 9,4,1,x32
- select 9,5,1,x32
- select 9,6,1,x32
- select 9,7,1,x32
- select 9,8,1,x32
- select 9,9,1,x32
- select 9,10,1x32
- select 9,11,1,x32
- select 9,12,1,x32
- select 9,13,1,x32
- select 9,14,1,x32
- select 9,15,1,x32
- select 9,16,1,x32
- select 9,17,1,x32
- select 9,18,1,x32
- select 9,19,1,x32
- select 9,20,1,x32
- select 9,21,1,x32
- select 9,22,1,x32
- select 9,23,1,x32
- select 9,24,1,x32
- select 9,25,1,x32
- select 9,26,1,x32
- select 9,27,1,x32
- select 9,28,1,nulx
- select 9,29,1,x8
- select 9,30,1,x8
- select 9,31,1,x8
- select 9,32,1,x8
- select 10,2,1,nulx
- select 10,3,1,nulx
- select 10,4,1,nulx
- select 10,5,1,nulx
- select 10,6,1,nulx
- select 10,7,1,nulx
- select 10,8,1,nulx
- select 10,9,1,nulx
- select 10,10,1,nulx
- select 10,11,1,nulx
- select 10,12,1,nulx
- select 10,13,1,nulx
- select 10,14,1,nulx
- select 10,15,1,nulx
- select 10,16,1,nulx
- select 10,17,1,nulx
- select 10,18,1,nulx
- select 10,19,1,nulx
- select 10,20,1,nulx
- select 10,21,1,nulx
- select 10,22,1,nulx
- select 10,23,1,nulx
- select 10,24,1,nulx
- select 10,25,1,nulx
- select 10,26,1,nulx
- select 10,27,1,nulx
- select 10,28,1,nulx
- select 10,29,1,nulx
- select 10,30,1,nulx
- select 10,31,1,nulx
- select 10,32,1,nulx
- select 11,2,1,x32
- select 11,3,1,nulx
- select 11,4,1,x33
- select 11,5,1,nulx
- select 11,6,1,x34
- select 11,7,1,nulx
- select 11,8,1,x35
- select 11,9,1,nulx
- select 11,10,1,x36
- select 11,11,1,nulx
- select 11,12,1,x37
- select 11,13,1,nulx
- select 11,14,1,x38
- select 11,15,1,nulx
- select 11,16,1,x39
- select 11,17,1,nulx
- select 11,18,1,x40
- select 11,19,1,nulx
- select 11,20,1,x41
- select 11,21,1,nulx
- select 11,22,1,x42
- select 11,23,1,nulx
- select 11,24,1,x43
- select 11,25,1,nulx
- select 11,26,1,x44
- select 11,27,1,nulx
- select 11,28,1,x45
- select 11,29,1,nulx
- select 11,30,1,x46
- select 11,31,1,nulx
- select 11,32,1,x47
- select 12,2,1,x48
- select 12,3,1,nulx
- select 12,4,1,x49
- select 12,5,1,nulx
- select 12,6,1,x50
- select 12,7,1,nulx
- select 12,8,1,x51
- select 12,9,1,nulx
- select 12,10,1,x52
- select 12,11,1,nulx
- select 12,12,1,x53
- select 12,13,1,nulx
- select 12,14,1,x54
- select 12,15,1,nulx
- select 12,16,1,x55
- select 12,17,1,nulx
- select 12,18,1,x56
- select 12,19,1,nulx
- select 12,20,1,x57
- select 12,21,1,nulx
- select 12,22,1,x58
- select 12,23,1,nulx
- select 12,24,1,x59
- select 12,25,1,nulx
- select 12,26,1,x60
- select 12,27,1,nulx
- select 12,28,1,x61
- select 12,29,1,nulx
- select 12,30,1,x62
- select 12,31,1,nulx
- select 12,32,1,x63
- select 13,2,1,nulx
- select 13,3,1,nulx
- select 13,4,1,nulx
- select 13,5,1,nulx
- select 13,6,1,nulx
- select 13,7,1,nulx
- select 13,8,1,nulx
- select 13,9,1,nulx
- select 13,10,1,nulx
- select 13,11,1,nulx
- select 13,12,1,nulx
- select 13,13,1,nulx
- select 13,14,1,nulx
- select 13,15,1,nulx
- select 13,16,1,nulx
- select 13,17,1,nulx
- select 13,18,1,nulx
- select 13,19,1,nulx
- select 13,20,1,nulx
- select 13,21,1,nulx
- select 13,22,1,nulx
- select 13,23,1,nulx
- select 13,24,1,nulx
- select 13,25,1,nulx
- select 13,26,1,nulx
- select 13,27,1,nulx
- select 13,28,1,nulx
- select 13,29,1,nulx
- select 13,30,1,nulx
- select 13,31,1,nulx
- select 13,32,1,nulx
- select 14,2,1,nulx
- select 14,3,1,home
- select 14,4,1,nulx
- select 14,5,1,upcur
- select 14,6,1,nulx
- select 14,7,1,pgup
- select 14,8,1,nulx
- select 14,9,1,nulx
- select 14,10,1,nulx
- select 14,11,3,f1
- select 14,14,1,nulx,
- select 14,15,3,f2
- select 14,18,1,nulx
- select 14,19,3,f3
- select 14,22,1,nulx
- select 14,23,3,f4
- select 14,26,1,nulx
- select 14,27,3,f5
- select 14,30,1,nulx
- select 14,31,1,nulx
- select 14,32,1,nulx
- select 15,2,1,nulx
- select 15,3,1,lcurs
- select 15,4,1,nulx
- select 15,5,1,ncurs
- select 15,6,1,nulx
- select 15,7,1,rcurs
- select 15,8,1,nulx
- select 15,9,1,nulx
- select 15,10,1,nulx
- select 15,11,3,f6
- select 15,14,1,nulx,
- select 15,15,3,f7
- select 15,18,1,nulx
- select 15,19,3,f8
- select 15,22,1,nulx
- select 15,23,3,f9
- select 15,26,1,nulx
- select 15,27,3,f10
- select 15,30,1,nulx
- select 15,31,1,nulx
- select 15,32,1,nulx
- select 16,2,1,nulx
- select 16,3,1,endx
- select 16,4,1,nulx
- select 16,5,1,dcurs
- select 16,6,1,nulx
- select 16,7,1,pgdn
- select 16,8,1,nulx
- PEND
-
- cpop: POPUP 2,40,NORMAL ;this is the 'control keys' menu
- text " ╔════╦════╦════╗"
- text " ║quit║Kybd║Symb║"
- text "╔══╬════╩════╬═══╦╝"
- text "║ 0║ NUL DLE ║ 10║"
- text "║ 1║ SOH DC1 ║ 11║"
- text "║ 2║ STX DC2 ║ 12║"
- text "║ 3║ ETX DC3 ║ 13║"
- text "║ 4║ EOT DC4 ║ 14║"
- text "║ 5║ ENQ NAK ║ 15║"
- text "║ 6║ ACK SYN ║ 16║"
- text "║ 7║ BEL ETB ║ 17║"
- text "║ 8║ BS CAN ║ 18║"
- text "║ 9║ HT EM ║ 19║"
- text "║ A║ LF SUB ║ 1A║"
- text "║ B║ VT ESC ║ 1B║"
- text "║ C║ FF FS ║ 1C║"
- text "║ D║ CR GS ║ 1D║"
- text "║ E║ SO RS ║ 1E║"
- text "║ F║ SI US ║ 1F║"
- text "╚══╩═════════╩═══╝"
- ;here are the SELECT statements
- ;for the 'control keys' menu.
- select 2,5,4,quit
- select 2,9,1,ctrl
- select 2,10,4,nulx
- select 2,14,1,ctrl
- select 2,15,4,nula
- select 3,5,4,ctrl
- select 3,9,1,ctrl
- select 3,10,4,ctrl
- select 4,5,4,x0
- select 4,9,1,ctrl
- select 4,10,4,x16
- select 5,5,4,x1
- select 5,9,1,ctrl
- select 5,10,4,x17
- select 6,5,4,x2
- select 6,9,1,ctrl
- select 6,10,4,x18
- select 7,5,4,x3
- select 7,9,1,ctrl
- select 7,10,4,x19
- select 8,5,4,x4
- select 8,9,1,ctrl
- select 8,10,4,x20
- select 9,5,4,x5
- select 9,9,1,ctrl
- select 9,10,4,x21
- select 10,5,4,x6
- select 10,9,1,ctrl
- select 10,10,4,x22
- select 11,5,4,x7
- select 11,9,1,ctrl
- select 11,10,4,x23
- select 11,19,3,f8
- select 12,5,4,x8
- select 12,9,1,ctrl
- select 12,10,4,x24
- select 13,5,4,x9
- select 13,9,1,ctrl
- select 13,10,4,x25
- select 14,5,4,x10
- select 14,9,1,ctrl
- select 14,10,4,x26
- select 15,5,4,x11
- select 15,9,1,ctrl
- select 15,10,4,x27
- select 16,5,4,x12
- select 16,9,1,ctrl
- select 16,10,4,x28
- select 17,5,4,x13
- select 17,9,1,ctrl
- select 17,10,4,x29
- select 18,5,4,x14
- select 18,9,1,ctrl
- select 18,10,4,x30
- select 19,5,4,x15
- select 19,9,1,ctrl
- select 19,10,4,x31
- PEND
-
- gpop: POPUP 2,40,NORMAL ;here is the 'graphics character' menu
- text "╔════╦══════════╤═════════╤═════╗"
- text "║quit║ Keyboard │ Control │Enter║"
- text "╠═╤═╤╩╤═╤═╤═╤═╤═╪═╤═╤═╤═╤═╪═╤═╤═╣"
- text "║Ç│ü│é│â│ä│à│å│ç│ê│ë│è│ï│î│ì│Ä│Å║"
- text "║É│æ│Æ│ô│ö│ò│û│ù│ÿ│Ö│Ü│¢│£│¥│₧│ƒ║"
- text "║á│í│ó│ú│ñ│Ñ│ª│º│¿│⌐│¬│½│¼│¡│«│»║"
- text "║α│ß│Γ│π│Σ│σ│µ│τ│Φ│Θ│Ω│δ│∞│φ│ε│∩║"
- text "║≡│±│≥│≤│⌠│⌡│÷│≈│°│∙│·│√│ⁿ│²│■│ ║"
- text "╚═╧═╧═╧═╧═╧═╧═╧═╧═╧═╧═╧═╧═╧═╧═╧═╝"
- ;here are the SELECT statements
- ;for the 'graphics character' menu.
- select 2,2,1,quit
- select 2,3,1,quit
- select 2,4,1,quit
- select 2,5,1,quit
- select 2,6,1,nula
- select 2,7,1,nulx
- select 2,8,1,nulx
- select 2,9,1,nulx
- select 2,10,1,nulx
- select 2,11,1,nulx
- select 2,12,1,nulx
- select 2,13,1,nulx
- select 2,14,1,nulx
- select 2,15,1,nulx
- select 2,16,1,nulx
- select 2,17,1,nula
- select 2,18,1,ctrl
- select 2,19,1,ctrl
- select 2,20,1,ctrl
- select 2,21,1,ctrl
- select 2,22,1,ctrl
- select 2,23,1,ctrl
- select 2,24,1,ctrl
- select 2,25,1,ctrl
- select 2,26,1,ctrl
- select 2,27,1,nula
- select 2,28,1,x13
- select 2,29,1,x13
- select 2,30,1,x13
- select 2,31,1,x13
- select 2,32,1,x13
- select 3,2,1,nula
- select 3,3,1,nula
- select 3,4,1,nula
- select 3,5,1,nula
- select 3,6,1,nula
- select 3,7,1,nula
- select 3,8,1,nula
- select 3,9,1,nula
- select 3,10,1,nula
- select 3,11,1,nula
- select 3,12,1,nula
- select 3,13,1,nula
- select 3,14,1,nula
- select 3,15,1,nula
- select 3,16,1,nula
- select 3,17,1,nula
- select 3,18,1,nula
- select 3,19,1,nula
- select 3,20,1,nula
- select 3,21,1,nula
- select 3,22,1,nula
- select 3,23,1,nula
- select 3,24,1,nula
- select 3,25,1,nula
- select 3,26,1,nula
- select 3,27,1,nula
- select 3,28,1,nula
- select 3,29,1,nula
- select 3,30,1,nula
- select 3,31,1,nula
- select 3,32,1,nula
- select 4,2,1,x128
- select 4,3,1,nula
- select 4,4,1,x129
- select 4,5,1,nula
- select 4,6,1,x130
- select 4,7,1,nula
- select 4,8,1,x131
- select 4,9,1,nula
- select 4,10,1,x132
- select 4,11,1,nula
- select 4,12,1,x133
- select 4,13,1,nula
- select 4,14,1,x134
- select 4,15,1,nula
- select 4,16,1,x135
- select 4,17,1,nula
- select 4,18,1,x136
- select 4,19,1,nula
- select 4,20,1,x137
- select 4,21,1,nula
- select 4,22,1,x138
- select 4,23,1,nula
- select 4,24,1,x139
- select 4,25,1,nula
- select 4,26,1,x140
- select 4,27,1,nula
- select 4,28,1,x141
- select 4,29,1,nula
- select 4,30,1,x142
- select 4,31,1,nula
- select 4,32,1,x143
- select 5,2,1,x144
- select 5,3,1,nula
- select 5,4,1,x145
- select 5,5,1,nula
- select 5,6,1,x146
- select 5,7,1,nula
- select 5,8,1,x147
- select 5,9,1,nula
- select 5,10,1,x148
- select 5,11,1,nula
- select 5,12,1,x149
- select 5,13,1,nula
- select 5,14,1,x150
- select 5,15,1,nula
- select 5,16,1,x151
- select 5,17,1,nula
- select 5,18,1,x152
- select 5,19,1,nula
- select 5,20,1,x153
- select 5,21,1,nula
- select 5,22,1,x154
- select 5,23,1,nula
- select 5,24,1,x155
- select 5,25,1,nula
- select 5,26,1,x156
- select 5,27,1,nula
- select 5,28,1,x157
- select 5,29,1,nula
- select 5,30,1,x158
- select 5,31,1,nula
- select 5,32,1,x159
- select 6,2,1,x160
- select 6,3,1,nula
- select 6,4,1,x161
- select 6,5,1,nula
- select 6,6,1,x162
- select 6,7,1,nula
- select 6,8,1,x163
- select 6,9,1,nula
- select 6,10,1,x164
- select 6,11,1,nula
- select 6,12,1,x165
- select 6,13,1,nula
- select 6,14,1,x166
- select 6,15,1,nula
- select 6,16,1,x167
- select 6,17,1,nula
- select 6,18,1,x168
- select 6,19,1,nula
- select 6,20,1,x169
- select 6,21,1,nula
- select 6,22,1,x170
- select 6,23,1,nula
- select 6,24,1,x171
- select 6,25,1,nula
- select 6,26,1,x172
- select 6,27,1,nula
- select 6,28,1,x173
- select 6,29,1,nula
- select 6,30,1,x174
- select 6,31,1,nula
- select 6,32,1,x175
- select 7,2,1,x224
- select 7,3,1,nula
- select 7,4,1,x225
- select 7,5,1,nula
- select 7,6,1,x226
- select 7,7,1,nula
- select 7,8,1,x227
- select 7,9,1,nula
- select 7,10,1,x228
- select 7,11,1,nula
- select 7,12,1,x229
- select 7,13,1,nula
- select 7,14,1,x230
- select 7,15,1,nula
- select 7,16,1,x231
- select 7,17,1,nula
- select 7,18,1,x232
- select 7,19,1,nula
- select 7,20,1,x233
- select 7,21,1,nula
- select 7,22,1,x234
- select 7,23,1,nula
- select 7,24,1,x235
- select 7,25,1,nula
- select 7,26,1,x236
- select 7,27,1,nula
- select 7,28,1,x237
- select 7,29,1,nula
- select 7,30,1,x238
- select 7,31,1,nula
- select 7,32,1,x239
- select 8,2,1,x240
- select 8,3,1,nula
- select 8,4,1,x241
- select 8,5,1,nula
- select 8,6,1,x242
- select 8,7,1,nula
- select 8,8,1,x243
- select 8,9,1,nula
- select 8,10,1,x244
- select 8,11,1,nula
- select 8,12,1,x245
- select 8,13,1,nula
- select 8,14,1,x246
- select 8,15,1,nula
- select 8,16,1,x247
- select 8,17,1,nula
- select 8,18,1,x248
- select 8,19,1,nula
- select 8,20,1,x249
- select 8,21,1,nula
- select 8,22,1,x250
- select 8,23,1,nula
- select 8,24,1,x251
- select 8,25,1,nula
- select 8,26,1,x252
- select 8,27,1,nula
- select 8,28,1,x253
- select 8,29,1,nula
- select 8,30,1,x254
- select 8,31,1,nula
- select 8,32,1,x255
- PEND
-
- ;the following labels define all of
- ;the keystrokes available within this
- ;menu. Note that the cursor and function
- ;key TYPE statements are defining
- ;extended key codes. Definitions for these
- ;extended key codes may be found in the
- ;various MS-DOS computer 'Hardware
- ;Technical Reference Manuals'.
- quit: nothing
- upcur: TYPE 0,72
- dcurs: TYPE 0,79
- lcurs: TYPE 0,75
- rcurs: TYPE 0,77
- home: TYPE 0,71
- endx: TYPE 0,79
- pgup: TYPE 0,73
- pgdn: TYPE 0,81
- ncurs: TYPE 0,76
- ins: TYPE 0,82
- del: TYPE 0,83
- f1: TYPE 0,59
- f2: TYPE 0,60
- f3: TYPE 0,61
- f4: TYPE 0,62
- f5: TYPE 0,63
- f6: TYPE 0,64
- f7: TYPE 0,65
- f8: TYPE 0,66
- f9: TYPE 0,67
- f10: TYPE 0,68
- x0: TYPE 0,3
- x1: TYPE 1
- x2: TYPE 2
- x3: TYPE 3
- x4: TYPE 4
- x5: TYPE 5
- x6: TYPE 6
- x7: TYPE 7
- x8: TYPE 8
- x9: TYPE 9
- x10: TYPE 10
- x11: TYPE 11
- x12: TYPE 12
- x13: TYPE 13
- x14: TYPE 14
- x15: TYPE 15
- x16: TYPE 16
- x17: TYPE 17
- x18: TYPE 18
- x19: TYPE 19
- x20: TYPE 20
- x21: TYPE 21
- x22: TYPE 22
- x23: TYPE 23
- x24: TYPE 24
- x25: TYPE 25
- x26: TYPE 26
- x27: TYPE 27
- x28: TYPE 28
- x29: TYPE 29
- x30: TYPE 30
- x31: TYPE 31
- x32: TYPE 32
- x33: TYPE 33
- x34: TYPE 34
- x35: TYPE 35
- x36: TYPE 36
- x37: TYPE 37
- x38: TYPE 38
- x39: TYPE 39
- x40: TYPE 40
- x41: TYPE 41
- x42: TYPE 42
- x43: TYPE 43
- x44: TYPE 44
- x45: TYPE 45
- x46: TYPE 46
- x47: TYPE 47
- x48: TYPE 48
- x49: TYPE 49
- x50: TYPE 50
- x51: TYPE 51
- x52: TYPE 52
- x53: TYPE 53
- x54: TYPE 54
- x55: TYPE 55
- x56: TYPE 56
- x57: TYPE 57
- x58: TYPE 58
- x59: TYPE 59
- x60: TYPE 60
- x61: TYPE 61
- x62: TYPE 62
- x63: TYPE 63
- x64: TYPE 64
- x65: TYPE 65
- x66: TYPE 66
- x67: TYPE 67
- x68: TYPE 68
- x69: TYPE 69
- x70: TYPE 70
- x71: TYPE 71
- x72: TYPE 72
- x73: TYPE 73
- x74: TYPE 74
- x75: TYPE 75
- x76: TYPE 76
- x77: TYPE 77
- x78: TYPE 78
- x79: TYPE 79
- x80: TYPE 80
- x81: TYPE 81
- x82: TYPE 82
- x83: TYPE 83
- x84: TYPE 84
- x85: TYPE 85
- x86: TYPE 86
- x87: TYPE 87
- x88: TYPE 88
- x89: TYPE 89
- x90: TYPE 90
- x91: TYPE 91
- x92: TYPE 92
- x93: TYPE 93
- x94: TYPE 94
- x95: TYPE 95
- x96: TYPE 96
- x97: TYPE 97
- x98: TYPE 98
- x99: TYPE 99
- x100: TYPE 100
- x101: TYPE 101
- x102: TYPE 102
- x103: TYPE 103
- x104: TYPE 104
- x105: TYPE 105
- x106: TYPE 106
- x107: TYPE 107
- x108: TYPE 108
- x109: TYPE 109
- x110: TYPE 110
- x111: TYPE 111
- x112: TYPE 112
- x113: TYPE 113
- x114: TYPE 114
- x115: TYPE 115
- x116: TYPE 116
- x117: TYPE 117
- x118: TYPE 118
- x119: TYPE 119
- x120: TYPE 120
- x121: TYPE 121
- x122: TYPE 122
- x123: TYPE 123
- x124: TYPE 124
- x125: TYPE 125
- x126: TYPE 126
- x127: TYPE 127
- x128: TYPE 128
- x129: TYPE 129
- x130: TYPE 130
- x131: TYPE 131
- x132: TYPE 132
- x133: TYPE 133
- x134: TYPE 134
- x135: TYPE 135
- x136: TYPE 136
- x137: TYPE 137
- x138: TYPE 138
- x139: TYPE 139
- x140: TYPE 140
- x141: TYPE 141
- x142: TYPE 142
- x143: TYPE 143
- x144: TYPE 144
- x145: TYPE 145
- x146: TYPE 146
- x147: TYPE 147
- x148: TYPE 148
- x149: TYPE 149
- x150: TYPE 150
- x151: TYPE 151
- x152: TYPE 152
- x153: TYPE 153
- x154: TYPE 154
- x155: TYPE 155
- x156: TYPE 156
- x157: TYPE 157
- x158: TYPE 158
- x159: TYPE 159
- x160: TYPE 160
- x161: TYPE 161
- x162: TYPE 162
- x163: TYPE 163
- x164: TYPE 164
- x165: TYPE 165
- x166: TYPE 166
- x167: TYPE 167
- x168: TYPE 168
- x169: TYPE 169
- x170: TYPE 170
- x171: TYPE 171
- x172: TYPE 172
- x173: TYPE 173
- x174: TYPE 174
- x175: TYPE 175
- x224: TYPE 224
- x225: TYPE 225
- x226: TYPE 226
- x227: TYPE 227
- x228: TYPE 228
- x229: TYPE 229
- x230: TYPE 230
- x231: TYPE 231
- x232: TYPE 232
- x233: TYPE 233
- x234: TYPE 234
- x235: TYPE 235
- x236: TYPE 236
- x237: TYPE 237
- x238: TYPE 238
- x239: TYPE 239
- x240: TYPE 240
- x241: TYPE 241
- x242: TYPE 242
- x243: TYPE 243
- x244: TYPE 244
- x245: TYPE 245
- x246: TYPE 246
- x247: TYPE 247
- x248: TYPE 248
- x249: TYPE 249
- x250: TYPE 250
- x251: TYPE 251
- x252: TYPE 252
- x253: TYPE 253
- x254: TYPE 254
- x255: TYPE 255
-
- \SAMPCODE\MOUSE\SOURCES\MPIBM.DEF
-
- BEGIN lb,rb,bb,lma,rma,uma,dma,32,16
-
- ;------------------------------BOTH BUTTONS----------------------------------
-
- bb: EXECUTE ESCAPE
-
- ;------------------------------LEFT BUTTON-----------------------------------
-
- lb: MATCH 24,7,NORMAL,"Y",YES,lb1 ;"Enter Y"
- lb1: MATCH 24,5,NORMAL,"w",YES,lb2 ;"Overwrite"
- lb2: MATCH 24,15,NORMAL,":",YES,lb3 ;"Confirm change:"
- lb3: MATCH 22,1,NORMAL,"H",NUL,MAIN ;"HELP:"
-
- ;------------------------------RIGHT BUTTON----------------------------------
-
- rb: MATCH 22,7,NORMAL,"D:",RETURN,rb1 ;"COMMAND:"
- rb1: MATCH 22,4,NORMAL,"Y:",RETURN,rb2 ;"COPY:"
- rb2: MATCH 22,6,NORMAL,"E:",RETURN,rb3 ;"DELETE:"
- rb3: MATCH 22,7,NORMAL,"T:",RETURN,rb4 ;"FORMAT:"
- rb4: MATCH 22,14,NORMAL,"T:",RETURN,rb5 ;"FORMAT DEFAULT:"
- rb5: MATCH 22,4,NORMAL,"O:",RETURN,rb6 ;"GOTO:"
- rb6: MATCH 22,6,NORMAL,"T:",RETURN,rb7 ;"INSERT:"
- rb7: MATCH 22,4,NORMAL,"K:",RETURN,rb8 ;"LOCK:"
- rb8: MATCH 22,4,NORMAL,"E:",RETURN,rb9 ;"MOVE:"
- rb9: MATCH 22,5,NORMAL,"T:",RETURN,rb10 ;"PRINT:"
- rb10: MATCH 22,8,NORMAL,"R:",RETURN,rb11 ;"TRANSFER:"
- rb11: MATCH 22,6,NORMAL,"W:",RETURN,rb12 ;"WINDOW:"
- rb12: MATCH 22,12,NORMAL,"T:",RETURN,rb13 ;"WINDOW SPLIT:"
- rb13: MATCH 22,8,NORMAL,"L:",RETURN,rb14 ;"EXTERNAL:"
- rb14: MATCH 22,1,NORMAL,"H",RETURN,rb15 ;"HELP:"
- rb15: MATCH 24,7,NORMAL,"Y",YES,rb16 ;"Enter Y"
- rb16: MATCH 24,5,NORMAL,"w",YES,rb17 ;"Overwrite"
- rb17: MATCH 24,15,NORMAL,":",YES,TB ;"Confirm change:"
-
- ;------------------------------LEFT MOTION-----------------------------------
-
- lma: MATCH 22,1,NORMAL,"H",BKSP,lma1 ;"HELP:"
- lma1: MATCH 24,18,NORMAL,"ty",LEFT,lma2 ;"Select option or type ...
- lma2: MATCH 24,1,NORMAL,"M",LEFT,lm1 ;"Multiplan ..."
-
- lmb: MATCH 24,18,NORMAL,"ty",BKSP,lmb1 ;"Select option or type ...
- lmb1: MATCH 24,1,NORMAL,"M",BKSP,lm1 ;"Multiplan ..."
-
- lm1: MATCH 24,1,NORMAL,"Se",BKSP,lm2 ;"Select option"
- lm2: MATCH 24,9,NORMAL,"op",SPBKSP,lm3 ;"Invalid option ..."
- lm3: MATCH 24,23,NORMAL,"w",NUL,lm4 ;"Press any key to redraw .
- lm4: MATCH 24,15,NORMAL,":",NUL,lm5 ;"Confirm change:"
- lm5: MATCH 24,7,NORMAL,"Y",NUL,lm6 ;"Enter Y"
- lm6: MATCH 24,5,NORMAL,"w",NUL,LEFT ;"Overwrite"
-
- ;------------------------------RIGHT MOTION----------------------------------
-
- rma: MATCH 22,1,NORMAL,"H",SP,rma1 ;"HELP:"
- rma1: MATCH 24,18,NORMAL,"ty",RIGHT,rma2 ;"Select option or type ...
- rma2: MATCH 24,1,NORMAL,"M",RIGHT,rm1 ;"Multiplan ..."
-
- rmb: MATCH 24,18,NORMAL,"ty",SP,rmb1 ;"Select option or type ...
- rmb1: MATCH 24,1,NORMAL,"M",SP,rm1 ;"Multiplan ..."
-
- rm1: MATCH 24,1,NORMAL,"Se",SP,rm2 ;"Select option"
- rm2: MATCH 24,9,NORMAL,"op",SPBKSP,rm3 ;"Invalid option ..."
- rm3: MATCH 24,23,NORMAL,"w",NUL,rm4 ;"Press any key to redraw .
- rm4: MATCH 24,15,NORMAL,":",NUL,rm5 ;"Confirm change:"
- rm5: MATCH 24,7,NORMAL,"Y",NUL,rm6 ;"Enter Y"
- rm6: MATCH 24,5,NORMAL,"w",NUL,RIGHT ;"Overwrite"
-
- ;------------------------------UP MOTION-------------------------------------
-
- uma: MATCH 22,1,NORMAL,"H",NUL,uma1 ;"HELP:"
- uma1: MATCH 24,18,NORMAL,"ty",UP,uma2 ;"Select option or type ...
- uma2: MATCH 24,1,NORMAL,"M",UP,um1 ;"Multiplan ..."
-
- umb: MATCH 24,18,NORMAL,"ty",NUL,umb1 ;"Select option or type ...
- umb1: MATCH 24,1,NORMAL,"M",NUL,um1 ;"Multiplan ..."
-
- um1: MATCH 24,1,NORMAL,"Se",NUL,um2 ;"Select option"
- um2: MATCH 24,9,NORMAL,"op",SPBKSP,um3 ;"Invalid option ..."
- um3: MATCH 24,23,NORMAL,"w",NUL,um4 ;"Press any key to redraw .
- um4: MATCH 24,15,NORMAL,":",NUL,um5 ;"Confirm change:"
- um5: MATCH 24,7,NORMAL,"Y",NUL,um6 ;"Enter Y"
- um6: MATCH 24,5,NORMAL,"w",NUL,UP ;"Overwrite"
-
- ;------------------------------DOWN MOTION-----------------------------------
-
- dma: MATCH 22,1,NORMAL,"H",NUL,dma1 ;"HELP:"
- dma1: MATCH 24,18,NORMAL,"ty",DOWN,dma2 ;"Select option or type ...
- dma2: MATCH 24,1,NORMAL,"M",DOWN,dm1 ;"Multiplan ..."
-
- dmb: MATCH 24,18,NORMAL,"ty",NUL,dmb1 ;"Select option or type ...
- dmb1: MATCH 24,1,NORMAL,"M",NUL,dm1 ;"Multiplan ..."
- dm1: MATCH 24,1,NORMAL,"Se",NUL,dm2 ;"Select option"
- dm2: MATCH 24,9,NORMAL,"op",SPBKSP,dm3 ;"Invalid option ..."
- dm3: MATCH 24,23,NORMAL,"w",NUL,dm4 ;"Press any key to redraw .
- dm4: MATCH 24,15,NORMAL,":",NUL,dm5 ;"Confirm change:"
- dm5: MATCH 24,7,NORMAL,"Y",NUL,dm6 ;"Enter Y"
- dm6: MATCH 24,5,NORMAL,"w",NUL,DOWN ;"Overwrite"
-
- ;------------------------------MENUS-----------------------------------------
-
- MAIN: popup 19,1,NORMAL
- text "───────────────────────────────────────────────────────────────────────
- text "MAIN: Enter Cancel Cell Command Reference Recalc : , Help CURSOR
- text "───────────────────────────────────────────────────────────────────────
- select 2,7,5,RETURN
- select 2,13,6,ESCAPE
- select 2,20,4,CELL
- select 2,25,7,COMMAND
- select 2,33,9,REFERENCE
- select 2,43,6,RECALC
- select 2,50,3,COLON
- select 2,54,3,COMMA
- select 2,58,4,HELP
- select 2,63,6,CURSOR
- pend
-
- COMMAND: ASSIGN ,,,lmb,rmb,umb,dmb,,
- CELL: ASSIGN ,,,lma,rma,uma,dma,,
-
- CURSOR: popup 19,1,NORMAL
- text "───────────────────────────────────────────────────────────────────────
- text "CURSOR: MAIN Home End NxtWindow NxtCell PageUp PageDown PageLeft PageRi
- text "───────────────────────────────────────────────────────────────────────
- select 2,9,4,MAIN
- select 2,14,4,HOME
- select 2,19,3,END
- select 2,23,9,NXTWINDOW
- select 2,33,7,NXTCELL
- select 2,41,6,PGUP
- select 2,48,8,PGDOWN
- select 2,57,8,PGLEFT
- select 2,66,9,PGRIGHT
- pend
-
- ;------------------------------KEYS------------------------------------------
-
- NUL: NOTHING
- BKSP: TYPE 8 ;Backspace
- TB: TYPE 9 ;Tab
- RETURN: TYPE 13 ;Enter
- ESCAPE: TYPE 27 ;Esc
- HELP: TYPE 0,35 ;Alt-H
- SP: TYPE " "
- YES: TYPE "Y"
- SPBKSP: TYPE " ",8 ;Space,Backspace
- NXTWINDOW: TYPE 0,59 ;F1
- NXTCELL: TYPE 0,60 ;F2
- REFERENCE: TYPE 0,61 ;F3
- RECALC: TYPE 0,62 ;F4
- COLON: TYPE ":"
- COMMA: TYPE ","
- HOME: TYPE 0,132 ;Ctrl-PgUp
- END: TYPE 0,79 ;End
- PGUP: TYPE 0,73 ;PgUp
- PGDOWN: TYPE 0,81 ;PgDn
- PGLEFT: TYPE 0,115 ;Ctrl-Left
- PGRIGHT: TYPE 0,116 ;Ctrl-Right
- LEFT: TYPE 0,75 ;Left
- RIGHT: TYPE 0,77 ;Right
- UP: TYPE 0,72 ;Up
- DOWN: TYPE 0,80 ;Down
-
-
- \SAMPCODE\MOUSE\SOURCES\MPMS.DEF
-
- BEGIN lb,rb,bb,lma,rma,uma,dma,32,16
-
- ;------------------------------BOTH BUTTONS----------------------------------
-
- bb: EXECUTE ESCAPE
-
- ;------------------------------LEFT BUTTON-----------------------------------
-
- lb: MATCH 24,7,NORMAL,"Y",YES,lb1 ;"Enter Y"
- lb1: MATCH 24,5,NORMAL,"w",YES,lb2 ;"Overwrite"
- lb2: MATCH 24,15,NORMAL,":",YES,lb3 ;"Confirm change:"
- lb3: MATCH 22,1,NORMAL,"H",NUL,MAIN ;"HELP:"
-
- ;------------------------------RIGHT BUTTON----------------------------------
-
- rb: MATCH 22,7,NORMAL,"D:",RETURN,rb1 ;"COMMAND:"
- rb1: MATCH 22,4,NORMAL,"Y:",RETURN,rb2 ;"COPY:"
- rb2: MATCH 22,6,NORMAL,"E:",RETURN,rb3 ;"DELETE:"
- rb3: MATCH 22,7,NORMAL,"T:",RETURN,rb4 ;"FORMAT:"
- rb4: MATCH 22,14,NORMAL,"T:",RETURN,rb5 ;"FORMAT DEFAULT:"
- rb5: MATCH 22,4,NORMAL,"O:",RETURN,rb6 ;"GOTO:"
- rb6: MATCH 22,6,NORMAL,"T:",RETURN,rb7 ;"INSERT:"
- rb7: MATCH 22,4,NORMAL,"K:",RETURN,rb8 ;"LOCK:"
- rb8: MATCH 22,4,NORMAL,"E:",RETURN,rb9 ;"MOVE:"
- rb9: MATCH 22,5,NORMAL,"T:",RETURN,rb10 ;"PRINT:"
- rb10: MATCH 22,8,NORMAL,"R:",RETURN,rb11 ;"TRANSFER:"
- rb11: MATCH 22,6,NORMAL,"W:",RETURN,rb12 ;"WINDOW:"
- rb12: MATCH 22,12,NORMAL,"T:",RETURN,rb13 ;"WINDOW SPLIT:"
- rb13: MATCH 22,8,NORMAL,"L:",RETURN,rb14 ;"EXTERNAL:"
- rb14: MATCH 22,1,NORMAL,"H",RETURN,rb15 ;"HELP:"
- rb15: MATCH 24,7,NORMAL,"Y",YES,rb16 ;"Enter Y"
- rb16: MATCH 24,5,NORMAL,"w",YES,rb17 ;"Overwrite"
- rb17: MATCH 24,15,NORMAL,":",YES,TB ;"Confirm change:"
-
- ;------------------------------LEFT MOTION-----------------------------------
-
- lma: MATCH 22,1,NORMAL,"H",BKSP,lma1 ;"HELP:"
- lma1: MATCH 24,18,NORMAL,"ty",LEFT,lma2 ;"Select option or type ...
- lma2: MATCH 24,1,NORMAL,"M",LEFT,lm1 ;"Multiplan ..."
-
- lmb: MATCH 24,18,NORMAL,"ty",BKSP,lmb1 ;"Select option or type ...
- lmb1: MATCH 24,1,NORMAL,"M",BKSP,lm1 ;"Multiplan ..."
-
- lm1: MATCH 24,1,NORMAL,"Se",BKSP,lm2 ;"Select option"
- lm2: MATCH 24,9,NORMAL,"op",SPBKSP,lm3 ;"Invalid option ..."
- lm3: MATCH 24,23,NORMAL,"w",NUL,lm4 ;"Press any key to redraw .
- lm4: MATCH 24,15,NORMAL,":",NUL,lm5 ;"Confirm change:"
- lm5: MATCH 24,7,NORMAL,"Y",NUL,lm6 ;"Enter Y"
- lm6: MATCH 24,5,NORMAL,"w",NUL,LEFT ;"Overwrite"
-
- ;------------------------------RIGHT MOTION----------------------------------
-
- rma: MATCH 22,1,NORMAL,"H",SP,rma1 ;"HELP:"
- rma1: MATCH 24,18,NORMAL,"ty",RIGHT,rma2 ;"Select option or type ...
- rma2: MATCH 24,1,NORMAL,"M",RIGHT,rm1 ;"Multiplan ..."
-
- rmb: MATCH 24,18,NORMAL,"ty",SP,rmb1 ;"Select option or type ...
- rmb1: MATCH 24,1,NORMAL,"M",SP,rm1 ;"Multiplan ..."
-
- rm1: MATCH 24,1,NORMAL,"Se",SP,rm2 ;"Select option"
- rm2: MATCH 24,9,NORMAL,"op",SPBKSP,rm3 ;"Invalid option ..."
- rm3: MATCH 24,23,NORMAL,"w",NUL,rm4 ;"Press any key to redraw .
- rm4: MATCH 24,15,NORMAL,":",NUL,rm5 ;"Confirm change:"
- rm5: MATCH 24,7,NORMAL,"Y",NUL,rm6 ;"Enter Y"
- rm6: MATCH 24,5,NORMAL,"w",NUL,RIGHT ;"Overwrite"
-
- ;------------------------------UP MOTION-------------------------------------
-
- uma: MATCH 22,1,NORMAL,"H",NUL,uma1 ;"HELP:"
- uma1: MATCH 24,18,NORMAL,"ty",UP,uma2 ;"Select option or type ...
- uma2: MATCH 24,1,NORMAL,"M",UP,um1 ;"Multiplan ..."
-
- umb: MATCH 24,18,NORMAL,"ty",NUL,umb1 ;"Select option or type ...
- umb1: MATCH 24,1,NORMAL,"M",NUL,um1 ;"Multiplan ..."
-
- um1: MATCH 24,1,NORMAL,"Se",NUL,um2 ;"Select option"
- um2: MATCH 24,9,NORMAL,"op",SPBKSP,um3 ;"Invalid option ..."
- um3: MATCH 24,23,NORMAL,"w",NUL,um4 ;"Press any key to redraw .
- um4: MATCH 24,15,NORMAL,":",NUL,um5 ;"Confirm change:"
- um5: MATCH 24,7,NORMAL,"Y",NUL,um6 ;"Enter Y"
- um6: MATCH 24,5,NORMAL,"w",NUL,UP ;"Overwrite"
-
- ;------------------------------DOWN MOTION-----------------------------------
-
- dma: MATCH 22,1,NORMAL,"H",NUL,dma1 ;"HELP:"
- dma1: MATCH 24,18,NORMAL,"ty",DOWN,dma2 ;"Select option or type ...
- dma2: MATCH 24,1,NORMAL,"M",DOWN,dm1 ;"Multiplan ..."
-
- dmb: MATCH 24,18,NORMAL,"ty",NUL,dmb1 ;"Select option or type ...
- dmb1: MATCH 24,1,NORMAL,"M",NUL,dm1 ;"Multiplan ..."
- dm1: MATCH 24,1,NORMAL,"Se",NUL,dm2 ;"Select option"
- dm2: MATCH 24,9,NORMAL,"op",SPBKSP,dm3 ;"Invalid option ..."
- dm3: MATCH 24,23,NORMAL,"w",NUL,dm4 ;"Press any key to redraw .
- dm4: MATCH 24,15,NORMAL,":",NUL,dm5 ;"Confirm change:"
- dm5: MATCH 24,7,NORMAL,"Y",NUL,dm6 ;"Enter Y"
- dm6: MATCH 24,5,NORMAL,"w",NUL,DOWN ;"Overwrite"
-
- ;------------------------------MENUS-----------------------------------------
-
- MAIN: popup 19,1,NORMAL
- text "───────────────────────────────────────────────────────────────────────
- text "MAIN: Enter Cancel Cell Command Reference Recalc : , Help CURSOR
- text "───────────────────────────────────────────────────────────────────────
- select 2,7,5,RETURN
- select 2,13,6,ESCAPE
- select 2,20,4,CELL
- select 2,25,7,COMMAND
- select 2,33,9,REFERENCE
- select 2,43,6,RECALC
- select 2,50,3,COLON
- select 2,54,3,COMMA
- select 2,58,4,HELP
- select 2,63,6,CURSOR
- pend
-
- COMMAND: ASSIGN ,,,lmb,rmb,umb,dmb,,
- CELL: ASSIGN ,,,lma,rma,uma,dma,,
-
- CURSOR: popup 19,1,NORMAL
- text "───────────────────────────────────────────────────────────────────────
- text "CURSOR: MAIN Home End NxtWindow NxtCell PageUp PageDown PageLeft PageRi
- text "───────────────────────────────────────────────────────────────────────
- select 2,9,4,MAIN
- select 2,14,4,HOME
- select 2,19,3,END
- select 2,23,9,NXTWINDOW
- select 2,33,7,NXTCELL
- select 2,41,6,PGUP
- select 2,48,8,PGDOWN
- select 2,57,8,PGLEFT
- select 2,66,9,PGRIGHT
- pend
-
- ;------------------------------KEYS------------------------------------------
-
- NUL: NOTHING
- BKSP: TYPE 8 ;Backspace
- TB: TYPE 9 ;Tab
- RETURN: TYPE 13 ;Enter
- ESCAPE: TYPE 27 ;Esc
- HELP: TYPE 0,68 ;F10
- SP: TYPE " "
- YES: TYPE "Y"
- SPBKSP: TYPE " ",8 ;Space,Backspace
- NXTWINDOW: TYPE 0,64 ;F6
- NXTCELL: TYPE 0,63 ;F5
- REFERENCE: TYPE 0,65 ;F7
- RECALC: TYPE 0,66 ;F8
- COLON: TYPE ":"
- COMMA: TYPE ","
- HOME: TYPE 0,71 ;Home
- END: TYPE 0,79 ;End
- PGUP: TYPE 0,73 ;PgUp
- PGDOWN: TYPE 0,81 ;PgDn
- PGLEFT: TYPE 0,115 ;Ctrl-Left
- PGRIGHT: TYPE 0,116 ;Ctrl-Right
- LEFT: TYPE 0,75 ;Left
- RIGHT: TYPE 0,77 ;Right
- UP: TYPE 0,72 ;Up
- DOWN: TYPE 0,80 ;Down
-
-
- \SAMPCODE\MOUSE\SOURCES\SYM.DEF
-
- BEGIN lb,rb,bb,lm,rm,um,dm,32,16
-
- ;********************************************************************
- ;* Microsoft Mouse definition file for Symphony *
- ;* Revised 6/25/86 *
- ;********************************************************************
-
- ;------------------------------BOTH BUTTONS--------------------------
- bb: EXECUTE ESCAPE
- ;------------------------------LEFT BUTTON---------------------------
- lb: MATCH 10,2,," ",MAIN,lb1
- lb1: MATCH 10,3,," ",MAIN,lb2
- lb2: MATCH 10,4,," ",MAIN,lb3
- lb3: MATCH 10,5,," ",MAIN,lb4
- lb4: MATCH 10,6,," ",MAIN,lb5
- lb5: MATCH 23,76,," ",MAIN,lb6
- lb6: MATCH 23,77,," ",MAIN,lb7
- lb7: MATCH 23,78,," ",MAIN,lb8
- lb8: MATCH 23,79,," ",MAIN,lb9
- lb9: MATCH 24,76,," ",MAIN,lb10
- lb10: MATCH 24,77,," ",MAIN,lb11
- lb11: MATCH 24,78,," ",MAIN,lb12
- lb12: MATCH 24,79,," ",MAIN,SLASH ;In Graphics mode, pop sym menu
-
- ;------------------------------RIGHT BUTTON--------------------------
- rb: MATCH 1,76,,"SHEET",SLASH,RETURN
- ;------------------------------LEFT MOTION---------------------------
- lm: MATCH 1,76,,"ERROR",NUL,lm1
- lm1: MATCH 23,3,,"[ESCAPE]",NUL,lm2 ;Install
- lm2: MATCH 2,35,,"Help Screen",NUL,lm3 ;Install Help
- lm3: MATCH 6,24,,"translate",NUL,LEFT ;Translate
-
- ;------------------------------RIGHT MOTION--------------------------
- rm: MATCH 1,76,,"ERROR",NUL,rm1
- rm1: MATCH 23,3,,"[ESCAPE]",NUL,rm2 ;Install
- rm2: MATCH 2,35,,"Help Screen",NUL,rm3 ;Install Help
- rm3: MATCH 6,24,,"translate",NUL,RIGHT ;Translate
-
- ;------------------------------UP MOTION-----------------------------
- um: MATCH 1,76,,"ERROR",NUL,um1
- um1: MATCH 1,76,,"MENU",NUL,um2
- um2: MATCH 1,77,,"MENU",NUL,um4
- um4: MATCH 3,3,,"Symphony",NUL,um5 ;Access title menu
- um5: MATCH 2,35,,"Help Screen",NUL,UP ;Install Help
-
- ;------------------------------DOWN MOTION---------------------------
- dm: MATCH 1,76,,"ERROR",NUL,dm1
- dm1: MATCH 1,76,,"MENU",NUL,dm2
- dm2: MATCH 1,77,,"MENU",NUL,dm4
- dm4: MATCH 3,3,,"Symphony",NUL,dm5 ;Access title menu
- dm5: MATCH 2,35,,"Help Screen",NUL,DOWN ;Install Help
-
- ;------------------------------MENUS---------------------------------
-
- MAIN: popup 23,1,NORMAL
- text "───────────────────────────────────────────────────────────────────────
- text "MAIN: Cancel Help Menu Service Anchor NxtWin Zoom Change Switch Update
- text "───────────────────────────────────────────────────────────────────────
- select 2,7,6,CANCEL
- select 2,14,4,F1
- select 2,19,4,F10
- select 2,24,7,F9
- select 2,32,6,PERIOD
- select 2,39,6,F6
- select 2,46,4,ALTF6
- select 2,51,6,ALTF10
- select 2,58,6,ALTF9
- select 2,65,6,ALTF8
- select 2,72,5,SHEET
- select 2,78,3,DOC
- pend
-
- SHEET: popup 23,1,NORMAL
- text "───────────────────────────────────────────────────────────────────────
- text "SHEET: MAIN Menu Services Anchor @Sum( ) ( + - * / Abs Edit Recalc Name
- text "───────────────────────────────────────────────────────────────────────
- select 2,8,4,MAIN
- select 2,13,4,F10
- select 2,18,8,F9
- select 2,27,6,PERIOD
- select 2,34,5,SUM
- select 2,40,1,RGTPRAN
- select 2,42,1,LFTPRAN
- select 2,44,1,ADD
- select 2,46,1,SUB
- select 2,48,1,MUL
- select 2,50,1,DIV
- select 2,52,3,F3
- select 2,56,4,F2
- select 2,61,6,F8
- select 2,68,4,RENAME
- select 2,73,4,HOME
- select 2,78,3,END
- pend
-
- DOC: popup 23,1,NORMAL
- text "───────────────────────────────────────────────────────────────────────
- text "DOC: MAIN Menu Services I? Align Split Center Indent Erase Compose GoTo
- text "───────────────────────────────────────────────────────────────────────
- select 2,6,4,MAIN
- select 2,11,4,F10
- select 2,16,8,F9
- select 2,25,2,ALTF2
- select 2,28,5,F2
- select 2,34,5,ALTF3
- select 2,40,6,ALTF4
- select 2,47,6,F3
- select 2,54,5,F4
- select 2,60,7,ALTF1
- select 2,68,4,F5
- select 2,73,3,END
- select 2,77,4,MOVE
- pend
-
- MOVE: popup 23,1,NORMAL
- text "───────────────────────────────────────────────────────────────────────
- text "MOVE: Left Right Ln_Start Ln_End Par_Start Par_End PgUp PgDn Doc_Start
- text "───────────────────────────────────────────────────────────────────────
- select 2,7,4,CTLLEFT
- select 2,12,5,CTLRGHT
- select 2,18,8,ENDLEFT
- select 2,27,6,ENDRGHT
- select 2,34,9,ENDUP
- select 2,44,7,ENDDOWN
- select 2,52,4,PGUP
- select 2,57,4,PGDN
- select 2,62,9,HOME
- select 2,72,7,ENDHOME
- pend
-
- ;------------------------------KEYS----------------------------------
- NUL: NOTHING
- RETURN: TYPE 13
- RENAME: TYPE "/","R","N"
- ESCAPE: TYPE 27
- SLASH: TYPE "/"
- CANCEL: TYPE 27,27,27,27,27,27,27,27
- PERIOD: TYPE "."
- COMMA: TYPE ","
- F1: TYPE 0,59
- F2: TYPE 0,60
- F3: TYPE 0,61
- F4: TYPE 0,62
- F5: TYPE 0,63
- F6: TYPE 0,64
- F7: TYPE 0,65
- F8: TYPE 0,66
- F9: TYPE 0,67
- F10: TYPE 0,68
- ALTF1: TYPE 0,104
- ALTF2: TYPE 0,105
- ALTF3: TYPE 0,106
- ALTF4: TYPE 0,107
- ALTF5: TYPE 0,108
- ALTF6: TYPE 0,109
- ALTF7: TYPE 0,110
- ALTF8: TYPE 0,111
- ALTF9: TYPE 0,112
- ALTF10: TYPE 0,113
- HOME: TYPE 0,71
- END: TYPE 0,79
- ENDUP: TYPE 0,79,0,72
- ENDDOWN: TYPE 0,79,0,80
- ENDLEFT: TYPE 0,79,0,75
- ENDRGHT: TYPE 0,79,0,77
- ENDHOME: TYPE 0,79,0,71
- CTLLEFT: TYPE 0,115
- CTLRGHT: TYPE 0,116
- BKTB: TYPE 0,15 ;BACK TAB
- TB: TYPE 9
- PGUP: TYPE 0,73
- PGDN: TYPE 0,81
- LEFT: TYPE 0,75
- RIGHT: TYPE 0,77
- UP: TYPE 0,72
- DOWN: TYPE 0,80
- SPACE: TYPE 32
- LFTPRAN: TYPE "("
- RGTPRAN: TYPE ")"
- MUL: TYPE "*"
- ADD: TYPE "+"
- SUB: TYPE "-"
- DIV: TYPE "/"
- SUM: TYPE "@Sum("
-
- \SAMPCODE\MOUSE\SOURCES\VC.DEF
-
-
- BEGIN lb,rb,bb,lm,rm,um,dm,32,16
-
- ;------------------------------BOTH BUTTONS----------------------------------
-
- bb: MATCH 2,1,INVERSE,"[",CTRLC,bb1 ;"[Edit]:"
- bb1: MATCH 2,1,INVERSE,"V",CTRLC,bb2 ;"Value"
- bb2: MATCH 2,5,INVERSE,"l ",CTRLC,ESCAPE ;"Label" not "Label:"
-
- ;------------------------------LEFT BUTTON-----------------------------------
-
- lb: MATCH 2,1,INVERSE," ",MAIN,lb1 ;Not in command mode
- lb1: MATCH 2,1,INVERSE,"(C)",MAIN,lb2 ;"(C)"
- lb2: MATCH 2,1,INVERSE,"V",VALUE,lb3 ;"Value"
- lb3: MATCH 2,5,INVERSE,"l ",LABEL,lb4 ;"Label" not "Label:"
- lb4: MATCH 2,12,INVERSE,"N=",NO,lb5 ;"Replicate: N=No Change ..."
- lb5: MATCH 2,13,INVERSE,"Y",YES,lb6 ;"Clear: Type Y ..."
- lb6: MATCH 2,12,INVERSE,"Y",YES,lb7 ;"Quit: Type Y ..."
- lb7: MATCH 2,25,INVERSE,"Y",YES,lb8 ;"... File already ..."
- lb8: MATCH 2,19,INVERSE,"Y",YES,RETURN ;"Delete File: Type Y
-
- ;------------------------------RIGHT BUTTON----------------------------------
-
- rb: MATCH 2,1,INVERSE," ",MAIN,rb1 ;Not in command mode
- rb1: MATCH 2,1,INVERSE,"(C)",MAIN,rb2 ;"(C)"
- rb2: MATCH 2,1,INVERSE,"V",VALUE,rb3 ;"Value"
- rb3: MATCH 2,5,INVERSE,"l ",LABEL,rb4 ;"Label" not "Label:"
- rb4: MATCH 2,12,INVERSE,"N=",REL,lb5 ;"Replicate: N=No Change ..."
- rb5: MATCH 2,13,INVERSE,"Y",YES,rb6 ;"Clear: Type Y ..."
- rb6: MATCH 2,12,INVERSE,"Y",YES,rb7 ;"Quit: Type Y ..."
- rb7: MATCH 2,25,INVERSE,"Y",YES,rb8 ;"... File already ..."
- rb8: MATCH 2,19,INVERSE,"Y",YES,RETURN ;"Delete File: Type Y
-
- ;------------------------------LEFT MOTION-----------------------------------
-
- lm: MATCH 2,1,INVERSE," ",LEFT,lm1 ;Not in command mode
- lm1: MATCH 2,1,INVERSE,"(C)",LEFT,lm2 ;"(C)"
- lm2: MATCH 2,1,INVERSE,"V",LEFT,lm3 ;"Value"
- lm3: MATCH 2,1,INVERSE,"M",LEFT,lm4 ;"Move:"
- lm4: MATCH 2,1,INVERSE,"[",LEFT,lm5 ;"[Edit]:"
- lm5: MATCH 2,1,INVERSE,"Rep",LEFT,lm6 ;"Replicate:"
- lm6: MATCH 2,6,INVERSE,": L",LEFT,lm7 ;"Print: Lower right ..."
- lm7: MATCH 2,10,INVERSE,": L",LEFT,NUL ;"Data save: Lower right ..."
-
- ;------------------------------RIGHT MOTION----------------------------------
-
- rm: MATCH 2,1,INVERSE," ",RIGHT,rm1 ;Not in command mode
- rm1: MATCH 2,1,INVERSE,"(C)",RIGHT,rm2 ;"(C)"
- rm2: MATCH 2,1,INVERSE,"V",RIGHT,rm3 ;"Value"
- rm3: MATCH 2,1,INVERSE,"M",RIGHT,rm4 ;"Move:"
- rm4: MATCH 2,1,INVERSE,"[",RIGHT,rm5 ;"[Edit]:"
- rm5: MATCH 2,1,INVERSE,"Rep",RIGHT,rm6 ;"Replicate:"
- rm6: MATCH 2,6,INVERSE,": L",RIGHT,rm7 ;"Print: Lower right ..."
- rm7: MATCH 2,10,INVERSE,": L",RIGHT,NUL ;"Data save: Lower right ..."
-
- ;------------------------------UP MOTION-------------------------------------
-
- um: MATCH 2,1,INVERSE," ",UP,um1 ;Not in command mode
- um1: MATCH 2,1,INVERSE,"(C)",UP,um2 ;"(C)"
- um2: MATCH 2,1,INVERSE,"V",UP,um3 ;"Value"
- um3: MATCH 2,1,INVERSE,"M",UP,um4 ;"Move:"
- um4: MATCH 2,1,INVERSE,"Rep",UP,um5 ;"Replicate:"
- um5: MATCH 2,6,INVERSE,": L",UP,um6 ;"Print: Lower right ..."
- um6: MATCH 2,10,INVERSE,": L",UP,NUL ;"Data save: Lower right ..."
-
- ;------------------------------DOWN MOTION-----------------------------------
-
- dm: MATCH 2,1,INVERSE," ",DOWN,dm1 ;Not in command mode
- dm1: MATCH 2,1,INVERSE,"(C)",DOWN,dm2 ;"(C)"
- dm2: MATCH 2,1,INVERSE,"V",DOWN,dm3 ;"Value"
- dm3: MATCH 2,1,INVERSE,"M",DOWN,dm4 ;"Move:"
- dm4: MATCH 2,1,INVERSE,"Rep",DOWN,dm5 ;"Replicate:"
- dm5: MATCH 2,6,INVERSE,": L",DOWN,dm6 ;"Print: Lower right ..."
- dm6: MATCH 2,10,INVERSE,": L",DOWN,NUL ;"Data save: Lower right ..."
-
- ;------------------------------MENUS-----------------------------------------
-
- MAIN: popup 2,1,INVERSE
- text "Main: Command Label Value Goto Home Window Recalc Absolute "
- select 1,7,7,COMMAND
- select 1,15,5,QUOTE
- select 1,21,5,PLUSBKSP
- select 1,27,4,GREAT
- select 1,32,4,HOME
- select 1,37,6,SEMICOLON
- select 1,44,6,BANG
- select 1,51,8,POUND
- pend
-
- COMMAND: popup 2,1,INVERSE
- text "Command: Blank Clear Delete Edit Format Global Insert Move "
- text " Print Replicate Storage Titles Version Window Repeat(-
- select 1,10,5,B
- select 1,16,5,C
- select 1,22,6,DELETE
- select 1,29,4,E
- select 1,34,6,FORMAT
- select 1,41,6,GLOBAL
- select 1,48,6,INSERT
- select 1,55,4,M
- select 2,10,5,PRINT
- select 2,16,9,R
- select 2,26,7,STORAGE
- select 2,34,6,TITLE
- select 2,41,7,V
- select 2,49,6,WINDOW
- select 2,56,9,REPEAT
- pend
- B: TYPE "/b"
- C: TYPE "/c"
- E: TYPE "/e"
- M: TYPE "/m"
- R: TYPE "/r"
- V: TYPE "/v"
- REPEAT: TYPE "/-"
-
- DELETE: popup 2,1,INVERSE
- text "Delete: Row Column "
- select 1,9,3,DR
- select 1,13,6,DC
- pend
- DR: TYPE "/dr"
- DC: TYPE "/dc"
-
- FORMAT: popup 2,1,INVERSE
- text "Format: Default General Integer Left Right Dollar($) Graph(*) "
- select 1,9,7,FD
- select 1,17,7,FG
- select 1,25,7,FI
- select 1,33,4,FL
- select 1,38,5,FR
- select 1,44,9,FDOLLAR
- select 1,54,8,FGRAPH
- pend
- FD: TYPE "/fd"
- FG: TYPE "/fg"
- FI: TYPE "/fi"
- FL: TYPE "/fl"
- FR: TYPE "/fr"
- FDOLLAR: TYPE "/f$"
- FGRAPH: TYPE "/f*"
-
- GLOBAL: popup 2,1,INVERSE
- text "Global: Column Order Recalc Format "
- select 1,9,6,GC
- select 1,16,5,ORDER
- select 1,22,6,RECALC
- select 1,29,6,FORMAT2
- pend
- GC: TYPE "/gc"
-
- ORDER: popup 2,1,INVERSE
- text "Reeval Order: Row Column "
- select 1,15,3,GOR
- select 1,19,6,GOC
- pend
- GOR: TYPE "/gor"
- GOC: TYPE "/goc"
-
- RECALC: popup 2,1,INVERSE
- text "Recalc: Auto Manual "
- select 1,9,4,GRA
- select 1,14,6,GRM
- pend
- GRA: TYPE "/gra"
- GRM: TYPE "/grm"
-
- FORMAT2: popup 2,1,INVERSE
- text "Format: Default General Integer Left Right Dollar($) Graph(*) "
- select 1,9,7,GFD
- select 1,17,7,GFG
- select 1,25,7,GFI
- select 1,33,4,GFL
- select 1,38,5,GFR
- select 1,44,9,GFDOLLAR
- select 1,54,8,GFGRAPH
- pend
- GFD: TYPE "/gfd"
- GFG: TYPE "/gfg"
- GFI: TYPE "/gfi"
- GFL: TYPE "/gfl"
- GFR: TYPE "/gfr"
- GFDOLLAR: TYPE "/gf$"
- GFGRAPH: TYPE "/gf*"
-
- INSERT: popup 2,1,INVERSE
- text "Insert: Row Column "
- select 1,9,3,IR
- select 1,13,6,IC
- pend
- IR: TYPE "/ir"
- IC: TYPE "/ic"
-
- PRINT: popup 2,1,INVERSE
- text "Print: Printer File "
- select 1,8,7,PP
- select 1,16,4,PF
- pend
- PP: TYPE "/pp"
- PF: TYPE "/pf"
-
- STORAGE: popup 2,1,INVERSE
- text "Storage: Load Save Delete Quit Data(#) "
- select 1,10,4,SL
- select 1,15,4,SS
- select 1,20,6,SD
- select 1,27,4,SQ
- select 1,32,7,DATA
- pend
- SL: TYPE "/sl"
- SS: TYPE "/ss"
- SD: TYPE "/sd"
- SQ: TYPE "/sq"
-
- DATA: popup 2,1,INVERSE
- text "Data: Save Load "
- select 1,7,4,SPOUNDS
- select 1,12,4,SPOUNDL
- pend
- SPOUNDS: TYPE "/s#s"
- SPOUNDL: TYPE "/s#l"
-
- TITLE: popup 2,1,INVERSE
- text "Titles: Horizontal Vertical Both None "
- select 1,9,10,TH
- select 1,20,8,TV
- select 1,29,4,TB
- select 1,34,4,TN
- pend
- TH: TYPE "/th"
- TV: TYPE "/tv"
- TB: TYPE "/tb"
- TN: TYPE "/tn"
-
- WINDOW: popup 2,1,INVERSE
- text "Window: Horizontal Vertical 1Window Synch Unsynch "
- select 1,9,10,WH
- select 1,20,8,WV
- select 1,29,7,W1
- select 1,37,5,WS
- select 1,43,7,WU
- pend
- WH: TYPE "/wh"
- WV: TYPE "/wv"
- W1: TYPE "/w1"
- WS: TYPE "/ws"
- WU: TYPE "/wu"
-
- LABEL: popup 2,1,INVERSE
- text "Label: Execute Edit "
- select 1,8,7,RETURN
- select 1,16,4,CTRLE
- pend
-
- VALUE: popup 2,1,INVERSE
- text "Value: Enter Period Edit Recalc Absolute "
- select 1,8,5,RETURN
- select 1,14,6,PERIOD
- select 1,21,4,CTRLE
- select 1,26,6,BANG
- select 1,33,8,POUND
- pend
-
-
- ;------------------------------KEYS------------------------------------------
-
- NUL: NOTHING
- CTRLC: TYPE 3
- CTRLE: TYPE 5
- BKSP: TYPE 8
- RETURN: TYPE 13
- ESCAPE: TYPE 27
- BANG: TYPE "!"
- QUOTE: TYPE 34
- POUND: TYPE "#"
- PLUSBKSP: TYPE "+",8
- PERIOD: TYPE "."
- SEMICOLON: TYPE ";"
- GREAT: TYPE ">"
- NO: TYPE "n"
- REL: TYPE "r"
- YES: TYPE "y"
- HOME: TYPE 0,71
- UP: TYPE 0,72
- LEFT: TYPE 0,75
- RIGHT: TYPE 0,77
- DOWN: TYPE 0,80
-
-
- \SAMPCODE\MOUSE\SOURCES\WS.DEF
-
- ;
- ; Wordstar pop-up mouse menus
- ;
-
- ; Set up initial labels for mouse commands
-
- begin leftb,rightb,bothb,mousel,mouser,mouseu,moused,16,40
-
- ; -------------------- Left Button ---------------------------
-
- ; Display edit/block menu if in edit mode else display no-file menu
-
- leftb: match 1,12,,"e",imen,chk33 ;Check for e in editing no file
- chk33: match 1,12,,"n",imen,chkl ;Check for n in not editing (V 3.3)
-
- chkl: match 1,11,,":",emen,nothing ;Check for : after drive letter
-
-
- ; -------------------- Right button ------------------------
-
- ; If in edit mode execute cursor movement menu else nothing
-
- rightb: match 1,11,,":",movmen,nothing ;Check state of WS
-
- ; --------------------- Both buttons ------------------------
-
- ; If in edit mode execute edit/file menu, if not in edit
- ; mode then type escape.
-
- bothb: match 1,11,,":",emen2,keyesc ;Both buttons - Check state
-
- ; -------------------- Mouse left -----------------------
-
- mousel: match 1,11,,":",lchkctrl,nothing ;Edit mode?
- lchkctrl: match 1,1,,"^",nothing,keyctrls ;Yes - Move left
-
- ; ------------------- Mouse right -----------------------
-
- mouser: match 1,11,,":",rchkctrl,nothing ;Edit mode?
- rchkctrl: match 1,1,,"^",nothing,keyctrld ;Yes - Move right
-
- ; --------------------- Mouse up -----------------------
-
- mouseu: match 1,11,,":",uchkctrl,nothing ;Edit mode?
- uchkctrl: match 1,1,,"^",nothing,keyctrle ;Yes - Move up
-
- ; ------------------- Mouse down -----------------------
-
- moused: match 1,11,,":",dchkctrl,nothing ;Edit mode?
- dchkctrl: match 1,1,,"^",nothing,keyctrlx ;Yes - Move down
-
- ; Initial menu displayed when left button pressed
-
- imen: popup 2,1
- text "╔══════════════════ < < < N O - F I L E M E N U > > > ═════
- text "║ Cancel menu Change drive Print a file Rename a file R
- text "║ Open document Toggle file dir Delete a file R
- text "║ Open non-doc Set help level Exit to DOS Copy a file R
- text "╚══════════════════════════════════════════════════════════════
- select 2,3,15
- select 3,3,15,keyd
- select 4,3,15,keyn
- select 2,18,15,keyl
- select 3,18,15,keyf
- select 4,18,15,hlpmen
- select 2,33,15,keyp
- ;
- select 4,33,15,keyx
- select 2,48,15,keye
- select 3,48,15,keyy
- select 4,48,15,keyo
- select 2,63,14,keyr
- select 3,63,14,keys
- select 4,63,14,keym
- pend
-
- ; Set help level
-
- hlpmen: popup 2,1
- text "╔═════ SET HELP LEVEL ════╗"
- text "║ Cancel menu ║"
- text "║ All menus displayed ║"
- text "║ Main menu suppressed ║"
- text "║ Prefix menus suppressed ║"
- text "║ All menus suppressed ║"
- text "╚═════════════════════════╝"
- select 2,3,23
- select 3,3,23,keyh3
- select 4,3,23,keyh2
- select 5,3,23,keyh1
- select 6,3,23,keyh0
- pend
-
- ; Edit/Block menu - selected by pressing left button in edit mode
-
- emen: popup 2,1
- text "╔══════ EDIT / BLOCK MENU ══════╗"
- text "║ Cancel Menu Begin block ║"
- text "║ Reform End block ║"
- text "║ Center text Copy block ║"
- text "║ Toggle insert Move block ║"
- text "║ Find text Delete block ║"
- text "║ Find/Replace Write block ║"
- text "║ Find/Replace agn Column block ║"
- text "╚═══════════════════════════════╝"
- select 2,3,17
- select 3,3,17,keyctrlb
- select 4,3,17,keyctrloc
- select 5,3,17,keyctrlv
- select 6,3,17,keyctrlqf
- select 7,3,17,keyctrlqa
- select 8,3,17,keyctrll
- select 2,20,12,keyctrlkb
- select 3,20,12,keyctrlkk
- select 4,20,12,keyctrlkc
- select 5,20,12,keyctrlkv
- select 6,20,12,keyctrlky
- select 7,20,12,keyctrlkw
- select 8,20,12,keyctrlkn
- pend
-
- ; Edit / File menu displayed when both buttons pressed in edit mode
-
- emen2: popup 2,1
- text "╔════════ EDIT / FILE MENU ════════╗"
- text "║ Cancel menu Print/Format menu ║"
- text "║ Save & Resume Margins/Tabs menu ║"
- text "║ Save & Done Toggles menu ║"
- text "║ Save & Exit File command menu ║"
- text "║ Abandon file Help menu ║"
- text "╚══════════════════════════════════╝"
- select 2,3,15
- select 3,3,15,keyctrlks
- select 4,3,15,keyctrlkd
- select 5,3,15,keyctrlkx
- select 6,3,15,keyctrlkq
- select 2,18,17,frmtmen
- select 3,18,17,mtmen
- select 4,18,17,togmen
- select 5,18,17,filmen
- select 6,18,17,hlpmen2
- pend
-
- ; Print/Format menu selected from Edit menu
-
- frmtmen: popup 2,1
- text "╔═════════════ PRINT FORMAT MENU ═══════════════╗"
- text "║ Cancel menu Subscript Print pause ║"
- text "║ Bold Superscript Overprint line ║"
- text "║ Double strike Strikeout Nonbreak space ║"
- text "║ Underscore Phantom space Standard pitch ║"
- text "║ Overprint char Phantom Rubout Alternate pitch ║"
- text "╚═══════════════════════════════════════════════╝"
- select 2,3,15
- select 3,3,15,keyctrlpb
- select 4,3,15,keyctrlpd
- select 5,3,15,keyctrlps
- select 6,3,15,keyctrlph
- select 2,18,15,keyctrlpv
- select 3,18,15,keyctrlpt
- select 4,18,15,keyctrlpx
- select 5,18,15,keyctrlpf
- select 6,18,15,keyctrlpg
- select 2,33,15,keyctrlpc
- select 3,33,15,keyctrlprk
- select 4,33,15,keyctrlpo
- select 5,33,15,keyctrlpn
- select 6,33,15,keyctrlpa
- pend
-
- ; Margins/Tabs menu selected from main edit menu
-
- mtmen: popup 2,1
- text "╔══════════ MARGINS / TABS MENU ════════════╗"
- text "║ Cancel menu Set a tab stop ║"
- text "║ Set left margin Set tab stop at cursor ║"
- text "║ Set right margin Set a paragraph tab ║"
- text "║ Release margins Clear a tab stop ║"
- text "╚═══════════════════════════════════════════╝"
- select 2,3,19
- select 3,3,19,keyctrlol
- select 4,3,19,keyctrlor
- select 5,3,19,keyctrlox
- select 2,22,22,keyctrloi
- select 3,22,22,keyctrloie
- select 4,22,22,keyctrlog
- select 5,22,22,keyctrlon
- pend
-
- ; Help menu selected from Edit/File menu
-
- hlpmen2: popup 2,1
- text "╔═════════════ HELP MENU ══════════════╗"
- text "║ Cancel menu Mouse help ║"
- text "║ Set help level Status line ║"
- text "║ Paragraph reform Ruler line ║"
- text "║ Flags in right column Margins & tabs ║"
- text "║ Dot commands Place markers ║"
- text "║ Index of commands Moving text ║"
- text "╚══════════════════════════════════════╝"
- select 2,3,22
- select 3,3,22,chlpmen
- select 4,3,22,keyctrljb
- select 5,3,22,keyctrljf
- select 6,3,22,keyctrljd
- select 7,3,22,keyctrlji
- select 2,25,14,mousehlp
- select 3,25,14,keyctrljs
- select 4,25,14,keyctrljr
- select 5,25,14,keyctrljm
- select 6,25,14,keyctrljp
- select 7,25,14,keyctrljv
- pend
-
- ; Set help level from edit mode - ctrlj then h0,h1,h2,h3
-
- chlpmen: execute keyctrlj,hlpmen
-
- ; Mouse help
-
- mousehlp: popup 2,1
- text "╔════════════════ MOUSE HELP ══════════════════╗"
- text "║ ║"
- text "║ Left button - Displays Edit/Block menu ║"
- text "║ Right button - Displays Cursor movement menu ║"
- text "║ Both buttons - Displays Edit/File menu ║"
- text "║ ║"
- text "║ Moving the mouse up,down,left, or right will ║"
- text "║ cause the cursor to move in that direction. ║"
- text "║ ║"
- text "╚═══════════════════════════════════════════════╝"
- select 1,19,11
- pend
-
- ; File command menu selected from main edit menu
-
- filmen: popup 2,1
- text "╔ FILE COMMANDS ╗"
- text "║ Cancel menu ║"
- text "║ Read a file ║"
- text "║ Copy a file ║"
- text "║ Delete a file ║"
- text "║ Rename a file ║"
- text "║ Print a file ║"
- text "╚═══════════════╝"
- select 2,3,13
- select 3,3,13,keyctrlkr
- select 4,3,13,keyctrlko
- select 5,3,13,keyctrlkj
- select 6,3,13,keyctrlke
- select 7,3,13,keyctrlkp
- pend
-
- ; Toggle menu selected from main edit menu
-
- togmen: popup 2,1
- text "╔════════════ TOGGLES MENU ══════════════╗"
- text "║ Cancel menu Toggle soft hyphen ║"
- text "║ Toggle ruler line Toggle vari-Tabs ║"
- text "║ Toggle word wrap Toggle print display ║"
- text "║ Toggle justify Toggle auto page brk ║"
- text "╚════════════════════════════════════════╝"
- select 2,3,18
- select 3,3,18,keyctrlot
- select 4,3,18,keyctrlow
- select 5,3,18,keyctrloj
- select 2,21,20,keyctrloe
- select 3,21,20,keyctrlov
- select 4,21,20,keyctrlod
- select 5,21,20,keyctrlop
- pend
-
- ; Cursor movement menu displayed when right button pressed in edit mode
-
- movmen: popup 2,1
- text "╔═══════ CURSOR MOVEMENT ═══════╗"
- text "║ Cancel menu Top of screen ║"
- text "║ Screen up Bottom of scrn ║"
- text "║ Screen down Start of file ║"
- text "║ Previous place End of file ║"
- text "╚═══════════════════════════════╝"
- select 2,3,15
- select 3,3,15,keyctrlr
- select 4,3,15,keyctrlc
- select 5,3,15,keyctrlqp
- select 2,18,15,keyctrlqe
- select 3,18,15,keyctrlqx
- select 4,18,15,keyctrlqr
- select 5,18,15,keyctrlqc
- pend
-
- ; --- Key Commands ---
-
- keyctrls: type 19 ;Ctrl S - Left char
- keyctrld: type 4 ;Ctrl D - Right char
- keyctrle: type 5 ;Ctrl E - Up char
- keyctrlx: type 24 ;Ctrl X - Down char
- keyctrlr: type 18 ;Ctrl R - Screen down
- keyctrlj: type 10
- keyctrlk: type 11
- keyctrlkb: type 11,"B"
- keyctrlkc: type 11,"C"
- keyctrlkd: type 11,"D"
- keyctrlkk: type 11,"K"
- keyctrlkn: type 11,"N"
- keyctrlkp: type 11,"P"
- keyctrlkx: type 11,"X"
- keyctrlks: type 11,"S"
- keyctrlkq: type 11,"Q"
- keyctrlkv: type 11,"V"
- keyctrlkw: type 11,"W"
- keyctrlky: type 11,"Y"
- keyctrlkr: type 11,"R"
- keyctrlko: type 11,"O"
- keyctrlkj: type 11,"J"
- keyctrlke: type 11,"E"
- keyctrll: type 12
- keyctrlb: type 2
- keyctrlc: type 3
- keyctrlg: type 7
- keyctrlp: type 16
- keyctrlq: type 17
- keyctrlo: type 15
- keyctrlv: type 22
- keyctrljb: type 10,"B"
- keyctrljf: type 10,"F"
- keyctrljd: type 10,"D"
- keyctrlji: type 10,"I"
- keyctrljs: type 10,"S"
- keyctrljr: type 10,"R"
- keyctrljp: type 10,"P"
- keyctrljm: type 10,"M"
- keyctrljv: type 10,"V"
- keyctrloc: type 15,"C"
- keyctrlox: type 15,"X"
- keyctrlol: type 15,"L"
- keyctrlor: type 15,"R"
- keyctrloi: type 15,"I"
- keyctrloie: type 15,"I",27
- keyctrlog: type 15,"G"
- keyctrlon: type 15,"N"
- keyctrlot: type 15,"T"
- keyctrlow: type 15,"W"
- keyctrloj: type 15,"J"
- keyctrloe: type 15,"E"
- keyctrlov: type 15,"V"
- keyctrlod: type 15,"D"
- keyctrlop: type 15,"P"
- keyctrlprk: type 16,13 ;Ctrl K then return key
- keyctrlpa: type 16,"A"
- keyctrlpb: type 16,"B"
- keyctrlpc: type 16,"C"
- keyctrlpd: type 16,"D"
- keyctrlpf: type 16,"F"
- keyctrlpg: type 16,"G"
- keyctrlph: type 16,"H"
- keyctrlpn: type 16,"N"
- keyctrlpo: type 16,"O"
- keyctrlps: type 16,"S"
- keyctrlpt: type 16,"T"
- keyctrlpv: type 16,"V"
- keyctrlpx: type 16,"X"
- keyctrlqa: type 17,"A"
- keyctrlqe: type 17,"E"
- keyctrlqf: type 17,"F"
- keyctrlqr: type 17,"R"
- keyctrlqc: type 17,"C"
- keyctrlqk: type 17,"K"
- keyctrlqp: type 17,"P"
- keyctrlqq: type 17,"Q"
- keyctrlqx: type 17,"X"
- keyctrlqy: type 17,"Y"
- keyd: type "D" ;D - Open Document
- keye: type "E" ;E - Rename
- keyf: type "F" ;F - Toggle directory
- keyh: type "H" ;H - Help menu
- keyh0: type "H0" ;H - Set help level 0
- keyh1: type "H1" ;H - Set help level 1
- keyh2: type "H2" ;H - Set help level 2
- keyh3: type "H3" ;H - Set help level 3
- keyl: type "L" ;L - Change drive
- keym: type "M" ;M - Run mailmerge
- keyn: type "N" ;N - Open Non document
- keyo: type "O" ;O - Copy
- keyp: type "P" ;P - Print
- keyr: type "R" ;R - Run program
- keys: type "S" ;S - Run spellstar
- keyx: type "X" ;X - Exit
- keyy: type "Y" ;Y - Delete
- keyesc: type 27 ;Escape
-
- NOTHING: NOTHING
-
- ; The end
-
- \SAMPCODE\VIDEO
- \SAMPCODE\VIDEO\1
- \SAMPCODE\VIDEO\1\1_3.C
-
- /* Listing 1-3 */
-
- main( argc, argv )
- int argc;
- char **argv;
- {
- int ModeNumber;
- void SetVmode();
-
-
- if (argc != 2) /* verify command line syntax */
- {
- printf( "\nSyntax: SETVMODE n\n" );
- exit( 1 );
- }
-
- sscanf( argv[1], "%x", &ModeNumber ); /* get desired mode number */
-
- SetVmode( ModeNumber ); /* call ROM BIOS via INT 10h
- }
-
- \SAMPCODE\VIDEO\1\1_4.C
-
- /* Listing 1-4 */
-
- main()
- {
- int GetVmode();
-
- return( GetVmode() );
- }
-
- \SAMPCODE\VIDEO\1\1_5.C
-
- /* Listing 1-5 */
-
- #include "dos.h"
-
- main()
- {
- struct BYTEREGS regs; /* BYTEREGS defined in dos.h */
-
-
- regs.ah = 0x0F; /* AH=0x0F (ROM BIOS function number)
-
- int86( 0x10, ®s, ®s ); /* perform interrupt 10h */
-
- return( (int)regs.al );
- }
-
- \SAMPCODE\VIDEO\1\1_1.ASM
-
- TITLE 'Listing 1-1'
- NAME SetVmode
- PAGE 55,132
-
- ;
- ; Name: SetVmode
- ;
- ; Function: Call IBM PC ROM BIOS to set a video display mode.
- ;
- ; Caller: Microsoft C:
- ;
- ; void SetVmode(n);
- ;
- ; int n; /* video mode */
- ;
-
- ARGn EQU byte ptr [bp+4] ; stack frame addressing
-
- EQUIP_FLAG EQU byte ptr ds:[10h] ; (in Video Display Data Area)
-
- CGAbits EQU 00100000b ; bits for EQUIP_FLAG
- MDAbits EQU 00110000b
-
- _TEXT SEGMENT byte public 'CODE'
- ASSUME cs:_TEXT
-
- PUBLIC _SetVmode
- _SetVmode PROC near
-
- push bp ; preserve caller registers
- mov bp,sp
- push ds
-
- mov ax,40h
- mov ds,ax ; DS -> Video Display Data Area
-
- mov bl,CGAbits ; BL := bits indicating presence of C
-
- mov al,ARGn ; AL := desired video mode number
-
- mov ah,al ; test if desired mode is monochrome
- and ah,7
- cmp ah,7
- jne L01 ; jump if desired mode not 7 or 0Fh
-
- mov bl,MDAbits ; BL := bits indicating presence of M
-
- L01: and EQUIP_FLAG,11001111b
- or EQUIP_FLAG,bl ; set bits in EQUIP_FLAG
-
- xor ah,ah ; AH := 0 (INT 10h function number)
-
- push bp
- int 10h ; call ROM BIOS to set the video mode
- pop bp
-
- pop ds ; restore caller registers and return
- mov sp,bp
- pop bp
- ret
-
- _SetVmode ENDP
-
- _TEXT ENDS
-
- END
-
- \SAMPCODE\VIDEO\1\1_2.ASM
-
- TITLE 'Listing 1-2'
- NAME GetVmode
- PAGE 55,132
-
- ;
- ; Name: GetVmode
- ;
- ; Function: Call IBM PC ROM BIOS to set a video display mode.
- ;
- ; Caller: Microsoft C:
- ;
- ; int GetVmode();
- ;
-
- _TEXT SEGMENT byte public 'CODE'
- ASSUME cs:_TEXT
-
- PUBLIC _GetVmode
- _GetVmode PROC near
-
- push bp ; preserve caller registers
- mov bp,sp
-
- mov ah,0Fh ; AH := 0Fh (INT 10h function number)
-
- push bp
- int 10h ; call ROM BIOS to get video mode num
- pop bp
-
- xor ah,ah ; AX := video mode number
-
- mov sp,bp
- pop bp
- ret
-
- _GetVmode ENDP
-
- _TEXT ENDS
-
- END
-
- \SAMPCODE\VIDEO\10
- \SAMPCODE\VIDEO\10\10_15.C
-
- /* Listing 10-15 */
-
- #define Points 14 /* displayed scan lines per character */
- #define StartCharCode 0x80 /* first character code in "window" */
- #define CGenDefSize 32 /* (use 16 for Hercules) */
-
- char far *CRT_MODE = 0x00400049; /* BIOS video mode number */
- int far *CRT_COLS = 0x0040004A; /* characters per row */
-
- char far *VideoBuffer; /* pointer to video buffer */
- char far *CharDefTable = 0xA0000000; /* pointer to char def RAM */
- /* (use 0xB0004000 for Hercules) */
- main()
- {
- int i;
- int CharCode;
- int CharOffset;
- int CharScanLine;
- int CharDefOffset;
- int Row,Column;
-
-
- /* establish alphanumeric mode */
-
- if (*CRT_MODE == 7) /* set video buffer pointer */
- VideoBuffer = 0xB0000000;
- else
- VideoBuffer = 0xB8000000;
-
- AlphaModeSet( 8, Points, 8 );
-
-
- /* establish a tiled graphics window in the upper left corner */
-
- CharCode = StartCharCode;
-
- for ( Row=0; Row<4; Row++ )
- for ( Column=0; Column< 32; Column++ )
- {
- CharOffset = (Row*(*CRT_COLS) + Column) * 2;
- VideoBuffer[CharOffset] = CharCode++;
- }
-
-
- /* clear the window */
-
- CGenModeSet(); /* make character generator RAM addressable *
-
- for (CharCode=StartCharCode; CharCode<256; CharCode++ )
- for ( CharScanLine=0; CharScanLine<Points; CharScanLine++ )
- {
- CharDefOffset = CharCode*CGenDefSize + CharScanLine;
- CharDefTable[CharDefOffset] = 0;
- }
-
-
- /* draw a few lines */
-
- for ( i=0; i<256; i++ ) /* horizontal lines */
- {
- SetPixel( i, 0 );
- SetPixel( i, 4*Points-1 );
- }
-
- for ( i=0; i<4*Points-1; i++ ) /* vertical lines */
- {
- SetPixel( 0, i );
- SetPixel( 255, i );
- }
-
- for( i=0; i<Points*4; i++ ) /* diagonal lines */
- {
- SetPixel( i, i );
- SetPixel( 255-i, i );
- }
-
- CGenModeClear(); /* restore alphanumeric mode */
-
- }
-
- SetPixel( x, y )
- int x,y; /* pixel coordinates */
- {
- int CharCode;
- int CharScanLine;
- int BitMask;
- int CharDefOffset;
-
-
- CharCode = StartCharCode + (y/Points)*32 + x/8;
- CharScanLine = y % Points; /* y MOD Points */
- BitMask = 0x80 >> (x % 8); /* 10000000b SHR (x MOD 8) */
-
- CharDefOffset = CharCode*CGenDefSize + CharScanLine;
- CharDefTable[CharDefOffset] |= BitMask; /* OR the pixel */
- }
-
- \SAMPCODE\VIDEO\10\10_16.C
-
- SetPixel( x, y )
- int x,y; /* pixel coordinates */
- {
- int CharCode;
- int CharScanLine;
- int BitMask;
- int CharDefOffset;
-
-
- /* the window is 32 characters across */
- CharCode = StartCharCode + (y/Points)*32 + x/8;
- CharScanLine = y % Points; /* y MOD Points */
- BitMask = 0x80 >> (x % 8); /* 10000000b SHR (x MOD 8) */
-
- CharDefOffset = CharCode*2 + CharScanLine*512 + 1;
- CharDefTable[CharDefOffset] |= BitMask; /* OR the pixel */
- }
-
- \SAMPCODE\VIDEO\10\10_12.ASM
-
- TITLE 'Listing 10-12'
- NAME AlphaModeSet
- PAGE 55,132
-
- ;
- ; Name: AlphaModeSet
- ;
- ; Program the CRTC in 80-column EGA alphanumeric modes
- ;
- ; Caller: Microsoft C:
- ;
- ; void AlphaModeSet(w,h,c);
- ;
- ; int w; /* width of character matrix */
- ; int h; /* height of character matrix */
- ; int c; /* character code size */
- ;
-
- ARGw EQU byte ptr [bp+4] ; must be 8 or 9 pixels wide
- ARGh EQU byte ptr [bp+6] ; must be 2-32 pixels high
- ARGc EQU byte ptr [bp+8] ; must be 8 or 9 bits
-
- CRT_MODE EQU 49h ; addresses in video BIOS data area
- CRT_COLS EQU 4Ah
- ADDR_6845 EQU 63h
-
- DGROUP GROUP _DATA
-
- _TEXT SEGMENT byte public 'CODE'
- ASSUME cs:_TEXT,ds:DGROUP
-
- PUBLIC _AlphaModeSet
- _AlphaModeSet PROC near
-
- push bp ; preserve caller registers
- mov bp,sp
- push si
-
- ; Program the CRTC
-
- mov bx,40h
- mov es,bx ; ES := video BIOS data segment
-
- mov bl,ARGw ; BL := character width
- mov bh,ARGh ; BH := character height
- call SetCRTC
-
- ; Program the Sequencer and Attribute Controller for 8 or 9 dots per characte
-
- mov dx,3C4h
- mov ax,0100h ; AH bit 1 := 0 (synchronous reset)
- ; AL := 0 (Reset register number)
- cli ; disable interrupts
- out dx,ax ; Sequencer synchronous reset
-
- mov bx,1 ; BH,BL := values for 8-wide chars:
- ; BH := 0 (value for Horiz Pel Pan)
- ; BL := 1 (value for Clocking Mode)
- cmp ARGw,8
- je L01 ; jump if 8-wide characters
-
- mov bx,0800h ; BH,BL := values for 9-wide characte
-
- L01: mov ah,bl ; AH := value for Clocking Mode reg
- mov al,1 ; AL := Clocking Mode reg number
- out dx,ax ; program the Sequencer
-
- mov ax,0300h ; AH := 3 (disable reset)
- ; AL := 0 (Sequencer register number)
- out dx,ax ; disable Sequencer reset
- sti ; enable interrupts
-
- mov bl,13h ; BL := Horizontal Pel Pan reg number
- mov ax,1000h ; AH := 10H (INT 10H function number)
- ; AL := 0 (set specified register)
- int 10h ; program Attribute Controller
-
- ; Program the Attribute Controller for 8- or 9-bit character codes
-
- mov ax,1000h ; AH := 10H (INT 10H function number)
- ; AL := 0 (set specified register)
- mov bx,0F12h ; BH := 0FH (Color Plane Enable value
- ; BL := 12H (Color Plane Enable reg #
- cmp ARGc,8
- je L02 ; jump if 8-bit character codes
-
- mov bh,7 ; BH bit 3 := 0 (ignore bit 3 of all
- ; attributes)
- L02: int 10h ; update Color Plane Enable register
-
- ; update video BIOS data area
-
- cmp byte ptr es:[CRT_MODE],7
- jne L03 ; jump if not monochrome mode
-
- mov ax,720 ; AX := displayed pixels per row
- div ARGw ; AL := displayed character columns
- mov es:[CRT_COLS],al
-
- L03: pop si
- pop bp
- ret
-
- _AlphaModeSet ENDP
-
-
- SetCRTC PROC near ; Caller: BH = character height
- ; BL = character width
-
- push dx
- mov dx,es:[ADDR_6845] ; CRTC I/O port
-
- ; establish CRTC vertical timing and cursor position in character matrix
-
- push bx ; preserve height and width
- mov ax,1110h ; AH := 11H (INT 10H function number)
- ; AL := 0 (user alpha load)
- xor cx,cx ; CX := 0 (store no characters)
- int 10h ; call BIOS to program CRTC for
- ; vertical size of characters
-
- pop ax ; AH := character height
- push ax ; preserve height and width
- sub ah,2 ; AH := starting scan line for cursor
- mov al,0Ah ; AL := 0AH (Cursor Start reg number)
- out dx,ax ; update CRTC Cursor Start register
-
- mov ax,000Bh ; AH := 0 (Cursor End value)
- ; AL := 0BH (Cursor End reg number)
- out dx,ax ; update CRTC Cursor End register
-
- ; establish CRTC horizontal timing
-
- pop bx ; BX := character height and width
- cmp byte ptr es:[CRT_MODE],7
- jne L10 ; exit if not monochrome mode
-
- xor bh,bh ; BX := character width
- sub bl,8 ; BX := 0 or 1
- neg bx ; BX := 0 or 0FFFFH
- and bx,14 ; BX := 0 or 14 (offset into table)
- mov si,bx ; SI := offset into table
-
- add si,offset DGROUP:HorizParms ; DS:SI -> parameters
- call UpdateCRTC
-
- L10: pop dx
- ret
-
- SetCRTC ENDP
-
-
- UpdateCRTC PROC near ; Caller: DX = CRTC address por
- ; DS:SI -> parameters
- ; Destroys: AX,CX
-
- mov cx,7 ; CX := number of registers to update
-
- L20: lodsw ; AH := data for CRTC register in AL
- out dx,ax ; update the register
- loop L20
-
- ret
-
- UpdateCRTC ENDP
-
- _TEXT ENDS
-
-
- _DATA SEGMENT word public 'DATA'
-
- HorizParms DW 6C00h,5901h,6002h,2403h,5B04h,6A05h,2D13h ; 8-wide
- DW 6000h,4F01h,5602h,3A03h,5104h,6005h,2813h ; 9-wide
-
- _DATA ENDS
-
- END
-
- \SAMPCODE\VIDEO\10\10_13.ASM
-
- TITLE 'Listing 10-13'
- NAME AlphaModeSet
- PAGE 55,132
-
- ;
- ; Name: AlphaModeSet
- ;
- ; Program the CRTC in 80-column VGA alphanumeric modes
- ;
- ; Caller: Microsoft C:
- ;
- ; void AlphaModeSet(w,h,c);
- ;
- ; int w; /* width of character matrix */
- ; int h; /* height of character matrix */
- ; int c; /* character code size */
- ;
-
- ARGw EQU byte ptr [bp+4] ; must be 8 or 9 pixels wide
- ARGh EQU byte ptr [bp+6] ; must be 2-32 pixels high
- ARGc EQU byte ptr [bp+8] ; must be 8 or 9 bits
-
- CRT_COLS EQU 4Ah ; addresses in video BIOS data area
- ADDR_6845 EQU 63h
-
- DGROUP GROUP _DATA
-
- _TEXT SEGMENT byte public 'CODE'
- ASSUME cs:_TEXT,ds:DGROUP
-
- PUBLIC _AlphaModeSet
- _AlphaModeSet PROC near
-
- push bp ; preserve caller registers
- mov bp,sp
- push si
-
- ; Program the CRTC
-
- mov bx,40h
- mov es,bx ; ES := video BIOS data segment
-
- mov bl,ARGw ; BL := character width
- mov bh,ARGh ; BH := character height
- call SetCRTC
-
- ; Program the Sequencer and Attribute Controller for 8 or 9 dots per characte
-
- mov dx,3C4h
- mov ax,0100h ; AH bit 1 := 0 (synchronous reset)
- ; AL := 0 (Reset register number)
- cli ; disable interrupts
- out dx,ax ; Sequencer synchronous reset
-
- mov bx,1 ; BH,BL := values for 8-wide chars:
- ; BH := 0 (value for Horiz Pel Pan)
- ; BL := 1 (value for Clocking Mode)
- cmp ARGw,8
- je L01 ; jump if 8-wide characters
-
- mov bx,0800h ; BH,BL := values for 9-wide characte
-
- L01: mov ah,bl ; AH := value for Clocking Mode reg
- mov al,1 ; AL := Clocking Mode reg number
- out dx,ax ; program the Sequencer
-
- mov ax,0300h ; AH := 3 (disable reset)
- ; AL := 0 (Sequencer register number)
- out dx,ax ; disable Sequencer reset
- sti ; enable interrupts
-
- mov bl,13h ; BL := Horizontal Pel Pan reg number
- mov ax,1000h ; AH := 10H (INT 10H function number)
- ; AL := 0 (set specified register)
- int 10h ; program Attribute Controller
-
- ; Program the Attribute Controller for 8- or 9-bit character codes
-
- mov ax,1000h ; AH := 10H (INT 10H function number)
- ; AL := 0 (set specified register)
- mov bx,0F12h ; BH := 0FH (Color Plane Enable value
- ; BL := 12H (Color Plane Enable reg #
- cmp ARGc,8
- je L02 ; jump if 8-bit character codes
-
- mov bh,7 ; BH bit 3 := 0 (ignore bit 3 of all
- ; attributes)
- L02: int 10h ; update Color Plane Enable register
-
- ; update video BIOS data area
-
- mov ax,720 ; AX := displayed pixels per row
- div ARGw ; AL := displayed character columns
- mov es:[CRT_COLS],al
-
- pop si
- pop bp
- ret
-
- _AlphaModeSet ENDP
-
-
- SetCRTC PROC near ; Caller: BH = character height
- ; BL = character width
-
- push dx
- mov dx,es:[ADDR_6845] ; CRTC I/O port
-
- ; establish CRTC vertical timing and cursor position in character matrix
-
- push bx ; preserve char height and width
- mov ax,1110h ; AH := 11H (INT 10H function number)
- ; AL := 0 (user alpha load)
- xor cx,cx ; CX := 0 (store no characters)
- int 10h ; call BIOS to program CRTC
- pop bx
-
- ; enable I/O writes to CRTC registers
-
- mov al,11h ; AL := Vertical Retrace End reg numb
- out dx,al
- inc dx
- in al,dx ; AL := current value of this registe
- dec dx
-
- mov ah,al ; AH := current value
- mov al,11h ; AL := register number
- push ax ; save on stack
-
- and ah,01111111b ; zero bit 7
- out dx,ax ; update this register
-
- ; establish CRTC horizontal timing
-
- xor bh,bh ; BX := character width
- sub bl,8 ; BX := 0 or 1
- neg bx ; BX := 0 or 0FFFFH
- and bx,14 ; BX := 0 or 14 (offset into table)
- mov si,bx ; SI := offset into table
-
- add si,offset DGROUP:HorizParms ; DS:SI -> parameters
- call UpdateCRTC
-
- ; write-protect CRTC registers
-
- pop ax ; AX := previous VR End register data
- out dx,ax ; restore this register
-
- pop dx
- ret
-
- SetCRTC ENDP
-
-
- UpdateCRTC PROC near ; Caller: DX = CRTC address por
- ; DS:SI -> parameters
- ; Destroys: AX,CX
-
- mov cx,7 ; CX := number of registers to update
-
- L10: lodsw ; AH := data for CRTC register in AL
- out dx,ax ; update the register
- loop L10
-
- ret
-
- UpdateCRTC ENDP
-
- _TEXT ENDS
-
-
- _DATA SEGMENT word public 'DATA'
-
- HorizParms DW 6A00h,5901h,5A02h,8D03h,6304h,8805h,2D13h ; 8-wide
- DW 5F00h,4F01h,5002h,8203h,5504h,8105h,2813h ; 9-wide
-
- _DATA ENDS
-
- END
-
- \SAMPCODE\VIDEO\10\10_14.ASM
-
- TITLE 'Listing 10-14'
- NAME AlphaModeSet
- PAGE 55,132
-
- ;
- ; Name: AlphaModeSet
- ;
- ; Function: Program the CRTC in alphanumeric modes on HGC+ or InColor car
- ;
- ; Caller: Microsoft C:
- ;
- ; void AlphaModeSet(w,h,c);
- ;
- ; int w; /* width of character matrix */
- ; int h; /* height of character matrix */
- ; int c; /* character code size */
- ;
-
- ARGw EQU byte ptr [bp+4] ; must be 8 or 9 pixels wide
- ARGh EQU byte ptr [bp+6] ; must be 4-16 pixels high
- ARGc EQU byte ptr [bp+8] ; must be 8 or 12 bits
-
- CRT_COLS EQU 4Ah
- CRT_LEN EQU 4Ch
- CRT_MODE_SET EQU 65h
- ROWS EQU 84h
-
- DGROUP GROUP _DATA
-
- _TEXT SEGMENT byte public 'CODE'
- ASSUME cs:_TEXT,ds:DGROUP
-
- PUBLIC _AlphaModeSet
- _AlphaModeSet PROC near
-
- push bp ; preserve caller registers
- mov bp,sp
- push ds
- push si
-
- ; Set Configuration Switch to bring RAM starting at B000:4000 into memory map
-
- mov dx,3BFh ; DX := Configuration Switch port
- mov al,1 ; AL bit 1 := 0 (exclude 2nd 32K of
- ; video buffer)
- ; AL bit 0 := 1 (make RAM at B000:400
- out dx,ax ; addressable)
-
- ; Blank the screen to avoid interference during CRTC programming
-
- mov dx,3B8h ; DX := CRTC Mode Control Register po
- xor al,al ; AL bit 3 := 0 (disable video signal
- out dx,al ; blank the screen
-
- ; Program the CRTC
-
- mov bh,ARGw ; BH := character width
- mov bl,ARGh ; BL := character height
- call SetHercCRTC
-
- ; Set the xModeReg
-
- mov dx,3B4h ; DX := CRTC address port
- mov ax,114h ; AH bit 0 := 1 (enable RAM-based
- ; character generator)
- ; AL := 14h (xModeReg number)
- cmp ARGw,9
- je L01 ; jump if 9-wide characters
-
- or ah,2 ; AH bit 1 := 1 (8-wide characters)
-
- L01: cmp ARGc,8
- je L02 ; jump if 8-bit character codes
-
- or ah,4 ; AH bit 2 := 1 (12-bit character cod
-
- L02: out dx,ax ; update the register
-
- ; update video BIOS data area
-
- mov ax,40h
- mov ds,ax ; DS := video BIOS data segment
-
- mov ax,720 ; AX := displayed pixels per row
- div ARGw ; AL := displayed character columns
- mov ds:[CRT_COLS],al
-
- mov ax,350 ; AX := number of displayed scan line
- div ARGh ; AL := displayed character rows
- dec al ; AL := (character rows) - 1
- mov ds:[ROWS],al
-
- inc al
- mul byte ptr ds:[CRT_COLS]
- shl ax,1 ; AX := rows * columns * 2
- mov ds:[CRT_LEN],ax
-
- ; re-enable display and exit
-
- mov dx,3B8h ; DX := CRT Mode Control port
- mov al,ds:[CRT_MODE_SET] ; restore previous value
- out dx,al
-
- pop si
- pop ds
- pop bp
- ret
-
- _AlphaModeSet ENDP
-
-
- SetHercCRTC PROC near ; Caller: BH = character width
- ; BL = character height
-
- push dx
- mov dx,3B4h ; DX := CRTC Address Reg port 3B4h
-
- ; establish cursor position in character matrix
-
- mov ah,bl
- dec ah ; AH := value for Max Scan Line reg
- mov al,9 ; AL := Max Scan Line register number
- out dx,ax
-
- mov al,0Bh ; AL := Cursor End reg number
- out dx,ax ; set cursor to end on last line of
- ; character matrix
-
- sub ax,101h ; AH := second-to-last line
- ; AL := 0AH (Cursor Start reg number)
- out dx,ax ; set cursor to start on second-to-
- ; last line
-
- ; compute offsets into parameter tables
-
- sub bx,0804h ; BH := 0 or 1
- ; BL := 0 through 12
- add bx,bx
- add bx,bx ; BH := 0 or 4
- ; BL := 0 through 48
- ; establish CRTC horizontal timing
-
- push bx ; preserve BX
- mov bl,bh
- xor bh,bh ; BX := 0 or 4
- add bx,offset DGROUP:HorizParms ; DS:BX -> parameters
-
- mov al,0 ; AL := first CRTC reg to update
- call UpdateCRTC
-
- ; establish vertical timing
-
- pop bx
- xor bh,bh ; BX := 0 through 48
- add bx,offset DGROUP:VertParms ; DS:BX -> parameters
-
- mov al,4 ; AL := first CRTC reg to update
- call UpdateCRTC
-
- pop dx ; restore DX
- ret
-
- SetHercCRTC ENDP
-
-
- UpdateCRTC PROC near ; Caller: AL = first reg number
- ; DX = CRTC address por
- ; DS:BX -> parameters
- ; Destroys: AX,CX
-
- mov cx,4 ; CX := number of registers to update
-
- L10: mov ah,[bx] ; AH := data for CRTC register in AL
- out dx,ax ; update the register
- inc ax ; AL := next register number
- inc bx ; DS:BX -> next value in table
- loop L10
-
- ret
-
- UpdateCRTC ENDP
-
- _TEXT ENDS
-
-
- _DATA SEGMENT word public 'DATA'
-
- HorizParms DB 6Dh,5Ah,5Ch,0Fh ; 8 pixels wide
- DB 61h,50h,52h,0Fh ; 9 pixels wide
-
-
- VertParms DB 5Ch,02h,58h,59h ; 4 scan lines high
- DB 4Ah,00h,46h,46h ; 5
- DB 3Dh,04h,3Ah,3Bh ; 6
- DB 34h,06h,32h,33h ; 7
- DB 2Dh,02h,2Bh,2Ch ; 8
- DB 28h,01h,26h,27h ; 9
- DB 24h,00h,23h,23h ; 10
- DB 20h,07h,1Fh,20h ; 11
- DB 1Dh,0Ah,1Dh,1Dh ; 12
- DB 1Bh,06h,1Ah,1Bh ; 13
- DB 19h,06h,19h,19h ; 14
- DB 17h,0Ah,17h,17h ; 15
- DB 16h,02h,15h,16h
-
- _DATA ENDS
-
- END
-
- \SAMPCODE\VIDEO\10\10_1A.ASM
-
- TITLE 'Listing 10-1a'
- NAME CGenModeSet
- PAGE 55,132
-
- ;
- ; Name: CGenModeSet
- ;
- ; Direct access to EGA and VGA alphanumeric character generator
- ;
- ; Caller: Microsoft C:
- ;
- ; void CGenModeSet();
- ;
-
- DGROUP GROUP _DATA
-
- _TEXT SEGMENT byte public 'CODE'
- ASSUME cs:_TEXT,ds:DGROUP
-
- PUBLIC _CGenModeSet
- _CGenModeSet PROC near
-
- push bp ; preserve caller registers
- mov bp,sp
- push si
-
- ; Program the Sequencer
-
- cli ; disable interrupts
- mov dx,3C4h ; Sequencer port address
- mov si,offset DGROUP:SeqParms
- mov cx,4
-
- L01: lodsw ; AH := value for Sequencer register
- ; AL := register number
- out dx,ax ; program the register
- loop L01
- sti ; enable interrupts
-
- ; Program the Graphics Controller
-
- mov dl,0CEh ; DX := 3CEH (Graphics Controller por
- ; address)
- mov si,offset DGROUP:GCParms
- mov cx,3
-
- L02: lodsw ; program the Graphics Controller
- out dx,ax
- loop L02
-
- pop si
- pop bp
- ret
-
- _CGenModeSet ENDP
-
- _TEXT ENDS
-
-
- _DATA SEGMENT word public 'DATA'
-
- ; Format of the parameters is: Lo-order byte: Register number
- ; Hi-order byte: Value for reg
-
- SeqParms DW 0100h ; synchronous reset
- DW 0402h ; CPU writes only to map 2
- DW 0704h ; sequential addressing
- DW 0300h ; clear synchronous reset
-
- GCParms DW 0204h ; select map 2 for CPU reads
- DW 0005h ; disable odd-even addressing
- DW 0006h ; map starts at A000:0000
-
- _DATA ENDS
-
- END
-
- \SAMPCODE\VIDEO\10\10_1B.ASM
-
- TITLE 'Listing 10-1b'
- NAME CGenModeClear
- PAGE 55,132
-
- ;
- ; Name: CGenModeClear
- ;
- ; Restore EGA or VGA alphanumeric mode after accessing
- ; character generator RAM
- ;
- ; Caller: Microsoft C:
- ;
- ; void CGenModeClear();
- ;
-
-
- DGROUP GROUP _DATA
-
- _TEXT SEGMENT byte public 'CODE'
- ASSUME cs:_TEXT,ds:DGROUP
-
- PUBLIC _CGenModeClear
- _CGenModeClear PROC near
-
- push bp ; preserve caller registers
- mov bp,sp
- push si
-
- ; Program the Sequencer
-
- cli ; disable interrupts
- mov dx,3C4h ; Sequencer port address
- mov si,offset DGROUP:SeqParms
- mov cx,4
-
- L01: lodsw ; AH := value for Sequencer register
- ; AL := register number
- out dx,ax ; program the register
- loop L01
- sti ; enable interrupts
-
- ; Program the Graphics Controller
-
- mov dl,0CEh ; DX := 3CEH (Graphics Controller por
- ; address)
- mov si,offset DGROUP:GCParms
- mov cx,3
-
- L02: lodsw ; program the Graphics Controller
- out dx,ax
- loop L02
-
- mov ah,0Fh ; AH := INT 10H function number
- int 10h ; get video mode
-
- cmp al,7
- jne L03 ; jump if not monochrome mode
-
- mov ax,0806h ; program Graphics Controller
- out dx,ax ; to start map at B000:0000
-
- L03: pop si
- pop bp
- ret
-
- _CGenModeClear ENDP
-
- _TEXT ENDS
-
-
- _DATA SEGMENT word public 'DATA'
-
- ; Format of the parameters is: Lo-order byte: Register number
- ; Hi-order byte: Value for reg
-
- SeqParms DW 0100h ; synchronous reset
- DW 0302h ; CPU writes to maps 0 and 1
- DW 0304h ; odd-even addressing
- DW 0300h ; clear synchronous reset
-
- GCParms DW 0004h ; select map 0 for CPU reads
- DW 1005h ; enable odd-even addressing
- DW 0E06h ; map starts at B800:0000
-
- _DATA ENDS
-
- END
-
- \SAMPCODE\VIDEO\10\10_5.ASM
-
- TITLE 'Listing 10-5'
- NAME SetFontPages
- PAGE 55,132
-
- ;
- ; Name: SetFontPages
- ;
- ; Update MCGA Font Pages
- ;
- ; Caller: Microsoft C:
- ;
- ; void SetFontPages(n0,n1);
- ;
- ; int n0,n1; /* font page values */
- ;
-
- ARGn0 EQU [bp+4]
- ARGn1 EQU [bp+6]
-
- _TEXT SEGMENT byte public 'CODE'
- ASSUME cs:_TEXT
-
- PUBLIC _SetFontPages
- _SetFontPages PROC near
-
- push bp ; preserve caller registers
- mov bp,sp
-
- mov ax,1103h ; AH := INT 10H function number
- ; AL := 3 (Set Block Specifier)
- mov bl,ARGn1 ; BL := value for bits 2-3
- shl bl,1
- shl bl,1 ; BL bits 2-3 := n1
- or bl,ARGn0 ; BL bits 0-1 := n0
- int 10h ; load font pages
-
- pop bp
- ret
-
- _SetFontPages ENDP
-
- _TEXT ENDS
-
- END
-
- \SAMPCODE\VIDEO\11
- \SAMPCODE\VIDEO\11\11_5.C
-
- /* Listing 11-5 */
-
- main()
- {
- int xc = 400; /* center of circle */
- int yc = 125;
- int a,b; /* semimajor and semiminor axes */
- int n = 12; /* pixel value */
- int i;
- float ScaleFactor = 1.37; /* for 640x350 16-color mode */
-
-
- for( i=0; i<10; i++ )
- for( a=0; a<100; a++ )
- {
- b = (float) a / ScaleFactor; /* scale semiminor axis */
- Ellipse10( xc, yc, a, b, n ); /* draw a circle */
- Ellipse10( xc, yc, a, b, n ); /* draw it again */
- }
- }
-
- \SAMPCODE\VIDEO\11\11_6.C
-
- /* Listing 11-6 */
-
- #define Xmax 640
-
- #define TRUE 1
- #define FALSE 0
-
- main()
- {
- int x0 = 0; /* corners of box at 0,0 and 150,100
- int y0 = 0;
- int x1 = 150;
- int y1 = 100;
- int n = 12; /* pixel value */
-
-
- while( x1 < Xmax ) /* slide box right */
- XORBox( x0++, y0, x1++, y1, n );
-
- while( x0 > 0 ) /* slide box left */
- XORBox( --x0, y0, --x1, y1, n );
- }
-
-
- XORBox ( x0, y0, x1, y1, n )
- int x0,y0,x1,y1; /* pixel coordinates of opposite corners */
- int n; /* pixel value */
- {
- Rectangle( x0, y0, x1, y1, n ); /* draw the box
- Rectangle( x0, y0, x1, y1, n ); /* erase the box
- }
-
-
- Rectangle( x0, y0, x1, y1, n )
- int x0,y0,x1,y1;
- int n;
- {
- Line10( x0, y0, x0, y1, n );
- Line10( x0, y0, x1, y0, n );
- Line10( x1, y1, x0, y1, n );
- Line10( x1, y1, x1, y0, n );
- }
-
- \SAMPCODE\VIDEO\11\11_7.C
-
- /* Listing 11-7 */
-
- #define Xmax 640 /* screen dimensions in 640x350 mode
- #define Ymax 350
-
- main()
- {
- int x0 = 150; /* fixed endpoint at 150,100 */
- int y0 = 100;
- int x = 0; /* moving endpoint at 0,0 */
- int y = 0;
- int n = 12; /* pixel value */
-
-
- for( ; x<Xmax; x++ ) /* move right */
- XORLine( x0, y0, x, y, n );
-
- for( --x; y<Ymax; y++ ) /* move down */
- XORLine( x0, y0, x, y, n );
-
- for( --y; x>=0; --x ) /* move left */
- XORLine( x0, y0, x, y, n );
-
- for( x++; y>=0; --y ) /* move up */
- XORLine( x0, y0, x, y, n );
- }
-
-
- XORLine ( x0, y0, x1, y1, n )
- int x0,y0,x1,y1; /* endpoints */
- int n; /* pixel value */
- {
- Line10( x0, y0, x1, y1, n ); /* the line is onscreen
- Line10( x0, y0, x1, y1, n ); /* the line is erased
- }
-
- \SAMPCODE\VIDEO\11\11_1.ASM
-
- TITLE 'Listing 11-1'
- NAME GetBitBlock06
- PAGE 55,132
-
- ;
- ; Name: GetBitBlock06
- ;
- ; Function: Copy bit block from video buffer to system RAM
- ; in 640x200 2-color mode
- ;
- ; Caller: Microsoft C:
- ;
- ; int GetBitBlock06(x0,y0,x1,y1,buf);
- ;
- ; int x0,y0; /* upper left corner of bit block
- ; int x1,y1; /* lower right corner */
- ; char far *buf; /* buffer */
- ;
- ; Notes: Returns size of bit block in system RAM.
- ;
-
-
- ARGx0 EQU word ptr [bp+4]
- ARGy0 EQU word ptr [bp+6]
- ARGx1 EQU word ptr [bp+8]
- ARGy1 EQU word ptr [bp+10]
- ADDRbuf EQU [bp+12]
-
- VARPixelRows EQU word ptr [bp-2]
- VARPixelRowLen EQU word ptr [bp-4]
- VARincr EQU word ptr [bp-6]
-
- ByteOffsetShift EQU 3 ; reflects number of pixels per byte
-
-
- _TEXT SEGMENT byte public 'CODE'
- ASSUME cs:_TEXT
-
- EXTRN PixelAddr06:near
-
- PUBLIC _GetBitBlock06
- _GetBitBlock06 PROC near
-
- push bp ; preserve caller registers
- mov bp,sp
- sub sp,6 ; establish stack frame
- push ds
- push si
- push di
-
- ; compute dimensions of bit block
-
- mov ax,ARGx1
- sub ax,ARGx0
- mov cx,0FF07h ; CH := unshifted bit mask
- ; CL := AND mask for AL
- and cl,al ; CL := number of pixels in last
- ; byte of row
- xor cl,7 ; CL := number of bits to shift
- shl ch,cl ; CH := bit mask for last byte of row
- mov cl,ch
- push cx ; save on stack
-
- mov cl,ByteOffsetShift
- shr ax,cl
- inc ax ; AX := number of bytes per row
- push ax ; save on stack
-
- mov ax,ARGy1
- sub ax,ARGy0
- inc ax ; AX := number of pixel rows
- push ax ; save on stack
-
- ; establish addressing
-
- mov ax,ARGy0
- mov bx,ARGx0
- call PixelAddr06 ; ES:BX -> x0,y0 in video buffer
- xor cl,7 ; CL := number of bits to shift left
- push es
- pop ds
- mov si,bx ; DS:SI -> video buffer
-
- mov bx,2000h ; BX := increment from 1st to 2nd
- ; interleave in CGA video buffer
- test si,2000h
- jz L01 ; jump if x0,y0 is in 1st interleave
-
- mov bx,80-2000h ; increment from 2nd to 1st interleav
-
- L01: mov VARincr,bx ; initialize this variable
-
- les di,ADDRbuf ; ES:DI -> buffer in system RAM
-
- ; build 5-byte bit block header
-
- pop ax
- mov VARPixelRows,ax
- stosw ; byte 0-1 := number of pixel rows
- pop ax
- mov VARPixelRowLen,ax
- stosw ; byte 2-3 := bytes per pixel row
- pop ax
- mov ch,al ; CH := bit mask for last byte
- stosb ; byte 4 := bit mask for last byte
-
- ; copy from video buffer to system RAM
-
- L02: mov bx,VARPixelRowLen
- push si ; preserve SI at start of pixel row
-
- L03: lodsw ; AL := next byte in video buffer
- ; AH := (next byte) + 1
- dec si ; DS:SI -> (next byte) + 1
- rol ax,cl ; AL := next 4 pixels in row
- stosb ; copy to system RAM
- dec bx ; loop across row
- jnz L03
-
- and es:[di-1],ch ; mask last byte of row
- pop si ; DS:SI -> start of row
- add si,VARincr ; DS:SI -> start of next row
- xor VARincr,2000h XOR (80-2000H) ; update increment
-
- dec VARPixelRows
- jnz L02 ; loop down rows
-
- mov ax,di
- sub ax,ADDRbuf ; AX := return value (size of bit blo
- ; in system RAM)
-
- pop di ; restore registers and exit
- pop si
- pop ds
- mov sp,bp
- pop bp
- ret
-
- _GetBitBlock06 ENDP
-
- _TEXT ENDS
-
- END
-
- \SAMPCODE\VIDEO\11\11_2.ASM
-
- TITLE 'Listing 11-2'
- NAME StoreBitBlock06
- PAGE 55,132
-
- ;
- ; Name: StoreBitBlock06
- ;
- ; Function: Copy bit block from video buffer to system RAM
- ; in 640x200 2-color mode
- ;
- ; Caller: Microsoft C:
- ;
- ; void StoreBitBlock06(buf,x,y);
- ;
- ; char far *buf; /* buffer */
- ; int x,y; /* upper left corner of bit block */
- ;
-
-
- ADDRbuf EQU dword ptr [bp+4]
- ARGx EQU word ptr [bp+8]
- ARGy EQU word ptr [bp+10]
-
- VARPixelRows EQU word ptr [bp-2]
- VARPixelRowLen EQU word ptr [bp-4]
- VARincr EQU word ptr [bp-6]
-
-
- DGROUP GROUP _DATA
-
- _TEXT SEGMENT byte public 'CODE'
- ASSUME cs:_TEXT,ds:DGROUP
-
- EXTRN PixelAddr06:near
-
- PUBLIC _StoreBitBlock06
- _StoreBitBlock06 PROC near
-
- push bp ; preserve caller registers
- mov bp,sp
- sub sp,6 ; establish stack frame
- push ds
- push si
- push di
-
- ; establish addressing
-
- mov ax,ARGy
- mov bx,ARGx
- call PixelAddr06 ; ES:BX -> byte offset of x,y
- xor cl,7 ; CL := number of bits to shift right
-
- mov di,bx ; ES:DI -> x,y in video buffer
-
- mov bx,2000h ; BX := increment from 1st to 2nd
- ; interleave in CGA video buffer
- test di,2000h
- jz L01 ; jump if x,y is in 1st interleave
-
- mov bx,80-2000h ; increment from 2nd to 1st interleav
-
- L01: mov VARincr,bx ; initialize this variable
-
- mov bx,StoreBitBlockOp ; BX := subroutine address
-
- lds si,ADDRbuf ; ES:DI -> buffer in system RAM
-
- ; obtain dimensions of bit block from header
-
- lodsw ; AX := number of pixel rows
- mov VARPixelRows,ax
- lodsw ; AX := bytes per pixel row
- mov VARPixelRowLen,ax
- lodsb ; AL := bit mask for last byte in row
- mov ch,al
-
- jmp bx ; jump to subroutine
-
-
- ReplaceBitBlock:
- cmp cx,0FF00h ; if mask <> 0FFH or bits to shift <>
- jne L15 ; jump if not byte-aligned
-
- ; routine for byte-aligned bit blocks
-
- mov cx,VARPixelRowLen
-
- L10: push di ; preserve DI and CX
- push cx
- rep movsb ; copy one pixel row into video buffe
- pop cx ; restore DI and CX
- pop di
- add di,VARincr ; ES:DI -> next pixel row in buffer
- xor VARincr,2000h XOR (80-2000h) ; update increment
- dec VARPixelRows
- jnz L10 ; loop down pixel rows
-
- jmp Lexit
-
- ; routine for all other bit blocks
-
- L15: not ch ; CH := mask for end of row
- mov dx,0FF00h
- ror dx,cl ; DX := rotated mask for each byte
-
- mov bx,VARPixelRowLen
- dec bx ; BX := bytes per row - 1
-
- L16: push di
- test bx,bx
- jz L18 ; jump if only one byte per row
-
- push bx
-
- L17: and es:[di],dx ; mask next 8 pixels in video buffer
- lodsb ; AL := pixels in bit block
- xor ah,ah
- ror ax,cl ; AX := pixels rotated into position
- or es:[di],ax ; set pixels in video buffer
- inc di ; ES:DI -> next byte in bit block
- dec bx
- jnz L17
-
- pop bx
-
- L18: mov al,ch
- mov ah,0FFh ; AX := mask for last pixels in row
- ror ax,cl ; AX := mask rotated into position
- and es:[di],ax ; mask last pixels in video buffer
- lodsb ; AL := last byte in row
- xor ah,ah
- ror ax,cl ; AX := pixels rotated into position
- or es:[di],ax ; set pixels in video buffer
-
- pop di
- add di,VARincr ; ES:DI -> next pixel row in buffer
- xor VARincr,2000h XOR (80-2000h)
- dec VARPixelRows
- jnz L16 ; loop down pixel rows
-
- jmp Lexit
-
-
- XORBitBlock:
- mov bx,VARPixelRowLen
-
- L20: push di
- push bx
-
- L21: lodsb ; AL := pixels in bit block
- xor ah,ah
- ror ax,cl ; AX := pixels rotated into position
- xor es:[di],ax ; XOR pixels into video buffer
- inc di ; ES:DI -> next byte in bit block
- dec bx
- jnz L21
-
- pop bx
- pop di
- add di,VARincr ; ES:DI -> next pixel row in buffer
- xor VARincr,2000h XOR (80-2000h)
- dec VARPixelRows
- jnz L20 ; loop down pixel rows
-
- jmp Lexit
-
- ANDBitBlock:
- not ch ; CH := mask for end of row
-
- mov bx,VARPixelRowLen
- dec bx ; BX := bytes per row - 1
-
- L30: push di
- test bx,bx
- jz L32 ; jump if only one byte per row
-
- push bx
-
- L31: lodsb ; AL := pixels in bit block
- mov ah,0FFh
- ror ax,cl ; AX := pixels rotated into position
- and es:[di],ax ; AND pixels into video buffer
- inc di ; ES:DI -> next byte in bit block
- dec bx
- jnz L31
-
- pop bx
-
- L32: lodsb ; AL := last byte in row
- or al,ch ; mask last pixels in row
- mov ah,0FFh
- ror ax,cl ; AX := pixels rotated into position
- and es:[di],ax ; AND pixels into video buffer
-
- pop di
- add di,VARincr ; ES:DI -> next pixel row in buffer
- xor VARincr,2000h XOR (80-2000h)
- dec VARPixelRows
- jnz L30 ; loop down pixel rows
-
- jmp Lexit
-
-
- ORBitBlock:
- mov bx,VARPixelRowLen
-
- L40: push di
- push bx
-
- L41: lodsb ; AL := pixels in bit block
- xor ah,ah
- ror ax,cl ; AX := pixels rotated into position
- or es:[di],ax ; OR pixels into video buffer
- inc di ; ES:DI -> next byte in bit block
- dec bx
- jnz L41
-
- pop bx
- pop di
- add di,VARincr ; ES:DI -> next pixel row in buffer
- xor VARincr,2000h XOR (80-2000h)
- dec VARPixelRows
- jnz L40 ; loop down pixel rows
-
-
- Lexit: pop di ; restore registers and exit
- pop si
- pop ds
- mov sp,bp
- pop bp
- ret
-
- _StoreBitBlock06 ENDP
-
- _TEXT ENDS
-
-
- _DATA SEGMENT word public 'DATA'
-
- StoreBitBlockOp DW ReplaceBitBlock ; address of selected subroutine
- ; (Replace, XOR, AND, OR)
-
- _DATA ENDS
-
- END
-
- \SAMPCODE\VIDEO\11\11_3.ASM
-
- TITLE 'Listing 11-3'
- NAME GetBitBlock10
- PAGE 55,132
-
- ;
- ; Name: GetBitBlock10
- ;
- ; Function: Copy bit block from video buffer to system RAM
- ; in native EGA and VGA graphics modes
- ;
- ; Caller: Microsoft C:
- ;
- ; int GetBitBlock10(x0,y0,x1,y1,buf);
- ;
- ; int x0,y0; /* upper left corner of bit block
- ; int x1,y1; /* lower right corner */
- ; char far *buf; /* buffer */
- ;
- ; Notes: Returns size of bit block in system RAM.
- ;
-
-
- ARGx0 EQU word ptr [bp+4]
- ARGy0 EQU word ptr [bp+6]
- ARGx1 EQU word ptr [bp+8]
- ARGy1 EQU word ptr [bp+10]
- ADDRbuf EQU [bp+12]
-
- VARPixelRows EQU word ptr [bp-2]
- VARPixelRowLen EQU word ptr [bp-4]
-
- BytesPerRow EQU 80
- ByteOffsetShift EQU 3 ; reflects number of pixels per byte
-
-
- _TEXT SEGMENT byte public 'CODE'
- ASSUME cs:_TEXT
-
- EXTRN PixelAddr10:near
-
- PUBLIC _GetBitBlock10
- _GetBitBlock10 PROC near
-
- push bp ; preserve caller registers
- mov bp,sp
- sub sp,4 ; establish stack frame
- push ds
- push si
- push di
-
- ; compute dimensions of bit block
-
- mov ax,ARGx1
- sub ax,ARGx0
- mov cx,0FF07h ; CH := unshifted bit mask
- ; CL := AND mask for AL
- and cl,al ; CL := number of pixels in last
- ; byte of row
- xor cl,7 ; CL := number of bits to shift
- shl ch,cl ; CH := bit mask for last byte of row
- mov cl,ch
- push cx ; save on stack
-
- mov cl,ByteOffsetShift
- shr ax,cl
- inc ax ; AX := number of bytes per row
- push ax ; save on stack
-
- mov ax,ARGy1
- sub ax,ARGy0
- inc ax ; AX := number of pixel rows
- push ax ; save on stack
-
- ; establish addressing
-
- mov ax,ARGy0
- mov bx,ARGx0
- call PixelAddr10 ; ES:BX -> x0,y0 in video buffer
- xor cl,7 ; CL := number of bits to shift left
- push es
- pop ds
- mov si,bx ; DS:SI -> video buffer
-
- les di,ADDRbuf ; ES:DI -> buffer in system RAM
-
- ; build 5-byte bit block header
-
- pop ax
- mov VARPixelRows,ax
- stosw ; byte 0-1 := number of pixel rows
- pop ax
- mov VARPixelRowLen,ax
- stosw ; byte 2-3 := bytes per pixel row
- pop ax
- mov ch,al ; CH := bit mask for last byte in row
- stosb ; byte 4 := bit mask for last byte
-
- ; set up Graphics Controller
-
- mov dx,3CEh ; DX := Graphics Controller address p
-
- mov ax,0005 ; AH := 0 (read mode 0, write mode 0)
- ; AL := 5 (Mode register number)
- out dx,ax ; set up read mode 0
-
- mov ax,0304h ; AH := 3 (first bit plane to read)
- ; AL := 4 (Read Map Select reg number
-
- ; copy from video buffer to system RAM
-
- L01: out dx,ax ; select next memory map to read
- push ax ; preserve memory map number
- push VARPixelRows ; preserve number of pixel rows
- push si ; preserve offset of x0,y0
-
- L02: mov bx,VARPixelRowLen
- push si ; preserve SI at start of pixel row
-
- L03: lodsw ; AL := next byte in video buffer
- ; AH := (next byte) + 1
- dec si ; DS:SI -> (next byte) + 1
- rol ax,cl ; AL := next 4 pixels in row
- stosb ; copy to system RAM
- dec bx ; loop across row
- jnz L03
-
- and es:[di-1],ch ; mask last byte in row
- pop si ; DS:SI -> start of row
- add si,BytesPerRow ; DS:SI -> start of next row
-
- dec VARPixelRows
- jnz L02 ; loop down rows
-
- pop si ; DS:SI -> start of bit block
- pop VARPixelRows ; restore number of pixel rows
- pop ax ; AH := last map read
- ; AL := Read Map Select reg number
- dec ah
- jns L01 ; loop across bit planes
-
- mov ax,di
- sub ax,ADDRbuf ; AX := return value (size of bit blo
- ; in system RAM)
-
- pop di ; restore registers and exit
- pop si
- pop ds
- mov sp,bp
- pop bp
- ret
-
- _GetBitBlock10 ENDP
-
- _TEXT ENDS
-
- END
-
- \SAMPCODE\VIDEO\11\11_4.ASM
-
- TITLE 'Listing 11-4'
- NAME StoreBitBlock10
- PAGE 55,132
-
- ;
- ; Name: StoreBitBlock10
- ;
- ; Function: Copy bit block from video buffer to system RAM
- ; in native EGA and VGA graphics modes
- ;
- ; Caller: Microsoft C:
- ;
- ; void StoreBitBlock10(buf,x,y);
- ;
- ; char far *buf; /* buffer */
- ; int x,y; /* upper left corner of bit block */
- ;
-
-
- ADDRbuf EQU dword ptr [bp+4]
- ARGx EQU word ptr [bp+8]
- ARGy EQU word ptr [bp+10]
-
- VARPixelRows EQU word ptr [bp-2]
- VARPixelRowLen EQU word ptr [bp-4]
- VARRowCounter EQU word ptr [bp-6]
- VARStartMask EQU word ptr [bp-8]
- VAREndMaskL EQU word ptr [bp-10]
- VAREndMaskR EQU word ptr [bp-12]
-
- BytesPerRow EQU 80 ; logical width of video buffer
- ByteOffsetShift EQU 3 ; reflects number of pixels per byte
- RMWbits EQU 18h ; selects replace, XOR, AND, or OR
-
- _TEXT SEGMENT byte public 'CODE'
- ASSUME cs:_TEXT
-
- EXTRN PixelAddr10:near
-
- PUBLIC _StoreBitBlock10
- _StoreBitBlock10 PROC near
-
- push bp ; preserve caller registers
- mov bp,sp
- sub sp,12 ; establish stack frame
- push ds
- push si
- push di
-
- ; establish addressing
-
- mov ax,ARGy
- mov bx,ARGx
- call PixelAddr10 ; ES:BX -> byte offset of x,y
- inc cl
- and cl,7 ; CL := number of bits to shift left
-
- mov di,bx ; ES:DI -> x,y in video buffer
-
- lds si,ADDRbuf ; ES:DI -> buffer in system RAM
-
- ; obtain dimensions of bit block from header
-
- lodsw ; AX := number of pixel rows
- mov VARPixelRows,ax
- lodsw ; AX := bytes per pixel row
- mov VARPixelRowLen,ax
- lodsb ; AL := bit mask for last byte in row
- mov ch,al
-
- ; set up Graphics Controller
-
- mov dx,3CEh ; DX := Graphics Controller I/O port
-
- mov ah,RMWbits ; AH := value for Data Rotate/Functio
- mov al,3 ; Select register
- out dx,ax ; update this register
-
- mov ax,0805h ; AH := 8 (read mode 1, write mode 0)
- ; AL := 5 (Mode register number)
- out dx,ax ; set up read mode 0
-
- mov ax,0007 ; AH := 0 (don't care for all maps;
- ; CPU reads always return 0FFH)
- ; AL := 7 (Color Don't Care reg numbe
- out dx,ax ; set up Color Don't Care reg
-
- mov ax,0FF08h ; AH := 0FFH (value for Bit Mask reg)
- out dx,ax ; set up Bit Mask reg
-
- mov dl,0C4h ; DX := 3C4H (Sequencer I/O port)
- mov ax,0802h ; AH := 1000B (value for Map Mask reg
- ; AL := 2 (Map Mask register number)
-
- cmp cx,0FF00h ; if mask <> 0FFH or bits to shift <>
- jne L15 ; jump if not byte-aligned
-
- ; routine for byte-aligned bit blocks
-
- mov cx,VARPixelRowLen
-
- L10: out dx,ax ; enable one bit plane for writes
- push ax ; preserve Map Mask value
- push di ; preserve video buffer offset of x,y
- mov bx,VARPixelRows
-
- L11: push di ; preserve DI and CX
- push cx
-
- L12: lodsb ; AL := next byte of pixels
- and es:[di],al ; update bit plane
- inc di
- loop L12
-
- pop cx ; restore DI and CX
- pop di
- add di,BytesPerRow ; ES:DI -> next pixel row in buffer
- dec bx
- jnz L11 ; loop down pixel rows
-
- pop di ; ES:DI -> video buffer offset of x,y
- pop ax ; AH := current Map Mask reg value
- shr ah,1 ; AH := new Map Mask value
- jnz L10 ; loop across all bit planes
-
- jmp Lexit
-
- ; routine for non-aligned bit blocks
-
- L15: push ax ; preserve Map Mask reg values
-
- mov bx,0FFh ; BH := 0 (mask for first byte in row
- ; BL := 0FFh
- mov al,ch ; AL := mask for last byte in pixel r
- cbw ; AH := 0FFh (mask for last-1 byte)
-
- cmp VARPixelRowLen,1
- jne L16 ; jump if more than one byte per row
-
- mov bl,ch
- mov ah,ch ; AH := mask for last-1 byte
- xor al,al ; AL := 0 (mask for last byte)
-
- L16: shl ax,cl ; shift masks into position
- shl bx,cl
-
- mov bl,al ; save masks along with ..
- mov al,8 ; .. Bit Mask register number
- mov VAREndMaskL,ax
- mov ah,bl
- mov VAREndMaskR,ax
- mov ah,bh
- mov VARStartMask,ax
-
- mov bx,VARPixelRowLen
- pop ax ; restore Map Mask reg values
-
- ; set pixels row by row in the bit planes
-
- L17: out dx,ax ; enable one bit plane for writes
- push ax ; preserve Map Mask value
- push di ; preserve video buffer offset of x,y
- mov dl,0CEh ; DX := 3CEH (Graphics Controller por
-
- mov ax,VARPixelRows
- mov VARRowCounter,ax ; initialize loop counter
-
- ; set pixels at start of row in currently enabled bit plane
-
- L18: push di ; preserve offset of start of pixel r
- push si ; preserve offset of row in bit block
- push bx ; preserve bytes per pixel row
-
- mov ax,VARStartMask
- out dx,ax ; set Bit Mask reg for first byte of
-
- lodsw ; AH := 2nd byte of pixels
- ; AL := 1st byte of pixels
- dec si ; DS:SI -> 2nd byte of pixels
- test cl,cl
- jnz L19 ; jump if not left-aligned
-
- dec bx ; BX := bytes per row - 1
- jnz L20 ; jump if at least 2 bytes per row
- jmp short L22 ; jump if only one byte per row
-
- L19: rol ax,cl ; AH := left part of 1st byte,
- ; right part of 2nd byte
- ; AL := right part of 1st byte,
- ; left part of 2nd byte
- and es:[di],ah ; set pixels for left part of first b
- inc di
- dec bx ; BX := bytes per row - 2
-
- L20: push ax ; preserve pixels
- mov ax,0FF08h
- out dx,ax ; set Bit Mask reg for succeeding byt
- pop ax
-
- dec bx
- jng L22 ; jump if only 1 or 2 bytes in pixel
-
- ; set pixels in middle of row
-
- L21: and es:[di],al ; set pixels in right part of current
- inc di ; byte and left part of next byte
-
- lodsw ; AH := next+1 byte of pixels
- dec si ; AL := next byte of pixels
- rol ax,cl ; AH := left part of next byte, right
- ; part of next+1 byte
- ; AL := right part of next byte, left
- ; part of next+1 byte
- dec bx
- jnz L21 ; loop across pixel row
-
- ; set pixels at end of row
-
- L22: mov bx,ax ; BH := right part of last byte, left
- ; part of last-1 byte
- ; BL := left part of last byte, right
- ; part of last-1 byte
- mov ax,VAREndMaskL ; AH := mask for last-1 byte
- ; AL := Bit Mask reg number
- out dx,ax ; set Bit Mask register
- and es:[di],bl ; set pixels for last-1 byte
-
- mov ax,VAREndMaskR ; mask for last byte in pixel row
- out dx,ax ; .. last byte in pixel row
- and es:[di+1],bh ; set pixels for last byte
-
- pop bx ; BX := bytes per pixel row
- pop si
- add si,bx ; DS:SI -> next row in bit block
- pop di
- add di,BytesPerRow ; ES:DI -> next pixel row in buffer
- dec VARRowCounter
- jnz L18 ; loop down pixel rows
-
- pop di ; ES:DI -> video buffer offset of x,y
- pop ax ; AX := current Map Mask value
- mov dl,0C4h ; DX := 3C4H
- shr ah,1 ; AH := next Map Mask value
- jnz L17 ; loop across bit planes
-
- ; restore Graphics Controller and Sequencer to their default states
-
- Lexit: mov ax,0F02h ; default Map Mask value
- out dx,ax
-
- mov dl,0CEh ; DX := 3CEh
- mov ax,0003 ; default Data Rotate/Function Select
- out dx,ax
-
- mov ax,0005 ; default Mode value
- out dx,ax
-
- mov ax,0F07h ; default Color Compare value
- out dx,ax
-
- mov ax,0FF08h ; default Bit Mask value
- out dx,ax
-
- pop di ; restore registers and exit
- pop si
- pop ds
- mov sp,bp
- pop bp
- ret
-
- _StoreBitBlock10 ENDP
-
- _TEXT ENDS
-
- END
-
- \SAMPCODE\VIDEO\12
- \SAMPCODE\VIDEO\12\12_2.C
-
- /* Listing 12-2 */
-
- int VRcount = 0; /* vertical interrupt counter */
-
- main()
- {
- if ( EnableISR0A() )
- {
- printf( "\nCan't enable vertical interrupt handler\n" );
- exit( 1 );
- }
-
- while (VRcount < 600)
- printf( "\015Number of vertical interrupts: %d", VRcount );
-
- DisableISR0A();
- }
-
- \SAMPCODE\VIDEO\12\12_1.ASM
-
- TITLE 'Listing 12-1'
- NAME VREGA
- PAGE 55,132
-
- ;
- ; Name: VREGA
- ;
- ; Function: Vertical Interrupt Service routine for EGA and VGA
- ;
- ; Caller: Microsoft C:
- ;
- ; int EnableISR0A(); /* returns 0 if installed ok
- ;
- ; void DisableISR0A();
- ;
-
- CRT_MODE EQU 49h ; addresses in video BIOS data area
- ADDR_6845 EQU 63h
-
- DGROUP GROUP _DATA
-
- _TEXT SEGMENT byte public 'CODE'
- ASSUME cs:_TEXT,ds:DGROUP
-
- ISR0A PROC far ; Interrupt handler for INT 0Ah
-
- push ax ; preserve registers
- push dx
- push ds
-
- mov ax,seg DGROUP
- mov ds,ax ; DS -> DGROUP
-
- ; determine whether a vertical interrupt has occurred
-
- mov dx,3C2h ; DX := I/O port for
- ; Input Status Register Zero
- in al,dx
- test al,80h ; test bit 7 of the Status Reg value
- jnz L10 ; jump if vertical interrupt
-
- ; not a vertical interrupt so chain to previous interrupt handler
-
- pushf ; simulate an INT
- call ds:PrevISR0A ; to the previous INT 0Ah handler
- jmp short Lexit
-
- ; handle a vertical interrupt
-
- L10: mov dx,Port3x4 ; DX := 3B4h or 3D4h
-
- in al,dx ; AL := value of CRTC address reg
- push ax ; preserve this value
-
- mov ax,DefaultVREnd ; AH := default value for VR End Reg
- ; AL := 11h (register number)
- and ah,11101111b ; AH bit 4 := 0 (clear interrupt latc
- out dx,ax ; update VR End Register
- jmp $+2 ; wait for CRTC to respond
-
- ; send End of Interrupt to Intel 8259A Programmable Interrupt Controller
- ; to allow subsequent IRQ2 interrupts to occur
-
- mov al,20h ; 8259A I/O port
- out 20h,al ; send nonspecific EOI to 8259A
- jmp $+2 ; wait for PIC to respond
- sti ; enable interrupts
-
- ; do something useful ...
-
- inc word ptr _VRcount ; increment a counter
-
- ; enable CRTC to generate another interrupt
-
- cli ; disable interrupts
- mov ax,DefaultVREnd ; AH := default value for VR End Reg
- ; AL := 11h (register number)
- and ah,11011111b ; AH bit 5 := 0 (enable vertical int)
- or ah,00010000b ; AH bit 4 := 1 (enable int latch)
- out dx,ax
- jmp $+2
-
- pop ax
- out dx,al ; restore previous Address reg value
-
- Lexit: pop ds ; restore registers and exit
- pop dx
- pop ax
- iret
-
- ISR0A ENDP
-
- ;
- ; EnableISR0A -- enable Vertical Interrupt Handler
- ;
- PUBLIC _EnableISR0A
- _EnableISR0A PROC near
-
- push bp ; preserve caller registers
- mov bp,sp
- push si
- push di
-
- mov ax,40h
- mov es,ax ; ES -> video BIOS data area
-
- ; save default CRTC register values
-
- mov dx,es:[ADDR_6845] ; DX := CRTC Address port
- mov Port3x4,dx ; save port address
-
- mov ax,1A00h ; AH := 1AH (INT 10H function number)
- ; AL := 0 (read Display Combination)
- int 10h ; AL := 1AH if function 1AH supported
- ; BL := active video subsystem
- cmp al,1Ah
- jne L20 ; jump if not a VGA
-
- cmp bl,7
- je L21 ; jump if VGA
-
- cmp bl,8
- je L21 ; jump if VGA
-
- mov ax,0FFFFh ; return 0FFFFh if neither EGA nor VG
- jmp short L23
-
- ; get default value for EGA Vertical Retrace End register
-
- L20: mov al,es:[CRT_MODE] ; AL := video BIOS mode number
- mov bx,offset DGROUP:EGADefaultVals
- xlat ; AL := default value for VR End reg
- jmp short L22
- ;
- ; get default value for VGA Vertical Retrace End register
-
- L21: mov al,VREndReg ; AL := VR End register number
- out dx,al
- inc dx ; DX := 3B5H or 3D5H
- in al,dx ; AL := current value for register
-
- L22: mov VREndValue,al ; save this value
-
- ; save old interrupt 0Ah vector
-
- mov ax,350Ah ; AH := 35H (INT 21h function number)
- ; AL := 0AH (interrupt number)
- int 21h ; ES:BX := previous INT 0AH vector
-
- mov word ptr PrevISR0A,bx
- mov word ptr PrevISR0A+2,es ; save previous vector
-
- ; update interrupt 0AH vector with address of this handler
-
- push ds ; preserve DS
- mov dx,offset ISR0A
- push cs
- pop ds ; DS:DX -> ISR0A
- mov ax,250Ah ; AH := 25H (INT 21H function number)
- ; AL := 0AH (interrupt number)
- int 21h ; update INT 0AH vector
- pop ds ; restore DS
-
- ; enable IRQ2 by zeroing bit 2 of the 8259A's mask register
-
- cli ; clear interrupts
- mov dx,21h ; DX := 8259A mask register
- in al,dx ; AL := mask register value
- and al,11111011b ; reset bit 2
- out dx,al
-
- ; enable vertical interrupts
-
- mov dx,Port3x4 ; DX := 3B4H or 3D4H
- mov ax,DefaultVREnd
-
- and ah,11001111b
- out dx,ax ; clear bits 4 and 5 of VR End reg
- jmp $+2 ; wait for CRTC to respond
- or ah,00010000b
- out dx,ax ; set bit 4
- jmp $+2
- sti ; enable interrupts
-
- xor ax,ax ; AX := 0 (return value)
-
- L23: pop di ; restore registers and exit
- pop si
- mov sp,bp
- pop bp
- ret
-
- _EnableISR0A ENDP
-
- ;
- ; DisableISR0A -- disable Vertical Interrupt Handler
- ;
- PUBLIC _DisableISR0A
- _DisableISR0A PROC near
-
- push bp
- mov bp,sp
- push si
- push di
- push ds
-
- ; disable vertical interrupts
-
- cli ; disable interrupts
- mov dx,Port3x4
- mov ax,DefaultVREnd
- out dx,ax ; restore Vertical Retrace End reg
- jmp $+2
- sti ; enable interrupts
-
- ; restore previous interrupt 0Ah handler
-
- lds dx,PrevISR0A ; DS:DX := previous INT 0AH vector
- mov ax,250Ah ; AH := 25H (INT 21H function number)
- ; AL := 0AH (interrupt number)
- int 21h
-
- pop ds ; restore registers and exit
- pop di
- pop si
- mov sp,bp
- pop bp
- ret
-
- _DisableISR0A ENDP
-
- _TEXT ENDS
-
- _DATA SEGMENT word public 'DATA'
-
- EXTRN _VRcount:word ; declared in C caller
-
- PrevISR0A DD ? ; save area for old int 0Ah vector
- Port3x4 DW ? ; 3B4h or 3D4h
-
- DefaultVREnd LABEL word
- VREndReg DB 11h ; Vertical Retrace End register numbe
- VREndValue DB ? ; default value for VR End register
-
- EGADefaultVals DB 2Bh,2Bh,2Bh,2Bh,24h,24h,23h,2Eh ; default values for
- DB 00h,00h,00h,00h,00h,24h,23h,2Eh ; EGA VR End reg
- DB 2Bh
-
- _DATA ENDS
-
- END
-
- \SAMPCODE\VIDEO\12\12_10.ASM
-
- TITLE 'Listing 12-10'
- NAME GetHercMode
- PAGE 55,132
-
- ;
- ; Name: GetHercMode
- ;
- ; Function: Determine video mode on Hercules adapters by estimating the s
- ; of the displayed portion of the video buffer.
- ;
- ; Caller: Microsoft C:
- ;
- ; int GetHercMode(n); /* returns approximate size *
- ; /* of displayed portion of *
- ; /* video buffer in words *
- ;
-
- _TEXT SEGMENT byte public 'CODE'
- ASSUME cs:_TEXT
-
- PUBLIC _GetHercMode
- _GetHercMode PROC near
-
- push bp ; preserve BP
- mov bp,sp
-
- ; reset CRTC light pen latch
-
- mov dx,3BBh ; DX := light pen reset port
- out dx,al ; OUT to this port clears the latch
- ; (the value in AL doesn't matter)
-
- ; wait for start of next vertical retrace
-
- dec dx ; DX := 3BAH (CRT status port)
- L01: in al,dx ; wait for start of vertical retrace
- test al,80h
- jnz L01
-
- L02: in al,dx ; wait for end of vertical retrace
- test al,80h
- jz L02
-
- cli ; disable interrupts
- L03: in al,dx ; wait for start of vertical retrace
- test al,80h
- jnz L03
-
- ; latch the current CRTC address counter in the Light Pen registers
-
- dec dx ; DX := 3B9H
- out dx,al ; OUT to this port loads the latch
- sti ; re-enable interrupts
-
- ; return the value in the Light Pen registers
-
- mov dl,0B4h ; DX := 3B4H (CRTC address port)
- mov al,10h ; AL := Light Pen High register numbe
- out dx,al
- inc dx
- in al,dx ; read this register
- dec dx
- mov ah,al ; AH := current Light Pen High value
-
- mov al,11h ; AL := Light Pen Low register number
- out dx,al
- inc dx
- in al,dx ; AX := current light pen latch value
- ; (i.e., value of CRTC address count
- ; at start of vertical retrace)
- pop bp
- ret
-
- _GetHercMode ENDP
-
- _TEXT ENDS
-
- END
-
- \SAMPCODE\VIDEO\12\12_3.ASM
-
- TITLE 'Listing 12-3'
- NAME VRMCGA
- PAGE 55,132
-
- ;
- ; Name: VRMCGA
- ;
- ; Function: Vertical Interrupt Service routine for MCGA
- ;
- ; Caller: Microsoft C:
- ;
- ; int EnableISR0A(); /* returns 0 if installed ok
- ;
- ; void DisableISR0A();
- ;
-
- ADDR_6845 EQU 63h
-
- DGROUP GROUP _DATA
-
- _TEXT SEGMENT byte public 'CODE'
- ASSUME cs:_TEXT,ds:DGROUP
-
- ISR0A PROC far ; Interrupt handler for INT 0Ah
-
- push ax ; preserve registers
- push dx
- push ds
-
- mov ax,seg DGROUP
- mov ds,ax ; DS -> DGROUP
-
- mov dx,Port3x4 ; DX := CRTC Address reg number
- in al,dx
- push ax ; preserve CRTC Address reg value
-
- ; determine whether a vertical interrupt has occurred
-
- mov al,IContReg ; AL := register number
- out dx,al
- jmp $+2 ; wait for MCGA to respond
- inc dx ; DX := 3D5H
- in al,dx ; AL := current Interrupt Control
- ; register value
- dec dx
- test al,40h ; test bit 6
- jnz L10 ; jump if vertical interrupt
-
- ; not a vertical interrupt so chain to previous interrupt handler
-
- pushf ; simulate an INT to the
- call ds:PrevISR0A ; previous INT 0Ah handler
- jmp short Lexit
-
- ; handle a vertical interrupt
-
- L10: mov ax,DefaultICont ; AH := default value for
- ; Interrupt Control register
- ; AL := 11h (register number)
- and ah,11101111b ; AH bit 4 := 0 (clear interrupt latc
- out dx,ax ; update Interrupt Control reg
- jmp $+2 ; wait for MCGA to respond
-
- ; send End of Interrupt to Programmable Interrupt Controller
- ; to allow subsequent IRQ2 interrupts to occur
-
- mov al,20h ; PIC I/O port
- out 20h,al ; send nonspecific EOI to PIC
- jmp $+2 ; wait for PIC to respond
- sti ; enable interrupts
-
- ; do something useful ...
-
- inc word ptr _VRcount ; increment a counter
-
- ; enable CRTC to generate another interrupt
-
- cli ; disable interrupts
- mov ax,DefaultICont ; AH := default value for
- ; Interrupt Control register
- ; AL := 11h (register number)
- and ah,11011111b ; AH bit 5 := 0 (enable vert int)
- or ah,00010000b ; AH bit 4 := 1 (enable int latch)
- out dx,ax
- jmp $+2
-
- Lexit: pop ax
- out dx,al ; restore previous 3D4H value
-
- pop ds ; restore registers and exit
- pop dx
- pop ax
- iret
-
- ISR0A ENDP
-
- ;
- ; EnableISR0A -- enable Vertical Interrupt Handler
- ;
- PUBLIC _EnableISR0A
- _EnableISR0A PROC near
-
- push bp ; preserve caller registers
- mov bp,sp
- push si
- push di
-
- mov ax,40h
- mov es,ax ; ES -> video BIOS data area
-
- ; save default CRTC register values
-
- mov dx,es:[ADDR_6845] ; DX := CRTC Address port
- mov Port3x4,dx ; save port address
-
- mov ax,1A00h ; AH := 1AH (INT 10H function number)
- ; AL := 0 (read Display Combination)
- int 10h ; AL := 1AH if function 1AH supported
- ; BL := active video subsystem
- cmp al,1Ah
- jne L20 ; jump if not an MCGA
-
- cmp bl,0Bh
- je L21 ; jump if MCGA
-
- cmp bl,0Ch
- je L21 ; jump if MCGA
-
- L20: mov ax,0FFFFh ; return 0FFFFh if not an MCGA
- jmp short L23
-
- ; get default value for MCGA Interrupt Control register
-
- L21: mov al,IContReg ; AL := Interrupt Control reg number
- cli
- out dx,al
- jmp $+2
- inc dx ; DX := 3D5H
- in al,dx ; AL := current value for register
- sti
-
- mov IContValue,al ; save this value
-
- ; save old interrupt 0Ah vector
-
- mov ax,350Ah ; AH := 35H (INT 21h function number)
- ; AL := 0AH (interrupt number)
- int 21h ; ES:BX := previous INT 0AH vector
-
- mov word ptr PrevISR0A,bx
- mov word ptr PrevISR0A+2,es ; save previous vector
-
- ; update interrupt 0AH vector with address of this handler
-
- push ds ; preserve DS
- mov dx,offset ISR0A
- push cs
- pop ds ; DS:DX -> ISR0A
- mov ax,250Ah ; AH := 25H (INT 21H function number)
- ; AL := 0AH (interrupt number)
- int 21h ; update INT 0AH vector
- pop ds ; restore DS
-
- ; enable IRQ2 by zeroing bit 2 of the PIC's mask register
-
- cli ; clear interrupts
- mov dx,21h ; DX := PIC mask register
- in al,dx ; AL := mask register value
- and al,11111011b ; reset bit 2
- out dx,al
-
- ; enable vertical interrupts
-
- mov dx,Port3x4 ; DX := CRTC Address port
- mov ax,DefaultICont
-
- and ah,11001111b
- out dx,ax ; clear bits 4 and 5 of Int Control r
- jmp $+2 ; wait for MCGA to respond
- or ah,00010000b
- out dx,ax ; set bit 4
- jmp $+2
- sti ; enable interrupts
-
- xor ax,ax ; AX := 0 (return value)
-
- L23: pop di ; restore registers and exit
- pop si
- mov sp,bp
- pop bp
- ret
-
- _EnableISR0A ENDP
-
- ;
- ; DisableISR0A -- disable Vertical Interrupt Handler
- ;
- PUBLIC _DisableISR0A
- _DisableISR0A PROC near
-
- push bp
- mov bp,sp
- push si
- push di
- push ds
-
- ; disable vertical interrupts
-
- cli ; disable interrupts
- mov dx,Port3x4
- mov ax,DefaultICont
- out dx,ax ; restore Interrupt Control register
- jmp $+2
- sti ; enable interrupts
-
- ; restore previous interrupt 0Ah handler
-
- lds dx,PrevISR0A ; DS:DX := previous INT 0AH vector
- mov ax,250Ah ; AH := 25H (INT 21H function number)
- ; AL := 0AH (interrupt number)
- int 21h
-
- pop ds ; restore registers and exit
- pop di
- pop si
- mov sp,bp
- pop bp
- ret
-
- _DisableISR0A ENDP
-
- _TEXT ENDS
-
- _DATA SEGMENT word public 'DATA'
-
- EXTRN _VRcount:word ; declared in C caller
-
- PrevISR0A DD ? ; save area for old int 0Ah vector
- Port3x4 DW ? ; 3B4h or 3D4h
-
- DefaultICont LABEL word
- IContReg DB 11h ; Interrupt Control register number
- IContValue DB ? ; default value for Int Control reg
-
- _DATA ENDS
-
- END
-
- \SAMPCODE\VIDEO\12\12_4.ASM
-
- TITLE 'Listing 12-4'
- NAME ScreenOrigin
- PAGE 55,132
-
- ;
- ; Name: ScreenOrigin
- ;
- ; Function: Set screen origin on EGA and VGA
- ;
- ; Caller: Microsoft C:
- ;
- ; void ScreenOrigin(x,y);
- ;
- ; int x,y; /* pixel x,y coordinates */
- ;
-
- ARGx EQU [bp+4]
- ARGy EQU [bp+6]
-
-
- CRT_MODE EQU 49h ; addresses in video BIOS data area
- ADDR_6845 EQU 63h
- POINTS EQU 85h
- BIOS_FLAGS EQU 89h
-
- DGROUP GROUP _DATA
-
- _TEXT SEGMENT byte public 'CODE'
- ASSUME cs:_TEXT,ds:DGROUP
-
- PUBLIC _ScreenOrigin
- _ScreenOrigin PROC near
-
- push bp ; preserve caller registers
- mov bp,sp
- push si
- push di
-
- mov ax,40h
- mov es,ax ; ES -> video BIOS data area
- mov cl,es:[CRT_MODE]
-
- mov ax,ARGx ; AX := pixel x-coordinate
- mov bx,ARGy ; BX := pixel y-coordinate
-
- cmp cl,7
- ja L01 ; jump if graphics mode
-
- je L02 ; jump if monochrome alpha
-
- test byte ptr es:[BIOS_FLAGS],1
- jnz L02 ; jump if VGA
-
- jmp short L03
-
- ; setup for graphics modes (8 pixels per byte)
-
- L01: mov cx,8 ; CL := 8 (displayed pixels per byte)
- ; CH := 0 (value for Preset Row Scan)
- div cl ; AH := bit offset in byte
- ; AL := byte offset in pixel row
- mov cl,ah ; CL := bit offset (for Horiz Pel Pan
- xor ah,ah
- xchg ax,bx ; AX := y
- ; BX := byte offset in pixel row
-
- mul word ptr _BytesPerRow
- ; AX := byte offset of start of row
- jmp short L05
-
- ; setup for VGA alphanumeric modes and EGA monochrome alphanumeric mode
- ; (9 pixels per byte)
-
- L02: ; routine for alpha modes
- mov cx,9 ; CL := 9 (displayed pixels per byte)
- ; CH := 0
- div cl ; AH := bit offset in byte
- ; AL := byte offset in pixel row
- dec ah ; AH := -1, 0-7
- jns L04 ; jump if bit offset 0-7
- mov ah,8 ; AH := 8
- jmp short L04
-
- ; setup for EGA color alphanumeric modes (8 pixels per byte)
-
- L03: mov cx,8 ; CL := 8 (displayed pixels per byte)
- ; CH := 0
- div cl ; AH := bit offset in byte
- ; AL := byte offset in pixel row
-
- L04: mov cl,ah ; CL := value for Horiz Pel Pan reg
- xor ah,ah
- xchg ax,bx ; AX := y
- ; BX := byte offset in row
- div byte ptr es:[POINTS] ; AL := character row
- ; AH := scan line in char matri
- xchg ah,ch ; AX := character row
- ; CH := scan line (value for Preset
- ; Row Scan register)
- mul word ptr _BytesPerRow ; AX := byte offset of char r
- shr ax,1 ; AX := word offset of character row
-
- L05: call SetOrigin
-
- pop di ; restore registers and exit
- pop si
- mov sp,bp
- pop bp
- ret
-
- _ScreenOrigin ENDP
-
-
- SetOrigin PROC near ; Caller: AX = offset of character r
- ; BX = byte offset within ro
- ; CH = Preset Row Scan value
- ; CL = Horizontal Pel Pan va
-
- add bx,ax ; BX := buffer offset
-
- mov dx,es:[ADDR_6845] ; CRTC I/O port (3B4H or 3D4H)
- add dl,6 ; video status port (3BAH or 3DAH)
-
- ; update Start Address High and Low registers
-
- L20: in al,dx ; wait for start of vertical retrace
- test al,8
- jz L20
-
- L21: in al,dx ; wait for end of vertical retrace
- test al,8
- jnz L21
-
- cli ; disable interrupts
- sub dl,6 ; DX := 3B4H or 3D4H
-
- mov ah,bh ; AH := value for Start Address High
- mov al,0Ch ; AL := Start Address High reg number
- out dx,ax ; update this register
-
- mov ah,bl ; AH := value for Start Address Low
- inc al ; AL := Start Address Low reg number
- out dx,ax ; update this register
- sti ; enable interrupts
-
- add dl,6 ; DX := video status port
-
- L22: in al,dx ; wait for start of vertical retrace
- test al,8
- jz L22
-
- cli ; disable interrupts
-
- sub dl,6 ; DX := 3B4H or 3D4H
- mov ah,ch ; AH := value for Preset Row Scan reg
- mov al,8 ; AL := Preset Row Scan reg number
- out dx,ax ; update this register
-
- mov dl,0C0h ; DX := 3C0h (Attribute Controller po
- mov al,13h OR 20h ; AL bit 0-4 := Horiz Pel Pan reg num
- ; AL bit 5 := 1
- out dx,al ; write Attribute Controller Address
- ; (Attribute Controller address
- ; flip-flop has been reset by
- ; the IN at L22.)
- mov al,cl ; AL := value for Horiz Pel Pan reg
- out dx,al ; update this register
-
- sti ; re-enable interrupts
- ret
-
- SetOrigin ENDP
-
- _TEXT ENDS
-
-
- _DATA SEGMENT word public 'DATA'
-
- EXTRN _BytesPerRow:word ; bytes per pixel row
-
- _DATA ENDS
-
- END
-
- \SAMPCODE\VIDEO\13
- \SAMPCODE\VIDEO\13\13_1B.C
-
- /* Listing 13-1b */
-
- /* draws an n-leaved rose of the form rho = a * cos(n*theta) */
-
- #define Leaves (double)11 /* n must be an odd number */
-
- #define Xmax 640
- #define Ymax 350
- #define PixelValue 14
- #define ScaleFactor (double) 1.37
-
- main()
- {
- int x,y; /* pixel coordinates */
- double a; /* length of the semi-axis */
- double rho,theta; /* polar coordinates */
-
- double pi = 3.14159265358979;
- double sin(),cos();
-
- void SetPixel();
-
-
- a = (Ymax / 2) - 1; /* a reasonable choice for a */
-
- for (theta=0.0; theta < pi; theta+=0.001)
- {
- rho = a * cos( Leaves*theta ); /* apply the formula */
-
- x = rho * cos( theta ); /* convert to rectangular coords */
- y = rho * sin( theta ) / ScaleFactor;
-
- SetPixel( x+Xmax/2, y+Ymax/2, PixelValue ); /* plot the point */
- }
- }
-
- \SAMPCODE\VIDEO\13\13_6.C
-
- /* Listing 13-6 */
-
- FilledRectangle( x1, y1, x2, y2, n )
- int x1,y1; /* upper left corner */
- int x2,y2; /* lower right corner */
- int n; /* pixel value */
- {
- int y;
-
- for (y=y1; y<=y2; y++) /* draw rectangle as a set of */
- Line( x1, y, x2, y, n ); /* adjacent horizontal lines */
- }
-
- \SAMPCODE\VIDEO\13\13_8.C
-
- /* Listing 13-8 */
-
-
- HWND hWnd; /* window handle */
- HDC hDC; /* device context handle */
-
- struct
- {
- HDC hdc; /* device context handle */
- BOOL fErase;
- RECT rcPaint;
- BOOL fRestore;
- BOOL fIncUpdate;
- BYTE rgbReserved[16];
- } ps; /* "paint structure" */
-
-
- /* create a window */
-
- hWnd = CreateWindow( ... );
- .
- .
- .
-
- /* initialize device context for window */
-
- BeginPaint( hWnd, &ps );
- hDC = ps.hdc;
- .
- .
- .
-
- /* associate attributes with device context */
-
- hpen = CreatePen( PS_SOLID, 0, GetSysColor(COLOR_WINDOWTEXT) );
- SelectObject( hDC, (HANDLE)hpen );
-
- hbr = CreateSolidBrush( GetNearestColor(hDC,RectFillColor) );
- SelectObject( hDC, (HANDLE)hbr );
- .
- .
- .
-
- /* draw a filled rectangle */
-
- Rectangle( hDC, 0, 0, 100, 100 );
-
- \SAMPCODE\VIDEO\13\13_1A.ASM
-
- TITLE 'Listing 13-1a'
- NAME SetPixel
- PAGE 55,132
-
- ;
- ; Name: SetPixel
- ;
- ; Function: Set the value of a pixel in native EGA graphics modes.
- ;
- ; Caller: Microsoft C (small memory model):
- ;
- ; void SetPixel(x,y,n);
- ;
- ; int x,y; /* pixel coordinates */
- ;
- ; int n; /* pixel value */
- ;
- ; Notes: This is the same routine as in Chapter 5.
- ;
-
- ARGx EQU word ptr [bp+4] ; stack frame addressing
- ARGy EQU word ptr [bp+6]
- ARGn EQU byte ptr [bp+8]
-
- RMWbits EQU 0 ; read-modify-write bits
-
-
- _TEXT SEGMENT byte public 'CODE'
- ASSUME cs:_TEXT
-
- EXTRN PixelAddr:near
-
- PUBLIC _SetPixel
- _SetPixel PROC near
-
- push bp ; preserve caller registers
- mov bp,sp
-
- mov ax,ARGy ; AX := y
- mov bx,ARGx ; BX := x
- call PixelAddr ; AH := bit mask
- ; ES:BX -> buffer
- ; CL := # bits to shift left
-
- ; set Graphics Controller Bit Mask register
-
- shl ah,cl ; AH := bit mask in proper position
- mov dx,3CEh ; GC address register port
- mov al,8 ; AL := Bit Mask register number
- out dx,ax
-
- ; set Graphics Controller Mode register
-
- mov ax,0005h ; AL := Mode register number
- ; AH := Write Mode 0 (bits 0,1)
- ; Read Mode 0 (bit 3)
- out dx,ax
-
- ; set Data Rotate/Function Select register
-
- mov ah,RMWbits ; AH := Read-Modify-Write bits
- mov al,3 ; AL := Data Rotate/Function Select r
- out dx,ax
-
- ; set Set/Reset and Enable Set/Reset registers
-
- mov ah,ARGn ; AH := pixel value
- mov al,0 ; AL := Set/Reset reg number
- out dx,ax
-
- mov ax,0F01h ; AH := value for Enable Set/Reset (a
- ; bit planes enabled)
- ; AL := Enable Set/Reset reg number
- out dx,ax
-
- ; set the pixel value
-
- or es:[bx],al ; load latches during CPU read
- ; update latches and bit planes durin
- ; CPU write
-
- ; restore default Graphics Controller registers
-
- mov ax,0FF08h ; default Bit Mask
- out dx,ax
-
- mov ax,0005 ; default Mode register
- out dx,ax
-
- mov ax,0003 ; default Function Select
- out dx,ax
-
- mov ax,0001 ; default Enable Set/Reset
- out dx,ax
-
- mov sp,bp ; restore caller registers and return
- pop bp
- ret
-
- _SetPixel ENDP
-
- _TEXT ENDS
-
- END
-
- \SAMPCODE\VIDEO\13\13_5.ASM
-
- TITLE 'Listing 13-5'
- NAME SetPixel
- PAGE 55,132
-
- ;
- ; Name: SetPixel
- ;
- ; Function: Set the value of a pixel in native EGA graphics modes.
- ;
- ; Caller: Memory-resident routine invoked via interrupt 60H:
- ;
- ; mov ax,PixelX ; pixel x-coordinate
- ; mov bx,PixelY ; pixel y-coordinate
- ; mov cx,PixelValue ; pixel value
- ;
- ; Notes: - Assemble and link to create SETPIXEL.EXE.
- ; - Execute once to make SetPixel resident in memory and to poi
- ; the INT 60H vector to the RAM-resident code.
- ; - Requires MS-DOS version 2.0 or later.
- ;
-
- RMWbits EQU 0
-
- _TEXT SEGMENT byte public 'CODE'
- ASSUME cs:_TEXT
-
- EXTRN PixelAddr:near
-
- PUBLIC SetPixel
- SetPixel PROC near ; RAM-resident interrupt 60H handler
-
- sti ; enable interrupts
- push ax ; preserve caller registers on
- push bx ; caller's stack
- push cx
- push dx
-
- push cx ; preserve pixel value on stack
-
- call PixelAddr ; compute pixel address
- shl ah,cl
-
- mov dx,3CEh ; program the Graphics Controller
- mov al,8 ; AL := Bit Mask register number
- out dx,ax
-
- mov ax,0005h
- out dx,ax
-
- mov ah,RMWbits ; AH := Read-Modify-Write bits
- mov al,3 ; AL := Data Rotate/Function Select r
- out dx,ax
-
- pop ax
- mov ah,al ; AH := pixel value
- mov al,0
- out dx,ax
-
- mov ax,0F01h
- out dx,ax
-
- or es:[bx],al ; set the pixel value
-
- mov ax,0FF08h ; restore default Graphics Controller
- out dx,ax ; values
-
- mov ax,0005
- out dx,ax
-
- mov ax,0003
- out dx,ax
-
- mov ax,0001
- out dx,ax
-
- pop dx ; restore caller registers and return
- pop cx
- pop bx
- pop ax
- iret
-
- SetPixel ENDP
-
- _TEXT ENDS
-
-
- TRANSIENT_TEXT SEGMENT para
- ASSUME cs:TRANSIENT_TEXT,ss:STACK
-
- Install PROC near
-
- mov ax,2560h ; AH := 25H (INT 21H function number)
- ; AL := 60H (interrupt number)
- mov dx,seg _TEXT
- mov ds,dx
- mov dx,offset _TEXT:SetPixel ; DS:DX -> interrupt handl
-
- int 21h ; point INT 60H vector to
- ; SetPixel routine
-
- mov dx,cs ; DX := segment of start of transient
- ; (discardable) portion of program
- mov ax,es ; ES := Program Segment Prefix
- sub dx,ax ; DX := size of RAM-resident portion
- mov ax,3100h ; AH := 31H (INT 21H function number)
- ; AL := 0 (return code)
- int 21h ; Terminate but Stay Resident
-
- Install ENDP
-
- TRANSIENT_TEXT ENDS
-
- STACK SEGMENT para stack 'STACK'
-
- DB 80h dup(?) ; stack space for transient portion
- ; of program
- STACK ENDS
-
- END Install
-
- \SAMPCODE\VIDEO\13\13_7.ASM
-
- TITLE 'Listing 13-7'
- NAME dgisrect
- PAGE 55,132
-
- ;
- ; Name: dgisrect
- ;
- ; Function: draw a filled rectangle using DGIS
- ;
- ; Notes: assemble and link to create DGISRECT.EXE
- ;
-
- CR EQU 0Dh
- LF EQU 0Ah
-
- _TEXT SEGMENT byte public 'CODE'
- ASSUME cs:_TEXT,ds:_DATA,ss:STACK
-
- EntryPoint PROC far
-
- mov ax,seg _DATA
- mov ds,ax ; DS -> _DATA
- push ss
- pop es ; ES -> stack segment
-
- ; look for installed DGIS devices
-
- xor dx,dx ; DX = 0 (buffer length)
- xor cx,cx ; CX = 0
- xor bx,bx ; BX = 0
- mov ax,6A00h ; AX = DGIS opcode (Inquire
- ; Available Devices)
- int 10h
- or cx,cx
- jnz L01 ; jump if device(s) installed
-
- mov dx,offset _DATA:Msg0
- jmp ErrorExit
-
- ; find a graphics output device in the list of installed DGIS devices
-
- L01: inc cx ; CX = (# of bytes in list) +
- and cx,0FFFEh ; CX = even number of bytes
- mov bp,sp
- sub sp,cx ; establish stack frame
- ; (SS:BP -> end of frame)
- mov di,sp ; ES:DI -> start of stack fra
-
- push di ; save for later
- mov dx,cx ; DX = size of buffer
- xor cx,cx
- xor bx,bx
- mov ax,6A00h ; AX = DGIS opcode (Inquire
- ; Available Devices)
- int 10h ; get device list at ES:DI
- pop di ; ES:DI -> device list
-
- L02: cmp word ptr es:[di+2],0 ; is this a graphics device?
- je L04 ; jump if so
-
- sub bx,es:[di] ; BX = bytes remaining in lis
- jnz L03 ; jump if more devices in lis
-
- mov dx,offset _DATA:Msg1
- jmp ErrorExit
-
- L03: add di,es:[di] ; ES:DI -> next device in lis
- jmp L02
-
- ; establish a logical connection to the graphics device
- ; using the first available configuration on the device
-
- L04: les di,es:[di+6] ; ES:DI -> device entry point
- mov word ptr GrDevEntry,di
- mov word ptr GrDevEntry+2,es ; save entry point
-
- mov cx,0 ; CX = first configuration in
- mov ax,0027h ; AX = DGIS opcode (Connect)
- call dword ptr GrDevEntry ; connect to graphics device
- cmp bx,-1 ; test returned handle
- jne L05 ; jump if connected
-
- mov dx,offset _DATA:Msg2
- jmp ErrorExit
-
- L05: mov ChannelHandle,bx ; save the handle for later
- mov ax,001Bh ; AX = DGIS opcode (Init DGI)
- call dword ptr GrDevEntry ; initialize the device with
- ; default attributes
-
- ; draw a filled rectangle using default attributes
-
- mov di,100 ; DI = lower right corner y
- mov si,100 ; SI = lower right corner x
- mov dx,0 ; DX = upper left corner y
- mov cx,0 ; CX = upper left corner x
- mov bx,ChannelHandle ; BX = handle
- mov ax,003Fh ; AX = DGIS opcode (Output
- ; Filled Rectangle)
- call dword ptr GrDevEntry
-
- ; disconnect and exit
-
- mov bx,ChannelHandle ; BX = handle
- mov ax,002Bh ; AX = DGIS opcode (Disconnec
- call dword ptr GrDevEntry
-
- Lexit: mov ax,4C00h
- int 21h ; return to DOS
-
- ErrorExit: mov ah,9
- int 21h ; display error message
- mov ax,4C01h
- int 21h ; return to DOS
-
- EntryPoint ENDP
-
- _TEXT ENDS
-
-
- _DATA SEGMENT para public 'DATA'
-
- GrDevEntry DD ? ; graphics device entry point
- ChannelHandle DW ? ; handle to connected device
- ; configuration
-
- Msg0 DB CR,LF,'No DGIS devices installed',CR,LF,'$'
- Msg1 DB CR,LF,'No graphics devices installed',CR,LF,'$'
- Msg2 DB CR,LF,'Can''t connect to graphics device',CR,LF,'$'
-
- _DATA ENDS
-
-
- STACK SEGMENT stack 'STACK'
-
- DB 400h dup(?)
-
- STACK ENDS
-
- END EntryPoint
-
- \SAMPCODE\VIDEO\2
- \SAMPCODE\VIDEO\2\2_2.ASM
-
- TITLE 'Listing 2-2'
- NAME HRTimeout
- PAGE 55,132
-
- ;
- ; Name: HRTimeout
- ;
- ; Function: Determine a timeout value for the horizontal blanking interva
- ;
- ; Caller: Microsoft C:
- ;
- ; int HRTimeout();
- ;
-
- _TEXT SEGMENT byte public 'CODE'
- ASSUME cs:_TEXT
-
- PUBLIC _HRTimeout
- _HRTimeout PROC near
-
- push bp ; usual C prologue to establish
- mov bp,sp ; stack frame
-
- mov ax,40h
- mov es,ax ; ES := video BIOS data segment
-
- mov dx,es:[63h] ; DX := port for CRTC Address registe
- add dl,6 ; DX := port for CRTC Status register
-
- ; synchronize with start of refresh cycle
-
- L01: in al,dx ; AL := CRTC status
- test al,8 ; test bit 3
- jz L01 ; loop while NOT in vertical retrace
-
- L02: in al,dx
- test al,8
- jnz L02 ; loop during vertical retrace
-
- ; synchronize with a horizontal scan and time the horizontal blanking interva
-
- mov cx,0FFFFh ; CX := loop counter
-
- cli ; disable interrupts
-
- L03: in al,dx
- test al,1
- jnz L03 ; loop while Display Enable is inacti
-
- L04: in al,dx
- test al,1
- jz L04 ; loop while Display Enable is active
-
- L05: in al,dx
- test al,1
- loopnz L05 ; decrement CX and loop while Display
- ; Enable is inactive
-
- sti ; enable interrupts again
-
- mov ax,cx ; AX := loop counter
- neg ax
- shl ax,1 ; AX := timeout value
-
- mov sp,bp ; discard stack frame and return to C
- pop bp
- ret
-
- _HRTimeout ENDP
-
- _TEXT ENDS
-
- END
-
- \SAMPCODE\VIDEO\2\2_4.ASM
-
- TITLE 'Listing 2-4'
- NAME HercGraphMode
- PAGE 55,132
-
- ;
- ; Name: HercGraphMode
- ;
- ; Function: Establish Hercules 720x348 graphics mode on HGC, HGC+, InColo
- ;
- ; Caller: Microsoft C:
- ;
- ; void HercGraphMode();
- ;
-
- DGROUP GROUP _DATA
-
- _TEXT SEGMENT byte public 'CODE'
- ASSUME cs:_TEXT,ds:DGROUP
-
- PUBLIC _HercGraphMode
- _HercGraphMode PROC near
-
- push bp ; preserve caller registers
- mov bp,sp
- push si
- push di
-
- ; Update Video BIOS Data Area with reasonable values
-
- mov ax,40h
- mov es,ax
- mov di,49h ; ES:DI := 0040:0049 (BIOS data area)
-
- mov si,offset DGROUP:BIOSData
- mov cx,BIOSDataLen
- rep movsb ; update BIOS data area
-
- ; Set Configuration Switch
-
- mov dx,3BFh ; DX := Configuration Switch port
- mov al,1 ; AL bit 1 := 0 (exclude 2nd 32K of
- ; video buffer)
- ; AL bit 0 := 1 (allow graphics mode
- out dx,al ; setting via 3B8h)
-
- ; Blank the screen to avoid interference during CRTC programming
-
- mov dx,3B8h ; DX := CRTC Mode Control Register po
- xor al,al ; AL bit 3 := 0 (disable video signal
- out dx,al ; blank the screen
-
- ; Program the CRTC
-
- sub dl,4 ; DX := CRTC Address Reg port 3B4h
-
- mov si,offset DGROUP:CRTCParms
- mov cx,CRTCParmsLen
-
- L01: lodsw ; AL := CRTC register number
- ; AH := data for this register
- out dx,ax
- loop L01
-
- ; Set graphics mode
-
- add dl,4 ; DX := 3B8h (CRTC Mode Control Reg)
- mov al,CRTMode ; AL bit 1 = 1 (enable graphics mode)
- ; bit 3 = 1 (enable video)
- out dx,al
-
- pop di ; restore registers and exit
- pop si
- mov sp,bp
- pop bp
- ret
-
- _HercGraphMode ENDP
-
- _TEXT ENDS
-
-
- _DATA SEGMENT word public 'DATA'
-
- ; These are the parameters recommended by Her
- ; They are based on 16 pixels/character and
- ; 4 scan lines per character.
-
- CRTCParms DB 00h,35h ; Horizontal Total: 54 characters
- DB 01h,2Dh ; Horizontal Displayed: 45 characters
- DB 02h,2Eh ; Horizontal Sync Position: at 46th characte
- DB 03h,07h ; Horizontal Sync Width: 7 character clocks
-
- DB 04h,5Bh ; Vertical Total: 92 characters (368 lines)
- DB 05h,02h ; Vertical Adjust: 2 scan lines
- DB 06h,57h ; Vertical Displayed: 87 character rows (348
- DB 07h,57h ; Vertical Sync Position: after 87th char ro
-
- DB 09h,03h ; Max Scan Line: 4 scan lines per char
-
- CRTCParmsLen EQU ($-CRTCParms)/2
-
- BIOSData DB 7 ; CRT_MODE
- DW 80 ; CRT_COLS
- DW 8000h ; CRT_LEN
- DW 0 ; CRT_START
- DW 8 dup(0) ; CURSOR_POSN
- DW 0 ; CURSOR_MODE
- DB 0 ; ACTIVE_PAGE
- CRTCAddr DW 3B4h ; ADDR_6845
- CRTMode DB 0Ah ; CRT_MODE_SET (value for port 3B8h)
- DB 0 ; CRT_PALETTE (unused)
-
- BIOSDataLen EQU $-BIOSData
-
- _DATA ENDS
-
- END
-
- \SAMPCODE\VIDEO\3
- \SAMPCODE\VIDEO\3\3_10.ASM
-
- TITLE 'Listing 3-10'
- NAME DisplayText
- PAGE 55,132
-
- ;
- ; Name: DisplayText
- ;
- ; Function: Display an alphanumeric string without interference on the CG
- ;
- ; Caller: Microsoft C:
- ;
- ; int DisplayText(buf,n,offset);
- ;
- ; char *buf; /* buffer containing text in
- ; CGA alphanumeric format
- ; (alternating character cod
- ; and attribute bytes)
- ; */
- ;
- ; int n; /* buffer length in bytes */
- ;
- ; unsigned int offset; /* offset into video buffer *
- ;
-
- ARGbuf EQU word ptr [bp+4]
- ARGn EQU word ptr [bp+6]
- ARGoffset EQU word ptr [bp+8]
- TIMEOUT EQU 6 ; horizontal timeout loop limit
- VBcount EQU 250 ; number of words to write during
- ; vertical blanking interval
-
- _TEXT SEGMENT byte public 'CODE'
- ASSUME cs:_TEXT
-
- PUBLIC _DisplayText
- _DisplayText PROC near
-
- push bp ; usual C prologue to establish
- mov bp,sp ; stack frame and preserve registers
- push si
- push di
-
- mov ax,0B800h
- mov es,ax
- mov di,ARGoffset ; ES:DI -> destination in video buffe
- mov si,ARGbuf ; DS:SI -> source buffer
- mov cx,ARGn
- shr cx,1 ; CX := buffer length in words
-
- mov dx,3DAh ; DX := CGA Status Port
-
- ; write during remaining vertical blanking interval
-
- L01: mov bx,cx ; preserve buffer length in BX
- mov cx,TIMEOUT ; CX := horizontal timeout
- cli ; disable interrupts during loop
-
- L02: in al,dx ; AL := video status
- test al,1
- loopnz L02 ; loop while Display Enable inactive
- jz L03 ; jump if loop did not time out
-
- movsw ; copy one word
- sti
- mov cx,bx ; CX := buffer length
- loop L01
-
- jmp short L10 ; exit (entire string copied)
-
- ; write during horizontal blanking intervals
-
- L03: sti
- mov cx,bx ; restore CX
-
- L04: lodsw ; AL := character code
- ; AH := attribute
- mov bx,ax ; BX := character and attribute
- push cx ; preserve word loop counter
- mov cx,TIMEOUT ; CX := timeout loop limit
-
- cli ; clear interrupts during one scan li
- L05: in al,dx
- test al,1
- loopnz L05 ; loop during horizontal blanking
- ; until timeout occurs
- jnz L07 ; jump if timed out (vertical
- ; blanking has started)
- L06: in al,dx
- test al,1
- jz L06 ; loop while Display Enable is active
-
- xchg ax,bx ; AX := character & attribute
- stosw ; copy 2 bytes to display buffer
-
- sti ; restore interrupts
- pop cx ; CX := word loop counter
- loop L04
-
- jmp short L10 ; exit (entire string copied)
-
- ; write during entire vertical blanking interval
-
- L07: pop bx ; BX := word loop counter
- dec si
- dec si ; DS:SI -> word to copy from buffer
-
- mov cx,VBcount ; CX := # of words to copy
- cmp bx,cx
- jnb L08 ; jump if more than VBcount words rem
- ; in buffer
- mov cx,bx ; CX := # of remaining words in buffe
- xor bx,bx ; BX := 0
- jmp short L09
-
- L08: sub bx,cx ; BX := (# of remaining words) - VBco
-
- L09: rep movsw ; copy to video buffer
-
- mov cx,bx ; CX := # of remaining words
- test cx,cx
- jnz L01 ; loop until buffer is displayed
-
- L10: pop di ; usual C epilogue to restore registe
- pop si ; and discard stack frame
- mov sp,bp
- pop bp
- ret
-
- _DisplayText ENDP
-
- _TEXT ENDS
-
- END
-
- \SAMPCODE\VIDEO\3\3_9.ASM
-
- TITLE 'Listing 3-9'
- NAME DisplayText
- PAGE 55,132
-
- ;
- ; Name: DisplayText
- ;
- ; Function: Display an alphanumeric string without interference on the CG
- ;
- ; Caller: Microsoft C:
- ;
- ; int DisplayText1(buf,n,offset);
- ;
- ; char *buf; /* buffer containing text in
- ; CGA alphanumeric format
- ; (alternating character cod
- ; and attribute bytes
- ; */
- ;
- ; int n; /* buffer length in bytes */
- ;
- ; unsigned int offset; /* offset into video buffer *
- ;
-
- Set80X25 EQU (1 SHL 0) ; bit masks for Mode Control Register
- Set320X200 EQU (1 SHL 1)
- BlackAndWhite EQU (1 SHL 2)
- EnableVideo EQU (1 SHL 3)
- Set640X200 EQU (1 SHL 4)
- EnableBlink EQU (1 SHL 5)
-
- ARGbuf EQU word ptr [bp+4] ; stack frame addressing
- ARGn EQU word ptr [bp+6]
- ARGoffset EQU word ptr [bp+8]
- TIMEOUT EQU 5 ; Horizontal Retrace timeout loop lim
-
-
- _TEXT SEGMENT byte public 'CODE'
- ASSUME cs:_TEXT
-
- PUBLIC _DisplayText
- _DisplayText PROC near
-
- push bp ; usual C prologue to establish
- mov bp,sp ; stack frame and preserve registers
- push si
- push di
-
- mov ax,0B800h
- mov es,ax
- mov di,ARGoffset ; ES:DI -> destination in video buffe
- mov si,ARGbuf ; DS:SI -> source buffer
- mov bx,ARGn
- shr bx,1 ; BX := buffer length in words
-
- mov dx,3DAh ; DX := CGA Status Port
-
- ; wait for start of vertical blanking period
-
- L01: mov cx,TIMEOUT ; CX := loop counter (timeout value)
-
- L02: in al,dx ; AL := video status
- test al,8
- jnz L02 ; loop if in vertical retrace
- test al,1
- jz L02 ; loop if not in horizontal retrace
-
- cli ; disable interrupts during horiz ret
-
- L03: in al,dx
- test al,1
- loopnz L03 ; loop until end of retrace or timeou
-
- sti ; re-enable interrupts
-
- jz L01 ; loop if no timeout
-
- ; blank the display
-
- mov dl,0D8h ; DX := 3D8h (Mode Control register)
- mov al,(Set80X25 OR EnableBlink)
- out dx,al ; turn video off
-
- ; copy the data to the video buffer
-
- mov cx,bx ; CX := buffer length in words
- rep movsw
-
- ; re-enable the display
-
- or al,EnableVideo
- out dx,al
-
- pop di ; usual C epilogue to restore registe
- pop si ; and discard stack frame
- mov sp,bp
- pop bp
- ret
-
- _DisplayText ENDP
-
- _TEXT ENDS
-
- END
-
- \SAMPCODE\VIDEO\4
- \SAMPCODE\VIDEO\4\4_1.ASM
-
- TITLE 'Listing 4-1'
- NAME PixelAddr04
- PAGE 55,132
-
- ;
- ; Name: PixelAddr04
- ;
- ; Function: Determine buffer address of pixel in 320x200 4-color mode
- ;
- ; Caller: AX = y-coordinate (0-199)
- ; BX = x-coordinate (0-319)
- ;
- ; Returns: AH = bit mask
- ; BX = byte offset in buffer
- ; CL = number of bits to shift left
- ; ES = video buffer segment
- ;
-
-
- OriginOffset EQU 0 ; byte offset of (0,0)
- VideoBufferSeg EQU 0B800h
-
- _TEXT SEGMENT byte public 'CODE'
- ASSUME cs:_TEXT
-
- PUBLIC PixelAddr04
- PixelAddr04 PROC near
-
- mov cl,bl ; CL := low-order byte of x
-
- xchg ah,al ; AX := 100h * y
- shr ax,1 ; AL := 80h * (y&1)
- add bh,al ; BX := x + 8000h*(y&1)
- xor al,al ; AX := 100h*(y/2)
- add bx,ax ; BX := x + 8000h*(y&1) + 100h*(y/2)
- shr ax,1
- shr ax,1 ; AX := 40h*(y/2)
- add bx,ax ; BX := x + 8000h*(y&1) + 140h*(y/2)
- shr bx,1
- shr bx,1 ; BX := x/4 + 2000h*(y&1) + 50h*(y/2)
- add bx,OriginOffset ; BX := byte offset in video buffer
-
- mov ax,VideoBufferSeg
- mov es,ax ; ES:BX := byte address of pixel
-
- mov ah,3 ; AH := unshifted bit mask
- and cl,ah ; CL := x & 3
- xor cl,ah ; CL := 3 - (x & 3)
- shl cl,1 ; CL := # bits to shift left
-
- ret
-
- PixelAddr04 ENDP
-
- _TEXT ENDS
-
- END
-
- \SAMPCODE\VIDEO\4\4_2.ASM
-
- TITLE 'Listing 4-2'
- NAME PixelAddr06
- PAGE 55,132
-
- ;
- ; Name: PixelAddr06
- ;
- ; Function: Determine buffer address of pixel in 640x200 2-color mode
- ;
- ; Caller: AX = y-coordinate (0-199)
- ; BX = x-coordinate (0-639)
- ;
- ; Returns: AH = bit mask
- ; BX = byte offset in buffer
- ; CL = number of bits to shift left
- ; ES = video buffer segment
- ;
-
-
- OriginOffset EQU 0 ; byte offset of (0,0)
- VideoBufferSeg EQU 0B800h
-
- _TEXT SEGMENT byte public 'CODE'
- ASSUME cs:_TEXT
-
- PUBLIC PixelAddr06
- PixelAddr06 PROC near
-
- mov cl,bl ; CL := low-order byte of x
-
- xchg ah,al ; AX := 100h * y
- shr bx,1 ; BX := x/2
- shr ax,1 ; AL := 80h*(y&1)
- add bh,al ; BX := x/2 + 8000h*(y&1)
- xor al,al ; AX := 100h*(y/2)
- add bx,ax ; BX := x/2 + 8000h*(y&1) + 100h*(y/2
- shr ax,1
- shr ax,1 ; AX := 40h*(y/2)
- add bx,ax ; BX := x/2 + 8000h*(y&1) + 140h*(y/2
- shr bx,1
- shr bx,1 ; BX := x/8 + 2000h*(y&1) + 50h*(y/2)
- add bx,OriginOffset ; BX := byte offset in video buffer
-
- mov ax,VideoBufferSeg
- mov es,ax ; ES:BX := byte address of pixel
-
- and cl,7 ; CL := x & 7
- xor cl,7 ; CL := number of bits to shift left
- mov ah,1 ; AH := unshifted bit mask
-
- ret
-
- PixelAddr06 ENDP
-
- _TEXT ENDS
-
- END
-
- \SAMPCODE\VIDEO\4\4_3.ASM
-
- TITLE 'Listing 4-3'
- NAME PixelAddrHGC
- PAGE 55,132
-
- ;
- ; Name: PixelAddrHGC
- ;
- ; Function: Determine buffer address of pixel in 720x348 Hercules graphic
- ;
- ; Caller: AX = y-coordinate (0-347)
- ; BX = x-coordinate (0-719)
- ;
- ; Returns: AH = bit mask
- ; BX = byte offset in buffer
- ; CL = number of bits to shift left
- ; ES = video buffer segment
- ;
-
- BytesPerLine EQU 90
- OriginOffset EQU 0 ; byte offset of (0,0)
- VideoBufferSeg EQU 0B000h
-
- _TEXT SEGMENT byte public 'CODE'
- ASSUME cs:_TEXT
-
- PUBLIC PixelAddrHGC
- PixelAddrHGC PROC near
-
- mov cl,bl ; CL := low-order byte of x
-
- shr ax,1 ; AX := y/2
- rcr bx,1 ; BX := 8000h*(y&1) + x/2
- shr ax,1 ; AX := y/4
- rcr bx,1 ; BX := 4000h*(y&3) + x/4
- shr bx,1 ; BX := 2000h*(y&3) + x/8
- mov ah,BytesPerLine
- mul ah ; AX := BytesPerLine*(y/4)
- add bx,ax ; BX := 2000h*(y&3) + x/8 + BytesPerL
- add bx,OriginOffset ; BX := byte offset in video buffer
-
- mov ax,VideoBufferSeg
- mov es,ax ; ES:BX := byte address of pixel
-
- and cl,7 ; CL := x & 7
- xor cl,7 ; CL := number of bits to shift left
- mov ah,1 ; AH := unshifted bit mask
-
- ret
-
- PixelAddrHGC ENDP
-
- _TEXT ENDS
-
- END
-
- \SAMPCODE\VIDEO\4\4_4.ASM
-
- TITLE 'Listing 4-4'
- NAME PixelAddr10
- PAGE 55,132
-
- ;
- ; Name: PixelAddr10
- ;
- ; Function: Determine buffer address of pixel in native EGA and VGA modes
- ; 320x200 16-color
- ; 640x200 16-color
- ; 640x350 16-color
- ; 640x350 monochrome (4-color)
- ; 640x480 2-color
- ; 640x480 16-color
- ;
- ; Caller: AX = y-coordinate
- ; BX = x-coordinate
- ;
- ; Returns: AH = bit mask
- ; BX = byte offset in buffer
- ; CL = number of bits to shift left
- ; ES = video buffer segment
- ;
-
-
- BytesPerLine EQU 80 ; bytes in one horizontal line
- OriginOffset EQU 0 ; byte offset of (0,0)
- VideoBufferSeg EQU 0A000h
-
- _TEXT SEGMENT byte public 'CODE'
- ASSUME cs:_TEXT
-
- PUBLIC PixelAddr10
- PixelAddr10 PROC near
-
- mov cl,bl ; CL := low-order byte of x
-
- push dx ; preserve DX
-
- mov dx,BytesPerLine ; AX := y * BytesPerLine
- mul dx
-
- pop dx
- shr bx,1
- shr bx,1
- shr bx,1 ; BX := x/8
- add bx,ax ; BX := y*BytesPerLine + x/8
- add bx,OriginOffset ; BX := byte offset in video buffer
-
- mov ax,VideoBufferSeg
- mov es,ax ; ES:BX := byte address of pixel
-
- and cl,7 ; CL := x & 7
- xor cl,7 ; CL := number of bits to shift left
- mov ah,1 ; AH := unshifted bit mask
- ret
-
- PixelAddr10 ENDP
-
- _TEXT ENDS
-
- END
-
- \SAMPCODE\VIDEO\4\4_5.ASM
-
- TITLE 'Listing 4-5'
- NAME PixelAddr13
- PAGE 55,132
-
- ;
- ; Name: PixelAddr13
- ;
- ; Function: Determine buffer address of pixel in 320x200 256-color mode
- ;
- ; Caller: AX = y-coordinate (0-199)
- ; BX = x-coordinate (0-319)
- ;
- ; Returns: BX = byte offset in buffer
- ; ES = video buffer segment
- ;
-
-
- OriginOffset EQU 0 ; byte offset of (0,0)
- VideoBufferSeg EQU 0A000h
-
- _TEXT SEGMENT byte public 'CODE'
- ASSUME cs:_TEXT
-
- PUBLIC PixelAddr13
- PixelAddr13 PROC near
-
- xchg ah,al ; AX := 256*y
- add bx,ax ; BX := 256*y + x
- shr ax,1
- shr ax,1 ; AX := 64*y
- add bx,ax ; BX := 320*y + x
-
- add bx,OriginOffset ; BX := byte offset in video buffer
-
- mov ax,VideoBufferSeg
- mov es,ax ; ES:BX := byte address of pixel
- ret
-
- PixelAddr13 ENDP
-
- _TEXT ENDS
-
- END
-
- \SAMPCODE\VIDEO\5
- \SAMPCODE\VIDEO\5\5_10.ASM
-
- TITLE 'Listing 5-10'
- NAME SetPixel06
- PAGE 55,132
-
- ;
- ; Name: SetPixel06
- ;
- ; Function: Set the value of a pixel in 640x200 2-color mode
- ;
- ; Caller: Microsoft C:
- ;
- ; void SetPixel(x,y,n);
- ;
- ; int x,y; /* pixel coordinates */
- ;
- ; int n; /* pixel value */
- ;
-
- ARGx EQU word ptr [bp+4] ; stack frame addressing
- ARGy EQU word ptr [bp+6]
- ARGn EQU byte ptr [bp+8]
-
-
- DGROUP GROUP _DATA
-
- _TEXT SEGMENT byte public 'CODE'
- ASSUME cs:_TEXT,ds:DGROUP
-
- EXTRN PixelAddr06:near
-
- PUBLIC _SetPixel06
- _SetPixel06 PROC near
-
- push bp ; preserve caller registers
- mov bp,sp
-
- mov ax,ARGy ; AX := y
- mov bx,ARGx ; BX := x
- call PixelAddr06 ; AH := bit mask
- ; ES:BX -> buffer
- ; CL := # bits to shift left
-
- mov al,ARGn ; AL := unshifted pixel value
- shl ax,cl ; AH := bit mask in proper position
- ; AL := pixel value in proper positio
-
- jmp word ptr SetPixelOp06 ; jump to Replace, AND,
- ; OR or XOR routine
-
-
- ; routine to Replace pixel value
-
- ReplacePixel06: not ah ; AH := inverse bit mask
- and es:[bx],ah ; zero the pixel value
- or es:[bx],al ; set the pixel value
- jmp short L02
-
-
- ; routine to AND pixel value
- ANDPixel06: test al,al
- jnz L02 ; do nothing if pixel value = 1
-
- L01: not ah ; AH := inverse of bit mask
- and es:[bx],ah ; set bit in video buffer to 0
- jmp short L02
-
-
- ; routine to OR pixel value
- ORPixel06: test al,al
- jz L02 ; do nothing if pixel value = 0
-
- or es:[bx],al ; set bit in video buffer
- jmp short L02
-
-
- ; routine to XOR pixel value
- XORPixel06: test al,al
- jz L02 ; do nothing if pixel value = 0
-
- xor es:[bx],al ; XOR bit in video buffer
-
-
- L02: mov sp,bp ; restore caller registers and return
- pop bp
- ret
-
- _SetPixel06 ENDP
-
- _TEXT ENDS
-
-
- _DATA SEGMENT word public 'DATA'
-
- SetPixelOp06 dw ReplacePixel06 ; contains addr of pixel operation
-
- _DATA ENDS
-
- END
-
- \SAMPCODE\VIDEO\5\5_11.ASM
-
- TITLE 'Listing 5-11'
- NAME SetPixel04
- PAGE 55,132
-
- ;
- ; Name: SetPixel04
- ;
- ; Function: Set the value of a pixel in 320x200 4-color mode
- ;
- ; Caller: Microsoft C:
- ;
- ; void SetPixel(x,y,n);
- ;
- ; int x,y; /* pixel coordinates */
- ;
- ; int n; /* pixel value */
- ;
-
- ARGx EQU word ptr [bp+4] ; stack frame addressing
- ARGy EQU word ptr [bp+6]
- ARGn EQU byte ptr [bp+8]
-
-
- DGROUP GROUP _DATA
-
- _TEXT SEGMENT byte public 'CODE'
- ASSUME cs:_TEXT,ds:DGROUP
-
- EXTRN PixelAddr04:near
-
- PUBLIC _SetPixel04
- _SetPixel04 PROC near
-
- push bp ; preserve caller registers
- mov bp,sp
-
- mov ax,ARGy ; AX := y
- mov bx,ARGx ; BX := x
- call PixelAddr04 ; AH := bit mask
- ; ES:BX -> buffer
- ; CL := #bits to shift left
-
- mov al,ARGn
- shl ax,cl ; AH := bit mask in proper position
- ; AL := pixel value in proper positio
-
- jmp word ptr SetPixelOp04 ; jump to Replace, AND,
- ; OR or XOR routine
-
-
- ; routine to Replace pixel value
-
- ReplacePixel04: not ah ; AH := inverse bit mask
- and es:[bx],ah ; zero the pixel value
- or es:[bx],al ; set the pixel value
- jmp short L02
-
- ; routine to AND pixel value
-
- ANDPixel04: not ah ; AH := inverse bit mask
- or al,ah ; AL := all 1's except pixel value
- and es:[bx],al
- jmp short L02
-
-
- ORPixel04: or es:[bx],al ; routine to OR pixel value
- jmp short L02
-
-
- XORPixel04: xor es:[bx],al ; routine to XOR pixel value
-
-
- L02: mov sp,bp ; restore caller registers and return
- pop bp
- ret
-
- _SetPixel04 ENDP
-
- _TEXT ENDS
-
-
- _DATA SEGMENT word public 'DATA'
-
- SetPixelOp04 DW ReplacePixel04 ; contains addr of pixel operation
-
- _DATA ENDS
-
- END
-
- \SAMPCODE\VIDEO\5\5_12.ASM
-
- TITLE 'Listing 5-12'
- NAME SetPixel10
- PAGE 55,132
-
- ;
- ; Name: SetPixel10
- ;
- ; Function: Set the value of a pixel in native EGA graphics modes.
- ;
- ; *** Write Mode 0, Set/Reset ***
- ;
- ; Caller: Microsoft C:
- ;
- ; void SetPixel(x,y,n);
- ;
- ; int x,y; /* pixel coordinates */
- ;
- ; int n; /* pixel value */
- ;
-
- ARGx EQU word ptr [bp+4] ; stack frame addressing
- ARGy EQU word ptr [bp+6]
- ARGn EQU byte ptr [bp+8]
-
- RMWbits EQU 18h ; read-modify-write bits
-
-
- _TEXT SEGMENT byte public 'CODE'
- ASSUME cs:_TEXT
-
- EXTRN PixelAddr10:near
-
- PUBLIC _SetPixel10
- _SetPixel10 PROC near
-
- push bp ; preserve caller registers
- mov bp,sp
-
- mov ax,ARGy ; AX := y
- mov bx,ARGx ; BX := x
- call PixelAddr10 ; AH := bit mask
- ; ES:BX -> buffer
- ; CL := # bits to shift left
-
- ; set Graphics Controller Bit Mask register
-
- shl ah,cl ; AH := bit mask in proper position
- mov dx,3CEh ; GC address register port
- mov al,8 ; AL := Bit Mask register number
- out dx,ax
-
- ; set Graphics Controller Mode register
-
- mov ax,0005h ; AL := Mode register number
- ; AH := Write Mode 0 (bits 0,1)
- ; Read Mode 0 (bit 3)
- out dx,ax
-
- ; set Data Rotate/Function Select register
-
- mov ah,RMWbits ; AH := Read-Modify-Write bits
- mov al,3 ; AL := Data Rotate/Function Select r
- out dx,ax
-
- ; set Set/Reset and Enable Set/Reset registers
-
- mov ah,ARGn ; AH := pixel value
- mov al,0 ; AL := Set/Reset reg number
- out dx,ax
-
- mov ax,0F01h ; AH := value for Enable Set/Reset (a
- ; bit planes enabled)
- ; AL := Enable Set/Reset reg number
- out dx,ax
-
- ; set the pixel value
-
- or es:[bx],al ; load latches during CPU read
- ; update latches and bit planes durin
- ; CPU write
-
- ; restore default Graphics Controller registers
-
- mov ax,0FF08h ; default Bit Mask
- out dx,ax
-
- mov ax,0005 ; default Mode register
- out dx,ax
-
- mov ax,0003 ; default Function Select
- out dx,ax
-
- mov ax,0001 ; default Enable Set/Reset
- out dx,ax
-
- mov sp,bp ; restore caller registers and return
- pop bp
- ret
-
- _SetPixel10 ENDP
-
- _TEXT ENDS
-
- END
-
- \SAMPCODE\VIDEO\5\5_13.ASM
-
- TITLE 'Listing 5-13'
- NAME SetPixel10
- PAGE 55,132
-
- ;
- ; Name: SetPixel10
- ;
- ; Function: Set the value of a pixel in native EGA graphics modes.
- ;
- ; *** Write Mode 0, Sequencer Map Mask ***
- ;
- ; Caller: Microsoft C:
- ;
- ; void SetPixel(x,y,n);
- ;
- ; int x,y; /* pixel coordinates */
- ;
- ; int n; /* pixel value */
- ;
-
- ARGx EQU word ptr [bp+4] ; stack frame addressing
- ARGy EQU word ptr [bp+6]
- ARGn EQU byte ptr [bp+8]
-
-
- _TEXT SEGMENT byte public 'CODE'
- ASSUME cs:_TEXT
-
- EXTRN PixelAddr10:near
-
- PUBLIC _SetPixel10
- _SetPixel10 PROC near
-
- push bp ; preserve caller registers
- mov bp,sp
-
- mov ax,ARGy ; AX := y
- mov bx,ARGx ; BX := x
- call PixelAddr10 ; AH := bit mask
- ; ES:BX -> buffer
- ; CL := # bits to shift left
-
- ; set Graphics Controller Bit Mask register
-
- shl ah,cl ; AH := bit mask in proper position
- mov dx,3CEh ; Graphics Controller address reg por
- mov al,8 ; AL := Bit Mask register number
- out dx,ax
-
- ; zero the pixel value
-
- mov al,es:[bx] ; latch one byte from each bit plane
- mov byte ptr es:[bx],0 ; zero masked bits in all planes
-
- ; set Sequencer Map Mask register
-
- mov dl,0C4h ; DX := 3C4h (Sequencer addr reg port
- mov ah,ARGn ; AH := value for Map Mask register
- ; (nonzero bits in pixel value selec
- ; enabled bit planes for Sequencer
- mov al,2 ; AL := Map Mask register number
- out dx,ax
-
- ; set the nonzero bits in the pixel value
-
- mov byte ptr es:[bx],0FFh ; set bits in enabled bit plane
-
- ; restore default Sequencer registers
-
- mov ah,0Fh ; AH := value for Map Mask reg (all b
- ; planes enabled)
- out dx,ax
-
- ; restore default Graphics Controller registers
-
- mov dl,0CEh ; DX := 3CEh (Graphics Controller por
- mov ax,0FF08h ; default Bit Mask
- out dx,ax
-
- mov sp,bp ; restore caller registers and return
- pop bp
- ret
-
- _SetPixel10 ENDP
-
- _TEXT ENDS
-
- END
-
- \SAMPCODE\VIDEO\5\5_14.ASM
-
- TITLE 'Listing 5-14'
- NAME SetPixel10
- PAGE 55,132
-
- ;
- ; Name: SetPixel10
- ;
- ; Function: Set the value of a pixel in native EGA graphics modes.
- ;
- ; *** Write Mode 2 ***
- ;
- ; Caller: Microsoft C:
- ;
- ; void SetPixel(x,y,n);
- ;
- ; int x,y; /* pixel coordinates */
- ;
- ; int n; /* pixel value */
- ;
-
- ARGx EQU word ptr [bp+4] ; stack frame addressing
- ARGy EQU word ptr [bp+6]
- ARGn EQU byte ptr [bp+8]
-
- RMWbits EQU 18h ; read-modify-write bits
-
-
- _TEXT SEGMENT byte public 'CODE'
- ASSUME cs:_TEXT
-
- EXTRN PixelAddr10:near
-
- PUBLIC _SetPixel10
- _SetPixel10 PROC near
-
- push bp ; preserve stack frame
- mov bp,sp
-
- mov ax,ARGy ; AX := y
- mov bx,ARGx ; BX := x
- call PixelAddr10 ; AH := bit mask
- ; ES:BX -> buffer
- ; CL := # bits to shift left
-
- ; set Graphics Controller Bit Mask register
-
- shl ah,cl ; AH := bit mask in proper position
- mov dx,3CEh ; GC address register port
- mov al,8 ; AL := Bit Mask register number
- out dx,ax
-
- ; set Graphics Controller Mode register
-
- mov ax,205h ; AL := Mode register number
- ; AH := Write Mode 2 (bits 0,1)
- ; Read Mode 0 (bit 3)
- out dx,ax
-
- ; set Data Rotate/Function Select register
-
- mov ah,RMWbits ; AH := Read-Modify-Write bits
- mov al,3 ; AL := Data Rotate/Function Select r
- out dx,ax
-
- ; set the pixel value
-
- mov al,es:[bx] ; latch one byte from each bit plane
- mov al,ARGn ; AL := pixel value
- mov es:[bx],al ; update all bit planes
-
- ; restore default Graphics Controller registers
-
- mov ax,0FF08h ; default Bit Mask
- out dx,ax
-
- mov ax,0005 ; default Mode register
- out dx,ax
-
- mov ax,0003 ; default Function Select
- out dx,ax
-
- mov sp,bp ; restore stack frame and return
- pop bp
- ret
-
- _SetPixel10 ENDP
-
- _TEXT ENDS
-
- END
-
- \SAMPCODE\VIDEO\5\5_15.ASM
-
- TITLE 'Listing 5-15'
- NAME SetPixelInC
- PAGE 55,132
-
- ;
- ; Name: SetPixelInC
- ;
- ; Function: Set the value of a pixel in 720x348 16-color mode
- ;
- ; Caller: Microsoft C:
- ;
- ; void SetPixel(x,y,n);
- ;
- ; int x,y; /* pixel coordinates */
- ;
- ; int n; /* pixel value */
- ;
-
- ARGx EQU word ptr [bp+4] ; stack frame addressing
- ARGy EQU word ptr [bp+6]
- ARGn EQU byte ptr [bp+8]
-
- DefaultRWColor EQU 0Fh ; default value for R/W Color Registe
-
-
- DGROUP GROUP _DATA
-
- _TEXT SEGMENT byte public 'CODE'
- ASSUME cs:_TEXT,ds:DGROUP
-
- EXTRN PixelAddrHGC:near
-
- PUBLIC _SetPixelInC
- _SetPixelInC PROC near
-
- push bp ; preserve caller registers
- mov bp,sp
-
- mov ax,ARGy ; AX := y
- mov bx,ARGx ; BX := x
- call PixelAddrHGC ; AH := bit mask
- ; ES:BX -> buffer
- ; CL := # bits to shift left
-
- shl ah,cl ; AH := bit mask in proper position
-
- mov dx,3B4h ; DX := CRTC port
-
- jmp word ptr SetPixelOpInC ; jump to Replace, AND,
- ; OR or XOR routine
-
-
- ReplacePixelInC: ; routine to Replace pixel value
-
- mov ch,ah ; CH := bit mask for pixel
- mov ax,1F19h ; AH bit 6 := 0 (Mask Polarity)
- ; AH bits 5-4 := 1 (Write Mode)
- ; AH bits 3-0 := "don't care" bits
- ; AL := R/W Control Register number
- out dx,ax ; set R/W Control Register
-
- inc ax ; AL := 1Ah (R/W Color Reg number)
- mov ah,ARGn ; AH := foreground value
- out dx,ax ; set R/W color register
-
- and es:[bx],ch ; update bit planes
- jmp short L01
-
- ANDPixelInC: ; routine to AND pixel value
-
- mov ch,ah ; CH := bit mask for pixel
- mov ax,1F19h ; AH bit 6 := 0 (Mask Polarity)
- ; AH bits 5-4 := 1 (Write Mode)
- ; AH bits 3-0 := "don't care" bits
- ; AL := R/W Control Register number
- out dx,ax ; set R/W Control Register
-
- dec ax ; AL := 18h (Plane Mask Register numb
- mov ah,ARGn ; AH := pixel value
- mov cl,4
- shl ah,cl ; AH bits 7-4 := writeable plane mask
- or ah,0Fh ; AH bits 3-0 := visible plane mask
- out dx,ax ; set Plane Mask Register
-
- mov ax,001Ah ; AH := 0 (foreground value)
- ; AL := 1Ah (R/W Color reg)
- out dx,ax ; set R/W Color Register
-
- and es:[bx],ch ; update bit planes
- jmp short L01
-
- ; routine to OR pixel value
- ORPixelInC:
- mov ch,ah ; CH := bit mask for pixel
- mov ax,1F19h ; AH bit 6 := 0 (Mask Polarity)
- ; AH bits 5-4 := 1 (Write Mode)
- ; AH bits 3-0 := "don't care" bits
- ; AL := R/W Control Register number
- out dx,ax ; set R/W Control Register
-
- dec ax ; AL := 18h (Plane Mask Register numb
- mov ah,ARGn ; AH := pixel value
- not ah ; AH := complement of pixel value
- mov cl,4
- shl ah,cl ; AH bits 7-4 := writeable plane mask
- or ah,0Fh ; AH bits 3-0 := visible plane mask
- out dx,ax ; set Plane Mask Register
-
- mov ax,0F1Ah ; AH := 0 (foreground value)
- ; AL := 1Ah (R/W Color reg)
- out dx,ax ; set R/W Color Register
-
- and es:[bx],ch ; update bit planes
- jmp short L01
-
- XORPixelInC: ; routine to XOR pixel value
- mov ch,ah ; CH := bit mask for pixel
- mov ax,3F19h ; AH bit 6 := 0 (Mask Polarity)
- ; AH bits 5-4 := 3 (Write Mode)
- ; AH bits 3-0 := "don't care" bits
- ; AL := R/W Control Register number
- out dx,ax ; set R/W Control Register
-
- dec ax ; AL := 18h (Plane Mask Register numb
- mov ah,ARGn ; AH := pixel value
- not ah ; AH := complement of pixel value
- mov cl,4
- shl ah,cl ; AH bits 7-4 := writeable plane mask
- or ah,0Fh ; AH bits 3-0 := visible plane mask
- out dx,ax ; set Plane Mask Register
-
- xor es:[bx],ch ; update bit planes
-
- L01: mov ax,0F18h
- out dx,ax ; restore default Plane Mask value
-
- mov ax,4019h ; restore default R/W Control value
- out dx,ax
-
- inc ax ; restore default R/W Color value
- mov ah,DefaultRWColor
- out dx,ax
-
- mov sp,bp ; restore caller registers and return
- pop bp
- ret
-
- _SetPixelInC ENDP
-
- _TEXT ENDS
-
-
- _DATA SEGMENT word public 'DATA'
-
- SetPixelOpInC DW ReplacePixelInc ; contains addr of pixel operation
-
- _DATA ENDS
-
- END
-
- \SAMPCODE\VIDEO\5\5_16.ASM
-
- TITLE 'Listing 5-16'
- NAME SetPixel11
- PAGE 55,132
-
- ;
- ; Name: SetPixel11
- ;
- ; Function: Set the value of a pixel in 640x480 2-color mode (MCGA or VGA
- ;
- ; Caller: Microsoft C:
- ;
- ; void SetPixel(x,y,n);
- ;
- ; int x,y; /* pixel coordinates */
- ;
- ; int n; /* pixel value */
- ;
-
- ARGx EQU word ptr [bp+4] ; stack frame addressing
- ARGy EQU word ptr [bp+6]
- ARGn EQU byte ptr [bp+8]
-
-
- DGROUP GROUP _DATA
-
- _TEXT SEGMENT byte public 'CODE'
- ASSUME cs:_TEXT,ds:DGROUP
-
- EXTRN PixelAddr10:near
-
- PUBLIC _SetPixel11
- _SetPixel11 PROC near
-
- push bp ; preserve caller registers
- mov bp,sp
-
- mov ax,ARGy ; AX := y
- mov bx,ARGx ; BX := x
- call PixelAddr10 ; AH := bit mask
- ; ES:BX -> buffer
- ; CL := # bits to shift left
-
- mov al,ARGn ; AL := unshifted pixel value
- shl ax,cl ; AH := bit mask in proper position
- ; AL := pixel value in proper positio
-
- jmp word ptr SetPixelOp11 ; jump to Replace, AND,
- ; OR or XOR routine
-
-
- ; routine to Replace pixel value
-
- ReplacePixel11: not ah ; AH := inverse bit mask
- and es:[bx],ah ; zero the pixel value
- or es:[bx],al ; set the pixel value
- jmp short L02
-
-
- ; routine to AND pixel value
- ANDPixel11: test al,al
- jnz L02 ; do nothing if pixel value = 1
-
- L01: not ah ; AH := inverse of bit mask
- and es:[bx],ah ; set bit in video buffer to 0
- jmp short L02
-
-
- ; routine to OR pixel value
- ORPixel11: test al,al
- jz L02 ; do nothing if pixel value = 0
-
- or es:[bx],al ; set bit in video buffer
- jmp short L02
-
-
- ; routine to XOR pixel value
- XORPixel11: test al,al
- jz L02 ; do nothing if pixel value = 0
-
- xor es:[bx],al ; XOR bit in video buffer
-
-
- L02: mov sp,bp ; restore caller registers and return
- pop bp
- ret
-
- _SetPixel11 ENDP
-
- _TEXT ENDS
-
-
- _DATA SEGMENT word public 'DATA'
-
- SetPixelOp11 DW ReplacePixel11 ; contains addr of pixel operation
-
- _DATA ENDS
-
- END
-
- \SAMPCODE\VIDEO\5\5_17.ASM
-
- TITLE 'Listing 5-17'
- NAME SetPixel13
- PAGE 55,132
-
- ;
- ; Name: SetPixel13
- ;
- ; Function: Set the value of a pixel in VGA 320x200 256-color mode
- ;
- ; Caller: Microsoft C:
- ;
- ; void SetPixel(x,y,n);
- ;
- ; int x,y; /* pixel coordinates */
- ;
- ; int n; /* pixel value */
- ;
-
- ARGx EQU word ptr [bp+4] ; stack frame addressing
- ARGy EQU word ptr [bp+6]
- ARGn EQU byte ptr [bp+8]
-
- DGROUP GROUP _DATA
-
- _TEXT SEGMENT byte public 'CODE'
- ASSUME cs:_TEXT,ds:DGROUP
-
- EXTRN PixelAddr13:near
-
- PUBLIC _SetPixel13
- _SetPixel13 PROC near
-
- push bp ; preserve caller registers
- mov bp,sp
-
- mov ax,ARGy ; AX := y
- mov bx,ARGx ; BX := x
- call PixelAddr13 ; ES:BX -> buffer
-
- mov al,ARGn ; AL := pixel value
-
- jmp word ptr SetPixelOp13 ; jump to Replace, AND,
- ; OR or XOR routine
-
-
- ReplacePixel13: mov es:[bx],al
- jmp short L01
-
- ANDPixel13: and es:[bx],al
- jmp short L01
-
- ORPixel13: or es:[bx],al
- jmp short L01
-
- XORPixel13: xor es:[bx],al
-
-
- L01: mov sp,bp ; restore caller registers and return
- pop bp
- ret
-
- _SetPixel13 ENDP
-
- _TEXT ENDS
-
-
- _DATA SEGMENT word public 'DATA'
-
- SetPixelOp13 DW ReplacePixel13
-
- _DATA ENDS
-
- END
-
- \SAMPCODE\VIDEO\5\5_2.ASM
-
- TITLE 'Listing 5-2'
- NAME ReadPixel06
- PAGE 55,132
-
- ;
- ; Name: ReadPixel06
- ;
- ; Function: Read the value of a pixel in 640x200 2-color mode
- ;
- ; Caller: Microsoft C:
- ;
- ; int ReadPixel06(x,y);
- ;
- ; int x,y; /* pixel coordinates */
- ;
-
- ARGx EQU word ptr [bp+4] ; stack frame addressing
- ARGy EQU word ptr [bp+6]
-
-
- _TEXT SEGMENT byte public 'CODE'
- ASSUME cs:_TEXT
-
- EXTRN PixelAddr06:near
-
- PUBLIC _ReadPixel06
- _ReadPixel06 PROC near
-
- push bp ; preserve caller registers
- mov bp,sp
-
- mov ax,ARGy ; AX := y
- mov bx,ARGx ; BX := x
- call PixelAddr06 ; AH := bit mask
- ; ES:BX -> buffer
- ; CL := #bits to shift
-
- mov al,es:[bx] ; AL := byte containing pixel
- shr al,cl ; shift pixel value to low-order bits
- and al,ah ; AL := pixel value
- xor ah,ah ; AX := pixel value
-
- mov sp,bp ; restore caller registers and return
- pop bp
- ret
-
- _ReadPixel06 ENDP
-
- _TEXT ENDS
-
- END
-
- \SAMPCODE\VIDEO\5\5_3.ASM
-
- TITLE 'Listing 5-3'
- NAME ReadPixel04
- PAGE 55,132
-
- ;
- ; Name: ReadPixel04
- ;
- ; Function: Read the value of a pixel in 320x200 4-color mode
- ;
- ; Caller: Microsoft C:
- ;
- ; int ReadPixel04(x,y);
- ;
- ; int x,y; /* pixel coordinates */
- ;
-
- ARGx EQU word ptr [bp+4] ; stack frame addressing
- ARGy EQU word ptr [bp+6]
-
-
- _TEXT SEGMENT byte public 'CODE'
- ASSUME cs:_TEXT
-
- EXTRN PixelAddr04:near
-
- PUBLIC _ReadPixel04
- _ReadPixel04 PROC near
-
- push bp ; preserve caller registers
- mov bp,sp
-
- mov ax,ARGy ; AX := y
- mov bx,ARGx ; BX := x
- call PixelAddr04 ; AH := bit mask
- ; ES:BX -> buffer
- ; CL := #bits to shift
-
- mov al,es:[bx] ; AL := byte containing pixel
- shr al,cl ; shift pixel value to low-order bits
- and al,ah ; AL := pixel value
- xor ah,ah ; AX := pixel value
-
- mov sp,bp ; restore caller registers and return
- pop bp
- ret
-
- _ReadPixel04 ENDP
-
- _TEXT ENDS
-
- END
-
- \SAMPCODE\VIDEO\5\5_4.ASM
-
- TITLE 'Listing 5-4'
- NAME ReadPixel10
- PAGE 55,132
-
- ;
- ; Name: ReadPixel10
- ;
- ; Function: Read the value of a pixel in EGA native graphics modes
- ;
- ; Caller: Microsoft C:
- ;
- ; int ReadPixel10(x,y);
- ;
- ; int x,y; /* pixel coordinates */
- ;
-
- ARGx EQU word ptr [bp+4] ; stack frame addressing
- ARGy EQU word ptr [bp+6]
-
-
- _TEXT SEGMENT byte public 'CODE'
- ASSUME cs:_TEXT
-
- EXTRN PixelAddr10:near
-
- PUBLIC _ReadPixel10
- _ReadPixel10 PROC near
-
- push bp ; preserve caller registers
- mov bp,sp
- push si
-
- mov ax,ARGy ; AX := y
- mov bx,ARGx ; BX := x
- call PixelAddr10 ; AH := bit mask
- ; ES:BX -> buffer
- ; CL := #bits to shift
-
- mov ch,ah
- shl ch,cl ; CH := bit mask in proper position
-
- mov si,bx ; ES:SI -> regen buffer byte
- xor bl,bl ; BL is used to accumulate the pixel
-
- mov dx,3CEh ; DX := Graphics Controller port
- mov ax,304h ; AH := initial bit plane number
- ; AL := Read Map Select register numb
-
- L01: out dx,ax ; select bit plane
- mov bh,es:[si] ; BH := byte from current bit plane
- and bh,ch ; mask one bit
- neg bh ; bit 7 of BH := 1 (if masked bit = 1
- ; bit 7 of BH := 0 (if masked bit = 0
- rol bx,1 ; bit 0 of BL := next bit from pixel
- dec ah ; AH := next bit plane number
- jge L01
-
- mov al,bl ; AL := pixel value
- xor ah,ah ; AX := pixel value
-
- pop si ; restore caller registers and return
- mov sp,bp
- pop bp
- ret
-
- _ReadPixel10 ENDP
-
- _TEXT ENDS
-
- END
-
- \SAMPCODE\VIDEO\5\5_5.ASM
-
- TITLE 'Listing 5-5'
- NAME ReadPixel0F
- PAGE 55,132
-
- ;
- ; Name: ReadPixel0F
- ;
- ; Function: Read the value of a pixel in 640x350 monochrome mode
- ;
- ; Caller: Microsoft C:
- ;
- ; int ReadPixel0F(x,y);
- ;
- ; int x,y; /* pixel coordinates */
- ;
-
- ARGx EQU word ptr [bp+4] ; stack frame addressing
- ARGy EQU word ptr [bp+6]
-
-
- _TEXT SEGMENT byte public 'CODE'
- ASSUME cs:_TEXT
-
- EXTRN PixelAddr10:near
-
- PUBLIC _ReadPixel0F
- _ReadPixel0F PROC near
-
- push bp ; preserve caller registers
- mov bp,sp
- push si
-
- mov ax,ARGy ; AX := y
- mov bx,ARGx ; BX := x
- call PixelAddr10 ; AH := bit mask
- ; ES:BX -> buffer
- ; CL := #bits to shift
-
- ; concatenate bits from bit planes 2 and 0
-
- mov ch,ah
- shl ch,cl ; CH := bit mask in proper position
- mov si,bx ; ES:SI -> regen buffer byte
-
- mov dx,3CEh ; DX := Graphics Controller port
- mov ax,204h ; AH := initial bit plane number
- ; AL := Read Map Select register numb
-
- xor bl,bl ; BL is used to accumulate the pixel
-
- L01: out dx,ax ; (same as before)
- mov bh,es:[si]
- and bh,ch
- neg bh
-
- rol bx,1
- sub ah,2
- jge L01
-
- mov al,bl
- xor ah,ah
-
- pop si
- mov sp,bp
- pop bp
- ret
-
- _ReadPixel0F ENDP
-
- _TEXT ENDS
-
- END
-
- \SAMPCODE\VIDEO\5\5_6.ASM
-
- TITLE 'Listing 5-6'
- NAME ReadPixel10
- PAGE 55,132
-
- ;
- ; Name: ReadPixel10
- ;
- ; Function: Read the value of a pixel in 640x350 modes on 64K EGA
- ;
- ; Caller: Microsoft C:
- ;
- ; int ReadPixel10(x,y);
- ;
- ; int x,y; /* pixel coordinates */
- ;
-
- ARGx EQU word ptr [bp+4] ; stack frame addressing
- ARGy EQU word ptr [bp+6]
-
-
- _TEXT SEGMENT byte public 'CODE'
- ASSUME cs:_TEXT
-
- EXTRN PixelAddr10:near
-
- PUBLIC _ReadPixel10
- _ReadPixel10 PROC near
-
- push bp ; preserve caller registers
- mov bp,sp
- push si
-
- mov ax,ARGy ; AX := y
- mov bx,ARGx ; BX := x
- call PixelAddr10 ; AH := bit mask
- ; ES:BX -> buffer
- ; CL := #bits to shift
-
- ; concatenate bits from bit planes 2 and 0 (even byte address)
- ; or 3 and 1 (odd byte address)
-
- mov ch,ah
- shl ch,cl ; CH := bit mask in proper position
-
- mov si,bx ; ES:SI -> regen buffer byte
-
- mov ah,bl ; AH := low-order byte of address
- and ax,100h ; AH := low-order bit of address
- ; AL := 0
- add ax,204h ; AH := initial bit plane number (2 o
- ; AL := Read Map Select register numb
-
- mov dx,3CEh ; DX := Graphics Controller port
- xor bl,bl ; BL is used to accumulate the pixel
-
- L01: out dx,ax ; (same as before)
- mov bh,es:[si]
- and bh,ch
- neg bh
-
- rol bx,1
- sub ah,2
- jge L01
-
- mov al,bl
- xor ah,ah
-
- pop si
- mov sp,bp
- pop bp
- ret
-
- _ReadPixel10 ENDP
-
- _TEXT ENDS
-
- END
-
- \SAMPCODE\VIDEO\5\5_7.ASM
-
- TITLE 'Listing 5-7'
- NAME ReadPixelInC
- PAGE 55,132
-
- ;
- ; Name: ReadPixelInC
- ;
- ; Function: Read the value of a pixel in InColor 720x348 16-color mode
- ;
- ; Caller: Microsoft C:
- ;
- ; int ReadPixelInC(x,y);
- ;
- ; int x,y;
- ;
-
- ARGx EQU word ptr [bp+4] ; stack frame addressing
- ARGy EQU word ptr [bp+6]
-
- DefaultRWColor EQU 0Fh ; default value for R/W Color Registe
-
-
- _TEXT SEGMENT byte public 'CODE'
- ASSUME cs:_TEXT
-
- EXTRN PixelAddrHGC:near
-
- PUBLIC _ReadPixelInC
- _ReadPixelInC PROC near
-
- push bp ; preserve caller registers
- mov bp,sp
- push si
-
- mov ax,ARGy ; AX := y
- mov bx,ARGx ; BX := x
- call PixelAddrHGC ; AH := bit mask
- ; ES:BX -> buffer
- ; CL := #bits to shift
-
- ; set up to examine each bit plane separately
-
- mov si,bx ; ES:SI -> buffer
-
- shl ah,cl
- mov cl,ah ; CL := bit mask in proper position
-
- mov dx,3B4h ; DX := graphics control port
-
- mov ax,0F01Ah ; AH bits 4-7 := 1111b (background va
- ; AL := 1Ah (R/W Color Register)
- out dx,ax ; set background value
-
- mov bx,800h ; BH := 1000b (initial "don't care" b
- ; BL := 0 (initial value for result)
-
- dec ax ; AL := 19h (R/W Control Register num
-
- ; loop across bit planes by updating "don't care" bits
-
- L01: mov ah,bh ; AH bits 0-3 := next "don't care" bi
- ; AH bit 6 := 0 (Mask Polarity bit)
- xor ah,1111b ; invert "don't care" bits
- out dx,ax ; set R/W Control Register
-
- mov ch,cl ; CH := bit mask
- and ch,es:[si] ; latch bit planes
- ; CH <> 0 if bit in latch is set
-
- neg ch ; cf set if CH <> 0
- rcl bl,1 ; accumulate result in BL
-
- shr bh,1 ; BH := shifted "don't care" bits
- jnz L01 ; loop until shifted out of BH,
- ; at which point BX = pixel value
- ; restore default state
-
- mov ah,40h ; AH := default R/W Control Register
- out dx,ax
-
- inc ax ; AL := 1Ah (R/W Color Register numbe
- mov ah,DefaultRWColor
- out dx,ax
-
- mov ax,bx ; AX := pixel value
-
- pop si ; restore caller registers and return
- mov sp,bp
- pop bp
- ret
-
- _ReadPixelInC ENDP
-
- _TEXT ENDS
-
- END
-
- \SAMPCODE\VIDEO\5\5_8.ASM
-
- TITLE 'Listing 5-8'
- NAME ReadPixel11
- PAGE 55,132
-
- ;
- ; Name: ReadPixel11
- ;
- ; Function: Read the value of a pixel in 640x480 2-color mode (MCGA or VG
- ;
- ; Caller: Microsoft C:
- ;
- ; int ReadPixel11(x,y);
- ;
- ; int x,y; /* pixel coordinates */
- ;
-
- ARGx EQU word ptr [bp+4] ; stack frame addressing
- ARGy EQU word ptr [bp+6]
-
-
- _TEXT SEGMENT byte public 'CODE'
- ASSUME cs:_TEXT
-
- EXTRN PixelAddr10:near
-
- PUBLIC _ReadPixel11
- _ReadPixel11 PROC near
-
- push bp ; preserve caller registers
- mov bp,sp
-
- mov ax,ARGy ; AX := y
- mov bx,ARGx ; BX := x
- call PixelAddr10 ; AH := bit mask
- ; ES:BX -> buffer
- ; CL := #bits to shift
-
- mov al,es:[bx] ; AL := byte containing pixel
- shr al,cl ; shift pixel value to low-order bits
- and al,ah ; AL := pixel value
- xor ah,ah ; AX := pixel value
-
- mov sp,bp ; restore caller registers and return
- pop bp
- ret
-
- _ReadPixel11 ENDP
-
- _TEXT ENDS
-
- END
-
- \SAMPCODE\VIDEO\5\5_9.ASM
-
- TITLE 'Listing 5-9'
- NAME ReadPixel13
- PAGE 55,132
-
- ;
- ; Name: ReadPixel13
- ;
- ; Function: Read the value of a pixel in 320x200 256-color mode (MCGA and
- ;
- ; Caller: Microsoft C:
- ;
- ; int ReadPixel13(x,y);
- ;
- ; int x,y; /* pixel coordinates */
- ;
-
- ARGx EQU word ptr [bp+4] ; stack frame addressing
- ARGy EQU word ptr [bp+6]
-
-
- _TEXT SEGMENT byte public 'CODE'
- ASSUME cs:_TEXT
-
- EXTRN PixelAddr13:near
-
- PUBLIC _ReadPixel13
- _ReadPixel13 PROC near
-
- push bp ; preserve caller registers
- mov bp,sp
-
- mov ax,ARGy ; AX := y
- mov bx,ARGx ; BX := x
- call PixelAddr13 ; ES:BX -> buffer
-
- mov al,es:[bx] ; AL := pixel value
- xor ah,ah ; AX := pixel value
-
- mov sp,bp
- pop bp
- ret
-
- _ReadPixel13 ENDP
-
- _TEXT ENDS
-
- END
-
- \SAMPCODE\VIDEO\6
- \SAMPCODE\VIDEO\6\6_1.C
-
- /* Listing 6-1 */
-
- Line( x1, y1, x2, y2, n )
- int x1,y1; /* endpoint */
- int x2,y2; /* endpoint */
- int n; /* pixel value */
- {
- int x,y;
- float m; /* slope */
- float b; /* y-intercept */
-
-
- if (x2 == x1) /* vertical line */
- {
- if (y1 > y2)
- Swap( &y1, &y2 ); /* force y1 < y2 */
-
- for (y=y1; y<=y2; y++) /* draw from y1 to y2 */
- SetPixel( x1, y, n );
-
- return;
- }
-
- if (x1 > x2) /* force x1 < x2 */
- {
- Swap( &x1, &x2 );
- Swap( &y1, &y2 );
- }
-
-
- m = (float)(y2-y1) / (float)(x2-x1); /* compute m and b */
- b = y1 - (m*x1);
-
- for (x=x1; x<=x2; x++) /* draw from x1 to x2 */
- {
- y = m*x + b;
- SetPixel( x, y, n );
- }
- }
-
- Swap( a, b ) /* exchange values of a and b */
- int *a,*b;
- {
- int t;
-
- t = *a;
- *a = *b;
- *b = t;
- }
-
- \SAMPCODE\VIDEO\6\6_11.C
-
- /* Listing 6-11 */
-
- struct EndpointStruct /* endpoints for clipped line */
- {
- int x1,y1;
- int x2,y2;
- };
-
- struct RegionStruct /* rectangular clipping region */
- {
- int Xul;
- int Yul;
- int Xlr;
- int Ylr;
- };
-
-
- union OutcodeUnion /* outcodes are represented as bit fields */
- {
- struct
- {
- unsigned code0 : 1; /* x < Xul */
- unsigned code1 : 1; /* y < Yul */
- unsigned code2 : 1; /* x > Xlr */
- unsigned code3 : 1; /* y > Ylr */
- }
- ocs;
-
- int outcodes;
- };
-
-
- #define X1 ep->x1
- #define Y1 ep->y1
- #define X2 ep->x2
- #define Y2 ep->y2
- #define XUL r->Xul
- #define YUL r->Yul
- #define XLR r->Xlr
- #define YLR r->Ylr
-
-
- Clip(ep,r)
- struct EndpointStruct *ep;
- struct RegionStruct *r;
- {
- union OutcodeUnion ocu1,ocu2;
- int Inside;
- int Outside;
-
-
- /* initialize 4-bit codes */
-
- SetOutcodes( &ocu1, r, X1, Y1 ); /* initial 4-bit codes */
- SetOutcodes( &ocu2, r, X2, Y2 );
-
- Inside = ((ocu1.outcodes | ocu2.outcodes) == 0);
- Outside = ((ocu1.outcodes & ocu2.outcodes) != 0);
-
- while (!Outside && !Inside)
- {
- if (ocu1.outcodes==0) /* swap endpoints if necessary so */
- { /* that (x1,y1) needs to be clipped
- Swap( &X1, &X2 );
- Swap( &Y1, &Y2 );
- Swap( &ocu1, &ocu2 );
- }
-
-
- if (ocu1.ocs.code0) /* clip left */
- {
- Y1 += (long)(Y2-Y1)*(XUL-X1)/(X2-X1);
- X1 = XUL;
- }
-
- else if (ocu1.ocs.code1) /* clip above */
- {
- X1 += (long)(X2-X1)*(YUL-Y1)/(Y2-Y1);
- Y1 = YUL;
- }
-
- else if (ocu1.ocs.code2) /* clip right */
- {
- Y1 += (long)(Y2-Y1)*(XLR-X1)/(X2-X1);
- X1 = XLR;
- }
-
- else if (ocu1.ocs.code3) /* clip below */
- {
- X1 += (long)(X2-X1)*(YLR-Y1)/(Y2-Y1);
- Y1 = YLR;
- }
-
- SetOutcodes( &ocu1, r, X1, Y1 ); /* update for (x1,y1) *
-
- Inside = ((ocu1.outcodes | ocu2.outcodes) == 0); /* update *
- Outside = ((ocu1.outcodes & ocu2.outcodes) != 0); /* 4-bit codes *
- }
-
- return( Inside );
- }
-
-
- SetOutcodes( u, r, x, y )
- union OutcodeUnion *u;
- struct RegionStruct *r;
- int x,y;
- {
- u->outcodes = 0;
- u->ocs.code0 = (x < XUL);
- u->ocs.code1 = (y < YUL);
- u->ocs.code2 = (x > XLR);
- u->ocs.code3 = (y > YLR);
- }
-
-
- Swap( pa, pb )
- int *pa,*pb;
- {
- int t;
-
- t = *pa;
- *pa = *pb;
- *pb = t;
- }
-
- \SAMPCODE\VIDEO\6\6_2.C
-
- /* Listing 6-2 */
-
- Line( x1, y1, x2, y2, n ) /* for lines with slope between -1 and 1 */
- int x1,y1;
- int x2,y2; /* endpoints */
- int n; /* pixel value */
- {
- int d,dx,dy;
- int Aincr,Bincr,yincr;
- int x,y;
-
-
- if (x1 > x2) /* force x1 < x2 */
- {
- Swap( &x1, &x2 );
- Swap( &y1, &y2 );
- }
-
- if (y2 > y1) /* determine increment for y
- yincr = 1;
- else
- yincr = -1;
-
- dx = x2 - x1; /* initialize constants */
- dy = abs( y2-y1 );
- d = 2 * dy - dx;
-
- Aincr = 2 * (dy - dx);
- Bincr = 2 * dy;
-
- x = x1; /* initial x and y */
- y = y1;
-
- SetPixel( x, y, n ); /* set pixel at (x1,y1) */
-
- for (x=x1+1; x<=x2; x++) /* do from x1+1 to x2 */
- {
- if (d >= 0)
- {
- y += yincr; /* set pixel A */
- d += Aincr;
- }
- else /* set pixel B */
- d += Bincr;
-
- SetPixel( x, y, n );
- }
- }
-
-
- Swap( pa, pb )
- int *pa,*pb;
- {
- int t;
-
- t = *pa;
- *pa = *pb;
- *pb = t;
- }
-
- \SAMPCODE\VIDEO\6\6_3.C
-
- /* Listing 6-3 */
-
- FilledRectangle( x1, y1, x2, y2, n )
- int x1,y1; /* upper left corner */
- int x2,y2; /* lower right corner */
- int n; /* pixel value */
- {
- int y;
-
- for (y=y1; y<=y2; y++) /* draw rectangle as a set of */
- Line( x1, y, x2, y, n ); /* adjacent horizontal lines */
- }
-
- \SAMPCODE\VIDEO\6\6_10.ASM
-
- TITLE 'Listing 6-10'
- NAME LineInC
- PAGE 55,132
-
- ;
- ; Name: LineInC
- ;
- ; Function: Draw a line in Hercules InColor 720x348 16-color mode
- ;
- ; Caller: Microsoft C:
- ;
- ; void LineInC(x1,y1,x2,y2,n);
- ;
- ; int x1,y1,x2,y2; /* pixel coordinates */
- ;
- ; int n; /* pixel value */
- ;
-
- ARGx1 EQU word ptr [bp+4] ; stack frame addressing
- ARGy1 EQU word ptr [bp+6]
- ARGx2 EQU word ptr [bp+8]
- ARGy2 EQU word ptr [bp+10]
- ARGn EQU byte ptr [bp+12]
- VARleafincr EQU word ptr [bp-2]
- VARincr1 EQU word ptr [bp-4]
- VARincr2 EQU word ptr [bp-6]
- VARroutine EQU word ptr [bp-8]
-
- ByteOffsetShift EQU 3 ; used to convert pixels to byte offs
- DefaultRWColor EQU 0Fh ; default value for R/W Color registe
-
-
- _TEXT SEGMENT byte public 'CODE'
- ASSUME cs:_TEXT
-
- EXTRN PixelAddrHGC:near
-
- PUBLIC _LineInC
- _LineInC PROC near
-
- push bp ; preserve caller registers
- mov bp,sp
- sub sp,8 ; stack space for local variables
- push si
- push di
-
- mov si,2000h ; increment for video buffer interlea
- mov di,90-8000h ; increment from last to first interl
-
- ; set up InColor CRTC registers
-
- mov dx,3B4h ; DX := CRTC I/O port
- mov ax,5F19h ; AH bit 6 := 1 (Mask Polarity)
- ; AH bits 5-4 := 1 (Write Mode)
- ; AH bits 3-0 := "don't care" bits
- ; AL := R/W Control Register number
- out dx,ax ; set R/W Control Register
-
- inc ax ; AL := 1Ah (R/W Color Reg number)
- mov ah,ARGn ; AH := foreground value
- out dx,ax ; set R/W color register
-
-
- mov cx,ARGx2
- sub cx,ARGx1 ; CX := x2 - x1
- jz VertLineInC ; jump if vertical line
-
- ; force x1 < x2
-
- jns L01 ; jump if x2 > x1
-
- neg cx ; CX := x1 - x2
-
- mov bx,ARGx2 ; exchange x1 and x2
- xchg bx,ARGx1
- mov ARGx2,bx
-
- mov bx,ARGy2 ; exchange y1 and y2
- xchg bx,ARGy1
- mov ARGy2,bx
-
- ; calculate dy = ABS(y2-y1)
-
- L01: mov bx,ARGy2
- sub bx,ARGy1 ; BX := y2 - y1
- jz HorizLineInC ; jump if horizontal line
-
- jns L03
-
- neg bx ; BX := y1 - y2
- neg si ; negate increments for buffer interl
- neg di
-
- ; select appropriate routine for slope of line
-
- L03: mov VARleafincr,di ; save increment for buffer interleav
-
- mov VARroutine,offset LoSlopeLineInC
- cmp bx,cx
- jle L04 ; jump if dy <= dx (slope <= 1)
- mov VARroutine,offset HiSlopeLineInC
- xchg bx,cx ; exchange dy and dx
-
- ; calculate initial decision variable and increments
-
- L04: shl bx,1 ; BX := 2 * dy
- mov VARincr1,bx ; incr1 := 2 * dy
- sub bx,cx
- mov di,bx ; DI := d = 2 * dy - dx
- sub bx,cx
- mov VARincr2,bx ; incr2 := 2 * (dy - dx)
-
- ; calculate first pixel address
-
- push cx ; preserve this register
- mov ax,ARGy1 ; AX := y
- mov bx,ARGx1 ; BX := x
- call PixelAddrHGC ; AH := bit mask
- ; ES:BX -> buffer
- ; CL := # bits to shift left
-
- shl ah,cl
- mov dh,ah ; DH := bit mask in proper position
-
- pop cx ; restore this register
- inc cx ; CX := # of pixels to draw
-
- jmp VARroutine ; jump to appropriate routine for slo
-
-
- ; routine for vertical lines
-
- VertLineInC: mov ax,ARGy1 ; AX := y1
- mov bx,ARGy2 ; BX := y2
- mov cx,bx
- sub cx,ax ; CX := dy
- jge L31 ; jump if dy >= 0
-
- neg cx ; force dy >= 0
- mov ax,bx ; AX := y2
-
- L31: inc cx ; CX := # of pixels to draw
- mov bx,ARGx1 ; BX := x
- push cx ; preserve this register
- call PixelAddrHGC ; AH := bit mask
- ; ES:BX -> video buffer
- ; CL := # bits to shift left
- shl ah,cl ; AH := bit mask in proper position
- pop cx ; restore this register
-
- L32: or es:[bx],ah ; update pixel in buffer
-
- add bx,si ; increment to next portion of interl
- jns L33
-
- add bx,di ; increment to first portion of inter
-
- L33: loop L32
-
- jmp Lexit
-
-
-
- ; routine for horizontal lines (slope = 0)
-
- HorizLineInC: mov ax,ARGy1
- mov bx,ARGx1
- call PixelAddrHGC ; AH := bit mask
- ; ES:BX -> video buffer
- ; CL := # bits to shift left
- mov di,bx ; ES:DI -> buffer
-
- mov dh,ah
- not dh ; DH := unshifted bit mask for leftmo
- ; byte
- mov dl,0FFh ; DL := unshifted bit mask for
- ; rightmost byte
-
- shl dh,cl ; DH := reverse bit mask for first by
- not dh ; DH := bit mask for first byte
-
- mov cx,ARGx2
- and cl,7
- xor cl,7 ; CL := number of bits to shift left
- shl dl,cl ; DL := bit mask for last byte
-
- ; determine byte offset of first and last pixel in the line
-
- mov ax,ARGx2 ; AX := x2
- mov bx,ARGx1 ; BX := x1
-
- mov cl,ByteOffsetShift ; number of bits to shift to
- ; convert pixels to bytes
-
- shr ax,cl ; AX := byte offset of x2
- shr bx,cl ; BX := byte offset of x1
- mov cx,ax
- sub cx,bx ; CX := (# bytes in line) - 1
-
- ; set pixels in leftmost byte of the line
-
- or dh,dh
- js L43 ; jump if byte-aligned (x1 is leftmos
- ; pixel in byte)
- or cx,cx
- jnz L42 ; jump if more than one byte in the l
-
- and dl,dh ; bit mask for the line
- jmp short L44
-
- L42: or es:[di],dh ; update masked pixels in buffer
- inc di
- dec cx
-
- ; use a fast 8086 machine instruction to draw the remainder of the line
-
- L43: mov al,0FFh ; 8-pixel bit mask
- rep stosb ; update all pixels in the line
-
- ; set pixels in the rightmost byte of the line
-
- L44: or es:[di],dl ; update masked pixels in buffer
- jmp Lexit
-
-
- ; routine for dy <= dx (slope <= 1) ; ES:BX -> video buffer
- ; CX = # pixels to draw
- ; DH = bit mask
- ; SI = buffer interleave increment
- ; DI = decision variable
- LoSlopeLineInC:
-
- L10: mov ah,es:[bx] ; latch bit planes
- ; AH := 0 because all planes
- ; are "don't care"
-
- L11: or ah,dh ; set pixel value in byte
-
- ror dh,1 ; rotate bit mask
- jc L14 ; jump if bit mask rotated to
- ; leftmost pixel position
-
- ; bit mask not shifted out
-
- or di,di ; test sign of d
- jns L12 ; jump if d >= 0
-
- add di,VARincr1 ; d := d + incr1
- loop L11
-
- mov es:[bx],ah ; store remaining pixels in buffer
- jmp short Lexit
-
- L12: add di,VARincr2 ; d := d + incr2
- mov es:[bx],ah ; update buffer
-
- add bx,si ; increment y
- jns L13 ; jump if not in last interleave
-
- add bx,VARleafincr ; increment into next interleave
-
- L13: loop L10
- jmp short Lexit
-
- ; bit mask shifted out
-
- L14: mov es:[bx],ah ; update buffer
- inc bx ; BX := offset of next byte
-
- or di,di ; test sign of d
- jns L15 ; jump if non-negative
-
- add di,VARincr1 ; d := d + incr1
- loop L10
- jmp short Lexit
-
- L15: add di,VARincr2 ; d := d + incr2
-
- add bx,si ; increment y
- jns L16 ; jump if not in last interleave
-
- add bx,VARleafincr ; increment into next interleave
-
- L16: loop L10 ; loop until all pixels are set
- jmp short Lexit
-
-
- ; routine for dy > dx (slope > 1) ; ES:BX -> video buffer
- ; CX = # pixels to draw
- ; DH = bit mask
- ; SI = buffer interleave increment
- ; DI = decision variable
- HiSlopeLineInC:
-
- L21: or es:[bx],dh ; set pixel value in video buffer
-
- add bx,si ; increment y
- jns L22 ; jump if not in last interleave
-
- add bx,VARleafincr ; increment into next interleave
-
- L22: or di,di
- jns L23 ; jump if d >= 0
-
- add di,VARincr1 ; d := d + incr1
- loop L21
- jmp short Lexit
-
-
- L23: add di,VARincr2 ; d := d + incr2
-
- ror dh,1 ; rotate bit mask
- adc bx,0 ; BX := offset of next byte (incremen
- ; if bit mask rotated to
- ; leftmost pixel position
-
- loop L21
-
-
- Lexit: mov dx,3B4h ; DX := CRTC I/O port
- mov ax,0F18h
- out dx,ax ; restore default Plane Mask value
-
- mov ax,4019h ; restore default R/W Control value
- out dx,ax
-
- inc ax ; restore default R/W Color value
- mov ah,DefaultRWColor
- out dx,ax
-
- pop di ; restore registers and return
- pop si
- mov sp,bp
- pop bp
- ret
-
- _LineInC ENDP
-
- _TEXT ENDS
-
- END
-
- \SAMPCODE\VIDEO\6\6_4.ASM
-
- TITLE 'Listing 6-4'
- NAME Line06
- PAGE 55,132
-
- ;
- ; Name: Line06
- ;
- ; Function: Draw a line in 640x200 2-color mode
- ;
- ; Caller: Microsoft C:
- ;
- ; void Line06(x1,y1,x2,y2,n);
- ;
- ; int x1,y1,x2,y2; /* pixel coordinates */
- ;
- ; int n; /* pixel value */
- ;
-
- ARGx1 EQU word ptr [bp+4] ; stack frame addressing
- ARGy1 EQU word ptr [bp+6]
- ARGx2 EQU word ptr [bp+8]
- ARGy2 EQU word ptr [bp+10]
- ARGn EQU byte ptr [bp+12]
- VARleafincr EQU word ptr [bp-2]
- VARincr1 EQU word ptr [bp-4]
- VARincr2 EQU word ptr [bp-6]
- VARroutine EQU word ptr [bp-8]
-
- ByteOffsetShift EQU 3 ; used to convert pixels to byte offs
-
- DGROUP GROUP _DATA
-
- _TEXT SEGMENT byte public 'CODE'
- ASSUME cs:_TEXT,ds:DGROUP
-
- EXTRN PixelAddr06:near
-
- PUBLIC _Line06
- _Line06 PROC near
-
- push bp ; preserve caller registers
- mov bp,sp
- sub sp,8 ; stack space for local variables
- push si
- push di
-
-
- mov si,2000h ; increment for video buffer interlea
- mov di,80-2000h ; increment from last to first interl
-
- mov cx,ARGx2
- sub cx,ARGx1 ; CX := x2 - x1
- jz VertLine06 ; jump if vertical line
-
- ; force x1 < x2
-
- jns L01 ; jump if x2 > x1
-
- neg cx ; CX := x1 - x2
-
- mov bx,ARGx2 ; exchange x1 and x2
- xchg bx,ARGx1
- mov ARGx2,bx
-
- mov bx,ARGy2 ; exchange y1 and y2
- xchg bx,ARGy1
- mov ARGy2,bx
-
- ; calculate dy = ABS(y2-y1)
-
- L01: mov bx,ARGy2
- sub bx,ARGy1 ; BX := y2 - y1
- jnz L02
-
- jmp HorizLine06 ; jump if horizontal line
-
- L02: jns L03
-
- neg bx ; BX := y1 - y2
- neg si ; negate increments for buffer interl
- neg di
- xchg si,di ; exchange increments
-
- ; select appropriate routine for slope of line
-
- L03: mov VARleafincr,di ; save increment for buffer interleav
-
- mov VARroutine,offset LoSlopeLine06
- cmp bx,cx
- jle L04 ; jump if dy <= dx (slope <= 1)
- mov VARroutine,offset HiSlopeLine06
- xchg bx,cx ; exchange dy and dx
-
- ; calculate initial decision variable and increments
-
- L04: shl bx,1 ; BX := 2 * dy
- mov VARincr1,bx ; incr1 := 2 * dy
- sub bx,cx
- mov di,bx ; DI := d = 2 * dy - dx
- sub bx,cx
- mov VARincr2,bx ; incr2 := 2 * (dy - dx)
-
- ; calculate first pixel address
-
- push cx ; preserve this register
- mov ax,ARGy1 ; AX := y
- mov bx,ARGx1 ; BX := x
- call PixelAddr06 ; AH := bit mask
- ; ES:BX -> buffer
- ; CL := # bits to shift left
-
- mov al,ARGn ; AL := unshifted pixel value
- shl ax,cl ; AH := bit mask in proper position
- ; AL := pixel value in proper positio
-
- mov dx,ax ; DH := bit mask
- ; DL := pixel value
- not dh ; DH := inverse bit mask
-
- pop cx ; restore this register
- inc cx ; CX := # of pixels to draw
-
- test bx,2000h ; set zero flag if BX in 1st interlea
- jz L05
-
- xchg si,VARleafincr ; exchange increment values if 1st pi
- ; lies in 1st interleave
-
- L05: jmp VARroutine ; jump to appropriate routine for slo
-
-
- ; routine for vertical lines
-
- VertLine06: mov ax,ARGy1 ; AX := y1
- mov bx,ARGy2 ; BX := y2
- mov cx,bx
- sub cx,ax ; CX := dy
- jge L31 ; jump if dy >= 0
-
- neg cx ; force dy >= 0
- mov ax,bx ; AX := y2
-
- L31: inc cx ; CX := # of pixels to draw
- mov bx,ARGx1 ; BX := x
- push cx ; preserve this register
- call PixelAddr06 ; AH := bit mask
- ; ES:BX -> video buffer
- ; CL := # bits to shift left
- mov al,ARGn ; AL := pixel value
- shl ax,cl ; AH := bit mask in proper position
- ; AL := pixel value in proper positio
- not ah ; AH := inverse bit mask
- pop cx ; restore this register
-
- test bx,si ; set zero flag if BX in 1st interlea
- jz L32
-
- xchg si,di ; exchange increment values if 1st pi
- ; lies in 1st interleave
-
- L32: test al,al
- jz L34 ; jump if pixel value = 0
-
- L33: or es:[bx],al ; set pixel values in buffer
- add bx,si ; increment to next portion of interl
- xchg si,di ; toggle between increment values
- loop L33 ; loop down the line
- jmp short L35
-
- L34: and es:[bx],ah ; reset pixel values in buffer
- add bx,si ; increment to next portion of interl
- xchg si,di ; toggle between increment values
- loop L34
-
- L35: jmp Lexit
-
-
- ; routine for horizontal lines (slope = 0)
-
- HorizLine06: mov ax,ARGy1
- mov bx,ARGx1
- call PixelAddr06 ; AH := bit mask
- ; ES:BX -> video buffer
- ; CL := # bits to shift left
- mov di,bx ; ES:DI -> buffer
-
- mov dh,ah
- not dh ; DH := unshifted bit mask for leftmo
- ; byte
- mov dl,0FFh ; DL := unshifted bit mask for
- ; rightmost byte
-
- shl dh,cl ; DH := reverse bit mask for first by
- not dh ; DH := bit mask for first byte
-
- mov cx,ARGx2
- and cl,7
- xor cl,7 ; CL := number of bits to shift left
- shl dl,cl ; DL := bit mask for last byte
-
- ; determine byte offset of first and last pixel in the line
-
- mov ax,ARGx2 ; AX := x2
- mov bx,ARGx1 ; BX := x1
-
- mov cl,ByteOffsetShift ; number of bits to shift to
- ; convert pixels to bytes
-
- shr ax,cl ; AX := byte offset of x2
- shr bx,cl ; BX := byte offset of x1
- mov cx,ax
- sub cx,bx ; CX := (# bytes in line) - 1
-
- ; propagate pixel value throughout one byte
-
- mov bx,offset DGROUP:PropagatedPixel
- mov al,ARGn ; AL := pixel value
- xlat
-
- ; set pixels in leftmost byte of the line
-
- or dh,dh
- js L43 ; jump if byte-aligned (x1 is leftmos
- ; pixel in byte)
- or cx,cx
- jnz L42 ; jump if more than one byte in the l
-
- and dl,dh ; bit mask for the line
- jmp short L44
-
- L42: mov ah,al
- and ah,dh ; AH := masked pixel bits
- not dh ; DH := reverse bit mask for 1st byte
- and es:[di],dh ; zero masked pixels in buffer
- or es:[di],ah ; update masked pixels in buffer
- inc di
- dec cx
-
- ; use a fast 8086 machine instruction to draw the remainder of the line
-
- L43: rep stosb ; update all pixels in the line
-
- ; set pixels in the rightmost byte of the line
-
- L44: and al,dl ; AL := masked pixels for last byte
- not dl
- and es:[di],dl ; zero masked pixels in buffer
- or es:[di],al ; update masked pixels in buffer
-
- jmp Lexit
-
-
- ; routine for dy <= dx (slope <= 1) ; ES:BX -> video buffer
- ; CX = # pixels to draw
- ; DH = inverse bit mask
- ; DL = pixel value in proper position
- ; SI = buffer interleave increment
- ; DI = decision variable
- LoSlopeLine06:
-
- L10: mov ah,es:[bx] ; AH := byte from video buffer
-
- L11: and ah,dh ; zero pixel value at current bit off
- or ah,dl ; set pixel value in byte
-
- ror dl,1 ; rotate pixel value
- ror dh,1 ; rotate bit mask
- jnc L14 ; jump if bit mask rotated to
- ; leftmost pixel position
-
- ; bit mask not shifted out
-
- or di,di ; test sign of d
- jns L12 ; jump if d >= 0
-
- add di,VARincr1 ; d := d + incr1
- loop L11
-
- mov es:[bx],ah ; store remaining pixels in buffer
- jmp short Lexit
-
- L12: add di,VARincr2 ; d := d + incr2
- mov es:[bx],ah ; update buffer
-
- add bx,si ; increment y
- xchg si,VARleafincr ; exchange interleave increment value
- loop L10
- jmp short Lexit
-
- ; bit mask shifted out
-
- L14: mov es:[bx],ah ; update buffer
- inc bx ; BX := offset of next byte
-
- or di,di ; test sign of d
- jns L15 ; jump if non-negative
-
- add di,VARincr1 ; d := d + incr1
- loop L10
- jmp short Lexit
-
- L15: add di,VARincr2 ; d := d + incr2
-
- add bx,si ; increment y
- xchg si,VARleafincr
-
- loop L10
- jmp short Lexit
-
-
- ; routine for dy > dx (slope > 1) ; ES:BX -> video buffer
- ; CX = # pixels to draw
- ; DH = inverse bit mask
- ; DL = pixel value in proper position
- ; SI = buffer interleave increment
- ; DI = decision variable
- HiSlopeLine06:
-
- L21: and es:[bx],dh ; zero pixel value in video buffer
- or es:[bx],dl ; set pixel value in byte
-
- add bx,si ; increment y
- xchg si,VARleafincr ; exchange interleave increment value
-
- L22: or di,di ; test sign of d
- jns L23 ; jump if d >= 0
-
- add di,VARincr1 ; d := d + incr1
- loop L21
-
- jmp short Lexit
-
-
- L23: add di,VARincr2 ; d := d + incr2
-
- ror dl,1 ; rotate pixel value
- ror dh,1 ; rotate bit mask
- cmc ; cf set if bit mask not rotated to
- ; leftmost pixel position
-
- adc bx,0 ; BX := offset of next byte
-
- loop L21
-
-
- Lexit: pop di ; restore registers and return
- pop si
- mov sp,bp
- pop bp
- ret
-
- _Line06 ENDP
-
- _TEXT ENDS
-
-
- _DATA SEGMENT word public 'DATA'
-
- PropagatedPixel DB 00000000b ; 0
- DB 11111111b ; 1
-
- _DATA ENDS
-
- END
-
- \SAMPCODE\VIDEO\6\6_5.ASM
-
- TITLE 'Listing 6-5'
- NAME Line04
- PAGE 55,132
-
- ;
- ; Name: Line04
- ;
- ; Function: Draw a line in 320x200 4-color mode
- ;
- ; Caller: Microsoft C:
- ;
- ; void Line04(x1,y1,x2,y2,n);
- ;
- ; int x1,y1,x2,y2; /* pixel coordinates */
- ;
- ; int n; /* pixel value */
- ;
-
- ARGx1 EQU word ptr [bp+4] ; stack frame addressing
- ARGy1 EQU word ptr [bp+6]
- ARGx2 EQU word ptr [bp+8]
- ARGy2 EQU word ptr [bp+10]
- ARGn EQU byte ptr [bp+12]
- VARleafincr EQU word ptr [bp-2]
- VARincr1 EQU word ptr [bp-4]
- VARincr2 EQU word ptr [bp-6]
- VARroutine EQU word ptr [bp-8]
-
- ByteOffsetShift EQU 2 ; used to convert pixels to byte offs
-
- DGROUP GROUP _DATA
-
- _TEXT SEGMENT byte public 'CODE'
- ASSUME cs:_TEXT,ds:DGROUP
-
- EXTRN PixelAddr04:near
-
- PUBLIC _Line04
- _Line04 PROC near
-
- push bp ; preserve caller registers
- mov bp,sp
- sub sp,8 ; stack space for local variables
- push si
- push di
-
-
- mov si,2000h ; increment for video buffer interlea
- mov di,80-2000h ; increment from last to first interl
-
- mov cx,ARGx2
- sub cx,ARGx1 ; CX := x2 - x1
- jz VertLine04 ; jump if vertical line
-
- ; force x1 < x2
-
- jns L01 ; jump if x2 > x1
-
- neg cx ; CX := x1 - x2
-
- mov bx,ARGx2 ; exchange x1 and x2
- xchg bx,ARGx1
- mov ARGx2,bx
-
- mov bx,ARGy2 ; exchange y1 and y2
- xchg bx,ARGy1
- mov ARGy2,bx
-
- ; calculate dy = ABS(y2-y1)
-
- L01: mov bx,ARGy2
- sub bx,ARGy1 ; BX := y2 - y1
- jnz L02
-
- jmp HorizLine04 ; jump if horizontal line
-
- L02: jns L03
-
- neg bx ; BX := y1 - y2
- neg si ; negate increments for buffer interl
- neg di
- xchg si,di ; exchange increments
-
- ; select appropriate routine for slope of line
-
- L03: mov VARleafincr,di ; save increment for buffer interleav
-
- mov VARroutine,offset LoSlopeLine04
- cmp bx,cx
- jle L04 ; jump if dy <= dx (slope <= 1)
- mov VARroutine,offset HiSlopeLine04
- xchg bx,cx ; exchange dy and dx
-
- ; calculate initial decision variable and increments
-
- L04: shl bx,1 ; BX := 2 * dy
- mov VARincr1,bx ; incr1 := 2 * dy
- sub bx,cx
- mov di,bx ; DI := d = 2 * dy - dx
- sub bx,cx
- mov VARincr2,bx ; incr2 := 2 * (dy - dx)
-
- ; calculate first pixel address
-
- push cx ; preserve this register
- mov ax,ARGy1 ; AX := y
- mov bx,ARGx1 ; BX := x
- call PixelAddr04 ; AH := bit mask
- ; ES:BX -> buffer
- ; CL := # bits to shift left
-
- mov al,ARGn ; AL := unshifted pixel value
- shl ax,cl ; AH := bit mask in proper position
- ; AL := pixel value in proper positio
-
- mov dx,ax ; DH := bit mask
- ; DL := pixel value
- not dh ; DH := inverse bit mask
-
- pop cx ; restore this register
- inc cx ; CX := # of pixels to draw
-
- test bx,2000h ; set zero flag if BX in 1st interlea
- jz L05
-
- xchg si,VARleafincr ; exchange increment values if 1st pi
- ; lies in 1st interleave
-
- L05: jmp VARroutine ; jump to appropriate routine for slo
-
-
- ; routine for vertical lines
-
- VertLine04: mov ax,ARGy1 ; AX := y1
- mov bx,ARGy2 ; BX := y2
- mov cx,bx
- sub cx,ax ; CX := dy
- jge L31 ; jump if dy >= 0
-
- neg cx ; force dy >= 0
- mov ax,bx ; AX := y2
-
- L31: inc cx ; CX := # of pixels to draw
- mov bx,ARGx1 ; BX := x
- push cx ; preserve this register
- call PixelAddr04 ; AH := bit mask
- ; ES:BX -> video buffer
- ; CL := # bits to shift left
- mov al,ARGn ; AL := pixel value
- shl ax,cl ; AH := bit mask in proper position
- ; AL := pixel value in proper positio
- not ah ; AH := inverse bit mask
- pop cx ; restore this register
-
- test bx,si ; set zero flag if BX in 1st interlea
- jz L32
-
- xchg si,di ; exchange increment values if 1st pi
- ; lies in 1st interleave
-
- L32: and es:[bx],ah ; zero pixel in buffer
- or es:[bx],al ; set pixel value in buffer
-
- add bx,si ; increment to next portion of interl
- xchg si,di ; toggle between increment values
-
- loop L32
-
- jmp Lexit
-
-
-
- ; routine for horizontal lines (slope = 0)
-
- HorizLine04: mov ax,ARGy1
- mov bx,ARGx1
- call PixelAddr04 ; AH := bit mask
- ; ES:BX -> video buffer
- ; CL := # bits to shift left
- mov di,bx ; ES:DI -> buffer
-
- mov dh,ah
- not dh ; DH := unshifted bit mask for leftmo
- ; byte
- mov dl,0FFh ; DL := unshifted bit mask for
- ; rightmost byte
-
- shl dh,cl ; DH := reverse bit mask for first by
- not dh ; DH := bit mask for first byte
-
- mov cx,ARGx2
- and cl,3
- xor cl,3
- shl cl,1 ; CL := number of bits to shift left
- shl dl,cl ; DL := bit mask for last byte
-
- ; determine byte offset of first and last pixel in the line
-
- mov ax,ARGx2 ; AX := x2
- mov bx,ARGx1 ; BX := x1
-
- mov cl,ByteOffsetShift ; number of bits to shift to
- ; convert pixels to bytes
-
- shr ax,cl ; AX := byte offset of x2
- shr bx,cl ; BX := byte offset of x1
- mov cx,ax
- sub cx,bx ; CX := (# bytes in line) - 1
-
- ; propagate pixel value throughout one byte
-
- mov bx,offset DGROUP:PropagatedPixel
- mov al,ARGn ; AL := pixel value
- xlat ; AL := propagated pixel value
-
- ; set pixels in leftmost byte of the line
-
- or dh,dh
- js L43 ; jump if byte-aligned (x1 is leftmos
- ; pixel in byte)
- or cx,cx
- jnz L42 ; jump if more than one byte in the l
-
- and dl,dh ; bit mask for the line
- jmp short L44
-
- L42: mov ah,al
- and ah,dh ; AH := masked pixel bits
- not dh ; DH := reverse bit mask for 1st byte
- and es:[di],dh ; zero masked pixels in buffer
- or es:[di],ah ; update masked pixels in buffer
- inc di
- dec cx
-
- ; use a fast 8086 machine instruction to draw the remainder of the line
-
- L43: rep stosb ; update all pixels in the line
-
- ; set pixels in the rightmost byte of the line
-
- L44: and al,dl ; AL := masked pixels for last byte
- not dl
- and es:[di],dl ; zero masked pixels in buffer
- or es:[di],al ; update masked pixels in buffer
-
- jmp Lexit
-
-
- ; routine for dy <= dx (slope <= 1) ; ES:BX -> video buffer
- ; CX = # pixels to draw
- ; DH = inverse bit mask
- ; DL = pixel value in proper position
- ; SI = buffer interleave increment
- ; DI = decision variable
- LoSlopeLine04:
-
- L10: mov ah,es:[bx] ; AH := byte from video buffer
-
- L11: and ah,dh ; zero pixel value at current bit off
- or ah,dl ; set pixel value in byte
-
- ror dl,1 ; rotate pixel value
- ror dl,1
- ror dh,1 ; rotate bit mask
- ror dh,1
- jnc L14 ; jump if bit mask rotated to
- ; leftmost pixel position
-
- ; bit mask not shifted out
-
- or di,di ; test sign of d
- jns L12 ; jump if d >= 0
-
- add di,VARincr1 ; d := d + incr1
- loop L11
-
- mov es:[bx],ah ; store remaining pixels in buffer
- jmp short Lexit
-
- L12: add di,VARincr2 ; d := d + incr2
- mov es:[bx],ah ; update buffer
-
- add bx,si ; increment y
- xchg si,VARleafincr ; exchange interleave increment value
-
- loop L10
- jmp short Lexit
-
- ; bit mask shifted out
-
- L14: mov es:[bx],ah ; update buffer
- inc bx ; BX := offset of next byte
-
- or di,di ; test sign of d
- jns L15 ; jump if non-negative
-
- add di,VARincr1 ; d := d + incr1
- loop L10
- jmp short Lexit
-
-
- L15: add di,VARincr2 ; d := d + incr2
-
- add bx,si ; increment y
- xchg si,VARleafincr
-
- loop L10
- jmp short Lexit
-
-
- ; routine for dy > dx (slope > 1) ; ES:BX -> video buffer
- ; CX = # pixels to draw
- ; DH = inverse bit mask
- ; DL = pixel value in proper position
- ; SI = buffer interleave increment
- ; DI = decision variable
- HiSlopeLine04:
-
- L21: and es:[bx],dh ; zero pixel value in video buffer
- or es:[bx],dl ; set pixel value in byte
-
- add bx,si ; increment y
- xchg si,VARleafincr ; exchange interleave increment value
-
- L22: or di,di ; test sign of d
- jns L23 ; jump if d >= 0
-
- add di,VARincr1 ; d := d + incr1
- loop L21
-
- jmp short Lexit
-
-
- L23: add di,VARincr2 ; d := d + incr2
-
- ror dl,1 ; rotate pixel value
- ror dl,1
- ror dh,1 ; rotate bit mask
- ror dh,1
- cmc ; cf set if bit mask not rotated to
- ; leftmost pixel position
-
- adc bx,0 ; BX := offset of next byte
-
- loop L21
-
-
- Lexit: pop di ; restore registers and return
- pop si
- mov sp,bp
- pop bp
- ret
-
- _Line04 ENDP
-
- _TEXT ENDS
-
-
- _DATA SEGMENT word public 'DATA'
-
- PropagatedPixel DB 00000000b ; 0
- DB 01010101b ; 1
- DB 10101010b ; 2
- DB 11111111b ; 3
-
- _DATA ENDS
-
- END
-
- \SAMPCODE\VIDEO\6\6_6.ASM
-
- TITLE 'Listing 6-6'
- NAME LineHGC
- PAGE 55,132
-
- ;
- ; Name: LineHGC
- ;
- ; Function: Draw a line in HGC or HGC+ 720x348 graphics
- ;
- ; Caller: Microsoft C:
- ;
- ; void LineHGC(x1,y1,x2,y2,n);
- ;
- ; int x1,y1,x2,y2; /* pixel coordinates */
- ;
- ; int n; /* pixel value */
- ;
-
- ARGx1 EQU word ptr [bp+4] ; stack frame addressing
- ARGy1 EQU word ptr [bp+6]
- ARGx2 EQU word ptr [bp+8]
- ARGy2 EQU word ptr [bp+10]
- ARGn EQU byte ptr [bp+12]
- VARleafincr EQU word ptr [bp-2]
- VARincr1 EQU word ptr [bp-4]
- VARincr2 EQU word ptr [bp-6]
- VARroutine EQU word ptr [bp-8]
-
- ByteOffsetShift EQU 3 ; used to convert pixels to byte offs
-
- DGROUP GROUP _DATA
-
- _TEXT SEGMENT byte public 'CODE'
- ASSUME cs:_TEXT,ds:DGROUP
-
- EXTRN PixelAddrHGC:near
-
- PUBLIC _LineHGC
- _LineHGC PROC near
-
- push bp ; preserve caller registers
- mov bp,sp
- sub sp,8 ; stack space for local variables
- push si
- push di
-
- mov si,2000h ; increment for video buffer interlea
- mov di,90-8000h ; increment from last to first interl
-
- mov cx,ARGx2
- sub cx,ARGx1 ; CX := x2 - x1
- jz VertLineHGC ; jump if vertical line
-
- ; force x1 < x2
-
- jns L01 ; jump if x2 > x1
-
- neg cx ; CX := x1 - x2
-
- mov bx,ARGx2 ; exchange x1 and x2
- xchg bx,ARGx1
- mov ARGx2,bx
-
- mov bx,ARGy2 ; exchange y1 and y2
- xchg bx,ARGy1
- mov ARGy2,bx
-
- ; calculate dy = ABS(y2-y1)
-
- L01: mov bx,ARGy2
- sub bx,ARGy1 ; BX := y2 - y1
- jnz L02
-
- jmp HorizLineHGC ; jump if horizontal line
-
- L02: jns L03
-
- neg bx ; BX := y1 - y2
- neg si ; negate increments for buffer interl
- neg di
-
- ; select appropriate routine for slope of line
-
- L03: mov VARleafincr,di ; save increment for buffer interleav
-
- mov VARroutine,offset LoSlopeLineHGC
- cmp bx,cx
- jle L04 ; jump if dy <= dx (slope <= 1)
- mov VARroutine,offset HiSlopeLineHGC
- xchg bx,cx ; exchange dy and dx
-
- ; calculate initial decision variable and increments
-
- L04: shl bx,1 ; BX := 2 * dy
- mov VARincr1,bx ; incr1 := 2 * dy
- sub bx,cx
- mov di,bx ; DI := d = 2 * dy - dx
- sub bx,cx
- mov VARincr2,bx ; incr2 := 2 * (dy - dx)
-
- ; calculate first pixel address
-
- push cx ; preserve this register
- mov ax,ARGy1 ; AX := y
- mov bx,ARGx1 ; BX := x
- call PixelAddrHGC ; AH := bit mask
- ; ES:BX -> buffer
- ; CL := # bits to shift left
-
- mov al,ARGn ; AL := unshifted pixel value
- shl ax,cl ; AH := bit mask in proper position
- ; AL := pixel value in proper positio
-
- mov dx,ax ; DH := bit mask
- ; DL := pixel value
- not dh ; DH := inverse bit mask
-
- pop cx ; restore this register
- inc cx ; CX := # of pixels to draw
-
- jmp VARroutine ; jump to appropriate routine for slo
-
-
- ; routine for vertical lines
-
- VertLineHGC: mov ax,ARGy1 ; AX := y1
- mov bx,ARGy2 ; BX := y2
- mov cx,bx
- sub cx,ax ; CX := dy
- jge L31 ; jump if dy >= 0
-
- neg cx ; force dy >= 0
- mov ax,bx ; AX := y2
-
- L31: inc cx ; CX := # of pixels to draw
- mov bx,ARGx1 ; BX := x
- push cx ; preserve this register
- call PixelAddrHGC ; AH := bit mask
- ; ES:BX -> video buffer
- ; CL := # bits to shift left
- mov al,ARGn ; AL := pixel value
- shl ax,cl ; AH := bit mask in proper position
- ; AL := pixel value in proper positio
- not ah ; AH := inverse bit mask
- pop cx ; restore this register
-
- ; draw the line
- test al,al
- jz L34 ; jump if pixel value is zero
-
- L32: or es:[bx],al ; set pixel values in buffer
-
- add bx,si ; increment to next portion of interl
- jns L33
- add bx,di ; increment to first portion of inter
- L33: loop L32
- jmp short L36
-
- L34: and es:[bx],ah ; reset pixel values in buffer
-
- add bx,si ; increment to next portion of interl
- jns L35
- add bx,di ; increment to first portion of inter
- L35: loop L34
-
- L36: jmp Lexit
-
-
- ; routine for horizontal lines (slope = 0)
-
- HorizLineHGC: mov ax,ARGy1
- mov bx,ARGx1
- call PixelAddrHGC ; AH := bit mask
- ; ES:BX -> video buffer
- ; CL := # bits to shift left
- mov di,bx ; ES:DI -> buffer
-
- mov dh,ah
- not dh ; DH := unshifted bit mask for leftmo
- ; byte
- mov dl,0FFh ; DL := unshifted bit mask for
- ; rightmost byte
-
- shl dh,cl ; DH := reverse bit mask for first by
- not dh ; DH := bit mask for first byte
-
- mov cx,ARGx2
- and cl,7
- xor cl,7 ; CL := number of bits to shift left
- shl dl,cl ; DL := bit mask for last byte
-
- ; determine byte offset of first and last pixel in the line
-
- mov ax,ARGx2 ; AX := x2
- mov bx,ARGx1 ; BX := x1
-
- mov cl,ByteOffsetShift ; number of bits to shift to
- ; convert pixels to bytes
-
- shr ax,cl ; AX := byte offset of x2
- shr bx,cl ; BX := byte offset of x1
- mov cx,ax
- sub cx,bx ; CX := (# bytes in line) - 1
-
- ; propagate pixel value throughout one byte
-
- mov bx,offset DGROUP:PropagatedPixel
- mov al,ARGn ; AL := pixel value
- xlat ; AL := propagated pixel value
-
- ; set pixels in leftmost byte of the line
-
- or dh,dh
- js L43 ; jump if byte-aligned (x1 is leftmos
- ; pixel in byte)
- or cx,cx
- jnz L42 ; jump if more than one byte in the l
-
- and dl,dh ; bit mask for the line
- jmp short L44
-
- L42: mov ah,al
- and ah,dh ; AH := masked pixel bits
- not dh ; DH := reverse bit mask for 1st byte
- and es:[di],dh ; zero masked pixels in buffer
- or es:[di],ah ; update masked pixels in buffer
- inc di
- dec cx
-
- ; use a fast 8086 machine instruction to draw the remainder of the line
-
- L43: rep stosb ; update all pixels in the line
-
- ; set pixels in the rightmost byte of the line
-
- L44: and al,dl ; AL := masked pixels for last byte
- not dl
- and es:[di],dl ; zero masked pixels in buffer
- or es:[di],al ; update masked pixels in buffer
-
- jmp Lexit
-
-
- ; routine for dy <= dx (slope <= 1) ; ES:BX -> video buffer
- ; CX = #pixels to draw
- ; DH = inverse bit mask
- ; DL = pixel value in proper position
- ; SI = buffer interleave increment
- ; DI = decision variable
- LoSlopeLineHGC:
-
- L10: mov ah,es:[bx] ; AH := byte from video buffer
-
- L11: and ah,dh ; zero pixel value at current bit off
- or ah,dl ; set pixel value in byte
-
- ror dl,1 ; rotate pixel value
- ror dh,1 ; rotate bit mask
- jnc L14 ; jump if bit mask rotated to
- ; leftmost pixel position
-
- ; bit mask not shifted out
-
- or di,di ; test sign of d
- jns L12 ; jump if d >= 0
-
- add di,VARincr1 ; d := d + incr1
- loop L11
-
- mov es:[bx],ah ; store remaining pixels in buffer
- jmp short Lexit
-
- L12: add di,VARincr2 ; d := d + incr2
- mov es:[bx],ah ; update buffer
-
- add bx,si ; increment y
- jns L13 ; jump if not in last interleave
-
- add bx,VARleafincr ; increment into next interleave
-
- L13: loop L10
- jmp short Lexit
-
- ; bit mask shifted out
-
- L14: mov es:[bx],ah ; update buffer
- inc bx ; BX := offset of next byte
-
- or di,di ; test sign of d
- jns L15 ; jump if non-negative
-
- add di,VARincr1 ; d := d + incr1
- loop L10
- jmp short Lexit
-
- L15: add di,VARincr2 ; d := d + incr2
-
- add bx,si ; increment y
- jns L16 ; jump if not in last interleave
-
- add bx,VARleafincr ; increment into next interleave
-
- L16: loop L10 ; loop until all pixels are set
- jmp short Lexit
-
-
- ; routine for dy > dx (slope > 1) ; ES:BX -> video buffer
- ; CX = #pixels to draw
- ; DH = inverse bit mask
- ; DL = pixel value in proper position
- ; SI = buffer interleave increment
- ; DI = decision variable
- HiSlopeLineHGC:
-
- L21: and es:[bx],dh ; zero pixel value in video buffer
- or es:[bx],dl ; set pixel value in byte
-
- add bx,si ; increment y
- jns L22 ; jump if not in last interleave
-
- add bx,VARleafincr ; increment into next interleave
-
- L22: or di,di
- jns L23 ; jump if d >= 0
-
- add di,VARincr1 ; d := d + incr1
- loop L21
- jmp short Lexit
-
-
- L23: add di,VARincr2 ; d := d + incr2
-
- ror dl,1 ; rotate pixel value
- ror dh,1 ; rotate bit mask
- cmc ; cf set if bit mask not rotated to
- ; leftmost pixel position
- adc bx,0 ; BX := offset of next byte
-
- loop L21
-
-
- Lexit: pop di
- pop si
- mov sp,bp
- pop bp
- ret
-
- _LineHGC ENDP
-
- _TEXT ENDS
-
- _DATA SEGMENT word public 'DATA'
-
- PropagatedPixel DB 00000000b ; 0
- DB 11111111b ; 1
-
- _DATA ENDS
-
- END
-
- \SAMPCODE\VIDEO\6\6_7.ASM
-
- TITLE 'Listing 6-7'
- NAME Line10
- PAGE 55,132
-
- ;
- ; Name: Line10
- ;
- ; Function: Draw a line in the following EGA and VGA graphics modes:
- ; 200-line 16-color modes
- ; 350-line modes
- ; 640x480 16-color
- ;
- ; Caller: Microsoft C:
- ;
- ; void Line10(x1,y1,x2,y2,n);
- ;
- ; int x1,y1,x2,y2; /* pixel coordinates */
- ;
- ; int n; /* pixel value */
- ;
-
- ARGx1 EQU word ptr [bp+4] ; stack frame addressing
- ARGy1 EQU word ptr [bp+6]
- ARGx2 EQU word ptr [bp+8]
- ARGy2 EQU word ptr [bp+10]
- ARGn EQU byte ptr [bp+12]
- VARvertincr EQU word ptr [bp-2]
- VARincr1 EQU word ptr [bp-4]
- VARincr2 EQU word ptr [bp-6]
- VARroutine EQU word ptr [bp-8]
-
- ByteOffsetShift EQU 3 ; used to convert pixels to byte offs
- BytesPerLine EQU 80
- RMWbits EQU 0 ; value for Data Rotate/Func Select r
-
-
- _TEXT SEGMENT byte public 'CODE'
- ASSUME cs:_TEXT
-
- EXTRN PixelAddr10:near
-
- PUBLIC _Line10
- _Line10 PROC near
-
- push bp ; preserve caller registers
- mov bp,sp
- sub sp,8 ; stack space for local variables
- push si
- push di
-
- ; configure the Graphics Controller
-
- mov dx,3CEh ; DX := Graphics Controller port addr
-
- mov ah,ARGn ; AH := pixel value
- xor al,al ; AL := Set/Reset Register number
- out dx,ax
-
- mov ax,0F01h ; AH := 1111b (bit plane mask for
- ; Enable Set/Reset
- out dx,ax ; AL := Enable Set/Reset Register #
-
- mov ah,RMWbits ; bits 3 and 4 of AH := function
- mov al,3 ; AL := Data Rotate/Func Select reg #
- out dx,ax
-
- ; check for vertical line
-
- mov si,BytesPerLine ; increment for video buffer
-
- mov cx,ARGx2
- sub cx,ARGx1 ; CX := x2 - x1
- jz VertLine10 ; jump if vertical line
-
- ; force x1 < x2
-
- jns L01 ; jump if x2 > x1
-
- neg cx ; CX := x1 - x2
-
- mov bx,ARGx2 ; exchange x1 and x2
- xchg bx,ARGx1
- mov ARGx2,bx
-
- mov bx,ARGy2 ; exchange y1 and y2
- xchg bx,ARGy1
- mov ARGy2,bx
-
- ; calculate dy = ABS(y2-y1)
-
- L01: mov bx,ARGy2
- sub bx,ARGy1 ; BX := y2 - y1
- jz HorizLine10 ; jump if horizontal line
-
- jns L03 ; jump if slope is positive
-
- neg bx ; BX := y1 - y2
- neg si ; negate increment for buffer interle
-
- ; select appropriate routine for slope of line
-
- L03: mov VARvertincr,si ; save vertical increment
-
- mov VARroutine,offset LoSlopeLine10
- cmp bx,cx
- jle L04 ; jump if dy <= dx (slope <= 1)
- mov VARroutine,offset HiSlopeLine10
- xchg bx,cx ; exchange dy and dx
-
- ; calculate initial decision variable and increments
-
- L04: shl bx,1 ; BX := 2 * dy
- mov VARincr1,bx ; incr1 := 2 * dy
- sub bx,cx
- mov si,bx ; SI := d = 2 * dy - dx
- sub bx,cx
- mov VARincr2,bx ; incr2 := 2 * (dy - dx)
-
- ; calculate first pixel address
-
- push cx ; preserve this register
- mov ax,ARGy1 ; AX := y
- mov bx,ARGx1 ; BX := x
- call PixelAddr10 ; AH := bit mask
- ; ES:BX -> buffer
- ; CL := # bits to shift left
-
- mov di,bx ; ES:DI -> buffer
- shl ah,cl ; AH := bit mask in proper position
- mov bl,ah ; AH,BL := bit mask
- mov al,8 ; AL := Bit Mask Register number
-
- pop cx ; restore this register
- inc cx ; CX := # of pixels to draw
-
- jmp VARroutine ; jump to appropriate routine for slo
-
-
- ; routine for vertical lines
-
- VertLine10: mov ax,ARGy1 ; AX := y1
- mov bx,ARGy2 ; BX := y2
- mov cx,bx
- sub cx,ax ; CX := dy
- jge L31 ; jump if dy >= 0
-
- neg cx ; force dy >= 0
- mov ax,bx ; AX := y2
-
- L31: inc cx ; CX := # of pixels to draw
- mov bx,ARGx1 ; BX := x
- push cx ; preserve this register
- call PixelAddr10 ; AH := bit mask
- ; ES:BX -> video buffer
- ; CL := # bits to shift left
- ; set up Graphics Controller
-
- shl ah,cl ; AH := bit mask in proper position
- mov al,8 ; AL := Bit Mask reg number
- out dx,ax
-
- pop cx ; restore this register
-
- ; draw the line
-
- L32: or es:[bx],al ; set pixel
- add bx,si ; increment to next line
- loop L32
-
- jmp Lexit
-
-
-
- ; routine for horizontal lines (slope = 0)
-
- HorizLine10:
- push ds ; preserve DS
-
- mov ax,ARGy1
- mov bx,ARGx1
- call PixelAddr10 ; AH := bit mask
- ; ES:BX -> video buffer
- ; CL := # bits to shift left
- mov di,bx ; ES:DI -> buffer
-
- mov dh,ah ; DH := unshifted bit mask for leftmo
- ; byte
- not dh
- shl dh,cl ; DH := reverse bit mask for first by
- not dh ; DH := bit mask for first byte
-
- mov cx,ARGx2
- and cl,7
- xor cl,7 ; CL := number of bits to shift left
- mov dl,0FFh ; DL := unshifted bit mask for
- ; rightmost byte
- shl dl,cl ; DL := bit mask for last byte
-
- ; determine byte offset of first and last pixel in the line
-
- mov ax,ARGx2 ; AX := x2
- mov bx,ARGx1 ; BX := x1
-
- mov cl,ByteOffsetShift ; number of bits to shift to
- ; convert pixels to bytes
-
- shr ax,cl ; AX := byte offset of x2
- shr bx,cl ; BX := byte offset of x1
- mov cx,ax
- sub cx,bx ; CX := (# bytes in line) - 1
-
- ; get Graphics Controller port address into DX
-
- mov bx,dx ; BH := bit mask for first byte
- ; BL := bit mask for last byte
- mov dx,3CEh ; DX := Graphics Controller port
- mov al,8 ; AL := Bit Mask Register number
-
- ; make video buffer addressible through DS:SI
-
- push es
- pop ds
- mov si,di ; DS:SI -> video buffer
-
- ; set pixels in leftmost byte of the line
-
- or bh,bh
- js L43 ; jump if byte-aligned (x1 is leftmos
- ; pixel in byte)
- or cx,cx
- jnz L42 ; jump if more than one byte in the l
-
- and bl,bh ; BL := bit mask for the line
- jmp short L44
-
- L42: mov ah,bh ; AH := bit mask for 1st byte
- out dx,ax ; update Graphics Controller
-
- movsb ; update bit planes
- dec cx
-
- ; use a fast 8086 machine instruction to draw the remainder of the line
-
- L43: mov ah,11111111b ; AH := bit mask
- out dx,ax ; update Bit Mask Register
-
- rep movsb ; update all pixels in the line
-
- ; set pixels in the rightmost byte of the line
-
- L44: mov ah,bl ; AH := bit mask for last byte
- out dx,ax ; update Graphics Controller
-
- movsb ; update bit planes
-
- pop ds ; restore DS
- jmp short Lexit
-
-
- ; routine for dy <= dx (slope <= 1) ; ES:DI -> video buffer
- ; AL = Bit Mask Register number
- ; BL = bit mask for 1st pixel
- ; CX = #pixels to draw
- ; DX = Graphics Controller port addr
- ; SI = decision variable
- LoSlopeLine10:
-
- L10: mov ah,bl ; AH := bit mask for next pixel
-
- L11: or ah,bl ; mask current pixel position
- ror bl,1 ; rotate pixel value
- jc L14 ; jump if bit mask rotated to
- ; leftmost pixel position
-
- ; bit mask not shifted out
-
- or si,si ; test sign of d
- jns L12 ; jump if d >= 0
-
- add si,VARincr1 ; d := d + incr1
- loop L11
-
- out dx,ax ; update Bit Mask Register
- or es:[di],al ; set remaining pixel(s)
- jmp short Lexit
-
- L12: add si,VARincr2 ; d := d + incr2
- out dx,ax ; update Bit Mask Register
-
- or es:[di],al ; update bit planes
-
- add di,VARvertincr ; increment y
- loop L10
- jmp short Lexit
-
- ; bit mask shifted out
-
- L14: out dx,ax ; update Bit Mask Register ...
-
- or es:[di],al ; update bit planes
- inc di ; increment x
-
- or si,si ; test sign of d
- jns L15 ; jump if non-negative
-
- add si,VARincr1 ; d := d + incr1
- loop L10
- jmp short Lexit
-
- L15: add si,VARincr2 ; d := d + incr2
- add di,VARvertincr ; vertical increment
- loop L10
- jmp short Lexit
-
-
- ; routine for dy > dx (slope > 1) ; ES:DI -> video buffer
- ; AH = bit mask for 1st pixel
- ; AL = Bit Mask Register number
- ; CX = #pixels to draw
- ; DX = Graphics Controller port addr
- ; SI = decision variable
- HiSlopeLine10:
- mov bx,VARvertincr ; BX := y-increment
-
- L21: out dx,ax ; update Bit Mask Register
- or es:[di],al ; update bit planes
-
- add di,bx ; increment y
-
- L22: or si,si ; test sign of d
- jns L23 ; jump if d >= 0
-
- add si,VARincr1 ; d := d + incr1
- loop L21
- jmp short Lexit
-
-
- L23: add si,VARincr2 ; d := d + incr2
-
- ror ah,1 ; rotate bit mask
- adc di,0 ; increment DI if when mask rotated t
- ; leftmost pixel position
-
- loop L21
-
-
- ; restore default Graphics Controller state and return to caller
-
- Lexit: xor ax,ax ; AH := 0, AL := 0
- out dx,ax ; restore Set/Reset Register
-
- inc ax ; AH := 0, AL := 1
- out dx,ax ; restore Enable Set/Reset Register
-
- mov al,3 ; AH := 0, AL := 3
- out dx,ax ; AL := Data Rotate/Func Select reg #
-
- mov ax,0FF08h ; AH := 1111111b, AL := 8
- out dx,ax ; restore Bit Mask Register
-
- pop di ; restore registers and return
- pop si
- mov sp,bp
- pop bp
- ret
-
- _Line10 ENDP
-
- _TEXT ENDS
-
- END
-
- \SAMPCODE\VIDEO\6\6_8.ASM
-
- TITLE 'Listing 6-8'
- NAME Line11
- PAGE 55,132
-
- ;
- ; Name: Line11
- ;
- ; Function: Draw a line in 640x480 2-color mode (MCGA, VGA)
- ;
- ; Caller: Microsoft C:
- ;
- ; void Line11(x1,y1,x2,y2,n);
- ;
- ; int x1,y1,x2,y2; /* pixel coordinates */
- ;
- ; int n; /* pixel value */
- ;
-
- ARGx1 EQU word ptr [bp+4] ; stack frame addressing
- ARGy1 EQU word ptr [bp+6]
- ARGx2 EQU word ptr [bp+8]
- ARGy2 EQU word ptr [bp+10]
- ARGn EQU byte ptr [bp+12]
- VARincr1 EQU word ptr [bp-2]
- VARincr2 EQU word ptr [bp-4]
- VARroutine EQU word ptr [bp-6]
-
- BytesPerLine EQU 80 ; bytes in one row of pixels
- ByteOffsetShift EQU 3 ; used to convert pixels to byte offs
-
- DGROUP GROUP _DATA
-
- _TEXT SEGMENT byte public 'CODE'
- ASSUME cs:_TEXT,ds:DGROUP
-
- EXTRN PixelAddr10:near
-
- PUBLIC _Line11
- _Line11 PROC near
-
- push bp ; preserve caller registers
- mov bp,sp
- sub sp,6 ; stack space for local variables
- push si
- push di
-
- ; check for vertical line
-
- mov si,BytesPerLine ; SI := initial y-increment
-
- mov cx,ARGx2
- sub cx,ARGx1 ; CX := x2 - x1
- jz VertLine11 ; jump if vertical line
-
- ; force x1 < x2
-
- jns L01 ; jump if x2 > x1
-
- neg cx ; CX := x1 - x2
-
- mov bx,ARGx2 ; exchange x1 and x2
- xchg bx,ARGx1
- mov ARGx2,bx
-
- mov bx,ARGy2 ; exchange y1 and y2
- xchg bx,ARGy1
- mov ARGy2,bx
-
- ; calculate dy = ABS(y2-y1)
-
- L01: mov bx,ARGy2
- sub bx,ARGy1 ; BX := y2 - y1
- jnz L02
-
- jmp HorizLine11 ; jump if horizontal line
-
- L02: jns L03
-
- neg bx ; BX := y1 - y2
- neg si ; negate y-increment
-
- ; select appropriate routine for slope of line
-
- L03: mov VARroutine,offset LoSlopeLine11
- cmp bx,cx
- jle L04 ; jump if dy <= dx (slope <= 1)
- mov VARroutine,offset HiSlopeLine11
- xchg bx,cx ; exchange dy and dx
-
- ; calculate initial decision variable and increments
-
- L04: shl bx,1 ; BX := 2 * dy
- mov VARincr1,bx ; incr1 := 2 * dy
- sub bx,cx
- mov di,bx ; DI := d = 2 * dy - dx
- sub bx,cx
- mov VARincr2,bx ; incr2 := 2 * (dy - dx)
-
- ; calculate first pixel address
-
- push cx ; preserve this register
- mov ax,ARGy1 ; AX := y
- mov bx,ARGx1 ; BX := x
- call PixelAddr10 ; AH := bit mask
- ; ES:BX -> buffer
- ; CL := # bits to shift left
-
- mov al,ARGn ; AL := unshifted pixel value
- shl ax,cl ; AH := bit mask in proper position
- ; AL := pixel value in proper positio
-
- mov dx,ax ; DH := bit mask
- ; DL := pixel value
- not dh ; DH := inverse bit mask
-
- pop cx ; restore this register
- inc cx ; CX := # of pixels to draw
-
- jmp VARroutine ; jump to appropriate routine for slo
-
-
- ; routine for vertical lines
-
- VertLine11: mov ax,ARGy1 ; AX := y1
- mov bx,ARGy2 ; BX := y2
- mov cx,bx
- sub cx,ax ; CX := dy
- jge L31 ; jump if dy >= 0
-
- neg cx ; force dy >= 0
- mov ax,bx ; AX := y2
-
- L31: inc cx ; CX := # of pixels to draw
- mov bx,ARGx1 ; BX := x
- push cx ; preserve this register
- call PixelAddr10 ; AH := bit mask
- ; ES:BX -> video buffer
- ; CL := # bits to shift left
- mov al,ARGn ; AL := pixel value
- shl ax,cl ; AH := bit mask in proper position
- ; AL := pixel value in proper positio
- not ah ; AH := inverse bit mask
- pop cx ; restore this register
-
- ; draw the line
-
- test al,al
- jz L33 ; jump if pixel value = 0
-
- L32: or es:[bx],al ; set pixel values in buffer
- add bx,si
- loop L32
- jmp short L34
-
- L33: and es:[bx],ah ; reset pixel values in buffer
- add bx,si
- loop L33
-
- L34: jmp Lexit
-
-
- ; routine for horizontal lines (slope = 0)
-
- HorizLine11: mov ax,ARGy1
- mov bx,ARGx1
- call PixelAddr10 ; AH := bit mask
- ; ES:BX -> video buffer
- ; CL := # bits to shift left
- mov di,bx ; ES:DI -> buffer
-
- mov dh,ah
- not dh ; DH := unshifted bit mask for leftmo
- ; byte
- mov dl,0FFh ; DL := unshifted bit mask for
- ; rightmost byte
-
- shl dh,cl ; DH := reverse bit mask for first by
- not dh ; DH := bit mask for first byte
-
- mov cx,ARGx2
- and cl,7
- xor cl,7 ; CL := number of bits to shift left
- shl dl,cl ; DL := bit mask for last byte
-
- ; determine byte offset of first and last pixel in the line
-
- mov ax,ARGx2 ; AX := x2
- mov bx,ARGx1 ; BX := x1
-
- mov cl,ByteOffsetShift ; number of bits to shift to
- ; convert pixels to bytes
-
- shr ax,cl ; AX := byte offset of x2
- shr bx,cl ; BX := byte offset of x1
- mov cx,ax
- sub cx,bx ; CX := (# bytes in line) - 1
-
- ; propagate pixel value throughout one byte
-
- mov bx,offset DGROUP:PropagatedPixel
- mov al,ARGn ; AL := pixel value
- xlat
-
- ; set pixels in leftmost byte of the line
-
- or dh,dh
- js L43 ; jump if byte-aligned (x1 is leftmos
- ; pixel in byte)
- or cx,cx
- jnz L42 ; jump if more than one byte in the l
-
- and dl,dh ; bit mask for the line
- jmp short L44
-
- L42: mov ah,al
- and ah,dh ; AH := masked pixel bits
- not dh ; DH := reverse bit mask for 1st byte
- and es:[di],dh ; zero masked pixels in buffer
- or es:[di],ah ; update masked pixels in buffer
- inc di
- dec cx
-
- ; use a fast 8086 machine instruction to draw the remainder of the line
-
- L43: rep stosb ; update all pixels in the line
-
- ; set pixels in the rightmost byte of the line
-
- L44: and al,dl ; AL := masked pixels for last byte
- not dl
- and es:[di],dl ; zero masked pixels in buffer
- or es:[di],al ; update masked pixels in buffer
-
- jmp Lexit
-
-
- ; routine for dy <= dx (slope <= 1) ; ES:BX -> video buffer
- ; CX = #pixels to draw
- ; DH = inverse bit mask
- ; DL = pixel value in proper position
- ; SI = bytes per pixel row
- ; DI = decision variable
- LoSlopeLine11:
-
- L10: mov ah,es:[bx] ; AH := byte from video buffer
-
- L11: and ah,dh ; zero pixel value at current bit off
- or ah,dl ; set pixel value in byte
-
- ror dl,1 ; rotate pixel value
- ror dh,1 ; rotate bit mask
- jnc L14 ; jump if bit mask rotated to
- ; leftmost pixel position
-
- ; bit mask not shifted out
-
- or di,di ; test sign of d
- jns L12 ; jump if d >= 0
-
- add di,VARincr1 ; d := d + incr1
- loop L11
-
- mov es:[bx],ah ; store remaining pixels in buffer
- jmp short Lexit
-
- L12: add di,VARincr2 ; d := d + incr2
- mov es:[bx],ah ; update buffer
-
- add bx,si ; increment y
- loop L10
- jmp short Lexit
-
- ; bit mask shifted out
-
- L14: mov es:[bx],ah ; update buffer
- inc bx ; BX := offset of next byte
-
- or di,di ; test sign of d
- jns L15 ; jump if non-negative
-
- add di,VARincr1 ; d := d + incr1
- loop L10
- jmp short Lexit
-
- L15: add di,VARincr2 ; d := d + incr2
-
- add bx,si ; increment y
- loop L10
- jmp short Lexit
-
-
- ; routine for dy > dx (slope > 1) ; ES:BX -> video buffer
- ; CX = #pixels to draw
- ; DH = inverse bit mask
- ; DL = pixel value in proper position
- ; SI = bytes per pixel row
- ; DI = decision variable
- HiSlopeLine11:
-
- L21: and es:[bx],dh ; zero pixel value in video buffer
- or es:[bx],dl ; set pixel value in byte
-
- add bx,si ; increment y
-
- L22: or di,di ; test sign of d
- jns L23 ; jump if d >= 0
-
- add di,VARincr1 ; d := d + incr1
- loop L21
-
- jmp short Lexit
-
-
- L23: add di,VARincr2 ; d := d + incr2
-
- ror dl,1 ; rotate pixel value
- ror dh,1 ; rotate bit mask
- cmc ; cf set if bit mask not rotated to
- ; leftmost pixel position
-
- adc bx,0 ; BX := offset of next byte
-
- loop L21
-
-
- Lexit: pop di
- pop si
- mov sp,bp
- pop bp
- ret
-
- _Line11 ENDP
-
- _TEXT ENDS
-
-
- _DATA SEGMENT word public 'DATA'
-
- PropagatedPixel DB 00000000b ; 0
- DB 11111111b ; 1
-
- _DATA ENDS
-
- END
-
- \SAMPCODE\VIDEO\6\6_9.ASM
-
- TITLE 'Listing 6-9'
- NAME Line13
- PAGE 55,132
-
- ;
- ; Name: Line13
- ;
- ; Function: Draw a line in MCGA/VGA 320x200 256-color mode
- ;
- ; Caller: Microsoft C:
- ;
- ; void Line13(x1,y1,x2,y2,n);
- ;
- ; int x1,y1,x2,y2; /* pixel coordinates */
- ;
- ; int n; /* pixel value */
- ;
-
- ARGx1 EQU word ptr [bp+4] ; stack frame addressing
- ARGy1 EQU word ptr [bp+6]
- ARGx2 EQU word ptr [bp+8]
- ARGy2 EQU word ptr [bp+10]
- ARGn EQU byte ptr [bp+12]
- VARincr1 EQU word ptr [bp-2]
- VARincr2 EQU word ptr [bp-4]
- VARroutine EQU word ptr [bp-6]
-
- BytesPerLine EQU 320
-
-
- _TEXT SEGMENT byte public 'CODE'
- ASSUME cs:_TEXT
-
- EXTRN PixelAddr13:near
-
- PUBLIC _Line13
- _Line13 PROC near
-
- push bp ; preserve caller registers
- mov bp,sp
- sub sp,6 ; stack space for local variables
- push si
- push di
-
- ; check for vertical line
-
- mov si,BytesPerLine ; initial y-increment
-
- mov cx,ARGx2
- sub cx,ARGx1 ; CX := x2 - x1
- jz VertLine13 ; jump if vertical line
-
- ; force x1 < x2
-
- jns L01 ; jump if x2 > x1
-
- neg cx ; CX := x1 - x2
-
- mov bx,ARGx2 ; exchange x1 and x2
- xchg bx,ARGx1
- mov ARGx2,bx
-
- mov bx,ARGy2 ; exchange y1 and y2
- xchg bx,ARGy1
- mov ARGy2,bx
-
- ; calculate dy = ABS(y2-y1)
-
- L01: mov bx,ARGy2
- sub bx,ARGy1 ; BX := y2 - y1
- jz HorizLine13 ; jump if horizontal line
-
- jns L03 ; jump if slope is positive
-
- neg bx ; BX := y1 - y2
- neg si ; negate y-increment
-
- ; select appropriate routine for slope of line
-
- L03: push si ; preserve y-increment
-
- mov VARroutine,offset LoSlopeLine13
- cmp bx,cx
- jle L04 ; jump if dy <= dx (slope <= 1)
- mov VARroutine,offset HiSlopeLine13
- xchg bx,cx ; exchange dy and dx
-
- ; calculate initial decision variable and increments
-
- L04: shl bx,1 ; BX := 2 * dy
- mov VARincr1,bx ; incr1 := 2 * dy
- sub bx,cx
- mov si,bx ; SI := d = 2 * dy - dx
- sub bx,cx
- mov VARincr2,bx ; incr2 := 2 * (dy - dx)
-
- ; calculate first pixel address
-
- push cx ; preserve this register
- mov ax,ARGy1 ; AX := y
- mov bx,ARGx1 ; BX := x
- call PixelAddr13 ; ES:BX -> buffer
-
- mov di,bx ; ES:DI -> buffer
-
- pop cx ; restore this register
- inc cx ; CX := # of pixels to draw
-
- pop bx ; BX := y-increment
- jmp VARroutine ; jump to appropriate routine for slo
-
-
- ; routine for vertical lines
-
- VertLine13: mov ax,ARGy1 ; AX := y1
- mov bx,ARGy2 ; BX := y2
- mov cx,bx
- sub cx,ax ; CX := dy
- jge L31 ; jump if dy >= 0
-
- neg cx ; force dy >= 0
- mov ax,bx ; AX := y2
-
- L31: inc cx ; CX := # of pixels to draw
- mov bx,ARGx1 ; BX := x
- push cx ; preserve this register
- call PixelAddr13 ; ES:BX -> video buffer
- pop cx
-
- mov di,bx ; ES:DI -> video buffer
- dec si ; SI := bytes/line - 1
-
- mov al,ARGn ; AL := pixel value
-
- L32: stosb ; set pixel value in buffer
- add di,si ; increment to next line
- loop L32
-
- jmp Lexit
-
-
-
- ; routine for horizontal lines (slope = 0)
-
- HorizLine13:
- push cx ; preserve CX
- mov ax,ARGy1
- mov bx,ARGx1
- call PixelAddr13 ; ES:BX -> video buffer
- mov di,bx ; ES:DI -> buffer
-
- pop cx
- inc cx ; CX := number of pixels to draw
-
- mov al,ARGn ; AL := pixel value
-
- rep stosb ; update the video buffer
-
- jmp short Lexit
-
-
- ; routine for dy <= dx (slope <= 1) ; ES:DI -> video buffer
- ; BX = y-increment
- ; CX = #pixels to draw
- ; SI = decision variable
- LoSlopeLine13:
-
- mov al,ARGn ; AL := pixel value
-
- L11: stosb ; store pixel, increment x
-
- or si,si ; test sign of d
- jns L12 ; jump if d >= 0
-
- add si,VARincr1 ; d := d + incr1
- loop L11
- jmp short Lexit
-
- L12: add si,VARincr2 ; d := d + incr2
- add di,bx ; increment y
- loop L11
- jmp short Lexit
-
-
- ; routine for dy > dx (slope > 1) ; ES:DI -> video buffer
- ; BX = y-increment
- ; CX = #pixels to draw
- ; SI = decision variable
- HiSlopeLine13:
- mov al,ARGn ; AL := pixel value
-
- L21: stosb ; update next pixel, increment x
-
- add di,bx ; increment y
-
- L22: or si,si ; test sign of d
- jns L23 ; jump if d >= 0
-
- add si,VARincr1 ; d := d + incr1
- dec di ; decrement x (already incremented
- ; by stosb)
- loop L21
- jmp short Lexit
-
-
- L23: add si,VARincr2 ; d := d + incr2
- loop L21
-
-
- Lexit: pop di ; restore registers and return
- pop si
- mov sp,bp
- pop bp
- ret
-
- _Line13 ENDP
-
- _TEXT ENDS
-
- END
-
- \SAMPCODE\VIDEO\7
- \SAMPCODE\VIDEO\7\7_1.C
-
- /* Listing 7-1 */
-
- Ellipse( xc, yc, a0, b0 ) /* using equation of ellipse */
- int xc,yc; /* center of ellipse */
- int a0,b0; /* major and minor axes */
- {
-
- double x = 0;
- double y = b0;
- double Bsquared = (double)b0 * (double)b0;
- double Asquared = (double)a0 * (double)a0;
- double sqrt();
-
-
- do /* do while dy/dx >= -1 */
- {
- y = sqrt( Bsquared - ((Bsquared/Asquared) * x*x) );
- Set4Pixels( (int)x, (int)y, xc, yc, PixelValue );
- ++x;
- }
- while ( (x <= a0) && (Bsquared*x < Asquared*y) );
-
-
- while (y >= 0) /* do while dy/dx < -1 */
- {
- x = sqrt( Asquared - ((Asquared/Bsquared) * y*y) );
- Set4Pixels( (int)x, (int)y, xc, yc, PixelValue );
- --y;
- }
- }
-
-
- Set4Pixels( x, y, xc, yc, n ) /* set pixels in 4 quadrants by symmetry */
- int x,y;
- int xc,yc;
- int n;
- {
- SPFunc(xc+x,yc+y,n);
- SPFunc(xc-x,yc+y,n);
- SPFunc(xc+x,yc-y,n);
- SPFunc(xc-x,yc-y,n);
- }
-
- \SAMPCODE\VIDEO\7\7_2.C
-
- /* Listing 7-2 */
-
- Ellipse( xc, yc, a0, b0 )
- int xc,yc; /* center of ellipse */
- int a0,b0; /* semiaxes */
- {
- int x = 0;
- int y = b0;
-
- long a = a0; /* use 32-bit precision */
- long b = b0;
-
- long Asquared = a * a; /* initialize values outside
- long TwoAsquared = 2 * Asquared; /* of loops */
- long Bsquared = b * b;
- long TwoBsquared = 2 * Bsquared;
-
- long d;
- long dx,dy;
-
-
- d = Bsquared - Asquared*b + Asquared/4L;
- dx = 0;
- dy = TwoAsquared * b;
-
- while (dx<dy)
- {
- Set4Pixels( x, y, xc, yc, PixelValue );
-
- if (d > 0L)
- {
- --y;
- dy -= TwoAsquared;
- d -= dy;
- }
-
- ++x;
- dx += TwoBsquared;
- d += Bsquared + dx;
- }
-
-
- d += (3L*(Asquared-Bsquared)/2L - (dx+dy)) / 2L;
-
- while (y>=0)
- {
- Set4Pixels( x, y, xc, yc, PixelValue );
-
- if (d < 0L)
- {
- ++x;
- dx += TwoBsquared;
- d += dx;
- }
-
- --y;
- dy -= TwoAsquared;
- d += Asquared - dy;
- }
- }
-
-
- Set4Pixels( x, y, xc, yc, n ) /* set pixels by symmetry in 4 quadrants
- int x,y;
- int xc,yc;
- int n;
- {
- SetPixel( xc+x, yc+y, n );
- SetPixel( xc-x, yc+y, n );
- SetPixel( xc+x, yc-y, n );
- SetPixel( xc-x, yc-y, n );
- }
-
- \SAMPCODE\VIDEO\7\7_3.C
-
- /* Listing 7-3 */
-
- Set4Pixels( x, y, xc, yc, n ) /* avoids setting the same pixel twice */
- int x,y;
- int xc,yc;
- int n;
- {
- if (x!=0)
- {
- SetPixel( xc+x, yc+y, n );
- SetPixel( xc-x, yc+y, n );
- if (y!=0)
- {
- SetPixel( xc+x, yc-y, n );
- SetPixel( xc-x, yc-y, n );
- }
- }
- else
- {
- SetPixel( xc, yc+y, n );
- if (y!=0)
- SetPixel( xc, yc-y, n );
- }
- }
-
- \SAMPCODE\VIDEO\7\7_5.C
-
- /* Listing 7-5 */
-
- Circle10( xc, yc, xr, yr, n) /* circles in 640x350 16-color mode *
- int xc,yc; /* center of circle */
- int xr,yr; /* point on circumference */
- int n; /* pixel value */
- {
- double x,y;
- double sqrt();
- double Scale10 = 1.37; /* pixel scaling factor */
- int a,b;
-
- x = xr - xc; /* translate center of ellipse */
- y = (yr - yc) * Scale10; /* to origin */
-
-
- a = sqrt( x*x + y*y ); /* compute major and minor axes */
- b = a / Scale10;
-
- Ellipse10( xc, yc, a, b, n); /* draw it */
- }
-
- \SAMPCODE\VIDEO\7\7_4.ASM
-
- TITLE 'Listing 7-4'
- NAME Ellipse10
- PAGE 55,132
-
- ;
- ; Name: Ellipse10
- ;
- ; Function: Draw an ellipse in native EGA/VGA graphics modes.
- ;
- ; Caller: Microsoft C:
- ;
- ; void Ellipse10(xc,yc,a,b,n);
- ;
- ; int xc,yc; /* center of ellipse */
- ;
- ; int a,b; /* major and minor axes */
- ;
- ; int n; /* pixel value */
- ;
-
- ARGxc EQU word ptr [bp+4] ; stack frame addressing
- ARGyc EQU word ptr [bp+6]
- ARGa EQU word ptr [bp+8]
- ARGb EQU word ptr [bp+10]
- ARGn EQU byte ptr [bp+12]
-
- ULAddr EQU word ptr [bp-2]
- URAddr EQU word ptr [bp-4]
- LLAddr EQU word ptr [bp-6]
- LRAddr EQU word ptr [bp-8]
- LMask EQU byte ptr [bp-10]
- RMask EQU byte ptr [bp-12]
-
- VARd EQU word ptr [bp-16]
- VARdx EQU word ptr [bp-20]
- VARdy EQU word ptr [bp-24]
- Asquared EQU word ptr [bp-28]
- Bsquared EQU word ptr [bp-32]
- TwoAsquared EQU word ptr [bp-36]
- TwoBsquared EQU word ptr [bp-40]
-
- RMWbits EQU 0 ; read-modify-write bits
- BytesPerLine EQU 80
-
-
- _TEXT SEGMENT byte public 'CODE'
- ASSUME cs:_TEXT
-
- EXTRN PixelAddr10:near
-
- PUBLIC _Ellipse10
- _Ellipse10 PROC near
-
- push bp ; preserve caller registers
- mov bp,sp
- sub sp,40 ; establish stack frame
- push si
- push di
-
- ; set Graphics Controller Mode register
-
- mov dx,3CEh ; DX := Graphics Controller I/O port
- mov ax,0005h ; AL := Mode register number
- ; AH := Write Mode 0 (bits 0,1)
- out dx,ax ; Read Mode 0 (bit 4)
-
- ; set Data Rotate/Function Select register
-
- mov ah,RMWbits ; AH := Read-Modify-Write bits
- mov al,3 ; AL := Data Rotate/Function Select r
- out dx,ax
-
- ; set Set/Reset and Enable Set/Reset registers
-
- mov ah,ARGn ; AH := pixel value
- mov al,0 ; AL := Set/Reset reg number
- out dx,ax
-
- mov ax,0F01h ; AH := value for Enable Set/Reset (a
- ; bit planes enabled)
- out dx,ax ; AL := Enable Set/Reset reg number
-
- ; initial constants
-
- mov ax,ARGa
- mul ax
- mov Asquared,ax
- mov Asquared+2,dx ; a^2
- shl ax,1
- rcl dx,1
- mov TwoAsquared,ax
- mov TwoAsquared+2,dx ; 2*a^2
-
- mov ax,ARGb
- mul ax
- mov Bsquared,ax
- mov Bsquared+2,dx ; b^2
- shl ax,1
- rcl dx,1
- mov TwoBsquared,ax
- mov TwoBsquared+2,dx ; 2*b^2
- ;
- ; plot pixels from (0,b) until dy/dx = -1
- ;
-
- ; initial buffer address and bit mask
-
- mov ax,BytesPerLine ; AX := video buffer line length
- mul ARGb ; AX := relative byte offset of b
- mov si,ax
- mov di,ax
-
- mov ax,ARGyc ; AX := yc
- mov bx,ARGxc ; BX := xc
- call PixelAddr10 ; AH := bit mask
- ; ES:BX -> buffer
- ; CL := # bits to shift left
- mov ah,1
- shl ah,cl ; AH := bit mask for first pixel
- mov LMask,ah
- mov RMask,ah
-
- add si,bx ; SI := offset of (0,b)
- mov ULAddr,si
- mov URAddr,si
- sub bx,di ; AX := offset of (0,-b)
- mov LLAddr,bx
- mov LRAddr,bx
-
- ; initial decision variables
-
- xor ax,ax
- mov VARdx,ax
- mov VARdx+2,ax ; dx = 0
-
- mov ax,TwoAsquared
- mov dx,TwoAsquared+2
- mov cx,ARGb
- call LongMultiply ; perform 32-bit by 16-bit mulitply
- mov VARdy,ax
- mov VARdy+2,dx ; dy = TwoAsquared * b
-
- mov ax,Asquared
- mov dx,Asquared+2 ; DX:AX = Asquared
- sar dx,1
- rcr ax,1
- sar dx,1
- rcr ax,1 ; DX:AX = Asquared/4
-
- add ax,Bsquared
- adc dx,Bsquared+2 ; DX:AX = Bsquared + Asquared/4
- mov VARd,ax
- mov VARd+2,dx
-
- mov ax,Asquared
- mov dx,Asquared+2
- mov cx,ARGb
- call LongMultiply ; DX:AX = Asquared*b
- sub VARd,ax
- sbb VARd+2,dx ; d = Bsquared - Asquared*b + Asquare
-
- ; loop until dy/dx >= -1
-
- mov bx,ARGb ; BX := initial y-coordinate
-
- xor cx,cx ; CH := 0 (initial y-increment)
- ; CL := 0 (initial x-increment)
- L10: mov ax,VARdx
- mov dx,VARdx+2
- sub ax,VARdy
- sbb dx,VARdy+2
- jns L20 ; jump if dx>=dy
-
- call Set4Pixels
-
- mov cx,1 ; CH := 0 (y-increment)
- ; CL := 1 (x-increment)
- cmp VARd+2,0
- js L11 ; jump if d < 0
-
- mov ch,1 ; increment in y direction
- dec bx ; decrement current y-coordinate
-
- mov ax,VARdy
- mov dx,VARdy+2
- sub ax,TwoAsquared
- sbb dx,TwoAsquared+2 ; DX:AX := dy - TwoAsquared
- mov VARdy,ax
- mov VARdy+2,dx ; dy -= TwoAsquared
-
- sub VARd,ax
- sbb VARd+2,dx ; d -= dy
-
- L11: mov ax,VARdx
- mov dx,VARdx+2
- add ax,TwoBsquared
- adc dx,TwoBsquared+2 ; DX:AX := dx + TwoBsquared
- mov VARdx,ax
- mov VARdx+2,dx ; dx += TwoBsquared
-
- add ax,Bsquared
- adc dx,Bsquared+2 ; DX:AX := dx + Bsquared
- add VARd,ax
- adc VARd+2,dx ; d += dx + Bsquared
-
- jmp L10
- ;
- ; plot pixels from current (x,y) until y < 0
- ;
-
- ; initial buffer address and bit mask
-
- L20: push bx ; preserve current y-coordinate
- push cx ; preserve x- and y-increments
-
- mov ax,Asquared
- mov dx,Asquared+2
- sub ax,Bsquared
- sbb dx,Bsquared+2 ; DX:AX := Asquared-Bsquared
-
- mov bx,ax
- mov cx,dx ; CX:BX := (Asquared-Bsquared)
-
- sar dx,1
- rcr ax,1 ; DX:AX := (Asquared-Bsquared)/2
- add ax,bx
- adc dx,cx ; DX:AX := 3*(Asquared-Bsquared)/2
-
- sub ax,VARdx
- sbb dx,VARdx+2
- sub ax,VARdy
- sbb dx,VARdy+2 ; DX:AX := 3*(Asquared-Bsquared)/2 -
-
- sar dx,1
- rcr ax,1 ; DX:AX :=
- ; ( 3*(Asquared-Bsquared)/2 - (dx+dy
- add VARd,ax
- adc VARd+2,dx ; update d
-
- ; loop until y < 0
-
- pop cx ; CH,CL := y- and x-increments
- pop bx ; BX := y
-
- L21: call Set4Pixels
-
- mov cx,100h ; CH := 1 (y-increment)
- ; CL := 0 (x-increment)
-
- cmp VARd+2,0
- jns L22 ; jump if d >= 0
-
- mov cl,1 ; increment in x direction
-
- mov ax,VARdx
- mov dx,VARdx+2
- add ax,TwoBsquared
- adc dx,TwoBsquared+2 ; DX:AX := dx + TwoBsquared
- mov VARdx,ax
- mov VARdx+2,dx ; dx += TwoBsquared
-
- add VARd,ax
- adc VARd+2,dx ; d += dx
-
- L22: mov ax,VARdy
- mov dx,VARdy+2
- sub ax,TwoAsquared
- sbb dx,TwoAsquared+2 ; DX:AX := dy - TwoAsquared
- mov VARdy,ax
- mov VARdy+2,dx ; dy -= TwoAsquared
-
- sub ax,Asquared
- sbb dx,Asquared+2 ; DX:AX := dy - Asquared
- sub VARd,ax
- sbb VARd+2,dx ; d += Asquared - dy
-
- dec bx ; decrement y
- jns L21 ; loop if y >= 0
-
-
- ; restore default Graphics Controller registers
-
- Lexit: mov ax,0FF08h ; default Bit Mask
- mov dx,3CEh
- out dx,ax
-
- mov ax,0003 ; default Function Select
- out dx,ax
-
- mov ax,0001 ; default Enable Set/Reset
- out dx,ax
-
- pop di ; restore registers and return
- pop si
- mov sp,bp
- pop bp
- ret
-
- _Ellipse10 ENDP
-
-
- Set4Pixels PROC near ; Call with: CH := y-increment (0, -
- ; CL := x-increment (0, 1
-
- push ax ; preserve these regs
- push bx
- push dx
-
- mov dx,3CEh ; DX := Graphics Controller port
-
- xor bx,bx ; BX := 0
- test ch,ch
- jz L30 ; jump if y-increment = 0
-
- mov bx,BytesPerLine ; BX := positive increment
- neg bx ; BX := negative increment
-
- L30: mov al,8 ; AL := Bit Mask reg number
-
- ; pixels at (xc-x,yc+y) and (xc-x,yc-y)
-
- xor si,si ; SI := 0
- mov ah,LMask
-
- rol ah,cl ; AH := bit mask rotated horizontally
- rcl si,1 ; SI := 1 if bit mask rotated around
- neg si ; SI := 0 or -1
-
- mov di,si ; SI,DI := left horizontal increment
-
- add si,ULAddr ; SI := upper left addr + horiz incr
- add si,bx ; SI := new upper left addr
- add di,LLAddr
- sub di,bx ; DI := new lower left addr
-
- mov LMask,ah ; update these variables
- mov ULAddr,si
- mov LLAddr,di
-
- out dx,ax ; update Bit Mask register
-
- mov ch,es:[si] ; update upper left pixel
- mov es:[si],ch
- mov ch,es:[di] ; update lower left pixel
- mov es:[di],ch
-
-
- ; pixels at (xc+x,yc+y) and (xc+x,yc-y)
-
- xor si,si ; SI := 0
- mov ah,RMask
-
- ror ah,cl ; AH := bit mask rotated horizontally
- rcl si,1 ; SI := 1 if bit mask rotated around
-
- mov di,si ; SI,DI := right horizontal increment
-
- add si,URAddr ; SI := upper right addr + horiz incr
- add si,bx ; SI := new upper right addr
- add di,LRAddr
- sub di,bx ; DI := new lower right addr
-
- mov RMask,ah ; update these variables
- mov URAddr,si
- mov LRAddr,di
-
- out dx,ax ; update Bit Mask register
-
- mov ch,es:[si] ; update upper right pixel
- mov es:[si],ch
- mov ch,es:[di] ; update lower right pixel
- mov es:[di],ch
-
- pop dx ; restore these regs
- pop bx
- pop ax
- ret
-
- Set4Pixels ENDP
-
-
- LongMultiply PROC near ; Caller: DX = u1 (hi-order wor
- ; of 32-bit number)
- ; AX = u2 (lo-order wor
- ; CX = v1 (16-bit numbe
- ; Returns: DX:AX = 32-bit result
-
- push ax ; preserve u2
- mov ax,dx ; AX :=
- mul cx ; AX := high-order word of result
- xchg ax,cx ; AX := v1, CX := high-order word
- pop dx ; DX := u2
- mul dx ; AX := low-order word of result
- ; DX := carry
- add dx,cx ; CX := high-order word of result
- ret
-
- LongMultiply ENDP
-
- _TEXT ENDS
-
- END
-
- \SAMPCODE\VIDEO\8
- \SAMPCODE\VIDEO\8\8_1.C
-
- /* Listing 6-3 */
-
- FilledRectangle( x1, y1, x2, y2, n )
- int x1,y1; /* upper left corner */
- int x2,y2; /* lower right corner */
- int n; /* pixel value */
- {
- int y;
-
- for (y=y1; y<=y2; y++) /* draw rectangle as a set of */
- Line( x1, y, x2, y, n ); /* adjacent horizontal lines */
- }
-
- \SAMPCODE\VIDEO\8\8_2.C
-
- /* Listing 8-2 */
-
- int FillValue; /* value of pixels in filled region
- int BorderValue; /* value of pixels in border */
-
- PixelFill( x, y )
- in⌠ x,y;
- {
- int v;
-
- v = ReadPixel( x, y );
-
- if ( (v!=FillValue) && (v!=BorderValue) )
- {
- SetPixel( x, y, FillValue );
-
- PixelFill( x-1, y );
- PixelFill( x+1, y );
- PixelFill( x, y-1 );
- PixelFill( x, y+1 );
- }
- }
-
- \SAMPCODE\VIDEO\8\8_3.C
-
- /* Listing 8-3 */
-
- #define UP -1
- #define DOWN 1
-
-
- LineAdjFill( SeedX, SeedY, D, PrevXL, PrevXR )
- int SeedX,SeedY; /* seed for current row of pixels */
- int D; /* direction searched to find current row */
- int PrevXL,PrevXR; /* endpoints of previous row of pixels */
- {
- int x,y;
- int xl,xr;
- int v;
-
- y = SeedY; /* initialize to seed coordinates */
- xl = SeedX;
- xr = SeedX;
-
- ScanLeft( &xl, &y ); /* determine endpoints of seed line segment *
- ScanRight( &xr, &y );
-
- Line( xl, y, xr, y, FillValue ); /* fill line with FillValue *
-
-
- /* find and fill adjacent line segments in same direction */
-
- for (x=xl; x<=xr; x++) /* inspect adjacent rows of pixels */
- {
- v = ReadPixel( x, y+D );
- if ( (v!=BorderValue) && (v!=FillValue) )
- x = LineAdjFill( x, y+D, D, xl, xr );
- }
-
- /* find and fill adjacent line segments in opposite direction */
-
- for (x=xl; x<PrevXL; x++)
- {
- v = ReadPixel( x, y-D );
- if ( (v!=BorderValue) && (v!=FillValue) )
- x = LineAdjFill( x, y-D, -D, xl, xr );
- }
-
- for (x=PrevXR; x<xr; x++)
- {
- v = ReadPixel( x, y-D );
- if ( (v!=BorderValue) && (v!=FillValue) )
- x = LineAdjFill( x, y-D, -D, xl, xr );
- }
-
- return( xr );
- }
-
-
- ScanLeft( x, y )
- int *x,*y;
- {
- int v;
-
-
- do
- {
- --(*x); /* move left one pixel */
- v = ReadPixel( *x, *y ); /* determine its value */
- }
- while ( (v!=BorderValue) && (v!=FillValue) );
-
- ++(*x); /* x-coordinate of leftmost pixel in row */
- }
-
-
- ScanRight( x, y )
- int *x,*y;
- {
- int v;
-
-
- do
- {
- ++(*x); /* move right one pixel */
- v = ReadPixel( *x, *y ); /* determine its value */
- }
- while ( (v!=BorderValue) && (v!=FillValue) );
-
- --(*x); /* x-coordinate of rightmost pixel in row */
- }
-
- \SAMPCODE\VIDEO\8\8_4.C
-
- /* Listing 8-3 */
-
- #define BLOCKED 1
- #define UNBLOCKED 2
- #define TRUE 1
- #define FALSE 0
-
- struct BPstruct /* table of border pixels */
- {
- int x,y;
- int flag;
- }
- BP[3000]; /* (increase if necessary) */
-
- int BPstart; /* start of table */
- int BPend = 0; /* first empty cell in table */
- int FillValue; /* value of pixels in filled region *
- int BorderValue; /* value of pixels in border */
-
-
- BorderFill( x, y )
- int x,y;
- {
- do /* do until entire table has been sca
- {
- TraceBorder( x, y ); /* trace border starting at x,y */
- SortBP( BP ); /* sort the border pixel table */
- ScanRegion( &x, &y ); /* look for holes in the interior */
- }
- while (BPstart < BPend);
-
- FillRegion(); /* use the table to fill the interior
- }
-
-
- ScanRegion( x, y )
- int *x,*y;
- {
- int i = BPstart;
- int xr;
-
- while (i<BPend)
- {
- if (BP[i].flag == BLOCKED) /* skip pixel if blocked */
- ++i;
-
- else
- if (BP[i].y != BP[i+1].y) /* skip pixel if last in line
- ++i;
-
- else
- { /* if at least one pixel to f
- if (BP[i].x < BP[i+1].x-1) /* .. scan the line */
- {
- xr = ScanRight( BP[i].x+1, BP[i].y );
-
- if (xr<BP[i+1].x) /* if a border pixel is found
- {
- *x = xr; /* .. return its x,y coordina
- *y = BP[i].y;
- break;
- }
- }
-
- i += 2; /* advance past this pair of
- }
- }
-
- BPstart = i;
- }
-
-
- SortBP() /* uses Microsoft C library quicksort routine
- {
- int CompareBP();
-
- qsort( BP+BPstart, BPend-BPstart, sizeof(struct BPstruct), CompareBP
- }
-
-
- CompareBP( arg1, arg2 ) /* returns -1 if arg1 < arg2 */
- struct BPstruct *arg1,*arg2;
- {
- int i;
-
- i = arg1->y - arg2->y; /* sort by y-coordinate */
- if (i!=0)
- return( (i<0) ? -1 : 1 ); /* (return -1 if i<0, 1 if i>0) */
-
- i = arg1->x - arg2->x; /* sort by x-coordinate */
- if (i!=0)
- return( (i<0) ? -1 : 1 );
-
- i = arg1->flag - arg2->flag; /* sort by flag */
- return( (i<0) ? -1 : 1 );
- }
-
-
- FillRegion()
- {
- int i;
-
-
- for(i=0; i<BPend;)
- {
- if (BP[i].flag == BLOCKED) /* skip pixel if blocked */
- ++i;
-
- else
- if (BP[i].y != BP[i+1].y) /* skip pixel if last in line
- ++i;
-
- else
- { /* if at least one pixel to f
- if (BP[i].x < BP[i+1].x-1) /* .. draw a line */
- Line( BP[i].x+1, BP[i].y, BP[i+1].x-1, BP[i+1].y, FillValue );
-
- i += 2;
- }
- }
- }
-
-
- /* border tracing routine */
-
- struct BPstruct CurrentPixel;
- int D; /* current search direction */
- int PrevD; /* previous search direction */
- int PrevV; /* previous vertical direction */
-
-
- TraceBorder( StartX, StartY )
- int StartX,StartY;
- {
- int NextFound; /* flags */
- int Done;
-
- /* initialize */
-
- CurrentPixel.x = StartX;
- CurrentPixel.y = StartY;
-
- D = 6; /* current search direction */
- PrevD = 8; /* previous search direction */
- PrevV = 2; /* most recent vertical direction */
-
- /* loop around the border until returned to the starting pixel */
-
- do
- {
- NextFound = FindNextPixel();
- Done =
- (CurrentPixel.x == StartX) && (CurrentPixel.y == StartY);
- }
- while (NextFound && !Done);
-
- /* if only one pixel in border, add it twice to the table */
-
- if (!NextFound) /* pixel has no neighbors */
- {
- AppendBPList( StartX, StartY, UNBLOCKED );
- AppendBPList( StartX, StartY, UNBLOCKED );
- }
-
- /* if last search direction was upward, add the starting pixel to the table *
-
- else
- if ( (PrevD <= 3) && (PrevD >= 1) )
- AppendBPList( StartX, StartY, UNBLOCKED );
- }
-
-
- FindNextPixel( )
- {
- int i;
- int flag;
-
-
- for (i=-1; i<=5; i++)
- {
- flag = FindBP( (D+i) & 7 ); /* search for next border pix
- if (flag) /* flag is TRUE if found */
- {
- D = (D+i) & 6; /* (D+i) MOD 2 */
- break; /* exit from loop */
- }
- }
-
- return(flag);
- }
-
-
- FindBP( d )
- int d; /* direction to search for next border pixel
- {
- int x,y;
-
- x = CurrentPixel.x;
- y = CurrentPixel.y;
-
-
- NextXY( &x, &y, d ); /* get x,y of pixel in direction d */
-
- if ( BorderValue == ReadPixel( x, y ) )
- {
- AddBPList( d ); /* add pixel at x,y to table */
- CurrentPixel.x = x; /* pixel at x,y becomes current pixel
- CurrentPixel.y = y;
- return( TRUE );
- }
-
- else
- return( FALSE );
- }
-
-
- NextXY( x, y, Direction )
- int *x,*y;
- int Direction;
- {
- switch( Direction ) /* 3 2 1 */
- { /* 4 0 */
- case 1: /* 5 6 7 */
- case 2:
- case 3:
-
- *y -= 1; /* up */
- break;
- case 5:
- case 6:
- case 7:
- *y += 1; /* down */
- break;
- }
-
- switch(Direction)
- {
- case 3:
- case 4:
- case 5:
- *x -= 1; /* left */
- break;
- case 1:
- case 0:
- case 7:
- *x += 1; /* right */
- break;
- }
- }
-
-
- AddBPList( d )
- int d;
- {
- if (d == PrevD)
- SameDirection();
-
- else
- {
- DifferentDirection( d );
- PrevV = PrevD; /* new previous vertical dire
- }
-
- PrevD = d; /* new previous search direct
- }
-
- SameDirection()
- {
- if (PrevD == 0) /* moving right ... */
- BP[BPend-1].flag = BLOCKED; /* .. block previous pixel */
-
- else
- if (PrevD != 4) /* if not moving horizontally
- AppendBPList( CurrentPixel.x, CurrentPixel.y, UNBLOCKED );
- }
-
-
- DifferentDirection( d )
- int d;
- {
-
- /* previously moving left */
-
- if (PrevD == 4)
- {
- if (PrevV == 5) /* if from above .. */
- BP[BPend-1].flag = BLOCKED; /* .. block rightmost in line
-
- AppendBPList( CurrentPixel.x, CurrentPixel.y, BLOCKED );
- }
-
- /* previously moving right */
-
- else
- if (PrevD == 0) /* previously moving right ..
- {
- BP[BPend-1].flag = BLOCKED; /* .. block rightmost in line
-
- if (d == 7) /* if line started from above
- AppendBPList( CurrentPixel.x, CurrentPixel.y, BLOCKED );
- else
- AppendBPList( CurrentPixel.x, CurrentPixel.y, UNBLOCKED );
- }
-
- /* previously moving in some vertical direction */
-
- else
- {
- AppendBPList( CurrentPixel.x, CurrentPixel.y, UNBLOCKED );
-
- /* add pixel twice if local vertical maximum or minimum */
-
- if ( ( (d>=1) && (d<=3) ) && ( (PrevD >= 5) && (PrevD <= 7) ) ||
- ( (d>=5) && (d<=7) ) && ( (PrevD >= 1) && (PrevD <= 3) ) )
- AppendBPList( CurrentPixel.x, CurrentPixel.y, UNBLOCKED );
- }
- }
-
-
- AppendBPList( p, q, f )
- int p,q; /* pixel x,y coordinates */
- int f; /* flag */
- {
- BP[BPend].x = p;
- BP[BPend].y = q;
- BP[BPend].flag = f;
-
- ++BPend; /* increment past last entry in table */
- }
-
-
- /* routine to scan a line for a border pixel */
-
- int Xmax; /* largest valid pixel x-coordinate */
-
- ScanRight( x, y )
- int x,y;
- {
- while ( ReadPixel( x, y ) != BorderValue )
- {
- ++x; /* increment x */
- if (x==Xmax) /* if end of line in buffer .. */
- break; /* .. exit from the loop */
- }
-
- return( x );
- }
-
- \SAMPCODE\VIDEO\8\8_5.ASM
-
- TITLE 'Listing 8-4'
- NAME ScanRight10
- PAGE 55,132
-
- ;
- ; Name: ScanRight10
- ;
- ; Function: Scan for a pixel of a given value in 16-color EGA/VGA graphic
- ;
- ; Caller: Microsoft C:
- ;
- ; int ScanRight10(x,y);
- ;
- ; int x,y; /* starting pixel */
- ;
- ; extern int BorderValue; /* value of border pi
- ;
- ; Returns the x-coordinate of the rightmost border pixel.
- ;
-
- ARGx EQU word ptr [bp+4] ; stack frame addressing
- ARGy EQU word ptr [bp+6]
-
- ByteOffsetShift EQU 3 ; used to convert pixels to byte offs
- BytesPerLine EQU 80 ; 80 for most 16-color graphics modes
- ; (40 for 320x200 16-color)
-
-
- DGROUP GROUP _DATA
-
- _TEXT SEGMENT byte public 'CODE'
- ASSUME cs:_TEXT,ds:DGROUP
-
- EXTRN PixelAddr10:near
-
- PUBLIC _ScanRight10
- _ScanRight10 PROC near
-
- push bp ; preserve caller registers
- mov bp,sp
- push si
- push di
-
- ; calculate pixel address of (0,y)
-
- mov ax,ARGy ; AX := y
- xor bx,bx ; BX := 0
- call PixelAddr10 ; ES:BX -> buffer
- mov di,bx ; ES:DI -> buffer
-
- ; calculate offset of x in row
-
- mov ax,ARGx
- mov si,ax ; SI,AX := x
- mov cl,ByteOffsetShift
- shr si,cl ; SI := offset of x in row y
- add di,si ; DI := offset of x in buffer
-
- ; calculate a bit mask for the first byte to scan
-
- mov cl,al
- and cl,7 ; CL := x & 7
- mov ch,0FFh
- shr ch,cl ; CH := bit mask for first scanned by
-
- ; configure the Graphics Controller
-
- mov dx,3CEh ; DX := Graphics Controller port addr
-
- mov ah,_BorderValue ; AH := pixel value for Color Compare
- mov al,2 ; AL := Color Compare Reg number
- out dx,ax
-
- mov ax,805h ; AH := 00001000b (Read Mode 1)
- out dx,ax ; AL := Mode reg number
-
- mov ax,0F07h ; AH := 00001111b (Color Compare reg
- out dx,ax ; AL := Color Compare reg number
-
- ; inspect the first byte for border pixels
-
- mov al,es:[di] ; AL := nonzero bits corresponding to
- ; border pixels
- inc di ; ES:DI -> next byte to scan
- and al,ch ; apply bit mask
- jnz L01 ; jump if border pixel(s) found
-
- ; scan remainder of line for border pixels
-
- mov cx,BytesPerLine
- sub cx,si ; CX := BytesPerLine - (byte offset o
- ; starting pixel)
- dec cx ; CX := # of bytes to scan
-
- repe scasb ; scan until nonzero byte read; i.e.,
- ; border pixel(s) found
-
- ; compute x value of border pixel
-
- mov al,es:[di-1] ; AL := last byte compared
-
- L01: sub di,bx ; DI := offset of byte past the one w
- ; contains a border pixel
- mov cl,ByteOffsetShift
- shl di,cl ; DI := x-coordinate of 1st pixel in
-
- mov cx,8 ; CX := loop limit
-
- L02: shl al,1 ; isolate first border pixel
- jc L03
-
- loop L02
-
- L03: sub di,cx ; DI := x-coordinate of border pixel
-
- ; restore default Graphics Controller state and return to caller
-
- mov ax,2 ; AH := 0 (default Color Compare valu
- out dx,ax ; restore Color Compare reg
-
- mov al,5 ; AH := 0, AL := 5
- out dx,ax ; restore Mode reg
-
- mov ax,di ; AX := return value
-
- pop di ; restore caller registers and return
- pop si
- mov sp,bp
- pop bp
- ret
-
- _ScanRight10 ENDP
-
- _TEXT ENDS
-
-
- _DATA SEGMENT word public 'DATA'
-
- EXTRN _BorderValue:byte
-
- _DATA ENDS
-
- END
-
- \SAMPCODE\VIDEO\9
- \SAMPCODE\VIDEO\9\9_2.ASM
-
- TITLE 'Listing 9-3'
- NAME DisplayChar06
- PAGE 55,132
-
- ;
- ; Name: DisplayChar06
- ;
- ; Function: Display a character in 640x200 2-color mode
- ;
- ; Caller: Microsoft C:
- ;
- ; void DisplayChar06(c,x,y,fgd,bkgd);
- ;
- ; int c; /* character code */
- ;
- ; int x,y; /* upper left pixel */
- ;
- ; int fgd,bkgd; /* foreground and background
- ; pixel values */
- ;
-
- ARGc EQU word ptr [bp+4] ; stack frame addressing
- ARGx EQU word ptr [bp+6]
- ARGy EQU word ptr [bp+8]
- ARGfgd EQU byte ptr [bp+10]
- ARGbkgd EQU byte ptr [bp+12]
-
- VARmask EQU [bp-2]
- VARtoggle EQU [bp-4]
-
-
- _TEXT SEGMENT byte public 'CODE'
- ASSUME cs:_TEXT
-
- EXTRN PixelAddr06:near
-
- PUBLIC _DisplayChar06
- _DisplayChar06 PROC near
-
- push bp ; preserve caller registers
- mov bp,sp
- sub sp,4 ; stack space for local variables
- push si
- push di
- push ds
-
- ; set up foreground pixel toggle mask
-
- mov ah,ARGfgd ; AH := 0 or 1 (foreground pixel valu
- ror ah,1 ; high-order bit of AH := 0 or 1
- cwd ; propagate high-order bit through DX
- not dx ; DX := 0 if foreground = 1
- ; or FFFFh if foreground = 0
- mov VARtoggle,dx
-
- ; calculate first pixel address
-
- mov ax,ARGy ; AX := y
- mov bx,ARGx ; BX := x
- call PixelAddr06 ; ES:BX -> buffer
- ; CL := # bits to shift left
-
- xor cl,7 ; CL := # bits to rotate right
-
- mov ax,0FF00h
- ror ax,cl ; AX := bit mask in proper position
- mov VARmask,ax
-
- ; set up video buffer addressing
-
- mov dx,2000h ; increment for video buffer interlea
- mov di,80-2000h ; increment from last to first interl
-
- test bx,2000h ; set zero flag if BX in 1st interlea
- jz L01
-
- xchg di,dx ; exchange increment values if 1st pi
- ; lies in 1st interleave
-
- ; set up character definition table addressing
-
- L01: push bx ; preserve buffer address
-
- mov ax,40h
- mov ds,ax ; DS := segment of BIOS Video
- ; Display Data area
- mov ch,ds:[85h] ; CH := POINTS (pixel rows in charact
-
- xor ax,ax
- mov ds,ax ; DS := absolute zero
-
- mov ax,ARGc ; AL := character code
- cmp al,80h
- jae L02
-
- mov bx,43h*4 ; DS:BX -> int 43h vector if char < 8
- jmp short L03
-
- L02: mov bx,1Fh*4 ; DS:BX -> int 1Fh vector if char >=
- sub al,80h ; put character code in range of tabl
-
- L03: lds si,ds:[bx] ; DS:SI -> start of character table
- mul ch ; AX := offset into char def table
- ; (POINTS * char code)
- add si,ax ; SI := addr of char def
-
- pop bx ; restore buffer address
-
- test cl,cl ; test # bits to rotate
- jnz L20 ; jump if character is not byte-align
-
-
- ; routine for byte-aligned characters
-
- mov ah,VARtoggle ; AH := foreground toggle mask
- xchg ch,cl ; CX := POINTS
-
- L10: lodsb ; AL := bit pattern for next pixel ro
- xor al,ah ; toggle pixels if foreground = 0
- mov es:[bx],al ; store pixels in buffer
-
- add bx,dx ; BX := next row in buffer
- xchg di,dx ; swap buffer increments
- loop L10
- jmp short Lexit
-
-
- ; routine for non-byte-aligned characters
-
- L20: mov ax,VARmask
- and es:[bx],ax ; mask character pixels in buffer
-
- xor ah,ah
- lodsb ; AX := bit pattern for next pixel ro
- xor al,VARtoggle ; toggle pixels if foreground = 0
-
- ror ax,cl ; rotate pixels into position
- or es:[bx],ax ; store pixels in buffer
-
- add bx,dx ; BX := next row in buffer
- xchg di,dx ; swap buffer increments
- dec ch
- jnz L20
-
-
- Lexit: pop ds ; restore registers and return
- pop di
- pop si
- mov sp,bp
- pop bp
- ret
-
- _DisplayChar06 ENDP
-
- _TEXT ENDS
-
- END
-
- \SAMPCODE\VIDEO\9\9_3.ASM
-
- TITLE 'Listing 9-3'
- NAME DisplayChar04
- PAGE 55,132
-
- ;
- ; Name: DisplayChar04
- ;
- ; Function: Display a character in 320x200 4-color graphics mode
- ;
- ; Caller: Microsoft C:
- ;
- ; void DisplayChar04(c,x,y,fgd,bkgd);
- ;
- ; int c; /* character code */
- ;
- ; int x,y; /* upper left pixel */
- ;
- ; int fgd,bkgd; /* foreground and background
- ; pixel values */
- ;
-
- ARGc EQU word ptr [bp+4] ; stack frame addressing
- ARGx EQU word ptr [bp+6]
- ARGy EQU word ptr [bp+8]
- ARGfgd EQU [bp+10]
- ARGbkgd EQU [bp+12]
-
- VARshift EQU word ptr [bp-2]
- VARincr EQU word ptr [bp-4]
-
-
- DGROUP GROUP _DATA
-
- _TEXT SEGMENT byte public 'CODE'
- ASSUME cs:_TEXT,ds:DGROUP
-
- EXTRN PixelAddr04:near
-
- PUBLIC _DisplayChar04
- _DisplayChar04 PROC near
-
- push bp ; preserve caller registers
- mov bp,sp
- sub sp,4 ; stack space for local variables
- push si
- push di
- push ds
-
- ; propagate pixel values
-
- mov bx,offset DGROUP:PropagatedPixel
- mov al,ARGfgd
- xlat ; propagate foreground pixel value
- mov ah,al
- mov ARGfgd,ax
-
- mov al,ARGbkgd
- xlat ; propagate background pixel value
- mov ah,al
- mov ARGbkgd,ax
-
- ; calculate first pixel address
-
- mov ax,ARGy ; AX := y
- mov bx,ARGx ; BX := x
- call PixelAddr04 ; ES:BX -> buffer
- ; CL := # bits to shift left
- ; to mask pixel
- mov ch,0FCh
- shl ch,cl ; CH := bit mask for right side of ch
-
- xor cl,6 ; CL := 6 - CL (# bits to rotate char
- ; into position)
- mov VARshift,cx
-
- ; set up video buffer addressing
-
- mov di,2000h ; increment for video buffer interlea
- mov VARincr,80-2000h ; increment from last to first inter
-
- test bx,2000h ; set zero flag if BX in 1st interlea
- jz L01
-
- xchg VARincr,di ; exchange increment values if 1st pi
- ; lies in 1st interleave
-
- ; set up character definition table addressing
-
- L01: push bx ; preserve buffer address
-
- mov ax,40h
- mov ds,ax ; DS := segment of BIOS Video
- ; Display Data area
- mov ch,ds:[85h] ; CH := POINTS (pixel rows in charact
-
- xor ax,ax
- mov ds,ax ; DS := absolute zero
-
- mov ax,ARGc ; AL := character code
- cmp al,80h
- jae L02
-
- mov bx,43h*4 ; DS:BX -> int 43h vector if char < 8
- jmp short L03
-
- L02: mov bx,1Fh*4 ; DS:BX -> int 1Fh vector if char >=
- sub al,80h ; put character code in range of tabl
-
- L03: lds si,ds:[bx] ; DS:SI -> start of character table
- mul ch ; AX := offset into char def table
- ; (POINTS * char code)
- add si,ax ; SI := addr of char def
-
- pop bx ; restore buffer address
-
- xchg ch,cl ; CH := # bits to rotate
- ; CL := POINTS
-
- test ch,ch ; test # bits to rotate
- jnz L20 ; jump if character is not byte-align
-
-
- ; routine for byte-aligned characters
-
- L10: lodsb ; AL := bit pattern for next pixel ro
- xor dx,dx ; DX := initial value for doubled bit
- mov ah,8 ; AH := # of bits in pattern
-
- L11: shr al,1 ; cf := lo-order bit of AL
- rcr dx,1 ; hi-order bit of CX := cf
- sar dx,1 ; double hi-order bit of DX
- dec ah ; loop 8 times
- jnz L11
-
- mov ax,dx ; AX,DX := doubled bit pattern
- and ax,ARGfgd ; AX := foreground pixels
- not dx
- and dx,ARGbkgd ; DX := background pixels
-
- or ax,dx ; AX := eight pixels
- xchg ah,al ; put bytes in proper order
- mov es:[bx],ax ; update video buffer
-
- add bx,di ; BX := next row in buffer
- xchg di,VARincr ; swap buffer increments
-
- loop L10
- jmp short Lexit
-
-
- ; routine for non-byte-aligned characters
-
- L20: xor ch,ch ; CX := POINTS
-
- L21: push cx ; preserve CX
-
- mov cx,VARshift ; CH := mask for right side of char
- ; CL := # bits to rotate
-
- lodsb ; AL := bit pattern for next pixel ro
- xor dx,dx ; DX := initial value for doubled bit
- mov ah,8 ; AH := # of bits in pattern
-
- L22: shr al,1 ; DX := double bits in AL
- rcr dx,1 ; (same as above)
- sar dx,1
- dec ah
- jnz L22
-
- xchg dh,dl ; DH := bits for right half of char
- ; DL := bits for left half of char
- mov ax,dx
- and ax,ARGfgd ; AX := foreground pixels
- not dx
- and dx,ARGbkgd ; DX := background pixels
-
- or dx,ax ; DX := eight pixels
- ror dx,cl ; DH := left and right side pixels
- ; DL := middle pixels
- mov al,ch
- xor ah,ah ; AX := mask for left and middle
- ; bytes of char
- and es:[bx],ax ; zero pixels in video buffer
-
- not ax
- and ax,dx
- or es:[bx],ax ; update pixels in left and middle by
-
- mov al,ch ; AL := mask for right-hand byte
- not al
- and es:[bx+2],al ; mask pixels in right-hand byte in b
- and ch,dl
- or es:[bx+2],ch ; update pixels in right-hand byte
-
- add bx,di ; BX := next row in buffer
- xchg di,VARincr ; swap buffer increments
-
- pop cx ; restore CX
- loop L21
-
-
- Lexit: pop ds ; restore registers and return
- pop di
- pop si
- mov sp,bp
- pop bp
- ret
-
- _DisplayChar04 ENDP
-
- _TEXT ENDS
-
-
- _DATA SEGMENT word public 'DATA'
-
- PropagatedPixel DB 00000000b ; 0
- DB 01010101b ; 1
- DB 10101010b ; 2
- DB 11111111b ; 3
-
- _DATA ENDS
-
- END
-
- \SAMPCODE\VIDEO\9\9_4.ASM
-
- TITLE 'Listing 9-4'
- NAME DisplayCharHGC
- PAGE 55,132
-
- ;
- ; Name: DisplayCharHGC
- ;
- ; Function: Display a character in Hercules 720x348 monochrome graphics m
- ;
- ; Caller: Microsoft C:
- ;
- ; void DisplayCharHGC(c,x,y,fgd,bkgd);
- ;
- ; int c; /* character code */
- ;
- ; int x,y; /* upper left pixel */
- ;
- ; int fgd,bkgd; /* foreground and background
- ; pixel values */
- ;
-
- ARGc EQU word ptr [bp+4] ; stack frame addressing
- ARGx EQU word ptr [bp+6]
- ARGy EQU word ptr [bp+8]
- ARGfgd EQU byte ptr [bp+10]
- ARGbkgd EQU byte ptr [bp+12]
-
- VARmask EQU [bp-2]
- VARtoggle EQU [bp-4]
- VAR9bits EQU byte ptr [bp-6]
-
-
- _TEXT SEGMENT byte public 'CODE'
- ASSUME cs:_TEXT
-
- EXTRN PixelAddrHGC:near
-
- PUBLIC _DisplayCharHGC
- _DisplayCharHGC PROC near
-
- push bp ; preserve caller registers
- mov bp,sp
- sub sp,6 ; stack space for local variables
- push si
- push di
- push ds
-
- ; calculate first pixel address
-
- mov ax,ARGy ; AX := y
- mov bx,ARGx ; BX := x
- call PixelAddrHGC ; ES:BX -> buffer
- ; CL := # bits to shift left
-
- xor cl,7 ; CL := # bits to rotate right
-
- ; set up 8- or 9-bit mask
-
- mov ax,40h
- mov ds,ax ; DS := segment of BIOS Video
- ; Display Data area
-
- mov ax,0FF00h ; AX := 8-bit mask
- mov VAR9bits,0 ; zero this flag
-
- cmp byte ptr ds:[4Ah],90 ; does CRT_COLS = 90?
- je L01 ; jump if characters are 8 pixels wid
-
- mov ah,7Fh ; AX := 9-bit mask
- cmp ARGc,0C0h
- jb L01 ; jump if character code ...
-
- cmp ARGc,0DFh
- ja L01 ; ... outside of range 0C0-0DFh
-
- inc VAR9bits ; set flag to extend to 9 bits
-
- L01: ror ax,cl ; AX := bit mask in proper position
- mov VARmask,ax
-
- ; set up foreground pixel toggle mask
-
- mov ah,ARGfgd ; AH := 0 or 1 (foreground pixel valu
- ror ah,1 ; high-order bit of AH := 0 or 1
- cwd ; propagate high-order bit through DX
- not dx ; DX := 0 if foreground = 1
- ; or FFFFh if foreground = 0
- mov ax,VARmask
- not ax
- and dx,ax ; zero unused bits of toggle mask in
- mov VARtoggle,dx
-
- ; set up character definition table addressing
-
- push bx ; preserve buffer address
-
- mov ch,ds:[85h] ; CH := POINTS (pixel rows in charact
-
- xor ax,ax
- mov ds,ax ; DS := absolute zero
-
- mov ax,ARGc ; AL := character code
- cmp al,80h
- jae L02
-
- mov bx,43h*4 ; DS:BX -> int 43h vector if char < 8
- jmp short L03
-
- L02: mov bx,1Fh*4 ; DS:BX -> int 1Fh vector if char >=
- sub al,80h ; put character code in range of tabl
-
- L03: lds si,ds:[bx] ; DS:SI -> start of character table
- mul ch ; AX := offset into char def table
- ; (POINTS * char code)
- add si,ax ; SI := addr of char def
-
- pop bx ; restore buffer address
-
- ; mask and set pixels in the video buffer
-
- L20: mov ax,VARmask
- and es:[bx],ax ; mask character pixels in buffer
-
- xor ah,ah
- lodsb ; AX := bit pattern for next pixel ro
- cmp VAR9bits,0
- je L21 ; jump if character is 8 pixels wide
-
- ror ax,1 ; copy lo-order bit of AX into ...
- rcl al,1 ; hi-order bit
-
- L21: ror ax,cl ; rotate pixels into position
- xor ax,VARtoggle ; toggle pixels if foreground = 0
- or es:[bx],ax ; store pixels in buffer
-
- add bx,2000h ; increment to next portion of interl
- jns L22
-
- add bx,90-8000h ; increment to first portion of inter
-
- L22: dec ch
- jnz L20
-
-
- Lexit: pop ds ; restore registers and return
- pop di
- pop si
- mov sp,bp
- pop bp
- ret
-
- _DisplayCharHGC ENDP
-
- _TEXT ENDS
-
- END
-
- \SAMPCODE\VIDEO\9\9_5.ASM
-
- TITLE 'Listing 9-5'
- NAME DisplayChar13
- PAGE 55,132
-
- ;
- ; Name: DisplayChar13
- ;
- ; Function: Display a character in MCGA/VGA 320x200 256-color mode
- ;
- ; Caller: Microsoft C:
- ;
- ; void DisplayChar13(c,x,y,fgd,bkgd);
- ;
- ; int c; /* character code */
- ;
- ; int x,y; /* upper left pixel */
- ;
- ; int fgd,bkgd; /* foreground and background
- ; pixel values */
- ;
-
- ARGc EQU word ptr [bp+4] ; stack frame addressing
- ARGx EQU word ptr [bp+6]
- ARGy EQU word ptr [bp+8]
- ARGfgd EQU byte ptr [bp+10]
- ARGbkgd EQU byte ptr [bp+12]
-
- BytesPerLine EQU 320
-
- _TEXT SEGMENT byte public 'CODE'
- ASSUME cs:_TEXT
-
- EXTRN PixelAddr13:near
-
- PUBLIC _DisplayChar13
- _DisplayChar13 PROC near
-
- push bp ; preserve caller registers
- mov bp,sp
- push si
- push di
- push ds
-
- ; calculate first pixel address
-
- mov ax,ARGy ; AX := y
- mov bx,ARGx ; BX := x
- call PixelAddr13 ; ES:BX -> buffer
- mov di,bx ; ES:DI -> buffer
-
- ; set up character definition table addressing
-
- mov ax,40h
- mov ds,ax ; DS := segment of BIOS Video
- ; Display Data area
- mov cx,ds:[85h] ; CX := POINTS (pixel rows in charact
-
- xor ax,ax
- mov ds,ax ; DS := absolute zero
-
- mov ax,ARGc ; AL := character code
- mov bx,43h*4 ; DS:BX -> int 43h vector if char < 8
- lds si,ds:[bx] ; DS:SI -> start of character table
- mul cl ; AX := offset into char def table
- ; (POINTS * char code)
- add si,ax ; SI := addr of char def
-
- ; store the character in the video buffer
-
- mov bl,ARGfgd ; BL := foreground pixel value
- mov bh,ARGbkgd ; BH := background pixel value
-
- L10: push cx ; preserve CX across loop
- mov cx,8 ; CX := character width in pixels
- lodsb
- mov ah,al ; AH := bit pattern for next pixel ro
-
- L11: mov al,bl ; AL := foreground pixel value
- shl ah,1 ; carry flag := high-order bit
- jc L12 ; jump if bit pattern specifies a
- ; foreground pixel (bit = 1)
- mov al,bh ; AL := background pixel value
-
- L12: stosb ; update one pixel in the buffer
- loop L11
-
- add di,BytesPerLine-8 ; increment buffer address to next
- ; row of pixels
- pop cx
- loop L10 ; loop down character
-
- pop ds ; restore registers and return
- pop di
- pop si
- mov sp,bp
- pop bp
- ret
-
- _DisplayChar13 ENDP
-
- _TEXT ENDS
-
- END
-
- \SAMPCODE\VIDEO\9\9_6.ASM
-
- TITLE 'Listing 9-6'
- NAME DisplayChar10
- PAGE 55,132
-
- ;
- ; Name: DisplayChar10
- ;
- ; Function: Display a character in native EGA and VGA graphics modes
- ;
- ; Caller: Microsoft C:
- ;
- ; void DisplayChar10(c,x,y,fgd,bkgd);
- ;
- ; int c; /* character code */
- ;
- ; int x,y; /* upper left pixel */
- ;
- ; int fgd,bkgd; /* foreground and background
- ; pixel values */
- ;
-
- ARGc EQU word ptr [bp+4] ; stack frame addressing
- ARGx EQU word ptr [bp+6]
- ARGy EQU word ptr [bp+8]
- ARGfgd EQU byte ptr [bp+10]
- ARGbkgd EQU byte ptr [bp+12]
-
- VARshift EQU [bp-2]
-
- BytesPerLine = 80 ; (must 40 in 320x200 16-color mode)
- RMWbits = 18h ; Read-Modify-Write bits
-
- _TEXT SEGMENT byte public 'CODE'
- ASSUME cs:_TEXT
-
- EXTRN PixelAddr10:near
-
- PUBLIC _DisplayChar10
- _DisplayChar10 PROC near
-
- push bp ; preserve caller registers
- mov bp,sp
- sub sp,2 ; stack space for local variable
- push si
- push di
- push ds
-
- ; calculate first pixel address
-
- mov ax,ARGy ; AX := y
- mov bx,ARGx ; BX := x
- call PixelAddr10 ; ES:BX -> buffer
- ; CL := # bits to shift left to mask
- ; pixel
- inc cx
- and cl,7 ; CL := # bits to shift to mask char
-
- mov ch,0FFh
- shl ch,cl ; CH := bit mask for right side of ch
- mov VARshift,cx
-
- push es ; preserve video buffer segment
- mov si,bx ; SI := video buffer offset
-
- ; set up character definition table addressing
-
- mov ax,40h
- mov ds,ax ; DS := segment of BIOS Video
- ; Display Data area
- mov cx,ds:[85h] ; CX := POINTS (pixel rows in charact
-
- xor ax,ax
- mov ds,ax ; DS := absolute zero
-
- mov ax,ARGc ; AL := character code
- mov bx,43h*4 ; DS:BX -> int 43h vector
- les di,ds:[bx] ; ES:DI -> start of character table
- mul cl ; AX := offset into char def table
- ; (POINTS * char code)
- add di,ax ; DI := addr of char def
-
- pop ds ; DS:SI -> video buffer
-
- ; set up Graphics Controller registers
-
- mov dx,3CEh ; Graphics Controller address reg por
-
- mov ax,0A05h ; AL := Mode register number
- ; AH := Write Mode 2 (bits 0-1)
- ; Read Mode 1 (bit 4)
- out dx,ax
-
- mov ah,RMWbits ; AH := Read-Modify-Write bits
- mov al,3 ; AL := Data Rotate/Function Select r
- out dx,ax
-
- mov ax,0007 ; AH := Color Don't Care bits
- ; AL := Color Don't Care reg number
- out dx,ax ; "don't care" for all bit planes
-
- ; select output routine depending on whether character is byte-aligned
-
- mov bl,ARGfgd ; BL := foreground pixel value
- mov bh,ARGbkgd ; BH := background pixel value
-
- cmp byte ptr VARshift,0 ; test # bits to shift
- jne L20 ; jump if character is not byte-align
-
-
- ; routine for byte-aligned characters
-
- mov al,8 ; AL := Bit Mask register number
-
- L10: mov ah,es:[di] ; AH := pattern for next row of pixel
- out dx,ax ; update Bit Mask register
- and [si],bl ; update foreground pixels
-
- not ah
- out dx,ax
- and [si],bh ; update background pixels
-
- inc di ; ES:DI -> next byte in char def tabl
- add si,BytesPerLine ; increment to next line in video buf
- loop L10
- jmp short Lexit
-
-
- ; routine for non-byte-aligned characters
-
- L20: push cx ; preserve loop counter
- mov cx,VARshift ; CH := mask for left side of charact
- ; CL := # bits to shift left
- ; left side of character
-
- mov al,es:[di] ; AL := bits for next row of pixels
- xor ah,ah
- shl ax,cl ; AH := bits for left side of char
- ; AL := bits for right side of char
- push ax ; save bits for right side on stack
- mov al,8 ; AL := Bit Mask Register number
- out dx,ax ; set bit mask for foreground pixels
-
- and [si],bl ; update foreground pixels
-
- not ch ; CH := mask for left side of char
- xor ah,ch ; AH := bits for background pixels
- out dx,ax ; set bit mask
-
- and [si],bh ; update background pixels
-
- ; right side of character
-
- pop ax
- mov ah,al ; AH := bits for right side of char
- mov al,8
- out dx,ax ; set bit mask
-
- inc si ; DS:SI -> right side of char in buff
-
- and [si],bl ; update foreground pixels
-
- not ch ; CH := mask for right side of char
- xor ah,ch ; AH := bits for background pixels
- out dx,ax ; set bit mask
-
- and [si],bh ; update background pixels
-
- ; increment to next row of pixels in character
-
- inc di ; ES:DI -> next byte in char def tabl
- dec si
- add si,BytesPerLine ; DS:SI -> next line in video buffer
-
- pop cx
- loop L20
-
-
- ; restore default Graphics Controller registers
-
- Lexit: mov ax,0FF08h ; default Bit Mask
- out dx,ax
-
- mov ax,0005 ; default Mode register
- out dx,ax
-
- mov ax,0003 ; default Data Rotate/Function Select
- out dx,ax
-
- mov ax,0F07h ; default Color Don't Care
- out dx,ax
-
- pop ds ; restore caller registers and return
- pop di
- pop si
- mov sp,bp
- pop bp
- ret
-
- _DisplayChar10 ENDP
-
- _TEXT ENDS
-
- END
-
- \SAMPCODE\VIDEO\9\9_7.ASM
-
- TITLE 'Listing 9-7'
- NAME DisplayCharInC
- PAGE 55,132
-
- ;
- ; Name: DisplayCharInC
- ;
- ; Function: Display a character in InColor 720x348 16-color mode
- ;
- ; Caller: Microsoft C:
- ;
- ; void DisplayCharInC(c,x,y,fgd,bkgd);
- ;
- ; int c; /* character code */
- ;
- ; int x,y; /* upper left pixel */
- ;
- ; int fgd,bkgd; /* foreground and background
- ; pixel values */
- ;
-
- ARGc EQU word ptr [bp+4] ; stack frame addressing
- ARGx EQU word ptr [bp+6]
- ARGy EQU word ptr [bp+8]
- ARGfgd EQU byte ptr [bp+10]
- ARGbkgd EQU byte ptr [bp+12]
-
- VARmask EQU word ptr [bp-2]
- VAR9bits EQU byte ptr [bp-4]
-
- _TEXT SEGMENT byte public 'CODE'
- ASSUME cs:_TEXT
-
- EXTRN PixelAddrHGC:near
-
- PUBLIC _DisplayCharInC
- _DisplayCharInC PROC near
-
- push bp ; preserve caller registers
- mov bp,sp
- sub sp,4 ; stack space for local variables
- push si
- push di
- push ds
-
- ; calculate first pixel address
-
- mov ax,ARGy ; AX := y
- mov bx,ARGx ; BX := x
- call PixelAddrHGC ; ES:BX -> buffer
- ; CL := # bits to shift left to mask
- ; pixel
- xor cl,7 ; CL := # bits to rotate right
-
- push es ; preserve video buffer segment
- mov si,bx ; DI := video buffer offset
-
- ; set up flag for 8- or 9-bit characters
-
- mov ax,40h
- mov ds,ax ; DS := segment of BIOS Video
- ; Display Data area
-
- mov ax,0FF00h ; AX := 8-bit mask
- mov VAR9bits,0 ; zero this flag
-
- cmp byte ptr ds:[4Ah],90 ; does CRT_COLS = 90?
- je L01 ; jump if characters are 8 pixels wid
-
- mov ah,7Fh ; AX := 9-bit mask
- cmp ARGc,0C0h
- jb L01 ; jump if character code ...
-
- cmp ARGc,0DFh
- ja L01 ; ... outside of range 0C0-0DFh
-
- inc VAR9bits ; set flag to extend to 9 bits
-
- L01: ror ax,cl ; AX := bit mask in proper position
- mov VARmask,ax
-
- ; set up character definition table addressing
-
- mov ax,40h
- mov ds,ax ; DS := segment of BIOS Video
- ; Display Data area
- mov ch,ds:[85h] ; CH := POINTS (pixel rows in charact
-
- xor ax,ax
- mov ds,ax ; DS := absolute zero
-
- mov ax,ARGc ; AL := character code
- cmp al,80h
- jae L02
-
- mov bx,43h*4 ; DS:BX -> int 43h vector if char < 8
- jmp short L03
-
- L02: mov bx,1Fh*4 ; DS:BX -> int 1Fh vector if char >=
- sub al,80h ; put character code in range of tabl
-
- L03: les di,ds:[bx] ; ES:DI -> start of character table
- mul ch ; AX := offset into char def table
- ; (POINTS * char code)
- add di,ax ; DI := addr of char def
-
- pop ds ; DS:SI -> video buffer
-
- ; set up control registers
-
- mov dx,3B4h ; control register I/O port
-
- push cx ; preserve CX
- mov ah,ARGbkgd ; AH := background pixel value
- mov cl,4
- shl ah,cl ; AH bits 4-7 := background pixel val
- or ah,ARGfgd ; AH bits 0-3 := foreground pixel val
- pop cx ; restore CX
-
- mov al,1Ah ; AL := Read/Write Color reg number
- out dx,ax ; set Read/Write Color value
-
- ; mask and set pixels in the video buffer
-
- L20: xor bh,bh
- mov bl,es:[di] ; BX := bit pattern for next pixel ro
- inc di ; increment pointer to char def table
- cmp VAR9bits,0
-
- je L21 ; jump if character is 8 pixels wide
-
- ror bx,1 ; copy lo-order bit of BX into ...
- rcl bl,1 ; hi-order bit
-
- L21: ror bx,cl ; rotate pixels into position
-
- mov ax,5F19h ; AH bit 6 := 1 (mask polarity)
- ; AH bits 4-5 := 01b (write mode 1)
- ; AH bits 0-3 := 1111b (don't care bi
- ; AL := 19h (Read/Write Control reg)
- out dx,ax ; set up Read/Write control reg
-
- or [si],bl ; update foreground pixels
- or [si+1],bh
-
- mov ah,6Fh ; set up write mode 2
- out dx,ax
-
- or bx,VARmask ; BX := background pixel bit pattern
- or [si],bl ; update background pixels
- or [si+1],bh
-
- add si,2000h ; increment to next portion of interl
- jns L22
-
- add si,90-8000h ; increment to first portion of inter
-
- L22: dec ch
- jnz L20
-
- ; restore default InColor register values
-
- mov ax,4019h ; default Read/Write Control reg
- out dx,ax
-
- mov ax,071Ah ; default Read/Write Color reg
- out dx,ax
-
- pop ds ; restore registers and return
- pop di
- pop si
- mov sp,bp
- pop bp
- ret
-
- _DisplayCharInC ENDP
-
- _TEXT ENDS
-
- END
-
- \SAMPCODE\VIDEO\A
- \SAMPCODE\VIDEO\A\A_1.ASM
-
- TITLE 'Listing A-1'
- NAME EstablishPSA
- PAGE 55,132
-
- ;
- ; Name: EstablishPSA
- ;
- ; Function: Establish a Parameter Save Area for the EGA or VGA video BIOS
- ; This save area will reflect the current values of the Attribu
- ; Controller's Palette and Overscan registers.
- ;
- ; Caller: Microsoft C:
- ;
- ; void EstablishPSA();
- ;
-
- SAVE_PTR EQU 0A8h
-
- DGROUP GROUP _DATA
-
- _TEXT SEGMENT byte public 'CODE'
- ASSUME cs:_TEXT,ds:DGROUP,es:DGROUP
-
- PUBLIC _EstablishPSA
- _EstablishPSA PROC near
-
- push bp
- mov bp,sp
- push si
- push di
-
- ; preserve previous SAVE_PTR
-
- push ds
- pop es ; ES -> DGROUP
- mov di,offset DGROUP:Old_SAVE_PTR
-
- mov ax,40h
- mov ds,ax ; DS -> video BIOS data area
- mov si,SAVE_PTR ; DS:SI -> SAVE_PTR
-
- mov cx,4
- rep movsb
-
- ; copy SAVE POINTER table to RAM
-
- lds si,es:Old_SAVE_PTR ; DS:SI -> SAVE POINTER table
- mov di,offset DGROUP:SP_TABLE1
- mov cx,7*4 ; number of bytes to move
- rep movsb
-
- ; update SAVE_PTR with the address of the new SAVE POINTER table
-
- mov ds,ax ; DS -> video BIOS data area
- mov si,SAVE_PTR
- mov word ptr [si],offset DGROUP:SP_TABLE1
- mov [si+2],es
-
- ; update SAVE POINTER table with address of Parameter Save Area
-
- push es
- pop ds ; DS -> DGROUP
-
- mov word ptr SP_TABLE1[4],offset DGROUP:PSA
- mov word ptr SP_TABLE1[6],ds
-
- ; restore registers and exit
-
- pop di
- pop si
- mov sp,bp
- pop bp
- ret
-
- _EstablishPSA ENDP
-
- _TEXT ENDS
-
-
- _DATA SEGMENT word public 'DATA'
-
- Old_SAVE_PTR DD ? ; previous value of SAVE_PTR
-
- SP_TABLE1 DD 7 dup(?) ; RAM copy of SAVE POINTER table
-
- PSA DB 256 dup(0) ; Parameter Save Area
-
- _DATA ENDS
-
- END
-
- \SAMPCODE\VIDEO\A\A_2.ASM
-
- TITLE 'Listing A-2'
- NAME EstablishUPP
- PAGE 55,132
-
- ;
- ; Name: EstablishUPP
- ;
- ; Function: Establish a User Palette Profile Save Area for the VGA video
- ; This save area overrides the usual default palette values for
- ; specified list of video modes.
- ;
- ; Caller: Microsoft C:
- ;
- ; void EstablishUPP();
- ;
-
- SAVE_PTR EQU 0A8h
-
- DGROUP GROUP _DATA
-
- _TEXT SEGMENT byte public 'CODE'
- ASSUME cs:_TEXT,ds:DGROUP,es:DGROUP
-
- PUBLIC _EstablishUPP
- _EstablishUPP PROC near
-
- push bp
- mov bp,sp
- push si
- push di
-
- ; preserve previous SAVE_PTR
-
- push ds
- pop es ; ES -> DGROUP
- mov di,offset DGROUP:Old_SAVE_PTR
-
- mov ax,40h
- mov ds,ax ; DS -> video BIOS data area
- mov si,SAVE_PTR ; DS:SI -> SAVE_PTR
-
- mov cx,4
- rep movsb
-
- ; copy SAVE POINTER table to RAM
-
- lds si,es:Old_SAVE_PTR ; DS:SI -> SAVE POINTER table
- mov di,offset DGROUP:SP_TABLE1
- mov cx,7*4 ; number of bytes to move
- rep movsb
-
- ; update SAVE_PTR with the address of the new SAVE POINTER table
-
- mov ds,ax ; DS -> video BIOS data area
- mov si,SAVE_PTR
- mov word ptr [si],offset DGROUP:SP_TABLE1
- mov [si+2],es
-
- ; copy SECONDARY SAVE POINTER table to RAM
-
- lds si,es:SP_TABLE1[16] ; DS:SI -> SEC SAVE POINTER t
- mov di,offset DGROUP:SP_TABLE2
- mov cx,[si]
- rep movsb
-
- ; update new SAVE POINTER table with address of new SECONDARY SAVE POINTER ta
-
- push es
- pop ds ; DS -> DGROUP
-
- mov word ptr SP_TABLE1[16],offset DGROUP:SP_TABLE2
- mov word ptr SP_TABLE1[18],ds
-
- ; update SECONDARY SAVE POINTER with address of User Palette Profile
-
- mov word ptr SP_TABLE2[10],offset DGROUP:UPP
- mov word ptr SP_TABLE2[12],ds
-
- ; restore registers and exit
-
- pop di
- pop si
- mov sp,bp
- pop bp
- ret
-
- _EstablishUPP ENDP
-
- _TEXT ENDS
-
-
- _DATA SEGMENT word public 'DATA'
-
- Old_SAVE_PTR DD ? ; previous value of SAVE_PTR
-
- SP_TABLE1 DD 7 dup(?) ; copy of SAVE POINTER table
-
- SP_TABLE2 DW ? ; copy of SECONDARY SAVE POINTER tabl
- DD 6 dup(?)
-
- UPP DB 0 ; underlining flag
- DB 0 ; (reserved)
- DW 0 ; (reserved)
- DW 17 ; # of palette & overscan registers
- DW 0 ; first register specified in table
- DW DGROUP:PalTable ; pointer to palette table
- DW seg DGROUP
- DW 0 ; number of video DAC color regs
- DW 0 ; first video DAC register
- DD 0 ; pointer to video DAC color table
- DB 3,0FFh ; list of applicable video modes
-
- PalTable DB 30h,31h,32h,33h,34h,35h,36h,37h ; a custom palette
- DB 00h,01h,02h,03h,04h,05h,14h,07h
- DB 01h ; overscan reg
-
- _DATA ENDS
-
- END
-
- \SAMPCODE\VIDEO\B
- \SAMPCODE\VIDEO\B\B_1.ASM
-
- TITLE 'Listing B-1'
- NAME ScreenDumpCGA
- PAGE 55,132
-
- ;
- ; Name: ScreenDumpCGA
- ;
- ; Function: Screen Dump for CGA 640x200 2-color and 320x200 4-color modes
- ;
- ; Caller: (undefined)
- ;
- ; Notes: The main procedure of this program, ScreenDumpCGA, may be
- ; called from an application program or as part of a TSR
- ; (Terminate-but-Stay Resident) handler for interrupt 5.
- ;
-
- STDPRN = 4 ; MS-DOS standard printer handle
-
-
- DGROUP GROUP _DATA
-
- _TEXT SEGMENT byte public 'CODE'
- ASSUME cs:_TEXT,ds:DGROUP
-
- ;
- ; PrintLine
- ;
- ; Writes one line of characters to the standard printer device. Ignore
- ; errors.
- ;
-
- PrintLine PROC near ; Caller: DS:DX -> data
- ; CX = # of bytes
- mov bx,STDPRN
- mov ah,40h ; INT 21h function 40h: Write
- int 21h
- ret
-
- PrintLine ENDP
-
- ;
- ; PrinterGraphics
- ;
- ; Puts the printer in its "graphics mode." This routine must be
- ; customized for different printers.
- ;
-
- PrinterGraphics PROC near ; Configures Epson MX-80 printer
- ; for 480 dots/line
-
- mov dx,offset DGROUP:EpsonGraphics
- mov cx,3
- call PrintLine
- ret
-
- PrinterGraphics ENDP
-
- ;
- ; PrinterDefault
- ;
- ; Puts the printer in its default (non-graphics) mode. Again, this
- ; routine must be customized for different printers.
- ;
-
- PrinterDefault PROC near ; Configures Epson MX-80 for default
- ; alphanumeric output
-
- mov dx,offset DGROUP:EpsonReset
- mov cx,2
- call PrintLine
- ret
-
- PrinterDefault ENDP
-
- ;
- ; ChopZeroes
- ;
- ; Chops trailing zeros from the printer output buffer.
- ;
-
- ChopZeroes PROC near ; Caller: ES:DI -> buffer
- ; CX = buffer length
- ; Returns: CX = adjusted length
-
- jcxz L01 ; exit if buffer is empty
-
- add di,cx
- dec di ; ES:DI -> last byte in buffer
-
- xor al,al ; AL := 0 (byte to scan for)
-
- std ; scan backwards
- repe scasb
- cld ; restore direction flag
- je L01 ; jump if buffer filled with zeroes
-
- inc cx ; adjust length past last nonzero byt
-
- L01: ret
-
- ChopZeroes ENDP
-
- ;
- ; PrintPixels
- ;
- ; Prints one row of pixels on an Epson MX-80.
- ;
-
- PrintPixels PROC near ; Caller: DI = offset of buffer
- ; CX = buffer length
-
- push ds
- pop es ; ES := DS
-
- push di ; preserve buffer offset
- call ChopZeroes
- push cx ; preserve length
-
- mov word ptr DataHeader+2,cx ; store buffer length
- ; in output data header
- mov dx,offset DGROUP:DataHeader
- mov cx,4
- call PrintLine ; print data header
-
- pop cx ; CX := buffer length
- pop dx ; DX := buffer offset
- call PrintLine ; print the pixels
-
- mov dx,offset DGROUP:CRLF
- mov cx,2
- call PrintLine
-
- ret
-
- PrintPixels ENDP
-
- ;
- ; TranslatePixels
- ;
- ; Copies one printable row of pixels from the video buffer to the
- ; print buffer. This routine can be modified at will to change the
- ; scaling or orientation of the printed image, to interpolate gray-
- ; scale values for color pixels, etc.
- ;
- ; This routine formats the printer buffer for output to an Epson
- ; MX-80. The page is printed sideways, with two horizontal printed pix
- ; for each vertical pixel in the video buffer. Since the CGA screen
- ; is 200 pixels high, the printed output is 400 pixels wide.
- ;
-
- TranslatePixels PROC near ; Caller: SI = video buffer off
- ; ES:DI -> print buffer
-
- push ds ; preserve DS
- mov ds,VideoBufSeg ; DS:SI -> video buffer
-
- add di,398 ; ES:DI -> 2 bytes before end of buff
-
- mov cx,200 ; CX := # of vertical pixels
- mov bx,2000h+1 ; BX := 1st video buffer increment
- mov dx,81-2000h ; DX := 2nd video buffer increment
-
- std ; fill the print buffer backwards
-
- L11: lodsb ; AL := 8 pixels from video buffer
- mov ah,al ; AX := 8 doubled pixels
- stosw ; write them to print buffer
-
- add si,bx ; increment to next interleave of
- xchg bx,dx ; video buffer
-
- loop L11
-
- cld ; clear direction flag
- pop ds ; restore DS
- ret
-
- TranslatePixels ENDP
-
- ;
- ; ScreenDumpCGA
- ;
-
- ScreenDumpCGA PROC near ; Caller: DS = DGROUP
-
- call PrinterGraphics ; configure the printer for graphics
-
- push ds
- pop es ; DS,ES := DGROUP
-
- xor si,si ; SI := offset of start of video buff
-
- L21: push si
- mov di,offset DGROUP:PrintBuf
- call TranslatePixels ; copy one printable row of pixels
-
- mov cx,400
- mov di,offset DGROUP:PrintBuf
- call PrintPixels ; print them
-
- pop si
- inc si
- cmp si,80 ; loop across all 80 columns in
- jb L21 ; the video buffer
-
- call PrinterDefault ; restore the printer to its default
- ; state
- ret
-
- ScreenDumpCGA ENDP
-
- _TEXT ENDS
-
-
- _DATA SEGMENT word public 'DATA'
-
- PrintBuf DB 400 dup(?) ; print output buffer
-
- VideoBufSeg DW 0B800h
-
- EpsonGraphics DB 1Bh,33h,18h
- EpsonReset DB 1Bh,40h
- DataHeader DB 1Bh,4Bh,00h,00h
- CRLF DB 0Dh,0Ah
-
- _DATA ENDS
-
- END
-
- \SAMPCODE\VIDEO\B\B_2.ASM
-
- TITLE 'Listing B-2'
- NAME ScreenDumpEGA
- PAGE 55,132
-
- ;
- ; Name: ScreenDumpEGA
- ;
- ; Function: Screen Dump for EGA 640x350 16-color mode
- ;
- ; Caller: (undefined)
- ;
- ; Notes: The main procedure of this program, ScreenDumpEGA, may be
- ; called from an application program or as part of a TSR
- ; (Terminate-but-Stay Resident) handler for interrupt 5.
- ;
-
- STDPRN = 4 ; MS-DOS standard printer handle
-
-
- DGROUP GROUP _DATA
-
- _TEXT SEGMENT byte public 'CODE'
- ASSUME cs:_TEXT,ds:DGROUP
-
- ;
- ; PrintLine
- ;
- ; Writes one line of characters to the standard printer device. Ignore
- ; errors.
- ;
-
- PrintLine PROC near ; Caller: DS:DX -> data
- ; CX = # of bytes
- mov bx,STDPRN
- mov ah,40h ; INT 21h function 40h: Write
- int 21h
- ret
-
- PrintLine ENDP
-
- ;
- ; PrinterGraphics
- ;
- ; Puts the printer in its "graphics mode." This routine must be
- ; customized for different printers.
- ;
-
- PrinterGraphics PROC near ; Configures Epson MX-80 printer
- ; for 480 dots/line
-
- mov dx,offset DGROUP:EpsonGraphics
- mov cx,3
- call PrintLine
- ret
-
- PrinterGraphics ENDP
-
- ;
- ; PrinterDefault
- ;
- ; Puts the printer in its default (non-graphics) mode. Again, this
- ; routine must be customized for different printers.
- ;
-
- PrinterDefault PROC near ; Configures Epson MX-80 for default
- ; alphanumeric output
-
- mov dx,offset DGROUP:EpsonReset
- mov cx,2
- call PrintLine
- ret
-
- PrinterDefault ENDP
-
- ;
- ; ChopZeroes
- ;
- ; Chops trailing zeros from the printer output buffer.
- ;
-
- ChopZeroes PROC near ; Caller: ES:DI -> buffer
- ; CX = buffer length
- ; Returns: CX = adjusted length
-
- jcxz L01 ; exit if buffer is empty
-
- add di,cx
- dec di ; ES:DI -> last byte in buffer
-
- xor al,al ; AL := 0 (byte to scan for)
-
- std ; scan backwards
- repe scasb
- cld ; restore direction flag
- je L01 ; jump if buffer filled with zeroes
-
- inc cx ; adjust length past last nonzero byt
-
- L01: ret
-
- ChopZeroes ENDP
-
- ;
- ; PrintPixels
- ;
- ; Prints one row of pixels on an Epson MX-80.
- ;
-
- PrintPixels PROC near ; Caller: DI = offset of buffer
- ; CX = buffer length
-
- push ds
- pop es ; ES := DS
-
- push di ; preserve buffer offset
- call ChopZeroes
- push cx ; preserve length
-
- mov word ptr DataHeader+2,cx ; store buffer length
- ; in output data header
- mov dx,offset DGROUP:DataHeader
- mov cx,4
- call PrintLine ; print data header
-
- pop cx ; CX := buffer length
- pop dx ; DX := buffer offset
- call PrintLine ; print the pixels
-
- mov dx,offset DGROUP:CRLF
- mov cx,2
- call PrintLine
-
- ret
-
- PrintPixels ENDP
-
- ;
- ; TranslatePixels
- ;
- ; Copies one printable row of pixels from the video buffer to the
- ; print buffer. This routine can be modified at will to change the
- ; scaling or orientation of the printed image, to interpolate gray-
- ; scale values for color pixels, etc.
- ;
- ; This routine formats the printer buffer for output to an Epson
- ; MX-80. The page is printed sideways, so the printed output is
- ; 350 pixels wide.
- ;
-
- TranslatePixels PROC near ; Caller: SI = video buffer off
- ; ES:DI -> print buffer
-
- push ds ; preserve DS
- mov ds,VideoBufSeg ; DS:SI -> video buffer
-
- add di,349 ; ES:DI -> last byte in print buffer
-
- mov cx,350 ; CX := # of vertical pixels
-
- ; set up the Graphics Controller for read mode 1
-
- mov dx,3CEh ; Graphics Controller I/O port
- mov ax,805h ; AH := 00001000b (read mode 1)
- ; AL := Mode register number
- out dx,ax
-
- mov ax,002 ; AH := 0 (color compare value)
- out dx,ax ; AL := Color Compare register number
-
- mov ax,0F07h ; AH := 00001111b (color don't care m
- out dx,ax ; AL := Color Don't Care register num
-
- ; fill the print buffer; all nonzero pixels in the video buffer are printed
-
- std ; fill the print buffer backwards
-
- L11: lodsb ; AL := 8-pixel color compare value
- ; (bits = 0 if pixel <> 0)
- not al ; AL := 8 printable pixels
- stosb ; store in print buffer
-
- add si,81 ; increment to next row in video buff
- loop L11
-
- cld ; clear direction flag
-
- ; restore Graphics Controller default state
-
- mov ax,5 ; AH := read mode 0, write mode 0
- out dx,ax ; AL := Mode register number
-
- mov ax,7 ; AH := 0 (color don't care mask)
- out dx,ax ; AL := Color Don't Care register num
-
- pop ds ; restore DS
- ret
-
- TranslatePixels ENDP
-
- ;
- ; ScreenDumpEGA
- ;
-
- ScreenDumpEGA PROC near ; Caller: DS = DGROUP
-
- call PrinterGraphics ; configure the printer for graphics
-
- push ds
- pop es ; DS,ES := DGROUP
-
- xor si,si ; SI := offset of start of video buff
-
- L21: push si
- mov di,offset DGROUP:PrintBuf
- call TranslatePixels ; copy one printable row of pixels
-
- mov cx,350
- mov di,offset DGROUP:PrintBuf
- call PrintPixels ; print them
-
- pop si
- inc si
- cmp si,80 ; loop across all 80 columns in
- jb L21 ; the video buffer
-
- call PrinterDefault ; restore the printer to its default
- ; state
- ret
-
- ScreenDumpEGA ENDP
-
- _TEXT ENDS
-
-
- _DATA SEGMENT word public 'DATA'
-
- PrintBuf DB 350 dup(?) ; print output buffer
-
- VideoBufSeg DW 0A000h
-
- EpsonGraphics DB 1Bh,33h,18h
- EpsonReset DB 1Bh,40h
- DataHeader DB 1Bh,4Bh,00h,00h
- CRLF DB 0Dh,0Ah
-
- _DATA ENDS
-
- END
-
- \SAMPCODE\VIDEO\B\B_3.ASM
-
- TITLE 'Listing B-3'
- NAME ScreenDumpAlpha
- PAGE 55,132
-
- ;
- ; Name: ScreenDumpAlpha
- ;
- ; Function: Screen Dump for EGA alphanumeric modes with 350-line resoluti
- ;
- ; Caller: (undefined)
- ;
- ; Notes: The main procedure of this program, ScreenDumpAlpha, may be
- ; called from an application program or as part of a TSR
- ; (Terminate-but-Stay Resident) handler for interrupt 5.
- ;
-
- STDPRN = 4 ; MS-DOS standard printer handle
-
-
- DGROUP GROUP _DATA
-
- _TEXT SEGMENT byte public 'CODE'
- ASSUME cs:_TEXT,ds:DGROUP,es:DGROUP
-
- ;
- ; PrintLine
- ;
- ; Writes one line of characters to the standard printer device. Ignore
- ; errors.
- ;
-
- PrintLine PROC near ; Caller: DS:DX -> data
- ; CX = # of bytes
- mov bx,STDPRN
- mov ah,40h ; INT 21h function 40h: Write
- int 21h
- ret
-
- PrintLine ENDP
-
- ;
- ; PrinterGraphics
- ;
- ; Puts the printer in its "graphics mode." This routine must be
- ; customized for different printers.
- ;
-
- PrinterGraphics PROC near ; Configures Epson MX-80 printer
- ; for 480 dots/line
-
- mov dx,offset DGROUP:EpsonGraphics
- mov cx,3
- call PrintLine
- ret
-
- PrinterGraphics ENDP
-
- ;
- ; PrinterDefault
- ;
- ; Puts the printer in its default (non-graphics) mode. Again, this
- ; routine must be customized for different printers.
- ;
-
- PrinterDefault PROC near ; Configures Epson MX-80 for default
- ; alphanumeric output
-
- mov dx,offset DGROUP:EpsonReset
- mov cx,2
- call PrintLine
- ret
-
- PrinterDefault ENDP
-
- ;
- ; ChopZeroes
- ;
- ; Chops trailing zeros from the printer output buffer.
- ;
-
- ChopZeroes PROC near ; Caller: ES:DI -> buffer
- ; CX = buffer length
- ; Returns: CX = adjusted length
-
- jcxz L01 ; exit if buffer is empty
-
- add di,cx
- dec di ; ES:DI -> last byte in buffer
-
- xor al,al ; AL := 0 (byte to scan for)
-
- std ; scan backwards
- repe scasb
- cld ; restore direction flag
- je L01 ; jump if buffer filled with zeroes
-
- inc cx ; adjust length past last nonzero byt
-
- L01: ret
-
- ChopZeroes ENDP
-
- ;
- ; PrintPixels
- ;
- ; Prints one row of pixels on an Epson MX-80.
- ;
-
- PrintPixels PROC near ; Caller: DI = offset of buffer
- ; CX = buffer length
-
- push ds
- pop es ; ES := DS
-
- push di ; preserve buffer offset
- call ChopZeroes
- push cx ; preserve length
-
- mov word ptr DataHeader+2,cx ; store buffer length
- ; in output data header
- mov dx,offset DGROUP:DataHeader
- mov cx,4
- call PrintLine ; print data header
-
- pop cx ; CX := buffer length
- pop dx ; DX := buffer offset
- call PrintLine ; print the pixels
-
- mov dx,offset DGROUP:CRLF
- mov cx,2
- call PrintLine
-
- ret
-
- PrintPixels ENDP
-
- ;
- ; TranslatePixels
- ;
- ; Copies one printable row of pixels from the first character definitio
- ; table in map 2 to the print buffer.
- ;
- ; This routine formats the printer buffer for output to an Epson
- ; MX-80. The page is printed sideways, so the printed output is
- ; 350 pixels wide.
- ;
-
- TranslatePixels PROC near ; Caller: SI = video buffer off
- ; ES:DI -> print buffer
-
- push ds ; preserve DS
- mov ds,VideoBufSeg ; DS:SI -> video buffer
-
- add di,es:PrintBufSize
- dec di ; ES:DI -> last byte in print buffer
-
- mov dx,3CEh ; Graphics Controller I/O port
-
- ; fill the print buffer
-
- mov cx,es:Rows ; CX := number of character rows
-
- L11: push cx ; preserve CX and SI
- push si
-
- mov ax,0004h ; AH := value for Read Map Select reg
- ; AL := Read Map Select reg number
- out dx,ax ; select map 0 (character codes)
-
- lodsb ; AX := next char code in video buffe
- mov cl,5
- shl ax,cl ; AX := AX * 32
- mov si,ax ; SI := offset of character definitio
- ; in map 2
- mov ax,0204h
- out dx,ax ; select map 2 (bit patterns)
-
- mov cx,es:Points ; CX := size of character definition
-
- L12: cld
- lodsb ; AL := 8-bit pattern from character
- ; definition table
- ; SI := SI + 1
- std
- stosb ; store bit pattern in print buffer
- ; DI := DI - 1
- loop L12 ; loop down character definition
-
- pop si ; restore SI and CX
- pop cx
-
- add si,es:Columns ; DS:SI -> next row of characters
- loop L11 ; loop down character rows
-
- cld ; clear direction flag
-
- pop ds ; restore DS
- ret
-
- TranslatePixels ENDP
-
- ;
- ; ScreenDumpAlpha
- ;
-
- ScreenDumpAlpha PROC near ; Caller: DS = DGROUP
-
- call PrinterGraphics ; configure the printer for graphics
-
- call CGenModeSet ; address EGA memory maps in parallel
- ; map 0 contains character codes
- ; map 2 contains character definitio
-
- ; copy screen dimensions from Video Display Data Area
-
- mov ax,40h
- mov es,ax ; ES -> video BIOS data area
-
- mov al,es:[84h] ; AX := ROWS
- inc ax
- mov Rows,ax
- mov ax,es:[4Ah] ; AX := CRT_COLS
- add ax,ax ; * 2 for proper buffer addressing
- mov Columns,ax
- mov ax,es:[85h] ; AX := POINTS
- mov Points,ax
- mul Rows ; AX := ROWS * POINTS
- mov PrintBufSize,ax
-
- ; print the screen
-
- push ds
- pop es ; DS,ES := DGROUP
-
- xor si,si ; SI := offset of start of video buff
-
- L21: push si
- mov di,offset DGROUP:PrintBuf
- call TranslatePixels ; copy one printable row of pixels
-
- mov cx,PrintBufSize
- mov di,offset DGROUP:PrintBuf
- call PrintPixels ; print them
-
- pop si
- add si,2 ; increment to next character column
- cmp si,Columns ; loop across all character columns
- jb L21
-
- call CGenModeClear ; restore previous alphanumeric mode
-
- call PrinterDefault ; restore the printer to its default
- ; state
- ret
-
- ScreenDumpAlpha ENDP
-
- ;
- ; CGenModeSet (from Chapter 10)
- ;
-
- CGenModeSet PROC near
-
- push si ; preserve these registers
- push cx
-
- cli ; disable interrupts
- mov dx,3C4h ; Sequencer port address
- mov si,offset DGROUP:SetSeqParms
- mov cx,4
-
- L31: lodsw ; AH := value for Sequencer register
- ; AL := register number
- out dx,ax ; program the register
- loop L31
- sti ; enable interrupts
-
- mov dl,0CEh ; DX := 3CEH (Graphics Controller por
- ; address)
- mov si,offset DGROUP:SetGCParms
- mov cx,3
-
- L32: lodsw ; program the Graphics Controller
- out dx,ax
- loop L32
-
- pop cx ; restore registers and return
- pop si
- ret
-
- CGenModeSet ENDP
-
-
- ;
- ; CGenModeClear (from Chapter 10)
- ;
-
- CGenModeClear PROC near
-
- push si ; preserve these registers
- push cx
-
- cli ; disable interrupts
- mov dx,3C4h ; Sequencer port address
- mov si,offset DGROUP:ClearSeqParms
- mov cx,4
-
- L41: lodsw ; AH := value for Sequencer register
- ; AL := register number
- out dx,ax ; program the register
- loop L41
- sti ; enable interrupts
-
- mov dl,0CEh ; DX := 3CEH (Graphics Controller por
- ; address)
- mov si,offset DGROUP:ClearGCParms
- mov cx,3
-
- L42: lodsw ; program the Graphics Controller
- out dx,ax
- loop L42
-
- mov ah,0Fh ; AH := INT 10H function number
- int 10h ; get video mode
-
- cmp al,7
- jne L43 ; jump if not monochrome mode
-
- mov ax,0806h ; program Graphics Controller
- out dx,ax ; to start map at B000:0000
-
- L43: pop cx ; restore registers and return
- pop si
- ret
-
- CGenModeClear ENDP
-
- _TEXT ENDS
-
-
- _DATA SEGMENT word public 'DATA'
-
- PrintBuf DB 400 dup(?) ; print output buffer
-
- VideoBufSeg DW 0A000h
-
- EpsonGraphics DB 1Bh,33h,18h
- EpsonReset DB 1Bh,40h
- DataHeader DB 1Bh,4Bh,00h,00h
- CRLF DB 0Dh,0Ah
-
- Columns DW ? ; number of displayed character colum
- Rows DW ? ; number of displayed character rows
- Points DW ? ; vertical size of character matrix
- PrintBufSize DW ? ; Rows * Points
-
- SetSeqParms DW 0100h ; parameters for CGenModeSet
- DW 0402h
- DW 0704h
- DW 0300h
-
- SetGCParms DW 0204h
- DW 0005h
- DW 0006h
-
- ClearSeqParms DW 0100h ; parameters for CGenModeClear
- DW 0302h
- DW 0304h
- DW 0300h
-
- ClearGCParms DW 0004h
- DW 1005h
- DW 0E06h
-
- _DATA ENDS
-
- END
-
- \SAMPCODE\VIDEO\C
- \SAMPCODE\VIDEO\C\C_2.C
-
- /* Listing C-2 */
-
- main()
- {
- char *SubsystemName();
- char *DisplayName();
-
- static struct
- {
- char Subsystem;
- char Display;
- }
- VIDstruct[2];
-
-
- /* detect video subsystems */
-
- VideoID( VIDstruct );
-
-
- /* show results */
-
- printf( "Video subsystems in this computer:" );
-
- printf( "\n %s (%s)", SubsystemName(VIDstruct[0].Subsystem),
- DisplayName(VIDstruct[0].Display) );
-
- if ( VIDstruct[1].Subsystem )
- printf( "\n %s (%s)", SubsystemName(VIDstruct[1].Subsystem),
- DisplayName(VIDstruct[1].Display) );
- }
-
-
- char *SubsystemName( a )
- char a;
- {
- static char *IBMname[] =
- {
- "(none)",
- "MDA",
- "CGA",
- "EGA",
- "MCGA",
- "VGA"
- };
-
- static char *Hercname[] =
- {
- "HGC",
- "HGC+",
- "InColor"
- };
-
- if ( a & 0x80 )
- return ( Hercname[a & 0x7F] );
- else
- return( IBMname[a] );
- }
-
-
- char *DisplayName( d )
- char d;
- {
- static char *name[] =
- {
- "(none)",
- "MDA-compatible monochrome display",
- "CGA-compatible color display",
- "EGA-compatible color display",
- "PS/2-compatible monochrome display",
- "PS/2-compatible color display"
- };
-
- return( name[d] );
- }
-
- \SAMPCODE\VIDEO\C\C_1.ASM
-
- TITLE 'Listing C-1'
- NAME VideoID
- PAGE 55,132
-
- ;
- ; Name: VideoID
- ;
- ; Function: Detects the presence of various video subsystems and associat
- ; monitors.
- ;
- ; Caller: Microsoft C:
- ;
- ; void VideoID(VIDstruct);
- ;
- ; struct
- ; {
- ; char VideoSubsystem;
- ; char Display;
- ; }
- ; *VIDstruct[2];
- ;
- ; Subsystem ID values:
- ; 0 = (none)
- ; 1 = MDA
- ; 2 = CGA
- ; 3 = EGA
- ; 4 = MCGA
- ; 5 = VGA
- ; 80h = HGC
- ; 81h = HGC+
- ; 82h = Hercules InColor
- ;
- ; Display types: 0 = (none)
- ; 1 = MDA-compatible monochrome
- ; 2 = CGA-compatible color
- ; 3 = EGA-compatible color
- ; 4 = PS/2-compatible monochrome
- ; 5 = PS/2-compatible color
- ;
- ;
- ; The values returned in VIDstruct[0].VideoSubsystem and
- ; VIDstruct[0].Display indicate the currently active subsystem.
- ;
-
- ARGpVID EQU word ptr [bp+4] ; stack frame addressing
-
-
- VIDstruct STRUC ; corresponds to C data structure
-
- Video0Type DB ? ; first subsystem type
- Display0Type DB ? ; display attached to first subsystem
-
- Video1Type DB ? ; second subsystem type
- Display1Type DB ? ; display attached to second subsyste
-
- VIDstruct ENDS
-
-
- Device0 EQU word ptr Video0Type[di]
- Device1 EQU word ptr Video1Type[di]
-
-
- MDA EQU 1 ; subsystem types
- CGA EQU 2
- EGA EQU 3
- MCGA EQU 4
- VGA EQU 5
- HGC EQU 80h
- HGCPlus EQU 81h
- InColor EQU 82h
-
- MDADisplay EQU 1 ; display types
- CGADisplay EQU 2
- EGAColorDisplay EQU 3
- PS2MonoDisplay EQU 4
- PS2ColorDisplay EQU 5
-
- TRUE EQU 1
- FALSE EQU 0
-
-
- DGROUP GROUP _DATA
-
- _TEXT SEGMENT byte public 'CODE'
- ASSUME cs:_TEXT,ds:DGROUP
-
- PUBLIC _VideoID
- _VideoID PROC near
-
- push bp ; preserve caller registers
- mov bp,sp
- push si
- push di
-
- ; initialize the data structure that will contain the results
-
- mov di,ARGpVID ; DS:DI -> start of data structure
-
- mov Device0,0 ; zero these variables
- mov Device1,0
-
- ; look for the various subsystems using the subroutines whose addresses are
- ; tabulated in TestSequence; each subroutine sets flags in TestSequence
- ; to indicate whether subsequent subroutines need to be called
-
- mov byte ptr CGAflag,TRUE
- mov byte ptr EGAflag,TRUE
- mov byte ptr Monoflag,TRUE
-
- mov cx,NumberOfTests
- mov si,offset DGROUP:TestSequence
-
- L01: lodsb ; AL := flag
- test al,al
- lodsw ; AX := subroutine address
- jz L02 ; skip subroutine if flag is false
-
- push si
- push cx
- call ax ; call subroutine to detect subsystem
- pop cx
- pop si
-
- L02: loop L01
-
- ; determine which subsystem is active
-
- call FindActive
-
- pop di ; restore caller registers and return
- pop si
- mov sp,bp
- pop bp
- ret
-
- _VideoID ENDP
-
-
- ;
- ; FindPS2
- ;
- ; This subroutine uses INT 10H function 1Ah to determine the video BIOS
- ; Display Combination Code (DCC) for each video subsystem present.
- ;
-
- FindPS2 PROC near
-
- mov ax,1A00h
- int 10h ; call video BIOS for info
-
- cmp al,1Ah
- jne L13 ; exit if function not supported (i.e
- ; no MCGA or VGA in system)
-
- ; convert BIOS DCCs into specific subsystems & displays
-
- mov cx,bx
- xor bh,bh ; BX := DCC for active subsystem
-
- or ch,ch
- jz L11 ; jump if only one subsystem present
-
- mov bl,ch ; BX := inactive DCC
- add bx,bx
- mov ax,[bx+offset DGROUP:DCCtable]
-
- mov Device1,ax
-
- mov bl,cl
- xor bh,bh ; BX := active DCC
-
- L11: add bx,bx
- mov ax,[bx+offset DGROUP:DCCtable]
-
- mov Device0,ax
-
- ; reset flags for subsystems that have been ruled out
-
- mov byte ptr CGAflag,FALSE
- mov byte ptr EGAflag,FALSE
- mov byte ptr Monoflag,FALSE
-
- lea bx,Video0Type[di] ; if the BIOS reported an MDA ...
- cmp byte ptr [bx],MDA
- je L12
-
- lea bx,Video1Type[di]
- cmp byte ptr [bx],MDA
- jne L13
-
- L12: mov word ptr [bx],0 ; ... Hercules can't be ruled out
- mov byte ptr Monoflag,TRUE
-
- L13: ret
-
- FindPS2 ENDP
-
-
- ;
- ; FindEGA
- ;
- ; Look for an EGA. This is done by making a call to an EGA BIOS function
- ; which doesn't exist in the default (MDA, CGA) BIOS.
-
- FindEGA PROC near ; Caller: AH = flags
- ; Returns: AH = flags
- ; Video0Type and
- ; Display0Type updated
-
- mov bl,10h ; BL := 10h (return EGA info)
- mov ah,12h ; AH := INT 10H function number
- int 10h ; call EGA BIOS for info
- ; if EGA BIOS is present,
- ; BL <> 10H
- ; CL = switch setting
- cmp bl,10h
- je L22 ; jump if EGA BIOS not present
-
- mov al,cl
- shr al,1 ; AL := switches/2
- mov bx,offset DGROUP:EGADisplays
- xlat ; determine display type from switche
- mov ah,al ; AH := display type
- mov al,EGA ; AL := subystem type
- call FoundDevice
-
- cmp ah,MDADisplay
- je L21 ; jump if EGA has a monochrome displa
-
- mov CGAflag,FALSE ; no CGA if EGA has color display
- jmp short L22
-
- L21: mov Monoflag,FALSE ; EGA has a mono display, so MDA and
- ; Hercules are ruled out
- L22: ret
-
- FindEGA ENDP
-
-
- ;
- ; FindCGA
- ;
- ; This is done by looking for the CGA's 6845 CRTC at I/O port 3D4H.
- ;
-
- FindCGA PROC near ; Returns: VIDstruct updated
-
- mov dx,3D4h ; DX := CRTC address port
- call Find6845
- jc L31 ; jump if not present
-
- mov al,CGA
- mov ah,CGADisplay
- call FoundDevice
-
- L31: ret
-
- FindCGA ENDP
-
-
- ;
- ; FindMono
- ;
- ; This is done by looking for the MDA's 6845 CRTC at I/O port 3B4H. If
- ; a 6845 is found, the subroutine distinguishes between an MDA
- ; and a Hercules adapter by monitoring bit 7 of the CRT Status byte.
- ; This bit changes on Hercules adapters but does not change on an MDA.
- ;
- ; The various Hercules adapters are identified by bits 4 through 6 of
- ; the CRT Status value:
- ;
- ; 000b = HGC
- ; 001b = HGC+
- ; 101b = InColor card
- ;
-
- FindMono PROC near ; Returns: VIDstruct updated
-
- mov dx,3B4h ; DX := CRTC address port
- call Find6845
- jc L44 ; jump if not present
-
- mov dl,0BAh ; DX := 3BAh (status port)
- in al,dx
- and al,80h
- mov ah,al ; AH := bit 7 (vertical sync on HGC)
-
- mov cx,8000h ; do this 32768 times
- L41: in al,dx
- and al,80h ; isolate bit 7
- cmp ah,al
- loope L41 ; wait for bit 7 to change
-
- jne L42 ; if bit 7 changed, it's a Hercules
-
- mov al,MDA ; if bit 7 didn't change, it's an MDA
- mov ah,MDADisplay
- call FoundDevice
- jmp short L44
-
- L42: in al,dx
- mov dl,al ; DL := value from status port
-
- mov ah,MDADisplay ; assume it's a monochrome display
-
- mov al,HGC ; look for an HGC
- and dl,01110000b ; mask off bits 4 thru 6
- jz L43
-
- mov al,HGCPlus ; look for an HGC+
- cmp dl,00010000b
- je L43 ; jump if it's an HGC+
-
- mov al,InColor ; it's an InColor card
- mov ah,EGAColorDisplay
-
- L43: call FoundDevice
-
- L44: ret
-
- FindMono ENDP
-
-
- ;
- ; Find6845
- ;
- ; This routine detects the presence of the CRTC on a MDA, CGA or HGC.
- ; The technique is to write and read register 0Fh of the chip (cursor
- ; low). If the same value is read as written, assume the chip is
- ; present at the specified port addr.
- ;
-
- Find6845 PROC near ; Caller: DX = port addr
- ; Returns: cf set if not present
- mov al,0Fh
- out dx,al ; select 6845 reg 0Fh (Cursor Low)
- inc dx
- in al,dx ; AL := current Cursor Low value
- mov ah,al ; preserve in AH
- mov al,66h ; AL := arbitrary value
- out dx,al ; try to write to 6845
-
- mov cx,100h
- L51: loop L51 ; wait for 6845 to respond
-
- in al,dx
- xchg ah,al ; AH := returned value
- ; AL := original value
- out dx,al ; restore original value
-
- cmp ah,66h ; test whether 6845 responded
- je L52 ; jump if it did (cf is reset)
-
- stc ; set carry flag if no 6845 present
-
- L52: ret
-
- Find6845 ENDP
-
-
- ;
- ; FindActive
- ;
- ; This subroutine stores the currently active device as Device0. The
- ; current video mode determines which subsystem is active.
- ;
-
- FindActive PROC near
-
- cmp word ptr Device1,0
- je L63 ; exit if only one subsystem
-
- cmp Video0Type[di],4 ; exit if MCGA or VGA present
- jge L63 ; (INT 10H function 1AH
- cmp Video1Type[di],4 ; already did the work)
- jge L63
-
- mov ah,0Fh
- int 10h ; AL := current BIOS video mo
-
- and al,7
- cmp al,7 ; jump if monochrome
- je L61 ; (mode 7 or 0Fh)
-
- cmp Display0Type[di],MDADisplay
- jne L63 ; exit if Display0 is color
- jmp short L62
-
- L61: cmp Display0Type[di],MDADisplay
- je L63 ; exit if Display0 is monochr
-
- L62: mov ax,Device0 ; make Device0 currently acti
- xchg ax,Device1
- mov Device0,ax
-
- L63: ret
-
- FindActive ENDP
-
-
- ;
- ; FoundDevice
- ;
- ; This routine updates the list of subsystems.
- ;
-
- FoundDevice PROC near ; Caller: AH = display #
- ; AL = subsystem #
- ; Destroys: BX
- lea bx,Video0Type[di]
- cmp byte ptr [bx],0
- je L71 ; jump if 1st subsystem
-
- lea bx,Video1Type[di] ; must be 2nd subsystem
-
- L71: mov [bx],ax ; update list entry
- ret
-
- FoundDevice ENDP
-
- _TEXT ENDS
-
-
- _DATA SEGMENT word public 'DATA'
-
- EGADisplays DB CGADisplay ; 0000b, 0001b (EGA switch values)
- DB EGAColorDisplay ; 0010b, 0011b
- DB MDADisplay ; 0100b, 0101b
- DB CGADisplay ; 0110b, 0111b
- DB EGAColorDisplay ; 1000b, 1001b
- DB MDADisplay ; 1010b, 1011b
-
- DCCtable DB 0,0 ; translate table for INT 10h func 1A
- DB MDA,MDADisplay
- DB CGA,CGADisplay
- DB 0,0
- DB EGA,EGAColorDisplay
- DB EGA,MDADisplay
- DB 0,0
- DB VGA,PS2MonoDisplay
- DB VGA,PS2ColorDisplay
- DB 0,0
- DB MCGA,EGAColorDisplay
- DB MCGA,PS2MonoDisplay
- DB MCGA,PS2ColorDisplay
-
- TestSequence DB TRUE ; this list of flags and addresses
- DW FindPS2 ; determines the order in which this
- ; program looks for the various
- EGAflag DB ? ; subsystems
- DW FindEGA
-
- CGAflag DB ?
- DW FindCGA
-
- Monoflag DB ?
- DW FindMono
-
- NumberOfTests EQU ($-TestSequence)/3
-
- _DATA ENDS
-
- END
-
- \SAMPCODE\VIDEO\DEMO
- \SAMPCODE\VIDEO\DEMO\DEMO.C
-
- /****************************************************************************
- *
- * Name: demo.c
- *
- * Description: This program shows how assembly language video graphics
- * can be built into a high-level program.
- *
- *
- * Notes: Use MAKE DEMO to build this program. You need the
- * following tools:
- *
- * - Microsoft C
- * - Microsoft Macro Assembler
- * - LINK
- *
- *
- * Use an IBM CGA, EGA, or VGA, or compatible hardware.
- *
- *****************************************************************************
-
- #define TRUE 1
- #define FALSE 0
-
- #define CGA 2
- #define EGA 3
- #define MCGA 4
- #define VGA 5
-
- #define Xmax 319
- #define Ymax 199
-
- #define FivePI (double)(5*3.1415926535)
-
- main()
- {
- static struct /* for video ID */
- {
- char Subsystem;
- char Display;
- } VIDstruct[2];
-
- int VIDok = FALSE;
-
- int x,y,Fgd;
- int i;
- double sin();
-
-
- /* verify presence of CGA-compatible hardware */
-
- VideoID( VIDstruct );
-
- for( i=0; (i<=1) && !VIDok; i++ )
- VIDok = ( VIDstruct[i].Subsystem == CGA ) ||
- ( VIDstruct[i].Subsystem == EGA ) ||
- ( VIDstruct[i].Subsystem == MCGA ) ||
- ( VIDstruct[i].Subsystem == VGA );
-
- if( !VIDok )
- {
- printf( "\nCan't find compatible video hardware\n");
- exit( 1 );
- }
-
- /* draw something in 320x200 4-color mode */
-
- SetVmode( 4 ); /* BIOS mode 4 is 320x200 4-color */
-
- Line04( 0, Ymax/2, Xmax, Ymax/2, 3 );
-
- for( x=0; x<=Xmax; x++ )
- {
- y = sin( FivePI * (double)x/(double)Xmax ) * (double)(Ymax/2);
- y += Ymax/2;
-
- Fgd = ( x%10 ? 2 : 3 ); /* select foreground pixel value */
-
- Line04( x, y, x, Ymax/2, Fgd ); /* draw a line or two */
- Line04( x, Ymax-y, x, Ymax/2, 5-Fgd );
- }
- }
-
- \SAMPCODE\VIDEO\DEMO\1_1.ASM
-
- TITLE 'Listing 1-1'
- NAME SetVmode
- PAGE 55,132
-
- ;
- ; Name: SetVmode
- ;
- ; Function: Call IBM PC ROM BIOS to set a video display mode.
- ;
- ; Caller: Microsoft C:
- ;
- ; void SetVmode(n);
- ;
- ; int n; /* video mode */
- ;
-
- ARGn EQU byte ptr [bp+4] ; stack frame addressing
-
- EQUIP_FLAG EQU byte ptr ds:[10h] ; (in Video Display Data Area)
-
- CGAbits EQU 00100000b ; bits for EQUIP_FLAG
- MDAbits EQU 00110000b
-
- _TEXT SEGMENT byte public 'CODE'
- ASSUME cs:_TEXT
-
- PUBLIC _SetVmode
- _SetVmode PROC near
-
- push bp ; preserve caller registers
- mov bp,sp
- push ds
-
- mov ax,40h
- mov ds,ax ; DS -> Video Display Data Area
-
- mov bl,CGAbits ; BL := bits indicating presence of C
-
- mov al,ARGn ; AL := desired video mode number
-
- mov ah,al ; test if desired mode is monochrome
- and ah,7
- cmp ah,7
- jne L01 ; jump if desired mode not 7 or 0Fh
-
- mov bl,MDAbits ; BL := bits indicating presence of M
-
- L01: and EQUIP_FLAG,11001111b
- or EQUIP_FLAG,bl ; set bits in EQUIP_FLAG
-
- xor ah,ah ; AH := 0 (INT 10h function number)
-
- push bp
- int 10h ; call ROM BIOS to set the video mode
- pop bp
-
- pop ds ; restore caller registers and return
- mov sp,bp
- pop bp
- ret
-
- _SetVmode ENDP
-
- _TEXT ENDS
-
- END
-
- \SAMPCODE\VIDEO\DEMO\4_1.ASM
-
- TITLE ''Listing 4-1'
- NAME PixelAddr04
- PAGE 55,132
-
- ;
- ; Name: PixelAddr04
- ;
- ; Function: Determine buffer address of pixel in 320x200 4-color mode
- ;
- ; Caller: AX = y-coordinate (0-199)
- ; BX = x-coordinate (0-319)
- ;
- ; Returns: AH = bit mask
- ; BX = byte offset in buffer
- ; CL = number of bits to shift left
- ; ES = video buffer segment
- ;
-
-
- OriginOffset EQU 0 ; byte offset of (0,0)
- VideoBufferSeg EQU 0B800h
-
- _TEXT SEGMENT byte public 'CODE'
- ASSUME cs:_TEXT
-
- PUBLIC PixelAddr04
- PixelAddr04 PROC near
-
- mov cl,bl ; CL := low-order byte of x
-
- xchg ah,al ; AX := 100h * y
- shr ax,1 ; AL := 80h * (y&1)
- add bh,al ; BX := x + 8000h*(y&1)
- xor al,al ; AX := 100h*(y/2)
- add bx,ax ; BX := x + 8000h*(y&1) + 100h*(y/2)
- shr ax,1
- shr ax,1 ; AX := 40h*(y/2)
- add bx,ax ; BX := x + 8000h*(y&1) + 140h*(y/2)
- shr bx,1
- shr bx,1 ; BX := x/4 + 2000h*(y&1) + 50h*(y/2)
- add bx,OriginOffset ; BX := byte offset in video buffer
-
- mov ax,VideoBufferSeg
- mov es,ax ; ES:BX := byte address of pixel
-
- mov ah,3 ; AH := unshifted bit mask
- and cl,ah ; CL := x & 3
- xor cl,ah ; CL := 3 - (x & 3)
- shl cl,1 ; CL := # bits to shift left
-
- ret
-
- PixelAddr04 ENDP
-
- _TEXT ENDS
-
- END
-
- \SAMPCODE\VIDEO\DEMO\6_5.ASM
-
- TITLE 'Listing 6-5'
- NAME Line04
- PAGE 55,132
-
- ;
- ; Name: Line04
- ;
- ; Function: Draw a line in 320x200 4-color mode
- ;
- ; Caller: Microsoft C:
- ;
- ; void Line04(x1,y1,x2,y2,n);
- ;
- ; int x1,y1,x2,y2; /* pixel coordinates */
- ;
- ; int n; /* pixel value */
- ;
-
- ARGx1 EQU word ptr [bp+4] ; stack frame addressing
- ARGy1 EQU word ptr [bp+6]
- ARGx2 EQU word ptr [bp+8]
- ARGy2 EQU word ptr [bp+10]
- ARGn EQU byte ptr [bp+12]
- VARleafincr EQU word ptr [bp-2]
- VARincr1 EQU word ptr [bp-4]
- VARincr2 EQU word ptr [bp-6]
- VARroutine EQU word ptr [bp-8]
-
- ByteOffsetShift EQU 2 ; used to convert pixels to byte offs
-
- DGROUP GROUP _DATA
-
- _TEXT SEGMENT byte public 'CODE'
- ASSUME cs:_TEXT,ds:DGROUP
-
- EXTRN PixelAddr04:near
-
- PUBLIC _Line04
- _Line04 PROC near
-
- push bp ; preserve caller registers
- mov bp,sp
- sub sp,8 ; stack space for local variables
- push si
- push di
-
-
- mov si,2000h ; increment for video buffer interlea
- mov di,80-2000h ; increment from last to first interl
-
- mov cx,ARGx2
- sub cx,ARGx1 ; CX := x2 - x1
- jz VertLine04 ; jump if vertical line
-
- ; force x1 < x2
-
- jns L01 ; jump if x2 > x1
-
- neg cx ; CX := x1 - x2
-
- mov bx,ARGx2 ; exchange x1 and x2
- xchg bx,ARGx1
- mov ARGx2,bx
-
- mov bx,ARGy2 ; exchange y1 and y2
- xchg bx,ARGy1
- mov ARGy2,bx
-
- ; calculate dy = ABS(y2-y1)
-
- L01: mov bx,ARGy2
- sub bx,ARGy1 ; BX := y2 - y1
- jnz L02
-
- jmp HorizLine04 ; jump if horizontal line
-
- L02: jns L03
-
- neg bx ; BX := y1 - y2
- neg si ; negate increments for buffer interl
- neg di
- xchg si,di ; exchange increments
-
- ; select appropriate routine for slope of line
-
- L03: mov VARleafincr,di ; save increment for buffer interleav
-
- mov VARroutine,offset LoSlopeLine04
- cmp bx,cx
- jle L04 ; jump if dy <= dx (slope <= 1)
- mov VARroutine,offset HiSlopeLine04
- xchg bx,cx ; exchange dy and dx
-
- ; calculate initial decision variable and increments
-
- L04: shl bx,1 ; BX := 2 * dy
- mov VARincr1,bx ; incr1 := 2 * dy
- sub bx,cx
- mov di,bx ; DI := d = 2 * dy - dx
- sub bx,cx
- mov VARincr2,bx ; incr2 := 2 * (dy - dx)
-
- ; calculate first pixel address
-
- push cx ; preserve this register
- mov ax,ARGy1 ; AX := y
- mov bx,ARGx1 ; BX := x
- call PixelAddr04 ; AH := bit mask
- ; ES:BX -> buffer
- ; CL := # bits to shift left
-
- mov al,ARGn ; AL := unshifted pixel value
- shl ax,cl ; AH := bit mask in proper position
- ; AL := pixel value in proper positio
-
- mov dx,ax ; DH := bit mask
- ; DL := pixel value
- not dh ; DH := inverse bit mask
-
- pop cx ; restore this register
- inc cx ; CX := # of pixels to draw
-
- test bx,2000h ; set zero flag if BX in 1st interlea
- jz L05
-
- xchg si,VARleafincr ; exchange increment values if 1st pi
- ; lies in 1st interleave
-
- L05: jmp VARroutine ; jump to appropriate routine for slo
-
-
- ; routine for vertical lines
-
- VertLine04: mov ax,ARGy1 ; AX := y1
- mov bx,ARGy2 ; BX := y2
- mov cx,bx
- sub cx,ax ; CX := dy
- jge L31 ; jump if dy >= 0
-
- neg cx ; force dy >= 0
- mov ax,bx ; AX := y2
-
- L31: inc cx ; CX := # of pixels to draw
- mov bx,ARGx1 ; BX := x
- push cx ; preserve this register
- call PixelAddr04 ; AH := bit mask
- ; ES:BX -> video buffer
- ; CL := # bits to shift left
- mov al,ARGn ; AL := pixel value
- shl ax,cl ; AH := bit mask in proper position
- ; AL := pixel value in proper positio
- not ah ; AH := inverse bit mask
- pop cx ; restore this register
-
- test bx,si ; set zero flag if BX in 1st interlea
- jz L32
-
- xchg si,di ; exchange increment values if 1st pi
- ; lies in 1st interleave
-
- L32: and es:[bx],ah ; zero pixel in buffer
- or es:[bx],al ; set pixel value in buffer
-
- add bx,si ; increment to next portion of interl
- xchg si,di ; toggle between increment values
-
- loop L32
-
- jmp Lexit
-
-
-
- ; routine for horizontal lines (slope = 0)
-
- HorizLine04: mov ax,ARGy1
- mov bx,ARGx1
- call PixelAddr04 ; AH := bit mask
- ; ES:BX -> video buffer
- ; CL := # bits to shift left
- mov di,bx ; ES:DI -> buffer
-
- mov dh,ah
- not dh ; DH := unshifted bit mask for leftmo
- ; byte
- mov dl,0FFh ; DL := unshifted bit mask for
- ; rightmost byte
-
- shl dh,cl ; DH := reverse bit mask for first by
- not dh ; DH := bit mask for first byte
-
- mov cx,ARGx2
- and cl,3
- xor cl,3
- shl cl,1 ; CL := number of bits to shift left
- shl dl,cl ; DL := bit mask for last byte
-
- ; determine byte offset of first and last pixel in the line
-
- mov ax,ARGx2 ; AX := x2
- mov bx,ARGx1 ; BX := x1
-
- mov cl,ByteOffsetShift ; number of bits to shift to
- ; convert pixels to bytes
-
- shr ax,cl ; AX := byte offset of x2
- shr bx,cl ; BX := byte offset of x1
- mov cx,ax
- sub cx,bx ; CX := (# bytes in line) - 1
-
- ; propagate pixel value throughout one byte
-
- mov bx,offset DGROUP:PropagatedPixel
- mov al,ARGn ; AL := pixel value
- xlat ; AL := propagated pixel value
-
- ; set pixels in leftmost byte of the line
-
- or dh,dh
- js L43 ; jump if byte-aligned (x1 is leftmos
- ; pixel in byte)
- or cx,cx
- jnz L42 ; jump if more than one byte in the l
-
- and dl,dh ; bit mask for the line
- jmp short L44
-
- L42: mov ah,al
- and ah,dh ; AH := masked pixel bits
- not dh ; DH := reverse bit mask for 1st byte
- and es:[di],dh ; zero masked pixels in buffer
- or es:[di],ah ; update masked pixels in buffer
- inc di
- dec cx
-
- ; use a fast 8086 machine instruction to draw the remainder of the line
-
- L43: rep stosb ; update all pixels in the line
-
- ; set pixels in the rightmost byte of the line
-
- L44: and al,dl ; AL := masked pixels for last byte
- not dl
- and es:[di],dl ; zero masked pixels in buffer
- or es:[di],al ; update masked pixels in buffer
-
- jmp Lexit
-
-
- ; routine for dy <= dx (slope <= 1) ; ES:BX -> video buffer
- ; CX = #pixels to draw
- ; DH = inverse bit mask
- ; DL = pixel value in proper position
- ; SI = buffer interleave increment
- ; DI = decision variable
- LoSlopeLine04:
-
- L10: mov ah,es:[bx] ; AH := byte from video buffer
-
- L11: and ah,dh ; zero pixel value at current bit off
- or ah,dl ; set pixel value in byte
-
- ror dl,1 ; rotate pixel value
- ror dl,1
- ror dh,1 ; rotate bit mask
- ror dh,1
- jnc L14 ; jump if bit mask rotated to
- ; leftmost pixel position
-
- ; bit mask not shifted out
-
- or di,di ; test sign of d
- jns L12 ; jump if d >= 0
-
- add di,VARincr1 ; d := d + incr1
- loop L11
-
- mov es:[bx],ah ; store remaining pixels in buffer
- jmp short Lexit
-
- L12: add di,VARincr2 ; d := d + incr2
- mov es:[bx],ah ; update buffer
-
- add bx,si ; increment y
- xchg si,VARleafincr ; exchange interleave increment value
-
- loop L10
- jmp short Lexit
-
- ; bit mask shifted out
-
- L14: mov es:[bx],ah ; update buffer
- inc bx ; BX := offset of next byte
-
- or di,di ; test sign of d
- jns L15 ; jump if non-negative
-
- add di,VARincr1 ; d := d + incr1
- loop L10
- jmp short Lexit
-
-
- L15: add di,VARincr2 ; d := d + incr2
-
- add bx,si ; increment y
- xchg si,VARleafincr
-
- loop L10
- jmp short Lexit
-
-
- ; routine for dy > dx (slope > 1) ; ES:BX -> video buffer
- ; CX = #pixels to draw
- ; DH = inverse bit mask
- ; DL = pixel value in proper position
- ; SI = buffer interleave increment
- ; DI = decision variable
- HiSlopeLine04:
-
- L21: and es:[bx],dh ; zero pixel value in video buffer
- or es:[bx],dl ; set pixel value in byte
-
- add bx,si ; increment y
- xchg si,VARleafincr ; exchange interleave increment value
-
- L22: or di,di ; test sign of d
- jns L23 ; jump if d >= 0
-
- add di,VARincr1 ; d := d + incr1
- loop L21
-
- jmp short Lexit
-
-
- L23: add di,VARincr2 ; d := d + incr2
-
- ror dl,1 ; rotate pixel value
- ror dl,1
- ror dh,1 ; rotate bit mask
- ror dh,1
- cmc ; cf set if bit mask not rotated to
- ; leftmost pixel position
-
- adc bx,0 ; BX := offset of next byte
-
- loop L21
-
-
- Lexit: pop di ; restore registers and return
- pop si
- mov sp,bp
- pop bp
- ret
-
- _Line04 ENDP
-
- _TEXT ENDS
-
-
- _DATA SEGMENT word public 'DATA'
-
- PropagatedPixel db 00000000b ; 0
- db 01010101b ; 1
- db 10101010b ; 2
- db 11111111b ; 3
-
- _DATA ENDS
-
- END
-
- \SAMPCODE\VIDEO\DEMO\C_1.ASM
-
- TITLE 'Listing C-1'
- NAME VideoID
- PAGE 55,132
-
- ;
- ; Name: VideoID
- ;
- ; Function: Detects the presence of various video subsystems and associat
- ; monitors.
- ;
- ; Caller: Microsoft C:
- ;
- ; void VideoID(VIDstruct);
- ;
- ; struct
- ; {
- ; char VideoSubsystem;
- ; char Display;
- ; }
- ; *VIDstruct[2];
- ;
- ; Subsystem ID values:
- ; 0 = (none)
- ; 1 = MDA
- ; 2 = CGA
- ; 3 = EGA
- ; 4 = MCGA
- ; 5 = VGA
- ; 80h = HGC
- ; 81h = HGC+
- ; 82h = Hercules InColor
- ;
- ; Display types: 0 = (none)
- ; 1 = MDA-compatible monochrome
- ; 2 = CGA-compatible color
- ; 3 = EGA-compatible color
- ; 4 = PS/2-compatible monochrome
- ; 5 = PS/2-compatible color
- ;
- ;
- ; The values returned in VIDstruct[0].VideoSubsystem and
- ; VIDstruct[0].Display indicate the currently active subsystem.
- ;
-
- ARGpVID EQU word ptr [bp+4] ; stack frame addressing
-
-
- VIDstruct STRUC ; corresponds to C data structure
-
- Video0Type DB ? ; first subsystem type
- Display0Type DB ? ; display attached to first subsystem
-
- Video1Type DB ? ; second subsystem type
- Display1Type DB ? ; display attached to second subsyste
-
- VIDstruct ENDS
-
-
- Device0 EQU word ptr Video0Type[di]
- Device1 EQU word ptr Video1Type[di]
-
-
- MDA EQU 1 ; subsystem types
- CGA EQU 2
- EGA EQU 3
- MCGA EQU 4
- VGA EQU 5
- HGC EQU 80h
- HGCPlus EQU 81h
- InColor EQU 82h
-
- MDADisplay EQU 1 ; display types
- CGADisplay EQU 2
- EGAColorDisplay EQU 3
- PS2MonoDisplay EQU 4
- PS2ColorDisplay EQU 5
-
- TRUE EQU 1
- FALSE EQU 0
-
-
- DGROUP GROUP _DATA
-
- _TEXT SEGMENT byte public 'CODE'
- ASSUME cs:_TEXT,ds:DGROUP
-
- PUBLIC _VideoID
- _VideoID PROC near
-
- push bp ; preserve caller registers
- mov bp,sp
- push si
- push di
-
- ; initialize the data structure that will contain the results
-
- mov di,ARGpVID ; DS:DI -> start of data structure
-
- mov Device0,0 ; zero these variables
- mov Device1,0
-
- ; look for the various subsystems using the subroutines whose addresses are
- ; tabulated in TestSequence; each subroutine sets flags in TestSequence
- ; to indicate whether subsequent subroutines need to be called
-
- mov cx,NumberOfTests
- mov si,offset DGROUP:TestSequence
-
- L01: lodsb ; AL := flag
- test al,al
- lodsw ; AX := subroutine address
- jz L02 ; skip subroutine if flag is false
-
- push si
- push cx
- call ax ; call subroutine to detect subsystem
- pop cx
- pop si
-
- L02: loop L01
-
- ; determine which subsystem is active
-
- call FindActive
-
- pop di ; restore caller registers and return
- pop si
- mov sp,bp
- pop bp
- ret
-
- _VideoID ENDP
-
-
- ;
- ; FindPS2
- ;
- ; This subroutine uses INT 10H function 1Ah to determine the video BIOS
- ; Display Combination Code (DCC) for each video subsystem present.
- ;
-
- FindPS2 PROC near
-
- mov ax,1A00h
- int 10h ; call video BIOS for info
-
- cmp al,1Ah
- jne L13 ; exit if function not supported (i.e
- ; no MCGA or VGA in system)
-
- ; convert BIOS DCCs into specific subsystems & displays
-
- mov cx,bx
- xor bh,bh ; BX := DCC for active subsystem
-
- or ch,ch
- jz L11 ; jump if only one subsystem present
-
- mov bl,ch ; BX := inactive DCC
- add bx,bx
- mov ax,[bx+offset DGROUP:DCCtable]
-
- mov Device1,ax
-
- mov bl,cl
- xor bh,bh ; BX := active DCC
-
- L11: add bx,bx
- mov ax,[bx+offset DGROUP:DCCtable]
-
- mov Device0,ax
-
- ; reset flags for subsystems that have been ruled out
-
- mov byte ptr CGAflag,FALSE
- mov byte ptr EGAflag,FALSE
- mov byte ptr Monoflag,FALSE
-
- lea bx,Video0Type[di] ; if the BIOS reported an MDA ...
- cmp byte ptr [bx],MDA
- je L12
-
- lea bx,Video1Type[di]
- cmp byte ptr [bx],MDA
- jne L13
-
- L12: mov word ptr [bx],0 ; ... Hercules can't be ruled out
- mov byte ptr Monoflag,TRUE
-
- L13: ret
-
- FindPS2 ENDP
-
-
- ;
- ; FindEGA
- ;
- ; Look for an EGA. This is done by making a call to an EGA BIOS function
- ; which doesn't exist in the default (MDA, CGA) BIOS.
-
- FindEGA PROC near ; Caller: AH = flags
- ; Returns: AH = flags
- ; Video0Type and
- ; Display0Type updated
-
- mov bl,10h ; BL := 10h (return EGA info)
- mov ah,12h ; AH := INT 10H function number
- int 10h ; call EGA BIOS for info
- ; if EGA BIOS is present,
- ; BL <> 10H
- ; CL = switch setting
- cmp bl,10h
- je L22 ; jump if EGA BIOS not present
-
- mov al,cl
- shr al,1 ; AL := switches/2
- mov bx,offset DGROUP:EGADisplays
- xlat ; determine display type from switche
- mov ah,al ; AH := display type
- mov al,EGA ; AL := subystem type
- call FoundDevice
-
- cmp ah,MDADisplay
- je L21 ; jump if EGA has a monochrome displa
-
- mov CGAflag,FALSE ; no CGA if EGA has color display
- jmp short L22
-
- L21: mov Monoflag,FALSE ; EGA has a mono display, so MDA and
- ; Hercules are ruled out
- L22: ret
-
- FindEGA ENDP
-
-
- ;
- ; FindCGA
- ;
- ; This is done by looking for the CGA's 6845 CRTC at I/O port 3D4H.
- ;
-
- FindCGA PROC near ; Returns: VIDstruct updated
-
- mov dx,3D4h ; DX := CRTC address port
- call Find6845
- jc L31 ; jump if not present
-
- mov al,CGA
- mov ah,CGADisplay
- call FoundDevice
-
- L31: ret
-
- FindCGA ENDP
-
-
- ;
- ; FindMono
- ;
- ; This is done by looking for the MDA's 6845 CRTC at I/O port 3B4H. If
- ; a 6845 is found, the subroutine distinguishes between an MDA
- ; and a Hercules adapter by monitoring bit 7 of the CRT Status byte.
- ; This bit changes on Hercules adapters but does not change on an MDA.
- ;
- ; The various Hercules adapters are identified by bits 4 through 6 of
- ; the CRT Status value:
- ;
- ; 000b = HGC
- ; 001b = HGC+
- ; 101b = InColor card
- ;
-
- FindMono PROC near ; Returns: VIDstruct updated
-
- mov dx,3B4h ; DX := CRTC address port
- call Find6845
- jc L44 ; jump if not present
-
- mov dl,0BAh ; DX := 3BAh (status port)
- in al,dx
- and al,80h
- mov ah,al ; AH := bit 7 (vertical sync on HGC)
-
- mov cx,8000h ; do this 32768 times
- L41: in al,dx
- and al,80h ; isolate bit 7
- cmp ah,al
- loope L41 ; wait for bit 7 to change
-
- jne L42 ; if bit 7 changed, it's a Hercules
-
- mov al,MDA ; if bit 7 didn't change, it's an MDA
- mov ah,MDADisplay
- call FoundDevice
- jmp short L44
-
- L42: in al,dx
- mov dl,al ; DL := value from status port
-
- mov ah,MDADisplay ; assume it's a monochrome display
-
- mov al,HGC ; look for an HGC
- and dl,01110000b ; mask off bits 4 thru 6
- jz L43
-
- mov al,HGCPlus ; look for an HGC+
- cmp dl,00010000b
- je L43 ; jump if it's an HGC+
-
- mov al,InColor ; it's an InColor card
- mov ah,EGAColorDisplay
-
- L43: call FoundDevice
-
- L44: ret
-
- FindMono ENDP
-
-
- ;
- ; Find6845
- ;
- ; This routine detects the presence of the CRTC on a MDA, CGA or HGC.
- ; The technique is to write and read register 0Fh of the chip (cursor
- ; low). If the same value is read as written, assume the chip is
- ; present at the specified port addr.
- ;
-
- Find6845 PROC near ; Caller: DX = port addr
- ; Returns: cf set if not present
- mov al,0Fh
- out dx,al ; select 6845 reg 0Fh (Cursor Low)
- inc dx
- in al,dx ; AL := current Cursor Low value
- mov ah,al ; preserve in AH
- mov al,66h ; AL := arbitrary value
- out dx,al ; try to write to 6845
-
- mov cx,100h
- L51: loop L51 ; wait for 6845 to respond
-
- in al,dx
- xchg ah,al ; AH := returned value
- ; AL := original value
- out dx,al ; restore original value
-
- cmp ah,66h ; test whether 6845 responded
- je L52 ; jump if it did (cf is reset)
-
- stc ; set carry flag if no 6845 present
-
- L52: ret
-
- Find6845 ENDP
-
-
- ;
- ; FindActive
- ;
- ; This subroutine stores the currently active device as Device0. The
- ; current video mode determines which subsystem is active.
- ;
-
- FindActive PROC near
-
- cmp word ptr Device1,0
- je L63 ; exit if only one subsystem
-
- cmp Video0Type[di],4 ; exit if MCGA or VGA present
- jge L63 ; (INT 10H function 1AH
- cmp Video1Type[di],4 ; already did the work)
- jge L63
-
- mov ah,0Fh
- int 10h ; AL := current BIOS video mo
-
- and al,7
- cmp al,7 ; jump if monochrome
- je L61 ; (mode 7 or 0Fh)
-
- cmp Display0Type[di],MDADisplay
- jne L63 ; exit if Display0 is color
- jmp short L62
-
- L61: cmp Display0Type[di],MDADisplay
- je L63 ; exit if Display0 is monochr
-
- L62: mov ax,Device0 ; make Device0 currently acti
- xchg ax,Device1
- mov Device0,ax
-
- L63: ret
-
- FindActive ENDP
-
-
- ;
- ; FoundDevice
- ;
- ; This routine updates the list of subsystems.
- ;
-
- FoundDevice PROC near ; Caller: AH = display #
- ; AL = subsystem #
- ; Destroys: BX
- lea bx,Video0Type[di]
- cmp byte ptr [bx],0
- je L71 ; jump if 1st subsystem
-
- lea bx,Video1Type[di] ; must be 2nd subsystem
-
- L71: mov [bx],ax ; update list entry
- ret
-
- FoundDevice ENDP
-
- _TEXT ENDS
-
-
- _DATA SEGMENT word public 'DATA'
-
- EGADisplays DB CGADisplay ; 0000b, 0001b (EGA switch values)
- DB EGAColorDisplay ; 0010b, 0011b
- DB MDADisplay ; 0100b, 0101b
- DB CGADisplay ; 0110b, 0111b
- DB EGAColorDisplay ; 1000b, 1001b
- DB MDADisplay ; 1010b, 1011b
-
- DCCtable DB 0,0 ; translate table for INT 10h func 1A
- DB MDA,MDADisplay
- DB CGA,CGADisplay
- DB 0,0
- DB EGA,EGAColorDisplay
- DB EGA,MDADisplay
- DB 0,0
- DB VGA,PS2MonoDisplay
- DB VGA,PS2ColorDisplay
- DB 0,0
- DB MCGA,EGAColorDisplay
- DB MCGA,PS2MonoDisplay
- DB MCGA,PS2ColorDisplay
-
- TestSequence DB TRUE ; this list of flags and addresses
- DW FindPS2 ; determines the order in which this
- ; program looks for the various
- EGAflag DB TRUE ; subsystems
- DW FindEGA
-
- CGAflag DB TRUE
- DW FindCGA
-
- Monoflag DB TRUE
- DW FindMono
-
- NumberOfTests EQU ($-TestSequence)/3
-
- _DATA ENDS
-
- END
-
-
-