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.slyngs...@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 > -- Doug Ingraham PDP-8 SN 1175