Wednesday, July 04, 2007

SNASM: 65816 support....

I've been adding more addressing modes during lunchtime, so now I can do full 16bit immediate mode stuff. This also means I had to put in 8/16 bit flow control using new LongA and LongI, so you can now do commands like this!

        LongA   off
LongI off

lda #$ff
adc #$55
and #$fe
cmp #$12
eor #$55
ora #$55
sbc #$55
bit #$55

ldx #$23
cpx #$55
ldy #$23
cpy #$55


LongA on
LongI on

lda #$ffff
adc #$5125
and #$fe34
cmp #$1112
eor #$5544
ora #$5555
sbc #$5566
bit #$5532

ldx #$2312
cpx #$5542
ldy #$2363
cpy #$5513


Great fun!! I found out from the forums on Lemon64 that I can happily run my SuperCPU on my C128 in C64 mode without fear of blowing it up, so I can probably start to test some of the output soon.

I was thinking of doing a bitmap scroller an actually blitting the bitmap on each frame - which at 20Mhz, should only take around 1/5th of a frame!! wow thats fast... I could then also do software sprites on top of that! The great thing being that the sprites would be much quicker (aside fom the 20Mhz stuff) since I dont have to copy character data around - AND you wouldn't be limited by the character set either -its a bitmap! Colour would also be possible with this as well I guess... and thats not even thinking about C64 hardware sprites yet either!

Theres surprisingly little added to the 6502, a couple of addressing modes (and I'm doing 24bit Absolute addressing just now), and a few extra instructions that take no effort at all really. So this shouldn't take that long at all to finish this....

Edit: Thinking a bit more about this....I really need to update my C64 emulator to allow 65816; development would go much quicker if I had an emulator to run it in... I'm not sure how much effort that would be, I've not looked at it in years - since I put it on the PS2/XBox really.

Tuesday, July 03, 2007

Paradroid!!!!

At long (long, long, long, long, long, long, long, long, long, long, LONG!) last... TNT has started a proper blog of his Paradriod update. Its basically a disassembled, updated (a lot) and then reassembled version of the original game. He's making heaps of improvements and its well worth a shot if you haven't already. You can find his blog HERE

I've decided to start the work of upgrading my assembler to be 65816 compatible (which is used in the SuperCPU) as I fancy having a little play with 20Mhz of power! I know - Im jumping around quite a bit, but that happens as I try and keep my interest going. I'll probably play with this at lunchtimes at work, so I hope it won't get in the way too much. The 65816 is very neat and I've used it a lot in the past when doing SNES work (Lemmings2), its got full 16 bit registers although you can swap them back and forth. Its also got access to a full 16Mb of RAM (which my Super CPU has!) which could make for some REALLY cool stuff - lots of space for buffers and tables here! Also Zero page becomes DirectPage and it can move!! In Lemmings2 I pointed zero page at my graphics so that the code ran faster! I'll need to look out my SNES assembler manual to see the syntax I used in that, but all in all - it should be pretty good fun!

Edit: So I've just added my first new 65816 instructions! yeeeeeeaaa!!
     inc a
opcode [$00]
opcode [$00],y

I'm so happy... :) This does 24bit indirect addressing through the direct page register (the new movable ZeroPage)

You know something....the THOUGHT of filling even 4Mb with C64 graphics/sound is frightning.... On the SNES I had a ROM disk system, and most of the memory was taken up with that, but here... its RAM...so you cna actually DO stuff with it - outstanding! I may have to update my C64 emulator to allow 65816 code as well...Mmmm... even simple stuff without the need to fallback to 1Mhz for custom chips would probably do - I dont think anyones done a SuperCPU emulator before....

The other thing I didn't realise is that the 65816 is also 65c02 compatable...which means I can probably add 65c02 to the assembler as well...

RetroEdit: Painting by numbers.

I got basic editing in last night, although I really do mean basic. I can paint with 2 pre-defined colours - which isn't very handy. Now I need to put all the really boring editor stuff in to allow you to select colours from a palette, swap between them, validate the system its on, and then swap between systems....I hate editors :)

(oh....then save it all)

Sunday, July 01, 2007

RetroEdit: Editing...

I've almost got editing working, I can click on the bitmap and it draws a pixel into the right place. Theres still loads to do, but it shouldn't take long now. Once I get editing and saving working, i can let Luca lose on it and try it out - it should help him do later level sprites. I'm expecting great things from him once he gets a good editor, as hes already done amazing things with - well, crap editors!

XeO3: Squishing bugs!

I've had a really bugging..well...bug! for a while now in the front end; after you die and return there I seemed to be losing a layer of stars and I couldn't think what it could be! My first that was that one of the couters werent being reset and so a layer was in fact 2, but I couldn't see how that was possible. So I then though that perhaps some stars were black, and I just wasn't seeing them. This wasn't right either - although I did discover some were in fact being made black - but it was fairly even throughout all the layers. Once I fixed that I went back to hunting for the missing layer.... Turns out my first instinct was right and a counter wasn't being reset! The slowest speed only moves every other frame and was being toggled with $FF and getting checked to 0, but since I use the game data area it wasn't being cleared to 0, which meant the EOR #$FF was setting it from one zero value to another, and so it was moving at the same speed as the middle layer.

Glad I fixed that, its been bugging me for a while now....

Saturday, June 30, 2007

XeO3: Feeling blue...

Well, since I was in a colour mood, I thought I'd smooth out some of the presentation a little so I've added a nice little fade on when the game starts and fade off when you die. It costs around 200-300 bytes in all, but it looks much nicer than the abrupt start/stop I did have before. Funnily the fade on looks much smoother, but I'm not really sure why - not that it really matters I guess, its probably an optical illusion and I can't really see what could be different about it.

I'm tempted to do a delayed DMA thing and scroll the panel on from the bottom, but thats probably a little too much when I dont have a lot of memory going spare...

XeO3: Colour....

Mmm... the more I look at the Plus4 version, the more I wish it had colour. If you followed the way spectrum games work - that is the background gets colour and ships dont, they just fly through it - then you might be able to pull it off. The biggest problem is moving the colour screen. Unlike the C64, you can't scroll a whole colour screen over 8 game cycles as I have to double buffer the software sprites (C64 doesn't need that due to hardware sprites), but...... if you could afford to lose another 4k (ouch!) then it might JUST be possible...

Basically you have 4 screens. 2 are active at any one time over 8 game cycles and the other 2 are hidden. Normal character rendering goes on as normal, but the hidden 2 screens get the colour slowly moved (or rather copied!) from screens 1&2 to 3&4 - but 1 character further on. It still requires you to shift around 5 lines per frame but thats a far cry from blitting a whole 21 line high screen each game cycle as I do now. However, if you did that (and you might have to drop a sprite to fit it in), you could get XeO3 - with colour!

Its way too late for me to add that now, but once the source is released, it be cool if someone else did it. 9 software sprites is still loads! So drop 1 sprite, and free 4K+space for colour tiles, and it should work!

Okay...More minor optimisations. I've removed a couple of functions and inline'd them whilst making them faster, and finally removed the old, slow PATH allocator. It was still using the simple loop rather than the stack method, so thats now changed. I got fed up writing that bloody thing, so I've macro-ized it even more, and here it is.


;****************************************************************************************
;
; Allocate/Free a Turret.
; Out: X=spare slot or -1 for error
;
; Best 29 - OLD
; Worst 134 - OLD
;
; Alloc - BEST/WORST - 12/18
; Free - Best/Worst - 24 (constant)
;
;
; Usage:- FastAlloc [xy], ListAddress, ObjectOnOff
; X or Y = index register to use
; ListAddress = Base of pre-filled stack
; ObjectOnOff = Value to clear/set when allocated/free'd
;
;****************************************************************************************
FastAlloc macro
ld\0 \1FreeIndex ; 3 ldx FreeIndex
lda \1FreeList,\0 ; 4 lda FreeList
bmi !NoneFree ; 2 bmi !NoneFree
in\0 ; 2 inx
st\0 \1FreeIndex ; 3 stx FreeIndex
!NoneFree: ; tax
ta\0 ; 2 get next free bullet (or $ff for none left)
endm

;****************************************************************************************
;
; Usage:- FreeTurret [xy], ListAddress, ObjectOnOff
; X or Y = index register to use (and hold the object to free)
; ListAddress = Base of pre-filled stack
; ObjectOnOff = Value to clear/set when allocated/free'd
;
;****************************************************************************************
FastFree macro
t\0a ; 2 txa
ld\0 \1FreeIndex ; 3 ldx FreeIndex
de\0 ; 2 dex
st\0 \1FreeIndex ; 3 stx FreeIndex
sta \1FreeList,\0 ; 5 sta FreeList,x
ta\0 ; 2 tax - restore index
lda #0 ; 2 lda #0
sta \2,\0 ; 5 sta BullInUse,x
endm



And this is how I use it - Its pretty simple although I do have to replicate a branch which technically speaking I could do without. However, if it comes down to the game not working because of 2 cycles wasted here....I'll kill myself!

        FastAlloc x,Path,PathsInUse 

These are obviously SNASM macros. SNASM has a really cool macro feature in that it lets you build new opcodes, labaels or anything! using the paramaters. This means I can decide later what register to use, and prepend a name and have a new label - cool eh!

Oh! And for the record....the micro-optimisations I've been doing are generally called peep-hole optimisations by compilers. That is were they look are a few instructions at a time and try and make them better - I'm pretty much doing the same.

XeO3: More micro optimisations....

I've spent some more time relaxing and scaning the code looking for the odd cycle here and there, and I've managed to smoothout some of the path code a little. I'd noticed that just before calling the actual command I set Y to 0 so that it pointer back to the start of the command (and not the index into the jump table), however the first thing all the commands did was to skip the first byte so it could read the paramaters (using an INY). This meant a wasted 2 cycles in every function. Not a lot... but 10 scripts, and around 20 functions means 20 cycles saved, and around 20 bytes as well - and the codes a little cleaner.

I also look at the Misc part - this is the messy bit that does all the grunt work of getting baddie numbers into sprites etc, and I've streamlined that a little too as it had duplicate checks and the average case wasn't as optimal as it could be.

All in all - good fun!

Thursday, June 28, 2007

XeO3: Scripts...

I've decided to release what little doc's I have for the scripting system to give you a better idea what its doing. This isn't finished by any means, but I started it to help Luca play with the some level editing. Its actually a refrence document and a few tutorials. Enyway - enjoy (even if you cant type them in and play with it just yet!!)

HERE it is!

XeO3: More and more.

Okay - I've changed the little bits of the script engine anyway... damn you all!! Making me feel guilty! bah! But I guess, a scanline is still a scanline saved so... *sigh* - your all bastards....the lot of you! :)

I'm also busy changing my code from using #<Address to #Lo(Address) so that I can remove the shortcut "<". This will let me add to my assembler and do 65816 and do a full 24bit address range, which will in turn allow me to do SuperCPU stuff someday.

If anyone uses SNASM, then you might want to start changing over now as the assembler supports both at the moment. Future versions will only support Lo() and Hi() operators - but its all in a good cause!

I find it oddly relaxing doing minor code changes, move this, changing that while not doing any real work, its all just cleaning up and making it better. This is probably because you don't really get the time to do it as a profesional developer, you code as best you can as quickly as you can, and rarely do you get to go back and polish the code just for the sake of it.