# Action! CARD LSB/MSB (high value compute failure)

Action!

8 replies to this topic

### #1 RipdubskiOFFLINE

Ripdubski

Stargunner

• 1,306 posts

Posted Wed Aug 5, 2015 7:14 AM

I'm having trouble computing the LSB and MSB of a CARD value.  My routine works fine through 65281.  At 65282 it breaks and I can't figure out why.  Values 65282 through 65535 (last 253) CARD values, compute with MSB=0 while the LSB is still correct.

Here is my routine (used to write a CARD value to a device (file) in LSB/MSB form:

```PROC PutCD(BYTE bDev CARD cVal)
BYTE bL=[0],bM=[0]

bM=cVal/255
bL=cVal%256
PrintF("PutCD: %U (L=%B,M=%B)%E",cVal,bL,bM)
PutD(bDev,bL)
PutD(bDev,bM)
RETURN
```

Output using 65281:

Output using 65282 (note you can also see the value 65535 being converted wrong (from an INT routine that calls PutCD).  Not worried about the INT at this point since the problem appears with the CARDs.

What have I done wrong?

### #2 kenfusedOFFLINE

kenfused

Stargunner

• 1,325 posts
• Location:Columbus, Ohio

Posted Wed Aug 5, 2015 7:29 AM

You should be dividing by 256 and not 255 to get the high byte.

--Ken

### #3 fujidudeOFFLINE

fujidude

• 5,217 posts
• Location:United States of America

Posted Wed Aug 5, 2015 8:20 AM

I'll be posting a solution to this shortly.  I need coffee.

### #4 fujidudeOFFLINE

fujidude

• 5,217 posts
• Location:United States of America

Posted Wed Aug 5, 2015 8:48 AM

Here is a procedure I whipped up which accepts a channel # and a CARD, then puts the corresponding LSB and MSB to a device/file.

```PROC PutCD(BYTE c, CARD v)
BYTE lsb, msb
lsb = v
msb = v RSH 8
PutD(c, lsb)
PutD(c, msb)
RETURN

```

The statement: lsb = v works because Action automatically converts a CARD to a BYTE by just retaining the LSB of the CARD.  This negates having to do something like this: lsb = v & \$00FF

The statement: msb = v RSH 8 works the same way, only the MSB is shifted over into the LSB portion of the card 1st.  Zeroes are supplied to fill in the vacated bits.

Edited by fujidude, Wed Aug 5, 2015 8:48 AM.

### #5 fujidudeOFFLINE

fujidude

• 5,217 posts
• Location:United States of America

Posted Wed Aug 5, 2015 8:52 AM

Here would be a device/file neutral version:

```PROC PutC(CARD v)
BYTE lsb, msb
lsb = v
msb = v RSH 8
Put(lsb)
Put(msb)
RETURN

```

### #6 RipdubskiOFFLINE

Ripdubski

Stargunner

• Topic Starter
• 1,306 posts

Posted Wed Aug 5, 2015 6:30 PM

Here is a procedure I whipped up which accepts a channel # and a CARD, then puts the corresponding LSB and MSB to a device/file.

```PROC PutCD(BYTE c, CARD v)
BYTE lsb, msb
lsb = v
msb = v RSH 8
PutD(c, lsb)
PutD(c, msb)
RETURN

```

The statement: lsb = v works because Action automatically converts a CARD to a BYTE by just retaining the LSB of the CARD.  This negates having to do something like this: lsb = v & \$00FF

The statement: msb = v RSH 8 works the same way, only the MSB is shifted over into the LSB portion of the card 1st.  Zeroes are supplied to fill in the vacated bits.

I originally had it dividing by 256, but the results were less predictable so I thought I was wrong. :/    I also had tried the CARD to BYTE trick, but it didn't work - likely due to my flawed logic.

Thanks for showing me another way.  I wasn't ready to start bit shift learning yet, but theres no better time than the present.

I'm going off to implement the method you've shown here.  Thanx!

### #7 fujidudeOFFLINE

fujidude

• 5,217 posts
• Location:United States of America

Posted Wed Aug 5, 2015 7:44 PM

I originally had it dividing by 256, but the results were less predictable so I thought I was wrong. :/    I also had tried the CARD to BYTE trick, but it didn't work - likely due to my flawed logic.

Thanks for showing me another way.  I wasn't ready to start bit shift learning yet, but theres no better time than the present.

I'm going off to implement the method you've shown here.  Thanx!

No problem.  Glad to help.  After I came up with this I was poking around the collection of toolkit and run-time stuff from OSS/ACS.  Turns out they have a PutCD procedure too, and it's different from mine and they way you were approaching it.  It went something like this (from memory):

```PROC PutCD(BYTE chan, CARD val)
BYTE lsb = val, msb = val + 1
PutD(chan, lsb)
PutD(chan, msb)
RETURN
```

This works because the source CARD get stored in val.  the byte variable lsb is declared and set to live at the same address val is.  Since a card is stored LSB 1st, that works.  The the variable msb is declared and set to live at the same location as the 2nd byte of the CARD val.  This works because it contains the MSB of the card.  Thus msb automatically is equal to the MSB of the CARD val.  Sweet.

What might be confusing to some that are new (or new again) to Action, is that lsb=val and msb=val+1 work on the address of val in the decalration statement, but would provide the actual stored value if used in most parts of the program.  Ask me to clarify further if any of that is murky.

Edited by fujidude, Wed Aug 5, 2015 7:44 PM.

### #8 RipdubskiOFFLINE

Ripdubski

Stargunner

• Topic Starter
• 1,306 posts

Posted Wed Aug 5, 2015 8:47 PM

Yup.  I followed that.  How did I overlook their PutCD?  I'll have to seek it out.  At any rate, I now have PutCD/GetCD/PutID/GetID that work.

Thx!

### #9 fujidudeOFFLINE

fujidude

• 5,217 posts
• Location:United States of America

Posted Wed Aug 5, 2015 8:50 PM

I don't think it is documented.  It is part of the BLOCK_IO.ACT from the toolkit.

### Also tagged with one or more of these keywords: Action!

#### 0 user(s) are browsing this forum

0 members, 0 guests, 0 anonymous users