Vince,
This struck me as a pretty clever bit of code. My first cut used 23 words
including 2 masks and 3 temporaries.
This is the working version of Vince's original. It uses 18 words
including 1 mask and 2 temporaries.
I have done some edge testing and it appears to work.
30 / THIS VERSION BY VINCE SLYNGSTAD
31 00210 0000 BSWI, .-. /ENTRY POINT
32 00211 3175 DCA SAVEAC
33 00212 7420 SNL /REMEMBER LINK STATE
34 00213 7040 CMA /AS A -1 FOR ISZ TEST
35 00214 3176 DCA SAVEL
36 00215 7100 CLL /NEED THE LINK CLEARED
37 00216 1175 TAD SAVEAC /GET 0 XXX XXX YYY YYY
38 00217 0177 AND C7700 / 0 XXX XXX 000 000
39 00220 1175 TAD SAVEAC / X XXX XX0 YYY YYY
40 00221 7006 RTL / X XXX 0YY YYY YXX
41 00222 7006 RTL / X X0Y YYY YYX XXX
42 00223 7006 RTL / 0 YYY YYY XXX XXX
43 00224 2176 ISZ SAVEL /WAS LINK SET?
44 00225 7020 CML /YES, RESTORE LINK
45 00226 5610 JMP I BSWI /RETURN
46 $
As Klemens Krause points out you do need the CLL (line 36) somewhere before
the second TAD SAVEAC or it will flip
what was the original leftmost bit (AC 0).
I have thought about this a bunch and have come up with an improved
version. It also uses 18 words including 2 constants
two temporaries. This is one less instruction executed.
32 00210 0000 BSWI, .-. /ENTRY POINT
33 00211 3174 DCA SAVEAC
34 00212 7430 SZL /REMEMBER LINK STATE
35 00213 1177 TAD C0100 /PRE ROTATE LINK POSITION
36 00214 3175 DCA SAVEL
37 00215 7100 CLL /NEED THE LINK CLEARED
38 00216 1174 TAD SAVEAC /GET 0 XXX XXX YYY YYY
39 00217 0176 AND C7700 / 0 XXX XXX 000 000
40 00220 1174 TAD SAVEAC / X XXX XX0 YYY YYY
41 00221 1175 TAD SAVEL / X XXX XXL YYY YYY
42 00222 7006 RTL / X XXX LYY YYY YXX
43 00223 7006 RTL / X XLY YYY YYX XXX
44 00224 7006 RTL / L YYY YYY XXX XXX
45 00225 5610 JMP I BSWI /RETURN
Not bad but I realized even more was possible.
31 00210 0000 BSWI, .-. /ENTRY POINT
32 00211 3174 DCA SAVEAC
33 00212 7430 SZL /REMEMBER LINK STATE
34 00213 1176 TAD C0100 /PRE ROTATE LINK POSITION
35 00214 7100 CLL /NEED THE LINK CLEARED
36 00215 1174 TAD SAVEAC /GET 0 XXX XXX YYY YYY
37 00216 0175 AND C7700 / 0 XXX XXX 000 000
38 00217 1174 TAD SAVEAC / X XXX XX0 YYY YYY
39 00220 7006 RTL / X XXX LYY YYY YXX
40 00221 7006 RTL / X XLY YYY YYX XXX
41 00222 7006 RTL / L YYY YYY XXX XXX
42 00223 5610 JMP I BSWI /RETURN
I realized I could add in the link with the first TAD and the result is the
same so was able to eliminate the DCA SAVEL and
the corresponding TAD SAVEL and since SAVEL was not used anymore I got rid
of that as well. This is 15 words long which
includes the two constants and the one temporary.
I think the only way you could do this faster would be to use a whole field
as a lookup table but that uses a lot more space.
48 00227 0000 BSWT1, .-.
49 00230 3175 DCA SAVEAC
50 00231 6271 CDF 070 /ASSUME LOOKUP TABLE IS ON PAGE 7
51 00232 1575 TAD I SAVEAC
52 00233 6201 CDF 000 /RESTORE DATA FIELD
53 00234 5627 JMP I BSWT1 /RETURN
Something like that anyway.
Thanks for an interesting bit of optimization!
Doug
On Thu, Sep 8, 2016 at 6:07 PM, Vincent Slyngstad <v.slyngstad at frontier.com>
wrote:
From: Kyle Owen: Thursday, September 08, 2016 3:53 PM
How does the following compare to your BSWEMU, by
the way? This ensures
that the link bit remains untouched, which may or may not be important in
every case of BSW in my application.
I'm sure I've seen some code before that does this, but I can't seem to
find any now that I'm looking for it. Maybe
there's a shorter way. I think
this takes 23 words if you include the (0100), (7700), and (0077), which
may or may not also be used elsewhere in the first page where I put this
subroutine.
Here's my slightly optimized version, for what it's worth:
1 *400
2 /
3 / BSW emulation
4 /
5 00400 0000 bsw, .-.
6 00401 3216 dca saveac / Save AC
7 00402 7630 szl cla / Link set?
8 00403 7140 cll cma / Yes, remember it
9 00404 3217 dca savel
10 00405 1216 tad saveac / Get 0 xxx xxx yyy yyy
11 00406 0220 and c7700
12 00407 1216 tad saveac / x xx xxx0 yyy yyy
13 00410 7006 rtl
14 00411 7006 rtl
15 00412 7006 rtl / 0 yyy yyy xxx xxx
16 00413 2217 isz savel / Was link set?
17 00414 7020 cml / Yes, restore it
18 00415 5600 jmp i bsw / return
19 00416 0000 saveac, .-.
20 00417 0000 savel, .-.
21 00420 7700 c7700, 7700
22 $
There is a fair chance that each of saveac, savel, and c7700 can be reused
elsewhere.
Some assemblers flag the "(" construct when used on page 0, BTW. It's
more correct
to use "[" there (or to avoid both).
I'm a "family of 8" guy, so I avoid using BSW to begin with.
Vince