results for "Amazonia".
Title : Amazonia
Publisher : Ciberne Software
Release Year: 1985
Machine Type: 48K
No. Players: 1
Entry Type: Adventure: Text
Availability: Available
Comments: Written for the TK95.#Based on the text adventure "Aventuras na Selva" for the ZX81 that was published in 1983 as type-in in Micro Sistemas 23.
Updated On : May 26, 2020
Roles : Renato Degiovani (Unknown);
Known Errors: Bugfixes provided by Einar Saukas:#
- There's a digital clock in the game that doesn't work properly. The time of day reaches 24:59 (instead of 23:59) before returning back to 0:00. Also the day of month restarts at 0 (instead of 1) after reaching 30. The following code controls the clock:#
9ec1 210000 ld hl,0000h^9ec4 22c89b ld (9bc8h),hl ; reset time counter^9ec7 21e99b ld hl,9be9h ; clock address^9eca 3e3c ld a,3ch ; minutes overflow at 60^9ecc cdda9e call 9edah ; increment/overflow minutes^9ecf 3e19 ld a,19h ; hours overflow at 25 -> SHOULD BE 24!^9ed1 cdda9e call 9edah ; increment/overflow hours^9ed4 3e1f ld a,1fh ; days overflow at 31^9ed6 cdda9e call 9edah ; increment/overflow days^9ed9 c9 ret ; exit^9eda 34 inc (hl) ; increment minutes/hours/days^9edb be cp (hl) ; reached overflow value for minutes/hours/days?^9edc 2802 jr z,9ee0h^9ede e1 pop hl ; otherwise exit^9edf c9 ret^9ee0 3600 ld (hl),00h ; reset minutes/hours/days -> DAY SHOULD NOT RESET TO ZERO!^9ee2 23 inc hl ; prepare to increment next one^9ee3 c9 ret
The time of day bug could be fixed just modifying the constant as indicated above, however this solution would not work properly for savegames that already store a time of day above 23:59. Also fixing day of month requires further changes. The best solution is as follows:#9ec1 af xor a^9ec2 32c99b ld (9bc9h),a ; reset time counter (the other byte is already zero)^9ec5 21e99b ld hl,9be9h ; clock address^9ec8 3e3b ld a,3bh ; minutes maximize at 59^9eca cdda9e call 9edah ; increment/overflow minutes^9ecd 3e17 ld a,17h ; hours maximize at 23^9ecf cdda9e call 9edah ; increment/overflow hours^9ed2 3e1e ld a,1eh ; days maximize at 30^9ed4 cdda9e call 9edah ; increment/overflow days^9ed7 2b dec hl ; prepare to fix days^9ed8 34 inc (hl) ; set days to 1^9ed9 c9 ret ; exit^9eda 34 inc (hl) ; increment minutes/hours/days^9edb be cp (hl) ; exceeded maximum value for minutes/hours/days?^9edc 3802 jr c,9ee0h^9ede e1 pop hl ; otherwise exit^9edf c9 ret^9ee0 3600 ld (hl),00h ; reset minutes/hours/days to zero^9ee2 23 inc hl ; prepare to increment next one^9ee3 c9 ret
Fixed using POKE 40641,175: POKE 40642,50: POKE 40643,201: POKE 40644,155: FOR f=40645 TO 40662: POKE f,PEEK (f+2): NEXT f: POKE 40649,59: POKE 40654,23: POKE 40659,30: POKE 40663,43: POKE 40664,52: POKE 40668,56## - When the game asks if you want to play again, if you press N in either lowercase OR uppercase the computer is supposed to reset. However nothing happens because the game is checking if you pressed N in both lowercase AND uppercase at the same time:#
a4a7 3a085c ld a,(5c08h) ; LASTK (last pressed key)^a4aa fe53 cp 53h ; pressed uppercase 'S'?^a4ac ca2e9f jp z,9f2eh ; if so, restart game^a4af fe73 cp 73h ; pressed lowercase 's'?^a4b1 ca2e9f jp z,9f2eh ; if so, restart game^a4b4 fe4e cp 4eh ; pressed uppercase 'N'?^a4b6 20e7 jr nz,0a49fh ; otherwise wait for another key -> OPS!^a4b8 fe6e cp 6eh ; pressed lowercase 'n'?^a4ba 20e3 jr nz,0a49fh ; otherwise wait for another key^a4bc c7 rst 00h ; reset computer
This problem is fixed as follows:#a4a7 3a085c ld a,(5c08h) ; LASTK (last pressed key)^a4aa fe53 cp 53h ; pressed uppercase 'S'?^a4ac ca2e9f jp z,9f2eh ; if so, restart game^a4af fe73 cp 73h ; pressed lowercase 's'?^a4b1 ca2e9f jp z,9f2eh ; if so, restart game^a4b4 fe4e cp 4eh ; pressed uppercase 'N'?^a4b6 2804 jr z,0a4bch ; if so, reset computer^a4b8 fe6e cp 6eh ; pressed lowercase 'n'?^a4ba 20e3 jr nz,0a49fh ; otherwise wait for another key^a4bc c7 rst 00h ; reset computer
Fixed using POKE 42166,40: POKE 42167,4## - Description of location 19 ("acampamento do exercito") is mispelled.#Fixed using POKE 43758,197: POKE 43759,102: POKE 43760,111: POKE 43761,115: FOR f=43762 TO 43815: POKE f,PEEK (f+1): NEXT f: POKE 43816,104: POKE 43817,153##
- Description of location 27 ("corredor muito estreito") is mispelled.#Fixed using POKE 44110,114##
- Messages 16, 34, 55, 61, 99, 100, and 116 are mispelled. Fixing them requires relocating several other messages to make enough room for the missing letters.#Fixed using POKE 50034,158: POKE 50439,108: POKE 49469,252: FOR f=49474 TO 54557: POKE f,PEEK (f+(f<51262)+(f<51628)+(f<53682)+(f<53696)+(f<5369 9)+(f<53761)+2): NEXT f: POKE 51262,110: POKE 51628,110: POKE 51633,237: POKE 53682,114: POKE 53696,45: POKE 53699,193: POKE 53722,234: POKE 53761,114: POKE 54558,120: POKE 54559,105##
- The game stores all words as hash codes in order to reduce memory usage. According to this hash algorithm, code $4467 could represent either 'DESMANCHE' (scrap) or 'DESCREVA' (describe). In practice the game adopted the former choice, defining this code as equivalent to 'QUEBRE' (break). However it also defined action "QUEBRE LAGO" (break lake or scrap lake) which makes no sense, so it seems the author actually intended to choose the latter meaning as equivalent to 'EXAMINE', and also to define "EXAMINE LAGO" (examine lake or describe lake) instead.#Fixed using POKE 42429,11: POKE 47878,11##
- Action "TIRE LAMPADA DO RADIO" incorrectly requires the player to have object 'LANTERNA' (instead of 'RADIO'). This action (and the previous one) is listed below:#
b2e8: 0b 0e 02 VERB(11) OBJ(14) OBJ(2) => 'EXAMINE' 'LAMPADA' 'LANTERNA'^b2eb: 16 12 EXEC FUNC(18) ; check if we have 'LANTERNA' (otherwise print error message and exit)^b2ed: 0c 11 00 03 IF REG(17)=0 GOTO b2f4 ; is 'LAMPADA' still working?^b2f1: 01 23 PRINT MSG(35) ; otherwise print "Ela esta queimada."^b2f3: 02 EXIT ; exit^b2f4: 01 24 PRINT MSG(36) ; print "Parece estar tudo ok."^b2f6: 02 EXIT ; exit^b2f7: fc^b2f8: 38 0e 0c VERB(56) OBJ(14) OBJ(12) => 'TIRE' 'LAMPADA' 'RADIO'^b2fb: 16 12 EXEC FUNC(18) ; -> OPS! checking 'LANTERNA' instead of 'RADIO'^b2fd: 01 19 PRINT MSG(25) ; print "Eu nao sei lidar com esses equipamentos eletronicos."^b2ff: 02 EXIT ; exit
Checking if the player has a 'RADIO' requires a few extra bytes that can be saved from the previous action (since another address already contains instructions to print MSG(36) and exit):#b2e8: 0b 0e 02 VERB(11) OBJ(14) OBJ(2) => 'EXAMINE' 'LAMPADA' 'LANTERNA'^b2eb: 16 12 EXEC FUNC(18) ; check if we have 'LANTERNA' (otherwise print error message and exit)^b2ed: 0c 11 00 29 IF REG(17)=0 GOTO b31a ; if 'LAMPADA' is still working then print "Parece estar tudo ok." and exit^b2f1: 01 23 PRINT MSG(35) ; otherwise print "Ela esta queimada."^b2f3: 02 EXIT ; exit^b2f4: fc^b2f5: 38 0e 0c VERB(56) OBJ(14) OBJ(12) => 'TIRE' 'LAMPADA' 'RADIO'^b2f8: 11 0c 02 IF HAVE OBJ(12) GOTO b2fd ; do we have object 'RÁDIO'?^b2fb: 1f 0c EXIT DONT_HAVE OBJ(12) ; otherwise print error message and exit^b2fd: 01 19 PRINT MSG(25) ; print "Eu nao sei lidar com esses equipamentos eletronicos."^b2ff: 02 EXIT ; exit
Fixed using POKE 45808,41: POKE 45812,252: POKE 45813,56: POKE 45814,14: POKE 45815,12: POKE 45816,17: : POKE 45817,12: POKE 45818,2: POKE 45819,31: POKE 45820,12## - Attempting to shoot 'ONÇA' with an unloaded revolver typing "ATIRE ONÇA" will fire it anyway but miss the shot. In this case, the bullets counter will overflow (underflow?) to 255, allowing the player to go on a killing spree afterwards:#
b4b5: 1e 05 00 VERB(30) OBJ(5) => 'ATIRE' 'ONÇA'^b4b8: 0f 05 02 IF OBJ(5) IS_NEARBY GOTO b4bd ; is 'ONÇA' here?^b4bb: 1e 05 EXIT CANNOT_SEE OBJ(5) ; otherwise print error message and exit^b4bd: 11 06 03 IF HAVE OBJ(6) GOTO b4c3 ; do we have object 'REVOLVER'?^b4c0: 01 35 PRINT MSG(53) ; otherwise print "O que?"^b4c2: 02 EXIT ; exit^b4c3: 0d 10 01 05 IF REG(16)>1 GOTO b4cc ; at least 2 bullets in revolver?^b4c7: 08 10 REG(16)-- ; otherwise waste a bullet -> WHAT IF REVOLVER IS UNLOADED?^b4c9: 01 3c PRINT MSG(60) ; print "@&++.!'?... errei."^b4cb: 02 EXIT ; exit^b4cc: 16 10 EXEC FUNC(16) ; kill 'ONÇA' (if there's ammo)
This problem is fixed as follows:#b4b5: 1e 05 00 VERB(30) OBJ(5) => 'ATIRE' 'ONÇA'^b4b8: 0f 05 02 IF OBJ(5) IS_NEARBY GOTO b4bd ; is 'ONÇA' here?^b4bb: 1e 05 EXIT CANNOT_SEE OBJ(5) ; otherwise print error message and exit^b4bd: 11 06 03 IF HAVE OBJ(6) GOTO b4c3 ; do we have object 'REVOLVER'?^b4c0: 01 35 PRINT MSG(53) ; otherwise print "O que?"^b4c2: 02 EXIT ; exit^b4c3: 0e 10 02 05 IF REG(16)<2 GOTO b4cc ; last bullet (or none)?^b4c7: 08 10 REG(16)-- ; otherwise waste a bullet^b4c9: 01 3c PRINT MSG(60) ; print "@&++.!'?... errei."^b4cb: 02 EXIT ; exit^b4cc: 16 10 EXEC FUNC(16) ; kill 'ONÇA' (if there's ammo)
Fixed using POKE 46275,14: POKE 46277,2## - It's not possible to solve the 'IDOLO' puzzle (which is a requirement to win the game) since action "COLOQUE CRISTAL NO IDOLO" produces no result (just a blank screen). There's a single incorrect bit in this script:#
b4e5: 12 16 19 VERB(18) OBJ(22) OBJ(25) => 'COLOQUE' 'CRISTAL' 'IDOLO'^b4e8: 11 16 02 IF HAVE OBJ(22) GOTO b4ed ; do we have object 'CRISTAL'?^b4eb: 1f 16 EXIT DONT_HAVE OBJ(22) ; otherwise print error message and exit^b4ed: 0e 19 02 1f IF REG(25)<2 GOTO b510 ; -> INCORRECT INSTRUCTION!^b4f1: 19 15 PUT OBJ(21) INTO_CONTAINER ; (nothing makes sense afterwards)^b4f3: 16 07 EXEC FUNC(7)^b4f5: 19 01 PUT OBJ(1) INTO_CONTAINER^b4f7: 41 ??? ; (invalid instruction)^b4f8: 02 EXIT
This problem is fixed as follows:#b4e5: 12 16 19 VERB(18) OBJ(22) OBJ(25) => 'COLOQUE' 'CRISTAL' 'IDOLO'^b4e8: 11 16 02 IF HAVE OBJ(22) GOTO b4ed ; do we have object 'CRISTAL'?^b4eb: 1f 16 EXIT DONT_HAVE OBJ(22) ; otherwise print error message and exit^b4ed: 0f 19 02 IF OBJ(25) IS_NEARBY GOTO b4f2 ; is object 'IDOLO' nearby?^b4f0: 1f 19 EXIT DONT_HAVE OBJ(25) ; otherwise print error message and exit^b4f2: 15 16 BREAK OBJ(22) ; loose object 'CRISTAL'^b4f4: 07 19 REG(25)++ ; set flag to indicate it's done^b4f6: 01 41 PRINT MSG(65) ; print "Uma luz intensa irradia dos olhos do idolo."^b4f8: 02 EXIT ; exit
Fixed using POKE 46317,15## - Typing "PUXE CORDA" at a certain location opens a secret passage, but repeating this action will change the passage to an invalid state:#
b712: 19 09 00 VERB(25) OBJ(9) => 'PUXE' 'CORDA'^b715: 10 0b 08 IF AT POS(11) GOTO b720 ; at location "esplanada"?^b718: 11 09 02 IF HAVE OBJ(9) GOTO b71d ; otherwise, do we have object 'CORDA'?^b71b: 1f 09 EXIT DONT_HAVE OBJ(9) ; otherwise print error message and exit^b71d: 01 10 PRINT MSG(16) ; print "Pirou companheiro..."^b71f: 02 EXIT ; exit^b720: 0c 14 01 08 IF REG(20)=1 GOTO b72c ; is 'CORDA' tied to 'PEDRA'?^b724: 11 09 02 IF HAVE OBJ(9) GOTO b729 ; otherwise, do we have object 'CORDA'?^b727: 1f 09 EXIT DONT_HAVE OBJ(9) ; otherwise print error message and exit^b729: 01 4f PRINT MSG(79) ; print "Por favor,seja mais objetivo."^b72b: 02 EXIT ; exit^b72c: 07 15 REG(21)++ ; open secret passage -> WHAT IF IT'S ALREADY OPEN?^b72e: 14 13 CREATE OBJ(19) ; create object 'PASSAGEM'^b730: 01 50 PRINT MSG(80) ; print "Grande descoberta..."^b732: 02 EXIT ; exit
Fortunately another address already contains instructions to print MSG(79) and exit, so this problem can be fixed as follows:#b712: 19 09 00 VERB(25) OBJ(9) => 'PUXE' 'CORDA'^b715: 10 0b 08 IF AT POS(11) GOTO b720 ; at location "esplanada"?^b718: 11 09 02 IF HAVE OBJ(9) GOTO b71d ; otherwise, do we have object 'CORDA'?^b71b: 1f 09 EXIT DONT_HAVE OBJ(9) ; otherwise print error message and exit^b71d: 01 10 PRINT MSG(16) ; print "Pirou companheiro..."^b71f: 02 EXIT ; exit^b720: 0c 14 01 07 IF REG(20)=1 GOTO b72b ; is 'CORDA' tied to 'PEDRA'?^b724: 11 09 13 IF HAVE OBJ(9) GOTO b73a ; otherwise, if we have 'CORDA' then print "Por favor,seja mais objetivo." and exit^b727: 1f 09 EXIT DONT_HAVE OBJ(9) ; otherwise print error message and exit^b729: 01 4f PRINT MSG(79) ; (not used anymore)^b72b: 09 15 01 REG(21):=1 ; open secret passage^b72e: 14 13 CREATE OBJ(19) ; create object 'PASSAGEM'^b730: 01 50 PRINT MSG(80) ; print "Grande descoberta..."^b732: 02 EXIT ; exit
Fixed using POKE 46883,7: POKE 46886,19: POKE 46891,9: POKE 46892,21: POKE 46893,1## - Attempting to examine a door typing "EXAMINE PORTA" incorrectly requires a 'MACHADO' and it will try to break it first (although its following action works correctly):#
b8b2: 0b 22 00 VERB(11) OBJ(34) => 'EXAMINE' 'PORTA'^b8b5: 16 23 EXEC FUNC(35) ; attempt to break 'PORTA' using 'MACHADO' -> OPS!^b8b7: 0c 20 00 0a IF REG(32)=0 GOTO b8c5 ; is 'PORTA' closed?^b8bb: 0c 20 01 03 IF REG(32)=1 GOTO b8c2 ; otherwise is 'PORTA' open?^b8bf: 01 60 PRINT MSG(96) ; otherwise print "Ela esta toda quebrada."^b8c1: 02 EXIT ; exit^b8c2: 01 39 PRINT MSG(57) ; print "Ela esta aberta."^b8c4: 02 EXIT ; exit^b8c5: 01 3a PRINT MSG(58) ; print "Ela esta fechada."^b8c7: 02 EXIT ; exit^b8c8: fc^b8c9: 16 22 21 VERB(22) OBJ(34) OBJ(33) => 'ABRA' 'PORTA' 'CHAVE'^b8cc: 16 3a EXEC FUNC(58) ; check if 'PORTA' is here (also print "Ela esta aberta" if it's open or broken)^b8ce: 11 21 02 IF HAVE OBJ(33) GOTO b8d3 ; do we have object 'CHAVE'?^b8d1: 1f 21 EXIT DONT_HAVE OBJ(33) ; otherwise print error message and exit^b8d3: 12 21 DROP OBJ(33) ; drop object 'CHAVE'^b8d5: 09 1f 01 REG(31):=1 ; set flag to indicate 'CHAVE' is now placed at 'PORTA'^b8d8: 09 20 01 REG(32):=1 ; open door^b8db: 1b EXIT OK ; print "Ok." and exit
Fixing this action requires an extra byte that can be saved from its following action:#b8b2: 0b 22 00 VERB(11) OBJ(34) => 'EXAMINE' 'PORTA'^b8b5: 10 1a 05 IF AT POS(26) GOTO b8bd ; at location on either side of door?^b8b8: 10 1b 02 IF AT POS(27) GOTO b8bd^b8bb: 1e 22 EXIT CANNOT_SEE OBJ(34) ; otherwise print error message and exit^b8bd: 0c 20 02 05 IF REG(32)=2 GOTO b8c6 ; is 'PORTA' broken?^b8c1: 16 3a EXEC FUNC(58) ; otherwise if it's open then print "Ela esta aberta" and exit^b8c3: 01 3a PRINT MSG(58) ; print "Ela esta fechada."^b8c5: 02 EXIT ; exit^b8c6: 01 60 PRINT MSG(96) ; print "Ela esta toda quebrada."^b8c8: 02 EXIT ; exit^b8c9: fc^b8ca: 16 22 21 VERB(22) OBJ(34) OBJ(33) => 'ABRA' 'PORTA' 'CHAVE'^b8cd: 16 3a EXEC FUNC(58) ; check if 'PORTA' is here (also print "Ela esta aberta" if it's open or broken)^b8cf: 11 21 02 IF HAVE OBJ(33) GOTO b8d4 ; do we have object 'CHAVE'?^b8d2: 1f 21 EXIT DONT_HAVE OBJ(33) ; otherwise print error message and exit^b8d4: 12 21 DROP OBJ(33) ; drop object 'CHAVE'^b8d6: 09 1f 01 REG(31):=1 ; set flag to indicate 'CHAVE' is now placed at 'PORTA'^b8d9: 07 20 REG(32)++ ; open door^b8db: 1b EXIT OK ; print "Ok." and exit
Fixed using FOR f=47322 TO 47299 STEP -1: POKE f,PEEK(f-1): NEXT f: POKE 47285,16: POKE 47286,26: POKE 47287,5: POKE 47288,16: POKE 47289,27: POKE 47290,2: POKE 47291,30: POKE 47292,34: POKE 47293,12: POKE 47294,32: POKE 47295,2: POKE 47296,5: POKE 47297,22: POKE 47298,58: POKE 47300,58: POKE 47303,96: POKE 47321,7## - Also searching for the door with "PROCURE PORTA" incorrectly requires a 'MACHADO' and it will try to break it first:#
b8dd: 0d 22 00 VERB(13) OBJ(34) => 'PROCURE' 'PORTA'^b8e0: 16 23 EXEC FUNC(35) ; attempt to break 'PORTA' using 'MACHADO' -> OPS!^b8e2: 01 0b PRINT MSG(11) ; print "Achei o que voce queria."^b8e4: 02 EXIT ; exit
This problem is fixed as follows:#b8dd: 0d 22 00 VERB(13) OBJ(34) => 'PROCURE' 'PORTA'^b8e0: 16 3a EXEC FUNC(58) ; check if 'PORTA' is here (also print "Ela esta aberta" if it's open or broken)^b8e2: 01 0b PRINT MSG(11) ; print "Achei o que voce queria."^b8e4: 02 EXIT ; exit
Fixed using POKE 47329,58## - The same problem (incorrectly attempting to break the door with a 'MACHADO') also happens in actions "COLOQUE CHAVE NA PORTA" and "FECHE PORTA" (although the preceding action "ABRA PORTA" works correctly):#
b910: 16 22 00 VERB(22) OBJ(34) => 'ABRA' 'PORTA'^b913: 16 3a EXEC FUNC(58) ; check if 'PORTA' is here (also print "Ela esta aberta" if it's open or broken)^b915: 0c 1f 01 02 IF REG(31)=1 GOTO b91b ; is object 'CHAVE' at 'PORTA'?^b919: 27 03 GOTO b91e^b91b: 10 1a 03 IF AT POS(26) GOTO b921 ; also is player at location "sala com porta ao sul"?^b91e: 01 61 PRINT MSG(97) ; otherwise print "Para isso precisaremos de uma chave."^b920: 02 EXIT ; exit^b921: 09 20 01 REG(32):=1 ; open door^b924: 1b EXIT OK ; print "Ok." and exit^...^b93a: 12 21 22 VERB(18) OBJ(33) OBJ(34) => 'COLOQUE' 'CHAVE' 'PORTA'^b93d: 11 21 02 IF HAVE OBJ(33) GOTO b942 ; do we have object 'CHAVE'?^b940: 1f 21 EXIT DONT_HAVE OBJ(33) ; otherwise print error message and exit^b942: 16 23 EXEC FUNC(35) ; attempt to break 'PORTA' using 'MACHADO' -> OPS!^b944: 12 21 DROP OBJ(33) ; release object 'CHAVE'^b946: 09 1f 01 REG(31):=1 ; set flag to indicate 'CHAVE' is now placed at 'PORTA'^b949: 1b EXIT OK ; print "Ok." and exit^...^b952: 17 22 00 VERB(23) OBJ(34) => 'FECHE' 'PORTA'^b955: 16 23 EXEC FUNC(35) ; attempt to break 'PORTA' using 'MACHADO' -> OPS!^b957: 0c 20 02 0b IF REG(32)=2 GOTO b966 ; is 'PORTA' broken?^b95b: 0c 20 01 03 IF REG(32)=1 GOTO b962 ; otherwise is 'PORTA' open?^b95f: 01 5f PRINT MSG(95) ; otherwise print "A porta esta fechada."^b961: 02 EXIT ; exit^b962: 09 20 00 REG(32):=0 ; close object 'PORTA'^b965: 1b EXIT OK ; print "Ok." and exit^b966: 01 12 PRINT MSG(18) ; print "Sinto muito mas isso nao sera possível."^b968: 02 EXIT ; exit
Fixing action "COLOQUE CHAVE NA PORTA" only requires calling FUNC(58) instead of FUNC(35). However a proper fix for action "FECHE PORTA" requires a few more bytes, so it's necessary to optimize action "ABRA PORTA" in order to save those bytes and also relocate other actions in between, as follows:#b910: 16 22 00 VERB(22) OBJ(34) => 'ABRA' 'PORTA'^b913: 16 3a EXEC FUNC(58) ; check if 'PORTA' is here (also print "Ela esta aberta" if it's open or broken)^b915: 0c 1f 00 03 IF REG(31)=0 GOTO b91c ; is object 'CHAVE' somewhere else (not at 'PORTA')?^b919: 10 1a 03 IF AT POS(26) GOTO b91f ; otherwise is player at location "sala com porta ao sul"?^b91c: 01 61 PRINT MSG(97) ; otherwise print "Para isso precisaremos de uma chave."^b91e: 02 EXIT ; exit^b91f: 09 20 01 REG(32):=1 ; open door^b922: 1b EXIT OK ; print "Ok." and exit^...^b938: 12 21 22 VERB(18) OBJ(33) OBJ(34) => 'COLOQUE' 'CHAVE' 'PORTA'^b93b: 11 21 02 IF HAVE OBJ(33) GOTO b940 ; do we have object 'CHAVE'?^b93e: 1f 21 EXIT DONT_HAVE OBJ(33) ; otherwise print error message and exit^b940: 16 3a EXEC FUNC(58) ; check if 'PORTA' is here (also print "Ela esta aberta" if it's open or broken)^b942: 12 21 DROP OBJ(33) ; release object 'CHAVE'^b944: 09 1f 01 REG(31):=1 ; set flag to indicate 'CHAVE' is now placed at 'PORTA'^b947: 1b EXIT OK ; print "Ok." and exit^...^b950: 17 22 00 VERB(23) OBJ(34) => 'FECHE' 'PORTA'^b953: 10 1a 05 IF AT POS(26) GOTO b95b ; at location on either side of door?^b956: 10 1b 02 IF AT POS(27) GOTO b95b^b959: 1e 22 EXIT CANNOT_SEE OBJ(34) ; otherwise print error message and exit^b95b: 0c 20 02 07 IF REG(32)=2 GOTO b966 ; is 'PORTA' broken?^b95f: 0c 20 00 37 IF REG(32)=0 GOTO b99a ; otherwise if closed then print "Isso já foi feito." and exit^b963: 08 20 REG(32)-- ; close object 'PORTA'^b965: 1b EXIT OK ; print "Ok." and exit^b966: 01 12 PRINT MSG(18) ; print "Sinto muito mas isso nao sera possível."^b968: 02 EXIT ; exit
Fixed using POKE 47383,0: FOR f=47384 TO 47442: POKE f,PEEK (f+2): NEXT f: POKE 47425,58: POKE 47443,16: POKE 47444,26: POKE 47445,5: POKE 47446,16: POKE 47447,27: POKE 47448,2: POKE 47449,30: POKE 47450,34: POKE 47453,2: POKE 47454,7: POKE 47455,12: POKE 47456,32: POKE 47457,0: POKE 47458,55: POKE 47459,8: POKE 47460,32## - Character 'CACIQUE' is supposed to follow the player whenever moving in and out of 'OCA', thus preventing the player from taking his possessions. But once inside, he's unable to ever go back outside due to an incorrect instruction order. There's also an incorrect error message in this action, as follows:#
bc38: 07 34 00 VERB(7) OBJ(52) => 'SAIA' 'OCA'^bc3b: 10 31 02 IF AT POS(49) GOTO bc40 ; at location "dentro da oca"?^bc3e: 1e 31 EXIT CANNOT_SEE OBJ(49) ; otherwise print error message about 'TRONCO' -> OPS!^bc40: 0f 33 02 IF OBJ(51) IS_NEARBY GOTO bc45 ; is 'CACIQUE' here?^bc43: 27 02 GOTO bc47 ; otherwise skip next instruction^bc45: 14 33 CREATE OBJ(51) ; if 'CACIQUE' is here, put 'CACIQUE' here -> OPS!^bc47: 09 01 30 REG(1):=48 ; move outside to location "aldeia"^bc4a: 25 EXIT DESC ; describe location
This problem is fixed as follows:#bc38: 07 34 00 VERB(7) OBJ(52) => 'SAIA' 'OCA'^bc3b: 10 31 03 IF AT POS(49) GOTO bc41 ; at location "dentro da oca"?^bc3e: 01 0e PRINT MSG(14) ; otherwise print "Ficou maluco ???"^bc40: 02 EXIT ; exit^bc41: 09 01 30 REG(1):=48 ; move outside to location "aldeia"^bc44: 0c 83 00 02 IF REG(131)=0 GOTO bc4a ; if 'CACIQUE' is dead then skip next instruction^bc48: 14 33 CREATE OBJ(51) ; put 'CACIQUE' here^bc4a: 25 EXIT DESC ; describe location
Fixed using POKE 48189,3: POKE 48190,1: POKE 48191,14: POKE 48192,2: POKE 48193,9: POKE 48194,1: POKE 48195,48: POKE 48196,12: POKE 48197,131: POKE 48198,0: POKE 48199,2: POKE 48200,20: POKE 48201,51## - Attempting "MATE CACIQUE COM MACHADO" without having object 'MACHADO' produces an unrelated error message:#
bc6d: 15 33 0a VERB(21) OBJ(51) OBJ(10) => 'MATE' 'CACIQUE' 'MACHADO'^bc70: 0f 33 02 IF OBJ(51) IS_NEARBY GOTO bc75 ; is 'CACIQUE' here?^bc73: 1e 33 EXIT CANNOT_SEE OBJ(51) ; otherwise print error message about 'CACIQUE' and exit^bc75: 11 0a 02 IF HAVE OBJ(10) GOTO bc7a ; do we have object 'MACHADO'?^bc78: 1f 06 EXIT DONT_HAVE OBJ(6) ; otherwise print error message about 'REVOLVER' and exit -> OPS!^bc7a: 01 79 PRINT MSG(121) ; print "Ele e muito forte. Nao da para encarar."^bc7c: 02 EXIT ; exit
This problem is fixed as follows:#bc6d: 15 33 0a VERB(21) OBJ(51) OBJ(10) => 'MATE' 'CACIQUE' 'MACHADO'^bc70: 0f 33 02 IF OBJ(51) IS_NEARBY GOTO bc75 ; is 'CACIQUE' here?^bc73: 1e 33 EXIT CANNOT_SEE OBJ(51) ; otherwise print error message about 'CACIQUE' and exit^bc75: 11 0a 02 IF HAVE OBJ(10) GOTO bc7a ; do we have object 'MACHADO'?^bc78: 1f 0a EXIT DONT_HAVE OBJ(10) ; otherwise print error message about 'MACHADO' and exit -> OPS!^bc7a: 01 79 PRINT MSG(121) ; print "Ele e muito forte. Nao da para encarar."^bc7c: 02 EXIT ; exit
Fixed using POKE 48249,10## - Also attempting to shoot 'CACIQUE' with an unloaded revolver typing "ATIRE CACIQUE" will fire it anyway but miss the shot, then the bullets counter will overflow (underflow?) to 255:#
bc7e: 1e 33 00 VERB(30) OBJ(51) => 'ATIRE' 'CACIQUE'^bc81: 0f 33 02 IF OBJ(51) IS_NEARBY GOTO bc86 ; is 'CACIQUE' here?^bc84: 1e 33 EXIT CANNOT_SEE OBJ(51) ; otherwise print error message and exit^bc86: 11 06 03 IF HAVE OBJ(6) GOTO bc8c ; do we have object 'REVOLVER'?^bc89: 01 35 PRINT MSG(53) ; otherwise print "O que?"^bc8b: 02 EXIT ; exit^bc8c: 0d 10 01 05 IF REG(16)>1 GOTO bc95 ; at least 2 bullets in revolver?^bc90: 08 10 REG(16)-- ; otherwise waste a bullet -> WHAT IF REVOLVER IS UNLOADED?^bc92: 01 3c PRINT MSG(60) ; print "@&++.!'?... errei."^bc94: 02 EXIT ; exit^bc95: 16 27 EXEC FUNC(39) ; kill 'CACIQUE' (if there's ammo)
This problem is fixed as follows:#bc7e: 1e 33 00 VERB(30) OBJ(51) => 'ATIRE' 'CACIQUE'^bc81: 0f 33 02 IF OBJ(51) IS_NEARBY GOTO bc86 ; is 'CACIQUE' here?^bc84: 1e 33 EXIT CANNOT_SEE OBJ(51) ; otherwise print error message and exit^bc86: 11 06 03 IF HAVE OBJ(6) GOTO bc8c ; do we have object 'REVOLVER'?^bc89: 01 35 PRINT MSG(53) ; otherwise print "O que?"^bc8b: 02 EXIT ; exit^bc8c: 0e 10 04 05 IF REG(16)<4 GOTO bc95 ; last 3 bullets (or none)?^bc90: 08 10 REG(16)-- ; otherwise waste a bullet^bc92: 01 3c PRINT MSG(60) ; print "@&++.!'?... errei."^bc94: 02 EXIT ; exit^bc95: 16 27 EXEC FUNC(39) ; kill 'CACIQUE' (if there's ammo)
Fixed using POKE 48268,14: POKE 48270,4## - It's not possible to solve the 'ABISMO' puzzle, thus an entire area of the game is inaccessible. The existing message MSG(150)="Uma rajada de vento derrubou o tronco que servia de ponte." implies the correct solution, although the corresponding action is not defined. In order to create enough room to implement the missing action, we can save a few bytes from actions "PEGUE FACAO" and "DE ESPELHO CACIQUE", and also completely replace an implementation of "DE RADIO CACIQUE" (which is defined twice at addresses bd3e and be80):#
bc98: 09 0f 00 VERB(9) OBJ(15) => 'PEGUE' 'FACAO'^bc9b: 0f 0f 07 IF OBJ(15) IS_NEARBY GOTO bca5 ; is 'FACAO' here?^bc9e: 11 0f 02 IF HAVE OBJ(15) GOTO bca3 ; do we already have object 'FACAO'?^bca1: 1e 0f EXIT CANNOT_SEE OBJ(15) ; otherwise print error message and exit^bca3: 21 0f EXIT ALREADY_HAVE OBJ(15) ; print error message and exit^bca5: 10 31 02 IF AT POS(49) GOTO bcaa ; at location "dentro da oca"?^bca8: 27 03 GOTO bcad^bcaa: 0f 33 03 IF OBJ(51) IS_NEARBY GOTO bcb0 ; if so, is 'CACIQUE' here?^bcad: 13 0f GET OBJ(15) ; otherwise get object 'FACAO'^bcaf: 1b EXIT OK ; print "Ok." and exit^bcb0: 01 7d PRINT MSG(125) ; print "O cacique ficou muito furioso com essa tentativa e nos expulsou da sua aldeia."^bcb2: 09 01 32 REG(1):=50 ; move to location "encruzilhada"^bcb5: 09 22 01 REG(34):=1 ; set flag to indicate natives are angry^bcb8: 02 EXIT ; exit^bcb9: fc^bcba: 1a 0b 33 VERB(26) OBJ(11) OBJ(51) => 'DE' 'ESPELHO' 'CACIQUE'^bcbd: 11 0b 02 IF HAVE OBJ(11) GOTO bcc2 ; do we have object 'ESPELHO'?^bcc0: 1f 0b EXIT DONT_HAVE OBJ(11) ; otherwise print error message and exit^bcc2: 0f 33 02 IF OBJ(51) IS_NEARBY GOTO bcc7 ; is 'CACIQUE' here?^bcc5: 1e 33 EXIT CANNOT_SEE OBJ(51) ; otherwise print error message and exit^bcc7: 01 7d PRINT MSG(125) ; print "O cacique ficou muito furioso com essa tentativa e nos expulsou da sua aldeia."^bcc9: 12 00 DROP ALL_OBJS ; player looses all carried objects^bccb: 09 01 32 REG(1):=50 ; move to location "encruzilhada"^bcce: 09 22 01 REG(34):=1 ; set flag to indicate natives are angry^bcd1: 02 EXIT ; exit^...^bd3e: 1a 0c 33 VERB(26) OBJ(12) OBJ(51) => 'DE' 'RADIO' 'CACIQUE' ; exactly the same definition in address be80^bd41: 11 0c 02 IF HAVE OBJ(12) GOTO bd46 ; do we have object 'RADIO'?^bd44: 1f 0c EXIT DONT_HAVE OBJ(12) ; otherwise print error message and exit^bd46: 0f 33 02 IF OBJ(51) IS_NEARBY GOTO bd4b ; is 'CACIQUE' here?^bd49: 1e 33 EXIT CANNOT_SEE OBJ(51) ; otherwise print error message and exit^bd4b: 15 0c BREAK OBJ(12) ; we will never see object 'RADIO' again^bd4d: 16 29 EXEC FUNC(41) ; process gifts to 'CACIQUE'
Implementation of new action "COLOQUE TRONCO NO ABISMO" is straighforward. Notice it uses the congratulations message MSG(151)="Grande ideia..." which is defined right after other messages related to this place but not used anywhere in the game, thus it was obviously intended for this missing action:#bc98: 09 0f 00 VERB(9) OBJ(15) => 'PEGUE' 'FACAO'^bc9b: 0f 0f 07 IF OBJ(15) IS_NEARBY GOTO bca5 ; is 'FACAO' here?^bc9e: 11 0f 02 IF HAVE OBJ(15) GOTO bca3 ; do we already have object 'FACAO'?^bca1: 1e 0f EXIT CANNOT_SEE OBJ(15) ; otherwise print error message and exit^bca3: 21 0f EXIT ALREADY_HAVE OBJ(15) ; print error message and exit^bca5: 10 31 02 IF AT POS(49) GOTO bcaa ; at location "dentro da oca"?^bca8: 27 03 GOTO bcad^bcaa: 0f 33 13 IF OBJ(51) IS_NEARBY GOTO bcc0 ; if so, and if 'CACIQUE' is here then escape from angry natives^bcad: 13 0f GET OBJ(15) ; otherwise get object 'FACAO'^bcaf: 1b EXIT OK ; print "Ok." and exit^bcb0: fc^bcb1: 1a 0b 33 VERB(26) OBJ(11) OBJ(51) => 'DE' 'ESPELHO' 'CACIQUE'^bcb4: 11 0b 02 IF HAVE OBJ(11) GOTO bcb9 ; do we have object 'ESPELHO'?^bcb7: 1f 0b EXIT DONT_HAVE OBJ(11) ; otherwise print error message and exit^bcb9: 0f 33 02 IF OBJ(51) IS_NEARBY GOTO bcbe ; is 'CACIQUE' here?^bcbc: 1e 33 EXIT CANNOT_SEE OBJ(51) ; otherwise print error message and exit^bcbe: 12 00 DROP ALL_OBJS ; player looses all carried objects^bcc0: 01 7d PRINT MSG(125) ; print "O cacique ficou muito furioso com essa tentativa e nos expulsou da sua aldeia."^bcc2: 09 01 32 REG(1):=50 ; move to location "encruzilhada"^bcc5: 09 22 01 REG(34):=1 ; set flag to indicate natives are angry^bcc8: 02 EXIT ; exit^...^bd35: 12 31 42 VERB(18) OBJ(49) OBJ(66) => 'COLOQUE' 'TRONCO' 'ABISMO'^bd38: 11 31 02 IF HAVE OBJ(49) GOTO bd3d ; do we have object 'TRONCO'?^bd3b: 1f 31 EXIT DONT_HAVE OBJ(49) ; otherwise print error message and exit^bd3d: 10 1c 05 IF AT POS(28) GOTO bd45 ; at location on either side of 'ABISMO'?^bd40: 10 25 02 IF AT POS(37) GOTO bd45^bd43: 1e 42 EXIT CANNOT_SEE OBJ(66) ; otherwise print error message and exit^bd45: 15 31 BREAK OBJ(49) ; loose object 'TRONCO'^bd47: 09 29 01 REG(41):=1 ; set flag to indicate it's done^bd4a: 01 97 PRINT MSG(151) ; print "Grande ideia..."^bd4c: 02 EXIT ; exit^bd4d: 16 29 EXEC FUNC(41) ; (not used anymore)
Fixed using POKE 48300,19: FOR f=48304 TO 48443: POKE f,PEEK (f+9): NEXT f: POKE 48318,18: POKE 48319,0: POKE 48320,1: POKE 48321,125: POKE 48437,18: POKE 48438,49: POKE 48439,66: POKE 48441,49: POKE 48444,49: POKE 48445,16: POKE 48446,28: POKE 48447,5: POKE 48448,16: POKE 48449,37: POKE 48450,2: POKE 48451,30: POKE 48452,66: POKE 48453,21: POKE 48454,49: POKE 48455,9: POKE 48456,41: POKE 48457,1: POKE 48458,1: POKE 48459,151: POKE 48460,2## - Typing action "PROCURE FOSSO" (search for pit) incorrectly provides an error message about 'PEDRA' (stone) instead of 'FOSSO' (pit):#
c06a: 0d 40 00 VERB(13) OBJ(64) => 'PROCURE' 'FOSSO'^c06d: 10 2f 08 IF AT POS(47) GOTO c078 ; at location "lado de um fosso"?^c070: 10 12 02 IF AT POS(18) GOTO c075 ; at location "fundo do fosso"?^c073: 1e 12 EXIT CANNOT_SEE OBJ(18) ; otherwise print error message about 'PEDRA' and exit -> OPS!^c075: 01 3f PRINT MSG(63) ; print "Nos estamos nele."^c077: 02 EXIT ; exit^c078: 01 0b PRINT MSG(11) ; "Achei o que voce queria."^c07a: 02 EXIT ; exit
This problem is fixed as follows:#c06a: 0d 40 00 VERB(13) OBJ(64) => 'PROCURE' 'FOSSO'^c06d: 10 2f 08 IF AT POS(47) GOTO c078 ; at location "lado de um fosso"?^c070: 10 12 02 IF AT POS(18) GOTO c075 ; at location "fundo do fosso"?^c073: 1e 40 EXIT CANNOT_SEE OBJ(64) ; otherwise print error message about 'FOSSO' and exit^c075: 01 3f PRINT MSG(63) ; print "Nos estamos nele."^c077: 02 EXIT ; exit^c078: 01 0b PRINT MSG(11) ; "Achei o que voce queria."^c07a: 02 EXIT ; exit
Fixed using POKE 49268,64## - Message MSG(48)="Eu nao estou segurando nenhuma onça po..." could only be an answer to action "SOLTE ONÇA", but this action is not defined anywhere, although another action "PROCURE CACHOEIRA" is defined twice (next to a couple unused instructions):#
c0c9: 0d 24 00 VERB(13) OBJ(36) => 'PROCURE' 'CACHOEIRA' ; (action already defined in b9bb)^c0cc: 2b EXIT DEFAULT_ACTION ; provides default response for SEARCH OBJECT^c0cd: fc^c0ce: 0d 1b 00 VERB(13) OBJ(27) => 'PROCURE' 'CAVERNA'^c0d1: 01 58 PRINT MSG(88) ; print "Estou comecando a me aborrecer com voce. Pense em coisas mais praticas para fazer."^c0d3: 02 EXIT ; exit^c0d4: 19 00 PUT ALL_OBJS INTO_CONTAINER ; (never used)^c0d6: 2b EXIT DEFAULT_ACTION ; (never used)
Thus the missing action can be implemented as follows:#c0c9: 0a 05 00 VERB(10) OBJ(5) => 'SOLTE' 'ONÇA'^c0cc: 01 30 PRINT MSG(48) ; print "Eu nao estou segurando nenhuma onça po..."^c0ce: 02 EXIT ; exit^c0cf: fc^c0d0: 0d 1b 00 VERB(13) OBJ(27) => 'PROCURE' 'CAVERNA'^c0d3: 01 58 PRINT MSG(88) ; print "Estou comecando a me aborrecer com voce. Pense em coisas mais praticas para fazer."^c0d5: 02 EXIT ; exit^c0d6: 2b EXIT DEFAULT_ACTION ; (never used)
Fixed using FOR f=49365 TO 49359 STEP -1: POKE f,PEEK (f-2): NEXT f: POKE 49353,10: POKE 49354,5: POKE 49356,1: POKE 49357,48: POKE 49358,2## - Function FUNC(35) is supposed to handle attempts to break the door, but parts of its logic don't make any sense:#
e1e8: FUNC(35)^e1e8: 11 0a 02 IF HAVE OBJ(10) GOTO e1ed ; do we have object 'MACHADO'?^e1eb: 1f 0a EXIT DONT_HAVE OBJ(10) ; otherwise print error message and exit^e1ed: 0c 20 0a 0e IF REG(32)=10 GOTO e1ff ; -> INVALID VALUE FOR R(32) AND INVALID GOTO ADDRESS^e1f1: 26 RETURN ; return back to action that called this function^e1f2: 04 EXIT LIST_PLAYER ; -> NO REASON TO LIST PLAYER'S INVENTARY HERE^e1f3: 01 26 PRINT MSG(38) ; -> MESSAGE ABOUT 'ONÇA' UNRELATED TO THIS LOCATION^e1f5: 07 26 REG(38)++ ; update break attempts counter^e1f7: 01 85 PRINT MSG(133) ; print "Ufa! Esta dificil mas continue tentando."^e1f9: 02 EXIT ; exit^e1fa: 01 4d PRINT MSG(77) ; print "Isso ja foi feito."^e1fc: 02 EXIT ; exit
The correct implementation would be as follows:#e1e8: FUNC(35)^e1e8: 11 0a 02 IF HAVE OBJ(10) GOTO e1ed ; do we have object 'MACHADO'?^e1eb: 1f 0a EXIT DONT_HAVE OBJ(10) ; otherwise print error message and exit^e1ed: 0c 20 02 09 IF REG(32)=2 GOTO e1fa ; is 'PORTA' broken?^e1f1: 0d 26 03 22 IF REG(38)>3 GOTO e217 ; otherwise if more than 3 attempts then return^e1f5: 07 26 REG(38)++ ; update break attempts counter^e1f7: 01 85 PRINT MSG(133) ; print "Ufa! Esta dificil mas continue tentando."^e1f9: 02 EXIT ; exit^e1fa: 01 4d PRINT MSG(77) ; print "Isso ja foi feito."^e1fc: 02 EXIT ; exit
Fixed using POKE 57839,2: POKE 57840,9: POKE 57841,13: POKE 57842,38: POKE 57843,3: POKE 57844,34## - Function FUNC(53) handles attempt to kill 'COBRA', however it incorrectly checks for location POS(63)="igarape" instead of OBJ(63)='COBRA':#
e30f: FUNC(53)^e30f: 10 3f 02 IF AT POS(63) GOTO e314 ; at location "igarape"? -> OPS!^e312: 1e 3f EXIT CANNOT_SEE OBJ(63) ; otherwise print error message about 'COBRA' and exit^e314: 09 8f 28 REG(143):=40 ; move 'COBRA' to random location^e317: 0b 8f 05 REG(143)+=RND(5) ;^e31a: 01 93 PRINT MSG(147) ; print "Zap, zup... Nao sobrou nadinha dela."^e31c: 02 EXIT ; exit
This problem is fixed as follows:#e30f: FUNC(53)^e30f: 0f 3f 02 IF OBJ(63) IS_NEARBY GOTO e314 ; is 'COBRA' here?^e312: 1e 3f EXIT CANNOT_SEE OBJ(63) ; otherwise print error message about 'COBRA' and exit^e314: 09 8f 28 REG(143):=40 ; move 'COBRA' to random location^e317: 0b 8f 05 REG(143)+=RND(5) ;^e31a: 01 93 PRINT MSG(147) ; print "Zap, zup... Nao sobrou nadinha dela."^e31c: 02 EXIT ; exit
Fixed using POKE 58127,15## - There's no way to visit location "dentro da cabana". Since the word 'CABANA' is not even defined, it's impossible to define an action such as "ENTRE NA CABANA", thus the only possible solution in this case is adding a regular North-South connection to access it.#Fixed using POKE 58396,46: POKE 58433,37