.Z80 ;A:JSW.OVY 0000..FFFF ; ;Disassembly of Jet Set Willy, done by John Elliott with the Dazzlestar ;disassembler under CP/M. ; ;Note: I have deleted most of the data structures (from the sprites onward) ; as the format of these areas is documented elsewhere. ; T4000 EQU 4000H T4800 EQU 4800H T481D EQU 481DH T481E EQU 481EH T4842 EQU 4842H T4845 EQU 4845H T4848 EQU 4848H T484B EQU 484BH T488F EQU 488FH T48CF EQU 48CFH T5000 EQU 5000H T5001 EQU 5001H T5060 EQU 5060H T5070 EQU 5070H T5079 EQU 5079H T50A0 EQU 50A0H T5800 EQU 5800H T5801 EQU 5801H B58CA EQU 58CAH B58CB EQU 58CBH B58CC EQU 58CCH B58CD EQU 58CDH B58D2 EQU 58D2H B58D3 EQU 58D3H B58D4 EQU 58D4H B58D5 EQU 58D5H T5900 EQU 5900H T5950 EQU 5950H B5950 EQU 5950H B5953 EQU 5953H B5956 EQU 5956H B5959 EQU 5959H B59CF EQU 59CFH B59D0 EQU 59D0H B59EF EQU 59EFH B59F0 EQU 59F0H T5A00 EQU 5A00H T5A60 EQU 5A60H T5A61 EQU 5A61H T5BFE EQU 5BFEH T5BFF EQU 5BFFH T5C00 EQU 5C00H T5C01 EQU 5C01H B5C78 EQU 5C78H W5D6E EQU 5D6EH W5D8E EQU 5D8EH T5DB4 EQU 5DB4H W5DBC EQU 5DBCH W5DDC EQU 5DDCH T5E00 EQU 5E00H T5F00 EQU 5F00H T6000 EQU 6000H ;Back screen T686E EQU 686EH T7000 EQU 7000H .PHASE 8000H T8000: DS 128 ;Air, earth, fire & water map for current room T8080: DS 32 ;Room title B80A0: DB 0,0,0,0,0,0,0,0,0 ;+A0h Attribute & shape for air B80A9: DB 0,0,0,0,0,0,0,0,0 ;+A9h water B80B2: DB 0,0,0,0,0,0,0,0,0 ;+B2h earth B80BB: DB 0,0,0,0,0,0,0,0,0 ;+BBh fire B80C4: DB 0,0,0,0,0,0,0,0,0 ;+C4h ramp B80CD: DB 0,0,0,0,0,0,0,0,0 ;+CDh conveyor B80D6: DB 0 ;+D6h conveyor direction W80D7: DW 0 ;+D7h conveyor start B80D9: DB 0 ;+D9h conveyor length B80DA: DB 0 ;+DAh ramp direction W80DB: DW 0 ;+DBh ramp start B80DD: DB 0 ;+DDh ramp length BDR: DB 0,0,0 ;+DEh border T80E1: DB 0,0,0,0,0,0,0,0 ;+E1h item bitmap EXITL: DB 0 ;+E9h exit left EXITR: DB 0 ;+EAh exit right EXITU: DB 0 ;+EBh exit up EXITD: DB 0,0,0,0 ;+ECh exit down T80F0: DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 T8100: DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 DB 0,0,0,0,0,0,0,0,0FFH,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 DB 0,0,0,0,0,0 ; ;A sprite (screen?) position lookup table. ;Addresses for other screen for each pixel line in top 2/3rds T8200: DB 0,60H, 0,61H, 0,62H, 0,63H, 0,64H, 0,65H, 0,66H, 0,67H DB 20H,60H, 20H,61H, 20H,62H, 20H,63H, 20H,64H, 20H,65H, 20H,66H, 20H,67H DB 40H,60H, 40H,61H, 40H,62H, 40H,63H, 40H,64H, 40H,65H, 40H,66H, 40H,67H DB 60H,60H, 60H,61H, 60H,62H, 60H,63H, 60H,64H, 60H,65H, 60H,66H, 60H,67H DB 80H,60H, 80H,61H, 80H,62H, 80H,63H, 80H,64H, 80H,65H, 80H,66H, 80H,67H DB 0A0H,60H,0A0H,61H,0A0H,62H,0A0H,63H,0A0H,64H,0A0H,65H,0A0H,66H,0A0H,67H DB 0C0H,60H,0C0H,61H,0C0H,62H,0C0H,63H,0C0H,64H,0C0H,65H,0C0H,66H,0C0H,67H DB 0E0H,60H,0E0H,61H,0E0H,62H,0E0H,63H,0E0H,64H,0E0H,65H,0E0H,66H,0E0H,67H DB 0,68H, 0,69H, 0,6AH, 0,6BH, 0,6CH, 0,6DH, 0,6EH, 0,6FH DB 20H,68H, 20H,69H, 20H,6AH, 20H,6BH, 20H,6CH, 20H,6DH, 20H,6EH, 20H,6FH DB 40H,68H, 40H,69H, 40H,6AH, 40H,6BH, 40H,6CH, 40H,6DH, 40H,6EH, 40H,6FH DB 60H,68H, 60H,69H, 60H,6AH, 60H,6BH, 60H,6CH, 60H,6DH, 60H,6EH, 60H,6FH DB 80H,68H, 80H,69H, 80H,6AH, 80H,6BH, 80H,6CH, 80H,6DH, 80H,6EH, 80H,6FH T82D0: DB 0A0H,68H,0A0H,69H,0A0H,6AH,0A0H,6BH,0A0H,6CH,0A0H,6DH,0A0H,6EH,0A0H,6FH DB 0C0H,68H,0C0H,69H,0C0H,6AH,0C0H,6BH,0C0H,6CH,0C0H,6DH,0C0H,6EH,0C0H,6FH DB 0E0H,68H,0E0H,69H,0E0H,6AH,0E0H,6BH,0E0H,6CH,0E0H,6DH,0E0H,6EH,0E0H,6FH T8300: ?? rope lookup table ?? ; horizontal increments ? DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 DB 1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2 DB 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2 DB 2,2,1,2,2,1,1,2,1,1,2,2,3,2,3,2 DB 3,3,3,3,3,3,0,0,0,0,0,0,0,0,0,0 DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; vertical increments (actually doubled) DB 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6 DB 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6 DB 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6 DB 4,6,6,4,6,4,6,4,6,4,4,4,6,4,4,4 DB 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4 DB 4,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0 DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; DI ;Entry point from BASIC LD HL,T5BFF LD (HL),86H DEC HL LD (HL),9FH ;L869F LD SP,T5BFE JP L87CA ;Run the game, bypasssing the protection. ;(I disassembled a hacked version) DB 0AH,47H,4,60H,0CBH,0CH,4EH,7DH,0A9H,0ACH,71H,23H,0CBH,7CH DB 20H,0F6H,0C9H ROOM: DB 21H ;Willy's location T8421: DB 0,1,0,1,1,3,1,3,2,0,2,0,0,1,2,3 T8431: DB 0C0H,0F0H,0FCH,0FFH,0FFH,0FFH,0FFH,0FFH,0,0,0,0,0C0H,0F0H DB 0FCH,0FFH,0FFH,0FFH,0FFH,0FFH,0FCH,0F0H,0C0H,0,0FCH,0F0H DB 0C0H,0,0,0,0,0 DB 'AIR' ;Left over from Manic Miner? T8454: DB '+++++ Press ENTER to Start +++++ JET-SET WILLY by Matthew ' DB 'Smith ',7FH ;(c) DB ' 1984 SOFTWARE PROJECTS Ltd . . . . .Guide Willy to collect' DB ' all the items around the house before Midnight so Maria' DB ' will let you get to your bed. . . . . . .+++++ Press' DB ' ENTER to Start +++++' ITEMS$: DB 'Items collected 000 Time 00:00 m' GAME$: DB 'Game' OVER$: DB 'Over' T857C: DB '000' CTIME: DB ' 7:00a' DEFTIME: DB ' 7:00a' ;Start time ENTERC1: DB 'Enter Code at grid location ' ENTERC2: DB 'Sorry, try code at location ' B85CB: DB 0 LIVES: DB 7 B85CD: DB 0 B85CE: DB 0 WILLYY: DB 0D0H B85D0: DB 0 B85D1: DB 0 W85D2: DB 0 WILLYX: DW 05DB4h ;Low 5 bits hold X coordinate, 0-31 B85D5: DB 0 B85D6: DB 0 INITDATA: DB 0,0,0,0,0,0,0 ;Backup of 7 bytes from WILLYY on. B85DE: DB 0ADH ;83 items to collect? STATUS: DB 0 ;Conventional mode. This changes when Willy PAUSECT: ;has all the objects. DB 0 ;When it reaches 256, game automatically pauses TICKER: DB 0 T85E2: DB 1 WTMODE: DB 0 ;WRITETYPER mode B85E4: DB 0E0H WTYP$: DB 1FH,1FH ;---------- DB 1DH,1FH ;-W-------- DB 17H,1FH ;---R------ DB 1FH,1BH ;-------I-- DB 0FH,1FH ;----T----- DB 1BH,1FH ;--E------- DB 0FH,1FH ;----T----- DB 1FH,0FH ;-----Y---- DB 1FH,1EH ;---------P DB 1BH,1FH ;--E------- DB 17H,1FH ;---R------ T85FB: DB 51H,3CH,33H,51H,3CH,33H,51H,3CH,33H,51H,3CH,33H,51H,3CH DB 33H,51H,3CH,33H,51H,3CH,33H,51H,3CH,33H,4CH,3CH,33H,4CH DB 3CH,33H,4CH,39H,2DH,4CH,39H,2DH,51H,40H,2DH,51H,3CH,33H DB 51H,3CH,36H,5BH,40H,36H,66H,51H,3CH,51H,3CH,33H,51H,3CH DB 33H,28H,3CH,28H,28H,36H,2DH,51H,36H,2DH,51H,36H,2DH,28H DB 36H,28H,28H,3CH,33H,51H,3CH,33H,26H,3CH,2DH,4CH,3CH,2DH DB 28H,40H,33H,51H,40H,33H,2DH,40H,36H,20H,40H,36H,3DH,79H DB 3DH,0FFH ;Title screen tune T865F: DB 80H,72H,66H,60H,56H,66H,56H,56H,51H,60H,51H,51H,56H,66H DB 56H,56H,80H,72H,66H,60H,56H,66H,56H,56H,51H,60H,51H,51H DB 56H,56H,56H,56H,80H,72H,66H,60H,56H,66H,56H,56H,51H,60H DB 51H,51H,56H,66H,56H,56H,80H,72H,66H,60H,56H,66H,56H,40H DB 56H,66H,80H,66H,56H,56H,56H,56H ;In-game tune L869F: LD HL,T4000 ;Clear screen LD DE,T4000+1 LD BC,1AFFh LD (HL),0 LDIR LD IX,ENTERC1 ;Now then, my good man, what's the password? CALL ENTERCDE JP Z,L87CA ;Ooh, he got it right first time and all LD IX,ENTERC2 CALL ENTERCDE JP Z,L87CA ;Got it right second time JP 0 ;Oops. ENTERCDE: LD DE,T4800 LD C,20H CALL PRINT ;Display prompt LD HL,T4842 LD DE,T9B00 ;Sprite data for the 1 2 3 4 LD C,0 CALL GDRAW LD HL,T4845 CALL GDRAW LD HL,T4848 CALL GDRAW LD HL,T484B CALL GDRAW LD HL,T9B80 LD DE,T5900 ;Attributes LD BC,80h LDIR LD A,(B5C78) ADD A,25H LD (B5C78),A CP 0B3H JR C,R8701 ;$+04 SUB 0B4H R8701: LD L,A LD H,09EH LD A,(HL) ADD A,L LD (B85E4),A LD C,L LD E,2FH R870C: INC E LD A,C CP 12H JR C,R8717 ;$+07 SUB 12H LD C,A JR R870C ;$-09 R8717: LD A,E LD DE,T481E CALL PUTCH LD A,C ADD A,41H LD DE,T481D CALL PUTCH R8727: LD IX,T5950 R872B: CALL C873C INC IX INC IX INC IX LD A,XL ;IX low - undocumented CP 5CH JR NZ,R872B ;$-0D JR R8727 ;$-13 C873C: LD BC,TF7FE IN A,(C) AND 0FH CP 0FH JR NZ,C873C ;$-09 L8747: LD B,0BFH IN A,(C) BIT 0,A JR NZ,R8785 ;$+38 LD A,(B5959) AND 7FH CP 7 JR Z,R8785 ;$+2F SUB 8 AND 18H RRCA RRCA RRCA LD C,A LD A,(B5953) SUB 8 AND 18H RLCA OR C LD C,A LD A,(B5956) SUB 8 AND 18H RRCA OR C LD C,A LD A,(B5950) SUB 8 AND 18H RLCA RLCA RLCA POP HL OR C LD HL,B85E4 CP (HL) RET R8785: SET 7,(IX+0) SET 7,(IX+1) SET 7,(IX+20H) SET 7,(IX+21H) LD BC,TF7FE IN A,(C) AND 0FH LD E,8 CP 0EH JR Z,R87B5 ;$+15 LD E,10H CP 0DH JR Z,R87B5 ;$+0F LD E,18H CP 0BH JR Z,R87B5 ;$+09 LD E,20H CP 7 JP NZ,L8747 R87B5: LD (IX+0),E LD (IX+1),E LD (IX+20H),E LD (IX+21H),E LD BC,18h R87C4: DJNZ R87C4 ;$-00 DEC C JR NZ,R87C4 ;$-03 RET L87CA: XOR A ;Actual game entry point LD (B85CE),A LD (TICKER),A LD (B85CD),A LD (B85D1),A LD (B85CB),A LD (PAUSECT),A LD (STATUS),A ;Playing in normal mode LD A,7 ;Initial no. of lives LD (LIVES),A LD A,0D0H LD (WILLYY),A ;Willy's Y-coordinate LD A,33 ;Initial room LD (ROOM),A LD HL,T5DB4 ;Willy's initial X-coordinate LD (WILLYX),HL LD HL,T857C ;Items collected 000 LD (HL),'0' ; 30H INC HL LD (HL),'0' ; 30H INC HL LD (HL),'0' ; 30H LD H,0A4H ;L8800 LD A,(BA3FF) LD L,A LD (B85DE),A ;256-no. items to collect R8809: SET 6,(HL) INC L JR NZ,R8809 ;$-03 LD HL,T85E2 SET 0,(HL) L8813: LD HL,T4000 ;Clear screen LD DE,T4000+1 LD BC,17FFh LD (HL),0 LDIR LD HL,T9800 ;Startup attributes LD BC,300h LDIR LD HL,T5A60 ;"Press ENTER to start" box LD DE,T5A61 LD BC,1Fh LD (HL),46H LDIR LD IX,T8454 ;+++ Press ENTER to start +++ LD DE,T5060 LD C,20H CALL PRINT LD DE,T5800 ;Draw the impossible triangle L8844: LD A,(DE) OR A JR Z,R888E ;$+48 CP 0D3H JR Z,R888E ;$+44 CP 9 JR Z,R888E ;$+40 CP 2DH JR Z,R888E ;$+3C CP 24H JR Z,R888E ;$+38 LD C,0 CP 8 JR Z,R8871 ;$+15 CP 29H JR Z,R8871 ;$+11 CP 2CH JR Z,R886E ;$+0A CP 5 JR Z,R8871 ;$+09 LD C,10H JR R8871 ;$+05 R886E: LD A,25H LD (DE),A R8871: LD A,E AND 1 RLCA RLCA RLCA OR C LD C,A LD B,0 LD HL,T8431 ADD HL,BC PUSH DE BIT 0,D LD D,40H JR Z,R8888 ;$+04 LD D,48H R8888: LD B,8 CALL C969B ;Output a character bitmap POP DE R888E: INC DE LD A,D CP 5AH JP NZ,L8844 LD BC,1Fh DI XOR A R889A: IN E,(C) OR E DJNZ R889A ;$-03 AND 20H JR NZ,R88A8 ;$+07 LD A,1 LD (B85CE),A R88A8: LD HL,T85FB CALL C96A2 ;Play the tune JP NZ,L88FC ;Start game XOR A LD (B85E4),A R88B5: CALL C8AEB ;Flash the colours LD HL,T5A60 LD DE,T5A61 LD BC,1Fh LD (HL),4FH LDIR LD A,(B85E4) LD IX,T8454 ;Scrollify the message LD E,A LD D,0 ADD IX,DE LD DE,T5060 LD C,20H CALL PRINT LD A,(B85E4) AND 1FH ADD A,32H CALL C96DE LD BC,0AFFEh ;Check for ENTER or zero IN A,(C) AND 1 CP 1 JR NZ,L88FC ;$+10 LD A,(B85E4) INC A CP 0E0H ;End of scrolly? LD (B85E4),A JR NZ,R88B5 ;$-42 JP L8813 ;Restart at L8813 L88FC: LD HL,DEFTIME ;Reset timer LD DE,CTIME LD BC,6 LDIR LD HL,T9A00 ;Attributes for bottom screen third LD DE,T5A00 LD BC,100h LDIR ; ;L8912 - Enter and draw room ; L8912: LD A,(ROOM) OR 0C0H LD H,A ;Find room address, move room to 8000h. LD L,0 ;1 room = 1 page LD DE,T8000 LD BC,100h LDIR LD IX,T80F0 ;Guardian table for room LD DE,T8100 LD A,8 ;max 8 guardians/room R892B: LD L,(IX+0) ;(IX+0)=Guardian ID RES 7,L LD H,14H ADD HL,HL ADD HL,HL ADD HL,HL ;Becomes A000h + 8*L LD BC,2 LDIR LD C,(IX+1) LD (HL),C ;8 sets of data initialised at 8100h LD BC,6 LDIR INC IX INC IX DEC A JR NZ,R892B LD HL,WILLYY ;Room initialisation data LD DE,T85D7 LD BC,7 LDIR CALL C8D33 LD HL,T5000 LD DE,T5000+1 LD BC,07FFh LD (HL),0 LDIR LD IX,T8080 ;Room title LD C,20H LD DE,T5000 CALL PRINT LD IX,ITEMS$ LD DE,T5060 LD C,20H CALL PRINT LD A,(BDR) LD C,0FEH OUT (C),A XOR A LD (B85D6),A ; initialise "JSW on rope" position JP L89AD C898B: LD A,(LIVES) LD HL,T50A0 OR A RET Z LD B,A R8994: LD C,0 ;Animate Willy's extra lives? PUSH HL PUSH BC LD A,(TICKER) RLCA RLCA RLCA AND 60H LD E,A LD D,09DH ;Willy sprite CALL GDRAW POP BC POP HL INC HL INC HL DJNZ R8994 ;$-16 RET L89AD: CALL C898B LD HL,T5E00 LD DE,T5C00 LD BC,200h LDIR LD HL,T7000 LD DE,T6000 LD BC,1000h LDIR CALL C90C0 ;update sprite positions [MJW] LD A,(STATUS) ;At end of game? CP 3 CALL NZ,C8DD3 LD A,(WILLYY) CP 0E1H CALL NC,C94B0 ;Move up LD A,(STATUS) CP 3 ;At end of game? CALL NZ,C95C8 LD A,(STATUS) CP 2 ;Moving right at speed? CALL Z,C9584 ;Check for collision with lavatory CALL C9534 ;Handle Maria & bathroom lavatory CALL C91BE CALL C94F9 ;Animate conveyor belts CALL C93D1 ;Handle collection of items L89F5: LD HL,T6000 ;Write back screen to main screen LD DE,T4000 LD BC,1000h LDIR LD A,(STATUS) ;Is manual control allowed? AND 2 RRCA LD HL,W85D2 OR (HL) LD (HL),A LD A,(B85CD) OR A JR Z,R8A26 ;$+17 DEC A LD (B85CD),A RLCA RLCA RLCA AND 38H LD HL,T5C00 LD DE,T5C01 LD BC,1FFh LD (HL),A LDIR R8A26: LD HL,T5C00 LD DE,T5800 LD BC,200h LDIR LD IX,CTIME ;Print time LD DE,T5079 LD C,6 CALL PRINT LD IX,T857C ;Print items count LD DE,T5070 LD C,3 CALL PRINT LD A,(B85CB) ;Ticker INC A LD (B85CB),A JR NZ,R8AAB ;$+5B LD IX,CTIME INC (IX+4) LD A,(IX+4) CP 3AH JR NZ,R8AAB ;$+4D LD (IX+4),30H INC (IX+3) LD A,(IX+3) CP 36H JR NZ,R8AAB ;$+3F LD (IX+3),30H LD A,(IX+0) CP 31H JR NZ,R8A99 ;$+22 INC (IX+1) LD A,(IX+1) CP 33H JR NZ,R8AAB ;$+2A LD A,(IX+5) CP 70H JP Z,L87CA LD (IX+0),20H LD (IX+1),31H LD (IX+5),70H JR R8AAB ;$+14 R8A99: INC (IX+1) LD A,(IX+1) CP 3AH JR NZ,R8AAB ;$+0A LD (IX+1),30H LD (IX+0),31H R8AAB: LD BC,TFEFE IN A,(C) LD E,A LD B,7FH IN A,(C) OR E AND 1 JP Z,L87CA ;BREAK pressed, go straight to title screen LD A,(PAUSECT) INC A LD (PAUSECT),A JR Z,PAUSE ;Zeroised to remove automatic pausing. LD B,0FDH IN A,(C) AND 1FH CP 1FH JR Z,R8B17 ;$+4B LD DE,0 PAUSE: LD B,2 IN A,(C) ;Check for keypress AND 1FH CP 1FH JR NZ,ENDPAUSE ;** Source for this bit left in the binary ** INC E JR NZ,PAUSE ;$-0B INC D JR NZ,PAUSE ;$-0E LD A,(WTMODE) CP 0AH ;WRITETYPER disables colours during pause CALL NZ,C8AEB JR PAUSE ;$-18 C8AEB: LD HL,T5800 LD A,(HL) AND 7 OUT (0FEH),A R8AF3: LD A,(HL) ADD A,3 AND 7 LD D,A LD A,(HL) ADD A,18H AND 0B8H OR D LD (HL),A INC HL LD A,H CP 5BH JR NZ,R8AF3 ;$-11 RET ENDPAUSE: LD HL,T9A00 ;Lowerscreen attributes LD DE,T5A00 LD BC,100h LDIR LD A,(BDR) OUT (0FEH),A R8B17: LD A,(B85D1) CP 0FFH JP Z,L8C01 ;Death? LD B,0BFH LD HL,T85E2 IN A,(C) AND 1FH CP 1FH JR Z,R8B36 ;$+0C BIT 0,(HL) JR NZ,R8B38 ;$+0A LD A,(HL) XOR 3 LD (HL),A JR R8B38 ;$+04 R8B36: RES 0,(HL) R8B38: BIT 1,(HL) JR NZ,R8B70 ;$+36 XOR A LD (PAUSECT),A LD A,(TICKER) INC A LD (TICKER),A AND 7EH ;6-bit value RRCA ;0-63 LD E,A LD D,0 LD HL,T865F ;The in-game tune ADD HL,DE LD A,(LIVES) ;Make it worse as lives decrease :-) RLCA RLCA SUB 1CH NEG ADD A,(HL) LD D,A ;D=note LD A,(BDR) ;Border LD E,D LD BC,3 R8B63: OUT (0FEH),A DEC E JR NZ,R8B6B ;$+05 LD E,D XOR 18H R8B6B: DJNZ R8B63 ;$-08 DEC C JR NZ,R8B63 ;$-0B ; ;Check for WRITETYPER teleportation. ; R8B70: LD BC,TEFFE ;6,7,8,9,0 IN A,(C) BIT 1,A ;User pressing 9? JP NZ,L8B97 AND 10H XOR 10H ;6 becomes bit 5 of room no. RLCA LD D,A LD A,(WTMODE) ;WRITETYPER on? CP 0AH JP NZ,L8B97 LD BC,TF7FE ;Read low 5 bits IN A,(C) CPL AND 1FH OR D LD (ROOM),A JP L8912 ;Teleport. L8B97: LD A,(WTMODE) CP 0AH JP Z,L89AD ;WRITETYPER already on, don't bother LD A,(ROOM) CP 1CH JP NZ,L89AD ;Not in room 28 (1st Landing), don't bother LD A,(WILLYY) CP 0D0H JP NZ,L89AD ;Not standing on floor, don't bother LD A,(WTMODE) RLCA LD E,A LD D,0 LD IX,WTYP$+2 ;WTYP$+2*WTMODE gives last WRITETYPER char ADD IX,DE LD BC,TFBFE ;QWERT IN A,(C) AND 1FH CP (IX+0) JR Z,R8BDA ;Correct keypress? CP 1FH JP Z,L89AD ;No keypress CP (IX-2) JP Z,L89AD ;Previous keypress? XOR A LD (WTMODE),A ;Wrong. Go back to beginning of WRITETYPER. JP L89AD R8BDA: LD B,0DFH ;YUIOP IN A,(C) AND 1FH CP (IX+1) JR Z,R8BF7 ;Correct, proceed CP 1FH JP Z,L89AD ;Nothing, ignore CP (IX-1) JP Z,L89AD ;Last, ignore XOR A ;Wrong LD (WTMODE),A JP L89AD R8BF7: LD A,(WTMODE) INC A LD (WTMODE),A JP L89AD L8C01: LD A,47H R8C03: LD HL,T5800 LD DE,T5801 LD BC,1FFh LD (HL),A LDIR LD E,A CPL AND 7 RLCA RLCA RLCA OR 7 LD D,A LD C,E RRC C RRC C RRC C OR 10H XOR A R8C23: OUT (0FEH),A XOR 18H LD B,D R8C28: DJNZ R8C28 DEC C JR NZ,R8C23 ;$-08 LD A,E DEC A CP 3FH JR NZ,R8C03 ;$-2E LD HL,LIVES LD A,(HL) OR A JP Z,L8C4A ;Game over DEC (HL) ;NOP out for infinite lives LD HL,INITDATA LD DE,WILLYY ;Willy's starting position in this room LD BC,7 LDIR JP L8912 ;Redraw room L8C4A: LD HL,T4000 LD DE,T4000+1 LD BC,0FFFh ;Clear top 2/3 of screen LD (HL),0 LDIR XOR A LD (B85E4),A LD DE,T9D40 ;Willy facing right LD HL,T488F LD C,0 CALL GDRAW LD DE,T9C60 ;Barrel LD HL,T48CF LD C,0 CALL GDRAW R8C71: LD A,(B85E4) LD C,A LD B,82H LD A,(BC) OR 0FH LD L,A INC BC LD A,(BC) SUB 20H LD H,A LD DE,T9C40 ;The foot LD C,0 CALL GDRAW LD A,(B85E4) CPL LD E,A XOR A LD BC,64 R8C91: OUT (0FEH),A XOR 18H LD B,E R8C96: DJNZ R8C96 ;$-00 DEC C JR NZ,R8C91 ;$-08 LD HL,T5800 LD DE,T5801 LD BC,1FFh LD A,(B85E4) AND 0CH RLCA OR 47H LD (HL),A LDIR AND 0FAH OR 2 LD (B59CF),A LD (B59D0),A LD (B59EF),A LD (B59F0),A LD A,(B85E4) ADD A,4 LD (B85E4),A CP 0C4H JR NZ,R8C71 ;$-58 LD IX,GAME$ ;GAME LD C,4 LD DE,40CAh CALL PRINT LD IX,OVER$ ;OVER LD C,4 LD DE,40D2h CALL PRINT LD BC,0 LD D,6 R8CE8: DJNZ R8CE8 LD A,C AND 7 OR 40H LD (B58CA),A INC A AND 7 OR 40H LD (B58CB),A INC A AND 7 OR 40H LD (B58CC),A INC A AND 7 OR 40H LD (B58CD),A INC A AND 7 OR 40H LD (B58D2),A INC A AND 7 OR 40H LD (B58D3),A INC A AND 7 OR 40H LD (B58D4),A INC A AND 7 OR 40H LD (B58D5),A DEC C JR NZ,R8CE8 ;$-43 DEC D JR NZ,R8CE8 ;$-46 JP L87CA C8D33: CALL C8D6B ;Generate room attributes LD IX,T5E00 LD A,70H LD (L8D5C+1),A CALL C8D4B LD IX,T5F00 LD A,78H LD (B8D5C+1),A C8D4B: LD C,0 L8D4D: LD E,C LD A,(IX+0) LD HL,B80A0 LD BC,36h CPIR LD C,E LD B,8 L8D5C: LD D,0 R8D5E: LD A,(HL) LD (DE),A INC HL INC D DJNZ R8D5E ;$-04 INC IX INC C JP NZ,L8D4D RET C8D6B: LD HL,T8000 ;Room description LD IX,T5E00 R8D72: LD A,(HL) ;Top 2 bits RLCA RLCA CALL C8DC0 ;Plot a square LD A,(HL) ;Next 2 bits RRCA RRCA RRCA RRCA CALL C8DC0 ;Next 2 bits LD A,(HL) RRCA RRCA CALL C8DC0 ;Bottom 2 bits LD A,(HL) CALL C8DC0 INC HL LD A,L ;Continue until all drawn AND 80H JR Z,R8D72 ;$-1C LD A,(B80D9) ;Conveyor length OR A JR Z,R8DA1 LD HL,(W80D7) ;Conveyor start LD B,A LD A,(B80CD) ;Conveyor colour R8D9D: LD (HL),A INC HL DJNZ R8D9D ;$-02 R8DA1: LD A,(B80DD) ;Ramp length OR A RET Z LD HL,(W80DB) ;Ramp start LD A,(B80DA) ;Ramp direction AND 1 RLCA ADD A,0DFH LD E,A LD D,0FFH LD A,(B80DD) ;Ramp length LD B,A LD A,(B80C4) ;Ramp colour R8DBB: LD (HL),A ADD HL,DE DJNZ R8DBB ;$-02 RET C8DC0: AND 3 LD C,A RLCA RLCA ;A:=A*9 RLCA ADD A,C ADD A,0A0H LD E,A LD D,80H LD A,(DE) LD (IX+0),A INC IX RET C8DD3: LD A,(B85D6) ; on rope (?) DEC A BIT 7,A JP Z,L8ED4 LD A,(B85D1) CP 1 JR NZ,R8E36 ;$+55 LD A,(B85D5) AND 0FEH SUB 8 LD HL,WILLYY ;Height ADD A,(HL) LD (HL),A CP 0F0H JP NC,C94B0 ;Move up CALL C8E9C LD A,(B80B2) CP (HL) JP Z,L8EBC INC HL CP (HL) JP Z,L8EBC LD A,(B85D5) INC A LD (B85D5),A SUB 8 JP P,L8E11 NEG L8E11: INC A RLCA RLCA RLCA LD D,A LD C,20H LD A,(BDR) R8E1B: OUT (0FEH),A XOR 18H LD B,D R8E20: DJNZ R8E20 ;$-00 DEC C JR NZ,R8E1B ;$-08 LD A,(B85D5) CP 12H JP Z,L8EB0 CP 10H JR Z,R8E36 ;$+07 CP 0DH JP NZ,L8FBC R8E36: LD A,(WILLYY) ;Height AND 0EH JR NZ,R8E62 ;$+27 LD HL,(WILLYX) LD DE,40h ADD HL,DE BIT 1,H JP NZ,L94D2 ;Move down LD A,(B80BB) CP (HL) JR Z,R8E62 ;$+15 INC HL LD A,(B80BB) CP (HL) JR Z,R8E62 ;$+0E LD A,(B80A0) CP (HL) DEC HL JP NZ,L8ED4 CP (HL) JP NZ,L8ED4 R8E62: LD A,(B85D1) CP 1 JP Z,L8FBC LD HL,B85D0 RES 1,(HL) LD A,(B85D1) OR A JP Z,L8EB6 INC A CP 10H JR NZ,R8E7D ;$+04 LD A,0CH R8E7D: LD (B85D1),A RLCA RLCA RLCA RLCA LD D,A LD C,20H LD A,(BDR) R8E8A: OUT (0FEH),A XOR 18H LD B,D R8E8F: DJNZ R8E8F ;$-00 DEC C JR NZ,R8E8A ;$-08 LD A,(WILLYY) ADD A,8 LD (WILLYY),A C8E9C: AND 0F0H LD L,A XOR A RL L ADC A,5CH LD H,A LD A,(WILLYX) AND 1FH OR L LD L,A LD (WILLYX),HL RET L8EB0: LD A,6 LD (B85D1),A RET L8EB6: LD A,2 LD (B85D1),A RET L8EBC: LD A,(WILLYY) ADD A,10H AND 0F0H LD (WILLYY),A CALL C8E9C LD A,2 LD (B85D1),A LD HL,B85D0 RES 1,(HL) RET L8ED4: LD E,0FFH LD A,(B85D6) DEC A BIT 7,A JR Z,R8EFA ;$+1E LD A,(B85D1) CP 0CH JP NC,L90B7 XOR A LD (B85D1),A LD A,(B80CD) CP (HL) JR Z,R8EF4 ;$+06 INC HL CP (HL) JR NZ,R8EFA ;$+08 R8EF4: LD A,(B80D6) ;Conveyor direction SUB 3 LD E,A R8EFA: LD BC,TDFFE ;YUIOP IN A,(C) AND 1FH OR 20H AND E LD E,A LD A,(STATUS) ;Is manual control allowed? AND 2 RRCA XOR E LD E,A LD BC,TFBFE IN A,(C) AND 1FH RLC A OR 1 AND E LD E,A LD B,0EFH IN A,(C) RRCA OR 0F7H AND E LD E,A LD B,0EFH IN A,(C) OR 0FBH AND E LD E,A IN A,(C) RRCA OR 0FBH AND E LD E,A LD A,(B85CE) OR A JR Z,R8F42 ;$+0C LD BC,1Fh IN A,(C) AND 3 CPL AND E LD E,A R8F42: LD C,0 LD A,E AND 2AH CP 2AH JR Z,R8F51 ;$+08 LD C,4 XOR A LD (PAUSECT),A R8F51: LD A,E AND 15H CP 15H JR Z,R8F5E ;$+08 SET 3,C XOR A LD (PAUSECT),A R8F5E: LD A,(B85D0) ADD A,C LD C,A LD B,0 LD HL,T8421 ADD HL,BC LD A,(HL) LD (B85D0),A LD BC,7EFEh IN A,(C) AND 1FH CP 1FH JR NZ,R8F8F ;$+19 LD B,0EFH IN A,(C) BIT 0,A JR Z,R8F8F ;$+11 LD A,(B85CE) OR A JR Z,L8FBC ;$+38 LD BC,1Fh IN A,(C) BIT 4,A JR Z,L8FBC ;$+2F R8F8F: LD A,(STATUS) ;Is manual control allowed? BIT 1,A JR NZ,L8FBC ;$+28 XOR A LD (B85D5),A LD (PAUSECT),A INC A LD (B85D1),A LD A,(B85D6) DEC A BIT 7,A JR NZ,L8FBC ;$+15 LD A,0F0H LD (B85D6),A LD A,(WILLYY) AND 0F0H LD (WILLYY),A LD HL,B85D0 SET 1,(HL) RET L8FBC: LD A,(B85D0) AND 2 RET Z LD A,(B85D6) DEC A BIT 7,A RET Z LD A,(B85D0) AND 1 JP Z,L9042 LD A,(W85D2) OR A JR Z,R8FDC ;$+07 DEC A LD (W85D2),A RET R8FDC: LD A,(B85D1) LD BC,0 CP 0 JR NZ,R900A ;$+26 LD HL,(WILLYX) LD BC,0 LD A,(B80DA) DEC A OR 0A1H XOR 0E0H LD E,A LD D,0 ADD HL,DE LD A,(B80C4) CP (HL) JR NZ,R900A ;$+0E LD BC,20h LD A,(B80DA) OR A JR NZ,R900A ;$+05 LD BC,TFFE0 R900A: LD HL,(WILLYX) LD A,L AND 1FH JP Z,L948A ;Move left ADD HL,BC DEC HL LD DE,20h ADD HL,DE LD A,(B80B2) CP (HL) RET Z LD A,(WILLYY) SRA C ADD A,C LD B,A AND 0FH JR Z,R9032 ;$+0B LD A,(B80B2) ADD HL,DE CP (HL) RET Z OR A SBC HL,DE R9032: OR A SBC HL,DE LD (WILLYX),HL LD A,B LD (WILLYY),A LD A,3 LD (W85D2),A RET L9042: LD A,(W85D2) CP 3 JR Z,R904E ;$+07 INC A LD (W85D2),A RET R904E: LD A,(B85D1) LD BC,0 OR A JR NZ,R9078 ;$+23 LD HL,(WILLYX) LD A,(B80DA) DEC A OR 09DH XOR 0BFH LD E,A LD D,0 ADD HL,DE LD A,(B80C4) CP (HL) JR NZ,R9078 ;$+0E LD BC,20h LD A,(B80DA) OR A JR Z,R9078 ;$+05 LD BC,TFFE0 R9078: LD HL,(WILLYX) ADD HL,BC INC HL INC HL LD A,L AND 1FH JP Z,L949E LD DE,20h LD A,(B80B2) ADD HL,DE CP (HL) RET Z LD A,(WILLYY) SRA C ADD A,C LD B,A AND 0FH JR Z,R90A1 ;$+0B LD A,(B80B2) ADD HL,DE CP (HL) RET Z OR A SBC HL,DE R90A1: LD A,(B80B2) OR A SBC HL,DE CP (HL) RET Z DEC HL LD (WILLYX),HL XOR A LD (W85D2),A LD A,B LD (WILLYY),A RET L90B6: POP HL L90B7: POP HL LD A,0FFH LD (B85D1),A ;Used in collision detection. JP L89F5 C90C0: LD IX,T8100 L90C4: LD A,(IX+0) ;End of guardians? CP 0FFH RET Z AND 3 ;Guardian type JP Z,L91B6 ;0 or arrow [this will just ; return for next sprite] CP 1 JP Z,L9133 ;Moving horizontally CP 2 JP Z,L917F ;Moving vertically BIT 7,(IX+0) JR Z,R90FF ;Rope LD A,(IX+1) ;what else is left? BIT 7,A JR Z,R90F5 SUB 2 CP 94H JR NC,R911D SUB 2 CP 80H JR NZ,R911D XOR A JR R911D R90F5: ADD A,2 CP 12H JR NC,R911D ADD A,2 JR R911D R90FF: LD A,(IX+1) ; get here for ropes, IX+1 = rope's other byte BIT 7,A JR NZ,R9115 ; could be direction? SUB 2 CP 14H JR NC,R911D SUB 2 OR A JR NZ,R911D LD A,80H JR R911D R9115: ADD A,2 CP 92H JR NC,R911D ADD A,2 R911D: LD (IX+1),A ; MJW all ropes get here in the end AND 7FH CP (IX+7) ; MJW if reached limit change direction????? JP NZ,L91B6 LD A,(IX+0) XOR 80H LD (IX+0),A JP L91B6 L9133: ; moving horizontally BIT 7,(IX+0) JR NZ,R915C LD A,(IX+0) SUB 20H AND 7FH LD (IX+0),A CP 60H JR C,L91B6 LD A,(IX+2) AND 1FH CP (IX+6) JR Z,R9156 DEC (IX+2) JR L91B6 R9156: LD (IX+0),81H JR L91B6 ;$+5C R915C: LD A,(IX+0) ADD A,20H OR 80H LD (IX+0),A CP 0A0H JR NC,L91B6 ;$+4E LD A,(IX+2) AND 1FH CP (IX+7) JR Z,R9179 ;$+07 INC (IX+2) JR L91B6 ;$+3F R9179: LD (IX+0),61H JR L91B6 ;$+39 L917F: ; moving vertically LD A,(IX+0) ;High-speed animation? XOR 8 LD (IX+0),A AND 18H JR Z,R9193 ;$+0A LD A,(IX+0) ADD A,20H LD (IX+0),A R9193: LD A,(IX+3) ;Height ADD A,(IX+4) ;Direction, U/D LD (IX+3),A CP (IX+7) JR NC,R91AE ;$+0F CP (IX+6) JR Z,R91A8 ;$+04 JR NC,L91B6 ;$+10 R91A8: LD A,(IX+6) LD (IX+3),A R91AE: LD A,(IX+4) NEG LD (IX+4),A L91B6: LD DE,8 ADD IX,DE JP L90C4 ; repeat for next sprite C91BE: ; draw monster sprites? LD IX,T8100 L91C2: LD A,(IX+0) CP 0FFH RET Z ;return when finished AND 7 ;Guardian type JP Z,L93B3 CP 3 ;Rope JP Z,L92A4 CP 4 JR Z,R9237 ;Arrow LD E,(IX+3) ;Y LD D,82H LD A,(DE) LD L,A LD A,(IX+2) ;X AND 1FH ADD A,L LD L,A LD A,E RLCA AND 1 OR 5CH LD H,A LD DE,1Fh LD A,(IX+1) AND 0FH ADD A,38H AND 47H LD C,A LD A,(HL) AND 38H XOR C LD C,A LD (HL),C INC HL LD (HL),C ADD HL,DE LD (HL),C INC HL LD (HL),C LD A,(IX+3) AND 0EH JR Z,R920F ;$+06 ADD HL,DE LD (HL),C INC HL LD (HL),C R920F: LD C,1 LD A,(IX+1) AND (IX+0) OR (IX+2) AND 0E0H LD E,A LD D,(IX+5) LD H,82H LD L,(IX+3) LD A,(IX+2) AND 1FH OR (HL) INC HL LD H,(HL) LD L,A CALL GDRAW ;Draw a monster? JP NZ,L90B7 JP L93B3 R9237: BIT 7,(IX+0) JR NZ,R9244 ;$+09 DEC (IX+4) LD C,2CH JR R9249 ;$+07 R9244: INC (IX+4) LD C,0F4H R9249: LD A,(IX+4) CP C JR NZ,R9262 ;$+15 LD BC,280h LD A,(BDR) R9255: OUT (0FEH),A XOR 18H R9259: DJNZ R9259 ;$-00 LD B,C DEC C JR NZ,R9255 ;$-08 JP L93B3 R9262: AND 0E0H JP NZ,L93B3 LD E,(IX+2) LD D,82H LD A,(DE) ADD A,(IX+4) LD L,A LD A,E AND 80H RLCA OR 5CH LD H,A LD (IX+5),0 LD A,(HL) AND 7 CP 7 JR NZ,R9286 ;$+05 DEC (IX+5) R9286: LD A,(HL) OR 7 LD (HL),A INC DE LD A,(DE) LD H,A DEC H LD A,(IX+6) LD (HL),A INC H LD A,(HL) AND (IX+5) JP NZ,L90B7 LD (HL),0FFH INC H LD A,(IX+6) LD (HL),A JP L93B3 L92A4: ; ROPES LD IY,T8200 ; IY:lookup table for screen addresses LD (IX+9),0 ; this is the first pixel in the rope LD A,(IX+2) LD (IX+3),A ; set up char position for point LD (IX+5),80H ; set up initial pattern (bit 7 set) L92B6: LD A,(IY+0) ; IY=addresses in screen ADD A,(IX+3) ; horz char of rope position LD L,A LD H,(IY+1) ; HL=screen address for byte to plot in LD A,(B85D6) ; is Willy on rope ? OR A JR NZ,R92D6 ; jump ahead if not LD A,(IX+5) AND (HL) ; is current point already plotted on screen? ; (ie does Willy sprite cover this point?) JR Z,R930E ; if not, jump ahead LD A,(IX+9) ; store current posn in rope as Willy's rope posn LD (B85D6),A SET 0,(IX+0BH) ; ? R92D6: CP (IX+9) JR NZ,R930E BIT 0,(IX+0BH) JR Z,R930E LD B,(IX+3) ; horiz char of point (will go into WILLYX_LO) LD A,(IX+5) ; A = bit pattern LD C,1 CP 4 JR C,R92FC ; C=1 for A=1,2 LD C,0 CP 10H JR C,R92FC ; C=0 for A=4,8 DEC B LD C,3 ; B decremented & C=3 for A=10,20 CP 40H JR C,R92FC LD C,2 ; B decremented & C=2 for A=40,80 R92FC: LD (W85D2),BC ; sets (85D2) = C; (WILLYX_LO) = B LD A,YL ;Undocumented SUB 10H LD (WILLYY),A ; set vertical position PUSH HL CALL C8E9C ; adjust WILLYX somehow? probably just keeps ; everything consistent POP HL JR R930E ; tut tut R930E: LD A,(IX+5) OR (HL) LD (HL),A ; plots the point on screen LD A,(IX+9) ; current position in this rope ADD A,(IX+1) ; current rope posn LD L,A SET 7,L LD H,83H ; rope lookup table at 8300H LD E,(HL) ; E = (2*) vertical increment LD D,0 ADD IY,DE ; update IY for next pixel line used RES 7,L LD A,(HL) ; A = horizontal increment OR A JR Z,R9350 ; skip next bit if no change LD B,A ; otherwise loop A times BIT 7,(IX+1) ; test direction rope is facing JR Z,R9341 R9330: RLC (IX+5) ; move plotted point left BIT 0,(IX+5) JR Z,R933D DEC (IX+3) ; decrement char pos if necessary R933D: DJNZ R9330 JR R9350 R9341: RRC (IX+5) ; move plotted point right BIT 7,(IX+5) JR Z,R934E INC (IX+3) ; increment char pos if necessary R934E: DJNZ R9341 R9350: LD A,(IX+9) CP (IX+4) JR Z,R935E INC (IX+9) ; if not finished, go back for new point JP L92B6 R935E: LD A,(B85D6) BIT 7,A JR Z,R936F INC A LD (B85D6),A RES 0,(IX+0BH) JR L93B3 R936F: BIT 0,(IX+0BH) JR Z,L93B3 LD A,(B85D0) BIT 1,A JR Z,L93B3 RRCA XOR (IX+0) RLCA RLCA AND 2 DEC A LD HL,B85D6 ADD A,(HL) LD (HL),A LD A,(EXITU) LD C,A LD A,(ROOM) ;Is upward exit = current room? CP C JR NZ,R939B LD A,(HL) ;If so, don't let Willy near the roof CP 0CH JR NC,R939B LD (HL),0CH R939B: LD A,(HL) CP (IX+4) JR C,L93B3 JR Z,L93B3 ;don't let Willy fall off end of rope (?) LD (HL),0F0H LD A,(WILLYY) AND 0F8H LD (WILLYY),A XOR A LD (B85D1),A ;indicate not collided with anything (?) JR L93B3 ;dearie dearie me L93B3: LD DE,8 ADD IX,DE JP L91C2 ; repeat for next monster DB 77H,3AH,0A0H,80H,0E6H,0F8H,0B6H,77H,11H,1FH,0,23H,77H,19H DB 77H,23H,77H,19H,77H,23H,77H,0C9H C93D1: LD H,0A4H LD A,(BA3FF) ;HL -> bottom of object stack LD L,A R93D7: LD C,(HL) RES 7,C LD A,(ROOM) ;Is this item in the current room? OR 40H CP C JR NZ,R9452 ;No LD A,(HL) RLCA AND 1 ;Address = 0x5C00+(([HL]&0x80) << 1)+ [HL+256] ADD A,5CH LD D,A INC H LD E,(HL) ;DE becomes address in 5C00-5DFF DEC H LD A,(DE) AND 7 ;Is Willy at the item's coordinates? CP 7 JR NZ,R9430 ;$+3F LD IX,T857C ;Increment onscreen item count R93F7: INC (IX+2) LD A,(IX+2) CP '9'+1 JR NZ,R9409 LD (IX+2),'0' DEC IX JR R93F7 ;$-10 R9409: LD A,(BDR) ;Make item-collection sound. LD C,80H R940E: OUT (0FEH),A XOR 18H LD E,A LD A,90H SUB C LD B,A LD A,E R9418: DJNZ R9418 ;$-00 DEC C DEC C JR NZ,R940E ;$-0E ; LD A,(B85DE) ;We've got another item INC A LD (B85DE),A JR NZ,R942C ;All done? LD A,1 LD (STATUS),A ;If that was the last object, flag it R942C: RES 6,(HL) ;Flag item as collected JR R9452 R9430: LD A,(B85CB) ;Ticker ADD A,L ;Add item number AND 3 ADD A,3 ;A=4-7, item colour LD C,A LD A,(DE) AND 0F8H OR C ;Reset item ink to A LD (DE),A ;(DE -> item attributes) LD A,(HL) RLCA RLCA RLCA RLCA AND 8 ADD A,60H ;DE:=item address in main screen LD D,A PUSH HL LD HL,T80E1 ;Item bitmap LD B,8 CALL C969B ;Print it. POP HL R9452: INC L ;Next item JR NZ,R93D7 RET GDRAW: LD B,10H ;Draw generic sprite R9458: BIT 0,C LD A,(DE) JR Z,R9461 ;$+06 AND (HL) RET NZ LD A,(DE) OR (HL) R9461: LD (HL),A INC L INC DE BIT 0,C LD A,(DE) JR Z,R946D ;$+06 AND (HL) RET NZ LD A,(DE) OR (HL) R946D: LD (HL),A DEC L INC H INC DE LD A,H AND 7 JR NZ,R9486 ;$+12 LD A,H SUB 8 LD H,A LD A,L ADD A,20H LD L,A AND 0E0H JR NZ,R9486 ;$+06 LD A,H ADD A,8 LD H,A R9486: DJNZ R9458 ;$-2E XOR A RET L948A: LD A,(EXITL) LD (ROOM),A ;Move left LD A,(WILLYX) OR 1FH AND 0FEH ;Reset X to 30 LD (WILLYX),A POP HL JP L8912 L949E: LD A,(EXITR) ;Move right LD (ROOM),A LD A,(WILLYX) ;Reset X to 0 AND 0E0H LD (WILLYX),A POP HL JP L8912 C94B0: LD A,(EXITU) LD (ROOM),A LD A,(WILLYX) AND 1FH ADD A,0A0H LD (WILLYX),A LD A,5DH LD (WILLYX+1),A LD A,0D0H ;Willy at floor level in room above LD (WILLYY),A XOR A LD (B85D1),A POP HL JP L8912 L94D2: LD A,(EXITD) LD (ROOM),A XOR A ;Move Willy to top of new room. LD (WILLYY),A ;Willy at ceiling level in room above LD A,(B85D1) CP 0BH JR NC,R94E8 ;$+07 LD A,2 LD (B85D1),A R94E8: LD A,(WIILLYX) AND 1FH LD (WILLYX),A LD A,5CH LD (WILLYX+1),A POP HL JP L8912 C94F9: LD HL,(W80D7) ;Conveyor start LD A,H AND 1 RLCA RLCA RLCA ADD A,70H ;7000h or 7800h LD H,A LD E,L LD D,H ;DE=dest. address LD A,(B80D9) ;Conveyor length OR A RET Z LD B,A ;B=length LD A,(B80D6) ;Conveyor direction OR A JR NZ,R9526 LD A,(HL) ;Animate the conveyor graphic RLC A RLC A INC H INC H LD C,(HL) RRC C RRC C R951F: LD (DE),A LD (HL),C INC L INC E DJNZ R951F ;$-04 RET R9526: LD A,(HL) ;Moving the other way RRC A RRC A INC H INC H LD C,(HL) RLC C RLC C JR R951F ;$-13 C9534: LD A,(ROOM) CP 23H ;Master Bedroom JR NZ,R959A ;Handle bathroom lavatory LD A,(STATUS) ;Should Maria be there at all? OR A JR NZ,R9576 LD A,(B85CB) ;Ticker - is her foot down or up? AND 2 RRCA RRCA RRCA RRCA OR 80H LD E,A LD A,(WILLYY) CP 0D0H JR Z,R955C ;At ground level? LD E,0C0H CP 0C0H ;As we get higher, JR NC,R955C LD E,0E0H ;Maria animates. R955C: LD D,09CH LD HL,T686E ;Write Maria-sprite. LD C,1 CALL GDRAW JP NZ,L90B7 LD HL,4545h LD (W5D6E),HL LD HL,0707h LD (W5D8E),HL RET R9576: LD A,(WILLYX) AND 1FH CP 6 RET NC LD A,2 LD (STATUS),A ;When Willy hits the bed, switch to auto RET C9584: LD A,(ROOM) ;Called when moving right on automatic CP 21H ;Bathroom? RET NZ LD A,(WILLYX) CP 0BCH RET NZ XOR A LD (B85CB),A LD A,3 LD (STATUS),A ;Head down lavatory RET R959A: LD A,(ROOM) CP 21H ;Bathroom? RET NZ LD A,(B85CB) AND 1 RRCA RRCA RRCA LD E,A ;Lavatory sprite, Willy absent LD A,(STATUS) CP 3 JR NZ,R95B2 SET 6,E ;Lavatory sprite, Willy present R95B2: LD D,0A6H LD IX,T82D0 ;Lookup table entry LD BC,101Ch CALL PDRAW LD HL,0707h LD (W5DBC),HL LD (W5DDC),HL RET C95C8: LD HL,(WILLYX) LD B,0 LD A,(B80DA) AND 1 ADD A,40H LD E,A LD D,0 ADD HL,DE LD A,(B80C4) CP (HL) JR NZ,R95F8 ;$+1C LD A,(B85D1) OR A JR NZ,R95F8 ;$+16 LD A,(W85D2) AND 3 RLCA RLCA LD B,A LD A,(B80DA) AND 1 DEC A XOR 0CH XOR B AND 0CH LD B,A R95F8: LD HL,(WILLYX) LD DE,1Fh LD C,0FH CALL C961E INC HL CALL C961E ADD HL,DE CALL C961E INC HL CALL C961E LD A,(WILLYY) ADD A,B LD C,A ADD HL,DE CALL C961E INC HL CALL C961E JR R9637 ;$+1B C961E: LD A,(B80A0) CP (HL) JR NZ,R962F ;$+0D LD A,C AND 0FH JR Z,R962F ;$+08 LD A,(B80A0) OR 7 LD (HL),A R962F: LD A,(B80BB) CP (HL) JP Z,L90B6 RET R9637: LD A,(WILLYY) ADD A,B LD XH,82H ;Undocumented LD XL,A ;IX:=T8200+WILLYY+B LD A,(B85D0) AND 1 RRCA LD E,A LD A,(W85D2) AND 3 RRCA RRCA RRCA OR E LD E,A LD D,09DH ;Willy sprite at 9Dxxh ; ;This could be changed to: LD A,(ROOM+xxh) ! OR A ! JR Z, R9660 ! LD D,A ;(which is what I did in JSW128) ; LD A,(ROOM) ;The Nightmare Room CP 1DH JR NZ,R9660 ;$+08 LD D,0B6H LD A,E ;Pig sprite at B6xxh. XOR 80H LD E,A R9660: LD B,10H ;DE=sprite address LD A,(WILLYX) AND 1FH ;B=sprite height LD C,A ;C=sprite X ;IX -> mask lookup table entry PDRAW: LD A,(IX+0) LD H,(IX+1) ;H=back screen address (back screen at 6000h) OR C ;Low byte = height offset LD L,A ;HL=byte base address LD A,(DE) OR (HL) LD (HL),A INC HL INC DE LD A,(DE) OR (HL) LD (HL),A INC IX INC IX INC DE DJNZ PDRAW ;$-15 RET PRINT: LD A,(IX+0) CALL PUTCH ;Print character INC IX INC E LD A,D ;D contains Y value for character SUB 8 LD D,A DEC C JR NZ,PRINT ;$-0E RET PUTCH: LD H,7 ;Find character in Spectrum font. LD L,A SET 7,L ADD HL,HL ADD HL,HL ADD HL,HL LD B,8 C969B: LD A,(HL) LD (DE),A INC HL INC D DJNZ C969B ;$-04 RET C96A2: LD A,(HL) ;Play a little tune CP 0FFH RET Z LD BC,64h XOR A LD E,(HL) LD D,E R96AC: OUT (0FEH),A DEC D JR NZ,R96B4 ;$+05 LD D,E XOR 18H R96B4: DJNZ R96AC ;$-08 EX AF,AF' LD A,C CP 32H JR NZ,R96BE ;$+04 RL E R96BE: EX AF,AF' DEC C JR NZ,R96AC ;$-14 CALL C96C9 RET NZ INC HL JR C96A2 ;$-25 C96C9: LD A,(B85CE) OR A JR Z,R96D4 ;$+07 IN A,(1FH) BIT 4,A RET NZ R96D4: LD BC,0AFFEh IN A,(C) AND 1 CP 1 RET C96DE: LD E,A LD C,0FEH R96E1: LD D,A RES 4,D RES 3,D LD B,E R96E7: CP B JR NZ,R96EC ;$+04 LD D,18H R96EC: OUT (C),D DJNZ R96E7 ;$-07 DEC A JR NZ,R96E1 ;$-10 RET LD HL,T5E00 LD DE,T5800 LD BC,200h LDIR LD HL,T4000 LD DE,T4000+1 LD BC,0FFFh LD (HL),18H LDIR LD BC,TFEFE R970F: IN A,(C) ;Wait for keypress, reset the machine BIT 2,A JP Z,0 JR R970F ;$-07 DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 DB 0,0,0,0,0,0,0,0 T9800: ;Startup attributes DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,28H DB 28H,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0D3H,0D3H,0D3H,0,0D3H DB 0D3H,0D3H,0,0D3H,0D3H,0D3H,0,28H,0D3H,0D3H,0D3H,25H,0D3H DB 0D3H,0D3H,0,0D3H,0D3H,0D3H,0,0,0,0,0,0,0,0,0,0D3H,0,0,0D3H DB 0,0,0,0,0D3H,28H,28H,2DH,0D3H,25H,25H,24H,0D3H,0,0,0,0 DB 0D3H,0,0,0,0,0,0,0,0,0,0,0D3H,0,0,0D3H,0D3H,0D3H,0,28H DB 0D3H,2DH,2DH,25H,0D3H,0D3H,0D3H,24H,0D3H,0D3H,0D3H,0,0 DB 0D3H,0,0,0,0,0,0,0,0,0,0,0D3H,0,0,0D3H,0,28H,28H,2DH,0D3H DB 25H,25H,24H,24H,4,0D3H,24H,0D3H,0,0,0,0,0D3H,0,0,0,0,0 DB 0,0,0,0,0D3H,0D3H,0,0,0D3H,0D3H,0D3H,2DH,25H,0D3H,24H,24H DB 4,0D3H,0D3H,0D3H,24H,0D3H,0D3H,0D3H,0,0,0D3H,0,0,0,0,0 DB 0,0,0,0,0,0,0,0,29H,29H,2DH,2DH,2CH,2CH,4,4,0,0,9,9,24H DB 24H,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,9,29H,29H,2DH DB 2DH,5,5,0,0,9,9,24H,24H,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 DB 0D3H,0,8,8,0D3H,9,0D3H,29H,0D3H,2DH,5,5,0D3H,9,24H,0D3H DB 0,0,0,0D3H,0,0,0,0,0,0,0,0,0,0,0,0,0D3H,0,0,0,0D3H,8,0D3H DB 9,0D3H,29H,2DH,2DH,0D3H,9,24H,0D3H,0,0,0,0D3H,0,0,0,0,0 DB 0,0,0,0,0,0,0,0D3H,0,0D3H,0,0D3H,0,0D3H,8,0D3H,9,29H,29H DB 0D3H,9,24H,0D3H,0D3H,0D3H,0D3H,0D3H,0,0,0,0,0,0,0,0,0,0 DB 0,0,0D3H,0,0D3H,0,0D3H,0,0D3H,0,0D3H,8,9,9,0D3H,9,24H,24H DB 0,0D3H,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0D3H,0D3H,0D3H,0D3H DB 0D3H,0,0D3H,0,0D3H,0D3H,0D3H,8,0D3H,0D3H,0D3H,24H,0,0D3H DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,8 DB 4,4,0,0,0,0,0,0,0,0,0,0 T9A00: ; ;Attributes for the bottom screen third ; DB 46H,46H,46H,46H,46H,46H,46H,46H,46H,46H,46H,46H,46H,46H,46H,46H DB 46H,46H,46H,46H,46H,46H,46H,46H,46H,46H,46H,46H,46H,46H,46H,46H DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 DB 1,2,3,4,5,6,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,6,5,4,3,2,1 DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 DB 45H,45H,6,6,4,4,41H,41H,5,5,43H,43H,44H,44H,0,0,0,0,0,0,0,0,0,0 DB 0,0,0,0,0,0,0,0 DB 45H,45H,6,6,4,4,41H,41H,5,5,43H,43H,44H,44H,0,0,0,0,0,0,0,0,0,0 DB 0,0,0,0,0,0,0,0 DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 T9B00: DB 7FH,0FEH,0C3H,3,0BFH,0FDH,0BFH,0FDH,0FFH,0FDH,0FFH,0FDH DB 0FFH,0FDH,0F9H,0FDH,0F1H,0FFH,0F9H,0FFH,0F9H,0FFH,0F9H DB 0FFH,0F9H,0FDH,0F9H,0FDH,0FFH,0FBH,7FH,0FEH,7FH,0FEH,0C7H DB 3,0BFH,0FDH,0BFH,0FDH,0FFH,0FDH,0FFH,0FDH,0FFH,0FDH,0F1H DB 0FFH,0ECH,0FFH,0FCH,0FFH,0F9H,0FFH,0F3H,0FFH,0E7H,0FFH DB 0E0H,0FDH,0FFH,0F3H,7FH,0FEH,7FH,0FEH,0C6H,3,0BFH,0FDH DB 0BFH,0FDH,0BFH,0FDH,0FFH,0FDH,0FFH,0FFH,0F1H,0FFH,0ECH DB 0FFH,0FCH,0FFH,0F1H,0FFH,0FCH,0FFH,0ECH,0FFH,0F1H,0FDH DB 0FFH,0E7H,7FH,0FEH,7FH,0FEH,0C6H,3,0BFH,0FDH,0BFH,0FDH DB 0BFH,0FDH,0BFH,0FFH,0FFH,0FFH,0FDH,0FFH,0F9H,0FFH,0F1H DB 0FFH,0E9H,0FFH,0E0H,0FFH,0F9H,0FFH,0F9H,0FDH,0FFH,09BH DB 7FH,0FEH T9B80: DB 45H,45H,45H,45H,45H,45H,45H,45H,45H,45H,45H,45H,45H,45H DB 45H,45H,45H,45H,45H,45H,45H,45H,45H,45H,45H,45H,45H,45H DB 47H,47H,47H,47H,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,41H,79H,0,42H,7AH,0,3,3BH,0 DB 4,3CH,0,0,0,7,7,0,7,7,0,7,7,0,7,7,0,0,0,0,0,0,0,41H,41H DB 0,42H,42H,0,3,3,0,4,4,0,0,0,7,7,0,7,7,0,7,7,0,7,7,0,0,0 DB 0,0 DB 'NZ,ENDPAUSE',082H,'J',6 DB ' INC E',0A3H,'J',0Ch DB ' JR NZ,PAUSE',0C4H,'J',6 DB ' INC D',0E5H,'J',0Ch DB ' JR NZ,PAUSE',6,'K',0CH DB ' C' T9C40: DS 20h ;Foot T9C60: DS 0A0h ;Plinth T9D00: DS 40h ;Willy facing left T9D40: DS 02C0h ;Willy facing right, and other sprites DS 03FFh ;Guardian table BA3FF: DB 0ADH ;Object count ; ;Everything past here is data. See other sources for its format. ;