Friday, April 06, 2007

Plus4 ROM disassmebly

After a post by Luca on Plus/4 world about clearing the screen via the kernal, I thought I'd have a quick poke around inside my kernal disassembly to see what it does. So I've spent an hour or so comenting my disassembly and how the screen clear stuff actually works. Its pretty simple really, and more or less loops around the current text window size clearing lines at a time. So, its not great, but its far from terrible. The "normal" kernal way of clearing a screen is to set the cursor to the top left and use Chrout to print each character. This doesn't, it hits the screen directly.
This also answers my question as to whether the kernal can move/relocate the main character map screen. The answer is no. This is because located at $d802 and $d81b you'll find a screen line lookup table, with the address of every line on the screen. and $0c00 is encoded into this table. Pitty.

Here's the main parts for anyone interested....


; *************************************************
;
; Clear screen with colour $10
;
; *************************************************
LD87E LDA #$10 ; Colour to clear screen to (black)
STA $053B ; Set current character colour
LDA #$04
STA $0541

; *************************************************
;
; Esc-n SCNCLR
;
; *************************************************
LD888:
JSR LDE70 ; Set full screen window
LD88B JSR LD89A ; Set the cursor HOME
LD88E JSR LD8AA ; Set screen pointers

; *************************************************
;
; Actual Screen Clear
;
; *************************************************
ClearScreen:
LD891:
JSR LDAF7 ; Clear the current line the cursor is on
CPX $07E5 ; At window lower edge?
INX ; move cursor down a line
BCC LD88E ; if not done, clear more


; *************************************************
;
; Set cursor HOME (set to top/left of current window)
;
; *************************************************
LD89A LDX $07E6 ; Get window TOP
STX $CD ; set cursor Y
STX $C4 ; cursor input row
LD8A1 LDY $07E7 ; Get window LEFT
STY $CA ; Set cursor X
STY $C5 ; Set cursor input X

LD8A8 LDX $CD ; get cursor Y
LD8AA LDA ScreenAddressLO,x ; look up screen xply table (LO)
STA $C8 ; store current screen address (low)
LDA ScreenAddressHI,x ; look up screen xply table (HI)
STA $C9 ; store current screen address (HI)

LD8B4 LDA $C8 ; get current screen address LO
STA $EA ; store in current editor COLOUR address LO
LDA $C9 ; now get the screen HI
AND #$03 ; and work out the HI addrews
ORA #$08 ; of the colour screen
STA $EB ; and store in the editor colour address HI
RTS




; *************************************************
;
; Clear the current line the cursor is on.
; (within the left/right window range)
;
; *************************************************
LDAF7 LDY $07E7 ; Get window LEFT edge
JSR LDF4A ; ???
LDAFD JSR LD8AA ; Setup screen addresses
DEY
LDB01 INY
LDA #$20 ; fill character address with spaces ($20)
STA ($C8),y
LDA $053B ; get current colour attribute
STA ($EA),y ; and store in colour address
CPY $07E8 ; right edge yet?
BNE LDB01 ; if not loop
RTS


; *************************************************
; Set window bottom and right
; *************************************************
LDE67 STA $07E5 ; Set current screen window bottom
STX $07E8 ; Set current screen window right
JMP LDE80

; *************************************************
; Reset current text window back to full screen
; (0,0) to (39,24)
; *************************************************
LDE70 LDA #$18 ; Set window bottom to 24
LDX #$27 ; Set window right to 39
JSR LDE67 ; set bottom and right variables
LDA #$00 ; Set window top to 0
TAX ; set window left to 0

; *************************************************
; Set window top and left
; *************************************************
LDE7A STA $07E6 ; Set current screen window top
STX $07E7 ; Set current screen window left


; *************************************************
; Clear screen line wrap table
; *************************************************
LDE80 LDA #$00
LDX #$04
LDE84 STA $07ED,x
DEX
BNE LDE84
RTS

Thursday, April 05, 2007

Let there be finger!!

Well, almost there. The big bandage came off today, so I can now see how its healing, and its pretty good. This means I dont feel too bad typing now, so I'll probably start debugging XeO3 over the weekend again. Because its over the joint, I still cantr bend that finger - not until I take those paper strips off, but I can get by okay as long as i can use 2 hands (mostly). Oh well.... Im off on holiday just now as I can't really do anything productive at work, but the suns out, the kids are off - so we can have a little R+R at least.

(Oh...and I know it doesn't LOOK bad now... but try and imagine pulling back the folds along the cut and almost seeing bone! Wish I'd gotten a picture of that! )

Monday, April 02, 2007

Slice and Dice!

Well, no sooner have I picked up XeO3 again, and Im forced to put it back down again! I was out giving the grass its first cut of the year, and managed to slice a rather large and impressively deep cut in my finger. So after a quick(ish) visit to the E.R., I'm now reduced to typing one handed, and thats no fun at all!

For those that haven't seen it yet, the new GTA 4 trailer is our for 360+ps3, check it out HERE

Sunday, April 01, 2007

XeO3: in for a qucikie....

Just a quick note really... I have verified that its the sprite system thats killing things by basically knocking it out and running the game without sprites. The game can then work as normal and does the full cycle of frontend->game->frontend->game->etc. This is good and bad news. This means I dont have to hunt everywhere, so thats good. But it also means I have to debug the most complex bit of code in the whole game. And because theres so much changed from the old engine, I can't use SSafe to do a DIFF - oh well....

BTW...this is a debugging technique that newbies often miss, when something wrong and you simply dont know what it is, comment out huge sections of code until its working as expected, and then start putting them back in one at a time. It should become clear then at least where to START looking! Sometimes its not in the obvious place, or even the block you commented out, but it gives you that valuable starting point.

Saturday, March 31, 2007

XeO3: I'mmmmmmmmmmmmm.............BAAAaaack!

Well, after a long break, I'm back and trying to get things swinging again. But needless to say, I screwed up yet again and left the game in a terrible state. There's at least 2 very serious bugs causing crashes and corruption through out the game that I need to track down before I even get started with new stuff.

I've managed to sort the 1st one out which was the turret and mine animations were going nuts! It turns out that a huge chunk of code had been deleted (I assume by accident!), and the only way I managed to find it was by doing a DIFF using source safe (a source control program).

Source control is great - even for use at home when your the only programmer. They are normally used for large teams and manage source merging and storage, but for a single programmer they give valuable check points where you can roll back to if all else fails. This is how I caught this bug; I simply checked the current version on disk, to the current version that was checked into SourceSafe - and a huge block of code had vanished. A simple copy+paste from SSafe to CodeWright, and its fixed.

The next bugs probably going to be a lot harder as Im sure its to do with the new sprite cache....

Edit: Oh! and I've been told Im not allowed to do any demos until I've finished XeO3....bummer :)

limiTED: Hard core fun!


I've been having great fun making some real hardcore demos for a new demo comp - my 1st demo comp in fact! limiTED was started and managed by Luca and has 3 catagorys: 64bytes, 128bytes and 1k. 64 bytes is about as hardcore as you get and is pretty hard to even start a program properly never mind do anything constructive, while 128 bytes you can just about do something nice. 1k is quite a lot, so your back into real demos which have to look nice as well as do something. The demos have to be anonymous for now so I cant say much more except its getting me back into 6502 fun land! So much so I hope to start back on XeO3 real soon... as soon as I've run out of demos to try and enter. I've never been much for doing cool demos, I've always been able to optimise and do stuff, but never come up with wierd shit that works well in a demo. So if I manage to do something, I'll be interested to see if everyone else thinks they're pooh or not.

Wednesday, March 28, 2007

Plodding on....

I'm still slowly progressing with wiring up the prototype, and I thought I was getting on well until I decided to finish one of them off - just to see how much more I had to do, and it turns out; LOADS! Oh well.... Onwards and upwards and all that.

I've been coding up a demo for Luca's new competition, and Im struggling a bit to fit it in. The original size was supposed to be 64 bytes(!) so I started working on that only to find out they had increased it to 128! DOH! Oh well.... Its nothing special, but I do prefer these smaller demos to the larger ones as you dont have to do very much, and it doesnt have to look too pretty.

I've also been speaking to Luca about the level2 on XeO3, so I may pick that up again soon. But once again, I've left it in a horrible state! Its got a pretty serious bug in there somewhere (probably the new sprite cache) which causes the whole thing o slowly get corrupted and crash. Bugger.

Thursday, March 15, 2007

The wiring begins!

Nothing much new, except I've started the long boring process of wiring up my prototype. I've been dreading this as its going to be really dull, and take AGES! I've decided that rather than wire up one at a time, I'll do them all at once, this means I'll get the correct connection from the schematic, and then wire that wire 5 times. It should save going back and forth all the time so it'll be quicker, but even more boring! Oh well....

The scrollys a foot....

After putting the display on a timer interrupt as well, I've managed ti get the whole thing going. So now the whole thing is interrupt driven. I optimised the IRQ routine so that the delay between each packet has been reduced and the overall update increased to around 20ms (rather than 100). So I've now started to wire up the prototype I started a while back but it'll take a while.

I put a new nib on my soldering Iron, but its already starting to lose its heat conductivity. Im not sure why but I think I may have it too hot and its losing its "tip", but I dont really know - this is the 1st time I've used an iron this long!

Friday, March 09, 2007

Alas poor scrolly, I knew him well..

I can't beleive how stupid I was last night. Banging my head off the wall trying to debug by just reading the source over and over without any feedback at all when suddenly today, I got one of those DOH! moments. I realised that I already HAVE a simple way of debugging (well...simpler). I can display an 8x5 pixel graphic! Or numbers and letters! What an idiot. So, I built the numbers 0 to 9 and then was able to find out the flow the program was taking (much like you'd do with PRINT's in your code). So, after an hour or so I've finally got it to run - more or less. It does work, but at the same time it doesn't. Theres still something wrong with the interrupts as if I get 2 packets very quickly, then the whole thing locks up. But if I delay 1ms between each packet, then all is well. This sounds like its getting a buffer overrun error (or I cant read it quick enough error). However, for testing, a 1ms delay is fine, particually as I have 100ms between displays to waste. This gives 64ms to send the whole row of pixels - fine.

But alas no.... Because of the system Im using I can actually test what it would be like to send 64 packets, and the load on the first units is far too heavy. It spends soo much time doing comm's, it has zero time left for anything else - like displaying the image. It flickers like mad! This isn't good. It simply can't handle passing on that many packets in an interrupt.

So, it looks like I'll have to try and reverse things. I'll put the comm's in the main loop, and the display in the interrupt. The display is VERY VERY simple, and will consist of a timer IRQ where by it sets 2 port variables - and thats it. This means when it does interrupt the comms, (which only happens every 3ms) it won't be in there for long.

*sigh*....its never easy.

EDIT: actually... it might not be all that bad.... The reason for the flicker could be that the delay in the main loop is being extended hugely due to the comms taking up more time. (the delay is a simple CPU loop). So before changing everything, I'll try using a timer for the counter instead which will of course be independent of CPU delays....