Ophis/book/x1030.html

374 lines
6.9 KiB
HTML
Raw Normal View History

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML
><HEAD
><TITLE
>fibonacci.oph</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
REL="HOME"
TITLE="Programming with Ophis"
HREF="book1.html"><LINK
REL="UP"
TITLE="Example Programs"
HREF="a975.html"><LINK
REL="PREVIOUS"
TITLE="structuredemo.oph"
HREF="x1026.html"><LINK
REL="NEXT"
TITLE="Ophis Command Reference"
HREF="a1034.html"></HEAD
><BODY
CLASS="SECTION"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>Programming with Ophis</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="x1026.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
>Example Programs</TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="a1034.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="SECTION"
><H1
CLASS="SECTION"
><A
NAME="FIB-SRC"
><TT
CLASS="FILENAME"
>fibonacci.oph</TT
></A
></H1
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>.include "../platform/c64_0.oph"
.require "../platform/c64kernal.oph"
.outfile "fibonacci.prg"
lda #&#60;opening ; Print opening text
sta fun'args
lda #&#62;opening
sta fun'args+1
jsr print'string
lda #$00
sta fun'vars ; Count num from 0 to 19
* lda fun'vars ; Main loop: print num, with leading space if &#60;10
cmp #$09
bcs +
lda #$20
jsr chrout
lda fun'vars
* sta fun'args ; Copy num to args, print it, plus ": "
inc fun'args
lda #$00
sta fun'args+1
jsr print'dec
lda #$3A
jsr chrout
lda #$20
jsr chrout
lda fun'vars ; Copy num to args, call fib, print result
sta fun'args
jsr fib
jsr print'dec
lda #$0D ; Newline
jsr chrout
inc fun'vars ; Increment num; if it's 20, we're done.
lda fun'vars
cmp #20
bne -- ; Otherwise, loop.
rts
opening:
.byte 147, " FIBONACCI SEQUENCE",13,13,0
.scope
; Uint16 fib (Uint8 x): compute Xth fibonnaci number.
; fib(0) = fib(1) = 1.
; Stack usage: 3.
fib: lda #$03
jsr save'stack
lda fun'vars ; If x &#60; 2, goto _base.
cmp #$02
bcc _base
dec fun'args ; Otherwise, call fib(x-1)...
jsr fib
lda fun'args ; Copy the result to local variable...
sta fun'vars+1
lda fun'args+1
sta fun'vars+2
lda fun'vars ; Call fib(x-2)...
sec
sbc #$02
sta fun'args
jsr fib
clc ; And add the old result to it, leaving it
lda fun'args ; in the 'result' location.
adc fun'vars+1
sta fun'args
lda fun'args+1
adc fun'vars+2
sta fun'args+1
jmp _done ; and then we're done.
_base: ldy #$01 ; In the base case, just copy 1 to the
sty fun'args ; result.
dey
sty fun'args+1
_done: lda #$03
jsr restore'stack
rts
.scend
.scope
; Stack routines: init'stack, save'stack, restore'stack
.data zp
.space _sp $02
.space _counter $01
.space fun'args $10
.space fun'vars $40
.text
init'stack:
lda #$00
sta _sp
lda #$A0
sta _sp+1
rts
save'stack:
sta _counter
sec
lda _sp
sbc _counter
sta _sp
lda _sp+1
sbc #$00
sta _sp+1
ldy #$00
* lda fun'vars, y
sta (_sp), y
lda fun'args, y
sta fun'vars, y
iny
dec _counter
bne -
rts
restore'stack:
pha
sta _counter
ldy #$00
* lda (_sp), y
sta fun'vars, y
iny
dec _counter
bne -
pla
clc
adc _sp
sta _sp
lda _sp+1
adc #$00
sta _sp+1
rts
.scend
; Utility functions. print'dec prints an unsigned 16-bit integer.
; It's ugly and long, mainly because we don't bother with niceties
; like "division". print'string prints a zero-terminated string.
.scope
.data
.org fun'args
.space _val 2
.space _step 2
.space _res 1
.space _allowzero 1
.text
print'dec:
lda #$00
sta _allowzero
lda #&#60;10000
sta _step
lda #&#62;10000
sta _step+1
jsr repsub'16
lda #&#60;1000
sta _step
lda #&#62;1000
sta _step+1
jsr repsub'16
lda #0
sta _step+1
lda #100
sta _step
jsr repsub'16
lda #10
sta _step
jsr repsub'16
lda _val
jsr _print
rts
repsub'16:
lda #$00
sta _res
* lda _val
sec
sbc _step
lda _val+1
sbc _step+1
bcc _done
lda _val
sec
sbc _step
sta _val
lda _val+1
sbc _step+1
sta _val+1
inc _res
jmp -
_done: lda _res
ora _allowzero
beq _ret
sta _allowzero
lda _res
_print: clc
adc #'0
jsr chrout
_ret: rts
.scend
print'string:
ldy #$00
* lda (fun'args), y
beq +
jsr chrout
iny
jmp -
* rts</PRE
></TD
></TR
></TABLE
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="x1026.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="book1.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="a1034.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><TT
CLASS="FILENAME"
>structuredemo.oph</TT
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="a975.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>Ophis Command Reference</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>