Ted: The byte to word address translation is what is causing the confusion. Those of us who wrote SPL procedures to be called from BASIC became very familiar with the address translation problem very quickly. At the bottom of page F-4 and on page F-5 of the "Systems Programming Language Reference Manual" is a description of the byte to word address translation problem and some sample code which takes care of the problem. As the text points out, the problem is that it is possible to have a byte address which points to the DB-minus area, but that it is also possible that a byte address points to a very large DB-plus address - an address greater than can be expressed as a signed, 2s complement integer. Think of how the stack looks. Register Area -------- ---- +----------------------+ | PCBX Area | DL +----------------------+ DL+0 | User DL Area | |----------------------| (DB-minus area, | Subsystem DL Area | DL-plus area) | (VPlus, etc.) | DB +----------------------+ DB+0 | Global Variable | | Storage | | | QI +----------------------+ Initial Q location | Stack markers, | | procedure local | | variables | Q +----------------------+ Q Last stack marker | Local variables for | | the current | | procedure | S +----------------------+ S Top of Stack | Unused space at the | | top of stack, area | | into which the | | current procedure | | or procedures it | | calls can expand | Z +----------------------+ Z Stack Limit | A 128 word stack | | overflow area | | reserved for error | | handling and stack | | overflows | +----------------------+ Now, consider the size of the stack. It fits into an extra data segment, and can be 32,764 words in size. Some of that space is reserved for MPE use (the PCBX area) so the available space (from your program's perspective) is less than 32,764 words - and in most cases is 31,232 words or less. If the addressable range of the stack is 31,232 words, how many bytes is that? Twice as many bytes, right? So that means the byte addresses cover a range of 62,464 bytes...in a 16 bit integer word. Okay, that means that those 62,464 byte address range must be mapped into an integer address space that spans from -32,768 through +32,767. Now further assume that you have not allocated any DL to DB area, so the DB register is near the base of the stack's extra data segment, and that you have declared many arrays - say 24,000 words worth. Most of your stack is now in the DB to initial Q region, and is global storage. To access these global variables, DB relative addressing will be used. Assume that at DB+22,000 (decimal) is a LOGICAL ARRAY named WORK which is your print buffer. The word address is simple ... +22,000. The byte address should be twice that value, or ... Oops! It is greater than 32,767, the largest integer. Okay, so what if it is treated as an unsigned integer (or logical, in other words). The value would be 44,000. But, use that value for addressing and it becomes the integer -21,536! Okay, byte addresses can be negative, so that COULD be a DB-minus address. But byte addresses can be greater than 32,767 also, in which case the address needs to be treated as an unsigned value rather than a signed value. So how do you know which? You use the "S" register, as explained on page F-5 of the manual. In your case the problem is going from a byte address that is expressed as a negative integer, to an integer word address. Your byte address is so large that while it looks like a negative number, it is really treated as an unsigned integer. Using the above addresses as an example, your stack might be laid out something like this: DB Relative Addresses --------------------- 2s Unsigned Comp Int Word Byte Byte Register Addr Addr Addr -------- ------ ------ ------ XDS Base +------+ -512 -1024 -1024 | | DL +------+ -88 -176 -176 | | DB +------+ 0 0 0 | | | | | | | | |------| | Work | 22000 -21536 44000 | Array| | | |------| | | Q +------+ 22136 -21264 44272 | | S +------+ 22142 -21252 44284 | | Z +------+ 23330 -18876 46660 | | +------+ Your situation is very similar to that of the variable at word address +22,000 in the above example. Assume for a moment that the byte address you have is the same as in the above example, and when expressed as an integer is -21,536. When you divide by two to get the word address (using the ASR instruction used with 2s complement integer operations), you get -10,768. When -10,768 is used as the word address, it points somewhere not only in the DB-minus area, but so far below DB that it goes below the DL register, below the PCBX area, and off the bottom of the extra data segment. Obviously a bounds violation. However, if you take the -21,536 address and instead of performing an integer divide by two perform a logical/unsigned divide by two operation (using the LSR instruction and treating the -21,536 value as the unsigned integer 44,000), you get +22,000, a valid address in the DB-plus area. The trick is to know whether the byte address is in the DB-plus area or in the DB-minus area. The code on page F-5 will take care of the problem for you. In summary: o If the byte address is in the DB-plus area, you must use LSR to calculate the proper word address. o If the byte address is in the DB-minus area, you must use ASR to calculate the proper word address. (if you come up with a DL-DB area so large that the negative byte address wraps around, expect more problems) Whenever possible, use a native word address rather than calculating the word address. The same goes for byte addresses. That is why declarations like: Logical Array LBuf(0:127); Byte Array BBuf(*)=LBuf; are so often found in SPL programs. The work of calculating the correct address to use is dumped on the SPL compiler (which knows whether where the variable is located), and there is far less chance of an addressing error. Hope the explaination helps, John At 3/3/99 09:44 AM , you wrote: >Thus it was written in the epistle of Frank McConnell, >> FREAD expects you to give it a logical array, so hand it WORKL >> instead of WORK. >> >> At least for SPL on the classic (meaning I have no idea how this works >> when Splash! and/or PA-RISC 3000s are involved), when you call an >> intrinsic that expects a word pointer but give it a byte pointer, the >> compiler inserts an arithmetic shift right (ASR) to convert the byte >> pointer to a word pointer (and should give you a warning to tell you >> that it's been so helpful). ASR preserves the sign bit, so if the >> value of the byte pointer is negative, so will be the value of the >> word pointer. (Also, if the byte pointer is odd (not word-aligned), >> the least significant bit will get lost, so the resulting word pointer >> will likely point one byte off from your byte pointer.) > >Ok, I'm confused. At least the code seems to have tried to do the right thing >with FREAD. It *is* passing a word address or what is trying to be a word >address. I'm sorry for miswriting in my original post. However this ASR vs. >LSR thing has got me confused. In the SPL manual (the December, 1976 version, >p 4-3), it claims, "All addresses are signed, one-word integers and are >treated as such in expressions." However, when @WORK was negative, passing >@WORK & ASR(1) to FREAD gave me a bounds violation, but passing @WORK & LSR(1) >gave me good results. From that, it seems that addresses are *unsigned*. So >what's up wid dat? > >Ted >-- >Ted Ashton ([log in to unmask]), Info Serv, Southern Adventist University > ========================================================== >[Of her:] >Her statistics were more than a study, they were indeed her religion. . . . >she held that the universe -- including human communities -- was evolving in >accordance with a divine plan; that it was man's business to endeavor to >understand this plan and guide his actions in sympathy with it. But to >understand God's thoughts, she held we must study statistics, for these are the >measure of His purpose. Thus the study of statistics was for her a religious >duty. > -- Nightingale, Florence (1820-1910) -------------------------------------------------------------- John Korb email: [log in to unmask] Innovative Software Solutions, Inc. The thoughts, comments, and opinions expressed herein are mine and do not reflect those of my employer(s), or anyone else.