Results 1 to 17 of 17

Thread: Old VAX homegrown database code

Threaded View

  1. #1

    Thread Starter
    MS SQL Powerposter szlamany's Avatar
    Join Date
    Mar 2004
    Location
    Connecticut
    Posts
    18,263

    Old VAX homegrown database code

    I've got tons of homegrown database code from the 1980's - from an old VAX/VMS minicomputer. We actually "implemented" a SIGMA function to loop through data manipulations! I've posted some snippets and attached two of the whole code files.

    Any value posting the whole set of code here? I've seen people discuss developing parsers and there own language - this is one as an example.

    Some of the upper level NON-MATH functions

    Code:
    	 New EQ Functions					01-Sep-1993
    	------------------
    
    	OPEN(open_opt%,dt_cnct_prefix$,open_acc%,open_all%,open_span%
    			,open_filesize%,open_extend%,open_file$,open_dcr$)
    	FIELD(dt_prefix$,field_opt%,field%,element%,format_opt%)
    	CONVERT(dt_prefix$,cnv_opt%,cnv_what?)
    
    	CNF(cnf_chnl%,cnf_file$)
    
    	DATE(in_type%,out_type%,in_date$)
    	NUMBER(out_len%,in_num$,out_format%)
    	INFO(info_what%)
    	MAIL(who$,subj$,text$)
    	RANDOM
    	DAY(date_typ%,date$)
    	IDENT(identifier$)
    	SIGMA$(loop_vbl,loop_start%,loop_end%,loop_step%,loop_expression$)
    
    	SET(set_opt%,set_extra%,set_text$)
    	ERROR(err_opt%,text$)
    	PUT(row%,col%,put_opt%,text$)
    
    	TYPE(typ_key$,typ_desc$,typ_master$,typ_primary$,typ_key%,typ_first$
    			,typ_last$,typ_read_crit$,typ_write_crit$
    			{{,typ_anc_file$,typ_key_field$,typ_key%}...})
    	PARAM(param_slot%,param_string$)
    	ABORT
    	END
    EQLOADRTL.BAS - loads the runtime library!

    Code:
    1	FUNCTION LONG EQ_LOAD_RTL(	 LONG	A_CHAN)			&
    									&
     !									&
     !	Product : Equation Functions					&
     !	Program : EQLOADRTL.BAS						&
     !	Author	: Stephen Zlamany					&
     !	Date    : May 1, 1989						&
     !									&
     !		    ANTARES Computing Systems, Inc.			&
     !		    19 Ripton Road, Huntington, CT			&
     !									&
    
    10	%INCLUDE "ACS$INC:ACSDEFS.INC"
    	%INCLUDE "ACS$INC:EQDEFS.INC"
    
    100	EXTERNAL LONG FUNCTION	 LIB$GET_VM
    
    	EXTERNAL LONG CONSTANT	 SS$_NORMAL
    
    	DECLARE LONG		 E_CHAN				&
    				,E_OPC_CHAN
    
    900	WHEN ERROR USE ERROR_HANDLER
    
    1000	! Start of Main Code
    
     BEGIN:
    
    	CALL PEEK_L(A_CHAN,ACS$A_CHAN,A.CHAN%)
    	IF A_CHAN <> A.CHAN% THEN
    		! Error condition
    	END IF
    
    	CALL PEEK_L(A_CHAN,ACS$E_CHAN,E_CHAN)
    
    	CALL PEEK_W(E_CHAN,EQP$OPC_FLAG,E.FLAG%)
    	IF E.FLAG% <> -1% THEN
    		! Error condition
    	END IF
    
    	CALL PEEK_L(E_CHAN,EQP$OPC_ADDR,E_OPC_CHAN)
    
    	GOSUB LOAD_OPC
    
    	GOSUB SORT_OPC
    
    	OPR_INIT		= -1%
    
    	GOTO RTN_CALLER
    
    1100	! Load opcodes
    
     LOAD_OPC:
    
    	OPC.CNT% = 1%
    
    	CALL POKE_S(E_OPC_CHAN,EQP$OPC_OP_NAME+OPC.CNT%*10%,10%,"*         ")
    	CALL POKE_B(E_OPC_CHAN,EQP$OPC_OP_NUM+OPC.CNT%,OPC.CNT%)
    	CALL POKE_B(E_OPC_CHAN,EQP$OPC_OP_NAMLNK+OPC.CNT%,OPC.CNT%)
    	CALL POKE_B(E_OPC_CHAN,EQP$OPC_OP_ARGCNT+OPC.CNT%,2%)
    	CALL POKE_B(E_OPC_CHAN,EQP$OPC_OP_FLAG+OPC.CNT%,EQT$OPR_INFIX	&
    							 OR EQT$OPR_NUMERIC)
    	CALL POKE_B(E_OPC_CHAN,EQP$OPC_OP_PRIO+OPC.CNT%,3%)
    
    	OPC.CNT% 		= OPC.CNT% + 1%
    
    	CALL POKE_S(E_OPC_CHAN,EQP$OPC_OP_NAME+OPC.CNT%*10%,10%,"+         ")
    	CALL POKE_B(E_OPC_CHAN,EQP$OPC_OP_NUM+OPC.CNT%,OPC.CNT%)
    	CALL POKE_B(E_OPC_CHAN,EQP$OPC_OP_NAMLNK+OPC.CNT%,OPC.CNT%)
    	CALL POKE_B(E_OPC_CHAN,EQP$OPC_OP_ARGCNT+OPC.CNT%,2%)
    	CALL POKE_B(E_OPC_CHAN,EQP$OPC_OP_FLAG+OPC.CNT%,EQT$OPR_INFIX	&
    							 OR EQT$OPR_NUMERIC)
    	CALL POKE_B(E_OPC_CHAN,EQP$OPC_OP_PRIO+OPC.CNT%,4%)
    
    	OPC.CNT% 		= OPC.CNT% + 1%
    
    	CALL POKE_S(E_OPC_CHAN,EQP$OPC_OP_NAME+OPC.CNT%*10%,10%,"+         ")
    	CALL POKE_B(E_OPC_CHAN,EQP$OPC_OP_NUM+OPC.CNT%,OPC.CNT%)
    	CALL POKE_B(E_OPC_CHAN,EQP$OPC_OP_NAMLNK+OPC.CNT%,OPC.CNT%)
    	CALL POKE_B(E_OPC_CHAN,EQP$OPC_OP_ARGCNT+OPC.CNT%,1%)
    	CALL POKE_B(E_OPC_CHAN,EQP$OPC_OP_FLAG+OPC.CNT%,EQT$OPR_UNARY	&
    							 OR EQT$OPR_NUMERIC)
    	CALL POKE_B(E_OPC_CHAN,EQP$OPC_OP_PRIO+OPC.CNT%,2%)
    
    	CALL POKE_W(E_OPC_CHAN,EQP$OPC_UNARY_PLUS,OPC.CNT%)
    
    	OPC.CNT% 		= OPC.CNT% + 1%
    
    	CALL POKE_S(E_OPC_CHAN,EQP$OPC_OP_NAME+OPC.CNT%*10%,10%,"-         ")
    	CALL POKE_B(E_OPC_CHAN,EQP$OPC_OP_NUM+OPC.CNT%,OPC.CNT%)
    	CALL POKE_B(E_OPC_CHAN,EQP$OPC_OP_NAMLNK+OPC.CNT%,OPC.CNT%)
    	CALL POKE_B(E_OPC_CHAN,EQP$OPC_OP_ARGCNT+OPC.CNT%,2%)
    	CALL POKE_B(E_OPC_CHAN,EQP$OPC_OP_FLAG+OPC.CNT%,EQT$OPR_INFIX	&
    							 OR EQT$OPR_NUMERIC)
    	CALL POKE_B(E_OPC_CHAN,EQP$OPC_OP_PRIO+OPC.CNT%,4%)
    
    	OPC.CNT% 		= OPC.CNT% + 1%
    and EQEXECUTE.MAR (written in machine code!).

    Code:
    	.title	EQ_EXECUTE
    	.sbttl	Program Heading
    	.ident	/V1.0/
    ;
    ;
    ; Product : Equation Functions
    ; Program : EQEXECUTE.MAR
    ; Date    : March 22, 1989
    ;
    ; ANTARES Computing Systems, Inc.
    ; 19 Ripton Road, Huntington, CT
    ;
    ;
    	.page
    	.sbttl MACRO definitions
    ;
    ; RPN Opcode block macros
    ;
    	.macro opstart sel,base,limit
    		caseb	sel,base,limit
    		op_start = .
    		op_ptr   = .
    		limit_l	   = %length(limit)-1
    		.blkw %extract(1,limit_l,limit)
    	.endm
    
    	.macro opcd num
    		.if nb num
    		  num.1 = num
    		.iff
    		  num.1 = 1
    		.endc
    		.rept num.1
    		  op_save = .
    		  . = op_ptr
    		  .word op_save - op_start
    		  op_ptr = .
    		  . = op_save
    		.endr
    	.endm
    
    	.macro	opend
    		op_ptr = 0
    		op_end = 0
    	.endm
    ;
    ; RPN word type case macro (literal, variable or operator)
    ;
    	.macro rinit sel,limit
    		caseb sel,#0,limit
    		rtype_start= .
    		limit_l = %length(limit)-1
    		.word <%extract(2,limit_l,limit)*2>+2
    		tmp_limit = .
    		.blkw %extract(2,limit_l,limit)
    		rtype_limit = <.-tmp_limit>/2
    	.endm
    
    	.macro rtype bits
    		rtype_save = .
    		. = rtype_start
    		tmp = 0
    		.rept <rtype_limit+1>
    		.if ne <bits & tmp> 
    			.word rtype_save - rtype_start
    		.iff
    			. = . + 2
    		.endc
    		tmp = <tmp + 1>
    		.endr		     
    		. = rtype_save
    	.endm
    
    	.page
    	.sbttl  Data Area (protected)
    	.psect	eq_data,nowrt,noexe,shr,pic,con,long
    ;
    ; Definitions
    ;
    	arg_achan	= 1 * 4		; A_CHAN
    	arg_option	= 2 * 4		; options
    	arg_object	= 3 * 4		; object string
    	arg_prec	= 4 * 4		; precision
    	arg_string	= 5 * 4		; result string
    	arg_value	= 6 * 4		; result value
    	arg_result	= 7 * 4		; result type
    ;
    ; DT offsets and constants
    ;
    	d_chan		= 8		; D_CHAN within A_CHAN
    	dc_flag		= 0		; D_CHAN flag
    	dc_workmap	= 2		; D_CHAN work map flag
    	dc_workaddr	= 4		; D_CHAN work map address
    	dc_recurse	= 8		; D_CHAN recursion count
    	dc_count	= 10		; D_CHAN slot count
    	dc_slots	= 12		; D_CHAN slot pool
    	dp_flag		= 0		; DS_CHAN flag
    	dp_prefix	= 8		; DS_CHAN prefix
    ;
    	dts$normal	= 0
    	dts$stk_ovr	= 36
    	dts$sub_ovr	= 55
    	dts$udef_sym	= 75
    	dts$not_yet_imp	= 250
    	dts$bad_addr    = -21
    	dts$ext_noopn	= -121
    	dts$inv_ste	= -131
    	dts$inv_obj	= -132
    ;
    ; EQ offsets and constants
    ;
    	obj_hdr_loff	= 12
    	obj_hdr_coff	= 14
    	obj_hdr_doff	= 16
    	obj_hdr_ver	= 20
    ;
    	eq_ver		= 5
    ;
    	rpn_oper	= 256
    	rpn_lit		= 512
    	rpn_var		= 1024
    ;
    	lit_byte	= 256
    	lit_word	= 512
    	lit_long	= 1024
    ;
    	stb_start	= 26
    	stb_len		= 26
    	stb_namptr	= 0
    	stb_namlen	= 2
    	stb_flg		= 4
    	stb_fld		= 6
            stb_slot	= 8
    	stb_addr	= 12
    	stb_bd0		= 20
    	stb_bd1		= 22
    	stb_bd2		= 24
    ;
    	ste_sub		= 3
    	ste_sub1	= 1
    	ste_sub2	= 2
    	ste_byte	= 4
    	ste_word	= 8
    	ste_long	= 16
    	ste_scalar	= 32
    	ste_def		= 64
    	ste_zhh		= 128
    	ste_icnt	= 256
    	ste_dcr		= 512
    ;
    ; Miscellaneous options and values
    ;
    blank_dsc:	.word	0		; no length
    		.byte	dsc$k_dtype_t	; text string
    		.byte	dsc$k_class_d	; dynamic string
    blank_str:	.word	0		; no length
    		.byte	dsc$k_dtype_t	; text string
    		.byte	dsc$k_class_d	; dynamic string
    		.long	0		; no address
    null_str:	.ascid //		; Null string
    zero_str:	.ascid /0/		; Zero value string
    		.align	long		; get on a longword boundary
    inf$username:	.long	1		; GET_INFO option
    inf$uic:	.long	2		; GET_INFO option
    frm$sto:	.long	1		; Format STO
    frm$inp:	.long	2		; Format INP
    frm$srt:	.long	3		; Format SRT
    frm$dsp:	.long	4		; Format DSP
    val$0:		.long	0		; general option value
    val$1:		.long	1		; general option value
    val$2:		.long	2		; general option value
    val$3:		.long	3		; general option value
    val$4:		.long	4		; general option value
    val$5:		.long	5		; general option value
    val$6:		.long	6		; general option value
    dto$field:	.long	<1@0>+<1@11>
    dto$name:	.long	<1@1>+<1@11>
    dto$fld_noerr:	.long	<1@0>+<1@11>+<1@15>
    dto$name_noerr:	.long	<1@1>+<1@11>+<1@15>
    dto$get:	.long	<1@2>+<1@11>
    dto$table:	.long	<1@4>+<1@11>
    dto$tb_init:	.long	<1@4>+<1@7>+<1@11>
    dto$tb_fnd_get:	.long	<1@4>+<1@2>+<1@8>+<1@11>
    dto$init:	.long	<1@7>+<1@11>
    dto$find:	.long	<1@8>+<1@11>
    dto$no_wrk_map:	.long	<1@11>
    dto$no_error:	.long	<1@15>
    eqo$value:	.long	<1@22>
    eqo$string:	.long	<1@23>
    eqo$either:	.long	<1@22>+<1@23>
    ;
    ; Stack Work Space
    ;
    	op_max		= 6		; Maximum number of operands
    	op_size		= 9		; Size of each operand block
    	ib_max		= 4		; Max number of iterative blocks
    	ib_size		= 9		; size of each iterative block
    	stack_size	= <op_max*op_size>+<ib_max*ib_size>+16
    	obo_start 	= 16+<ib_max*ib_size>
    	obo_type	= 0		; Offset to type byte
    	obo_str		= 1		; Offset to Descriptor
    	obo_long	= 1		; Offset to longword value
    	obo_arg1	= obo_start	; Arguments
    	obo_arg2	= obo_arg1+op_size
    	obo_arg3	= obo_arg2+op_size
    	obo_arg4	= obo_arg3+op_size
    	obo_arg5	= obo_arg4+op_size
    	obo_arg6	= obo_arg5+op_size
    	obo_int1	= obo_arg1+obo_long
    	obo_int2	= obo_arg2+obo_long
    	obo_int3	= obo_arg3+obo_long
    	obo_int4	= obo_arg4+obo_long
    	obo_int5	= obo_arg5+obo_long
    	obo_int6	= obo_arg6+obo_long
    	obo_str1	= obo_arg1+obo_str
    	obo_str2	= obo_arg2+obo_str
    	obo_str3	= obo_arg3+obo_str
    	obo_str4	= obo_arg4+obo_str
    	obo_str5	= obo_arg5+obo_str
    	obo_str6	= obo_arg6+obo_str
    	obo_tmp1	= obo_start+1	; STE address, subscript value
    	obo_tmp2	= obo_tmp1+4	; Subscript value, index
    	obo_tmp3	= obo_tmp2+5	; Index offset
    	obo_tmp4	= obo_tmp3+4	; Array bound
    ;
    ; Operand Types
    ;
    	opt_long	= 1		; long
    	opt_str		= 2		; string
    	opt_either	= 3		; either type
    	opt_dyn		= 4		; dynamic bit
    	opt_strdyn	= 6		; dynamic string
    	opt_valerr	= 8		; value error
    ;
    ; Temporaries for op_get
    ;
    	opg_get		= 8		; operands to get
    	opg_got		= 12		; operands gotten
    ;
    ; Iteration Work Space
    ;
    	ibo_start	= 16		; Start 
    	ibo_type	= 0		; Type offset
    	ibo_long	= 1		; Long offset
    	ibo_float	= 1		; D-Float offset
    ;
    	ibt_long	= 1		; Iteration index - long
    	ibt_float	= 2		; Iteration index - D-float
    ;
    	ifo_blk		= 0		; Number
    	ifo_bpc		= 4		; PC
    	ifo_spc		= 8		; Saved PC
    	ifo_sum		= 12		; Sum
    	ifo_end		= 20		; End value - D-float
    	ifo_step	= 28		; Step value - D-float
    	.page
    	.sbttl	EQ_EXECUTE code - setup registers
    	.psect	eq_execute,nowrt,exe,shr,pic,con
    	.entry  eq_execute,^m<r2,r3,r4,r5,r6,r7,r8,r9,r10,r11>
    ;
    ; Register Use
    ;
    ; r2 - temporary
    ; r3 - temporary, used for A_CHAN
    ; r4 - RPN code PC
    ; r5 - Address of literal pool
    ; r6 - Address of literal blocks
    ; r7 - temporary
    ; r8 - Address of object
    ; r9 - pointer to Stack Work space
    ;
    	cmpw	@arg_object(ap),#26	; is object size of header
    	blss	10$			; no - branch
    	movaq	@arg_string(ap),r0	; address of return string
    	movaq	null_str,r1		; address of null string
    	jsb	g^str$copy_dx_r8	; copy string
    	clrl	@arg_value(ap)		; clear return value
    	clrl	@arg_result(ap)		; clear result type
    	movaq	@arg_object(ap),r8	; address of object
    	movab	@4(r8),r8		; address of object data
    	cmpw	obj_hdr_ver(r8),#eq_ver	; compare version
    	beql	20$			; same - branch
    10$:	movl	#dts$inv_obj,r0		; otherwise, bad object
    	ret				; return
    20$:	moval	err_handler,(fp)	; frame up the err_handler
    	subl2	#stack_size,sp		; push size of work space
    	movq	blank_str,-(sp)		; push a blank string
    	movl	sp,r9			; pointer to temporary storage
    	movzwl	obj_hdr_coff(r8),r4	; offset to rpn pool
    	movzwl	obj_hdr_doff(r8),r5	; offset to literal pool
    	movzwl	obj_hdr_loff(r8),r6	; offset to lte's
    	addl2	r8,r4			; add address to rpn
    	addl2	r8,r5			; add address to literal
    	addl2	r8,r6			; add address to lte's
    	decl	r5			; adjust literal
    	subl2	#4,r6			; adjust lte's
    	.page
    	.sbttl  Execute a word of RPN
    ;
    ; Here we loop through RPN words - executing each
    ;
    rpnexe:	cmpl	r4,r5			; still more rpn code
    	bgtru	30$			; no - branch
    	movzwl	(r4)+,r7		; get RPN word
    	extzv	#8,#3,r7,r1		; get flags
    	rinit	r1,#07			; rpn init macro based on RPN word type
    	movl	#dts$not_yet_imp,r0	; give error
    	ret				; return
    ;
    ; We are now done - lets write out our results
    ;
    30$:	clrl	r0			; Get one operand
    	mcoml	l^eqo$either,r1		; Create a mask of both bits
    	bicl3	r1,@arg_option(ap),r1	; Pass options through mask
    	divl2	l^eqo$value,r1		; Shift down to bits 0 and 1
    	movab	obo_start(r9),r7	; Placing at start
    	jsb	op_get			; Get operand(s)
    	bitb	#opt_str,(r7)		; Is it string
    	beql	50$			; No - branch
    	pushaq	obo_str(r7)		; Get address of operand
    	pushaq	@arg_string(ap)		; Get address of return string
    	calls	#2,g^str$copy_dx	; Call STRING Copy
    	movl	#opt_str,@arg_result(ap); Pass back result type
    	mull2	l^eqo$value,@arg_result(ap)
    					; Shift up to actual bits
    	bitb	#opt_dyn,(r7)		; Is it dynamic string
    	beql	40$			; No - branch
    	moval	obo_str(r7),r0		; Get address of operand
    	jsb	g^str$free1_dx_r4	; Call STRING Free
    40$:	clrl	r0			; Set status to success
    	ret				; Return
    50$:	movl	obo_long(r7),@arg_value(ap)
    					; Copy into return value
    	movl	#opt_long,@arg_result(ap)
    					; Pass back result type
    	mull2	l^eqo$value,@arg_result(ap)
    					; Shift up to actual bits
    	clrl	r0			; Set status to success
    	ret				; Return
    	.page
    	.sbttl	Execute Literals
    ;
    ; RPN literals
    ;
    	rtype	rpn_lit/256		; Handle literals
    	bicw2	#rpn_lit,r7		; Clear flag
    	movl	(r6)[r7],r1		; Address of LTE
    	movzwl	r1,r0			; Offset to data
    	addl2	r5,r0			; Address of data
    	extzv	#16,#12,r1,r1		; Length of data
    	bitw	#lit_byte,r1		; Is it a byte
    	beql	60$			; No - branch
    	cvtbl	(r0),-(sp)		; Put it on the stack 
    	movb	#opt_long,-(sp)		; Push long type
    The DO_SIGMA block of machine code!

    Code:
    do_sigma:
    	opcd				; Op-code 24, "SIGMA"
    	movzbl	(sp)+,(r9)		; Get type off stack
    	movl	(sp)+,(r9)		; Get address off stack
    	movl	#3,r0			; Get three operands
    	movl	#opt_either,r1		; Get either
    	movab	obo_arg3(r9),r7		; Placing at argument 3
    	jsb	op_get			; Get operand(s)
    	movzbl	(sp)+,r0		; Get iterative count type
    	bitb	#opt_long,r0		; Is it long
    	bneq	440$			; Yes - branch
    	pushr	#^m<r0,r1,r4>		; Save some registers
    	moval	12(sp),r0		; Address of string
    	jsb	g^str$free1_dx_r4	; Free up string
    	popr	#^m<r0,r1,r4>		; Restore some registers
    	clrl	(sp)+			; Clear first part of string
    440$:	clrl	(sp)+			; Clear second part or long value
    	subl2	#36,sp			; Put iterative work space on stack
    	ashl	#-4,r0,r0		; Get iterative counter
    	mull2	#ib_size,r0		; Make it an offset
    	moval	ibo_start(r9),r7	; Get address
    	addl2	r0,r7			; Get iterative address
    	movl	r7,(sp)			; Put it on the stack
    	movl	(r9),ifo_bpc(sp)	; Set iterative PC
    	movl	r4,ifo_spc(sp)		; Save current RPN PC
    	bitb	#opt_long,r1		; Is it long
    	beql	510$			; No - branch
    	clrl	ifo_sum(sp)		; Clear sum
    	movl	obo_int1(r9),ibo_long(r7)
    					; Set start value
    	movl	obo_int2(r9),ifo_end(sp); Set end value
    	movb	#ibt_long,(r7)		; Set type
    	movl	obo_int3(r9),ifo_step(sp)
    					; Set step - is it negative
    	bleq	450$			; Yes - branch
    	cmpl	ibo_long(r7),ifo_end(sp); Are we done already
    	brb	460$			; Jump to check
    450$:	cmpl	ifo_end(sp),ibo_long(r7); Are we done already
    460$:	bgtr	500$			; Yes - branch
    470$:	movl	ifo_bpc(sp),r4		; Get iterative PC
    	jsb	rpnexe			; Execute it
    	clrl	r0			; Get one operand
    	movl	#opt_long,r1		; Get long
    	movab	obo_arg1(r9),r7		; Placing at argument 1
    	jsb	op_get			; Get operand(s)
    	addl2	obo_int1(r9),ifo_sum(sp); Sum the result
    	movl	(sp),r7			; Get iterative address
    	addl2	ifo_step(sp),ibo_long(r7)
    					; Increment counter
    	tstl	ifo_step(sp)		; Are we a negative step
    	bleq	480$			; Yes - branch
    	cmpl	ibo_long(r7),ifo_end(sp); Are we done already
    	brb	490$			; Jump to check
    480$:	cmpl	ifo_end(sp),ibo_long(r7); Are we done already
    490$:	bleq	470$			; No - branch
    500$:	movl	ifo_spc(sp),r4		; Restore RPN PC
    	movl	ifo_sum(sp),r0		; Save sum'd value
    	addl2	#36,sp			; Remove iterative work space
    	pushl	r0			; Push sum'd value
    	movb	#opt_long,-(sp)		; Push long type
    	brw	rpnexe			; Next RPN
    510$:					; Handle float iteration
    	clrd	ifo_sum(sp)		; Clear sum
    	pushal	obo_str1(r9)		; Push operand 1
    	calls	#1,g^bas$val_d		; Call VAL()
    	movd	r0,ibo_long(r7)		; Set start value
    	pushal	obo_str2(r9)		; Push operand 2
    	calls	#1,g^bas$val_d		; Call VAL()
    	movd	r0,ifo_end(sp)		; Set end value
    	movb	#ibt_float,(r7)		; Set type
    	pushal	obo_str3(r9)		; Push operand 3
    	calls	#1,g^bas$val_d		; Call VAL()
    	movd	r0,ifo_step(sp)		; Set step
    	pushr	#^m<r7>			; Save r7
    	movl	#3,r7			; 3 possible operands
    	jsb	op_free			; Free operands
    	popr	#^m<r7>			; Restore r7
    	tstd	ifo_step(sp)		; Is step negative
    	bleq	520$			; Yes - branch
    	cmpd	ibo_long(r7),ifo_end(sp); Are we done already
    	brb	530$			; Jump to check
    520$:	cmpd	ifo_end(sp),ibo_long(r7); Are we done already
    530$:	bgtr	570$			; Yes - branch
    540$:	movl	ifo_bpc(sp),r4		; Get iterative PC
    	jsb	rpnexe			; Execure it
    	clrl	r0			; Get one operand
    	movl	#opt_str,r1		; Get string
    	movab	obo_arg1(r9),r7		; Placing at argument 1
    	jsb	op_get			; Get operand(s)
    	pushal	obo_str1(r9)		; Push operand 1
    	calls	#1,g^bas$val_d		; Call VAL()
    	addd2	r0,ifo_sum(sp)		; Sum the result
    	movl	#1,r7			; 1 possible operand
    	jsb	op_free			; Free operands
    	movl	(sp),r7			; Get iterative address
    	addd2	ifo_step(sp),ibo_long(r7)
    					; Increment counter
    	tstd	ifo_step(sp)		; Are we a negative step
    	bleq	550$			; Yes - branch
    	cmpd	ibo_long(r7),ifo_end(sp); Are we done already
    	brb	560$			; Jump to check
    550$:	cmpd	ifo_end(sp),ibo_long(r7); Are we done already
    560$:	bleq	540$			; No - branch
    570$:	movl	ifo_spc(sp),r4		; Restore RPN PC
    	movd	ifo_sum(sp),r0		; Save sum'd value
    	addl2	#36,sp			; Remove iterative work space
    	movq	blank_str,-(sp)		; Push a blank string
    	movd	r0,-(sp)		; Push sum'd value
    	pushal	8(sp)			; Push result address
    	calls	#3,g^bas$num1_d		; Call NUM1()
    	movb	#opt_strdyn,-(sp)	; Push temporary string type
    	brw	rpnexe			; Next RPN
    do_xor:
    	opcd				; Op-code 25, "XOR"
    Attached Files Attached Files

    *** Read the sticky in the DB forum about how to get your question answered quickly!! ***

    Please remember to rate posts! Rate any post you find helpful - even in old threads! Use the link to the left - "Rate this Post".

    Some Informative Links:
    [ SQL Rules to Live By ] [ Reserved SQL keywords ] [ When to use INDEX HINTS! ] [ Passing Multi-item Parameters to STORED PROCEDURES ]
    [ Solution to non-domain Windows Authentication ] [ Crazy things we do to shrink log files ] [ SQL 2005 Features ] [ Loading Pictures from DB ]

    MS MVP 2006, 2007, 2008

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width