CBM64 Bard's Tale 1 Disassembly

Any developer realated stuff
User avatar
Darendor
Posts: 1502
Joined: Wed Jan 14, 2009 1:53 am
Location: Red Deer, Alberta, Canada

Post by Darendor »

So the MACO spell has its own variable in the game engine?

Wonder if the same is for the other dungeon exploration spells:
- light
- "eye"
- shield
- levitation
Jojo80011
Posts: 1
Joined: Tue Sep 04, 2012 1:44 pm
Location: Denver, CO

Re: CBM64 Bard's Tale 1 Disassembly

Post by Jojo80011 »

What does "BAD" mean in the disassembled code?
User avatar
Flanimal
Posts: 107
Joined: Sun Aug 08, 2010 3:40 pm
Location: London, England

Re: CBM64 Bard's Tale 1 Disassembly

Post by Flanimal »

Jojo80011 wrote:What does "BAD" mean in the disassembled code?
Same as ??? I guess, meaning that the binary value is not a valid machine code instruction, like when you disassemble data?
Or there may be some undocumented instructions that are not supported by the disassembler? I'm guessing as I don't know for certain, but BAD certainly is not listed in the 6502 instruction set.
User avatar
ZeroZero
Posts: 286
Joined: Tue Mar 10, 2009 9:10 pm
Location: Germany

Re: CBM64 Bard's Tale 1 Disassembly

Post by ZeroZero »

Flaminal is right: BAD means an illegal opcode or an opcode that really has no (known) function. But BT is completely coded with legal codes, so likely you disassembled beyond the boundaries of regular code into a data section.
Mordred
Posts: 21
Joined: Mon Nov 10, 2014 8:51 pm
Location: Germany

Re: CBM64 Bard's Tale 1 Disassembly

Post by Mordred »

I compared all weapons in your bt1 json files with the html-tables on wikia.
http://bardstale.wikia.com/wiki/Tales_o ... wn_:_Items

most items there are perfectly correct. only a few things to debate:

thief dagger on wikia states that he increases chance to hide, but there is nothing inside the json-file to confirm this. can you confirm it, zerozero?

wikia says Arcs Hammer casts a LERE if you use it. your json file says the light of arcs hammer is stronger: according to the json file, arc hammers distance is 5, while LERE has a distance of 4 (see spell.json).

conjurstaff is known to halve spell costs even if it is not equiped. this feature is missing in the json-file. can you confirm it?

are there any other items that work without the need to equip them? would be nice :-)
Mordred
Posts: 21
Joined: Mon Nov 10, 2014 8:51 pm
Location: Germany

Re: CBM64 Bard's Tale 1 Disassembly

Post by Mordred »

can someone answer the following question after disassembling the code?

resistence and classes:
do all classes have the same resistance (chance to avoid spell damage) if they have the same luck-value, level and the same items equipped? is there a class-bonus to resistance or do some classes get more resistence per level-up?
as far as i know, luck and level affect the chance to resist a spell, is that correct?
drifting
Posts: 152
Joined: Wed Dec 07, 2011 10:21 pm

Re: CBM64 Bard's Tale 1 Disassembly

Post by drifting »

Mordred wrote:can someone answer the following question after disassembling the code?

resistence and classes:
do all classes have the same resistance (chance to avoid spell damage) if they have the same luck-value, level and the same items equipped? is there a class-bonus to resistance or do some classes get more resistence per level-up?
as far as i know, luck and level affect the chance to resist a spell, is that correct?
Paladins get a resistance bonus based on level from +1 to +6. The other classes get a static bonus between +1 and +3.

Level and Luck do affect the spell resistance.
User avatar
Quantum Reality
Posts: 91
Joined: Mon Mar 15, 2010 8:34 pm

Re: CBM64 Bard's Tale 1 Disassembly

Post by Quantum Reality »

Hey! Mad props to Darendor and ZeroZero for keeping this thing going for almost five years now.

:mrgreen:

A parenthetical note is that if you see a lot of nonsense instructions you're seeing data, not a program. (or, as I found in my partial disassembly of BT1 on the Apple, obfuscated code)
User avatar
ZeroZero
Posts: 286
Joined: Tue Mar 10, 2009 9:10 pm
Location: Germany

Re: CBM64 Bard's Tale 1 Disassembly

Post by ZeroZero »

I only wished, that Burgerbecky could decide to publish the complete sources of BT1. She was so kind to send me some snippets to get me on the track.

Imho BT had the most sophisticated RPG-Engine on the CBM64 ever, but thats only my 2 cents.
User avatar
Flanimal
Posts: 107
Joined: Sun Aug 08, 2010 3:40 pm
Location: London, England

Re: CBM64 Bard's Tale 1 Disassembly

Post by Flanimal »

ZeroZero wrote:Imho BT had the most sophisticated RPG-Engine on the CBM64 ever, but thats only my 2 cents.
Agreed. I was always in awe of how sophisticated the graphics compression of BT1 must be. I had BT1 on tape, and and each dungeon level would be a short load - which unbelievably included monster graphics!

I had similar thoughts when I saw the BT1 disk intro animations for the first time.
User avatar
ZeroZero
Posts: 286
Joined: Tue Mar 10, 2009 9:10 pm
Location: Germany

Re: CBM64 Bard's Tale 1 Disassembly

Post by ZeroZero »

Flanimal wrote: Agreed. I was always in awe of how sophisticated the graphics compression of BT1 must be.
...
I had similar thoughts when I saw the BT1 disk intro animations for the first time.
In one of the articles here the animation mechanism is explained (based on the excellent work of tedious). Afaik the title animation is done the very same way. I made a little proggy in VB6 in 2010 that loads anims directly from a D64-Image and displays them. Although the title bar reads "Editor" it rather is a viewer - no encoding or editing is implemented.

Image
Weber G
Posts: 125
Joined: Tue Dec 15, 2020 9:58 am

Re: CBM64 Bard's Tale 1 Disassembly

Post by Weber G »

No posts here the last 3 years, so I want to open again this topic.

It's because I woundering why the 'character change to hit' sould be a comparison of the armor classes.

I already disassembled, or better investigated, this part of the code in the 80s. But since my notices were lost :roll: over the years, I did it again. And it was a lot of fun :lol: .

Unfortunately the 'character-chance-to-hit' code is very long with many subs. Therefore I will just mention the addresses. But the code can be found on your C64 :D .

start: $58D1
1. load AC of monster from table $7DA8 (only the 5 right bits) in ZP (zero page) $4A
(example: AC 7 => 03h =>$4A; AC L0 => 14h => $4A)
2. check if weapon with a bonus is equiped (jsr $5A6E); the weapon bonus can be found in table $A377 (MSB); if yes, e.g. mthr sword (+1), subtract the weapon bonus from $4A and store the result in $4A
(example: AC 7 => 02h; AC L0 => 13h)
3. substract class bonus (located in table $82B5 + class index) from $4A and store the result in $4A
(example: warrior with class bonus 2; AC 7 => 00h; AC L0 => 11h)
4. substract party bonus, which is stored in ZP $40, from $4A and store the result in $4A
(example: bard song 2 => group bonus +1; AC 7 => 00h; AC L0 => 0Ah)
5. add party malus (stored in ZP $DF) to $4A and store the resut in $4A
(example: not tested yet; maybe if party is affected by the spells FRFO, FEAR or CURS)
6. check if AC of monster ($4A) > 15h; if yes, set it to 15h; if not => next step
7. store this value in ZP $3B
(example: AC 7 => 00h; AC L0 => 0Ah)
8. create a random number by using jsr $18CE twice and add 03h to this random number; result is between 3 and 17 (decimal).
(example: 09h)
9. add character bonus (stored in table $82FA + character no) to the random number
(example: character is affected by BASK, which adds 04h; 09h + 04h => 0Dh)
10. compare this value (0Dh) with the AC of the monster; in our example, both, AC 7 (00h) and AC L0 (0Ah) are lower than 0Dh => hit; without BASK => 09h => only AC 7 is a hit and AC L0 is missed.

Just a short summary:
hit: if monster AC - item bonus - class bonus - group bonus + group malus < random no (3-17 dec) + character bonus

It's very interesting that there is no level bonus for the 'chance to hit'.
Weber G
Posts: 125
Joined: Tue Dec 15, 2020 9:58 am

Re: CBM64 Bard's Tale 1 Disassembly

Post by Weber G »

And here is the code of the monster 'chance to hit' from the C64 (Bard's Tale I):

Code: Select all

.C:5a92  A9 00       LDA #$00		;not needed for hit detection
.C:5a94  85 C8       STA $C8		;not needed for hit detection
.C:5a96  A5 44       LDA $44		;load no. of character which is attacked in A
.C:5a98  0A          ASL A		;double it due to 2 byte address
.C:5a99  AA          TAX		;transfer A to X
.C:5a9a  BD 8D 09    LDA $098D,X	;identify address of attacked character (LSB)
.C:5a9d  8D A9 5A    STA $5AA9		;and store it
.C:5aa0  BD 8E 09    LDA $098E,X	;identify address of attacked character (MSB)
.C:5aa3  8D AA 5A    STA $5AAA		;and store it
.C:5aa6  A0 3F       LDY #$3F		;load byte position of AC
.C:5aa8  B9 80 CB    LDA $CB80,Y	;load AC of character in A
.C:5aab  A6 47       LDX $47		;load monster group no. (0-3)		
.C:5aad  18          CLC
.C:5aae  7D 24 83    ADC $8324,X	;add monster group malus to A (e.g. the spell FEAR increase this value by 1)
.C:5ab1  C9 15       CMP #$15		;compare AC with 15h
.C:5ab3  90 02       BCC $5AB7		;if AC < 15h => jump
.C:5ab5  A9 15       LDA #$15		;set AC to 15h (max)
.C:5ab7  8D E2 5A    STA $5AE2		;and store it
.C:5aba  BC B0 03    LDY $03B0,X	;load monster type
.C:5abd  B9 28 7E    LDA $7E28,Y	;load attack value of monster type
.C:5ac0  29 1F       AND #$1F		;use only the 5 bits from the right
.C:5ac2  4A          LSR A		;half this value by moving the bits one position to the right
.C:5ac3  85 0B       STA $0B		;store value
.C:5ac5  20 CE 18    JSR $18CE		;create two random numbers between 00-FF and store them in $5A and $5B
.C:5ac8  A5 5A       LDA $5A		;load first random number in A
.C:5aca  29 07       AND #$07		;use only the 4 bits from the right (value: 0-7)		
.C:5acc  18          CLC		
.C:5acd  65 0B       ADC $0B		;add modified (in $5AC2) monster attack value to A
.C:5acf  85 0B       STA $0B		;store result in $0B
.C:5ad1  A5 5B       LDA $5B		;load 2nd random number in A
.C:5ad3  29 07       AND #$07		;use only the 4 bits from the right (value: 0-7)	
.C:5ad5  18          CLC
.C:5ad6  65 0B       ADC $0B		;add content of $0B to the result
.C:5ad8  A6 47       LDX $47		;load monster group no. (0-3)
.C:5ada  18          CLC
.C:5adb  7D 34 83    ADC $8334,X	;add monster group bonus to A (unclear; maybe if party is affected by FEAR or other spells)
.C:5ade  18          CLC
.C:5adf  69 02       ADC #$02		;add 2 to A; now the final attack value of the monster is in A		
.C:5ae1  C9 15       CMP #$15		;compare monster attack value with AC of character
.C:5ae3  B0 02       BCS $5AE7		;if monster attack value >= AC of character => HIT => jump
.C:5ae5  38          SEC
.C:5ae6  60          RTS		;if no HIT => return
And for Bard's Tale II (very similar):

Code: Select all

.C:a35f  A9 00       LDA #$00		;not needed for hit detection
.C:a361  85 C8       STA $C8		;not needed for hit detection
.C:a363  A5 44       LDA $44		;load no. of character which is attacked in A
.C:a365  0A          ASL A		;double it due to 2 byte address
.C:a366  AA          TAX		;transfer A to X
.C:a367  BD 8D AA    LDA $AA8D,X	;identify address of attacked character (LSB)
.C:a36a  8D 76 A3    STA $A376		;and store it
.C:a36d  BD 8E AA    LDA $AA8E,X	;identify address of attacked character (MSB)
.C:a370  8D 77 A3    STA $A377		;and store it
.C:a373  A0 3F       LDY #$3F		;load byte position of AC	
.C:a375  B9 00 B8    LDA $B800,Y	;load AC of character in A
.C:a378  A6 47       LDX $47		;load monster group no. (0-3)
.C:a37a  18          CLC
.C:a37b  7D 95 02    ADC $0295,X	;add monster group malus to A (e.g. the spell FEAR increase this value by 1)
.C:a37e  C9 1F       CMP #$1F		;compare AC with 1Fh
.C:a380  90 02       BCC $A384		;if AC < 1Fh => jump
.C:a382  A9 1F       LDA #$1F		;set AC to 1Fh (max)
.C:a384  8D AB A3    STA $A3AB		;and store it
.C:a387  20 02 09    JSR $0902		;set up address for monster type => $67 (LSB) $68 (MSB)
.C:a38a  A0 1D       LDY #$1D		;load byte position of monster type attack value
.C:a38c  B1 67       LDA ($67),Y	;load monster type attack value
.C:a38e  4A          LSR A		;half this value by moving the bits one position to the right
.C:a38f  85 97       STA $97		;store value
.C:a391  20 90 08    JSR $0890		;create two random numbers between 00-FF and store them in $5A and $5B
.C:a394  A5 5A       LDA $5A		;load first random number in A
.C:a396  29 07       AND #$07		;use only the 4 bits from the right (value: 0-7)
.C:a398  18          CLC
.C:a399  65 97       ADC $97		;add modified (in $A38E) monster attack value to A
.C:a39b  85 97       STA $97		;store result in $97
.C:a39d  A5 5B       LDA $5B		;load 2nd random number in A
.C:a39f  29 07       AND #$07		;use only the 4 bits from the right (value: 0-7)
.C:a3a1  18          CLC
.C:a3a2  65 97       ADC $97		;add content of $97 to the result
.C:a3a4  A6 47       LDX $47		;load monster group no. (0-3)
.C:a3a6  18          CLC
.C:a3a7  7D A5 02    ADC $02A5,X	;add monster group bonus to A (unclear; maybe if party is affected by FEAR or other spells)
.C:a3aa  C9 07       CMP #$07		;compare monster attack value with AC of character	
.C:a3ac  B0 02       BCS $A3B0		;if monster attack value >= AC of character => HIT => jump
.C:a3ae  38          SEC
.C:a3af  60          RTS		;if no HIT => return
User avatar
Darendor
Posts: 1502
Joined: Wed Jan 14, 2009 1:53 am
Location: Red Deer, Alberta, Canada

Re: CBM64 Bard's Tale 1 Disassembly

Post by Darendor »

You managed to disassemble BTII as well?
Weber G
Posts: 125
Joined: Tue Dec 15, 2020 9:58 am

Re: CBM64 Bard's Tale 1 Disassembly

Post by Weber G »

Only the parts I'm interested in => the melee attacks (including monster- and item tables).

I was always a bit frustrated with the high (or low) monster ACs. But now I know how to hit them :D
Post Reply