John Wilson wrote:
On Sun, Jul 14,
2013 at 07:11:16PM -0400, Jerome H. Fine wrote:
I have unsuccessfully attempted to isolate the
first 5 characters
of STRING in the MACRO ABC, but I have been unsuccessful.
Fun problem! Thanks for the hack break. I may have missed the point of what
you're doing but I got something which I *think* is on the right track (actual
code generated by the macro may miss the point), by nesting .IRPCs until I got
all six characters in separate .IRPC variables. May be all wrong, but what
else is new ...
---------------------------------------------------------------------------
;+
;
; Hideously inefficient macro which explodes a symbol name using six nested
; .IRPCs (each level started only when outer ones reach correct character --
; otherwise assembly is SUPER slow).
;
; JMBW 17-Jul-2013.
;
;-
.macro abc foo
.nchr ct1,<foo> ;must be .GE. 6 chars long
.iif lt ct1-6, .mexit ;no op if not
ct1= 0 ;CH1 is first char
.irpc ch1,<foo>
ct1= ct1+1
.if eq ct1-1
ct2= 0 ;CH2 is second char
.irpc ch2,<foo>
ct2= ct2+1
.if eq ct2-2
ct3= 0 ;you see where I'm going with this
.irpc ch3,<foo>
ct3= ct3+1
.if eq ct3-3
ct4= 0 ;nested .IRPCs run until each position found
.irpc ch4,<foo>
ct4= ct4+1
.if eq ct4-4
ct5= 0
.irpc ch5,<foo>
ct5= ct5+1
.if eq ct5-5
ct6= 0
.irpc ch6,<foo>
ct6= ct6+1
.if eq ct6-6 ;got 'em all, in order
; do whatever you had in mind, with
ch1''ch2''ch3''ch4''ch5''ch6 = sym name
.if df ch1''ch2''ch3''ch4''ch5'2 ;***** N.B. must be
backward ref *****
mov #ch1''ch2''ch3''ch4''ch5'2,-(sp) ;replace CH6
with 2
.iff
mov #foo,r0 ;use original string
.endc
; unwind all that
.endc ; CT6.EQ.6
.endm ; .IRPC CH6
.endc ; CT5.EQ.5
.endm ; .IRPC CH5
.endc ; CT4.EQ.4
.endm ; .IRPC CH4
.endc ; CT3.EQ.3
.endm ; .IRPC CH3
.endc ; CT2.EQ.2
.endm ; .IRPC CH2
.endc ; CT1.EQ.1
.endm ; .IRPC CH1
.endm abc
;
tstvar: .blkw ;exists with and without 2 as sixth char
tstva2: .blkw ;(so macro will choose this one)
;
tstnum: .blkw ;only exists without
;
pig: .blkw ;not long enough (won't really be touched)
;
.list me
abc tstvar ;MOV #TSTVA2,-(SP)
abc tstnum ;MOV #TSTNUM,R0
abc pig ;no op (name too short)
;
.end
John, you are correct, your solution does increase the total time to
assemble
the program. Details on why I have written the code in the manner specified
are present in the reply to Ernest that I posted just prior to this
response.
Your solution is brilliant and does the job. THANK YOU!!!!!!!!!!!!!!
However, I neglected to accurately portray the difficulty of the problem
since I want to simplify the sample code. In actual practise, the line of
code produced is always the same:
Mov #WRKTXT,R0
Mov #WRKTX2,R0
But since the executable code is a device driver which uses the .Macro $Rel
to make the code Position Independent at LOAD time, different, methods are
used to determine the second word of the instruction depending on where the
text data is located (Low Memory or one of the extended memory PAR1s).
If the text data is in Low Memory (which is where it was originally),
then at
assemble time, the .Macro $Rel produces a symbol which is the offset
into the
Low Memory portion of the device driver and a table of such offsets allows
the LOAD code to add the starting address of the device driver thereby
producing the actual address of the text data with only 2 instructions
rather
than 3 instructions when the .Macro .Addr is used for PIC (Position
Independent Code). When the text data is moved from Low Memory to
the second PAR1, the actual address can be determined by MACRO-11
since the address becomes virtual and KISAR1 is used to locate the PAR1
memory. The LOAD code allocates that extended memory and finds the
value of KISAR1 to be used, then places that value of KISAR1 in Low
Memory to be used when the device driver is activated. NEAT!!!!!!
The fly in the ointment is that in most cases, during PASS1, the symbol
WRKTX2 is STILL undefined, so the wrong $Rel value was used. This
created a symbol during PASS1 which was NOT used during PASS2
and that resulted in a Phase Error. The solution was to defined two
additional options within the .MACRO $Rel which used the same symbol, but
which added another symbol that was either 0 or 1 (and which MACRO-11
was happy with changing during PASS2) so that the table of offsets produced
at the very end of PASS2 included that offset if the text data was still
in Low
Memory (the second symbol was 0) and the table omitted that offset if the
text data was in a PAR1 (the second symbol was 1).
As of the moment, I am still having difficulty in modifying a second
.Macro which
also has text data which can be in either Low Memory or a PAR1. Your
solution works for the "Mov #WRKTXT,R0" instruction, but the .Macro $Rel
still produces produces errors. In this case, there are very few
optional uses
of the text data being moved out of Low Memory into a PAR1, so if it can't
be solved right now, it can be left as two different invocations of the
.Macro
at this point.
All in all, THANK YOU John for a brilliant solution - and you are welcome
as far as the hack break is concerned.
If anyone else can use some help with the .Macro $Rel in RT-11 device
drivers, just ask.
Jerome Fine