NyanSIDBBCMicroDevDiary

From Retrosoftware

(Difference between revisions)
Jump to: navigation, search
(Jan-Feb 2012 - "''The Music''")
(Week 2: 20-25 Feb 2012 - "''Writing the Game''")
Line 144: Line 144:
==Week 2: 20-25 Feb 2012 - "''Writing the Game''"==
==Week 2: 20-25 Feb 2012 - "''Writing the Game''"==
-
 
+
<span style="font-variant:small-caps; font-weight:bold;">Mon 20 Feb 2012: Writing the Game</span><br/>
-
<span style="font-variant:small-caps">Mon 20 Feb 2012: Writing the Game</span><br/>
+
Draw the rainbow, stars and animated the cat. I count frames to see how fast it runs and display that as dashes at the top of the screen.
-
Draw the rainbow.<br/>
+
-
Draw the stars.<br/>
+
-
Animate the cat.
+
-
 
+
-
I count frames to see how fast it runs and display that as dashes at the top of the screen.
+
-
 
+
The frame rate is ok until I draw the rainbow then it drops to 3/50ths.... This is a shame because I know moving to hardware scrolling is going to be a pain.
The frame rate is ok until I draw the rainbow then it drops to 3/50ths.... This is a shame because I know moving to hardware scrolling is going to be a pain.
- 
<center>[[Image:Nyan_2012_02_20.png|320px]]</center>
<center>[[Image:Nyan_2012_02_20.png|320px]]</center>
-
 
+
<span style="font-variant:small-caps; font-weight:bold;">Tue 21 Feb 2012: Speeding it up - Using Hardware Scrolling</span><br/>
-
<span style="font-variant:small-caps">Tue 21 Feb 2012: Speeding it up - Using Hardware Scrolling</span><br/>
+
It now runs a lot faster but the cat leaves a trail.
It now runs a lot faster but the cat leaves a trail.
- 
<center>[[Image:02-21-tue.png|320px]]</center>
<center>[[Image:02-21-tue.png|320px]]</center>
-
 
+
<span style="font-variant:small-caps; font-weight:bold;">Wed 22 Feb 2012: Hardware Scrolling</span><br/>
-
<span style="font-variant:small-caps">Wed 22 Feb 2012: Hardware Scrolling</span><br/>
+
Add the rainbow back - now with hardware scrolling it takes no time - I just have to clear a rectangle at the edge of the screen every frame.<br/>
Add the rainbow back - now with hardware scrolling it takes no time - I just have to clear a rectangle at the edge of the screen every frame.<br/>
Fix the sprite routine screen wrap.<br/>
Fix the sprite routine screen wrap.<br/>
I gain some more speed when I draw the cat in one pass with a special double height sprite drawer instead of two passes with the original drawer.
I gain some more speed when I draw the cat in one pass with a special double height sprite drawer instead of two passes with the original drawer.
-
 
+
Add the stars. I discover drawing one star per frame is a lot a faster than drawing all 8!
-
Add the stars.
+
-
 
+
-
I discover drawing one star per frame is a lot a faster than drawing all 8!
+
-
 
+
<center>[[Image:02-22-wed.png|320px]]</center>
<center>[[Image:02-22-wed.png|320px]]</center>
-
 
+
<span style="font-variant:small-caps; font-weight:bold;">Thu 23 Feb 2012: Running out of memory</span><br/>
-
<span style="font-variant:small-caps">Thu 23 Feb 2012: Running out of memory</span><br/>
+
Add print_byte. I need to add a character set - 10 characters at 4x5 pixels means +120 bytes I find this nifty code to print a hex digit - it manages to print 0-9 and A-F without any jumps!
-
 
+
-
Add print_byte.
+
-
 
+
-
I need to add a character set - 10 characters at 4x5 pixels means +120 bytes I find this nifty code to print a hex digit - it manages to print 0-9 and A-F without any jumps!
+
Line 245: Line 227:
-
Throwing away bootup code (Fri 24 Feb 2012 )
+
<span style="font-variant:small-caps; font-weight:bold;">Throwing away bootup code (Fri 24 Feb 2012 )</span><br>
Previously I had the program load in two parts - $400-$800 and $900-$3000. This is because all the memory from $400-$3000 can be used by the game except $800-$900 which is used by the OS's sound system. I load the $400 section directly in at $400 and the $900 in at $1900 and then relocate it. So the loader program sits at $4000 and has bootup code in it that is only called once and can be thrown away thus saving a bit of memory.
Previously I had the program load in two parts - $400-$800 and $900-$3000. This is because all the memory from $400-$3000 can be used by the game except $800-$900 which is used by the OS's sound system. I load the $400 section directly in at $400 and the $900 in at $1900 and then relocate it. So the loader program sits at $4000 and has bootup code in it that is only called once and can be thrown away thus saving a bit of memory.
Anyhow I decide it's simipler to load program as one file from $400-$3000 and then just let the OS overwrite page 8 later.
Anyhow I decide it's simipler to load program as one file from $400-$3000 and then just let the OS overwrite page 8 later.
This means I now move my loader code up to $4500. I move more bootup code up into the loader region and save 128 bytes! \
This means I now move my loader code up to $4500. I move more bootup code up into the loader region and save 128 bytes! \
-
Speed - Timing the code (Sat 25 Feb 2012 )
+
<span style="font-variant:small-caps; font-weight:bold;">Speed - Timing the code (Sat 25 Feb 2012 )</span><br>
Display the time taken at the top of the screen.
Display the time taken at the top of the screen.
Measure the frame rate with a hardware counter.
Measure the frame rate with a hardware counter.
Line 261: Line 243:
</pre>
</pre>
I find when the counter hits around $20 the game takes longer than a 1/50th and the screen gets all corrupted.
I find when the counter hits around $20 the game takes longer than a 1/50th and the screen gets all corrupted.
-
I add RTW's hardware keyscan code and gain about 5 ticks - amazing speed increase!
+
I add RTW's hardware keyscan code from these forums: and gain about 5 ticks - an amazing speed increase!
-
+
http://www.retrosoftware.co.uk/wiki/index.php/Reading_the_keyboard_by_direct_hardware_access
-
Out of Memory again - Finding dead code (Sun 26 Feb 2012 )
+
<span style="font-variant:small-caps; font-weight:bold;">Out of Memory again - Finding dead code (Sun 26 Feb 2012 )</span><br>
I change Beebem to count when each address is used by the processors PC. Using this info I can see what code is never used or only used a little. This helps me get some bytes back by deleting unused code and moving other code used only once into the 'throw away' bootup area.
I change Beebem to count when each address is used by the processors PC. Using this info I can see what code is never used or only used a little. This helps me get some bytes back by deleting unused code and moving other code used only once into the 'throw away' bootup area.

Revision as of 11:15, 3 May 2012

Contents

Nyan SID

The development diary for Nyan SID - a quick little mini game with SID and BBC music.
Maybe not as quick as I thought it was going to be.


Sept 2011 - "The Beginning"

Mon 19 Sept 2011: A Funny Demo
Lion posts a video of a BBC Demo called Nyan Cat over on the Stardot forums:

Link Here

What the hell is Nyan Cat I think?
I soon discover it comes from an animated gif called 'Pop Tart Cat' by prguitarman: http://www.prguitarman.com

And then somebody else added some music and posted the result on YouTube: http://www.youtube.com/watch?v=QH2-TGUlwu4

I think the music makes it!
Anyhow it occurs to me this will make the perfect starter project - I've been meaning to write a proper Mode2 game for some time and even had a couple of goes that have ended up unfinished.

Since the scope of this is a lot smaller maybe I'll be able to complete it this time.

And Sir Morris asks for a BeebSID version - no problem I figure!

Nov 2011 - "Midi 2 SID"

Sat 26 Nov 2011: Making some music
I try converting a midi file to run on the BBC SID chip. My very first test is a 3 channel Tetris tune. I convert the midi format into a 3 byte format: TIME, FREQ, CHANNEL. I also add a SID envelope editor so I can change the sound - the result sounds very BBC-ish, unfortunately not as impressive as the existing SIDs. There must be some other magic that makes existing SID tunes sound so good.

Image:Midi2sid.jpg

Dec 2011 - "Proving the Game"

Wed 14 Dec 2011: Detecting the SID chip
I want to be able to detect if the SID chip is there so can automatically use it to play the music or switch to the standard BBC. I ask around on the forums and MartinB comes to the rescue. http://www.retrosoftware.co.uk/forum/viewtopic.php?f=73&t=712 The method is to play a noise sound on channel#3 and pick up the output from a special register to see if it changes - if it doesn't then the SID is not present.

._IS_SID_PRESENT:
	;   set master volume to zero
        LDA	#0
	STA 	SD_VOLUME

	;// set freq of channel 3
	LDX	#24
	LDA	FreqTablePalLo,X
	STA	SD_FREQL_3
        LDA	FreqTablePalHi,X
	STA	SD_FREQH_3

	;// play a noise sound
       	LDA	#$81
       	STA 	SD_CNTRL_3

	LDA	SID_OUTPUT
	STA	firstvalue

	LDX	#0
.loop44:
	LDA	SID_OUTPUT
	CMP	firstvalue
	BNE	gotsid
	INX
	BNE	loop44
	LDA	#0
	RTS

.gotsid:LDA	#1
	RTS


Thu 15 Dec 2011: The Sprites
Time to start the game. I get the cat frames from a gif.


Fri 16 Dec 2011: The Game - on the PC
Now I have all the elements - the cat and star sprites - I write the game in 'c' on the pc to see if it will work.

It's pretty simple - you have three stars - neutral, good and bad. Bad sucks energy from you, good boosts your energy. When you're out of energy the game ends. The time you survive is your score.

Image:Pc_nyan.png

Jan-Feb 2012 - "The Music"

Sun 29 Jan 2012: Envelope Explorer
I've got a program called Envelope Explorer as a way to test different pre-defined envelopes. I can select one for 64 envelopes to find the best match. I modify it a little to edit the envelope values and it plays a tune in the background so I can pick the best sounding envelopes.

Image:Envexp.jpg


Sat 04 Feb 2012: Getting some Midi
I've been using a nyan midi I had found but then come upon a SNES .FTM version that I think sounds better. Converting it involves changing the FTM into a NFS in FamiTracker and then to the midi. For some reason only one track comes through, but as a bonus this version of the music has the intro tune as well.


Sun 05 Feb 2012: More Midi
I'm using Famitracker to play the orginal .FTM file.

http://famitracker.com/
I discover this program will not save a midi file but can output a midi stream. To capture this stream I have to use another program called 'Midi Yoke'. This program will enable other programs to pick up the stream. I then use a third program called 'WinJammer' to pick up the midi stream and save it out as midi. Phew - what a load of messing about, anyway I now have a full 4 track version of the music. The first thing I do is remove the drum track as I want at least 1 channel free on the BBC to play sound sound effects.


Tue 07 Feb 2012: Loop the Music
Get the music to loop correctly. Get it to play the intro only once.

Sat 11 Feb 2012: Envelopes
Experimenting with different envelopes for the SID tune. I write a program to test what the filter does. The Duty wave is quite good a making a buzzing type sound. The lowpass filter makes the sound less electronic and more 'natural' I notice existing SIDs will often change the cutoff frequency dynamically but I don't do that, I just have to select a cutoff frequency above all the notes in my particular track - in this case the bass track.

Image:Sidplayerb.jpg

Tue 14 Feb 2012: SID File Creator
Another way to test sid envelopes. This time I create a C64 sid file directly that I can play on the pc sidplayer.exe This program helps me change and see what the envelope parameters are. It's actually faster to use than creating a BBC disk each time and playing that through an emulator. Talking of emulators I normally use Beebem to develop with over B-em as it autoruns the disk and so is a little quicker to use with lots of iterations, the big disadvantage being it doesn't play SID music of course - so I fact I end up using both emulators! I decide on a slow die off for the backing track and a square wave like one for the lead with a but of duty to give it a bit of a buzz.


Sat 18 Feb 2012: Finishing the Music
Finally I'm happy with all the envelopes so the BBC and SID tunes are finished!
Now it's time to think about the graphics code.

I use Francis G. Loch's BBC Micro Image Converter to make a background picture from the original gif.

Week 1: 14-19 Feb 2012 - "Starting the Graphics"

Sun 19 Feb 2012: Starting the Graphics
To start I set a Mode2 screen and load a picture into screen memory. Then I grab Steve O'Learys sprite routine from: http://www.retrosoftware.co.uk/wiki/index.php/Basic_Sprite_plotter and draw the cat sprite. As my pixels are double height I modify the routine to double space the lines. It's a real shame I can't put the video chip into some sort of line double mode - then drawing sprites would be twice as fast and I'll have lots of free memory - oh well... Then I add some keyboard reading so I can move the cat around the screen.

Image:Nyan_2012_02_19.png

Week 2: 20-25 Feb 2012 - "Writing the Game"

Mon 20 Feb 2012: Writing the Game
Draw the rainbow, stars and animated the cat. I count frames to see how fast it runs and display that as dashes at the top of the screen. The frame rate is ok until I draw the rainbow then it drops to 3/50ths.... This is a shame because I know moving to hardware scrolling is going to be a pain.

Tue 21 Feb 2012: Speeding it up - Using Hardware Scrolling
It now runs a lot faster but the cat leaves a trail.

Wed 22 Feb 2012: Hardware Scrolling
Add the rainbow back - now with hardware scrolling it takes no time - I just have to clear a rectangle at the edge of the screen every frame.
Fix the sprite routine screen wrap.
I gain some more speed when I draw the cat in one pass with a special double height sprite drawer instead of two passes with the original drawer. Add the stars. I discover drawing one star per frame is a lot a faster than drawing all 8!

Thu 23 Feb 2012: Running out of memory
Add print_byte. I need to add a character set - 10 characters at 4x5 pixels means +120 bytes I find this nifty code to print a hex digit - it manages to print 0-9 and A-F without any jumps!


._PRINT_DIGIT:                                                 
        SED             ;Enter BCD mode                        
        CLC             ;Ensure the carry is clear             
        ADC  #$90       ;Produce $90-$99 (C=0) or $00-$05 (C=1)
        ADC  #$40       ;Produce $30-$39 or $41-$46            
        CLD             ;Leave BCD mode                        
        JSR  _PRCHAR                                           
        RTS                                                    


http://www.obelisk.demon.co.uk/6502/algorithms.html

Fix a screen boundary address wrap bug in the sprite drawer - as the screen now has hardware scrolling addresses above $8000 have to wrap back to $3000.
Move the init code high in memory so it's only used once.
Sort and display the map file to see what's using all the memory.
The stars are not very random so I find a new random routine that does a better job:

._RANDOM: TXA
	PHA
	TYA
	PHA
	LDA #1              ; store 1 in TMP
        LDX #3
.RAND1  STA TMP,X
        LSR A
        DEX
        BPL RAND1
        LDY #$20            ; calculate SEED = SEED * RAND4 + TMP
        BNE RAND5           ; branch always
.RAND2  BCC RAND4           ; branch if a zero was shifted out
        CLC                 ; add multiplier to product
        LDX #3
.RAND3  LDA TMP,X
        ADC RAND6,X
        STA TMP,X
        DEX
        BPL RAND3
.RAND4  ROR TMP             ; shift result right
        ROR TMP+1
        ROR TMP+2
        ROR TMP+3
.RAND5  ROR SEED3           ; shift out old seed, and shift in new seed
        ROR SEED2
        ROR SEED1
        ROR SEED0
        DEY
        BPL RAND2
	PLA
	TAY
	PLA
	TAX
	LDA	SEED3
        RTS
RAND6    DB  $00,$19,$66,$0D ; multiplier (high byte first!)


http://6502.org/source/integers/random/random.html
Actually on their page theres a bug I think - mixing up ADC RAND4,X when it should be ADC RAND6,X The stars are now good.


Throwing away bootup code (Fri 24 Feb 2012 )
Previously I had the program load in two parts - $400-$800 and $900-$3000. This is because all the memory from $400-$3000 can be used by the game except $800-$900 which is used by the OS's sound system. I load the $400 section directly in at $400 and the $900 in at $1900 and then relocate it. So the loader program sits at $4000 and has bootup code in it that is only called once and can be thrown away thus saving a bit of memory. Anyhow I decide it's simipler to load program as one file from $400-$3000 and then just let the OS overwrite page 8 later. This means I now move my loader code up to $4500. I move more bootup code up into the loader region and save 128 bytes! \

Speed - Timing the code (Sat 25 Feb 2012 )
Display the time taken at the top of the screen. Measure the frame rate with a hardware counter.

	LDA	$FE45
	STA	clk1
	JSR	_MAINLOOP
	LDA	$FE45
	STA	clk2

I find when the counter hits around $20 the game takes longer than a 1/50th and the screen gets all corrupted. I add RTW's hardware keyscan code from these forums: and gain about 5 ticks - an amazing speed increase! http://www.retrosoftware.co.uk/wiki/index.php/Reading_the_keyboard_by_direct_hardware_access

Out of Memory again - Finding dead code (Sun 26 Feb 2012 )
I change Beebem to count when each address is used by the processors PC. Using this info I can see what code is never used or only used a little. This helps me get some bytes back by deleting unused code and moving other code used only once into the 'throw away' bootup area.

Week 3: 27-04 March 2012 - "Hardware Sounds"

I want to add a energy bar at the bottom of the screen but the processor has no free cycles. As reading the keyboard is a lot faster than using the OS I think doing the same thing for the sounds might help as well.

I get the following code to succesfully make some sounds and integrate it into the music player. The only problem is now I have no envelope control and even have to turn the sounds off myself - luckily I have some memory spare in which to fit all the new code. This code comes from the Advance User Guide.

._MAKE_SOUND:	SEI
		LDA 	#&FF      ;// PortB set as output
		STA 	&FE43

		LDA	Midi2Bbc_Low,X
		ORA	#&80
	        JSR	_DIRECT0

		LDA	Midi2Bbc_High,X
	        JSR	_DIRECT0

		LDA	#&90  	 ;// volume
		JSR	_DIRECT0

		CLI
		RTS



._DIRECT0:    	STA	&FE41  	;// Set volume or frequency

	        LDA	#0
	     	STA	&FE40	;// Output register B
	     	NOP
	        NOP
	     	NOP
	        NOP
		NOP
	        LDA	#8
	     	STA	&FE40	;// Output register B

		RTS


Thu 01 Mar 2012: Need more memory - Grabbing Page 8
As I'm not using OSWORD to make sounds anymore I should get able to use the memory from $800-$8FF for my own purposes. However I find this area is getting corrupted even if I'm not making any sounds. Eventually I set the IRQ vector to turn of the OS before I relocate my code downwards and this fixes it - I guess the OS is processing sound even if you can't hear anything...

Fri 02 March 2012: Writing the Envelopes Myself
I add code to create envelopes as the OS is no longer there to do it for me - I have a table of volumes I set every 50th of a second. Then the next day I rewrite the envelope routine: I change it to use four ADSR rate bytes so it uses less memory. It's almost like the standard Acorn Envelopes now as well except I update mine at 50Hz and they did theirs at 100Hz.

Week 4: 5-11 March 2012 - "HiScore"

Week 5: 12-18 March 2012 - "A Memory Breakthrough!"

Week 6: 19-24 March 2012 - "Hardware Palette"

Week 7: 26-1 April 2012 - "Hardware Envelopes"

Week 8: 2-8 April 2012 - "New Cat Sprite"

Week 9: 9-15 April 2012 - "Fixes"

Week 10: 16-22 April 2012 - "Almost Finished"

Fri 20 Apr 2012: Almost Finished
Almost finished but the sprite tearing isn't so good.Not sure what to do about that. I have a look at the other games here like Harry and Jungle but they don't seem to be doing anything to avoid tearing but they still look fine - strange.

Image:Nyan_2012_04_20.png




I set the background palette to cyan at the start of vblank, dark blue when I start to draw the cat and magenta when I've finished (with STA $FE21) . This is a pretty good trick as it's really fast and easy to see. Drawing the cat takes a very long time - over half the frame! It is pretty big at 36x42 pixels.

Image:Nyan_2012_04_21_timea.png




I rewrite the draw routine to be a little faster. The blue area gets smaller as a result.

Image:Nyan_2012_04_21_timeb.png




I add a timer interrupt which goes off on the y line after the cat - (I set the timer in vblank to be a different amount depending on the y position of the cat) This removes the tear as the scanlines the cat is drawn at have already been refreshed. However the cat draw still takes a lot of time so you then can't avoid the tear sometimes.

Image:Nyan_2012_04_21_timec.png


Week 11: 27-29 April 2012 - "The End"

I work on the waves a little more to give the game more structure. Tweak their positions so they match where the player can move to. I run out of memory again, but find some dead code I can delete and finally fit my 8 level types in 64 bytes. I have to clean up the uniform to random wave transition by making sure the stars delete themselves and increase the red star frequency so you die a little quicker. I add a loading page and after some final testing - it's posted!