100 REM ************************************************************ 110 REM 120 REM FILENAME ROUTDEMI.BAS 130 REM WRITTEN BY GARY PEEK 140 REM LAST UPDATE 01/13/93 150 REM 160 REM DESCRIPTION DEMONSTRATES HOW TO USE ASSEMBLY LANGUAGE SUBROUTINE 170 REM TO CALL INTERRUPTS AND MOUSE INTERFACE. 180 REM REQUIRES EGA OR VGA MONITOR. 190 REM ************************************************************ 200 KEY OFF:FOR A=1 TO 10:KEY A,"":NEXT A:CLS 210 REM ----- 940 GOSUB 65250:REM LOAD ASSEMBLY LANGUAGE SUBROUTINE 950 GOSUB 62000:REM GET VIDEO MONITOR TYPE 970 IF MONITOR$="EGA" OR MONITOR$="VGA" THEN SCREEN 9:CLS:GOTO 1000 980 BEEP:CLS:PRINT "THIS PROGRAM REQUIRES AN EGA OR VGA MONITOR" 985 IN$=INKEY$:IF IN$="" THEN 985 ELSE END 990 REM ----- 1000 GOSUB 63000:REM MOUSE RESET AND STATUS 1010 IF STATUS=-1 THEN 1020 1015 BEEP:CLS:PRINT "MOUSE DRIVER NOT INSTALLED OR MOUSE NOT FOUND" 1017 IN$=INKEY$:IF IN$="" THEN 1017 ELSE END 1018 REM ----- 1020 GOSUB 63800:REM SET MOUSE GRAPHICS CURSOR 1025 TOPLIMIT=48:BOTTOMLIMIT=328:LEFTLIMIT=142:RIGHTLIMIT=497 1030 GOSUB 63700:REM SET MOUSE CURSOR LIM. 1035 XSENS=30:YSENS=30:THRESHOLD=50:GOSUB 64600:REM SET MOUSE SENSITIVITY 1040 REM ----- 1045 GRAFCOLOR=15:GRIDCOLOR=3 1050 LINEWIDTH$="NARROW" 1060 REM ----- 1210 GOSUB 6000:REM DRAW BORDERS 1220 REM ----- 1230 GOSUB 63100:REM MOUSE SHOW CURSOR 1980 REM --------------------------------------------------------------------- 1990 REM ----- MAIN LOOP 2000 OLDX=X:OLDY=Y 2010 GOSUB 63300:REM GET CURSOR POSITION AND BUTTONS 2020 REM ----- CHECK KEYBOARD 2030 IN$=INKEY$:IF IN$="" THEN 2180 2040 IF IN$=CHR$(0)+CHR$(75) THEN X=X-1:GOSUB 63400:REM LEFT 2050 IF IN$=CHR$(0)+CHR$(77) THEN X=X+1:GOSUB 63400:REM RIGHT 2060 IF IN$=CHR$(0)+CHR$(72) THEN Y=Y-1:GOSUB 63400:REM UP 2070 IF IN$=CHR$(0)+CHR$(80) THEN Y=Y+1:GOSUB 63400:REM DOWN 2110 IF IN$="W" THEN LINEWIDTH$="WIDE " 2120 IF IN$="N" THEN LINEWIDTH$="NARROW" 2130 IF IN$="D" THEN INS=-1:DEL=0 2140 IF IN$="E" THEN DEL=-1:INS=0 2150 IF IN$="C" THEN INS=0:DEL=0 2160 IF IN$=CHR$(27) THEN CLS:END 2170 REM ----- DISPLAY SOME STUFF 2180 COLOR 15,0:LOCATE 25,2:PRINT "X =";X;" Y =";Y;" "; 2190 IF LEFT OR INS THEN LOCATE 25,37:COLOR 10,0:PRINT "DRAWING"; 2200 IF RIGHT OR DEL THEN LOCATE 25,37:COLOR 12,0:PRINT "ERASING"; 2210 IF NOT RIGHT AND NOT LEFT AND NOT INS AND NOT DEL THEN LOCATE 25,37:PRINT " "; 2215 COLOR 15,0:LOCATE 25,63:PRINT "LINE WIDTH=";LINEWIDTH$; 2220 REM ----- SKIP THE REST IF WE HAVE NOT MOVED 2230 IF X=OLDX AND Y=OLDY THEN 2000 2240 REM ----- SET OR ERASE POINTS 2250 IF NOT LEFT AND NOT RIGHT AND NOT INS AND NOT DEL THEN 2000 2260 IF LEFT OR INS THEN POINTCOLOR=GRAFCOLOR 2270 IF RIGHT OR DEL THEN POINTCOLOR=0 2280 GOSUB 63200:REM HIDE MOUSE CURSOR 2290 PSET(X,Y),POINTCOLOR 2300 IF LINEWIDTH$="NARROW" THEN 2390 2310 PSET(X-1,Y-1),POINTCOLOR 2320 PSET(X+1,Y+1),POINTCOLOR 2330 PSET(X+1,Y),POINTCOLOR 2340 PSET(X-1,Y),POINTCOLOR 2350 PSET(X,Y+1),POINTCOLOR 2360 PSET(X,Y-1),POINTCOLOR 2370 PSET(X-1,Y+1),POINTCOLOR 2380 PSET(X+1,Y-1),POINTCOLOR 2390 GOSUB 63100:REM SHOW MOUSE CURSOR 2400 GOTO 2000 2410 REM 2420 REM ----- END OF MAIN LOOP 5990 REM -------------------------------------------------------------------- 6000 CLS:REM ----- PRINT SOME MESSAGES 6005 LOCATE 1,2:PRINT "Mouse:";:LOCATE 1,66:PRINT "CAPITAL Keys:"; 6010 LOCATE 2,2:PRINT "Left button to draw"; 6020 LOCATE 2,36:PRINT "D=draw, E=erase, C=cancel, W=wide, N=narrow,"; 6030 LOCATE 3,2:PRINT "Right button to erase"; 6050 REM ----- DRAW GRID 6060 FOR YY=48 TO 328 STEP 56:LINE(142,YY)-(497,YY),GRIDCOLOR:NEXT YY 6070 FOR XX=142 TO 497 STEP 71:LINE (XX,48)-(XX,328),GRIDCOLOR:NEXT XX 6080 REM ----- PRINT SOME MESSAGES 6100 COLOR 7,0:LOCATE 4,1:PRINT "----------------"; 6101 COLOR 7,0:LOCATE 24,1:PRINT "----------------"; 6102 COLOR 7,0:LOCATE 4,65:PRINT "----------------"; 6103 COLOR 7,0:LOCATE 24,65:PRINT "---------------"; 6104 REM ----- 6105 LOCATE 5,1:PRINT ""; 6110 LOCATE 6,1:PRINT ""; 6115 LOCATE 7,1:PRINT ""; 6117 LOCATE 8,1:PRINT ""; 6120 LOCATE 9,1:PRINT ""; 6125 LOCATE 10,1:PRINT ""; 6130 LOCATE 11,1:PRINT ""; 6132 LOCATE 12,1:PRINT ""; 6135 LOCATE 13,1:PRINT ""; 6140 LOCATE 14,1:PRINT ""; 6141 LOCATE 15,1:PRINT ""; 6142 LOCATE 16,1:PRINT ""; 6160 LOCATE 17,1:PRINT ""; 6165 LOCATE 18,1:PRINT ""; 6170 LOCATE 19,1:PRINT ""; 6175 LOCATE 20,1:PRINT ""; 6180 LOCATE 21,1:PRINT ""; 6185 LOCATE 22,1:PRINT ""; 6190 LOCATE 23,1:PRINT ""; 6197 LOCATE 5,65:PRINT ""; 6200 LOCATE 6,65:PRINT ""; 6205 LOCATE 7,65:PRINT ""; 6207 LOCATE 8,65:PRINT ""; 6210 LOCATE 9,65:PRINT ""; 6215 LOCATE 10,65:PRINT ""; 6220 LOCATE 11,65:PRINT ""; 6222 LOCATE 12,65:PRINT ""; 6225 LOCATE 13,65:PRINT ""; 6230 LOCATE 14,65:PRINT ""; 6235 LOCATE 15,65:PRINT ""; 6240 LOCATE 16,65:PRINT ""; 6242 LOCATE 17,65:PRINT ""; 6243 LOCATE 18,65:PRINT ""; 6244 LOCATE 19,65:PRINT ""; 6245 LOCATE 20,65:PRINT ""; 6246 LOCATE 21,65:PRINT ""; 6247 LOCATE 22,65:PRINT ""; 6248 LOCATE 23,65:PRINT ""; 6265 RETURN 61960 REM ******************************************************************** 61965 REM ------------------------- GET MONITOR ------------------------------ 61970 REM 61975 REM This routine finds the type of video monitor hardware installed. 61980 REM It requires that the assembly language interface be installed. 61985 REM 61990 REM exit with - MONITOR$="MONO","HERC","CGA","EGA",or"VGA", monitor used 61995 REM 62000 DEF SEG=0:STATUS=PEEK(&H463):DEF SEG 62005 IF STATUS<>&HB4 THEN 62040 62010 STATUS=(INP(&H3BA) AND &H80) 62015 FOR DELAYLOOP=1 TO 30000 62020 IF (INP(&H3BA) AND &H80)<>STATUS THEN MONITOR$="HERC":RETURN 62025 NEXT DELAYLOOP 62030 MONITOR$="MONO":RETURN 62035 REM ----- 62040 REGAX%=&H1A00 62045 INTERRUPT%=&H10:GOSUB 65000:REM CALL ASM 62050 IF (REGAX% AND &HFF)=&H1A THEN MONITOR$="VGA":RETURN 62055 REM ----- 62060 REGAX%=&H1200:REGBX%=&H10 62065 INTERRUPT%=&H10:GOSUB 65000:REM CALL ASM 62070 IF (REGBX% AND &HFF)=&H10 THEN MONITOR$="CGA":RETURN 62075 REM ----- 62080 MONITOR$="EGA":RETURN 62085 REM 62110 REM ******************************************************************** 62115 REM ------------------------- MOUSE ROUTINES --------------------------- 62120 REM 62125 REM The following routines provide access to some mouse function calls. 62130 REM They require that the assembly language interface be installed. 62135 REM 62140 REM 62145 REM 62150 REM 62155 REM 63000 hardware reset and status 62160 REM 63100 show cursor 62165 REM 63200 hide cursor 62170 REM 63300 get button status and mouse position 62175 REM 63400 set cursor position 62180 REM 63500 get button press info 62185 REM 63600 get button release info 62190 REM 63700 set cursor limits 62195 REM 63800 set graphics cursor 62200 REM 62205 REM 64000 set text cursor 62210 REM 64100 read motion counters 62215 REM 64200 62220 REM 64300 62225 REM 64400 62230 REM 64500 62235 REM 64600 set sensitivity and double speed 62240 REM 64700 62245 REM 64800 62250 REM 64900 get driver version, type, IRQ 62255 REM 62260 REM 62265 REM 62270 REM ******************************************************************** 62275 REM ------------------- MOUSE - RESET AND STATUS ----------------------- 62280 REM 62285 REM exit with - STATUS = -1 if mouse found and reset, otherwise 0 62290 REM BUTTONS = number of buttons 62295 REM 63000 REGAX%=0:REGBX%=0:REGCX%=0:REGDX%=0 63005 INTERRUPT%=&H33:GOSUB 65000:REM CALL ASM 63010 STATUS=REGAX%:BUTTONS=REGBX% 63015 RETURN 63020 REM 63085 REM ******************************************************************** 63090 REM ------------------- MOUSE - SHOW CURSOR ---------------------------- 63095 REM 63100 REGAX%=1:INTERRUPT%=&H33:GOSUB 65000:REM CALL ASM 63105 RETURN 63110 REM 63185 REM ******************************************************************** 63190 REM ------------------- MOUSE - HIDE CURSOR ---------------------------- 63195 REM 63200 REGAX%=2:INTERRUPT%=&H33:GOSUB 65000:REM CALL ASM 63205 RETURN 63210 REM 63270 REM ******************************************************************** 63275 REM ---------- MOUSE - GET CURSOR POSITION AND BUTTON STATUS ----------- 63280 REM 63285 REM exit with - X and Y = cursor coordinates 63290 REM LEFT, RIGHT, or BOTH = true for buttons pressed 63295 REM 63300 REGAX%=3 63305 INTERRUPT%=&H33:GOSUB 65000:REM CALL ASM 63310 X=REGCX%:Y=REGDX% 63315 REM ----- 63320 LEFT=0:RIGHT=0:BOTH=0 63325 IF (REGBX% AND 7)=0 THEN RETURN 63330 T=TIMER 63335 IF TIMER32767 THEN BINVALUE=BINVALUE-65536! 63845 MOUSECURSOR%(CURSLOOP%)=BINVALUE 63850 NEXT CURSLOOP% 63855 REM 63860 REGAX%=9:REM SET GRAPHICS CURSOR 63865 REGBX%=8:REM HORIZONTAL HOT SPOT 63870 REGCX%=7:REM VERTICAL HOT SPOT 63875 REGDX%=VARPTR(MOUSECURSOR%(1)) :REM VERSION 6.25 AND LATER 63880 INTERRUPT%=&H33:GOSUB 65000:REM CALL ASM 63885 RETURN 63890 REM 63895 REM ----- SCREEN MASK 63900 DATA "1111111111111111" 63901 DATA "1111111000111111" 63902 DATA "1111111010111111" 63903 DATA "1111111010111111" 63904 DATA "1111111010111111" 63905 DATA "1111111010111111" 63906 DATA "1000000111000000" 63907 DATA "1011111111111110" 63908 DATA "1000000111000000" 63909 DATA "1111111010111111" 63910 DATA "1111111010111111" 63911 DATA "1111111010111111" 63912 DATA "1111111010111111" 63913 DATA "1111111000111111" 63914 DATA "1111111111111111" 63915 DATA "1111111111111111" 63916 REM ----- CURSOR MASK 63917 DATA "0000000000000000" 63918 DATA "0000000111000000" 63919 DATA "0000000101000000" 63920 DATA "0000000101000000" 63921 DATA "0000000101000000" 63922 DATA "0000000101000000" 63923 DATA "0111111000111111" 63924 DATA "0100000000000001" 63925 DATA "0111111000111111" 63926 DATA "0000000101000000" 63927 DATA "0000000101000000" 63928 DATA "0000000101000000" 63929 DATA "0000000101000000" 63930 DATA "0000000111000000" 63931 DATA "0000000000000000" 63932 DATA "0000000000000000" 63933 REM 63935 REM 63985 REM ******************************************************************** 63990 REM ------------------- MOUSE - SET SOFTWARE TEXT CURSOR --------------- 63995 REM 64000 REGAX%=10:REM SET TEXT CURSOR 64005 REGBX%=0:REM SOFTWARE TEXT CURSOR 64010 REGCX%=&H77FF :REM TRY &HFFFF 64015 REGDX%=&H7700 64020 INTERRUPT%=&H33:GOSUB 65000:REM CALL ASM 64025 RETURN 64030 REM 64035 REM 64075 REM ******************************************************************** 64080 REM ------------------- MOUSE - READ MOTION COUNTERS ------------------- 64085 REM 64090 REM exit with - XMICKEY, YMICKEY, mickey counts since last called 64095 REM 64100 REGAX%=11 64105 INTERRUPT%=&H33:GOSUB 65000:REM CALL ASM 64110 XMICKEY=REGCX%:YMICKEY=REGDX% 64115 RETURN 64120 REM 64125 REM 64565 REM ******************************************************************** 64570 REM ------------------- MOUSE - SET SENSITIVITY ------------------------ 64575 REM 64580 REM enter with - XSENS, YSENS = 1 to 100, horiz. and vert. sensitivity 64585 REM THRESHOLD = 0 to 100, threshold for double speed 64590 REM 64595 REM 64600 REGAX%=26:REGBX%=XSENS:REGCX%=YSENS:REGDX%=THRESHOLD 64605 INTERRUPT%=&H33:GOSUB 65000:REM CALL ASM 64610 RETURN 64615 REM 64620 REM 64865 REM ******************************************************************** 64870 REM ------------------- MOUSE - GET VERSION, TYPE, IRQ ----------------- 64875 REM 64880 REM exit with - VERSION = mouse driver version number 64885 REM MOUSETYPE = type of mouse 64890 REM IRQ = interrupt request 64895 REM 64900 REGAX%=36 64905 INTERRUPT%=&H33:GOSUB 65000:REM CALL ASM 64910 VERSION=VAL(HEX$(INT(REGBX%/256))+"."+HEX$(REGBX% MOD 256)) 64915 MOUSETYPE=INT(REGCX%/256):IRQ=REGCX% MOD 256 64920 RETURN 64925 REM 64930 REM ******************************************************************** 64935 REM ----------- SET UP AND CALL ASSEMBLY LANGUAGE SUBROUTINE ----------- 64940 REM 64945 REM This routine sets up and calls a previously loaded general purpose 64950 REM assembly language subroutine to access DOS and other interrupts. 64955 REM Knowledge of how to call these interrupts is required. Interrupts 64960 REM that use only registers AX,BX,CX,DX are the only ones supported. 64965 REM 64970 REM enter with - REGAX%,REGBX%,REGCX%,REGDX% 64975 REM (registers required for calling the interrupt) 64980 REM INTERRUPT%, the interrupt to call 64985 REM exit with - REGAX%,REGBX%,REGCX%,REGDX% 64990 REM (registers after returning from the interrupt) 64995 REM 65000 DEF SEG=&H4B :REM POINT TO SEGMENT 65005 POKE 33,INTERRUPT% :REM FILL IN THE INTERRUPT TO CALL 65010 POKE 4,INT(REGAX%/256):POKE 3,REGAX% MOD 256 :REM FILL IN THE REGISTERS 65015 POKE 6,INT(REGBX%/256):POKE 5,REGBX% MOD 256 65020 POKE 8,INT(REGCX%/256):POKE 7,REGCX% MOD 256 65025 POKE 10,INT(REGDX%/256):POKE 9,REGDX% MOD 256 65030 ASMSUB=0:CALL ASMSUB :REM USE THIS LINE FOR THE INTERPRETER 65035 REM CALL ABSOLUTE(0) :REM USE THIS LINE FOR THE COMPILER 65040 REGAX=(PEEK(4)*256)+PEEK(3):IF REGAX>32767 THEN REGAX=REGAX-65536! 65045 REGAX%=REGAX 65050 REGBX=(PEEK(6)*256)+PEEK(5):IF REGBX>32767 THEN REGBX=REGBX-65536! 65055 REGBX%=REGBX 65060 REGCX=(PEEK(8)*256)+PEEK(7):IF REGCX>32767 THEN REGCX=REGCX-65536! 65065 REGCX%=REGCX 65070 REGDX=(PEEK(10)*256)+PEEK(9):IF REGDX>32767 THEN REGDX=REGDX-65536! 65075 REGDX%=REGDX 65080 DEF SEG:RETURN :REM RETURN TO BASIC SEGMENT 65085 REM 65090 REM 65095 REM ******************************************************************** 65100 REM ---------------- LOAD ASSEMBLY LANGUAGE SUBROUTINE ----------------- 65105 REM 65110 REM This routine loads the following general purpose assembly language 65115 REM subroutine to access DOS and other interrupts. It is loaded into 65120 REM the area just below the DOS inter-program communication area. 65125 REM 65130 REM ASSUME CS:CODE 65135 REM JMP HERE 65140 REM 65145 REM WORKA DW 0 ;STORAGE FOR REGISTERS- 65150 REM WORKB DW 0 ;BASIC WRITES THESE, 65155 REM WORKC DW 0 ;THEN THE INTERRUPT% HAPPENS, 65160 REM WORKD DW 0 ;THEN BASIC READS THESE 65165 REM 65170 REM HERE: MOV AX,WORKA ;GET PARM 1 FROM BASIC 65175 REM MOV BX,WORKB ;GET PARM 2 FROM BASIC 65180 REM MOV CX,WORKC ;GET PARM 3 FROM BASIC 65185 REM MOV DX,WORKD ;GET PARM 4 FROM BASIC 65190 REM PUSH DS ;MAKE ES THE SAME AS DS 65195 REM POP ES 65200 REM INT 21H ;DOS (or other) INTERRUPT 65205 REM MOV WORKA,AX ;SEND PARM 1 TO BASIC 65210 REM MOV WORKB,BX ;SEND PARM 2 TO BASIC 65215 REM MOV WORKC,CX ;SEND PARM 3 TO BASIC 65220 REM MOV WORKD,DX ;SEND PARM 4 TO BASIC 65225 REM DB 0CBH ;ASSEMBLER REJECTS "RETF" 65230 REM 65235 REM CODE ENDS 65240 REM END 65245 REM 65250 DEF SEG=&H4B:RESTORE 65270 65255 FOR I=0 TO 53:READ B:POKE I,B:NEXT I 65260 DEF SEG:RETURN 65265 REM ----- 65270 DATA &HEB,&H09,&H90 65275 DATA &H00,&H00,&H00,&H00,&H00,&H00,&H00,&H00 :REM REGISTERS AX-DX 65280 DATA &H2E,&HA1,&H03,&H00 65285 DATA &H2E,&H8B,&H1E,&H05,&H00 65290 DATA &H2E,&H8B,&H0E,&H07,&H00 65295 DATA &H2E,&H8B,&H16,&H09,&H00 65300 DATA &H1E,&H07 65305 DATA &HCD,&H21 :REM INTERRUPT% XX 65310 DATA &H2E,&HA3,&H03,&H00 65315 DATA &H2E,&H89,&H1E,&H5,&H0 65320 DATA &H2E,&H89,&H0E,&H07,&H00 65325 DATA &H2E,&H89,&H16,&H09,&H00 65330 DATA &HCB :REM RETF