Bangkok Knights

From Software Archive
Revision as of 02:17, 4 October 2026 by Enigma (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

mobygames link

Source 1

Property Data
Title Bangkok Knights
Publisher and/or Developer System 3 Software Ltd., Activision Ltd.
Year 1987
Disk(s) 1
Number of Index Holes 1
Media Type 5.25 DSDD
Retail, Budget or Compilation (with name) Retail
Country of Release UK
Language(s) English
Platform C64
NTSC or PAL PAL
Protection Para Protect
Working? Yes (requires 1541, protection check does not work on 1541-II)
Archived 8 Jul 2014 Rakki
Verified by enigma

Purchased from: ebay.co.uk / gurl_gamer

Streams

File:Streams BangkokKnights Rakki.zip

G64

File:BangkokKnights Rakki s0.g64

File:BangkokKnights Rakki s1.g64

Source 2

Property Data
Title Bangkok Knights
Publisher and/or Developer Boeder/bitstar Games, System 3 Software Ltd., Activision Ltd.
Year 03/1992
Disk(s) 1
Number of Index Holes 1
Media Type 5.25 DSDD
Retail, Budget or Compilation (with name) Budget
Country of Release DE
Language(s) English
Platform C64
NTSC or PAL PAL
Protection None
Working? Yes, Stream has an error on side 1 track 31 sector 11, but could be repaired in G64.
Archived 18 Dec 2022 Rene
Verified by enigma
Streams

File:Streams bangkok knights rene.zip

G64

File:Bangkok knights rene s0.g64

File:Bangkok knights rene s1.g64

Why Bangkok Knights does not load on a 1541-II

Bangkok Knights loads on a 1541 but hangs on a 1541-II. The cause is not the Para Protect track-40 read. Every ROM routine its drive-side reader calls ($F6D0, $F8E0, $F24B, $F969, the job loop at $F31B) is byte-identical in both drive ROMs: 1541 325302-01 + 901229-05, and 1541-II 251968-03. The failure also happens earlier, about 5 seconds into loading, while the head is still on track 18.

The faulty loop

The cause is a drive-side loop in the game's boot chain. It copies drive ROM from $C000 over code at $0700 that has already run, presumably to erase it:

$0727  A2 29     LDX #$29
$0729  BD 00 C0  LDA $C000,X
$072C  9D 00 07  STA $0700,X
$072F  CA        DEX
$0730  10 F7     BPL $0729

The counter starts one byte too high. The first store (X = $29) writes ROM byte $C029 over the loop's own opcode at $0729, so the next pass executes whatever that ROM byte is.

On a 1541

The 1541 ROM area $C000–$C0FF is filler, so $C029 = $AA, which is TAX:

  1. $0729 now reads AA 00 C0. The next pass executes
 TAX, so X = $AA.
  1. $072A is $00, a BRK. The drive's IRQ
 handler at $FE67 doesn't check for BRK and returns with
 RTI to $072C.
  1. STA $0700,X writes to $07AA. Then
 DEX gives $A9, which is negative, so
 BPL falls through.

The loop ends after copying a single byte, and loading carries on as if nothing happened.

On a 1541-II

The 1541-II ROM holds its copyright text in that area: "…COPYRIGHT (C)1982,1985,1987 COMMODORE ELECTRONICS…". So $C029 = $4C (the letter "L"), which is JMP:

  1. $0729 now reads 4C 00 C0, which is
 JMP $C000.
  1. The drive executes the copyright text as code and ends up at
 $C05F. That is inside a helper routine that exists only in
 the 1541-II ROM ($C04E, called from the format code at
 $FCAE).
  1. The helper waits for byte-ready at $C066, which never comes,
 so the drive hangs there.
  1. The C64 waits forever for the drive.

Comparison with After Burner

After Burner uses the same buffer-2 loader and contains the same loop:

$072E  A2 2F     LDX #$2F
$0730  BD 00 C0  LDA $C000,X
$0733  9D 00 07  STA $0700,X
$0736  CA        DEX
$0737  10 F7     BPL $0730

Here the copy covers $0700–$072F and stops one byte short of the loop itself, so After Burner works on both drives. In Bangkok Knights the counter is one too high for where the loop sits. This looks like an off-by-one bug that the 1541's $AA filler happened to hide, not a deliberate 1541-II check.

Minimal patch that makes the game work on 1541-II

The loop is stored unencrypted on the disk in track 18, sector 18. The drive loads this sector to $0700 with an ordinary DOS READ job, but it has two quirks:

  • Its data block ID is $12 instead of $07.
  • Its data checksum ($F2) is reused afterwards as a decryption key (LDA $3A / STA $C1 at $0705), so the sector's checksum must not change.

A two-byte patch fixes the problem and leaves the checksum unchanged:

Sector offset Address Old New Effect
$2A $072A $00 $C9 LDA $C000,X becomes LDA $C0C9,X. With X = $29 it reads $C0F2, which is filler $AA in both ROMs.
$AA $07AA $00 $C9 Compensates the checksum ($00 XOR $C9 twice, so the XOR stays $F2). The loop overwrites this byte with $AA before anything reads it.