Post on 19-Dec-2015
Program Control and Data Structures
• CREATE…DOES>
• Program Control– A Simple Jump Table– A Jump Table With WHYP Words
• Data Structures– Arrays– Linked Lists
CREATE…DOES>
: table ( list n +++ ) CREATE 0 DO C, LOOP DOES> ( ix pfa -- c ) + C@ ;
Figure 13.1 Example of a defining word using CREATE...DOES>
3 15 7 2 4 table junk
3 15 7 2 4 table junk
junk JSR ^DOESPFA 2 ix = 0
7 ix = 115 ix = 23 ix = 3
Figure 13.2 The table, junk, created with the defining word table
: table ( list n +++ ) CREATE 0 DO C, LOOP DOES> ( ix pfa -- c ) + C@ ;
table 5000 16 46 93 JSR (CREATE) 5003 16 45 22 JSR (LIT) 5006 00 00 0 5008 16 46 CC JSR (DO)
500B 00 0A 10 ----| 500D 16 46 31 JSR C, <-| | 5010 16 47 1 JSR (LOOP) | |
5013 FF FA –6 --| | 5015 16 46 AE JSR (;CODE) <---| 5018 16 46 B5 JSR DODOES <---| 501B 16 42 E2 JSR + | 501E 16 41 EB JSR C@ |
5021 3D RTS | |
If you then type | |
3 15 7 2 4 table junk | |
the following code will be added in the 68HC12. | |
JUNK 5022 16 50 18 JSR ^DOES -----| PFA 5025 02 2
5026 07 75027 0F 155028 03 3
; (;CODE) ( -- ) Compile time code for DOES>PSCODEPULD ;get addr of JSR DODOESLDY LAST ;replace DOVAR with DODOESSTD 0,Y ;at addr in LASTRTS ;return up one level
; DODOES ( -- pfa ) Run time code for DOES>DODOESPULY ;Y -> code following DOES>PULD ;D = pfa of defined wordPSHYSTD 2,-X ;push pfa on data stackRTS ;return to code after DOES>
Figure 13.3 68HC12 code for the WHYP words (;CODE) and DODOES
Program Control and Data Structures
• CREATE…DOES>
• Program Control– A Simple Jump Table– A Jump Table With WHYP Words
• Data Structures– Arrays– Linked Lists
do.key JSR ^DOESPFA 5 # of words
0word n = 01word n = 12word n = 23word n = 34word n = 4
Figure 13.4 Structure of a simple jump table
JUMP.TABLE do.key ', 0word ', 1word ', 2word ', 3word ', 4word
DROP
Figure 13.5 WHYP code used to create a simple jump table
: JUMP.TABLE ( +++ ) CREATE HERE 0 , DOES> ( n pfa -- ) SWAP 1+ SWAP \ n+1 pfa 2DUP @ > \ n+1 pfa (n+1)>nmax IF 2DROP ELSE SWAP \ pfa n+1 2* + \ addr = pfa + 2(n+1) @ EXECUTE THEN ;
: ', ( pfa -- pfa ) ' , \ store addr of word in table 1 OVER +! ; \ increment count at PFA
Figure 13.6 Definition of WHYP words used to create a simple jump table
Program Control and Data Structures
• CREATE…DOES>
• Program Control– A Simple Jump Table– A Jump Table With WHYP Words
• Data Structures– Arrays– Linked Lists
do.key JSR ^DOESPFA 5 # of entries
A choice 1add
B choice 2subtract
C choice 3multiply
D choice 4divide
E choice 5enter
chrout default
Figure 13.7 Structure of a general jump table
HEXEXEC.TABLE do.key
A | add \ addition B | subtract \ subtraction C | multiply \ multiplication
D | divide \ divisionE | enter \ store number
DEFAULT| chrout \ display digits
Figure 13.8 WHYP code used to create the general jump table in Figure 13.7
: EXEC.TABLE ( +++ ) CREATE HERE 0 , \ pfa DOES> ( n pfa -- ) DUP 2+ \ n pfa pfa+2 SWAP @ \ n pfa+2 cnt 0 DO \ n code.addr 2DUP @ = \ n addr (n=code)
IF \ n addr NIP 2+
LEAVEELSE 4 + \ n addr'THEN
LOOP @ EXECUTE ;
: | ( addr n -- addr ) , ' , \ store n and addr in table 1 OVER +! ; \ increment count at PFA
: DEFAULT| ( addr -- ) DROP ' , ;
Figure 13.9 Definition of WHYP words used to create a general jump table
Program Control and Data Structures
• CREATE…DOES>
• Program Control– A Simple Jump Table– A Jump Table With WHYP Words
• Data Structures– Arrays– Linked Lists
Arrays : array ( size +++ ) CREATE
VHERE , \ save vdp ram addr 2* DUP VALLOT \ allocate memory
, \ save #bytes in array DOES> ( ix pfa -- addr )
@ \ get array addr SWAP 2* + ; \ get address of element
Figure 13.10 Defining word for creating arrays
JSR DOVAR
array address
array size
EPROM
RAM
my_array
ix
0
1
2
3
4
5
6
1234
pfa
1234 3 my_array !
3 my_array @ .
a
b
c d ec d e 0
head
35 21 56
64
a
b
c d eb d e 0
head
35 21 56
64
c
ptr
val
addr Typical node in linked list
Before inserting node b
After inserting node b
Linked Lists
Listing 13.1 Linked List in WHYP\ LINKLIST.WHP\ Linked lists for the 68HC12/68HC11\ Written by Richard E. Haskell\ ------------------------------------------------------\ Linked lists\ Nodes: | ptr | val |
HEX6000 CONSTANT LPTR0 \ the start of some free ram memoryVARIABLE LPTR \ list pointer to unused free memoryLPTR0 LPTR !VARIABLE HEAD \ list header0 HEAD ! \ list initially emptyVARIABLE FREE \ free list header0 FREE ! \ free list initially empty
: LALLOT ( n -- ) LPTR +! ;
\ create a new node: new.node ( -- node.addr ) LPTR @ 4 LALLOT ;
The name of the list is HEAD
\ ------------------------------------------------------\ Node manipulation words
: insert.node ( node.addr list.addr --- ) \ insert at head of list 2DUP @ \ na la na @la SWAP ! ! ;
: remove.node ( list.addr -- node.addr ) \ remove 1st node DUP @ \ a b DUP @ \ a b c ROT ! ; \ b
: get.node ( -- node.addr ) FREE @ IF \ if free node available FREE remove.node \ get it ELSE \ else new.node \ make it from new memory THEN ;
: delete.node ( list.addr -- node.addr ) DUP @ \ a b IF \ if list is not empty remove.node \ remove node from list DUP FREE insert.node \ and put in free list ELSE \ if list is empty DROP 0 \ return 0 THEN ;
\ ------------------------------------------------------\ Data manipulation words
\ push value at head of list: push ( value list.addr -- ) get.node \ get a new node DUP ROT insert.node \ insert it a head of list 2+ ! ; \ store value in node
\ pop value at head of list: pop ( list.addr -- value ) delete.node ?DUP IF \ node.addr 2+ @ \ get value ELSE FFFF \ return ffff if list empty THEN ;
5 head push
head pop
THEN ;
: ?pop ( list.addr -- value tf | ff ) \ ff if list is empty delete.node ?DUP IF \ node.addr 2+ @ TRUE \ get value ELSE FALSE THEN ;
: ?list.empty ( list.addr -- f ) DUP ?pop \ try to pop IF \ if something in list SWAP push FALSE \ push it back - set false ELSE DROP TRUE \ else, set true THEN ;
\ List display and tests
: .all ( list.addr -- ) \ print list contents BEGIN \ a @ ?DUP \ b b | 0 WHILE \ b DUP 2+ @ . REPEAT ; \ b
: get.#nodes ( list.addr -- n ) 0 SWAP \ 0 a BEGIN \ # a @ ?DUP \ 0 b b | 0 0 WHILE \ 0 b SWAP 1+ SWAP \ # b REPEAT ;
head .all
head get.#nodes .
\ find position of node after which to insert value\ so that values will be stored in the list in ascending order
: findpos< ( val list -- val node ) BEGIN \ v a TUCK @ ?DUP \ a v b b | a v 0 WHILE \ a v b 2+ @ \ a v v' OVER > \ a v f - true if v'>v IF \ a v SWAP EXIT \ v a THEN \ a v SWAP @ \ v n REPEAT \ v n SWAP ; \ v n
35 head findpos< push
\ find position of node after which to insert value\ so that values will be stored in the list in descending order
: findpos> ( val list -- val node ) BEGIN \ v a TUCK @ ?DUP \ a v b b | a v 0 WHILE \ a v b 2+ @ \ a v v' OVER < \ a v f - true if v'>v IF \ a v SWAP EXIT \ v a THEN \ a v SWAP @ \ v n REPEAT \ v n SWAP ; \ v n
DECIMAL
35 head findpos> push
Summary
Box 13.1 WHYP Words Introduced in Chapter 13
CREATE...DOES> ( -- )Used in the definition of defining words. When the defining word is executed, thewords between CREATE and DOES> are executed. When the word defined by thedefining word is executed, the words following DOES> (with the pfa on the datastack) are executed.
EXECUTE ( addr -- )Execute the 68HC12 (68HC11) code starting at address addr.