22.10.2013 Views

4 - Forth Interest Group

4 - Forth Interest Group

4 - Forth Interest Group

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

none were found for bit accessing, so we use C@ L and C ! L.<br />

C@L expects paragraph and offset on the stack, and returns<br />

a byte. C ! L expects a byte, paragraph, and offset, and stores<br />

the byte.<br />

For navigation (see code at the end of the article), we<br />

define three SEGMENTS: HEADER. SEG, IMAGE. BOT . SEG,<br />

and IMAGE. TOP. SEG. IMAGE. BOT . SEG holds image rows<br />

879 through 440, while IMAGE. TOP. SEG holds rows 439<br />

through zero. (Recall that Paintbrush reverses the order of the<br />

image rows.)<br />

To get an image of the Paintbrush .BMP file into memory,<br />

we use GET-IMAGE. First, GET-IMAGE uses HS-<strong>Forth</strong>'s<br />

OPEN-Rto find the file whose file-spec address is passed, and<br />

OPEN-R obtains a file handle. The handle is stored on the<br />

return stack.<br />

ymax<br />

Using HS-<strong>Forth</strong>'s READH command, GET-IMAGE then<br />

fills the respective memory areas with a file's contents.<br />

READH expects a memory paragraph segment, offset, file<br />

handle, and number of bytes to read. It returns on the stack<br />

the number of bytes it read into the memory location.<br />

GET-IMAGE "anchors" the image at IMAGE. BOT . SEG. In<br />

other words, after the first half of the image is loaded into<br />

memory, the location of the second half is computed relative<br />

to the first. (Math for the last segment takes advantage of the<br />

fact that eighty divided by sixteen equals five.) CLOSEH<br />

consumes the file handle as it closes the file.<br />

PUT-IMAGE works analogously to GET-IMAGE. Neither<br />

command tests the header or image, but simply moves the<br />

data. Both commands need rewriting for better error han-<br />

dling, if needed.<br />

The image is accessed relative to its first row, which<br />

happens to be its last row in memory. The arcane method of<br />

calculating the paragraph's segment of the first row of the<br />

image is shown next in the code. Fetching the<br />

IMAGE. BOT . SEG paragraph starts the process. Indexing to<br />

the very first image row requires moving the pointer down<br />

879 rows. One VAR receives the segment value, another<br />

receives the offset.<br />

Mappingx and y coordnates to the image byte containing<br />

the pixel uses the command XY->ADR. Notice the use of<br />

high-level words to write a machine language command<br />

using the HS-<strong>Forth</strong> OPT" command. XY->ADR converts y<br />

into a paragraph segment by multiplying y by minus five and<br />

adding the result to the location of row zero (which is last in<br />

memory).<br />

Dividing x by eight converts the pixel number into the<br />

byte number in the row. Adding that to the offset indexes into<br />

the image row. (For several reasons, the beginning offset of<br />

each of the image rows is zero, so some of these steps are<br />

superfluous for the images we are accessing.)<br />

The remainder of x divided by eight points to the pixel,<br />

as shown below.<br />

bit position 7654321 0<br />

The above is performed inside the PIXEL command by<br />

8 MOD (obtaining the bit position) and the data structure<br />

CLEAR. BIT. CLEAR. BIT provides a mask for ANDing the<br />

bit clear (i.e., to zero), thus forcing the pixel lit. In our case,<br />

Paintbrush thinks a zero pixel is lit (black) while a pixel equal<br />

to one is white. (PIXEL performs no range checking, so<br />

either make your own, or be careful.)<br />

O+ xmax<br />

ymax<br />

The PIXEL? command works like PIXEL except a flag<br />

is returned instead of the pixel being set. PIXEL? selects a<br />

bit, then tests it. When the pixel tested is zero, we say it is lit,<br />

or true. Otherwise, PIXEL? returns false.<br />

Finally, we have filename buffers and (rather uninterest-<br />

ing) test code. TEST1 fills an entire Paintbrush page with<br />

black pixels in about twenty-five seconds on my system.<br />

O+ xmax<br />

ymax<br />

TEST2, TEST3, and TEST4 draw lines. TI sets the filenames<br />

buffers and loads an image. GBS is set to a blank page<br />

previously created in Paintbrush, while PBS is set for keeping<br />

results.<br />

These tests were used to verify PIXEL and, oddly<br />

enough, GET-IMAGE and PUT-IMAGE. Strangely, I still<br />

haven't completely figured out HS-<strong>Forth</strong>'s SEGMENT com-<br />

November 1993 December 28 <strong>Forth</strong> Dimensions

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!