CBM64 Bard's Tale 1 Disassembly

Any developer realated stuff
Weber G
Posts: 125
Joined: Tue Dec 15, 2020 9:58 am

Re: CBM64 Bard's Tale 1 Disassembly

Post by Weber G »

The initiative (or who strikes first) calculation for Bard's Tale I (C64):

Code: Select all

;character initiative ###
.C:5421  A9 01       LDA #$01		;start with 1st character
.C:5423  85 0D       STA $0D		;store character no. in $0D
.C:5425  A5 0D       LDA $0D		;load character no. in A
.C:5427  0A          ASL A		;double A by moving bit positions to the left
.C:5428  AA          TAX		;transfer A to X
.C:5429  BD 8D 09    LDA $098D,X	;load character address (LSB)
.C:542c  85 50       STA $50		;store it
.C:542e  BD 8E 09    LDA $098E,X	;load character address (MSB)
.C:5431  85 51       STA $51		;store it
.C:5433  A0 00       LDY #$00		;set y to byte 0 of character
.C:5435  B1 50       LDA ($50),Y	;load first letter of character
.C:5437  D0 03       BNE $543C		;if first letter of character > 0 => jump
.C:5439  4C D4 54    JMP $54D4		;else jump to slot S initiative creation
.C:543c  20 CE 18    JSR $18CE		;create two random numbers between 00-FF and store them in $5A and $5B
.C:543f  A0 3C       LDY #$3C		;set y to byte 3C of character
.C:5441  B1 50       LDA ($50),Y	;load MSB of number of won combats
.C:5443  4A          LSR A		;half A by moving bit positions to the right
.C:5444  85 3B       STA $3B		;store it in $3B
.C:5446  A0 11       LDY #$11		;set y to byte 11h of character
.C:5448  B1 50       LDA ($50),Y	;load attributes (the byte which includes dex)
.C:544a  29 1F       AND #$1F		;AND with 1F (only the 5 bits from the right can be 1)
.C:544c  38          SEC		
.C:544d  E9 0E       SBC #$0E		;substract 0E => dex18=>4;dex17=>3;dex16=>2;dex15=1
.C:544f  90 0A       BCC $545B		;if result <= 0 (no bonus) => jump
.C:5451  0A          ASL A		;shift A left
.C:5452  0A          ASL A		;shift A left
.C:5453  0A          ASL A		;shift A left => dex bonus: dex18=>20h;dex17=>18h;dex16=>10h;dex15=>8h
.C:5454  18          CLC
.C:5455  65 3B       ADC $3B		;add initiative value ($5444) to A (dex bonus)
.C:5457  B0 63       BCS $54BC		;if > FF (max initiative reached) => jump
.C:5459  85 3B       STA $3B		;store result
.C:545b  A5 5B       LDA $5B		;load random number ($543C) in A
.C:545d  29 1F       AND #$1F		;use only the 5 bits from the right (value: 0-31)
.C:545f  18          CLC
.C:5460  65 3B       ADC $3B		;add initiative value ($5455) to A (random number)
.C:5462  B0 58       BCS $54BC		;if > FF (max initiative reached) => jump
.C:5464  85 3B       STA $3B		;store result
.C:5466  A0 22       LDY #$22		;set y to byte 22h of character		
.C:5468  B1 50       LDA ($50),Y	;load MSB of current character level
.C:546a  85 64       STA $64		;store it
.C:546c  C8          INY		;set y to byte 23h of character
.C:546d  B1 50       LDA ($50),Y	;load LSB of current character level
.C:546f  46 64       LSR $64		;shift A bitwise right
.C:5471  6A          ROR A		;rotate A
.C:5472  85 63       STA $63		;store it
.C:5474  A5 64       LDA $64		;load MSB of current character level in A
.C:5476  F0 08       BEQ $5480		;if A = 0 (character level < 256) => jump
.C:5478  A9 00       LDA #$00		;0 => A
.C:547a  85 64       STA $64		;set MSB of current level to 0
.C:547c  A9 40       LDA #$40		;40h (64dec) => A (load max level for bonus to A)
.C:547e  85 63       STA $63		;store max level for bonus in LSB current character level
.C:5480  A5 63       LDA $63		;load LSB of current character level 
.C:5482  C9 41       CMP #$41		;compare it with 41h (65dec)
.C:5484  90 04       BCC $548A		;if LSB of current character level < 41h (65dec) => jump
.C:5486  A9 40       LDA #$40		;else: set LSB of current character level to 40h (64dec)
.C:5488  85 63       STA $63		;store it
.C:548a  A0 38       LDY #$38		;set y to byte 38h of character
.C:548c  B1 50       LDA ($50),Y	;load class of character
.C:548e  F0 1A       BEQ $54AA		;if class = 0 (warrior) => jump
.C:5490  C9 07       CMP #$07		;compare character class with 07h
.C:5492  F0 16       BEQ $54AA		;if class = 7 (paladin) => jump
.C:5494  C9 08       CMP #$08		;compare character class with 08h
.C:5496  F0 12       BEQ $54AA		;if class = 8 (hunter) => jump
.C:5498  C9 05       CMP #$05		;compare character class with 05h
.C:549a  90 13       BCC $54AF		;if class < 5 (conjuror, magician, sorcerer, wizard) => jump
.C:549c  C9 09       CMP #$09		;compare character class with 09h
.C:549e  D0 16       BNE $54B6		;if class <> 9 (no monk) => jump
.C:54a0  A5 63       LDA $63		;load current character level (LSB; max = 64)
.C:54a2  0A          ASL A		;double it (level/class bonus monk => 2*level)
.C:54a3  18          CLC
.C:54a4  65 3B       ADC $3B		;add initiative value ($5460) to A (level/class bonus)
.C:54a6  B0 14       BCS $54BC		;if > FF (max initiative reached) => jump
.C:54a8  90 14       BCC $54BE		;else (max initiative not reached) => jump
.C:54aa  A5 63       LDA $63		;load current character level (LSB; max = 64; level/class bonus warrior/paladin/hunter => level)
.C:54ac  4C A3 54    JMP $54A3		;=> jump
.C:54af  A5 63       LDA $63		;load current character level (LSB; max = 64)
.C:54b1  4A          LSR A		;half it
.C:54b2  4A          LSR A		;half if (level/class bonus conjuror/magician/sorcerer/wizard => level/4)
.C:54b3  4C A3 54    JMP $54A3		;=> jump
.C:54b6  A5 63       LDA $63		;load current character level (LSB; max = 64)
.C:54b8  4A          LSR A		;half it (level/class bonus bard/rouge => level/2)
.C:54b9  4C A3 54    JMP $54A3		;=> jump
.C:54bc  A9 FF       LDA #$FF		;if max bonus was reached: FF => A
.C:54be  A6 0D       LDX $0D		;character no. => X
.C:54c0  C9 00       CMP #$00		;compare A with 0
.C:54c2  D0 02       BNE $54C6		;if A not 0 (if initiative not 0) => jump
.C:54c4  A9 01       LDA #$01		;if initiative = 0: 01 (min initiative) => A
.C:54c6  9D 0F 83    STA $830F,X	;store character initiative in table (1-6) [finished for this character]
.C:54c9  E6 0D       INC $0D		;increase $0D by 1 (next character)
.C:54cb  A5 0D       LDA $0D		;load next character no.
.C:54cd  C9 07       CMP #$07		;compare with 7
.C:54cf  B0 03       BCS $54D4		;if character no. = 7 [finished for all characters] => jump
.C:54d1  4C 25 54    JMP $5425		;else: calculate initiative for next character
;slot S initiative ###
.C:54d4  20 CE 18    JSR $18CE		;create two random numbers between 00-FF and store them in $5A and $5B		
.C:54d7  AD 00 CB    LDA $CB00		;load first letter of solt S
.C:54da  F0 18       BEQ $54F4		;if first letter of character = 0 (slot S is empty) => jump
.C:54dc  AD 15 CB    LDA $CB15		;load attack value of monster
.C:54df  29 1F       AND #$1F		;use only the 5 bits from the right
.C:54e1  0A          ASL A		;double it
.C:54e2  0A          ASL A		;double it
.C:54e3  8D EC 54    STA $54EC		;store it
.C:54e6  A5 5A       LDA $5A		;load random number in A
.C:54e8  29 1F       AND #$1F		;use only the 5 bits from the right (value: 0-31)
.C:54ea  18          CLC
.C:54eb  69 00       ADC #$00		;add modified attack value ($54E3) to the random number
.C:54ed  90 02       BCC $54F1		;if A <= FF (max initiative not reached) => jump	
.C:54ef  A9 FF       LDA #$FF		;if max initiative was reached: FF => A
.C:54f1  8D 0F 83    STA $830F		;store slot S initiative [finished]
;monster initiative ###
.C:54f4  A9 00       LDA #$00		;set monster group (0-3) to 0	
.C:54f6  85 0D       STA $0D		;store it
.C:54f8  A6 0D       LDX $0D		;load monster group => X
.C:54fa  BC B0 03    LDY $03B0,X	;load monster type => Y	
.C:54fd  F0 32       BEQ $5531		;if Y = 0 (no monster in this group) => jump		
.C:54ff  B9 28 7E    LDA $7E28,Y	;load attack value of monster
.C:5502  29 1F       AND #$1F		;use only the 5 bits from the right
.C:5504  0A          ASL A		;double it
.C:5505  0A          ASL A		;double it
.C:5506  8D 24 55    STA $5524		;store it
.C:5509  BD D3 7C    LDA $7CD3,X	;load monster address (LSB)
.C:550c  8D 2D 55    STA $552D		;store it
.C:550f  BD D7 7C    LDA $7CD7,X	;load monster address (MSB)
.C:5512  8D 2C 55    STA $552C		;store it
.C:5515  BC B8 03    LDY $03B8,X	;load number of monsters in group	
.C:5518  F0 17       BEQ $5531		;if Y = 0 (no monsters in this group) => jump
.C:551a  88          DEY		;decrease number of monsters in group by 1
.C:551b  20 CE 18    JSR $18CE		;create two random numbers between 00-FF and store them in $5A and $5B		
.C:551e  A5 5A       LDA $5A		;load random number in A
.C:5520  29 1F       AND #$1F		;use only the 5 bits from the right (value: 0-31)	
.C:5522  18          CLC
.C:5523  69 00       ADC #$00		;add modified attack value ($5506) to the random number
.C:5525  90 02       BCC $5529		;if A <= FF (max initiative not reached) => jump		
.C:5527  A9 FF       LDA #$FF		;if max initiative was reached: FF => A
.C:5529  09 01       ORA #$01		;OR A with 1 => set initiative to a minimum of 1 if it was below	
.C:552b  99 00 20    STA $2000,Y	;store monster initiative in address which was created ($550C and $5512)
.C:552e  88          DEY		;decrease number of monsters in group by 1
.C:552f  10 EA       BPL $551B		;if Y > 0 (more monsters in group) => jump
.C:5531  A5 0D       LDA $0D		;else: load monster group in A
.C:5533  C9 04       CMP #$04		;compare A with 4
.C:5535  B0 08       BCS $553F		;if A >= 4 (last monster group was reached) => jump
.C:5537  C5 3A       CMP $3A		;compare A with # of monster groups (0-3)
.C:5539  B0 04       BCS $553F		;if A >= # of monster groups => jump
.C:553b  E6 0D       INC $0D		;increase monster group by 1 (next one)
.C:553d  D0 B9       BNE $54F8		;if content of $0D <> 0 => jump
.C:553f  60          RTS		;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 »

I was obsessed for a while on disassembling BTII in its entirety for the sake of making a BTCS for the C64 version. Sadly I'm too stupid to figure it all out. :?
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 »

Weber G wrote: Wed Dec 16, 2020 1:23 pm The initiative (or who strikes first) calculation for Bard's Tale I (C64):

Code: Select all

;character initiative ###
.C:5421  A9 01       LDA #$01		;start with 1st character
.C:5423  85 0D       STA $0D		;store character no. in $0D
.C:5425  A5 0D       LDA $0D		;load character no. in A
.C:5427  0A          ASL A		;double A by moving bit positions to the left
.C:5428  AA          TAX		;transfer A to X
.C:5429  BD 8D 09    LDA $098D,X	;load character address (LSB)
.C:542c  85 50       STA $50		;store it
.C:542e  BD 8E 09    LDA $098E,X	;load character address (MSB)
.C:5431  85 51       STA $51		;store it
.C:5433  A0 00       LDY #$00		;set y to byte 0 of character
.C:5435  B1 50       LDA ($50),Y	;load first letter of character
.C:5437  D0 03       BNE $543C		;if first letter of character > 0 => jump
.C:5439  4C D4 54    JMP $54D4		;else jump to slot S initiative creation
.C:543c  20 CE 18    JSR $18CE		;create two random numbers between 00-FF and store them in $5A and $5B
.C:543f  A0 3C       LDY #$3C		;set y to byte 3C of character
.C:5441  B1 50       LDA ($50),Y	;load MSB of number of won combats
.C:5443  4A          LSR A		;half A by moving bit positions to the right
.C:5444  85 3B       STA $3B		;store it in $3B
.C:5446  A0 11       LDY #$11		;set y to byte 11h of character
.C:5448  B1 50       LDA ($50),Y	;load attributes (the byte which includes dex)
.C:544a  29 1F       AND #$1F		;AND with 1F (only the 5 bits from the right can be 1)
.C:544c  38          SEC		
.C:544d  E9 0E       SBC #$0E		;substract 0E => dex18=>4;dex17=>3;dex16=>2;dex15=1
.C:544f  90 0A       BCC $545B		;if result <= 0 (no bonus) => jump
.C:5451  0A          ASL A		;shift A left
.C:5452  0A          ASL A		;shift A left
.C:5453  0A          ASL A		;shift A left => dex bonus: dex18=>20h;dex17=>18h;dex16=>10h;dex15=>8h
.C:5454  18          CLC
.C:5455  65 3B       ADC $3B		;add initiative value ($5444) to A (dex bonus)
.C:5457  B0 63       BCS $54BC		;if > FF (max initiative reached) => jump
.C:5459  85 3B       STA $3B		;store result
.C:545b  A5 5B       LDA $5B		;load random number ($543C) in A
.C:545d  29 1F       AND #$1F		;use only the 5 bits from the right (value: 0-31)
.C:545f  18          CLC
.C:5460  65 3B       ADC $3B		;add initiative value ($5455) to A (random number)
.C:5462  B0 58       BCS $54BC		;if > FF (max initiative reached) => jump
.C:5464  85 3B       STA $3B		;store result
.C:5466  A0 22       LDY #$22		;set y to byte 22h of character		
.C:5468  B1 50       LDA ($50),Y	;load MSB of current character level
.C:546a  85 64       STA $64		;store it
.C:546c  C8          INY		;set y to byte 23h of character
.C:546d  B1 50       LDA ($50),Y	;load LSB of current character level
.C:546f  46 64       LSR $64		;shift A bitwise right
.C:5471  6A          ROR A		;rotate A
.C:5472  85 63       STA $63		;store it
.C:5474  A5 64       LDA $64		;load MSB of current character level in A
.C:5476  F0 08       BEQ $5480		;if A = 0 (character level < 256) => jump
.C:5478  A9 00       LDA #$00		;0 => A
.C:547a  85 64       STA $64		;set MSB of current level to 0
.C:547c  A9 40       LDA #$40		;40h (64dec) => A (load max level for bonus to A)
.C:547e  85 63       STA $63		;store max level for bonus in LSB current character level
.C:5480  A5 63       LDA $63		;load LSB of current character level 
.C:5482  C9 41       CMP #$41		;compare it with 41h (65dec)
.C:5484  90 04       BCC $548A		;if LSB of current character level < 41h (65dec) => jump
.C:5486  A9 40       LDA #$40		;else: set LSB of current character level to 40h (64dec)
.C:5488  85 63       STA $63		;store it
.C:548a  A0 38       LDY #$38		;set y to byte 38h of character
.C:548c  B1 50       LDA ($50),Y	;load class of character
.C:548e  F0 1A       BEQ $54AA		;if class = 0 (warrior) => jump
.C:5490  C9 07       CMP #$07		;compare character class with 07h
.C:5492  F0 16       BEQ $54AA		;if class = 7 (paladin) => jump
.C:5494  C9 08       CMP #$08		;compare character class with 08h
.C:5496  F0 12       BEQ $54AA		;if class = 8 (hunter) => jump
.C:5498  C9 05       CMP #$05		;compare character class with 05h
.C:549a  90 13       BCC $54AF		;if class < 5 (conjuror, magician, sorcerer, wizard) => jump
.C:549c  C9 09       CMP #$09		;compare character class with 09h
.C:549e  D0 16       BNE $54B6		;if class <> 9 (no monk) => jump
.C:54a0  A5 63       LDA $63		;load current character level (LSB; max = 64)
.C:54a2  0A          ASL A		;double it (level/class bonus monk => 2*level)
.C:54a3  18          CLC
.C:54a4  65 3B       ADC $3B		;add initiative value ($5460) to A (level/class bonus)
.C:54a6  B0 14       BCS $54BC		;if > FF (max initiative reached) => jump
.C:54a8  90 14       BCC $54BE		;else (max initiative not reached) => jump
.C:54aa  A5 63       LDA $63		;load current character level (LSB; max = 64; level/class bonus warrior/paladin/hunter => level)
.C:54ac  4C A3 54    JMP $54A3		;=> jump
.C:54af  A5 63       LDA $63		;load current character level (LSB; max = 64)
.C:54b1  4A          LSR A		;half it
.C:54b2  4A          LSR A		;half if (level/class bonus conjuror/magician/sorcerer/wizard => level/4)
.C:54b3  4C A3 54    JMP $54A3		;=> jump
.C:54b6  A5 63       LDA $63		;load current character level (LSB; max = 64)
.C:54b8  4A          LSR A		;half it (level/class bonus bard/rouge => level/2)
.C:54b9  4C A3 54    JMP $54A3		;=> jump
.C:54bc  A9 FF       LDA #$FF		;if max bonus was reached: FF => A
.C:54be  A6 0D       LDX $0D		;character no. => X
.C:54c0  C9 00       CMP #$00		;compare A with 0
.C:54c2  D0 02       BNE $54C6		;if A not 0 (if initiative not 0) => jump
.C:54c4  A9 01       LDA #$01		;if initiative = 0: 01 (min initiative) => A
.C:54c6  9D 0F 83    STA $830F,X	;store character initiative in table (1-6) [finished for this character]
.C:54c9  E6 0D       INC $0D		;increase $0D by 1 (next character)
.C:54cb  A5 0D       LDA $0D		;load next character no.
.C:54cd  C9 07       CMP #$07		;compare with 7
.C:54cf  B0 03       BCS $54D4		;if character no. = 7 [finished for all characters] => jump
.C:54d1  4C 25 54    JMP $5425		;else: calculate initiative for next character
;slot S initiative ###
.C:54d4  20 CE 18    JSR $18CE		;create two random numbers between 00-FF and store them in $5A and $5B		
.C:54d7  AD 00 CB    LDA $CB00		;load first letter of solt S
.C:54da  F0 18       BEQ $54F4		;if first letter of character = 0 (slot S is empty) => jump
.C:54dc  AD 15 CB    LDA $CB15		;load attack value of monster
.C:54df  29 1F       AND #$1F		;use only the 5 bits from the right
.C:54e1  0A          ASL A		;double it
.C:54e2  0A          ASL A		;double it
.C:54e3  8D EC 54    STA $54EC		;store it
.C:54e6  A5 5A       LDA $5A		;load random number in A
.C:54e8  29 1F       AND #$1F		;use only the 5 bits from the right (value: 0-31)
.C:54ea  18          CLC
.C:54eb  69 00       ADC #$00		;add modified attack value ($54E3) to the random number
.C:54ed  90 02       BCC $54F1		;if A <= FF (max initiative not reached) => jump	
.C:54ef  A9 FF       LDA #$FF		;if max initiative was reached: FF => A
.C:54f1  8D 0F 83    STA $830F		;store slot S initiative [finished]
;monster initiative ###
.C:54f4  A9 00       LDA #$00		;set monster group (0-3) to 0	
.C:54f6  85 0D       STA $0D		;store it
.C:54f8  A6 0D       LDX $0D		;load monster group => X
.C:54fa  BC B0 03    LDY $03B0,X	;load monster type => Y	
.C:54fd  F0 32       BEQ $5531		;if Y = 0 (no monster in this group) => jump		
.C:54ff  B9 28 7E    LDA $7E28,Y	;load attack value of monster
.C:5502  29 1F       AND #$1F		;use only the 5 bits from the right
.C:5504  0A          ASL A		;double it
.C:5505  0A          ASL A		;double it
.C:5506  8D 24 55    STA $5524		;store it
.C:5509  BD D3 7C    LDA $7CD3,X	;load monster address (LSB)
.C:550c  8D 2D 55    STA $552D		;store it
.C:550f  BD D7 7C    LDA $7CD7,X	;load monster address (MSB)
.C:5512  8D 2C 55    STA $552C		;store it
.C:5515  BC B8 03    LDY $03B8,X	;load number of monsters in group	
.C:5518  F0 17       BEQ $5531		;if Y = 0 (no monsters in this group) => jump
.C:551a  88          DEY		;decrease number of monsters in group by 1
.C:551b  20 CE 18    JSR $18CE		;create two random numbers between 00-FF and store them in $5A and $5B		
.C:551e  A5 5A       LDA $5A		;load random number in A
.C:5520  29 1F       AND #$1F		;use only the 5 bits from the right (value: 0-31)	
.C:5522  18          CLC
.C:5523  69 00       ADC #$00		;add modified attack value ($5506) to the random number
.C:5525  90 02       BCC $5529		;if A <= FF (max initiative not reached) => jump		
.C:5527  A9 FF       LDA #$FF		;if max initiative was reached: FF => A
.C:5529  09 01       ORA #$01		;OR A with 1 => set initiative to a minimum of 1 if it was below	
.C:552b  99 00 20    STA $2000,Y	;store monster initiative in address which was created ($550C and $5512)
.C:552e  88          DEY		;decrease number of monsters in group by 1
.C:552f  10 EA       BPL $551B		;if Y > 0 (more monsters in group) => jump
.C:5531  A5 0D       LDA $0D		;else: load monster group in A
.C:5533  C9 04       CMP #$04		;compare A with 4
.C:5535  B0 08       BCS $553F		;if A >= 4 (last monster group was reached) => jump
.C:5537  C5 3A       CMP $3A		;compare A with # of monster groups (0-3)
.C:5539  B0 04       BCS $553F		;if A >= # of monster groups => jump
.C:553b  E6 0D       INC $0D		;increase monster group by 1 (next one)
.C:553d  D0 B9       BNE $54F8		;if content of $0D <> 0 => jump
.C:553f  60          RTS		;return
What does the "h" mean in your notes; e.g. 07h, 20h, and so on?
drifting
Posts: 152
Joined: Wed Dec 07, 2011 10:21 pm

Re: CBM64 Bard's Tale 1 Disassembly

Post by drifting »

Darendor wrote: Sat Dec 19, 2020 2:28 am
Weber G wrote: Wed Dec 16, 2020 1:23 pm The initiative (or who strikes first) calculation for Bard's Tale I (C64):

Code: Select all

;character initiative ###
.C:5421  A9 01       LDA #$01		;start with 1st character
.C:5423  85 0D       STA $0D		;store character no. in $0D
.C:5425  A5 0D       LDA $0D		;load character no. in A
.C:5427  0A          ASL A		;double A by moving bit positions to the left
.C:5428  AA          TAX		;transfer A to X
.C:5429  BD 8D 09    LDA $098D,X	;load character address (LSB)
.C:542c  85 50       STA $50		;store it
.C:542e  BD 8E 09    LDA $098E,X	;load character address (MSB)
.C:5431  85 51       STA $51		;store it
.C:5433  A0 00       LDY #$00		;set y to byte 0 of character
.C:5435  B1 50       LDA ($50),Y	;load first letter of character
.C:5437  D0 03       BNE $543C		;if first letter of character > 0 => jump
.C:5439  4C D4 54    JMP $54D4		;else jump to slot S initiative creation
.C:543c  20 CE 18    JSR $18CE		;create two random numbers between 00-FF and store them in $5A and $5B
.C:543f  A0 3C       LDY #$3C		;set y to byte 3C of character
.C:5441  B1 50       LDA ($50),Y	;load MSB of number of won combats
.C:5443  4A          LSR A		;half A by moving bit positions to the right
.C:5444  85 3B       STA $3B		;store it in $3B
.C:5446  A0 11       LDY #$11		;set y to byte 11h of character
.C:5448  B1 50       LDA ($50),Y	;load attributes (the byte which includes dex)
.C:544a  29 1F       AND #$1F		;AND with 1F (only the 5 bits from the right can be 1)
.C:544c  38          SEC		
.C:544d  E9 0E       SBC #$0E		;substract 0E => dex18=>4;dex17=>3;dex16=>2;dex15=1
.C:544f  90 0A       BCC $545B		;if result <= 0 (no bonus) => jump
.C:5451  0A          ASL A		;shift A left
.C:5452  0A          ASL A		;shift A left
.C:5453  0A          ASL A		;shift A left => dex bonus: dex18=>20h;dex17=>18h;dex16=>10h;dex15=>8h
.C:5454  18          CLC
.C:5455  65 3B       ADC $3B		;add initiative value ($5444) to A (dex bonus)
.C:5457  B0 63       BCS $54BC		;if > FF (max initiative reached) => jump
.C:5459  85 3B       STA $3B		;store result
.C:545b  A5 5B       LDA $5B		;load random number ($543C) in A
.C:545d  29 1F       AND #$1F		;use only the 5 bits from the right (value: 0-31)
.C:545f  18          CLC
.C:5460  65 3B       ADC $3B		;add initiative value ($5455) to A (random number)
.C:5462  B0 58       BCS $54BC		;if > FF (max initiative reached) => jump
.C:5464  85 3B       STA $3B		;store result
.C:5466  A0 22       LDY #$22		;set y to byte 22h of character		
.C:5468  B1 50       LDA ($50),Y	;load MSB of current character level
.C:546a  85 64       STA $64		;store it
.C:546c  C8          INY		;set y to byte 23h of character
.C:546d  B1 50       LDA ($50),Y	;load LSB of current character level
.C:546f  46 64       LSR $64		;shift A bitwise right
.C:5471  6A          ROR A		;rotate A
.C:5472  85 63       STA $63		;store it
.C:5474  A5 64       LDA $64		;load MSB of current character level in A
.C:5476  F0 08       BEQ $5480		;if A = 0 (character level < 256) => jump
.C:5478  A9 00       LDA #$00		;0 => A
.C:547a  85 64       STA $64		;set MSB of current level to 0
.C:547c  A9 40       LDA #$40		;40h (64dec) => A (load max level for bonus to A)
.C:547e  85 63       STA $63		;store max level for bonus in LSB current character level
.C:5480  A5 63       LDA $63		;load LSB of current character level 
.C:5482  C9 41       CMP #$41		;compare it with 41h (65dec)
.C:5484  90 04       BCC $548A		;if LSB of current character level < 41h (65dec) => jump
.C:5486  A9 40       LDA #$40		;else: set LSB of current character level to 40h (64dec)
.C:5488  85 63       STA $63		;store it
.C:548a  A0 38       LDY #$38		;set y to byte 38h of character
.C:548c  B1 50       LDA ($50),Y	;load class of character
.C:548e  F0 1A       BEQ $54AA		;if class = 0 (warrior) => jump
.C:5490  C9 07       CMP #$07		;compare character class with 07h
.C:5492  F0 16       BEQ $54AA		;if class = 7 (paladin) => jump
.C:5494  C9 08       CMP #$08		;compare character class with 08h
.C:5496  F0 12       BEQ $54AA		;if class = 8 (hunter) => jump
.C:5498  C9 05       CMP #$05		;compare character class with 05h
.C:549a  90 13       BCC $54AF		;if class < 5 (conjuror, magician, sorcerer, wizard) => jump
.C:549c  C9 09       CMP #$09		;compare character class with 09h
.C:549e  D0 16       BNE $54B6		;if class <> 9 (no monk) => jump
.C:54a0  A5 63       LDA $63		;load current character level (LSB; max = 64)
.C:54a2  0A          ASL A		;double it (level/class bonus monk => 2*level)
.C:54a3  18          CLC
.C:54a4  65 3B       ADC $3B		;add initiative value ($5460) to A (level/class bonus)
.C:54a6  B0 14       BCS $54BC		;if > FF (max initiative reached) => jump
.C:54a8  90 14       BCC $54BE		;else (max initiative not reached) => jump
.C:54aa  A5 63       LDA $63		;load current character level (LSB; max = 64; level/class bonus warrior/paladin/hunter => level)
.C:54ac  4C A3 54    JMP $54A3		;=> jump
.C:54af  A5 63       LDA $63		;load current character level (LSB; max = 64)
.C:54b1  4A          LSR A		;half it
.C:54b2  4A          LSR A		;half if (level/class bonus conjuror/magician/sorcerer/wizard => level/4)
.C:54b3  4C A3 54    JMP $54A3		;=> jump
.C:54b6  A5 63       LDA $63		;load current character level (LSB; max = 64)
.C:54b8  4A          LSR A		;half it (level/class bonus bard/rouge => level/2)
.C:54b9  4C A3 54    JMP $54A3		;=> jump
.C:54bc  A9 FF       LDA #$FF		;if max bonus was reached: FF => A
.C:54be  A6 0D       LDX $0D		;character no. => X
.C:54c0  C9 00       CMP #$00		;compare A with 0
.C:54c2  D0 02       BNE $54C6		;if A not 0 (if initiative not 0) => jump
.C:54c4  A9 01       LDA #$01		;if initiative = 0: 01 (min initiative) => A
.C:54c6  9D 0F 83    STA $830F,X	;store character initiative in table (1-6) [finished for this character]
.C:54c9  E6 0D       INC $0D		;increase $0D by 1 (next character)
.C:54cb  A5 0D       LDA $0D		;load next character no.
.C:54cd  C9 07       CMP #$07		;compare with 7
.C:54cf  B0 03       BCS $54D4		;if character no. = 7 [finished for all characters] => jump
.C:54d1  4C 25 54    JMP $5425		;else: calculate initiative for next character
;slot S initiative ###
.C:54d4  20 CE 18    JSR $18CE		;create two random numbers between 00-FF and store them in $5A and $5B		
.C:54d7  AD 00 CB    LDA $CB00		;load first letter of solt S
.C:54da  F0 18       BEQ $54F4		;if first letter of character = 0 (slot S is empty) => jump
.C:54dc  AD 15 CB    LDA $CB15		;load attack value of monster
.C:54df  29 1F       AND #$1F		;use only the 5 bits from the right
.C:54e1  0A          ASL A		;double it
.C:54e2  0A          ASL A		;double it
.C:54e3  8D EC 54    STA $54EC		;store it
.C:54e6  A5 5A       LDA $5A		;load random number in A
.C:54e8  29 1F       AND #$1F		;use only the 5 bits from the right (value: 0-31)
.C:54ea  18          CLC
.C:54eb  69 00       ADC #$00		;add modified attack value ($54E3) to the random number
.C:54ed  90 02       BCC $54F1		;if A <= FF (max initiative not reached) => jump	
.C:54ef  A9 FF       LDA #$FF		;if max initiative was reached: FF => A
.C:54f1  8D 0F 83    STA $830F		;store slot S initiative [finished]
;monster initiative ###
.C:54f4  A9 00       LDA #$00		;set monster group (0-3) to 0	
.C:54f6  85 0D       STA $0D		;store it
.C:54f8  A6 0D       LDX $0D		;load monster group => X
.C:54fa  BC B0 03    LDY $03B0,X	;load monster type => Y	
.C:54fd  F0 32       BEQ $5531		;if Y = 0 (no monster in this group) => jump		
.C:54ff  B9 28 7E    LDA $7E28,Y	;load attack value of monster
.C:5502  29 1F       AND #$1F		;use only the 5 bits from the right
.C:5504  0A          ASL A		;double it
.C:5505  0A          ASL A		;double it
.C:5506  8D 24 55    STA $5524		;store it
.C:5509  BD D3 7C    LDA $7CD3,X	;load monster address (LSB)
.C:550c  8D 2D 55    STA $552D		;store it
.C:550f  BD D7 7C    LDA $7CD7,X	;load monster address (MSB)
.C:5512  8D 2C 55    STA $552C		;store it
.C:5515  BC B8 03    LDY $03B8,X	;load number of monsters in group	
.C:5518  F0 17       BEQ $5531		;if Y = 0 (no monsters in this group) => jump
.C:551a  88          DEY		;decrease number of monsters in group by 1
.C:551b  20 CE 18    JSR $18CE		;create two random numbers between 00-FF and store them in $5A and $5B		
.C:551e  A5 5A       LDA $5A		;load random number in A
.C:5520  29 1F       AND #$1F		;use only the 5 bits from the right (value: 0-31)	
.C:5522  18          CLC
.C:5523  69 00       ADC #$00		;add modified attack value ($5506) to the random number
.C:5525  90 02       BCC $5529		;if A <= FF (max initiative not reached) => jump		
.C:5527  A9 FF       LDA #$FF		;if max initiative was reached: FF => A
.C:5529  09 01       ORA #$01		;OR A with 1 => set initiative to a minimum of 1 if it was below	
.C:552b  99 00 20    STA $2000,Y	;store monster initiative in address which was created ($550C and $5512)
.C:552e  88          DEY		;decrease number of monsters in group by 1
.C:552f  10 EA       BPL $551B		;if Y > 0 (more monsters in group) => jump
.C:5531  A5 0D       LDA $0D		;else: load monster group in A
.C:5533  C9 04       CMP #$04		;compare A with 4
.C:5535  B0 08       BCS $553F		;if A >= 4 (last monster group was reached) => jump
.C:5537  C5 3A       CMP $3A		;compare A with # of monster groups (0-3)
.C:5539  B0 04       BCS $553F		;if A >= # of monster groups => jump
.C:553b  E6 0D       INC $0D		;increase monster group by 1 (next one)
.C:553d  D0 B9       BNE $54F8		;if content of $0D <> 0 => jump
.C:553f  60          RTS		;return
What does the "h" mean in your notes; e.g. 07h, 20h, and so on?
Hexadecimal
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 »

Oh.

Trying to follow through that sample of coding made my ears bleed. :?
Weber G
Posts: 125
Joined: Tue Dec 15, 2020 9:58 am

Re: CBM64 Bard's Tale 1 Disassembly

Post by Weber G »

Correct. It's the value in hex.

The initiative for Bard's Tale I (C64) in short (decimal):

The value for each combatant is 1-255. The higher the better (strikes earlier in the combat phase).

Characters:
= won combats (0-765=>0;767-1278=>1;1279-1790=>2;1791-2302=>3;...)
+ dexterity (15=>+8;16=>+16;17=>+24;18=>+32)
+ random number (0-31)
+ class/level (mages:+level/4;bard/rouge:+level/2;warrior/paladin/hunter:+level;monk:+level*2)
max considered level is 64; for levels above 64 you get only the bonus for level 64 (level64 bonus: mages=>16;bard/rogue=>32;warrior/paladin/hunter=>64;monk=>128)

e.g.: a level 20 warrior with 2000 won combats and dex 18 has the following initiative:
3 + 32 + 20 + (0-31) => 55 - 86

slot S:
= initiative value (stored in $CB15 => AND with 1F => 2x biswise shift left)
+ random number (0-31)

e.g.: wolf: initiative value (12) + (0-31) => 12 - 43
e.g.: demon: initiative value (80) + (0-31) => 80 - 111

monsters:
works in the same way as for slot S
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 »

Mind = blown.
DMan
Posts: 19
Joined: Mon May 14, 2012 12:06 am

Re: CBM64 Bard's Tale 1 Disassembly

Post by DMan »

Does anyone have the data values for the spell effects table (not the spell point cost or spell code names)? I’m assuming there’s a table (or tables) for attributes such as range, effect, combat/non-combat and self/party. Trawled through all of these Dev threads and can’t find reference to it.

I’m currently involved with disassembling the ZX Spectrum version of BT. These threads have been extremely useful in identifying most of the data - same data values, just (in a lot of cases) partially packed in the ZX source code.
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 »

Once upon a time I trawled through and found the spell names and cost values, but I kind of gave up. I imagine the other data was right there staring at me.

I remember editing the game memory so ZZGO cost 0 spell points. That was fun.
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 »

So I found my notes about the spells in BTII, and I found what appears to be a data field immediately after the spell names and level.

The first 4 spells in the list are MAFL, ARFI, TRZP, and FRFO. Knowing what those 4 spells are and do will help decipher the code, since it stands to reason that the data is sequentially listed in the same way.

Code: Select all

.C:7af3  D1 4C       CMP ($4C),Y
.C:7af5  8E 4D 20    STX $204D
.C:7af8  5E 5C 5D    LSR $5D5C,X
.C:7afb  33 5B       RLA ($5B),Y
.C:7afd  4B 56       ASR #$56
.C:7aff  D1 4C       CMP ($4C),Y
.C:7b01  FD 5A C8    SBC $C85A,X
.C:7b04  57 B9       SRE $B9,X
.C:7b06  52          JAM
.C:7b07  4B 56       ASR #$56
.C:7b09  D1 4C       CMP ($4C),Y
.C:7b0b  C8          INY
.C:7b0c  57 B9       SRE $B9,X
.C:7b0e  52          JAM
.C:7b0f  FD 5A 4B    SBC $4B5A,X
.C:7b12  56 AC       LSR $AC,X
.C:7b14  5B A5 5E    SRE $5EA5,Y
.C:7b17  B9 52 22    LDA $2252,Y
.C:7b1a  5B 4B 56    SRE $564B,Y
.C:7b1d  E1 59       SBC ($59,X)
.C:7b1f  2A          ROL A
.C:7b20  4D 22 5B    EOR $5B22
.C:7b23  54 5B       NOOP $5B,X
.C:7b25  84 5B       STY $5B
.C:7b27  D3 5A       DCP ($5A),Y
.C:7b29  C8          INY
.C:7b2a  57 DF       SRE $DF,X
.C:7b2f  46 5D       LSR $5D
.C:7b31  98          TYA
.C:7b32  4F 63 57    SRE $5763
.C:7b35  84 5B       STY $5B
.C:7b37  4B 56       ASR #$56
.C:7b39  98          TYA
.C:7b3a  4F B9 52    SRE $52B9
.C:7b3d  2D 52 8E    AND $8E52
.C:7b40  4D A9 5D    EOR $5DA9
.C:7b43  54 5B       NOOP $5B,X
.C:7b45  DC 5D B9    NOOP $B95D,X
.C:7b48  52          JAM
.C:7b49  74 57       NOOP $57,X
.C:7b4b  B9 52 A9    LDA $A952,Y
.C:7b4e  5D 54 5B    EOR $5B54,X
.C:7b51  D1 4C       CMP ($4C),Y
.C:7b53  B9 52 DC    LDA $DC52,Y
.C:7b56  5D B3 57    EOR $57B3,X
.C:7b2c  4D C8 57    EOR $57C8
.C:7b59  B9 52 54    LDA $5452,Y
.C:7b5c  5B B9 52    SRE $52B9,Y
.C:7b5f  B9 52 2A    LDA $2A52,Y
.C:7b62  4D DB 5E    EOR $5EDB
.C:7b65  B9 52 C8    LDA $C852,Y
.C:7b68  57 B9       SRE $B9,X
.C:7b6a  52          JAM
.C:7b6b  2A          ROL A
.C:7b6c  4D C8 57    EOR $57C8
.C:7b6f  4B 56       ASR #$56
.C:7b71  B9 52 98    LDA $9852,Y
.C:7b74  4F FC 53    SRE $53FC
.C:7b77  DF 4D B9    DCP $B94D,X
.C:7b7a  52          JAM
.C:7b7b  4B 56       ASR #$56
drifting
Posts: 152
Joined: Wed Dec 07, 2011 10:21 pm

Re: CBM64 Bard's Tale 1 Disassembly

Post by drifting »

DMan wrote: Tue Dec 29, 2020 11:33 am Does anyone have the data values for the spell effects table (not the spell point cost or spell code names)? I’m assuming there’s a table (or tables) for attributes such as range, effect, combat/non-combat and self/party. Trawled through all of these Dev threads and can’t find reference to it.

I’m currently involved with disassembling the ZX Spectrum version of BT. These threads have been extremely useful in identifying most of the data - same data values, just (in a lot of cases) partially packed in the ZX source code.
In the DOS version of BT1, there are two tables for spells. BTII adds a third table that is the range of the spell.

Code: Select all

spellAttrMask db 1Ch,0Bh,0Ch,14h,0Ah,1Ch,8,19h,0Ah,1Ch; 0
db 1Dh,8Ah,1Ch,99h,0Bh,1Ch,8,4Ah,1Ch,1Dh; 10
db 9Dh,14h,8Bh,0Dh,1Ch,0Ah,0Dh,0Ch,8Bh,0Ah; 20
db 1Ch,0Ch,9Ch,0Ah,1Dh,1Ch,0Dh,1Ch,0Dh,8Eh; 30
db 1Ch,0Bh,1Ch,9Ch,8,0Ch,1Ch,14h,6Bh,0Bh; 40
db 8,5Ch,1Dh,9,0Dh,0Ah,6Bh,0Ah,1Ch,0Dh,0Dh; 50
db 0Bh,14h,1Dh,9Dh,0Bh,1Dh,0Ah,1Dh,2Bh,1Dh; 61
db 0D8h,1Dh,18h,0Ah,2Ah,1Dh,0F8h,1Dh,2Ah; 71
db 0Ah,0Ah,0Ah,4Ah,6Ah,6Ah,0Ah,8Ah,0AAh; 80
db 0CAh,1Ch,1Ch,1Dh,1Dh,1Dh,1Dh,1Dh,1Dh; 89
db 1Dh,1Dh,1Dh,1Dh,1Dh,1Dh,1Dh,0; 98
This one's a bitmask for casting the spells. I'd have to dig in deeper to get all of the bits but I know 10h is the "combat only" flag for spells

Code: Select all

durationArrayMaybe db 0,1,0,0              ; 0
db 0,28h,0,2            ; 4
db 0,1,0,4              ; 8
db 0,6,1,2              ; 12
db 1,8,1,1              ; 16
db 86h,0,2,0            ; 20
db 14h,0,1,82h          ; 24
db 3,0,80h,1            ; 28
db 3Ch,1,3,83h          ; 32
db 1,81h,0FFh,0Ah       ; 36
db 84h,3,85h,0FFh       ; 40
db 1,2,4,0              ; 44
db 6,4,2,14h            ; 48
db 28h,2,2,6            ; 52
db 0Ch,8,5,0            ; 56
db 6,6,0,0FFh           ; 60
db 8Fh,7,47h,10h        ; 64
db 9,20h,4Ah,0          ; 68
db 0Ch,5,0,20h          ; 72
db 4Dh,0,4Fh,18h        ; 76
db 20h,28h,30h,22h      ; 80
db 2Ch,40h,48h,10h      ; 84
db 12h,14h,6,7          ; 88
db 11h,12h,13h,14h      ; 92
db 15h,16h,17h,18h      ; 96
db 19h,1Ah,1Bh,1Ch      ; 100
db 1Dh,0                ; 104
This one holds all of the other data for the spells. The meaning of the values depend on the spell being cast.
Weber G
Posts: 125
Joined: Tue Dec 15, 2020 9:58 am

Re: CBM64 Bard's Tale 1 Disassembly

Post by Weber G »

It seems that for BT2 (C64), each spell has it's own routine. There is a address table for spells:

Code: Select all

>C:7af3  d1 4c 8e 4d  20 5e 5c 5d  33 5b 4b 56  d1 4c fd 5a   .L.M ^\]3[KV.L.Z
>C:7b03  c8 57 b9 52  4b 56 d1 4c  c8 57 b9 52  fd 5a 4b 56   .W.RKV.L.W.R.ZKV
>C:7b13  ac 5b a5 5e  b9 52 22 5b  4b 56 e1 59  2a 4d 22 5b   .[.^.R"[KV.Y*M"[
>C:7b23  54 5b 84 5b  d3 5a c8 57  df 4d c8 57  46 5d 98 4f   T[.[.Z.W.M.WF].O
>C:7b33  63 57 84 5b  4b 56 98 4f  b9 52 2d 52  8e 4d a9 5d   cW.[KV.O.R-R.M.]
>C:7b43  54 5b dc 5d  b9 52 74 57  b9 52 a9 5d  54 5b d1 4c   T[.].RtW.R.]T[.L
>C:7b53  b9 52 dc 5d  b3 57 b9 52  54 5b b9 52  b9 52 2a 4d   .R.].W.RT[.R.R*M
>C:7b63  db 5e b9 52  c8 57 b9 52  2a 4d c8 57  4b 56 b9 52   .^.R.W.R*M.WKV.R
>C:7b73  98 4f fc 53  df 4d b9 52  4b 56 c8 57  b9 52 06 52   .O.S.M.RKV.W.R.R
>C:7b83  84 5e 2e 5e  cc 51 c8 57  4b 56 b9 52  b3 57 c1 7b   .^.^.Q.WKV.R.W.{
>C:7b93  e1 7b 01 7c  21 7c 41 7c  61 7c 81 7c  a1 7c c1 7c   .{.|!|A|a|.|.|.|
>C:7ba3  e1 7c 01 7d  21 7d 41 7d  61 7d 81 7d  e1 7b a1 7d   .|.}!}A}a}.}.{.}
>C:7bb3  c1 7d 61 7d  e1 7d 01 7e  61 7c 21 7d  41 7d d7 ef   .}a}.}.~a|!}A}..
e.g. ARFI has the spell# 01. With the following code, the address of that spell is identified:

Code: Select all

.C:4ca1  A5 CA       LDA $CA        ;spell#
.C:4ca3  A8          TAY            ;A => Y
.C:4ca4  C9 50       CMP #$50       ;
.C:4ca6  90 18       BCC $4CC0      ;A < 50h => jump
.C:4cc0  0A          ASL A          ;move A bitwise left (2 byte address)
.C:4cc1  AA          TAX            ;A => X
.C:4cc2  BD F3 7A    LDA $7AF3,X    ;LSB spell address => A
.C:4cc5  8D CF 4C    STA $4CCF      ;A => $4CCF 
.C:4cc8  BD F4 7A    LDA $7AF4,X    ;MSB spell address => A
.C:4ccb  8D D0 4C    STA $4CD0      ;A => $4CD0 
.C:4cce  4C 8E 4D    JMP $4D8E      ;jump to spell address
and the routine for ARFI starts at this address ($4D8E):

Code: Select all

ARFI
.C:4d8e  A5 D0       LDA $D0		;character# => A
.C:4d90  30 4D       BMI $4DDF		
.C:4d92  20 F4 54    JSR $54F4		
.C:4d95  B0 48       BCS $4DDF
.C:4d97  A4 CA       LDY $CA		;spell# => Y (ARFI: 01)
.C:4d99  BE 5D 78    LDX $785D,Y	;ARFI damage => X
.C:4d9c  8E C9 4D    STX $4DC9		;X => $4DC9 ######1
.C:4d9f  A9 00       LDA #$00		;0 => A
.C:4da1  85 45       STA $45		;clear LSB damage
.C:4da3  85 46       STA $46		;clear MSB damage
.C:4da5  85 C8       STA $C8		;set special effect (e.g. stones) but ARFI hasn't => 0
.C:4da7  A0 22       LDY #$22		;22h => Y
.C:4da9  B1 6E       LDA ($6E),Y	;MSB character level => A
.C:4dab  85 51       STA $51		;A => $51
.C:4dad  C8          INY		;Y = Y +1
.C:4dae  B1 6E       LDA ($6E),Y	;LSB character level => A
.C:4db0  85 50       STA $50		;A => $50
.C:4db2  20 2C 44    JSR $442C		;create random numbers (00-FF) and store them in $5A/ $5B
.C:4db5  A5 5A       LDA $5A		;$5A (random number) => A
.C:4db7  29 03       AND #$03		;3 AND A (result is 0-3)
.C:4db9  18          CLC
.C:4dba  69 01       ADC #$01		;A + 1 (result is 1-4)
.C:4dbc  18          CLC
.C:4dbd  65 45       ADC $45		;A + $45
.C:4dbf  85 45       STA $45		;A => $45
.C:4dc1  90 02       BCC $4DC5		;carry flag not set => jump
.C:4dc3  E6 46       INC $46		;increase MSB damage
.C:4dc5  CA          DEX		;X = X -1 
.C:4dc6  D0 EA       BNE $4DB2		;X > 0 => jump (depends on spell damage $785D,Y)
.C:4dc8  A2 01       LDX #$01		;######1 => X
.C:4dca  A5 50       LDA $50		;$50 (LSB character level) => A
.C:4dcc  38          SEC
.C:4dcd  E9 01       SBC #$01		;A (LSB character level) -1
.C:4dcf  85 50       STA $50		;A => $50 (LSB character level)
.C:4dd1  B0 02       BCS $4DD5		;A >= 0 => jump
.C:4dd3  C6 51       DEC $51		;decrease $51 (MSB character level)
.C:4dd5  A5 51       LDA $51		;$51 (MSB character level) => A
.C:4dd7  D0 D9       BNE $4DB2		;A > 0 => jump
.C:4dd9  A5 50       LDA $50		;$50 (LSB character level) => A
.C:4ddb  D0 D5       BNE $4DB2		;A > 0 => jump
.C:4ddd  F0 23       BEQ $4E02		;A = 0 => jump
There is a SP cost table...

Code: Select all

>C:7796  02 03 02 03  03 04 05 04  05 06 06 07  07 09 08 0c   ................
>C:77a6  0f 12 0c 03  03 02 04 05  05 06 06 06  08 07 08 08   ................
>C:77b6  09 0a 0c 0e  0b 1e 03 02  02 04 05 04  06 06 06 07   ................
>C:77c6  0c 08 0a 0d  0b 0e 10 28  64 0a 0b 0c  0b 0e 0c 0f   .......(d.......
...and a table for different effects (e.g. damage, maybe duration => not investigated yet):

Code: Select all

>C:785d  00 01 00 00  28 04 01 00  05 00 0a 02  0a 01 01 8a   ....(...........
>C:786d  00 00 0d 01  11 00 06 02  14 28 02 08  0f 0b 00 06   .........(......
>C:787d  00 ff 8f 07  0e 00 02 00  14 01 82 00  81 01 3c 03   ..............<.
>C:788d  83 ff 19 84  ff 85 86 3c  c8 07 19 08  64 16 00 09   .......<....d...
But I couldn't find a range table for spells. Maybe the sub routine $54F4 checks the range. That's an open point to investigate. For the special attack effects of the spells (e.g. stones) there should be no table, since the value of $C8 (special attack effect) is directly set in the spell routine (see $4da5).
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 »

Wow. You guys are smart.

I couldn't make head or tails of any of that code looking at it last night. :?
drifting
Posts: 152
Joined: Wed Dec 07, 2011 10:21 pm

Re: CBM64 Bard's Tale 1 Disassembly

Post by drifting »

Weber G wrote: Wed Dec 30, 2020 12:44 am But I couldn't find a range table for spells. Maybe the sub routine $54F4 checks the range. That's an open point to investigate. For the special attack effects of the spells (e.g. stones) there should be no table, since the value of $C8 (special attack effect) is directly set in the spell routine (see $4da5).
In the DOS version, the range table is:

Code: Select all

spellRange db 0,1,0,0,0,0,0,0      ; 0 ; This is the range of the combat spells. A monster
db 82h,0,0,0,83h,0,0,0  ; 8 ; group's distance has to be less than the range for
db 0,0,0,0,0,0,1,0      ; 16 ; the attack to succeed.
db 0,0,0,84h,7,83h,0,1  ; 24 ;
db 0,0,0,1,0,0,84h,0    ; 32 ; If the 0x80 bit is set, groups within double the
db 0,0,0,0,0,0,0,0      ; 40 ; range of the spell receive half damage.
db 0,0,83h,0,0,0,0,0Ah  ; 48 ;
db 0Ah,0,1,0,3,83h,0,0  ; 56
db 0,0,7,0,0,5,0,0      ; 64
db 0,0,0,6,0,0,0Ah,0    ; 72
db 2,2,3,3,4,5,5,6      ; 80
db 6,7,7,8,8,8,9,9      ; 88
db 1,1,3,2,2,3,4,5      ; 96
db 4,6,9,7,7,8,8,9      ; 104
drifting
Posts: 152
Joined: Wed Dec 07, 2011 10:21 pm

Re: CBM64 Bard's Tale 1 Disassembly

Post by drifting »

Weber G wrote: Wed Dec 30, 2020 12:44 am For the special attack effects of the spells (e.g. stones) there should be no table, since the value of $C8 (special attack effect) is directly set in the spell routine (see $4da5).
That probably depends on the spell. In DOS, the Stone Touch, Death Strike, and Animate Dead spells use the same routine that uses a table (durationArrayMaybe I posted above) for the special attack.

Code: Select all

mov     al, durationArrayMaybe[bx] ; bx = spell number. al = special attack type
mov     specialAttackType, al      ; set specialAttackType to al
Post Reply