view dod.s @ 22:b54feb3d64eb

Identified several aspects related to object creation Identified the object creation routine (SWI call 23). Also identified SWI call 24 which sets the specifications for an object based on its type. Also identified the initial equipment creation code. Also identified several variable areas including the object data table. Also identified the data tables for objects in the ROM.
author William Astle <lost@l-w.ca>
date Fri, 26 Dec 2014 00:51:50 -0700
parents 0a6eb8cabe1d
children 7c2f57937862
line wrap: on
line source
; Dungeons of Daggorath
;
; Original game copyright © 1982 by Dyna Micro
;
; The code contained in this file is not the original source code to Dungeons of Daggorath. It was
; constructed by William Astle in 2013 by disassembling the Dungeons of Daggorath ROM.
;
; According to a web page retrieved from http://frodpod.tripod.com/lisence.html on May 24, 2013,
; this endeavour is permitted. In case the web page becomes unavailable, and because it contains what
; I believe to be important credit information, I have reproduced the text of it below:
;
;***********************************************************************************************************
;* Grant of license to reproduce Dungeons of Daggorath
;*
;* My name is Douglas J. Morgan.  I was the president of DynaMicro, Inc. (since dissolved), the company
;* which conceived, created and wrote Dungeons of Daggorath, a best selling Radio Shack Color Computer
;* adventure game. 
;*
;* I have examined the contract I signed with Radio Shack for their license of the game.  The contract
;* provides that Radio Shack shall have an exclusive license to manufacture and produce the game, but
;* that said exclusive license shall revert to a non-exclusive license should Radio Shack cease to
;* produce and sell the game.  To the best of my knowledge, they have not produced the game for many
;* years.  Thus, it is my belief that the right to grant a license for the game has reverted to me. 
;*
;* I hereby grant a non-exclusive permanent world-wide license to any and all Color Computer site
;* administrators, emulator developers, programmers or any other person or persons who wish to develop,
;* produce, duplicate, emulate, or distribute the game on the sole condition that they exercise every
;* effort to preserve the game insofar as possible in its original and unaltered form. 
;*
;* The game was a labor of love.  Additional credits to Phillip C. Landmeier - who was my partner and
;* who originally conceived the vision of the game and was responsible for the (then) state of the art
;* sounds and realism, to April Landmeier, his wife - the artist who drew all the creatures as well as
;* all the artwork for the manual and game cover, and to Keith Kiyohara - a gifted programmer who helped
;* write the original game and then contributed greatly to compressing a 16K game into 8K so that it
;* could be carried and produced by Radio Shack.
;*
;* The game did very well for us.  I give it to the world with thanks to all who bought it, played it
;* or enjoyed it. 
;*
;* There is one existing copy of the original source code.  Anyone willing to pay for the copying of
;* the listing (at Kinko's) and shipment to them, who intends to use it to enhance or improve the emulator
;* versions of the game is welcome to it. 
;*
;* Verification of this license grant or requests for the listing can be made by contacting Louis Jordan,
;* Thank you.
;***********************************************************************************************************
;
; Louis Jordan's email address is given as louisgjordan@yahoo.com in a hyperlink in the above statement.
;
; It is my belief that this endeavor to disassemble Dungeons of Daggorath is in compliance with the above
; license grant. I have done so for my own amusement and for the challenge. I have also done so because
; I failed to elicit a response from Louis Jordan as described in the license grant. I am not surprised
; that I received no reply given that the page above was put online during or prior to 2006.

; some utility macros
dod		macro noexpand
		swi
		fcb \1
		ifeq \1-$1B
		fcb \2
		endc
		endm

skip2		macro noexpand
		fcb $8c
		endm


; macros for color basic ROM calls
romcall		macro noexpand
		swi2
		fcb \1
		endm

; draw a graphic with graphic data at (X)
drawgraphic	macro noexpand
		dod S01
		endm
; render a packed string (immediate data)
renderstrimmp	macro noexpand
		dod S02
		endm
; render a packed string from (X)
renderstr	macro noexpand
		dod S03
		endm
; render character in A
renderchar	macro noexpand
		dod S04
		endm
; decode a 5 bit packed string from (X) to stringbuf
decodestrsb	macro noexpand
		dod S05
		endm
; decode a 5 bit packed string from (X) to (U)
decodestr	macro noexpand
		dod S06
		endm

; clear graphics screen currently visible; return parameter pointer in U
cleargfx1	macro noexpand
		dod S08
		endm
; clear graphics screen currently used for drawing; return parameter pointer in U
cleargfx2	macro noexpand
		dod S09
		endm
; clear the status line
clearstatus	macro noexpand
		dod S0A
		endm
; clear the command entry area
clearcommand	macro noexpand
		dod S0B
		endm
; update the inventory on the status line
updatestatus	macro noexpand
		dod S0D
		endm
; do a newline, show prompt, and cursor
showprompt	macro noexpand
		dod S0F
		endm

; do a delay for about 1.33 seconds
delay		macro noexpand
		dod S10
		endm

; set a block of memory (from X to U-1) to $00
clearblock	macro noexpand
		dod S11
		endm
; set a block of memory (from X to U-1) to $ff
setblock	macro noexpand
		dod S12
		endm
; fade in the image at (X) with sound effects at scale 1.0, clear status and command area
fadeinclrst	macro noexpand
		dod S13
		endm
; fade in the image at (X) with sound effects at scale 1.0, clear command area
fadein		macro noexpand
		dod S14
		endm
; fade out image at (X) with sound effects, clear command area
fadeout		macro noexpand
		dod S15
		endm
; display the PREPARE! screen
showprepare	macro noexpand
		dod S16
		endm
; create object of type in A
createobject	macro noexpand
		dod S17
		endm
; set object specs (object pointer in U)
setobjectspecs	macro noexpand
		dod S18
		endm
; play a sound number from immediate data at full volume
playsoundimm	macro noexpand
		dod S1B,\1
		endm
; play sound specified in A, volume in B
playsound	macro noexpand
		dod S1C
		endm

; ROM call numbers
POLCAT		equ 0
CSRDON		equ 4
BLKIN		equ 6
BLKOUT		equ 8
WRTLDR		equ 12

ROMTAB		equ $A000

BLKTYP		equ $7c
BLKLEN		equ $7d
CBUFAD		equ $7e

RESVEC		equ $A027

; SWI routines
S00		equ 0
S01		equ 1
S02		equ 2
S03		equ 3
S04		equ 4
S05		equ 5
S06		equ 6
S07		equ 7
S08		equ 8
S09		equ 9
S0A		equ $0A
S0B		equ $0B
S0C		equ $0C
S0D		equ $0D
S0E		equ $0E
S0F		equ $0F
S10		equ $10
S11		equ $11
S12		equ $12
S13		equ $13
S14		equ $14
S15		equ $15
S16		equ $16
S17		equ $17
S18		equ $18
S19		equ $19
S1A		equ $1A
S1B		equ $1B
S1C		equ $1C

PIA0		equ $ff00
PIA1		equ $ff20
SAMREG		equ $ffc0
TOPRAM		equ $4000
STACK		equ $1000

; the direct page
		org $200
V1F4		equ $1f4
zero		rmb 2				initialized to $0000
V202		rmb 1
allones		rmb 2				initialized to $ffff
V205		rmb 1
V206		rmb 1
V207		rmb 1
V208		rmb 1
screenvis	rmb 2				pointer to the parameter block of the currently shown screen
screendraw	rmb 2				pointer to the parameter block of the screen to use for drawing
V20D		rmb 2				pointer to demo game command sequence
objectfree		rmb 2				; pointer to next free object data slot
V211		rmb 2
V213		rmb 1
V214		rmb 1
carryweight	rmb 2
powerlevel	rmb 2				; player power
V219		rmb 1
V21A		rmb 1
V21B		rmb 1
V21C		rmb 1
lefthand	rmb 2				; pointer to object carried in left hand
righthand	rmb 2				; pointer to object carried in right hand
damagelevel	rmb 2				; player damage level
V223		rmb 1
curtorch	rmb 2				; pointer to currently mounted torch
V226		rmb 2
V228		rmb 1
backpack	rmb 2
V22B		rmb 1
levbgmask	rmb 1				the current level background colour mask
lightlevel	rmb 1				the current light level, $ff means dark
lightcount	rmb 1				counter between pixels when drawing lines
ybeg		rmb 2				start Y coord for line drawing
xbeg		rmb 2				start X coord for line drawing
yend		rmb 2				end Y coord for line drawing
xend		rmb 2				end X coord for line drawing
xcur		rmb 3				current X coordinate when drawing line
ycur		rmb 3				current Y coordinate when drawing line
xpstep		rmb 3				difference in X coordinate between pixels when drawing line
ypstep		rmb 3				difference in Y coordinate between pixels when drawing line
pixelcount	rmb 2				number of pixels to draw in a line
xbstep		rmb 1				the offset to add to pointer when moving to new byte (line drawing)
xystep		rmb 1				the offset to add to pointer when moving to new row (line drawing)
drawstart	rmb 2				start address of drawing area (line drawing)
drawend		rmb 2				end address of drawing area (line drawing)
V24B		rmb 4
V24F		rmb 1
V250		rmb 1
V251		rmb 1
V252		rmb 2
V254		rmb 2
V256		rmb 3
V259		rmb 2
V25B		rmb 2
V25D		rmb 2
V25F		rmb 2
soundvol	rmb 1				sound: volume multiplier for sound playing
V262		rmb 1
V263		rmb 2
V265		rmb 6
V26B		rmb 1
V26C		rmb 1
V26D		rmb 1
V26E		rmb 1
V26F		rmb 1
V270		rmb 3
V273		rmb 1
V274		rmb 1
V275		rmb 2
V277		rmb 1
V278		rmb 1
V279		rmb 2
V27B		rmb 1
V27C		rmb 1
V27D		rmb 1
V27E		rmb 3
V281		rmb 1
V282		rmb 4
V286		rmb 2
V288		rmb 2
V28A		rmb 1
V28B		rmb 1
V28C		rmb 1
V28D		rmb 1
V28E		rmb 1
V28F		rmb 1
V290		rmb 1
V291		rmb 1
V292		rmb 2
V294		rmb 1				; nonzero means to show creatures when displaying a scroll
V295		rmb 2
V297		rmb 3
V29A		rmb 1
V29B		rmb 1
V29C		rmb 1
V29D		rmb 1
V29E		rmb 1
V29F		rmb 2
V2A1		rmb 10
V2AB		rmb 2
V2AD		rmb 1
V2AE		rmb 1
V2AF		rmb 1
V2B0		rmb 1
V2B1		rmb 1
displayptr	rmb 2				; pointer to routine to display the main dungeon area
pageswap	rmb 1				nonzero means we're ready to swap graphics screens during IRQ
V2B5		rmb 1
V2B6		rmb 1
V2B7		rmb 1				nonzero means nonstandard text location
V2B8		rmb 1				load/save flag - <0 = ZLOAD, >0 = ZSAVE, 0 = regular init
V2B9		rmb 2
V2BB		rmb 1
keybufread	rmb 1				keyboard buffer read offset
keybufwrite	rmb 1				keyboard buffer write offset
		rmb 3
V2C1		rmb 1				temporary variable used during line drawing and division
V2C2		rmb 1				temporary variable used during division
V2C3		rmb 1				temporary variable used during division
V2C4		rmb 1
V2C5		rmb 1
V2C6		rmb 1
V2C7		rmb 10
keybuf		rmb 32				keyboard ring buffer
V2F1		rmb 32
V311		rmb 2
wordbuff		rmb 32
V333		rmb 2
stringbuf	rmb 34				temporary buffer used for decoding immediate packed strings
fontbuf		rmb 10				temporary buffer used for decoding font data
V361		rmb 31
V380		rmb 2				screen start address of info text area
V382		rmb 2				number of character cells in info text area
V384		rmb 2				current cursor position in info text area
V386		rmb 1				background colour mask for info text area
V387		rmb 1				nonzero if info text area should not be rendered on secondary screen
V388		rmb 2				screen start address of status line area
V38A		rmb 2				number of character cells in status line area
V38C		rmb 2				cursor position in status line area
V38E		rmb 1				background colour mask for status line area
V38F		rmb 1				nonzero if status line text should not be rendered on secondary screen
V390		rmb 2				start offset of the command entry area
V392		rmb 2				numer of character cells in command entry area
V394		rmb 2				current cursor position in entry area
V396		rmb 1				background colour mask of background area
V397		rmb 1				nonzero if main text should not be rendered on secondary screen
V398		rmb 43
V3C3		rmb 17
V3D4		rmb $220
mazedata	rmb $400
V9F4		rmb 9
V9FD		rmb $10a
emptyhand	rmb 10				; "object" information for empty hand
objecttab	rmb 72*14			; the object data table (room for 72 entries)
VF05		equ *


		org $c000
START		ldu #dodemo			point to the demo setup routine
		bra LC008			go handle the game
LC005		ldu #dogame			point to the real game setup routine
LC008		lds #STACK			put the stack somewhere safe
		ldx #PIA0			point at PIA0
		ldd #$34fa			initializers for the PIA
		sta 3,x				set data mode, interrupts disabled (side B)
		sta 1,x				set data mode, interrupts disabled (side A)
		ldx #PIA1			point at PIA1
		sta 1,x				set data mode, interrupts disabled (side A)
		clr 3,x				set direction mode for side B
		stb 2,x				set VDG and single bit sound to output
		lda #$3c			flags for data mode, no interrupts, sound enabled
		sta 3,x				set side B for data mode
		ldd #$2046			SAM value for "pmode 4" graphics, screen at $1000
		jsr setSAM			go set the SAM register
		lda #$f8			value for "pmode 4", color set 1
		sta 2,x				set VDG mode
		ldx #zero			point to start of variables
LC030		clr ,x+				clear a byte
		cmpx #TOPRAM			are we at the top of memory?
		blo LC030			brif not
		stu ,--s			set return address to the game initialization routine
		lda #zero/256			point to MSB of direct page
		tfr a,dp			set DP appropriately
		setdp zero/256			tell the assembler about DP
		ldy #LD7E8			point to variable initialization table
LC041		lda ,y+				fetch number of bytes in this initializer
		beq LC086			brif zero - we're done
		ldx ,y++			get address to copy bytes to
		bsr LC04B			go copy bytes
		bra LC041			go handle another initializer
LC04B		ldb ,y+				fetch source byte
		stb ,x+				stow at destination
		deca				are we done yet?
		bne LC04B			brif not
		rts				return to caller
LC053		pshs cc,a,b,x,y,u		save registers and interrupt status
		orcc #$10			disable IRQ
		ldx #V29F
LC05A		clr ,x+
		cmpx #V2AD
		blo LC05A
		ldx #V9FD
		stx V2B9
LC066		clr ,x+
		cmpx #emptyhand
		blo LC066
		ldy #LD7DC
		dec V2BB
		ldd #12
LC076		ldx ,y++
		beq LC084
		jsr LC25C
		stx 3,u
		jsr LC21D
		bra LC076
LC084		puls cc,a,b,x,y,u,pc
LC086		bsr LC053
		ldu #LDA91
		clra
LC08C		ldb ,u
		andb #$0f
		stb V28C
		ldb ,u+
		lsrb
		lsrb
		lsrb
		lsrb
		stb V28D
LC09A		createobject
		dec 5,x
		incb
		cmpb #5
		ble LC0A5
		ldb V28D
LC0A5		dec V28C
		bne LC09A
		inca
		cmpu #LDAA3
		blo LC08C
		ldu #V388				point to text parameters for status area
		dec V2B7				indicate nonstandard text area
		clearstatus				blank status line (where we'll put the copyright notice)
		renderstrimmp				display copyright message
		fcb $f8,$df,$0c,$c9			packed string "COPYRIGHT  DYNA MICRO  MCMLXXXII"
		fcb $27,$45,$00,$02
		fcb $65,$c1,$03,$52
		fcb $39,$3c,$00,$68
		fcb $da,$cc,$63,$09
		fcb $48
		clr V2B7				reset text rendering to standard mode
		rts					
dodemo		dec V277
		bsr LC114
		ldx #img_wizard				; point to wizard image
		dec V29E
		fadein					; fade the wizard in
		renderstrimmp				; display <CR>"I DARE YE ENTER..."<CR>
		fcb $9f,$d2,$02,$06			; packed "\rI DARE YE ENTER...\r" string
		fcb $45,$06,$4a,$02
		fcb $ba,$85,$97,$bd
		fcb $ef,$80
		renderstrimmp				; display "...THE DUNGEONS OF DAGGORATH!!!"
		fcb $f7,$bd,$ea,$20			; packed "...THE DUNGEONS OF DAGGORATH!!!" string
		fcb $a0,$25,$5c,$72
		fcb $bd,$d3,$03,$cc
		fcb $02,$04,$e7,$7c
		fcb $83,$44,$6f,$7b
		delay					;* wait for about 2.6 seconds
		delay					;*
		fadeout					; fade the wizard out
		cleargfx2				; clear second graphics screen
		dec pageswap				; flag graphics swap ready
		sync					; wait for swap to happen
		lda #2					; create maze for level 3
		ldu #startobjdemo			; point to demo game object list
		bra LC131				; go start demo running
LC114		ldd #$343c				; set up initializers for PIAs
		sta PIA1+1				; set data mode, no interrupts, cassette off
		stb PIA1+3				; set data mode, no interrupts, sound on
		inca					; adjust to enable interrupt
		sta PIA0+3				; set data mode, enable VSYNC, clear MSB of analog MUX
		cwai #$ef				; enable IRQ and wait for one
		rts					; return to caller
dogame		bsr LC114				; set up interrupts and sound
		ldd #$100b
		std V213
		clr powerlevel				; reset power level to new game level (keeps LSB of default value)
		clra					; create maze for level 1
		ldu #startobj				; point to new game backpack object list
LC131		showprepare				; show the PREPARE! screen
		dod S1A					; create maze
		ldy #backpack				; point to backpack list head pointer
LC139		lda ,u+					; get object to create
		bmi LC14F				; brif end of list
		createobject				; create requested object
		inc 5,x
		exg x,u					; swap object pointer and list pointer
		setobjectspecs				; set the specs properly (as in fully revealed)
		exg x,u					; swap pointers back
		clr 11,x				; mark object revealed
		stx ,y					; save new object in backpack list
		tfr x,y					; move list pointer to object just created
		bra LC139				; go look for another object to create
LC14F		tst V277
		beq LC166
		dec V29B
		ldx #LCDB2
		stx displayptr
		dec V294
		dod S0E
		delay
		delay
		clr V29B
		sync
		sync
LC166		dod S19
		showprompt
		jmp LC1F5
LC16D		stx CBUFAD			; set address to read to
		romcall BLKIN			; read a block
		tsta				; is it the end of the file?
		lbne RESVEC			; brif so - premature end, fail with a reset
		ldb BLKTYP			; get type of block
		rts
LC17C		ldu #PIA0
		ldd #$343c
		sta 3,u
		sta PIA1+3
		stb PIA1+1
		rts
LC18B		ldx zero			; get long delay constant
LC18D		leax -1,x			; have we reached 0?
		bne LC18D			; brif not
		rts
LC192		bsr LC17C			; set up PIA for cassette I/O
		bsr LC18B			; delay for a bit
		bsr LC18B
		romcall WRTLDR			; write a file header
		romcall BLKOUT
		bsr LC18B			; delay for a bit
		romcall WRTLDR			; write a leader for data area
		ldx #zero			; point to start of game state
LC1A6		ldd #$0180			; set block type to data, size to 128 bytes
		std BLKTYP
		stx CBUFAD			; set start of buffer to write
		romcall BLKOUT			; write a data block
		cmpx #VF05			; have we reached end of state?
		blo LC1A6			; brif not
		stu BLKTYP			; write trailing block
		romcall BLKOUT
		bsr LC18B			; delay for a bit
		bra LC1EC			; go init things and restart main loop
LC1C1		bsr LC17C			; set up PIA for cassette I/O
		romcall CSRDON			; start tape
LC1C6		ldu screendraw			; point to drawing area
		ldx ,u				; get pointer to screen data - use as a read buffer
		bsr LC16D			; read a block
		bne LC1C6			; brif data block
		ldx ,u				; get buffer pointer
		ldu #wordbuff			; point to requested file name
		ldb #8				; 8 characters in file name
LC1D5		lda ,x+				; does character match?
		cmpa ,u+
		bne LC1C1			; brif not - look for another header
		decb				; end of file name?
		bne LC1D5			; brif not - check another
		romcall CSRDON			; start tape
		ldx #zero			; point to game state area
LC1E4		bsr LC16D			; read a block
		bpl LC1E4			; brif it was still a data block
		lds #STACK			; reset stack pointer
LC1EC		jsr LC114			; make sure PIAs are set right
		clr V2B8			; flag regular operations
		dod S19
		showprompt
LC1F5		ldu #V2AB
		clr V2BB
LC1FA		tfr u,y
LC1FC		tst V2B8			; are we loading or saving?
		bgt LC192			; brif saving
		bmi LC1C1			; brif loading
		ldu ,u
		beq LC1F5
		pshs y,u
		jsr [3,u]
		puls y,u
		tst V2BB
		bne LC1F5
		cmpb #12
		beq LC1FA
		bsr LC238
		bsr LC21D
		tfr y,u
		bra LC1FC
LC21D		pshs cc,a,b,x
		orcc #$10
		sta 2,u
		ldx #V29F
		abx
		clra
		clrb
		std ,u
LC22B		cmpd ,x
		beq LC234
		ldx ,x
		bra LC22B
LC234		stu ,x
		puls cc,a,b,x,pc
LC238		pshs cc,x
		orcc #$10
		ldx ,u
		stx ,y
		puls cc,x,pc
LC242		pshs b,x,y,u
		tst V29B
		bne LC25A
LC248		tfr u,y
		ldu ,u
		beq LC25A
		dec 2,u
		bne LC248
		bsr LC238
		ldb #12
		bsr LC21D
		bra LC248
LC25A		puls b,x,y,u,pc
LC25C		pshs x
		ldu V2B9
		leax 7,u
		stx V2B9
		puls x,pc
; Set the SAM video mode and display offset register to the value in D. Starting at the lsb of
; D, the SAM bits are programmed from FFC0 upward. This sets bits 9-0 of the SAM register
; to match the value in D.
setSAM		pshs x,b,a			save registers
		ldx #SAMREG			point to SAM register
setSAM000	lsra				; shift the bit value to set to carry
		rorb				;
		bcs setSAM001			brif bit set
		sta ,x				clear the bit
		skip2				skip next instruction
setSAM001	sta 1,x				set the bit
		leax 2,x			move to next SAM register bit
		cmpx #SAMREG+$14		are we at the end of the register?
		blo setSAM000			brif not
		puls a,b,x,pc			restore registers and return
; IRQ service routine
LC27D		ldx #PIA1
		lda -29,x
		lbpl LC320
		lda #2
		tfr a,dp
		tst pageswap			do we have a screen swap to do?
		beq LC29D			brif not
		ldd screenvis			get currently visible screen pointer
		ldu screendraw			get newly drawn screen pointer
		std screendraw			save current screen as screen to draw
		stu screenvis			save drawn screen as current
		ldd 4,u				get the SAM value for the new screen
		bsr setSAM			go program the SAM
		clr pageswap			flag no swap needed
LC29D		tst V29C
		beq LC2A9
		com V29D
		lda V29D
		lsla
		lsla
		sta ,x
LC2A9		tst V2B1
		beq LC2DC
		dec V2AE
		bne LC2DC
		lda V2AF
		sta V2AE
		ldb 2,x
		eorb #2
		stb 2,x
		tst V2AD
		beq LC2DC
		ldu #V388
		ldx 4,u
		ldd #15
		std 4,u
		lda #$20
		com V2B0
		beq LC2D1
		lda #$22
LC2D1		jsr LCA17
		inc 5,u
		inca
		jsr LCA17
		stx 4,u
LC2DC		ldu #V2A1
		jsr LC242
		ldx #V295
		ldy #LC324
LC2E9		inc ,x
		cmpx #V29A
		beq LC2FF
		lda ,x
		cmpa ,y+
		blt LC2FF
		clr ,x+
		leau 2,u
		jsr LC242
		bra LC2E9
LC2FF		tst V228
		bne LC320
		tst V277
		beq LC318
		clr PIA0+2			strobe all keyboard columns
		lda PIA0			fetch row data
		anda #$7f			mask off comparator input
		cmpa #$7f			did we have any keys down?
		beq LC320			brif not
		ldx #LC005			; stop any demo game active; start a game
		stx 10,s			;
LC318		romcall POLCAT			poll the keyboard
		tsta				was a key down?
		beq LC320			brif not
		bsr LC340			go process keyboard input
LC320		lda PIA0+2			clear interrupt status
		rti
LC324		fcb $06,$0a,$3c,$3c,$18
LC329		pshs cc,b,x			save registers and interrupt status
		orcc #$10			disable IRQ
		clra				flag no key pressed
		ldx #keybuf			point to keyboard ring buffer
		ldb keybufread			get buffer read offset
		cmpb keybufwrite		same as buffer write offset?
		beq LC33E			brif so - no key available
		lda b,x				fetch key from buffer
		incb				bump buffer pointer
		andb #$1f			wrap around if needed
		stb keybufread			save new buffer read offset
LC33E		puls cc,b,x,pc			restore registers and interrupts
LC340		pshs cc,b,x			save registers and interrupt status
		orcc #$10			disable IRQ
		ldx #keybuf			point to keyboard ring buffer
		ldb keybufwrite			get buffer write offset
		sta b,x				stash new key
		incb				bump buffer pointer
		andb #$1f			wrap around if needed
		stb keybufwrite			save new buffer write offset
		puls cc,b,x,pc			restore registers and interrupts
; SWI handler
LC352		andcc #$ef			re-enable IRQ - SWI disables it
		ldx 10,s			get return address
		lda ,x+				get operation code
		stx 10,s			save new return address
		ldx #LC384			point to first SWI routine
		ldu #LC995			point to routine offset table
LC360		ldb ,u+				get length of previous routine
		abx				add to routine pointer
		deca				are we at the right routine?
		bpl LC360			brif not
		stx ,--s			save routine address
		ldd 3,s				restore D register
		ldx 6,s				restore X register
		ldu 10,s			restore U register
		jsr [,s++]			call the routine
		rti				return to caller
; SWI2 handler
LC371		clrb				; restore direct page for ROM call
		tfr b,dp			;
		ldu 10,s			get return address
		ldb ,u+				get ROM routine offset
		stu 10,s			save new return address
		ldu #ROMTAB			point to ROM vector table
		jsr [b,u]			call the ROM routine
		sta 1,s				; save return values
		stx 4,s				;
		rti				return to caller
; SWI 0 routine
LC384		lda V26E
		tst V275
		beq LC38E
		lda V26F
		clr V275
LC38E		clrb
		suba #7
		suba V28B
		bge LC39F
		decb
		cmpa #$f9
		ble LC39F
		ldx #LCB96
		ldb a,x
LC39F		stb lightlevel
		rts
; SWI 1 routine
;***********************************************************************************************************
; This routine renders a line graphic from the specification stored at (X).
;
; The data at (X) is a series of operations as follows:
;
; if (X) is < $FA, then the two bytes at (X) are an absolute Y and X coordinate. If V251 is clear, this is
; the first vertex in a polygon and the coordinates are simply recorded. Otherwise, a line is drawn from
; the previous coordinates to the new coordinates. These coordinates have the Y coordinate first.
;
; If (X) is >= $FA, it is a special operation defined as follows:
;
; FA: return from a "subroutine" to the previous flow
; FB: call a subroutine at the memory address in the next two bytes
; FC: draw a series of points using relative motion. The following byte is split into nibbles with the
;	upper nibble being the Y displacement and the lower nibble being the X displacement. These values
;	are signed and will be doubled when applied to the drawing. This gives a range of -32 to +30 in
;	steps of 2 for each direction. If both displacements are zero (a zero byte), this is the end of
;	the relative sequence. The end of one of these sequences is the end of a polygon.
; FD: like FB but doesn't record the previous location
; FE: flags the end of the input and causes a return to the caller. Do not use this in a subroutine as
;	the stack will have been used to record the return data location.
; FF: mark the next coordinates as the start of a new polygon.
;
; In all cases, the X and Y coordinates actually used have a scale factor applied to them based on the
; distance from the defined centre of the graphics area which is stored in (V205,V207). The horizontal
; scale factor is at V24F and the vertical scaling factor is at V250. A factor of 128 serves as a scale
; factor of 1. 192 would be 1.5 and 64 would be 0.5.
;
; Variables used:
;
; V205		the horizontal centre point for rendering graphics and scaling
; V207		the vertical centre point for rendering graphics and scaling
; lightlevel	the light level with respect to rendering the graphic
; V24F		the horizontal scaling factor (binary point to the right of bit 7)
; V250		the vertical scaling factor (binary point to the right of bit 7)
; V251		nonzero if this is not the first coordinate in a polygon
; V252		the most recent absolute unscaled X coordinate
; V254		the most recent absolute unscaled Y coordinate
LC3A2		clr V251			mark input as start of polygon
		lda lightlevel			fetch dungeon light level
		inca				is it $ff (dark)?
		beq LC3F6			brif so - skip rendering
LC3A9		ldb ,x				fetch input data
		subb #$fa			adjust for operation codes
		blo LC3CF			brif not operation code
		leax 1,x			move on to next image data byte
		ldy #LC3B9			point to jump table for operation codes
		ldb b,y				get offset to operation routine
		jmp b,y				execute operation routine
LC3B9		fcb LC3C9-LC3B9			(FA) return from a "subroutine"
		fcb LC3BF-LC3B9			(FB) call a "subroutine"
		fcb LC417-LC3B9			(FC) polygon
		fcb LC3C6-LC3B9			(FD) jump to a new "routine"
		fcb LC3F6-LC3B9			(FE) end of input - return to caller
		fcb LC3CB-LC3B9			(FF) next coordinates are start of new polygon
LC3BF		ldd ,x++			get address of "subroutine" to call
		stx ,--s			save return address
		tfr d,x				set new "execution" address
		skip2				skip next instruction
LC3C6		ldx ,x				get address of "routine" to jump to
		skip2				skip next instruction
LC3C9		ldx ,s++			get back saved input location
LC3CB		clr V251			reset polygon start flag to start
		bra LC3A9			go process more input
LC3CF		tst V251			is this the first coordinate in a polygon?
		bne LC3D9			brif not
		bsr LC3E2			fetch input coordinates and save them
		dec V251			flag as not first coordinate
		bra LC3A9			go process more input
LC3D9		bsr LC3E0			set up coordinates to draw a line
		jsr drawline			draw the line
		bra LC3A9			go process more input
LC3E0		bsr LC3F7			move last end coordinates to line start
LC3E2		ldb ,x+				get the next Y coordinate and move pointer forward
		stb V254			save unscaled Y coordinate
		bsr LC400			scale the Y coordinate
		addd V207			add in base Y coordinate
		std yend			save scaled end coordinate for line
		ldb ,x+				get the next X coordinate and move pointer forward
		stb V252			save unscaled X coordinate
		bsr LC406			scale the X coordinate
		addd V205			add in base X coordinate
		std xend			save scaled X coordinate for line
LC3F6		rts				return to caller
LC3F7		ldd yend			fetch last Y coordinate
		std ybeg			save as begining of new line segment
		ldd xend			fetch last X coordinate
		std xbeg			save as beginning of new line segment
		rts				return to caller
LC400		lda V250			get desired vertical scaling factor
		subb V208			find difference from Y base coordinate
		bra LC40A			go finish calculating scale
LC406		lda V24F			get desired horizontal scale factor
		subb V206			find difference from X base coordinate
LC40A		bcs LC40F			brif negative difference
		mul				apply the scaling factor
		bra LC414			normalize to an integer in D and return
LC40F		negb				make coordinate difference positive
		mul				apply the scaling factor
		jsr LCA99			negate coordinate value
LC414		jmp LD377			normalize to an integer in D and return
LC417		lda ,x+				get next byte in input
		beq LC3CB			brif NUL - end of values
		bsr LC3F7			move last end coordinate to start coordinate for line
		ldb -1,x			get the relative movement specifications
		asrb				; fetch high nibble signed extended into B
		asrb				;
		asrb				;
		asrb				;
		lslb				and multiply by two
		addb V254			add in previous Y coordinate
		stb V254			save new Y coordinate
		bsr LC400			go scale the Y coordinate
		addd V207			add in the Y base coordinate
		std yend			save new ending Y coordinate
		ldb -1,x			get back the input byte again
		andb #$0f			mask off the upper bits
		bitb #8				is bit 3 set?
		beq LC438			brif not
		orb #$f0			sign extend to 8 bits
LC438		lslb				multiply by two
		addb V252			add in saved X coordinate
		stb V252			save new X coordinate
		bsr LC406			go scale the X coordinate
		addd V205			add in base X coordinate
		std xend			save new ending X coordinate
		jsr drawline			go draw a line
		bra LC417			look for another line segment
; swi 2 routine
; fetch a packed string immediately following the call and display it
LC448		ldx 12,s			fetch return address - string address
		decodestrsb			go decode string
		stx 12,s			save new return address - after string
		ldx #stringbuf			point to decoded string
		skip2				skip the next instruction - nothing to display yet
LC452		renderchar			display character in A
; swi 3 routine
; display an unpacked string pointed to by X
LC454		lda ,x+				fetch byte from string
		bpl LC452			brif not end of string - display it
		rts				return to caller
; swi 4 routine
; display character in A
LC459		tst V2B7			are we looking for standard text mode?
		bne LC460			brif not
		ldu #V390			point to display state information
LC460		ldx 4,u				fetch current screen location
		jsr LC9B2			actually display the appropriate character
		cmpx 2,u			are we at the end of text area?
		blo LC46C			brif not
		jsr LC9D4			go scroll the text area
LC46C		stx 4,u				save new screen location
		rts				return to caller
; swi 5 routine - decode packed string at X to stringbuf
LC46F		ldu #stringbuf			point to output buffer
; swi 6 routine - decode a packed string at X to U
; the first value is the length of the string less one
LC472		leay -1,u			point to working data before buffer
		clr ,y				initialize value counter
		bsr LC48C			fetch a value
		tfr b,a				save length
LC47A		bsr LC48C			fetch a value
		stb ,u+				save in output
		deca				done yet?
		bpl LC47A			brif not
		sta ,u				flag end of string with $ff
		tst ,y				did we consume an even number of bytes?
		beq LC489			brif so
		leax 1,x			move pointer forward
LC489		stx 6,s				save pointer past end of input
		rts				return to caller
LC48C		pshs a,u			save registers
		lda ,y				get value counter
		ldu #LC4A2			point to value handlers
		lda a,u				get offset to handler for this value
		jsr a,u				call the handler for this value
		lda ,y				get value counter
		inca				bump it
		anda #7				wrap it around - the pattern repeats every 8 values
		sta ,y				save new value counter
		andb #$1f			values are only 5 bits - clear out extra bits
		puls a,u,pc			restore registers and return
LC4A2		fcb LC4AA-LC4A2			value 0 handler
		fcb LC4B0-LC4A2			value 1 handler
		fcb LC4B5-LC4A2			value 2 handler
		fcb LC4B9-LC4A2			value 3 handler
		fcb LC4BE-LC4A2			value 4 handler
		fcb LC4C3-LC4A2			value 5 handler
		fcb LC4C7-LC4A2			value 6 handler
		fcb LC4CC-LC4A2			value 7 handler
; value 0: upper 5 bits of current input byte
LC4AA		ldb ,x				fetch input byte
		lsrb				; align in low bits of B
LC4AD		lsrb				;
LC4AE		lsrb				;
		rts				return to caller
; value 1: lower 3 bits of current input byte and upper 2 bits of next one
; consumes a byte
LC4B0		ldd ,x+				fetch input data and consume a byte
		jmp LD379			; align in low bits of B
; value 2: bits 5...1 of current input byte
LC4B5		ldb ,x				fetch input byte
		bra LC4AE			align in low bits of B
; value 3: bits 0 of current byte and upper 4 bits of next one
; consumes a byte
LC4B9		ldd ,x+				fetch input data and consume a byte
		jmp LD37D			align in low bits of B
; value 4: low 4 bits of input byte and high bit of next one
; consumes a byte
LC4BE		ldd ,x+				fetch input data and consume a byte
		jmp LD377			align in low bits of B
; value 5: bits 6...2 of current input byte
LC4C3		ldb ,x				fetch input data
		bra LC4AD			align in low bits of B
; value 6: low two bits of current input byte and high 3 bits of next one
; consums a byte
LC4C7		ldd ,x+				fetch input data and consume a byte
		jmp LD37B			align in low bits of B
; value 7: low 5 bits of current input byte
; consumes a byte
LC4CC		ldb ,x+				fetch input data - already aligned
		rts				return to caller
; swi 7 routine
LC4CF		ldx #8
LC4D2		clrb
		ldy #8
		lda V26D
		anda #$e1
LC4DB		lsla
		bcc LC4DF
		incb
LC4DF		leay -1,y
		bne LC4DB
		lsrb
		rol V26B
		rol V26C
		rol V26D
		leax -1,x
		bne LC4D2
		lda V26B
		sta 3,s
		rts
; swi 8 routine - clear first graphics screen
LC4F3		ldu screenvis			point to first screen parameter block
		skip2				skip next instruction
; swi 9 routine - clear second graphics screen
LC4F6		ldu screendraw			point to second screen parameter block
		ldb levbgmask			get current level background colour
		bsr LC517			go clear the graphics area of the screen
		stu 10,s			save pointer to parameter block for the caller
		rts				return to caller
; swi 10 routine - clear the status line
LC4FF		ldx #V388			point to text area parameters for the status line
		ldu #LD87C			point to screen address table for the status line
		bra LC50D			go clear the status line
; swi 11 routine - clear the command entry area
LC507		ldx #V390			point to text area parameters for the command area
		ldu #LD888			point to screen address table for the command area
LC50D		clr 4,x				; set current cursor to start of text area
		clr 5,x				;
		ldb 6,x				get background colour of text area
		bsr LC517			go clear text area
		leau 6,u			and repeat the process for the other graphics screen
LC517		pshs a,b,x,y,u			save regsiters
		sex				get background colour to A
		tfr d,y				move it into Y too (4 bytes of background colour)
		leax ,u				point to start of parameter area
		ldu 2,u				get address of end of text area (+1)
LC520		pshu a,b,y			blast 4 background bytes to area
		cmpu ,x				are we at the start of the area?
		bne LC520			brif not
		puls a,b,x,y,u,pc		restore registers and return
; swi 12 routine
LC529		clr V2C1
		ldd powerlevel
		std V2C2
		lda #6
LC531		lsl V2C3
		rol V2C2
		rol V2C1
		deca
		bne LC531
		clr V2C4
		ldd damagelevel
		std V2C5
		lsl V2C6
		rol V2C5
		rol V2C4
		ldd powerlevel
		addd V2C5
		std V2C5
		ldb V2C4
		adcb #0
		stb V2C4
		clr V2C7
LC554		ldd V2C2
		subd V2C5
		std V2C2
		lda V2C1
		sbca V2C4
		sta V2C1
		inc V2C7
		bcc LC554
		lda V2C7
		suba #19
		sta V2AF
		tst V228
		bne LC595
		cmpa #3
		bgt LC5AE
		clearcommand
		lda V26E
		sta V270
LC578		dec V26F
		jsr [displayptr]		; update the main display area
		dec pageswap			; set graphics swap required
		sync				; wait for swap to happen
		dec V26E
		lda V26E
		cmpa #$f8
		bgt LC578
		cleargfx2
		dec pageswap			set graphics swap required
		dec V228
		clr keybufread			; reset keyboard buffer
		clr keybufwrite			;
		bra LC5AE
LC595		cmpa #4
		ble LC5AE
LC599		jsr [displayptr]		; update the main display area
		dec pageswap			; set graphics swap required
		sync				; wait for swap to happen
		inc V26F
		inc V26E
		lda V26E
		cmpa V270
		ble LC599
		clr V228
		showprompt
LC5AE		ldx powerlevel
		cmpx damagelevel
		blo LC5B5
		rts
; This routine handles player death
LC5B5		ldx #img_wizard			
		dec V29E
		fadeinclrst
		renderstrimmp
		fcb $ff,$c1,$92,$d0		"YET ANOTHER DOES NOT RETURN..."
		fcb $01,$73,$e8,$82
		fcb $c8,$04,$79,$66
		fcb $07,$3e,$80,$91
		fcb $69,$59,$3b,$de
		fcb $f0
		clr V228
		dec V277
LC5D7		bra LC5D7			wait forever (or until the IRQ does something)
; swi 13 routine
LC5D9		ldu #V388			; point to parameters for status line
		dec V2B7			; set to nonstandard text area
		lda levbgmask			; get current level background
		coma				; invert it for status line
		sta 6,u				; set up for displaying status line
		clra				; set position to start clearing (start of line)
		clrb
		bsr LC609			; clear half the line
		std 4,u				; save display position
		ldx lefthand			; fetch object in left hand
		bsr LC617			; get name of object
		renderstr			; display left hand object
		ldd #17				; set position to start clearing
		bsr LC609			; go clear half the line
		ldx righthand			; fetch object in right hand
		bsr LC617			; get name of object
		tfr x,y				; save start pointer
		ldd #$21			; set up offset for displaying right justified
LC5FD		decb				; move cursor point left
		tst ,y+				; end of string yet?
		bpl LC5FD			; brif not - keep moving left
		std 4,u				; save render position
		renderstr			; display the right hand object
		clr V2B7			; reset to standard text rendering
		rts
LC609		pshs a,b			; save registers
		std 4,u				; save the start position
		ldd #15				; set up for a space (code 0) 15 times
LC610		renderchar			; render a space
		decb				; done yet?
		bne LC610			; brif not
		puls a,b,pc			; restore registers and return
LC617		pshs a,b,y,u			; save registers
		leay ,x				; point to object data
		bne LC622			; brif there is object data
		ldx #LC650			; point to "EMPTY" string
		bra LC63C			; return result
LC622		ldu #wordbuff			; point to word buffer
		tst 11,y			; has it been revealed?
		bne LC632			; brif not
		lda 9,y				; fetch sub type
		ldx #kw_supreme			; point to first "adjective" keyword
		bsr LC63E			; copy correct string into buffer
		clr -1,u			; make a space after adjective
LC632		lda 10,y			; get base type
		ldx #kw_flask			; point to first base type keyword
		bsr LC63E			; copy correct string into buffer
		ldx #wordbuff			; point to start of string
LC63C		puls a,b,y,u,pc			; restore registers and return
LC63E		pshs a,x			; save registers
LC640		decodestrsb			; decode the current string into buffer
		deca				; are we there yet?
		bpl LC640			; brif not
		ldx #stringbuf+1		; point to actual string (past object type)
LC648		lda ,x+				; fetch character from decoded keyword
		sta ,u+				; save in output buffer
		bpl LC648			; brif not end of string yet
		puls a,x,pc			; restore registers and return
LC650		fcb $05,$0d,$10,$14,$19,$ff	; unpacked string "EMPTY"
; swi 14 routine
LC656		tst V228
		bne LC65F
		bsr LC660			; go update the display
		dec pageswap			; flag graphics swap required
		sync				; wait for swap to happen
LC65F		rts
LC660		pshs a,b,x,y,u
		ldd V226
		ldu curtorch			; is there a torch lit?
		beq LC66C			; brif not
		adda 7,u
		addb 8,u
LC66C		std V26E
		jsr [displayptr]		; update the main display area
		puls a,b,x,y,u,pc
; swi 15 routine
LC674		ldx #LC67A			point to newline followed by prompt
		renderstr			go display the newline and prompt
		rts				return to caller
LC67A		fcb $1f,$1e			unpacked string CR PERIOD UNDERSCORE BS (including following)
LC67C		fcb $1c,$24,$ff			unpacked string UNDERSCORE BS

; swi 16 routine
; delay for 81 ticks (1.3 seconds)
LC67F		ldb #$51			fetch delay tick count
LC681		sync				wait for a tick
		decb				are we done yet?
		bne LC681			brif not
		rts
; these two routine clear an area to 0 (black) or $ff (white) starting at X and
; ending at U
; swi 17 routine
LC686		clra				set area to $00 (clear to black)
		skip2				skip next byte
; swi 18 routine
LC688		lda #$ff			set area to $FF (clear to white)
LC68A		sta ,x+				clear a byte
		cmpx 10,s			are we done yet?
		bne LC68A			brif not
		rts				return to caller
; This looks like a leftover from earlier development which had the
; rom calls as a SWI call instead of using SWI2. This routine cannot
; be reached through the SWI mechanism and it cannot be called directly
LC691		clrb				; reset direct page for ROM call
		tfr b,dp			;
		ldu 12,s			fetch return address
		ldb ,u+				fetch rom call wanted
		stu 12,s			save new return address
		ldu #ROMTAB			point to ROM vector table
		jsr [b,u]			call the routine
		sta 3,s				; save return values
		stx 6,s				;
		rts
; swi 19 routine
; fade in the image specified by (X) with sound effects, clear status line and command area
LC6A4		clr V2B1
		clearstatus			clear the status area
; swi 20 routine
; fade in the image specified by (X) with sound effects, clear command area
LC6A8		clearcommand			clear the command area
		ldd #$8080			; set X and Y scale values to 1.0
		std V24F			;
		ldb V29E
		beq LC6B7
		ldb #$20			set apparent lighting to 32 (less apparent)
		dec V29C
LC6B7		bsr LC6D7			go draw the image
		decb				; reduce lighting count - make more apparent
		decb				;
		bpl LC6B7			brif not done 16 steps
		clr V29C
		clr V29E
LC6C1		playsoundimm $16
		rts				return to caller
; swi 21 routine
; fade out the image specified by (X) with sound effects, clear command area
LC6C5		clearcommand			clear the command entry area
		bsr LC6C1
		clrb				set apparent illumination to fully lit			
		dec V29C
LC6CC		bsr LC6D7			go draw the image
		incb				; bump lighting count (make less apparent)
		incb				;
		cmpb #$20			have we done 16 steps?
		bne LC6CC			brif not
		clr V29C
		rts				return to caller
LC6D7		pshs x,u			save registers
		stb lightlevel			set illumination value for graphic rendering
		stb V29D
		cleargfx2			clear second graphics screen
		drawgraphic			go draw graphic
		dec pageswap			flag graphics swap required
		sync				wait for swap to happen
		puls x,u,pc			restore registers and return
; swi 22 routine - display the PREPARE! screen
LC6E6		jsr LD489			clear second graphics screen and set up for text mode
		ldd #$12c			; set cursor position to the middle of the screen
		std 4,u				;
		renderstrimmp			display the PREPARE! message
		fcb $3c,$24,$58,$06		packed string "PREPARE!"
		fcb $45,$d8
		clr V2B7			reset to standard text rendering
		dec pageswap			set graphic swap required
		rts				return to caller
; swi 23 routine
LC6FB		ldu objectfree			; fetch free point in object table
		stu 6,s				; save pointer for return
		leax 14,u			; move to next entry in table
		stx objectfree			; save as new free point in object table
		sta 9,u				; set object type to requested type
		stb 4,u
		setobjectspecs			; set up object specs from data tables
		ldb 10,u			; fetch object general type
		ldx #LC719			; point to modifier table
		lda b,x				; get modified type entry
		bmi LC718			; brif no modification
		ldb 11,u			; get reveal strength of original object type
		setobjectspecs			; set up object data from replacement type
		stb 11,u			; restore reveal strength
LC718		rts
LC719		fcb $ff				; flasks do not get a replacment
		fcb $ff				; rings do not get a replacement
		fcb $ff				; scrolls do not get a replacement
		fcb $10				; shields default to leather shield specs
		fcb $11				; swords default to wooden sword specs
		fcb $0f				; torches default to pine torch specs
; swi 24 routine
LC71F		lsla				; four bytes per object specs entry
		lsla
		ldx #objspecs			; point to object data table
		leay a,x			; point to correct entry in table
		leax 10,u			; point to location in data table
		lda #4				; four bytes to copy
		jsr LC04B			; copy data into new object
		ldx #objextraspecs-4		; point to extra object data
LC730		leax 4,x			; move to next entry
		lda ,x				; is it end of table?
		bmi LC742			; brif so
		cmpa 3,s			; is this entry for the object type we're creating?
		bne LC730			; brif not - try another
		ldd 1,x				; copy the ring charges and defensive values
		std 6,u
		lda 3,x
		sta 8,u
LC742		rts				; return to caller
; swi 25 routine
LC743		clearstatus
		clearcommand
		dod S0C
		inc V2AE
		dec V2AD
		dec V2B1
		updatestatus
cmd_look	ldx #LCE66
		stx displayptr
		dod S0E
		rts
; swi 26 routine
LC759		sta V281
		ldb #12
		mul
		addd #V398
		std V282
		ldb V281
		ldx #LCFFD
LC768		stx V286
LC76A		lda ,x+
		bpl LC76A
		decb
		bpl LC768
		ldx #V3D4			get start address to clear
		ldu #mazedata			get end address to clear
		clearblock			go clear area to zeros
		jsr LC053
		jsr LCC9C
		ldu V282
		lda #11
LC783		ldb a,u
		beq LC78D
LC787		jsr LCFA5
		decb
		bne LC787
LC78D		deca
		bpl LC783
		ldu #V3C3
		clr V291
LC795		jsr LCF63
		beq LC7B6
		tst 5,x
		bpl LC795
LC79E		leau 17,u
		cmpu #mazedata
		blo LC7AA
		ldu #V3D4
LC7AA		tst 12,u
		beq LC79E
		ldd 8,u
		stx 8,u
		std ,x
		bra LC795
LC7B6		lda V281
		anda #1
		nega
		sta levbgmask
		sta V396
		sta V386
		coma
		sta V38E
		rts
; swi 27 routine
; play a sound specified by the immediate identifier
LC7C8		ldx 12,s			fetch return address
		lda ,x+				fetch immediate data
		stx 12,s			update return address
		ldb #$ff			set to maximum volume
; swi 28 routine
; play a sound specified by the value in A
LC7D0		stb soundvol			set the volume for the sound playing routine
		ldx #LC7DC			point to sound routine jump table
		lsla				two bytes per jump table entry
		jsr [a,x]			call the sound generator routine
		clr PIA1			turn off sound output
		rts				return to caller
; the jump table for sound routines
LC7DC		fdb LC82B			sound 0
		fdb LC850			sound 1
		fdb LC951			sound 2
		fdb LC83C			sound 3
		fdb LC8E2			sound 4
		fdb LC955			sound 5
		fdb LC84A			sound 6
		fdb LC8DE			sound 7
		fdb LC84D			sound 8
		fdb LC959			sound 9
		fdb LC877			sound 10
		fdb LC877			sound 11
		fdb LC80A			sound 12 - flask sound
		fdb LC811			sound 13 - ring sound
		fdb LC827			sound 14 - scroll sound
		fdb LC8DA			sound 15 - shield sound
		fdb LC8A6			sound 16 - sword sound
		fdb LC8B2			sound 17 - torch sound
		fdb LC93F			sound 18 - attack hit
		fdb LC8E6			sound 19
		fdb LC872			sound 20
		fdb LC86D			sound 21
		fdb LC88A			sound 22 - wizard
; sound 12
LC80A		ldu #LC823			point to 144Hz base tone
		lda #4				repeat sound 4 times
		bra LC816			go do the sound
; sound 13
LC811		ldu #LC81F			point to 288Hz base tone
		lda #10				repeat sound 10 times
LC816		sta V25F			set repeat counter
LC818		jsr ,u				make a sound
		dec V25F			have we done enough of them?
		bne LC818			brif not
		rts
; These routines produce a "sliding" tone starting at the base frequency. The specified base
; frequency is a rough estimate. The tones are created using square waves. After each full wave,
; the delay in reduced by one which increases the frequency. The last cycle is with the delay
; equal to 1 which yields an approximate frequency of 9520Hz.
LC81F		ldx #$40			set low frequency of sliding tone to ~288Hz
		fcb $10
LC823		ldx #$80			set low frequency of sliding tone to ~144Hz
		fcb $10
; sound 14
LC827		ldx #$100			set low frequency of sliding tone to ~72Hz
		fcb $10
; sound 0
LC82B		ldx #$20			set low frequency of sliding tone to ~566Hz
LC82E		bsr LC835			do one square wave
		leax -1,x			reduce delay (increase frequency)
		bne LC82E			brif not yet reached maximum frequency
		rts
; Output a square wave with wave time defined by delay in X
LC835		lda #$ff			(2~) hold DAC high for delay in X
		bsr LC869			(7~)
		clra				(2~) hold DAC low for delay in X
		bra LC869			(3~)
; sound 3
; Output a series of 16 ascending tones with a base frequency descending from 14.5Hz to 9Hz.
LC83C		ldx #$500			set for an ascending tone from 14.5Hz
LC83F		bsr LC835			go make the sound
		leax $30,x			decrease starting tone frequency by a bit
		cmpx #$800			have we reached 9Hz?
		blo LC83F			brif not
		rts
; sound 6
LC84A		lda #2
		skip2
; sound 8
LC84D		lda #1
		skip2
; sound 1
LC850		lda #10
		sta V262
LC854		ldy #$c0
LC858		bsr LC8CE
		bsr LC8C5
		leay -1,y
		bne LC858
		bsr LC8BA
		dec V262
		bne LC854
		rts
LC867		bsr LC8CE
LC869		bsr LC8C5			(7~) program the DAC
		bra LC8BD			(3~) count down delay non-destructively
; sound 21
LC86D		ldu #LDBDA
		bra LC893
; sound 20
LC872		ldu #LDBD2
		bra LC893
; sound 10, sound 11
LC877		lda #8
		sta V25F
LC87B		bsr LC8CE
		clra
		lsrb
		bne LC882
		incb
LC882		tfr d,x
		bsr LC82E
		dec V25F
		bne LC87B
; sound 22
LC88A		ldu #LDBD2
		bsr LC893
		bsr LC8BA
		leau 4,u
LC893		ldx ,u
LC895		ldy 2,u
LC898		bsr LC867
		leay -1,y
		bne LC898
		leax 2,x
		cmpx #$150
		bne LC895
		rts
; sound 16
LC8A6		jsr LC931
		fcb $80
LC8AA		bsr LC922
		bcs LC8B2
		bsr LC8C5
		bra LC8AA
; sound 17
LC8B2		jsr LC92E
		fcb $a0
LC8B6		bsr LC926
		bra LC8B6
LC8BA		ldx #$1000
LC8BD		pshs x				(7~) save delay counter
LC8BF		leax -1,x			(5~) has timer expired?
		bne LC8BF			(3~) brif not
LC8C3		puls x,pc			(9~) restore delay counter and return
LC8C5		ldb soundvol			(5~) fetch volume multiplier for sound
		mul				(11~) multiply it by the value we're trying to set
		anda #$fc			(2~) lose the non-DAC bits
		sta PIA1			(5~) set DAC
		rts				(5~)
LC8CE		ldd V256
		lslb
		rola
		lslb
		rola
		addd V256
		incb
		std V256
		rts
; sound 15
LC8DA		bsr LC915
		fdb $6424
; sound 7
LC8DE		bsr LC915
		fdb $3212
; sound 4
LC8E2		bsr LC915
		fdb $AF36
; sound 19
LC8E6		bsr LC915
		fdb $1909
LC8EA		bsr LC92E
		fcb $60
LC8ED		ldx V263
		ldy V265
		clra
LC8F3		leax -1,x
		bne LC8FD
		ldx V263
		eora #$7f
		bsr LC90A
LC8FD		leay -1,y
		bne LC8F3
		ldy V265
		eora #$80
		bsr LC90A
		bra LC8F3
LC90A		sta V259
		bsr LC97E
		bls LC8C3			skip the caller to this routine and return to its caller
		bsr LC8C5
		lda V259
		rts
; this routine doesn't return to the caller but to the caller's caller
LC915		ldx ,s++
		ldb ,x+
		clra
		std V263
		ldb ,x+
		std V265
		bra LC8EA
LC922		bsr LC8CE
		bra LC98D
LC926		bsr LC8CE
LC928		bsr LC97E
		bls LC8C3			skip the caller to this routine and return to its caller
		bra LC8C5
LC92E		ldx allones
		fcb $10
LC931		ldx zero
LC933		stx V25B
		ldx ,s
		ldb ,x+
		clra
		std V25D
		stx ,s
		rts
; sound 18
LC93F		bsr LC92E
		fcb $60
LC942		jsr LC8CE
		lsra
		bsr LC928
		jsr LC8CE
		ora #$80
		bsr LC928
		bra LC942
; sound 2
LC951		ldx #$300
		fcb $10
; sound 5
LC955		ldx #$200
		fcb $10
; sound 9
LC959		ldx #$100
		stx V25D
		clra
		clrb
		std V25B
LC962		bsr LC922
		bcs LC971
		jsr LC8C5
		ldx #$f0
		jsr LC8BD
		bra LC962
LC971		bsr LC92E
		fcb $40
LC974		bsr LC926
		ldx #$60
		jsr LC8BD
		bra LC974
LC97E		pshs a
		ldd V25B
		subd V25D
LC984		pshs cc
		std V25B
		ldb 1,s
		mul
		puls cc,b,pc
LC98D		pshs a
		ldd V25B
		addd V25D
		bra LC984
; this is the swi routine offset table - each byte is the difference between the entry point
; of the previous routine and itself
LC995		fcb 0				first routine has nothing before it
		fcb LC3A2-LC384
		fcb LC448-LC3A2
		fcb LC454-LC448
		fcb LC459-LC454
		fcb LC46F-LC459
		fcb LC472-LC46F
		fcb LC4CF-LC472
		fcb LC4F3-LC4CF
		fcb LC4F6-LC4F3
		fcb LC4FF-LC4F6
		fcb LC507-LC4FF
		fcb LC529-LC507
		fcb LC5D9-LC529
		fcb LC656-LC5D9
		fcb LC674-LC656
		fcb LC67F-LC674
		fcb LC686-LC67F
		fcb LC688-LC686
		fcb LC6A4-LC688
		fcb LC6A8-LC6A4
		fcb LC6C5-LC6A8
		fcb LC6E6-LC6C5
		fcb LC6FB-LC6E6
		fcb LC71F-LC6FB
		fcb LC743-LC71F
		fcb LC759-LC743
		fcb LC7C8-LC759
		fcb LC7D0-LC7C8
;***********************************************************************************************************
; The following code handles displaying text on the screen. It works as follows.
;
; The graphics screen is divided into a grid of character cells 32 columns wide by 24 rows high. Each cell
; is 8 pixels wide by 8 pixels high. Text can be rendered anywhere on the screen as long as it fits within
; a character cell. The cells line up on even bytes which makes actually rendering the characters fast.
;
; Characters are encoded in 5 bits as follows: A through Z are given codes 1 through 26. 0 is a space. 27
; is the exclamation point, 28 is the underscore, 29 is the question mark, and 30 is the period. Code 31
; is used as a carriage return. Codes 32 and 33 are the left and right parts of the contracted heart symbol
; while 34 and 35 are the left and right parts of the expanded heart symbol. 36 is backspace.
;
; Glyphs for codes 0 through 30 are encoded using the packed five bit encoding and are located at LDB1B. They
; are encoded in a 5 by 7 bitmap which is shifted to be offset one pixel from the left of the character cell
; upon decoding.
;
; The glyphs for the heart codes are in unpacked encoding and are located at LDBB6 and occupy the entire
; 8 bit width of the character cell.
;
; These routines expect a pointer to the text configuration parameters in U. At offset 0 is the start address
; of the scrollable area of the screen (memory address). At offset 2 is the ending character cell address of
; the scrollable area of the screen. At offset 4 is the current printing position. At offset 6 is a mask with
; all pixels set to the background colour. At offset 7 a flag which when nonzero inhibits rendering text to
; the secondary graphics screen area. For the ordinary command entry area at the bottom of the screen, this
; will point to V390.
LC9B2		cmpa #$24			is it backspace?	
		beq LC9BF			brif so
		cmpa #$1f			vertical spacer?
		beq LC9CA			brif so
		bsr LCA17			go handle a glyph
		leax 1,x			move to next character position
		rts				return to caller
LC9BF		leax -1,x			move display pointer back one
		cmpx allones			did we wrap around negative?			
		bne LC9C9			brif not
		ldx 2,u				get end of text area
		leax -1,x			move back one position to be in the text area
LC9C9		rts				return to caller
LC9CA		leax $20,x			move pointer forward one character row
		exg d,x				move pointer so we can do math
		andb #$e0			force pointer to the start of the line
		exg d,x				put pointer back where it belongs
		rts				return to caller
LC9D4		pshs a,b,x,y			save registers
		ldx ,u				get start of screen address
		ldd 2,u				get end of text area
		subd #$20			knock one character row off it
		std 2,s				save new display location
		bsr LCA10			multiply by 8 - 8 pixel rows per cell
		tfr d,y				save counter
LC9E3		ldd $100,x			get bytes 8 pixel rows ahead
		tst 7,u				do we need to skip the second screen?
		bne LC9EF			brif so
		std $1800,x			save scroll data on second screen
LC9EF		std ,x++			save scroll data and move pointer ahead
		leay -2,y			are we done yet?
		bne LC9E3			brif not
		ldb 6,u				fetch current background colour
		sex				and make A match
		ldy #$100			number of bytes to blank bottom row
LC9FC		tst 7,u				are we doing second screen too?
		bne LCA04			brif not
		std $1800,x			blank pixels in second screen
LCA04		std ,x++			blank pixels and move pointer forward
		leay -2,y			are we done yet?
		bne LC9FC			brif not
		puls a,b,x,y,pc			restore registers and return
LCA0C		lslb				; enter here to shift D left 5 bits
		rola				;
		lslb				;
		rola				;
LCA10		lslb				; enter here to shift D left 3 bits
		rola				;
LCA12		lslb				; enter here to shift D left 2 bits
		rola				;
		lslb				;
		rola				;
		rts
LCA17		pshs a,b,x,y,u			save registers
		cmpa #$20			is it a printing character?
		blo LCA29			brif so
		suba #$20			mask off printing characters
		ldb #7				7 bytes per font table entry
		mul				get offset in table
		addd #LDBB6			add in base address of table
		tfr d,x				put font pointer somewhere useful
		bra LCA44			go draw glyph
LCA29		ldb #5				5 bytes per font table entry
		mul				get offset in table
		addd #LDB1B			add in base address of table
		tfr d,x				put pointer somewhere useful
		ldu #fontbuf			point to buffer to decode glyph data
		decodestr			go decode a packed string
		ldx #fontbuf+7			point one past end of buffer
LCA39		lsl ,-x				; centre glyph data in byte
		lsl ,x				;
		cmpx #fontbuf			at start of buffer?
		bhi LCA39			brif not - keep centring
		ldu 6,s				get back U value
LCA44		ldd 4,u				get display address location
		bsr LCA10			multiply by 8 - gets start of row in 11..8
		lsrb				; and divide lsb by 8 again to get offset within
		lsrb				; the row to bits 4..0
		lsrb				; and force to top of character cell
		addd ,u				add in start of text area
		tfr d,y				put pointer somewhere useful
		ldb #7				seven bytes to copy
LCA51		lda ,x+				get byte from font data
		eora 6,u			merge with background colour
		sta ,y				save it on the screen
		tst 7,u				do we need to update second screen?
		bne LCA5F			brif not
		sta $1800,y			save pixels on second screen
LCA5F		leay $20,y			move display pointer down one pixel row
		decb				are we done yet?
		bne LCA51			brif not - do another
		puls a,b,x,y,u,pc		restore registers and return
; This routine divides a 16 bit unsigned value in D by a 16 bit unsigned value in X. The result
; will be in D with the binary point to the right of A.
LCA67		pshs a,b,x			make hole for result and save divisor
		clr ,s				; initialize quotient
		clr 1,s				;
		clr V2C1			use V2C1 for extra precision on dividend
		std V2C2			save dividend
		beq LCA97			brif dividend is zero - nothing to do
		cmpd 2,s			is dividend equal to divisor?
		bne LCA7C			brif not
		inc ,s				set quotient to 1.0
		bra LCA97			go return
LCA7C		ldx #16				we need to do 16 iterations
LCA7F		lsl V2C3			; shift dividend
		rol V2C2			;
		rol V2C1			;
		lsl 1,s				= shift quotient
		rol ,s				=
		ldd V2C1			get dividend high word
		subd 2,s			subtract out divisor
		bcs LCA93			brif it doesn't go
		std V2C1			save new dividend residue
		inc 1,s				record the fact that it went
LCA93		leax -1,x			have we done all 16 bits?
		bne LCA7F			brif not
LCA97		puls a,b,x,pc			fetch result, restore registers, and return
LCA99		coma				; do a one's complement of D
		comb				;
		addd #1				adding 1 turns it into negation
		rts				return to caller
LCA9F		pshs a,b,x			save registers
		ldx pixelcount			get number of pixels to draw
		ldd ,s				get the difference
		bpl LCAAE			brif positive
		bsr LCA99			negate difference
		bsr LCA67			divide by number of pixels
		bsr LCA99			negate the result
		skip2				skip next instruction
LCAAE		bsr LCA67			divide by number of pixels
		std ,s				save step value
		puls a,b,x,pc			restore registers and return
LCAB4		jmp LCB8A			go return from the line drawing routine
; Draw a line from (xbeg,ybeg) to (xend,yend) respecting the light level in the dungeon (lightlevel)
; which is used as a step count between when to actually draw pixels.
;
; Variables used:
; lightlevel	the current light level in the dungeon
; lightcount	how many pixels left before we actually draw another
; ybeg		input start Y
; xbeg		input start X
; yend		input end Y
; xend		input end X
; xcur		X coordinate of pixel to be drawn (24 bits with 8 bits after binary point)
; ycur		U cpprdomate of pixel to be drawn (24 bits with 8 bits after binary point)
; xpstep	24 bit X coordinate difference (per pixel)
; ypstep	24 bit Y coordinate difference (per pixel)
; pixelcount	number of pixels to draw in the line
; xbstep	the offset for when X coordinate goes to a new byte
; xystep	the offset for when Y coordinate goes to a new line
; drawstart	the start address of the graphics screen area the line is within
; drawend	the end address of the graphics screen area the line is within
; V2C1		a temporary scratch variable
;
; Note: ypstep+1 and xpstep+1 are also used as temporary holding values for the
; integer difference in the Y and X coordinates respectively.
drawline	pshs a,b,x,y,u			save registers
		inc lightlevel			are we completely dark?
		beq LCAB4			brif so - we can short circuit drawing entirely
		lda lightlevel			get light level in dungeon
		sta lightcount			save in working count (skip count for pixel drawing)
		ldd xend			get end X coordinate
		subd xbeg			subtract start X coordinate
		std xpstep+1			save coordinate difference
		bpl LCACB			brif positive difference
		bsr LCA99			negate the difference
LCACB		std pixelcount			save absolute value of X difference as pixel count
		ldd yend			get end Y coordinate
		subd ybeg			subtract start Y coordinate
		std ypstep+1			save coordinate difference
		bpl LCAD7			brif positive difference
		bsr LCA99			negate the difference
LCAD7		cmpd pixelcount			is the Y difference bigger than X?
		blt LCAE0			brif not
		std pixelcount			save Y difference as pixel count
		beq LCAB4			brif no pixels to draw - short circuit
LCAE0		ldd xpstep+1			get X difference
		bsr LCA9F			calculate X stepping value
		std xpstep+1			save X stepping value
		tfr a,b				save msb of difference
		sex				sign extend it
		ldb #1				X stepping value - 1 for ascending
		sta xpstep			sign extend stepping difference to 24 bits
		bpl LCAF0			brif positive
		negb				set stepping value to -1
LCAF0		stb xbstep			save X byte stepping value
		ldd ypstep+1			get Y difference
		bsr LCA9F			calculate Y step value
		std ypstep+1			save result
		tfr a,b				save msb of difference
		sex				sign extend it
		ldb #$20			Y byte stepping value - 32 bytes per line, ascending
		sta ypstep			sign extend the difference to 24 bits
		bpl LCB02			brif positive
		negb				negate the difference - -32 bytes per line, descending
LCB02		stb xystep			save Y byte stepping value
		ldd xbeg			get start X coordinate
		std xcur			save in X coordinate counter
		ldd ybeg			get start Y coordinate
		std ycur			save in Y coordinate counter
		lda #$80			value for low 8 bits to make the values ".5"
		sta xcur+2			set X coordinate to ".5"
		sta ycur+2			set Y coordinate to ".5"
		ldx 2,u				get end of graphics area address
		stx drawend			save it for later
		ldx ,u				get start of graphics area address
		stx drawstart			save it for later
		ldd ycur			get Y coordinate for pixel
		jsr LCA0C			shift left 5 bits - 32 bytes per row
		leax d,x			add to screen start address
		ldd xcur			get X coordinate for pixel
		jsr LD37F			shift right 3 bits - 8 pixels per byte
		leax d,x			add to row start address
		ldu #LCB8E			point to table of pixel masks
		ldy pixelcount			get number of pixels to draw
LCB2E		dec lightcount			are we ready to draw another pixel (due to light level)?
		bne LCB54			brif not
		lda lightlevel			get light level
		sta lightcount			reset current "pixel delay"
		tst xcur			is X coordinate off the right of the screen?
		bne LCB54			brif so
		cmpx drawstart			is the pixel address before the start of the graphics area?
		blo LCB54			brif so
		cmpx drawend			is the pixel address after the end of the graphics area?
		bhs LCB54			brif so
		ldb xcur+1			get X coordinate lsb
		andb #7				mask off low 3 bits for offset in byte
		lda b,u				get pixel mask to use
		tst levbgmask			currently using black background?
		beq LCB50			brif so
		coma				invert mask for white background
		anda ,x				merge in existing graphics data
		skip2				skip next instruction
LCB50		ora ,x				merge in existing graphics data (black background)
		sta ,x				save new graphics data on the screen
LCB54		lda xcur+1			get X coordinate lsb
		anda #$f8			mask off the pixel offset in the byte
		sta V2C1			save it for later
		ldd xcur+1			get X coordinate low bits
		addd xpstep+1			add in X difference
		std xcur+1			save new low bits for X coordinate
		ldb xcur			get X coordinate high bits
		adcb xpstep			add in difference high bits
		stb xcur			save new X coordinate high bits
		anda #$f8			mask off pixel offset in data byte
		cmpa V2C1			are we in the same byte?
		beq LCB70			brif so
		ldb xbstep			get byte X step value 
		leax b,x			move pointer appropriately
LCB70		ldd ycur+1			get Y coord low bits
		sta V2C1			save screen Y coordinate
		addd ypstep+1			add in Y step value low bits
		std ycur+1			save new low bits
		ldb ycur			get Y coord high bits
		adcb ypstep			add in Y step value high bits
		stb ycur			save new Y coord high bits
		cmpa V2C1			are we on the same scren row?
		beq LCB86			brif so
		ldb xystep			get Y byte step value
		leax b,x			move pointer appropriately
LCB86		leay -1,y			have we drawn all the pixels?
		bne LCB2E			brif not - draw another
LCB8A		dec lightlevel			compensate for "inc" above
		puls a,b,x,y,u,pc		restore registers and return
LCB8E		fcb $80,$40,$20,$10		pixels 0, 1, 2, 3 (left to right) in byte
		fcb $08,$04,$02,$01		pixels 4, 5, 6, 7 (left to right) in byte
LCB96		pshs a,x,u			; save registers
		ldx V211			; get input buffer/line pointer
		ldu #wordbuff			; point to word buffer
LCB9D		lda ,x+				; get character from input
		beq LCB9D			; brif end of line
		bra LCBA5			; get on with things
LCBA3		lda ,x+				; get new character from input
LCBA5		ble LCBAF			; brif not valid character
		sta ,u+				; save filename character
		cmpu #V333			; are we at the end of the buffer?
		blo LCBA3			; brif not - check another
LCBAF		lda #$ff			; put end of word marker
		sta ,u+
		stx V211			; save new input pointer location
		tst wordbuff			; set flags for whether we have a word
		puls a,x,u,pc			; restore registers and return
LCBBA		clr V290
		ldx #kwlist_obj
		bsr LCBEC
		bmi LCBC8
		beq LCBDF
		std V28E
		rts
LCBC8		dec V290
		ldx #kwlist_adj
		bsr LCBE7
		ble LCBDF
		std V28E
		ldx #kwlist_obj
		bsr LCBEC
		ble LCBDF
		cmpb V28F
		bne LCBDF
		rts
LCBDF		leas 2,s			; don't return to caller - we're bailing out
LCBE1		renderstrimmp			; display "???" for unknown command
		fcb $17,$7b,$d0			; packed "???" string
		rts				; return to caller's caller
LCBE7		pshs a,b,x,y,u
		clra
		bra LCBF4
LCBEC		pshs a,b,x,y,u			; save registers
		clra
		clrb
		bsr LCB96			; parse a word from the input line
		bmi LCC2D			; brif no word present
LCBF4		clr V278			; flag no match
		clr V27B			; 
		ldb ,x+				; fetch number of keywords in list
		stb V279			; save it in temp counter
LCBFC		ldu #wordbuff			; point to decode buffer
		decodestrsb			; decode the keyword string
		ldy #stringbuf+1		; point to decoded keyword string (past the object code)
LCC05		ldb ,u+				; get a character from word string
		bmi LCC17			; brif end of string
		cmpb ,y+			; does it match?
		bne LCC22			; brif not
		tst ,y				; are we at the end of the keyword?
		bpl LCC05			; brif not
		tst ,u				; are we at the end of the word?
		bpl LCC22			; brif not
LCC15		dec V27B
LCC17		tst V278			; do we already have a match?
		bne LCC2B			; brif so
		inc V278			; mark match found
		ldb stringbuf			; get the keyword code
		std ,s				; save keyword number and object code
LCC22		inca				; bump keyword count
		dec V279			; have we reached the end of the list?
		bne LCBFC			; brif not - check another keyword
		tst V278			; do we have a match?
		bne LCC2F			; brif so
LCC2B		ldd allones			; flag error (-1)
LCC2D		std ,s				; save result
LCC2F		puls a,b,x,y,u,pc		; restore registers and return value, return
LCC31		ldx #kwlist_dir			; point to direction keywords
		bsr LCBEC			; evaluate the specified keyword
		ble LCBDF			; brif no matching keyword
		ldu #righthand			; point to right hand contents
		cmpa #1				; is it right hand wanted?
		beq LCC46			; brif so - return pointer
		ldu #lefthand			; point to left hand contents
		cmpa #0				; is it left hand wanted?
		bne LCBDF			; brif not - error
LCC46		ldx ,u				; fetch object pointer to X (and set Z if nothing)
		rts
LCC49		pshs a,b,x,u
		deca
		bsr LCC56
		inca
		bsr LCC56
		inca
		bsr LCC56
		puls a,b,x,u,pc
LCC56		pshs a,b
		decb
		bsr LCC60
		incb
		bsr LCC60
		incb
		skip2
LCC60		pshs a,b
		bsr LCC8E
		bne LCC6B
		bsr LCC7B
		lda ,x
		skip2
LCC6B		lda #$ff
		sta ,u+
		puls a,b,pc
LCC71		dod S07
		anda #$1f
		tfr a,b
		dod S07
		anda #$1f
LCC7B		pshs a,b
		anda #$1f
		andb #$1f
		tfr d,x
		ldb #$20
		mul
		addd #mazedata
		exg d,x
		abx
		puls a,b,pc
LCC8E		pshs a,b
		anda #$1f
		cmpa ,s
		bne LCC9A
		andb #$1f
		cmpb 1,s
LCC9A		puls a,b,pc
LCC9C		ldx #mazedata			get start address to set to $ff
		ldu #V9F4			get end address
		setblock			go set block to $ff
		ldx #LCD9F
		ldb V281
		abx
		ldd ,x++
		std V26B
		lda ,x
		sta V26D
		ldy #V1F4
		jsr LCC71
		std V27C
LCCBB		dod S07
		anda #3
		sta V28A
		dod S07
		anda #7
		inca
		sta V27E
		bra LCCD2
LCCCA		ldd V288
		std V27C
		dec V27E
		beq LCCBB
LCCD2		ldd V27C
		jsr LD11B
		bsr LCC8E
		bne LCCBB
		std V288
		tst ,x
		beq LCCCA
		ldu #V9F4
		jsr LCC49
		lda 3,u
		adda ,u
		adda 1,u
		beq LCCBB
		lda 1,u
		adda 2,u
		adda 5,u
		beq LCCBB
		lda 5,u
		adda 8,u
		adda 7,u
		beq LCCBB
		lda 7,u
		adda 6,u
		adda 3,u
		beq LCCBB
		clr ,x
		leay -1,y
		bne LCCCA
		clr V27C
		clr V27D
LCD11		ldd V27C
		jsr LCC7B
		lda ,x
		inca
		beq LCD41
		ldd V27C
		ldu #V9F4
		jsr LCC49
		lda ,x
		ldb #$ff
		cmpb 1,u
		bne LCD2D
		ora #3
LCD2D		cmpb 3,u
		bne LCD33
		ora #$c0
LCD33		cmpb 5,u
		bne LCD39
		ora #$0c
LCD39		cmpb 7,u
		bne LCD3F
		ora #$30
LCD3F		sta ,x
LCD41		ldb #$20
		inc V27D
		cmpb V27D
		bne LCD11
		clr V27D
		inc V27C
		cmpb V27C
		bne LCD11
		ldb #$46
		ldu #LCDAA
LC056		bsr LCD6D
		decb
		bne LC056
		ldb #$2d
		ldu #LCDAE
LCD60		bsr LCD6D
		decb
		bne LCD60
		ldb V297
LCD67		dod S07
		decb
		bne LCD67
		rts
LCD6D		pshs a,b,x,y,u
		ldy #LCDA6
LCD73		jsr LCC71
		std V288
		ldb ,x
		cmpb #$ff
		beq LCD73
		dod S07
		anda #3
		sta V28A
		bitb a,y
		bne LCD73
		orb a,u
		stb ,x
		ldd V288
		jsr LD11B
		ldb V28A
		addb #2
		andb #3
		lda ,x
		ora b,u
		sta ,x
		puls a,b,x,y,u,pc
LCD9F		fcb $73,$c7,$5d,$97
		fcb $f3,$13,$87
LCDA6		fcb $03,$0c,$30,$c0
LCDAA		fcb $01,$04,$10,$40
LCDAE		fcb $02,$08,$20,$80
LCDB2		ldu screendraw
		ldd #$1f1f
		std V27C
LCDB9		ldd V27C
		bsr LCE11
		jsr LCC7B
		clrb
		lda ,x
		inca
		bne LCDC7
		decb
LCDC7		lda #6
LCDC9		stb ,y
		leay $20,y
		deca
		bne LCDC9
		dec V27D
		bpl LCDB9
		lda #$1f
		sta V27D
		dec V27C
		bpl LCDB9
		tst V294
		beq LCE2B
		clr V291
LCDE3		jsr LCF63
		beq LCDF7
		tst 5,x
		bne LCDE3
		ldd 2,x
		bsr LCE11
		ldd #8
		bsr LCE1D
		bra LCDE3
LCDF7		ldx #V3C3
LCDFA		leax $11,x
		cmpx #mazedata
		beq LCE2B
		tst 12,x
		beq LCDFA
		ldd 15,x
		bsr LCE11
		ldd #$1054
		bsr LCE1D
		bra LCDFA
LCE11		tfr d,y
		ldb #$c0
		mul
		addd ,u
		exg d,y
		leay b,y
		rts
LCE1D		sta $20,y
		stb $40,y
		stb $60,y
		sta $80,y
LCE2A		rts
LCE2B		ldd V213
		bsr LCE11
		ldd #$2418
		bsr LCE1D
		ldx V286
		bsr LCE38
LCE38		lda ,x+
		bmi LCE2A
		ldd ,x++
		bsr LCE11
		ldd #$3c24
		bsr LCE1D
		bra LCE38
LCE47		pshs a,x
		ldx #LCF48
		tst V273
		bne LCE5C
		leax >1,x
		tst V274
LCE56		bne LCE5C
		leax $fff5,x
LCE5C		lda V28B
		lda a,x
		sta V24F
		sta V250
		puls a,x,pc
LCE66		cleargfx2
		clr V28B
		ldd V213
		std V27C
LCE6E		bsr LCE47
		ldd V27C
		jsr LCC7B
		lda ,x
		ldu #V9F4
		ldx #4
LCE7D		tfr a,b
		andb #3
		stb 4,u
		stb ,u+
		lsra
		lsra
		leax -1,x
		bne LCE7D
		ldb V223
		ldu #V9F4
		leau b,u
		ldy #LDBDE
LCE96		lda ,y+
		bmi LCED8
		ldb a,u
		lslb
		cmpb #4
		bne LCEA9
		ldx b,y
		dec V275
		bsr LCECE
		ldb #6
LCEA9		ldx b,y
		bsr LCECE
		leay 8,y
		bra LCE96
LCEB1		rts
LCEB2		tfr x,y
		tst b,u
		bne LCEB1
		addb V223
		stb V28A
		ldd V27C
		jsr LD11B
		jsr LCF82
		beq LCEB1
		exg x,y
LCEC8		tst 2,y
		beq LCECE
		dec V275
LCECE		pshs u
		dod S00
		ldu screendraw
		drawgraphic
		puls u,pc
LCED8		ldd V27C
		jsr LCF82
		beq LCEEB
		tfr x,y
		ldb 13,y
		lslb
		ldx #LDAA3
		ldx b,x
		bsr LCEC8
LCEEB		ldb #3
		ldx #LDCB0
		bsr LCEB2
		ldb #1
		ldx #LDCB9
		bsr LCEB2
		ldx #LDD3C
		ldd V27C
		jsr LCFE1
		bmi LCF09
		ldx #LDCC2
		lsla
		ldx a,x
LCF09		bsr LCECE
		clr V291
LCF0D		ldd V27C
		jsr LCF53
		beq LCF24
		lda 10,x
		lsla
		ldx #LD9EE
		ldx a,x
		dec V275
		bsr LCECE
		bsr LCECE
		bra LCF0D
LCF24		tst ,u
		bne LCF3D
		lda V223
		sta V28A
		ldd V27C
		jsr LD11B
		std V27C
		inc V28B
		lda V28B
		cmpa #9
		lble LCE6E
LCF3D		rts
LCF3E		fcb $c8,$80,$50,$32
		fcb $1f,$14
LCF44		fcb $0c,$08,$04,$02
LCF48		fcb $ff,$9c,$64,$41
		fcb $28,$1a,$10,$0a
LCF50		fcb $06,$03,$01
LCF53		bsr LCF63
		beq LCF62
		cmpd 2,x
		bne LCF53
		tst 5,x
		bne LCF53
		andcc #$fb
LCF62		rts
LCF63		pshs a
		lda V281
		ldx V292
		tst V291
		bne LCF72
		ldx #emptyhand
		dec V291
LCF72		leax 14,x
		stx V292
		cmpx objectfree
		beq LCF80
		cmpa 4,x
		bne LCF72
		andcc #$fb
LCF80		puls a,pc
LCF82		ldx #V3C3
LCF85		leax $11,x
		cmpx #mazedata
		beq LCF96
		cmpd 15,x
		bne LCF85
		tst 12,x
		beq LCF85
LCF96		rts
LCF97		pshs a,b,x
LCF99		jsr LCC71
		std ,s
		lda ,x
		inca
		beq LCF99
		puls a,b,x,pc
LCFA5		pshs a,b,x,y,u
LCFA7		ldu #V3C3
LCFAA		leau $11,u
		tst 12,u
		bne LCFAA
		dec 12,u
		sta 13,u
		ldb #8
		mul
		addd #LDABB
		tfr d,y
		tfr u,x
		lda #8
		jsr LC04B
LCFC4		bsr LCF97
		bsr LCF82
		bne LCFC4
		std 15,u
		tfr u,x
		jsr LC25C
		stx 5,u
		ldd #LD041
		std 3,u
		lda 6,x
		ldb #4
		jsr LC21D
		puls a,b,x,y,u,pc
LCFE1		pshs a,b,x,u
		ldu V286
		bsr LCFF2
		tsta
		bpl LCFEE
		bsr LCFF2
		adda #2
LCFEE		sta ,s
		puls a,b,x,u,pc
LCFF2		lda ,u+
		bmi LCFFC
		ldx ,u++
		cmpx 2,s
		bne LCFF2
LCFFC		rts
LCFFD		fcb $80,$01,$00,$17
LD001		fcb $00,$0f,$04,$00
LD005		fcb $14,$11,$01,$1c
LD009		fcb $1e,$80,$01,$02
LD00D		fcb $03,$00,$03,$1f
LD011		fcb $00,$13,$14,$00
LD015		fcb $1f,$00,$80,$80
LD019		fcb $00,$00,$1f,$00
LD01D		fcb $05,$00,$00,$16
LD021		fcb $1c,$00,$1f,$10
LD025		fcb $80,$80
LD027		ldx V282
		ldb #11
		clra
LD02C		adda b,x
		decb
		bpl LD02C
		cmpa #$20
		bhs LD03D
		dod S07
		anda #7
		adda #2
		inc a,x
LD03D		ldd #$0508
		rts
LD041		ldy 5,u
		tst V22B
		bne LD06A
		ldb 12,y
		bne LD04D
		rts
LD04D		lda 13,y
		cmpa #6
		beq LD06D
		cmpa #10
		bge LD06D
		ldd 15,y
		clr V291
		jsr LCF53
		beq LD06D
		ldd 8,y
		stx 8,y
		std ,x
		dec 5,x
		dod S0E
LD06A		jmp LD103
LD06D		ldd 15,y
		cmpd V213
		bne LD0B2
		lda 13,y
		ldb #$ff
		playsound
		ldd #$8080
		ldx lefthand
		bsr LD09E
		ldx righthand
		bsr LD09E
		sta V21A
		stb V21C
		tfr y,x
		ldu #powerlevel
		jsr LD3D7
		bmi LD099
		playsoundimm $13
		jsr LD40C
LD099		dod S0C
		jmp LD10F
LD09E		pshs a,b,x
		beq LD0B0
		lda 10,x
		cmpa #3
		bne LD0B0
		ldx 6,x
		cmpx ,s
		bhs LD0B0
		stx ,s
LD0B0		puls a,b,x,pc
LD0B2		cmpa V213
		bne LD0C3
		lda 16,y
		ldb #1
		suba V214
		bmi LD0D0
		ldb #3
		bra LD0D0
LD0C3		ldd 15,y
		cmpb V214
		bne LD0E4
		ldb #2
		suba V213
		bmi LD0D0
		clrb
LD0D0		stb V28A
		ldd 15,y
LD0D4		bsr LD136
		bne LD0E4
		cmpd V213
		bne LD0D4
		ldb V28A
		stb 14,y
		clrb
		bra LD101
LD0E4		ldx #LD114
		dod S07
		tsta
		bmi LD0EE
		leax 3,x
LD0EE		anda #3
		bne LD0F4
		leax 1,x
LD0F4		lda #3
LD0F6		ldb ,x+
		bsr LD14F
		beq LD103
		deca
		bne LD0F6
		ldb #2
LD101		bsr LD14F
LD103		lda 6,y
		ldx 15,y
		cmpx V213
		bne LD111
		dod S0E
		clr V2B5
LD10F		lda 7,y
LD111		ldb #4
		rts
LD114		fcb $00,$03,$01,$00
		fcb $01,$03,$00		
LD11B		pshs a,b
		ldb V28A
		andb #3
		lslb
		ldx #LD12E
		ldd b,x
		adda ,s+
		addb ,s+
		jmp LCC7B
LD12E		fdb $ff00
		fdb 1
		fdb $100
		fdb $ff
LD136		pshs a,b,x,y,u
		bsr LD11B
		jsr LCC8E
		bne LD14D
		tfr d,u
		lda ,x
		inca
		beq LD14C
		stu ,s
		stx 2,s
		lda #1
LD14C		deca
LD14D		puls a,b,x,y,u,pc
LD14F		pshs a,b,x
		addb 14,y
		andb #3
		stb V28A
		ldd 15,y
		bsr LD136
		bne LD199
		jsr LCF82
		bne LD199
		std 15,y
		ldb V28A
		stb 14,y
		ldd 15,y
		suba V213
		bpl LD16F
		nega
LD16F		subb V214
		bpl LD174
		negb
LD174		stb V2C1
		cmpa V2C1
		bge LD17C
		exg a,b
LD17C		sta V2C1
		cmpa #8
		bgt LD198
		cmpb #2
		bgt LD198
		dod S07
		bita #1
		beq LD196
		lda V2C1
		ldb #$1f
		mul
		comb
		lda 13,y
		playsound
LD196		dec V2B5
LD198		clra
LD199		puls a,b,x,pc
LD19B		ldu curtorch
		beq LD1BC
		lda 6,u
		beq LD1BC
		deca
		sta 6,u
		cmpa #5
		bgt LD1B0
		ldb #$18
		stb 9,u
		clr 11,u
LD1B0		cmpa 7,u
		bge LD1B6
		sta 7,u
LD1B6		cmpa 8,u
		bge LD1BC
		sta 8,u
LD1BC		dec V2B5
		ldd #$0108
		rts
LD1C2		tst V2B5
		bne LD1CD
		ldx #LCDB2
		cmpx displayptr
		bne LD1D1
LD1CD		clr V2B5
		dod S0E
LD1D1		ldd #$0304
		rts
LD1D5		clra
		clrb
		subd damagelevel
		jsr LD379
		addd damagelevel
		bgt LD1E2
		clra
		clrb
LD1E2		std damagelevel
		dod S0C
		lda V2AF
		ldb #2
		rts
LD1EB		tst V277
		bne LD21B
LD1EF		jsr LC329
		tsta
		beq LD248
		tst V228
		bne LD1EF
		cmpa #$20
		beq LD215
		ldb #$1f
		cmpa #$0d
		beq LD212
		ldb #$24
		cmpa #8
		beq LD212
		clrb
		cmpa #$41
		blo LD212
		cmpa #$5a
		bls LD215
LD212		tfr b,a
		skip2
LD215		anda #$1f
		bsr LD24C
		bra LD1EF
LD21B		ldy V20D			fetch pointer to command sequence
		ldb ,y+				do we have a command to do?
		bpl LD229			brif so
		delay				wait for a bit
		delay				wait for a bit more
		jmp START			go start over again with the splash and demo
LD229		ldx ,y++			get pointer to the word
		ldu #V361			point to command decode buffer
		decodestr			decode the keyword
		leau 1,u			move past the "object type" flag
		delay				wait a bit
		skip2				skip next instruction
LD235		bsr LD24C
		lda ,u+				fetch a character from the decoded string
		bpl LD235			brif not end of string
		clra				code for a space
		bsr LD24C			
		decb				have we consumed all the words in this command?
		bne LD229			brif not - get another
		lda #$1f			code for carriage return
		bsr LD24C
		sty V20D			save new command stream pointer
LD248		ldd #$0102
		rts
LD24C		pshs a,b,x,y,u
		tst V2AD
		bne LD256
		dod S19
		showprompt
LD256		ldu V211
		cmpa #$1f
		beq LD26F
		cmpa #$24
		beq LD27D
		renderchar
		sta ,u+
		ldx #LC67C
		renderstr
		cmpu #V311
		bne LD2B4
LD26F		clra
		renderchar
		ldd allones
		std ,u++
		ldu #V2F1
		stu V211
		bra LD292
LD27D		cmpu #V2F1
		beq LD2B4
		leau -1,u
		ldx #LD28C
		renderstr
		bra LD2B4
LD28C		fcb $00,$24,$24,$1c
		fcb $24,$ff
LD292		ldx #kwlist_cmd
		jsr LCBEC
		beq LD2A7
		bpl LD2A1
		jsr LCBE1
		bra LD2A7
LD2A1		lsla
		ldx #LD9D0
		jsr [a,x]
LD2A7		ldu #V2F1
		tst V2AD
		beq LD2B4
		tst V228
		bne LD2B4
		showprompt
LD2B4		stu V211
		puls a,b,x,y,u,pc
cmd_attack	jsr LCC31			; get pointer to specified hand
		ldu ,u				; fetch item in specified hand
		bne LD2C2			; brif item there
		ldu #emptyhand			; point to data for emtpy hand
LD2C2		tfr u,y				; save object data pointer
		lda 12,u			
		sta V219
		lda 13,u
		sta V21B
		adda V219			; calculate sum of magical and physical damage
		rora				; divide by 8
		lsra
		lsra
		ldx powerlevel			; fetch current player power
		jsr applyscale			; apply the scale factor calculated above
		addd damagelevel		; apply the wielding cost to play damage
		std damagelevel			; save new damage value
		lda 10,u			; get object type
		adda #12			; offset into sound table
		ldb #$ff			; set full volume
		playsound			; play the attack sound for the object
		lda 9,u				; get object subtype
		cmpa #$13			; is it less than "ENERGY"?
		blt LD2F7			; brif so - not an expiring ring
		cmpa #$15			; is it more than "FIRE"?
		bgt LD2F7			; brif so - not an expiring ring
		dec 6,u				; count down ring usages
		bne LD2F7			; brif not used up
		lda #$16			; type for "GOLD"
		sta 9,u				; set to GOLD ring
		jsr LD638			; update object stats appropriately
LD2F7		ldd V213
		jsr LCF82
		beq LD375
		ldu #powerlevel
		exg x,u
		lda 10,y			; fetch object type
		cmpa #1				; is it a ring?
		beq LD31F			; go do successful attack if so - rings never miss
		jsr LD3D7
		bmi LD375
		ldy curtorch			; do we have a torch burning?
		beq LD319			; brif not
		lda 9,y				; get torch type
		cmpa #$18			; is it "DEAD"?
		bne LD31F			; brif not
LD319		dod S07				; get random number
		anda #3				; 1 in 4 chance of a hit in the dark
		bne LD375			; brif we didn't hit
LD31F		playsoundimm $12		; play the "HIT" sound
		renderstrimmp			; display the "!!!" for a successful hit
		fcb $16,$f7,$b0			; packed "!!!" string
		jsr LD40C
		bhi LD375
		leax 8,u
LD32E		ldx ,x
		beq LD33A
		clr 5,x
		ldd 15,u
		std 2,x
		bra LD32E
LD33A		ldx V282
		ldb 13,u
		dec b,x
		clr 12,u
		dod S0E
		playsoundimm $15
		ldd ,u
		bsr LD37F
		addd powerlevel
		bpl LD351
		lda #$7f
LD351		std powerlevel
		lda 13,u
		cmpa #10
		beq LD386
		cmpa #11
		bne LD375
		dec V22B
		ldd #$713
		std V226
		ldx #$b23
		stx objectfree
		ldd zero
		std backpack
		std curtorch
		std righthand
		std lefthand
		dod S19
LD375		dod S0C
LD377		asra
		rorb
LD379		asra
		rorb
LD37B		asra
		rorb
LD37D		asra
		rorb
LD37F		asra
		rorb
LD381		asra
		rorb
LD383		asra
		rorb
		rts
LD386		ldx #img_wizard			; point to Wizard graphic
		fadeinclrst			; fade in the wizard
		renderstrimmp			; dipslay "ENOUGH! I TIRE OF THIS PLAY..."
		fcb $ff,$c0,$57,$3e		; packed string "ENOUGH! I TIRE OF THIS PLAY..."
		fcb $a7,$46,$c0,$90
		fcb $51,$32,$28,$1e
		fcb $60,$51,$09,$98
		fcb $20,$c0,$e7,$de
		fcb $f0
		renderstrimmp			; also display "PREPARE TO MEET THY DOOM!!!"
		fcb $e8,$00,$08,$48		; packed string "PREPARE TO MEET THY DOOM!!!"
		fcb $b0,$0c,$8a,$0a
		fcb $3c,$0d,$29,$68
		fcb $0a,$23,$20,$23
		fcb $de,$dd,$ef,$60
		delay				; delay a bit
		ldu curtorch			; fetch current torch
		stu backpack			; put it in the backpack
		beq LD3C4			; brif no torch
		clra				; make sure the torch is the only thing in the backpack
		clrb
		std ,u
LD3C4		ldd #200			; set player carry weight to 200
		std carryweight
		lda #3				
		dod S1A
		jsr LCF97
		std V213
		fadeout				; fade out the wizard
		dod S19
		rts
LD3D7		pshs a,b,x,u
		lda #15
		sta V2C1
		ldd ,u
		subd 10,u
		jsr LCA12
LD3E4		subd ,x
		bcs LD3EC
		dec V2C1
		bne LD3E4
LD3EC		ldb V2C1
		subb #3
		bpl LD3FB
		negb
		lda #$19
		mul
		jsr LCA99
		bra LD3FE
LD3FB		lda #10
		mul
LD3FE		std ,--s
		dod S07
		tfr a,b
		clra
		addd ,s++
		subd #$7f
		puls a,b,x,u,pc
LD40C		pshs a,b,x,y,u
		tfr x,y
		ldx ,y
		lda 2,y
		bsr applyscale
		tfr d,x
		lda 3,u
		bsr applyscale
		addd 10,u
		std 10,u
		ldx ,y
		lda 4,y
		bsr applyscale
		tfr d,x
		lda 5,u
		bsr applyscale
		addd 10,u
		std 10,u
		ldx ,u
		cmpx 10,u
		puls a,b,x,y,u,pc
; Multiply X by the value in A, where the binary point in A is to the left of bit 6. Return only the
; integer result in D (rounded down).
applyscale	pshs a,b,x			; save parameters and registers
		clr V2C1			; blank out temp storage area
		ldb 3,s				; get LSB of X
		mul				; multiply LSB
		std V2C2			; save in scratch variable
		lda ,s				; fetch muliplier
		ldb 2,s				; fetch MSB of X
		mul				; multiply it
		addd V2C1			; add in partial product
		lsl V2C3			;* shift product left so binary point is to the right of
		rolb				;* of the upper 16 bits - leave interger result in D.
		rola
		std ,s				; save integer result for return
		puls a,b,x,pc			; clean up parameters, fetch product, and return
cmd_climb	ldd V213
		jsr LCFE1
		bmi LD46F
		sta V2C1
		ldx #kwlist_dir
		jsr LCBEC
		ble LD46F
		ldb V2C1
		cmpa #4
		beq LD472
		cmpa #5
		bne LD46F
		lda #1
		bitb #2
		bne LD478
LD46F		jmp LCBE1
LD472		lda #$ff
		cmpb #1
		bne LD46F
LD478		showprepare
		adda V281
		dod S1A
		dod S19
		rts
cmd_examine	ldx #LD495			; pointer to the inventory display routine
		stx displayptr			; set up the display update routine
		dod S0E				; update the display
		rts
LD489		cleargfx2			; clear graphics
		ldx ,u
		ldu #V380
		stx ,u
		dec V2B7			set to nonstandard text rendering
		rts
LD495		bsr LD489			; clear the graphics area and set up for text rendering
		clr V2B6			; flag column zero in object list
		ldd #10				; set up to centre "IN THIS ROOM"
		std 4,u
		renderstrimmp			; show the "IN THIS ROOM" heading
		fcb $62,$5c,$0a,$21		; packed string "IN THIS ROOM"
		fcb $33,$04,$9e,$f6
		fcb $fc
		ldd V213
		jsr LCF82
		beq LD4C0
		ldx 4,u
		leax 11,x
		stx 4,u
		renderstrimmp			; show the "!CREATURE!" string if a creature is present
		fcb $56,$c7,$22,$86		; packed string "!CREATURE!"
		fcb $95,$91,$77,$f0
LD4C0		clr V291
LD4C2		ldd V213
		jsr LCF53
		beq LD4CD
		bsr LD505
		bra LD4C2
LD4CD		tst V2B6
		beq LD4D3
		bsr LD4FE
LD4D3		ldd #$1b20			; set up for displaying a row of !!!!
LD4D6		renderchar			; display a !
		decb				; done enough of them?
		bne LD4D6			; brif not
		ldx 4,u				; set up to centre "BACKPACK"
		leax 12,x
		stx 4,u
		renderstrimmp			; display "BACKPACK" heading
		fcb $40,$82,$35,$c0		; packed string "BACKPACK"
		fcb $23,$5f,$c0
		ldx #backpack			; point to backpack head pointer
LD4ED		ldx ,x				; get next item in backpack
		beq LD4FB			; brif nothing else in backpack
		cmpx curtorch			; is the object the currently burning torch?			
		bne LD4F7			; brif not
		com 6,u				; invert video if it is
LD4F7		bsr LD505			; display ojbect name
		bra LD4ED			; go display another object
LD4FB		clr V2B7			; reset to standard text rendering
		rts
LD4FE		lda #$1f			; character code for newline
		renderchar			; go move to next line
		clr V2B6			; flag column 1
		rts
LD505		pshs a,b,x			; save registers
		jsr LC617			; fetch object name string (decoded)
		renderstr			; display object name
		lda levbgmask			; restore the proper text coloring
		sta 6,u
		com V2B6			; are we on column 1 or 2?
		beq LD51E			; brif back at column 1
		ldd 4,u				; get cursor position
		addd #$10			; move right 16 cells
		andb #$f0			; round down to multiple of 16
		std 4,u				; save new cursor position
		skip2				; move on with routine
LD51E		bsr LD4FE			; do a newline
		puls a,b,x,pc			; restore registers and return
cmd_get		bsr LD576
		bne LD573
		jsr LCBBA
		clr V291
LD52B		ldd V213
		jsr LCF53
		beq LD573
		tst V290
		bne LD53C
		lda 10,x
		cmpa V28F
		bra LD540
LD53C		lda 9,x
		cmpa V28E
LD540		bne LD52B
		stx ,u
		inc 5,x
		ldb 10,x
		ldx #LD9FA
		ldb b,x
		clra
		bra LD56B
cmd_drop	bsr LD576
		beq LD573
		clra
		clrb
		std ,u
		clr 5,x
		ldd V213
		std 2,x
		lda V281
		sta 4,x
		ldb 10,x
		ldx #LD9FA
		ldb b,x
		negb
		sex
LD56B		addd carryweight
		std carryweight
		dod S0C
		bra LD5B7
LD573		jmp LCBE1
LD576		jmp LCC31
cmd_stow	bsr LD576			; get pointer to object in requested hand
		beq LD573			; brif no object in the hand
LD57D		ldd backpack			; add this item to the start of the backpack list
		std ,x
		stx backpack
		clra				; mark the selected hand as empty
		clrb
		std ,u
		bra LD5B7			; update status line, etc.
cmd_pull	bsr LD576
		bne LD573
		jsr LCBBA
		ldx #backpack
LD593		tfr x,y
		ldx ,x
		beq LD573
		tst V290
		bne LD5A3
		lda 10,x
		cmpa V28F
		bra LD5A7
LD5A3		lda 9,x
		cmpa V28E
LD5A7		bne LD593
		ldd ,x
		std ,y
		stx ,u
LD5AF		clra
		clrb
		cmpx curtorch
		bne LD5B7
		std curtorch
LD5B7		updatestatus
		dod S0E
		rts
cmd_incant	ldx #kwlist_adj
		jsr LCBEC
		ble LD5EF
		tst V27B
		beq LD5EF
		std V28E
		ldu lefthand
		bsr LD5D0
		ldu righthand
LD5D0		beq LD5EF
		lda 10,u
		cmpa #1
		bne LD5EF
		lda 7,u
		beq LD5EF
		cmpa V28E
		bne LD5EF
		sta 9,u
		setobjectspecs
		playsoundimm $0D
		updatestatus
		clr 7,u
		cmpa #$12
		beq LD5F0
LD5EF		rts
LD5F0		ldx #img_goodwiz
		dec V29E
		fadeinclrst
		renderstrimmp
		fcb $ff,$c4,$54,$3d		packed string victory message line 1
		fcb $84,$d8,$08,$59
		fcb $D1,$2e,$c8,$03
		fcb $70,$a6,$93,$05
		fcb $10,$50,$20,$2e
		fcb $20
		renderstrimmp
		fcb $c8,$00,$00,$00		packed string victory message line 2
		fcb $00,$03,$cc,$00
		fcb $81,$c5,$b8,$2e
		fcb $9d,$06,$44,$f7
		fcb $bc
LD621		bra LD621
cmd_reveal	jsr LCC31
		ldu ,u
		beq LD63E
		lda 11,u
		beq LD63E
		ldb #$19
		mul
		cmpd powerlevel
		bgt LD63E
		lda 9,u
LD638		setobjectspecs
		clr 11,u
		updatestatus
LD63E		rts
cmd_turn	ldx #kwlist_dir
		jsr LCBEC
		ble LD693
		ldb V223
		cmpa #0
		bne LD654
		decb
		bsr LD66D
		bsr LD674
		bra LD669
LD654		cmpa #1
		bne LD65D
		incb
		bsr LD66D
		bra LD667
LD65D		cmpa #3
		bne LD693
		addb #2
		bsr LD66D
		bsr LD684
LD667		bsr LD684
LD669		dec pageswap			set graoguc swao required
		sync				wait for swap to happen
		rts
LD66D		andb #3
		stb V223
		jmp LC660
LD674		bsr LD696
		bne LD683
		ldd #8
LD67B		bsr LD6BA
		addd #$20
		tsta
		beq LD67B
LD683		rts
LD684		bsr LD696
		bne LD692
		ldd #$f8
LD68B		bsr LD6BA
		subd #$20
		bpl LD68B
LD692		rts
LD693		jmp LCBE1
LD696		ldu displayptr
		cmpu #LCE66
		bne LD6B9
		ldx #$8080
		stx V24F
		clr V28B
		dod S00
		cleargfx1
		ldx #LD6C6
		drawgraphic
		ldx #$11
		stx ybeg
		ldx #$87
		stx yend
		clra
LD6B9		rts
LD6BA		std xbeg
		std xend
		bsr LD6C0
LD6C0		jsr drawline
		com levbgmask
		rts
LD6C6		fcb $10,$00,$10,$ff
		fcb $ff,$88,$00,$88
		fcb $ff,$fe
cmd_move	ldx #kwlist_dir
		jsr LCBEC
		blt LD693
		bgt LD6E3
		dec V273
		dod S0E
		clrb
		clr V273
		bra LD6EF
LD6E3		cmpa #2
		bne LD6F3
		dec V274
		dod S0E
		ldb #2
		clr V274
LD6EF		bsr LD720
		bra LD70E
LD6F3		cmpa #1
		bne LD701
		ldb #1
		bsr LD720
		bne LD70E
		bsr LD684
		bra LD70E
LD701		cmpa #0
		bne LD693
		ldb #3
		bsr LD720
		bne LD70E
		jsr LD674
LD70E		ldd carryweight
		jsr LD37F
		addd #3
		addd damagelevel
		std damagelevel
		dod S0C
		dec pageswap			set graphics swap required
		sync				wait for swap to happen
		rts
LD720		pshs a,b
		clr ,-s
		addb V223
		andb #3
		stb V28A
		ldd V213
		jsr LD136
		beq LD738
		playsoundimm $14
		dec ,s
		ldd V213
LD738		std V213
		jsr LC660
		tst ,s+
		puls a,b,pc
cmd_use		jsr LCC31			; fetch pointer to object in specified hand
		beq LD767			; brif nothing in the hand
		ldd 9,x				; fetch object type and subtype
		cmpb #5				; is it a torch?
		bne LD757			; brif not
		stx curtorch			; set object as currently mounted
		jsr LD57D			; go place the object in the backpack
		playsoundimm $11		; play the torch sound
		dod S0E
		rts
LD757		tfr x,u				; save object pointer
		ldx #LD76B			; point to jump table
LD75C		cmpa ,x				; does the sub type match?
		beq LD768			; brif so
		leax 3,x			; move to next entry
		cmpx #LD77A			; end of table?
		blo LD75C			; brif not - try another
LD767		rts				; no match - do nothing
LD768		jmp [1,x]			; transfer control to specified routine
LD76B		fcb $05				; "THEWS" (thews flask)
		fdb LD77A
		fcb $09				; "HALE" (hale flask)
		fdb LD783
		fcb $08				; "ABYE" (abye flask)
		fdb LD787
		fcb $04				; "SEER" (seer scroll)
		fdb LD7A2
		fcb $07				; "VISION" (vision scroll)
		fdb LD7A0
LD77A		ldd #1000			; thews increases player power by 1000
		addd powerlevel			; add to existing power value
		std powerlevel			; save new power value
		bra LD792			; go empty the flask and update things
LD783		clra				; new damage level = 0
		clrb
		bra LD790			; go set damage level and clean up flask
LD787		ldx powerlevel			; fetch player power level
		lda #$66			; roughly 0.8
		jsr applyscale			; go calculate 80% of player power level
		addd damagelevel		; add that to the current damage level
LD790		std damagelevel			; save new damage level
LD792		ldb #$17			; type for "EMPTY"
		stb 9,u				; change flask to EMPTY
		clr 11,u
		playsoundimm $0c		; play the flask sound
		updatestatus			; update status line to reflect changed flask state
		dod S0C
		rts
LD7A0		clra				; flag for not showing creatures
		skip2				; skip over next instruction
LD7A2		lda #$ff			; flag for do show creatures
		sta V294			; set creature display flag
		tst 11,u
		bne LD7B6
		playsoundimm $0e		; play the scroll sound
		clr V2AD
		ldx #LCDB2
		stx displayptr
		dod S0E
LD7B6		rts
cmd_zload	bsr LD7BC			; parse the file name
		dec V2B8			; flag ZLOAD
		rts
LD7BC		ldx #wordbuff			; get start address to set to $ff
		leau $20,x			; set $20 bytes
		setblock			; go clear block to $ff
		jmp LCB96
cmd_zsave	bsr LD7BC			; parse the file name
		stx CBUFAD			
		ldd #$0f
		std BLKTYP
		inc V2B8			; flag ZSAVE
		rts
; Objects in backpack for demo game
startobjdemo	fcb 13				; iron sword
		fcb 15				; pine torch
		fcb 16				; leather shield
		fcb $ff				; end of list
; Objects in backpack for normal game
startobj	fcb 17				; wooden sword
		fcb 15				; pine torch
		fcb $ff				; end of list
LD7DC		fdb LD1EB
		fdb LD1C2
		fdb LD1D5
		fdb LD19B
		fdb LD027
		fdb 0
; cold start variable initializers
LD7E8		fcb 12
		fdb $103
		jmp LC371
		jmp LC352
		jmp LC27D
		jmp LC27D
		fcb $17
		fdb V202
		fcb $01				V202
		fdb $ffff			allones - 16 bit all ones value, or -1
		fcb $00				V205
		fcb $80				V206
		fcb 0				V207
		fcb $4c				V208
		fdb LD870			screenvis - pointer to primary display screen info
		fdb LD876			screendraw - pointer to secondary display screen info
		fdb demogame			V20D - pointer to demo game command sequence
		fdb objecttab			objectfree - next free object entry
		fdb V2F1			V211
		fcb $0c				V213
		fcb $16				V214
		fdb $23				carryweight - the weight of objects the player is carrying
		fdb $17a0			powerlevel - player power level
		fcb $54	
		fdb V380
		fdb $1000			V380 - text area starts at top of screen
		fdb $0260			V382 - text area ends after 19 lines
		fdb 0				V384 - text cursor position at top of screen
		fcb 0				V386 - black background
		fcb $ff				V387 - do not render on secondary screen
		fdb $2300			V388 - text area starts at row 19 on screen
		fdb $40				V38A - text area goes for two lines
		fdb 0				V38C - text cursor is at top of area
		fcb $ff				V38E - background is white
		fcb 0				V38F - do render on secondary screen
		fdb $2400			V390 - text area starts at row 20 on screen
		fdb $80				V392 - text area goes for four lines
		fdb 0				V394 - text cursor is at top of area
		fcb 0				V396 - background is black
		fcb 0				V397 - do render on secondary screen
		fcb $09,$09,$04,$02
		fcb $00,$00,$00,$00
		fcb $00,$00,$00,$00
		fcb $02,$04,$00,$06
		fcb $06,$06,$00,$00
		fcb $00,$00,$00,$00
		fcb $00,$00,$00,$04
		fcb $00,$06,$08,$04
		fcb $00,$00,$01,$00
		fcb $00,$00,$00,$00
		fcb $00,$00,$08,$06
		fcb $06,$04,$00,$00
		fcb $02,$02,$02,$02
		fcb $02,$02,$02,$04
		fcb $04,$08,$00,$01
		fcb 4
		fdb emptyhand+10
		fcb $04,$00,$00,$05		; empty hand attack data
		fcb 0

; these tables are used for clearing and otherwise setting up the graphics screens
LD870		fdb $1000			primary screen start address
		fdb $2300			primary screen gfx area end address
		fdb $2046			primary screen SAM register value
LD876		fdb $2800			secondary screen start address
		fdb $3b00			secondary screen gfx area end address
		fdb $20a6			secondary screen SAM register value
LD87C		fdb $2300			start address of status line on first screen
		fdb $2400			end address of status line on first screen
		fdb 0				dummy (SAM regster setting)
		fdb $3b00			start address of status line on second screen
		fdb $3c00			end address of status line on second screen
		fdb 0				dummy (SAM register setting)
LD888		fdb $2400			start address of command area on first screen
		fdb $2800			end address of command area on first screen
		fdb 0				dummy (SAM register setting)
		fdb $3c00			start address of command area on second screen
		fdb $4000			end address of command area on second screen
		fdb 0				dummy (SAM register setting)

; This is the keyword table used for command parsing. Each keyword is stored in packed format.
; Each keyword is preceded by a value which indicates the object type. Where the object type is
; not relevant, that value will be zero. The value is shown in parentheses below.
kwlist_cmd	fcb 15				15 keywords in the command list
kw_attack	fcb $30,$03,$4a,$04,$6b		"ATTACK" keyword
		fcb $28,$06,$c4,$b4,$40		"CLIMB" keyword
		fcb $20,$09,$27,$c0		"DROP" keyword
kw_examine	fcb $38,$0b,$80,$b5,$2e,$28	"EXAMINE" keyword
		fcb $18,$0e,$5a,$00		"GET" keyword
		fcb $30,$12,$e1,$85,$d4		"INCANT" keyword
kw_look		fcb $20,$18,$f7,$ac		"LOOK" keyword
kw_move		fcb $20,$1A,$fb,$14		"MOVE" keyword
kw_pull		fcb $20,$21,$56,$30		"PULL" keyword
		fcb $30,$24,$5b,$14,$2c		"REVEAL" keyword
		fcb $20,$27,$47,$dc		"STOW" keyword
kw_turn		fcb $20,$29,$59,$38		"TURN" keyword
kw_use		fcb $18,$2b,$32,$80		"USE" keyword
		fcb $28,$34,$c7,$84,$80		"ZLOAD" keyword
		fcb $28,$35,$30,$d8,$a0		"ZSAVE" keyword
kwlist_dir	fcb 6				6 keywords in direction list
kw_left		fcb $20,$18,$53,$50		"LEFT" keyword
kw_right	fcb $28,$24,$93,$a2,$80		"RIGHT" keyword
		fcb $20,$04,$11,$ac		"BACK" keyword
		fcb $30,$03,$27,$d5,$c4		"AROUND" keyword		
		fcb $10,$2b,$00			"UP" keyword
		fcb $20,$08,$fb,$b8		"DOWN" keyword
kwlist_adj	fcb 25				25 keywords in the misc keywords list
kw_supreme	fcb $38,$67,$58,$48,$ad,$28	"SUPREME" keyword (1)
		fcb $28,$54,$fa,$b0,$a0		"JOULE" keyword (1)
		fcb $31,$0a,$cb,$26,$68		"ELVISH" keyword (4)
		fcb $38,$da,$9a,$22,$49,$60	"MITHRIL" keyword (3)
		fcb $20,$a6,$52,$c8		"SEER" keyword (2)
		fcb $28,$28,$82,$de,$60		"THEWS" keyword (0)
		fcb $20,$64,$96,$94		"RIME" keyword (1)
		fcb $30,$ac,$99,$a5,$ee		"VISION" keyword (2)
		fcb $20,$02,$2c,$94		"ABYE" keyword (0)
		fcb $20,$10,$16,$14		"HALE" keyword (0)
		fcb $29,$66,$f6,$06,$40		"SOLAR" keyword (5)
		fcb $30,$c5,$27,$bb,$45		"BRONZE" keyword (3)
		fcb $30,$6d,$56,$0c,$2e		"VULCAN" keyword (1)
		fcb $21,$13,$27,$b8		"IRON" keyword (4)
		fcb $29,$59,$57,$06,$40		"LUNAR" keyword (5)
		fcb $21,$60,$97,$14		"PINE" keyword (5)
		fcb $38,$d8,$50,$d1,$05,$90	"LEATHER" keyword (3)
		fcb $31,$2e,$f7,$90,$ae		"WOODEN" keyword (4)
		fcb $28,$4c,$97,$05,$80		"FINAL" keyword (1)
		fcb $30,$4a,$e2,$c8,$f9		"ENERGY" keyword (1)
		fcb $18,$52,$32,$80		"ICE" keyword (1)
		fcb $20,$4c,$99,$14		"FIRE" keyword (1)
		fcb $20,$4e,$f6,$10		"GOLD" keyword (1)
		fcb $28,$0a,$d8,$53,$20		"EMPTY" keyword (0)
		fcb $21,$48,$50,$90		"DEAD" keyword (5)
kwlist_obj	fcb 6				6 object types in the following list
kw_flask	fcb $28,$0c,$c0,$cd,$60		"FLASK" keyword (0)
		fcb $20,$64,$97,$1c		"RING" keyword (1)
		fcb $30,$a6,$39,$3d,$8c		"SCROLL" keyword (2)
kw_shield	fcb $30,$e6,$84,$95,$84		"SHIELD" keyword (3)
kw_sword	fcb $29,$27,$77,$c8,$80		"SWORD" keyword (4)
kw_torch	fcb $29,$68,$f9,$0d,$00		"TORCH" keyword (5)
; The following is the sequence of commands used in the demo game
demogame	fcb 1				EXAMINE
		fdb kw_examine
		fcb 3				PULL RIGHT TORCH
		fdb kw_pull
		fdb kw_right
		fdb kw_torch
		fcb 2				USE RIGHT
		fdb kw_use
		fdb kw_right
		fcb 1				LOOK
		fdb kw_look
		fcb 1				MOVE
		fdb kw_move
		fcb 3				PULL LEFT SHIELD
		fdb kw_pull
		fdb kw_left
		fdb kw_shield
		fcb 3				PULL RIGHT SWORD
		fdb kw_pull
		fdb kw_right
		fdb kw_sword
		fcb 1				MOVE
		fdb kw_move
		fcb 1				MOVE
		fdb kw_move
		fcb 2				ATTACK RIGHT
		fdb kw_attack
		fdb kw_right
		fcb 2				TURN RIGHT
		fdb kw_turn
		fdb kw_right
		fcb 1				MOVE
		fdb kw_move
		fcb 1				MOVE
		fdb kw_move
		fcb 1				MOVE
		fdb kw_move
		fcb 2				TURN RIGHT
		fdb kw_turn
		fdb kw_right
		fcb 1				MOVE
		fdb kw_move
		fcb 1				MOVE
		fdb kw_move
		fcb $ff
; jump table for commands
LD9D0		fdb cmd_attack			ATTACK
		fdb cmd_climb			CLIMB
		fdb cmd_drop			DROP
		fdb cmd_examine			EXAMINE
		fdb cmd_get			GET
		fdb cmd_incant			INCANT
		fdb cmd_look			LOOK
		fdb cmd_move			MOVE
		fdb cmd_pull			PULL
		fdb cmd_reveal			REVEAL
		fdb cmd_stow			STOW
		fdb cmd_turn			TURN
		fdb cmd_use			USE
		fdb cmd_zload			ZLOAD
		fdb cmd_zsave			ZSAVE
; pointers to the image data for object types
LD9EE		fdb img_flask			flask
		fdb img_ring			ring
		fdb img_scroll			scroll
		fdb img_shield			shield
		fdb img_sword			sword
		fdb img_torch			torch

LD9FA		fcb $05,$01

LD9FC		fcb $0A,$19,$19,$0A
; This is the object data table. Each entry is four bytes as follows:
; 0	object type
; 1	reveal strength required
; 2	magical offense multiplier	
; 3	physical offense multiplier
objspecs	fcb $01,$FF,$00,$05		; supreme ring
		fcb $01,$AA,$00,$05		; joule ring
		fcb $04,$96,$40,$40		; elvish sword
		fcb $03,$8C,$0D,$1A		; mithril shield
		fcb $02,$82,$00,$05		; seer scroll
		fcb $00,$46,$00,$05		; thews flask
		fcb $01,$34,$00,$05		; rime ring
		fcb $02,$32,$00,$05		; vision scroll
		fcb $00,$30,$00,$05		; abye flask
		fcb $00,$28,$00,$05		; hale flask
		fcb $05,$46,$00,$05		; solar torch
		fcb $03,$19,$00,$1A		; bronze shield
		fcb $01,$0D,$00,$05		; vulcan ring
		fcb $04,$0D,$00,$28		; iron sword
		fcb $05,$19,$00,$05		; lunar torch
		fcb $05,$05,$00,$05		; pine torch
		fcb $03,$05,$00,$0A		; leather shield
		fcb $04,$05,$00,$10		; wooden sword
		fcb $01,$00,$00,$00		; final ring
		fcb $01,$00,$FF,$FF		; energy ring
		fcb $01,$00,$FF,$FF		; ice ring
		fcb $01,$00,$FF,$FF		; fire ring
		fcb $01,$00,$00,$05		; gold ring
		fcb $00,$00,$00,$05		; empty flask
		fcb $05,$05,$00,$05		; dead torch
; This table has additional object data including ring charges, etc, organized as follows:
; 0	object number
; 1	burn time (torch), charges (ring), magical defense (shield)
; 2	physical light (torch), physical defense (shield)
; 3	magical ight (torch)
objextraspecs	fcb $00,$03,$12,$00		; supreme ring
		fcb $01,$03,$13,$00		; joule ring
		fcb $03,$40,$40,$00		; mithril shield
		fcb $06,$03,$14,$00		; rime ring
		fcb $0A,$3C,$0D,$0B		; solar torch
		fcb $0B,$60,$80,$00		; bronze shield
		fcb $0C,$03,$15,$00		; vulcan ring
		fcb $0E,$1E,$0A,$04		; lunar torch
		fcb $0F,$0F,$07,$00		; pine torch
		fcb $10,$6C,$80,$00		; leather shield
		fcb $18,$00,$00,$00		; dead torch
		fcb $FF				; end of table

LDA91		fcb $41,$31,$31

LDA94		fcb $32,$23,$23,$11
LDA98		fcb $13,$16,$14,$14
LDA9C		fcb $16,$01,$04,$08
LDAA0		fcb $08,$03,$04

; pointers to creature images
LDAA3		fdb LDE26
		fdb LDFCA
		fdb LDD41
		fdb LDE59
		fdb LDE82
		fdb LDD51
		fdb LDE3F
		fdb LDE9D
		fdb LDE07
		fdb LDDA3
		fdb img_wizardgen
		fdb img_wizard

LDABB		fcb $00

LDABC		fcb $20,$00,$FF,$80
LDAC0		fcb $FF,$17,$0B,$00
LDAC4		fcb $38,$00,$FF,$50
LDAC8		fcb $80,$0F,$07,$00
LDACC		fcb $C8,$00,$FF,$34
LDAD0		fcb $C0,$1D,$17,$01
LDAD4		fcb $30,$00,$FF,$60
LDAD8		fcb $A7,$1F,$1F,$01
LDADC		fcb $F8,$00,$80,$60
LDAE0		fcb $3C,$0D,$07,$02
LDAE4		fcb $C0,$00,$80,$80
LDAE8		fcb $30,$11,$0D,$01
LDAEC		fcb $90,$FF,$80,$FF
LDAF0		fcb $80,$05,$04,$03
LDAF4		fcb $20,$00,$40,$FF
LDAF8		fcb $08,$0D,$07,$03
LDAFC		fcb $20,$C0,$10,$C0
LDB00		fcb $08,$03,$03,$03
LDB04		fcb $E8,$FF,$05,$FF
LDB08		fcb $03,$04,$03,$03
LDB0C		fcb $E8,$FF,$06,$FF
LDB10		fcb $00,$0D,$07,$1F
LDB14		fcb $40,$FF,$06,$FF
LDB18		fcb $00,$0D,$07

; This is the text font - these values are in packed format
LDB1B		fcb $30,$00,$00,$00,$00		char code 0 - space
		fcb $31,$15,$18,$fe,$31		char code 1 - A
		fcb $37,$a3,$1f,$46,$3e		char code 2 - B
		fcb $33,$a3,$08,$42,$2e		char code 3 - C
		fcb $37,$a3,$18,$c6,$3e		char code 4 - D	
		fcb $37,$e1,$0f,$42,$1f		char code 5 - E
		fcb $37,$e1,$0f,$42,$10		char code 6 - F
		fcb $33,$e3,$08,$4e,$2f		char code 7 - G
		fcb $34,$63,$1f,$c6,$31		char code 8 - H
		fcb $33,$88,$42,$10,$8e		char code 9 - I
		fcb $30,$42,$10,$86,$2e		char code 10 - J
		fcb $34,$65,$4c,$52,$51		char code 11 - K
		fcb $34,$21,$08,$42,$1f		char code 12 - L
		fcb $34,$77,$5a,$d6,$31		char code 13 - M
		fcb $34,$63,$9a,$ce,$31		char code 14 - N
		fcb $33,$a3,$18,$c6,$2e		char code 15 - O
		fcb $37,$a3,$1f,$42,$10		char code 16 - P
		fcb $33,$a3,$18,$d6,$4d		char code 17 - Q
		fcb $37,$a3,$1f,$52,$51		char code 18 - R
		fcb $33,$a3,$07,$06,$2e		char code 19 - S
		fcb $37,$ea,$42,$10,$84		char code 20 - T
		fcb $34,$63,$18,$c6,$2e		char code 21 - U
		fcb $34,$63,$15,$28,$84		char code 22 - V
		fcb $34,$63,$1a,$d7,$71		char code 23 - W
		fcb $34,$62,$a2,$2a,$31		char code 24 - X
		fcb $34,$62,$a2,$10,$84		char code 25 - Y
		fcb $37,$c2,$22,$22,$1f		char code 26 - Z
		fcb $31,$08,$42,$10,$04		char code 27 - !
		fcb $30,$00,$00,$00,$1f		char code 28 - underscore
		fcb $33,$a2,$13,$10,$04		char code 29 - ?
		fcb $30,$00,$00,$00,$04		char code 30 - .
; some special glyphs
LDBB6		fcb $00,$00,$01,$01,$00,$00,$00	char code 32 - left part of contracted heart
		fcb $00,$a0,$f0,$f0,$e0,$40,$00	char code 33 - right part of contracted heart
		fcb $00,$01,$03,$03,$01,$00,$00	char code 34 - left half of expanded heart
		fcb $00,$b0,$f8,$f8,$f0,$e0,$40	char code 35 - right part of expanded heart

LDBD2		fcb $00,$80

LDBD4		fcb $00,$01,$00,$50
LDBD8		fcb $00,$04

LDBDA		fcb $00,$50

LDBDC		fcb $00,$05

LDBDE		fcb 3
		fdb LDC4F
		fdb LDC6B
		fdb LDC9B
		fdb LDC33
		fcb 0
		fdb LDC6A
		fdb LDC8B
		fdb LDCA9
		fdb LDC45
		fcb 1
		fdb LDC5D
		fdb LDC7B
		fdb LDCA2
		fdb LDC3C
		fcb $ff

; image data for a shield
img_shield	fcb 134,172
		fcb 128,192
		fcb 122,186
		fcb 128,168
		fcb $fc
		fcb $3e,$04,$00
		fcb $fe
; image data for a torch
img_torch	fcb 118,60
		fcb $fc
		fcb $f7,$ff,$2a,$00
		fcb $fe
; image data for a sword
img_sword	fcb 114,80
		fcb 124,100
		fcb $ff
		fcb 118,82
		fcb 114,86
		fcb $fe

; image data for a flask
img_flask	fcb 110,162
		fcb $fc
		fcb $51,$0e,$b1,$00
		fcb $fe
; image data for a ring
img_ring	fcb 122,60
		fcb $fc
		fcb $11,$1f,$ff,$f1,$00
		fcb $fe
; image data for a scroll
img_scroll	fcb 118,194
		fcb $fc
		fcb $1f,$34,$f1,$dc,$00
		fcb $fe

; Creature around corner to the left indicator graphic
LDC33		fcb 16,27		
		fcb 38,64
		fcb 114,64
		fcb 136,27
		fcb $fe
; Creature around corner to the right indicator graphic
LDC3C		fcb 16,229
		fcb 38,192
		fcb 114,192
		fcb 136,229
		fcb $fe
LDC45		fcb 38,64
		fcb 38,192
		fcb $ff
		fcb 114,64
		fcb 114,192
		fcb $fe
LDC4F		fcb 38,29
		fcb 38,64
		fcb 114,64
		fcb 114,27
		fcb $ff
		fcb 16,27
		fcb 38,64
		fcb $fe
LDC5D		fcb 38,229
		fcb 38,192
		fcb 114,192
		fcb 114,229
		fcb $ff
		fcb 16,229
		fcb 38,192
LDC6A		fcb $fe
LDC6B		fcb 128,40
		fcb 65,40
		fcb 68,56
		fcb 119,56
		fcb $ff
		fcb 92,48
		fcb 93,52
		fcb $fd
		fdb LDC33
LDC7B		fcb 128,216
		fcb 65,216
		fcb 68,200
		fcb 119,200
		fcb $ff
		fcb 92,208
		fcb 93,204
		fcb $fd
		fdb LDC3C
LDC8B		fcb 114,108
		fcb 67,108
		fcb 67,148
		fcb 114,148
		fcb $ff
		fcb 94,126
		fcb 94,130
		fcb $fd
		fdb LDC45
LDC9B		fcb 128,40
		fcb 66,50
		fcb 117,58
		fcb $fe
LDCA2		fcb 128,216
		fcb 66,206
		fcb 117,198
		fcb $fe
LDCA9		fcb 113,108
		fcb 67,128
		fcb 114,148
		fcb $fe
LDCB0		fcb 100,28
		fcb $fc
		fcb $44,$2e,$42,$4c,$00
		fcb $fe
LDCB9		fcb 100,228
		fcb $fc
		fcb $4c,$22,$4e,$44,$00
		fcb $fe
LDCC2		fcb 221,14
		fcb 220,202
		fcb 221,42
		fcb 220,208
		fcb $fb
		fdb LDCD6
		fcb $fd
		fdb LDD0E
LDCD0		fcb $fb
		fdb LDCD6
		fcb $fd
		fdb LDD2A
LDCD6		fcb 24,116
		fcb 128,116
		fcb $ff
		fcb 24,140
		fcb 128,140
		fcb $ff
		fcb 28,116
		fcb 28,140
		fcb $ff
		fcb 40,116
		fcb 40,140
		fcb $ff
		fcb 52,116
		fcb 52,140
		fcb $ff
		fcb 64,116
		fcb 64,140
		fcb $ff
		fcb 76,116
		fcb 76,140
		fcb $ff
		fcb 88,116
		fcb 88,140
		fcb $ff
		fcb 100,116
		fcb 100,140
		fcb $ff
		fcb 112,116
		fcb 112,140
		fcb $ff
		fcb 123,116
		fcb 123,140
		fcb $ff
		fcb $fa
LDD0E		fcb 34,100
		fcb 24,92
		fcb 24,164
		fcb 34,156
		fcb 34,100
		fcb 24,100
		fcb $ff
		fcb 34,156
		fcb 24,156
		fcb $ff
		fcb 28,47
		fcb 28,96
		fcb $ff
		fcb 28,161
		fcb 28,210
		fcb $fe
LDD2A		fcb 118,100
		fcb 128,92
		fcb 128,164
		fcb 118,156
		fcb 118,100
		fcb 128,100
		fcb $ff
		fcb 118,156
		fcb 128,156
		fcb $ff
LDD3C		fcb 28,47
		fcb 28,210
		fcb $fe
LDD41		fcb 104,98
		fcb $fc
		fcb $d7,$d4,$14,$12,$30,$1d,$0d,$fd
		fcb $29,$00
		fcb $fd
		fdb LDD62
LDD51		fcb 104,98
		fcb 94,124
		fcb 96,126
		fcb 106,100
		fcb $ff
		fcb 102,132
		fcb 92,114
		fcb 102,118
		fcb 110,114
LDD62		fcb 102,132
		fcb $fc
		fcb $02,$56,$56,$17,$ee,$02,$ea,$bb
		fcb $bb,$ea,$ea,$00
		fcb 78,92
		fcb $fc
		fcb $c2,$51,$3e,$cf,$fc,$42,$13,$00
		fcb 106,90
		fcb $fc
		fcb $1e,$11,$f3,$62,$39,$e2,$0c,$e4
		fcb $8a,$e2,$00
		fcb 86,84
		fcb $fc
		fcb $54,$65,$2e,$ca,$ba,$a1,$d4,$ee
		fcb $12,$d2,$13,$e1,$20,$f6,$24,$72
		fcb $58,$ee,$c5,$be,$00
		fcb $fe
LDDA3		fcb 80,124
		fcb 94,114
		fcb 110,120
		fcb 132,112
		fcb 104,78
		fcb 132,48
		fcb 68,72
		fcb 84,32
		fcb 22,88
		fcb 52,114
		fcb 92,128
		fcb 52,142
		fcb 22,168
		fcb 88,224
		fcb 68,184
		fcb 132,208
		fcb 112,178
		fcb 132,144
		fcb 110,136
		fcb 94,142
		fcb 80,132
		fcb $ff
		fcb 132,112
		fcb $fc
		fcb $c5,$92,$be,$c3,$43,$5e,$72,$45
		fcb $00
		fcb 82,122
		fcb $fc
		fcb $78,$e9,$8d,$ec,$33,$0c,$24,$72
		fcb $47,$e7,$00
		fcb 22,168
		fcb $fc
		fcb $2d,$c2,$3d,$30,$4b,$4b,$ed,$b2
		fcb $9d,$71,$3d,$dd,$91,$7d,$52,$63
		fcb $a3,$2d,$ed,$2d,$cb,$cb,$d0,$dd
		fcb $42,$ed,$00
		fcb $fe
LDE07		fcb 62,68
		fcb 68,88
		fcb 56,100
		fcb $ff
		fcb 74,90
		fcb 70,74
		fcb $fc
		fcb $33,$f5,$f5,$c1,$5a,$62,$0e,$00
		fcb 100,80
		fcb $fc
		fcb $b3,$17,$34,$eb,$0a,$3d,$00
		fcb $fe
LDE26		fcb 124,160
		fcb $fc
		fcb $c2,$22,$e4,$24,$2c,$ec,$04,$04
		fcb $e2,$42,$00
		fcb 124,168
		fcb $fc
		fcb $c1,$21,$12,$f2,$e1,$41,$00
		fcb $fe
LDE3F		fcb 112,74
		fcb $fc
		fcb $e0,$ee,$2c,$42,$14,$14,$20,$0c
		fcb $cc,$22,$0c,$22,$00
		fcb 124,90
		fcb $fc
		fcb $e0,$0c,$2c,$20,$04,$00
		fcb $fe
LDE59		fcb 82,130
		fcb $fc
		fcb $28,$7d,$5f,$50,$5b,$f5,$2f,$d5
		fcb $17,$17,$f3,$22,$e1,$14,$dd,$8f
		fcb $8d,$db,$ec,$00
		fcb 86,130
		fcb $fc
		fcb $33,$31,$1b,$91,$3b,$5f,$f5,$00
		fcb 108,116
		fcb 114,118
		fcb 120,144
		fcb $fe
LDE82		fcb 34,124
		fcb $fc
		fcb $04,$1f,$0e,$ff,$00
		fcb 80,142
		fcb 64,136
		fcb 46,146
		fcb 64,156
		fcb 82,140
		fcb 76,136
		fcb 64,146
		fcb 58,140
		fcb $fd
		fdb LDEB3
LDE9D		fcb 30,126
		fcb $fc
		fcb $50,$0f,$e0,$00
		fcb 44,150
		fcb 52,166
		fcb 76,164
		fcb 92,150
		fcb 76,136
		fcb 52,134
		fcb 44,150
		fcb $ff
LDEB3		fcb 80,140
		fcb 128,152
		fcb 132,160
		fcb 132,144
		fcb 126,144
		fcb 84,130
		fcb $ff
		fcb 84,126
		fcb 126,110
		fcb 132,110
		fcb 132,92
		fcb 128,102
		fcb 80,116
		fcb $ff
		fcb 80,140
		fcb $fc
		fcb $3a,$d9,$83,$de,$ad,$e6,$a1,$e2
		fcb $22,$61,$26,$ea,$20,$3d,$dd,$e0
		fcb $00
		fcb 52,128
		fcb 20,128
		fcb $fc
		fcb $0e,$21,$02,$e1,$0e,$00
		fcb 74,102
		fcb $fc
		fcb $e0,$02,$d0,$08,$30,$02,$20,$01
		fcb $30,$02,$d0,$01,$87,$00
		fcb 46,110
		fcb 64,102
		fcb 64,100
		fcb 30,102
		fcb 20,98
		fcb 30,94
		fcb 64,96
		fcb 64,98
		fcb 20,98
		fcb $FE
; Image for the Wizard
img_wizard	fcb 46,98
		fcb $fc
		fcb $21,$2f,$2d,$fd,$ce,$c2,$f2,$12
		fcb $0f,$1e,$3f,$21,$12,$e3,$e0,$00
		fcb 104,154
		fcb $fc
		fcb $21,$2f,$2d,$fd,$ce,$c2,$f2,$12
		fcb $0f,$1e,$3f,$22,$12,$e2,$e0,$00
		fcb $fd
		fdb img_wizardgen
; Image for the "good" wizard
img_goodwiz	fcb 40,86
		fcb 64,92
		fcb 42,100
		fcb 54,82
		fcb 56,104
		fcb 40,86
		fcb $ff
		fcb 66,140
		fcb $fc
		fcb $70,$ad,$35,$1b,$b3,$00
		fcb 96,146
		fcb 120,148
		fcb 100,136
		fcb 106,154
		fcb 116,138
		fcb 96,146
		fcb $ff
		fcb 80,116
		fcb $fc
		fcb $53,$ec,$e4,$4d,$b0,$00
img_wizardgen	fcb 64,124
		fcb $fc
		fcb $4e,$c0,$7b,$9c,$d4,$e4,$e1,$e1
		fcb $dd,$1c,$96,$03,$00
		fcb 28,130
		fcb $fc
		fcb $03,$45,$71,$da,$1e,$11,$e1,$00
		fcb 48,134
		fcb 54,142
		fcb 116,164
		fcb 132,132
		fcb 130,118
		fcb 120,94
		fcb 90,110
		fcb 132,132
		fcb 72,106
		fcb $ff
		fcb 64,102
		fcb $fc
		fcb $1f,$bd,$f1,$53,$00
		fcb 66,102
		fcb $fc
		fcb $1e,$32,$11,$73,$00
		fcb 88,112
		fcb 72,120
		fcb $ff
		fcb 62,132
		fcb 20,128
		fcb 52,122
		fcb 64,122
		fcb 60,124
		fcb 114,128
		fcb 80,130
		fcb 68,130
		fcb 62,132
		fcb $ff
		fcb 40,130
		fcb $fc
		fcb $ff,$1e,$11,$f2,$3f,$20,$0f,$c0
		fcb $ff,$31,$00
		fcb $fe
LDFCA		fcb 132,130
		fcb 112,122
		fcb 92,124
		fcb 94,126
		fcb 94,130
		fcb 92,132
		fcb 112,130
		fcb 128,140
		fcb 132,136
		fcb 132,114
		fcb 120,108
		fcb 106,118
		fcb 120,112
		fcb 124,116
		fcb 124,126
		fcb $ff
		fcb 100,120
		fcb $fc
		fcb $e0,$e2,$ee,$e0,$f1,$22,$ee,$06
		fcb $2e,$e2,$11,$20,$2e,$22,$20,$00
		fcb $fe
		fcc 'KSK'