Article View: alt.lang.asm
Article #182Help with ASM function in IBM PC-DOS 7.0 REXX
From: Binyamin Dissen
Date: Sun, 24 Mar 1996 14:16
Date: Sun, 24 Mar 1996 14:16
303 lines
10570 bytes
10570 bytes
I am trying to write an INKEY function for IBM PC-DOS 7.0 REXX. Following
is the code:
PAGE 60,132
TITLE ZINKEY
; Program ZINKEY.ASM
; Purpose Perform an INKEY function for IBM PC/DOS 7 - Rexx
; Input NONE
; Parms NONE
; Output Pressed Key
DOSSEG
.MODEL small
.286
INCLUDE equates.inc ; Get standard equates
.STACK 0100h
REXXPSP SEGMENT AT 0 ; Option table entry
ORG $+54h ; Skip
RX_CODE DB "REXX" ; REXX string
SHVENTRY DD ? ; Long pointer to routine
ORG REXXPSP+82h ; Skip again
RXARGC DW ? ; Count of arguments
RXARGV DD ? ; Long pointer to arguments
RXRESULT DD ? ; Long pointer to result
.DATA
Error1 DB "Not valid outside of Rexx",CR,LF,"$"
Error2 DB "ZINKEY does not support arguments",CR,LF,"$"
GotChar DB "ZINKEY has read a character",CR,LF,"$"
NoChar DB "ZINKEY did not read a character",CR,LF,"$"
.CODE
ASSUME cs:@CODE,ds:@DATA,es:REXXPSP
start: mov ax,@DATA ; Initialize data segment
mov ds,ax
mov dx,OFFSET Error1
mov al,RX_CODE ; Program type
cmp al,"R" ; Is it REXX
jne ErrorMsg ; No, report error
mov dx,OFFSET Error2
mov ax,RXARGC ; Get arguments count
cmp ax,0 ; Any arguments?
jne ErrorMsg ; No arguments
mov ah,11h ; Is character ready?
int 16h ; Check
jnz ReadChar ; Character is available
mov dx,OFFSET NoChar
mov ah,09h ; Write $ terminated string
int 21h ; Issue the message
mov al,0 ; Return a null
jmp SHORT RetChar ; No, return Null
ReadChar:
mov dx,OFFSET GotChar
mov ah,09h ; Write $ terminated string
int 21h ; Issue the message
mov ah,10h ; Read Character function
int 16h ; Get the pending character
RetChar:
mov bl,al ; Save character
mov ax,WORD PTR RXRESULT ; Point to result string seg
mov di,WORD PTR RXRESULT+2; Point to result offset
mov es,ax ; Set segment
mov es:[di],bl ; Store character
mov BYTE PTR es:[di+1],0 ; zero terminated
mov ax,4c00h ; Terminate process Call
int 21h ; All done
ErrorMsg:
mov ah,09h ; Write $ terminated string
int 21h ; Issue the message
mov ax,4c01h ; Terminate process Call
int 21h ; All done
END start
The routine is invoked by the following batch file:
/* rexx */
Trace I
ZZ = zinkey()
Do II = 1 to 10 While ZZ = ""
RC = RXSLEEP(1)
ZZ = ZINKEY()
END
The trace code in the program shows that the key press was detected but the
value does not seem to be returned. I think I understand the doc that IBM
provides, but they had a C example rather than ASM as follows:
============================================================================
C Language Example
The following example is a sample of code written in the C programming
language. It demonstrates how to write an external function that receives
arguments, uses the variable pool interface, and returns a result string.
The sample code uses RXARGC and the RXARGV-argument array to process
arguments, SHVBLOCK to access the variables of a REXX procedure, and the
RXRESULT pointer to return a result string.
/***** REXXVAR.C - Access the variables of an active REXX procedure
******/
#include <string.h> /* Needed Header files
*/
#include <stdio.h>
#include <dos.h>
#include <stdlib.h>
#define RXSHV_SET 0x00 /* Set var from given value
*/
#define RXSHV_FETCH 0x01 /* Copy value of var to buffer
*/
#define RXSHV_DROPV 0x02 /* Drop variable
*/
#define RXSHV_SYSET 0x03 /* Symbolic name Set variable
*/
#define RXSHV_SYFET 0x04 /* Symbolic name Fetch variable
*/
#define RXSHV_SYDRO 0x05 /* Symbolic name Drop variable
*/
#define RXSHV_NEXTV 0x06 /* Fetch "next" variable
*/
#define RXSHV_PRIV 0x07 /* Fetch private information
*/
#define RXSHV_EXIT 0x08 /* Set function exit value
*/
#define RXSHV_OK 0x00 /* Execution was OK
*/
#define RXSHV_NEWV 0x01 /* Variable did not exist
*/
#define RXSHV_LVAR 0x02 /* Last var trans via SHVNEXTV
*/
#define RXSHV_TRUNC 0x04 /* Truncation occurred-Fetch
*/
#define RXSHV_BADN 0x08 /* Invalid variable name
*/
#define RXSHV_MEMFL 0x10 /* Out of memory failure
*/
#define RXSHV_BADF 0x80 /* Invalid funct code (shvcode)
*/
struct RXSTR /****** REXX String Format
******/
{
unsigned int StrLen; /* Length of string
*/
char far * StrPtr; /* Pointer to string
*/
};
struct SHVBLOCK /**** Shared Variable Block
*****/
{
struct SHVBLOCK far * ShvNext; /* Point to next block or NULL
*/
struct RXSTR ShvNam; /* Variable name
*/
struct RXSTR ShvVal; /* Variable value
*/
unsigned int ShvNamL; /* Returned variable name
length */
unsigned int ShvValL; /* Returned variable value
length */
unsigned char ShvCode; /* Function code
*/
unsigned char ShvRet; /* Return code from call
*/
};
struct ARGBUF /*** Information passed in PSP
**/
{
char Rexx[4]; /* Points to "REXX" string in
PSP */
void far * ShvEntry; /* Entry point to REXX
interface */
char Filler[38]; /* Unused area in PSP
*/
unsigned int RXargc; /* Argument count
*/
struct RXSTR far * RXargv; /* Ptr to RXSTR argument array
*/
char far * RXresult; /* Ptr to 256-byte result
buffer */
};
void (far *RXcall)(void far *); /* Function pointer to REXX
*/
char ValBuf[200]; /* Returned var value from REXX
*/
struct ARGBUF far * myPSP; /* Pointer to extract values in
PSP */
struct SHVBLOCK Shv = {0,{0,0},{200,0},0,0,0,0}; /* Init SHVBLOCK struct
*/
void main( void )
{
FP_SEG( myPSP ) = _psp; /* Initialize to Program Segment Prefix
(PSP) */
FP_OFF( myPSP ) = 0x54; /* Offset 0x54
*/
if(_fstrncmp( (char far *)myPSP, (char far *)"REXX", 4 ) != 0)
exit( 0xff ); /* Called from REXX? If not, exit with
error. */
(void far *)RXcall = myPSP->ShvEntry; /* Initialize to REXX's entry
point */
switch( toupper( *myPSP->RXargv[0].StrPtr ) ) /* Get function to
execute */
{
case 'S' : /* Was SET specified?
*/
Shv.ShvCode = RXSHV_SYSET; /* Set variable function
*/
Shv.ShvNam.StrLen = myPSP->RXargv[1].StrLen;/* Get length of var
name */
Shv.ShvNam.StrPtr = myPSP->RXargv[1].StrPtr;/* Get pointer to var
name */
Shv.ShvVal.StrLen = myPSP->RXargv[2].StrLen;/* Get length of value
*/
Shv.ShvVal.StrPtr = myPSP->RXargv[2].StrPtr;/* Get pointer to value
*/
(RXcall)( ); /* Call REXX
*/
break;
case 'G' : /* Was GET specified?
*/
Shv.ShvCode = RXSHV_SYFET; /* Set variable function
*/
Shv.ShvNam.StrLen = myPSP->RXargv[1].StrLen;/* Get length of var
name */
Shv.ShvNam.StrPtr = myPSP->RXargv[1].StrPtr;/* Get pointer to var
name */
Shv.ShvVal.StrPtr = (char far *)ValBuf; /* Get ptr to Value
buffer */
(RXcall)( ); /* Call REXX
*/
if( Shv.ShvRet != RXSHV_OK ) /* Error?, exit with that return
code */
return;
printf("\n%s\n", ValBuf); /* If value came back OK, display
it */
break;
case 'D' : /* Was DROP specified?
*/
Shv.ShvCode = RXSHV_SYDRO; /* Set variable function
*/
Shv.ShvNam.StrLen = myPSP->RXargv[1].StrLen;/* Get length of var
name */
Shv.ShvNam.StrPtr = myPSP->RXargv[1].StrPtr;/* Get pointer to var
name */
(RXcall)( ); /* Call REXX
*/
break;
default :
exit( 0xff ); /* Else, exit with error
*/
}
/** Set Return value to either 1 or 0 based on the return code from
REXX **/
_fstrcpy(myPSP->RXresult,((Shv.ShvRet) ? (char far *)"1" : (char far
*)"0"));
exit( (int)Shv.ShvRet ); /* Exit with return code
*/
}
Can anyone tell me how I am screwing up?
--
Binyamin Dissen <bdissen@netvision.net.il>
Technical Details
Message-ID:
<31555312.42398529@news.netvision.net.il>Path:
arc1-ca.pugleaf.net!news.NetVision.net.il!newsShow Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!news.NetVision.net.il!news From: bdissen@netvision.net.il (Binyamin Dissen) Newsgroups: alt.lang.asm,comp.lang.rexx,comp.os.msdos.programmer,comp.sys.ibm.pc.programmer,comp Subject: Help with ASM function in IBM PC-DOS 7.0 REXX Date: Sun, 24 Mar 1996 14:16:58 GMT Organization: DISSEN Software, Bar & Grill - Israel Ltd. Distribution: inet Message-ID: <31555312.42398529@news.netvision.net.il> NNTP-Posting-Host: ts006p7.pop2a.netvision.net.il X-Newsreader: Forte Agent .99d/16.182