You are on page 1of 25

FixingE.T.

TheExtraTerrestrialfortheAtari2600

Ifyou'rereadingthispage,chancesarethatyou'realreadywellawarethatE.T.fortheAtari2600isoneofthemost
reviledgamesevermade.Ineverunderstoodwhy.Asachild,itwasoneofmyfavoritegames.Istillthinkit'sagood
game.Apparently,I'mnotalone.
OnthispageI'mgoingtobrieflyexplorewhypeoplehateE.T.,andhowthegamecanbefixed.

Contents:
Incaseyoucan'twait
Downloads
WhypeoplehateE.T.
Whypeoplefallinwells
Fixingthefallingproblem
Dealingwiththedifficulty
E.T.isNOTgreen
Spitandpolish
Anewfeature
Squashing30yearoldbugs
NinjaE.T.easteregg
Anewgamemode
Summaryofchanges
Conclusion

Incaseyoucan'twait
OpenyourNTSCE.T.ROMinahexeditorandmakethefollowingchanges:

E.T.isNotGreen

17FA:FEFCF8F8F8
1DE8:04

DifficultyFix(Walk,Run,Hover)

0707:A4F8
071B:A4F8
0685:A4F8
0FEF:AD820229084C4EBB
0B4D:604A4A4A490185F8
04F0:A581291E

FallingFix

002A:4CF6BB
0BF6:A59C690785F64CABBC
1013:05D965E365F6858B4C4BF0
101E:08E48BD00624137002852CE49E08E8
102D:A4868A
1034:8502841C
1060:A587851BA58885068AA8B1BA850EB1BC
1070:850FE49F4C1EF0
18F3:2EF0
0B40:A9EF
07ED:E904
0BA5:22

BUGFIXES

Don'tFallLeavingForestonRight

0D54:4A
0D6C:01

ShipShouldn'tCrushElliott

07BD:4CD9BA

FIXSCORINGTOMATCHMANUAL

058E:85F4A5DD85F565F485DD6910EAEA
1382:4C9DF3
1395:A99985D385D4D009A5F8D002AAA8
13BD:A90105DE85DEA207A0702041F3EA
1341:A5D2C90AF008E91085D2A204A090A5DD
1351:F84CE9F7
17E9:C91F900A8A0910AAA5D3E90785D3D860
13FD:A99985D385D4A90085F485E3
147A:A90085DD85D98594A529C5DCB002A5DC
148A:4CA5F4

Note:Ifyoudon'tincludethedifficultyfix,make
thefollowingchangetothescoringfix:
139D:EAEAEAEAEAEA

EasterEggNinjaE.T.

148A:A5F4C5F5D00CC903D008A9AA85D285D3
149A:85D44CA5F4EAEAEA

AddExtraGameOptionScientistOnly

0471:E005
02ED:2901F009

SpecialthankstoAtariAgeusersNukeyShay,RandomTerrain,KevinMos3,iesposta,androadrunnerfortheir
excellentcommentsandsuggestions.

Downloads
Ifyoudon'tknowhowtouseahexeditor,orifyou'rejustlazy,youcandownloadamodified.binfilehere:
ET_Fixed_Final.bin
ET.bin(unmodified)
NOTE:Ifyouwanttoplaythegamewiththeoriginaldifficulty,settheB&W/ColorswitchtotheB&Wposition.
Thiswillcompletelydisablethedifficultyfix,butleavetheotherchangesinplace.

WhydopeoplehateE.T.?
So,whydopeoplehateE.T.?Whenitwasreleased,itwaswellaheadofitstime.Itpioneeredalotofconceptsthat
wetakeforgrantedingamestoday,butwereunheardofin1982(Atari'sAdventureandHauntedHousehadsomeof
thesefeatures,butnotall):
Itwasoneofthefirsthomevideogameswithatitlescreen.
Itfeaturedanopenendedworldwithgameplayfocusedonexploration.
Itwascompletelynonviolent.Youcan'thurtthebadguys,andtheycan'thurtyou.Thereisn'tevenany
competition!
Youcouldcompletethegame.Therearealsoseveralgoalsthatyouneedtocompletetowinthegame.
Thereweremultiplewaystocompletegoals.Youcanactuallyfinishthegamewithoutfallinginasinglewell.
Thegamenotonlyhadanending,italsofeaturedananimatedcutsceneasareward.
Thegamefeaturedoptionaladditionalgoalstocomplete(sidequests).
Whilethatseemslikeagreatlistoffeatures,playersin1982weren'tpreparedforthatmuchchange.Youreally
neededtoreadthemanualtounderstandthegameandhowtoplayit.Asyoungerchildrenweretheprimary
audience,it'snosurprisethatitwasn'twellreceived.
Ofcourse,thatdoesn'texplainwhythegameissohatedtoday.Ifwecanidentifythereasonswhy,wecantryto
addressthem.Herearetheproblemsthispagewilladdress:
Thegameseemsincrediblycomplex.Thisisn'tarealproblem.Onceyoulearnhowtoplay,it'sreallyvery
simple.Youjustneedtoreadthemanual,orwatchatutorialvideo,tounderstandit.
Thegameisincrediblyhard.It'sdifficultfornovicestocompletethegameevenonmode3,theeasiest
setting.Fortunately,thiscanbefixed.
Youspendalotoftimeaccidentallyfallingintowells.IbelievethatIknowreasonwhythishappenstoso
manypeople,andwhatcanbedonetofixit.
E.T.isnotgreen.I'mreallysurprisedthatthisisn'tacommoncomplaint.We'llfixthataswell.

Whypeopleaccidentallyfallintothewells
Themyth:Alotofpeopleblamepoorcollisiondetectionforthisproblem.Thatissimplynottrue.Thecollision
detectioninE.T.isperfect.Therearenoboundingboxeslikeinmoremoderngames.Collisiondetectionhappensat
thepixellevel.Youcan'tgetanybetterthanthat.Ifyoufallintoawell,it'sbecauseyourplayercharactervisually
overlapsit.
Theactualproblem:Wedon'twantpixelperfectcollisiondetection!
Thereasonthatpeoplesoeasilyfallintowellsisthattheydon'texpecttofallwhen,forexample,E.T.'shead
overlapsawell.Afterall,hisfeetareclearlyonsolidground!

Figure1:E.T.appearstobestandinginfrontofawell.
However,becausecollisiondetectionispixelperfectand
someofthespritepixelsoverlapthewellpixels,E.T.is
suretofall.Thisisabadthing.
E.T.usesaweirdperspectivenotwellsuitedforpixelperfectcollisiondetection.It'sanoverheadview,butwesee
E.T.andtheothercharactersfromtheside.Anarticleontvtropes.orgcallsthis"ThreeQuartersView"anddescribes
itasa"tiltedbird'seyeviewperspective".
Nintendo'sTheLegendofZeldausesthesameperspective,butyoudon'thearalotofcomplaintsaboutaccidentally
runningintoenemiesorobstacles.

Figure2:AsimilarperspectiveisusedinTheLegendof
Zeldathoughitsomehowmanagestobeevenstranger.
Thefloortilesandblocks,theouterwalls,andtheplayer
characterareallshownfromdifferentperspectives.This

doesn'thurtthegameinanyway,itactuallymakesit
better.
Zeldausesaneattricktomaketheperspectivefeelmorenaturalwhenplayingandlesslikethecharactersarelying
ontheirsides.Collisiondetectionisdesignedaroundwhereyourplayercharacterappearstobe,notbywhatsprites
happenstooverlap.InZelda,whenyouapproachanobstaclefromthesouth,forexample,itdoesn'tobstructyour
movementuntilabouthalfofyourspriteoverlapsit.

Figure3:(Left)Ourplayercharacterappearstobe
standingintherowoffloortilesbelowtheblock.The
playerassumesthattheyareabletomoveforwardasthere
areclearlynoobstaclesintheway.However,ifcollision
detectionwaspixelperfecttheywouldbeobstructedby
theblock.(Right)Thankstogooddesign,wecandothe
obvious:walkonthetilesinfrontoftheblock.
IfwecanmodifythecollisiondetectioninE.T.sothatit'snotpixelperfect,butbasedonwheretheplayercharacter
appearstobe,wecangivetheplayerthesameintuitiveadvantagesthatZeldaplayersenjoy.InthecaseofE.T.,such
achangeissimple:wejustneedtoensurethatonlycollisionswithE.T.'sfeetaredetected.Thegamewillfeelmuch
morenatural,andplayerswon'tfallintowellsaccidentallynearlyasoften.

Fixingthefallingproblem
Thefixisprettysimple.AllweneedtodoisclearthecollisionlatchessometimebeforewefinishdrawingtheE.T.
sprite.Oneortwoscanlinesbeforetheendshouldworkoutgreat.Thatmaynotseemlikealot,butitreallyisthe
mostappropriateplace.It'llalsoletusstandontheinneredgeofthe"v"shapedwells.I'vealwaysthoughtyoushould
beabletodothat.

Figure4:Wherenoextraterrestrialhasgonebefore!
Wedon'thaveaccesstothegame'ssourcecodeandthedisassemblerIhavefor2600gameswon'tworkifthegameis
over4k.Ifwe'regoingtofixtheproblem,we'vegottomodifytheROMsomehow.Agoodhexeditorcoupledwith
theniftydebuggerincludedinStellaandwe'rereadytogo.Thatmaybeabitoptimistic.AseveryAtari2600

developerknows,yourarelyhaveandabundanceoffreespaceontheROMandroutines(particularlyinthekernel)
aregenerallykeptverytightwithlittleornowastedcode.
Tomakemattersworse,toimplementourfixwe'llneedtoaddsomecodetothekernel.Ifyou'refollowingalong,
takealookatkernelcodestartingat1006.Asit'sunlikelythatHowardScottWarshaw(thedeveloper)includedsome
uselesscodeforustoreplace,wemaywanttoconsiderhijackingajump,runningourroutineinsomeunusedspoton
theROM,andreturning.Aquicklookpresentsuswithacandidateat1074.Wecouldrunourroutineandjumpback
to1022.Unfortunately,timeisalsoanimportantfactor,especiallyinthekernel.Wedon'tevenhaveenoughtimeto
jumpoutandreturn,letalonerunourroutine.Wecoulduseanextrascanline,butthatdoesfarmoreharmthanjust
makingourgraphicslookblocky:candywon'tappearandhintareas,forthemostpart,won'tdisplaythelocationof
phoneparts.Giveitatryifyou'refeelingambitious,justdon'tforgettoincrementXoryou'llendupwithaflickering
mess!
Backtothekernelwegotoseewhatwecanchange.Afewroundswiththedebuggerandyou'llnoticethatthecode
at101Cto101EultimatelydoesnothingasthereisaTXArightafterthejump.Uselesscodeinthekernelisunusual.
Lookingalittlefurtherback,wefindthatthecodestartingat1013setsCOLUP0tosomeinexplicablytwistedvalue
basedonwhateverisstoredin81.Thisisweirdbecause88isusedtoholdthatcolor,aswecanseefromthecodeat
1047to1049.Evenstranger,thiscodeisnevercalledonlineswherewedrawGRP0.Thecodefrom1013to101E
appearstodonothingbutburnafewcycles.(That'sexactlywhatit'ssupposedtodo,fortiming.)Afteragoodbitof
doublechecking,itbecomesobviousthatcansafelyreplaceit.Thisisgreatnewsforusasthatmeanswehavea
whole12byteswecanchange!SinceXholdsthecurrentyposition,that'smorethanweneedforourroutine.Lucky.
TheideaistostrobeCXCLRbeforewedrawthelastlineofthespritesothatanycollisionsrecordedtothatpointare
eliminated.TheeffectwillbethatonlycollisionswithE.T.'sfeetwillbedetected.Thecodeisprettysimple,9Cholds
E.T.'sypositionsowejustneedtosubtractsomeamountofE.T.'sheightfromourcurrentypositionandcompareit
tothevalueat9Ctoseeifwecansafelyclearthecollisionlatches:

1013:TXA;2;8A
1014:SBC#$08;2;E908
1016:CMP$9C;3;C59C
1018:BCS$F01C;2;B002
101A:STACXCLR;3;852C

Giveitatry.Itlookslikewe'redone,buttherearestillafewproblems:
Wecan'tpickupphoneparts.(We'llfixthisalittlelater.)
Weneedtosteponcandytocollectit.(Thisisaproblemwecan'tyetavoid.)
Theroutineisn'tcalledwhenthereisanothercharacternexttoyou.(Rememberthatwediscoveredthecode
wereplacedwasnevercalledonlineswherewedrawGRP0?)Ifpartofyourspriteoverlapsawelland
anothercharacterapproaches,thecollisionlatcheswon'tgetclearedandyou'llfallrightit!
Thereisn'tanotherjunkspotwecandumpourroutinethatisalwayscalled,sowe'llneedtofindanadditional9bytes
thatwecansafelyoverwrite.Constraintsaretighterhere,aswe'llneedtofindsomecodethatwecaneliminatethat
alsohappenstobecalledallthetime,orwhenourotherroutineisn't.That'saprettytallorder.Couldwereallybethat
luckyorwillweneedtofindsomecodethatisn'tessentialtothegame,anddealwithanyunwantedconsequences?
Afewroundswiththedebuggerturnsup8wholebytesat1062thatlookredundant.Didn'twealreadyhandlethatat
103B?Itturnsoutthatwedidn't.Takealookat1043.Thenextspriterowisreadandsavedforlateruse.Later,sadly,
meansat1062.Ifwereplacethiscodeitmeansthatwewon'tupdateGRP0andCOLUP0.Thatmeanswe'llendup
duplicatingthepreviousrow.We'llessentiallybetossingouthalfofourspritedata.Itwillappearasthoughevery
otherlineinourspritewasoverwrittenbythepreviousline.Thatsoundsbad,butintheenditmeansthatwecanuse
thesebyteswithoutfearastheonlyconsequencewillbethattheothercharactersandthephonepartswilllookabit
pixelated(eachrowbeingfourscanlinestall).Ofcourse,onanAtari2600,that'snotexactlyamajorissue.Weneed
atleast9bytesforourroutine,butourluckisholdingoutandwecansafelyeliminatetheWSYNCat1060givingus
awhole10bytestouseasweplease.We'llalsoneedtoslightlymodifyourroutine.Ifyou'vebeenfollowingalong
withadebugger,youcanprobablyguesswhy.

1060:NOP;2;EA
1061:TXA;2;8A
1062:SBC#$07;2;E907
1064:CMP$9C;3;C59C
1066:BCS$F06A;2;B002
1068:STACXCLR;3;852C

Note:Wesubtract7,not8likebefore.

Figure5:TheFBIAgentbeforeandafter.Itlooksworse
whenyouputthemsidebyside.OnlydiehardE.T.fans
willnoticethechangeduringactualplay.
::UPDATE::ThankstotheexcellentsuggestionofAtariAgeuserNukeyShay,wecan(mostly)saveoursprites.
(Apparently,thediehardE.T.fansnoticedandwerenotimpressed!)Everyotherlinewillstillbethesamecolor,but
atleasttheywon'tbeablockymess.
NukeyShay'sideawastoprecalculatethelocationwherewewanttostrobeCXCLR.Insteadcalculatingtheposition
we'relookingforoneveryline,wedoitonceperframeandstoretheresultsothatwecanjustdoaquickCPX.This
savesusa3bytesand4cycles.Wecanspendthese(plus2cyclesfromtheNOP)onanLDAandSTAtoupdate
GRP0.Thatwillmakeourspriteslessblocky,butwe'llstilllosesomecolordetail.Elliott'sshirtwillloseitsstripes
andtheFBIagentwilllosehishair.
Oursecondroutinenowlookslikethis:

1060:LDA$87;3;A587
1062:STAGRP0;3;851B
1064:CPX$8B;3;E48B
1066:BCS$F06A;2;B002
1068:STACXCLR;3;852C

Note:We'llsaveourprecalculatedlocationat8B,whichisunused.

Ofcourse,westillneedtoprecalculatethepositionandstoreitat8B.We'vegotalittlefreeROMspaceinBank0,
andtonsoftimeduringVBLANK,sowecanrunourroutinejustbeforewewaitoutthetimer.We'llstealthejumpto
0CABat002A,callourroutineat0FF0,andthenjumpto0CABtowaitoutthetimer.

002A:JMP$BFF0;3;4CF0BF

0FF0:LDA$9C;3;A59C
0FF2:ADC#$07;3;6907
0FF4:STA$8B;3;858B
0FF6:JMP$BCAB;3;4CABBC

Thatsolvestheproblem.NowE.T.won'tfallintoawellunlesshisfeetareoverthehole.Movingaroundinthegame
feelsalotmorenatural.Ofcourse,itdoesn'tmatterhowgreatthecontrolsareifwecan'tcollectphonepartsto
completethegame!
Ifyou'vebeenfollowingalong,you'veprobablyalreadyfiguredoutthatthereasonwecan'tcollectphonepartsis
becauseE.T.'sfeetnevertouchthem.HoveringuptomakeE.T.'sfeettouchthemdoesn'twork,whichseemsobvious
inretrospect.
Thesimplestsolutionistojustmovethephonepartsdownthescreenalittlebitsothatthey'relyingontheground
andnothoveringinmidair.It'saneasyfix,justonebyte.Change0BEEfrom32to36.

0BED:LDA#$36;2;A936

That'sallthereistoit.It'snotperfect,butwe'llimproveitlater.

Dealingwiththedifficulty
Thegameisnowactuallyeasytocompleteoneasymodeandmuchmorefuntoplayintheothergamemodes.Itmay
stillbeabittoodifficultforsome,solet'sseewhatwecandotomakethegamelesspunishing.
E.T.focusesheavilyonexploration.Notonlydoyouneedtofindthephoneparts,butalsoalocationforyourshipto
land,andasuitablespotto"phonehome".Thereisalsostrategicexplorationtoidentifythespotswhereyoucancall
Elliott,eatcandy,andsendthescientistandFBIagentbacktotheirrespectivebuildings.Let'snotforgetsidequests.
Theproblem,ofcourse,isthatthegamepunishesyouforexploring.Everystepyoutakeusespreciousenergy.Rather
thanafunactivity,explorationissomethingtoavoidwheneverpossible.
Asthereareplentyofotherwaystoloseenergyasidefromjustmovingaround,wecanreducetheamountofenergy
ittakestomovearoundtozerowithoutmakingourselvesinvincible.Thegamewillstillbechallenging,justnot
nearlyasfrustrating.
E.T.losesenergybymovingaroundinthreedifferentways:walking,running,andhoveringupward.Usingour
debugger,wecanstepthroughthecodetofindtheplaceorplaceswhereweloseenergy.Somepeoplemaythinkthat
runningorhoveringshouldstilltakeenergyaway.Conveniently,therearethreeplacesweneedtochange.Eachline
presentedbelowisindependentoftheothers,sojustdon'tmakethechangesforrunningorhoveringifyoudon'twant
them.

TheOriginalcode:
0707:LDY#$01;3;A001;LoseenergyWalking
071B:LDY#$01;3;A001;LoseenergyRunning
0685:LDY#$01;3;A001;LoseenergyHovering

TheNewcode:
0707:LDY#$00;3;A000;LosenoenergyWalking
071B:LDY#$00;3;A000;LosenoenergyRunning
0685:LDY#$00;3;A000;LosenoenergyHovering

It'seasytoseehowtochangethecodetotakemoreenergyawayifyou'reafteradditionalchallenge.Youcould,for
example,doubletheenergyyouusewhenrunningbychanging071Cto02.
::UPDATE::AtariAgeuserRandomTerrainnoticedthatthereisaproblemwiththesoundthatplayswhenE.T.is
hovering.
Thatparticularproblemiscausedbytheseeminglysimpledifficultyfixforhovering.Itturnsoutthattheroutinethat
playsthehoveringsoundusesthelowerpartofyourenergy(thelastdigit,maskedoffwithanAND#$0F)topace
thetones.Ifweset0686to0,you'lleitherhearanannoyingtoneornosoundatall,dependingonthelastdigitof
yourenergycounterwhenyoustarthovering.Tofixthis,we'llneedmodifythatroutineat04EE.
We'llneedtoreplacethereferencetoD4withanothermemorylocationwithavaluethatchangesregularly.81isa
goodcandidate,butitchangesabittoofrequently.Wecanslowthepacetomatchtheoriginalfairlywellbychanging
themaskto1E.

04F0:LDA$81;3;A581
04F2:AND#$1E;2;291E

Ifyoustillthinkthegameistoodifficult,youcanskipthechangesabove(exceptthesoundfix)andmakethe
followingchange:

0FD5:LDA$D3;3;A5D3

Thischangecopiestheupperpartofyourenergycountertothelowerpart,makingenergyanonissue.Youonlylose
energyifyoufallintoawellandfailtocatchyourself.You'dneedtomakethatmistake99timesbeforeyoupass
out,assumingthatyoudon'teatanycandybetweenfalls.Ifthatwasn'tenough,youstillwon'tloseasElliottwill
cometoreviveyouafewtimes.Idon'trecommendthischange.

E.T.isNOTgreen!
WhyisE.T.green?YouneedtoaskHowardScottWarshawaboutthat.E.T.isbrown,however,notgreen.Thereis
absolutelynoreasonwhythegameshouldn'tuseapropercolorforE.T.
Here'swhatweknow:
TheE.T.spriteusesGRP1.
COLUP1isnotsetanywhereinthekernel
E.T.'scolorchangesashelosesenergy
OurenergylevelisstoredacrossD3andD4
ThevaluesatD3andD4arestoredasBCD
Wedon'tknow,butcanassume,thatGRP1and,consequently,COLUP1areusedinthetopbar.(Itturnsoutthatthey
are.)Withourdebugger,wecanstepthroughthecodecalledafterthetopbarhasbeenrenderedandbeforeweenter
thekernelat102E.We'relookingforanythingthatchecksourenergylevelorthatsetsCOLUP1.It'snotlongbefore
wefindthisgem:

165E:LDA$D3;3;A5D3
1660:LSRA;2;4A
1661:LSRA;2;4A
1662:LSRA;2;4A

1663:LSRA;2;4A
1664:LSRA;2;4A
1665:TAX;2;AA
1666:INX;2;E8
1667:LDAF7F9,X;4;BDF9F7
166A:STACOLUP1;3;8507

Itdoeseverything:ItreadstheupperpartofourenergylevelandsetsCOLUP1.WenowknowthatE.T.'scolorsare
storedstartingat17F9,buthowmanyofthosebytesdoweneedtochange?RememberingthatthevaluestoredatD3
isBCDweknowthatafter1163we'llhaveavaluebetween0and9.Onemoreshift(todivideby2)andwe'releft
withoneof5possiblevalues:0,1,2,3,and4.Clever,isn'tit?
WhytheINX?You'dthinkthatitwasunnecessaryaswe'dneedonlychangeF7F9toF7FAtoskiptheinstructionand
saveapreciousbyteofROMspaceandtwocycles.Ifyoutakealookatthecodealittlefartherbackyou'llfindthat
thebyteatindex0isusedasacolor,butinaspecialcase.(WhenE.T.haspassedout,ifyou'recurious).The
importantthinghereisthatwenowknowthattochangeE.T.'scolor,weneedonlychangethose6bytesstartingat
17F9.
We'llneedtoconsultaTIAcolorcharttofigureoutwhatcolorsweshoulduse.

OriginalColors:
17F9:0EDEDCDADADA

NewColors:
17F9:0EFEFCF8F8F8

IchangedtheluminanceandnotjustthehueasFAlookedtoolight.Unfortunately,thatchoicemakesE.T.practically
invisibleagainstthegraybackgroundinthewells.Ratherthangiveinandusethelightercolor,wecanjustmakethe
backgroundofthewellabitdarker.It'sasmalldifferencethatwon'tbenoticeableduringplay.
Asyou'vealreadyguessed,thecodetochangeCOLUPFandCOLUBKoughttobenearthecodetosetCOLUP1:
afterwedrawthetopbarbutbeforeweenterthemainkernel.Nosurprise,wefindthecodewe'reinterestedinjusta
fewbytesdownat166Eto1680.Thecodeworksthesameway,readingacolorfromabytearray.COLUPFfrom
1DD9andCOLUBKfrom1DE2.Playuntilyoufallintoawellandthentakealookatthevaluestoredat80when
wegetto166Etogettheindexweneed.(Forthelazy:It's6,givingus1DE8.)
Betweenthecolorchartandourunderstandingofthecodestartingat166Ewecanchangethewellforegroundand
backgroundcolorstoanythingthatwewant.Grayalwaysseemedtometobeanoddchoice,butI'llstickwith
traditionhereandjustmakethebackgroundashadedarkersothatE.T.standsout.

1DE8:04

Ifyouwanttochangethewellforegroundcolor,thatvalueisstoredat1DDF.

Figure6:E.T.lookingsharpwithhisfancynewcolor.

SpitandPolishFinishingtheProject
Thingsarelookinggood,butthey'renotgoodenough.Let'sseeifwecanpolishthisupandmakeitreadyfor
production.
Herearetheproblems:
Elliott'sShirthasnostripes
TheFBIAgentlosthishair
E.T.losesdetailontherightsideofthescreen
CandyPiecesaremuchmoredifficulttocollect
Objectsinwellsaredrawntoofardown,makingtheflowerlookodd
ABigOne:Elliottcan'treviveE.T.
AsaBonus,let'salsomakeourdifficultyfixaselectableoption.

Findingsomespace
WhatpurposedoesM0serve?Ihaveabsolutelynoidea.It'sonlysettooneoftwofixedverticalpositions(7Fand
33),andonlyattwofixedhorizontalpositions.It'sdisplayedonlywhenE.T.isdead(onthesadendingscene),about
halfwayacrossthethebottomoftheplayarea.Itchangestovariousshadesofred.That'sfromthecode,I'venever
actuallyseenitduringplay.I'vetakenthetimetoseeifthatreallydoeshappen,andwhatitlookslike.M0showsup
directlyoveradeadE.T.,givinghimtheappearanceofbeingfatallywounded.
WhileIwashopingforanocompromisesolution,thisissomethingI'mwillingtoremove.Itwon'tbemissed.We'll
tradeitforanimprovedkernelandanewfeaturemuchbetterthanableedingE.T.
Withthatgone,wefreeup3bytesand6cyclesinourkernelat1028.Lookingafewbytesdownat102F,you'llsee
anobviouslyuselessSEC.It'sactuallyusedfortiming,butwe'llmakeupforthatwithournewchangesanyway.For
now,itcanbeconsidered1freebyteand2preciouscycles.CoupledwiththeWSYNCwecanremoveat1060,that
givesus6freebytesand11cycles.We'llusethesetomakeachangetoourkerneltoimplementourfallingfixwhile
preservingspritecolorsandmakingiteasiertocollectcandy.
Theideaissimple:Wehavealotofstufftodrawearly,sodothatfirst.Withtheextraspaceandtime,we'llcheckto
seeifwe'reonthelinewe'dnormallystrobeCXCLRforourfallingfix.Insteadofclearingitrightaway,checkto
makesurewehaven'ttouchedanycandy.That'sgoingtotakeawhopping10bytesand12cycles.

CPX$8B;3;E48B
BNE+6;2;D006
BITCXP1FB;2;2413
BVS+2;2;7002
STACXCLR;3;852C

Thankfully,wecansparetheextracycle.Thoughwherearewegoingtofindanextra4bytes?
Rememberallthatdeadcodeat1013weusedforthefirstversionofourfallingfix?It'sjusttimingcode,thereto
wastesomecyclessothateverythingisdrawnatjusttherightplace.Wedon'tultimatelyneeditforourfallingfix
(thoughweleftitinanyway)sowe'refreetouseitforsomethingelse,providedwe'recarefulaboutourtiming.The
codewe'regoingtochangestartsat1060andbranchesintothecodeat1022.Thatputsusdirectlybelowtheuseless
codeat1013.Wecansnagafewbytesfromthereandjustadjustthejumpat1074.
Tostart,we'llkilltheWSYNCat1060andmoveeverythingbeforethejumpto1022(at1074)uptwobytes.We'll
movetheCPXat1022totheholewecreatedat1072givingus:

1060:LDA$87;3;A587
1062:STAGRP0;3;851B
1064:LDA$88;3;A588
1066:STACOLUP0;3;8506
1068:TXA;2;8A
1069:TAY;2;A8
106A:LDA$BA,Y;5;B1BA
106C:STAPF1;3;850E
106E:LDA$BC,Y;5;B1BC
1070:STAPF2;3;850F
1072:CPX$9F;3;E49F

Next,we'llgrabfourbytesfromourdeadcodebymovingthejumpat101Fto101B.We'llthenupdateourjumpat
1074(thatusedtopointto1022)topointto101E.

101B:JMPF04B;3;4C4BF0

1074:JMPF01E;3;4C1EF0

Nowwecancleara10bytespotforourroutine.MovethePHPat1024to101E.(WecangetawaywiththisasJMP
doesn'taffectanyflags.)NowmoveeverythingfromtheCPXat1025totheTXAat102Edownabyte,overwriting
theuselessSECat102F.
Poppinginournewroutineat101F,weget:

101B:JMPF04B;3;4C4BF0

101E:PHP;3;08

1029:CPX$9E;3;E49E
102B:PHP;3;08
102C:INX;2;E8
102D:LDY$86;2;A486

101F:CPX$8B;3;E48B
1021:BNE+6;2;D006
1023:BITCXP1FB;2;2413
1025:BVS+2;2;7002
1027:STACXCLR;3;852C

102F:TXA;2;8A

Ifwetrythegamenow,it'llcrash.Thekernelentrypointisat102E,whichnowinthemiddleofaninstruction!The
CPUwillthinkthatwe'retryingtoSTX$8Aandwhoknowswhatelseafterward!We'llneedtoadjustourentrypoint
downabyte.It'sburiedinatableat18F3.Theaddressisloadedat16A0andshovedontothestack.Wejumpinto
thekernelwithanRTSat16B5.TheRTSinstructionpopstheaddressoffthestackassetsthePC,butinexplicably
adds1intheprocess.Thatmeanswe'llneedtospecifyanaddress1bytebeforetheonewewant.It'sweird.Wejump
toournewaddress...byspecifyingouroldone.

18F3:$F02F;;2EF0

Nowifwereplacethe8bytesfrom1013to101AwithNOP's(EA,usingup16cycles)wecantryoutournewkernel.
Aquicktestshowsthatwe'reclearlynotdone.E.T.stilllosesresolutionontherightsideofthescreen!Remember
thatuselessSEC?WeneededittodelayupdatingGRP1at1034untilwewerefinisheddrawingtheplayarea.Thefix
iseasy,justswapitwiththeWYSNCat1036.

1034:STAWSYNC;3;8502
1036:STYGRP1;3;841C

That'salotbetter,butwe'restillnotdone.Elliottstillcan'treviveE.T.,andwestillneedtotouchphonepartswith
ourfeet,meaningwestillneedtopushobjectsinwellsdownafewlines.We'vealsointroducedanewproblem:E.T.
isn'tcenteredinthespaceshiponlandingortakeoff.Atleastthatoneiseasytofix.Allweneedtodoisadjustthe
startingpositionofthespaceshipforlanding(at0B40)andtakeoff(at07ED):

0B40:LDA#$EF;2;A9EF
07ED:SBC#$04;2;E904

So,whycan'tElliottreviveE.T.?ToreviveE.T.,Elliottneedstotouchhim.Unfortunately,the"E.T.haspassedout"
spriteismuchshorterthanthenormalE.T.sprite,andweclearthecollisionlatcheswellbelowthelastline.Itdoesn't
matterwhereElliottispositioned,he'llnevertouchE.T.afterwestrobeCXCLRastherewillbenothingforhimto
touch.
Thereareacouplethingswecoulddo.Insteadofadding7whenwecalculatethepositiontoclearthecollision
latches,wecoulddothesensiblethingandaddE.T.'sheightandposition,thensubtract2beforestoringitin8B.That
waywe'llhavealineforElliotttotouchonthemuchshorterE.T.sprite.Unfortunately,thatwon'twork.Evenifwe
movethecodetocalculatethepositionjustaboveE.T.'sfeettothe10freebytesat0BF6(whichwewillanyway)
we'llneed8bytesforthemathandthreetojumpto0CAB.That's11bytes.Ourluckisn'tholdingout,astheredoesn't
seemtobeanyuselessbytestospare.Allthesame,let'smovethatroutineanywayinpreparationforourcoolnew
feature.

002A:JMP$BBF6;3;4CF6BB

0BF6:LDA$9C;3;A59C
0BF8:ADC07;3;6907
0BFA:STA$F6;3;85F6
0BFC:JMP$BCAB;3;4CABBC

(Waitaminute!WhyarewestoringtheresultatF6whenournewkernelisexpectingthatat8B?Thereisareason,
aswe'llsoonsee.)

WecouldalternatelychecktoseeifE.T.haspassedout,andskipstrobingCXCLR.Thesametrickwouldworkfor
PhonePartsaswell,bycheckingtoseeifE.T.isinawell.Ofcourse,there'sabsolutelynowaywecandothatatthe
sameplacewedoourotherchecksat1023.Thatshouldn'tbeaproblem,asweonlyreallyneedtodothosechecks
onceasthey'renotdependentonE.T.'sverticalposition.That'sgreat,buthowdoweskipclearingthecollision
latches?There'snotenoughroomforevenoneextracheck.
Wecouldmodifyourcalculatedvaluetopointtosomeotherlocation.Settingitto0wouldbeideal,butwhatabout
thisprocesshasbeenideal?Wealsoneedaplacetostuffourchecks.Acheckusuallycostsusagood4bytes,twoto
setflagsandanothertwotobranch.Thatwouldmakeitseemlikewe'dneedatleast10bytes(another2bytestozero
8B).Naturally,wedon'thave10usablebytesplus1or3extrabytesforareturn.Notanywhere.
Now,wedohave8bytesat1013,fortiming,justbeggingtobeusedinourkernel.Theproblemisthatnotonlydo
weneedtosqueezeourroutineinto8bytes,wemustalsoburnthrough12to16cycles(nomore,noless)tokeepour
timingright.
Here'swhatweknow:
D9isnormally0,butissetto40whenwe'rehoveringoverawell,20whenwe'reatthebottomofawell,and
80whilewe'refallingin.
E3isnormally0,butissettoC0whenE.T.haspassedout
E.T.'sverticalpositionwillneverexceed3A
E.T.'sverticalpositionwillneverfallbelow30whilestandinginawell
E.T.willnevercollectanythingorfallinawellwhenhisverticalpositionis0
WeonlydrawGRP0onthefirstscanlinewhenthemothershipistakingofforlanding
Thatmeansourtimingcodeat1013,forallpracticalpurposes,willalwaysbecalledonthefirstscanline.
Whatcanwedowiththis?AddingD9andE3to8Bwillnormallydonothing.Ifwe'reatthebottomofawell,D9
willbesetto20,andE3willbe0(ifE.T.ishealthy)andC0(ifnot)Thatmeans8Bwillbearound10(+16)or50
(+80),inanycase,welloutsidetheareawecareabout.(It'llbewellaboveE.T.orbelowtheplayarea).Ifwe'renotin
awell,D9willbe0andaddingC0(64)toanypossibleE.T.positionwillalwaysresultinavalueintherangeFA(6)
toC0(64).
Thisisgreat.Wecandothatin8bytesandinprecisely12cycles(theminimumweneedtoburn).Theonlyproblem
isthatourlittleroutinewillbecalledmorethanonce.Wecan'tjustkeepmodifying8Bandhopeforthebest.The
simplesolutionistokeepanoriginalcopyofourcalculatedvalueinadifferentlocation,runourroutineusingthat
value,andstoretheresultin8B.(That'swhywestoredourcalculatedvalueinF6insteadof8Bwhenwemovedthe
routinetocalculatethepositionwewanttostrobeCXCLR.)Ourslicklittleroutinelookslikethis:

1013:ORA$D9;3;05D9
1015:ADC$E3;3;65E3
1017:ADC$F6;3;65F6
1019:STA$8B;3;858B

WhyORAandnotLDA?Awillalwaysbe0atthispointsotheeffectwillbethesame.Withneedlesslycryptic
things(liketheSECusedlikeaNOP)scatteredaroundthecode,itseemedtofitwithH.S.W.'sstyle.
Update:AtariAgeuseriespostanoticedthatit'spossibleforE.T.tofallintoawellifhe'stouchingbothawellanda
pieceofcandy.Thisonlyhappensinonespot(onthescreenwiththe"V"shapedwells)andyou'vegottobelinedup
nearperfectly.Wecanpreventthatfromhappeningbypushingthatcandydownatinybit.

0BA5:22;;22

Wedidit!Thegameisnowvirtuallyidenticaltotheoriginalexceptforthechangesthatwewantedtomake.The
goreistheonlyexception,butitwasworthremovingitfor...

Ournewfeature
Aspromised,we'regoingtomakeourdifficultyfixoptional.NolongerwillskilledE.T.playersneedtogiveupour
muchneededchangesinexchangeforamorechallenginggame.Bothdifficultyswitchesarealreadyused,butthe
B&W/Colorswitchisunused.Allweneedtodoisfindaplacetoputourroutine.
We'llneedtofirstmodifyourolddifficultyfixtoreadfromabyteinmemory,ratherthanourexplicit1or0.That's
theeasypart.We'lluseF8,fornorealreason.

0707:LDY$F8;3;A4F8
071B:LDY$F8;3;A4F8
0685:LDY$F8;3;A4F8

Thestateofthecolorswitchisatbit3inSWCHB.We'llneedtoloadthatintomemory,maskoffbit3,andcheckthe
stateagainstthat.Naturally,wedon'thavethespacetodoallofthatandstoreit.We'dneed13bytesfortheobvious
routine,ifwemagicallyfoundaplacetostuffourroutinethatdidn'trequirewehijackajump.That'snotgoingto
happen.
ThesmallestroutineIcouldmanageworkslikethis:readSWCHB,maskoffbit3,shiftrightthreetimes,storethe
result.That'lltake10bytes,notincludingareturnjump.Evenifwehadthe10bytes,thatalsowouldmeanthatthe
difficultyfixwouldbeoffbydefault(theswitchissettocolor)whichisn'toptimal.
Wehavewhatappearstobe10bytes,butisreally8bytes,freeat0FF0whereweusedtohavethe9byteroutine
usedtocalculatethepositiontoclearthecollisionlatches.(Idon'tknowhowwegotawaywithit.)Wealsohavethe
8bytesthatsetM0'shorizontalandverticalpositionforthegoryendingsceneat0B4D.Ifweswitchfromonegroup
totheother,itcouldbeenough.
We'lllikelyneedtouse6ofthosebytesjustforjumps,oncetoswitchbetweenouropenareas,andoncetocomplete
thejumpwehijack.Luckily,theroutinejustbeforeour8freebytesat0FF0endswithanRTS.Itturnsoutthatthisis
theroutinethatdecrementsE.T.'senergy.It'sabitofgoodluck,andanicematchforourdifficultyfix.Tomake
thingsevenbetter,there'sanRTSattheendofourother8bytes(thatsetM0'sposition).With16bytes,andareturn
that'sreadymade,wecanimplementourroutine,swapthefunctionsoftheColorandB&Wsettings(sothatColoris
easy),allwithabytetospare.
We'lloverwritetheRTSat0FEFtoallowtheroutinetocontinueintoourroutine,grabSWCHB,andmaskoffbit3
beforethejump.WecoulddoanLSRhere,butwe'llsaveitforafterthejumptomakeourroutinelineupwiththe
existingRTSat0B55.

0FEF:LDASWCHB;4;AD8202
0FF2:AND#$08;2;2908
0FF4:JMP$BB4E;6;4C4EBB

We'llneedtouseabytetocapoffthecheckstoruntheoldroutinesothatourroutinedoesn'taccidentallyrun.That's
whywe'llenterthesecondpartat0B4Einsteadof0B4D.

0B4D:RTS;6;60
0B4E:LSR;2;4A
0B4F:LSR;2;4A
0B50:LSR;2;4A
0B51:EOR#$01;2;4901
0B53:STA$F8;3;85F8

Bit3ofSWCHBis1iftheB&W/ColorswitchisintheColorposition,0otherwise.TheEORat0B51willreverse
thatsothatwestorea0inF8whentheswitchissettoColorinsteadof1.
That'sallthereistoit.

Squashingsome30yearoldBugs
E.T.hasareputationforbeingloadedwithbugs.Bugsthatmakethegame"virtuallyunplayable".Thisjustisn'ttrue.
Therearen'tactuallythatmanybugs,andonlyonethatseemstoimpactnormalgameplay.

Bugmythsandfacts
Thereareafewoftcitedbugsthat,well,aren'tbugsatall.Beforewebegin,let'ssettherecordstraightonthemost
commonnonbugs:
Myth:Somegamestatevariablesaren'tclearedwhenstartinganewgameasevidencedbytheappearanceof
theScientistandFBIagentafterstartinganewgameonmode3.
Thissimplyisn'ttrue.TheScientistandFBIagentalwaysappearregardlessofthegamemode.Inevery
mode,allthehumansareshownreturningtotheirrespectivebuildingsthatincludesmode3,evenfrom
poweron.Thedifference,ofcourse,isthatinmode3theyneverleave.

Myth:Thefirstcountdowntimerdoesn'tfinishtickingdownlikethesecond,faster,timer.
Thisisjustamisunderstandingofwhatthe"two"timersrepresent.Thetimertakes64"ticks"tocomplete.
Every8ticks,asectiondisappears.Thesecondtimerisa"closeup"ofthelastsectionofthefirsttimer.It
ticksoffoneofitseightsectionsevery"tick".It'slikethefirsttimerisminutes,andthesecondtimerseconds.
Therereallyisjustone64ticktimer,wejustseethehigherprecision("second")viewwhenwegettotheend
(thelast"minute").

Myth:ThenumberoftimesElliottcanreviveE.T.isincorrect/canbeexploitedtogainandextrarevival.
Thisissimplynottrue.Themanualstatesthat"ElliottcanmergewithE.T.threetimespergame."Whichis
correct.Italsostatesthat"Onceduringaround,however,E.T.canencounterawiltedflowerhiddeninthe
bottomofawell.IfE.T.isrevivestheflower,ElliottisgiventheabilitytomergewithE.T.oneextratime."
Thisisalsocorrect.Extramerges/livesaccumulateasyouwouldexpectfromthedescription,thoughthat's
notexplicitlystatedinthemanual.
Inshort,therearenobugsrelatedtothenumberoftimesElliottcanreviveE.T.(Notunderanynormalplay
circumstancesanyhow.Ifyouaccumulatemorethan127"lives",ElliottwillnotreviveE.T.Idoubtthathas
everhappened!)

RealBugs
Bug1:OndifficultymodeswhereElliottisallowedtobeonscreenwhentheshiplands,theShipCrushesElliott.
Thisbughappensbecausetheship'spositionisoverwrittenbyElliott'spositionimmediatelyaftertheship'sposition
issettostartthelandinganimation.Thefixissimple,justskipoverthecodethatupdatesthecurrentobjectson
screenpositionafterwestartinitializetheshiplandingsequence.

07BD:JMP$BAD9;3;4CD9BA

Bug2:Youalwaysfallintoawellwhenexitingtheforestontheright,andwhenexitingthecityontheleft
Thisisalsoaneasyfix.Thefallingfixautomaticallytakescareofthebugwhenexitingleftfromthecityscreen.For
theforest,wejustneedtoslightlyadjustE.T.'sstartingpositiononthenextscreen.Theplayerwillbepushingright
onthejoystick,sowe'lljustmoveE.T.atinybitupandtotherighttoavoidimmediatelyfallingintothetopcenter
wellonthescreenwitheightpits.E.T.'sstartingpositionisreadfromatable,sowejustneedtoupdateacoupleof
values:

0D54:3A+10;;4A
0D6C:043;;01

We'llmoveE.T.16unitstotheleft,and3unitsupfromtheoriginalpositions.
Bug3:Scoringiswildlyincorrect.
It'sconsistent,forthemostpart,butit'sveryconfusing.Italsodoesn'tevencomeclosetomatchingthemanual.
Therearesomemoreseriousproblems,however.Collectingmorethan31piecesofcandywillcauseanerror,often
leadingtothefamous"NinjaE.T."bug.Thestartingenergypenaltyandcandybonusesarealsoincorrect.
Thecodeforscoringalsodeterminesotherthings,likeE.T.'senergywhenstartinganewgame,sowe'llneedtobe
carefulmakingdrasticchangestomakesurewedon'taccidentallybreakanything.Ofcousre,thecodeisalsoamess,
sowewillbemakingsomeratherdramaticchanges.
Rightnow,pointsforcandyE.T.bringsontheship,bonuspointsforcandycollectedbeyondacertainamount,and
theenergypenaltyaredeterminedbytablelookups.Normally,alookuptableisusedtosaveROMspace,time,or
bothtoavoidacomplexcalculationorprovideamoreaccuratecalculation.Thesetablesjustwastespaceastimeisn't
animportantfactorhere.Evenworse,onlypointsforE.T.'scandyarescoredcorrectly!We'lleliminatetheseawful
tablesandputthosebytestobetteruse.
Currently,scoringfollowsthissequence:Aftertheendinganimationstarts,youaregiven1pointforeveryunitof
remainingenergy,then490pointsforeverycandybroughtontotheship.Thecandymunchingpartoftheanimation
thenbegins,nettingyou770pointsforeachcandyheldbyElliottoneatatimewhiletheanimationruns.Whena
newroundstarts,you'regivenbonuspointsforcollectedcandyaboveacertainamount(21pieces,not31asspecified
inthemanual)andtheenergypenaltydeterminesyourstartingenergyfortheround.
We'regoingtochangethat.We'llstartoffthesameway,givingonepointforeveryunitofremainingenergy.We'll
thensetE.T.'senergyto9999.Asthemunchinganimationruns,we'lldeductenergyforthepenalty,addbonuspoints
forcandiescollectedoveracertainamount,andaddthenormal490or770pointsforcollectedcandytoyourscore.
TheenergypenaltycodealsosetsE.T.'senergyatthestartofanewgame.We'llneedtorememberthatcodethat
beginsanewroundisalsocalledwhenanewgamestarts,andaddsomecodetomakesureE.T.'sstartingenergyis
setto9999atthebeginningofanewgame.
FixingthescoringcodewillalsofixtheNinjaE.T.bug.Asit'sbecomeapopular,ifunintended,EasterEgginitsown
right,we'lladdittothegameasanintentionaleffect.(Withouttheotherstrangeartifacts,ofcourse).
Sincewe'refixingthescoring,itmakessensetomakethescoringmatchthemanual.Thismeanswe'llalsoneedto
makeasmallchangetohowmuchcandycanbefoundduringaroundsothatyoucanmeaningfullycollectmorethan
31pieces.Thereistechnicallyabughere,astheflagsthatshowwhichwellscreenscurrentlyhavecandyisnever
cleared.Thecounterthatholdshowmuchadditionalcandycanbefoundduringtheroundoftendoesn'treachzero.
We'llleavethisinasitaddsanicebitofpseudorandomnesstotheamountofcandyyoucanfind.

Wait.What?There'seffectivelyapotential+4or3totheamountofcandythancanappearduringaround.
Rememberingthatcandyleftonthegroundfromthepreviousroundisn'tcleared,therecanbeasmanyasfourpieces
leftonthegroundfromapreviousround.Thosewon'tbedeductedfromthecounter,effectivelyincreasingthe
potentialamountofcandybyasmuchasfourpieces.The3isabitmorecomplicated.Whencandyappears,it
appearsoneverywellscreen.ThevalueatDCisreducedbytheamountofcandyneededtoaddacandytoevery
screen.(Ifallfourscreensneedcandy,DCisreducedbyfour.Ifthreescreensneedcandy,DCisreducedbythree,
andsoon.)Ifthereisn'tenoughcandylefttoplaceacandyoneveryscreen,accordingtoDC,thennocandyisadded.
ThatmeansthatDCcanget"stuck"at3,2,or1.(IfallfourwellscreensneedcandywhenDCislessthanfour,no
candyisadded.IfthreescreensneedcandywhenDCislessthan3,nocandywillbeadded,andsoon.)Ifyou're
lookingtomaximizetheamountofcandyyoucancollect,collectonlyonecandyatatime,allowingthecandyto
replenishinbetween,whenyougetclosetothemaximum.
Withoutfurtherexposition,let'sgetstarted.Thefirstthingwe'lldoismakeachangetothecodethatrunsrightafter
wefinisharound.Thecodewe'reinterestedininitializesthecounterforremainingcandyforthenextroundand
totalsthecollectedcandy(whatElliottisholdingpluswhatE.T.isholding.)

058E:STA$F4;3;85F4
0590:LDA$DD;3;A5DD
0592:STA$F5;3;85F5
0594:ADC$F4;3;65F4
0596:STA$DD;3;85DD
0598:ADC16;3;6910
059A:NOP;2;EA
059B:NOP;2;EA

MemorylocationDDholdstheamountofcandyheldbyElliott,whichwillnowbesettothetotalamountofcandy
collected.F4andF5holdtheamountofcandyheldbyE.T.andElliott,respectively.At0598,wesettheamountof
candyavailableinthenextroundto16plusthetotalamountofcandycollected.(ItwillbestoredinDCjustafterthe
twoNOP's).We'llcomebacktothatlater.
WeonlyneedF4andF5toimplementtheNinjaE.T.bugasanEasterEgg,sothisroutinecouldbemademuch
simpler.
Withthatoutoftheway,let'skillthecodethatscoresE.T.'scandyaswe'llhandlethatinournewscoringroutine.As
we'llbedeductingenergyforthepenaltyinournewscoreroutine,we'llusethisopportunitytosetE.T.'senergyto
9999.

1395:LDA#$99;2;A999
1397:STA$D3;3;85D3
1399:STA$D4;3;85D4
139B:BNE+9;3;D009
139D:NOP;2;EA
139E:NOP;2;EA
139F:NOP;2;EA
13A0:NOP;2;EA
13A1:NOP;2;EA
13A2:NOP;2;EA

Thebranchattheendskipsoverthejumptotheroutinethatupdatesourscore.
Thosesixbytesarejustbeggingtobeused!Aswe'refixingthescoring,let'stakethisopportunitytoaddressa
scoringissuewiththedifficultyfix.Normally,youget1bonuspointforeveryremainingunitofenergythatE.T.has
attheendofaround.Withthedifficultyfixinplace,playersessentiallygettonsoffreepoints.Ithardlyseemsfair,
sowe'lladdachecksothattheplayerstakingadvantageofthedifficultyswitchreceivenobonuspointsfor
remainingenergy.

139D:LDA$F8;3;A5F8
139F:BNE+2;2;D002
13A1:TAX;2;AA
13A2:TAY;2;A8

We'llhijackthejumpat1382,pushingitbackabitsothatourroutineisactuallycalled.Theroutinetoincrementour
scorewillbecalleddirectlyafterwardlikenormal,onlywithXandYsetto0insteadofE.T.'sremainingenergy,if
thedifficultyfixisenabled.

1382:JMP13A36;6;4C9DF3

Nowwe'vefreedupthe20bytesthatmakeupthetableat1341.We'llfreeupthe16bytesat17E9usedforthe
energypenaltylaterwhenweupdatethecodethatstartanewround.Fornow,we'llassumethatthey'refree.That
shouldgiveus36bytesforournewscoringroutine.
We'llcallournewscoringroutinefromthemunchingroutineat13AC.We'llneedtoeitherhijackajumporfind
somefreebytesforourown.Luckily,we'vegotfouruselessbytesat13BD.Allthosedoarestorethenumber6in
8B.It'stheonlyplaceintheROMthatdoesanythingwith8B(ourchangesexcepted,ofcourse)soit'sessentially
useless.We'llusethosefourbytesforourjump.

13BD:LDA#$01;2;A901
13BF:ORA$DE;2;05DE
13C1:STA$DE;3;85DE
13C3:LDX#$07;2;A207
13C5:LDY#$70;2;A070
13C7:JSR$1341;6;2041F3
13CA:NOP;2;EA

We'llwanttotakeadvantageoftheLDXandLDY(whichholdthenumberofpointstoscore)tosaveafewbytes,so
we'lljustpusheverythingbeforethatupintothefourbyteholewemadeat13BDandaddourjump.Ourjumponly
takesthreebytes,sowe'llfillthatextrabytewithaNOP.
Finally,wecanaddournewscoreroutine!Theideahereissimple.Assumefrom13C5and13C7thatthecandywe're
munchingisworth770points.IfE.T.isholdinganycandy,reducethatamountbyoneandchangethepointstoscore
to490.Finally,checktoseeifthecurrentcandyisoneofthecandiescollectedafterthe31stpiece.Ifso,add1000
pointstowhateverwe'veplannedtoscoreanddeduct700unitsofenergyasthepenalty.Thismatchesthescoring
describedinthemanual.Thepointswillactuallybeaddedtothescoreafterwereturnfromourroutine.

1341:LDA$D2;2;A5D2
1343:CMP#$0A;2;C90A
1345:BEQ+8;2;F008
1347:SBC16;3;E910
1349:STA$D2;3;85D2
134B:LDX#$04;2;A204
134D:LDY#$90;2;A090
134F:LDA$DD;2;A5DD
1351:SED;2;F8
1352:JMP$17E9;6;4CE9F7

17E9:CMP#$1F;2;C91F
17EB:BCC+10;2;900A
17ED:TXA;2;8A
17EE:ORA#$10;2;0910
17EF:TAX;2;AA
17F1:LDA$D3;2;A5D3
17F3:SBC7;3;E907

17F5:STA$D3;3;85D3
17F7:CLD;2;D8
17F8:RET;6;60

Nowweneedtoupdatethecodethatstartsanewroundtokeepitfromscoringbonuspointsandissuingapenalty.
Thereisanadditionalproblem,asthecodethatdeterminestheenergypenaltyalsosetsE.T.'senergyto9999forthe
firstround,we'llneedtoalsomodifythecodethatstartsanewgameorE.T.willstartthegamewithoutanyenergy!
Lookingatthenewgamecodeat13DCweinitializealotofstufftozero,includingthingsthataresetlaterorcanbe
setlater.Wewon'tneedtheSTA$EB(shipstatus)asthat'ssetlater.WecanalsosafelysetDD,D9,and94(Elliot's
candy,wellflags,andE.T.'sneckheight)atthestartofeachround.That'llfreeupafewbytestosetE.T.'sstarting
energyatthebeginningofanewgame.

13FD:LDA#$99;2;A999
13FF:STA$D3;3;85D3
1401:STA$D4;3;85D4
1403:LDA#0;2;A900
1405:STA$F4;2;85F4
1407:STA$E3;3;85E3

We'llalsowanttoresetF4(whichholdsthetotalcandycollectedusedforourNinjaE.T.EasterEgg)sowe'llinclude
thatbetweentheold13FDand13FF(now1403and1407)thatwepusheddowntomakeroomforournewcode.
WestillneedtosetDD,D9,and94to0sowewe'lldothatatthestartofanewround.(Thenewroundcodeisalso
calledwhenwestartanewgame.)Everythingfrom147Atothejumpat14A2isfreeforustouse,thankstoournew
scoringroutine.

147A:LDA#$0;2;A900
147C:STA$DD;3;85DD
147E:STA$D9;3;85D9
1480:STA$94;3;8594

Wealsoneedtolimittheamountofcandyavailableinthenextroundsothatourenergypenaltydoesn't"wrap
around"andstartdeductingfromthemaxagain.RememberthatDCholdstheamountofcandythatcanappearinthe
nextround.We'llcapitoffat41pieces,givinguspotentially38to45piecesinthenextround.At45piecesour
penaltywillbe(4531)*700or9800.AnymorethanthatandE.T.'senergywouldwrapto9300.

1482:LDA#$29;3;A529
1484:CMP$DC;3;C5DC
1486:BCS+2;3;B002
1488:STA$DC;2;A5DC
148A:JMP$14A5;6;4CA5F4

Nowscoringworksexactlyasstatedinthemanual.There'sjustonethinglefttodo.

AddingtheNinjaE.T.EasterEgg
NinjaE.T.wasn'tanintentionaleastereggintheoriginalgame,itwasabug.Ifyoucollectedtoomuchcandy(most
sourcessay33pieces)onthenextround,E.T.wouldturnblackandyourenergywouldshowpartofH.S.W.'sinitials
andotherjunk.Thishappensbecauseavalueotherthan09appearsintheuppernibbleintheupperpartofE.T.'s
energy,whichwillmakethecode"point"tothewrongimage.AsE.T.changescolordependingtheamountof
remainingenergy,thecolorselectedwillbeoutsideofthecolortable,whichjusthappenstohaveafew0'saroundit.

We'lltakeadvantageofthattoimplementNinjaE.T.thoughwe'llmakesurethattheenergycounterdoesn'tlook
broken.
Withthescoringfixed,collecting33piecesofcandyseemslikeaperfectlyreasonable,andlikelycommon,amount.
Aneastereggshouldn'tbetriggeredsoeasily.Echoingtheoftcitedtrigger,we'llenableNinjaE.T.onlyifaplayer
completesaroundwithbothE.T.andElliottinposessionofexactlythreecandies.
Asabonus,we'llgiveNinjaE.T.tenpiecesofcandytomakeupforthepreviouscandypoorround.It'llalsoletNinja
E.T.makeaquicktradewithElliottforaphonepart.

148A:LDA$F4;2;A5F4
148C:CMP$F5;2;C5F5
148E:BNE+12;3;D00C
1490:CMP#$03;2;C903
1492:BNE+8;2;D008
1494:LDA#$AA;2;A9AA
1496:STA$D2;3;85D2
1498:STA$D3;3;85D3
149A:STA$D4;3;85D4
149C:JMP$14A5;6;4CA5F4
149F:NOP;2;EA
14A0:NOP;2;EA
14A1:NOP;2;EA

WhyAA?ThatwillbothgiveNinjaE.T.10piecesofcandyandmaketheenergycounterappeartobeempty.AsE.T.
losesenergy,thecounterwillreturntonormal,onedigitatatime.Whenallfourdigitsofthecounterarebackto
normal,NinjaE.T.willalsoreturntonormal.

AnExtraGameMode
Playerslookingforadditionalchallengeabovegamemode3,butnotquiteaschallengingasgamemode2(withthe
nastyFBIAgent)havealwaysfeltleftout.AtariAgeuserroadrunnersuggestedthatanextragamemodethat
includedjustthescientistwouldbeawelcomeaddition.
ThevariousgamemodesremovehumansbysendingtheScientistortheFBIagenthomerepeatedlysothattheydon't
appearingame.Toallowanextramodetobeselected,wejustneedtochangethemaximumgamemodefrom3to4.
Thegamecheckstoseeifthecurrentmodeisonehigherthanthemaximumbeforesettingthegamemodebackto1,
sowe'llchecktoseeifthethegamemodeis5.We'llalsoneedtomodifythechecktosendthescientistbackhome.If
wemakethescientistonlyoptiongamemode3andpushthe"nohumans"optiontogamemode4,wecancheckto
seeifweneedtosendthescientisthomewithanANDandbychangingthebranchinstruction.Ultimately,it'safour
bytechange.

0471:CPX#$05;2;E005

02ED:AND#$01;2;2901
02EF:BEQ+9;2;F009

AlloftheFinalChanges
Hereareallthefinalchanges:

E.T.FixedFinalVersion(NTSC)20130201

E.T.isNotGreen

17FA:ETColors;;FEFCF8F8F8
1DE8:WellBG;;04

DifficultyFix(Walk,Run,Hover)

0707:LDY$F8;3;A4F8
071B:LDY$F8;3;A4F8
0685:LDY$F8;3;A4F8

0FEF:LDASWCHB;4;AD8202
0FF2:AND#$08;2;2908
0FF4:JMP$BB4E;6;4C4EBB

0B4D:RTS;6;60
0B4E:LSR;2;4A
0B4F:LSR;2;4A
0B50:LSR;2;4A
0B51:EOR#$01;2;4901
0B53:STA$F8;3;85F8

HoveringSoundFix

04F0:LDA$81;3;A581
04F2:AND#$1E;2;291E

FallingFix

002A:JMP$BBF6;3;4CF6BB
0BF6:LDA$9C;3;A59C
0BF8:ADC07;3;6907
0BFA:STA$F6;3;85F6
0BFC:JMP$BCAB;3;4CABBC

1013:ORA$D9;3;05D9
1015:ADC$E3;3;65E3
1017:ADC$F6;3;65F6
1019:STA$8B;3;858B
101B:JMPF04B;3;4C4BF0

101E:PHP;3;08
101F:CPX$8B;3;E48B
1021:BNE+6;2;D006
1023:BITCXP1FB;2;2413
1025:BVS+2;2;7002
1027:STACXCLR;3;852C
1029:CPX$9E;3;E49E
102B:PHP;3;08
102C:INX;2;E8
102D:LDY$86;2;A486
102F:TXA;2;8A

1034:STAWSYNC;3;8502
1036:STYGRP1;3;841C

1060:LDA$87;3;A587
1062:STAGRP0;3;851B
1064:LDA$88;3;A588
1066:STACOLUP0;3;8506
1068:TXA;2;8A
1069:TAY;2;A8

106A:LDA$BA,Y;5;B1BA
106C:STAPF1;3;850E
106E:LDA$BC,Y;5;B1BC
1070:STAPF2;3;850F
1072:CPX$9F;3;E49F
1074:JMPF01E;3;4C1EF0

ChangeKernelEntryPoint

18F3:$F02F;;2EF0

Landing/LaunchingShipPositionFix

0B40:LDA#$EF;2;A9EF
07ED:SBC#$04;2;E904

MoveCandyonVScreenToPreventFalls

0BA5:22;;22

BUGFIXES

Don'tFallLeavingForestonRight

0D54:3A+10;;4A
0D6C:043;;01

ShipShouldn'tCrushElliott

07BD:JMP$BAD9;3;4CD9BA

FIXSCORINGTOMATCHMANUAL

058E:STA$F4;3;85F4
0590:LDA$DD;3;A5DD
0592:STA$F5;3;85F5
0594:ADC$F4;3;65F4
0596:STA$DD;3;85DD
0598:ADC16;3;6910
059A:NOP;2;EA
059B:NOP;2;EA

1382:JMP13A36;6;4C9DF3

1395:LDA#$99;2;A999
1397:STA$D3;3;85D3
1399:STA$D4;3;85D4
139B:BNE+9;3;D009
139D:NOP;2;EA
139E:NOP;2;EA
139F:NOP;2;EA
13A0:NOP;2;EA
13A1:NOP;2;EA
13A2:NOP;2;EA

Scorenopointsforremainingenergy
withthedifficultyfixenabled(6bytes)

139D:LDA$F8;3;A5F8
139F:BNE+2;2;D002
13A1:TAX;2;AA
13A2:TAY;2;A8

13BD:LDA#$01;2;A901
13BF:ORA$DE;2;05DE
13C1:STA$DE;3;85DE

13C3:LDX#$07;2;A207
13C5:LDY#$70;2;A070
13C7:JSR$1341;6;2041F3
13CA:NOP;2;EA

1341:LDA$D2;2;A5D2
1343:CMP#$0A;2;C90A
1345:BEQ+8;2;F008
1347:SBC16;3;E910
1349:STA$D2;3;85D2
134B:LDX#$04;2;A204
134D:LDY#$90;2;A090
134F:LDA$DD;2;A5DD
1351:SED;2;F8
1352:JMP$17E9;6;4CE9F7

17E9:CMP#$1F;2;C91F
17EB:BCC+10;2;900A
17ED:TXA;2;8A
17EE:ORA#$10;2;0910
17EF:TAX;2;AA
17F1:LDA$D3;2;A5D3
17F3:SBC7;3;E907
17F5:STA$D3;3;85D3
17F7:CLD;2;D8
17F8:RET;6;60

13FD:LDA#$99;2;A999
13FF:STA$D3;3;85D3
1401:STA$D4;3;85D4
1403:LDA#0;2;A900
1405:STA$F4;2;85F4
1407:STA$E3;3;85E3

147A:LDA#$0;2;A900
147C:STA$DD;3;85DD
147E:STA$D9;3;85D9
1480:STA$94;3;8594
1482:LDA#$29;3;A529
1484:CMP$DC;3;C5DC
1486:BCS+2;3;B002
1488:STA$DC;2;A5DC
148A:JMP$14A5;6;4CA5F4

EasterEggNinjaE.T.

148A:LDA$F4;2;A5F4
148C:CMP$F5;2;C5F5
148E:BNE+12;3;D00C
1490:CMP#$03;2;C903
1492:BNE+8;2;D008
1494:LDA#$AA;2;A9AA
1496:STA$D2;3;85D2
1498:STA$D3;3;85D3
149A:STA$D4;3;85D4
149C:JMP$14A5;6;4CA5F4
149F:NOP;2;EA
14A0:NOP;2;EA
14A1:NOP;2;EA

AddExtraGameOptionScientistOnly

0471:CPX#$05;2;E005

02ED:AND#$01;2;2901
02EF:BEQ+9;2;F009

Conclusion
ItturnsoutthatE.T.isn'tabadgameafterall.Withafewsimplechangeswewereabletodramaticallyimprovean
alreadygoodgamebyeliminatingthemostcommoncomplaints.Withafewadditionalchanges,wewereableto
clearupanyconfusionforplayerswhocareaboutthescore,andwereconfusedbythedifferencesbetweenwhatthe
manualclaimsandwhatactuallyhappensingame.Nexttimesomeonetellsyouthat"E.T.fortheAtari2600isthe
worstgameevermade"youcantellthemthatthisisnotthecase.It'sbeenfixed,andyouknowhow.

HomeLastmodified:February2013

You might also like