mirror of
https://github.com/A2osX/A2osX.git
synced 2024-11-22 00:32:44 +00:00
initial commit
This commit is contained in:
parent
77b34feef3
commit
62ebd7a9f4
416
BIN/SEQ.S.txt
Normal file
416
BIN/SEQ.S.txt
Normal file
@ -0,0 +1,416 @@
|
||||
NEW
|
||||
AUTO 3,1
|
||||
.LIST OFF
|
||||
.OP 65C02
|
||||
.OR $2000
|
||||
.TF bin/seq
|
||||
*/-------------------------------------
|
||||
* # SEQ
|
||||
* Prints sequences of numbers.
|
||||
*
|
||||
* ## Arguments
|
||||
* **<first>**
|
||||
* Starting number for the sequence of numbers.
|
||||
*
|
||||
* **<incr>**
|
||||
* Count in increments of <incr>. Default is 1 if omitted.
|
||||
*
|
||||
* **<last>**
|
||||
* Last number to count to. If <last> is less than <first>, then the default <incr> is -1.
|
||||
*
|
||||
* ## Return Value
|
||||
* N/A
|
||||
*
|
||||
* ### Author
|
||||
* 2021-11-17, Brian J. Bernstein <brian@dronefone.com>.
|
||||
*\-------------------------------------
|
||||
.INB inc/macros.i
|
||||
.INB inc/a2osx.i
|
||||
|
||||
*--------------------------------------
|
||||
* Defines / Consts
|
||||
*--------------------------------------
|
||||
DIR_INCREMENT .EQ 1
|
||||
DIR_DECREMENT .EQ 0
|
||||
|
||||
*--------------------------------------
|
||||
* 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
|
||||
NumArgIndex .BS 1 ; used for numerical argument indexing
|
||||
Direction .BS 1 ; direction of counting, 0=backwards, 1=forwards
|
||||
wFirst .BS 2 ; arg variable - starting count
|
||||
wIncr .BS 2 ; arg variable - increment
|
||||
wLast .BS 2 ; arg variable - ending count
|
||||
bFormat .BS 1 ; flag that the format -f option was specified
|
||||
ZPPtrFormat .BS 2 ; pointer to format -f string
|
||||
bString .BS 1 ; flag that the string -s option was specified
|
||||
ZPPtrString .BS 2 ; pointer to string -s string
|
||||
bTerminating .BS 1 ; flag that the terminating -t option was specified
|
||||
ZPPtrTerm .BS 2 ; pointer to terminating -t string
|
||||
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
|
||||
L.FMT.FORMAT .DA FMT.FORMAT
|
||||
L.FMT.STRING .DA FMT.STRING
|
||||
L.FMT.TERM .DA FMT.TERM
|
||||
.DA 0
|
||||
*--------------------------------------
|
||||
* Called once at process creation
|
||||
* Put code for loading LIB here
|
||||
*--------------------------------------
|
||||
CS.INIT clc
|
||||
|
||||
lda L.FMT.FORMAT ; set default format
|
||||
sta ZPPtrFormat
|
||||
lda L.FMT.FORMAT+1
|
||||
sta ZPPtrFormat+1
|
||||
|
||||
lda L.FMT.STRING ; set default string separator
|
||||
sta ZPPtrString
|
||||
lda L.FMT.STRING+1
|
||||
sta ZPPtrString+1
|
||||
|
||||
lda L.FMT.TERM ; set default seq terminator string
|
||||
sta ZPPtrTerm
|
||||
lda L.FMT.TERM+1
|
||||
sta ZPPtrTerm+1
|
||||
|
||||
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
|
||||
bcc .10 ; if it exists, keep checking
|
||||
jmp .8 ; otherwise, we're done with args
|
||||
|
||||
.10 >STYA ZPPtr1 ; ArgV pointer was in Y,A so stick into ZPPtr1
|
||||
lda (ZPPtr1)
|
||||
cmp #'-' ; does arg have a hyphen?
|
||||
bne .11 ; if not, check for string args
|
||||
|
||||
jsr CS.RUN.CheckOpt ; if it had a hyphen, check and set arg if recognized
|
||||
bcc .1 ; if we recognized the arg, then loop again to check next
|
||||
|
||||
|
||||
*--- Checking of argument -F ----------
|
||||
.11 bit bFormat ; did we just see the -f option?
|
||||
bpl .112 ; no, jump to next arg flag
|
||||
lda ArgIndex ; yes, then get the pointer to the arg string
|
||||
>SYSCALL ArgV ; and set it to the pointer for the -f
|
||||
>STYA ZPPtrFormat ; string storage
|
||||
lda #0 ; and clear out that we processed the -f
|
||||
sta bFormat ; argument so that we don't try it again
|
||||
jmp .1 ; and then go process the next arg
|
||||
|
||||
*--- Checking of argument -S ----------
|
||||
.112 bit bString ; did we just see the -s option?
|
||||
bpl .113 ; no, jump to next arg flag
|
||||
lda ArgIndex ; yes, then get the pointer to the next arg string
|
||||
>SYSCALL ArgV ; and set it to the pointer for the -s
|
||||
>STYA ZPPtrString ; string storage
|
||||
lda #0 ; and clear out that we processed the -s
|
||||
sta bString ; argument so that we don't try to do it again
|
||||
jmp .1 ; and then go process the next arg
|
||||
|
||||
*--- Checking of argument -T ----------
|
||||
.113 bit bTerminating ; did we just see the -t option?
|
||||
bpl .2 ; no, jump to the next arg flag
|
||||
lda ArgIndex ; yes, then get the pointer to the arg string
|
||||
>SYSCALL ArgV ; and set it to the pointer for the -t
|
||||
>STYA ZPPtrTerm ; string storage
|
||||
lda #0 ; and clear out that we processed the -t
|
||||
sta bTerminating ; argument so that we don't try it again
|
||||
jmp .1 ; and then go process the next arg
|
||||
|
||||
|
||||
*--- Processing numerical args --------
|
||||
.2 lda ArgIndex
|
||||
>SYSCALL ArgV ; check for an arg at index in A
|
||||
|
||||
.20 >SYSCALL AToI ; get the next value on the command line
|
||||
>STYA wIncr ; temporarily store it as the increment value
|
||||
|
||||
inc NumArgIndex
|
||||
lda NumArgIndex ; check what argument value we were looking at
|
||||
cmp #1 ; because if it was the first, then it is probably wFirst
|
||||
bne .3
|
||||
>LDYA wIncr ; copy the value to wFirst
|
||||
>STYA wFirst
|
||||
|
||||
.3 cmp #2 ; but if we were looking at second value, then
|
||||
bne .4 ; we assume it is 'wLast' for the moment
|
||||
>LDYA wIncr ; and copy it over
|
||||
>STYA wLast
|
||||
|
||||
.4 cmp #3 ; if we're looking at third value, then we must have had
|
||||
bne .5 ; an increment value, so we need to swap what we recorded
|
||||
ldx wLast ; as wLast and swap it with the just-read wIncr
|
||||
ldy wIncr
|
||||
stx wIncr
|
||||
sty wLast
|
||||
ldx wLast+1 ; as wLast and swap it with the just-read wIncr
|
||||
ldy wIncr+1
|
||||
stx wIncr+1
|
||||
sty wLast+1
|
||||
|
||||
.5 jmp .1 ; go check for another argument
|
||||
|
||||
|
||||
|
||||
*--- Done with args so figure out -----
|
||||
*--- what numerical args are for ------
|
||||
.8 lda NumArgIndex ; check that we got 1 to 3 numeric arguments.
|
||||
cmp #1
|
||||
bmi .9 ; otherwise, display help and error out
|
||||
cmp #4
|
||||
bpl .9
|
||||
|
||||
cmp #1 ; if we only got one, then it was wLast
|
||||
bne .81
|
||||
lda wFirst ; copy what we thought was wFirst to wLast
|
||||
sta wLast
|
||||
lda wFirst+1
|
||||
sta wLast+1
|
||||
ldy #1 ; set 1 as wFirst
|
||||
lda #0
|
||||
>STYA wFirst
|
||||
>STYA wIncr ; and set 1 as wIncr
|
||||
jmp .82
|
||||
|
||||
.81 cmp #2 ; check to see if we didn't get an increment
|
||||
bne .82
|
||||
ldy #1 ; if not, then just store +1 as the increment
|
||||
lda #0
|
||||
>STYA wIncr
|
||||
|
||||
.82 jsr CS.RUN.Seq ; everything is set, go 'seq' fame and fortune
|
||||
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
|
||||
|
||||
*--------------------------------------
|
||||
* CheckOpt assumes a set ZPPtr1 which is the address of the command line argument being examined.
|
||||
* We start at 1 to look past the '-' as position 0 since that was checked by the caller.
|
||||
* OptionList is a list of possible options and each character correlates with a memory offset
|
||||
* in OptionVars, which are only one byte since they are in ZP but this also allows for us to
|
||||
* simply use indexed addressing to reference them easily as well instead of doing 16-bit
|
||||
* address juggling.
|
||||
* The options are checked in reverse from end-to-start and indexed by X.
|
||||
*--------------------------------------
|
||||
CS.RUN.CheckOpt ldy #1 ; set up y to look at second character of passed in arg
|
||||
lda (ZPPtr1),y ; check second character of passed in argument into A
|
||||
ldx #OptionVars-OptionList-1 ; clever way to put size of OptionList into X
|
||||
|
||||
.2 cmp OptionList,x ; compare the arg we got to the OptionList at X
|
||||
beq .3 ; if it is a match, go handle it.
|
||||
dex ; if not, decrement so we can check next OptionList
|
||||
bpl .2 ; if we haven't reached end of OptionList, go check next
|
||||
sec ; set carry if we didn't find a match
|
||||
rts ; return to caller
|
||||
|
||||
.3 ldy OptionVars,x ; since we matched, find ZP addr of matching option into Y
|
||||
lda #$ff ; we will set this ZP option to $FF
|
||||
sta 0,y ; store A into the ZP address we have in Y
|
||||
clc ; clear carry since we found a match
|
||||
rts ; return to caller
|
||||
*--------------------------------------
|
||||
|
||||
*--------------------------------------
|
||||
* CS.RUN.Seq - Entry point for when args are handled and we're ready to 'seq'.
|
||||
* This is anything we need to do before actually 'seq'encing.
|
||||
*--------------------------------------
|
||||
CS.RUN.Seq jsr CS.DetermineDir ; determine if we're doing increment or decrement
|
||||
|
||||
*--------------------------------------
|
||||
* CS.DoSeq - the actual 'SEQ' work once everything is set up.
|
||||
*--------------------------------------
|
||||
CS.DoSeq
|
||||
|
||||
*--- Print the number in ZPPtrFormat --
|
||||
.1 >PUSHW ZPPtrFormat ; set up the format that we're printing sequence with
|
||||
>PUSHW wFirst ; current seq value is kept in wFirst
|
||||
>PUSHBI 2
|
||||
>SYSCALL PrintF ; print the current seq count.
|
||||
|
||||
*--- Print the string sepators --------
|
||||
>PUSHW ZPPtrString
|
||||
>PUSHBI 0
|
||||
>SYSCALL PrintF ; print string separator
|
||||
|
||||
lda Direction ; check which direction we're counting
|
||||
cmp #DIR_INCREMENT ; going up?
|
||||
bne .2 ; nope, go to decrement code
|
||||
|
||||
*--- Do INCREMENTAL math on the seq ---
|
||||
clc ; ADDING wIncr to wFirst
|
||||
lda wFirst ; do 16-bit addition of wFirst + wIncr
|
||||
adc wIncr
|
||||
sta wFirst
|
||||
lda wFirst+1
|
||||
adc wIncr+1
|
||||
sta wFirst+1
|
||||
|
||||
jsr CS.CmpFirstLast ; is wFirst >= wLast?
|
||||
bcs .1 ; no, so keep going
|
||||
|
||||
lda wFirst ; check to see if wFirst == wLast
|
||||
cmp wLast
|
||||
bne .9
|
||||
lda wFirst+1
|
||||
cmp wLast+1
|
||||
bne .9
|
||||
jmp .1 ; wFirst == wLast, so go around one more time
|
||||
|
||||
|
||||
*--- Do DECREMENTAL math on the seq ---
|
||||
.2 sec ; SUBTRACTING wIncr from wFirst
|
||||
lda wFirst
|
||||
sbc wIncr
|
||||
sta wFirst
|
||||
lda wFirst+1
|
||||
sbc wIncr+1
|
||||
sta wFirst+1
|
||||
|
||||
jsr CS.CmpFirstLast ; is wFirst still >= wLast?
|
||||
bcc .1 ; yes, keep going.
|
||||
|
||||
lda wFirst ; check to see if wFirst == wLast
|
||||
cmp wLast
|
||||
bne .9
|
||||
lda wFirst+1
|
||||
cmp wLast+1
|
||||
bne .9
|
||||
jmp .1 ; wFirst == wLast, so go around one more time
|
||||
|
||||
*--- Done with sequence, finish up ----
|
||||
.9
|
||||
>PUSHW ZPPtrTerm ; set up terminating string
|
||||
>PUSHBI 0
|
||||
>SYSCALL PrintF ; print terminating string
|
||||
rts ; done with SEQ!
|
||||
|
||||
|
||||
* TODO: negatives in incr shouldn't be allowed.
|
||||
|
||||
|
||||
|
||||
|
||||
*--------------------------------------
|
||||
* CS.DetermineDir - checks that increment value in relation +/- to
|
||||
* wFirst / wLast, and then sets the Direction flag.
|
||||
*--------------------------------------
|
||||
CS.DetermineDir jsr CS.CmpFirstLast ; compare first/last values
|
||||
bcc .1 ; if first < last, then we're counting forward
|
||||
lda #DIR_INCREMENT
|
||||
jmp .2
|
||||
.1 lda #DIR_DECREMENT
|
||||
.2 sta Direction ; set the direction
|
||||
rts ; and return to caller.
|
||||
|
||||
|
||||
*--------------------------------------
|
||||
* CS.CmpFirstLast - compares wFirst to wLast value and sets carry based on
|
||||
* if wFirst greater than or equal to wLast, or clear carry
|
||||
* if wFirst is less than wLast.
|
||||
*
|
||||
* IN: n/a (uses global wFirst/wLast)
|
||||
* OUT: carry flag; set if wFirst >= wLast, clear if wFirst < wLast.
|
||||
*--------------------------------------
|
||||
CS.CmpFirstLast >PUSHW wFirst ; using FPU macro, so push first,
|
||||
>PUSHW wLast ; and call the macro
|
||||
>FPU iGE
|
||||
lda (pStack) ; get result from stack
|
||||
bne .1 ; yes, wFirst is >= wLast
|
||||
>POP 2 ; wFirst < wLast
|
||||
sec ; return to caller with carry set
|
||||
rts
|
||||
|
||||
.1 >POP 2 ; wFirst is >= wLast
|
||||
clc ; return to caller with carry clear
|
||||
rts
|
||||
|
||||
|
||||
*--------------------------------------
|
||||
CS.END
|
||||
*--------------------------------------
|
||||
MSG.USAGE .AS "Usage : SEQ [first [incr]] last\r\n"
|
||||
.AS " -F numeric format\r\n"
|
||||
.AS " -S string separator\r\n"
|
||||
.AZ " -T terminating string\r\n"
|
||||
MSG.MSG.NEWLINE .AZ "\r\n"
|
||||
*--------------------------------------
|
||||
FMT.FORMAT .AZ "%I"
|
||||
FMT.STRING .AZ "\r\n"
|
||||
FMT.TERM .AZ ""
|
||||
*--------------------------------------
|
||||
OptionList .AS "FfSsTt"
|
||||
OptionVars .DA #bFormat,#bFormat,#bString,#bString,#bTerminating,#bTerminating
|
||||
*--------------------------------------
|
||||
* Per Process DATA segment (0 filled before INIT)
|
||||
*--------------------------------------
|
||||
.DUMMY
|
||||
.OR 0
|
||||
DS.START
|
||||
DS.END .ED
|
||||
*--------------------------------------
|
||||
|
||||
MAN
|
||||
SAVE usr/src/bin/seq.s
|
||||
ASM
|
203
BIN/XMASTREE.S.txt
Normal file
203
BIN/XMASTREE.S.txt
Normal file
@ -0,0 +1,203 @@
|
||||
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
|
||||
*--------------------------------------
|
||||
* 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
|
||||
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
|
||||
*--------------------------------------
|
||||
STAR .da #'*'
|
||||
BLANK .da #' '
|
||||
MAX .da #30
|
||||
|
||||
* storage
|
||||
|
||||
ROW .bs 1 ; current row
|
||||
MARGIN .bs 1 ; number of blanks to chop from margin
|
||||
|
||||
CS.RUN.Tree lda bSize
|
||||
cmp #3 ; did they specify a size of 2?
|
||||
bpl CS.RUN.Start ; if not, go normal tree drawing
|
||||
cmp #2 ; did they specify a size of 2?
|
||||
bmi CS.RUN.Sapling
|
||||
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
|
||||
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
|
||||
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
|
||||
rol
|
||||
tax ; put into x register and -2
|
||||
dex
|
||||
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
|
||||
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
|
||||
pha
|
||||
phx
|
||||
>SYSCALL PutChar
|
||||
plx
|
||||
pla
|
||||
dex
|
||||
CS.RUN.Disp1 cpx #0 ; loop until we decrement X to 0
|
||||
bne CS.RUN.Disp
|
||||
rts
|
||||
CS.RUN.Newline >PUSHW L.MSG.NEWLINE
|
||||
>PUSHBI 0
|
||||
>SYSCALL PrintF
|
||||
rts
|
||||
|
||||
|
||||
*--------------------------------------
|
||||
CS.END
|
||||
*--------------------------------------
|
||||
MSG.USAGE .AS "Usage : XMASTREE <size>\r\n"
|
||||
.AZ " size : height of the tree to generate\r\n"
|
||||
MSG.MSG.NEWLINE .AZ "\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
|
75
HELP/seq.txt
Normal file
75
HELP/seq.txt
Normal file
@ -0,0 +1,75 @@
|
||||
TITLE
|
||||
A2osX seq (bin/seq) Command Help
|
||||
|
||||
seq -- print sequences of numbers
|
||||
|
||||
SYNOPSIS
|
||||
seq [-f format] [-s string] [-t string] [first [incr]] last
|
||||
|
||||
DESCRIPTION
|
||||
The seq utility prints a sequence of numbers, one per line (default), from
|
||||
first (default 1), to near last as possible, in increments of incr
|
||||
(default 1). When first is larger than last the default incr is -1.
|
||||
|
||||
All numbers are interpreted as integer values.
|
||||
|
||||
PAGE
|
||||
The seq utility accepts the following options:
|
||||
|
||||
-f format Use a printf style format to print each number. Only the D, H,
|
||||
and I conversion characters are valid, along with any optional
|
||||
flags and an optional numeric minimum field width or precision.
|
||||
The format can contain character escape sequences in backslash
|
||||
notation as defined in A2osX kernel documentation.
|
||||
The default is \%I.
|
||||
|
||||
-s string Use string to separate numbers. The string can contain
|
||||
character escape sequences in backslash notation as defined in
|
||||
A2osX kernel documentation. The default is \\r\\n.
|
||||
|
||||
-t string Use string to terminate sequence of numbers. The string can
|
||||
contain character escape sequences in backslash notation as
|
||||
defined in A2osX kernel documentation. This option is
|
||||
useful when the default separator does not contain a \\n.
|
||||
|
||||
The seq utility exits 0 on success and non-zero if an error occurs.
|
||||
|
||||
PAGE
|
||||
EXAMPLES
|
||||
# seq 1 3
|
||||
1
|
||||
2
|
||||
3
|
||||
|
||||
# seq 3 1
|
||||
3
|
||||
2
|
||||
1
|
||||
|
||||
# seq -f "\%02I" 0 5 20
|
||||
00
|
||||
05
|
||||
10
|
||||
15
|
||||
20
|
||||
|
||||
|
||||
PAGE
|
||||
HISTORY
|
||||
The seq command first appeared in Plan 9 from Bell Labs. A seq command
|
||||
appeared in NetBSD 3.0, and ported to FreeBSD 9.0. This command was based
|
||||
on the command of the same name in Plan 9 from Bell Labs and the GNU core
|
||||
utilities. The GNU seq command first appeared in the 1.13 shell utilities
|
||||
release. The A2osX seq command was developed by Brian J. Bernstein
|
||||
<brian@dronefone.com> in November 2021.
|
||||
|
||||
BUGS
|
||||
Floating point numbers are not supported.
|
||||
|
||||
Does not gracefully handle alpha characters where it expects numbers.
|
||||
Behavior of seq when it encounters a non-numeric is undefined.
|
||||
|
||||
This version of seq does not support the -w option which automatically
|
||||
sets numerical output to identical width. Instead, use the -f option as
|
||||
appropriate to get desired results.
|
||||
|
45
HELP/xmastree.txt
Normal file
45
HELP/xmastree.txt
Normal file
@ -0,0 +1,45 @@
|
||||
TITLE
|
||||
A2osX xmastree (bin/xmastree) Command Help
|
||||
|
||||
xmastree -- displays a Christmas tree of user defined height.
|
||||
|
||||
SYNOPSIS
|
||||
xmastree <height>
|
||||
|
||||
DESCRIPTION
|
||||
xmastree is a simple console-based utility that displays a Christmas tree
|
||||
of user defined height. You provide a height in the range of 1-130 and it
|
||||
will produce a Christmas tree of that height. However, 41 is the practical
|
||||
maximum for it to display fully on the Apple II's 80-column screen. As
|
||||
well, while you can go higher than 41, on the local console display it
|
||||
will disappear horizontally off the right side of the screen due to the
|
||||
80-column limit.
|
||||
|
||||
PAGE
|
||||
The xmastree utility does not accept any options, only a single integer to
|
||||
specify tree height.
|
||||
|
||||
The xmastree utility always exits with a successful result of 0.
|
||||
|
||||
EXAMPLES
|
||||
# xmastree 5
|
||||
*
|
||||
***
|
||||
*****
|
||||
*******
|
||||
*
|
||||
|
||||
HISTORY
|
||||
The xmastree utility was originally written in January of 2012 as part of
|
||||
a coding kata challenge. Other entries were done in Java, Python, C#, etc.
|
||||
and I decided to be different by writing it in 6502 for an Apple II.
|
||||
The program sat on a hard drive for almost a decade before I decided to
|
||||
port it to A2osX. While I originally did the work during KansasFest 2021,
|
||||
I figured I'd wait for December to release it to align with the holiday
|
||||
season. Brian J. Bernstein <brian@dronefone.com>, December 2 2021.
|
||||
|
||||
BUGS
|
||||
Negative values and those greater than an 8-bit (0-255) results are not
|
||||
defined, though it will most likely just display a tree of unexpected
|
||||
height.
|
||||
|
Loading…
Reference in New Issue
Block a user