; Disassembly of the Sinclair ZX Spectrum game 'Gulpman' with annotations.
; Latest change: 27 Jan 2013. V1.00.
; 
; Program Copyright (C) 1982 John A. Campbell (Trading as Campbell Systems)
; Comments Copyright (C) 2012 Rob Probin.
;
; For the original game see: http://www.worldofspectrum.org/infoseekid.cgi?id=0002175
;
; The commands and annotations were added independently by Rob Probin and there 
; has been no review or checking to ensure accuracy. Therefore the comments 
; should be regarded as a guide only and NO GUARANTEE OR WARRANY IS GIVEN for 
; their accuracy, either by Rob Probin or John Campbell.
;
; Comments and suggestions gratefully accepted at rob.probin at gmail dot com
; For latest updates see http://robprobin.com
;
; Technical Production Details
; ============================
; RAW DISASSEMBLY CREATED BY (customised version of) Z80DIS from GULPMAN.SNA
; Modifications and comments added afterwards. 
; Thanks to John Campbell for permission and to World of Specrtum for helping.
; World of Spectrum is a fantastic resource!
;
; The main entry point is at 'program_entry' (also L67E0, i.e. 67E0 hex), but 
; things start to get interesting about main_game_start.
;
;
; -----------------------------------------------------------------------------
; Permission for distribution of the Program:
; ===========================================
; "I regard all my ancient software to be in the public domain and I have no 
; problem with people copying or emulating, provided not for private or
; commercial gain.  So, help yourselves! All I ask is some acknowledgement to 
; the original author such as your web/blog site presents." - John Campbell
;
; Permission for distribution of the Comments:
; ===========================================
; The following two conditions apply to the comments only:
;
;  * Attribution Ñ You must mention the authors in all redistribution and 
;    copying leave the source file header where they are distributed as source or 
;    derived source where technically possible (but not in any way 
;    that suggests that they endorse you or your use of the work).
;
;  * No implied warranties, no liability for damages (where permitted by law).
;    If your location does not permit this, then please refriane from using
;    the comments.
;
; I did consider licensing the comments under the GPL and CC-BY-SA (or CC-BY), 
; but the complexity of others distributing made me avoid this.
;
; If you have other needs, let me know.
; -----------------------------------------------------------------------------





; SNA header
;
; Byte offset    Contents
;    0          i  register		= 3F
;    1          lÕ register		= 58
;    2          hÕ register		= 27
;    3          eÕ register		= 00
;    4          dÕ register		= 00
;    5          cÕ register		= 21
;    6          bÕ register		= 15
;    7          fÕ register		= 44
;    8          aÕ register		= 00
;    9          l  register		= 07
;   10          h  register		= 74
;   11          e  register		= 35
;   12          d  register		= 65
;   13          c  register		= 00
;   14          b  register		= F1
;   15          iy low register		= 3A
;   16          iy high register	= 5C
;   17          ix low register		= 2A
;   18          ix high register	= 63
;   19          bit 2 contains iff2	= FF
;   20          r register		= 0B
;   21          flags register		= 42
;   22          a register		= 00
;   23          sp low register		= 38
;   24          sp high register		= FF
;   25          interrupt mode (0, 1 or 2)	= 01
;   26          border colour (0..7).		= 07
;

; Screen display
; Screen is 32 characters wide and 24 characters high.
; bitmap screen is 192 pixels high, and 256 pixels wide. 
; One bit per pixel, 8 pixels per byte. Screen is 256/8 = 32 bytes wide.
; Therefore bitmap screen is 6144 bytes long
;
; Colour attributes are 1 per character, or 24x32 = 768 bytes
;
; Therefore screen is 6912 from 0x4000 to 0x5AFF.
; The colour attributes start at 0x5800.
;
; Printer and system variables start from 0x5B00. 


; Printer buffer from 0x5B00 to 5BFF

; System Variables from 0x5c00 to 0x5cB6
L5C00:              DEFB FF, 00, 00, 00, FF, 00, 14, 0D	; N8	23552	KSTATE	Used in reading the keyboard.
L5C08:				DEFB 00 ; Nl	23560	LAST K	Stores newly pressed key.
L5C09:              DEFB 14, 03, 00, 00, 00, 16, 03
L5C10:              DEFB 01, 00, 06, 00, 0B, 00, 01, 00, 01, 00, 06, 00, 10, 00, 00, 00
L5C20:              DEFB 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00
L5C30:              DEFB 00, 00, 00, 00, 00, 00, 00
L5C37:              DEFB "<@"
L5C39:              DEFB 00
L5C3A:              DEFB FF	; (=IY) 1	23610	ERR NR	1 less than the report code. Starts off at 255 (for 1) so PEEK 23610 gives 255.
L5C3B:              DEFB CD	; X1	23611	FLAGS	Various flags to control the BASIC system.
L5C3B:              DEFB 00 ; X1	23612	TV FLAG	Flags associated with the television.
L5C3D:              DEFB "T"
L5C3E:              DEFB FF, 00, 00, 00, 01, 00, FF
L5C45:              DEFB "("
L5C46:              DEFB 00, 01
L5C48:              DEFB "8"
L5C49:              DEFB 00, 00
L5C4B:              DEFB "=]"
L5C4D:              DEFB 00, 00, B6
L5C50:              DEFB "\\"
L5C51:              DEFB BB
L5C52:              DEFB "\\"
L5C53:              DEFB CB
L5C54:              DEFB "\\"
L5C55:              DEFB F1
L5C56:              DEFB "\\"
L5C57:              DEFB CA
L5C58:              DEFB "\\>]A]"
L5C5D:              DEFB F0
L5C5E:              DEFB "\\v]C]C]C]-"
L5C68:              DEFB 92
L5C69:              DEFB "\\"
L5C6A:              DEFB 00, 02, 00, 00, 00, 00, 00, 00, 00, 00, B6, 1A, 00, 00
L5C78:              DEFB "=", 01, 00	; 3	23672	FRAMES	3 byte (least significant first), frame counter. Incremented every 20ms. See Chapter 18.
L5C7B:              DEFB "`c"
L5C7D:              DEFB 00, 00
L5C7F:              DEFB "!"
L5C80:              DEFB 00
L5C81:              DEFB "["
L5C82:              DEFB 01, 17
L5C84:              DEFB "`@"
L5C86:              DEFB 00
L5C87:              DEFB "Q!"
L5C89:              DEFB 15, 01, 17, 03
L5C8D:              DEFB "8"
L5C8E:              DEFB 00
L5C8F:              DEFB "8"
L5C90:              DEFB 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00
L5CA0:              DEFB 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00
L5CB0:              DEFB 00, 00
L5CB2:              DEFB 57, FF	; 2	23730	RAMTOP	Address of last byte of BASIC system area.
L5CB4:              DEFB FF, FF, F4

;
; Microdrive maps and Channel information.
;
L5CB7:              DEFB 09, A8, 10
L5CBA:              DEFB "K"
L5CBB:              DEFB F4, 09, C4, 15
L5CBF:              DEFB "S"
L5CC0:              DEFB 81, 0F, C4, 15
L5CC4:              DEFB "R"
L5CC5:              DEFB F4, 09, C4, 15
L5CC9:              DEFB "P"
L5CCA:              DEFB 80, 

;
; BASIC program, variables, etc.
;
; This is PROG, the start of the basic program. 
; 001E is line 30.
; 0x10 (16 bytes in the BASIC first program line
;
L5CCB:              DEFB 00, 1E, 10, 00, EF
L5CD0:              DEFB "\"\""
L5CD2:              DEFB AF
L5CD3:              DEFB "24576"
L5CD8:              DEFB 0E, 00, 00, 00
L5CDC:              DEFB "`"
L5CDD:              DEFB 00, 0D, 00
L5CE0:              DEFB "("
L5CE1:              DEFB 0E, 00, F9, C0
L5CE5:              DEFB "26592"
L5CEA:              DEFB 0E, 00, 00, E0
L5CEE:              DEFB "g"
L5CEF:              DEFB 00, 0D, 00
L5CF2:              DEFB "2"
L5CF3:              DEFB 13, 00, F8
L5CF6:              DEFB "\"GULPMAN\""
L5CFF:              DEFB CA
L5D00:              DEFB "1"
L5D01:              DEFB 0E, 00, 00, 01, 00, 00, 0D, 00
L5D09:              DEFB "<#"
L5D0B:              DEFB 00, F8
L5D0D:              DEFB "\"GULPCODE\""
L5D17:              DEFB AF
L5D18:              DEFB "24576"
L5D1D:              DEFB 0E, 00, 00, 00
L5D21:              DEFB "`"
L5D22:              DEFB 00
L5D23:              DEFB ",6150"
L5D28:              DEFB 0E, 00, 00, 06, 18, 00, 0D, 00
L5D30:              DEFB "F"
L5D31:              DEFB 0A, 00, EC
L5D34:              DEFB "40"
L5D36:              DEFB 0E, 00, 00
L5D39:              DEFB "("
L5D3A:              DEFB 00, 00, 0D, 80, EF
L5D3F:              DEFB "\"\""
L5D41:              DEFB 0D, 80, 00, 00, E0
L5D46:              DEFB "g"
L5D47:              DEFB 00
L5D48:              DEFB "      "
L5D4E:              DEFB 00, 00, 00
L5D51:              DEFB "`"
L5D52:              DEFB 00, 00, 03
L5D55:              DEFB "GULPCODE  "
L5D5F:              DEFB 06, 18, 00
L5D62:              DEFB "`r"
L5D64:              DEFB 80, 00, 00, 00
L5D68:              DEFB "`"

L5D69: 00           NOP
;;
;; LOTS OF NOPS IN HERE
;;
L5E2F: 00           NOP
L5E30:
; NOPS for 464 bytes
; NOP stop address = 5FFF


; Standard Spectrum special control charactersÉ
;
; 6	PRINT comma	0x06
; 7	EDIT		0x07
; 8	<-		0x08
; 9	->		0x09
; 10	v		0x0A
; 11	^		0x0B
; 12	DELETE		0x0C 
; 13	ENTER		0x0D
; 14	number		0x0E
; 15	not used	0x0F
; 16	INK control	0x10	(1 operand)
; 17	PAPER control	0x11	(1 operand)
; 18	FLASH control	0x12	(1 operand)
; 19	BRIGHT control	0x13	(1 operand)
; 20	INVERSE control	0x14	(1 operand)
; 21	OVER control	0x15	(1 operand)
; 22	AT control	0x16	(2 operands)
; 23	TAB control	0x17	(2 operands)

; User Defined Graphics (UDG) for Gulpman
;
; 'a' = Space = 0x90
; 'b' = Apple = 0x91
; 'c' = Player Graphic = 0x92
; 'd' = Angry monster = 0x93
; 'e' = Angry monster = 0x94
; 'f' = Angry monster = 0x95
; 'g' = Angry monster = 0x96
; 'h' = Happy monster = 0x97
; each monster has it's down code

map_text:
                    ; at(2, 0); ink(1), paper(5), inverse(0)
L6000:              DEFB 16, 02, 00, 10, 01, 11, 05, 14, 00
                    ; map data, 8F = filled block, 91 = UDG 'b' = apple
L6009:              DEFB 8F, 8F, 8F, 8F, 8F, 8F, 8F, 8F, 8F, 8F, 8F, 8F, 8F, 8F, 8F, 8F
L6019:              DEFB 8F, 8F, 8F, 8F, 8F, 8F, 8F, 8F, 8F, 8F, 8F, 8F, 8F, 8F, 8F, 8F
map_second_line:
L6029:              DEFB 8F, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91
L6039:              DEFB 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 8F
L6049:              DEFB 8F, 91, 8F, 8F, 8F, 8F, 8F, 8F, 8F, 8F, 8F, 8F, 8F, 8F, 8F, 8F
L6059:              DEFB 91, 8F, 8F, 8F, 8F, 8F, 8F, 8F, 8F, 8F, 8F, 8F, 8F, 8F, 91, 8F
L6069:              DEFB 8F, 91, 8F, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91
L6079:              DEFB 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 8F, 91, 8F
L6089:              DEFB 8F, 91, 8F, 91, 8F, 8F, 8F, 8F, 8F, 8F, 91, 8F, 8F, 8F, 8F, 8F
L6099:              DEFB 91, 8F, 8F, 8F, 8F, 8F, 91, 8F, 8F, 8F, 8F, 8F, 91, 8F, 91, 8F
L60A9:              DEFB 8F, 91, 8F, 91, 91, 91, 91, 91, 91, 8F, 91, 91, 91, 91, 91, 8F
L60B9:              DEFB 91, 91, 91, 91, 91, 8F, 91, 91, 91, 91, 91, 8F, 91, 8F, 91, 8F
L60C9:              DEFB 8F, 91, 8F, 91, 8F, 8F, 8F, 8F, 91, 8F, 8F, 8F, 8F, 8F, 91, 8F
L60D9:              DEFB 8F, 8F, 8F, 8F, 91, 8F, 8F, 8F, 8F, 8F, 91, 8F, 91, 8F, 91, 8F
L60E9:              DEFB 8F, 91, 8F, 91, 91, 91, 91, 91, 91, 8F, 91, 91, 91, 91, 91, 8F
L60F9:              DEFB 91, 91, 91, 91, 91, 8F, 91, 91, 91, 91, 91, 8F, 91, 8F, 91, 8F
L6109:              DEFB 8F, 91, 8F, 91, 8F, 8F, 8F, 8F, 8F, 8F, 91, 8F, 8F, 8F, 8F, 8F
L6119:              DEFB 91, 8F, 8F, 8F, 8F, 8F, 91, 8F, 8F, 8F, 8F, 8F, 91, 8F, 91, 8F
L6129:              DEFB 8F, 91, 8F, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91
L6139:              DEFB 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 8F, 91, 8F
L6149:              DEFB 8F, 91, 91, 91, 8F, 8F, 8F, 8F, 8F, 91, 8F, 8F, 8F, 8F, 8F, 8F
L6159:              DEFB 91, 8F, 8F, 8F, 8F, 8F, 8F, 91, 8F, 8F, 8F, 8F, 91, 91, 91, 8F
L6169:              DEFB 8F, 91, 8F, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91
L6179:              DEFB 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 8F, 91, 8F
L6189:              DEFB 8F, 91, 8F, 91, 8F, 8F, 8F, 8F, 8F, 8F, 91, 8F, 8F, 8F, 8F, 8F
L6199:              DEFB 91, 8F, 8F, 8F, 8F, 8F, 91, 8F, 8F, 8F, 8F, 8F, 91, 8F, 91, 8F
L61A9:              DEFB 8F, 91, 8F, 91, 91, 91, 91, 91, 91, 8F, 91, 91, 91, 91, 91, 8F
L61B9:              DEFB 91, 91, 91, 91, 91, 8F, 91, 91, 91, 91, 91, 8F, 91, 8F, 91, 8F
L61C9:              DEFB 8F, 91, 8F, 91, 8F, 8F, 8F, 8F, 91, 8F, 8F, 8F, 8F, 8F, 91, 8F
L61D9:              DEFB 8F, 8F, 8F, 8F, 91, 8F, 8F, 8F, 8F, 8F, 91, 8F, 91, 8F, 91, 8F
L61E9:              DEFB 8F, 91, 8F, 91, 91, 91, 91, 91, 91, 8F, 91, 91, 91, 91, 91, 8F
L61F9:              DEFB 91, 91, 91, 91, 91, 8F, 91, 91, 91, 91, 91, 8F, 91, 8F, 91, 8F
L6209:              DEFB 8F, 91, 8F, 91, 8F, 8F, 8F, 8F, 8F, 8F, 91, 8F, 8F, 8F, 8F, 8F
L6219:              DEFB 91, 8F, 8F, 8F, 8F, 8F, 91, 8F, 8F, 8F, 8F, 8F, 91, 8F, 91, 8F
L6229:              DEFB 8F, 91, 8F, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91
L6239:              DEFB 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 8F, 91, 8F
L6249:              DEFB 8F, 91, 8F, 8F, 8F, 8F, 8F, 8F, 8F, 8F, 8F, 8F, 8F, 8F, 8F, 8F
L6259:              DEFB 91, 8F, 8F, 8F, 8F, 8F, 8F, 8F, 8F, 8F, 8F, 8F, 8F, 8F, 91, 8F
L6269:              DEFB 8F, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91
L6279:              DEFB 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 8F
last_map_line:
L6289:              DEFB 8F, 8F, 8F, 8F, 8F, 8F, 8F, 8F, 8F, 8F, 8F, 8F, 8F, 8F, 8F, 8F
L6299:              DEFB 8F, 8F, 8F, 8F, 8F, 8F, 8F, 8F, 8F, 8F, 8F, 8F, 8F, 8F, 8F, 8F
                    ; 0xFF = terminate print_string()
L62A9:              DEFB FF

maze_letter_text:
L62AA:              DEFB 16, 01, 05
maze_letter:
L62AD:              DEFB "A"
L62AE:              DEFB FF

menu_printer_text:
L62AF:              DEFB 11, 07, 10, 00, 13, 01
L62B5:              DEFB 16, 11, 16, 17, 1F, 00, 16, 12, 16
L62BE:              DEFB " S=Save  "
L62C7:              DEFB FF

tempo_and_grade_text:
L62C8:              DEFB 16, 01, 0D
L62CB:              DEFB "5"
L62CC:              DEFB FF

tempo_number:
L62CD:              DEFB "5"
grade_number:
L62CE:              DEFB "1"

best_score_number_text:
L62CF:              DEFB 16, 01, 10
best_score_number_text_digits:
L62D2:              DEFB "00000"
L62D7:              DEFB FF

demo_mode:
L62D8:              DEFB 00	; either 00 or 'D' (44h) for demo

score_number_text:
L62D9:              DEFB 16, 01, 06
score_number_text_digits:
L62DC:              DEFB "01890"
L62E1:              DEFB FF

laser_number_text:
L62E2               DEFB 16, 01, 1C
laser_number_text_digits:
L62E5:              DEFB "20"
L62E7:              DEFB FF

lives_copy:
L62E8:              DEFB 0A

lives_number_text:
L62E9:              DEFB 16, 01, 1D
lives_number_text_digits:
L62EC:              DEFB "7"
L62ED:              DEFB FF

;
; Monster data
;
; Byte	Action
;  0    monster code (same as UDG character code)
;  1    default position in map as address
;  2    default position in map as address
;  3    monster_position in map as address
;  4    monster_position in map as address
;  5    what is under the monster? (e.g. an Apple or a space)
;  6    second choice offset if primary fails? (0=no primary/secondary, i.e. back up system off)
;  7	primary offset to move in ...
;       "Primary choice" in this case is the way we REALLY want to go towards
;       the player!
;

; monster 1 data
monster_data:
L62EE:              DEFB 93, 2A, 60, 7C, 60, 20, 00, 20

; monster 2 data
L62F6:              DEFB 94, 47, 60, 45, 60, 20, 00, 20

; monster 3 data
L62FE:              DEFB 95, 6A, 62, 3E, 61, 91, 00, E0

; monster 4 data
L6306:              DEFB 96, 87, 62, 79, 61, 20, 00, E0



; 96 is the monster UDG
monster_text:
L630E:              DEFB 16, 0D, 10, 11, 07, 10, 00, 14, 00
monster_text_object:
                    DEFB 96, FF

rewrite_after_move_text:
L6319:              DEFB 16, 0D, 11
L631C:              DEFB 11, 05, 10, 01, 13, 01
rewrite_after_move_text_object:
                    DEFB 91, FF

; This is the thing that prints the player...
player_text:
L6324:              DEFB 16, 03, 04 
L6327:              DEFB 11, 07, 10, 00, 13
L632C:              DEFB 01, 92, FF			; 92 = player graphic

; Usage out IX register (outside monster subroutines)
;
; IX = 632Ah (when not dealing with monsters)
;
; IX+10h = 633Ah = player_position_address
; IX+11h = 633Bh = player_position_address+1
; IX+12h = 633Ch = player success. Starts at 14 and decreases by 2 (bottom 0) every 1000 points earnt. Used in monster speed calculation.
; IX+1Bh = 6345h = fire key
; IX+1Dh = 6347h = offset to move player by (= direction requested to move player)
; IX+1Eh = 6348h = player speed, player_only moves every 16 game_loops
; IX+1Fh = 6349h = monster speed, only allows monsters to run on certain frames
; IX+20h = 634Ah = ?? - something to do with demo mode (auto-player) offset
; IX+83h = IX-7Dh = 62ADh = maze_letter
; IX+8Ch = IX-74h = 62B6h = AT control for menu_printer_text
; IX+92h = IX-6Eh = 62BCh = AT control for menu_printer_text
; IX+95h = IX-6Bh = 62BFh = Menu letter for menu_printer_text
; IX+0A0h = IX-60h = 62CAh = AT control for tempo_and_grade_text
; IX+0A1h = IX-5Fh = 62CBh = Number for tempo_and_grade_text
; IX+0A3h = IX-5Dh = 62CDh = tempo_number
; IX+0A4h = IX-5Ch = 62CEh = grade_number
; IX+0AEh = IX-52h = 62D8h = demo_mode
; IX+0BBh = IX-45h = 62E5h = laser_number_text_digits
; IX+0BCh = IX-44h = 62E6h = laser_number_text_digits+1
; IX+0C2h = IX-3Eh = 62ECh = lives_number_text_digits
; 


; blank space text
; used when the player moves to blank out the apples
blank_space_text
L632F:              DEFB 16, 03, 04
L6332:              DEFB 11, 05, 13, 01, 10, 01
L6338:              DEFB " "
L6339:              DEFB FF

player_position_address:
L633A:              DEFB "-`"

L633C:              DEFB 0C	; (IX+12h) player success. Starts at 14 and decreases by 2 (bottom 0) every 1000 points earnt. Used in monster speed calculation. 
key_control_map:
L633D:              DEFB "7"
L633E:              DEFB E0
L633F:              DEFB "6",20
L6341:              DEFB "5"
L6342:              DEFB FF
L6343:              DEFB "8"
L6344:              DEFB 01
L6345:              DEFB "9" ; (IX+1Bh) - fire key
L6346:              DEFB 00

L6347:              DEFB 00	; (IX+1Dh) offset to move player by (= direction requested to move player)
L6348:              DEFB 03	; (IX+1Eh) player speed, player_only moves every 16 game_loops
L6349:              DEFB 08	; (IX+1Fh) monster speed, only allows monsters to run on certain frames
L634A:              DEFB E0	; (IX+20h) demo player direction to move

set_colour_text:
                    ; paper=7, ink=0, bright=1
L634B               DEFB 11, 07, 10, 00, 13, 01, FF

;
; laser next block offsets has the map data (and attribute data) steps for right, left, down, up
; Next to each of these is stored the ...
laser_next_block_offsets:
L6352:              DEFB 01, 00, FF, 00
L6356:              DEFB 20, 00, E0, 00

L635A: 00           NOP
L635B: 00           NOP
L635C: 00           NOP
L635D: 00           NOP
L635E: 00           NOP
L635F: 00           NOP

;
; Blank Graphic, UDG 'a' 0x90
;

user_defined_graphics:
L6360:              DEFB 00
L6361:              DEFB 00
L6362:              DEFB 00
L6363:              DEFB 00
L6364:              DEFB 00
L6365:              DEFB 00
L6366:              DEFB 00
L6367:              DEFB 00

;
; Apple Graphic, UDG 'b' 0x91
; 
apple_graphic:
L6368:              DEFB 04
L6369:              DEFB 08
L636A:              DEFB 3C
L636B:              DEFB 52
L636C:              DEFB 42
L636D:              DEFB 52
L636E:              DEFB 3C
L636F:              DEFB 00

;
; Player Graphic, UDG 'c' 0x92
;
L6370:              DEFB 1C
L6371:              DEFB 1C
L6372:              DEFB 49
L6373:              DEFB 3E
		            DEFB 08
L6375:              DEFB 08
L6376:              DEFB 14
L6377:              DEFB 14

;
; Sad monster graphic (1 of 4 identical), UDG 'd' 0x93
;
L6378:              DEFB 7E
L6379:              DEFB BD
L637A:              DEFB 99
L637B:              DEFB FF
L637C:              DEFB FF
L637D:              DEFB 81
L637E:              DEFB BD
L637F:              DEFB 7E

;
; Sad monster graphic (2 of 4 identical), UDG 'e' 0x94
;
L6380:              DEFB 7E
L6381:              DEFB BD
L6382:              DEFB 99
L6383:              DEFB FF
L6384:              DEFB FF
L6385:              DEFB 81
L6386:              DEFB BD
L6387:              DEFB 7E

;
; Sad monster graphic (3 of 4 identical), UDG 'f' 0x95
;
L6388:              DEFB 7E
L6389:              DEFB BD
L638A:              DEFB 99
L638B:              DEFB FF
L638C:              DEFB FF
L638D:              DEFB 81
L638E:              DEFB BD
L638F:              DEFB 7E

;
; Sad monster graphic (4 of 4 identical), UDG 'g' 0x96
;
L6390:              DEFB 7E
L6391:              DEFB BD
L6392:              DEFB 99
L6393:              DEFB FF
L6394:              DEFB FF
L6395:              DEFB 81
L6396:              DEFB BD
L6397:              DEFB 7E

;
; Happy Monster Graphic, UDG 'h' 0x97
;
L6398:              DEFB 7E
L6399:              DEFB 99
L639A:              DEFB DB, FF
L639C:              DEFB BD
L639D:              DEFB 99
L639E:              DEFB C3, 7E


;
; Print from HL until 0xFF
;
print_string:
L63A0: 7E           LD A,(HL)
L63A1: FE FF        CP 0FFh
L63A3: C8           RET Z
L63A4: C5           PUSH BC
L63A5: D5           PUSH DE
L63A6: E5           PUSH HL
L63A7: D7           RST 10h		; System print Text in Register A
L63A8: E1           POP HL
L63A9: D1           POP DE
L63AA: C1           POP BC
L63AB: 23           INC HL
L63AC: 18 F2        JR 0F2h = print_string


print_string_bottom:
L63AE: FD CB 02 C6  SET 0,(IY+2) ; IY holds +ERR-NR, +2=TV FLAG, bit 0 = editing area
L63B2: CD A0 63     CALL print_string
L63B5: FD CB 02 86  RES 0,(IY+2)	; TV Flag, bit 0 = editing area print. bit 0 reset =not editing area
L63B9: C9           RET


print_main_menu:
L63BA: 3E 03        LD A,3h
L63BC: 21 EE 63     LD HL, main_menu_text
L63BF: 06 08        LD B,8h			; number of menu entries
L63C1: C5           PUSH BC
L63C2: E5           PUSH HL
L63C3: DD 77 8C     LD (IX+8Ch),A	; 632A-74h = 62B6h = AT control for menu_printer_text
L63C6: 3C           INC A
L63C7: DD 77 92     LD (IX+92h),A	; 632A-6Eh = 62BCh = AT control for menu_printer_text
L63CA: 3C           INC A
L63CB: 46           LD B,(HL)
L63CC: DD 70 95     LD (IX+95h),B	; 632A-6Bh = 62BFh = Menu letter for menu_printer_text
L63CF: 11 C1 62     LD DE,62C1h
L63D2: 01 05 00     LD BC,5h
L63D5: ED B0        LDIR
L63D7: 21 AF 62     LD HL,menu_printer_text
L63DA: F5           PUSH AF
L63DB: CD A0 63     CALL print_string
L63DE: F1           POP AF
L63DF: E1           POP HL
L63E0: 01 05 00     LD BC,5h			; goto next menu line
L63E3: 09           ADD HL,BC
L63E4: C1           POP BC
L63E5: 10 DA        DJNZ 0DAh
L63E7: 21 1B 64     LD HL,641Bh
L63EA: CD A0 63     CALL print_string
L63ED: C9           RET

;
; Various Texts - Menu
;
main_menu_text:
L63EE:              DEFB "Maze TempoGradeResetInstrDemo Play Save Quit "
L641B:              DEFB 16, 13, 16, 17, 1F, 00, FF


;
; Game Over Text
;
game_over_text:
L6422:              DEFB 16, 02, 0A, 11, 05, 10, 00, 13, 01
L642B:              DEFB " GAME OVER "
L6436:              DEFB FF
;
; New best Score Text
;
L6437:              DEFB 16, 02, 06, 11, 05, 10, 00, 13, 01
L6440:              DEFB " !!NEW BEST SCORE!! "
L6454:              DEFB FF

temp_attribute_copy:
L6455:              DEFB "ppppppxxxx8"

; -------------------------------------------------------------------------
print_maze:
L6460: DD 7E 83     LD A,(IX+83h)	; 	; 632A-7Dh = 62ADh = maze_letter (which maze)
L6463: 21 34 6D     LD HL, maze_bitmap_data-4Ch	; 0x6D80 - 0x4C
L6466: 01 4C 00     LD BC,4Ch	; 4Ch = 76 = 19 lines x 4 bytes (32 bits) wide
L6469: D6 40        SUB 40h	; 40 = @ (i.e., make A = 1) 
L646B: 09           ADD HL,BC	; remember, always increment by 1
L646C: 3D           DEC A
L646D: 20 FC        JR NZ,0FCh
L646F: EB           EX DE,HL
L6470: 21 29 60     LD HL, map_second_line
L6473: 06 13        LD B,13h	; 13h = 19 lines (24 screen lines -3 status -2 top/bottom)
L6475: C5           PUSH BC
L6476: 06 04        LD B,4h	; 4 bytes per line
L6478: C5           PUSH BC
L6479: 06 08        LD B,8h	; 8 bits per byte
L647B: 1A           LD A,(DE)
L647C: 36 91        LD (HL),91h		; UDG 'b', Apple
L647E: CB 27        SLA A
L6480: 30 02        JR NC,2h
L6482: 36 8F        LD (HL),8Fh		; Square block
L6484: 23           INC HL
L6485: 10 F5        DJNZ 0F5h
L6487: 13           INC DE
L6488: C1           POP BC
L6489: 10 ED        DJNZ 0EDh
L648B: C1           POP BC
L648C: 10 E7        DJNZ 0E7h
L648E: 21 89 62     LD HL, last_map_line
L6491: 36 FF        LD (HL),0FFh		; stop the last line being printed
L6493: E5           PUSH HL
L6494: 21 00 60     LD HL, map_text
L6497: CD A0 63     CALL print_string
L649A: E1           POP HL
L649B: 36 8F        LD (HL),8Fh			; return the last line to printing status
L649D: C9           RET


L649E: 00           NOP
L649F: 00           NOP

;
; Screen Setup Text - Top lines
;
top_line_text:
L64A0:              DEFB 16, 00, 00, 11, 02, 10, 09, 13, 00
L64A9:              DEFB "GULPMAN  "
L64B2:              DEFB 7F		; copyright symbol
L64B3:              DEFB " 1982 CAMPBELL SYSTEMS"
L64C9:              DEFB 11, 06, 10, 00, 13, 01
L64CF:              DEFB " MAZE"
L64D4:              DEFB 11, 07
text_line_maze_letter:
L64D6:              DEFB "A"
L64D7:              DEFB 11, 06
L64D9:              DEFB "  "
L64DB:              DEFB 11, 06
L64DD:              DEFB "TEMPO"
L64E2:              DEFB 11, 07
text_line_tempo_number:
L64E4:              DEFB "5"
L64E5:              DEFB 11, 06
L64E7:              DEFB "  "
L64E9:              DEFB 11, 06
L64EB:              DEFB "GRADE"
L64F0:              DEFB 11, 07
text_line_grade_number:
L64F2:              DEFB "1"
L64F3:              DEFB 11, 06
L64F5:              DEFB "  "
L64F7:              DEFB 11, 06
L64F9:              DEFB "LIVES"
L64FE:              DEFB 11, 07
L6500:              DEFB "9"
L6501:              DEFB 11, 06
L6503:              DEFB "  "
L6505:              DEFB FF
;
;
;
L6506:              DEFB 1F, 90, FF
;
; Bottom line Text
;
L6509:              DEFB 00, 

bottom_line_text:
L650A:              DEFB 16, 00, 00, 11, 01, 17, 1D, 00
L6512:              DEFB "   "
L6515:              DEFB 11, 06, 11, 06, 10, 00
L651B:              DEFB " SCORE"
L6521:              DEFB 11, 07
L6523:              DEFB "00000"
L6528:              DEFB 11, 06
L652A:              DEFB " BEST"
L652F:              DEFB 11, 07
bottom_line_best_score_text:
L6531:              DEFB "00000"
L6536:              DEFB 11, 06
L6538:              DEFB " LASERS"
L653F:              DEFB 11, 07
L6541:              DEFB "00"
L6543:              DEFB 11, 06
L6545:              DEFB "  "
L6547:              DEFB FF


L6548: 00           NOP
L6549: 00           NOP
L654A: 00           NOP
L654B: 00           NOP

;
; Get key. Return in A. 0=no key, transforms a-z to A-Z. Also Z or NZ set.
;
get_key:
L654C: 3A 08 5C     LD A,(5C08h)	; LAST K (Stores newly pressed key)
L654F: B7           OR A
L6550: C8           RET Z
L6551: FE 61        CP 61h
L6553: D8           RET C		; if upper case
L6554: D6 20        SUB 20h		; make lower case
L6556: C9           RET


L6557: 00           NOP
L6558: 00           NOP
L6559: 00           NOP
L655A: 00           NOP
L655B: 00           NOP


; -------------------------------------------------------------------------
colour_change_routine:
L655C: C3 98 6C     JP actual_colour_change_routine		; revector

; B = ?? maybe duration?
; C = length of colours to change
; HL = address of attribute data
colour_attribute_flash:
L655F: 11 55 64     LD DE,temp_attribute_copy
L6562: 06 00        LD B,0h
L6564: ED B0        LDIR
L6566: E1           POP HL
L6567: D1           POP DE
L6568: C1           POP BC
L6569: C5           PUSH BC
L656A: D5           PUSH DE
L656B: E5           PUSH HL
L656C: 58           LD E,B
L656D: 41           LD B,C
L656E: 16 58        LD D,58h
L6570: C5           PUSH BC
L6571: 7A           LD A,D
L6572: E5           PUSH HL
L6573: 77           LD (HL),A
L6574: C6 08        ADD 8h
L6576: FE 78        CP 78h
L6578: 38 02        JR C,2h
L657A: 3E 58        LD A,58h
L657C: 23           INC HL
L657D: 10 F4        DJNZ 0F4h
L657F: E1           POP HL
L6580: 06 38        LD B,38h
L6582: C5           PUSH BC
L6583: 06 00        LD B,0h
L6585: 00           NOP
L6586: 10 FD        DJNZ 0FDh
L6588: C1           POP BC
L6589: 10 F7        DJNZ 0F7h
L658B: C1           POP BC
L658C: 7A           LD A,D
L658D: C6 08        ADD 8h
L658F: 57           LD D,A
L6590: FE 78        CP 78h
L6592: 38 DC        JR C,0DCh
L6594: 1D           DEC E
L6595: 20 D7        JR NZ,0D7h
L6597: E1           POP HL
L6598: D1           POP DE
L6599: C1           POP BC
L659A: C5           PUSH BC
L659B: D5           PUSH DE
L659C: E5           PUSH HL
L659D: 11 55 64     LD DE, temp_attribute_copy
L65A0: EB           EX DE,HL
L65A1: 06 00        LD B,0h
L65A3: ED B0        LDIR
L65A5: E1           POP HL
L65A6: D1           POP DE
L65A7: C1           POP BC
L65A8: C9           RET

L65A9: 00           NOP

increase_maze_letter:
L65AA: 21 21 58     LD HL,5821h		; attribute data
L65AD: 01 04 01     LD BC,104h		; 
L65B0: CD 5C 65     CALL colour_change_routine 
L65B3: 21 AD 62     LD HL, maze_letter
L65B6: 34           INC (HL)
L65B7: 7E           LD A,(HL)
L65B8: FE 50        CP 50h		; 'P' (one after last maze)
L65BA: 20 02        JR NZ,2h
L65BC: 36 41        LD (HL),41h		; 'A'
L65BE: 21 AA 62     LD HL, maze_letter_text
L65C1: CD A0 63     CALL print_string
L65C4: CD 80 6B     CALL change_maze_colour
L65C7: CD 60 64     CALL print_maze
L65CA: C9           RET

L65CB: 00           NOP
L65CC: 00           NOP
L65CD: 00           NOP
L65CE: 00           NOP
L65CF: 00           NOP

;
; Returns column in A and line in B
;
calculate_line_and_column:
L65D0: E5           PUSH HL
L65D1: B7           OR A
L65D2: 01 C9 5F     LD BC,5FC9h		; why isn't this 0x6000 - 64 ?
L65D5: ED 42        SBC HL,BC
L65D7: 7D           LD A,L
L65D8: E6 1F        AND 1Fh
L65DA: 06 05        LD B,5h
L65DC: CB 3C        SRL H
L65DE: CB 1D        RR L
L65E0: 10 FA        DJNZ 0FAh
L65E2: 45           LD B,L
L65E3: E1           POP HL
L65E4: C9           RET

L65E5: 00           NOP
L65E6: 00           NOP
L65E7: 00           NOP

; monster routine to move a monster to a map address in HL
move_monster_to_specified_position:
L65E8: C5           PUSH BC
L65E9: E5           PUSH HL
L65EA: E5           PUSH HL
L65EB: DD 66 04     LD H,(IX+4h)	; get current position in map
L65EE: DD 6E 03     LD L,(IX+3h)	; get current position in map
L65F1: CD 6D 6D     CALL fetch_under_monster
L65F4: 77           LD (HL),A		; put what was underneath back in the map (assuming not an apple)
L65F5: 32 22 63     LD (rewrite_after_move_text_object),A
L65F8: CD D0 65     CALL calculate_line_and_column      ; B=line A=column
L65FB: 21 1B 63     LD HL,rewrite_after_move_text+2
L65FE: 77           LD (HL),A		; position to write to on screen
L65FF: 2B           DEC HL
L6600: 70           LD (HL),B
L6601: 2B           DEC HL
L6602: CD A0 63     CALL print_string	; replace the monster in the maze
L6605: E1           POP HL			; get the requested position back
L6606: 7E           LD A,(HL)		; what's at that location
L6607: DD 77 05     LD (IX+5h),A	; store it in the monster data
L660A: DD 74 04     LD (IX+4h),H	; store the requested position in the monster data
L660D: DD 75 03     LD (IX+3h),L	; store the requested position in the monster data
L6610: DD 7E 00     LD A,(IX+0h)	; get the monster code
L6613: 77           LD (HL),A		; store that in the map
L6614: 32 17 63     LD (monster_text_object),A	; store it in the print routine
L6617: CD D0 65     CALL calculate_line_and_column      ; B=line A=column
L661A: 21 10 63     LD HL,monster_text+2
L661D: 77           LD (HL),A		; position to write to on the screen
L661E: 2B           DEC HL
L661F: 70           LD (HL),B
L6620: 2B           DEC HL
L6621: CD A0 63     CALL print_string	; print monster in the new position
L6624: E1           POP HL
L6625: C1           POP BC
L6626: C9           RET

L6627: 00           NOP

print_monsters:
L6628: 21 EF 62     LD HL,62EFh
L662B: 06 04        LD B,4h
L662D: 7E           LD A,(HL)
L662E: 23           INC HL
L662F: 4E           LD C,(HL)
L6630: 23           INC HL
L6631: 77           LD (HL),A
L6632: 23           INC HL
L6633: 71           LD (HL),C
L6634: 23           INC HL
L6635: 36 20        LD (HL),20h
L6637: 11 04 00     LD DE,4h
L663A: 19           ADD HL,DE
L663B: 10 F0        DJNZ 0F0h

move_all_monsters_to_default_locations:
L663D: DD E5        PUSH IX			; save IX whilst we use it for something else
L663F: DD 21 EE 62  LD IX, monster_data
L6643: 06 04        LD B,4h			; there are 4 monsters
L6645: DD 66 02     LD H,(IX+2h)	; the default location (address in map)
L6648: DD 6E 01     LD L,(IX+1h)
L664B: CD E8 65     CALL move_monster_to_specified_position
L664E: DD 36 06 00  LD (IX+6h),0h	; default control data
L6652: DD 36 07 00  LD (IX+7h),0h	; default control data
L6656: 11 08 00     LD DE,8h		; the monster data for each monster is 8 bytes
L6659: DD 19        ADD IX,DE
L665B: 10 E8        DJNZ 0E8h
L665D: DD E1        POP IX
L665F: C9           RET


L6660: 00           NOP
L6661: 00           NOP

print_man_init_position:
L6662: 21 59 61     LD HL,6159h		; position of man
print_man_set_position:
L6665: 22 3A 63     LD (player_position_address),HL	; load position?
L6668: 36 92        LD (HL),92h		; man graphic into maze
L666A: CD D0 65     CALL calculate_line_and_column      ; B=line A=column
L666D: 21 26 63     LD HL, player_text+2
L6670: 77           LD (HL),A
L6671: 2B           DEC HL
L6672: 70           LD (HL),B
L6673: 2B           DEC HL
L6674: CD A0 63     CALL print_string
L6677: C9           RET

; get map cell value with horizontal offset
; INPUT: 
;        HL = position address in map
;         A = offset value (1 or -1)
get_map_cell_at_HL_with_offset_in_A:
L6678: C5           PUSH BC
; we want BC to be either 1 or -1, 16 bit wide (i.e. 1 or 0xFFFF)
L6679: 4F           LD C,A
L667A: 06 00        LD B,0h
L667C: 17           RLA
L667D: 30 01        JR NC,1h = not_negative_skip
L667F: 05           DEC B
not_negative_skip:
L6680: 09           ADD HL,BC
L6681: 7E           LD A,(HL)
L6682: C1           POP BC
L6683: C9           RET

L6684: 00           NOP
L6685: 00           NOP


; IN: A = offset requested.
; returns Z flag set if cannot move, NZ if have moved.
request_move_monster:
L6686: DD 66 04     LD H,(IX+4h)
L6689: DD 6E 03     LD L,(IX+3h)
L668C: CD 78 66     CALL get_map_cell_at_HL_with_offset_in_A
L668F: FE 8F        CP 8Fh		; filled block
L6691: C8           RET Z
L6692: FE 93        CP 93h		; angry monster. A-93, C if A<93
L6694: 38 06        JR C,6h = can_move_monster
L6696: FE 97        CP 97h		; happy monster. A-97. C if A<97, NC if A>=97
L6698: 30 02        JR NC,2h = can_move_monster
L669A: 97           SUB A
L669B: C9           RET
can_move_monster:
L669C: CD E8 65     CALL move_monster_to_specified_position
L669F: 97           SUB A
L66A0: 3C           INC A
L66A1: C9           RET

; IX is the specific monster data in this subroutine
;
; Because of the way this is set up, it will always try to go toward the player,
; but if that fails it will step twice in a different directions (favouring 
; perpendicular) twice before it re-evaluates the situation.
process_monster_movement:
L66A2: DD 7E 06     LD A,(IX+6h)
L66A5: B7           OR A
L66A6: 28 18        JR Z,18h = PM_no_move_decided
L66A8: DD 7E 07     LD A,(IX+7h)	; primary direction
L66AB: CD 86 66     CALL request_move_monster
L66AE: 28 05        JR Z,5h	= PM_cannot_move
L66B0: DD 36 06 00  LD (IX+6h),0h	; done movement, clear out intention
L66B4: C9           RET
PM_cannot_move:
L66B5: DD 7E 06     LD A,(IX+6h)	; second direction
L66B8: CD 86 66     CALL request_move_monster
L66BB: C0           RET NZ			; moved, good, finish
L66BC: DD 36 06 00  LD (IX+6h),0h	; clear out ... no intention

PM_no_move_decided:
L66C0: DD 66 04     LD H,(IX+4h)	; current position
L66C3: DD 6E 03     LD L,(IX+3h)
L66C6: CD D0 65     CALL calculate_line_and_column      ; B=line A=column
L66C9: 50           LD D,B
L66CA: 5F           LD E,A
L66CB: 2A 3A 63     LD HL,(player_position_address)
L66CE: CD D0 65     CALL calculate_line_and_column      ; B=line A=column
L66D1: 4F           LD C,A	; after: C=player column 
;
; Check the column we are in to start. This is logical because the screen is
; wider than high, and therefore getting in the right part of the screen is
; not a bad strategy (although maybe moving to the lesser of the row and column 
; is a more effective strategy on an open field - on a closed playing area like a 
; maze it depends up the maze layout).
;
L66D2: 7B           LD A,E	; after: A=monster column
L66D3: B9           CP C	; A-C, Carry if A<C, NC if A>=C. So NC if monster_col >= player_col
L66D4: 30 06        JR NC,6h = PM_monster_column_greater_or_equal_to_player_column

; player > monster column
L66D6: 3E 01        LD A,1h		; want monster to move right
L66D8: CD 86 66     CALL request_move_monster		; ask him to do that
L66DB: C0           RET NZ	; if success, quit

PM_monster_column_greater_or_equal_to_player_column:
; to get here monster >= player columns *OR* the way right is BLOCKED.
L66DC: 79           LD A,C	; after: A=player_column, E=monster_column
L66DD: BB           CP E	; A-E, carry if A<E. NC if A>=E. So NC if player_col >= monster_col
L66DE: 30 06        JR NC,6h = PM_player_column_gte_monster_column
	; That previous line is interesting:
	; 1. In the case that we skipped the move-right clause because mc >= pc, then 
	;    the test here (C if pc < mc) here will succeed (unless pc=mc) and drop 
	;    through to the move-left clause, which is what you'd expect.
	; 2. In the case that we are blocked right, then we know mc < pc, but we can't 
	;    go that way. So this clause will ALWAYS jump and never try to move left.
	;    That's sort of what you'd expect, but is non-obvious from the code, since
	;    NC is used with reversed notation.
L66E0: 3E FF        LD A,0FFh ; move left
L66E2: CD 86 66     CALL request_move_monster
L66E5: C0           RET NZ	; quit if successful

PM_player_column_gte_monster_column:
; to get here the columns must be the same *OR* the way left is BLOCKED.
L66E6: 7A           LD A,D	; A = monster line
L66E7: B8           CP B	; carry if monster_line < player_line
L66E8: 30 06        JR NC,6h = PM_ml_gte_pl
; here the monster is at a lower line than the player, so wants to move down...
L66EA: 3E 20        LD A,20h
L66EC: CD 86 66     CALL request_move_monster
L66EF: C0           RET NZ	; return if ok
; ml >= pl OR blocked down
PM_ml_gte_pl:
L66F0: 78           LD A,B	; A = player line
L66F1: BA           CP D	; carry if player_line < monster_line
L66F2: 30 06        JR NC,6h = PM_pl_gte_ml
	;
	; Notes about second compare/jump in column apply to line here as well
	;
L66F4: 3E E0        LD A,0E0h	; try upwards
L66F6: CD 86 66     CALL request_move_monster
L66F9: C0           RET NZ
; lines the same or way is blocked upwards
PM_pl_gte_ml:
; So we've tried the direct approach, and realistically the way to the player 
; is blocked in both the line(=row) and column directions towards the player.
;
; Therefore we fall back on a different method.
;
L66FA: 21 2D 67     LD HL,monster_move_offsets_1
L66FD: 78           LD A,B ; A = player line, D = monster line
L66FE: BA           CP D	
L66FF: 20 0A        JR NZ,0Ah = PM_lines_not_the_same

L6701: 7B           LD A,E	; A = monster_column, C = player_column
L6702: B9           CP C	; A-C, carry if A<C if monster_column< player_column
L6703: 3E 01        LD A,1h	; right
L6705: 38 02        JR C,2h	; move right if monster_column < player_column
L6707: 3E FF        LD A,0FFh	; left if player_column <= monster_column
L6709: 18 09        JR 9h = PM_lines_are_the_same

PM_lines_not_the_same:
L670B: 3E E0        LD A,0E0h	; upwards? (good if pl < ml)
L670D: 38 02        JR C,2h	; A-D, carry if A<C, player_line < monster_line, jump if pl < ml
L670F: 3E 20        LD A,20h	; no pl >= ml ... so go down.
L6711: 21 31 67     LD HL, monster_move_offsets_2

PM_lines_are_the_same:
; swap the values in the first two entries of the table
;
; This *might* have several effects: specific monsters don't make the same
; decision if they are in the same predicament. It also might solve 'stuck' problems
; for a specific monster.
L6714: 56           LD D,(HL)
L6715: 23           INC HL
L6716: 5E           LD E,(HL)
L6717: 72           LD (HL),D
L6718: 2B           DEC HL
L6719: 73           LD (HL),E
; load the logical desired direction into the primary register to try first
L671A: DD 77 07     LD (IX+7h),A
; search for a second choice if primary fails
L671D: 06 04        LD B,4h	; 4 options for movement, step though each one
PM_next_attempt:
L671F: 7E           LD A,(HL)
L6720: DD 77 06     LD (IX+6h),A	; try this way next time as well
L6723: E5           PUSH HL
L6724: CD 86 66     CALL request_move_monster
L6727: E1           POP HL
L6728: C0           RET NZ	; if we can move, success!
L6729: 23           INC HL	; next entry
L672A: 10 F3        DJNZ 0F3h = PM_next_attempt
; look, we can't move at all and are blocked in with walls (or monsters) ... live with it...
L672C: C9           RET

; used when the lines are the same ... we want to go up or down really ... but 
; if that fails try right and left.
monster_move_offsets_1:
L672D:              DEFB E0, 20, 01, FF

; used when the lines aren't the same ... try lines then columns for movement.
monster_move_offsets_2:
L6731:              DEFB FF, 01 E0 20


L6735: 00           NOP
L6736: 00           NOP
L6737: 00           NOP

demo_player_control:
L6738: DD 7E 20     LD A,(IX+20h)	; 632A+20=demo player direction to move
L673B: DD 77 1D     LD (IX+1Dh),A	; 632A+1D= copy offset to move player by
L673E: 21 9A 67     LD HL,move_data
;
; find the line that matches the current direction
;
find_line_loop:
L6741: BE           CP (HL)	; remember this is CP A, (HL).
L6742: 28 06        JR Z,6h = got_the_line	; if equal to previous movement direcion, this line is it
L6744: 01 05 00     LD BC,5h
L6747: 09           ADD HL,BC
L6748: 18 F7        JR 0F7h = find_line_loop
got_the_line:
;
; We mix up the 2, 3, 4 (by rolling them) randomly (but approx every other 
; frame), probably to give a more interesting movement.
; 
L674A: 23           INC HL
       FD CB 3E 46  BIT 0,(IY+3E) ; Frames bit 0,. random number bit
L674F: 28 0A        JR Z,0Ah = skip2
L6751: 7E           LD A,(HL)		; 2nd
L6752: 23           INC HL
L6753: 46           LD B,(HL)		; 3rd
L6754: 23           INC HL
L6755: 4E           LD C,(HL)		; 4th
L6756: 70           LD (HL),B		; 3rd goes to 4th
L6757: 2B           DEC HL
L6758: 77           LD (HL),A		; 2st goes to 3rd
L6759: 2B           DEC HL
L675A: 71           LD (HL),C		; 4th goes to 2nd

skip2:
L675B: 01 00 04     LD BC,400h		; four times around the loop. Also C=0.

; we repeat this 4 times: this means we access the 2nd to the 5th
demo_decide_what_to_do_loop:
L675E: 7E           LD A,(HL)		; fetch the second offset
L675F: 57           LD D,A			; D = current direction offset
L6760: E5           PUSH HL
L6761: 2A 3A 63     LD HL,(player_position_address)
L6764: CD 78 66     CALL get_map_cell_at_HL_with_offset_in_A
; what is at this player position + offset?

L6767: FE 91        CP 91h		; apple
L6769: 20 01        JR NZ,1h = demo_no_apple
L676B: 4A           LD C,D

demo_no_apple:
L676C: FE 8F        CP 8Fh		; block
L676E: 28 1E        JR Z,1Eh = this_way_is_a_block_so_try_another
; not a block
L6770: F5           PUSH AF
L6771: 79           LD A,C
L6772: B7           OR A
L6773: 20 01        JR NZ,1h = skip4
L6775: 4A           LD C,D				; make sure C = chosen offset
skip4:
L6776: F1           POP AF
L6777: FE 93        CP 93h	; A-93, C if A<93
L6779: 38 13        JR C,13h = not_a_monster
L677B: FE 97        CP 97h
L677D: 30 0F        JR NC,0Fh = not_a_monster ; NC if A >=97
; block is a monster
L677F: 79           LD A,C
L6780: ED 44        NEG			; A = -A. Go the opposite way
L6782: 4F           LD C,A
L6783: C5           PUSH BC
L6784: D5           PUSH DE
       FD CB 3E 46  BIT 0,(IY+3E) ; Frames bit 0,. random number bit
L6789: CC D4 6A     CALL Z,shoot_lasers
L678C: D1           POP DE
L678D: C1           POP BC

not_a_monster:
this_way_is_a_block_so_try_another:
L678E: E1           POP HL
L678F: 23           INC HL			; next 'column'
L6790: 10 CC        DJNZ 0CCh = demo_decide_what_to_do_loop

; at this point we have scanned through all the directions (in columns 2-5)
; C contains our attempt the best option
; Towards an apple or away from a monster is prioritised
; wall directions are ignored
; Because of the way they are ordered and the fact that you eat apples
; on your way, that we are unlikely to reverse (since that is is column 5). The
; 4 lines in the table ensure once we've decided to change direction we don't 
; reverse unless necessary since the that is in the new lines last column.
; 
; It's not entirely clear what the effect the randomisation of column 2-4 does.

L6792: 79           LD A,C
L6793: DD 77 1D     LD (IX+1Dh),A	; 632A+1D= 6347h = offset to move player by
L6796: DD 77 20     LD (IX+20h),A	; 632A+20=demo player direction to move
L6799: C9           RET

;
; Each line in the table reflects a primary direction to move in...
;
move_data:
L679A:              DEFB 01, 01, E0, 20, FF
L679F:              DEFB FF, 20, FF, E0, 01 
L67A4:              DEFB E0, 01, FF, E0, 20, 
L67A9:              DEFB 20, FF, 20, 01, E0
L67AE:              DEFB 00						; end of list

L67AF: 00           NOP

flash_border:
L67B0: C5           PUSH BC
L67B1: 06 80        LD B,80h
L67B3: C5           PUSH BC
L67B4: 3E 06        LD A,6h
flash_border_port_setting:
L67B6: 06 D6        LD B,0D6h		; the is altered depending upon what size the 
L67B8: D3 FE        OUTA (0FEh)		; set the border colour
L67BA: F5           PUSH AF
L67BB: F1           POP AF
L67BC: 10 FA        DJNZ 0FAh
L67BE: 3D           DEC A
L67BF: 20 F5        JR NZ,0F5h
L67C1: C1           POP BC
L67C2: 10 EF        DJNZ 0EFh
L67C4: C1           POP BC
L67C5: 3E A5        LD A,0A5h
L67C7: D3 FE        OUTA (0FEh)		; set the border colour back to 
L67C9: C9           RET

print_laser_text_and_beep:
L67CA: 21 4B 63     LD HL, set_colour_text
L67CD: CD A0 63     CALL print_string
L67D0: 21 E2 62     LD HL, laser_number_text
L67D3: CD AE 63     CALL print_string_bottom
L67D6: 06 01        LD B,1h
L67D8: CD B0 6B     CALL three_rising_tones
L67DB: C9           RET


L67DC: 00           NOP
L67DD: 00           NOP
L67DE: 00           NOP
L67DF: 00           NOP

program_entry:
L67E0: 21 60 63     LD HL, user_defined_graphics
L67E3: 22 7B 5C     LD (5C7Bh),HL	; 0x5c7B is the address of the UDG system variable
L67E6: 21 D2 62     LD HL, best_score_number_text_digits
L67E9: 11 31 65     LD DE, bottom_line_best_score_text
L67EC: 01 04 00     LD BC,4h
L67EF: ED B0        LDIR		; copy
L67F1: 3A AD 62     LD A,(maze_letter)
L67F4: 32 D6 64     LD (text_line_maze_letter),A
L67F7: 3A CD 62     LD A,(tempo_number)
L67FA: 32 E4 64     LD (text_line_tempo_number),A
L67FD: C3 F0 77     JP more_init

;
; Main Game Start, but not the entry point
;
main_game_start:
L6800: DD 21 2A 63  LD IX,632Ah
       FD CB 02 86  RES 0,(IY+02)	; TV Flag, bit 0 = editing area print. bit 0 reset =not editing area
L6808: 21 A0 64     LD HL, top_line_text
L680B: CD A0 63     CALL print_string
L680E: 21 0A 65     LD HL, bottom_line_text
L6811: CD AE 63     CALL print_string_bottom
L6814: CD 4B 6D     CALL print_instructions
L6817: CD 60 64     CALL print_maze
L681A: CD BA 63     CALL print_main_menu

mgs_loop:
L681D: CD 4C 6C     CALL pause_get_key
L6820: FE 53        CP 53h		; key is 'S' for save?
L6822: C8           RET Z
L6823: FE 49        CP 49h		; key is 'I' for instructions?
L6825: 28 ED        JR Z,0EDh
L6827: FE 54        CP 54h		; key is 'T' for tempo change?
L6829: 20 27        JR NZ,27h = try_grade
; we change tempo here
L682B: 21 28 58     LD HL,5828h	; attribute location address
L682E: 01 05 01     LD BC,105h
L6831: CD 5C 65     CALL colour_change_routine
L6834: 21 CD 62     LD HL,tempo_number
L6837: DD 36 A0 0D  LD (IX+0A0h),0Dh	; 632A-60h = 62CAh = AT control for tempo_and_grade_text
common_grade_tempo_change:
L683B: 00           NOP
L683C: 00           NOP
L683D: 00           NOP
L683E: 34           INC (HL)
L683F: 7E           LD A,(HL)
L6840: FE 3A        CP 3Ah			; 3A = '9' + 1
L6842: 38 02        JR C,2h	; C if A<3Ah, i.e. jump if tempo is not '9' + 1.
L6844: 3E 31        LD A,31h		; reset temp to '1'
; print tempo/grade
L6846: 77           LD (HL),A	; store back in variable
L6847: DD 77 A1     LD (IX+0A1h),A	; 632A-5F = 62CBh = Number for tempo_and_grade_text
L684A: 21 C8 62     LD HL,tempo_and_grade_text
L684D: CD A0 63     CALL print_string
L6850: 18 CB        JR 0CBh=mgs_loop

try_grade:
L6852: FE 47        CP 47h		; key is 'G' for grade change?
L6854: 20 12        JR NZ,12h=try_maze_change
L6856: 21 30 58     LD HL,5830h
L6859: 01 05 01     LD BC,105h
L685C: CD 5C 65     CALL colour_change_routine
L685F: 21 CE 62     LD HL,grade_number
L6862: DD 36 A0 15  LD (IX+0A0h),15h	; 632A-60h = 62CAh = AT control for tempo_and_grade_text
L6866: 18 D3        JR 0D3 = common_grade_tempo_change
try_maze_change:
L6868: FE 4D        CP 4Dh		; key is 'M' for maze change?
L686A: 20 05        JR NZ,5h
L686C: CD AA 65     CALL increase_maze_letter
L686F: 18 A9        JR 0A9h
L6871: FE 52        CP 52h		; key is 'R' for reset high score?
L6873: 20 38        JR NZ,38h
L6875: 21 EC 5A     LD HL,5AECh
L6878: 01 04 03     LD BC,304h
L687B: CD 5C 65     CALL colour_change_routine
L687E: 21 D2 62     LD HL, best_score_number_text_digits
L6881: 06 05        LD B,5h
L6883: 36 30        LD (HL),30h		; write '0' into best score
L6885: 23           INC HL
L6886: 10 FB        DJNZ 0FBh
L6888: 21 CF 62     LD HL, best_score_number_text
L688B: CD AE 63     CALL print_string_bottom
L688E: 00           NOP
L688F: 00           NOP
L6890: 00           NOP
L6891: 18 8A        JR 8Ah

print_key_instructions:
L6893: 21 CD 6C     LD HL,6CCDh		; destination, part of key_hint_text (i.e. key instructions)
L6896: 11 3D 63     LD DE,key_control_map ; with keys in
L6899: 06 05        LD B,5h
L689B: 1A           LD A,(DE)
L689C: 77           LD (HL),A		; copy key
L689D: 13           INC DE
L689E: 13           INC DE		; 2 apart in key control map
L689F: C5           PUSH BC
L68A0: 01 0A 00     LD BC,0Ah		; 10 apart in key_hint_text
L68A3: 09           ADD HL,BC
L68A4: C1           POP BC
L68A5: 10 F4        DJNZ 0F4h
L68A7: 21 C4 6C     LD HL, key_hint_text
L68AA: C3 A6 6C     JP print_and_game_start_beep

L68AD: 21 D8 62     LD HL,demo_mode
L68B0: FE 50        CP 50h			; key is 'P' for play game?
L68B2: 20 0D        JR NZ,0Dh = no_p_for_play
L68B4: 97           SUB A
L68B5: 77           LD (HL),A			; store 0 into 62D8 == demo_mode
L68B6: CD 93 68     CALL print_key_instructions

pre_run_game:
L68B9: 01 09 03     LD BC,309h
L68BC: CD 5C 65     CALL colour_change_routine
L68BF: 18 2C        JR 2Ch = init_game

; not 'P' for play
no_p_for_play:
L68C1: FE 44        CP 44h			; key is 'D' for demo?
L68C3: 20 06        JR NZ,6h
L68C5: 77           LD (HL),A			; store 'D' into 62D8 == demo_mode
L68C6: 21 D6 59     LD HL,59D6h		; colour attribute to flash (1D6h=470=line 14, column 22 (both zero based))
L68C9: 18 EE        JR 0EEh = pre_run_game

; not D or P
L68CB: 3E 44        LD A,44h	; demo can be auto-pressed for the next time around.
L68CD: BE           CP (HL)
L68CE: 20 09        JR NZ,9h = not_auto_demo
L68D0: 06 08        LD B,8h
inform_user_auto_demo_loop:
L68D2: CD 4C 65     CALL get_key
L68D5: 28 04        JR Z,4h = do_auto_demo_start
L68D7: 36 00        LD (HL),0h
not_auto_demo:
L68D9: 18 B6        JR 0B6h

; flash demo mode 8 times, allow for key to cancel
do_auto_demo_start:
L68DB: C5           PUSH BC
L68DC: E5           PUSH HL
L68DD: 21 D6 59     LD HL,59D6h			; colour attribute to flash
L68E0: 01 09 01     LD BC,109h
L68E3: CD 5C 65     CALL colour_change_routine
L68E6: E1           POP HL
L68E7: C1           POP BC
L68E8: 10 E8        DJNZ 0E8h = inform_user_auto_demo_loop
L68EA: CD AA 65     CALL increase_maze_letter	; autodemo always switches mazes on each new run (after first demo maze)

init_game:
L68ED: CD 60 64     CALL print_maze
L68F0: CD 80 6C     CALL game_chime
L68F3: 21 E1 5A     LD HL,5AE1h
L68F6: 01 05 02     LD BC,205h
L68F9: CD 5C 65     CALL colour_change_routine
L68FC: 21 DC 62     LD HL, score_number_text_digits
L68FF: 06 05        LD B,5h
init_score_loop:
L6901: 36 30        LD (HL),30h		; write '0' into score
L6903: 23           INC HL
L6904: 10 FB        DJNZ 0FBh = init_score_loop
L6906: 21 D9 62     LD HL, score_number_text
L6909: CD AE 63     CALL print_string_bottom	; write score onto screen
L690C: 21 F6 5A     LD HL,5AF6h
L690F: 01 06 02     LD BC,206h
L6912: CD 5C 65     CALL colour_change_routine	; flash score
; these two lines make lasers = 20
L6915: DD 36 BB 32  LD (IX+0BBh),32h	; 632A-45h=62E5h=laser_number_text_digits = '2'
L6919: DD 36 BC 30  LD (IX+0BCh),30h	; 632A-44h = 62E6h = laser_number_text_digits+1 = '0'
L691D: 21 E2 62     LD HL, laser_number_text
L6920: CD AE 63     CALL print_string_bottom	; write laser into screen
L6923: 21 38 58     LD HL,5838h
L6926: 01 05 02     LD BC,205h
L6929: CD 5C 65     CALL colour_change_routine	; flash laser
; lives = 9
L692C: DD 36 C2 39  LD (IX+0C2h),39h		; 	; 632A-3Eh = 62ECh = lives_number_text_digits = '9'
L6930: 21 E9 62     LD HL, lives_number_text
L6933: CD A0 63     CALL print_string
L6936: CD 62 66     CALL print_man_init_position
L6939: CD 28 66     CALL print_monsters
L693C: DD 36 12 0E  LD (IX+12h),0Eh	; 632A+12=Player Success. Starts at 14 and goes down.

; -------------------------------------------------------------------------
game_loop:
L6940: 3E 3A        LD A,3Ah			; 3A = 10
L6942: DD 96 A3     SUB (IX+0A3h)		; 632A-5Dh = 62CDh = tempo_number 
L6945: 47           LD B,A			
	; tempo = '1', B = 10-1 = 9 (slow, 9 inner loops run)
	; tempo = '9', B = 10-9 = 1 (fast, only one inner loop run)
; delay loop for tempo
delay_loop_outer:
L6946: 0E E0        LD C,0E0h
delay_loop_inner:
L6948: 0D           DEC C
L6949: 20 FD        JR NZ,0FDh = delay_loop_inner
L694B: 10 F9        DJNZ 0F9h = delay_loop_outer

;
; Exit key part
;
L694D: CD 66 6C     CALL clear_last_key_if_no_key_pressed
L6950: FE 58        CP 58h		; if 'X' pressed, end game
L6952: CA F4 6B     JP Z,end_game

;
; This is the player movement part
;
L6955: 06 04        LD B,4h		; loops
L6957: 21 3D 63     LD HL,key_control_map
key_check_loop
L695A: BE           CP (HL)		; this key?
L695B: 23           INC HL
L695C: 4E           LD C,(HL)		; movement
L695D: 28 04        JR Z,4h = key_check_exit	; found
L695F: 23           INC HL
L6960: 10 F8        DJNZ 0F8h = key_check_loop
L6962: 48           LD C,B		; will be 0
key_check_exit:

L6963: DD 71 1D     LD (IX+1Dh),C	; 632A+1D= 6347h = offset to move player by
L6966: DD BE 1B     CP (IX+1Bh)		; 632A+1B=fire key '9'
L6969: 20 03        JR NZ,3h
L696B: CD D4 6A     CALL shoot_lasers	; notice we can do this EVEN IF we are in demo mode :-)

L696E: DD 35 1E     DEC (IX+1Eh)	; 632A+1E= player speed, decrease player speed counter
L6971: 20 3D        JR NZ,3Dh = skip_player_movement ; allow to play if 0
L6973: 00           NOP
L6974: DD 36 1E 10  LD (IX+1Eh),10h	; 632A+1E= reset player speed so that player gets to move every 16 game loops

       DD CB AE 76  BIT 6,(IX+AEh)	; 632A-52h = 62D8h = demo_mode ('D' (44h) for demo)
L697C: C4 38 67     CALL NZ,demo_player_control

L697F: 2A 3A 63     LD HL,(player_position_address)
L6982: E5           PUSH HL
L6983: D1           POP DE
L6984: DD 7E 1D     LD A,(IX+1Dh)	; 632A+1D= 6347h = offset to move player by
L6987: CD 78 66     CALL get_map_cell_at_HL_with_offset_in_A
L698A: FE 8F        CP 8Fh			; filled block, i.e. wall
L698C: 28 16        JR Z,16h
L698E: F5           PUSH AF
L698F: EB           EX DE,HL
L6990: 36 20        LD (HL),20h		; write a space where the player was in the map data
L6992: CD D0 65     CALL calculate_line_and_column      ; B=line A=column
L6995: 21 31 63     LD HL,blank_space_text+2
L6998: 77           LD (HL),A
L6999: 2B           DEC HL
L699A: 70           LD (HL),B
L699B: 2B           DEC HL
L699C: CD A0 63     CALL print_string	; write a space on the screen
L699F: EB           EX DE,HL
L69A0: CD 65 66     CALL print_man_set_position	; write the man on the screen
L69A3: F1           POP AF
L69A4: FE 91        CP 91h		; apple
L69A6: 20 05        JR NZ,5h
L69A8: CD 3B 6D     CALL make_eat_sound
L69AB: 18 03        JR 3h
L69AD: CD 84 6A     CALL check_if_monsters_have_got_player

skip_player_movement:
L69B0: DD 35 1F     DEC (IX+1Fh)	; 632A+1F = 6349h = decrease monster speed
L69B3: 20 27        JR NZ,27h = skip_monster_movement	; don't run unless zero
; reset monster speed
; this is made up of several components... grade, 
L69B5: 3E 40        LD A,40h
L69B7: DD 96 A4     SUB (IX+0A4h)	; 632A-5Ch = 62CEh = grade_number '1' (31h) to '9' (39h)
                                    ; A result will be 15 for easy and 7 for hard
L69BA: 87           ADD A			; A=A*2, so easy is 30 and 14 is hard.
L69BB: DD 86 12     ADD (IX+12h)	; 632A+12=Player Success. 14 at start. 0 at lowest.
									; A total = 44 or 14.
L69BE: C6 08        ADD 8h			; Give the player more advantage. 
									; A total = 52 or 22.
L69C0: DD 77 1F     LD (IX+1Fh),A	; 632A+1F=monster speed, load with new calculated value

; so player is always faster than monsters. Slightly at worst case (37%). 325% at best case.

L69C3: DD E5        PUSH IX
L69C5: DD 21 EE 62  LD IX, monster_data
L69C9: 06 04        LD B,4h
mon_loop:
L69CB: C5           PUSH BC
L69CC: CD A2 66     CALL process_monster_movement
L69CF: 01 08 00     LD BC,8h
L69D2: DD 09        ADD IX,BC
L69D4: C1           POP BC
L69D5: 10 F4        DJNZ 0F4h = mon_loop
L69D7: DD E1        POP IX
L69D9: CD 84 6A     CALL check_if_monsters_have_got_player

skip_monster_movement:
L69DC: C3 40 69     JP 6940h = game_loop
; -------------------------------------------------------------------------

L69DF: 00           NOP

add_10_to_score:
L69E0: 21 DF 62     LD HL,score_number_text_digits+4	; 10's coloumn
L69E3: 06 04        LD B,4h		; 4 digits (units are always zero)
L69E5: 7E           LD A,(HL)
L69E6: FE 39        CP 39h		'9'	; A-39 ... C if A<39
L69E8: 38 08        JR C,8h = digit_to_increment		; if C not '9'
L69EA: 36 30        LD (HL),30h	; adding one makes this digit column zero
L69EC: 2B           DEC HL		; go to high digit
L69ED: 10 F6        DJNZ 0F6h	; loop back 
L69EF: C3 F4 6B     JP end_game	; max score ends the game (!), but lower digits already zerod. So best will be 90000.
digit_to_increment:
L69F2: 34           INC (HL)
L69F3: 21 4B 63     LD HL, set_colour_text
L69F6: CD AE 63     CALL print_string_bottom
L69F9: 21 D9 62     LD HL, score_number_text	; print score
L69FC: CD AE 63     CALL print_string_bottom
L69FF: 3E 02        LD A,2h
L6A01: B8           CP B		; A-B, C if A<B ... 
L6A02: 38 0D        JR C,0Dh = not_1000s_change ; if the 1000s column has been changed
L6A04: DD 7E 12     LD A,(IX+12h)	; 632A+12=633Ch Player success. Get
L6A07: D6 02        SUB 2h			; A-2, C if A<2, i.e. 0. (Since init is 14).
L6A09: 38 06        JR C,6h			; if A = 0 or 1 then no sound and no back store
L6A0B: DD 77 12     LD (IX+12h),A	; 632A+12=Player success. Store back in updated.
L6A0E: CD D9 77     CALL bonus_1000_score_sound
not_1000s_change:
;
; Check if there are any Apple's left
;
screen_clear_of_apples_check:
L6A11: 21 2A 60     LD HL,map_second_line+1
L6A14: 01 60 02     LD BC,260h
L6A17: 3E 91        LD A,91h		; apple
L6A19: ED B1        CPIR		; check if there are apples
L6A1B: C8           RET Z		; if there is one, return
L6A1C: 21 F4 62     LD HL, monster_data+6
L6A1F: 16 04        LD D,4h
next_compare:
L6A21: BE           CP (HL)		; apple under monster?
L6A22: C8           RET Z
L6A23: 01 08 00     LD BC,8h
L6A26: 09           ADD HL,BC
L6A27: 15           DEC D
L6A28: 20 F7        JR NZ,0F7h = next_compare

L6A2A: 21 6F 6A     LD HL, bonus_set_position_text
L6A2D: CD A0 63     CALL print_string
L6A30: 01 02 10     LD BC,1002h
bonus_print_loop:
L6A33: 3E 07        LD A,7h
L6A35: 91           SUB C
L6A36: 4F           LD C,A
L6A37: 32 74 6A     LD (bonus_text+1),A		; bonus text paper colour
L6A3A: 21 73 6A     LD HL, bonus_text
L6A3D: CD A0 63     CALL print_string
L6A40: 10 F1        DJNZ 0F1h = bonus_print_loop

L6A42: CD B0 67     CALL flash_border

; adjust number of lasers
L6A45: 16 0A        LD D,0Ah
L6A47: 21 E6 62     LD HL,laser_number_text_digits+1
L6A4A: 7E           LD A,(HL)
L6A4B: FE 39        CP 39h	; '9'
L6A4D: 38 0F        JR C,0Fh = laser_increase_lower_than_9
L6A4F: 36 30        LD (HL),30h	; '0'
L6A51: 2B           DEC HL
L6A52: 7E           LD A,(HL)
L6A53: FE 39        CP 39h	; '9'
L6A55: 38 07        JR C,7h = laser_increase_lower_than_9
L6A57: 23           INC HL
L6A58: 36 39        LD (HL),39h	; '9'
L6A5A: CD CA 67     CALL print_laser_text_and_beep
L6A5D: C9           RET
laser_increase_lower_than_9:
L6A5E: 34           INC (HL)
L6A5F: CD CA 67     CALL print_laser_text_and_beep
L6A62: 15           DEC D
L6A63: 20 E2        JR NZ,0E2h
L6A65: CD 60 64     CALL print_maze
L6A68: CD 28 66     CALL print_monsters
L6A6B: CD 62 66     CALL print_man_init_position
L6A6E: C9           RET

bonus_set_position_text:
L6A6F:              DEFB 16, 0A, 00, FF

bonus_text:
L6A73:              DEFB 11, 02, 10, 09, 13, 01
L6A79:              DEFB "BONUS!!!"
L6A81:              DEFB FF

L6A82: 00           NOP
L6A83: 00           NOP

; -----------------------------------------
check_if_monsters_have_got_player:
L6A84: 21 F1 62     LD HL, monster_data+3
L6A87: 06 04        LD B,4h
monster_check_loop:
L6A89: C5           PUSH BC
L6A8A: E5           PUSH HL
L6A8B: DD 7E 10     LD A,(IX+10h)	; 632A+10=  player position (MSB)
L6A8E: BE           CP (HL)
L6A8F: 23           INC HL
L6A90: 20 37        JR NZ,37h = not_same_position
L6A92: DD 7E 11     LD A,(IX+11h)	; 632A+11=  player position+1 (LSB)
L6A95: BE           CP (HL)
L6A96: 20 31        JR NZ,31h = not_same_position
L6A98: 21 38 58     LD HL,5838h			; attribute data
L6A9B: 01 05 01     LD BC,105h
L6A9E: CD 1C 6D     CALL show_happy_monster
L6AA1: 21 4B 63     LD HL, set_colour_text
L6AA4: CD A0 63     CALL print_string
L6AA7: 21 EC 62     LD HL, lives_number_text_digits
L6AAA: 35           DEC (HL)			; one less life, in 
L6AAB: 21 E9 62     LD HL, lives_number_text	; print the number of lives
L6AAE: CD A0 63     CALL print_string
L6AB1: 2B           DEC HL			; life copy
L6AB2: 7E           LD A,(HL)
L6AB3: FE 30        CP 30h			; if it's '0' zero, it's the end of the game
L6AB5: 20 06        JR NZ,6h = lost_a_life_not_dead
L6AB7: E1           POP HL
L6AB8: E1           POP HL
L6AB9: E1           POP HL
L6ABA: C3 F4 6B     JP end_game

lost_a_life_not_dead:
L6ABD: CD 3D 66     CALL move_all_monsters_to_default_locations
L6AC0: 2A 3A 63     LD HL,(player_position_address)
L6AC3: CD 65 66     CALL print_man_set_position
L6AC6: CD 11 6A     CALL screen_clear_of_apples_check

not_same_position:
L6AC9: E1           POP HL
L6ACA: 01 08 00     LD BC,8h		; 8 bytes per monster
L6ACD: 09           ADD HL,BC
L6ACE: C1           POP BC
L6ACF: 10 B8        DJNZ 0B8h = monster_check_loop
L6AD1: C9           RET


L6AD2: 00           NOP
L6AD3: 00           NOP

shoot_lasers:
L6AD4: 3E 30        LD A,30h
L6AD6: 21 E5 62     LD HL,laser_number_text_digits
L6AD9: BE           CP (HL)
L6ADA: 23           INC HL
L6ADB: 20 02        JR NZ,2h = laser_skip
L6ADD: BE           CP (HL)
L6ADE: C8           RET Z		; no lasers to fire :-(
laser_skip:
L6ADF: 7E           LD A,(HL)
L6AE0: FE 30        CP 30h
L6AE2: 20 03        JR NZ,3h	; bottom digit is zero?
L6AE4: 36 39        LD (HL),39h
L6AE6: 2B           DEC HL

L6AE7: 35           DEC (HL)	; decrease number of lasers

;
; make laser lines
;
L6AE8: 11 52 63     LD DE,laser_next_block_offsets
L6AEB: 06 04        LD B,4h		; 4 directions simulaneously for laser

laser_loop:
L6AED: 1A           LD A,(DE)	; get offset
L6AEE: 4F           LD C,A
L6AEF: 97           SUB A		
L6AF0: 13           INC DE		; move to location store
L6AF1: 12           LD (DE),A	; clear location store
L6AF2: 2A 3A 63     LD HL,(player_position_address)

laser_loop2:
L6AF5: 79           LD A,C
L6AF6: CD 78 66     CALL get_map_cell_at_HL_with_offset_in_A
L6AF9: FE 8F        CP 8Fh			; filled block (i.e. wall)
L6AFB: 28 14        JR Z,14h = laser_hit_wall
L6AFD: C5           PUSH BC
L6AFE: 01 C9 07     LD BC,7C9h		; convert from map position to attribute position
L6B01: B7           OR A			; clear carry flag
L6B02: ED 42        SBC HL,BC
L6B04: F5           PUSH AF
L6B05: 7E           LD A,(HL)		; copy attribute
L6B06: D6 10        SUB 10h			; subtract red from paper colour
L6B08: 77           LD (HL),A		; store attribute
L6B09: F1           POP AF
L6B0A: 09           ADD HL,BC		; restore map position (address)
L6B0B: C1           POP BC
L6B0C: FE 93        CP 93h		; 93h = sad monster, CP = A-93h, therefore anything below 93 will cause carry
L6B0E: 38 E5        JR C,0E5h = laser_loop2	; stop here if hit monster, loop if not

L6B10: 12           LD (DE),A	; store final monster hit
laser_hit_wall:
L6B11: 13           INC DE
L6B12: 10 D9        DJNZ 0D9h = laser_loop

;
; make beeping noises and wait a bit
;
L6B14: CD CA 67     CALL print_laser_text_and_beep
laser_delay2:
L6B17: C5           PUSH BC
L6B18: 06 00        LD B,0h
laser_delay:
L6B1A: 00           NOP
L6B1B: 00           NOP
L6B1C: 10 FC        DJNZ 0FCh = laser_delay
L6B1E: C1           POP BC
L6B1F: 10 F6        DJNZ 0F6h = laser_delay2

;
; Remove laser lines
;
L6B21: 11 52 63     LD DE,laser_next_block_offsets
L6B24: 06 04        LD B,4h
L6B26: 1A           LD A,(DE)
L6B27: 4F           LD C,A
L6B28: 2A 3A 63     LD HL,(player_position_address)
L6B2B: 79           LD A,C
L6B2C: CD 78 66     CALL get_map_cell_at_HL_with_offset_in_A
L6B2F: FE 8F        CP 8Fh
L6B31: 28 12        JR Z,12h
L6B33: C5           PUSH BC
L6B34: 01 C9 07     LD BC,7C9h
L6B37: B7           OR A			; clear carry
L6B38: ED 42        SBC HL,BC
L6B3A: 7E           LD A,(HL)
L6B3B: C6 10        ADD 10h		; remove laser colour by subtracting 
L6B3D: 77           LD (HL),A
L6B3E: 09           ADD HL,BC
L6B3F: C1           POP BC
L6B40: 7E           LD A,(HL)
L6B41: FE 93        CP 93h
L6B43: 38 E6        JR C,0E6h
L6B45: 13           INC DE
L6B46: 13           INC DE
L6B47: 10 DD        DJNZ 0DDh
L6B49: 00           NOP

;
; This goes though any laser hits of monsters and resets them to default positions
;
L6B4A: 06 04        LD B,4h
L6B4C: 21 53 63     LD HL,laser_next_block_offsets+1	; where recorded 
L6B4F: 7E           LD A,(HL)		; get the data
L6B50: B7           OR A			; set flags
L6B51: 28 21        JR Z,21h = laser_no_monster_to_get	; if zero nothing to do
L6B53: E5           PUSH HL
L6B54: C5           PUSH BC
L6B55: DD E5        PUSH IX
L6B57: DD 21 EE 62  LD IX, monster_data
laser_next_monster:
L6B5B: DD BE 00     CP (IX+0h)		; is the monster at this position?
L6B5E: 28 07        JR Z,7h = this_monster_here 
L6B60: 01 08 00     LD BC,8h		; step to next monster
L6B63: DD 09        ADD IX,BC
L6B65: 18 F4        JR 0F4h = laser_next_monster
this_monster_here:
L6B67: DD 66 02     LD H,(IX+2h)
L6B6A: DD 6E 01     LD L,(IX+1h)	; load default location
L6B6D: CD E8 65     CALL move_monster_to_specified_position	; move to this location
L6B70: DD E1        POP IX
L6B72: C1           POP BC
L6B73: E1           POP HL
laser_no_monster_to_get:
L6B74: 23           INC HL
L6B75: 23           INC HL
L6B76: 10 D7        DJNZ 0D7h
;
; make sure no key is pressed after the laser is shot
;
L6B78: 97           SUB A		; A = 0 = no key
L6B79: 32 08 5C     LD (5C08h),A	; Store 'no key' in LAST K (Stores newly pressed key)
L6B7C: C9           RET


L6B7D: 00           NOP
L6B7E: 00           NOP
L6B7F: 00           NOP



change_maze_colour:
L6B80: CD 10 6D     CALL copy_best_score_number_to_bottom_line_text
;
; Uses the lowest bits of the 50Hz Frame counter as a random number...

L6B83: 3A 78 5C     LD A,(5C78h)	; Frames: 3 bytes. Least significant first.
L6B86: E6 07        AND 7h			; bottom 3 bits
L6B88: 3C           INC A			; make it 1-8
L6B89: 21 5B 6D     LD HL,maze_colour_table-2
this_loop:
L6B8C: 23           INC HL
L6B8D: 23           INC HL
L6B8E: 3D           DEC A			; make it 0-7
L6B8F: 20 FB        JR NZ,0FBh = this_loop
L6B91: 7E           LD A,(HL)		; get paper colour
L6B92: 32 06 60     LD (map_text+6),A
L6B95: 32 33 63     LD (blank_space_text+4),A
L6B98: 32 1D 63     LD (rewrite_after_move_text+4),A
L6B9B: 23           INC HL			; get ink colour
L6B9C: 7E           LD A,(HL)
L6B9D: 32 04 60     LD (map_text+4),A
L6BA0: 32 0E 65     LD (bottom_line_text+4),A
L6BA3: 32 1F 63     LD (rewrite_after_move_text+6),A
L6BA6: 21 0A 65     LD HL, bottom_line_text
L6BA9: CD AE 63     CALL print_string_bottom
L6BAC: C9           RET

L6BAD: 00           NOP
L6BAE: 00           NOP
L6BAF: 00           NOP

three_rising_tones:
L6BB0: E5           PUSH HL
L6BB1: 21 00 05     LD HL,500h
L6BB4: CD C7 6B     CALL short_beep
L6BB7: 21 00 04     LD HL,400h
L6BBA: CD C7 6B     CALL short_beep
L6BBD: 21 40 03     LD HL,340h
L6BC0: CD C7 6B     CALL short_beep
L6BC3: 10 EC        DJNZ 0ECh
L6BC5: E1           POP HL
L6BC6: C9           RET

short_beep:
L6BC7: C5           PUSH BC
L6BC8: D5           PUSH DE
L6BC9: DD E5        PUSH IX
L6BCB: 11 20 00     LD DE,20h
L6BCE: CD B5 03     CALL 3B5h		; ROM BEEPER routine
L6BD1: DD E1        POP IX
L6BD3: D1           POP DE
L6BD4: C1           POP BC
L6BD5: C9           RET

death_beep:
L6BD6: C5           PUSH BC
L6BD7: D5           PUSH DE
L6BD8: E5           PUSH HL
L6BD9: DD E5        PUSH IX
L6BDB: 06 C0        LD B,0C0h
L6BDD: 21 00 01     LD HL,100h
L6BE0: 11 02 00     LD DE,2h
L6BE3: E5           PUSH HL
L6BE4: C5           PUSH BC
L6BE5: CD B5 03     CALL 3B5h		; ROM BEEPER routine
L6BE8: C1           POP BC
L6BE9: E1           POP HL
L6BEA: 23           INC HL
L6BEB: 10 F3        DJNZ 0F3h
L6BED: DD E1        POP IX
L6BEF: E1           POP HL
L6BF0: D1           POP DE
L6BF1: C1           POP BC
L6BF2: C9           RET


L6BF3: 00           NOP

end_game:
L6BF4: 21 22 64     LD HL,game_over_text
L6BF7: CD A0 63     CALL print_string
L6BFA: 06 03        LD B,3h
L6BFC: 21 00 03     LD HL,300h
L6BFF: CD C7 6B     CALL short_beep
L6C02: 21 00 06     LD HL,600h
L6C05: CD C7 6B     CALL short_beep
L6C08: 10 F2        DJNZ 0F2h
L6C0A: 11 D2 62     LD DE, best_score_number_text_digits
L6C0D: 21 DC 62     LD HL, score_number_text_digits
L6C10: 06 04        LD B,4h
L6C12: 1A           LD A,(DE)
L6C13: BE           CP (HL)
L6C14: 38 09        JR C,9h
L6C16: 20 04        JR NZ,4h
L6C18: 23           INC HL
L6C19: 13           INC DE
L6C1A: 10 F6        DJNZ 0F6h
L6C1C: C3 1A 68     JP 681Ah
L6C1F: 21 DC 62     LD HL, score_number_text_digits
L6C22: 11 D2 62     LD DE, best_score_number_text_digits
L6C25: 01 04 00     LD BC,4h
L6C28: ED B0        LDIR
L6C2A: 21 37 64     LD HL,6437h
L6C2D: CD A0 63     CALL print_string
L6C30: 06 04        LD B,4h
L6C32: C5           PUSH BC
L6C33: CD B0 6B     CALL three_rising_tones
L6C36: C1           POP BC
L6C37: 10 F9        DJNZ 0F9h
L6C39: 21 4B 63     LD HL, set_colour_text
L6C3C: CD A0 63     CALL print_string
L6C3F: 21 CF 62     LD HL, best_score_number_text
L6C42: CD AE 63     CALL print_string_bottom
L6C45: CD B0 67     CALL flash_border
L6C48: 18 D2        JR 0D2h
L6C4A: 00           NOP
L6C4B: 00           NOP

; Clear the key
; Pause a short while
; Get the key
pause_get_key:
L6C4C: 97           SUB A		; A = 0 = no key
L6C4D: 32 08 5C     LD (5C08h),A	; Store 'no key' in LAST K (Stores newly pressed key)
L6C50: 06 80        LD B,80h
L6C52: C5           PUSH BC
L6C53: 06 00        LD B,0h
L6C55: 10 FE        DJNZ 0FEh
L6C57: C1           POP BC
L6C58: 10 F8        DJNZ 0F8h
L6C5A: C3 4C 65     JP get_key

even_more_init:
L6C5D: 3A CE 62     LD A,(grade_number)
L6C60: 32 F2 64     LD (text_line_grade_number),A
L6C63: C3 00 68     JP main_game_start

clear_last_key_if_no_key_pressed:
L6C66: C5           PUSH BC
L6C67: D5           PUSH DE
L6C68: E5           PUSH HL
L6C69: CD 8E 02     CALL 28Eh		; ROM keyboard scanning routine
L6C6C: 14           INC D
L6C6D: 20 07        JR NZ,7h = key_skip	; if D is not 0xFF then return
L6C6F: 1C           INC E
L6C70: 20 04        JR NZ,4h = key_skip	; if E is not 0xFF then return 
L6C72: 97           SUB A		; A = 0 = no key
L6C73: 32 08 5C     LD (5C08h),A	; Store 'no key' in LAST K (Stores newly pressed key)
key_skip:
L6C76: E1           POP HL
L6C77: D1           POP DE
L6C78: C1           POP BC
L6C79: C3 4C 65     JP get_key

L6C7C: 00           NOP
L6C7D: 00           NOP
L6C7E: 00           NOP
L6C7F: 00           NOP

game_chime:
L6C80: 21 4B 63     LD HL, set_colour_text
L6C83: CD A0 63     CALL print_string
L6C86: 06 03        LD B,3h
game_chime_beep_loop:
L6C88: 21 00 02     LD HL,200h
L6C8B: CD C7 6B     CALL short_beep
L6C8E: 21 80 02     LD HL,280h
L6C91: CD C7 6B     CALL short_beep
L6C94: 10 F2        DJNZ 0F2h	= game_chime_beep_loop
L6C96: C9           RET


L6C97: 00           NOP

;
actual_colour_change_routine:
L6C98: C5           PUSH BC
L6C99: D5           PUSH DE
L6C9A: E5           PUSH HL
L6C9B: 21 80 02     LD HL,280h
L6C9E: CD C7 6B     CALL short_beep
L6CA1: E1           POP HL
L6CA2: E5           PUSH HL
L6CA3: C3 5F 65     JP colour_attribute_flash

print_and_game_start_beep:
L6CA6: CD A0 63     CALL print_string
L6CA9: 06 06        LD B,6h
L6CAB: 21 00 04     LD HL,400h
L6CAE: CD C7 6B     CALL short_beep
L6CB1: C5           PUSH BC
L6CB2: 06 00        LD B,0h
L6CB4: C5           PUSH BC
L6CB5: 06 00        LD B,0h
L6CB7: 10 FE        DJNZ 0FEh
L6CB9: C1           POP BC
L6CBA: 10 F8        DJNZ 0F8h
L6CBC: C1           POP BC
L6CBD: 10 EC        DJNZ 0ECh
L6CBF: 21 16 5A     LD HL,5A16h		; colour attribute area
L6CC2: C9           RET


L6CC3: 00           NOP

key_hint_text:
L6CC4:              DEFB 16, 03, 01, 11, 07, 10, 01, 13, 01
L6CCD:              DEFB "7=up   "
L6CD4:              DEFB 16, 04, 01
L6CD7:              DEFB "6=down "
L6CDE:              DEFB 16, 05, 01
L6CE1:              DEFB "5=left "
L6CE8:              DEFB 16, 06, 01
L6CEB:              DEFB "8=right"
L6CF2:              DEFB 16, 07, 01
L6CF5:              DEFB "9=laser"
L6CFC:              DEFB 16, 08, 01
L6CFF:              DEFB "X=exit "
L6D06:              DEFB FF

L6D07: 00           NOP
L6D08: 00           NOP
L6D09: 00           NOP
L6D0A: 00           NOP
L6D0B: 00           NOP
L6D0C: 00           NOP
L6D0D: 00           NOP
L6D0E: 00           NOP
L6D0F: 00           NOP

copy_best_score_number_to_bottom_line_text:
L6D10: 21 D2 62     LD HL, best_score_number_text_digits
L6D13: 11 31 65     LD DE, bottom_line_best_score_text
L6D16: 01 04 00     LD BC,4h
L6D19: ED B0        LDIR
L6D1B: C9           RET


;
; Show happy monster
;
show_happy_monster:
L6D1C: 2A 3A 63     LD HL,(player_position_address)
L6D1F: CD D0 65     CALL calculate_line_and_column      ; B=line A=column
L6D22: 21 32 6D     LD HL,happy_monster_text+2	; position
L6D25: 77           LD (HL),A
L6D26: 2B           DEC HL
L6D27: 70           LD (HL),B
L6D28: 2B           DEC HL
L6D29: CD A0 63     CALL print_string		; show happy monster
L6D2C: CD D6 6B     CALL death_beep
L6D2F: C9           RET


; 0x97 = happy monster

happy_monster_text:
L6D30:              DEFB 16, 0C, 03, 11 07 10, 00, 13, 01, 97, FF     

make_eat_sound:
L6D3B: 21 E0 00     LD HL,0E0h
L6D3E: 11 02 00     LD DE,2h
L6D41: DD E5        PUSH IX
L6D43: CD B5 03     CALL 3B5h		; ROM BEEPER routine
L6D46: DD E1        POP IX
L6D48: C3 E0 69     JP add_10_to_score

print_instructions:
L6D4B: 21 F4 71     LD HL, instructions_text
L6D4E: CD A0 63     CALL print_string
L6D51: CD 4C 6C     CALL pause_get_key
L6D54: B7           OR A
L6D55: 28 FA        JR Z,0FAh		; wait for key
L6D57: 23           INC HL		; do to next instructions
L6D58: 7E           LD A,(HL)
L6D59: 3C           INC A		; is this an FF as well?
L6D5A: 20 F2        JR NZ,0F2h		; if not, print the next set of instructions
L6D5C: C9           RET

; 0=black, 1=blue, 2=red, 3=magenta, 4=green, 5=cyan, 6=yellow, 7=white
maze_colour_table:
L6D5D:              DEFB 06, 02		; yellow, red
L6D5F:              DEFB 07, 03		; white, magenta
L6D61:              DEFB 05, 01		; cyan, blue
L6D62:              DEFB 07, 04		; white, green
L6D65:              DEFB 06, 00		; yellow, black
L6D67:              DEFB 07, 01		; white, blue
L6D69:              DEFB 06, 03		; yellow, magenta
L6D6B:              DEFB 07, 02		; white, red


; fetch under monster
fetch_under_monster:
L6D6D: DD 7E 05     LD A,(IX+5h)
L6D70: FE 92        CP 92h		; 92 = man graphic. carry set if A-92 is negative, i.e. A < 92. Carry clear if A>=92.
L6D72: 38 02        JR C,2h=skipx	; skip if space or apple (or 0x8F = wall)
L6D74: 3E 20        LD A,20h	; return a space if it's not a space or Apple
skipx:
L6D76: C9           RET



L6D77: 00           NOP
L6D78: 00           NOP
L6D79: 00           NOP
L6D7A: 00           NOP
L6D7B: 00           NOP
L6D7C: 00           NOP
L6D7D: 00           NOP
L6D7E: 00           NOP
L6D7F: 00           NOP

;
; The maze bitmaps
;
; There are A to O (i.e. 15)
; Each are 19 x 4 = 76 bytes long
; Total 1140 bytes
; 0x6d80 to 0x71f4

maze_bitmap_data:
L6D80:              DEFB 80, 00, 00, 01, BF, FF, 7F, FD, A0, 00, 00, 05, AF, DF, 7D, F5
L6D90:              DEFB A0, 41, 04, 15, AF, 7D, F7, D5, A0, 41, 04, 15, AF, DF, 7D, F5
L6DA0:              DEFB A0, 00, 00, 05, 8F, BF, 7E, F1, A0, 00, 00, 05, AF, DF, 7D, F5
L6DB0:              DEFB A0, 41, 04, 15, AF, 7D, F7, D5, A0, 41, 04, 15, AF, DF, 7D, F5
L6DC0:              DEFB A0, 00, 00, 05, BF, FF, 7F, FD, 80, 00, 00, 01, 88, 80, 01, 11
L6DD0:              DEFB AA, BF, FD, 55, AA, 80, 01, 55, AA, FF, 7F, 55, AA, 80, 01, 55
L6DE0:              DEFB A2, 3F, FC, 45, AA, 80, 01, 55, AA, FF, 7F, 55, AA, 80, 01, 55
L6DF0:              DEFB 88, FF, 7F, 11, AA, 80, 01, 55, AA, FF, 7F, 55, AA, 80, 01, 55
L6E00:              DEFB A2, 3F, FC, 45, AA, 80, 01, 55, AA, FF, 7F, 55, AA, 80, 01, 55
L6E10:              DEFB AA, BF, FD, 55, 88, 80, 01, 11, A0, 20, FC, 01, 8F, AE, 01, FF
L6E20:              DEFB AF, AF, F4, 07, AF, AF, F7, F7, AF, A0, 17, F7, A1, BF, D7, F1
L6E30:              DEFB BD, BF, D7, FD, 81, 80, 50, 01, FF, FF, 07, FF, 88, 00, 50, 1F
L6E40:              DEFB AB, FF, 57, DF, AA, 07, 57, DF, AA, F0, 57, DF, AA, FF, D2, 1F
L6E50:              DEFB A2, C0, DA, DF, BE, 1E, DA, C1, BF, FE, DA, DD, BF, FE, DA, 1D
L6E60:              DEFB 80, 00, C3, FD, 80, 00, 00, 01, BB, BF, 7E, EF, A0, A1, 42, 83
L6E70:              DEFB AA, AD, 5A, AB, AA, 80, 00, AB, AA, AD, 5A, AB, AA, 21, 42, AB
L6E80:              DEFB AA, BF, 7E, AB, AA, 80, 00, AB, 8A, BF, 7E, AB, AA, 80, 00, AB
L6E90:              DEFB AA, BF, 7E, AB, AA, A1, 42, 2B, AA, AD, 5A, AB, AA, 80, 00, AB
L6EA0:              DEFB AA, AD, 5A, AB, A0, A1, 42, 83, BB, BF, 7E, EF, 80, 00, 00, 01
L6EB0:              DEFB 81, 10, 08, 81, B5, 57, EA, AD, B5, 54, 2A, AD, B5, 55, EA, AD
L6EC0:              DEFB 85, 55, 0A, A1, FD, 55, EA, BD, 81, 54, 0A, 81, BF, 55, FA, FD
L6ED0:              DEFB 80, 45, 02, 01, BF, DD, 7B, FD, 80, 40, 22, 01, BF, 5F, AA, FD
L6EE0:              DEFB 81, 50, 2A, 81, FD, 57, AA, BD, 85, 50, AA, A1, B5, 57, AA, AD
L6EF0:              DEFB B5, 54, 2A, AD, B5, 57, EA, AD, 81, 10, 08, 81, A2, 11, 11, 11
L6F00:              DEFB AA, D5, 55, 55, AA, D5, 55, 55, 88, D5, 54, 45, AA, 84, 45, 55
L6F10:              DEFB AA, D5, 55, 55, AA, F7, FD, 55, AA, 80, 01, 55, AA, FF, EF, 55
L6F20:              DEFB AA, 80, 01, 55, AA, F7, FD, 55, AA, 80, 01, 55, AA, BF, EF, 55
L6F30:              DEFB AA, A2, AB, 55, AA, 88, 89, 55, A2, 2A, AB, 11, AA, AA, AB, 55
L6F40:              DEFB AA, A2, 23, 55, 88, 88, A8, 45, 80, 00, 00, 01, AF, FF, 7F, F5
L6F50:              DEFB A8, 00, 00, 15, AA, FF, FF, 55, AA, 80, 01, 55, AA, AF, F5, 55
L6F60:              DEFB AA, A8, 15, 55, AA, AA, 55, 55, AA, AA, 55, 55, 8A, AA, 55, 51
L6F70:              DEFB AA, AA, 55, 55, AA, AB, D5, 55, AA, A0, 05, 55, AA, BF, FD, 55
L6F80:              DEFB AA, 00, 00, 55, AB, FF, FF, D5, A0, 00, 00, 05, BF, FF, 7F, FD
L6F90:              DEFB 80, 00, 00, 01, 80, 00, 80, 01, BF, FE, BF, FD, A0, 02, A0, 05
L6FA0:              DEFB AF, FA, AF, F5, A8, 0A, A8, 15, AF, EA, AB, F5, A0, 0A, A8, 05
L6FB0:              DEFB BF, FA, AF, FD, 80, 00, 00, 01, FF, 7F, 7F, 7F, 80, 00, 00, 01
L6FC0:              DEFB BF, FA, AF, FD, A0, 0A, A8, 05, AF, EA, AB, F5, A8, 0A, A8, 15
L6FD0:              DEFB AF, FA, AF, F5, A0, 02, A0, 05, BF, FE, BF, FD, 80, 00, 80, 01
L6FE0:              DEFB 80, 00, 00, 01, BA, BA, DD, 5D, A2, 8A, 51, 45, AE, EB, 57, 75
L6FF0:              DEFB A0, 08, 50, 05, AE, EB, 57, 75, A2, 8A, 51, 45, BA, BA, DD, 5D
L7000:              DEFB 80, 02, 00, 01, BF, FF, 7F, FD, 80, 02, 00, 01, BA, BA, DD, 5D
L7010:              DEFB A2, 8A, 51, 45, AE, EB, 57, 75, A0, 08, 50, 05, AE, EB, 57, 75
L7020:              DEFB A2, 8A, 51, 45, BA, BA, DD, 5D, 80, 00, 00, 01, 81, 00, 00, 81
L7030:              DEFB B5, DD, BB, AD, 94, 44, 22, 29, D7, 77, EE, EB, D1, 11, 88, 8B
L7040:              DEFB DD, DD, BB, BB, 84, 44, 22, 21, B7, 75, AE, ED, 81, 11, 88, 81
L7050:              DEFB BD, DC, 3B, BD, 81, 11, 88, 81, B7, 75, AE, ED, 84, 44, 22, 21
L7060:              DEFB DD, DD, BB, BB, D1, 11, 88, 8B, D7, 77, EE, EB, 94, 44, 22, 29
L7070:              DEFB B5, DD, BB, AD, 81, 00, 00, 81, 83, 1C, 1C, 61, A8, 41, 41, 0B
L7080:              DEFB AF, 5F, 7D, 7B, A1, 51, 45, 41, BD, 55, 55, 5F, 81, 55, 55, 41
L7090:              DEFB AF, 55, 55, 7D, A0, 55, 55, 01, AF, C0, 01, FD, A8, 1F, 7C, 05
L70A0:              DEFB AF, C0, 01, FD, A0, 55, 55, 01, AF, 55, 55, 7D, 81, 55, 55, 41
L70B0:              DEFB BD, 55, 55, 5F, A1, 51, 45, 41, AF, 5F, 7D, 7B, A8, 41, 41, 0B
L70C0:              DEFB 83, 1C, 1C, 61, 80, 00, 80, 01, BF, FE, FF, 7D, 80, 00, 01, 45
L70D0:              DEFB BF, FF, FD, 55, 80, 00, 05, 55, FF, 5F, F5, 55, 81, 40, 15, 15
L70E0:              DEFB D5, 57, D5, 55, D5, 54, 55, 55, D5, 55, 55, 55, D4, 55, D5, 55
L70F0:              DEFB D5, 54, 15, 41, D5, 57, F5, 7F, D5, 50, 00, 01, D5, 5F, FF, FD
L7100:              DEFB D1, 40, 00, 01, DF, 7F, FF, FD, 80, 00, 00, 01, BF, FF, FF, FD
L7110:              DEFB 80, 00, 00, 01, BD, EF, 7B, DF, A1, 01, 40, 43, AD, 7D, 5F, 5B
L7120:              DEFB A1, 01, 40, 43, BD, EF, 7B, DF, 80, 00, 00, 01, BD, EF, 7B, DF
L7130:              DEFB A0, 28, 0A, 03, AF, AF, 7A, FB, A0, 28, 0A, 03, BD, EF, 7B, DF
L7140:              DEFB 80, 00, 00, 01, BD, EF, 7B, DF, A1, 01, 40, 43, AD, 7D, 5F, 5B
L7150:              DEFB A1, 01, 40, 43, BD, EF, 7B, DF, 80, 00, 00, 01, 80, 00, 00, 01
L7160:              DEFB BD, 7F, FF, DD, A1, 40, 00, 55, AD, 5F, FF, 45, A5, 50, 01, 55
L7170:              DEFB BD, 57, FD, 5D, 81, 54, 05, 41, BD, 55, F5, 5D, A1, 55, 15, 55
L7180:              DEFB AD, 55, 55, 45, A5, 54, 55, 55, BD, 57, 75, 5D, 81, 50, 05, 41
L7190:              DEFB BD, 5F, 7D, 5D, A1, 40, 01, 55, AD, 7F, 7F, 45, A5, 00, 00, 55
L71A0:              DEFB BD, FF, 7F, DD, 80, 00, 00, 01, 80, 00, 00, 01, BF, B3, 61, FD
L71B0:              DEFB BF, B3, 61, FD, B1, B3, 61, 8D, B0, 33, 61, BD, B3, B3, 61, BD
L71C0:              DEFB B1, B3, 61, 81, BF, BF, 7D, 8F, BF, BF, 7D, 8F, 80, 00, 00, 01
L71D0:              DEFB 83, FD, FD, F9, 83, FD, FD, F9, 83, 6D, 8D, 99, 83, 6D, 8D, 99
L71E0:              DEFB BB, 6D, ED, 99, BB, 6D, ED, 99, 83, 0D, 8D, 99, 83, 0D, 8D, 99
L71F0:              DEFB 80, 00, 00, 01


;
; instruction text
;

instructions_text:
L71F4:              DEFB 11, 05, 10, 00, 13, 00, 16, 03, 00
L71FD:              DEFB "Instructions"
L7209:              DEFB 11, 07
L720B:              DEFB " Welcome to GULPMAN."
L721F:              DEFB 17, 00, 00
L7222:              DEFB "The object is to steer yourself ("
L7243:              DEFB 92		; man graphic
L7244:              DEFB ") around a maze and eat all   the food ("
L726C:              DEFB 91
L726D:              DEFB ") to get points (10  per "
L7286:              DEFB 91
L7287:              DEFB "). But you must avoid the  four grumpy chasers ("
L72B7:              DEFB 93
L72B8:              DEFB ") who onlysmile ("
L72C9:              DEFB 97
L72CA:              DEFB ") when they catch you,  whereupon you lose a life."
L72FC:              DEFB 17, 00, 00
L72FF:              DEFB " "
L7300:              DEFB 17, 00, 00
L7303:              DEFB "But you have a laser which when fired will send any "
L7337:              DEFB 93
L7338:              DEFB " in direct line back to his corner."
L735B:              DEFB 17, 00, 00
L735E:              DEFB " "
L735F:              DEFB 17, 00, 00
L7362:              DEFB "If you clear up all the "
L737A:              DEFB 91, 91, 91
L737D:              DEFB " thenyou get bonus lasers and more "
L73A0:              DEFB 91, 91
L73A2:              DEFB "to eat. But every 1000 points "
L73C0:              DEFB 93
L73C1:              DEFB " go a little faster - how nice.   "
L73E3:              DEFB 17, 00, 00, 11, 05
L73E8:              DEFB "(Any key to continue..)"
L73FF:              DEFB 11, 07, 17, 00, 00, 16, 03, 00, FF
L7408:              DEFB "You steer up/down/left/right andfire lasers using keys listed atstart of Play. Alternative keys may be POKEd."
L7475:              DEFB 17, 00, 00
L7478:              DEFB " "
L7479:              DEFB 17, 00, 00
L747C:              DEFB "A game ends when LIVES=0 or you hold down the X (exit) key."
L74B7:              DEFB 17, 00, 00
L74BA:              DEFB " "
L74BB:              DEFB 17, 00, 00
L74BE:              DEFB "The 'menu' which appears betweengames offers many facilities...  "
L74FF:              DEFB 17, 00, 00, 11, 05
L7504:              DEFB "M"
L7505:              DEFB 11, 07
L7507:              DEFB " Selects one of 15 mazes."
L7520:              DEFB 17, 00, 00
L7523:              DEFB " "
L7524:              DEFB 17, 00, 00, 11, 05
L7529:              DEFB "T"
L752A:              DEFB 11, 07
L752C:              DEFB " Sets overall game speed."
L7545:              DEFB 17, 00, 00
L7548:              DEFB " "
L7549:              DEFB 17, 00, 00, 11, 05
L754E:              DEFB "G"
L754F:              DEFB 11, 07
L7551:              DEFB " Sets the grade which is the     relative start speed of "
L758A:              DEFB 93
L758B:              DEFB "s. "
L758E:              DEFB FF, 16, 03, 00, 11, 05
L7594:              DEFB "R"
L7595:              DEFB 11, 07
L7597:              DEFB " Resets BEST back to 00000."
L75B2:              DEFB 17, 00, 00
L75B5:              DEFB " "
L75B6:              DEFB 17, 00, 00, 11, 05
L75BB:              DEFB "I"
L75BC:              DEFB 11, 07
L75BE:              DEFB " Shows these instructions."
L75D8:              DEFB 17, 00, 00
L75DB:              DEFB " "
L75DC:              DEFB 17, 00, 00, 11, 05
L75E1:              DEFB "D"
L75E2:              DEFB 11, 07
L75E4:              DEFB " Demo lets you relax and watch   the "
L7609:              DEFB 92		; man graphic
L760A:              DEFB " play all by himself. He   even changes mazes if you do    not interrupt him."
L7657:              DEFB 17, 00, 00
L765A:              DEFB " "
L765B:              DEFB 17, 00, 00, 11, 05
L7660:              DEFB "P"
L7661:              DEFB 11, 07
L7663:              DEFB " is how you Play a game."
L767B:              DEFB 17, 00, 00
L767E:              DEFB " "
L767F:              DEFB 17, 00, 00, 11, 05
L7684:              DEFB "S"
L7685:              DEFB 11, 07
L7687:              DEFB " Saves GULPMAN on tape. Note"
L76A3:              DEFB 17, 02, 00
L76A6:              DEFB "this is in 2 parts, BASIC then  a CODE block."
L76D3:              DEFB 17, 00, 00
L76D6:              DEFB " "
L76D7:              DEFB 17, 00, 00
L76DA:              DEFB "BREAK the SAVE to make any POKEsand resume with GOTO 40."
L7712:              DEFB 17, 00, 00, 11, 06, 13, 01
L7719:              DEFB "Have lots of fun !!!"
L772D:              DEFB FF, FF			; double FF terminates the instructions
L772F:              DEFB "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"

;
; This calls a lower level beeper routineÉ so its some sort of sound routine
;
bonus_1000_score_sound:
L77D9: 06 14        LD B,14h
L77DB: 21 00 03     LD HL,300h
L77DE: 11 80 03     LD DE,380h
L77E1: C5           PUSH BC
L77E2: 01 E0 FF     LD BC,0FFE0h
L77E5: 09           ADD HL,BC
L77E6: E5           PUSH HL
L77E7: CD C7 6B     CALL short_beep
L77EA: E1           POP HL
L77EB: EB           EX DE,HL
L77EC: C1           POP BC
L77ED: 10 F2        DJNZ 0F2h
L77EF: C9           RET

more_init:
L77F0: 3E D6        LD A,0D6h		; D6h = 11010110
       FD CB 79 7E  BIT 7,(IY+79h)		; RAMTOP, Most signifcant byte. 16K/48K test?

L77F6: 20 02        JR NZ,2h		; not 16K
L77F8: 3E CD        LD A,0CDh		; CDh = 11001101

L77FA: 32 B7 67     LD (flash_border_port_setting+1),A	; what the B register outputs
L77FD: C3 5D 6C     JP even_more_init

L7800:

; --------------------------------------------------------------------------------
;
; NOPS (till right before the end of memory)
;
; --------------------------------------------------------------------------------

LFF12: DB 02        INA (2h)
LFF14: 4D           LD C,L
LFF15: 00           NOP
LFF16: 97           SUB A
LFF17: 56           LD D,(HL)
LFF18: DB 02        INA (2h)
LFF1A: 4D           LD C,L
LFF1B: 00           NOP
LFF1C: 38 00        JR C,0h
LFF1E: CE 0B        ADC 0Bh
LFF20: BF           CP A
LFF21: 50           LD D,B
LFF22: 02           LD (BC),A
LFF23: 03           INC BC
LFF24: DC 0A FE     CALL C,0FE0Ah
LFF27: 15           DEC D
LFF28: B7           OR A
LFF29: 50           LD D,B
LFF2A: 3E 0C        LD A,0Ch
LFF2C: DB 02        INA (2h)
LFF2E: 4D           LD C,L
LFF2F: 00           NOP
LFF30: 35           DEC (HL)
LFF31: 65           LD H,L
LFF32: 00           NOP
LFF33: 26 07        LD H,7h
LFF35: 74           LD (HL),H
LFF36: 42           LD B,D
LFF37: 00           NOP

; current return address (run address for SNA) = 6C55
LFF38: 55           LD D,L
LFF39: 6C           LD L,H
LFF3A: 00           NOP
LFF3B: 73           LD (HL),E
LFF3C: 54           LD D,H
LFF3D: 6D           LD L,L
LFF3E: 17           RLA
LFF3F: 68           LD L,B
LFF40: 2B           DEC HL
LFF41: 2D           DEC L
LFF42: 65           LD H,L
LFF43: 33           INC SP
LFF44: 58           LD E,B
LFF45: 27           DAA
LFF46: ED 10        unknown_10
LFF48: 0D           DEC C
LFF49: 00           NOP
LFF4A: 09           ADD HL,BC
LFF4B: 00           NOP
LFF4C: 85           ADD L
LFF4D: 1C           INC E
LFF4E: 10 1C        DJNZ 1Ch
LFF50: 52           LD D,D
LFF51: 1B           DEC DE
LFF52: 76           HALT
LFF53: 1B           DEC DE
LFF54: 03           INC BC
LFF55: 13           INC DE
LFF56: 00           NOP
LFF57: 3E 18        LD A,18h
LFF59: 3C           INC A
LFF5A: 66           LD H,(HL)
LFF5B: 66           LD H,(HL)
LFF5C: 7E           LD A,(HL)
LFF5D: 66           LD H,(HL)
LFF5E: 66           LD H,(HL)
LFF5F: 00           NOP
LFF60: FC 66 66     CALL M,6666h
LFF63: 7C           LD A,H
LFF64: 66           LD H,(HL)
LFF65: 66           LD H,(HL)
LFF66: FC 00 3C     CALL M,3C00h
LFF69: 66           LD H,(HL)
LFF6A: C0           RET NZ
LFF6B: C0           RET NZ
LFF6C: C0           RET NZ
LFF6D: 66           LD H,(HL)
LFF6E: 3C           INC A
LFF6F: 00           NOP
LFF70: F8           RET M
LFF71: 6C           LD L,H
LFF72: 66           LD H,(HL)
LFF73: 66           LD H,(HL)
LFF74: 66           LD H,(HL)
LFF75: 6C           LD L,H
LFF76: F8           RET M
LFF77: 00           NOP
LFF78: FE 62        CP 62h
LFF7A: 68           LD L,B
LFF7B: 78           LD A,B
LFF7C: 68           LD L,B
LFF7D: 62           LD H,D
LFF7E: FE 00        CP 0h
LFF80: FE 62        CP 62h
LFF82: 68           LD L,B
LFF83: 78           LD A,B
LFF84: 68           LD L,B
LFF85: 60           LD H,B
LFF86: F0           RET P
LFF87: 00           NOP
LFF88: 3C           INC A
LFF89: 66           LD H,(HL)
LFF8A: C0           RET NZ
LFF8B: C0           RET NZ
LFF8C: CE 66        ADC 66h
LFF8E: 3E 00        LD A,0h
LFF90: 66           LD H,(HL)
LFF91: 66           LD H,(HL)
LFF92: 66           LD H,(HL)
LFF93: 7E           LD A,(HL)
LFF94: 66           LD H,(HL)
LFF95: 66           LD H,(HL)
LFF96: 66           LD H,(HL)
LFF97: 00           NOP
LFF98: 7E           LD A,(HL)
LFF99: 18 18        JR 18h
LFF9B: 18 18        JR 18h
LFF9D: 18 7E        JR 7Eh
LFF9F: 00           NOP
LFFA0: 1E 0C        LD E,0Ch
LFFA2: 0C           INC C
LFFA3: 0C           INC C
LFFA4: CC CC 78     CALL Z,78CCh
LFFA7: 00           NOP
LFFA8: E6 66        AND 66h
LFFAA: 6C           LD L,H
LFFAB: 78           LD A,B
LFFAC: 6C           LD L,H
LFFAD: 66           LD H,(HL)
LFFAE: E6 00        AND 0h
LFFB0: F0           RET P
LFFB1: 60           LD H,B
LFFB2: 60           LD H,B
LFFB3: 60           LD H,B
LFFB4: 62           LD H,D
LFFB5: 66           LD H,(HL)
LFFB6: FE 00        CP 0h
LFFB8: C6 EE        ADD 0EEh
LFFBA: FE FE        CP 0FEh
LFFBC: D6 C6        SUB 0C6h
LFFBE: C6 00        ADD 0h
LFFC0: C6 E6        ADD 0E6h
LFFC2: F6 DE        OR 0DEh
LFFC4: CE C6        ADC 0C6h
LFFC6: C6 00        ADD 0h
LFFC8: 38 6C        JR C,6Ch
LFFCA: C6 C6        ADD 0C6h
LFFCC: C6 6C        ADD 6Ch
LFFCE: 38 00        JR C,0h
LFFD0: FC 66 66     CALL M,6666h
LFFD3: 7C           LD A,H
LFFD4: 60           LD H,B
LFFD5: 60           LD H,B
LFFD6: F0           RET P
LFFD7: 00           NOP
LFFD8: 38 6C        JR C,6Ch
LFFDA: C6 C6        ADD 0C6h
LFFDC: DA CC 76     JP C,76CCh
LFFDF: 00           NOP
LFFE0: FC 66 66     CALL M,6666h
LFFE3: 7C           LD A,H
LFFE4: 6C           LD L,H
LFFE5: 66           LD H,(HL)
LFFE6: E6 00        AND 0h
LFFE8: 3C           INC A
LFFE9: 66           LD H,(HL)
LFFEA: 60           LD H,B
LFFEB: 3C           INC A
LFFEC: 06 66        LD B,66h
LFFEE: 3C           INC A
LFFEF: 00           NOP
LFFF0: 7E           LD A,(HL)
LFFF1: 5A           LD E,D
LFFF2: 18 18        JR 18h
LFFF4: 18 18        JR 18h
LFFF6: 3C           INC A
LFFF7: 00           NOP
LFFF8: 66           LD H,(HL)
LFFF9: 66           LD H,(HL)
LFFFA: 66           LD H,(HL)
LFFFB: 66           LD H,(HL)
LFFFC: 66           LD H,(HL)
LFFFD: 66           LD H,(HL)
LFFFE: 3C           INC A
LFFFF: 00           NOP
