16-bit PEEKs and POKEs

Started by hydrophilic, September 07, 2007, 01:08 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

hydrophilic

This applies to most classic Commodore computers.  With BASIC 7.0, PEEKs and POKEs are used less frequently, but anyway...

--------------------
16-bit (unsigned) POKE

First issue the statment,
DEF FNHB(X)=INT(X/256):DEF FNLB(X)=X-32768 AND 255

From then on, to poke address A with value X use
POKE A,FNLB(X):POKE A+1,FNHB(X)

This method is shorter to type than the often used
H=INT(X/256):POKE A,X-256*H:POKE A+1,H
plus it saves a variable (H)

--------------------
16-bit (unsigned) PEEK

First issue the statement,
DEF FNDP(X)=PEEK(X)+256*PEEK(X+1)

From then on, to peek address A into variable X use
X=FNDP(A)

This method saves quite a bit of typing!

--------------------
Finally for the 128, note there is a documented bug with DEF'd functions.  You must define them after allocating the VIC bitmap (assuming program uses VIC bitmap) because the text that defines the functions gets moved in memory (allong with the whole program) but the function pointers are not updated!

smf

How does:
DEF FNLB(X)=X-32768 AND 255
differ from
DEF FNLB(X)=X AND 255
?

nikoniko

Because the AND operation expects to operate with a signed 16-bit integer value, BASIC blows up with an Illegal Quantity Error when you give it something larger than 32767. So to allow for calculating the low byte of addresses 32768 and above, 32768 is subtracted first.

BigDumbDinosaur

This method is shorter to type than the often used H=INT(X/256):POKE A,X-256*H:POKE A+1,H plus it saves a variable (H)

Yes, but actually slower, due to the use of indirect references to the defined function.  Which is more important: fast typing or fast execution.

Also, if X is the 16 bit value to be POKEd, why not use POKE A,(32768-X) AND 255:POKE A+1,X/256?

BASIC automatically converts POKE parameters to integers, so the INT(X/256) step is unnecessary.  Small code tends to be fast code.

BDD
x86?  We ain't got no x86.  We don't need no stinking x86!

hydrophilic

Good point about INT being unneccessary. The trick is for easy reading/writing.  For speed, use assembly language. :)

BigDumbDinosaur

Quote from: hydrophilicGood point about INT being unneccessary. The trick is for easy reading/writing.  For speed, use assembly language. :)
Even when speed isn't important I tend to default to assembly language, simply because I have worked with it almost since the inception of the 6502 MPU.  :)

It was nearly two years after I learned 6502 assembly language that I finally became reasonably proficient in BASIC.  I did that so I could test concepts in a more abstract way prior to making the time investment in writing and assembling machine code.  I never considered any version of Commodore BASIC suitable for serious applications, simply because it is too slow (especially when garbage collection gets you, although that isn't a serious issue with BASIC 7.0).

I got my first C-128 in late 1985 and had to exchange it because of poor 80 column video quality.  The replacement worked fine.  About a year-and-a-half later I bought a Xetec Lt. Kernal system and soon discovered that there was a whole other world hidden behind that DOS, and out of reach of BASIC.  It was a world of minicomputer technology shrunk to fit an 8 bit machine with a limited operating system.

In mid-1987, I bought two C128D boxes, got some Lt. Kernal host adapters for them, and a multiplexer to wire the whole mess together, creating a multiuser system that fit into my spare bedroom.  I never much looked at Commodore BASIC after that, other than to write simple "proof of concept" programs, since getting into all those Lt. Kernal goodies required a healthy dose of machine code.

As for easy reading/writing, I'm accustomed to typing in literally thousands of lines of computer gibberish into a source code editor, so easy is a relative thing.  Since any reasonably complete assembly language program (that is, one that actually does something useful besides turn the screen into something resembling baby puke) can be upwards of 8000 to 10,000 lines total, I was always on the lookout for ways to reduce wear-and-tear on my already stubby fingers.  That was why macros were invented.  BASIC has nothing like them (at least not Microsoft BASIC -- the timesharing versions that were developed for minicomputers were and still are a different breed altogether).

Commodore's BASIC also tends to not be particularly easy to read.  The tokenizer mostly allows run-together code (e.g., FORT=1to100), which other BASIC versions usually don't tolerate.  Other than a few REMs here and there, it's difficult to really communicate the programmer's thinking in a way that someone with no prior exposure to the program can easily figure out what it is supposed to do.  Being limited to two char variable names doesn't help matters.  Now, it we could use longer variable names, that would help, eh?  So would a CALL statement, which is conceptually similar to the block function structure of ANSI C.  But those will never appear either, so it must sound like a lot of wishful thinking, eh?
x86?  We ain't got no x86.  We don't need no stinking x86!