Atari Star Wars Mathbox

How does it work and what does it do?

This file is a work in progress for the unit vector math box, to try to understand how it works. There is no guarantee any of it is correct.

I took the disassembled code from matread and rewrote it in a form more like the actual unit vector equations.

-------------------------------------------------------
Star Wars / ESB Matrix Processor Microcode Disassembler
Version 0.8 by Frank Palazzolo
http://www.brouhaha.com/~eric/software/mathdis/
-------------------------------------------------------

You will need to refer to Jed Margolin's website to try to understand what the mathbox is doing:
http://www.jmargolin.com/uvmath/uvmenu.htm

Mathbox memory:

In 6809 address space is from 0x5000 - 0x5FFF 8 bit bytes
In mathbox address space is from 0x0000 - 0x7FF 16 bit words
First 128 words are absolute addressable from mathbox, and used as fixed variables.

Block Index Counter (BIC) is a pointer to blocks of 4 words. Seems to use first 3 words as X, Y and Z, with 4th word unused.
Assume this is to point to XYZ vertices data for objects like stars (single point), tie fighters, towers, bunkers, catwalks, trench, etc.

BIC,0 = X object data
BIC,1 = Y object data
BIC,2 = Z object data
BIC,3 = Unused

BIC++ instruction increments counter by 4 words, to point to next X, Y, Z data block.


First 128 words are directly addressable from mathbox, seem to be used as fixed variables for math parameters and results.
I've named the variables as RegXX, where XX is the mathbox hex word address, until I can work out more useful names. Some I have named based on Jed's notes.


$5000    Reg00    X result
$5002    Reg01    Y result
$5004    Reg02    Z result


Matrix 1. For transposed multiply?

$5006    Reg03    Ax
$5008    Reg04    Ay
$500A    Reg05    Az

$500C    Reg06    Bx
$500E    Reg07    By
$5010    Reg08    Bz

$5012    Reg09    Cx
$5014    Reg0A    Cy
$5016    Reg0B    Cz

$5018    Reg0C    XT
$501A    Reg0D    YT
$501C    Reg0E    ZT

$501E    Reg0F    Constant 0000 Zero. For clarity I've removed references to unused zeros in the functions below
$5020    Reg10    Constant $4000 One.
$5022    Reg11    Sine for rotation
$5024    Reg12    Cosine for rotation

$5026    Reg13    Constant $E000 (Is that -0.5 ?)


Matrix 2. For regular multiply?

$5028    Reg14    Ax2
$502A    Reg15    Ay2
$502C    Reg16    Az2

$5030    Reg18    Bx2
$5032    Reg19    By2
$5034    Reg1A    Bz2

$5038    Reg1C    Cx2
$503A    Reg1D    Cy2
$503C    Reg1E    Cz2

$5040    Reg20    XT2
$5042    Reg21    YT2
$5044    Reg22    ZT2


Matrix 3

$5048    Reg24    Ax3
$504A    Reg25    Ay3
$504C    Reg26    Az3

$5050    Reg28    Bx3
$5052    Reg29    By3
$5054    Reg2A    Bz3

$5058    Reg2C    Cx3
$505A    Reg2D    Cy3
$505C    Reg2E    Cz3

$5060    Reg30    XT3
$5062    Reg31    YT3
$5064    Reg32    ZT3


$5068    Reg34    Constant $0040
$506A    Reg35    Constant $0080
$506C    Reg36    Constant $4000 One.

$5070    Reg38   
$5072    Reg39   
$5074    Reg3A   

$5076    Reg3B   
$5078    Reg3C   
$507A    Reg3D   
$507C    Reg3E   

$5080    Reg40    Matrix 4
$5082    Reg41   
$5084    Reg42   
$5086    Reg43   

$508A    Reg45   

$508E    Reg47   
$5090    Reg48   


$5096    Reg4B   
$5098    Reg4C   
$509A    Reg4D   
$509C    Reg4E   

Reg14 through to Reg 3A seem to be only using the first 3 words of a 4 byte block. Is this so those registers can be also pointed to by the BIC I wonder?

-------------------------------------------------------



Math program 0x00: Roll


Watch out for read of BIC,1 before store of previous result!


[BIC,1] = [BIC,1] x Cosine + 0 - [BIC,2] x Sine + (CONST_0040 x CONST_0080)
[BIC,2] = [OLDBIC,1] x Sine + [BIC,2] x Cosine + (CONST_0040 x CONST_0080)
BIC++

[BIC,1] = [BIC,1] x Cosine - [BIC,2] x Sine + (CONST_0040 x CONST_0080)
[BIC,2] = [OLDBIC,1] x Sine + [BIC,2] x Cosine + (CONST_0040 x CONST_0080)
BIC++

[BIC,1] = [BIC,1] x Cosine - [BIC,2] x Sine + (CONST_0040 x CONST_0080)
[BIC,2] = [OLDBIC,1] x Sine + [BIC,2] x Cosine + (CONST_0040 x CONST_0080)



Math program 0x0E: Pitch

Watch out for read of BIC,2 before store of previous result!


[BIC,2] = [BIC,2] x Cosine + 0 - (BIC,0) x Sine + (CONST_0040 x CONST_0080)
[BIC,0] = [OLDBIC,2] x Sine + [BIC,0] x Cosine + (CONST_0040 x CONST_0080)
BIC++

[BIC,2] = [BIC,2] x Cosine - [BIC,0] x Sine + (CONST_0040 x CONST_0080)
[BIC,0] = [OLDBIC,2] x Sine + [BIC,0] x Cosine + (CONST_0040 x CONST_0080)
BIC++

[BIC,2] = [BIC,2] x Cosine - [BIC,0] x Sine + (CONST_0040 x CONST_0080)
[BIC,0] = [OLDBIC,2] x Sine + [BIC,0] x Cosine + (CONST_0040 x CONST_0080)



Math program 0x1C: Yaw


Watch out for read of BIC,0 before store of previous result!

[BIC,0] = [BIC,0] x Cosine + 0 - [BIC,1] x Sine + (CONST_0040 x CONST_0080)
[BIC,1] = [OLDBIC,0] x Sine + [BIC,1] x Cosine + (CONST_0040 x CONST_0080)
BIC++

[BIC,0] = [BIC,0] x Cosine + [BIC,1] x Sine + (CONST_0040 x CONST_0080)
[BIC,1] = [OLDBIC,0] x Sine + [BIC,1] x Cosine + (CONST_0040 x CONST_0080)
BIC++

[BIC,0] = [BIC,0] x Cosine + [BIC,1] x Sine + (CONST_0040 x CONST_0080)
[BIC,1] = [OLDBIC,0] x Sine + [BIC,1] x Cosine + (CONST_0040 x CONST_0080)


Math program 0x2A

Reg00 = (([BIC,0] - XT2) x Ax2)  +  (([BIC,1] - YT2) x Bx2)  +  (([BIC,2] - ZT2) x Cx2)
Reg01 = (([BIC,0] - XT2) x Ay2)  +  (([BIC,1] - YT2) x By2)  +  (([BIC,2] - ZT2) x Cy2)
Reg02 = (([BIC,0] - XT2) x Az2)  +  (([BIC,1] - YT2) x Bz2)  +  (([BIC,2] - ZT2) x Cz2)
BIC++


Math program 0x40 Matrix 1 = Matrix 2 x Matrix 3

Ax = (Ax3 x Ax2)  +  (Bx3 x Bx2)  +  (Cx3 x Cx2)
Ay = (Ax3 x Ay2)  +  (Bx3 x By2)  +  (Cx3 x Cy2)
Az = (Ax3 x Az2)  +  (Bx3 x Bz2)  +  (Cx3 x Cz2)

Bx = (Ay3 x Ax2)  +  (By3 x Bx2)  +  (Cy3 x Cx2)
By = (Ay3 x Ay2)  +  (By3 x By2)  +  (Cy3 x Cy2)
Bz = (Ay3 x Az2)  +  (By3 x Bz2)  +  (Cy3 x Cz2)

Cx = (Ay3 x Ax2)  +  (Bz3 x Bx2)  +  (Cz3 x Cx2)
Cy = (Ay3 x Ay2)  +  (Bz3 x By2)  +  (Cz3 x Cy2)
Cz = (Az3 x Az2)  +  (Bz3 x Bz2)  +  (Cz3 x Cz2)



Math program 0x50

Matrix Multiply - Transposed?

Reg00 = XT + ([BIC,0] x Ax)  +  ([BIC,1] x Bx)  +  ([BIC,2] x Cx)
Reg01 = YT + ([BIC,0] x Ay)  +  ([BIC,1] x By)  +  ([BIC,2] x Cy)
Reg02 = ZT + ([BIC,0] x Az)  +  ([BIC,1] x Bz)  +  ([BIC,2] x Cz)
Reg37 = Reg00 x CONST_4000
BIC++

-------------------------------------------------------

Math diagnostic tests programs 0x57 to 0x5F


Math program  0x57

lda (0x0f), mhalt



Math program MW0 0x58

ldb (0x0f), mhalt



Math program MW0 0x59

ldc (0x0f), mhalt



Math program MW0 0x5a

clearacc, mhalt



Math program MW0 0x5b

BIC++, mhalt



Math program MW0 0x5c

ldacc (0x00)
readcc (0x01), mhalt



Math program MW0 0x5d

lda (0x0c), clearacc
ldb (0x0d)
ldc (0x0e)
readcc (0x00), mhalt



Math program MW0 0x5e

lda (0x0c)
ldb (0x0d)
ldc (0x0e)
readcc (0x00), mhalt



Math program MW0 0x5f

lda (BIC,0), clearacc
ldb (0x0f)
ldc (0x10)
readcc (0x00), mhalt


-------------------------------------------------------



Math program 0x60

Matrix Multiply - Regular

Reg00 = XT2 + ([BIC,0] x Ax2)  +  [BIC,1] x Ay2)  +  ([BIC,2] x Az2)
Reg01 = YT2 + ([BIC,0] x Bx2)  +  [BIC,1] x By2)  +  ([BIC,2] x Bz2)
Reg02 = ZT2 + ([BIC,0] x Cx2)  +  [BIC,1] x Cy2)  +  ([BIC,2] x Cz2)
BIC++


Math program 0x67


XT = ([BIC,0] - XT2) x CONST_E000
YT = ([BIC,1] - YT2) x CONST_E000
ZT = ([BIC,2] - ZT2) x CONST_E000

Reg00 = (XT x Ax2) + (YT x Bx2) + (ZT x Cx2)
Reg01 = (XT x Ay2) + (YT x By2) + (ZT x Cy2)
Reg02 = (XT x Az2) + (YT x Bz2) + (ZT x Cy2)

Reg37 = Reg00 x CONST_4000
Reg3B = Reg37 x Reg37

Reg38 = Reg00 x Reg00
Reg39 = Reg01 x Reg01
Reg3A = Reg02 x Reg02



Math program 0x77 Load Matrix 2 from BIC pointer

Ax2 = [BIC,0]
Ay2 = [BIC,1]
Az2 = [BIC,2]
BIC++
Bx2 = [BIC,0]
By2 = [BIC,1]
Bz2 = [BIC,2]
BIC++
Cx2 = [BIC,0]
Cy2 = [BIC,1]
Cz2 = [BIC,2]
BIC++
XT2 = [BIC,0]
YT2 = [BIC,1]
ZT2 = [BIC,2]




Math program 0x80 Load Matrix 3 from BIC pointer

Ax3 = [BIC,0]
Ay3 = [BIC,1]
Az3 = [BIC,2]
BIC++
Bx3 = [BIC,0]
By3 = [BIC,1]
Bz3 = [BIC,2]
BIC++
Cx3 = [BIC,0]
Cy3 = [BIC,1]
Cz3 = [BIC,2]
BIC++
XT3 = [BIC,0]
YT3 = [BIC,1]
ZT3 = [BIC,2]



Math program 0x86

Am assuming Reg B = 0 for all this math run. Assuming (Reg0F) holds zero on entry.

Reg01 = Reg01 x Reg00
Reg02 = Reg02 x Reg00



Math program 0x88


Reg3C = (Ax2 x Ax2) + (Bx2 x Bx2)



Math program 0x8A


Register B is NOT loaded for first 3 operations, so must have a previous value from preceding program

Reg3D = (Reg3C - RegB) x Reg3D
Reg3F = (Reg3D - RegB) x Bx2
Reg3E = (Reg3D - RegB) x Ax2

Reg38 = ((Ax2 - Reg3F) x Az2) + (Bx2 x Bz2) + (Reg3E x Bz2)
Reg39 = ((Ax2 - Reg3F) x Ay2) + (Bx2 x By2) + (Reg3E x By2)

Reg3A = (Ax2 x Az2) + (Reg3F x Az2) + ((Bx2 - Reg3E) x Bz2)
Reg3B = (Ax2 x Ay2) + (Reg3F x Ay2) + ((Bx2 - Reg3E) x By2)



Math program 0x95


Reg2F = Reg2F x Reg01

Reg3C = (0 - Reg17) x Az2 + (0 - Reg1B) x Bz2 (0 - Reg1F) x Cz2

Reg23 = (0 - Reg2F) x Ax2 + (0 - Reg00) x Reg17 (0 - Reg3C) x Az2
Reg27 = (0 - Reg2F) x Bx2 + (0 - Reg00) x Reg1B (0 - Reg3C) x Bz2

Reg2B = Reg33 + (0 - Reg2F) x Cx2 + (0 - Reg00) x Reg1F (0 - Reg3C) x Cz2



Math program 0x9E


Reg2F = Reg2F x Reg01

Reg23 = (Reg2F x Az2) + (Reg00 x Reg17)
Reg27 = (Reg2F x Bz2) + (Reg00 x Reg1B)

Reg2B = Reg33 + (Reg2F x Cz2) + (Reg00 x Reg1F)



Math program 0xA3


Reg2F = Reg2F x Reg01

Reg3C = (0 - Reg17) x Az2 + (0 - Reg1B) x Bz2 + (0 - Reg1F) x Cz2

Reg23 = (Reg2F x Az2) + (Reg00 x Reg17) x (Reg3C x Az2)
Reg27 = (Reg2F x Bz2) + (Reg00 x Reg1B) x (Reg3C x Bz2)

Reg2B = Reg33 + (Reg2F x Cz2) + (Reg00 x Reg1F) x  (Reg3C x Cz2)



Math program 0xAC


Reg3F = (Reg17 x Ax2) + (Reg1B x Bx2) + (Reg1F x Cx2)



Math program 0xAE


[BIC,2] = ([BIC,0] - Reg01) x (YT)
(BIC,3) = ([BIC,1] - Reg02) x (YT)
BIC++
XT = (BIC,3) - Reg00
BIC++


Math program 0xB0
Calls last part of program 0xAE which is:

XT = (BIC,3) - Reg00
BIC++

-------------------------------------------------------


Empire Strikes Back extra functions


Math program 0xC0


Reg00 = XT3 + ([BIC,0] x Ax3) + ([BIC,1] x Ay3) + ([BIC,2] x Az3)
Reg01 = YT3 + ([BIC,0] x Bx3) + ([BIC,1] x By3) + ([BIC,2] x Bz3)
Reg02 = ZT3 + ([BIC,0] x Cx3) + ([BIC,1] x Cy3) + ([BIC,2] x Cz3)
BIC++


Math program 0xC7


Reg38 = ([BIC,0] - XT3) x CONST_E000
Reg39 = ([BIC,1] - YT3) x CONST_E000
Reg3A = ([BIC,2] - YT3) x CONST_E000
Reg00 = (Reg38 x Ax3) + (Reg39 x Bx3) + (Reg3A x Cx3)
Reg01 = (Reg38 x Ay3) + (Reg39 x By3) + (Reg3A x Cy3)
Reg02 = (Reg38 x Az3) + (Reg39 x Bz3) + (Reg3A x Cz3)
BIC++




-------------------------------------------------------