News:

Printed Amstrad Addict magazine announced, check it out here!

Main Menu
avatar_Xyphoe

Uridium - Game breaking bug/crash? Budget only release?

Started by Xyphoe, 08:27, 10 April 19

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Xyphoe

Hello!I have 2 questions regarding URIDIUM. 

1) Was this ever released at full price from Hewson?  I can only find box art scans for the Rackit budget release (CPC-Power, CPC Rulez & Moby Games sites). I've even gone through all the issues of Amstrad Action from Dec 1986 to Jan 1988 and it wasn't reviewed (Speccy version was reviewed in Crash in their Dec 1986 issue).

2) Has anyone ever completed it / does the game always crash on later levels?
A few years ago I looked to do a longplay video of it, and gave up when the game crashed on a really far on level. Today I've used I believe a different cracked disk dump, and it goes bananas on level 12 - either crashes, or if I manage to make it to the end it's impossible to land and complete the level. Later I'm going to try out the CDT of the game to see if it happens there. (There's 15 levels in total)

Xyphoe

OK this game is BUGGED!!

I've now tested using the CDT from CPC Power (http://cpc-power.com/index.php?page=detail&onglet=dumps&num=2239) - which will make 3 different dumps of the game now - and YES this also crashes on level 12.
BUT I spotted something playing through it this time that I might have missed before.
Something a little bit strange happens (and sometimes it only happens briefly from reloads) when you hit 100,000 points. When you hit that you get a bonus life. But if you load up the WinApe snapshot file attached in a zip (latest version of WinApe) watch what happens! From reloads it seems if you destroy a land target (rather than a ship) to take you over 100,000 points that's when things go odd. Maybe it's to do with the sound/audio?

This is probably the start of the problems, any maybe things go downhill from there. Although I'm on level 9 at this point (completely crashes at level 12).
I think this is a big clue for whoever wants to dare fixing this bug and crash....!

zhulien

with such a level based game, i wonder what is the effort to patch it to skip level 12?

Nich

Quote from: Xyphoe on 08:27, 10 April 19
Hello!I have 2 questions regarding URIDIUM. 

1) Was this ever released at full price from Hewson?  I can only find box art scans for the Rackit budget release (CPC-Power, CPC Rulez & Moby Games sites). I've even gone through all the issues of Amstrad Action from Dec 1986 to Jan 1988 and it wasn't reviewed (Speccy version was reviewed in Crash in their Dec 1986 issue).

I've never seen any copies of a full-price CPC release anywhere, so I'm fairly sure that Uridium was only ever released on budget on the CPC. Here's a link to another post I wrote back in 2016.

I'm not sure I'll be able to find a bugfix, though!

Shaun M. Neary

Just weighing in here but has anyone tried the version that was on Christmas Collection / Joystick Thunder compilation that came out circa 89?


Might be a duplicate of the same version but can't hurt?
*returns to occasional lurk mode*
Currently playing on: 2xCPC464, 1xCPC6128, 1x464Plus, 1x6128Plus, 2xGX4000. M4 board, ZMem 1MB and still forever playing Bruce Lee.
No cheats, snapshots or emulation. I play my games as they're intended to be played. What about you?

mahlemiut

I've had a weird crash bug in Zub that occurs in emulation (at least in MAME and RVM, need to try it in WinAPE).  Shoot enemies enough, and the game eventually crashes hard.  It can be mitigated a bit by lowering the difficulty (less things to shoot), but it just happens later.  It's not something I ever saw on an actual hardware, so it's rather surprising.  I've tried multiple dumps (including a tape dump), to no avail.
- Barry Rodewald

Xyphoe

Quote from: Shaun M. Neary on 23:30, 10 April 19
Just weighing in here but has anyone tried the version that was on Christmas Collection / Joystick Thunder compilation that came out circa 89?

Might be a duplicate of the same version but can't hurt?
*returns to occasional lurk mode*
It's a fair point. I would have dismissed that because it's extremely unlikely the code would have been altered/fixed for that - however someone on the 'Amstrad CPC 464' Facebook group says that it was on the Amstrad Action cover tape (it was) and that they completed it... I'm not sure if I believe that given how mentally hard the game is, but lo - we have a CDT dump of that covertape - http://cpc-power.com/index.php?page=detail&onglet=dumps&num=3465
So I will try that out later, but will be bloody mad if they were wrong and the bugs still exist!  :laugh:

Then again, could have been a mastering error on the tape duplications from Hewson. But given how it crashes after an 'event' happens, I strongly suspect it's in the code and the by product of a quick Speccy port.

Xyphoe

Quote from: mahlemiut on 23:50, 10 April 19
I've had a weird crash bug in Zub that occurs in emulation (at least in MAME and RVM, need to try it in WinAPE).  Shoot enemies enough, and the game eventually crashes hard.  It can be mitigated a bit by lowering the difficulty (less things to shoot), but it just happens later.  It's not something I ever saw on an actual hardware, so it's rather surprising.  I've tried multiple dumps (including a tape dump), to no avail.
Yes! I did that one recently -> http://www.cpcwiki.eu/forum/longplays/xyphoe-(amstrad-cpc)-zub-longplay-review/
I'm sure I talked about that very bug/crash in the commentary - and yes it's when you're on the hardest difficulty when you have the most enemies spawned.

Nich

Quote from: Nich on 22:01, 10 April 19
I'm not sure I'll be able to find a bugfix, though!

Well, you can always rely on Nich to come up with the goods. I've found the source of all the bugs. ;)

At the beginning of each level, the game creates a buffer at address &0400 to store the locations of all the homing mine launchers. However, it isn't large enough to hold this information correctly for levels 12 and 14, and as a result, it can't work out where the information ends and it will read garbage data as you play the level and cause all sorts of interesting bugs.

The solution is to move the buffer to another area of memory, such as &00E0, and to increase its size slightly. The following pokes will do this:

23BB,00 → E0; 23BC,04 → 00
23BE,01 → E1; 23BF,04 → 00
23C1,0F → 14
2582,00 → E0; 2583,04 → 00

I played the game through to the end of level 15 (with an invulnerability cheat, of course :laugh:) and I didn't encounter any major bugs.

zeropolis79

Quote from: Xyphoe on 08:21, 11 April 19
It's a fair point. I would have dismissed that because it's extremely unlikely the code would have been altered/fixed for that - however someone on the 'Amstrad CPC 464' Facebook group says that it was on the Amstrad Action cover tape (it was) and that they completed it... I'm not sure if I believe that given how mentally hard the game is, but lo - we have a CDT dump of that covertape - http://cpc-power.com/index.php?page=detail&onglet=dumps&num=3465
So I will try that out later, but will be bloody mad if they were wrong and the bugs still exist!  :laugh:

Then again, could have been a mastering error on the tape duplications from Hewson. But given how it crashes after an 'event' happens, I strongly suspect it's in the code and the by product of a quick Speccy port.
The game was bloody hard and I would have used Multiface pokes to get somewhere.

ervin

Quote from: Nich on 21:03, 11 April 19
Well, you can always rely on Nich to come up with the goods. I've found the source of all the bugs. ;)

At the beginning of each level, the game creates a buffer at address &0400 to store the locations of all the homing mine launchers. However, it isn't large enough to hold this information correctly for levels 12 and 14, and as a result, it can't work out where the information ends and it will read garbage data as you play the level and cause all sorts of interesting bugs.

The solution is to move the buffer to another area of memory, such as &00E0, and to increase its size slightly. The following pokes will do this:

23BB,00 → E0; 23BC,04 → 00
23BE,01 → E1; 23BF,04 → 00
23C1,0F → 14
2582,00 → E0; 2583,04 → 00

I played the game through to the end of level 15 (with an invulnerability cheat, of course :laugh: ) and I didn't encounter any major bugs.


Amazing!
Did you figure out that stuff from a disassembly of the game?
I don't know how you do that so quickly!

Xyphoe

Quote from: Nich on 21:03, 11 April 19
Well, you can always rely on Nich to come up with the goods. I've found the source of all the bugs. ;)

At the beginning of each level, the game creates a buffer at address &0400 to store the locations of all the homing mine launchers. However, it isn't large enough to hold this information correctly for levels 12 and 14, and as a result, it can't work out where the information ends and it will read garbage data as you play the level and cause all sorts of interesting bugs.

The solution is to move the buffer to another area of memory, such as &00E0, and to increase its size slightly. The following pokes will do this:

23BB,00 → E0; 23BC,04 → 00
23BE,01 → E1; 23BF,04 → 00
23C1,0F → 14
2582,00 → E0; 2583,04 → 00

I played the game through to the end of level 15 (with an invulnerability cheat, of course :laugh: ) and I didn't encounter any major bugs.

That's awesome Nich! Thank you so much!
Just enter this poke when the game is loaded on the title screen or at any point during the game prior to level 12 yea?

Xyphoe

Oh and Nich, did you spot what was happening and going on when you get 10,000 points after hitting a land target?

Xyphoe

I put the pokes in at the end of level 11 before 12, and yes! It worked! WOOO!
Nich rocks! \m/

Nich

Quote from: ervin on 23:27, 11 April 19
Did you figure out that stuff from a disassembly of the game?
I don't know how you do that so quickly!

I used WinAPE's debugger. I noticed that the game crashes immediately after a homing mine is launched. I discovered where the routine for launching a homing mine was located by in turn working out where the routine that generated sound is located, and by a process of trial and error, finding out where the program played the sound for launching a homing mine (this was also how I found cheats for invulnerability).

I then disabled the routine for launching a homing mine, and then played level 12, and lo and behold, it didn't crash - so that confirmed the source of the bug! After analysing that routine, I saw that it used memory at &0400, so I tested each level one at a time and viewed the contents of memory at &0400 onwards in the debugger, and I eventually noticed that it overflowed on level 12. After that, I located another routine that sets up the buffer at &0400, and that's how I was able to patch the game.

I spent a long time thinking that the level data was corrupted, but thankfully that wasn't the case.

Nich

Quote from: Xyphoe on 23:51, 11 April 19
Oh and Nich, did you spot what was happening and going on when you get 10,000 points after hitting a land target?

No I didn't. Even after the patch is applied, there is sometimes a significant pause when you receive an extra life, but I don't know what causes it, and anyway, it doesn't crash the game so I'm not worried about it.

Nich

Quote from: Nich on 22:01, 10 April 19
I've never seen any copies of a full-price CPC release anywhere, so I'm fairly sure that Uridium was only ever released on budget on the CPC. Here's a link to another post I wrote back in 2016.

I've done some more research on this. The Rack It budget release of Uridium was released in 1988 according to reviews in a couple of Spectrum magazines, but it seems that its first appearance on the CPC was on the Four Smash Hits compilation which was released in Christmas 1987.

Nich

Right, here is a new crack of Uridium that incorporates my fixes and also lets you save the high scores to disc. Enjoy! :)

Xyphoe

Quote from: Nich on 18:37, 12 April 19
Right, here is a new crack of Uridium that incorporates my fixes and also lets you save the high scores to disc. Enjoy! :)
AMAZING WORK!!! Thank you so much again :)

I'm just sat here thinking, what a brilliant awesome little community we have .... and what would we do without people like Nich and others that contribute so much to preserving CPC software?
THANK YOU!

Xyphoe

Quote from: Nich on 18:31, 12 April 19
I've done some more research on this. The Rack It budget release of Uridium was released in 1988 according to reviews in a couple of Spectrum magazines, but it seems that its first appearance on the CPC was on the Four Smash Hits compilation which was released in Christmas 1987.
Yea I found this too earlier! Last night I pinged Rob and Andrew Hewson about that and what happened to the CPC release.
What's interesting is the compilation advertises "Uridium Plus" - which is the same game but 15 new levels. I tested the CPC version on that compo this morning and it's basically normal Uridium, unlike the Speccy and C64 version. But it's likely to be the first appearance of Uridium on the Amstrad.


Xyphoe

Haha! Dave Rogers (musician) has been in touch!
He's on the Amstrad CPC 464 Facebook group, and has shared his assembly code for the Uridium sound driver!!

https://www.facebook.com/permalink.php?story_fbid=1242571215919757&id=100005006718145


; URIDISD.ASM      URIDIUM Sound Driver      J.DAVE ROGERS. Liverpool. 1987.
;**************************************************************************
SOUNDCOD        EQU       40000     ;machine code load address. length 758
SOUNDATA        EQU       40760     ;datablock load address.   length 1430
;**************************************************************************
                 NOLIST
PITCHTAB        EQU       SOUNDATA        ;200 bytes
ENVSINDEX       EQU       PITCHTAB+200    ;70  bytes
TUNESINDEX      EQU       ENVSINDEX+70    ;104 bytes
ENVS            EQU       TUNESINDEX+110  ;304 bytes
TUNEBLOCS       EQU       ENVS+307        ;
envcounts       EQU 0    ;offsets within channel stores:
entcounts       EQU 2
envptr          EQU 4
entptr          EQU 6
env0            EQU 8
ent0            EQU 10
envadr          EQU 12
entadr          EQU 14
chanactive      EQU 16   ;1
maincount       EQU 17   ;1
dataptr         EQU 18   ;2
conptr          EQU 20   ;2
ptrrefr         EQU 22   ;2
pitchshift      EQU 24   ;1
noiseflag       EQU 25   ;1
noisedis        EQU 26   ;1
ch_enable       EQU 27   ;1
advolreg        EQU 28   ;2
stophang        EQU 30   ;1
                 ORG  SOUNDCOD
                 WRITE "URIDISD.BIN"
start           DEFL $
;------------------------------------------------------------------------------
JUMPBLOCK       JP PLAY          ;used for convenience in Basic Demo
                 JP SILENCE
POKE_BASIC      LD E,1           ;tunebloc
                 LD A,1           ;chan
                 JR STARTACHAN
;------------------------
;  "E" MUST CONTAIN THE NUMBER OF THE TUNEBLOC TO BE STARTED
;  CALL CH1, PUTS TUNE ON CHANNEL 1, CH2 = CHANNEL 2
;  CALL CHANALT, DYNAMICALLY ALLOCATES TO CHANS 2/3 ALTERNATELY
CH1             LD A,1
                 JR STARTACHAN
CH2             LD A,2
                 JR STARTACHAN
CHANALT         LD A,2
                 XOR 1
                 LD (CHANALT+1),A   ;A GOES 2,3,2,3....
STARTACHAN      LD IX,STORE1      ;E contains tunebloc num, A contains chan num
                 DEC A
                 JR Z ,IXfound
                 LD IX,STORE2
                 DEC A
                 JR Z,IXfound
                 LD IX,STORE3
IXfound         CALL FINDBLOC           ;RETURNS BLOCAD IN HL
                 LD   (IX+DATAPTR),L     ;set pointers for this channel
                 LD   (IX+DATAPTR+1),H
                 LD   (IX+CONPTR),L
                 LD   (IX+CONPTR+1),H
                 LD   (IX+PTRREFR),L     ;ptr refresh
                 LD   (IX+PTRREFR+1),H
                 LD (IX+CHANACTIVE),1
                 LD (IX+MAINCOUNT),1
                 LD A,0
                 LD (IX+PITCHSHIFT),A
                 LD (CHORUSFLAG),A
                 RET
;-----------------------
SILENCE         XOR A
                 LD  (STORE1+CHANACTIVE),A    ;channel-active-flags 0
                 LD  (STORE2+CHANACTIVE),A
                 LD  (STORE3+CHANACTIVE),A
                 LD (BUFF+8),A                ;volume registers 0
                 LD (BUFF+9),A
                 LD (BUFF+10),A
                 LD   A,1+2+4+8+16+32         ;all gates shut
                 LD   (BUFF+7),A              ;follow through to allregist
ALLREGIST       XOR  A
                 LD   HL,BUFF+13              ;register buffer
                 LD   DE, # F40D                ;D=Psg data port, E=counter
nextreg         LD   B,D
                 OUT  (C),E                   ;output register No
                 LD   BC,# F6*256+%11000000
                 OUT  (C),C                   ;tell PSG to latch reg No
                 OUT  (C),A                   ;PSG to inactive
                 LD   B,D
                 LD   C,(HL)                  ;C=register data
                 DEC  HL
                 OUT  (C),C                   ;output register data
                 LD   BC,# F6*256+%10000000
                 OUT  (C),C                   ;tell PSG to read reg data
                 OUT  (C),A                   ;PSG to inactive
                 DEC  E
                 JP   P,nextreg
                 RET
;------------
FINDBLOC        LD   A,E
                 ADD  A,A
                 ADD  A,TUNESINDEX AND # 00FF
                 LD   L,A
                 ADC  A,TUNESINDEX AND # FF00 /256
                 SUB  L
                 LD   H,A              ;HL now points to 2byte value in table
                 LD   E,(HL)
                 INC  HL
                 LD   D,(HL)           ;DE=value(offset)
                 LD HL,TUNEBLOCS
                 ADD HL,DE             ;HL=address of new tunebloc
                 RET
FINDENV         LD   A,E
                 ADD  A,A
                 ADD  A,ENVSINDEX AND # 00FF       ;16 bit add using 8 bit ops
                 LD   L,A
                 ADC  A,ENVSINDEX AND # FF00 / 256
                 SUB  L
                 LD   H,A              ;HL points to 2byte offset
                 LD   E,(HL)
                 INC  HL
                 LD   D,(HL)           ;DE=offset
                 LD HL,ENVS
                 ADD HL,DE             ;HL=envelope address
                 RET
;--------------------MAIN CALL--------EVERY 1/50 SECOND-----------------------
PLAY            CALL ALLREGIST     ;throw all buffer into sound chip registers
                 LD   IX,STORE1     ;---do channel 1 (IX points to chan1 store)
                 LD   IY,BUFF       ;  (IY holds addr of pitchstore for chan1)
                 CALL TESTCHAN
                 LD   IX,STORE2     ;---do channel 2
                 LD   IY,BUFF+2
                 CALL TESTCHAN
                 LD   IX,STORE3     ;---do channel 3
                 LD   IY,BUFF+4
                 CALL TESTCHAN
                 CALL DOENSE        ;do noise envelope
                 LD A,(CHORUSFLAG)  ;test if autochorus on
                 OR A
                 RET Z
                 LD HL,(BUFF)
                 LD BC,4
                 ADD HL,BC
                 LD (BUFF+4),HL
                 RET              ;-------------->>>>>>> out
;FOR EACH OF THE 3 CHANNELS:
TESTCHAN        LD  A,(IX+CHANACTIVE)   ;CHAN ACTIVE?
                 OR A
                 RET Z                   ;do nothing if channel not active
                 DEC  (IX+maincount)     ;duration countdown, new note when 0
                 JP NZ,DOENV_ENT
                 LD (IX+STOPHANG),30
READDECIDE      LD  H,(IX+dataptr+1)    ;get data ptr address
                 LD  L,(IX+dataptr)
DECI            LD   A,(HL)             ;A=peek(ptr)
                 INC  HL
                 LD   E,(HL)             ;E=peek(ptr+1)
                 INC HL                  ;inc and store ptr for next time
CONTPTR         LD (IX+DATAPTR+1),H
                 LD (IX+DATAPTR),L
                 DEC (IX+STOPHANG)
                 RET Z     ;gets out of possible endless loops after 30 passes
;-------------------------------------------------------------
; THE FOLLOWING ROUTINES RESPOND TO DATA AND JUMP BACK TO READDECIDE OR DECI,
; EVENTUALLY EXITING VIA "NEWNOTE" OR "KILLCHAN" ROUTINES
SUBSELECT       CP   0             ;A=VALUE
                 JP   Z,DOPAUSE     ;pitch 0 = pause
                 CP   101
                 JP   C,NEWNOTE     ;LESS THAN 100=normal note
                 CP   220
                 JP   C,SINGLENOTE
                 CP   228
                 JR   Z,NOISE       ;add noise to a note
                 CP   225
                 JR   Z,KILLCHAN    ;shut chan after e.g.short sound effects
                 CP   233
                 JR   Z,NEWENT      ;set new tone-envelope for current channel
                 CP   232
                 JR   Z,NEWENV      ;set new volume-env for current chan
                 CP   234
                 JR   Z,NEWENSE     ;set new noise-envelope
                 CP   229
                 JR   Z,GONEWBLOCK  ;play a given tunebloc,then return to 1st
                 CP   230
                 JR   Z,NEWKEY      ;change musical key for current chan
                 CP   235
                 JR   Z,CHORUSONOFF ;switch autochorus on or off
                 CP   255
                 JR   Z,RETCONBLOC  ;end-of-tunebloc marker
                 CP   252
                 RET  C        ;SAFETY NET
                               ;vals 252,253,254=follow through:
STARTLOOP       PUSH IX            ;252=STARTCHAN1, 253=CHAN2, 254=CHAN3
                 SUB 251            ;A=CHAN E=TUNEBLOC
                 CALL STARTACHAN
                 POP IX
                 JR READDECIDE
NOISE           LD   A,E
                 LD   (BUFF+6),A        ;noisepitch
                 LD   (IX+noiseflag),1
                 JR   DECI
NEWKEY          LD   (IX+pitchshift),E
                 JR   DECI
NEWENT          CALL FINDENV           ;returns with envelope address in HL
                 LD (IX+ENTADR),L
                 LD (IX+ENTADR+1),H
                 JR READDECIDE
NEWENV          CALL FINDENV
                 LD (IX+ENVADR),L
                 LD (IX+ENVADR+1),H
                 JR READDECIDE
NEWENSE         CALL FINDENV
                 LD (ENSSTORE+12),HL
                 JP READDECIDE
GONEWBLOCK      LD   (IX+conptr+1),H
                 LD   (IX+conptr),L    ;leaving bloc so store ptr
                 CALL FINDBLOC
                 JP   DECI
RETCONBLOC      LD   H,(IX+conptr+1)  ;(ptr re-enters original "conductor" bloc)
                 LD   L,(IX+conptr)
                 LD   A,(HL)
                 INC A                 ;TEST FOR 255,end-of-conductor-bloc marker
                 JR   NZ,NOTEND
                 LD   H,(IX+ptrrefr+1)        ;refresh
                 LD   L,(IX+ptrrefr)
notend          JP   DECI
KILLCHAN        LD (IX+CHANACTIVE),0
killvol         LD H,(IX+ADVOLREG+1)
                 LD L,(IX+ADVOLREG)     ;HL=address of vol register,current chan
                 LD (HL),0
                 RET
CHORUSONOFF     LD HL,CHORUSFLAG
                 LD (HL),E
                 JP READDECIDE
SINGLENOTE      AND 127
                 DEC HL
                 LD E,10
                 JP CONTPTR
NEWNOTE         ADD  A,(IX+pitchshift)       ;A=notenum
DOPAUSE         LD   (IX+maincount),E        ;E=duration
                 ADD  A,A                     ;get new pitch from pitchtable
                 ADD  A,PITCHTAB AND # 00FF
                 LD   E,A
                 ADC  A,PITCHTAB AND # FF00 /256
                 SUB  E
                 LD   D,A
                 LD   A,(DE)
                 LD   (IY+0),A        ;IY=address of pitchstore for current chan
                 INC  DE
                 LD   A,(DE)
                 LD   (IY+1),A
                 call killvol ;zero volume of current chan
                 PUSH IX              ;RESTART ENV/ent
                 POP  DE              ;DE=start of chan store
                 LD   HL,8
                 ADD  HL,DE           ;HL=start of chan store+8
                 LDI
                 LDI
                 LDI
                 LDI
                 LDI
                 LDI
                 LDI
                 LDI
                 DEC  (IX+noiseflag)      ;test noiseflag
                 LD  (IX+NOISEFLAG),0     ;RESET EVERY TIME!
                 LD  L,(IX+NOISEDIS)      ;DEFAULT DISABLE
                 JR   NZ,GATING
NOISEon         LD HL,(ENSSTORE+envadr)  ;restart noise envelope
                 LD (ENSSTORE+envptr),HL
                 LD HL,00
                 LD (ENSSTORE),HL         ;L=0,no noisedisable
GATING          LD   A,(BUFF+7)
                 AND  (IX+ch_enable)      ;chan ENable (pitch AND noise on)
                 OR   L                   ;noise DISable
                 AND 32+16+8+4+2+1        ;SAFETY, top 2 bits must remain off
                 LD   (BUFF+7),A          ;FINAL RESULT IN A!
;------------------------------------------------------
                            ;IX points to volume-env workspace for current chan
DOENV_ENT       CALL ENGENERAL         ;returns with "volume change+128" in C
                 LD   H,(IX+advolreg+1)
                 LD   L,(IX+advolreg)
                 LD   A,(HL)
                 ADD  A,C
                 SUB  128
                 LD   (HL),A
DOENT           INC  IX  ;make IX work on tone-envelope workspace,2 bytes along
                 INC  IX
                 CALL ENGENERAL         ;returns with "pitch change+128" in C
                 LD   H,(IY+1)          ;get pitch of note
                 LD   L,(IY+0)
                 LD A,H
                 OR L
                 RET Z         ;no ent if pitch zero(pause)
                 ADD  HL,BC
                 LD   C,128             ;deduct 128, allows negative changes
                 SBC  HL,BC
                 LD   (IY+1),H          ;replace in current channel pitch store
                 LD   (IY+0),L
                 RET
DOENSE          LD   IX,ENSSTORE       ;IX now = noise envelope workspace
                 CALL ENGENERAL         ;returns with "noise shift+128" in C
                 LD   A,(BUFF+6)        ;get current noise value
                 ADD  A,C
                 SUB  128               ;add shift, minus 128
                 LD   (BUFF+6),A        ;replace
                 CP 17
                 RET C
noiseoff        LD A,(BUFF+7)
                 OR 32+16+8
                 LD (BUFF+7),A
                 RET
ENGENERAL       PUSH IX       ;subroutine to do envelope and return value
                 POP  HL                ;points to counts
                 LD   D,(IX+ENVPTR+1)   ;points to envelope
                 LD   E,(IX+ENVPTR)
                 INC  (HL)              ;inc count
                 LD   A,(DE)
                 SUB  (HL)              ;compare to envelope
                 LD   BC,128             ;DEFAULT (C= 128 = 0 )
                 RET  NZ                ;count not reached
                 LD   (HL),A            ;A=0, resets count
                 INC DE                 ;move along envelope
                 LD  A,(DE)
                 LD  C,A                ;C HOLDS INCREMENT
                 INC  DE                ;point at repeats number
                 INC  HL
                 INC  (HL)              ;point at repeats count
                 LD   A,(DE)
                 SUB  (HL)              ;compare
                 RET  NZ                ;count not reached
                 LD   (HL),A            ;A=0, resets count;
                 INC  DE                ;move to next section of envelope
                 LD   A,(DE)
                 INC  A                 ;test for A=255 (end of envelope marker)
                 JR   NZ,nextsect
                 LD   D,(IX+envadr+1)   ;refresh ptr to start of envelope
                 LD   E,(IX+envadr)
nextsect        LD   (IX+envptr+1),D
                 LD   (IX+envptr),E
                 RET
;--------------------------------------------------------
BUFF      DW  00       ;a pitch     ;holds replica of sound chip registers
           DW  00       ;b pitch
           DW  00       ;c pitch
           DB  0        ;noise pitch
           DB  32+16+8  ;gates
           DB  0        ;a vol
           DB  0        ;b vol
           DB  0        ;c vol
           DW  100       ;hard env len
           DB  10        ;hard env type
CHORUSFLAG  DB  0
ensstore  DW 00 ;ENSCOUNTS    ;noise envelope workspace
           DW 10               ;dummy spacer to give same format as chan stores
           DW 00 ;ENSPTR
           DW 04
           DW 00 ;ENS0
           DW 18
           DW 00 ;ENSADR
;----------------------------------
;channel stores
STORE1    DW  00        ;env counts
           DW  00        ;ENT COUNTS
           DW  00        ;ENV PTR
           DW  00        ;ENT PTR
           DW  00        ;ENV ZEROERS
           DW  00        ;ENT ZEROERS
           DW  00        ;ENV ADDR
           DW  00        ;ENT ADDR
           DB  0         ;CHAN ACTIVE
           DB  0         ;MAIN COUNT
           DW  00        ;MAIN PTR
           DW  00        ;CON PTR
           DW  00        ;PTR REFRESH
           DB  0         ;PITCHSHIFT
           DB  0         ;NOISE FLAG
           DB   8        ;NOISE DIS
           DB  32+16+4+2 ;chan ENable
           DW  BUFF+8    ;AD OF VOL REG
           DB  0
STORE2  DW  00
         DW  00
         DW  00
         DW  00
         DW  00
         DW  00
         DW  00
         DW  00
         DB  0
         DB  0
         DW  00
         DW  00
         DW  00
         DB  0
         DB  0
         DB  16        ;NOISE DIS
         DB  32+8+4+1  ;chan ENable
         DW  BUFF+9    ;AD OF VOL REg
         DB  0
STORE3  DW  00
         DW  00
         DW  00
         DW  00
         DW  00
         DW  00
         DW  00
         DW  00
DB  0
         DB  0
         DW  00
         DW  00
         DW  00
         DB  0
         DB  0
         DB  32       ;NOISE DIS
         DB  16+8+2+1 ;CHAN ENABLE
         DW  BUFF+10  ;AD OF VOL REG
         DB  0
;------------------------------------------------
FINISH          DEFL $
                 LIST
                 CLOSE
START           DEFL START
FINISH          DEFL FINISH
LENGTH          DEFL FINISH-START

Zoe Robinson

Does anyone else get the impression that Hewson intended to fix the bug to put out a full-price release on CPC, never got around to it, forgot and then went ahead with the bugged version as a budget "re-release"? Because I have a feeling that might have happened.

andycadley

Yes, I wondered if it just failed QA and got sidelined, but when it came to re-release time everyone just assumed it must be ok and shipped it as is. Henson always seemed quite good at quality control and it seems weird it shipped that buggy.

JayBlood

Jay

Powered by SMFPacks Menu Editor Mod