Finding the Vertex Table
===========================

Okay, so now we've got a point table at $388e, which points to a set of points. The length of the point table comes first (size of table in bytes including length byte) followed by the 16 bit point triples, each triple entry being 6 bytes.

Now the vertex array lookup table is at $7472, which points to a set of vertexes. This vertex list is terminated with an FF byte.

So what's the format of this vertex table?
We lookup an address for our vertex table at $7472, put it into $3b and then start getting values from ($3b),y:
Code
  50209 5C5E: lda $7472, y
  50216 5C61: sta $3b
  50222 5C63: lda $7473, y
  50229 5C66: sta $3c
  50235 5C68: ldy #$00
  50240 5C6A: lda ($3b), y
  ...
  50264 5C72: and #$f8
  ...
  50280 5C77: and #$07


there's an and #$f8 which is bits 11111000
and an and #$07 which is bits 00000111

These low 3 bits get multiplied by 2 and used as an offset in a lookup table at $5c84. The address of the routine gets pushed on the stack and then an rts jumps to the routine address + 1.
Code
  50295 5C7B: lda $5c85, x
  50302 5C7E: pha
  50308 5C7F: lda $5c84, x
  50315 5C82: pha
  50321 5C83: rts


The high 5 bits are the vertex number or a parameter for the routine in the lookup table.

The lookup table at $5c84:
Code
[MAME]> hexdump16(0x5c84,7,1)
HEXDUMP16 addr=5c84  len=07
5c84: 5c91   (address is +1, so $5c92  00)
5c86: 5c9e   (address is +1, so $5c9f  01)
5c88: 5ce0   (address is +1, so $5ce1  02)
5c8a: 5cd3   (address is +1, so $5cd4  03)
5c8c: 5ce4   (address is +1, so $5ce5  04)
5c8e: 5cec   (address is +1, so $5ced  05)
5c90: 5d0d   (address is +1, so $5d0e  06)
5c92: (first routine in jump table)


Let's try to decode the data:
Code
[MAME]> hexdump(0x3c5a,16)
HEXDUMP addr=3c5a  len=10
3c5a: 31 80 fd 80 fd c0 fe 80 
3c62: fd 80 02 c0 fe 80 02 80 
3c6a: 02 

stuckcount=0 i=0x74d7  while mem:read_u8(i)~=0xff do m=mem:read_u8(i) print(hex(i,4)..":"..hex(m).."   "..hex(getbits(m,3,7)).."  "..hex(getbits(m,0,2))) i=i+1 stuckcount=stuckcount+1 if stuckcount>50 then break end end print(hex(i,4)..":"..hex(mem:read_u8(i)))

       param   routine
    (high 5)   (low 3 bits)
           |   | 
74d7:03   00  03
74d8:a1   14  01
74d9:0c   01  04
74da:14   02  04
74db:1c   03  04
74dc:04   00  04
74dd:24   04  04
74de:2c   05  04
74df:34   06  04
74e0:3c   07  04
74e1:24   04  04
74e2:2a   05  02
74e3:0c   01  04
74e4:12   02  02
74e5:34   06  04
74e6:3a   07  02
74e7:1c   03  04
74e8:ff


In the last column we have the routine that gets called, a number from 0 to 5.

03 starts the object, moves to a new location (MoveToStart)
01 sets the intensity
04 continues the vector (DrawTo)
02 ends the current line, then moves to a new location (MoveTo)

So if we put our generated AVG commands next to the vertex table decode, it's easy to see the pattern (you may need to widen the window or scroll to see all of it):

All DrawTos have (i=1)
All MoveTos have (i=0)
Code
20e4: 8040 CMD=8 CNTR									
20e6: 1ff6 CMD=0  20e6:f6 1f 87 00 VCTR 1ff60087 0   x= 135  y=-10  i=0	  ( 135,-10)	74d7:03	  00  03 Start New Object (point 0)
20ea: 6430 CMD=6 STAT									74d8:a1	  14  01 Stat (set brightness)
20ec: 0000 CMD=0  20ec:00 00 11 20 VCTR 00002011 0   x= 17  y=	0  i=1	 ( 17,	 0)	74d9:0c	  01  04 DrawTo (point 1)
20f0: 0000 CMD=0  20f0:00 00 0d 20 VCTR 0000200d 0   x= 13  y=	0  i=1	 ( 13,	 0)	74da:14	  02  04 DrawTo (point 2)
20f4: 0000 CMD=0  20f4:00 00 ef 3f VCTR 00003fef 0   x=-17  y=	0  i=1	 (-17,	 0)	74db:1c	  03  04 DrawTo (point 3)
20f8: 0000 CMD=0  20f8:00 00 f3 3f VCTR 00003ff3 0   x=-13  y=	0  i=1	 (-13,	 0)	74dc:04	  00  04 DrawTo (point 0)
20fc: 0009 CMD=0  20fc:09 00 00 20 VCTR 00092000 0   x=	 0  y=	9  i=1	 (  0,	 9)	74dd:24	  04  04 DrawTo (point 4)
2100: 0000 CMD=0  2100:00 00 11 20 VCTR 00002011 0   x= 17  y=	0  i=1	 ( 17,	 0)	74de:2c	  05  04 DrawTo (point 5)
2104: 0000 CMD=0  2104:00 00 0d 20 VCTR 0000200d 0   x= 13  y=	0  i=1	 ( 13,	 0)	74df:34	  06  04 DrawTo (point 6)
2108: 0000 CMD=0  2108:00 00 ef 3f VCTR 00003fef 0   x=-17  y=	0  i=1	 (-17,	 0)	74e0:3c	  07  04 DrawTo (point 7)
210c: 0000 CMD=0  210c:00 00 f3 3f VCTR 00003ff3 0   x=-13  y=	0  i=1	 (-13,	 0)	74e1:24	  04  04 DrawTo (point 4)
2110: 0000 CMD=0  2110:00 00 11 00 VCTR 00000011 0   x= 17  y=	0  i=0	 ( 17,	 0)	74e2:2a	  05  02 MoveTo (point 5)
2114: 1ff7 CMD=0  2114:f7 1f 00 20 VCTR 1ff72000 0   x=	 0  y= -9  i=1	 (  0, -9)	74e3:0c	  01  04 DrawTo (point 1)
2118: 0000 CMD=0  2118:00 00 0d 00 VCTR 0000000d 0   x= 13  y=	0  i=0	 ( 13,	 0)	74e4:12	  02  02 MoveTo (point 2)
211c: 0009 CMD=0  211c:09 00 00 20 VCTR 00092000 0   x=	 0  y=	9  i=1	 (  0,	 9)	74e5:34	  06  04 DrawTo (point 6)
2120: 0000 CMD=0  2120:00 00 ef 1f VCTR 00001fef 0   x=-17  y=	0  i=0	 (-17,	 0)	74e6:3a	  07  02 MoveTo (point 7)
2124: 1ff7 CMD=0  2124:f7 1f 00 20 VCTR 1ff72000 0   x=	 0  y= -9  i=1	 (  0, -9)	74e7:1c	  03  04 DrawTo (point 3)
2128: 8040 CMD=8 CNTR									



So let's write some routines to print out the vertex table and points table

Code
mem=manager:machine().devices[":maincpu"].spaces["program"]
mem2=manager:machine():memory().regions[":maincpu"]  -- alternate way to access memory
function hex(a,digits) digits = digits or 2 return string.format("%0"..digits.."x",a) end
function int(i) return math.floor(i) end
function tablelookup16(item,base) return mem:read_u16(base+item*2) end
function maskbits(a,b) local r = 0,i for i=a,b do r=r|(2^i) end return r end
function getbits(n,a,b) return (n & maskbits(a,b))>>a end
function iif(a,b,c) if a then return b else return c end end

function printvertextable(i) stuckcount=0 while mem:read_u8(i)~=0xff do m=mem:read_u8(i) print(hex(i,4)..":"..hex(m).."   "..hex(getbits(m,3,7)).."  "..hex(getbits(m,0,2))) i=i+1 stuckcount=stuckcount+1 if stuckcount>100 then print("STUCK LOOP="..stuckcount)  break end end print(hex(i,4)..":"..hex(mem:read_u8(i))) end

function printpointstable(adr) a=mem:read_u8(adr) local count=0 for i=adr+1,adr+1+a-1-1,6 do  x=mem:read_i16(i) y=mem:read_i16(i+2) z=mem:read_i16(i+4) print(hex(i,4).."  vertex "..count.." ("..int(x)..","..int(y)..","..int(z)..")") count=count+1 end end

function printline() print(string.rep("-",40)) end

battlezoneobjecttable={
"pyramid",
"cube",
"enemy tank",
"shot",
"rear tread 1",
"rear tread 2",
"rear tread 3",
"rear tread 4",
"front tread 1",
"front tread 2",
"front tread 3",
"front tread 4",
"pyramid wide",
"radar1",
"dot",
"short cube",
"fragment 1",
"fragment 2",
"fragment 3",
"fragment 4",
"fragment 5",
"fragment 6",
"missile",
"BA",
"fragment 7",
"fragment 8",
"fragment 9",
"fragment 10",
"fragment 11",
"fragment 12",
"TTLE",
"ZONE",
"saucer",
"supertank"
}

function printobject(obj) 
printline() print("OBJECT "..obj.." "..battlezoneobjecttable[obj+1])  printline() 
printpointstable(tablelookup16(obj,0x388e)) 
printvertextable(tablelookup16(obj,0x7472)) 
end


Code
printobject(0xf)

----------------------------------------
OBJECT 15 short cube
----------------------------------------
3c5b  vertex 0 (-640,-640,-320)
3c61  vertex 1 (-640,640,-320)
3c67  vertex 2 (640,640,-320)
3c6d  vertex 3 (640,-640,-320)
3c73  vertex 4 (-640,-640,-40)
3c79  vertex 5 (-640,640,-40)
3c7f  vertex 6 (640,640,-40)
3c85  vertex 7 (640,-640,-40)
74d7:03   00  03
74d8:a1   14  01
74d9:0c   01  04
74da:14   02  04
74db:1c   03  04
74dc:04   00  04
74dd:24   04  04
74de:2c   05  04
74df:34   06  04
74e0:3c   07  04
74e1:24   04  04
74e2:2a   05  02
74e3:0c   01  04
74e4:12   02  02
74e5:34   06  04
74e6:3a   07  02
74e7:1c   03  04
74e8:ff


for i=0,33 do printobject(i) end