A.N.A.L.O.G. ISSUE 41 / APRIL 1986 / PAGE 101

One for the Road

32K Cassette or Disk

by Clayton Walnum

“Things are tough,” I said. “Tough all over.”

The bartender shrugged and relieved me of another dollar. I’d been perched by the bar for a couple hours now, knocking back snakebites and taking in the circus sideshow that was Smitty’s Roadside Tavern.

You never knew what you’d find at Smitty’s. Just then, I was watching a jerk snatch flies out of the air and toss them into his half-filled mug of brew. Every time he snagged one, he’d look around and suck his teeth. Yeah, you’re cool, buddy. All I could think about was those poor flies, spending their last moments gagging on that cheap beer. I turned back to the bar in disgust and inhaled my tenth shot.

“Things are tough,” I mumbled.

And things were tough. I hadn’t worked in months. Okay, I’ll grant you that my type of work is hard to find. Not too many people are interested in hiring a professional risk-taker, but I had always managed to stay busy. After all, I’d do virtually anything — climb mountains, fly planes, hack through jungles. I was tough. They didn’t call me “Nails” O’Riley for nothing.

I was just about to order another shot when it occurred to me that things had gotten awfully quiet. I looked back to the fly killer, assuming he was somehow responsible for the sudden silence. But he was just staring toward the front door. Everyone was staring that way, but me. I decided to make it unanimous and turned to discover what was so interesting.

The strangest man was standing there, couldn’t have been more than five-foot-three. His face was buried beneath a thick white beard, and his snowy hair was blown into such disarray that it looked teased. Large drops of water oozed from his outdated suit to the floor. I guessed that it had started to rain.

As I watched him, I was struck by the melodrama of the scene. My imagination immediately began to create a story around this little man. I cast him as a professor from the local university who had stumbled upon some amazing discovery. He had come to Smitty’s to find the famous “Nails” O’Riley, with an offer of danger, excitement and, of course, ample remuneration. He would walk up, tap my shoulder and say something like “Mr. O’Riley, I presume?”

I chuckled at my foolishness and signaled for another shot. I was about to convert the amber fluid to the past tense when someone tapped my shoulder.

“Mr. O’Riley, I presume?” It’s a good thing the liquor hadn’t passed my lips; I’d be choking still.

I listened, open-mouthed, while he introduced himself as Pip Sigourney a professor from the local university who had made an amazing discovery. He told me he had evidence that, long before our present age, there existed a civilization with a technology superior to ours.

“But they didn’t gain their knowledge of the sciences through the empirical methods we incorporate,” he squeaked excitedly. “No, indeed. They worshipped powerful gods. These gods, in turn, provided them with amazing things!” He went on about strange machinery and midnight sacrifices and all sorts of weird stuff. All I cared about was how much this fruitcake would pay for what had to be a wild goose chase.

My assignment was to go to a small island off the coast of Africa and verify the existence of this civilization. He would use whatever evidence I could dig up to convince his colleagues to mount a full-scale expedition. I agreed, of course. I didn’t care if he was nuts; his money was just as green as anyone else’s.

After the professor left, I snatched up the waiting shot. The wad of bills he’d left with me was lying on the bar, and I noticed that the fly killer was staring at it goggle-eyed. Taking advantage of his distraction, I raised my glass and said good-naturedly, “One for the road!” He grinned, grabbed his mug and downed its contents in three swallows. It took him a few seconds to realize what he’d done.

I left, a happy man.

Adventure awaits!

Well, Nails O’Riley got a boat, the “Sea Hammer” and left on schedule for the mysterious island Pip Sigourney had marked on an old map. It didn’t take him long to get into serious trouble. A storm popped up out of nowhere, and Nails soon found himself concerned with much more than verifying the professor’s claim. He was in a battle for his life!

As we enter the story, Nails is just off the island’s coast, fighting to keep the Sea Hammer from an appointment with the rocks. Quite honestly, I don’t see that he has much chance. The way the storm’s blowing, his boat is going to be ground into toothpicks any second.

Why are you being told all this? You are Nails O’Riley. It’s up to you to get to the relative safety of the island, then figure out a way to get home. You may even get a few surprises along the way (in fact, you can be sure of it). Sound easy? Well…

Typing it in.

Before typing anything, look at the listings accompanying this article.

Listing 1 is the BASIC data and data checking routine. This listing is used to create both cassette and disk versions of One for the Road. The data statements are listed in hexadecimal (base 16), so the program will fit in 16K cassette systems.

Listing 2 is the assembly language source code for One for the Road, created with the OSS MAC/65 assembler. You don’t have to type this listing to play the game! It is included for those readers interested in assembly language.

Follow the instructions below to make either a cassette or disk version of One for the Road.

Cassette instructions.

  1. Type Listing 1 into your computer using the BASIC cartridge and verify your typing with Unicheck (see page 13).
  2. Type RUN and press RETURN. The program will begin and ask:
    MAKE CASSETTE (0), OR DISK (1)? Type 0 and press RETURN. The program will begin checking the data statements, printing the line number of each as it goes. It will alert you if it finds any problems. Fix any incorrect lines and re-RUN the program, if necessary, until all errors are eliminated.
  3. When all of your data lines are correct, the computer will beep twice and prompt you to READY CASSETTE AND PRESS RETURN. Now insert a blank cassette in your recorder, press the RECORD and PLAY buttons simultaneously and hit RETURN. The message WRITING FILE will appear, and the program will create a machine language boot tape version of One for the Road, printing each data line number as it goes. When the READY prompt appears, the game is recorded and ready to play. CSAVE the BASIC program onto a separate tape before continuing.
  4. To play, rewind the tape created by the BASIC program to the beginning. Turn your computer OFF and remove all cartridges. Press the PLAY button on your recorder and turn ON your computer while holding down the START key. If you have a 600 or 800XL computer, you must hold the START and OPTION keys when you turn on the power. The computer will “beep” once. Hit the RETURN key, and One for the Road will LOAd and RUN automatically.

Disk instructions.

  1. Type Listing 1 into your computer using the BASIC cartridge and verify your typing with Unicheck (see page 13).
  2. Type RUN and press RETURN. The program will ask:
    MAKE CASSETTE (0), OR DISK (1)? Type 1 and press RETURN. The program will begin checking the data lines, printing the line number of each statement as it goes. It will alert you if it finds any problems. Fix incorrect lines and re-RUN the program, if necessary, until all errors are eliminated.
  3. When all the data lines are correct, you will be prompted to INSERT DISK WITH DOS, PRESS RETURN. Put a disk containing DOS 2.0S into drive 1 and press RETURN. The message WRITING FILE will appear, and the program will create an AUTORUN.SYS file on the disk, displaying each data line number as it goes. When the READY prompt appears, the game is ready to play. Be sure the BASIC program is SAVEd before continuing.
  4. To play the game, insert the disk containing the AUTORUN.SYS file into drive 1. Turn your computer OFF, remove all cartridges and turn the computer back ON. One for the Road will LOAd and RUN automatically.

Playing the game.

One for the Road is a text adventure and, like most games of its type, you communicate with the program by two-word commands. These commands should be in a verb/noun format (i.e., LOOK CABINET, GET KNIFE).

There are a few exceptions. All directions should be abbreviated to a single letter (N, S, E, W, U, D). Other single-letter commands include X, A, and Q. Use X whenever you wish to save the game. The command A repeats the last command you entered. Q is for Quit. After using Q you’ll be asked to verify your choice. If you type Y, you’ll return to the game’s title screen.

One for the Road will not understand everything you type. To help you find the right commands, the program will give you short “Syntax Error” messages. The messages Bad verb or Bad noun indicate that the verb or noun you used is not in the program’s vocabulary.

If you need hints, don’t call ANALOG Computing. We are absolutely not giving out adventure hints over the telphone! If you’re really stuck, send a self-addressed, stamped envelope to: ONE FOR THE ROAD, c/o ANALOG Computing Magazine, P.O. Box 23, Worcester, MA 01603.

The “Without Whom” Department

Regular readers of ANALOG Computing will no doubt suffer a bit of deja vu when they get their first look at this program. This is because, rather than spending months duplicating code already in existence, I used Brian Moriarty’s excellent program Crash Dive! (from issue 18) as a skeleton for One for the Road.

I want to give a hearty “Bravo!” to Brian Moriarty for the superb job he did in writing Crash Dive! (issue 18). Brian’s squeaky clean code was a delight to work with, and I only hope he won’t think I mucked it up too much!

Listing 1.
BASIC listing.

10 REM *** ONE FOR THE ROAD ***
20 TRAP 20:? "MAKE CASSETTE (0), OR DISK (1)";:INPUT DSK:IF DSK>1 THEN 20
30 TRAP 40000:DATA 0,1,2,3,4,5,6,7,8,9,0,0,0,0,8,0,0,18,11,12,13,14,15
40 DIM DAT$(91),HEX(22):FOR X=0 TO 22:READ N:HEX(X)=N:NEXT X:LINE=990:RESTORE 1000: TRAP 120:? "CHECKING DATA"
50 LINE=LINE+10:? "LINE:";LINE:READ DAT$:IF LEN(DAT$)<>90 THEN 220
60 DATLIN=PEEK(183)+PEEK(184)*256:IF DATLIN<>LINE THEN ? "LINE ";LINE;" MISSING!":END
70 FOR X=1 TO 89 STEP 2:D1=ASC(DAT$(X,X))-48:D2=ASC(DAT$(X+1,X+1))-48:BYTE=HEX(D1)*16+HEX(D2)
80 IF PASS=2 THEN PUT #1,BYTE:NEXT X:READ CHKSUM:GOTO 50
90 TOTAL=TOTAL+BYTE:IF TOTAL>999 THEN TOTAL=TOTAL-1000
100 NEXT X:READ CHKSUM:IF TOTAL=CHKSUM THEN 50
110 GOTO 220
120 IF PEEK(195)<>6 THEN 220
130 IF PASS=0 THEN 170
140 IF  NOT DSK THEN 160
150 PUT #1,224:PUT #1,2:PUT #1,225:PUT #1,2:PUT #1,128:PUT #1,31:CLOSE #1:END 
160 FOR X=1 TO 35:PUT #1,0:NEXT X:CLOSE #1:END 
170 IF  NOT DSK THEN 200
180 ? "INSERT DISK WITH DOS, PRESS RETURN";:DIM IN$(1):INPUT IN$:OPEN #1,8,0,"D:AUTORUN.SYS"
190 PUT #1,255:PUT #1,255:PUT #1,128:PUT #1,31:PUT #1,52:PUT #1,61:GOTO 210
200 ? "READY CASSETTE AND PRESS RETURN";:OPEN #1,8,128,"C:":RESTORE 230:FOR X=1 TO 40:READ N:PUT #1,N:NEXT X
210 ? :? "WRITING FILE":PASS=2:LINE=990:RESTORE 1000:TRAP 120:GOTO 50
220 ? "BAD DATA: LINE ";LINE:END 
230 DATA 0,60,88,31,127,31,169,0,141,47,2,169,60,141,2,211,169,0,141,231,2,133,14,169,56,141,232,2
240 DATA 133,15,169,128,133,10,169,31,133,11,24,96
1000 DATA A2008E4402E8860920B63A2065E44CBB1F7070707042403C901002901002901002020202020290100202901002,136
1010 DATA 028080100202020202027041911FA2FF9A20D92BA20CA006209E2BA9BFA03420842BA216A007209E2BA9D0A034,163
1020 DATA 20842BA208A009209E2BA9E1A03420842BA205A010209E2BA9FAA03420842BA203A012209E2BA919A03520842B,359
1030 DATA A9068D2C3C8D2D3CA9228D2F0220A32BAD1FD0C907F0F9AE1FD0E007D0F9C906F00AC903F00C20A72B4C172020,184
1040 DATA 01304C9E20A205A014209E2BA93CA03520842B20A32B20CE2CC944F00DC943F00F20E22F20A72B4C4A2020EC2F,337
1050 DATA 4C672020F32FA9039D4203A9049D4A03A9009D4B032056E430DAA210A9C09D4403A93A9D4503A9519D4803A901,566
1060 DATA 9D4903A9079D42032056E430BA20E22F20D92BA9918D3002A91F8D3102A95BA03520842BA90C8553A980A03520,894
1070 DATA 842BA996A03520842B20BE2C20BE2C20BE2C20BE2C20C62CA9C2A03520842B20C62CA9E3A03520842B20BE2C20,317
1080 DATA BE2CA9278553A90C8DC002A9308D01D0A9CA8D02D0A9408D03D0A2FF8E0ED08E0FD08E10D0E88E04D0E88E6F02,950
1090 DATA A9038D09D08D0AD08D0BD0A9F08581A91E8582A90D8552A02FA22EA906205CE4A9588D0002A92B8D0102A9C08D,929
1100 DATA 0ED4ADC23A4CCD23A2FF9A20662EEEC03AD003EEC13AADC23AC90390034C7E21CED53AADD53AD01420D92BA209,458
1110 DATA A003209E2BA9EEA03920842B4CC32FADDC3AF06FCEDC3AADDC3AD067ADC23ACDCF3AF048A91920822FF041ADCF,346
1120 DATA 3A0A85900A1865906905A8B9673BC919F00388D0F6ADCF3AC909D01CA90099673BA90A8D1C3BA00A209C2BA911,16
1130 DATA A03820842B205C2C4CF221A9FF99673BD0E720D92BA20CA003209E2BA999A03920842B205C2C4CC32FADD33AC9,873
1140 DATA FFF023C900D01CADC23AC903F018A017B9673BC9FFF00788C011D0F4F008A90299673BCED33AADD13AF016CEDB,99
1150 DATA 3AD011A9008DD13AA00A209C2BA9DEA03620842BADCC3AF01CCECC3AADCC3AD01420D92BA20BA003209E2BA9ED,273
1160 DATA A03620842B4CC32FA9228D2F0220932D20BB2EA684E001D027AD0006A208DD1931F010CA10F820B32EA90CA036,682
1170 DATA 20842B4C522BBD45238591BD4E2385926C9100A920858A858BA201BD0006C920F012E8E48490F420B32EA918A0,678
1180 DATA 3620842B4C522B868DE0029002A202BD00069589CA10F8A200868E868CA000B98900DD2231D008E8C8C00390F2,625
1190 DATA B00DE68EA68CE8E8E8E05D90E1B0BEA68DE8A000BD0006998900E8C8C00390F4A200868F868CA000B98900DDB8,39
1200 DATA 31D008E8C8C00390F2B018E68FA68CE8E8E8E08790E120B32EA921A03620842B4C522BA58E85A70AAABD7C3185,983
1210 DATA 91E8BD7C318592A58F85A8AABDEB3B85906C91008181818181815744B7232323232323232424A00C209C2BA94E,872
1220 DATA A03620842BA222A00C209E2B868020A32B20CE2CC959F008A20C20C52B4C522B4CBB1FB593100AA93CA0362084,116
1230 DATA 2B4C522BD8859FC902D00CADC53AF069AEC43AF064D023C901D00CAEC53AF01AA91620822FF066C909D00FADD9,757
1240 DATA 3AD00AA9E3A03720842B4C4C2B20C224A59F8DC23A202224A005B1A0999300B1A29999008810F3A20120C52BA0,564
1250 DATA 01209C2BAEC23A20882CBD3C33BC523320842B20092F20D42E20412F4C732F20D92BA209A003209E2BA982A039,397
1260 DATA 20842B4CC32FA951A03720842B4C4C2B0A85900A18659085901869E385A0A93A690085A118A590696785A2A93B,971
1270 DATA 690085A36020C22420D92BA205A00B209E2BA93CA03A20842BA9228D2F0220A32B20CE2CC944F00DC943F00F20,237
1280 DATA E22F20A72B4C602420EC2F4C7D2420F32FA9039D4203A9089D4A03A9009D4B032056E430DAA210A9C09D4403A9,595
1290 DATA 3A9D4503A9519D4803A9019D4903A90B9D42032056E430BA20E22F4C9E20A5A7858EA5A8858F4C2723ADC23A20,147
1300 DATA 2224A005B9930091A0B9990091A28810F360A58FC915B0034CF22AA59020822FD0034C1F2BA59020952FF0034C,959
1310 DATA 162B20802FF0034C042BA6A5A4A4B59999DD3AA9FF959920092F20412F4C732F20822FF0034C282B20932FF003,298
1320 DATA 4C0D2BA590C913D007A9008DC83AF00AC919D006ADC23A8DCF3AA6A5A4A4B9DD3A9599A9FF99DD3AD0C0C901D0,354
1330 DATA 1CADC23AD014ADC33AD012A9018DC33AA9A6A03720842B4C4C2B4C162B4C312BA58FC927F03FC929F03BA590C9,414
1340 DATA 16D00CADC23AC902D0034C7426A59020952FF00AA59020822FF0034C162BA590C901D035ADC33AD00AA9B9A036,398
1350 DATA 20842B4C4C2BADD73AF0034C3A2B20932FF0034C0D2BA91BA03720842BA9168DD73AA6A5959920092F4C4C2BC9,607
1360 DATA 02D035ADC63AD00AA991A03720842B4C4C2BADD83AF0034C3A2B20932FF0034C0D2BA91BA03720842BA9198DD8,85
1370 DATA 3AA6A5959920092F4C4C2BC90FD019ADC73AD00AA948A03820842B4C4C2BA981A03820842B4C4C2BC90ED01FAD,558
1380 DATA C23AC90ED00AA937A03820842B4C4C2BC914D00AA911A03920842B4C4C2BC911D024AED43AD01F20802FD017A9,81
1390 DATA 148DD43AA6A49DDD3AA91BA03720842B20412F4C4C2B4C0D2B0AAABD8326E8BC832620842B4C4C2B0C370C370C,42
1400 DATA 378037563A0C3723380C370C370C375C380C37673A0C370C370C370C370C370C370C375E39E83830370C370C37,304
1410 DATA D3370C370C370C370C370C370C370C370C370C374CF22AA58FC912F025C929D01BA91620822FD017ADC53AD015,102
1420 DATA A9018DC53AA93EA03720842B4C4C2B4C312B4C282B4C432B20822FD0034C312BADC23AC90EF007C914F0234C31,125
1430 DATA 2BADC93AF05CA91C20822FD058ADCA3AD053A9018DCA3AA9D0A03820842B4C4C2BADC93AF03CADCC3AF044ADCD,777
1440 DATA 3AD022ADCE3AF03A20412C20412C20D92BA00A209C2BA991A03A20842BA9228D2F024C5E2720412C20412CA900,579
1450 DATA 8DCD3AA90E4C8F234C432BA9BAA03720842B4C4C2B20D92BA208A003209E2BA9D5A03920842B4CC32F20952FF0,28
1460 DATA 0AA59020822FF0034C162BA590C901D00FADC33AD013A9B9A03620842B4C4C2BC902D01CAEC63AF00AA926A03A,841
1470 DATA 20842B4C522B8DC63AA9C4A03820842B4C4C2BC90FD019AEC73AF00AA926A03A20842B4C4C2BA976A03820842B,296
1480 DATA 4C4C2B4CF22AC904D029ADD93AD024A91B20822FD020A90420952FD016A9F8A03720842BA917A6A595998DD93A,353
1490 DATA 20092F4C4C2B4CF22A20D92BA20EA003209E2BA906A03A20842B4CC32F20822FD029A590C914D00A8DCE3AA900,558
1500 DATA 8DCD3AF007C915D0188DCD3AA9FF9DDD3AA9B6A03820842B20412F4C4C2B4C282B4CF22AC906D015ADC23AC90B,632
1510 DATA D005A90C4C8F23C90CD008A90B4C8F234CF22A4C162BA58FC92BD025A91C20822FD021ADCA3AF01CADCC3AD01A,458
1520 DATA A9048DCC3AA9008DCA3AA932A03920842B4C4C2B4CF22A4C282B20D92BA20BA003209E2BA9EDA03620842B4CC3,920
1530 DATA 2FC916D013A91220822FD00FADC23AC902D005A9034C8F234CF22A4CFB2AA58FC92AD025A90F20822FD021ADC7,834
1540 DATA 3AF01FADD03AD01DADC23AC912D0208DD03AA9AAA03920842B4C4C2B4CF22A4C282B4CFB2AA926A03A20842B4C,684
1550 DATA 522BA97DA03A20842B4C4C2BC919D0034C132520822FD025A590C916D01CADC23AC901D015A9FF8DC43A9DDD3A,625
1560 DATA A960A03720842B20412F4C4C2B4C312B4C282BC913D028ADC83AD016A59020822FD019A9018DC83AA96EA03920,955
1570 DATA 842B4C4C2BA926A03A20842B4C522B4C282B4CF22AC910D02020822FD028A90F20822FD014ADC73AD012A9018D,179
1580 DATA C73AA9C4A03820842B4C4C2B4C312BA926A03A20842B4C522B4CFB2AC91AD02C20822FD01AADD23AF018CED23A,890
1590 DATA 8DD13AA9028DDB3AA9A4A03A20842B4C4C2B4C282BA913A03A20842B4C4C2BC919D01920952FF007A91920822F,144
1600 DATA D050ADD13AF04BA9038DDC3A4C732FA58FC92AF004C920D039ADC23AC912D032A91720952FD02BADD03AF026AD,772
1610 DATA D13AF021ADC83AF01F8DC93AA993A03820842BA91720952FA9FF959920092F4C4C2B4CF22A4CFB2A20D92BA206,771
1620 DATA A003209E2BA9B9A03920842B4CC32FC91BD022A91820822FD01EADC23AC906D021ADDA3AD02620932FD024A91B,607
1630 DATA 959920092F4C732F4CF22AA976A03820842B4C4C2BA96FA03720842B4C4C2B4C312B4C0D2BC90CD02A20952FD0,596
1640 DATA 28ADCB3AD02620932FD024A90D8DCB3A9599A91BA03720842BA914859420D42E20092F4C4C2B4CF22A4C162B4C,910
1650 DATA 312B4C0D2BA92AA03620842BD051A986A03620842BD048A998A03620842BD045A9ACA03620842BD03CA97BA036,614
1660 DATA 20842BD033A968A03620842BD02AA9C4A03620842BD021A900A03720842BD012A90CA03720842BD009A9A6A038,239
1670 DATA 20842BD00020A32B4C4A2120A72B4C5822488A489848A685BD762BBC7D2B8D0AD48D18D08C0DD0E68568A868AA,32
1680 DATA 68407060706070006000000000000000A2008D44038C4503A9098D4203A97F8D48038E49034C56E4A20D865584,444
1690 DATA 5460A919D002A9648D00D2A9AA8D01D2A9008514A514C905D0FAA2008E01D2CA8EFC0260BD6D2D8586BD802D85,824
1700 DATA 87A018A90091868810FB60A9408D0ED4856AA200A90C8D42032056E4A2008E4B03A9038D4203A9AD8D4403A934,367
1710 DATA 8D4503A90C8D4A032056E4A9008D00D48D2F028D0DD08D0ED08D0FD08D10D0A2089DC002CA10FAA90E8DC502A9,172
1720 DATA 748DC402A2018EF002E88652A97085108D0ED2A9448DF40260A900207D2CA2FFCAD0FD186901F002D0F18DCC3A,811
1730 DATA AEC23A20882C60A9968D00D2A94A8D01D2A2008614A614E00AD0FA38E901C940D0ECA9008D01D260A00099C102,128
1740 DATA C8C008D0F860BDA82C8DC6028DC8028DC1028DC2028DC302A90E8DC5028DC002A9748DC40260343472080808C6,194
1750 DATA C6C60400142020A620645664565636A9ACA03520842B60A9B7A03520842B60ADFC02C9FFF0F9A8A2FF8EFC0229,507
1760 DATA C0F00620A72B4CCE2C98A20DDD1A2DF0F2CA10F8B9292DC920F010C99BF00CC97EF008C96190DCD838E920A07F,509
1770 DATA 8483A4838C1FD0A208CA10FDC68310F2601C2C27603C36370F2002222606070E6C6A3B8A8B6B2B2A6F8070759B,659
1780 DATA 692D3D7680638C8D62787A348033361B3532312C202E6E806D2F81728065797F747771398030377E383C3E6668,682
1790 DATA 6480826773612040006075759DC5ED153D658DB5DD052D557DA5CDF51D3C3C3C3C3C3D3D3D3D3D3D3E3E3E3E3E,978
1800 DATA 3E3E3FD8A218A9209D0006CA10FAA00C209C2BA2FF86808EFC02E8868420CE2CC920F008C97EF004C99BD00620,311
1810 DATA A72B4C9E2D20A52E2056E4E68420CE2CC99BF032C97ED010C68430E320A52E2056E4A584F0BBD0E520A52E2056,946
1820 DATA E4E684A584C91890D720A72B20CE2CC99BF006C97EF0D4D0F020A52E86802056E4A01818B92D3E99053E2A2A2A,467
1830 DATA 2A2903AAB9053E291F1D692D990006A900992D3E8810DF60A9008585A580F029D8A5550A0A1869308D00D0AD2B,522
1840 DATA 02F00BA9F08D822B8581A93C8582A581C682D008A01E848249F085818D822B4C5FE4A9B085A985AA85ABA99B85,541
1850 DATA ADADC03A85D4ADC13A85D520AAD920E6D8D8A0FFC8B1F310FBA203B1F3098095A9CA8810F6A221A000209E2BA9,64
1860 DATA A9A00020842B60A20B8E4203A2008E48038E490360A904A03620842B60A20920C52BE820C52BA0094C9C2BA20D,29
1870 DATA 20C52BE8E01390F860A20220C52BA000A20086A6B593300ABD032F999D3CE6A6C8C8E8E00690EDA5A6D00CA002,669
1880 DATA 209C2BA99FA03A20842B602E3325373524A20320C52BE8E00990F8A003209C2BA20086A6868CB599300CE6A6AA,411
1890 DATA BD7334BC903420842BA68CE8E00690E7A5A6D007A9D6A03620842B6020C92EA00D209C2BA20086A6868CBDDD3A,834
1900 DATA 300CE6A6AABD7334BC903420842BA68CE8E00690E6A5A6D007A9D6A03620842B6020BB2EA963A03620842B4C4C,101
1910 DATA 2BA9FFA205DDDD3AF005CA10F88A6086A4A90060A9FFA205D599F005CA10F98A6086A5A9006020AAD920E6D8D8,323
1920 DATA A0FFC8B1F310FB297F91F3C8A99B91F3A5F3A4F44C842BA20EA005209E2BA925A03920842BA218A007209E2BA9,119
1930 DATA 51A03920842B4CEB1FA210A90C9D42034C56E4A9B3A0344CF72FA9B0A034A2109D4403989D450360A21CA9009D,827
1940 DATA C03ACA10FAA200A9FF9D673B9DE33AE8E08490F5A2059DDD3A95999593CA10F6A9118DDD3AA9038DD23AA91E8D,61
1950 DATA D33AA90F8DD53AA9008DC23AA225BD67309DEB3BCA10F7A22BBD8D30BCB93099E33ACA10F4A219BDE530BCFF30,991
1960 DATA 99673BCA10F46000010203030405050607070809090A0B0B0C0D0D0E0E0F1011121313141516161718191A1B1C,373
1970 DATA 0100020705040603040805030406070603070806050907080B090A150D0F0E0C0D100C110F12130F1011130C02,793
1980 DATA 090B131415191A1B1F2021242526272A2B2C2D303133363D3E42494A4B5051575B5C5D606167686C72787E011A,403
1990 DATA 1812160303030405060B06070A0E1008090A130C150E0F1C0001060C12242A3031364248494E5455565A5B6061,875
2000 DATA 7273787E7F4E534557554451584154414B47455450554C44524F4B49434C4F4F45584153454152454150555350,531
2010 DATA 52454F5045434C4F5749544B494C4849544C494750554C434C49534341494E53445249535741524F57504F5554,989
2020 DATA 48524845415745414C41534D4F56D824D824CC2613254A256D256D256D25C926FA26FA269227312B9A29F627F6,205
2030 DATA 27CE29CC266E286E283A288D288D28D228EF28372937296B29752AB82A43415643414243484550414C54524553,910
2040 DATA 4E4150494C52554247415453544F484F5554454D4D415242554950414953484F414241534845444F4F5345434D,289
2050 DATA 41435354524A55474B4E4957414C4F4152434552524F4250484F504150524146494E46434152524F5044594E4D,686
2060 DATA 4154434F43474F42737061425554494E56434F524F494C4C4951596F757220636162696E9B4F6E206465636B9B,656
2070 DATA 496E2074686520726166749B42656163689B576573742062656163689B456173742062656163689B4A756E676C,130
2080 DATA 659B4A756E676C659B4A756E676C659B426573696465206120636C6966662077616C6C9B496E20746865206361,570
2090 DATA 76659B4761746520746F206C6F737420636974799B416E6369656E74207374726565749B416C6C65797761799B,249
2100 DATA 53746F6E6520686F7573659B427269636B20726F61649B54656D706C659B4D6172626C65206275696C64696E67,848
2110 DATA 9B42657369646520616E20616C7461729B53746F7261676520726F6F6D9B53656372657420726F6F6D9B416261,412
2120 DATA 6E646F6E65642073686F709B3C474F5B616C777E858CA0ACBECDD6E2EDF40414212D3232323232323232323232,997
2130 DATA 3232323232323233333333436176659B436162696E65749B43686573749B50616C6D2074726565739B536E616B,121
2140 DATA 659B50696C65206F6620727562626C659B476174659B53746F6E6520686F7573659B54656D706C659B4D617262,791
2150 DATA 6C65206275696C64696E679B5061696E74696E679B4162616E646F6E65642073686F709B5368656C7665739B53,503
2160 DATA 656372657420646F6F727761799B537472616E6765206D616368696E659B4A75679B4B6E6966659B57616C6C65,228
2170 DATA 749B4F6172739B436572656D6F6E69616C20726F62659B50686F746F9B50617065729B496E666C617461626C65,39
2180 DATA 20726166749B436172636173739B526F70659B44796E616D6974659B4D61746368626F6F6B9B436F636F6E7574,863
2190 DATA 9B476F626C65749B686D757B868C9BA0ACB3C3CCDBE3F202060C1318282E34444C515A646C3333333333333333,390
2200 DATA 333333333333333434343434343434343434343434453A9B433A9B44313A524F41442E4441549B436C6179746F,544
2210 DATA 6E2057616C6E756D27739B4F4E4520464F522054484520524F41449B2843293139383520414E414C4F4720436F,889
2220 DATA 6D707574696E679B507265737320A0D3D4C1D2D4A020746F20706C6179206E65772067616D659B507265737320,976
2230 DATA A0CFD0D4C9CFCEA020746F20726573746F7265206F6C642067616D659B526573746F72652066726F6D20C46973,204
2240 DATA 6B206F7220C3617373657474653F9BA0CFCEC5A0C6CFD2A0D4C8C5A0D2CFC1C4A0A0A0A0A0A0C5D6C5CED4A0A3,363
2250 DATA A0A0A0A0A0A09BA0CCCFC3C1D4C9CFCEA020A0A0A0A0C5D8C9D4D3A09BA0A0D6C9D3C9C2CCC5A020A0A0A0A0C9,222
2260 DATA D4C5CDD3A09BA0A0A0A0A0A0A0A0A0A09BA0A0A0A0A0D7C8C1D4A09BA0A0C8C1D0D0C5CED3A020A0A0A0A0A0D9,4
2270 DATA CFD5D2A020A0D2C5D3D0CFCED3C5A09BA0A0A0A0A0A0D9CFD5A020A0A0A0A0A0A0C1D2C5A020A0C3C1D2D2D9C9,875
2280 DATA CEC7A09B53796E7461783A9B42616420636F6D6D616E649B42616420766572629B426164206E6F756E9B546861,704
2290 DATA 74277320696D706F737369626C659B43616E277420676F2074686174207761799B54797065205920746F207175,964
2300 DATA 69742067616D653A9B4F6B61799B416C726561647920686F6C64696E672069749B49736E277420686572659B43,413
2310 DATA 616E277420646F2074686174207965749B596F75722061726D73206172652066756C6C219B4E6F20726F6F6D20,603
2320 DATA 686572659B4974277320737475636B9B596F7520646F6E277420686176652069749B4E6F7468696E679B4D6174,119
2330 DATA 636820676F6573206F75749B54686520737472616E6765206C69717569649B57687920626F746865723F9B5365,617
2340 DATA 656D73206F7264696E6172799B596F7520666F756E6420736F6D657468696E67219B497420686173206120636F,992
2350 DATA 72649B546865207261667420696E666C61746573219B52616674277320746F6F206269679B496E746F20746865,362
2360 DATA 206F6365616E9B5468657927726520746F6F20686967689B5468657265277320636F636F6E7574739B49742773,770
2370 DATA 2066726F6D20796F757220626F6174219B4F7563682120427574206974206F70656E732E9B4C69717569642073,936
2380 DATA 70696C6C73206F76657220666C6F6F729B4974277320676F74206120667573659B536E616B6520776F6E277420,206
2390 DATA 6C657420796F75219B54686520636F636F6E757420636C6F62626572732068696D9B426F6F6F6F6F6F6F6F6D6D,737
2400 DATA 6D6D6D2121219B497427732070726574747920686967682E2E2E9B54686572652773206120627574746F6E9B49,829
2410 DATA 7427732074696768746C7920636F726B65649B536163726966696365206265696E6720706572666F726D65649B,328
2420 DATA 5769746820776861743F9B54686572652773206F696C20696E2069749B41206669657279207361637269666963,603
2430 DATA 65219B4E6F7468696E672068617070656E739B496E746F2074686520736C6F749B596F75206F70656E2069749B,148
2440 DATA 4C69717569642066696C6C732074686520676F626C65749B49742073686F777320612073746F6E6520686F7573,489
2450 DATA 659B412073656372657420646F6F72776179219B4120627574746F6E20616E64206120736C6F749B646F657320,810
2460 DATA 796F7520696E219B4F6E6520666F722074686520726F6164219B416C7265616479206F70656E9B796F75206172,157
2470 DATA 6520444541449B4974277320796F757220686F7573659B596F75207075742074686520726F6265206F6E9B5468,387
2480 DATA 652073746F726D20746F73736564206F6365616E9B412068756765206578706C6F73696F6E9B4F6E2074686520,756
2490 DATA 636172636173739B426C61737068656D79212041206C696768746E696E6720626F6C749B4120626C617374206F,100
2500 DATA 6620646976696E6520656E657267799B4372617368696E6720696E746F2074686520726F636B739B4120736E61,504
2510 DATA 6B6520626974659B54686572652773206E6F6E65206C656674219B596F7520616C726561647920646964207468,764
2520 DATA 6174219B5361766520746F20C469736B206F7220C3617373657474653F9B4974206C6F6F6B7320646561646C79,273
2530 DATA 219B446F6E2774206C6F6F6B20766572792068656176799B446F6E277420646F20746861742068657265219B59,469
2540 DATA 6F752061726520686F6D65219B4E6F6E659B446F6E277420676574206275726E6564219BA90085CBA94485CCA9,145
2550 DATA 0085CDA9E085CEA204A000B1CD91CBC8D0F9E6CEE6CCCAD0F0A90085CFA93685CDA93B85CEA4CFBE2D3BB9303B,42
2560 DATA 85CBB9333B85CCE6CFA000B1CD91CBC8C008D0F7CAF01120213B18A90865CB85CB90E6E6CC4CF53AA5CFC903F0,619
2570 DATA 0620213B4CE43A6018A90865CD85CD9002E6CE600A1A1A800808444547007E666E76767E000078781818187E00,282
2580 DATA 007E660C38707E00007E0E180C767E00001C3C7C6C7E0E00007E607E06767E00007C607E66767E00007E060E0E,146
2590 DATA 0E0E00007E663C66767E00007E667E060E0E00007C6C6CFEC6C600007C6C7E66667E00007E666070767E00007C,678
2600 DATA 666676767E00007E607E70707E00007E607E70707000007E66606E767E000066667EE6E6E60000303030383838,636
2610 DATA 00000C0C0E0E6E7E00006C6C7C7E6666000060607070707E000077777F6B636300007E666666666600007E6E6E,900
2620 DATA 66667E00007E66767E606000007E6666667E1C00007C6C6C7E767600007E607E06667E00007E18181C1C1C0000,22
2630 DATA 66666666767E00006666767E3C18000063636B7F7777000076763C3C7676000066667E18181800007E0E187070,258
2640 DATA 7E0000003E063E667E000060607E76767E0000007C6060707C000006067E666E7E0000007E667E707E00001E18,96
2650 DATA 7E3838380000007E666E7E067E0060607E6676760000180018181C1C00000E000E0E0E0E7E00606C6C786E6E00,618
2660 DATA 00381818181C3C000000777F7F6B630000007E666666660000007E6676767E0000007E66667E707000007E6666,547
2670 DATA 7E0E0E00007E666070700000007E607E067E0000187E18181C1C000000666676767E0000006666767E18000000,21
2680 DATA 636B7F7F77000000667E187E660000006666667E067E00007E0C38707E00000000000000000000000000000000,76
2690 REM * 7605 BYTES

Listing 2.
Assembly listing.

; ------------------------
; ONE FOR THE ROAD
; by Clayton Walnum
; ANALOG Computing #
; (C)1985 ANALOG Computing
; ------------------------
;
; MACRO DEFINITIONS
; -----------------
;
;          POSITION MACRO
;          --------------
; SYNTAX:
; POSITION xpos,ypos
;
	.MACRO	POSITION 
	.IF	%0<>2.OR%1>39.OR%2>23
	.ERROR	"POS parameters"
	.ELSE
	.IF	%1=13
	LDY	#%2
	JSR	POSIT13
	.ELSE
	LDX	#%1
	LDY	#%2
	JSR	POSIT
	.ENDIF
	.ENDIF
	.ENDM
;
;          PRINT MACRO
;          -----------
; SYNTAX:
; PRINT <addr of EOL-terminated string>
;
	.MACRO	PRINT 
	.IF	%0<>1
	.ERROR	"PRINTE parameters"
	.ELSE
	LDA	# <%1
	LDY	# >%1
	JSR	EPRINT
	.ENDIF
	.ENDM
;
;          TEXT MACRO
;          ----------
; SYNTAX:
; TEXT <"string">
;
	.MACRO	TEXT 
	.IF	%0<>1.OR%1>127
	.ERROR	"TEXT parameters"
	.ELSE
	.BYTE	%$1,EOL
	.ENDIF
	.ENDM
;
; SYSTEM  EQUATES
; ---------------
;
;           ZERO-PAGE
;           ---------
BOOT?	=	$09	; OS boot flag
POKMSK	=	$10	; interrupt mask
RTCLOK	=	$14	; system clock
LMARGN	=	$52	; left margin
RMARGN	=	$53	; right margin
ROWCRS	=	$54	; cursor row
COLCRS	=	$55	; cursor column
RAMTOP	=	$6A	; # pages of RAM
FR0	=	$D4	; floating point register
CIX	=	$F2	; FP index register
INBUFF	=	$F3	; FP pointer
;
;         PAGES 2-3
;         ---------
VDSLST	=	$0200	; DLI vector
SRTIMR	=	$022B	; key repeat timer
SDMCTL	=	$022F	; DMA control
SDLSTL	=	$0230	; D-list addr
COLDST	=	$0244	; coldstart flag
GPRIOR	=	$026F	; PMG priority
PCOLR0	=	$02C0	; player 0 color
PCOLR1	=	$02C1	; player 1 color
PCOLR2	=	$02C2	; player 2 color
PCOLR3	=	$02C3	; player 3 color
COLOR0	=	$02C4	; playfield 0 color
COLOR1	=	$02C5	; playfield 1 color
COLOR2	=	$02C6	; playfield 2 color
COLOR4	=	$02C8	; background color
CRSINH	=	$02F0	; cursor inhibit
CHBAS	=	$02F4	; adr of char set
CH	=	$02FC	; keypress register
ICCOM	=	$0342	; CIO command
ICBADR	=	$0344	; CIO addr
ICBLEN	=	$0348	; CIO length
ICAUX1	=	$034A	; AUX byte 1
ICAUX2	=	$034B	; AUX byte 2
;
;          CTIA/GTIA
;          ---------
HPOSP0	=	$D000	; h-pos player 0
HPOSP1	=	$D001	; "          " 1
HPOSP2	=	$D002	; "          " 2
HPOSP3	=	$D003	; "          " 3
SIZEP0	=	$D004	; width player 0
SIZEP1	=	$D009	; "          " 1
SIZEP2	=	$D00A	; "          " 2
SIZEP3	=	$D00B	; "          " 3
GRAFP0	=	$D00D	; graphics player 0
GRAFP1	=	$D00E	; "             " 1
GRAFP2	=	$D00F	; "             " 2
GRAFP3	=	$D010	; "             " 3
COLPF2	=	$D018	; color register 2
CONSOL	=	$D01F	; console keys
;
;          POKEY
;          -----
AUDF1	=	$D200	; frequency channel 1
AUDC1	=	$D201	; vol/dist channel 1
AUDCTL	=	$D208	; audio control
RANDOM	=	$D20A	; random # generator
IRQEN	=	$D20E	; interrupt enable
;
;         ANTIC
;         -----
DMACTL	=	$D400	; DMA control
WSYNC	=	$D40A	; wait for horz sync
NMIEN	=	$D40E	; NMI enable
;
;         FLOATING POINT
;         --------------
FASC	=	$D8E6	; FP-to-ATASCII
IFP	=	$D9AA	; integer-to-FP
ZFR0	=	$DA44	; clear FR0
;
;          OS ROUTINES
;          -----------
CIOV	=	$E456	; CIO entry
SETVBV	=	$E45C	; set v-blank vector
SYSVBV	=	$E45F	; OS VBI entry
SIOINV	=	$E465	; SIO init
;
; INTERNAL EQUATES
; ----------------
;
;          MEMORY ALLOCATION
;          -----------------
INLINE	=	$0600	; text input buffer
GAMEDATA	=	$3AC0	; working area
EDLIST	=	$3C20	; start of E: display list
SCREEN	=	$3C40	; start of screen RAM
;
; Game play database
;
	*=	GAMEDATA
;
EVENT	*=	*+2	; event #
PLACE	*=	*+1	; location
CABINET	*=	*+1	; cabibet opened
RAFTIN	*=	*+1	; raft in the water
INFLATE	*=	*+1	; raft inflated?
CHEST	*=	*+1	; chest open?
JUG	*=	*+1	; jug open?
ROBE	*=	*+1	; wearing robe?
SACRIF	*=	*+1	; sacrifice performed?
GOBLET	*=	*+1	; goblet filled?
SHELVES	*=	*+1	; shelves moved?
DRINK	*=	*+1	; liquid consumed?
PAPER	*=	*+1	; paper inserted?
PHOTO	*=	*+1	; photo inserted?
DPLACE	*=	*+1	; location of dynamite
OIL	*=	*+1	; oil poured?
LIT	*=	*+1	; match lit?
MATCNT	*=	*+1	; # of matches
CHECNT	*=	*+1	; chest turn counter
WALLET	*=	*+1
ROCKCNT	*=	*+1	; hit rocks counter
CORD	*=	*+1	; cord pulled?
RAFTFND	*=	*+1	; raft found?
DYNAFND	*=	*+1	; dynamite found?
SNAKE	*=	*+1	; snake dead?
LASSO	*=	*+1	; got coconut?
LITCNT	*=	*+1	; match counter
BLAST	*=	*+1	; dynamite lit?
HOLDINGS	*=	*+6	; current inventory
VECTORS	*=	*+132	; current vector table
OBJECTS	*=	*+132	; current object table
NTRANS	*=	*+38	; current translation matrix
;
;         MISCELLANEOUS
;         -------------
EOL	=	$9B
SPACE	=	$20
SETPNT	=	$CD
OFFCNT	=	$CF
NEWSET	=	$4400
ROMSET	=	$E000
;
;          ZERO-PAGE
;          ---------
	*=	$80
;
; Cursor control
;
CURSEN	*=	*+1	; cursor on/off flag
CSHAPE	*=	*+1	; current cursor shape
BLINK	*=	*+1	; cursor blink timer
;
; Keyboard handler
;
CLICK	*=	*+1	; key click counter
LENGTH	*=	*+1	; line length register
;
; DLI control
;
DLICOL	*=	*+1	; DLI color index
;
; Screen clearing
;
CLPOINT	*=	*+2	; screen clear pointer
CINDEX	*=	*+1	; window clear index
;
; Parser
;
PBUFF	*=	*+3	; parsing buffer
PDEX	*=	*+1	; scanning index
LBREAK	*=	*+1	; pos. of space char
VCODE	*=	*+1	; verb code #
UCODE	*=	*+1	; untranslated noun code #
NCODE	*=	*+1	; translated noun code #
DOVECT	*=	*+2	; verb execution vector
CURVECT	*=	*+6	; current room vectors
CUROBJS	*=	*+6	; current room objects
NEWPLACE	*=	*+1	; next room code #
VPNT	*=	*+2	; addr of current v-buffer
OPNT	*=	*+2	; addr of current o-buffer
INVPOS	*=	*+1	; position in inventory buffer
ROOMPOS	*=	*+1	; position in room buffer
ANY?	*=	*+1	; flag for empty room/inv
VLAST	*=	*+1	; last verb
ULAST	*=	*+1	; last noun
;
; Event counter
;
EBUFF	*=	*+5	; printing buffer
;
;         INITIALIZATION
;         --------------
;
	*=	$1F80
;
ENTRY
	LDX	#0
	STX	COLDST
	INX		; = 1
	STX	BOOT?
	JSR	MOVESET	; redefine char set
	JSR	SIOINV	; for sound init
	JMP	TITLE
;
;         CUSTOM DISPLAY LIST
;         -------------------
DLIST
	.BYTE	$70,$70,$70,$70	; blank 32 lines
	.BYTE	$42,<SCREEN,>SCREEN	; text w/LMS
	.BYTE	$90,$10	; blank 4 w/DLI
	.BYTE	$02	; text (location)
	.BYTE	$90,$10	; blank 4 w/DLI
	.BYTE	$02	; text (exits)
	.BYTE	$90,$10	; blank 4 w/DLI
	.BYTE	$02,$02,$02,$02,$02,$02	; text (v-items)
	.BYTE	$90,$10	; blank 4 w/DLI
	.BYTE	$02,$02	; text (events)
	.BYTE	$90,$10	; blank 4 w/DLI
	.BYTE	$02,$02	; text (response)
	.BYTE	$80,$80,$10	; blank 4 w/DLIs
	.BYTE	$02,$02,$02,$02,$02,$02	; text (i-items)
	.BYTE	$70	; blank 8
	.BYTE	$41,<DLIST,>DLIST	; JVB
;
;         TITLE SCREEN
;         ------------
TITLE
	LDX	#$FF
	TXS
	JSR	NEWSCREEN	; reset E:
		POSITION 12,6
		PRINT T0	; "Clayton Walnum's"
		POSITION 22,7
		PRINT T1	; "ONE FOR THE ROAD"
		POSITION 8,9
		PRINT T2	; "(C)1985 ANALOG Computing"
;
STARTOP
		POSITION 5,16
		PRINT T3	; "Press  START  to play new game"
		POSITION 3,18
		PRINT T4	; "Press  OPTION  to restore old game"
;
	LDA	#6
	STA	EDLIST+12	; modify
	STA	EDLIST+13	; display list
;
	LDA	#$22
	STA	SDMCTL	; restore screen
	JSR	BEEP
;
; Wait for selection
;
POLL
	LDA	CONSOL
	CMP	#7	; scan until a
	BEQ	POLL	; key is pressed
LETGO
	LDX	CONSOL
	CPX	#7
	BNE	LETGO
	CMP	#6	; START pressed?
	BEQ	NEWGAME	; yes, do a new game
	CMP	#3	; OPTION pressed?
	BEQ	RESTORE	; yes, restore old game
BADPOLL
	JSR	BOOP	; else
	JMP	POLL	; resume scan
;
; Start new game
;
NEWGAME
	JSR	INITDATA
	JMP	PLAYSCREEN
;
; Restore a previous game
;
RESTORE
		POSITION 5,20
		PRINT T5	; "Restore from Disk or Tape?"
	JSR	BEEP
DORT
	JSR	GETKEY
	CMP	#'D	; disk?
	BEQ	GETDISK
	CMP	#'C	; tape?
	BEQ	GETAPE
DORTERR
	JSR	CLOSE1
	JSR	BOOP
	JMP	DORT
;
; Get game from disk
;
GETDISK
	JSR	DPOINT
	JMP	READOPEN
;
; Get game from tape
;
GETAPE
	JSR	TPOINT
;
READOPEN
	LDA	#3	; OPEN command
	STA	ICCOM,X
	LDA	#4	; READ
	STA	ICAUX1,X
	LDA	#0
	STA	ICAUX2,X
	JSR	CIOV
	BMI	DORTERR
;
; Get game data thru IOCB #1
;
GETDATA
	LDX	#$10
	LDA	# <GAMEDATA
	STA	ICBADR,X
	LDA	# >GAMEDATA
	STA	ICBADR+1,X
	LDA	#$51
	STA	ICBLEN,X
	LDA	#$01
	STA	ICBLEN+1,X
	LDA	#7	; GET RECORD
	STA	ICCOM,X
	JSR	CIOV
	BMI	DORTERR
	JSR	CLOSE1
;
;         PLAYSCREEN INIT
;         ---------------
PLAYSCREEN
	JSR	NEWSCREEN	; reset E:
;
; Enable custom display list
;
	LDA	# <DLIST
	STA	SDLSTL
	LDA	# >DLIST
	STA	SDLSTL+1
;
; Print title & labels
;
		PRINT T6	; "ONE FOR THE ROAD EVENT #"
	LDA	#12	; set right margin
	STA	RMARGN	; for wraparound
		PRINT T7	; "LOCATION/EXITS"
		PRINT T8	; "VISIBLE ITEMS"
	JSR	BAR
	JSR	BAR
	JSR	BAR
	JSR	BAR	; 4 blank bars
	JSR	SAYWHAT	; "WHAT"
		PRINT T11	; "HAPPENS/YOUR RESPONSE"
	JSR	SAYWHAT	; "WHAT"
		PRINT T12	; "YOU ARE CARRYING"
	JSR	BAR
	JSR	BAR	; more blank bars
	LDA	#39
	STA	RMARGN	; reset
;
	LDA	#$0C	; white
	STA	PCOLR0	; cursor
;
; Setup P/M borders & mask
;
	LDA	#48
	STA	HPOSP1	; position left
	LDA	#202	; and
	STA	HPOSP2	; right borders
	LDA	#64	; and
	STA	HPOSP3	; title cover
	LDX	#255
	STX	GRAFP1	; set up
	STX	GRAFP2	; side borders and
	STX	GRAFP3	; title mask
	INX		; = 0
	STX	SIZEP0	; set cursor width
	INX		; = 1
	STX	GPRIOR	; set player priority
	LDA	#3
	STA	SIZEP1	; set border
	STA	SIZEP2	; and mask
	STA	SIZEP3	; widths
;
	LDA	#$F0	; init
	STA	CSHAPE	; cursor shape
	LDA	#30	; and
	STA	BLINK	; blink timer
;
	LDA	#13
	STA	LMARGN	; init left margin
;
	LDY	# <IMMVBI	; set VBI vector,
	LDX	# >IMMVBI	; specifying
	LDA	#6	; immediate-mode
	JSR	SETVBV
;
	LDA	# <DLI
	STA	VDSLST	; tell OS where
	LDA	# >DLI	; we put our
	STA	VDSLST+1	; DLI service routine
	LDA	#$C0	; set bits 6 & 7 of NMIEN
	STA	NMIEN	; to enable DLIs and VBIs
;
	LDA	PLACE
	JMP	REENTRY
;
;         EVENT GENERATOR
;         ---------------
;
NEXTEVENT
	LDX	#$FF	; empty stack
	TXS		; just in case!
	JSR	SHOWEV	; show event #
	INC	EVENT	; update
	BNE	HITROCKS	; event
	INC	EVENT+1	; counter
;
; Handle rocks
;
HITROCKS
	LDA	PLACE
	CMP	#3
	BCC	R1
	JMP	EXPLODE
R1
	DEC	ROCKCNT
	LDA	ROCKCNT
	BNE	EXPLODE
	JSR	NEWSCREEN
		POSITION 9,3
		PRINT T77	; "Crashing into the rocks"
	JMP	KILLS
;
; Handle explosion
;
EXPLODE
	LDA	BLAST	; counter set?
	BEQ	CHESTRTN	; no
	DEC	BLAST	; -1 from counter
	LDA	BLAST	; time to explode?
	BNE	CHESTRTN	; no
	LDA	PLACE
	CMP	DPLACE	; player in same room as dynamite?
	BEQ	EXP4	; yes, too bad!
	LDA	#25	; dynamite
	JSR	OWNIT?
	BEQ	EXP4	; deep trouble!
	LDA	DPLACE	; room with dynamite
	ASL	A	; * 2   ; calculate position
	STA	NCODE	; in objects buffer
	ASL	A	; * 4
	CLC
	ADC	NCODE	; *2 + *4 = *6
	ADC	#5
	TAY		; use Y as index
EXP0
	LDA	OBJECTS,Y	; get object
	CMP	#25	; dynamite?
	BEQ	EXP1	; sure is!
	DEY
	BNE	EXP0	; try next object
EXP1
	LDA	DPLACE
	CMP	#9	; explosion in room 9?
	BNE	EXP3	; nope
	LDA	#0	; cave
	STA	OBJECTS,Y	; put in room 9
	LDA	#10	; new room vector
	STA	VECTORS+57
EXP2
		POSITION 13,10
		PRINT T48	; "Booooommmmm!!"
	JSR	BOOM
	JMP	CHESTRTN
EXP3
	LDA	#255
	STA	OBJECTS,Y	; get rid of dynamite
	BNE	EXP2
EXP4
	JSR	NEWSCREEN
		POSITION 12,3
		PRINT T73	; "Huge explosion"
	JSR	BOOM
	JMP	KILLS
;
; handle chest
;
CHESTRTN
	LDA	CHECNT
	CMP	#255	; chest already placed?
	BEQ	MATCHRTN	; yes
	CMP	#0	; time for chest to show up?
	BNE	CRTN1	; nope
	LDA	PLACE	; current room
	CMP	#3	; is it room 3?
	BEQ	MATCHRTN	; yes
	LDY	#23	; point to room 3 object buffer
CRTN
	LDA	OBJECTS,Y
	CMP	#255	; got space?
	BEQ	CRTN0	; yes!
	DEY
	CPY	#17	; end of room 3 buffer?
	BNE	CRTN	; no, try again
	BEQ	MATCHRTN	; no space yet
CRTN0
	LDA	#2	; chest
	STA	OBJECTS,Y	; put in room
CRTN1
	DEC	CHECNT
;
; handle matches
;
MATCHRTN
	LDA	LIT	; match lit?
	BEQ	DRNKRTN	; nope
	DEC	LITCNT	; -1 from counter
	BNE	DRNKRTN	; still lit
	LDA	#0
	STA	LIT	; match goes out
		POSITION 13,10
		PRINT T29	; "Match goes out"
;
; handle liquid
;
DRNKRTN
	LDA	DRINK	; drank liquid?
	BEQ	PARSER	; no
	DEC	DRINK	; yes, decrement counter
	LDA	DRINK	; time up?
	BNE	PARSER	; no, whew!
	JSR	NEWSCREEN
		POSITION 11,3
		PRINT T32	; "Strange liquid"
	JMP	KILLS
;
;         INPUT PARSER
;         ------------
;
PARSER
	LDA	#$22
	STA	SDMCTL
	JSR	GETLINE	; put line into INLINE
	JSR	CLWH
	LDX	LENGTH
	CPX	#1	; if length is 1
	BNE	DOCLAUSE	; check for legality
;
; Check for a legal single-char command
;
	LDA	INLINE	; get the character
	LDX	#8	; init search index
LEGSING
	CMP	SCOMS,X
	BEQ	EXSING	; matched! go do it
	DEX		; otherwise
	BPL	LEGSING	; keep searching
	JSR	SYNERR	; error, so print
		PRINT T14	; "Invalid command"
	JMP	BADPARSE	; and try again
;
; Execute a single-char command
;
EXSING
	LDA	SVECTL,X	; fetch the lsb
	STA	DOVECT	; and
	LDA	SVECTH,X	; msb of the
	STA	DOVECT+1	; execution addr
	JMP	(DOVECT)	; and do it!
;
; Find the 1st space character
; in the user's response
;
DOCLAUSE
	LDA	#SPACE
	STA	PBUFF+1
	STA	PBUFF+2
	LDX	#1
FIND1
	LDA	INLINE,X	; length is in X
	CMP	#SPACE	; is it a space?
	BEQ	ENDV	; yes!
	INX		; else keep scanning
	CPX	LENGTH
	BCC	FIND1
BADVERB
	JSR	SYNERR	; verb is no good, so print
		PRINT T15	; "Verb not recognized"
	JMP	BADPARSE	; and try again
;
; Space char found, so record its
; position and move the first half
; of the clause into the parsing buffer
;
ENDV
	STX	LBREAK
	CPX	#2
	BCC	TOVB
	LDX	#2
TOVB
	LDA	INLINE,X
	STA	PBUFF,X
	DEX
	BPL	TOVB
;
; Check for a legal verb
;
	LDX	#0	; init verb index
	STX	VCODE
VNEXT
	STX	PDEX
	LDY	#0	; init buffer char index
VSCAN
	LDA	PBUFF,Y	; get a char from buffer
	CMP	VERBS,X	; match?
	BNE	NEXTRY	; nope - try another verb
	INX
	INY
	CPY	#3
	BCC	VSCAN	; if all 3 chars match
	BCS	LEGALV	; the verb is legal
NEXTRY
	INC	VCODE
	LDX	PDEX
	INX
	INX
	INX
	CPX	#NV*3+3	; out of verbs?
	BCC	VNEXT	; nope - keep scanning
	BCS	BADVERB	; else verb is worthless
;
; Verb is legal, so fetch its execution
; vector
;
; Move the second half of the
; clause into the parsing buffer
;
LEGALV
	LDX	LBREAK	; fetch pos. of space char
	INX		; plus 1
	LDY	#0	; init buffer char index
MOVEN
	LDA	INLINE,X	; fetch character
	STA	PBUFF,Y	; stuff into buffer
	INX
	INY
	CPY	#3	; until 3 characters
	BCC	MOVEN	; have been moved
;
; Check for a legal noun
;
	LDX	#0	; init noun index
	STX	UCODE
NNEXT
	STX	PDEX
	LDY	#0	; init buffer char index
NSCAN
	LDA	PBUFF,Y	; get a char from buffer
	CMP	NOUNS,X	; match?
	BNE	NEXTRY2	; nope - try another noun
	INX
	INY
	CPY	#3
	BCC	NSCAN	; if all 3 chars match
	BCS	LEGALN	; the noun is legal
NEXTRY2
	INC	UCODE
	LDX	PDEX
	INX
	INX
	INX
	CPX	#NN*3+3	; out of nouns?
	BCC	NNEXT	; nope - keep scanning
	JSR	SYNERR	; else noun is garbage
		PRINT T16	; "Bad noun"
	JMP	BADPARSE
;
; Noun's code # is in UCODE;
; verb's code # is in VCODE;
; verb execution addr is in DOVECT
;
LEGALN
	LDA	VCODE	; fetch
	STA	VLAST
	ASL	A	; execution addr
	TAX		; and
	LDA	VVECTS,X	; save it
	STA	DOVECT	; in DOVECT
	INX
	LDA	VVECTS,X
	STA	DOVECT+1
	LDA	UCODE
	STA	ULAST
	TAX
	LDA	NTRANS,X	; translate noun
	STA	NCODE
	JMP	(DOVECT)	; execute verb
;
;         EXECUTE SINGLE-CHAR COMMANDS
;         ----------------------------
;
;         COMMAND VECTOR TABLES
;         ---------------------
SVECTL
	.BYTE	<DOM,<DOM,<DOM,<DOM,<DOM
	.BYTE	<DOM,<DOQ,<DOX,<DOA
SVECTH
	.BYTE	>DOM,>DOM,>DOM,>DOM,>DOM
	.BYTE	>DOM,>DOQ,>DOX,>DOA
;
;         HANDLE "Q" (QUIT)
;         -----------------
DOQ
		POSITION 13,12
		PRINT T19	; "Type Y to quit game:"
		POSITION 34,12
	STX	CURSEN	; enable cursor
	JSR	BEEP
	JSR	GETKEY
	CMP	#'Y
	BEQ	DOQUIT
	LDX	#12
	JSR	ERASE
	JMP	BADPARSE
DOQUIT
	JMP	TITLE
;
;         HANDLE MOVEMENT
;         ---------------
; ENTRY: Vector (0-5) in X
;
DOM
	LDA	CURVECT,X
	BPL	EXMOVE
CANTGO
		PRINT T18	; "You can't go that way."
	JMP	BADPARSE
EXMOVE
	CLD		; for safety
	STA	NEWPLACE	; save destination
	CMP	#2	; going to room 2?
	BNE	EXMV0	; no
	LDA	INFLATE	; raft inflated?
	BEQ	EXMV3	; no
	LDX	RAFTIN	; raft in the water?
	BEQ	EXMV3	; no
	BNE	EXMV2
EXMV0
	CMP	#1	; going to room 1?
	BNE	EXMV1	; no
	LDX	INFLATE	; raft inflated?
	BEQ	EXMV2	; no
	LDA	#22	; raft
	JSR	OWNIT?
	BEQ	EXMV4
EXMV1
	CMP	#9	; going to room 9?
	BNE	EXMV2	; no
	LDA	SNAKE	; snake dead?
	BNE	EXMV2	; yes
		PRINT T46	; "Snake won't let you!"
	JMP	GOODPARSE
EXMV2
	JSR	SAVELOC	; save status
	LDA	NEWPLACE	; get destination,
	STA	PLACE	; make it current, and
REENTRY
	JSR	BPOINT	; point to the new buffers
;
; Get new buffer data
;
	LDY	#5
RLOOP
	LDA	(VPNT),Y
	STA	CURVECT,Y
	LDA	(OPNT),Y
	STA	CUROBJS,Y
	DEY
	BPL	RLOOP
;
; Refresh screen
;
SHOWPLACE
	LDX	#1
	JSR	ERASE	; clear location window
		POSITION 13,1
	LDX	PLACE	; get loc #
	JSR	CHGCLR	; set screen colors
	LDA	RDLS,X	; fetch lsb and
	LDY	RDHS,X	; msb of text addr and
	JSR	EPRINT	; print it
;
	JSR	SHOWVIS	; display visible items
	JSR	SHOWVECTS	; display new vectors
	JSR	SHOWINV	; show inventory
	JMP	POKAY	; congratulations!
EXMV3
	JSR	NEWSCREEN
		POSITION 9,3
		PRINT T71	; "Storm tossed ocean"
	JMP	KILLS
EXMV4
		PRINT T38	; "Raft's too big"
	JMP	GOODPARSE
;
;         POINT TO NEW BUFFERS
;         --------------------
; ENTRY: Buffer # (0-23) in A
;
BPOINT
	ASL	A	; * 2
	STA	NCODE	; save it
	ASL	A	; * 4
	CLC
	ADC	NCODE	; *2 + *4 = *6
	STA	NCODE	; save it
	CLC
	ADC	# <VECTORS
	STA	VPNT
	LDA	# >VECTORS
	ADC	#0
	STA	VPNT+1
	CLC
	LDA	NCODE
	ADC	# <OBJECTS
	STA	OPNT
	LDA	# >OBJECTS
	ADC	#0
	STA	OPNT+1
	RTS
;
;         HANDLE "X" (SAVE GAME)
;         ----------------------
DOX
	JSR	SAVELOC	; save current status
	JSR	NEWSCREEN
		POSITION 5,11
		PRINT T82	; "Save game to Disk or Cassette?"
	LDA	#$22
	STA	SDMCTL
	JSR	BEEP
SAVEPOLL
	JSR	GETKEY
	CMP	#'D
	BEQ	DSAVE
	CMP	#'C
	BEQ	CSAVE
BADWRITE
	JSR	CLOSE1
	JSR	BOOP
	JMP	SAVEPOLL
;
; Save to disk
;
DSAVE
	JSR	DPOINT
	JMP	GSAVE
;
; Save to cassette
;
CSAVE
	JSR	TPOINT
;
GSAVE
	LDA	#3
	STA	ICCOM,X
	LDA	#8
	STA	ICAUX1,X
	LDA	#0
	STA	ICAUX2,X
	JSR	CIOV
	BMI	BADWRITE
;
; Write out game data
;
WRITE
	LDX	#$10
	LDA	# <GAMEDATA
	STA	ICBADR,X
	LDA	# >GAMEDATA
	STA	ICBADR+1,X
	LDA	#$51
	STA	ICBLEN,X
	LDA	#$01
	STA	ICBLEN+1,X
	LDA	#11
	STA	ICCOM,X
	JSR	CIOV
	BMI	BADWRITE
	JSR	CLOSE1
	JMP	PLAYSCREEN
;
;         HANDLE "A" (AGAIN)
;         ------------------
DOA
	LDA	VLAST	; restore old verb
	STA	VCODE
	LDA	ULAST	; and noun
	STA	UCODE
	JMP	LEGALN	; and do it again!
;
;         SAVE LOC STATUS
;         ---------------
SAVELOC
	LDA	PLACE
	JSR	BPOINT
	LDY	#5
SLOOP
	LDA	CURVECT,Y
	STA	(VPNT),Y
	LDA	CUROBJS,Y
	STA	(OPNT),Y
	DEY
	BPL	SLOOP
	RTS
;
;         VERB EXECUTORS
;         --------------
;
; ENTRY: Translated noun code in A
;        and in NCODE;
;        untranslated code in UCODE
;
;         TAKE
;         ----
DOTAKE
	LDA	UCODE
	CMP	#21	; is it moveable?
	BCS	DT0	; yes
	JMP	IMPOSS
DT0
	LDA	NCODE
	JSR	OWNIT?	; already have it?
	BNE	DT1
	JMP	ALREADY
DT1
	LDA	NCODE
	JSR	INROOM?	; is it here?
	BEQ	DT3
	JMP	NOTHERE
DT3
	JSR	INVSPACE?	; arms full?
	BEQ	DT4
	JMP	ARMSFULL
DT4
	LDX	ROOMPOS	; get object position
	LDY	INVPOS	; and inv position
	LDA	CUROBJS,X	; pick it up
	STA	HOLDINGS,Y	; add to inventory
	LDA	#$FF
	STA	CUROBJS,X	; leave a blank slot
SHOWALL
	JSR	SHOWVIS	; show room
	JSR	SHOWINV	; and inventory
	JMP	POKAY	; done!
;
;         DROP
;         ----
DODROP
	JSR	OWNIT?	; do you have it?
	BEQ	DD0
	JMP	DONTHAVE
DD0
	JSR	ROOMSPACE?	; enough room for it?
	BEQ	DD1
	JMP	ROOMFULL
DD1
	LDA	NCODE
	CMP	#19	; robe?
	BNE	DD2	; no
	LDA	#0
	STA	ROBE	; turn off flag
	BEQ	DROPIT
DD2
	CMP	#25	; dynamite?
	BNE	DROPIT	; no
	LDA	PLACE	; keep track of where
	STA	DPLACE	; the dynamite is
DROPIT
	LDX	ROOMPOS
	LDY	INVPOS
	LDA	HOLDINGS,Y
	STA	CUROBJS,X
	LDA	#$FF
	STA	HOLDINGS,Y
	BNE	SHOWALL
;
;         KICK
;         ----
DOKICK
	CMP	#1	; cabinet?
	BNE	DK1	; no
	LDA	PLACE
	BNE	DK0
	LDA	CABINET	; already open?
	BNE	DK1	; sure is!
	LDA	#1
	STA	CABINET	; set flag
		PRINT T43	; "Ouch! But it opens"
	JMP	GOODPARSE
DK0
	JMP	NOTHERE
DK1
	JMP	WHYBOTH
;
;         LOOK/EXAM
;         ---------
DOLOOK
	LDA	UCODE
	CMP	#39	; button?
	BEQ	CABC	; yep
	CMP	#41	; cord?
	BEQ	CABC	; yep
	LDA	NCODE
DLRF1
	CMP	#22	; raft?
	BNE	DOLK1	; no
	LDA	PLACE
	CMP	#2	; in raft?
	BNE	DOLK
	JMP	LK4
DOLK
	LDA	NCODE
DOLK1
	JSR	INROOM?	; is it in room?
	BEQ	LOOKOK
	LDA	NCODE	; if not,
	JSR	OWNIT?	; do you have it?
	BEQ	LOOKOK
	JMP	NOTHERE	; guess not
LOOKOK
	LDA	NCODE
	CMP	#1	; cabinet?
	BNE	LK0
	LDA	CABINET	; already open?
	BNE	CAB0	; yep!
		PRINT T26	; "It's stuck"
	JMP	GOODPARSE
CAB0
	LDA	RAFTFND	; found raft?
	BEQ	CAB1	; nope
CABC
	JMP	SEEMSORD	; yep
CAB1
	JSR	ROOMSPACE?	; room for raft?
	BEQ	CAB2	; sure is!
	JMP	ROOMFULL	; guess not
CAB2
		PRINT T35	; "Found something!"
	LDA	#22	; raft
	STA	RAFTFND	; set flag
	LDX	ROOMPOS
	STA	CUROBJS,X	; put raft in room
	JSR	SHOWVIS
	JMP	GOODPARSE
LK0
	CMP	#2	; chest?
	BNE	LK1	; no
	LDA	CHEST	; already open?
	BNE	CH0	; yes
		PRINT T42	; "From your boat"
	JMP	GOODPARSE
CH0
	LDA	DYNAFND	; found dynamite?
	BEQ	CH1	; not yet
	JMP	SEEMSORD
CH1
	JSR	ROOMSPACE?	; room for dynamite?
	BEQ	CH2	; yep!
	JMP	ROOMFULL	; no way
CH2
		PRINT T35	; "Found something!"
	LDA	#25	; dynamite
	STA	DYNAFND	; set flag
	LDX	ROOMPOS
	STA	CUROBJS,X	; put dynamite in room
	JSR	SHOWVIS
	JMP	GOODPARSE
LK1
	CMP	#15	; jug?
	BNE	LK2	; no
	LDA	JUG	; already open?
	BNE	J0	; yes
		PRINT T51	; "Tightly corked"
	JMP	GOODPARSE
J0
		PRINT T54	; "Filled with oil"
	JMP	GOODPARSE
LK2
	CMP	#14	; machine?
	BNE	LK3	; no
	LDA	PLACE
	CMP	#14	; in stone house?
	BNE	M0	; no
		PRINT T50	; "Has a button"
	JMP	GOODPARSE
M0
	CMP	#20	; in secret room?
	BNE	LK3	; no
		PRINT T62	; "Has button and slot"
	JMP	GOODPARSE
LK3
	CMP	#17	; wallet
	BNE	LK4
	LDX	WALLET	; already looked?
	BNE	LK4	; yep
	JSR	INVSPACE?
	BNE	WL0
	LDA	#20	; photo
	STA	WALLET	; set flag
	LDX	INVPOS
	STA	HOLDINGS,X	; give player the photo
		PRINT T35	;"Found Something!"
	JSR	SHOWINV
	JMP	GOODPARSE
WL0
	JMP	ROOMFULL
LK4
	ASL	A	; * 2
	TAX		; use as an index
	LDA	LKLK,X	; fetch lsb
	INX		; and
	LDY	LKLK,X	; msb of text addr
	JSR	EPRINT	; print text
LKX
	JMP	GOODPARSE	; and exit
;
;         EXAM TEXT LOOKUP TABLE
;         ----------------------
LKLK
	.WORD	T34,T34,T34,T41
	.WORD	T83,T34,T49,T34
	.WORD	T34,T34,T52,T34
	.WORD	T84,T34,T34,T34
	.WORD	T34,T34,T34,T34
	.WORD	T68,T60,T36,T34
	.WORD	T34,T45,T34,T34
	.WORD	T34,T34,T34,T34
	.WORD	T34,T34,T34
;
;         READ
;         ----
DOREAD
	JMP	IMPOSS
;
;         PULL
;         ----
;
DOPULL
	LDA	UCODE
	CMP	#18	; door?
	BEQ	DP2
	CMP	#41	; cord?
	BNE	DP0	; no
	LDA	#22	; raft
	JSR	OWNIT?
	BNE	DP1
	LDA	INFLATE	; already inflated?
	BNE	DP2	; yes
	LDA	#1
	STA	INFLATE	; set flag
		PRINT T37	; "Raft inflates"
	JMP	GOODPARSE
DP0
	JMP	WHYBOTH
DP1
	JMP	DONTHAVE
DP2
	JMP	NOTHAP
;
;         PUSH
;         ----
DOPUSH
	JSR	OWNIT?
	BNE	DPH
	JMP	WHYBOTH
DPH
	LDA	PLACE
	CMP	#14	; in room 14?
	BEQ	DPH0	; yes
	CMP	#20	; in room 20?
	BEQ	DPH1	; yes
	JMP	WHYBOTH
DPH0
	LDA	SACRIF	; sacrifice performed?
	BEQ	DPH3	; no
	LDA	#28	; goblet
	JSR	OWNIT?
	BNE	DPH4
	LDA	GOBLET	; already filled?
	BNE	DPH4	; yes
	LDA	#1
	STA	GOBLET	; set flag
		PRINT T59	; "Liquid fills goblet"
	JMP	GOODPARSE
DPH1
	LDA	SACRIF	; sacrifice performed?
	BEQ	DPH3	; no
	LDA	DRINK	; drank liquid?
	BEQ	DPH5	; nope, trouble!
	LDA	PAPER	; paper inserted?
	BNE	DPH2	; yes
	LDA	PHOTO	; photo inserted?
	BEQ	DPH5	; no, too bad!
	JSR	FLASH
	JSR	FLASH
	JSR	NEWSCREEN
		POSITION 13,10
		PRINT T86	; "You are home!"
	LDA	#$22
	STA	SDMCTL	; turn on screen
SOLVED
	JMP	SOLVED
DPH2
	JSR	FLASH
	JSR	FLASH
	LDA	#0
	STA	PAPER	; turn off flag
	LDA	#14
	JMP	EXMOVE
DPH3
	JMP	NOTHAP
DPH4
		PRINT T44	; "Liquid spills"
	JMP	GOODPARSE
DPH5
	JSR	NEWSCREEN
		POSITION 8,3
		PRINT T76	; "Blast of energy"
	JMP	KILLS
;
;         OPEN
;         ----
DOOPEN
	JSR	INROOM?
	BEQ	OPENOK
	LDA	NCODE
	JSR	OWNIT?
	BEQ	OPENOK
	JMP	NOTHERE
OPENOK
	LDA	NCODE
	CMP	#1	; cabinet?
	BNE	OP0	; no
	LDA	CABINET	; already open?
	BNE	OPC	; yep!
		PRINT T26	; "It's stuck"
	JMP	GOODPARSE
OP0
	CMP	#2	; chest?
	BNE	OP1	; no
	LDX	CHEST	; already open?
	BEQ	CHE1	; no
OPC
		PRINT T80	; "Already did that!"
	JMP	BADPARSE
CHE1
	STA	CHEST	; set flag
		PRINT T58	; "You open it"
	JMP	GOODPARSE
OP1
	CMP	#15	; jug?
	BNE	OP2	; no
	LDX	JUG	; already open?
	BEQ	JU0	; no
		PRINT T80	; "Already did that!"
	JMP	GOODPARSE
JU0
		PRINT T53	; "With what?"
	JMP	GOODPARSE
OP2
	JMP	IMPOSS
;
;         KILL
;         ----
DOKILL
	CMP	#4	; snake?
	BNE	DKI0	; no
	LDA	SNAKE	; already dead?
	BNE	DKI0	; yep
	LDA	#27	; coconut
	JSR	OWNIT?
	BNE	DKI1
	LDA	#4	; snake
	JSR	INROOM?
	BNE	DKI0
		PRINT T47	; "Coconut clobbers him!"
	LDA	#23	; dead snake
	LDX	ROOMPOS
	STA	CUROBJS,X	; put in room
	STA	SNAKE
	JSR	SHOWVIS
	JMP	GOODPARSE
DKI0
	JMP	IMPOSS
DKI1
	JSR	NEWSCREEN
		POSITION 14,3
		PRINT T78	; "Snake bite"
	JMP	KILLS
;
;         INSERT
;         ------
;
DOINSERT
	JSR	OWNIT?
	BNE	DIN2
	LDA	NCODE
	CMP	#20	; photo?
	BNE	DIN0	; no
	STA	PHOTO	; set flag
	LDA	#0
	STA	PAPER	; turn off other flag
	BEQ	DIN1
DIN0
	CMP	#21	; paper?
	BNE	DIN3
	STA	PAPER	; set flag
DIN1
	LDA	#$FF
	STA	HOLDINGS,X	; remove from inv
		PRINT T57	; "Into the slot"
	JSR	SHOWINV
	JMP	GOODPARSE
DIN2
	JMP	DONTHAVE
DIN3
	JMP	IMPOSS
;
;         CLIMB
;         -----
DOCLIMB
	CMP	#6	; gate?
	BNE	DC1	; no
	LDA	PLACE
	CMP	#11	; in room 11?
	BNE	DC0	; no
	LDA	#12	; room 12
	JMP	EXMOVE	; move to new room
DC0
	CMP	#12	; in room 12?
	BNE	DC2	; nope
	LDA	#11	; room 11
	JMP	EXMOVE	; move to new room
DC1
	JMP	IMPOSS
DC2
	JMP	NOTHERE
;
;         DRINK
;         -----
;
DODRINK
	LDA	UCODE
	CMP	#43	; liquid?
	BNE	DDRK	; no
	LDA	#28	; goblet
	JSR	OWNIT?
	BNE	DDRK0
	LDA	GOBLET	; goblet filled?
	BEQ	DDRK0	; no
	LDA	DRINK	; already drank?
	BNE	DDRK1	; yep!  Trouble!
	LDA	#4	; # turns to survive
	STA	DRINK	; set counter
	LDA	#0
	STA	GOBLET	; goblet now empty
		PRINT T64	; "One for the Road!"
	JMP	GOODPARSE
DDRK
	JMP	IMPOSS
DDRK0
	JMP	DONTHAVE
DDRK1
	JSR	NEWSCREEN
		POSITION 11,3
		PRINT T32	; "The strange liquid"
	JMP	KILLS
;
;         ROW
;         ---
DOROW
	CMP	#22	; raft?
	BNE	DR0	; no
	LDA	#18	; oars
	JSR	OWNIT?
	BNE	DR1
	LDA	PLACE
	CMP	#2	; in raft?
	BNE	DR0	; no
	LDA	#3	; room 3
	JMP	EXMOVE
DR0
	JMP	IMPOSS
DR1
	JMP	NOTYET
;
;         POUR
;         ----
;
DOPOUR
	LDA	UCODE
	CMP	#42	; oil?
	BNE	DPR0	; no
	LDA	#15	; jug
	JSR	OWNIT?
	BNE	DPR1
	LDA	JUG	; is it open?
	BEQ	DPR2	; no
	LDA	OIL	; already poured?
	BNE	DPR3	; yes
	LDA	PLACE
	CMP	#18	; player in room 18?
	BNE	DPR4	; no
	STA	OIL	; set flag
		PRINT T74	; "On the carcass"
	JMP	GOODPARSE
DPR0
	JMP	IMPOSS
DPR1
	JMP	DONTHAVE
DPR2
	JMP	NOTYET
DPR3
		PRINT T80	; "Already did that"
	JMP	BADPARSE
DPR4
		PRINT T85	; "Don't do that here!"
	JMP	GOODPARSE
;
;         THROW
;         -----
DOTHROW
	CMP	#25	; dynamite?
	BNE	DTH
	JMP	DODROP
DTH
	JSR	OWNIT?
	BNE	DTH1
	LDA	NCODE
	CMP	#22	; raft?
	BNE	DTH0	; no
	LDA	PLACE
	CMP	#1	; in room 1?
	BNE	DTH0	; no
	LDA	#$FF
	STA	RAFTIN	; set flag
	STA	HOLDINGS,X	; remove raft from inv
		PRINT T39	; "Into the ocean"
	JSR	SHOWINV
	JMP	GOODPARSE
DTH0
	JMP	WHYBOTH
DTH1
	JMP	DONTHAVE
;
;         WEAR
;         ----
DOWEAR
	CMP	#19	; robe?
	BNE	DWR1	; no
	LDA	ROBE	; already wearing it?
	BNE	DWR	; yes
	LDA	NCODE
	JSR	OWNIT?
	BNE	DWR0
	LDA	#1
	STA	ROBE	; set flag
		PRINT T70	; "You put on the robe"
	JMP	GOODPARSE
DWR
		PRINT T80	; "Already did that"
	JMP	BADPARSE
DWR0
	JMP	DONTHAVE
DWR1
	JMP	IMPOSS
;
;         WITH
;         ----
;
DOWITH
	CMP	#16	; knife
	BNE	DWTH
	JSR	OWNIT?
	BNE	DWTH1
	LDA	#15	; jug
	JSR	OWNIT?
	BNE	DWTH
	LDA	JUG	; already open?
	BNE	DWTH0	; yes
	LDA	#1
	STA	JUG	; set flag
		PRINT T58	; "You open it"
	JMP	GOODPARSE
DWTH
	JMP	WHYBOTH
DWTH0
		PRINT T80	; "Already did that"
	JMP	BADPARSE
DWTH1
	JMP	NOTYET
;
;         LIGHT
;         -----
;
DOLIGHT
	CMP	#26	; match?
	BNE	DLT2	; no
	JSR	OWNIT?
	BNE	DLT0
	LDA	MATCNT	; have matches left?
	BEQ	DLT1	; all gone
	DEC	MATCNT	; use 1 match
	STA	LIT	; set flag
	LDA	#2
	STA	LITCNT	; life of burning match
		PRINT T88	; "Don't get burned!"
	JMP	GOODPARSE
DLT0
	JMP	DONTHAVE
DLT1
		PRINT T79	; "None left"
	JMP	GOODPARSE
DLT2
	CMP	#25	; dynamite?
	BNE	DLT4	; no
	JSR	INROOM?
	BEQ	DLT3
	LDA	#25
	JSR	OWNIT?
	BNE	DLT6
DLT3
	LDA	LIT	; match lit?
	BEQ	DLT6	; no
	LDA	#3
	STA	BLAST	; set counter
	JMP	POKAY
DLT4
	LDA	UCODE
	CMP	#42	; oil
	BEQ	DLTO
	CMP	#32	; carcass?
	BNE	DLT6
DLTO
	LDA	PLACE
	CMP	#18	; in room 18?
	BNE	DLT6
	LDA	#23	; carcass
	JSR	INROOM?
	BNE	DLT6
	LDA	OIL	; oil poured?
	BEQ	DLT6
	LDA	LIT	; match lit?
	BEQ	DLT6
	LDA	ROBE	; wearing robe?
	BEQ	DLT7	; no, too bad!
	STA	SACRIF	; set flag
		PRINT T55	; "A fiery sacrifice!"
	LDA	#23	; carcass
	JSR	INROOM?
	LDA	#$FF
	STA	CUROBJS,X	; get rid of carcass
	JSR	SHOWVIS
	JMP	GOODPARSE
DLT5
	JMP	IMPOSS
DLT6
	JMP	NOTYET
DLT7
	JSR	NEWSCREEN
		POSITION 6,3
		PRINT T75	; "Blasphemy!"
	JMP	KILLS
;
;          LASSO
;          -----
;
DOLASSO
	CMP	#27	; coconut?
	BNE	DLA0	; no
	LDA	#24	; rope
	JSR	OWNIT?
	BNE	DLA1
	LDA	PLACE
	CMP	#6	; in room 6?
	BNE	DLA2	; no
	LDA	LASSO	; already got one?
	BNE	DLA3	; yep
	JSR	ROOMSPACE?	; someplace to put it?
	BNE	DLA4	; all filled up!
	LDA	#27	; coconut
	STA	CUROBJS,X	; put in room
	JSR	SHOWVIS
	JMP	POKAY
DLA0
	JMP	IMPOSS
DLA1
		PRINT T53	; "With what?"
	JMP	GOODPARSE
DLA2
		PRINT T40	; "Too high"
	JMP	GOODPARSE
DLA3
	JMP	WHYBOTH
DLA4
	JMP	ROOMFULL
;
;       MOVE
;       ----
;
DOMOVE
	CMP	#12	; shelves?
	BNE	DMV	; no
	JSR	INROOM?
	BNE	DMV0
	LDA	SHELVES	; already moved?
	BNE	DMV1	; yep
	JSR	ROOMSPACE?
	BNE	DMV2
	LDA	#13	; secret doorway
	STA	SHELVES	; set flag
	STA	CUROBJS,X	; put door in room
		PRINT T35	; "Found something!"
	LDA	#20	; new room vector
	STA	CURVECT+1	; add new exit
	JSR	SHOWVECTS
	JSR	SHOWVIS
	JMP	GOODPARSE
DMV
	JMP	IMPOSS
DMV0
	JMP	NOTHERE
DMV1
	JMP	WHYBOTH
DMV2
	JMP	ROOMFULL
;
IMPOSS
		PRINT T17	; "That's impossible."
	BNE	GOODPARSE
;
NOTYET
		PRINT T23	; "You can't do that yet."
	BNE	GOODPARSE
;
ARMSFULL
		PRINT T24	; "You're carrying too much!"
	BNE	BADPARSE
;
ROOMFULL
		PRINT T25	; "Not enough room here."
	BNE	BADPARSE
;
NOTHERE
		PRINT T22	; "It isn't here."
	BNE	BADPARSE
;
ALREADY
		PRINT T21	; "You already have it."
	BNE	BADPARSE
;
DONTHAVE
		PRINT T27	; "You don't have it."
	BNE	BADPARSE
;
;
WHYBOTH
		PRINT T33	; "Why bother?"
	BNE	GOODPARSE
;
SEEMSORD
		PRINT T34	; "Seems ordinary."
	BNE	GOODPARSE
;
NOTHAP
		PRINT T56	; "Nothing happens."
	BNE	GOODPARSE
;
GOODPARSE
	JSR	BEEP
	JMP	NEXTEVENT
;
BADPARSE
	JSR	BOOP
	JMP	PARSER
;
;         SUBROUTINES
;         -----------
;
;         DLI ROUTINE
;         -----------
DLI
	PHA		; save A,
	TXA
	PHA		; X
	TYA		; and
	PHA		; Y registers
	LDX	DLICOL	; fetch color index
	LDA	DCOLS,X	; fetch new color
	LDY	CURSES,X	; and cursor shape
	STA	WSYNC	; wait for scan
	STA	COLPF2	; change color
	STY	GRAFP0	; and player shape
	INC	DLICOL	; update index
	PLA
	TAY		; restore Y,
	PLA		; X
	TAX		; and
	PLA		; A registers
	RTI		; back to mainline
;
DCOLS
	.BYTE	$70,$60,$70,$60,$70,$00,$60
CURSES
	.BYTE	$00,$00,$00,$00,$00
CURSOR
	.BYTE	$00,$00
;
;         PRINT MACRO SUBROUTINE
;         ----------------------
; ENTRY: Addr of EOL-terminated string
;        in A/Y registers (LSB/MSB).
;
EPRINT
	LDX	#0	; IOCB #0 (E:)
	STA	ICBADR	; lsb of string addr
	STY	ICBADR+1	; msb of string addr
	LDA	#$09	; PUT LINE command
	STA	ICCOM
	LDA	#$7F
	STA	ICBLEN	; lsb max string length
	STX	ICBLEN+1	; msb (0)
	JMP	CIOV
;
;         POSITION MACRO ROUTINE
;         ----------------------
; ENTRY: X-pos in X, Y-pos in Y.
;
POSIT13
	LDX	#13
POSIT
	STX	COLCRS
	STY	ROWCRS
	RTS
;
;         AUDIO PROMPTS
;         -------------
BEEP
	LDA	#25	; high tone
	BNE	BTONE
;
BOOP
	LDA	#100	; low tone
BTONE
	STA	AUDF1
	LDA	#$AA	; dist/vol = 10
	STA	AUDC1
	LDA	#0
	STA	RTCLOK
SOUND
	LDA	RTCLOK
	CMP	#5	; 5 jiffies
	BNE	SOUND
	LDX	#0
	STX	AUDC1	; silence!
	DEX
	STX	CH	; clear last key
	RTS
;
;         ERASE A STATUS LINE
;         -------------------
; ENTRY: Target line (0-18) in X.
;
ERASE
	LDA	LADRSL,X	; lsb of line addr
	STA	CLPOINT
	LDA	LADRSH,X	; msb of addr
	STA	CLPOINT+1
	LDY	#24	; clear 25 characters
	LDA	#0
CLLOOP
	STA	(CLPOINT),Y
	DEY
	BPL	CLLOOP
	RTS
;
;         INIT SCREEN
;         -----------
NEWSCREEN
	LDA	#$40
	STA	NMIEN
	STA	RAMTOP	; set system to 16K
;
; Close IOCB #0 (E:)
;
	LDX	#0	; IOCB #0 (E:)
	LDA	#$0C	; CLOSE command
	STA	ICCOM
	JSR	CIOV	; slam!
;
; Re-open E: with new RAM size
;
	LDX	#0	; E: again
	STX	ICAUX2	; zero this byte
	LDA	#3	; OPEN command
	STA	ICCOM
	LDA	# <EADR	; point to "E:"
	STA	ICBADR
	LDA	# >EADR
	STA	ICBADR+1
	LDA	#$0C	; allow read/write
	STA	ICAUX1
	JSR	CIOV	; do the OPEN
;
	LDA	#0
	STA	DMACTL
	STA	SDMCTL	; shut off ANTIC
	STA	GRAFP0
	STA	GRAFP1
	STA	GRAFP2
	STA	GRAFP3	; blank out borders
;
	LDX	#8	; all colors black
COLOFF
	STA	PCOLR0,X
	DEX
	BPL	COLOFF
	LDA	#14
	STA	COLOR1	; except text
	LDA	#$74
	STA	COLOR0
;
	LDX	#1
	STX	CRSINH	; disable system cursor
	INX		; = 2
	STX	LMARGN	; fix margin
	LDA	#$70
	STA	POKMSK
	STA	IRQEN	; disable BREAK key
	LDA	# >NEWSET	; addr char set
	STA	CHBAS	; point to char set
	RTS		; and return
;
;       FLASH ROUTINE
;       -------------
;
FLASH
	LDA	#0	; black
LP1	JSR	CLRCHG	; change colors
	LDX	#$FF	; delay loop
LP2	DEX
	BNE	LP2
	CLC
	ADC	#1	; next color
	BEQ	FLH	; all done
	BNE	LP1	; change colors again
FLH
	STA	DRINK	; turn off counter
	LDX	PLACE	; get current room #
	JSR	CHGCLR	; restore screen colors
	RTS
;
;     EXPLOSION ROUTINE
;     -----------------
;
BOOM
	LDA	#150
	STA	AUDF1
	LDA	#$4A
SND
	STA	AUDC1
	LDX	#0
	STX	RTCLOK
SND0
	LDX	RTCLOK
	CPX	#10
	BNE	SND0
	SEC
	SBC	#$01
	CMP	#$40
	BNE	SND
	LDA	#0
	STA	AUDC1
	RTS
;
CLRCHG
	LDY	#0	; y is index
NXCLR	STA	$02C1,Y	; change color
	INY		; point to next register
	CPY	#8	; done?
	BNE	NXCLR	; no
	RTS
;
;      SET SCREEN COLORS
;      -----------------
;
CHGCLR
	LDA	RMCOLS,X	; get room color
	STA	COLOR2	; set colors
	STA	COLOR4
	STA	PCOLR1
	STA	PCOLR2
	STA	PCOLR3
	LDA	#14	; white
	STA	COLOR1	; text color
	STA	PCOLR0	; cursor color
	LDA	#$74
	STA	COLOR0
	RTS
;
; color table for rooms
;
RMCOLS
	.BYTE	$34,$34,$72,$08,$08,$08,$C6,$C6
	.BYTE	$C6,$04,$00,$14,$20,$20,$A6,$20
	.BYTE	$64,$56,$64,$56,$56,$36
;         BLANK BAR
;         ---------
BAR
		PRINT T9
	RTS
;
;         "WHAT" BAR
;          ---------
SAYWHAT
		PRINT T10
	RTS
;
;         KEYBOARD INPUT HANDLER
;         ----------------------
; These routines are based in part on
; Steve Howard's "Alternative Keyboard Handler"
; (ANALOG Computing #15, pp. 96-103).
;
;         FETCH A KEYPRESS
;         ----------------
GETKEY
	LDA	CH
	CMP	#$FF	; key pressed?
	BEQ	GETKEY	; not yet - keep scanning
;
; Analyze keycode
;
ANALYZE
	TAY		; save key for later
	LDX	#$FF
	STX	CH	; reset key
	AND	#$C0	; bit 6 or 7 set?
	BEQ	LEGAL?	; nope
;
; Handle a bad keypress
;
BADKEY
	JSR	BOOP	; razz user and
	JMP	GETKEY	; try again
;
; Look for illegal keys
;
LEGAL?
	TYA		; restore keycode
	LDX	#13
KLOOP
	CMP	ILLEGAL,X
	BEQ	BADKEY	; razz if illegal key
	DEX
	BPL	KLOOP
;
; Get ATASCII equivalent
;
	LDA	ATASCI,Y
;
; Screen out numbers, pass EOL and BS
;
	CMP	#SPACE	; space bar?
	BEQ	CLK1	; that's okay
	CMP	#EOL	; RETURN?
	BEQ	CLK1	; fine by me
	CMP	#$7E	; backspace?
	BEQ	CLK1	; love 'em
	CMP	#'a
	BCC	BADKEY
	CLD
	SEC
	SBC	#$20	; convert to upper case
;
; Click the speaker
;
CLK1
	LDY	#$7F
	STY	CLICK
CLK2
	LDY	CLICK
	STY	CONSOL	; tick!
	LDX	#8	; click freq
DELAY
	DEX
	BPL	DELAY
	DEC	CLICK
	BPL	CLK2	; 128 times
;
	RTS		; ATASCII code in A
;
;         ILLEGAL KEYS
;         ------------
ILLEGAL
	.BYTE	$1C	; escape
	.BYTE	$2C	; tab
	.BYTE	$27	; atari
	RTS
	.BYTE	$3C	; caps
	.BYTE	$36	; <
	.BYTE	$37	; >
	.BYTE	$0F	; =
	.BYTE	$20	; ,
	.BYTE	$02	; ;
	.BYTE	$22	; .
	.BYTE	$26	; /
	.BYTE	$06	; +
	.BYTE	$07	; *
	.BYTE	$0E	; -
;
;         ATASCII CONVERSION TABLE
;         ------------------------
; We use our own table because the
; location of the ROM-based table varies
; depending on which computer you have.
;
ATASCI
	.BYTE	$6C,$6A,$3B,$8A,$8B,$6B,$2B,$2A
	.BYTE	$6F,$80,$70,$75,$9B,$69,$2D,$3D
	.BYTE	$76,$80,$63,$8C,$8D,$62,$78,$7A
	.BYTE	$34,$80,$33,$36,$1B,$35,$32,$31
	.BYTE	$2C,$20,$2E,$6E,$80,$6D,$2F,$81
	.BYTE	$72,$80,$65,$79,$7F,$74,$77,$71
	.BYTE	$39,$80,$30,$37,$7E,$38,$3C,$3E
	.BYTE	$66,$68,$64,$80,$82,$67,$73,$61
;
;         INTERNAL CONVERSION TABLE
;         -------------------------
INTATA
	.BYTE	$20,$40,$00,$60
;
;         Y-OFFSET TABLES
;         ---------------
; These two tables contain the
; starting address of each status line
; (absolute screen line address + 13).
; LADRSL holds the LSBs, LADRSH the MSBs.
;
LADRSL
	.BYTE	<SCREEN+53,<SCREEN+53,<SCREEN+93,<SCREEN+133
	.BYTE	<SCREEN+173,<SCREEN+213,<SCREEN+253,<SCREEN+293
	.BYTE	<SCREEN+333,<SCREEN+373,<SCREEN+413,<SCREEN+453
	.BYTE	<SCREEN+493,<SCREEN+533,<SCREEN+573,<SCREEN+613
	.BYTE	<SCREEN+653,<SCREEN+693,<SCREEN+733
LADRSH
	.BYTE	>SCREEN+53,>SCREEN+53,>SCREEN+93,>SCREEN+133
	.BYTE	>SCREEN+173,>SCREEN+213,>SCREEN+253,>SCREEN+293
	.BYTE	>SCREEN+333,>SCREEN+373,>SCREEN+413,>SCREEN+453
	.BYTE	>SCREEN+493,>SCREEN+533,>SCREEN+573,>SCREEN+613
	.BYTE	>SCREEN+653,>SCREEN+693,>SCREEN+733
;
;         FETCH INPUT LINE
;         ----------------
GETLINE
;
; Clear line input buffer
;
	CLD
	LDX	#24
	LDA	#SPACE
CLINL
	STA	INLINE,X
	DEX
	BPL	CLINL
;
; Get first character of line
;
GETONE
		POSITION 13,12
	LDX	#$FF
	STX	CURSEN	; turn on PMG cursor
	STX	CH	; clear key
	INX
	STX	LENGTH	; zero line length
	JSR	GETKEY	; fetch a keycode
	CMP	#SPACE	; first char not be
	BEQ	BADONE	; a space
	CMP	#$7E	; a backspace
	BEQ	BADONE
	CMP	#EOL	; or an EOL
	BNE	PUT1
;
; Handle bad first character
;
BADONE
	JSR	BOOP	; razz user and
	JMP	GETONE	; try again
;
; Print 1st char
;
PUT1
	JSR	SETCIO	; to E:
	JSR	CIOV
	INC	LENGTH
;
; Get rest of input line
;
REST
	JSR	GETKEY	; grab another keycode
	CMP	#EOL	; if it's an EOL,
	BEQ	GOTEOL	; line entry complete
	CMP	#$7E	; backspace?
	BNE	PUTNEXT	; no - send to screen
;
; Handle a backspace
;
BACKS
	DEC	LENGTH	; if 1st char of line
	BMI	BADONE	; signal error
	JSR	SETCIO	; E:
	JSR	CIOV	; let CIO do backspace
	LDA	LENGTH	; if length=0,
	BEQ	GETONE	; handle as 1st char
	BNE	REST	; else continue
;
; Print latest character
;
PUTNEXT
	JSR	SETCIO
	JSR	CIOV	; print character
	INC	LENGTH	; next position
	LDA	LENGTH
	CMP	#24	; end of line?
	BCC	REST	; not yet - get another key
;
; Too many chars in line!
;
GETLAST
	JSR	BOOP	; a warning razz
	JSR	GETKEY
	CMP	#EOL	; must have an EOL
	BEQ	GOTEOL
	CMP	#$7E	; or a backspace
	BEQ	BACKS
	BNE	GETLAST	; insist!
;
; EOL recieved
;
GOTEOL
	JSR	SETCIO	; specify E:
	STX	CURSEN	; shut off cursor
	JSR	CIOV	; and send EOL
;
; Convert screen bytes to ATASCII
; and move to INLINE
;
	LDY	#24
TOBUFF
	CLC
	LDA	SCREEN+493,Y	; grab screen byte
	STA	SCREEN+453,Y	; move to upper line
	ROL	A
	ROL	A
	ROL	A
	ROL	A
	AND	#3	; transform byte, and
	TAX		; use as an index
	LDA	SCREEN+453,Y	; restore original value
	AND	#$1F	; clear bits 5-7
	ORA	INTATA,X	; merge with code table
	STA	INLINE,Y	; send to buffer
	LDA	#0
	STA	SCREEN+493,Y	; clear response line
	DEY
	BPL	TOBUFF
	RTS
;
;         IMMEDIATE VBI ROUTINE
;         ---------------------
; Positions and blinks cursor,
; resets DLI color index
;
IMMVBI
;
; Reset DLI color index
;
	LDA	#0
	STA	DLICOL
;
; Okay to update cursor?
;
	LDA	CURSEN	; if enable flag = 0,
	BEQ	VEXIT	; don't redraw cursor
;
; Calculate cursor X-position:
; XNEW = ( XOLD * 4 ) + 48
;
	CLD
	LDA	COLCRS
	ASL	A
	ASL	A	; times 4
	CLC
	ADC	#48	; plus 48
	STA	HPOSP0	; use as h-pos
;
; Don't blink cursor if a key
; is being pressed.
;
	LDA	SRTIMR	; 0 = no press
	BEQ	BLINK?
;
	LDA	#$F0
	STA	CURSOR
	STA	CSHAPE	; force cursor on
	LDA	#60	; for at least
	STA	BLINK	; 1 second
;
BLINK?
	LDA	CSHAPE
	DEC	BLINK	; next jiffy
	BNE	VEXIT	; don't blink until 0
;
; Blink the cursor
;
	LDY	#30
	STY	BLINK	; reset timer
	EOR	#$F0	; flip the cursor shape
	STA	CSHAPE	; and save it for later
VEXIT
	STA	CURSOR	; plot the cursor
	JMP	SYSVBV	; sayonara
;
;         DISPLAY EVENT COUNTER
;         ---------------------
SHOWEV
;
; Initialize EBUFF
;
	LDA	#'0
	STA	EBUFF
	STA	EBUFF+1
	STA	EBUFF+2
	LDA	#EOL
	STA	EBUFF+4
;
; Convert event # to ATASCII
;
ECON
	LDA	EVENT
	STA	FR0
	LDA	EVENT+1
	STA	FR0+1
	JSR	IFP	; convert to floating point
	JSR	FASC	; then to ATASCII
	CLD
;
; Determine length of number
;
	LDY	#$FF	; init loop index
FINDE
	INY
	LDA	(INBUFF),Y	; check characters
	BPL	FINDE
;
; Change # to inverse video and
; move to EBUFF
;
	LDX	#3	; move 3 chars maximum
TOEB
	LDA	(INBUFF),Y
	ORA	#$80	; set msb
	STA	EBUFF,X	; put in EBUFF
	DEX
	DEY
	BPL	TOEB
;
; Display contents of EBUFF
;
		POSITION 33,0
		PRINT EBUFF
	RTS
;
;         SET CIO TO PUT CHAR MODE
;         ------------------------
SETCIO
	LDX	#$0B
	STX	ICCOM
	LDX	#0
	STX	ICBLEN
	STX	ICBLEN+1
	RTS
;
;         SYNTAX ERROR
;         ------------
SYNERR
		PRINT T13	; "Syntax:"
	RTS
;
;         CLEAR WINDOWS
;         -------------
; What Happens window
;
CLWH
	LDX	#9
	JSR	ERASE
	INX
	JSR	ERASE
	LDY	#9
	JMP	POSIT13
;
; Inventory window
;
CLINV
	LDX	#13
CLINV1
	JSR	ERASE
	INX
	CPX	#19
	BCC	CLINV1
	RTS
;
;         DISPLAY ROOM VECTORS
;         --------------------
SHOWVECTS
	LDX	#2
	JSR	ERASE
	LDY	#0
	LDX	#0
	STX	ANY?
SVL
	LDA	CURVECT,X
	BMI	VSKIP
	LDA	VNAMES,X
	STA	SCREEN+93,Y
	INC	ANY?
	INY
	INY
VSKIP
	INX
	CPX	#6
	BCC	SVL
	LDA	ANY?
	BNE	VECTEX
		POSITION 13,2
		PRINT T87	; "None"
VECTEX
	RTS
;
; Vector initials
;
VNAMES
	.SBYTE	"NSEWUD"
;
;         DISPLAY ROOM OBJECTS
;         --------------------
SHOWVIS
	LDX	#3
CLVIS
	JSR	ERASE
	INX
	CPX	#9
	BCC	CLVIS
		POSITION 13,3
	LDX	#0
	STX	ANY?
SHV1
	STX	PDEX
	LDA	CUROBJS,X
	BMI	SHV2
	INC	ANY?
	TAX
	LDA	OBDLS,X
	LDY	OBDHS,X
	JSR	EPRINT
SHV2
	LDX	PDEX
	INX
	CPX	#6
	BCC	SHV1
	LDA	ANY?
	BNE	SHEXIT
		PRINT T28	; "Nothing"
SHEXIT
	RTS
;
;         DISPLAY INVENTORY
;         -----------------
SHOWINV
	JSR	CLINV
		POSITION 13,13
	LDX	#0
	STX	ANY?
SHI1
	STX	PDEX
	LDA	HOLDINGS,X
	BMI	SHI2
	INC	ANY?
	TAX
	LDA	OBDLS,X
	LDY	OBDHS,X
	JSR	EPRINT
SHI2
	LDX	PDEX
	INX
	CPX	#6
	BCC	SHI1
	LDA	ANY?
	BNE	SIEXIT
		PRINT T28	; "Nothing"
SIEXIT
	RTS
;
;         "OKAY" PROMPT
;         -------------
POKAY
	JSR	CLWH
		PRINT T20	; "Okay"
	JMP	GOODPARSE
;
;         SEARCH INVENTORY
;         ----------------
INVSPACE?
	LDA	#$FF
OWNIT?
	LDX	#5
OLOOP
	CMP	HOLDINGS,X
	BEQ	FOUND
	DEX
	BPL	OLOOP
	TXA
	RTS
FOUND
	STX	INVPOS
	LDA	#0
	RTS
;
;         SEARCH ROOM
;         -----------
ROOMSPACE?
	LDA	#$FF
INROOM?
	LDX	#5
IRLOOP
	CMP	CUROBJS,X
	BEQ	FOUND2
	DEX
	BPL	IRLOOP
	TXA
	RTS
FOUND2
	STX	ROOMPOS
	LDA	#0
	RTS
;
;         PRINT INTEGER IN FR0
;         --------------------
VPRINT
	JSR	IFP
	JSR	FASC
	CLD
	LDY	#$FF
VLOOP
	INY
	LDA	(INBUFF),Y
	BPL	VLOOP
	AND	#$7F
	STA	(INBUFF),Y
	INY
	LDA	#EOL
	STA	(INBUFF),Y
	LDA	INBUFF
	LDY	INBUFF+1
	JMP	EPRINT
;
;         DEATH
;         -----
KILLS
		POSITION 14,5
		PRINT T63	; "does you in!"
DEATH
		POSITION 24,7
		PRINT T66	; "YOU ARE DEAD"
	JMP	STARTOP
;
;         CLOSE IOCB #1
;         -------------
CLOSE1
	LDX	#$10
	LDA	#12
	STA	ICCOM,X
	JMP	CIOV
;
;         POINT TO FILENAMES
;         ------------------
DPOINT
	LDA	# <FILE
	LDY	# >FILE
	JMP	POINT
TPOINT
	LDA	# <CADR
	LDY	# >CADR
POINT
	LDX	#$10
	STA	ICBADR,X
	TYA
	STA	ICBADR+1,X
	RTS
;
;         INIT DATABASE
;         -------------
;
INITDATA
;
; Set status flags
;
	LDX	#28
	LDA	#0
ID0
	STA	EVENT,X
	DEX
	BPL	ID0
;
; Clear vector/object matrix
;
	LDX	#0
	LDA	#$FF
ID1
	STA	OBJECTS,X
	STA	VECTORS,X
	INX
	CPX	#132
	BCC	ID1
;
; Clear working arrays
;
	LDX	#5
ID2
	STA	HOLDINGS,X
	STA	CUROBJS,X
	STA	CURVECT,X
	DEX
	BPL	ID2
	LDA	#17	; wallet
	STA	HOLDINGS	; put in inv
	LDA	#3
	STA	MATCNT	; 3 matches
	LDA	#30	; # of turns till chest appears
	STA	CHECNT
	LDA	#15	; # of turns till hit rocks
	STA	ROCKCNT
	LDA	#0
	STA	PLACE	; start in cabin
;
; Init tranlation table
;
	LDX	#37
ID3
	LDA	TRANS,X
	STA	NTRANS,X
	DEX
	BPL	ID3
;
; Init vector matrix
;
	LDX	#43
ID4
	LDA	VDATA,X
	LDY	VSETS,X
	STA	VECTORS,Y
	DEX
	BPL	ID4
;
; Init object matrix
;
	LDX	#25
ID5
	LDA	ODATA,X
	LDY	OSETS,X
	STA	OBJECTS,Y
	DEX
	BPL	ID5
	RTS
;
; Translator data
;
TRANS
	.BYTE	0,1,2,3,3,4,5,5
	.BYTE	6,7,7,8,9,9,10,11
	.BYTE	11,12,13,13,14,14,15,16
	.BYTE	17,18,19,19,20,21,22,22
	.BYTE	23,24,25,26,27,28
;
; Vector data
;
VDATA
	.BYTE	1,0,2,7,5,4,6,3
	.BYTE	4,8,5,3,4,6,7,6
	.BYTE	3,7,8,6,5,9,7
	.BYTE	8,11,9,10,21,13,15,14
	.BYTE	12,13,16,12,17,15,18,19
	.BYTE	15,16,17,19,12
VSETS
	.BYTE	2,9,11,19,20,21,25,26
	.BYTE	27,31,32,33,36,37,38,39
	.BYTE	42,43,44,45,48,49,51
	.BYTE	54,61,62,66,73,74,75,80
	.BYTE	81,87,91,92,93,96,97,103
	.BYTE	104,108,114,120,126
;
; Object data
;
ODATA
	.BYTE	1,26,24,18,22,3,3,3
	.BYTE	4,5,6,11,6,7,10,14
	.BYTE	16,8,9,10,19,12,21,14
	.BYTE	15,28
OSETS
	.BYTE	0,1,6,12,18,36,42,48
	.BYTE	49,54,66,72,73,78,84,85
	.BYTE	86,90,91,96,97,114,115,120
	.BYTE	126,127
;
;         DICTIONARY
;         ----------
;
; SINGLE-CHAR COMMANDS
; --------------------
SCOMS
	.BYTE	"N"	; 0 - North
	.BYTE	"S"	; 1 - South
	.BYTE	"E"	; 2 - East
	.BYTE	"W"	; 3 - West
	.BYTE	"U"	; 4 - Up
	.BYTE	"D"	; 5 - Down
	.BYTE	"Q"	; 6 - Quit
	.BYTE	"X"	; 7 - Save
	.BYTE	"A"	; 8 - Again
;
; COMPOUND VERBS
; --------------
VERBS
	.BYTE	"TAK"	; 0 - take
	.BYTE	"GET"	; 1 - get
	.BYTE	"PUL"	; 2 - pull
	.BYTE	"DRO"	; 3 - drop
	.BYTE	"KIC"	; 4 - kick
	.BYTE	"LOO"	; 5 - look
	.BYTE	"EXA"	; 6 - examine
	.BYTE	"SEA"	; 7 - search
	.BYTE	"REA"	; 8 - read
	.BYTE	"PUS"	; 9 - push
	.BYTE	"PRE"	; 10 - press
	.BYTE	"OPE"	; 11 - open
	.BYTE	"CLO"	; 12 - close
	.BYTE	"WIT"	; 13 - with
	.BYTE	"KIL"	; 14 - kill
	.BYTE	"HIT"	; 15 - hit
	.BYTE	"LIG"	; 16 - light
	.BYTE	"PUL"	; 17 - pull
	.BYTE	"CLI"	; 18 - climb
	.BYTE	"SCA"	; 19 - scale
	.BYTE	"INS"	; 20 - insert
	.BYTE	"DRI"	; 21 - drink
	.BYTE	"SWA"	; 22 - swallow
	.BYTE	"ROW"	; 23 - row
	.BYTE	"POU"	; 24 - pour
	.BYTE	"THR"	; 25 - throw
	.BYTE	"HEA"	; 26 - heave
	.BYTE	"WEA"	; 27 - wear
	.BYTE	"LAS"	; 28 - lasso
	.BYTE	"MOV"	; 29 - move
;
NV	=	30	; total # of verbs
;
; VERB VECTOR TABLE
; -----------------
VVECTS
	.WORD	DOTAKE	; 0
	.WORD	DOTAKE	; 1
	.WORD	DOPULL	; 2
	.WORD	DODROP	; 3
	.WORD	DOKICK	; 4
	.WORD	DOLOOK	; 5
	.WORD	DOLOOK	; 6
	.WORD	DOLOOK	; 7
	.WORD	DOREAD	; 8
	.WORD	DOPUSH	; 9
	.WORD	DOPUSH	; 10
	.WORD	DOOPEN	; 11
	.WORD	WHYBOTH	; 12
	.WORD	DOWITH	; 13
	.WORD	DOKILL	; 14
	.WORD	DOKILL	; 15
	.WORD	DOLIGHT	; 16
	.WORD	DOPULL	; 17
	.WORD	DOCLIMB	; 18
	.WORD	DOCLIMB	; 19
	.WORD	DOINSERT	; 20
	.WORD	DODRINK	; 21
	.WORD	DODRINK	; 22
	.WORD	DOROW	; 23
	.WORD	DOPOUR	; 24
	.WORD	DOTHROW	; 25
	.WORD	DOTHROW	; 26
	.WORD	DOWEAR	; 27
	.WORD	DOLASSO	; 28
	.WORD	DOMOVE	; 29
;
; COMPOUND NOUNS
; --------------
NOUNS
	.BYTE	"CAV"	; 0 - cave
	.BYTE	"CAB"	; 1 - cabinet
	.BYTE	"CHE"	; 2 - chest
	.BYTE	"PAL"	; 3 - palm
	.BYTE	"TRE"	; 4 - trees
	.BYTE	"SNA"	; 5 - snake
	.BYTE	"PIL"	; 6 - pile
	.BYTE	"RUB"	; 7 - rubble
	.BYTE	"GAT"	; 8 - gate
	.BYTE	"STO"	; 9 - stone
	.BYTE	"HOU"	; 10 - house
	.BYTE	"TEM"	; 11 - temple
	.BYTE	"MAR"	; 12 - marble
	.BYTE	"BUI"	; 13 - building
	.BYTE	"PAI"	; 14 - painting
	.BYTE	"SHO"	; 15 - shop
	.BYTE	"ABA"	; 16 - abandoned
	.BYTE	"SHE"	; 17 - shelves
	.BYTE	"DOO"	; 18 - doorway
	.BYTE	"SEC"	; 19 - secret
	.BYTE	"MAC"	; 20 - machine
	.BYTE	"STR"	; 21 - strange
	.BYTE	"JUG"	; 22 - jug
	.BYTE	"KNI"	; 23 - knife
	.BYTE	"WAL"	; 24 - wallet
	.BYTE	"OAR"	; 25 - oars
	.BYTE	"CER"	; 26 - ceremonial
	.BYTE	"ROB"	; 27 - robe
	.BYTE	"PHO"	; 28 - photo
	.BYTE	"PAP"	; 29 - paper
	.BYTE	"RAF"	; 30 - raft
	.BYTE	"INF"	; 31 - inflatable
	.BYTE	"CAR"	; 32 - carcass
	.BYTE	"ROP"	; 33 - rope
	.BYTE	"DYN"	; 34 - dynamite
	.BYTE	"MAT"	; 35 - matches
	.BYTE	"COC"	; 36 - coconut
	.BYTE	"GOB"	; 37 - goblet
	.BYTE	"spa"	; 38 - spare
	.BYTE	"BUT"	; 39 - button
	.BYTE	"INV"	; 40 - inventory
	.BYTE	"COR"	; 41 - cord
	.BYTE	"OIL"	; 42 - oil
	.BYTE	"LIQ"	; 43 - liquid
;
NN	=	44	; total # of nouns
;
;         ROOM DESCRIPTIONS
;         -----------------
;
RD0
		TEXT "Your cabin"
RD1
		TEXT "On deck"
RD2
		TEXT "In the raft"
RD3
		TEXT "Beach"
RD4
		TEXT "West beach"
RD5
		TEXT "East beach"
RD6
		TEXT "Jungle"
RD7
		TEXT "Jungle"
RD8
		TEXT "Jungle"
RD9
		TEXT "Beside a cliff wall"
RD10
		TEXT "In the cave"
RD11
		TEXT "Gate to lost city"
RD12
		TEXT "Ancient street"
RD13
		TEXT "Alleyway"
RD14
		TEXT "Stone house"
RD15
		TEXT "Brick road"
RD16
		TEXT "Temple"
RD17
		TEXT "Marble building"
RD18
		TEXT "Beside an altar"
RD19
		TEXT "Storage room"
RD20
		TEXT "Secret room"
RD21
		TEXT "Abandoned shop"
;
;         ROOM DESC. ADDRESS TABLES
;         -------------------------
RDLS
	.BYTE	<RD0,<RD1,<RD2,<RD3,<RD4,<RD5
	.BYTE	<RD6,<RD7,<RD8,<RD9,<RD10,<RD11
	.BYTE	<RD12,<RD13,<RD14,<RD15,<RD16,<RD17
	.BYTE	<RD18,<RD19,<RD20,<RD21
;
RDHS
	.BYTE	>RD0,>RD1,>RD2,>RD3,>RD4,>RD5
	.BYTE	>RD6,>RD7,>RD8,>RD9,>RD10,>RD11
	.BYTE	>RD12,>RD13,>RD14,>RD15,>RD16,>RD17
	.BYTE	>RD18,>RD19,>RD20,>RD21
;
;         OBJECT DESCRIPTIONS
;         -------------------
;
OBD0
		TEXT "Cave"
OBD1
		TEXT "Cabinet"
OBD2
		TEXT "Chest"
OBD3
		TEXT "Palm trees"
OBD4
		TEXT "Snake"
OBD5
		TEXT "Pile of rubble"
OBD6
		TEXT "Gate"
OBD7
		TEXT "Stone house"
OBD8
		TEXT "Temple"
OBD9
		TEXT "Marble building"
OBD10
		TEXT "Painting"
OBD11
		TEXT "Abandoned shop"
OBD12
		TEXT "Shelves"
OBD13
		TEXT "Secret doorway"
OBD14
		TEXT "Strange machine"
OBD15
		TEXT "Jug"
OBD16
		TEXT "Knife"
OBD17
		TEXT "Wallet"
OBD18
		TEXT "Oars"
OBD19
		TEXT "Ceremonial robe"
OBD20
		TEXT "Photo"
OBD21
		TEXT "Paper"
OBD22
		TEXT "Inflatable raft"
OBD23
		TEXT "Carcass"
OBD24
		TEXT "Rope"
OBD25
		TEXT "Dynamite"
OBD26
		TEXT "Matchbook"
OBD27
		TEXT "Coconut"
OBD28
		TEXT "Goblet"
;
;         DESCRIPTION ADDR TABLES
;         -----------------------
OBDLS
	.BYTE	<OBD0,<OBD1,<OBD2,<OBD3
	.BYTE	<OBD4,<OBD5,<OBD6,<OBD7
	.BYTE	<OBD8,<OBD9,<OBD10,<OBD11
	.BYTE	<OBD12,<OBD13,<OBD14,<OBD15
	.BYTE	<OBD16,<OBD17,<OBD18,<OBD19
	.BYTE	<OBD20,<OBD21,<OBD22,<OBD23
	.BYTE	<OBD24,<OBD25,<OBD26,<OBD27
	.BYTE	<OBD28
;
OBDHS
	.BYTE	>OBD0,>OBD1,>OBD2,>OBD3
	.BYTE	>OBD4,>OBD5,>OBD6,>OBD7
	.BYTE	>OBD8,>OBD9,>OBD10,>OBD11
	.BYTE	>OBD12,>OBD13,>OBD14,>OBD15
	.BYTE	>OBD16,>OBD17,>OBD18,>OBD19
	.BYTE	>OBD20,>OBD21,>OBD22,>OBD23
	.BYTE	>OBD24,>OBD25,>OBD26,>OBD27
	.BYTE	>OBD28
;
;         TEXT
;         ----
;
EADR
		TEXT "E:"
CADR
		TEXT "C:"
FILE
		TEXT "D1:ROAD.DAT"
T0
		TEXT "Clayton Walnum's"
T1
		TEXT "ONE FOR THE ROAD"
T2
		TEXT "(C)1985 ANALOG Computing"
T3
		TEXT "Press  START  to play new game"
T4
		TEXT "Press  OPTION  to restore old game"
T5
		TEXT "Restore from Disk or Cassette?"
T6
		TEXT " ONE FOR THE ROAD      EVENT #      "
T7
		TEXT " LOCATION      EXITS "
T8
		TEXT "  VISIBLE      ITEMS "
T9
		TEXT "          "
T10
		TEXT "     WHAT "
T11
		TEXT "  HAPPENS       YOUR   RESPONSE "
T12
		TEXT "      YOU        ARE   CARRYING "
T13
		TEXT "Syntax:"
T14
		TEXT "Bad command"
T15
		TEXT "Bad verb"
T16
		TEXT "Bad noun"
T17
		TEXT "That's impossible"
T18
		TEXT "Can't go that way"
T19
		TEXT "Type Y to quit game:"
T20
		TEXT "Okay"
T21
		TEXT "Already holding it"
T22
		TEXT "Isn't here"
T23
		TEXT "Can't do that yet"
T24
		TEXT "Your arms are full!"
T25
		TEXT "No room here"
T26
		TEXT "It's stuck"
T27
		TEXT "You don't have it"
T28
		TEXT "Nothing"
T29
		TEXT "Match goes out"
T32
		TEXT "The strange liquid"
T33
		TEXT "Why bother?"
T34
		TEXT "Seems ordinary"
T35
		TEXT "You found something!"
T36
		TEXT "It has a cord"
T37
		TEXT "The raft inflates!"
T38
		TEXT "Raft's too big"
T39
		TEXT "Into the ocean"
T40
		TEXT "They're too high"
T41
		TEXT "There's coconuts"
T42
		TEXT "It's from your boat!"
T43
		TEXT "Ouch! But it opens."
T44
		TEXT "Liquid spills over floor"
T45
		TEXT "It's got a fuse"
T46
		TEXT "Snake won't let you!"
T47
		TEXT "The coconut clobbers him"
T48
		TEXT "Boooooooommmmm!!!"
T49
		TEXT "It's pretty high..."
T50
		TEXT "There's a button"
T51
		TEXT "It's tightly corked"
T52
		TEXT "Sacrifice being performed"
T53
		TEXT "With what?"
T54
		TEXT "There's oil in it"
T55
		TEXT "A fiery sacrifice!"
T56
		TEXT "Nothing happens"
T57
		TEXT "Into the slot"
T58
		TEXT "You open it"
T59
		TEXT "Liquid fills the goblet"
T60
		TEXT "It shows a stone house"
T61
		TEXT "A secret doorway!"
T62
		TEXT "A button and a slot"
T63
		TEXT "does you in!"
T64
		TEXT "One for the road!"
T65
		TEXT "Already open"
T66
		TEXT "you are DEAD"
T68
		TEXT "It's your house"
T70
		TEXT "You put the robe on"
T71
		TEXT "The storm tossed ocean"
T73
		TEXT "A huge explosion"
T74
		TEXT "On the carcass"
T75
		TEXT "Blasphemy! A lightning bolt"
T76
		TEXT "A blast of divine energy"
T77
		TEXT "Crashing into the rocks"
T78
		TEXT "A snake bite"
T79
		TEXT "There's none left!"
T80
		TEXT "You already did that!"
T82
		TEXT "Save to Disk or Cassette?"
T83
		TEXT "It looks deadly!"
T84
		TEXT "Don't look very heavy"
T85
		TEXT "Don't do that here!"
T86
		TEXT "You are home!"
T87
		TEXT "None"
T88
		TEXT "Don't get burned!"
;
;      REDEFINE CHARACTER SET
;      ----------------------
;
; MOVE ROM SET
; ------------
;
MOVESET
	LDA	# <NEWSET
	STA	$CB	; lo byte of new set
	LDA	# >NEWSET
	STA	$CC	; hi byte of new set
	LDA	# <ROMSET	; lo byte of ROM set
	STA	$CD
	LDA	# >ROMSET	; hi byte of ROM set
	STA	$CE
	LDX	#4	; # of pages to move
MR1
	LDY	#0	; reset index
MR2
	LDA	($CD),Y	; get ROM byte
	STA	($CB),Y	; move to new location
	INY		; add 1 to index
	BNE	MR2	; go move next byte
	INC	$CE	; point to next page
	INC	$CC
	DEX		; -1 from # of pages
	BNE	MR1	; go move next 256 bytes
;
; MOVE NEW SET
; ------------
;
	LDA	#0	; init counter
	STA	OFFCNT
	LDA	# <CHSET	; move char set adr lo
	STA	SETPNT	; to temp work space
	LDA	# >CHSET	; move char set adr hi
	STA	SETPNT+1	; to temp work space
MS1
	LDY	OFFCNT	; use y to index tables
	LDX	CHARCNT,Y	; # of chars to move
	LDA	CHARADRL,Y	; get offset adr lo
	STA	$CB	; and store it
	LDA	CHARADRH,Y	; get offset adr hi
	STA	$CC	; and store it
	INC	OFFCNT	; add 1 to counter
MS2
	LDY	#0	; reset index
MS3
	LDA	(SETPNT),Y	; get char data and
	STA	($CB),Y	; move to new set
	INY		; add 1 to index
	CPY	#8	; done with char?
	BNE	MS3	; no, get next byte
;
	DEX		; yes, -1 from number of chars
	BEQ	MS5	; go check if done
	JSR	MS7
	CLC
	LDA	#8
	ADC	$CB
	STA	$CB
	BCC	MS2
	INC	$CC
	JMP	MS2
MS5
	LDA	OFFCNT
	CMP	#3
	BEQ	MS6
	JSR	MS7
	JMP	MS1
MS6
	RTS
MS7
	CLC
	LDA	#8
	ADC	SETPNT
	STA	SETPNT
	BCC	MS8
	INC	SETPNT+1
MS8
	RTS
;
; character offset tables
; -----------------------
;
CHARCNT
	.BYTE	10,26,26
CHARADRL
	.BYTE	$80,$08,$08
CHARADRH
	.BYTE	$44,$45,$47
;
; CHARACTER SET DATA
; ------------------
;
CHSET
	.BYTE	0,126,102,110,118,118,126,0
	.BYTE	0,120,120,24,24,24,126,0
	.BYTE	0,126,102,12,56,112,126,0
	.BYTE	0,126,14,24,12,118,126,0
	.BYTE	0,28,60,124,108,126,14,0
	.BYTE	0,126,96,126,6,118,126,0
	.BYTE	0,124,96,126,102,118,126,0
	.BYTE	0,126,6,14,14,14,14,0
	.BYTE	0,126,102,60,102,118,126,0
	.BYTE	0,126,102,126,6,14,14,0
	.BYTE	0,124,108,108,254,198,198,0
	.BYTE	0,124,108,126,102,102,126,0
	.BYTE	0,126,102,96,112,118,126,0
	.BYTE	0,124,102,102,118,118,126,0
	.BYTE	0,126,96,126,112,112,126,0
	.BYTE	0,126,96,126,112,112,112,0
	.BYTE	0,126,102,96,110,118,126,0
	.BYTE	0,102,102,126,230,230,230,0
	.BYTE	0,48,48,48,56,56,56,0
	.BYTE	0,12,12,14,14,110,126,0
	.BYTE	0,108,108,124,126,102,102,0
	.BYTE	0,96,96,112,112,112,126,0
	.BYTE	0,119,119,127,107,99,99,0
	.BYTE	0,126,102,102,102,102,102,0
	.BYTE	0,126,110,110,102,102,126,0
	.BYTE	0,126,102,118,126,96,96,0
	.BYTE	0,126,102,102,102,126,28,0
	.BYTE	0,124,108,108,126,118,118,0
	.BYTE	0,126,96,126,6,102,126,0
	.BYTE	0,126,24,24,28,28,28,0
	.BYTE	0,102,102,102,102,118,126,0
	.BYTE	0,102,102,118,126,60,24,0
	.BYTE	0,99,99,107,127,119,119,0
	.BYTE	0,118,118,60,60,118,118,0
	.BYTE	0,102,102,126,24,24,24,0
	.BYTE	0,126,14,24,112,112,126,0
	.BYTE	0,0,62,6,62,102,126,0
	.BYTE	0,96,96,126,118,118,126,0
	.BYTE	0,0,124,96,96,112,124,0
	.BYTE	0,6,6,126,102,110,126,0
	.BYTE	0,0,126,102,126,112,126,0
	.BYTE	0,30,24,126,56,56,56,0
	.BYTE	0,0,126,102,110,126,6,126
	.BYTE	0,96,96,126,102,118,118,0
	.BYTE	0,24,0,24,24,28,28,0
	.BYTE	0,14,0,14,14,14,14,126
	.BYTE	0,96,108,108,120,110,110,0
	.BYTE	0,56,24,24,24,28,60,0
	.BYTE	0,0,119,127,127,107,99,0
	.BYTE	0,0,126,102,102,102,102,0
	.BYTE	0,0,126,102,118,118,126,0
	.BYTE	0,0,126,102,102,126,112,112
	.BYTE	0,0,126,102,102,126,14,14
	.BYTE	0,0,126,102,96,112,112,0
	.BYTE	0,0,126,96,126,6,126,0
	.BYTE	0,24,126,24,24,28,28,0
	.BYTE	0,0,102,102,118,118,126,0
	.BYTE	0,0,102,102,118,126,24,0
	.BYTE	0,0,99,107,127,127,119,0
	.BYTE	0,0,102,126,24,126,102,0
	.BYTE	0,0,102,102,102,126,6,126
	.BYTE	0,0,126,12,56,112,126,0