Branching and Looping

Download Report

Transcript Branching and Looping

Branching and Looping
Chapter 5
Branching and Looping
• 68HC12 Branch Instructions
• WHYP Branching and Looping Words
• Recursion in WHYP
Table 5.1 Simple Short Conditional Branch Instructions
Operation
Mnemonic
Branch Test
Branch if equal zero
BEQ
Z=1
Branch if not equal zero
BNE
Z=0
Branch if plus
BPL
N=0
Branch if minus
BMI
N=1
Branch if carry clear
BCC
C=0
Branch if carry set
BCS
C=1
Branch if overflow set
BVS
V=1
Branch if overflow clear
BVC
V=0
Branch Displacement
PC =
PC + 2 =
5012
5014
5016
5017
501A
27
-----
06
--
Z=0
BEQ DONE
------ ----DONE:
---
Z=1
= 5014 + 06 = 501A
Negative Branch
PC =
PC + 2 =
500C
500D
500F
5012
5014
5016
---26
---
--F8
---
--LOOP1:
-----BNE LOOP1
---500CLOOP1
-5014IP + 2
FFF8
Table 5.2 Unconditional Branch and Jump Instructions
Operation
Mnemonic
Operand
Short Branch Always
BRA
8-bit displacement
Long Branch Always
LBRA
16-bit displacement
Jump
JMP
<effective address>
Branch on Z flag
44be
44c0
44c2
44c4
44c5
44c7
ed
68
65
03
26
3d
31
01
00
f9
; LSHIFT
( n1 n2 -- n1 )
;
Left shift bits of n1 n2 times
LSHIFT
LDY
2,X+
;Y = n2
LS1
ASL
1,X
;arith shift left
ROL
0,X
; n2 bits
DEY
BNE
LS1
RTS
Branch on Z flag
;
;
EESTA
409c
409d
409f
40a1
40a3
40a5
40a6
40a8
40aa
40ac
40ae
40b0
40b3
40b5
40b7
40ba
36
a6
81
27
07
32
c6
5b
6a
c6
5b
16
c6
5b
79
3d
40
ff
02
16
EEB1
02
f3
40
03
f3
40 d8
02
f3
00 f3
EEPROM PROGRAMMING ROUTINES
STORE BYTE A AT ADDRESS Y
PSHA
LDAA
CMPA
BEQ
BSR
PULA
LDAB
STAB
STAA
LDAB
STAB
JSR
LDAB
STAB
CLR
RTS
0,Y
#$FF
EEB1
BYTEE
#$02
EEPROG
0,Y
#$03
EEPROG
DLY10
#$02
EEPROG
EEPROG
;save byte
;if @addr != FF
;erase byte
;get byte
;set EELAT bit
;store data to EEPROM
;set EEPGM bit
;10 msec delay
;turn off hi voltage
;clear EELAT bit
Branch on Z flag
;
NEGATE
446e
4470
4472
4474
4475
4477
60
27
61
3d
60
3d
01
03
00
00
NG1
NEGATE
NEG
BEQ
COM
RTS
NEG
RTS
( n -- -n )
1,X
NG1
0,X
0,X
;negate low byte
;if not zero
;complement high byte
;else
; negate high byte
Branch on N flag
; ABS
ABS
4478
447a
447c
447e
4480
4482
4483
4485
e7
2a
60
27
61
3d
60
3d
00
09
01
03
00
00
AB1
AB2
( n -- |n| )
TST
BPL
NEG
BEQ
COM
RTS
NEG
RTS
0,X
AB2
1,X
AB1
0,X
0,X
;if negative
;negate:
;negate low byte
;if not zero
;complement high byte
;else
; negate high byte
Branch on N flag
; S>D
STOD
4513
4516
4518
451a
451d
451f
cc
e7
2b
cc
6c
3d
ff ff
00
03
00 00
2e
SD1
( n -- d )
LDD
TST
BMI
LDD
STD
RTS
#$FFFF
0,X
SD1
#$0000
2,-X
sign extend single to double
;negative extend
;if n positive
;extend zeros
;else extend 1's
Branch on C and V flags
435a
435b
435d
435f
4361
4362
4364
4366
4369
436c
436d
436f
4371
4373
34
ed
ec
ee
11
25
28
cc
cd
30
1a
6c
6d
3d
02
04
00
02
06
ff ff
ff ff
02
02
00
; UM/MOD
( udl udh un -- ur uq )
32/16 = 16:16
; Unsigned divide of a double by a single.
; Return mod and quotient.
UMMOD
PSHX
LDY
2,X
LDD
4,X
LDX
0,X
EDIV
BCS
UM1
;if div by 0
BVC
UM2
; or overflow
UM1
LDD
#$FFFF
; rem = $FFFF
LDY
#$FFFF
; quot = $FFFF
UM2
PULX
LEAX
2,X
STD
2,X
STY
0,X
RTS
Bit-Condition Branch Instruction
Table 5.3 Bit-Condition Branch Instructions
Operation
Mnemonic
Branch Test
(M) & (mask) = 0
Branch if Selected Bits Clear
BRCLR
!(M) & (mask) = 0
Branch if Selected Bits Set
BRSET
FD80
CODE_START:
----FD89 4F6F0103
BRCLR
FD8D 061000
JMP
FD90
DB12:
PORTAD, $01, DB12
EESTART
;if bit 0 of PORTAD is 1
;then jump to start of EEPROM
;else stay in D-Bug12
Table 5.4 Conditional Jump Instructions to Use Following
a Comparison of UNSIGNED Numbers
Operation
Mnemonic
Branch Test
Branch if Higher
BHI
C or Z = 0
Branch if Lower or Same
BLS
C or Z = 1
Branch if Higher or Same
BHS
C=0
Branch if Lower
BLO
C=1
Table 5.5 Conditional Jump Instructions to Use Following
a Comparison of SIGNED Numbers
Operation
Mnemonic
Branch Test
Branch if Greater Than or equal
BGE
N xor V = 0
Branch if Less Than
BLT
N xor V = 1
Branch if Greater Than
BGT
Z or (N xor V) = 0
Branch if Less than or Equal
BLE
Z or (N xor V) = 1
How many times is the
instruction INCB executed?
LOOP
CLRB
INCB
CMPB
#$C8
BLT
LOOP
;set B = 0
;increment B
;compare B to C8H
;loop if B < 200
Signed Branch Instructions
;
MIN
445c
445e
4460
4462
4464
ed
ad
2c
6d
3d
31
00
02
00
MIN1
;
MAX
4465
4467
4469
446b
446d
ed
ad
2f
6d
3d
31
00
02
00
MX1
MIN
LDY
CPY
BGE
STY
RTS
MAX
LDY
CPY
BLE
STY
RTS
(n1 n2 -- min )
2,X+
0,X
MIN1
0,X
;Y = n2
;if n2 < n1
;leave n2 on stack
;else leave n1
(n1 n2 -- max )
2,X+
0,X
MX1
0,X
;Y = n2
;if n2 > n1
;leave n2 on stack
;else leave n1
Branching and Looping
• 68HC12 Branch Instructions
• WHYP Branching and Looping Words
• Recursion in WHYP
WHYP Branching and Looping Words
•
•
•
•
•
IF…ELSE…THEN
FOR…NEXT
BEGIN…AGAIN
BEGIN…WHILE…REPEAT
DO…LOOP
Box 5.1 WHYP Conditional Words
The following WHYP conditional words produce a true/false flag:
<
( n1 n2 -- f )
( "less-than" )
flag, f, is true if n1 is less than n2.
>
( n1 n2 -- f )
( "greater-than" )
flag, f, is true if n1 is greater than n2.
=
( n1 n2 -- f )
flag, f, is true if n1 is equal to n2.
<>
( n1 n2 -- f )
( "not-equal" )
flag, f, is true if n1 is not equal to n2.
<=
( n1 n2 -- f )
( "less-than or equal" )
flag, f, is true if n1 is less than or equal to n2.
>=
( n1 n2 -- f )
( "greater-than or equal" )
flag, f, is true if n1 is greater than or equal to n2.
0<
( n -- f )
( "zero-less" )
flag, f, is true if n is less than zero (negative).
0>
( n -- f )
( "zero-greater" )
flag, f, is true if n is greater than zero (positive).
0=
( n -- f )
( "zero-equals" )
flag, f, is true if n is equal to zero.
( "equals" )
The following conditional words compare two unsigned numbers on the stack.
U<
( u1 u2 -- f )
( "U-less-than" )
flag, f, is true if u1 is less than u2.
U>
( u1 u2 -- f )
( "U-greater-than" )
flag, f, is true if u1 is greater than u2.
U<=
( u1 u2 -- f )
( "U-less-than or equal" )
flag, f, is true if u1 is less than or equal to u2.
U>=
( u1 u2 -- f )
( "U-greater-than or equal" )
flag, f, is true if u1 is greater than or equal to u2.
68HC12 Code for <
;
< ( n1 n2 -- t )
; Return true if n1 is less than n2.
LT
LDY
#$FFFF
;true
LDD
2,X+
;D = n2
CPD
0,X
;if n2 <= n1
BGT
LT1
LDY
#0
;set false
LT1
STY
0,X
;set flag
RTS
68HC12 Code for U<
;
U< ( u1 u2 -- t )
; Return true if u1 is less than u2.
ULT
LDY
#$FFFF
;true
LDD
2,X+
;D = u2
CPD
0,X
;if u2 <= u1
BHI
ULT1
LDY
#0
;set false
ULT1
STY
0,X
;set flag
RTS
Box 5.2 WHYP Logical Operators
INVERT ( n -- 1's_comp )
Leaves the bitwise 1's complement of n on top of the stack.
NOT
( n -- not )
Leaves the logical NOT of n on top of the stack.
NOT is equivalent to 0=.
AND
( n1 n2 -- and )
Leaves n1 AND n2 on top of the stack. This is a bitwise AND.
OR
( n1 n2 -- or )
Leaves n1 OR n2 on top of the stack. This is a bitwise OR.
XOR
( n1 n2 -- xor )
Leaves n1 XOR n2 on top of the stack. This is a bitwise XOR.
TRUE = -1
FALSE = 0
68HC12 Code for AND
;
;
ANDD
AND ( n1 n2 -- and )
Bitwise AND.
LDD
ANDA
STAA
ANDB
STAB
RTS
2,X+
0,X
0,X
1,X
1,X
;pop n2 into D
IF…ELSE…THEN
<cond> IF <true statements> ELSE <false statements> THEN
: iftest
( f -- )
IF
CR ." true statements"
THEN
CR ." next statements" CR ;
: if.else.test ( f -- )
IF
CR ." true statements"
ELSE
CR ." false statements"
THEN
CR ." next statements" CR ;
: iftest
( f -- )
IF
CR ." true statements"
THEN
CR ." next statements" CR ;
: if.else.test ( f -- )
IF
CR ." true statements"
ELSE
CR ." false statements"
THEN
CR ." next statements" CR ;
TRUE iftest
true statements
next statements
FALSE iftest
next statements
: iftest
( f -- )
IF
CR ." true statements"
THEN
CR ." next statements" CR ;
: if.else.test ( f -- )
IF
CR ." true statements"
ELSE
CR ." false statements"
THEN
CR ." next statements" CR ;
TRUE if.else.test
true statements
next statements
FALSE if.else.test
false statements
next statements
IF…ELSE…THEN Example
HEX
: hex2asc
( n -- asc )
0F AND
\ mask upper nibble
DUP 9 >
\ if n > 9
IF
37 +
\
add $37
ELSE
30 +
\ else add $30
THEN ;
ok
see hex2asc
hex2asc
(LIT) 0 F AND DUP (LIT) 0 9
> LBEQ 0 C (LIT) 0 37 + LBRA
+ ;
ok
0
8 (LIT)
0 30
HEX
: hex2asc
ok
show hex2asc
hex2asc
16 45 22 0 F
16 41 F3
16 41 8
16 45 22 0 9
16 42 6A
EC 31
18 27 0 C
16 45 22 0 37
16 42 E2
18 20 0 8
16 45 22 0 30
16 42 E2
3D
ok
( n -- asc )
0F AND
\ mask upper nibble
DUP 9 >
\ if n > 9
IF
37 +
\
add $37
ELSE
30 +
\ else add $30
THEN ;
HEX2ASC
JSR (LIT)
JSR AND
JSR DUP
JSR (LIT)
JSR >
LDD 2,X+
LBEQ +12
JSR (LIT)
JSR +
LBRA +8
JSR (LIT)
JSR +
RTS
0F
9
IF
37
ELSE
30
THEN
FOR…NEXT Loop
n FOR <WHYP statements> NEXT
C:\WHYP\WHYP12>whyp12
Using WHYP12.HED
Communicating with COM1
68HC12 WHYP12 - Version 4.6
Press <Esc> or type BYE to exit
ok
: stars for ." *" next ; ok
5 stars *****ok
10 stars **********ok
2 stars **ok
: pattern 10 for cr r@ stars next cr ; ok
pattern
**********
*********
********
*******
******
*****
****
***
**
*
ok
: stars
for ." *" next ;
ok
see stars
stars
>R (.")
ok
show stars
stars
16 41 B1
16 45 C7 1 2A
B7 76
EC 40
83 0 1
6C 40
26 F0
16 41 C4
3D
ok
1 2A DONEXT R>DROP ;
JSR
JSR
TSY
LDD
SUBD
STD
BNE
JSR
RTS
>R
(.") 1 '*'
FOR
NEXT
0,Y
#1
0,Y
-16
R>DROP
FOR…NEXT Delay Loop
ok
: delay 20000 for next ; ok
see delay
delay
(LIT) 4E 20 >R DONEXT R>DROP ;
ok
show delay
delay
#clock cycles
16 45 22 4E 20
JSR (LIT) 20000
4+17 = 21
16 41 B1
FOR
JSR >R
4+15 = 19
B7 76
DONEXT
TSY
1
EC 40
LDD 0,Y
3
83 0 1
SUBD #1
2
6C 40
STD 0,Y
2
26 F5
BNE -16
3
11 * N
16 41 C4
JSR R>DROP
4+13 = 17
3D
RTS
5
ok
JSR delay
4
62 + 11*N
8 MHz clock: #ms = #clock_cycles/8 = 7.75 +1.375*N
N = (#ms - 7.75)/1.375
Ex: 50 ms delay: N = (50000 - 7.75)/1.375 = 36358
;
;
LIT
(LIT)
PULY
LDD
STD
INY
INY
PSHY
RTS
( -- n )
Runtime routine for single literals
0,Y
2,-X
3
3
2
1
1
2
5
17
;Y -> number
;Push number
;on data stack
;jump over number
;
>R ( w -- )
( R: -- w )
; Push the data stack to the return stack.
TOR
PULY
3
;save return addr
LDD
2,X+
3
;D = w
PSHD
2
;push D on ret stack
PSHY
2
;restore return addr
RTS
5
15
;
RFDROP
R>DROP
PULY
PULD
PSHY
RTS
( R: sys -- )
3
3
2
5
13
;save return addr
;pop sys
;restore return addr
Longer Delays
ok
: 50ms.delay 36358 FOR NEXT ; ok
: 1s.delay 20 FOR 50ms.delay NEXT ;
: 10s.delay 200 FOR 50ms.delay NEXT ;
Note: A 10 second delay on the MC68HC12A4EVB
takes about 17 seconds because one wait state
has been added to each access to external RAM.
The 68HC11 takes over twice as long to execute
the same delay instructions.
BEGIN…AGAIN
BEGIN <WHYP statements> AGAIN
: stars.forever
( -- )
BEGIN
pattern
AGAIN ;
ok
show stars.forever
stars.forever
BEGIN
16 50 17
18 20
FF F9
3D
ok
JSR pattern
LBRA
-7
RTS
AGAIN
BEGIN…UNTIL
BEGIN <WHYP statements> <flag> UNTIL
: stars
( n -- )
FOR
." *"
NEXT ;
: rows.of.stars ( n -- )
1
BEGIN
CR DUP stars
1+
2DUP <
UNTIL
2DROP CR ;
\ n i
\
\
\
\
n
n
n
n
i
i+1
i+1 f
i+1
ok
5 rows.of.stars
*
**
***
****
*****
ok
15 rows.of.stars
*
**
***
****
*****
******
*******
********
*********
**********
***********
************
*************
**************
***************
ok
see rows.of.stars
rows.of.stars
(LIT) 0 1 CR DUP stars
1+ 2DUP < LBEQ FF E8 2DROP
CR ;
ok
show rows.of.stars
rows.of.stars
16 45 22 0 1
JSR (LIT) 0001
BEGIN
16
16
16
16
16
16
EC
18
16
16
3D
ok
46
41
50
44
41
42
31
27
41
46
4E
8
0
86
4F
3F
FF E8
4A
4E
JSR
JSR
JSR
JSR
JSR
JSR
LDD
LBEQ
JSR
JSR
RTS
CR
DUP
stars
1+
2DUP
<
2,X+
-24
2DROP
CR
UNTIL
BEGIN…WHILE…REPEAT
BEGIN <words> <flag> WHILE <words> REPEAT
x = 1
i = 2
WHILE (i <= n)
{
x = x * i
i = i + 1
}
factorial = x
: factorial
( n -- n! )
1 2 ROT
BEGIN
2DUP <=
WHILE
-ROT TUCK
* SWAP
1+ ROT
REPEAT
2DROP ;
\
\
\
\
\
\
\
\
\
x i n
x i n
x i n f
x i n
n i x i
n x' i
x' i' n
x i n
x
load fact.whp
\
Example of BEGIN...WHILE...REPEAT
: factorial
Current value
ok
3 factorial .
5 factorial .
0 factorial .
( n -- n! )
1 2 ROT
BEGIN
2DUP <=
WHILE
-ROT TUCK
* SWAP
1+ ROT
REPEAT
2DROP ;
of target dp is 5033
6 ok
120 ok
1 ok
\
\
\
\
\
\
\
\
\
x i n
x i n
x i n f
x i n
n i x i
n x' i
x' i' n
x i n
x
see factorial
factorial
(LIT) 0 1 (LIT) 0 2 ROT 2DUP
<= LBEQ 0 16 -ROT TUCK *
SWAP 1+ ROT LBRA FF DE 2DROP ;
ok
show factorial
factorial
16 45 22 0 1
JSR (LIT) 0001
16 45 22 0 2
JSR (LIT) 0002
16 41 1E
JSR ROT
16 41 4F
JSR 2DUP
16 42 88
JSR <=
EC 31
LDD 2,X+
18 27 0 16
LBEQ +22
16 41 2B
JSR -ROT
16 41 3D
JSR TUCK
16 43 3B
JSR *
16 41 D
JSR SWAP
16 44 86
JSR 1+
16 41 1E
JSR ROT
18 20 FF DE
LBRA -34
16 41 4A
JSR 2DROP
3D
RTS
BEGIN
WHILE
REPEAT
\
Sine and Arcsine
Sine table
File: SINE.WHP
DECIMAL
CREATE SINTBL
00000 ,
00872 ,
01736 ,
02588 ,
03420 ,
04226 ,
05000 ,
05736 ,
06428 ,
07071 ,
07660 ,
08192 ,
08660 ,
09063 ,
09397 ,
09659 ,
09848 ,
09962 ,
10000 ,
\
: ASIN
00175
01045
01908
02756
03584
04384
05150
05878
06561
07193
07771
08290
08746
09135
09455
09703
09877
09976
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
00349
01219
02079
02924
03746
04540
05299
06018
06691
07314
07880
08387
08829
09205
09511
09744
09903
09986
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
00524
01392
02250
03090
03907
04695
05446
06157
06820
07431
07986
08480
08910
09272
09563
09781
09925
09994
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
00698
01571
02419
03256
04076
04848
05592
06293
06947
07547
08090
08572
08988
09336
09613
09816
09945
09998
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
00
05
10
15
20
25
30
35
40
45
50
55
60
65
70
75
80
85
90
-
04
09
14
19
24
29
34
39
44
49
54
59
64
69
74
79
84
89
ARCSIN
\ n = 0 - 10000
( n -- angle )
\ angle = 0 - 90 degrees
SINTBL SWAP 0 -ROT
\ 0 pfa n
BEGIN
OVER @ OVER <
\ 0 add n (val<n)
WHILE
SWAP 2+ SWAP
\ cnt add+2 n
ROT 1+ -ROT
\ cnt+1 add+2 n
REPEAT
2DUP SWAP @ - ABS
\ angle add n dela
-ROT SWAP 2- @ - ABS >
\ angle f
IF
1\ round down
THEN ;
Sine and Arcsine
ok
0 asin . 0 ok
10000 asin . 90 ok
7071 asin . 45 ok
1234 asin . 7 ok
1238 asin . 7 ok
1380 asin . 8 ok
5000 asin . 30 ok
5150 asin . 31 ok
5100 asin . 31 ok
5075 asin . 31 ok
5074 asin . 30 ok
CREATE SINTBL
00000 ,
00872 ,
01736 ,
02588 ,
03420 ,
04226 ,
05000 ,
05736 ,
06428 ,
07071 ,
07660 ,
08192 ,
08660 ,
09063 ,
09397 ,
09659 ,
09848 ,
09962 ,
10000 ,
00175
01045
01908
02756
03584
04384
05150
05878
06561
07193
07771
08290
08746
09135
09455
09703
09877
09976
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
00349
01219
02079
02924
03746
04540
05299
06018
06691
07314
07880
08387
08829
09205
09511
09744
09903
09986
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
00524
01392
02250
03090
03907
04695
05446
06157
06820
07431
07986
08480
08910
09272
09563
09781
09925
09994
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
00698
01571
02419
03256
04076
04848
05592
06293
06947
07547
08090
08572
08988
09336
09613
09816
09945
09998
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
00
05
10
15
20
25
30
35
40
45
50
55
60
65
70
75
80
85
90
-
04
09
14
19
24
29
34
39
44
49
54
59
64
69
74
79
84
89
Sine and Cosine
: SIN
( a -- s )
2* SINTBL + @ ;
\ angle = 0 - 90 degrees
\ s = 0 - 10000
: COS
( a -- c )
90 SWAP 2* SINTBL + @ ;
\ angle = 0 - 90 degrees
CREATE SINTBL
00000 ,
00872 ,
01736 ,
02588 ,
03420 ,
04226 ,
05000 ,
05736 ,
06428 ,
07071 ,
07660 ,
08192 ,
08660 ,
09063 ,
09397 ,
09659 ,
09848 ,
09962 ,
10000 ,
00175
01045
01908
02756
03584
04384
05150
05878
06561
07193
07771
08290
08746
09135
09455
09703
09877
09976
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
00349
01219
02079
02924
03746
04540
05299
06018
06691
07314
07880
08387
08829
09205
09511
09744
09903
09986
\ c = 0 - 10000
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
00524
01392
02250
03090
03907
04695
05446
06157
06820
07431
07986
08480
08910
09272
09563
09781
09925
09994
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
00698
01571
02419
03256
04076
04848
05592
06293
06947
07547
08090
08572
08988
09336
09613
09816
09945
09998
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
00
05
10
15
20
25
30
35
40
45
50
55
60
65
70
75
80
85
90
-
04
09
14
19
24
29
34
39
44
49
54
59
64
69
74
79
84
89
Table 5.6 Table Lookup and Interpolate Instructions
Mnemonic
Function
Operation
TBL
Linearly interpolate 8-bit table
(M) + [(B) X ((M+1) – (M))] => A
ETBL
Linearly interpolate 16-bit table (M : M+1) + [(B) X ((M+2 : M+3) –
(M : M +1))] => D
;
B.LOOKUP ( addr frac -- interp )
BLOOKUP
LDD
2,X+
LDY
0,X
TBL
0,Y
TAB
LDAA #0
STD
0,X
RTS
;8-bit table lookup wrapper
;
W.LOOKUP ( addr frac -- interp )
WLOOKUP
LDD
2,X+
LDY
0,X
ETBL 0,Y
STD
0,X
RTS
;16-bit table lookup wrapper
: SIN10
( a -- s )
10 IDIV
SWAP 256 10 */
SWAP 2* SINTBL +
SWAP W.LOOKUP ;
\
\
\
\
\
angle = 0 - 900 tenths of a degree
tenths angle
angle frac
frac addr
s = 0 - 10000
DO…LOOP
<limit> <index> DO <WHYP statements> LOOP
Moves <limit> and <index>
to return stack
Increments <index> on return stack
and loops back to <WHYP statements>
if <index> is less than <limit>,
else pop <limit> and <index> from
return stack and exit loop
DO…LOOP
The WHYP word I copies the index value from
the return stack to the top of the parameter stack.
: test
( -- )
11 1 DO
I .
LOOP ;
will print
1 2 3 4 5 6 7 8 9 10
DO…LOOP Example
: stars
( n -- )
FOR
." *"
NEXT ;
: rows.of.stars ( n -- )
0 DO
CR I 1+ stars
LOOP
CR ;
ok
5 rows.of.stars
*
**
***
****
*****
The Word LEAVE
Exits a DO loop prematurely
CREATE TABLE
9600 , 4800 , 2400 , 1200 , 600 , 300 , 150 , 75 ,
CFA JSR DOVAR
PFA
9600
4800
2400
1200
600
300
150
75
: find.n
<---- TABLE
0
1
2
3
4
5
6
7 = imax–1
( imax n -- ff | index tf )
0 SWAP ROT
\ 0 n imax
0 DO
\ 0 n
DUP I TABLE
\ 0 n n ix pfa
SWAP 2* +
\ 0 n n pfa+2*ix
@ =
\ 0 n f
IF
\ 0 n
DROP I TRUE
\ 0 ix tf
ROT LEAVE
\ ix tf 0
THEN
LOOP
\ 0 n
DROP ;
\ 0 | ix tf
Branching and Looping
• 68HC12 Branch Instructions
• WHYP Branching and Looping Words
• Recursion in WHYP
Recursion in WHYP
n! = n * (n - 1)!
: fact
( n -- n! )
?DUP
IF
DUP 1RECURSE *
ELSE
1
THEN ;
\
\
\
\
n n | 0
n
n n-1
n*(n-1)!
\ 1
ok
: fact .s ?dup if dup 1- recurse * .s else 1 .s then ;
ok
4 fact
S:[1] 4
S:[2] 4 3
S:[3] 4 3 2
S:[4] 4 3 2 1
S:[5] 4 3 2 1 0
S:[5] 4 3 2 1 1
S:[4] 4 3 2 1
S:[3] 4 3 2
S:[2] 4 6
S:[1] 24 ok
Recursion in WHYP
ok
see fact
fact
?DUP LBEQ 0 F DUP 1- BSR EF * LBRA
(LIT) 0 1 ;
ok
show fact
fact
16 41 9E
EC 31 18 27
16 41 8
16 44 96
7 EF
16 43 3B
18 20 0 5
16 45 22 0
3D
ok
0
1
F
JSR
LBEQ
JSR
JSR
BSR
JSR
LBRA
JSR
RTS
0
5
?DUP
+15
DUP
1RECURSE (BSR FACT)
-17
*
+5
(LIT) 1
Box 5.3 WHYP Branching and Looping Words
IF...ELSE...THEN
<flag> IF <true statements> ELSE <false statements> THEN
FOR...NEXT
n FOR <WHYP statements> NEXT
Execute <WHYP statements> n times.
BEGIN...AGAIN
BEGIN <words> AGAIN
Execute <words> forever.
BEGIN...UNTIL
BEGIN <words> <flag> UNTIL
Execute <words> until <flag> is true.
BEGIN...WHILE...REPEAT
BEGIN <words1> <flag> WHILE <words2> REPEAT
Execute <words1>; if <flag> is true, execute <words2> and branch back to <words1>;
if <flag> is false, exit loop.
DO...LOOP
<limit> <index> DO <WHYP statements> LOOP
Execute <WHYP statements> as long as <index> is less than <limit>;
LOOP increments <index> by 1.
Box 5.4 Other WHYP Words Introduced in Chapter 5
MIN
( n1 n2 -- n3 )
Leaves the smaller of n1 and n2 on the stack.
MAX
( n1 n2 -- n3 )
Leaves the larger of n1 and n2 on the stack.
NEGATE ( n -- -n )
Changes the sign of n.
ABS
( n -- |n| )
Leaves the absolute value of n on the stack.
S>D
( n -- d )
Sign extend a single to a double.
LEAVE ( -- )
Immediately exit a DO loop.
RECURSE
( -- )
Execute the current word recursively.
?DUP
( n -- n n | 0 )
Duplicate the top of the stack only if n is non-zero.
B.LOOKUP ( addr frac -- interp )
8-bit table lookup wrapper
W.LOOKUP ( addr frac -- interp )
16-bit table lookup wrapper