Pds far strings and asm

 BBS: Inland Empire Archive
Date: 05-01-92 (22:46)             Number: 128
From: MATT PRITCHARD @ 930/21      Refer#: NONE
  To: HUGH MARTIN                   Recvd: NO  
Subj: Pds far strings and asm        Conf: (2) Quik_Bas
HM> I have some ASM routines that work with QuickBasic 4.5 that I would
HM> like to update to work with PDS 7.1.  What changes do I have to
HM> make to the ASM source code to support far strings, i.e. how
HM> does one access far string characters?  Are any other changes
HM> necessary to get these routines to work with PDS?

Given the numbers of people now migrating to PDS 7.1
(yeah... :) ) this will probably be a popular question.  Oh
well, here goes my 2 cents worth...


Going from QuickBASIC 4.5 TO PDS 7.1, nothing changes in
the way you call Assembly routines *EXCEPT* for string
variables.

*NOTE*  You now need to preserve the contents of the SI and
DI regesters, as well return a clear direction flag.

QuickBasic versions 2.00, 2.01, 3.0, 4.0x, and 4.5 all pass
a 16 bit offset to a String Descriptor when calling another
routine.  This is what is now known as "Near Strings".

Both the String Descriptor and the actual String Data are stored in the 64K
segment known as DGROUP.  The Descriptor is a 4 byte
structure, consisting of (2) 16 bit values.  The first is
the Length of the String (0 to 32767), the second is the
offset to the actual string data in the DGROUP segment.

The QBX (Basic 7.1) Enviroment and BC compiler passes a 16
bit "Descriptor ID Reference" (I don't know the correct
name) when calling another routine.  The routine must then
call other routines find out the length and address of the
string.  This is what is called "Far Strings".  The BC
compiler can be made to use "near strings", but the QBX
enviroment can't.


Dang!  Now we have 2 different string types to support.  I made a few calls
to Microsoft Tech support to find out if you can tell what
string system is being used from a running program... and
you can't.

When you are using far strings, you have to call a routine
named "stringaddress" to get the segment and offset of the
string's data.

*NOTE* what they don't tell you is that "stringaddress"
also returns the string's length.  They tell you to call
yet another routine, named "stringlength" to find that out.

A thing to watch for is this:  Strings now reside outside of DGROUP, so you
have to keep track of the segments as well as the offsets.

I have made my .ASM files so that I can make both Near
String and Far String versions of a routine from a single
source file.  I do this by defining a symbol (aptly named
"FARSTRINGS") when the assembly command is issued..  Making
batch files that use different output file names helps alot.


What follows is a routine to print a string directly to the
DOS console. To make a far string version use the command
line:

MASM /DFARSTRINGS DOSPRINT.ASM, DOSPRINT.OBJ, NUL, NUL;

To make a near string version, use:

MASM DOSPRINT.ASM, DOSPRINT.OBJ, NUL, NUL;

----------------------- DOSPRINT.ASM --------------------

        .MODEL Medium, Basic
        .CODE

IFDEF FARSTRINGS
        EXTRN   stringaddress:far
        EXTRN   stringlength:far
ENDIF

        PUBLIC  DOSPRINTS

DOSPRINTS        PROC    FAR

        PUSH    BP              ;Save Base Pointer on Stack
        PUSH    DS              ;Save DS
        PUSH    SI              ;** for BC7 - save SI
        PUSH    DI              ;** for BC7 - save DI

        MOV     BP,SP           ;Set Base Pointer to Top of Stack
        MOV     SI,[BP].DP_Text ;Get Addr of Text$ descriptor (near)
                                ;or reference to it (far strings)

IFDEF FARSTRINGS

        ;Code to get Far String Info

        PUSH    SI              ;Push Addr of BC7 Decriptor (parameter)
        CALL    stringaddress   ;Get Address + Len of string!!!
                                ;DX:AX = Addr  CX = Len!

        MOV     DS,DX           ;DS = DX = Segment of string
        MOV     DX,AX           ;DX = AX = Offset of String

ELSE
        ;Code to get Near String Info

        MOV     CX,[SI]         ;put its length into CX
        MOV     DX,[SI+02]      ;now DS:DX points to the String ENDIF

        ;now DS:DX points to string, CX has the length

        JCXZ    @DPS_Exit       ;Don't Print if empty

        MOV     BX, 1           ;1= DOS Handle for Display
        MOV     AH,40h          ;Write Text Function
        INT     21h             ;Call DOS to do it

@DPS_Exit:
        CLD                     ;PDS/BC7 needs this clear

        POP     DI              ;Needed for BC7
        POP     SI              ;Needed for BC7
        POP     DS              ;Far strings can change the segment!
        POP     BP              ;Restore Base Pointer

        RET 2                   ;Exit & Clear Stack

DOSPRINTS        ENDP

        END

---------------------- CUT HERE -----------------------------------
===
 * SLMR 2.1a * Corporations don't care about you

--- InterPCB 1.50
 # Origin: CENTRAL BBS -Texas' BEST BBS! 214-393-7090 HST  3+GIGs (8:930/21)
 * Origin: Gateway System to/from RBBS-NET (RBBS-PC 1:10/8)
Outer Court
Echo Basic Postings

Books at Amazon:

Back to BASIC: The History, Corruption, and Future of the Language

Hackers: Heroes of the Computer Revolution (including Tiny BASIC)

Go to: The Story of the Math Majors, Bridge Players, Engineers, Chess Wizards, Scientists and Iconoclasts who were the Hero Programmers of the Software Revolution

The Advent of the Algorithm: The Idea that Rules the World

Moths in the Machine: The Power and Perils of Programming

Mastering Visual Basic .NET