I've spent twenty minutes today adding a *tiny* (and simple) little intro screen to the game before the main title screen appears. This intro displays information about the type of machine the game is being played on as detected by the code added yesterday in the previous diary entry here...
This intro informs the user the machine type being used (PAL or NTSC) and the fact that the music and sound was designed for an 8580 SID chip.
It also gives me a chance to use the 'Cosine' sprites that I designed months ago and that have been languishing in the sprite bank unseen and unused up until now! The sprites and messages look a little like this when running in WinVICE using NTSC...
Obviously, the message changes to PAL if such a machine is being used.
I'll own up to hacking my own code a bit! The game essentially uses two 'modes', title screen on or title screen off, which is stored in a label called 'title_mode'. When title screen is off, the game is in play - the two modes use slightly different code branches. For example, the colour washing of text on the title screen is handled in one of my IRQ splits, but when the title screen mode is off, the colour washing code is skipped.
However, for this little intro and for various reasons, I need to run a little portion of title screen code and a little portion of game screen code, so there is now an intro check to skip or add certain elements and I admit to doing this in a quite hacky, yucky way! It works, but I may need to recode this as it's stirring my OCD tendencies!
Next diary entry...
Showing posts with label code. Show all posts
Showing posts with label code. Show all posts
Friday, 6 March 2020
Thursday, 5 March 2020
NTSC
I'm guessing that this little game of mine will mainly appeal to people in Europe (hopefully!), but since I'm part of a C64 group (Arkanix Labs) that is U.S. and therefore NTSC based as well as a U.K. and PAL based group (Cosine Systems), I would feel a little disloyal towards my American cousins if I didn't include compatibility for NTSC systems.
If you don't know anything about NTSC, then do some research possibly by starting here...
Basically, NTSC machines run at 60Hz instead of 50Hz as on PAL. Also, they have fewer display scanlines, 262 versus 312. For my game, this means that my blue top border I wanted for 2 levels and which works nicely under PAL (see diary entry here...), starts waaay too early on NTSC and appears at the bottom of the screen, something like this...
To combat this, I've included an extra IRQ split in the top border. Thus, the first IRQ split colours the background (therefore border area) black to eliminate the blue at the bottom of the screen under NTSC and the second IRQ split, which starts just as a PAL machine begins displaying the visible area of the top display, then colours the background blue.
Miraculously, this seemed to work! Well, in WinVICE at least - I'll have to wait for my NTSC friends to test on real hardware for me and report back to be sure! At present, it now look like this under NTSC in WinVICE...
Adding an additional split did have a knock on effect on some other timings; since the NTSC display has less screen time to execute in it seems, the title screen code was over-running and everything was slow and flickery. A little rearrangement of some of my IRQ code later and all was back up to speed!
The other NTSC issue is the music. Since NTSC machines run slightly quicker, the music was playing too fast and sounded awful. Therefore, I've coded up a timer/counter that skips calling the music driver every few frames thereby slowing it down. Of course, the game needs to know what type of machine it is running on, so I've now included a check at the start of the code to do this.
I've used a modified version of code that was posted on CSDb so thanks to all those involved in that discussion and who shared code, which you can find here...
Next diary entry...
If you don't know anything about NTSC, then do some research possibly by starting here...
Basically, NTSC machines run at 60Hz instead of 50Hz as on PAL. Also, they have fewer display scanlines, 262 versus 312. For my game, this means that my blue top border I wanted for 2 levels and which works nicely under PAL (see diary entry here...), starts waaay too early on NTSC and appears at the bottom of the screen, something like this...
To combat this, I've included an extra IRQ split in the top border. Thus, the first IRQ split colours the background (therefore border area) black to eliminate the blue at the bottom of the screen under NTSC and the second IRQ split, which starts just as a PAL machine begins displaying the visible area of the top display, then colours the background blue.
Miraculously, this seemed to work! Well, in WinVICE at least - I'll have to wait for my NTSC friends to test on real hardware for me and report back to be sure! At present, it now look like this under NTSC in WinVICE...
Adding an additional split did have a knock on effect on some other timings; since the NTSC display has less screen time to execute in it seems, the title screen code was over-running and everything was slow and flickery. A little rearrangement of some of my IRQ code later and all was back up to speed!
The other NTSC issue is the music. Since NTSC machines run slightly quicker, the music was playing too fast and sounded awful. Therefore, I've coded up a timer/counter that skips calling the music driver every few frames thereby slowing it down. Of course, the game needs to know what type of machine it is running on, so I've now included a check at the start of the code to do this.
I've used a modified version of code that was posted on CSDb so thanks to all those involved in that discussion and who shared code, which you can find here...
Next diary entry...
Wednesday, 4 March 2020
Player Characteristics
I still need to calculate coordinate locations for crosses on many levels and seem to be putting this off at the moment, mainly down to the fact I find it rather boring...
However, I'm putting this task off by actually tweaking and/or adding code to other sections! Honest!
The girl finally became 'properly' selectable/playable the other day and until now has shared characteristics with the boy. But no longer! I've altered certain variables so that when the girl or boy are selected they handle slightly differently.
The boy is slightly 'stronger' than the girl - he can be in contact with enemies or dangerous parts of the scenery for just a few milliseconds longer before experiencing an energy drain.
The girl is slightly 'lighter' than the boy - although she can jump no higher, she can stay in the air just a few milliseconds longer than the boy, making it a tiny bit easier to successfully make the longer jumps between platforms on some levels.
Those differences above are only subtle, but does give the player some choice as to how to play - do you choose easier jumps or more strength? No doubt the variables will be altered further once play testers get their hands on the game and maul my efforts to death, but it will be easy for me to change in the code now since it's all handled by a couple of labels.
I've also finally got round to moving my screen splits slightly to accommodate the fact that on two of the levels (Level 3 - The Apartments and Level 7 - The Park, if you're interested!) I've used a blue background.
I wanted to 'extend' the blue sky background into the upper border, an easy task since the top border is open, but not-to-hot looking because the split was in the wrong place, therefore the blue colour 'bled' too far down the screen. Also, the blue was appearing on levels where the background and top border should have been black.
It was simple fix in the end - the two levels needing a blue top border set a flag telling my top border split to colour itself blue, otherwise colour itself black. The result on Level 3 looks like this...
Next diary entry...
However, I'm putting this task off by actually tweaking and/or adding code to other sections! Honest!
The girl finally became 'properly' selectable/playable the other day and until now has shared characteristics with the boy. But no longer! I've altered certain variables so that when the girl or boy are selected they handle slightly differently.
The boy is slightly 'stronger' than the girl - he can be in contact with enemies or dangerous parts of the scenery for just a few milliseconds longer before experiencing an energy drain.
The girl is slightly 'lighter' than the boy - although she can jump no higher, she can stay in the air just a few milliseconds longer than the boy, making it a tiny bit easier to successfully make the longer jumps between platforms on some levels.
Those differences above are only subtle, but does give the player some choice as to how to play - do you choose easier jumps or more strength? No doubt the variables will be altered further once play testers get their hands on the game and maul my efforts to death, but it will be easy for me to change in the code now since it's all handled by a couple of labels.
I've also finally got round to moving my screen splits slightly to accommodate the fact that on two of the levels (Level 3 - The Apartments and Level 7 - The Park, if you're interested!) I've used a blue background.
I wanted to 'extend' the blue sky background into the upper border, an easy task since the top border is open, but not-to-hot looking because the split was in the wrong place, therefore the blue colour 'bled' too far down the screen. Also, the blue was appearing on levels where the background and top border should have been black.
It was simple fix in the end - the two levels needing a blue top border set a flag telling my top border split to colour itself blue, otherwise colour itself black. The result on Level 3 looks like this...
Next diary entry...
Monday, 13 January 2020
Level 3 Insertion
A fair few months ago, I started to design Level 3 for the game (see blog post here). Up until yesterday, it only existed in my screen editor, but I've finally exported the screen and colour ram data and inserted it into the game, along with the code to set-up and call the level.
Since this level has been languishing for a while, I thought it deserved some habitation, so I've also added some data to the enemy table for this level and there are now various baddies crawling and flying around. I still need to add some x and y data for the cross locations; currently the data table contains my stand-by data that only contains 2 locations that strobe back and forth.
Once it was all up and running, I wanted more screen action, but in a subtle way. I've seen a couple of games recently that have rain in the background (it seems fashionable to have rain in your game at present and, at time of writing, appropriate given the weather outside) so I decided this level shall have rain!
I must also admit to having watched Simon Jameson's Twitch channel the other night where he demonstrated how he had implemented rain in his game and this also provided the idea and motivation for me to include rain in Chiller 2. However, I wanted a much simpler solution for my game compared to Simon's code, so decided to go with the 'copying char data around' route rather than the pixel plotting through a char route he demonstrated.
So, to start I set aside 5 sequential chars that will be used for the rainfall and plotted a 1,2,3,4,5 repeating sequence in columns using these chars. In the editor to begin with, the rain looked a little like this...
I did my very best to ensure it looked 'random', with columns of chars that were near or adjacent to each other not having identical numbers that were in-line (1's in line with other 1's, 2's next to other 2's and so on) - not doing this would have resulted in very unnatural looking rainfall methinks! Once I was happy with the layout, I cleared the chars themselves of the numbers, knowing the chars were still actually in place on the screen.
I then designed a simple raindrop, not in the editor, but on a scrap piece of paper which I then turned into a table of hex bytes. If you're interested, that table of data looks a little like this within my code...
And then it was time to code a very simple rainfall by copy my raindrop pattern above into each char sequentially. The code I came up with looks a little like this (please note, this is wholly unoptimised at present but was written this way to ensure it could be followed in the future by me!):
What's happening? Well, when this routine is called, first of all I'm clearing all five rain chars to erase any previously drawn chars (this could be optimised to clear only the last previously drawn char!). Then, using a 'variable' that stores which raindrop we're on (it starts with '0'), the code determines which char should be drawn to next and jumps to the drawing code for that char and copies the raindrop pattern data pattern into that char's memory location. The code then jumps to a label called 'draw_rain_dun' which increases the raindrop variable and then checks to see if all five chars have been drawn to in sequence. If they have all been drawn to sequentially over the course of the routine being called a few times (i.e. the fifth raindrop char was last drawn to), the code resets the raindrop variable to '0' so next run through the raindrop pattern is drawn to the first char again.
Hopefully that makes sense?! Of course, this code is also inside a timer that executes it (at present) once every 4th frame. Without the timer that rain would, er, rain too fast!
To be honest, if this code was applied to the whole screen and not just the top of the buildings as in my level, it would probably look pretty jerky. However, in the context of my level and game, it has a nice cartoony feel that I'm very happy with! What does it look like? Something like this...
Next diary entry...
Since this level has been languishing for a while, I thought it deserved some habitation, so I've also added some data to the enemy table for this level and there are now various baddies crawling and flying around. I still need to add some x and y data for the cross locations; currently the data table contains my stand-by data that only contains 2 locations that strobe back and forth.
Once it was all up and running, I wanted more screen action, but in a subtle way. I've seen a couple of games recently that have rain in the background (it seems fashionable to have rain in your game at present and, at time of writing, appropriate given the weather outside) so I decided this level shall have rain!
I must also admit to having watched Simon Jameson's Twitch channel the other night where he demonstrated how he had implemented rain in his game and this also provided the idea and motivation for me to include rain in Chiller 2. However, I wanted a much simpler solution for my game compared to Simon's code, so decided to go with the 'copying char data around' route rather than the pixel plotting through a char route he demonstrated.
So, to start I set aside 5 sequential chars that will be used for the rainfall and plotted a 1,2,3,4,5 repeating sequence in columns using these chars. In the editor to begin with, the rain looked a little like this...
I did my very best to ensure it looked 'random', with columns of chars that were near or adjacent to each other not having identical numbers that were in-line (1's in line with other 1's, 2's next to other 2's and so on) - not doing this would have resulted in very unnatural looking rainfall methinks! Once I was happy with the layout, I cleared the chars themselves of the numbers, knowing the chars were still actually in place on the screen.
I then designed a simple raindrop, not in the editor, but on a scrap piece of paper which I then turned into a table of hex bytes. If you're interested, that table of data looks a little like this within my code...
; raindrop pattern
rain_patt !byte $ff,$ef,$ff,$ff,$ef,$ff,$ef,$ff
And then it was time to code a very simple rainfall by copy my raindrop pattern above into each char sequentially. The code I came up with looks a little like this (please note, this is wholly unoptimised at present but was written this way to ensure it could be followed in the future by me!):
l3_bkgrd_anim ; level 3 rain
; clear all raindrops first
ldx #$00
lda #$ff ; char needs to be solid!
clear_rain
sta $2400,x ; raindrop 1
sta $2408,x ; raindrop 2
sta $2410,x ; etc
sta $2418,x
sta $2420,x
inx
cpx #$08 ; all 8 bytes of each char cleared?
bne clear_rain ; no? branch back
; now check which raindrop should be drawn!
lda raindrop ; which raindrop are we on?
cmp #$00 ; drop '0'?
bne *+$05 ; no? go and check drop '1'
jmp draw_rain0 ; yes? go draw rain0!
cmp #$01
bne *+$05
jmp draw_rain1
cmp #$02
bne *+$05
jmp draw_rain2
cmp #$03
bne *+$05
jmp draw_rain3
cmp #$04
bne *+$05
jmp draw_rain4
draw_rain0
ldx #$00
rain0_loop
lda rain_patt,x
sta $2400,x
inx
cpx #$08
bne rain0_loop
jmp draw_rain_dun
draw_rain1
ldx #$00
rain1_loop
lda rain_patt,x
sta $2408,x
inx
cpx #$08
bne rain1_loop
jmp draw_rain_dun
draw_rain2
ldx #$00
rain2_loop
lda rain_patt,x
sta $2410,x
inx
cpx #$08
bne rain2_loop
jmp draw_rain_dun
draw_rain3
ldx #$00
rain3_loop
lda rain_patt,x
sta $2418,x
inx
cpx #$08
bne rain3_loop
jmp draw_rain_dun
draw_rain4
ldx #$00
rain4_loop
lda rain_patt,x
sta $2420,x
inx
cpx #$08
bne rain4_loop
draw_rain_dun
lda raindrop
inc raindrop
cmp #$04
bne reset_bkgrd_anim_tmr
lda #$00
sta raindrop
What's happening? Well, when this routine is called, first of all I'm clearing all five rain chars to erase any previously drawn chars (this could be optimised to clear only the last previously drawn char!). Then, using a 'variable' that stores which raindrop we're on (it starts with '0'), the code determines which char should be drawn to next and jumps to the drawing code for that char and copies the raindrop pattern data pattern into that char's memory location. The code then jumps to a label called 'draw_rain_dun' which increases the raindrop variable and then checks to see if all five chars have been drawn to in sequence. If they have all been drawn to sequentially over the course of the routine being called a few times (i.e. the fifth raindrop char was last drawn to), the code resets the raindrop variable to '0' so next run through the raindrop pattern is drawn to the first char again.
Hopefully that makes sense?! Of course, this code is also inside a timer that executes it (at present) once every 4th frame. Without the timer that rain would, er, rain too fast!
To be honest, if this code was applied to the whole screen and not just the top of the buildings as in my level, it would probably look pretty jerky. However, in the context of my level and game, it has a nice cartoony feel that I'm very happy with! What does it look like? Something like this...
Next diary entry...
Friday, 10 January 2020
Unsung Routines
I've been working quite a bit of what I've come to call 'unsung routines', as opposed to the 'hero routines' such as the all important sprite and background collision detection or the gravity and animation routines.
These unsung routines have no apparent visible effect on screen but are important to keeping the code running in a modular way so it's easy for me to add more features.
An example of this is my 'process background animations' subroutine. When this was routine was coded originally, it was done only for the animating torch flame character (see this blog entry for more about animating chars) that appears in the current level 2 (the church). Since this routine was called from the main game loop code, it meant that the flame char animation code was executed for every level, even if the flame wasn't present on the level!
What a waste of processing time! How lame!
So, my background animations subroutine has now been restructured and had some code added so that it can handle multiple levels - it now checks the level the game is currently on and only executes the animations needed for that level. If the level has no character animations at all, the animation code is skipped completely, so no processing time is wasted!
Of course, I had always originally intended to do things this way, it's just that I've only just got round to it!
Another example of making things more modular is the variables and code I've added for background colours. I had originally set the background colour to black and had intended for every level to have a black background. However, when designing level 3, I chose to have a dark blue sky just to make the level look different to the previous two levels (see this blog entry for more about the level 3 design). The background is still actually black, but blue characters are used to represent the sky.
This created the problem of the sky being blue, but the top border being black and seeing that the borders are 'open' and the player sprite can jump up into the top border, it looked a little strange with the sprite moving over blue then into black 'sky'. So the solution was, quite simply, to make the top border (now controlled by the background colour register since the border is open) blue. Now there is a nice extension of the blue sky right to the top of the visible screen.
Problem - all other levels now have a blue top border, when not needed, including the title screen and intermediate screens!
To overcome this and returning to the idea of making the code more modular and flexible, the colour of the top border part is no longer hard coded, but controlled by a 'variable' that is changed for each level as part of that levels set-up code.
To be honest, these are the sort of things that more seasoned coders probably do right from the start, but since this is my first 'real' game, I'm still coming to terms with such things!
Next diary entry...
These unsung routines have no apparent visible effect on screen but are important to keeping the code running in a modular way so it's easy for me to add more features.
An example of this is my 'process background animations' subroutine. When this was routine was coded originally, it was done only for the animating torch flame character (see this blog entry for more about animating chars) that appears in the current level 2 (the church). Since this routine was called from the main game loop code, it meant that the flame char animation code was executed for every level, even if the flame wasn't present on the level!
What a waste of processing time! How lame!
So, my background animations subroutine has now been restructured and had some code added so that it can handle multiple levels - it now checks the level the game is currently on and only executes the animations needed for that level. If the level has no character animations at all, the animation code is skipped completely, so no processing time is wasted!
Of course, I had always originally intended to do things this way, it's just that I've only just got round to it!
Another example of making things more modular is the variables and code I've added for background colours. I had originally set the background colour to black and had intended for every level to have a black background. However, when designing level 3, I chose to have a dark blue sky just to make the level look different to the previous two levels (see this blog entry for more about the level 3 design). The background is still actually black, but blue characters are used to represent the sky.
This created the problem of the sky being blue, but the top border being black and seeing that the borders are 'open' and the player sprite can jump up into the top border, it looked a little strange with the sprite moving over blue then into black 'sky'. So the solution was, quite simply, to make the top border (now controlled by the background colour register since the border is open) blue. Now there is a nice extension of the blue sky right to the top of the visible screen.
Problem - all other levels now have a blue top border, when not needed, including the title screen and intermediate screens!
To overcome this and returning to the idea of making the code more modular and flexible, the colour of the top border part is no longer hard coded, but controlled by a 'variable' that is changed for each level as part of that levels set-up code.
To be honest, these are the sort of things that more seasoned coders probably do right from the start, but since this is my first 'real' game, I'm still coming to terms with such things!
Next diary entry...
Tuesday, 6 August 2019
Whoosh Hair
It didn't take long for the 'walking in the air' to get on my nerves - see the end of the previous diary entry here!
As a result, I spent an hour today pixelling a 'jump' left/right frame and then modifying my player movement routine to display the frame. The result has been christened 'Whoosh Hair'!
I will be honest, I was inspired to pixel whoosh hair by a game I used to play on the Amiga called 'Kid Gloves 2', which made locks of the players hair 'stick up' when falling.
The jump now looks much better methinks - no silly mid-air walk! Oh? What does it look like? Something like this...
Next diary entry...
As a result, I spent an hour today pixelling a 'jump' left/right frame and then modifying my player movement routine to display the frame. The result has been christened 'Whoosh Hair'!
I will be honest, I was inspired to pixel whoosh hair by a game I used to play on the Amiga called 'Kid Gloves 2', which made locks of the players hair 'stick up' when falling.
The jump now looks much better methinks - no silly mid-air walk! Oh? What does it look like? Something like this...
Next diary entry...
Monday, 5 August 2019
Jumping
A couple of weeks ago, I asked about people's preferences on Twitter (read here...) for joystick control in relation to 'jumping' a player character and the general consensus seems to be to use the fire button to jump.
Therefore from this day forth, the fire button will activate the jump function in Chiller 2!
After a bout of coding (I won't share the code here because it's so tied into the main control code, it would be too long!), the player can now jump! At present, no platforms are detected, but these will be coded up in the next few weeks.
The jump looks like this...
The only slight annoyance is that the sprite carries on the walking animation while in the air which to my mind looks rather silly, so I'll probably have to fix that next less my O.C.D. tendencies will play havoc...
Next diary entry...
Therefore from this day forth, the fire button will activate the jump function in Chiller 2!
After a bout of coding (I won't share the code here because it's so tied into the main control code, it would be too long!), the player can now jump! At present, no platforms are detected, but these will be coded up in the next few weeks.
The jump looks like this...
The only slight annoyance is that the sprite carries on the walking animation while in the air which to my mind looks rather silly, so I'll probably have to fix that next less my O.C.D. tendencies will play havoc...
Next diary entry...
Tuesday, 9 July 2019
Other Projects
If things have seemed a little quiet on the Chiller 2 front recently, it's because I've been working on other projects!
What? Why? Quite simply, I'm still learning 6502 assembler and the best way to learn is by actually doing something. When doing a longer term project like a game, there are so many other things to do as well, such as design, graphics, sound and so on and as a result you're not coding all the time, which is something I NEED to do to learn!
Just to prove it, here are some links to CSDb that contain two of my recently completed projects from which I canborrow steal code for Chiller 2!
PETSCII Doctors
Unused Shmup Tunes
Going forward, I can now dedicate more time to Chiller 2!
Next diary entry...
What? Why? Quite simply, I'm still learning 6502 assembler and the best way to learn is by actually doing something. When doing a longer term project like a game, there are so many other things to do as well, such as design, graphics, sound and so on and as a result you're not coding all the time, which is something I NEED to do to learn!
Just to prove it, here are some links to CSDb that contain two of my recently completed projects from which I can
PETSCII Doctors
Unused Shmup Tunes
Going forward, I can now dedicate more time to Chiller 2!
Next diary entry...
Friday, 19 April 2019
Joystick Detection
I fancy a mini-break from ChillED; it's occupying too much of my head-space at the moment and I need to do something different!
Thus, I've decided to write and slot into place the joystick detection code. At the moment, the code is very general since it's not being called by any other routine or not actually doing anything itself other than detecting the joystick move.
To be honest, I've meddled with joystick code before in a previous project (Super Galax-I-Birds), so this new code is a modification of that projects code for Chiller 2 and it all starts with memory location $dc00.
Memory location $dc00 can detect various joystick inputs by 'and'ing in various values as above. In the code, if an input isn't detected, it skips and checks the next input, but if an input is detected some other code can be run, but here it just jumps down to the end at the moment.
Note, there is no detection for up or down because Chiller 2 won't be using those movements, otherwise it would be simple to add more code to the above for those movements also.
And it's that simple in assembly language to detect joysticks!
Next diary entry...
Thus, I've decided to write and slot into place the joystick detection code. At the moment, the code is very general since it's not being called by any other routine or not actually doing anything itself other than detecting the joystick move.
To be honest, I've meddled with joystick code before in a previous project (Super Galax-I-Birds), so this new code is a modification of that projects code for Chiller 2 and it all starts with memory location $dc00.
; check joystick left, right and button press joy_check lda $dc00 sta joystick joy_left lda joystick and #$04 bne joy_right jmp joy_end ; jsr to another routine in future! joy_right lda joystick and #$08 bne joy_fire jmp joy_end; jsr to another routine in future!joy_fire lda joystick and #$10 bne joy_end; jst to another routine in future!joy_end jmp joy_check
Memory location $dc00 can detect various joystick inputs by 'and'ing in various values as above. In the code, if an input isn't detected, it skips and checks the next input, but if an input is detected some other code can be run, but here it just jumps down to the end at the moment.
Note, there is no detection for up or down because Chiller 2 won't be using those movements, otherwise it would be simple to add more code to the above for those movements also.
And it's that simple in assembly language to detect joysticks!
Next diary entry...
Sunday, 17 March 2019
Project Set-Up
While continuing to work on my screen editor, ChillED, I've decided to set-up a work project folder containing everything needed for the game. My usual way of saving things means direct to my (paid for) Dropbox folder, so I get automatic backups with version history in case as well as being able to access all my files from any computer I sign in to - I can code in work too!
The project folder will contain all code, data and work files (sprites, charsets, music, ChillED screens), a copy of both ACME cross assembler and Exomizer (for assembling and compressing the game) and a .bat file that turns my source text file into a C64 executable by calling the afore-mentioned ACME.
While doing this, I also started a new source code file (thus begins the code for the game) and copied in my usual set-up code that, for Chiller 2, looks a little like this...
What on earth is all that?!?!
Quite simply, it's some code that tells the ACME cross-assembler to set the C64 up and that we're taking full control of the machine so that we will have all 64K available for the project. This code does things like wiping out all the ROM characters and disabling the C64's internal routines (Kernal) that detects and controls things like I/O functions (keyboard detections and so on).
This code is also setting up a couple of labels/variables for controlling the raster, as well as generating an SYS call so that future builds will create an executable that will autorun when loaded.
Other than that, the code is fairly well commented already! It is missing some things such as memory locations assignements for where the charset. music, sprites and so on will be, but since I haven't decided on this yet, the code isn't in!
I must give credit to Jason 'T.M.R' Kelk who showed me how to set this up originally and Jon 'Moloch' Mines for providing further explanations.
Next diary entry...
The project folder will contain all code, data and work files (sprites, charsets, music, ChillED screens), a copy of both ACME cross assembler and Exomizer (for assembling and compressing the game) and a .bat file that turns my source text file into a C64 executable by calling the afore-mentioned ACME.
While doing this, I also started a new source code file (thus begins the code for the game) and copied in my usual set-up code that, for Chiller 2, looks a little like this...
; the name and file format for the assembled program
!to "chiller2.prg",cbm
; position of the raster interrupt(s) on-screen
; 'rp' is short for 'raster position'! duh!
raster_1_pos = $00 ; start of screen
; some zp label assignments (variables)
raster_num = $50 ; raster counter stores which split we are working in
sync = $51 ; interupt sync variable
; add a BASIC startline (SYS 16384) for auto-run after loading
* = $0801
!word code_entry-2
!byte $00,$00,$9e
!text "16384"
!byte $00,$00,$00
; entry point for the code
* = $4000 ; hence sys 16384!
code_entry
; stop interrupts, disable the roms and set up nmi and irq interrupt pointers
sei ; disable maskable IRQs
lda #$35 ; kill EVERYTHING (MWHAHA!) except $f000-$ffff
sta $01
; setup nmi
lda #<nmi ; some nmi stuff
sta $fffa
lda #>nmi
sta $fffb
; setup irq's
lda #<int ; some irq stuff
sta $fffe
lda #>int
sta $ffff
lda #$7f
sta $dc0d ; disable timer interrupts which can be generated by the two CIA chips
sta $dd0d ; the kernal uses such an interrupt to flash the cursor and scan
; the keyboard, so we better stop it
lda $dc0d ; by reading this two registers we negate any pending CIA irqs
lda $dd0d ; if we don't do this, a pending CIA irq might occur after we
; finish setting up our irq. we don't want that to happen
lda #raster_1_pos ; starting point of raster on screen ($00)
sta $d012
lda #$1b ; as there are more than 256 rasterlines, the topmost bit of $d011 serves as
sta $d011 ; the 9th bit for the rasterline we want our irq to be triggered
lda #$01
sta $d019 ; clear interupt bit
sta $d01a ; tell vicii to generate interupt
lda #$35 ; turn off basic and kernal rom thus
sta $01 ; c64 now sees RAM everywhere except at $d000-$e000
lda #$18 ; use our custom font charset
sta $d018
cli
What on earth is all that?!?!
Quite simply, it's some code that tells the ACME cross-assembler to set the C64 up and that we're taking full control of the machine so that we will have all 64K available for the project. This code does things like wiping out all the ROM characters and disabling the C64's internal routines (Kernal) that detects and controls things like I/O functions (keyboard detections and so on).
This code is also setting up a couple of labels/variables for controlling the raster, as well as generating an SYS call so that future builds will create an executable that will autorun when loaded.
Other than that, the code is fairly well commented already! It is missing some things such as memory locations assignements for where the charset. music, sprites and so on will be, but since I haven't decided on this yet, the code isn't in!
I must give credit to Jason 'T.M.R' Kelk who showed me how to set this up originally and Jon 'Moloch' Mines for providing further explanations.
Next diary entry...
Subscribe to:
Posts (Atom)







