[Search for users] [Overall Top Noters] [List of all Conferences] [Download this site]

Conference noted::hackers_v1

Title:-={ H A C K E R S }=-
Notice:Write locked - see NOTED::HACKERS
Moderator:DIEHRD::MORRIS
Created:Thu Feb 20 1986
Last Modified:Mon Aug 03 1992
Last Successful Update:Fri Jun 06 1997
Number of topics:680
Total number of notes:5456

452.0. "Macro (?) 1/2 byte shift subprogram?" by JETSAM::REZUCHA () Fri Apr 24 1987 18:40

 Sales support asked me to provide a conversion program but I am stuck
on a feature. I have binary data which I need to convert to signed binary
data. The input format is:
   unsigned packed decimal %D 2043 and %X 01F1 and I need to convert this to
     signed packed decimal %D 2043 and %X 1F1C where 1c represents +1.

 To do this it was suggested that I write a macro program which takes the input
string, concatenates binary "11000000" onto it (C in left 1/2 byte), shift the
new string 1/2 byte left putting the "1100" in the low order half byte of the
new string and return the new value to the calling program.

 Question:
  1) Does anyone have a Fortran example which passes values to a macro 
     subroutine and return's a value back to the Fortran program?
  2) Does anyone have a Macro routine which I could modify to do my routine?


*Any* examples, or suggestions would be greatly appreciated!

-Tom Rezucha

PS: This was also entered in TLE::PUBD$:[VAXNOTES]FORTRAN.NOTE;1
T.RTitleUserPersonal
Name
DateLines
452.1ALBANY::KOZAKIEWICZYou can call me Al...Sat Apr 25 1987 19:2381
I can answer you first question - not so sure about the second.

To call a macro routine from FORTRAN (this is a VAX, I assume...), you
have two choices.  Depends on whether you want to call your routine
as a function or subroutine.  Makes very little difference, except
how the value is returned.  Since function call return values are limited to
atomic data types (value must fit in R0), I will demonstrate the other.  
Example:

		(from FORTRAN)

	INTEGER*4	A, B, C		!Arguments
	INTEGER*4	WHATZIT		!Function
		.
		.
		.
	CALL WHATZIT (A, B, C)		!A = B XOR C

In a file, WHATZIT.MAR:

	.TITLE	WHATZIT

	.PSECT	$CODE
	.ENTRY	WHATZIT, ^M<>

; Upon entry, the argument pointer (AP) points to a list of arguments.
; This list consists of N+1 longwords, where N=number of arguments.  The
; low order byte of the first longword contains N.  The rest contain the
; addresses of the arguments.
;
; In order to move the address of the argument in a register, you use
; indexed addressing mode. Example :
;
;	 MOVL	8(AP), R1	;Move the address of the second argument
;				; into register 1
;
; In order to get the value, use index deferred mode. Example:
;
;	MOVL	@8(AP), R1	; Same as above, except gets value.


;
; Executable code starts (and ends) here:
;

	XORL3	@8(AP), @12(AP), @4(AP)	!A = B xor C

	RET

	.END

Things get a little hairy when you are dealing with FORTRAN CHRACTER data
types.  These are passed by descriptor.  Thus to put the address of the string
into R1 and the length into R2, do the following:

	MOVL	4(AP), R0
	MOVL	4(RO), R1
	MOVL	(R0), R2

If you know the length of the string already, you can pass the CHARACTER string
by reference and not worry about decoding the descriptor:

		CHARACTER*99	ABC

		CALL	THING (%REF(ABC))

For a much better discussion and (I think) examples of how to do these things,
look in the FORTRAN users guide.

You second question is harder for me since I have never dealt with packed
decimal strings.  FORTRAN does not support them as a data type, and it
is not clear from your note how you are reading them in or what data types
you are using to store them. You will need to store the length somehow, unless
they are fixed.  The VAX-11 architecture reference manual explains how
this type is represented on page 2-13.

Also, if this is for a benchmark, you may need to be careful. If I am not
mistaken (it has been known to happen...) not all VAX processors implement
the decimal string instructions in firmware (uVAX, 82/8300??) but by
emulation.  If you need to use any (it doesn't sound like it) a lot
on one of these processors, performance may not be too good.
452.2CLT::GILBERTeager like a childTue Apr 28 1987 23:4153
I'm having a difficult time understanding the problem; decimal 2043
equals hexadecimal 7FB, and hex 1F1 equals decimal 497.

Suppose that you have the sequence of bytes:

	.BYTE	^X20, ^X43

and you want to convert this to the sequence of bytes:

	.BYTE	^X02, ^X04, ^X3C

(note that VAXen store packed decimal this way -- the least significant
nibbles are in the highest-addressed locations).


To this end, I'll assume the things are passed in character strings:

		CHARACTER*2	SRC
		CHARACTER*3	DST

		CALL	CVT (SRC, DST)

The Macro-32 code is ...

	.TITLE	CVTMODULE
	.PSECT	$CODE

	.ENTRY	CVT, ^M<R2,R3,R4,R5>	; Save R2 thru R5
	MOVQ	@4(AP), R0		; Load source descriptor
	MOVQ	@8(AP), R2		; Load destination descriptor
	MOVZWL	R0, R0			; Source length is a word
	MOVZWL	R2, R2			; Ditto destination length
	ADDL2	R0, R1			; Point just past end of source
	ADDL2	R2, R3			; Point just past end of destination
	MOVL	#^X0C, R5		; Initialize what we're 'adding in'
	BRB	20$			; Jump into the loop
	;
10$:	MOVZBL	-(R1), R4		; Fetch a source byte
	ASHL	#4, R4, R4		; Shift left 4 places
	DECL	R2			; Can we store it?
	BLSS	50$			; Branch if we run out of destination
	ADDB3	R4, R5, -(R3)		; Add and store
	ASHL	#-4, R4, R5		; Shift that nibble back down
20$:	SOBGEQ	R0, 10$			; Another byte of source to grab?
	BRB	40$			; Go finish filling the destination
	;
30$:	MOVB	R5, -(R3)		; Store it
	ASHL	#-4, R5, R5		; Clears R5, but reuses above technique
40$:	SOBGEQ	R2, 30$			; Can we store another byte?
	;
50$:	RET				; We've filled the destination

	.END
452.3MACRO not necessaryWINERY::JENSENPaul JensenFri May 29 1987 16:414
    Note that there is really no need to resort to MACRO to do this.
    A combination of the FORTRAN MVBITS and ISHFT routines should
    work fine.