---input---
;--------------------------------------
; Lychrel numbers.
; 
; :author: Marc 'BlackJack' Rintsch
; :date: 2008-03-07
; :version: 0.1
; 
; Prints all `Lychrel numbers`_ between 1 and 100000.
; 
; The numbers are stored as array of "digits" in little endian
; order.  Each digit is a byte with a value between 0 and 9.
; 
; Runtime on C64: 00:21:01
; 
; .. _Lychrel numbers: http://en.wikipedia.org/wiki/Lychrel_number
; 
; .. cl65 -l -tnone -C simple.cfg lychrel.s -o lychrel.prg
;--------------------------------------

;--------------------------------------
; External addresses.
;--------------------------------------
	chrout	= $ffd2

;--------------------------------------
; Constants.
;--------------------------------------
	TO		= 100000
	TO_DIGITS	= 10
	ITERATIONS	= 100
	MAX_DIGITS	= TO_DIGITS + ITERATIONS

;--------------------------------------
; Global variables.
;--------------------------------------
.zeropage
; 
; Length of the currently tested `n` in digits.
; 
n_length:
	.res 1
; 
; Length of the number(s) `xa` and `xb` while testing.
; 
length:
	.res 1

.bss
; 
; Number to be tested as digits i.e. bytes with values between
; 0 and 9.  The length is stored in `n_length`.
; 
n:
	.res TO_DIGITS
; 
; Space for calculating the reversed and added values.
; In the `main` code the current number is copied into `xa`
; and then repeatedly `reverse_add`\ed to itself with the
; result of that adding stored in `xb`.
; 
xa:
	.res MAX_DIGITS
xb:
	.res MAX_DIGITS

;--------------------------------------
; BASIC header.
;--------------------------------------
.code
	.word 0800h		; Load address.
	.byte 0
	.word @line_end
	.word 2008		; Line number.
	.byte $9e		; SYS token.
	.byte "2080 "		; SYS argument.
	.byte "LYCHREL NUMBERS/BJ"
@line_end:
	.byte 0, 0, 0		; Line and program end marker.

;--------------------------------------
; Main program.
;--------------------------------------
.proc main

.zeropage
; 
; Three byte counter for `TO` iterations (100000 = $0186a0).
; 
i:
	.res 3

.code
; 
; Clear and set `n` and `i` to 1.
; 
	lda #0		; n := 0; n := 1; i := 1
	sta i+1
	sta i+2
	ldx #TO_DIGITS
clear_n:
	sta n-1,x
	dex
	bne clear_n
	inx
	stx i
	stx n
	stx n_length
	
mainloop:
	jsr is_lychrel
	bcc no_lychrel
	jsr print_n
no_lychrel:
	jsr increase_n
	
	inc i		; INC(i)
	bne skip
	inc i+1
	bne skip
	inc i+2
skip:
	lda i
	cmp #<TO
	bne mainloop
	lda i+1
	cmp #>TO
	bne mainloop
	lda i+2
	cmp #^TO
	bne mainloop
	
	rts
.endproc

;--------------------------------------
; Print `n` and a trailing newline.
;
; :in: `n_length`, `n`
;--------------------------------------
.proc print_n
	ldy n_length
L1:
	lda n-1,y
	ora #%110000    ; = '0'
	jsr chrout
	dey
	bne L1
	
	lda #13
	jmp chrout
.endproc

;--------------------------------------
; Increase `n` by one.
; 
; This procedure expects n[n_length] == 0 in case the number gets
; one digit longer.
; 
; :in: `n`, `n_length`
; :out: `n`, `n_length`
;--------------------------------------
.proc increase_n
	ldx #0
L1:
	inc n,x		; Increase digit.
	lda n,x
	cmp #10		; If "carry", store 0 and go to next digit.
	bne return
	lda #0
	sta n,x
	inx
	bne L1
return:
	cpx n_length	; If "carry" after last digit, increase length.
	bcc skip
	inc n_length
skip:
	rts
.endproc

;--------------------------------------
; Tests if `n` is a Lychrel number.
; 
; :in: `n`, `n_length`
; :out: C is set if yes, cleared otherwise.
; :uses: `length`, `xa`, `xb`
;--------------------------------------
.proc is_lychrel
.zeropage
i:
	.res 1

.code
	ldx n_length		; xa := n; length := n_length
	stx length
L1:
	lda n-1,x
	sta xa-1,x
	dex
	bne L1
	
	lda #ITERATIONS		; i := ITERATIONS
	sta i
L2:
	jsr reverse_add
	jsr is_palindrome
	bne no_palindrome
	clc
	rts
no_palindrome:
	ldx length		; a := b
L3:
	lda xb-1,x
	sta xa-1,x
	dex
	bne L3
	
	dec i			; Loop body end.
	bne L2
	
	sec
	rts
.endproc

;--------------------------------------
; Add the reverse to `xa` to itself and store the result in `xb`.
; 
; :in: `length`, `xa`
; :out: `length`, `xb`
;--------------------------------------
.proc reverse_add
.code
	ldx #0
	ldy length
	clc
L1:
	lda xa,x
	adc xa-1,y
	
	cmp #10
	bcc no_adjust
	sbc #10
no_adjust:
	sta xb,x
	
	dey
	inx
	txa		; ``eor`` instead of ``cpx`` to keep the carry flag
	eor length	; of the addition above.
	bne L1
	
	bcc no_carry
	lda #1
	sta xb,x
	inc length
no_carry:
	rts
.endproc

;--------------------------------------
; Checks if `xb` is a palindrome.
; 
; :in: `length`, `xb`
; :out: Z flag set if `xb` is a palindrome, cleared otherwise.
;--------------------------------------
.proc is_palindrome
.code
	ldx #0
	lda length
	tay
	lsr
	sta L1+1	; Self modifying code!
L1:
	cpx #0		; <<< 0 replaced by (`length` / 2).
	beq return
	lda xb,x
	cmp xb-1,y
	bne return
	dey
	inx
	bne L1
return:
	rts
.endproc

---tokens---
';--------------------------------------' Comment.Single
'\n'          Text

'; Lychrel numbers.' Comment.Single
'\n'          Text

'; '          Comment.Single
'\n'          Text

"; :author: Marc 'BlackJack' Rintsch" Comment.Single
'\n'          Text

'; :date: 2008-03-07' Comment.Single
'\n'          Text

'; :version: 0.1' Comment.Single
'\n'          Text

'; '          Comment.Single
'\n'          Text

'; Prints all `Lychrel numbers`_ between 1 and 100000.' Comment.Single
'\n'          Text

'; '          Comment.Single
'\n'          Text

'; The numbers are stored as array of "digits" in little endian' Comment.Single
'\n'          Text

'; order.  Each digit is a byte with a value between 0 and 9.' Comment.Single
'\n'          Text

'; '          Comment.Single
'\n'          Text

'; Runtime on C64: 00:21:01' Comment.Single
'\n'          Text

'; '          Comment.Single
'\n'          Text

'; .. _Lychrel numbers: http://en.wikipedia.org/wiki/Lychrel_number' Comment.Single
'\n'          Text

'; '          Comment.Single
'\n'          Text

'; .. cl65 -l -tnone -C simple.cfg lychrel.s -o lychrel.prg' Comment.Single
'\n'          Text

';--------------------------------------' Comment.Single
'\n\n'        Text

';--------------------------------------' Comment.Single
'\n'          Text

'; External addresses.' Comment.Single
'\n'          Text

';--------------------------------------' Comment.Single
'\n\t'        Text
'chrout'      Name
'\t'          Text
'='           Operator
' '           Text
'$ffd2'       Literal.Number.Hex
'\n\n'        Text

';--------------------------------------' Comment.Single
'\n'          Text

'; Constants.' Comment.Single
'\n'          Text

';--------------------------------------' Comment.Single
'\n\t'        Text
'TO'          Name
'\t\t'        Text
'='           Operator
' '           Text
'100000'      Literal.Number.Integer
'\n\t'        Text
'TO_DIGITS'   Name
'\t'          Text
'='           Operator
' '           Text
'10'          Literal.Number.Integer
'\n\t'        Text
'ITERATIONS'  Name
'\t'          Text
'='           Operator
' '           Text
'100'         Literal.Number.Integer
'\n\t'        Text
'MAX_DIGITS'  Name
'\t'          Text
'='           Operator
' '           Text
'TO_DIGITS'   Name
' '           Text
'+'           Operator
' '           Text
'ITERATIONS'  Name
'\n\n'        Text

';--------------------------------------' Comment.Single
'\n'          Text

'; Global variables.' Comment.Single
'\n'          Text

';--------------------------------------' Comment.Single
'\n'          Text

'.zeropage'   Keyword.Pseudo
'\n'          Text

'; '          Comment.Single
'\n'          Text

'; Length of the currently tested `n` in digits.' Comment.Single
'\n'          Text

'; '          Comment.Single
'\n'          Text

'n_length:'   Name.Label
'\n\t'        Text
'.res'        Keyword.Pseudo
' '           Text
'1'           Literal.Number.Integer
'\n'          Text

'; '          Comment.Single
'\n'          Text

'; Length of the number(s) `xa` and `xb` while testing.' Comment.Single
'\n'          Text

'; '          Comment.Single
'\n'          Text

'length:'     Name.Label
'\n\t'        Text
'.res'        Keyword.Pseudo
' '           Text
'1'           Literal.Number.Integer
'\n\n'        Text

'.bss'        Keyword.Pseudo
'\n'          Text

'; '          Comment.Single
'\n'          Text

'; Number to be tested as digits i.e. bytes with values between' Comment.Single
'\n'          Text

'; 0 and 9.  The length is stored in `n_length`.' Comment.Single
'\n'          Text

'; '          Comment.Single
'\n'          Text

'n:'          Name.Label
'\n\t'        Text
'.res'        Keyword.Pseudo
' '           Text
'TO_DIGITS'   Name
'\n'          Text

'; '          Comment.Single
'\n'          Text

'; Space for calculating the reversed and added values.' Comment.Single
'\n'          Text

'; In the `main` code the current number is copied into `xa`' Comment.Single
'\n'          Text

'; and then repeatedly `reverse_add`\\ed to itself with the' Comment.Single
'\n'          Text

'; result of that adding stored in `xb`.' Comment.Single
'\n'          Text

'; '          Comment.Single
'\n'          Text

'xa:'         Name.Label
'\n\t'        Text
'.res'        Keyword.Pseudo
' '           Text
'MAX_DIGITS'  Name
'\n'          Text

'xb:'         Name.Label
'\n\t'        Text
'.res'        Keyword.Pseudo
' '           Text
'MAX_DIGITS'  Name
'\n\n'        Text

';--------------------------------------' Comment.Single
'\n'          Text

'; BASIC header.' Comment.Single
'\n'          Text

';--------------------------------------' Comment.Single
'\n'          Text

'.code'       Keyword.Pseudo
'\n\t'        Text
'.word'       Keyword.Pseudo
' '           Text
'0800h'       Literal.Number.Hex
'\t\t'        Text
'; Load address.' Comment.Single
'\n\t'        Text
'.byte'       Keyword.Pseudo
' '           Text
'0'           Literal.Number.Integer
'\n\t'        Text
'.word'       Keyword.Pseudo
' '           Text
'@line_end'   Name
'\n\t'        Text
'.word'       Keyword.Pseudo
' '           Text
'2008'        Literal.Number.Integer
'\t\t'        Text
'; Line number.' Comment.Single
'\n\t'        Text
'.byte'       Keyword.Pseudo
' '           Text
'$9e'         Literal.Number.Hex
'\t\t'        Text
'; SYS token.' Comment.Single
'\n\t'        Text
'.byte'       Keyword.Pseudo
' '           Text
'"2080 "'     Literal.String
'\t\t'        Text
'; SYS argument.' Comment.Single
'\n\t'        Text
'.byte'       Keyword.Pseudo
' '           Text
'"LYCHREL NUMBERS/BJ"' Literal.String
'\n'          Text

'@line_end:'  Name.Label
'\n\t'        Text
'.byte'       Keyword.Pseudo
' '           Text
'0'           Literal.Number.Integer
','           Punctuation
' '           Text
'0'           Literal.Number.Integer
','           Punctuation
' '           Text
'0'           Literal.Number.Integer
'\t\t'        Text
'; Line and program end marker.' Comment.Single
'\n\n'        Text

';--------------------------------------' Comment.Single
'\n'          Text

'; Main program.' Comment.Single
'\n'          Text

';--------------------------------------' Comment.Single
'\n'          Text

'.proc'       Keyword.Pseudo
' '           Text
'main'        Name
'\n\n'        Text

'.zeropage'   Keyword.Pseudo
'\n'          Text

'; '          Comment.Single
'\n'          Text

'; Three byte counter for `TO` iterations (100000 = $0186a0).' Comment.Single
'\n'          Text

'; '          Comment.Single
'\n'          Text

'i:'          Name.Label
'\n\t'        Text
'.res'        Keyword.Pseudo
' '           Text
'3'           Literal.Number.Integer
'\n\n'        Text

'.code'       Keyword.Pseudo
'\n'          Text

'; '          Comment.Single
'\n'          Text

'; Clear and set `n` and `i` to 1.' Comment.Single
'\n'          Text

'; '          Comment.Single
'\n\t'        Text
'lda'         Keyword
' '           Text
'#'           Punctuation
'0'           Literal.Number.Integer
'\t\t'        Text
'; n := 0; n := 1; i := 1' Comment.Single
'\n\t'        Text
'sta'         Keyword
' '           Text
'i'           Name
'+'           Operator
'1'           Literal.Number.Integer
'\n\t'        Text
'sta'         Keyword
' '           Text
'i'           Name
'+'           Operator
'2'           Literal.Number.Integer
'\n\t'        Text
'ldx'         Keyword
' '           Text
'#'           Punctuation
'TO_DIGITS'   Name
'\n'          Text

'clear_n:'    Name.Label
'\n\t'        Text
'sta'         Keyword
' '           Text
'n'           Name
'-'           Operator
'1'           Literal.Number.Integer
','           Punctuation
'x'           Name
'\n\t'        Text
'dex'         Keyword
'\n\t'        Text
'bne'         Keyword
' '           Text
'clear_n'     Name
'\n\t'        Text
'inx'         Keyword
'\n\t'        Text
'stx'         Keyword
' '           Text
'i'           Name
'\n\t'        Text
'stx'         Keyword
' '           Text
'n'           Name
'\n\t'        Text
'stx'         Keyword
' '           Text
'n_length'    Name
'\n\t\n'      Text

'mainloop:'   Name.Label
'\n\t'        Text
'jsr'         Keyword
' '           Text
'is_lychrel'  Name
'\n\t'        Text
'bcc'         Keyword
' '           Text
'no_lychrel'  Name
'\n\t'        Text
'jsr'         Keyword
' '           Text
'print_n'     Name
'\n'          Text

'no_lychrel:' Name.Label
'\n\t'        Text
'jsr'         Keyword
' '           Text
'increase_n'  Name
'\n\t\n\t'    Text
'inc'         Keyword
' '           Text
'i'           Name
'\t\t'        Text
'; INC(i)'    Comment.Single
'\n\t'        Text
'bne'         Keyword
' '           Text
'skip'        Name
'\n\t'        Text
'inc'         Keyword
' '           Text
'i'           Name
'+'           Operator
'1'           Literal.Number.Integer
'\n\t'        Text
'bne'         Keyword
' '           Text
'skip'        Name
'\n\t'        Text
'inc'         Keyword
' '           Text
'i'           Name
'+'           Operator
'2'           Literal.Number.Integer
'\n'          Text

'skip:'       Name.Label
'\n\t'        Text
'lda'         Keyword
' '           Text
'i'           Name
'\n\t'        Text
'cmp'         Keyword
' '           Text
'#'           Punctuation
'<'           Operator
'TO'          Name
'\n\t'        Text
'bne'         Keyword
' '           Text
'mainloop'    Name
'\n\t'        Text
'lda'         Keyword
' '           Text
'i'           Name
'+'           Operator
'1'           Literal.Number.Integer
'\n\t'        Text
'cmp'         Keyword
' '           Text
'#'           Punctuation
'>'           Operator
'TO'          Name
'\n\t'        Text
'bne'         Keyword
' '           Text
'mainloop'    Name
'\n\t'        Text
'lda'         Keyword
' '           Text
'i'           Name
'+'           Operator
'2'           Literal.Number.Integer
'\n\t'        Text
'cmp'         Keyword
' '           Text
'#'           Punctuation
'^'           Operator
'TO'          Name
'\n\t'        Text
'bne'         Keyword
' '           Text
'mainloop'    Name
'\n\t\n\t'    Text
'rts'         Keyword
'\n'          Text

'.endproc'    Keyword.Pseudo
'\n\n'        Text

';--------------------------------------' Comment.Single
'\n'          Text

'; Print `n` and a trailing newline.' Comment.Single
'\n'          Text

';'           Comment.Single
'\n'          Text

'; :in: `n_length`, `n`' Comment.Single
'\n'          Text

';--------------------------------------' Comment.Single
'\n'          Text

'.proc'       Keyword.Pseudo
' '           Text
'print_n'     Name
'\n\t'        Text
'ldy'         Keyword
' '           Text
'n_length'    Name
'\n'          Text

'L1:'         Name.Label
'\n\t'        Text
'lda'         Keyword
' '           Text
'n'           Name
'-'           Operator
'1'           Literal.Number.Integer
','           Punctuation
'y'           Name
'\n\t'        Text
'ora'         Keyword
' '           Text
'#'           Punctuation
'%110000'     Literal.Number.Bin
'    '        Text
"; = '0'"     Comment.Single
'\n\t'        Text
'jsr'         Keyword
' '           Text
'chrout'      Name
'\n\t'        Text
'dey'         Keyword
'\n\t'        Text
'bne'         Keyword
' '           Text
'L1'          Name
'\n\t\n\t'    Text
'lda'         Keyword
' '           Text
'#'           Punctuation
'13'          Literal.Number.Integer
'\n\t'        Text
'jmp'         Keyword
' '           Text
'chrout'      Name
'\n'          Text

'.endproc'    Keyword.Pseudo
'\n\n'        Text

';--------------------------------------' Comment.Single
'\n'          Text

'; Increase `n` by one.' Comment.Single
'\n'          Text

'; '          Comment.Single
'\n'          Text

'; This procedure expects n[n_length] == 0 in case the number gets' Comment.Single
'\n'          Text

'; one digit longer.' Comment.Single
'\n'          Text

'; '          Comment.Single
'\n'          Text

'; :in: `n`, `n_length`' Comment.Single
'\n'          Text

'; :out: `n`, `n_length`' Comment.Single
'\n'          Text

';--------------------------------------' Comment.Single
'\n'          Text

'.proc'       Keyword.Pseudo
' '           Text
'increase_n'  Name
'\n\t'        Text
'ldx'         Keyword
' '           Text
'#'           Punctuation
'0'           Literal.Number.Integer
'\n'          Text

'L1:'         Name.Label
'\n\t'        Text
'inc'         Keyword
' '           Text
'n'           Name
','           Punctuation
'x'           Name
'\t\t'        Text
'; Increase digit.' Comment.Single
'\n\t'        Text
'lda'         Keyword
' '           Text
'n'           Name
','           Punctuation
'x'           Name
'\n\t'        Text
'cmp'         Keyword
' '           Text
'#'           Punctuation
'10'          Literal.Number.Integer
'\t\t'        Text
'; If "carry", store 0 and go to next digit.' Comment.Single
'\n\t'        Text
'bne'         Keyword
' '           Text
'return'      Name
'\n\t'        Text
'lda'         Keyword
' '           Text
'#'           Punctuation
'0'           Literal.Number.Integer
'\n\t'        Text
'sta'         Keyword
' '           Text
'n'           Name
','           Punctuation
'x'           Name
'\n\t'        Text
'inx'         Keyword
'\n\t'        Text
'bne'         Keyword
' '           Text
'L1'          Name
'\n'          Text

'return:'     Name.Label
'\n\t'        Text
'cpx'         Keyword
' '           Text
'n_length'    Name
'\t'          Text
'; If "carry" after last digit, increase length.' Comment.Single
'\n\t'        Text
'bcc'         Keyword
' '           Text
'skip'        Name
'\n\t'        Text
'inc'         Keyword
' '           Text
'n_length'    Name
'\n'          Text

'skip:'       Name.Label
'\n\t'        Text
'rts'         Keyword
'\n'          Text

'.endproc'    Keyword.Pseudo
'\n\n'        Text

';--------------------------------------' Comment.Single
'\n'          Text

'; Tests if `n` is a Lychrel number.' Comment.Single
'\n'          Text

'; '          Comment.Single
'\n'          Text

'; :in: `n`, `n_length`' Comment.Single
'\n'          Text

'; :out: C is set if yes, cleared otherwise.' Comment.Single
'\n'          Text

'; :uses: `length`, `xa`, `xb`' Comment.Single
'\n'          Text

';--------------------------------------' Comment.Single
'\n'          Text

'.proc'       Keyword.Pseudo
' '           Text
'is_lychrel'  Name
'\n'          Text

'.zeropage'   Keyword.Pseudo
'\n'          Text

'i:'          Name.Label
'\n\t'        Text
'.res'        Keyword.Pseudo
' '           Text
'1'           Literal.Number.Integer
'\n\n'        Text

'.code'       Keyword.Pseudo
'\n\t'        Text
'ldx'         Keyword
' '           Text
'n_length'    Name
'\t\t'        Text
'; xa := n; length := n_length' Comment.Single
'\n\t'        Text
'stx'         Keyword
' '           Text
'length'      Name
'\n'          Text

'L1:'         Name.Label
'\n\t'        Text
'lda'         Keyword
' '           Text
'n'           Name
'-'           Operator
'1'           Literal.Number.Integer
','           Punctuation
'x'           Name
'\n\t'        Text
'sta'         Keyword
' '           Text
'xa'          Name
'-'           Operator
'1'           Literal.Number.Integer
','           Punctuation
'x'           Name
'\n\t'        Text
'dex'         Keyword
'\n\t'        Text
'bne'         Keyword
' '           Text
'L1'          Name
'\n\t\n\t'    Text
'lda'         Keyword
' '           Text
'#'           Punctuation
'ITERATIONS'  Name
'\t\t'        Text
'; i := ITERATIONS' Comment.Single
'\n\t'        Text
'sta'         Keyword
' '           Text
'i'           Name
'\n'          Text

'L2:'         Name.Label
'\n\t'        Text
'jsr'         Keyword
' '           Text
'reverse_add' Name
'\n\t'        Text
'jsr'         Keyword
' '           Text
'is_palindrome' Name
'\n\t'        Text
'bne'         Keyword
' '           Text
'no_palindrome' Name
'\n\t'        Text
'clc'         Keyword
'\n\t'        Text
'rts'         Keyword
'\n'          Text

'no_palindrome:' Name.Label
'\n\t'        Text
'ldx'         Keyword
' '           Text
'length'      Name
'\t\t'        Text
'; a := b'    Comment.Single
'\n'          Text

'L3:'         Name.Label
'\n\t'        Text
'lda'         Keyword
' '           Text
'xb'          Name
'-'           Operator
'1'           Literal.Number.Integer
','           Punctuation
'x'           Name
'\n\t'        Text
'sta'         Keyword
' '           Text
'xa'          Name
'-'           Operator
'1'           Literal.Number.Integer
','           Punctuation
'x'           Name
'\n\t'        Text
'dex'         Keyword
'\n\t'        Text
'bne'         Keyword
' '           Text
'L3'          Name
'\n\t\n\t'    Text
'dec'         Keyword
' '           Text
'i'           Name
'\t\t\t'      Text
'; Loop body end.' Comment.Single
'\n\t'        Text
'bne'         Keyword
' '           Text
'L2'          Name
'\n\t\n\t'    Text
'sec'         Keyword
'\n\t'        Text
'rts'         Keyword
'\n'          Text

'.endproc'    Keyword.Pseudo
'\n\n'        Text

';--------------------------------------' Comment.Single
'\n'          Text

'; Add the reverse to `xa` to itself and store the result in `xb`.' Comment.Single
'\n'          Text

'; '          Comment.Single
'\n'          Text

'; :in: `length`, `xa`' Comment.Single
'\n'          Text

'; :out: `length`, `xb`' Comment.Single
'\n'          Text

';--------------------------------------' Comment.Single
'\n'          Text

'.proc'       Keyword.Pseudo
' '           Text
'reverse_add' Name
'\n'          Text

'.code'       Keyword.Pseudo
'\n\t'        Text
'ldx'         Keyword
' '           Text
'#'           Punctuation
'0'           Literal.Number.Integer
'\n\t'        Text
'ldy'         Keyword
' '           Text
'length'      Name
'\n\t'        Text
'clc'         Keyword
'\n'          Text

'L1:'         Name.Label
'\n\t'        Text
'lda'         Keyword
' '           Text
'xa'          Name
','           Punctuation
'x'           Name
'\n\t'        Text
'adc'         Keyword
' '           Text
'xa'          Name
'-'           Operator
'1'           Literal.Number.Integer
','           Punctuation
'y'           Name
'\n\t\n\t'    Text
'cmp'         Keyword
' '           Text
'#'           Punctuation
'10'          Literal.Number.Integer
'\n\t'        Text
'bcc'         Keyword
' '           Text
'no_adjust'   Name
'\n\t'        Text
'sbc'         Keyword
' '           Text
'#'           Punctuation
'10'          Literal.Number.Integer
'\n'          Text

'no_adjust:'  Name.Label
'\n\t'        Text
'sta'         Keyword
' '           Text
'xb'          Name
','           Punctuation
'x'           Name
'\n\t\n\t'    Text
'dey'         Keyword
'\n\t'        Text
'inx'         Keyword
'\n\t'        Text
'txa'         Keyword
'\t\t'        Text
'; ``eor`` instead of ``cpx`` to keep the carry flag' Comment.Single
'\n\t'        Text
'eor'         Keyword
' '           Text
'length'      Name
'\t'          Text
'; of the addition above.' Comment.Single
'\n\t'        Text
'bne'         Keyword
' '           Text
'L1'          Name
'\n\t\n\t'    Text
'bcc'         Keyword
' '           Text
'no_carry'    Name
'\n\t'        Text
'lda'         Keyword
' '           Text
'#'           Punctuation
'1'           Literal.Number.Integer
'\n\t'        Text
'sta'         Keyword
' '           Text
'xb'          Name
','           Punctuation
'x'           Name
'\n\t'        Text
'inc'         Keyword
' '           Text
'length'      Name
'\n'          Text

'no_carry:'   Name.Label
'\n\t'        Text
'rts'         Keyword
'\n'          Text

'.endproc'    Keyword.Pseudo
'\n\n'        Text

';--------------------------------------' Comment.Single
'\n'          Text

'; Checks if `xb` is a palindrome.' Comment.Single
'\n'          Text

'; '          Comment.Single
'\n'          Text

'; :in: `length`, `xb`' Comment.Single
'\n'          Text

'; :out: Z flag set if `xb` is a palindrome, cleared otherwise.' Comment.Single
'\n'          Text

';--------------------------------------' Comment.Single
'\n'          Text

'.proc'       Keyword.Pseudo
' '           Text
'is_palindrome' Name
'\n'          Text

'.code'       Keyword.Pseudo
'\n\t'        Text
'ldx'         Keyword
' '           Text
'#'           Punctuation
'0'           Literal.Number.Integer
'\n\t'        Text
'lda'         Keyword
' '           Text
'length'      Name
'\n\t'        Text
'tay'         Keyword
'\n\t'        Text
'lsr'         Keyword
'\n\t'        Text
'sta'         Keyword
' '           Text
'L1'          Name
'+'           Operator
'1'           Literal.Number.Integer
'\t'          Text
'; Self modifying code!' Comment.Single
'\n'          Text

'L1:'         Name.Label
'\n\t'        Text
'cpx'         Keyword
' '           Text
'#'           Punctuation
'0'           Literal.Number.Integer
'\t\t'        Text
'; <<< 0 replaced by (`length` / 2).' Comment.Single
'\n\t'        Text
'beq'         Keyword
' '           Text
'return'      Name
'\n\t'        Text
'lda'         Keyword
' '           Text
'xb'          Name
','           Punctuation
'x'           Name
'\n\t'        Text
'cmp'         Keyword
' '           Text
'xb'          Name
'-'           Operator
'1'           Literal.Number.Integer
','           Punctuation
'y'           Name
'\n\t'        Text
'bne'         Keyword
' '           Text
'return'      Name
'\n\t'        Text
'dey'         Keyword
'\n\t'        Text
'inx'         Keyword
'\n\t'        Text
'bne'         Keyword
' '           Text
'L1'          Name
'\n'          Text

'return:'     Name.Label
'\n\t'        Text
'rts'         Keyword
'\n'          Text

'.endproc'    Keyword.Pseudo
'\n'          Text
