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.

IF 52 C, THEN \ PUSH DX<br />

THEN NEXT, ; --><br />

Screen 13<br />

\ EXTERN 15FEB93 RA 03JAN93<br />

\ : HEADER CREATE -2 ALLOT ; \ if you need it<br />

: CREATE-EXTERN ( cfa patch-addr --- )<br />

HEADER \ lays down <strong>Forth</strong> name and link for this word<br />

SWAP , , EXT-LINK, \ I cfa I patch I next-extern I<br />

BL WORD<br />

\ HERE $MOVE HERE \ include if WORD doesn't work at HERE<br />

C@ 1+ ALLOT ; \ I linker-name I<br />

: EXTERN ( #out #in --- ) ( ... --- ax dx I ax I )<br />

OVER 0 2 WITHIN O= IF ." INVALID # OUT PARAMS " ABORT THEN<br />

CODE-EXTERN \ cfa patch-addr<br />

CREATE-EXTERN ;<br />

--> USAGE: #out #in EXTERN DOG -dog<br />

creates <strong>Forth</strong> word DOG to execute external -dog<br />

with #in params on stack before and #out after<br />

Screen 14<br />

\ SHOW-FIXUPS UTILITY WORD RA 17JAN93<br />

: 4H.R BASE @ SWAP HEX 4 .R BASE ! ;<br />

: SHOWlFIXUP ( xlink --- )<br />

DUP 4H.R 2 SPACES \ XLINK<br />

XLINK>FIXADR DUP 4H.R 2 SPACES \ FIXADR<br />

2@ SWAP 4H.R ." :" 4H:R SPACE \ FIXUP<br />

DUP 2+ COUNT TYPE ;<br />

: SHOW-FIXUPS<br />

CR ." FIXUPS "<br />

CR . " XLINK FXADR SEG:OFF label "<br />

CR 1ST-XLINK<br />

BEGIN @ ?DUP<br />

WHILE DUP SHOWlFIXUP CR<br />

REPEAT ; --><br />

Screen 15<br />

\ SAVE-OBJ: OBJ RECORD WRITING 03JAN93 RA 29DEC92<br />

HEX FFFF CONSTANT TOP-ADDR \ we save up to this addr = 64K<br />

VARIABLE RECBUF \ holds address of record buffer<br />

VARIABLE RECBUFP \ pointer into record fbuffer<br />

: OBUF RECBUF RECBUFP @! ; \ sets pointer to beginning of buf<br />

: REC.HERE RECBUFP @ ; \ a minor convenience<br />

: BUF$, ( Sadr --- ) \ move and "comma-in" a string<br />

REC.HERE $MOVE REC.HERE C@ 1+ RECBUFP +! ;<br />

: (BUF,") \ based on ( . "1<br />

R> DUP COUNT + >R BUF$, ; COMPILE-ONLY<br />

: BUF, " COMPILE (BUF, 'I)<br />

11<br />

I ; IMMEDIATE COMPILE-ONLY<br />

: BUFC, ( c --- ) REC .HERE C! 1 RECBUFP +! ;<br />

: BUF,<br />

--><br />

( n --- ) REC.HERE ! 2 RECBUFP +! ;<br />

: DMP.REC RECBUF @ REC.HERE OVER - DUMP ;<br />

Screen 16<br />

\ SAVE-EXE: WR.REC RA 29DEC92<br />

VARIABLE REC-FBUF \ other <strong>Forth</strong> DOS interfaces use a handle<br />

other languages) are left there<br />

for the caller to clean up. Func-<br />

tions that return values return<br />

them in registers: in Borland<br />

and Microsoft C, 16-bit values<br />

are returned in AX and 32-bit<br />

values in DX;AX. Since <strong>Forth</strong><br />

tends to live in (single or mul-<br />

tiple) 64K segments, the exter-<br />

nal C (or other) functions we<br />

use will have to be referenced<br />

by long calls (segment:offset)<br />

and should therefore be com-<br />

piled in the medium, large, or<br />

huge models, or at least be<br />

declared as "far" or "huge."<br />

The huge model, though of<br />

course slowest, is the most<br />

straightforward, since huge<br />

functions save and set the DS<br />

register when they're entered<br />

and restore it when they leave,<br />

keeping <strong>Forth</strong> from having to<br />

know where C keeps its data,<br />

and preventing unexpected<br />

access to <strong>Forth</strong>'s own. The<br />

only data we have to share is<br />

passed (directly or by refer-<br />

ence) on the stack, which had<br />

better be big enough.<br />

So in <strong>Forth</strong> we need a way<br />

to make long calls to places we<br />

don't know about, in such a<br />

way that the Microsoft or<br />

Borland linker can fur them up<br />

for us. I have written a defining<br />

word, EXTERN, which lays<br />

down code for long calls and<br />

links all the words it creates<br />

into a forward-linked list of<br />

external references so they can<br />

be found easily when we write<br />

out the OBJ file.<br />

EXTERN takes two param-<br />

eters on the stack and is fol-<br />

lowed by two names: the <strong>Forth</strong><br />

word that will invoke the long<br />

call, and the external reference<br />

that the linker will use to re-<br />

solve the address of the call<br />

with the appropriate C func-<br />

tion. The usage is<br />

EXTERN <br />

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

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

Saved successfully!

Ooh no, something went wrong!