A2osX/BIN/XMASTREE.S.txt
2022-12-23 17:50:50 +01:00

215 lines
7.8 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

NEW
AUTO 3,1
.LIST OFF
.OP 65C02
.OR $2000
.TF bin/xmastree
*/-------------------------------------
* # XMASTREE
* Displays a Christmas Tree of user defined height. Ho Ho Ho.
*
* ## Arguments
* **<height>**
* Height of the tree. A positive number up to about 41 is realistic, beyond that you're on your own...
*
* ## Return Value
* N/A
*
* ### Author
* Original algorithm Jan 2012, Brian J. Bernstein.
* Updated for A2osx 2021-07-02.
*\-------------------------------------
.INB inc/macros.i
.INB inc/a2osx.i
*--------------------------------------
STAR .EQ '*'
BLANK .EQ ' '
MAX .EQ 30
*--------------------------------------
* Zero Page Segment, up to 32 bytes
*--------------------------------------
.DUMMY
.OR ZPBIN
ZS.START
ZPPtr1 .BS 2 ; address pointer (used in arg parsing)
ArgIndex .BS 1 ; index offset for argument parsing
bSize .BS 2 ; arg variable - size of the tree, though we only use first byte
ROW .BS 1 ; current row
MARGIN .BS 1 ; number of blanks to chop from margin
ZS.END .ED
*--------------------------------------
* File Header (16 Bytes)
*--------------------------------------
CS.START cld
jmp (.1,x)
.DA #$61 ; 6502,Level 1 (65c02)
.DA #1 ; BIN Layout Version 1
.DA #0 ; Events disabled (enable with S.PS.F.EVENT)
.DA #0
.DA CS.END-CS.START ; Code Size (without Constants)
.DA DS.END-DS.START ; Data SegmentSize
.DA #32 ; Stack Size
.DA #ZS.END-ZS.START ; Zero Page Size
.DA 0
*--------------------------------------
* Relocation Table
*--------------------------------------
.1 .DA CS.INIT
.DA CS.RUN
.DA CS.DOEVENT
.DA CS.QUIT
L.MSG.USAGE .DA MSG.USAGE ; msg for usage / help text
L.MSG.NEWLINE .DA MSG.MSG.NEWLINE
.DA 0
*--------------------------------------
* Called once at process creation
* Put code for loading LIB here
*--------------------------------------
CS.INIT clc ; nothing to init, so just clc and return
rts
*--------------------------------------
* Called until exit with CS
* if RUN exits with CC, RUN entered again
*--------------------------------------
CS.RUN
.1 inc ArgIndex ; Check next argument
lda ArgIndex
>SYSCALL ArgV ; check for an arg at index in A
bcs .9 ; If doesn't exist, we're done with args
>SYSCALL AToI
>STYA bSize
.2 jsr CS.RUN.Tree ; build the tree
jmp .99
*--- Display usage and error out ------
.9
>PUSHW L.MSG.USAGE ; push address for usage text
>PUSHBI 0
>SYSCALL PrintF ; print usage message
lda #E.SYN ; set OS return code as Syntax Error
sec ; indicate we don't want CS.RUN called again
rts ; return to OS
*--- Successful exit ------------------
.99
lda #0 ; set OS return code to success
sec ; indicate we don't want CS.RUN called again
rts ; return to OS
*--------------------------------------
* Called if option S.PS.F.EVENT enabled in Header
* Timer Event : every 10th seconds
*--------------------------------------
CS.DOEVENT sec ; we don't use this since we don't have timer events
rts
*--------------------------------------
* Called once, when RUN exited with CS
* Put code for unloading LIB here
*--------------------------------------
CS.QUIT clc ; nothing to do on exit except clear carry and return
rts
*--------------------------------------
CS.RUN.Tree lda bSize
cmp #3 ; did they specify a size of 2?
bcs CS.RUN.Start ; CC if < 3 !!! if not, go normal tree drawing
cmp #2 ; did they specify a size of 2?
bcc CS.RUN.Sapling ; CC if < 2 !!!
lda #'Y'
>SYSCALL PutChar
jsr CS.RUN.Newline
rts
CS.RUN.Sapling lda #'|'
>SYSCALL PutChar
jsr CS.RUN.Newline
rts
CS.RUN.Start lda #2 ; start from row 2
sta ROW
lda #MAX ; calculate margin chop
sec ; SEC before SBC !!!
sbc bSize
sta MARGIN
jsr CS.RUN.Stump ; display a stump first since same as top of tree
CS.RUN.Blanks lda #MAX ; calculate number of blanks to tab
clc
sbc ROW
sbc MARGIN
tax ; put into x register
lda #BLANK ; load blank character
jsr CS.RUN.Disp ; display ́x ́ blanks
CS.RUN.Stars lda ROW ; calculate number of stars to display
asl ; ASL not ROL !!!
tax ; put into x register and -2
* dex ; -1 !!! not -2
dex
lda #STAR ; load star character
jsr CS.RUN.Disp ; display ́x ́ stars
CS.RUN.Next jsr CS.RUN.Newline
ldx ROW ; increment row
inx
stx ROW
cpx bSize ; are we done?
bne CS.RUN.Blanks
jsr CS.RUN.Stump ; display a stump...
rts ; ...and we ́re done
CS.RUN.Stump lda #MAX-2 ; calculate number of blanks to place stump
sec
sbc MARGIN
tax
lda #BLANK
jsr CS.RUN.Disp ; display ́x ́ blanks
lda #STAR ; display star as a stump
ldy ROW ; unless the tree is only 3 rows tall,
cpy #3 ; then give it a much skinnier stump
bne .2
lda #'|' ; <-- skinny stump
.2 >SYSCALL PutChar
jsr CS.RUN.Newline
rts
CS.RUN.Disp cpx #0
beq .9
.1 pha
phx
>SYSCALL PutChar
plx
pla
dex ; loop until we decrement X to 0
bne .1
.9 rts
CS.RUN.Newline >PUSHW L.MSG.NEWLINE
>PUSHBI 0
>SYSCALL PrintF
rts
*--------------------------------------
CS.END
*--------------------------------------
MSG.USAGE .CS "Usage : XMASTREE <size>\r\n"
.CZ " size : height of the tree to generate\r\n"
MSG.MSG.NEWLINE .CZ "\r\n"
*--------------------------------------
* Per Process DATA segment (0 filled before INIT)
*--------------------------------------
.DUMMY
.OR 0
DS.START
DS.END .ED
*--------------------------------------
MAN
SAVE usr/src/bin/xmastree.s
ASM