We just released a Feb. 5 '89 prototype of DuckTales for the NES!
If you'd like to support our preservation efforts (and this wasn't cheap), please consider donating or supporting us on Patreon. Thank you!

Notes:The Adventures of Captain Comic (DOS)

From The Cutting Room Floor
Revision as of 04:11, 14 November 2019 by Mouser (talk | contribs) (Disassembly changes, to be referenced from the main page.)
Jump to navigation Jump to search

This page contains notes for the game The Adventures of Captain Comic (DOS).


Revisions

The Internet Archive has all five revisions under the item TheAdventuresOfCaptainComic:

It also has three other versions:

  • swh11988 (file_id.diz labels it "Hacked/grafitti version 1")
  • swh21988 (file_id.diz labels it "Hacked/grafitti version 2")
  • R4a1sw1989 (file_id.diz labels it "Alternate version 1")

File Formats

Malvineous has documented the file formats here.

Executable Packing

In every revision, COMIC.EXE is packed with EXEPACK. Revision 1 uses an earlier version of EXEPACK that not all unpackers can handle. Try these ones:

R1swh21988 (a hacked version) doesn't have COMIC.EXE but rather MENU.EXE, and the EXEPACK layer appears to be wrapped in another layer that adds an advertisement for "Red Point".

Sound Effects

The format of a sound effect is an array of

struct {
    uint16_t freq_divider;
    uint16_t duration;
};

The 16-bit values are stored little-endian. Each freq_divider divides the Programmable Interval Timer base frequency of 1193182 Hz. For example, a freq_divider of 1c3f would result in an output frequency of 1193182 / 0x1c3f ≈ 165 Hz. The special freq_divider value 0028 indicates a rest. duration is in number of beats; each beat is about 55 ms (one tick of the 18.2 Hz IRQ 0 timer). The end of the sound is marked by a freq_divider of 0000.

Table of offsets to sound effects in the unpacked executable. Assumes that the unpacked executable has an EXE header of 512 bytes. Changed sounds are highlighted.

R1sw1988 R1swh11988 R2sw1988 R3sw1989 R4a1sw1989 R4sw1989 R5sw1991
title 2521 2521 25a2 25d2 27a2 27a2 29c4
start 2665 2665 2bc0 2bf2 2daa 2d9e
door eda9 eda9 f309 f339 f4f9 f4e9 fc29
player death edd1 edd1 f331 f361 f521 f511 fc51
teleport edf9 edf9 f359 f389 f549 f539 fc79
bonus ee19 ee19 f379 f3a9 f569 f559 fc99
materialize ee25 ee25 f385 f3b5 f575 f565 fca5
game over ee85 ee85 f3e5 f415 f5d5 f5c5 fd05
screen transition eede eede f43e f46f f62f f61f fd3f
lost life eefe eefe f45e f48f f64f f63f fd5f
shoot ef4e ef4e f4ae f4de f69e f68e fdae
enemy death ef5a ef5a f4ba f4ea f6aa f69a fdba
player damaged ef71 ef71 f4d1 f501 f6c1 f6b1 fdd1
item get ef81 ef81 f4e1 f511 f6d1 f6c1 fde1
extra life ef95 ef95 f4f5 f525 f6e5 f6d5 fdf5

References for Code Changes

R3 Esc

Revision 2 @ 76 Revision 3 @ 76
    cd16	int 0x16	; get keystroke; al=ASCII code
    3c6b	cmp al, 0x6b	; 'k'
    7407	je setup_keyboard
    3c4b	cmp al, 0x4b	; 'K'
    7403	je setup_keyboard
    e95001	jmp game_start
    cd16	int 0x16	; get keystroke; al=ASCII code
    3c6b	cmp al, 0x6b	; 'k'
    740e	je setup_keyboard
    3c4b	cmp al, 0x4b	; 'K'
    740a	je setup_keyboard
    3c1b	cmp al, 0x1b	; Esc
    7503	jne any_other_key
    e95203	jmp terminate_program
any_other_key:
    e95401	jmp game_start

R3 Del

Revision 2 @ 1b6 Revision 3 @ 1a0
await_keypress:
; [...]
; bx is scancode
    4b		dec bx			; scancode == 0x1 (Esc)?
    74c5	je await_keypress
    83fb51	cmp bx, 0x51		; scancode > 0x52 (Ins)?
    7fc0	jg await_keypress
; assign scancode to action
await_keypress:
; [...]
; bx is scancode
    4b		dec bx
    74d1	je await_keypress	; scancode == 0x1 (Esc)?
    83fb52	cmp bx, 0x52
    7fcc	jg await_keypress	; scancode > 0x53 (Del)?
; assign scancode to action

R3 Keyboard Buffer

Revision 2 @ 2b4 Revision 3 @ 1d1
; 0040:1a is pointer to beginning of the buffer of pending keystrokes
; 0040:1c is pointer to end
    268a0e1a04	mov cl, byte es:[0x41a]
    26880e1c04	mov byte es:[0x41c], cl ; set end = beginning
; 0040:1a is pointer to beginning of the buffer of pending keystrokes
; 0040:1c is pointer to end
    fa		cli			; disable interrupts
    268a0e1a04	mov cl, byte es:[0x41a]
    26880e1c04	mov byte es:[0x41c], cl ; set end = beginning
    fb		sti			; enable interrupts