Assembly language text adventure

Discuss all aspects of programming here. From 8-bit through to modern architectures.
fuzzel
Posts: 438
Joined: Sun Jan 02, 2005 1:16 pm
Location: Cullercoats, North Tyneside
Contact:

Re: Assembly language text adventure

Post by fuzzel » Mon Apr 22, 2019 9:52 am

I've decided to use Lords of Time's Level 1 - contemporary setting, to test my adventure as I know it so well. The way I've done it so far is to create data files for the locations, messages and objects and I run these first from Basic to store them in the appropriate memory locations (no data compression here which I'll have to fix at some point because they're already taking up a decent chunk of memory). I then run the main program which currently takes up memory from &1100 to &1600. You can wander around all the locations and view the objects (although I've only managed to word wrap the location text, word wrapping the object text as well is proving a bit tricky). It should be fairly straightforward to include an inventory command as I just need to repeat the location object printing for the inventory location (historically 0 or &FF). I also need to get my head round commands, thinking about it, the obvious way is to allocate 4 letters to each command, put them in a table, and when the user inputs a verb it will find the relevant one in the table, eg TAKE is verb no. 5 then JSR to the appropriate TAKE subroutine. A similar process will handle the nouns. I'm sticking to VERB + NOUN at present, handling multi nouns is a bit of a step up.

User avatar
0xC0DE
Posts: 339
Joined: Tue Mar 19, 2019 7:52 pm
Location: The Netherlands
Contact:

Re: Assembly language text adventure

Post by 0xC0DE » Mon Apr 22, 2019 9:57 am

You're making good progress! Would be great to see some live demo.
0xC0DE
:idea: Follow me on Twitter :idea: Visit my YouTube channel featuring my demos for Acorn Electron and BBC Micro

fuzzel
Posts: 438
Joined: Sun Jan 02, 2005 1:16 pm
Location: Cullercoats, North Tyneside
Contact:

Re: Assembly language text adventure

Post by fuzzel » Mon Apr 22, 2019 11:55 am

Will sort out a live demo a bit later, I just need to delete / rename a few of my test files on the .ssd disc first.
I take it I can upload .ssd and notepad files as attachments to messages ?

User avatar
0xC0DE
Posts: 339
Joined: Tue Mar 19, 2019 7:52 pm
Location: The Netherlands
Contact:

Re: Assembly language text adventure

Post by 0xC0DE » Mon Apr 22, 2019 12:00 pm

Yes, or make a zip file and attach that instead. Looking forward to your demo. Keep up the good work!
0xC0DE
:idea: Follow me on Twitter :idea: Visit my YouTube channel featuring my demos for Acorn Electron and BBC Micro

fuzzel
Posts: 438
Joined: Sun Jan 02, 2005 1:16 pm
Location: Cullercoats, North Tyneside
Contact:

Re: Assembly language text adventure

Post by fuzzel » Mon Apr 22, 2019 1:23 pm

Here it is then:

FILE1: Assembly Text Adventure - notepad file with all my annotations to the program itself. I write the code first here, it's easier to view / debug than in Beebem,

FILE 2:DH Assembly Programs.ssd - disc with the various files on for the adventure:

MESDATA - Contains the data for all the messages (Basic)
LOCLOTD - Contains the locations (Basic)
OBJDATA - Contains the objects (Basic)
MAIN - The main program - run it to create the Assembled game code. See notepad file above. Call&1100 to run.

Running the above four programs in turn will run the game unless (like I did) you end up overriding the memory location of your data !

The easiest way though is to do the following - these data files were created after running the above.
<CHANGE> - Just noticed a bug, you'll need to CH."OBJDATA" first otherwise the objects won't appear (A00-AFF will be all 0).
*LOAD LOCS
*LOAD MESS
*LOAD OBJS
*LOAD LOOKUP
*RUN ADVENT

But don't type GET or the program will crash !

The rest of the files are just throwaways.

Comments would be much appreciated (even criticism!)
Attachments
DH Assembly Programs.ssd
(95 KiB) Downloaded 7 times
Assembly Text Adventure.txt
(26.98 KiB) Downloaded 14 times
Last edited by fuzzel on Mon Apr 22, 2019 3:24 pm, edited 1 time in total.

User avatar
0xC0DE
Posts: 339
Joined: Tue Mar 19, 2019 7:52 pm
Location: The Netherlands
Contact:

Re: Assembly language text adventure

Post by 0xC0DE » Mon Apr 22, 2019 2:15 pm

Excellent job! This seems like the perfect route for you to learn about 6502 asm.

If I may offer some helpful tips.

Your program is going to get very large, very soon. So, unless you are really having fun developing on your target machine (Beeb), I would recommend putting some time in your tool chain on a host machine. Maybe Notepad++ and BeebAsm? Or VScode + BeebAsm?
Try to make a few batch files (if you're on Windows) to automate the build process for making a fresh disk image that you can test in your favorite emulator.

Secondly, I really recommend using meaningful labels and variable names in your source code instead of literal constants. Either in the BASIC part of your program, or in the Assembler part, or both. I have made a very contrived example to show what I mean (I'm used to BeebAsm myself):

1.png

When run, this assembles into:

2.png

See how those labels and names make your program more readable and more flexible as your code expands?
Hope this helps!
0xC0DE
:idea: Follow me on Twitter :idea: Visit my YouTube channel featuring my demos for Acorn Electron and BBC Micro

fuzzel
Posts: 438
Joined: Sun Jan 02, 2005 1:16 pm
Location: Cullercoats, North Tyneside
Contact:

Re: Assembly language text adventure

Post by fuzzel » Mon Apr 22, 2019 3:01 pm

Thanks, I'll bear this in mind. Here's a quick stab at verb recognition (takes the first four characters of the verb stored at &C20-&C23:

3740.analyseverb
3745LDA#0:STA&89:LDY#0:LDX#1 &89 will be the verb number from our list
3750.anverb0
3755CPX#40:BEQ anverbend Currently allow up to 40 verbs (160 bytes)
3757LDA&B00,Y:CMP&C20:BEQ anverb1 1st character recognised - goto 2nd..
3760INY:INY:INY:INY:INX:JMP anverb0 Fail on 1st char, jump to next verb in list
3765.anverb1
3770INY:LDA&B00,Y:CMP&C21:BEQ anverb2 2nd character recognised - goto 3rd..
3775INY:INY:INY:INX:JMP anverb0 Fail on 2nd char, jump to next verb in list
3780.anverb2
3785INY:LDA&B00,Y:CMP&C22:BEQ anverb3 3rd character recognised - goto 4th..
3790INY:INY:INX:JMP anverb0 Fail on 3rd char, jump to next verb in list
3795.anverb3
3800INY:LDA&B00,Y:CMP&C23:BEQ verbhit 4th character recognised - we got a match
3805INY:INX:JMP anverb0 Fail on 4th char, jump to next verb in list
3810.verbhit We got here so verb found !
3815STX&89 Store the verb number (X) at &89 for examination
3820.anverbend
3825RTS
Attachments
Verbs at B00.jpg

User avatar
0xC0DE
Posts: 339
Joined: Tue Mar 19, 2019 7:52 pm
Location: The Netherlands
Contact:

Re: Assembly language text adventure

Post by 0xC0DE » Mon Apr 22, 2019 3:46 pm

I would filter the user input first. For example, discard all non-alphanumerical characters, and convert to uppercase maybe?
Or at least discard extra spaces and interpunction anywhere in the input.
Only then try to match the input with verbs and nouns that your program recognizes.

Just an idea. Maybe a simple hash (non-unique!) function would work also for matching words? E.g. the word "TAKE" could be hashed to 'T' EOR 'A' EOR 'K' EOR 'E'. Then you would only need one byte comparison (CMP) to recognize the right word. You could experiment with better hash functions.
0xC0DE
:idea: Follow me on Twitter :idea: Visit my YouTube channel featuring my demos for Acorn Electron and BBC Micro

fuzzel
Posts: 438
Joined: Sun Jan 02, 2005 1:16 pm
Location: Cullercoats, North Tyneside
Contact:

Re: Assembly language text adventure

Post by fuzzel » Mon Apr 22, 2019 5:16 pm

i tried to convert each four letter verb into a single byte with a unique value between 0-255 but always came unstuck with two being the same.
I tried for example to take the first character ascii code, ROR, then take the second and add eg 60 then take the third and ROR etc but kept failing. The way I've done it now seems to work ok for me.
I also made the decision when creating the input routine to limit the range of characters you could input to capitals, space, backspace and return. I'm not sure if the numbers will be necessary but can add them if they are.

fuzzel
Posts: 438
Joined: Sun Jan 02, 2005 1:16 pm
Location: Cullercoats, North Tyneside
Contact:

Re: Assembly language text adventure

Post by fuzzel » Wed Apr 24, 2019 9:40 am

I've found a bug in my program which I've narrowed down (I think) to a subroutine which splits the inputted text into a verb and noun.
I'm storing the input line at &C00 (limited to 10 characters for testing). The program then analyses it below and puts the verb at &C20 and the noun at &C30 for further analysis. When I run the program I get a bad string message and I can't see why. However, when just a verb is entered it appears to be ok.

Am I ok to use C00-CFF or is this the problem ? I'm also using &900-&BFF as well as &70-&94 elsewhere in the program.

I wonder if someone can spot something obvious? My routine is as follows:

.splitstring THIS SPLITS THE STRING INTO VERB AND NOUN
LDY#0 Y STORES CHAR POSN OF NOUN / VERB STRING
LDX#0 X STORES CURRENT CHARACTER POSN ON FULL STRING
.verb A STORES CURRENT CHARACTER BEING EXAMINED
TXA:CMP &71:BEQ end2:TAX &71 IS THE FULL LENGTH OF THE STRING - CHANGE CODE TO CPX ?
LDA&C00,X
CMP#32
BEQ noun WHEN WE FIND A SPACE GO TO NOUN SECTION OTHERWISE CONTINUE WITH VERB
STA&C20,Y
INX:INY
JMP verb
.noun
STY&73:LDA#0:LDY#0 STORES THE LENGTH OF THE VERB AT &73
.beforezero THIS ROUTINE BLANKS C30 ONWARDS IN CASE FINAL NOUN IS SHORTER THAN PREVIOUS ONE
STA&C30,Y:PHA:TYA COULD WE REPLACE WITH CPY ?
CMP#10:BEQ afterzero:TAY:PLA:INY:JMP beforezero THE CMP#10 PUTS A 0 IN EACH MEMLOC UNTIL THE 10TH CHAR
.afterzero
INX:LDY#0 - THIS MOVES THE COUNTER ON ONE FROM THE SPACE
.noun2
TXA:CMP &71:BEQ end2:TAX - DO WE NEED PHA, TXA, TAX, PLA HERE ?
LDA&C00,X
CMP#32:BEQ noun - IF ANOTHER SPACE (WORD) IS DETECTED THEN START AGAIN
STA&C30,Y - IMPORTANT - IF THE 2ND WORD IS LONGER THAN THE 3RD AFTER THE 3RD NEED BLANKS
INX:INY
JMP noun2
.end2
STY&74 - STORES THE LENGTH OF THE NOUN AT &74

User avatar
SimonSideburns
Posts: 392
Joined: Mon Aug 26, 2013 8:09 pm
Location: Purbrook, Hampshire
Contact:

Re: Assembly language text adventure

Post by SimonSideburns » Wed Apr 24, 2019 1:16 pm

If nothing else, to make it clearer to read your code, you ought to enclose it in code tags within the forum.

Code: Select all

Here's an example
Last edited by SimonSideburns on Wed Apr 24, 2019 1:17 pm, edited 1 time in total.
Just remember kids, Beeb spelled backwards is Beeb!

User avatar
hoglet
Posts: 8530
Joined: Sat Oct 13, 2012 6:21 pm
Location: Bristol
Contact:

Re: Assembly language text adventure

Post by hoglet » Wed Apr 24, 2019 1:27 pm

Could you attach a complete example that can actually be run?

It may be the issue is on the BASIC side.

Dave

fuzzel
Posts: 438
Joined: Sun Jan 02, 2005 1:16 pm
Location: Cullercoats, North Tyneside
Contact:

Re: Assembly language text adventure

Post by fuzzel » Wed Apr 24, 2019 4:25 pm

Hi, file attached.
*LOAD NOUNS - this is a lookup table of the nouns in the game
*LOAD COMMAND - this is a list of all the commands
CH."INPUT"
CALL&1100

If you enter a single verb command eg N then it seems to work ok.
If you enter a verb followed by a noun eg EXAM ROPE then it crashes (there's a gap to the prompt line back in Basic).

Lines 3060-3440 deal with the text input (stored at C00). This seems to work when I *MZAP C00
Lines 3460-3720 then split the text input into noun and verb (stored at C20 and C30 respectively). This seems to work when I *MZAP C00
Lines 3740-3862 look up the verb and noun in turn from the tables in COMMAND and NOUN and if they recognise them they store their
identifiers in &89 and &8A respectively. This also seems to work when I PRINT ?&89 and ?&8A.
I'll have another look at this myself in a day or two.
Attachments
DH Assembly Programs.ssd
(95 KiB) Downloaded 6 times

fuzzel
Posts: 438
Joined: Sun Jan 02, 2005 1:16 pm
Location: Cullercoats, North Tyneside
Contact:

Re: Assembly language text adventure

Post by fuzzel » Wed Apr 24, 2019 4:40 pm

I think I may have solved it. Instead of using PHA,TXA, CMP, TAX, PLA I used CPY and it seems to work ok now.
I'll modify my full program and test it thoroughly.

User avatar
pixelblip
Posts: 1356
Joined: Wed Feb 04, 2015 7:19 pm
Location: London
Contact:

Re: Assembly language text adventure

Post by pixelblip » Fri Apr 26, 2019 6:01 am

Very impressive with the progress. You start tinkering and have come on lots with help from everyone here. That’s what it’s all about. Maybe someone out there can help you write the text so you can concentrate on programming which you clearly have a knack for :wink:

fuzzel
Posts: 438
Joined: Sun Jan 02, 2005 1:16 pm
Location: Cullercoats, North Tyneside
Contact:

Re: Assembly language text adventure

Post by fuzzel » Fri Apr 26, 2019 10:08 am

Thanks for the encouragement pixelblip. I've now got examine objects working and my next step is to incorporate an inventory which hopefully should be easy because it's basically my print objects in current location routine copied over to list a notional inventory location instead eg &FF. I will then do a wearables inventory eg &FE for the rucksack.
One headscratcher I have at the moment is how to handle the score. If the score is out of 1000 and your score always ends in a zero then the actual score is really out of 100 with a zero on the end which would conveniently fit into one byte. How though do you print on screen the value of a byte ?
There must be an easy way but it eludes me (0-9 is easy because you just ADC# whatever to get the ascii value of the character to print).
Btw, when LOT Level 1 is complete I'll start on the actual game, hopefully I'll have a flair for the text as well (I've certainly got some ideas ready).

User avatar
tricky
Posts: 3727
Joined: Tue Jun 21, 2011 8:25 am
Contact:

Re: Assembly language text adventure

Post by tricky » Fri Apr 26, 2019 10:52 am

For scores I usually store the in BCD so the the decimal value looks the same as the hex value.
73 is encoded as &73
You need to use decimal mode to ADC/SBC and that is the only way to inc/DEC.
To increment you would.

Code: Select all

lda score : SEI : SED : ADC #1 : CLD : CLI : sta score
The reason to SEI/CLI is to stop an interrupt that doesn't clear the decimal flag from getting its sums wrong!
To print you can the use

Code: Select all

LDA score: and #&F .. Lda score : lsr A : lsr A : lsr A : lsr A...
If you need it as a number, I often &F0 and asl as I need to copy bitmaps for the digits that are 16 bytes apart.

PS this only works 0..99 so, unless 100 is "You win", you might need to a little extra.
Last edited by tricky on Fri Apr 26, 2019 10:54 am, edited 1 time in total.

fuzzel
Posts: 438
Joined: Sun Jan 02, 2005 1:16 pm
Location: Cullercoats, North Tyneside
Contact:

Re: Assembly language text adventure

Post by fuzzel » Fri Apr 26, 2019 6:15 pm

Thanks tricky. I'll probably just have a separate message stating "Your score is 1000 of 1000.", that would get around it. I've had a busy afternoon incorporating get, drop and inventory. It's now starting to look like the real thing (apart from the annoying lack of word wrap on the objects which will take a bit of crafting to solve). Next I'll look at opening and closing doors and solving some of the puzzles.
Last edited by fuzzel on Fri Apr 26, 2019 6:18 pm, edited 1 time in total.

fuzzel
Posts: 438
Joined: Sun Jan 02, 2005 1:16 pm
Location: Cullercoats, North Tyneside
Contact:

Re: Assembly language text adventure

Post by fuzzel » Fri May 03, 2019 7:39 pm

Another thing I liked about the Level 9 games is the fact that they even took the repetitive "I don't understand" message used by other software houses and introduced a bit of variety by having "Eh?", "I don't understand" and "Arfle barfle gloop" appearing randomly instead. I'd like to do the same and I gather that in assembly language I would probably need to access the clock memory location(s) to generate a random number. Could someone point out a suitable memory location / os call please ? I could then have message 1 if the value is less than 86, message 2 for 86 to 170 and message 3 for 171 to 255.

User avatar
richardtoohey
Posts: 3717
Joined: Thu Dec 29, 2011 5:13 am
Location: Tauranga, New Zealand
Contact:

Re: Assembly language text adventure

Post by richardtoohey » Sat May 04, 2019 4:35 am

Read the value of e.g. &FE64 ...

I can't remember what's there but it changes ...

Code: Select all

>P.?&FE64
        39
>P.?&FE64
       111
>P.?&FE64 
       114
>P.?&FE64
       228

fuzzel
Posts: 438
Joined: Sun Jan 02, 2005 1:16 pm
Location: Cullercoats, North Tyneside
Contact:

Re: Assembly language text adventure

Post by fuzzel » Sat May 04, 2019 8:49 am

Many thanks Richard, I shall add it to my program this morning.

User avatar
0xC0DE
Posts: 339
Joined: Tue Mar 19, 2019 7:52 pm
Location: The Netherlands
Contact:

Re: Assembly language text adventure

Post by 0xC0DE » Sat May 04, 2019 11:35 am

Alternatively:

Read CFS counter at $0240. Officially via OSBYTE 176.

Read system clock (TIME) or the interval timer via OSWORD.

Note: these are not random numbers but good enough for your purpose I think.
Last edited by 0xC0DE on Sat May 04, 2019 11:36 am, edited 1 time in total.
0xC0DE
:idea: Follow me on Twitter :idea: Visit my YouTube channel featuring my demos for Acorn Electron and BBC Micro

fuzzel
Posts: 438
Joined: Sun Jan 02, 2005 1:16 pm
Location: Cullercoats, North Tyneside
Contact:

Re: Assembly language text adventure

Post by fuzzel » Mon May 06, 2019 12:47 pm

Very annoyingly my basic program no longer runs as there's "no room". The program itself excludes all text (locations, messages, objects etc) and runs at P%=&1100 to &1FFF so I've been running it at &2000 so far without a hitch. Is there any way I can get it to run without splitting the basic program up into bits and running them separately saving the assembled code in several parts ? eg using a different emulated beeb or with a second processor (I'm using beebem) ? I have no experience of using anything other than a humble BBC B.

LordVaderUK
Posts: 64
Joined: Thu Jan 31, 2019 12:26 am
Contact:

Re: Assembly language text adventure

Post by LordVaderUK » Mon May 06, 2019 12:59 pm

fuzzel wrote:
Mon May 06, 2019 12:47 pm
Very annoyingly my basic program no longer runs as there's "no room". The program itself excludes all text (locations, messages, objects etc) and runs at P%=&1100 to &1FFF so I've been running it at &2000 so far without a hitch. Is there any way I can get it to run without splitting the basic program up into bits and running them separately saving the assembled code in several parts ? eg using a different emulated beeb or with a second processor (I'm using beebem) ? I have no experience of using anything other than a humble BBC B.
I've come up across the same issues, I'm writing a smallish adventure in BASIC (46 rooms, 31 items) and very quickly came up against the 'No Room' issue. I found this thread which gave me the idea of stripping all the text out into data files. That worked a treat (although slowed it to a crawl on a real BBC :roll:) but now again as I develop the adventure I've run out of space. It really gives me such admiration for programmers who were able to create incredible games in 32K or less, back in the day - we have all got lazy these days I think!

So, sorry I don't have any solution for you, but I will continue to watch this thread with interest in case you or someone else does!

fuzzel
Posts: 438
Joined: Sun Jan 02, 2005 1:16 pm
Location: Cullercoats, North Tyneside
Contact:

Re: Assembly language text adventure

Post by fuzzel » Mon May 06, 2019 1:21 pm

I have certain routines, eg wordwrap, and the text input, which won't change and which I can run independently and save as separate files.
These can then be *LOADed after I've run my main Basic program (I'll need to change the main program so I'd include at line 10 say, wordwrap = &7000 so I could still JSR wordwrap in the program to call that routine). I suppose that would be my best solution to it.
It would be nice though if a second processor would allow you a separate memory area for loading the basic file in.

User avatar
lurkio
Posts: 2177
Joined: Tue Apr 09, 2013 11:30 pm
Location: Doomawangara
Contact:

Re: Assembly language text adventure

Post by lurkio » Mon May 06, 2019 2:48 pm

fuzzel wrote:
Mon May 06, 2019 12:47 pm
Very annoyingly my basic program no longer runs as there's "no room". ... I have no experience of using anything other than a humble BBC B.
Try switching BeebEm to Master 128 mode, and then change to MODE 135 (instead of MODE 7). Then you'll be able to use RAM from PAGE (&E00 in BeebEm's Master 128 mode) up to &8000.

:idea:

User avatar
lurkio
Posts: 2177
Joined: Tue Apr 09, 2013 11:30 pm
Location: Doomawangara
Contact:

Re: Assembly language text adventure

Post by lurkio » Mon May 06, 2019 2:55 pm

LordVaderUK wrote:
Mon May 06, 2019 12:59 pm
I've come up across the same issues, I'm writing a smallish adventure in BASIC (46 rooms, 31 items) and very quickly came up against the 'No Room' issue. I found this thread which gave me the idea of stripping all the text out into data files. That worked a treat (although slowed it to a crawl on a real BBC :roll:) but now again as I develop the adventure I've run out of space.
Try compressing the BASIC program using the Pack option in the PRES Advanced BASIC Editor ROMs. It can be quite effective. Let me know if you need help setting up.

:idea:

fuzzel
Posts: 438
Joined: Sun Jan 02, 2005 1:16 pm
Location: Cullercoats, North Tyneside
Contact:

Re: Assembly language text adventure

Post by fuzzel » Fri May 10, 2019 7:21 am

I've been working on my wordwrap amendment for displaying the list of objects in a location eg "You are carrying a book, a bell and a candle." and it works except for the final noun. I suspect it's the commas and the "and" at fault so I'd like to use A=GET each time the wordwrap routine is called to see how the text is displayed. Is there a simple A=GET call in assembly language I can use to temporarily halt the program ?

roganjosh
Posts: 98
Joined: Sat Dec 10, 2016 6:51 pm
Location: W.Yorks
Contact:

Re: Assembly language text adventure

Post by roganjosh » Fri May 10, 2019 9:13 am

fuzzel wrote:
Fri May 10, 2019 7:21 am
I've been working on my wordwrap amendment for displaying the list of objects in a location eg "You are carrying a book, a bell and a candle." and it works except for the final noun. I suspect it's the commas and the "and" at fault so I'd like to use A=GET each time the wordwrap routine is called to see how the text is displayed. Is there a simple A=GET call in assembly language I can use to temporarily halt the program ?
Something like this should do what you want. It leaves the key value in 'A'. X and Y are
preserved unless Esc is the key pressed.

Code: Select all

osbyte = &fff4
osrdch = &ffe0

.WaitKey
	{
	jsr	osrdch
	bcc	out
	cmp	#&1b
	bne	WaitKey
	pha
	lda	#&7e
	jsr	osbyte
	pla
.out	rts
	}

fuzzel
Posts: 438
Joined: Sun Jan 02, 2005 1:16 pm
Location: Cullercoats, North Tyneside
Contact:

Re: Assembly language text adventure

Post by fuzzel » Fri May 10, 2019 4:56 pm

Thanks for that, it came in very handy. My assembly wordwrap routine now very nearly always works although about 1 in 10 times it prints a blank line so I'll need to double check how it handles spaces at the end of a word (whether it includes them when considering whether (current line + next word >=40?). I'll be glad when this wordwrap problem is over so I can get back to writing the adventure proper (much more fun). I still have text compression to look forward to at some point, it will definitely be needed. I wonder how that will affect the wordwrap routine.....

Post Reply