A2osX/BIN/XMASTREE.S.txt

215 lines
7.8 KiB
Plaintext
Raw Normal View History

2021-12-02 21:06:35 +00:00
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
*--------------------------------------
2021-12-02 21:06:35 +00:00
* 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
2021-12-02 21:06:35 +00:00
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
2021-12-02 21:06:35 +00:00
cmp #2 ; did they specify a size of 2?
bcc CS.RUN.Sapling ; CC if < 2 !!!
2021-12-02 21:06:35 +00:00
lda #'Y'
>SYSCALL PutChar
jsr CS.RUN.Newline
rts
2021-12-02 21:06:35 +00:00
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
2021-12-02 21:06:35 +00:00
sta MARGIN
jsr CS.RUN.Stump ; display a stump first since same as top of tree
2021-12-02 21:06:35 +00:00
CS.RUN.Blanks lda #MAX ; calculate number of blanks to tab
clc
sbc ROW
2021-12-02 21:06:35 +00:00
sbc MARGIN
tax ; put into x register
lda #BLANK ; load blank character
2021-12-02 21:06:35 +00:00
jsr CS.RUN.Disp ; display ́x ́ blanks
2021-12-02 21:06:35 +00:00
CS.RUN.Stars lda ROW ; calculate number of stars to display
asl ; ASL not ROL !!!
2021-12-02 21:06:35 +00:00
tax ; put into x register and -2
* dex ; -1 !!! not -2
2021-12-02 21:06:35 +00:00
dex
lda #STAR ; load star character
2021-12-02 21:06:35 +00:00
jsr CS.RUN.Disp ; display ́x ́ stars
CS.RUN.Next jsr CS.RUN.Newline
2021-12-02 21:06:35 +00:00
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
2021-12-02 21:06:35 +00:00
CS.RUN.Stump lda #MAX-2 ; calculate number of blanks to place stump
sec
sbc MARGIN
2021-12-02 21:06:35 +00:00
tax
lda #BLANK
2021-12-02 21:06:35 +00:00
jsr CS.RUN.Disp ; display ́x ́ blanks
lda #STAR ; display star as a stump
2021-12-02 21:06:35 +00:00
ldy ROW ; unless the tree is only 3 rows tall,
cpy #3 ; then give it a much skinnier stump
bne .2
2021-12-02 21:06:35 +00:00
lda #'|' ; <-- skinny stump
2021-12-02 21:06:35 +00:00
.2 >SYSCALL PutChar
jsr CS.RUN.Newline
rts
CS.RUN.Disp cpx #0
beq .9
.1 pha
2021-12-02 21:06:35 +00:00
phx
>SYSCALL PutChar
plx
pla
dex ; loop until we decrement X to 0
bne .1
.9 rts
2021-12-02 21:06:35 +00:00
CS.RUN.Newline >PUSHW L.MSG.NEWLINE
>PUSHBI 0
>SYSCALL PrintF
rts
*--------------------------------------
CS.END
*--------------------------------------
2022-11-02 06:54:30 +00:00
MSG.USAGE .CS "Usage : XMASTREE <size>\r\n"
.CZ " size : height of the tree to generate\r\n"
MSG.MSG.NEWLINE .CZ "\r\n"
2021-12-02 21:06:35 +00:00
*--------------------------------------
* Per Process DATA segment (0 filled before INIT)
*--------------------------------------
.DUMMY
.OR 0
DS.START
DS.END .ED
*--------------------------------------
MAN
SAVE usr/src/bin/xmastree.s
ASM