diff --git a/notes.txt b/notes.txt index b781c84..6e9146b 100644 --- a/notes.txt +++ b/notes.txt @@ -1,11 +1,11 @@ TODO: -- Switch to another ROM that has 'stage select'? - - Reverse engineer and reapply turbofix, sprite flickering fix, jump button fix, R800 enable - Re-work all music with proper speakers -- drums sound distorted in R800 mode. a lot better in Z80 although not perfect - maybe the player is too fast somehow and it misses a transient? -- SCC doesn't sound loud enough and/or SFX sound too loud (on my TurboR) -- game over music should have sharper instrument + - heart of fire - lead instrument should be louder + - stage clear theme - not bright enough + needs to be higher octave + - out of time need brighter lead + (one at the start is ok) + - ending music needs brighter instruments turbofix patch (19 dec 2017) @@ -19,6 +19,46 @@ sidenote: the turbofix patch causes graphics corruption on the ending titles (when you complete the game) +kick drum fix notes +------------------- +The Konami PSG kick and snare rely on a click noise generated by a PSG envelope. +The snare consists of a click, followed by noise. The bass drum is just a click +(a slightly longer one). The problem is that if the oscillator is in the 'off' +state at the start of the envelope, you don't hear the initial 'click'. +This means that the sound of the kick/snare is not consistent. +The fix is to set the oscillator frequency to '0', which makes it output +a solid '1'. This way the sound of the click is consistent. + +SCC player reverse engineering notes: + +229c <- contains bit of PSG register that need to be set +229d/e/f <- contains the values of PSG registers 11, 12, 13 + + +6b51 <- where the jump table is used +6b5d <- jump table of addresses for drum set routines??? +6bed <- kick drum routine + + +PSG frequency eg. register 0, 1 values are stored in IX+a/b, e.g. 200A, 200B + + +66EE <- frequency is set here +if I NOP this routine out and force the frequency to 0000 then the kick/snare are consistent +but we lose the tonal part of some of the drums + +the frequency that 66EE sets comes from IX+10/11 +(these are basically copied from 10/11 -> a/b) + +6509 <- 10/11 frequency is set here + for the kick drum, HL = 7485? + kick drum settings are at 7484: + 7484 = 0A envelope frequency + 7485 = 94 flags + frequency (high bits) + 7486 = 50 frequency low bits + + + music corruption when changing songs ------------------------------------ when changing songs, the music must first be stopped using command 00 diff --git a/patch.py b/patch.py index 972f712..bcb659a 100644 --- a/patch.py +++ b/patch.py @@ -31,7 +31,17 @@ def patch_mapper(rom): rom[offset + 2] += 0x10 PATCH_IGNORE_LIST = [0x20daa, 0x23340, 0x20beb] -CHANNEL_OFFSET = -0xc0 # 0e00h -> 02000h +#CHANNEL_OFFSET = -0xc000 # 0e00h -> 02000h +CHANNEL_OFFSET = +0x0e00 # 0e00h -> 0ee00h + + +def offset_address(rom, index, offset): + """Modify an address in the ROM by a certain amount""" + addr = rom[index] + rom[index + 1] * 256 + addr += offset + rom[index] = addr & 255 + rom[index + 1] = addr >> 8 + def patch_music_channel_locations(rom): """Patch scc player to move channel data locations""" @@ -41,10 +51,10 @@ def patch_music_channel_locations(rom): if (rom[offset] == 0xdd and rom[offset + 1] == 0x21 and (rom[offset + 3] & 0xfc) == 0xe0): - rom[offset + 3] += CHANNEL_OFFSET + offset_address(rom, offset + 2, CHANNEL_OFFSET) if (rom[offset] in [0x01, 0x11, 0x21, 0x32, 0x3a, 0x22, 0x2a] and (rom[offset + 2] & 0xfc) == 0xe0): - rom[offset + 2] += CHANNEL_OFFSET + offset_address(rom, offset + 1, CHANNEL_OFFSET) def patch_bios_psg_calls(rom): @@ -78,7 +88,38 @@ def save_kss_file(filename, rom): # Nemesis 3 kick drum fix # See: https://www.msx.org/forum/msx-talk/general-discussion/nemesis-3-gofers-ambition-episode-ii-bass-drum-lost assert rom[0x21484] == 0x0a -rom[0x21484] = 0xf0 +#rom[0x21484] = 0xf0 # make kick envelope longer +# kick fix (maybe?) +rom[0x21485] = 0x90 +rom[0x21486] = 0 +# snare fix (maybe?) +rom[0x21487] = 0x90 +rom[0x21488] = 0 + +# kick +rom[0x213e0] = 0xc0 +rom[0x213e1] = 0 + +# snare click +rom[0x213ec] = 0xc0 +rom[0x213ed] = 0 + +# snare2 click +rom[0x21404] = 0xa0 +rom[0x21405] = 0 + +# move the stack to 0xfaf0. this is a bit of memory +# that is used by the MSX BASIC 'PAINT' command so it +# is unused for our purposes. This then frees up the area +# that Vampire Killer has reserved for the stack: +# 0xee00 - 0xf100. We then use this area of memory +# for the Nemesis 3 SCC player's state data +rom[0x0078] = 0xfa +rom[0x0077] = 0xf0 + +# there are lots of these, and some of the drums +# will iterate through a list of them over time + # compile new music into ROM compile('mml/vkiller_scc.mml', rom, nemesis3, 0x1a000, 0x7510, 0x8000) diff --git a/vkiller_scc.asm b/vkiller_scc.asm index d7f5d65..865ae09 100644 --- a/vkiller_scc.asm +++ b/vkiller_scc.asm @@ -23,10 +23,10 @@ ; disable R800 mode ; R800 mode causes the PSG drums to sound inconsistent/weird - output vkiller_patch01db2.bin - nop - nop - nop +; output vkiller_patch01db2.bin +; nop +; nop +; nop output vkiller_patch01c8a.bin @@ -124,7 +124,7 @@ write_psg: ; if the game is paused, don't write PSG ch7 ; this is to prevent interference with the game paused jingle - ld a, (02280h) + ld a, (0f080h) and 2 ret nz ; paused @@ -152,58 +152,11 @@ not_register_seven: ret map_slots: - ; map RAM into bank 0000-3fff - ; returns original value of #ffff in a - ; returns original slot select in b/c - ld c, 0a8h - in b, (c) - push bc - push hl - ld a, b - rlca ; replicate slot in page 3 to page 0 - rlca - and 03h - ld l, a - ld a, b - and ~03h - or l - out (c), a - - ; SOFAROM uses these addresses for SCC patching - ; to take into account that we map RAM into page 0, we need - ; to change these values. this is a SOFAROM specific hack - ld (0f6ebh), a ; primary slot select (game) - ld a, (0f6eah) ; primary slot select (SCC) - or 03h - ld (0f6eah), a - - ; get subslot from page 3 (c000-ffff) and apply to page 0 (0000-3fff) - ld hl, 0ffffh - ld a, (hl) - cpl - push af - ld b, a - and 011000000b - rlca - rlca - ld c, a - ld a, b - and 011111100b - or c - ld (hl), a - ; map music data using konami SCC mapper ld a, 17 ld (09000h), a ld a, 18 ld (0b000h), a - - ld a, 1 - out (0fch), a - - pop af - pop hl - pop bc ret music_start: @@ -211,10 +164,6 @@ music_start: call map_slots - push bc - push hl - push af - ; interpret the command ld a, e cp 0xfa ; 0xfa and higher = commands: fade out, pause, etc. @@ -234,9 +183,9 @@ music_stop: ; clear music player state push bc push de - ld hl, 02000h - ld de, 02001h - ld bc, 00300h + ld hl, 0ee00h + ld de, 0ee01h + ld bc, 00280h ld (hl), 0 ldir pop de @@ -256,18 +205,10 @@ music_start_command: music_start_call: push bc call 06003h ; nemesis 3 song start function + call 06180h ; initialize some state which fixes boss music cutting out pop bc music_start_skip: - - pop af - ld (0ffffh), a - pop hl - pop bc - - ; restore BIOS ROM - out (c), b - di ld a, 14 ld (09000h), a @@ -288,21 +229,12 @@ music_update: call map_slots - push bc - push af - call 06006h ; nemesis 3 song update function - pop af - ld (0ffffh), a - ; set a flag which vkiller uses to know whether music is playing - ld a,(020c0h) + ld a,(0eec0h) ld (0c0a7h), a - ; restore ROM - pop bc - out (c), b ram_not_initialised: ld a, 14 ld (09000h), a