Hacking Asteroids

guddler

Busting vectors like it's 1982!
vacBacker
Feedback
10 (100%)
Credits
4,055CR
For many years now there has been a 9010 script "out there" for Asteroids. One of the tests that it does is to draw a cross on the screen exercising the extremities of X & Y.

Does anyone know the origin of this? Was it in an official bulletin by some company, or was it just something someone knocked up?

The reason for asking is that in a totally unrelated, almost entirely non arcade related endeavour I've been dissecting and hacking away at the Asteroids vector ROM today. On my travels I've had to go right back to the schematics as the two main texts that I was following either seemed to fall apart in incompleteness, incorrectness, assumptions, or any combination thereof!!

In the end I've managed to thoroughly come to an understanding, well, enough of one to achieve what I want, and along the way, I believe that the writer of that script is incorrect.

My understanding is that while the co-ordinate system for the screen goes from 0 - 1023 in both axis, for X 0 is the far left, 512 is the middle and 1023 is the far right, but for Y the bottom isn't 0, it's 128, the middle is (correctly) 512 and the top, again, is not 1023 but 996.

So, this script that moves the beam to absolute position Y:1023, and then relative Y:-1023 is actually trying to draw off-screen and is only being prevented by the overflow on the position counters pulling the positioning back to a sensible value.

Does anyone agree? Disagree? Am I talking double dutch, or barking up completely the wrong tree?

The only thing I've not got my head around yet is the scaling. But...

1) I'm not convinced it's relevant for what I'm up to as I believe it's related to the time the beam takes to be drawn and thus keeping the thing in proportion and at the correct intensity

2) I've not actually looked it up yet
smiley1.gif


guddler2011-01-01 22:15:42
 

guddler

Busting vectors like it's 1982!
vacBacker
Feedback
10 (100%)
Credits
4,055CR
And further to that...

Is it possible to get mame to display my own stuff. So, like if I had a real PCB on the bench and I wrote the relevant instructions to the vector memory, it will draw the aforementioned cross on the screen. Can I get mame to do it?

I ask as the PCB I have on the bench at the moment is a non worker so it won't display bugger all. Tomorrow I can go up the shed and get a worker, or even (radical!) fix the one on the bench but I was just wondering...
 

DanP

Administrator
Staff member
vacBacker
Feedback
5 (100%)
Credits
2,190CR
Hi Gudd, the origin of the Cross test is the CAT Box DVG tests (see the Cat box UG manual). I've not looked at the 9010 script but I assumed (probably incorrectly) that it's ripped from that test. As I understand Asteroids the code positions the beam, and then draws a long or short relative vector with a scale and intensity bit setting. Here's an excerpt from some notes I've gathered;

'For Asteroids (and probably Asteroids deluxe and Lunar Lander):

Draw relative vector 0x80 1000YYYY YYYYYYYY IIIIXXXX XXXXXXXX

Draw relative vector
and load scale 0x90 1001YYYY YYYYYYYY SSSSXXXX XXXXXXXX

Beam to absolute
screen position 0xA0 1010YYYY YYYYYYYY UUUUXXXX XXXXXXXX

Halt 0xB0 1011UUUU UUUUUUUU

Jump to subroutine 0xC0 1100AAAA AAAAAAAA

Return from subroutine 0xD0 1101UUUU UUUUUUUU

Jump to new address 0xE0 1110AAAA AAAAAAAA

Short vector draw 0xF0 1111YYYY IIIIXXXX

Bit Key:

X - X coordinate bits
Y - Y coordinate bits
I - Vector intensity(brightness) bits
A - Vector address bits
R - Red color bit
G - Green color bit
B - Blue color bit
S - Scale (size)
U - Unused bit

If you wish to see a constant image on the screen, remember that the main processor will have to poll the VGHALT until all the vector instructions have been executed, then write to VGGO to start again.
Also make sure that you return the beam to the centre of the screen
before halting the AVG, because if the beam were fully deflected and left there'

It sounds like you're trying to do the same thing I tried a while back and yes it is perfectly possible to get MAME to run your own code using the Asteroids driver. I did manage to get exactly what you're doing working to a point, I could display the cross fine, unfortunately I'd missed something because it then went on to draw the test cross hatch over the top of it. The second issue I had was that the CPU was in too tight a loop, I guess I needed to pad out the program a bit (which is what I think the original code does) between cycles. From memory to do this you'll need to grab a 6502 assembler, build your code (basically populate the Vector RAM with your DVG code), export the code in a 2k block using x'6000' as your program entry point, and alter the reset and interrupt vectors to point to the entry point of your code. I wouldn't run my test program on a real board until I sorted the tight loop (I didn't want to fry anything). I'd also planned once I got it working to alter the test to utilise some of the Vector Rom (say draw a large Asteroid in each quadrant for example, the idea was to write a full Test Rom which would be more featured than the built in tests. Unfortunately I never quite found the time to get back to it. Some of the mathematics were frankly getting quite tricky for my 25year old 'O' level to get my head round quickly...

DanDanP2010-12-29 09:35:46
 

guddler

Busting vectors like it's 1982!
vacBacker
Feedback
10 (100%)
Credits
4,055CR
Excellent reply! Thanks
smiley1.gif


I'll take a look at the CAT box UG to check that all out. On the one hand it's odd that Atari would write something that draws beyond the realm of the visible screen, on the other, if it is for testing purposes then you probably should since the circuitry deals with the full 1024 positions in both directions. I guess otherwise you could feasibly not pick up a fault in the counters if it doesn't occur until the carry bit is set etc.

The text you quoted is one of the two that I was talking about. It's a good example of where I say descriptions fall apart in incompleteness and assumptions. The whole section where he talks about the scale instruction is assumption and any reference to the 4 bit scale in the draw relative and load scale is completely missing. Also there is no text about the short vector. So anyway, that's why I ended up studying the schematics and the notes on them for the info. I'm not knocking the text (and the other one), there's extremely useful information in there, but I ended up getting a lot out of the drawing package in the end.

Do you know how the short vector instructions work? I went through and tried to make sense of the stored routine that draws one of the asteroids for instance. And I just couldn't work out how it could be correct - yet clearly it is! Using one of the texts would pull all of the values out as positive values so you couldn't possibly be drawing something roughly akin to a circle. Using the other I hit some other problem. I was getting very tired by this point!

On to mame etc., what I was really after was just being able to hack the vector ram, leaving the CPU alone suspended like you can with the Flukes (9010 / 9100). I gave it a go though through the mame debugger and clearly it's not possible. I guess that didn't surprise me. I'll write a small program as you did and use that instead. All I was wanting to do was hack away and further my understanding of how the drawing works.

As for your issues. There's no such thing as too tight of a loop so it won't have been that as to why it went to the test pattern. A program can be just a few instructions, as long as everything is handled correctly then it's fine. Especially for mame!.

What I suspect it will have been is the state machine's program counter. If $4000-$47FF is full of 00's, and you then write you code into it, unless you factor in resetting the VSM's program counter to 0 ($4000) so that it goes round again, then it's going to keep going until it eventually hits the ROM at $5000. The first thing in the ROM, located exactly at $5000 is the routine to draw the test pattern. So my guess is that is what it was doing.

I'm not sure that the real hardware would behave like this since I don't think $00 is a valid state machine OP code? I'd need to look that up. Maybe it is. I'd expect a real board to just reset itself I think. Again, I'm speculating without trying it.

For a real program you'd also need to write something to clear the watchdog but I don't know if mame honours this, or what it does with it.

So, why am I doing all of this? Well, as I said, it's not really anything arcade related at all. I've had an idea in my head for over a year now about writing something vector related on the BBC micro and it involves me fully understanding how the Atari vector ROM works. It's all good though because once I've got to that point and I can draw objects from the ROM, and also draw my own stuff then I can progress on to writing some decent troubleshooting stuff for my 9100.

Once I've got to that point I intend to write a routing in Objective C or something that displays vectors by reading the vector memory. Essentially a very crude DVG emulator. But intentionally NOT of the same style as mame. That's way over complicated for what I want.

I think I'm nearly there with all of my understanding, there's just a few holes to fill.
 

guddler

Busting vectors like it's 1982!
vacBacker
Feedback
10 (100%)
Credits
4,055CR
Interestingly enough (maybe!), I just pulled up Asteroids in SDL Mame 0.134 and when you flip the virtual test switch (F2) you do actually get a little popup that says "Reset caused by the watchdog!!!".

So these days, they clearly DO handle the watchdog properly
smiley1.gif
 

guddler

Busting vectors like it's 1982!
vacBacker
Feedback
10 (100%)
Credits
4,055CR
Ok, there's something fundamental I'm not "getting" here...

The Asteroids code space is 3 x 2716's from 0x6800 - 0x7FFF. So I write my code starting at 0x6800.

Atari's code starts at 0x7CF3 (odd place but there we are!).

The reset and IRQ vectors need to be set but my understanding is that they are at 0xFFFC/FD and 0xFFFE/FF. If the only ROM space available to me is 0x6800 - 0x7FFF, but the program isn't going to start executing that code until it's directed there, how on earth am I supposed to populate the two vectors??

Like I say, I'm missing something fundamental here
smiley36.gif
 

guddler

Busting vectors like it's 1982!
vacBacker
Feedback
10 (100%)
Credits
4,055CR
Right - ok, got it!

1. Asteroids appears to be mapping the ROM data to both $6800-$7FFF and $E800-$FFFF, hence all I need to do is to intialise the vectors by writing the addresses to 7FFC / 7FFE and the board is doing the rest.

2. I had my code wrong in mame. I am now only using a single ROM image since this is mame so it's possible to have a single ROM that is the size of 3 x 2716's. I had commented out the other two ROMs but forgotten to increase the ROM from $800 to $1800. DOH!

3. An even bigger slip up was that I was forgetting to copy my ROM over to the mame ROM directory every time I modified it!!

So, now I'm where I wanted to be
smiley1.gif
 

DanP

Administrator
Staff member
vacBacker
Feedback
5 (100%)
Credits
2,190CR
Hi Gudd, sounds like you're there. Sorry I couldn't pitch in earlier, it'd been easier if I was working and not at home helping with the kids all day. Yep you're right I had remembered wrong that 6000 was the starting point, in my effort I actually just used 7800 as a starting vector and ignored the rest of the ROM space. Here's some notes that I made on the rom files (I used the Rev 2 code).

035143.02 = 7800, 0x0800

035145.02 = 6800, 0x0800
035144.02 = 7000, 0x0800

/* Vector ROM */
035127.02 = 5000, 0x0800

I'm sure you found that the vectors at 7FFC/7FFE are arse about face, the nibbles are reversed which makes things interesting if you forget. I did the same as you and altered them in the appropriate rom file to point to where I wanted. I kept the files separate cos I wanted to have the potential to run directly on a real board, keeping the files as they were seemed sensible from that point of view. Is the ROM double mapped or is it just that the DVG references them from a different offset? Be interesting to see what you come up with.

Cheers,

Dan
 

guddler

Busting vectors like it's 1982!
vacBacker
Feedback
10 (100%)
Credits
4,055CR
Yeah, not sure on the ROM space at the moment - I guess I'd have to look at the schematics to work out what's actually going on there, doesn't really matter though, that's just one of those things that I can just take "as-is".

The main reason for merging the ROMs together is due to the assembler that I'm using. I'm using "BeebASM" which is a compiler explicitly designed for programming the BBC micro so it has a lot of convenience stuff built in. It even has some of the BBC basic type stuff (FOR loops etc.) but there's absolutely nothing to stop you from using it for pure 6502 forsaking a lot of the BBC stuff as I'm doing here.

It means I don't need to pad the ROM, it just does it for me.

As an example, here's the code to print the cross. Mame displays this perfectly, but I know it's not right as I can see the processor "free running" from in the debugger. I'm working on that at the moment. I think it basically needs to poll for the state machine to signal that it's done drawing, reset the vector program counter and give it something else to do. That or just sit in a loop if we're done.

This is almost certainly sub-optimal, and I'm part working on it so cutting and pasting this may not even work, however, it's just to show how nice the assembler is. The second ORG statement at the end (7FFC) automatically pads the file out with no messing. I can always split it again later. Or even add more labels and save statements to get my 3 files.

Code:
ORG &6800

; Globals

dma_go = &3000

vector_ram = &4000

vector_pc = 0

.start

	ldx vector_pc

	ldy #18    ; Sizeof cross data

.crossloop

	lda crossdata,x

	sta vector_ram,x

	inx

	dey

	bne crossloop

.go	

	lda #&0

	sta dma_go

; 18 Bytes for drawing the cross

ALIGN &100

.crossdata

	equb &FF, &A3

	equb &00, &02

	equb &FF, &97

	equb &00, &90

	equb &00, &A2

	equb &00, &00

	equb &00, &90

	equb &FF, &33

	equb &00, &E0

; Reset and interrupt vectors (memory mapped to &FFFC)

ORG &7FFC

	equb 0

	equb &68

	equb 0

	equb &68

.end

SAVE "testprog.bin", start, end

This forum seems really screwy with non printing characters incidentally. In my editor that code is all nicely spaced and tabbed!!

[EDIT] Oh, now it is! In the preview window there were no tabs
smiley5.gif


guddler2010-12-29 20:01:01
 

guddler

Busting vectors like it's 1982!
vacBacker
Feedback
10 (100%)
Credits
4,055CR
I've basically sussed this out properly now and have a bit of code that draws the cross and then adds an asteroid. It then properly waits for the draw operations to finish before going round again.

I'm still tidying the code and may not do any more on it tomorrow as I'm a bit boggle eyed now! Let me know if anyone would like me to put the assembly listing here for everyone to laugh at (I'm no experienced assembly programmer)
smiley4.gif


ast_debug_pic.png
 

DanP

Administrator
Staff member
vacBacker
Feedback
5 (100%)
Credits
2,190CR
Nice one Gudd, have to say your asm is a lot more elegant than mine :) Just one question, in my program I coded a watchdog clear to avoid it barking, you don't seem to be doing any of that, is the dmago somehow performing this for you? I'd like to see the code, either by PM or in thread please. All this has reignited myinterest in working on it a bit more :))). Also if you have deciphered how to code the coordinates that would save me a headache or two.

Cheers,

Dan
 

guddler

Busting vectors like it's 1982!
vacBacker
Feedback
10 (100%)
Credits
4,055CR
For the coordinates I found a much, much better document than I hadn't seen before which among other things is correct. Well, in all but one respect. It still gives the wrong origin for the screen! I'll dig out a link when I'm not on my phone.

As far as the watchdog goes, no, the DMAGO won't do it for you and I have forgotten. It's not barking but I guess that's down to mame maybe? I need to lookup whether I can overlay this code without burning a rom using the 9100. If I can I'll dig out a working board and give it a go, see what it does.

I'm pretty much just playing now. I've achieved what I wanted. I'll finish the code today or tomorrow and post it here. It's not like it's doing anything desperately amazing.

Oh, for the asteroid you realize I'm just calling a pre-built routine in the vector rom don't you? I'm not actually plotting it myself.
guddler2010-12-30 13:03:45
 

guddler

Busting vectors like it's 1982!
vacBacker
Feedback
10 (100%)
Credits
4,055CR
Oh, PS: the problem with your original idea of writing a better test rom is that it's not really possible! In a raster game the video and program are entirely separate so you can write routines to test stuff with only the very basic program functionality working and as long as the video side of things is working you'll see the results.

On Asteroids though, the video side can't do anything until it's told to do so by the CPU side of things. So to see stuff not only does the video side need to work but also, so does the entire program side. All you've really got left that you could test are inputs and audio. I suppose you could, but they're usually the easy bits
smiley1.gif


For a vector game you really need to force it to do known things at known times and sample the results in various places. You could do this with a 9010 and a logic analyzer or a 9100 and 1 or more parallel I/O pods. That's a side project for another day. I need a couple more modules for my pods first though and it may turn out just as cheap to buy a USB analyzer.
 

guddler

Busting vectors like it's 1982!
vacBacker
Feedback
10 (100%)
Credits
4,055CR
Ok, here's a final(ish) listing. There's comments at the top that say where the information has come from. There's two uses of BBC syntax that have crept in. One is valid (the first FOR loop), the second is most definitely a fudge. I actually consider them both to be a fudge so I'm going to investigate as to how to achieve the same result without using the loops. It does the job for now though.

I've shifted over to the idea of just a single ROM from &7800 as I liked that idea. The program draws the cross and then an asteroid in each quadrant. Every second or so (not exact) the whole lot is redrawn with the next asteroid in the table until all four have been drawn at which point it cycles. I could cycle the scaling too but frankly my head hurts and, well, it's relatively pointless as it is!

Sorry, code is pretty long now (and may not format right)!!

Code:
;-------------------------------------------------------------------------------

;             

;            Atari Asteroids 'test program'. M White: Dec 2010.

;                        http://www.guddler.co.uk

;

; A very simple and non optimal program to just draw some stuff on the screen of

; an Atari Asteroids PCB. Basically to show some of the principles.

;

; The code is written for 'BeebASM' and some of the directives may not work

; with other assemblers (GUARD springs to mind for sure). Generally however this

; program avoids beebasm specific functionality such as BBC basic style FOR loops

; etc. so as to be remotely portable. In a word, I had BeebASM to hand and I

; happen to like it. If you already use some other assembler then you'll know

; what to do with this code.

;

; BeebASM lives here: http://www.retrosoftware.co.uk/wiki/index.php/BeebAsm

;

; I have also used three other documents for information in building this code.

; Thanks go to their respective authors.

;

; http://www.ionpool.net/arcade/asteroidtech/dvg.txt

; http://www.ionpool.net/arcade/asteroidtech/neilw_xy.txt

; http://www.philpem.me.uk/elec/vecgen.pdf

;

; And not forgeting the Atari drawing package - lots of info in there.

;

; THIS PROGRAM HAS NOT YET BEEN TRIED ON REAL HARDWARE - YOU HAVE BEEN WARNED!!

;

;-------------------------------------------------------------------------------

;

ORG 	&7800					; Just use the last of the 3 program ROMs

GUARD	&8000					; Prevent going over the bounds of a 2716

; Globals

halt			= &2002			; Address that indicates drawing has finished

dma_go			= &3000			; Address to tell the state machine to start

vector_ram 		= &4000			; Start of vector ram (4000-47FF)

vector_pc		= &20			; Store the Vector PC in zero page

watchdog		= &3400			; Watchdog reset position

ast_lookup		= &10			; two byte vector to asteroid lookup table

ast_index		= &12			; current selected asteroid

loop_index		= &13			; just a counter

quad_index		= &14			; current drawing quadrant

pos_lookup		= &15			; two byte vector to position data

.start

	cld

	; Setup asteroid lookup

	lda #&DE

	sta &10

	lda #&51

	sta &11

	; Setup position lookup

	lda #&10

	sta &15

	lda #&7F

	sta &16

.begin

	; Set the vector position counter

	lda #0

	sta vector_pc

; Load up the vector memory

	jsr drawcross				; Draw the cross

FOR n, 0, 12, 4

		lda #n

		sta quad_index

		jsr positionbeam			; Go to position for drawing asteroid

		ldy ast_index				; Select asteroid

		jsr draw_asteroid			; Draw asteroid

	NEXT

jsr haltvsm					; Stop the VSM

; For the next two commands, we don't care what we write as the signal is

	; generated from the address decode and the data is ignored

	;

	; Execute vector memory

	sta dma_go

	; Reset watchdog

	sta watchdog

; Wait for drawing to finish

.waitfordraw

	lda halt

	bmi waitfordraw

; Check for a change in asteroid

	lda loop_index

	cmp #&FF

	bne end_loop

	jsr change_asteroid

.end_loop

	inc loop_index

	; And repeat

	jmp begin

;-------------------------------------------------------------------------------

;

; Increment the required asteroid and reset the loop counter

;

;-------------------------------------------------------------------------------

;

.change_asteroid

	inc ast_index

	lda ast_index

	cmp #4

	bne reset_loop

	lda #0

	sta ast_index

.reset_loop

	lda #0

	sta loop_index

	rts

;-------------------------------------------------------------------------------

;

; The following are routines that load instructions

; for the DVG into the vector memory

;

;-------------------------------------------------------------------------------

; State machine HALT instruction

;

.haltvsm

	ldx vector_pc

	lda #&00

	sta vector_ram,x

	inx

	lda #&B0

	sta vector_ram,x

	inx

	stx vector_pc

	rts

;-------------------------------------------------------------------------------

; Routine to draw the selected asteroid. Y must contain the required asteroid

;

; There is a lookup table of jump vectors in the vector ROM.

; See: http://www.ionpool.net/arcade/asteroidtech/dvg.txt

;

; 0 : rock with V notch in top

; 1 : X-shaped rock

; 2 : rock with bottom and left notches

; 3 : rock with left and right notches; 

;

.draw_asteroid

	; Modify Y to point where we need it

	tya

	beq skip

	clc

	rol a

	tay

.skip

	ldx vector_pc

	lda (ast_lookup),y

	sta vector_ram,x

	iny

	inx

	lda (ast_lookup),y

	sta vector_ram,x

	inx

	stx vector_pc

	rts

;-------------------------------------------------------------------------------

; State machine LABS instruction (load absolute)

;

.positionbeam

	ldx vector_pc

ldy quad_index

	FOR n, 0, 3, 1

		lda (pos_lookup),y

		sta vector_ram,x

		inx

		iny

	NEXT

stx vector_pc

	rts

;-------------------------------------------------------------------------------

; Bunch of instructions to draw a cross

;

.drawcross

	ldx vector_pc

	ldy #16				; Sizeof cross data

.crossloop

	lda crossdata,x

	sta vector_ram,x

	inx

	dey

	bne crossloop

	stx vector_pc

	rts

;-------------------------------------------------------------------------------

;

; The following are data for the vector routines

;

;-------------------------------------------------------------------------------

;

; 16 Bytes for drawing the cross

; (00 E0 removed from end as not needed)

; 4 bytes each for positioning to the centres

; of the cross

;

ORG &7F00

.crossdata

	equb &FF, &A3

	equb &00, &02

	equb &FF, &97

	equb &00, &90

	equb &00, &A2

	equb &00, &00

	equb &00, &90

	equb &FF, &93

.topleft

	equb &C0, &A2

	equb &00, &01

.topright

	equb &C0, &A2

	equb &00, &03

.btmright

	equb &40, &A1

	equb &00, &03

.btmleft

	equb &40, &A1

	equb &00, &01

;-------------------------------------------------------------------------------

; Reset and interrupt vectors (memory mapped to &FFFC)

;

ORG &7FFC

	equb 0

	equb &78

	equb 0

	equb &78

.end

SAVE "testprog.bin", start, end

[EDIT] PS: I may do a quick screen-cast of it tomorrow if I get round to it.

guddler2010-12-31 03:00:36
 

Macro

Active member
vacBacker
Feedback
4 (100%)
Credits
1,982CR
You'll need to look after the watchdog on real hardware. Mame only enables the watchdog once the program has written to it (the first write enables it) - real hardware it's going all the time!

caused me some fun with pac90 - each CPU has a watchdog, none are mapped in Mame (or at least they were not back then)
 

guddler

Busting vectors like it's 1982!
vacBacker
Feedback
10 (100%)
Credits
4,055CR
To be honest, I've no idea what mame is or isn't doing! I can't make it do what I would expect on the watchdog. The second listing above takes care of the watchdog properly albeit that I may need to do some proper cycle counting if I'm not resetting it often enough. To see what you were talking about though I changed it so that it only writes to the watchdog once at the beginning and then doesn't any more after that and mame isn't telling me that it's resetting. I've definitely seen that message once before though! Maybe it was in a different version. I'm on .140 now.

Anyway, here's a screencast of the finished thing for those who don't have any way of seeing it but may be interested...

[FLASH WIDTH=640 HEIGHT=502]http://content.screencast.com/users/MartinWhite/folders/Jing/media/7b945bcb-9158-4e01-9ff0-644d38369cd6/00000004.swf[/FLASH]

guddler2010-12-31 14:40:13
 

Macro

Active member
vacBacker
Feedback
4 (100%)
Credits
1,982CR
Excellent, vector 0's and X's here we come ...

so are you going to convert one of the many 6502 BBC based vector(ish) games to drive a real vector monitor then ?

personally, I'd just port the code to the Atari hardware, but then thats the sort of thing I usually do!

XY always wanted Elite converted to use a vector monitor ... and the source code is available on Ian Bells website
 

guddler

Busting vectors like it's 1982!
vacBacker
Feedback
10 (100%)
Credits
4,055CR
smiley36.gif
Ever heard of walking before you can run!!!

Actually, it's the other way around. Planning on doing a BBC version of Asteroids that uses real Atari vector code. So basically having a DVG coded and running on the main CPU and the game coded and running on the Tube.

And now that the cats out of the bag I'm actually going to have to try and do something!

All of this here was just a learning exercise and groundwork.
 
Top