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++
-------------------------------------------------------