A partial disassembly of Podd (for translation into Welsh)

reminisce about classic bbc micro and acorn electron games here
Related forum: adventures


Post Reply
Kazzie
Posts: 1401
Joined: Sun Oct 15, 2017 8:10 pm
Location: North Wales
Contact:

A partial disassembly of Podd (for translation into Welsh)

Post by Kazzie » Wed Apr 24, 2019 3:01 pm

It's everyone's favourite anthropomorphic tomato, Podd!

Motivation
As some of you will have learned in other threads, this program is one that I remember using in my early years in primary school. The version I used, however, was translated into Welsh, and named Pod ('dd' being a separate letter in Welsh). My father, who worked as a primary teacher at the time, can vouch for the fact that it was available in both langauges, and isn't a figment of my imagination. But the odds of stumbling across a thirty-year-old floppy disc with the Welsh version on it are remote indeed.

My young kids are displaying an interest in using my Beeb (and Archimedes), and I've been thinking about what software I could offer them. I'd like them to be able to use some Welsh software as well as the (readily available) English software. While I don't expect to find a copy of Welsh Pod, I figured I may be able to translate it again myself, making something comparable to the original.

Initial Listing
The SSD contains four files, IBOOT, PODD, PODD1 and PODD2

!BOOT is uninteresting, it simply CHAINs PODD

PODD starts as a tokenised BASIC file. An initial detokenisation gives:

Code: Select all

   10MODE5:VDU23;8202;0;0;0;
   20!&70=&426B41EB
   30!&74=&44694104
   40!&78=&42A1
   50L%=TOP-16644
   60FORI%=&70TO&78STEP2
   70!I%=!I%+L%:NEXT
   80!&7B=0:CALLTOP+987:*fx15
   90REPEATUNTILGET=32:CLS
  100*L.PODD1
  110*/PODD2
but that's not all the contents, by any means. There's a &0D &FF after line 110, which indicates the end of the file, but there's a whole load of data after that point. This code is called at line 80 (with entry point TOP+987 equating to &1D90), and uses the values inserted (and obfuscated) in the user routine space at &70-&7F to display the title screen, waits for the user to press the space bar, then loads PODD1 and PODD2.

PODD1 is loaded to memory at &0C00-0CFF, which is the memory space allocated to user-defined character definitions. It presumably redefines characters used in the program (as sprites?).

PODD2 is where the real meat of the program is. It's straight 6502 assembly code, and has been the main focus of my work. I'll write about it in the next post...

Attached are the control and label files I've created for disassembling PODD and PODD2, for use with Phill (Prime)'s BeebDis disassembler.
Attachments
PODD2Labels.txt
Labels for use with PODD2control
(4.61 KiB) Downloaded 18 times
PODD2control.txt
Control file for disassembling PODD2
(7.35 KiB) Downloaded 19 times
PODDcontrol.txt
Simple control file for PODD, disassembling from entry point 1D90 only
(215 Bytes) Downloaded 17 times
Last edited by Kazzie on Wed Apr 24, 2019 6:12 pm, edited 1 time in total.
BBC Model B 32k issue 7, Sidewise ROM board with 16K RAM
Archimedes 420/1 upgraded to 4MB RAM, ZIDEFS with 512MB CF card
Acorn System 1 home-made replica

Kazzie
Posts: 1401
Joined: Sun Oct 15, 2017 8:10 pm
Location: North Wales
Contact:

Re: An partial disassembly of Podd (for translation into Welsh)

Post by Kazzie » Wed Apr 24, 2019 3:01 pm

The Structure of Podd's Word List

The list of words that Podd can recognise are listed from $1900 onwards. Each word is a $0D-terminated string, with the next two bytes indicating the memory location of the animation subroutine to be executed when the word is guessed correctly.

For example, at location $1900:

Code: Select all

        EQUS    "glide",$0D
        EQUB    $13,$37
we have the word "glide", a carriage return, and the information that the gliding subroutine is at $3713. (multiple words can share the same animation). Words are stored in lower case, as user input is converted to lower case when it is validated.

When the user guesses a word, the subroutine at $1E7A (S_CHECK_WORD) starts comparing the guess with $1900, incrementing one byte at a time. If it gets as far as a $0D without a mis-match, it returns the address of the animation subroutine. The check for $0D is only carried out after the fourth characters match, so the minimum word length is four characters. (The maximum word length permitted is 10 characters.) If a mis-match happens before the end of a word, the subroutine skips ahead to the end of the word, skips past the two bytes of the animation address, and tries again. If the first character of the next word is $23 ( a '#'), this indicates that the end of he list has been reached, i.e. Podd doesn't know that word.

Looking at the memory above $1900, the '#' marker is found at $1CB9. The nine strings that follow are duplicates of "expand" to "pop", and aren't searched by S_CHECK_WORD. They're probably left over in memory from development. From $1D01 onward, we seem to have a partial disassembly of the game code itself in memory! In particular, the contents from $1D42:

Code: Select all

LDA chcnt%
&    CMP noch:BCC cont009
0    PLA:JMP loop100
:   .cont009
D    PLA
N    LDY chcnt%:STA(v7d1%),Y
looks very similar to my disassembly of $1E37 onwards:

Code: Select all

.L1E36
        PHA
        LDA     CHAR_POS
        CMP     S_INPUT_WORD
        BCC     L1E43

        PLA
        JMP     L1DD9

.L1E43
        PLA
        LDY     CHAR_POS
        STA     (ADDR_L),Y
(ADDR_L is at location $0070. The first instruction at S_INPUT_WORD has value $0A, so represents the number of characters permitted ('noch').

That's enough information for me to change the words associated with Podd's actions. But as well as the list of words Podd recognises, I will want to translate the user interface.

The User Interface
The main menu program loop is at $2CE2, and prompts the user to choose one of two games: guess a word/action ($25BA), or chain 2-5 actions together ($2E4C). Each has their own subroutine for inputting words, using the S_READKB subroutine at $1850.

Podd has two sets of subroutines for printing strings of text. The simpler ones is at $1FC4 (S_PRINT_STR), which simply prints a string through OSWRCH until it finds a $0D character. It's used for executing VDU commands.

The text displayed onscreen is double-height, and a pair of subroutines at $23C4 and $23D4 (S_2L_PRINT_STR and S_2L_PRINT_CH) are responsible for this. S_2L_PRINT_CH takes a character from the A register, looks up the character's definition with OSWORD 0A, then expands the character vertically by repeating each line of pixels. The resulting pair of characters are printed on the current line and the one below. S_2L_PRINT_STR simply feeds a $0D-terminated string to S_2L_PRINT_CH instead of OSWRCH.

The original version gives this prompt (in game 1):
Image
followed by this response for an incorrect guess:
Image
(Yes, I pulled suitable random screenshots from the internet, rather than make my own. So shoot me...)

Here we hit upon a problem, as the Welsh for "Podd can" requires more space on the screen: " Mae Pod yn gallu" needs an extra eight characters. And we need up to ten characters for the guessed word. In the original that required 19 characters, but the Welsh equivalent won't fit on a single line.

My father distinctly recalls the Welsh version repeating the word back at you if it don't recognise it, which isn't part of the original's functionality at all. I think that this was part of the way the translators got around the above problem. As there is space for two lines of text, if they arranged the "Podd can" prompt as :

Code: Select all

Mae Pod yn
gallu __________
Then instead of adding a second line of text when the word is wrong, they could overwrite the first, to give:

Code: Select all

Tydy Pod ddim yn
gallu __________
that is, "Podd can't ___" or "Podd isn't able to ___".

Tweaking the VDU codes that set the text cursor's location before each string is printed could be done in-situ, but the strings to be printed won't be the same length. That means they probably won't fit into the space reserved for them in between subroutines. There is, however, free space at the end of the list of words from $1900: as far as I can make out everything up until $1DB0 is reserved for the word list. As we've seen, the end of that consists of garbage memory from the unassembled/disassembled code. Plus, my Welsh word list will be shorter than the English one, as the language has fewer synonyms. (English has taken loanwords from so many different sources, e.g. "big" and "large" would both equate to "mawr".) That ought to give me plenty of memory space in which to place my modifications.

So that's most of the theory and research done. I'll need to do a detailed decoding of the VDU commands I want to change, of course. But I've gotten to the point where I can start modifying the codebase with the expectation that the program will still run. :)
Last edited by Kazzie on Wed Apr 24, 2019 6:14 pm, edited 2 times in total.
BBC Model B 32k issue 7, Sidewise ROM board with 16K RAM
Archimedes 420/1 upgraded to 4MB RAM, ZIDEFS with 512MB CF card
Acorn System 1 home-made replica

User avatar
Phipli
Posts: 87
Joined: Sun Sep 16, 2012 8:12 pm
Location: Derby
Contact:

Re: A partial disassembly of Podd (for translation into Welsh)

Post by Phipli » Sun Mar 08, 2020 11:19 am

Yup - also used to have the Welsh version of Pod in my primary school. Thank you for also explaining why in my memories it was spelt with one "d" and not that I just have a terrible memory.

I remember playing it on an A300x0 of some description. Sadly, the school doesn't even exist any more as they moved it to another site and knocked the building down, the odds of the Archimedes and software having survived are... minimal.

Kazzie
Posts: 1401
Joined: Sun Oct 15, 2017 8:10 pm
Location: North Wales
Contact:

Re: A partial disassembly of Podd (for translation into Welsh)

Post by Kazzie » Fri Apr 10, 2020 12:53 pm

It seems like ages since I got the main body of Pod translated back into Welsh, leaving just the title screen to be done. For whatever reason, that felt like a completely separate job, and it fell off the back burner!

Recently, with all this stay-at-home-time, I got around to looking at the title screen, and sheepishly found that the job was as simple as tweaking some strings with a hex editor. :oops:


So here we are, a SSD image of Pod fully translated back into Welsh, as well as the latest disassembly files I have for PODD2 (the main bulk of the program).
Pod-Cy.png
There's also an ODT file listing the Welsh translations of the English phrases I've programmed in. Think of it as a spolier log. :P
Attachments
Pod-Cy.ssd
SSD of Pod in Welsh, ready to run
(200 KiB) Downloaded 11 times
PODD2Labels.txt
Labels file for use with BeebDis
(5.57 KiB) Downloaded 8 times
PODD2dis.txt
Latest disassembly of PODD2
(141.44 KiB) Downloaded 9 times
PODD2control.txt
Control file for use with BeebDis
(9.53 KiB) Downloaded 8 times
PodCymraeg.odt
Listing of Welsh words Pod understands
(19.31 KiB) Downloaded 10 times
BBC Model B 32k issue 7, Sidewise ROM board with 16K RAM
Archimedes 420/1 upgraded to 4MB RAM, ZIDEFS with 512MB CF card
Acorn System 1 home-made replica

stuslayer
Posts: 142
Joined: Thu Feb 28, 2019 6:17 pm
Location: Kellington, North Yorkshire
Contact:

Re: A partial disassembly of Podd (for translation into Welsh)

Post by stuslayer » Sat May 23, 2020 1:31 am

Podd is pretty much my first memory of using computers, in primary school during the 80's (probably somewhere between 1986-88). It's one of the things that got me started 'retro-ing' all these years later :)

Post Reply

Return to “8-bit acorn software: classic games”