; ------------------------------------------------------------------------
;
; wordmaster
;
; A game similar in content to Hangman, but without all the nasty side
; effects of losing.  Instead, you play for points as follows...
;      bad letter    ->  -1 point
;      good letter   ->   0 points
;      finish a word ->   5 points
;
; You start with 20 points.  If you make it to 50, you win.  If you drop
; to zero...well...you can always try again.
;

	.ORIG 12288

	LEA R0,WELCOMESTR	; say hello
	TRAP 34

	LD R0,FUNCONE		; seed the random number generator
	JSRR R0
	LD R0,FUNCTWO		; build the dictionary of words
	JSRR R0
	JSR PLAY		; play the game until you win or lose

	; R0 = 0 is a lose, 1 is a quit, 2 is a win

	LEA R1,TERMSTRMAP	; print the right message and stop
	ADD R0,R0,R1
	LDR R0,R0,0
	TRAP 34
	TRAP 37

; hardcoded because we left out the '.FILL label' format...

FUNCONE	
.FILL 13138 ; SRANDOM		; functions to execute...
FUNCTWO	
.FILL 13210 ; BUILDDICT

TERMSTRMAP			; a table of possible termination strings
	.FILL 12381 ; LOSESTR
	.FILL 12490 ; QUITSTR
	.FILL 12580 ; WINSTR


WELCOMESTR 
.STRINGZ "\n***               Welcome to wordmaster!  Good luck!                 ***\n\n"

LOSESTR 
.STRINGZ "\nLooks like you're out of points.  Better luck next time.\nThe Union bookstore sells dictionaries, you know.\n"

QUITSTR 
.STRINGZ "\nQuitting already?  You can't be a word master unless you master the words,\nyou realize?\n"

WINSTR	
.STRINGZ "\n***          Congratulations!  You are a master of words!            ***\n\n"

; ------------------------------------------------------------------------
; the main game routines are in this section

; R5 points to the current word

PLAY	
ST R7,PLAYRX		; save R7 to allow further calls

PLAYNEWWORD
	JSR PICKAWORD		; pick a new word
PLAYSAMEWORD
	JSR PRINTSTATUS	; print the status/word/letters tried
	JSR GUESSALETTER	; handle one guess; returns R0=1 if 
				;    word is completed, 0 if not completed,
				;    and -1 for quitting the game

	; check score conditions
	LD R1,POINTS		; > 0 ?
	br  p NOTLOSTYET

	AND R0,R0,0		; nope, out of points...tough luck!
	br  nzp PLAYDONE

NOTLOSTYET
	LD R2,NEGWIN		; enough points to win?
	ADD R2,R2,R1
	br  n NOTWONYET

	AND R0,R0,0		; yes!  The player has won.
	ADD R0,R0,2
	br nzp PLAYDONE

NOTWONYET
	ADD R0,R0,0		; guess again or generate new word?
	br z PLAYSAMEWORD
	br p PLAYNEWWORD

	AND R0,R0,0		; player quit
	ADD R0,R0,1

PLAYDONE
	LD R7,PLAYRX		; restore R7
	RET

PLAYRX	
.BLKW 1			; storage for R7
NEGWIN	
.FILL 65486		; score required to win (only prints
				;    2 digits, so don't raise > 100)

;
; -----------------------------------------------------------------------
; You have xx points.  The word is _ _ _ h a _ a _ _ .
;
; So far, you have tried: a b d f g h x y .
; -----------------------------------------------------------------------
;
 

PRINTSTATUS
	ST R7,PSTATRR		; save R7 to allow traps

	LEA R0,STATSA		; print first part of status string
	TRAP 34
	LD R0,ASCIIZERO
	LD R1,POINTS

PSTATTENS			; calculate tens digit of points
	ADD R0,R0,1
	ADD R1,R1,-10
	br zp PSTATTENS
	ADD R1,R1,10
	ADD R0,R0,-1
	TRAP 33			; and print it

	LD R0,ASCIIZERO	; then print ones digit of points
	ADD R0,R0,R1
	TRAP 33

	LEA R0,STATSB		; print second part of status string
	TRAP 34
	LD R0,ASCIIZERO
	LD R1,POINTS

	; print word with blanks for letters not yet guessed
	ADD R1,R5,0		; R1 points to letters in word
	LEA R2,CORRECT		; R2 points to array of boolean values
				;    0 if not guessed, 1 if guessed

PSTATPRINTWORD
	LDR R0,R1,0		; end of string yet?
	br z PSTATWORDDONE

	LDR R3,R2,0		; this letter guessed?
	br np PSTATPRINTLET
	LD R0,ABLANK		; if not, print a blank
PSTATPRINTLET
	TRAP 33

	LD R0,ASPACE		; after letter/blank, print a space
	TRAP 33

	ADD R1,R1,1		; move on to next letter
	ADD R2,R2,1
	br nzp PSTATPRINTWORD

PSTATWORDDONE
	LEA R0,STATSC		; print third part of status string
	TRAP 34
	LD R0,ASCIIZERO
	LD R1,POINTS

	; print the letters already tried for this word
	LD R1,ASCIILCA	; R1 holds ASCII lower case 'a'
	LEA R2,TRIED		; R2 points to array of boolean values
				;    0 if letter not tried, 1 if tried
	LD R3,NUMLETTERS	; R3 counts down from 26

PSTATPRINTTRIES
	LDR R4,R2,0		; did the player try this letter?
	br z PSTATNOTTRIED

	ADD R0,R1,0		; if so, print the letter and a space
	TRAP 33
	LD R0,ASPACE
	TRAP 33

PSTATNOTTRIED
	ADD R1,R1,1		; loop back over all letters
	ADD R2,R2,1
	ADD R3,R3,-1
	br p PSTATPRINTTRIES


	LEA R0,STATSD		; print fourth part of status string
	TRAP 34
	LD R0,ASCIIZERO
	LD R1,POINTS

	LD R7,PSTATRR		; restore R7
	RET


ASCIIZERO
.FILL 48	; '0'
ABLANK		
.FILL 95	; '_' for blanks
ASPACE		
.FILL 32	; ' '
ASCIILCA	
.FILL 97	; 'a'
NUMLETTERS	
.FILL 26
STATSA	
.STRINGZ "-----------------------------------------------------------------------\nYou have "
STATSB	
.STRINGZ " points.  The word is: "
STATSC	
.STRINGZ "\n\nSo far, you have tried: "
STATSD	
.STRINGZ "\n"
PSTATRR	
.BLKW 1


PICKAWORD
	ST R7,PAWRX		; save R7

	AND R0,R0,0

	LEA R5,TRIED		; zero out array of tried letters
	LD R1,NUMLETTERS
CLEARTRIED
	STR R0,R5,0
	ADD R5,R5,1
	ADD R1,R1,-1
	br p CLEARTRIED
	
	LEA R5,CORRECT		; zero out array of guessed letters
	LD R1,MAXLEN
CLEARCORRECT
	STR R0,R5,0
	ADD R5,R5,1
	ADD R1,R1,-1
	br p CLEARCORRECT

	; pick a word at random
	JSR RANDOM		; get a random number in R0 (0...2^15-1)
	LDI R1,DICTPTR		; read the number of words in R1
	JSR MOD			; use MOD to find a word 
	LD R5,DICTPTR		; point R5 to the word
	ADD R5,R5,R0
	LDR R5,R5,1		; words start at DICTPTR + 1

	ADD R0,R5,0		; count the letters in the word
	AND R1,R1,0
PAWFINDLEN
	LDR R2,R0,0
	br z PAWFOUNDLEN
	ADD R0,R0,1
	ADD R1,R1,1
	br nzp PAWFINDLEN
PAWFOUNDLEN
	ST R1,REMAIN		; all letters must be guessed

	LD R7,PAWRX		; restore R7

	RET

PAWRX
.BLKW 1


POINTS	
.FILL 20	 	; start with 20 points
TRIED	
.BLKW 26		; letter A...Z tried for this word?
REMAIN  
.BLKW 1			; missing letters remaining
CORRECT	
.BLKW 40		; letters in word have been guessed?
				;    (length is negative of NEGMAXLEN 
				;    value later in code)
MAXLEN	
.FILL 40		; also here...


GUESSALETTER
	ST R7,GUESSRX		; save R7 to allow traps

GUESSLOOP
	TRAP 32			; get a key
	
	LD R1,ASCIINEGESC	; does player want to quit?
	ADD R1,R1,R0
	br np GUESSNOTESC

	AND R0,R0,0		; yes, so return R0=-1
	ADD R0,R0,-1
	br nzp GUESSDONE

GUESSNOTESC
	LD R1,ASCIINEGLCA	; key in range 'a'...'z'?
	ADD R1,R0,R1		; < 'a' (including upper case!)
	br n GUESSLOOP
	LD R2,NEGNUMLETTERS	; > 'z'
	ADD R2,R2,R1
	br zp GUESSLOOP
	
	; note that R0 is still the ASCII character pressed, while
	; R1 is the corresponding index (0...25).

	LEA R2,TRIED		; was letter tried already?
	ADD R2,R2,R1
	LDR R3,R2,0
	br np GUESSLOOP

	ADD R3,R3,1		; mark the letter as tried now
	STR R3,R2,0

	; mark and count occurences in word
	NOT R0,R0		; negate character in R0 for comparisons
	ADD R0,R0,1
	ADD R1,R5,0		; point R1 to word
	LEA R2,CORRECT		; point R2 to array of correctly guessed
				;    letters
	AND R3,R3,0		; count of guessed letter in word

GUESSCHECKWORD
	LDR R4,R1,0		; read a character from the word
	br z GUESSENDWORD
	ADD R4,R4,R0		; is it a match?
	br np GUESSNOMATCH

	ADD R4,R4,1		; mark letter as correctly guessed
	STR R4,R2,0
	ADD R3,R3,1		; and increment match count

GUESSNOMATCH
	ADD R1,R1,1		; advance pointers and continue
	ADD R2,R2,1
	br nzp GUESSCHECKWORD

GUESSENDWORD
	ADD R3,R3,0		; any matches?
	br z GUESSMISSED

	NOT R3,R3		; subtract from remaining letter count
	ADD R3,R3,1
	LD R0,REMAIN
	ADD R0,R0,R3
	ST R0,REMAIN
	br p GUESSAGAIN		; and guess again if necessary

	LD R0,POINTS		; word completed!  score 5 points
	ADD R0,R0,5
	ST R0,POINTS

	JSR PRINTSTATUS	; show full word

	AND R0,R0,0		; return R0=1 to indicate completion
	ADD R0,R0,1
	br nzp GUESSDONE

GUESSMISSED
	LD R0,POINTS		; lose a point
	ADD R0,R0,-1
	ST R0,POINTS		; and must guess again...

GUESSAGAIN
	AND R0,R0,0		; word not completed

GUESSDONE
	LD R7,GUESSRX		; restore R7
	RET

GUESSRX	
.BLKW 1

ASCIINEGESC	
.FILL 65509	; negated ASCII ESCAPE character
ASCIINEGLCA	
.FILL 65439 	; negated ASCII 'a'
NEGNUMLETTERS 
.FILL 65510

DICTPTR	
.FILL 28672

; ------------------------------------------------------------------------
; arithmetic routines that are useful when generating random numbers,
; including a logical shift right routine used to avoid the non-random 
; low-order bit of the simple generator and a MOD routine used to restrict
; the range of the random numbers as desired


; LOGRIGHTSHIFT -- logically shift R0 right by one bit (MSB <- 0)
;     INPUTS -- R0
;     OUTPUTS -- R0 shifted right by a bit
;     SIDE EFFECTS -- none

LOGRIGHTSHIFT
	ST R1,LRSHFTRO		; save a copy of R1

	AND R0,R0,-2		; set low bit to 0 (will become MSB)

	AND R1,R1,0		; loop 15 times...
	ADD R1,R1,15

LRSHFTLOOP
	ADD R0,R0,0		; rotate left (copy high bit to low bit)
	br n LOWBITISA
	ADD R0,R0,R0
	br nzp LRSHFTNEXT
LOWBITISA
	ADD R0,R0,R0
	ADD R0,R0,1

LRSHFTNEXT
	ADD R1,R1,-1
	br p LRSHFTLOOP

	LD R1,LRSHFTRO		; restore R1
	RET

LRSHFTRO
	.BLKW 1



; MOD -- calculate the modulus of R0 relative to R1
;     INPUTS -- R0 and R1
;     OUTPUTS -- R0 as the original value MOD R1 (0 <= R0 < ABS (R1))
;     SIDE EFFECTS -- none


MOD	
ST R1,MODRA		; save R1 through R4
	ST R2,MODRB
	ST R3,MODRC
	ST R4,MODRD

	ADD R1,R1,0		; set R1 to its absolute value
	br p MODROPOS
	br z MODZEROERR
	NOT R1,R1
	ADD R1,R1,1
	br p MODROPOS

	NOT R1,R1		; handle special case of R1=x8000
	AND R0,R0,R1		;    by ANDing with x7FFF
	br nzp MODFOUND

MODZEROERR
	ST R7,MODRE		; save R7 to allow trap below
	LEA R0,MSGMOD		; handle special case of R1=x0000
	TRAP 34			;    by printing a warning
	AND R0,R0,0		;    and returning 0
	LD R7,MODRE		; restore R7
	br nzp MODFOUND

MODROPOS
	ADD R0,R0,0		; is R0 non-negative?
	br zp MODPOSLOOP

; R0 is negative, so add multiples of R1 to make it positive

MODRZNEG
	ADD R3,R1,0		; start by adding R1
MODNEGLOOP
	ADD R2,R3,0
	ADD R4,R0,R2		; check if R2 is enough to make R0 >= 0
	br zp FOUNDGOODADD
	ADD R3,R2,R2		; if not, try doubling R2
	br zp MODNEGLOOP
	ADD R0,R0,R2		; if necessary, add in old R2 and start over
	br nzp MODRZNEG
FOUNDGOODADD
	ADD R0,R0,R2		; add R2 to make R0 >= 0 

; R0 is non-negative, so subtract multiples of R1 to force it into the
;    correct range

MODPOSLOOP
	NOT R4,R1		; is R0 < R1 ?
	ADD R4,R4,1
	ADD R4,R4,R0
	br n MODFOUND

	; find biggest left shift of R1 that is both positive and <= R0
	ADD R2,R1,0
MODSHIFTLOOP
	ADD R3,R2,0		; last value checked (R2) was acceptable
	ADD R2,R2,R2		; try multiplying again by 2
	br n MODTOOBIG
	NOT R4,R0		; is R2 < R0 ?
	ADD R4,R4,1
	ADD R4,R4,R2
	br nz MODSHIFTLOOP

MODTOOBIG			; subtract R3 (the biggest left shift of 
	NOT R4,R3		;    R1 that is <= R0) from R0
	ADD R4,R4,1
	ADD R0,R0,R4

	br nzp MODPOSLOOP	; start over with new value of R0

MODFOUND
	LD R1,MODRA		; restore R1 through R4
	LD R2,MODRB
	LD R3,MODRC
	LD R4,MODRD

	RET			; and return...

MODRA	
.BLKW 1			; register storage for R1, R2, R3, and R4
MODRB	
.BLKW 1
MODRC	
.BLKW 1
MODRD	
.BLKW 1
MODRE	
.BLKW 1
MSGMOD	
.STRINGZ "\nWARNING: MOD called with R1=0\n"

; ------------------------------------------------------------------------
; the following subroutines provide random numbers using
; a simple pseudo-random number generator and a loop to
; wait for user input (the number of iterations becomes
; the seed for the generator).


; SRANDOM -- generate new random seed
;     INPUTS -- none
;     OUTPUTS -- none
;     SIDE EFFECTS -- changes random seed, destroys R0 and R1

SRANDOM	
ST R7,RANDRA		; save R7 to allow trap call below
	LEA R0,MSGSRANDOM	; print a message
	TRAP 34
	LD R7,RANDRA		; restore R7

	AND R0,R0,0		; wait for a keystroke, counting iterations
SRANDOMLOOP
	ADD R0,R0,1
	LDI R1,SRKBSR
	br zp SRANDOMLOOP
	
	LDI R1,SRKBDR		; read (and ignore) the key

	ST R0,RANDSEED		; store the newly generated random seed
	RET


; RANDOM -- generate random number
;     INPUTS -- none
;     OUTPUTS -- R0 is a random value
;     SIDE EFFECTS -- changes random seed

; function used is NEW = (27193 * OLD) + 35993   MOD 65536
;	low bit is right-shifted out before returning, since
;       it is not random (the rest are not too bad, at least by 
;       separation of order 2 in Knuth's methods...)

RANDOM	
ST R1,RANDRA		; save R1 and R7
	ST R7,RANDRB
	LD R0,RANDSEED
	ADD R1,R0,R0		; x 0002
	ADD R1,R1,R0		; x 0003
	ADD R1,R1,R1		; x 0006
	ADD R1,R1,R1		; x 000C
	ADD R1,R1,R0		; x 000D
	ADD R1,R1,R1		; x 001A
	ADD R1,R1,R1		; x 0034
	ADD R1,R1,R0		; x 0035
	ADD R1,R1,R1		; x 006A
	ADD R1,R1,R1		; x 00D4
	ADD R1,R1,R1		; x 01A8
	ADD R1,R1,R1		; x 0350
	ADD R1,R1,R0		; x 0351
	ADD R1,R1,R1		; x 06A2
	ADD R1,R1,R0		; x 06A3
	ADD R1,R1,R1		; x 0D46
	ADD R1,R1,R0		; x 0D47
	ADD R1,R1,R1		; x 1A8E
	ADD R1,R1,R1		; x 351C
	ADD R1,R1,R1		; x 6A38
	ADD R0,R1,R0		; x 6A39 = #27193
	LD R1,RANDADD
	ADD R0,R0,R1
	ST R0,RANDSEED
	JSR LOGRIGHTSHIFT	; drop the low bit
	LD R1,RANDRA		; restore R1 and R7
	LD R7,RANDRB
	RET

; storage for SRANDOM and RANDOM

SRKBSR	
.FILL 65024
SRKBDR	
.FILL 65026
MSGSRANDOM
	.STRINGZ "\nPlease press a key...\n"
RANDRA	
.BLKW 1
RANDRB	
.BLKW 1
RANDSEED 
	.BLKW 1
RANDADD
	.FILL 35993

; ------------------------------------------------------------------------
; This subroutine builds a table of strings (starting addresses) from
; the list of strings below.  The number of entries in the table is
; stored at x7000, and the table starts at x7001.

; BUILDDICT -- build the wordmaster dictionary from the strings below
;     INPUTS -- none
;     OUTPUTS -- none
;     SIDE EFFECTS -- builds a dictionary at x7000 from strings below,
;                     storing the number of strings (not to exceed 4000) 
;		      at x7000 and the string addresses as an array 
;		      starting at x7001.


BUILDDICT
	ST R0,BUILDRA		; save R0, R1, R2, R3, and R4 to stack
	ST R1,BUILDRB
	ST R2,BUILDRC
	ST R3,BUILDRD
	ST R4,BUILDRE

	LD R0,DICTLOC		; R0 points to our dictionary
	ADD R0,R0,1
	LEA R1,THEWORDS	; R1 points to the list of strings
	AND R2,R2,0		; R2 counts the words found

BUILDLOOP
	LDR R3,R1,0		; R3 is a character from the strings
	br z BUILDDONE

	STR R1,R0,0		; write string pointer to dictionary
	ADD R0,R0,1
	ADD R2,R2,1

	AND R4,R4,0		; count characters in string
BUILDFINDEND
	ADD R1,R1,1		; point R1 past end of current string
	ADD R4,R4,1
	LDR R3,R1,0
	br np BUILDFINDEND
	ADD R1,R1,1		; NUL doesn't count for string length (R4)

	LD R3,NEGMAXLEN	; is string too long?
	ADD R4,R4,R3
	br nz BUILDSTROK
	ADD R0,R0,-1		; if so, discard silently
	ADD R2,R2,-1

BUILDSTROK
	LD R3,NEGLIMIT		; continue if we have fewer than maximum
	ADD R3,R3,R2		;    allowed string count 
	br n BUILDLOOP

BUILDDONE
	STI R2,DICTLOC		; write number of strings into dictionary

	LD R0,BUILDRA		; restore R0, R1, R2, and R3, then return
	LD R1,BUILDRB
	LD R2,BUILDRC
	LD R3,BUILDRD
	LD R4,BUILDRE
	RET

DICTLOC	
.FILL 28672	; start of dictionary
NEGLIMIT	
.FILL 61536 ; word count limit (negated)
NEGMAXLEN	
.FILL 65496	; words are limited to 40 characters;
				;    matched to size of CORRECT array
BUILDRA	
.BLKW 1		; storage to save registers used
BUILDRB	
.BLKW 1
BUILDRC	
.BLKW 1
BUILDRD	
.BLKW 1
BUILDRE	
.BLKW 1
	

; IMPORTANT NOTE: No string can have more than 40 characters!

THEWORDS	; Apologies to Percy, ee, Bill, Tom, etc.
		; It's harder to think than to recite!

	.STRINGZ "apple"
	.STRINGZ "banana"
	.STRINGZ "cucumber"
	.STRINGZ "doppleganger"
	.STRINGZ "eggplant"
	.STRINGZ "ferocious"
	.STRINGZ "gangrene"
	.STRINGZ "hierarchical"
	.STRINGZ "idiomatic"
	.STRINGZ "juice"
	.STRINGZ "kangaroo"
	.STRINGZ "leopard"
	.STRINGZ "mongoose"
	.STRINGZ "nougat"
	.STRINGZ "orange"
	.STRINGZ "perspicacious"
	.STRINGZ "quality"
	.STRINGZ "reality"
	.STRINGZ "serenity"
	.STRINGZ "testimony"
	.STRINGZ "umbrella"
	.STRINGZ "voice"
	.STRINGZ "watershed"
	.STRINGZ "xylophone"
	.STRINGZ "yellow"
	.STRINGZ "yesterday"
	.STRINGZ "zinger"
	.STRINGZ "zymurgy"
	.STRINGZ "anticlimactic"
	.STRINGZ "imperial"
	.STRINGZ "persimmon"
	.STRINGZ "rutebaga"
	.STRINGZ "watermelon"
	.STRINGZ "yam"
	.STRINGZ "pester"
	.STRINGZ "poster"
	.STRINGZ "pistol"
	.STRINGZ "postal"
	.STRINGZ "pallet"
	.STRINGZ "pumpkin"
	.STRINGZ "red"
	.STRINGZ "hardly"
	.STRINGZ "garbled"
	.STRINGZ "master"
	.STRINGZ "once"
	.STRINGZ "zinger"
	.STRINGZ "which"
	.STRINGZ "much"
	.STRINGZ "wind"
	.STRINGZ "gave"
	.STRINGZ "truth"
	.STRINGZ "summer"
	.STRINGZ "bloodied"
	.STRINGZ "dizzying"
	.STRINGZ "leaves"
	.STRINGZ "sun"
	.STRINGZ "yanked"
	.STRINGZ "immortal"
	.STRINGZ "stars"
	.STRINGZ "awry"
	.STRINGZ "trunkless"
	.STRINGZ "antique"
	.STRINGZ "vast"
	.STRINGZ "legs"
	.STRINGZ "stone"
	.STRINGZ "stand"
	.STRINGZ "desert"
	.STRINGZ "dessert"
	.STRINGZ "sand"
	.STRINGZ "visage"
	.STRINGZ "wrinkled"
	.STRINGZ "command"
	.STRINGZ "sneer"
	.STRINGZ "sculptor"
	.STRINGZ "passions"
	.STRINGZ "remain"
	.STRINGZ "stamped"
	.STRINGZ "lifeless"
	.STRINGZ "things"
	.STRINGZ "bare"
	.STRINGZ "nothing"
	.STRINGZ "beside"
	.STRINGZ "colossal"
	.STRINGZ "boundless"
	.STRINGZ "lone"
	.STRINGZ "level"
	.STRINGZ "stretch"
	.STRINGZ "compare"
	.STRINGZ "lovely"
	.STRINGZ "temperate"
	.STRINGZ "rough"
	.STRINGZ "shake"
	.STRINGZ "darling"
	.STRINGZ "lease"
	.STRINGZ "short"
	.STRINGZ "date"
	.STRINGZ "sometimes"
	.STRINGZ "eye"
	.STRINGZ "shine"
	.STRINGZ "often"
	.STRINGZ "gold"
	.STRINGZ "complexion"
	.STRINGZ "dimmed"
	.STRINGZ "declines"
	.STRINGZ "fair"
	.STRINGZ "chance"
	.STRINGZ "nature"
	.STRINGZ "untrimmed"
	.STRINGZ "course"
	.STRINGZ "eternal"
	.STRINGZ "fade"
	.STRINGZ "possession"
	.STRINGZ "obsession"
	.STRINGZ "poesy"
	.STRINGZ "poems"
	.STRINGZ "poetry"
	.STRINGZ "brag"
	.STRINGZ "breathe"
	.STRINGZ "long"
	.STRINGZ "this"
	.STRINGZ "life"
	.STRINGZ "throw"
	.STRINGZ "drummer"
	.STRINGZ "coffin"
	.STRINGZ "found"
	.STRINGZ "around"
	.STRINGZ "mound"
	.STRINGZ "sound"
	.STRINGZ "pound"
	.STRINGZ "kopje"
	.STRINGZ "veldt"
	.STRINGZ "constellations"
	.STRINGZ "foreign"
	.STRINGZ "night"
	.STRINGZ "never"
	.STRINGZ "knew"
	.STRINGZ "home"
	.STRINGZ "meaning"
	.STRINGZ "gloam"
	.STRINGZ "portion"
	.STRINGZ "plain"
	.STRINGZ "forever"
	.STRINGZ "homely"
	.STRINGZ "breast"
	.STRINGZ "brain"
	.STRINGZ "grown"
	.STRINGZ "tree"
	.STRINGZ "happy"
	.STRINGZ "despair"
	.STRINGZ "repair"
	.STRINGZ "fortune"
	.STRINGZ "beweep"
	.STRINGZ "outcast"
	.STRINGZ "state"
	.STRINGZ "trouble"
	.STRINGZ "bootless"
	.STRINGZ "self"
	.STRINGZ "curse"
	.STRINGZ "wishing"
	.STRINGZ "like"
	.STRINGZ "rich"
	.STRINGZ "hope"
	.STRINGZ "featured"
	.STRINGZ "desiring"
	.STRINGZ "scope"
	.STRINGZ "despising"
	.STRINGZ "lark"
	.STRINGZ "break"
	.STRINGZ "day"
	.STRINGZ "arising"
	.STRINGZ "rhythm"
	.STRINGZ ""			; empty string marks end

; ------------------------------------------------------------------------

	.END
