🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: alt.lang.asm
Article #182

Help with ASM function in IBM PC-DOS 7.0 REXX

#182
From: Binyamin Dissen
Date: Sun, 24 Mar 1996 14:16
303 lines
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!news

Show 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