Advanced Revelation Assembler Interface Module - Yves Pattyn, Technical Manager, Distribase, France
Published By | Date | Version | Knowledge Level | Keywords |
---|---|---|---|---|
Sprezzatura Ltd | 01 AUG 1992 | 2.12+ | EXPERT | ASSEMBLER, MOUSE, TEMPLATE.ASM |
Although you can solve most of your problems in good old R/Basic, you might sometimes need to do something really special. The little examples that I'll treat in this article came from a simple question: `Could I manage the mouse in Advanced Revelation, through R/Basic programming?'.
Since no tools (paint, window, menus etc.) offer full mouse-support, don't expect them to do it with the routines listed below! You'll have that in the 3.0 version from RevTI themselves!
We'll see how to develop two little programs called MOUSE and MPOS in assembler and make them $MOUSE and $MPOS in your own BP file. In figure 1 you can see the general scheme for doing this. First you should use the TEMPLATE.ASM source code you find on the Revelation Assembly Interface disk. Copy this file to the file you'll use as your source-code file. Enter your own assembler code in the area reserved for that purpose and assemble the code. Link it, make it a .BIN file with EXE2BIN and grab it into your AREV with the FIXASM (which you'll find on the Interface disk as well).
ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ ; TEMPLATE.ASM ³ ³ ; MYPROG.ASM ³ ³ ... ³ ³ ... ³ ³ RET ÃÄÄÄÄÄÄ´ mov ax,01h ³ ³ ENDS ³ ³ ... (Your code) ³ ³ ³ ³ RET ³ ³ ³ ³ ENDS ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ÀÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÙ ³ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ TLINK MYPROG ³ ³ TASM MYPROG ³ ³ (Gives MYPROG.EXE) ÃÄÄÄÄÄÄ´ (Gives MYPROG.OBJ) ³ ÀÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÙ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ³ ÚÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ EXE2BIN MYPROG ³ ³ In AREV now: ³ ³ (Gives MYPROG.BIN) ÃÄÄÄÄÄÄ´ RUN BP FIXASM ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ³ answer the questions ³ ³ (Gives $MYPROG in BP)³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
Figure 1
As you might have noticed, I was using the TASM (Turbo Assembler, Borland), which gave no compatibility problems for Advanced Revelation.
Let's first take a look at the MOUSE.ASM.
1 ; 2 ; TITLE: MOUSE.ASM 3 ; 4 ; DESCRIPTION: Simple subroutine to turn mousepointer on 5 ; and off from an R/Basic call. 6 ; 7 ; DATE: July, 1992 8 ; 9 ; VERSION: 1.0 10 ; 11 ; No Copyright 12 ; Please feel free to copy the code for your personal use 13 ; 14 PAGE 60,132 15 TITLE MOUSE 16 CSEG SEGMENT PARA PUBLIC 'CODE' 17 ASSUME CS:CSEG 18 ROUTINE PROC FAR 19 ORG 0 ; START AT ADDRESS ZERO 20 DB 'ASSM' ; 4 BYTE FLAG 21 DB 2 ; IDENTIFY AS ASSEMBLER ROUTINE 22 NO_ARGS DB 1 ; NUMBER OF ARGUMENTS PASSED 23 NO_COMS DW 0 ; NUMBER OF COMMON VARIABLES 24 DW 0 ; UNUSED 25 FUNCTION DD 0 ; ADDRESS FOR REV FUNCTION CALLS 26 mov ah,11h 27 mov al,00h 28 mov dx,01h 29 CALL FUNCTION ; get first arg from arev 30 mov ax,ooh 31 cmp ax,cx 32 jne TurnOn 33 jmp TurnOff 34 TurnOn: 35 mov ax,0000h 36 int 33h 37 mov dx,02h 38 mov cx,bx 39 mov ah,12h 40 mov al,00h 41 CALL FUNCTION ; send nbr of buttons to Arev 2nd param 42 mov ax,0001h 43 int 33h ; Turn Mouse cursor on 44 jmp DONE 45 TurnOff: 46 mov ax,0002h 47 int 33h 48 DONE: 49 RET ; JUMP HERE WHEN FINISHED 50 ROUTINE ENDP 51 CSEG ENDS 52 END
Lines 1 to 13 are comment, while lines 14 to 25 is non-altered source code from the TEMPLATE.ASM, found on your distribution disk. This code should not be modified. From line 26 to line 47, is the code you need to insert in the TEMPLATE.ASM to make your own assembler routines. The rest of the code is again coming from TEMPLATE.ASM.
Let's have a look to WHAT we want this routine to do. We'll comment later HOW it does it. Initialising the mouse from an R/Basic program, turning the mousepointer on and off from within R/Basic is the purpose. We'd like to be able to do the following in R/Basic
Subroutine MouseTest Declare Subroutine Mouse On = 1 Off = 0 Mouse(On, NbrOfButtons) ... ... Mouse(Off) Return
Mouse takes two parameters, the first one controls if the mouse-pointer is visible or not, the second one returns the number of buttons detected at initialisation of the mouse.
Let's see how this is done in the assembler code. In the interface manual all 45 functions of the interface are documented, we will only use two of them :
- 11h retrieve integer from AREV - 12h send integer to AREV
Lines 26-29 set the function to 11h, prepare for a simple variable and indicate in the dx register that we want the first parameter to be used. (MOUSE(Param1,Param2). Finally the function (link to AREV) is called. In line 31 the received value is compared to 0. In non-zero, we go to line 34 (TurnOn), else (so if zero) we go to line 45 (TurnOff). Lines 35-36 call the mouse interrupt (33h). Line 37 selects the second parameter to be used, next the button information is moved to the cx register, which has to contain the integer information to send to AREV. Finally line 39 selects the 12h function. (send integer to AREV). Lines 42-43 make the mouse-pointer visible. Lines 46-47, jumped to if the first parameter passed is zero, make the mouse-pointer invisible.
In the next code, well, try to work it out for yourself what's happening, based upon what we've done above!
1 ; 2 ; TITLE: MPOS.ASM 3 ; 4 ; DESCRIPTION: Routine that returns both mouse position 5 ; and buttons-state 6 ; 7 ; DATE: July, 1992 8 ; 9 ; VERSION: 1.0 10 ; 11 ; No Copyright 12 ; Please feel free to copy the code for your personal use 13 ; 14 PAGE 60,132 15 TITLE MPOS - Mouse Position and buttons-state 16 CSEG SEGMENT PARA PUBLIC 'CODE' 17 ASSUME CS:CSEG 18 ROUTINE PROC FAR 19 ORG 0 ; START AT ADDRESS ZERO 20 DB 'ASSM' ; 4 BYTE FLAG 21 DB 2 ; IDENTIFY AS ASSEMBLER ROUTINE 22 NO_ARGS DB 0 ; NUMBER OF ARGUMENTS PASSED 23 NO_COMS DW 0 ; NUMBER OF COMMON VARIABLES 24 DW 0 ; UNUSED 25 FUNCTION DD 0 ; ADDRESS FOR REV FUNCTION CALLS 26 jmp DataSkipped 27 SaveY DW ? 28 SaveB DW ? 29 DataSkipped: 30 mov ax,oo03h ; Function 03h for Int 33h (mouse) 31 int 33h ; Call for mouse position 32 ; bx : button info 33 ; cx : X-position 34 ; dx : Y-position 35 mov [SaveB],ax ; saves button information 36 mov [SaveY],dx ; saves Y-Position 37 mov dx,01h 38 mov ah,12h 39 mov al,00h 40 CALL FUNCTION ; sends X-position to 1st arev param 41 mov bx,OFFSET SaveY 42 mov cx,[bx] 43 mov dx,02h 44 mov ah,12h 45 mov al,00h 46 CALL FUNCTION ; sends Y-position to 2nd arev param 47 mov bx,OFFSET SaveB 48 mov cx,[bx] 49 mov dx,03h 50 mov ah,12h 51 mov al,00h 52 CALL FUNCTION ; sends button info to 3rd arev param 53 DONE: 54 RET ; JUMP HERE WHEN FINISHED 55 ROUTINE ENDP 56 CSEG ENDS 57 END
Something special here is worth mentioning: the code starts with a `jmp DataSkipped' instruction. The Assembly Interface documentation says that you may not have a STACK segment defined in your code, nor can you define a DATA segment. So, when data storage is needed, this is one way to have a pseudo data-segment in your code. The jump instruction lets you start the program by jumping over the data-part. In the above example we could have used a push and pop instruction to save the bx and dx registers. So don't think push and pop won't work because you don't have a STACK segment.
By the way, I started assembler programming only a few days ago. One shouldn't be worried about it. Programming little very useful routines in Assembler and linking them to AREV is not as hard as one might think. Just do it once… you'll love it! At least, I did.
Here is a small R/Basic program that uses both the MOUSE and MPOS routines. It might give you some ideas for your own programs.
Declare Subroutine Mpos, Video.Rw, Mouse Video.Rw(0,0,@CrtWide-1,@CrtMaxHigh-1,"R",Image) A = 0 ; B = 0 ; C = 0 Print @(-1) : Print @(5,5) : "ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»" Print @(5,6) : "º º" Print @(5,7) : "º X : º" Print @(5,8) : "º Y : º " Print @(5,9) : "º B : º " Print @(5,10): "º ±±OK±± º" Print @(5,11): "º º" Print @(5,12): "º ±±MENU±± º " Print @(5,13): "ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ" On = 1 ; Off = 0 ; But = 0 Mouse(On,But) Loop Mpos(A,B,C) X = Int(A/8) Y = Int(B/8) Until (X >= 21) and (X<=26) and (Y=10) and (C=1) If (X >=20) and (X<=27) and (Y=12) and (C=1) then Mouse(Off) Call Catalyst(`M', `MAIN') Mouse(On,But) End Print @(11,7) : Int(A/8) "R#5" Print @(11,8) : Int(B/8) "R#5" Print @(11,9) : C "R#5" Repeat Mouse(Off,But) Video.RW(0,0,@CrtWide-1,@CrtMaxHigh-1,"W",Image)
Have Fun and Good luck!
(Volume 4, Issue 4, Pages 8-11)