; Debugging flags. Set these to 1 to turn on various debugging output. ; texture setup debug_texture = 0 ; This is designed to be serial-line downloaded to cdcode. ; ; Our memory map: ; ; [8c000000,8c010000) Stack (r15 set by cdcode) ; [8c010000,8c01????) cdcode ; [8c020000,8c0?????) Us ; Throughout this file, MC, used as a name in the comments, means ; Marcus Comstedt, and tatest is a C program of his which he ; distributes as an example of a 3D rendering program. This file is ; largely a manual rewriting in assembly of tatest. .include "regs.s" .include "ta-cmds.s" TRIG_TABLE_SIZE = 2048 ; must be a power of two VRAM_BASE = 0xa4000000 VRAM_SIZE = 8 << 20 STOREQ_BASE = 0xe0000000 VIDREG_BASE = 0xa05f0000 X_SIZE = 640 Y_SIZE = 480 VBLANK_REG = 0xa05f6900 VBLANK_VBIT = 0x08 DISPLAY_VRAM = 0xa05f8050 . = 0x8c020000 SETS.L #main,r0 jmp @r0 nop SETCONST ; Our "data segment". We don't really have segments the way ; the term implies. The data is here rather than at the end ; so the symbols' values are known by the time the assembler ; sees them later. This is not critical, but does produce ; slightly better code. ; ; Things here are ordered approximately by decreasing alignment ; requirement. Not essential, just avoids needless gaps. ; The base matrix (composition of screenview, projection, and ; translation). .align 8 base_matrix: .space 16*4 ; Pointers to the texture memory. We have two different ; textures (each of which is used with three different ; palettes). .align 4 textures: .space 2*4 ; Pointers to the two places screens get rendered into. Each ; one has an two 640x480 fields (hence the 2*). render_buf: .long 0xa5000000 .long 0xa5000000+[2*640*480] ; Texture twiddling table. Why "twiddle"? That's the term ; used in tatest's comments. It appears to be interleaving ; the bits of the numbers that form texture coordinates, so ; that the texels conceptually at (x,y) and (x+1,y), where ; x=ABCDEFG0 and y=abcdefgh (say), are stored at offsets ; aAbBcCdDeEfFgGh0 (x) and aAbBcCdDeEfFgGh1 (x+1). ; ; Why do it? Because, in the words of another tatest comment, ; "palette based textures can not be non-twiddled". Why ; design hardware that way? MC, in email, passed along an ; explanation from someone who worked on the hardware, saying ; that twiddled textures provide higher performance, so the ; designers figured the only reason to use non-twiddled ; textures was to use a rendered frame as a texture (for, eg, ; reflections). Since the renderer output is always ; true-colour, that's all they implemented. (The ; "non-twiddled" bit got reused for a different meaning for ; palette-based textures.) ; ; tatest generates a 1024-entry table. We reserve (and set up) ; that much space, but as of this writing use only 256 entries ; of it. ; ; One possible note to beware of is that this may not apply to ; the large dimension of non-square textures. Done naïvely, ; doing this for non-square textures could use excessive ; amounts of memory; it would appear, for example, that an ; 8x256 texture would take up almost as much memory space as a ; 128x256 one (because of all the gaps between the address ; bits). But it may be smarter than that; when I mentioned ; that in mail to MC, he said he had a fuzzy memory that the ; high bits of non-square textures aren't twiddled, that, eg, ; an 8x256 texture in memory consists of 32 consecutive 8x8 ; (twiddled) blocks. But he also warned that memory could be ; wrong, so test this before depending on it. ; .align 2 twiddles: .space 1024*2 ; Tile descriptors. There is one of these, at 6 longs, per ; tile; there is also a 24-long header. Each tile is 32x32 ; pixels. So for a 640x480 screen, we need ; 24+(6*(640/32)*(480/32)) longs of space. (I don't know what ; happens if the screen width or height is not a multiple of ; 32.) Each tile also uses 64 bytes of buffer space. ; ; All of that is per-buffer. We double-buffer, so we need two ; copies. But it all lives in video RAM. .align 4 ; Cookies to pass to the hardware (void *tiles[2] in tatest) tiledesc_cookies: .space 2*4 ; Command lists (ta_buffers cmd_list arrays in tatest; we point ; to them rather than using a struct to generate offsets) cmdlists: .space 2*4 ; Tile buffers (the 64-bytes-per-tile space mentioned above) tilebuffers: .space 2*4 ; Tile descriptors (the space in which the descriptors are ; built) tiledescs: .space 2*4 ; Current rotation figures in X, Y, and Z. rotations: .space 3*4 ; Cube corner coordinates. .align 4 sf_m1 = 0x80000000 | [127<<23] ; single-float +1 sf_p1 = 127<<23 ; single-float +1 cube_coords: .long sf_m1, sf_m1, sf_m1 ; 0 .long sf_m1, sf_m1, sf_p1 ; 1 .long sf_m1, sf_p1, sf_p1 ; 2 .long sf_m1, sf_p1, sf_m1 ; 3 .long sf_p1, sf_p1, sf_m1 ; 4 .long sf_p1, sf_p1, sf_p1 ; 5 .long sf_p1, sf_m1, sf_p1 ; 6 .long sf_p1, sf_m1, sf_m1 ; 7 xform_coords: .space 8*3*4 ; Coordinate numbers of the various faces' corners, with ; palette numbers and texture numbers. cube_faces: .byte 0,1,2,3, 0, 0 .byte 0,1,2,3, 0, 0 .byte 0,1,2,3, 0, 0 .byte 0,1,2,3, 0, 0 .byte 0,1,2,3, 0, 0 .byte 0,1,2,3, 0, 0 .byte 0,1,2,3, 0, 0 .byte 0,1,6,7, 1, 0 .byte 0,3,4,7, 2, 0 .byte 0,1,2,3, 0, 0 .byte 0,1,6,7, 1, 0 .byte 0,3,4,7, 2, 0 .byte 7,6,5,4, 0, 1 .byte 5,4,3,2, 1, 1 .byte 6,5,2,1, 2, 1 ; A command to be sent to the TA. There are two kinds of ; commands, one 32 bytes and one 64 bytes. We reserve space ; for the larger against future need (we don't currently use ; 64-byte commands). .align 4 ta_cmd: .space 64 ; These palettes are straight from tatest; I've just ; reformatted them from C to assembly. It doesn't say where, ; if anywhere, they came from. They're small enough I haven't ; bothered trying to compress them. .align 4 palette_0: .long 0xff000000,0xff3c3c3c,0xff413c3c,0xff493c3c,0xff4d3838,0xff553838,0xff593434,0xff613434 .long 0xff653030,0xff6d3030,0xff712c2c,0xff792c2c,0xff822828,0xff862828,0xff8e2424,0xff922424 .long 0xff9a2020,0xff9e2020,0xffa61c1c,0xffaa1c1c,0xffb21818,0xffb61818,0xffbe1414,0xffc71414 .long 0xffcb1010,0xffd31010,0xffd70c0c,0xffdf0c0c,0xffe30808,0xffeb0808,0xffef0404,0xfff70404 .long 0xffff0000,0xffff0400,0xffff0c00,0xffff1400,0xffff1c00,0xffff2400,0xffff2c00,0xffff3400 .long 0xffff3c00,0xffff4500,0xffff4d00,0xffff5500,0xffff5d00,0xffff6500,0xffff6d00,0xffff7500 .long 0xffff7d00,0xffff8600,0xffff8e00,0xffff9600,0xffff9e00,0xffffa600,0xffffae00,0xffffb600 .long 0xffffbe00,0xffffc700,0xffffcf00,0xffffd700,0xffffdf00,0xffffe700,0xffffef00,0xfffff700 .long 0xffffff00,0xffffff04,0xffffff0c,0xffffff14,0xffffff1c,0xffffff24,0xffffff2c,0xffffff34 .long 0xffffff3c,0xffffff45,0xffffff4d,0xffffff55,0xffffff5d,0xffffff65,0xffffff6d,0xffffff75 .long 0xffffff7d,0xffffff86,0xffffff8e,0xffffff96,0xffffff9e,0xffffffa6,0xffffffae,0xffffffb6 .long 0xffffffbe,0xffffffc7,0xffffffcf,0xffffffd7,0xffffffdf,0xffffffe7,0xffffffef,0xfffffff7 .long 0xffffffff,0xffffffff,0xfffffbfb,0xfffffbf7,0xfffff7f3,0xfffff7ef,0xfffff3eb,0xfffff3e7 .long 0xffffefe3,0xffffefdf,0xffffebdb,0xffffebd7,0xffffe7d3,0xffffe7cf,0xffffe3cb,0xffffe3c7 .long 0xffffdfc3,0xffffdfbe,0xffffdbba,0xffffdbb6,0xffffd7b2,0xffffd7ae,0xffffd3aa,0xffffd3a6 .long 0xffffcfa2,0xffffcf9e,0xffffcb9a,0xffffcb96,0xffffc792,0xffffc78e,0xffffc38a,0xffffc386 .long 0xffffbe82,0xffffba7d,0xffffba79,0xffffb675,0xffffb671,0xffffb26d,0xffffb269,0xffffae65 .long 0xffffae61,0xffffaa5d,0xffffaa59,0xffffa655,0xffffa651,0xffffa24d,0xffffa249,0xffff9e45 .long 0xffff9e41,0xffff9a3c,0xffff9a38,0xffff9634,0xffff9630,0xffff922c,0xffff9228,0xffff8e24 .long 0xffff8e20,0xffff8a1c,0xffff8a18,0xffff8614,0xffff8610,0xffff820c,0xffff8208,0xffff7d04 .long 0xffff7900,0xffff7900,0xffff7500,0xffff7100,0xffff6d00,0xffff6900,0xffff6500,0xffff6100 .long 0xffff5d00,0xffff5900,0xffff5500,0xffff5100,0xffff4d00,0xffff4900,0xffff4500,0xffff4100 .long 0xffff3c00,0xffff3c00,0xffff3800,0xffff3400,0xffff3000,0xffff2c00,0xffff2800,0xffff2400 .long 0xffff2000,0xffff1c00,0xffff1800,0xffff1400,0xffff1000,0xffff0c00,0xffff0800,0xffff0400 .long 0xffff0000,0xffff0000,0xfffb0000,0xfff70000,0xfff70000,0xfff30000,0xffef0000,0xffeb0000 .long 0xffeb0000,0xffe70000,0xffe30000,0xffe30000,0xffdf0000,0xffdb0000,0xffd70000,0xffd70000 .long 0xffd30000,0xffcf0000,0xffcf0000,0xffcb0000,0xffc70000,0xffc30000,0xffc30000,0xffbe0000 .long 0xffba0000,0xffba0000,0xffb60000,0xffb20000,0xffae0000,0xffae0000,0xffaa0000,0xffa60000 .long 0xffa20000,0xffa20000,0xff9e0404,0xff9a0404,0xff960808,0xff920808,0xff8e0c0c,0xff8e0c0c .long 0xff8a1010,0xff861010,0xff821414,0xff7d1414,0xff791818,0xff791818,0xff751c1c,0xff711c1c .long 0xff6d2020,0xff692020,0xff652424,0xff652424,0xff612828,0xff5d2828,0xff592c2c,0xff552c2c .long 0xff513030,0xff513030,0xff4d3434,0xff493434,0xff453838,0xff413838,0xff3c3c3c,0xff3c3c3c palette_1: .long 0xff000000,0xff000000,0xff000004,0xff00000c,0xff000010,0xff000018,0xff000020,0xff000024 .long 0xff00002c,0xff000030,0xff000038,0xff000041,0xff000045,0xff00004d,0xff000051,0xff000059 .long 0xff000061,0xff000065,0xff00006d,0xff000075,0xff000079,0xff000082,0xff000086,0xff00008e .long 0xff000096,0xff00009a,0xff0000a2,0xff0000a6,0xff0000ae,0xff0000b6,0xff0000ba,0xff0000c3 .long 0xff0000cb,0xff0004cb,0xff000ccb,0xff0010cf,0xff0018cf,0xff001cd3,0xff0024d3,0xff0028d3 .long 0xff0030d7,0xff0038d7,0xff003cdb,0xff0045db,0xff0049db,0xff0051df,0xff0055df,0xff005de3 .long 0xff0065e3,0xff0069e3,0xff0071e7,0xff0075e7,0xff007deb,0xff0082eb,0xff008aeb,0xff008eef .long 0xff0096ef,0xff009ef3,0xff00a2f3,0xff00aaf3,0xff00aef7,0xff00b6f7,0xff00bafb,0xff00c3fb .long 0xff00cbff,0xff04cbff,0xff0ccbff,0xff14cfff,0xff1ccfff,0xff24d3ff,0xff2cd3ff,0xff34d3ff .long 0xff3cd7ff,0xff45d7ff,0xff4ddbff,0xff55dbff,0xff5ddbff,0xff65dfff,0xff6ddfff,0xff75e3ff .long 0xff7de3ff,0xff86e3ff,0xff8ee7ff,0xff96e7ff,0xff9eebff,0xffa6ebff,0xffaeebff,0xffb6efff .long 0xffbeefff,0xffc7f3ff,0xffcff3ff,0xffd7f3ff,0xffdff7ff,0xffe7f7ff,0xffeffbff,0xfff7fbff .long 0xffffffff,0xfffbffff,0xfff7ffff,0xfff3ffff,0xffebffff,0xffe7ffff,0xffe3ffff,0xffdbffff .long 0xffd7ffff,0xffd3ffff,0xffcbffff,0xffc7ffff,0xffc3ffff,0xffbaffff,0xffb6ffff,0xffb2ffff .long 0xffaaffff,0xffa6ffff,0xffa2ffff,0xff9effff,0xff96ffff,0xff92ffff,0xff8effff,0xff86ffff .long 0xff82ffff,0xff7dffff,0xff75ffff,0xff71ffff,0xff6dffff,0xff65ffff,0xff61ffff,0xff5dffff .long 0xff55ffff,0xff51ffff,0xff4dffff,0xff49ffff,0xff41ffff,0xff3cffff,0xff38ffff,0xff30ffff .long 0xff2cffff,0xff28ffff,0xff20ffff,0xff1cffff,0xff18ffff,0xff10ffff,0xff0cffff,0xff08ffff .long 0xff00ffff,0xff00fbff,0xff00f7ff,0xff00f3ff,0xff00ebff,0xff00e7ff,0xff00e3ff,0xff00dbff .long 0xff00d7ff,0xff00d3ff,0xff00cbff,0xff00c7ff,0xff00c3ff,0xff00baff,0xff00b6ff,0xff00b2ff .long 0xff00aaff,0xff00a6ff,0xff00a2ff,0xff009eff,0xff0096ff,0xff0092ff,0xff008eff,0xff0086ff .long 0xff0082ff,0xff007dff,0xff0075ff,0xff0071ff,0xff006dff,0xff0065ff,0xff0061ff,0xff005dff .long 0xff0055ff,0xff0051ff,0xff004dff,0xff0049ff,0xff0041ff,0xff003cff,0xff0038ff,0xff0030ff .long 0xff002cff,0xff0028ff,0xff0020ff,0xff001cff,0xff0018ff,0xff0010ff,0xff000cff,0xff0008ff .long 0xff0000ff,0xff0000fb,0xff0000f7,0xff0000f3,0xff0000ef,0xff0000eb,0xff0000e7,0xff0000e3 .long 0xff0000df,0xff0000db,0xff0000d7,0xff0000d3,0xff0000cf,0xff0000cb,0xff0000c7,0xff0000c3 .long 0xff0000be,0xff0000ba,0xff0000b6,0xff0000b2,0xff0000ae,0xff0000aa,0xff0000a6,0xff0000a2 .long 0xff00009e,0xff00009a,0xff000096,0xff000092,0xff00008e,0xff00008a,0xff000086,0xff000082 .long 0xff00007d,0xff000079,0xff000075,0xff000071,0xff00006d,0xff000069,0xff000065,0xff000061 .long 0xff00005d,0xff000059,0xff000055,0xff000051,0xff00004d,0xff000049,0xff000045,0xff000041 .long 0xff00003c,0xff000038,0xff000034,0xff000030,0xff00002c,0xff000028,0xff000024,0xff000020 .long 0xff00001c,0xff000018,0xff000014,0xff000010,0xff00000c,0xff000008,0xff000000,0xff000000 palette_2: .long 0xff000000,0xff9208e7,0xff9208e3,0xff9608e3,0xff9a04df,0xff9e04df,0xff9e04db,0xffa204db .long 0xffa600d7,0xffaa00d7,0xffaa00d3,0xffae00cf,0xffb200cf,0xffb600cb,0xffb600c7,0xffba00c7 .long 0xffbe00c3,0xffbe00be,0xffc300be,0xffc700ba,0xffc700b6,0xffcb00b6,0xffcf00b2,0xffcf00ae .long 0xffd300aa,0xffd700aa,0xffd700a6,0xffdb04a2,0xffdb049e,0xffdf049e,0xffdf049a,0xffe30896 .long 0xffe30892,0xffe70892,0xffe7088e,0xffeb0c8a,0xffeb0c86,0xffef0c82,0xffef1082,0xffef107d .long 0xfff31479,0xfff31475,0xfff31475,0xfff71871,0xfff7186d,0xfff71c69,0xfffb1c65,0xfffb2065 .long 0xfffb2061,0xfffb245d,0xffff2859,0xffff2859,0xffff2c55,0xffff2c51,0xffff304d,0xffff344d .long 0xffff3449,0xffff3845,0xffff3c45,0xffff3c41,0xffff413c,0xffff453c,0xffff4538,0xffff4934 .long 0xffff4d34,0xffff4d30,0xffff512c,0xffff552c,0xffff5928,0xffff5928,0xfffb5d24,0xfffb6120 .long 0xfffb6520,0xfffb651c,0xfff7691c,0xfff76d18,0xfff77118,0xfff37514,0xfff37514,0xfff37914 .long 0xffef7d10,0xffef8210,0xffef820c,0xffeb860c,0xffeb8a0c,0xffe78e08,0xffe79208,0xffe39208 .long 0xffe39608,0xffdf9a04,0xffdf9e04,0xffdb9e04,0xffdba204,0xffd7a600,0xffd7aa00,0xffd3aa00 .long 0xffcfae00,0xffcfb200,0xffcbb600,0xffc7b600,0xffc7ba00,0xffc3be00,0xffbebe00,0xffbec300 .long 0xffbac700,0xffb6c700,0xffb6cb00,0xffb2cf00,0xffaecf00,0xffaad300,0xffaad700,0xffa6d700 .long 0xffa2db04,0xff9edb04,0xff9edf04,0xff9adf04,0xff96e308,0xff92e308,0xff92e708,0xff8ee708 .long 0xff8aeb0c,0xff86eb0c,0xff82ef0c,0xff82ef10,0xff7def10,0xff79f314,0xff75f314,0xff75f314 .long 0xff71f718,0xff6df718,0xff69f71c,0xff65fb1c,0xff65fb20,0xff61fb20,0xff5dfb24,0xff59ff28 .long 0xff59ff28,0xff55ff2c,0xff51ff2c,0xff4dff30,0xff4dff34,0xff49ff34,0xff45ff38,0xff45ff3c .long 0xff41ff3c,0xff3cff41,0xff3cff45,0xff38ff45,0xff34ff49,0xff34ff4d,0xff30ff4d,0xff2cff51 .long 0xff2cff55,0xff28ff59,0xff28ff59,0xff24fb5d,0xff20fb61,0xff20fb65,0xff1cfb65,0xff1cf769 .long 0xff18f76d,0xff18f771,0xff14f375,0xff14f375,0xff14f379,0xff10ef7d,0xff10ef82,0xff0cef82 .long 0xff0ceb86,0xff0ceb8a,0xff08e78e,0xff08e792,0xff08e392,0xff08e396,0xff04df9a,0xff04df9e .long 0xff04db9e,0xff04dba2,0xff00d7a6,0xff00d7aa,0xff00d3aa,0xff00cfae,0xff00cfb2,0xff00cbb6 .long 0xff00c7b6,0xff00c7ba,0xff00c3be,0xff00bebe,0xff00bec3,0xff00bac7,0xff00b6c7,0xff00b6cb .long 0xff00b2cf,0xff00aecf,0xff00aad3,0xff00aad7,0xff00a6d7,0xff04a2db,0xff049edb,0xff049edf .long 0xff049adf,0xff0896e3,0xff0892e3,0xff0892e7,0xff088ee7,0xff0c8aeb,0xff0c86eb,0xff0c82ef .long 0xff1082ef,0xff107def,0xff1479f3,0xff1475f3,0xff1475f3,0xff1871f7,0xff186df7,0xff1c69f7 .long 0xff1c65fb,0xff2065fb,0xff2061fb,0xff245dfb,0xff2859ff,0xff2859ff,0xff2c55ff,0xff2c51ff .long 0xff304dff,0xff344dff,0xff3449ff,0xff3845ff,0xff3c45ff,0xff3c41ff,0xff413cff,0xff453cff .long 0xff4538ff,0xff4934ff,0xff4d34ff,0xff4d30ff,0xff512cff,0xff552cff,0xff5928ff,0xff5928ff .long 0xff5d24fb,0xff6120fb,0xff6520fb,0xff651cfb,0xff691cf7,0xff6d18f7,0xff7118f7,0xff7514f3 .long 0xff7514f3,0xff7914f3,0xff7d10ef,0xff8210ef,0xff820cef,0xff860ceb,0xff8a0ceb,0xff8e08e7 ; Video initialization parameters. Most of these I don't ; understand; what documentation I have has been saved here as ; comments. The comment "magic" means "meaning unknown". ; ; These lists are taken pretty much directly from tatest, which ; says of them "These values mainly from Dans 3dtest ; program...". ; .macro param offset, value .word $(offset) .long $(value) .endm .align 2 three_d_params: param 0x80a8, 0x15d1c951 ; magic param 0x80a0, 0x00000020 ; magic param 0x8008, 0x00000000 ; TA out of reset param 0x8048, 0x00000009 ; "alpha config" - ? param 0x8068, [X_SIZE<<16]|0 ; pixel clipping x param 0x806c, [Y_SIZE<<16]|0 ; pixel clipping y param 0x8110, 0x00093f39 ; magic param 0x8098, 0x00800408 ; magic param 0x804c, [X_SIZE*2]/8 ; "display align" - ? param 0x8078, 0x3f800000 ; polygon culling (single-float 1.0) param 0x8084, 0x00000000 ; magic param 0x8030, 0x00000101 ; magic param 0x80b0, 0x007f7f7f ; fog table colour param 0x80b4, 0x007f7f7f ; fog vertex colour param 0x80c0, 0x00000000 ; colour clamp min param 0x80bc, 0xffffffff ; colour clamp max param 0x8080, 0x00000007 ; magic param 0x8074, 0x00000001 ; "cheap shadow" - ? param 0x807c, 0x0027df77 ; magic param 0x8008, 0x00000001 ; TA into reset param 0x8008, 0x00000000 ; TA out of reset param 0x80e4, 0x00000000 ; "stride width" - ? param 0x6884, 0x00000000 ; disable all interrupt enables param 0x6930, 0x00000000 param 0x6938, 0x00000000 param 0x6900, 0xffffffff ; reset all pending interrupts param 0x6908, 0xffffffff param 0x6930, 0x002807ec ; re-enable some events (which?) param 0x6938, 0x0000000e param 0x80b8, 0x0000ff07 ; fog density (meanings?) param 0x80b4, 0x007f7f7f ; fog vertex colour param 0x80b0, 0x007f7f7f ; fog table colour param 0x8108, 0x00000003 ; 32bit palette (?) .word 1 screen_params: param 0x80e8, 0x00160000 ; screen control (?) param 0x8044, 0x00800000 ; pixel mode ("vb+0x11" - ?) param 0x805c, 0x00000000 ; size modulo and display lines ("vb+0x17" - ?) param 0x80d0, 0x00000100 ; interlace flags (bit meanings?) param 0x80d8, 0x020c0359 ; magic param 0x80cc, 0x001501fe ; magic param 0x80d4, 0x007e0345 ; horizontal border (meaning? - see below) param 0x80dc, 0x00240204 ; vertical position (meaning?) param 0x80e0, 0x07d6c63f ; sync control (meaning?) param 0x80ec, 0x000000a4 ; horizontal position (meaning?) param 0x80f0, 0x00120012 ; vertical border (meanings?) param 0x80c8, 0x03450000 ; "set to same as border H in 80d4" - ? param 0x8068, [X_SIZE-1]<<16 ; (X resolution - 1) << 16 param 0x806c, [Y_SIZE-1]<<16 ; (Y resolution - 1) << 16 param 0x804c, 0x000000a0 ; "display align" - ? param 0x8118, 0x00008040 ; magic param 0x80f4, 0x00000401 ; "anti-aliasing" - ? param 0x8048, 0x00000009 ; "alpha config" - ? param 0x7814, 0x00000000 ; "more interrupt control stuff" - ? param 0x7834, 0x00000000 param 0x7854, 0x00000000 param 0x7874, 0x00000000 param 0x78bc, 0x4659404f param 0x8040, 0x00000000 ; border colour .word 1 ; "???" here means "not documented in tatest at all" cmdlist_params: param 0x8008, 0x00000001 ; TA into reset param 0x8008, 0x00000000 ; TA out of reset cmdlist_param_tilebuf_a = 2 + . - cmdlist_params param 0x8124, 0 param 0x812c, 0 ; ??? cmdlist_param_cmdlist = 2 + . - cmdlist_params param 0x8128, 0 param 0x8130, 0 ; ??? param 0x813c, [[[Y_SIZE/32]-1]<<16] | [[X_SIZE/32]-1] cmdlist_param_tilebuf_b = 2 + . - cmdlist_params param 0x8164, 0 param 0x8140, 0x00100002 ; ??? param 0x8144, 0x80000000 ; confirm settings .word 1 ; Current double-buffering buffer number. Always 0 or 1. curbuf: .space 1 .align 2 main: ; The only things startup.s sets up that cdcode hasn't already done for ; us are (1) fpscr and (2) clearing bss. We don't have bss because we ; aren't linked by a conventional linker. FPSCR needs setup too. So ; does the VBR. Make sure FD, RB, and BL are clear in the SR. We ; don't need to copy r10-r15, even for the sake of returning to ; cdcode, because only r0-r7 are banked. We save r10-r14 on the stack ; so that we can use them; they matter only on return to cdcode, which ; happens only controlledly. mov.l r14,@-r15 mov.l r13,@-r15 mov.l r12,@-r15 mov.l r11,@-r15 mov.l r10,@-r15 ldc r14,gbr stc sr,r1 SETS.L #~[SR_FD|SR_RB|SR_BL],r2 and r2,r1 ldc r1,sr ; Note that r0-r7 may have just changed if we switched banks. mov #0,r1 lds r1,fpscr SETS.L #intvec,r0 ldc r0,vbr ; Real code begins here. bsr clear_vram nop bsr init_powervr nop bsr init_video nop bsr init_palette nop bsr init_twiddling nop bsr init_textures nop bsr init_tiledesc nop bsr init_3dvalues nop bsr putchar2 mov #'I,r1 1: bsr one_frame nop bsr putchar2 mov #'J,r1 bsr nbgetchar nop cmp/pz r0 bf 1b bsr putchar mov #13,r1 bsr putchar mov #10,r1 ; Turn SR.BL (back) on before returning to cdcode. stc sr,r1 SETS.L #SR_BL,r2 or r2,r1 ldc r1,sr mov.l @r15+,r10 mov.l @r15+,r11 mov.l @r15+,r12 mov.l @r15+,r13 lds r11,pr rts mov.l @r15+,r14 clear_vram: SETS.L #QACR0,r1 SETS.L #QACR1,r2 SETS.L #[[VRAM_BASE>>26]&7]<<2,r3 SETS.L #STOREQ_BASE+[4*16],r4 SETS.L #0,r5 mov.l r3,@r1 mov.l r3,@r2 SETS.L #16,r0 1: dt r0 bf/s 1b mov.l r5,@-r4 SETS.L #VRAM_SIZE/32,r1 SETS.L #[VRAM_BASE&0x03ffffc0]|0xe0000000,r2 1: pref @r2 dt r1 bf/s 1b add #32,r2 mov.l r5,@r4 add #4*16,r4 rts mov.l r5,@r4 set_params: ; r1 points to params table SETS.L #VIDREG_BASE,r2 1: mov.w @r1+,r0 tst #1,r0 bf/s 1f extu.w r0,r0 mov.w @r1+,r3 mov.w @r1+,r4 SHLL #16,r4 extu.w r3,r3 or r3,r4 add r2,r0 bra 1b mov.l r4,@r0 1: rts nop init_powervr: sts.l pr,@-r15 SETS.L #three_d_params,r1 bsr set_params nop SETS.L #0xa05f810c,r1 ; what does this point to? SETS.L #0x000001ff,r2 ; what does this mask mean? SETS.L #65536,r4 mov r4,r3 1: mov.l @r1,r0 tst r2,r0 bt 1b 1: mov.l @r1,r0 tst r2,r0 bf 1b SETS.L #screen_params,r1 bsr set_params nop lds.l @r15+,pr rts nop init_video: sts.l pr,@-r15 ; Get cable type from port A bits 8 and 9 ; 0=VGA, 1=???, 2=RGB, 3=composite SETS.L #PCTRA,r8 SETS.L #~0x000f0000,r2 ; control bits for pins 8 and 9 SETS.L #0x000a0000,r3 ; configure as inputs, pullups enabled mov.l @r8,r0 and r2,r0 or r3,r0 mov.l r0,@r8 .if [[PDTRA-PCTRA] < 128] & [[PDTRA-PCTRA] >= -128] add #PDTRA-PCTRA,r8 .else SETS.L #PDTRA,r8 .endif mov.w @r8,r0 SHXR #8,r0 and #3,r0 mov r0,r9 SETS.L #VIDREG_BASE+0x8000,r8 mov r8,r2 add #8,r2 SETS.L #0,r6 mov.l r6,@r2 ; 0xa05f8008, "TA out of reset" add #0x40-8,r2 mov.l r6,@r2 ; 0xa05f8040, border colour mov #0xd,r3 ; 8/8/8 4bpp, no scan doubling, display enabled SETS.L #240,r7 mov r9,r0 tst #2,r0 bf 1f SHLL #1,r7 swap.w r3,r0 ; |= 0x00800000, clock doubler or #0x80,r0 swap.w r0,r3 1: add #0x44-0x40,r2 mov.l r3,@r2 ; 0xa05f8044, display mode add #0x50-0x44,r2 mov.l r6,@r2 ; 0xa05f8050, vram base offset 1 SETS.L #X_SIZE*4,r3 ; pixels * bytes-per-pixel add #0x54-0x50,r2 mov.l r3,@r2 ; 0xa05f8054, vram base offset 2 SETS.L #1<<8,r3 ; VO, negative H and V sync SETS.L #X_SIZE,r4 SETS.L #1,r5 mov r9,r0 tst #2,r0 bt 1f add r4,r5 SETS.L #0x10,r0 ; interlaced, NTSC colour or r0,r3 1: SHLL #10,r5 add r7,r5 add #-1,r5 SHLL #10,r5 add r4,r5 add #-1,r5 add #0x5c-0x54,r2 mov.l r5,@r2 ; 0xa05f805c, display size and modulo SETS.L #0x007e0345,r8 ; doesn't make sense per doc add #0xd4-0x5c,r2 mov.l r8,@r2 ; 0xa05f80d4, H border range SETS.L #[524<<16]|857,r8; NTSC/VGA add #0xd8-0xd4,r2 mov.l r8,@r2 ; 0xa05f80d8, full video size mov r9,r0 and #2,r0 mov r0,r3 SHLL #3,r0 or r3,r0 SETS.L #36,r3 sub r0,r3 mov r3,r0 SHLL #16,r0 or r0,r3 mov r3,r8 add r7,r8 add #0xdc-0xd8,r2 mov.l r8,@r2 ; 0xa05f80dc, V border range SETS.L #22<<16,r8 ; N=magic, pixel duplication disabled add #0xe8-0xdc,r2 mov.l r8,@r2 ; 0xa05f80e8, additional video settings SETS.L #0xa4,r8 add #0xec-0xe8,r2 mov.l r8,@r2 ; 0xa05f80ec, H position add #0xf0-0xec,r2 mov.l r3,@r2 ; 0xa05f80f0, V position SETS.L #260,r4 mov r9,r0 tst #2,r0 bf 1f SETS.L #510,r4 1: SETS.L #0x21<<16,r3 or r3,r4 add #0xcc-0xf0,r2 mov.l r4,@r2 ; 0xa05f80cc, raster event position mov r9,r0 tst #1,r0 bt/s 1f mov #0,r8 mov #3,r8 1: SETS.L #0xa0702c00,r3 mov.l r8,@r2 ; 0xa0702c00, "Select RGB/CVBS" (??) lds.l @r15+,pr rts nop SETCONST init_palette: SETS.L #0xa05f9000,r1 SETS.L #256*4,r7 mov r1,r3 add r7,r3 mov r3,r5 add r7,r5 SETS.L #palette_0,r2 SETS.L #palette_1,r4 SETS.L #palette_2,r6 SETS.L #256,r7 1: mov.l @r2+,r0 mov.l r0,@r1 mov.l @r4+,r0 mov.l r0,@r3 mov.l @r6+,r0 mov.l r0,@r5 add #4,r1 add #4,r3 dt r7 bf/s 1b add #4,r5 rts nop init_twiddling: SETS.L #twiddles+[1024*2],r1 SETS.L #1024,r2 SETS.L #0x00300,r3 SETS.L #0x000f0,r4 SETS.L #0x00c0c,r5 SETS.L #0x22222,r6 1: add #-1,r2 mov r2,r0 and r3,r0 SHLL #8,r0 mov r2,r7 not r3,r8 and r8,r7 or r0,r7 mov r7,r0 and r4,r0 SHLL #4,r0 not r4,r8 and r8,r7 or r0,r7 mov r7,r0 and r5,r0 SHLL #2,r0 not r5,r8 and r8,r7 or r0,r7 mov r7,r0 and r6,r0 SHLL #1,r0 not r6,r8 and r8,r7 or r0,r7 tst r2,r2 bf/s 1b mov.w r7,@-r1 rts nop ; The C code this is based upon (again, from tatest) ; ; for(i=0; i<256; i++) ; for(j=0; j<256; j+=2) { ; /* Texture 0 = Mandelbrot */ ; tex[0][twiddletab[i]|(twiddletab[j]>>1)] = ; compute_texture(i, j, 0) | (compute_texture(i, j+1, 0)<<8); ; /* Texture 1 = Julia */ ; tex[1][twiddletab[i]|(twiddletab[j]>>1)] = ; compute_texture(i, j, 1) | (compute_texture(i, j+1, 1)<<8); ; } ; ; We change some names (eg, compute_texture_a and compute_texture_b ; rather than a third arg to compute_texture), but it's otherwise ; pretty similar. We keep a lot of stuff on the stack rather than in ; registers; while we might have enough registers, this means I don't ; have to think about register allocation as much. It also means the ; texture computation functions have a much freer hand with registers. init_textures: sts.l pr,@-r15 SETS.L #twiddles,r7 mov.l r7,@-r15 SETS.L #textures,r9 SETS.L #0xa4400000,r8 mov.l r8,@r9 swap.w r8,r0 add #1,r0 swap.w r0,r6 mov.l r6,@(4,r9) mov.l r6,@-r15 mov.l r8,@-r15 mov #0,r0 mov.l r0,@-r15 2: mov #0,r0 mov.l r0,@-r15 ; stack = x y tex0 tex1 twiddles 1: mov.l @r15,r1 ; x bsr compute_texture_a mov.l @(4,r15),r2 ; y mov.l r0,@-r15 ; valA(x,y) mov.l @(4,r15),r1 ; x mov.l @(8,r15),r2 ; y bsr compute_texture_a add #1,r1 mov.l @r15+,r1 ; valA(x+1,y) SHLL #8,r0 or r1,r0 ; combined vals mov.l r0,@-r15 mov.l @(4,r15),r1 ; x bsr compute_texture_b mov.l @(8,r15),r2 ; y mov.l r0,@-r15 ; valB(x,y) mov.l @(8,r15),r1 ; x mov.l @(12,r15),r2 ; y bsr compute_texture_b add #1,r1 mov.l @r15+,r1 ; valB(x+1,y) SHLL #8,r0 or r1,r0 ; combined vals mov.l r0,@-r15 ; stack = valsB valsA x y tex0 tex1 twiddles mov.l @(24,r15),r2 ; twiddles mov.l @(8,r15),r1 ; x SHLL #1,r1 add r2,r1 mov.w @r1,r1 mov.l @(12,r15),r3 ; y SHLL #1,r3 add r2,r3 mov.w @r3,r3 SHLL #1,r3 or r1,r3 ; r3 now holds twiddled texture offset mov.l @(16,r15),r2 ; tex0 add r3,r2 .if debug_texture bsr printhex8 mov.l @(8,r15),r1 bsr putchar mov #' ,r1 bsr printhex8 mov.l @(12,r15),r1 bsr putchar2 mov #' ,r1 bsr printhex8 mov r2,r1 bsr putchar mov #' ,r1 bsr printhex8 mov.l @(4,r15),r1 bsr putchar2 mov #' ,r1 .endif mov.l @(4,r15),r0 ; valA mov.w r0,@r2 mov.l @(20,r15),r2 ; tex1 add r3,r2 .if debug_texture bsr printhex8 mov r2,r1 bsr putchar mov #' ,r1 bsr printhex8 mov.l @r15,r1 bsr putchar mov #13,r1 bsr putchar mov #10,r1 .endif mov.l @r15,r0 ; valB mov.w r0,@r2 add #8,r15 ; pop valA, valB SETS.L #256,r1 mov.l @r15,r0 ; x add #2,r0 cmp/hs r1,r0 bf/s 1b mov.l r0,@r15 add #4,r15 ; pop x mov.l @r15,r0 ; y add #1,r0 cmp/hs r1,r0 bf/s 2b mov.l r0,@r15 add #16,r15 ; pop remaining lds.l @r15+,pr rts nop ; The disabled code below is an attempt at cloning tatest's texture ; computation. It doesn't work and I don't care why enough to bother ; debugging it when I can do something quicker and cheaper and just as ; good for smoke-test purposes (see the .else block). .if 0 ; Texture computation. Texture A is the Mandelbrot set; ; texture B is the Julia set - or, at least, quick-&-dirty ; approximations to them; as tatest says, "I'm not trying to ; get any points for correct mathematics here, only a cheap ; way to get some textures for my code :)". ; These functions use r1 and r2 for input (x=r1, y=r2) and r0 ; for output. CPU registers r3-r9 and all FPU registers are ; available for use, as is the stack (r15 is the SP). compute_texture_a: SETS.L #texsetup_a,r0 bra compute_texture_common nop compute_texture_b: SETS.L #texsetup_b,r0 compute_texture_common: SETS.L #128,r3 lds r3,fpul float fpul,fr0 lds r1,fpul float fpul,fr1 lds r2,fpul float fpul,fr2 SETS.L #16384,r3 lds r3,fpul float fpul,fr3 fsub fr0,fr1 fsub fr0,fr2 fmul fr3,fr1 fmul fr3,fr2 ; Single-float 1.313747 = s=0, e=127+0, m=(1.)5051b93... ; This rounds up to 23 fraction bits as 1.5051ba. SETS.L #[[127+0]<<23]|[0x5051ba>>1],r3 lds r3,fpul fsts fpul,fr5 fsub fr5,fr1 ; Single-float 0.073227 = s=0, e=127-4, m=(1.)2bf01322f27... ; This rounds up to 23 fraction bits as 1.2bf014. SETS.L #[[127-4]<<23]|[0x2bf014>>1],r3 lds r3,fpul fsts fpul,fr6 sts pr,r3 jsr @r0 fsub fr6,fr2 lds r3,pr ; Inner loop from tatest's analogous function ; ; do { ; float tmp_r = z_re; ; z_re = z_re*z_re - z_im*z_im + c_re; ; z_im = 2*tmp_r*z_im + c_im; ; } while(++n<255 && z_re*z_re+z_im*z_im<=2.0); ; ; Register usage ; ; fr0 tmp_r ; fr1 c_re ; fr2 c_im ; fr3 z_re ; fr4 z_im ; fr5 2.0 ; fr6 z_re**2 ; fr7 z_im**2 (LHS of comparison, at end) ; fr8+ scratch ; r0 ~n (we count down and complement later) ; ; We don't use fr5 for the 2*, but we do for the <=2.0. fldi1 fr5 fadd fr5,fr5 SETS.L #255,r0 1: ; tmp_r = z_re fmov fr3,fr0 ; z_re = z_re*z_re - z_im*z_im + c_re fmov fr3,fr6 fmul fr3,fr6 fmov fr4,fr7 fmul fr4,fr7 fmov fr6,fr3 fsub fr7,fr3 fadd fr1,fr3 ; z_im = 2*tmp_r*z_im + c_im fmul fr0,fr4 fadd fr4,fr4 dt r0 bt/s 1f fadd fr2,fr4 fadd fr6,fr7 fcmp/gt fr5,fr7 bf 1b 1: not r0,r0 rts extu.b r0,r0 texsetup_a: fldi0 fr3 rts fldi0 fr4 texsetup_b: fmov fr1,fr3 fmov fr2,fr4 fmov fr5,fr1 fneg fr1 fmov fr6,fr2 rts fneg fr2 .else ; Texture A is diagonal stripes; texture B is concentric circles ; centred on (0,80). compute_texture_a: ; return(255&(x+y)) add r2,r1 rts extu.b r1,r0 compute_texture_b: ; return(255&(int)hypot(x,y-80)) lds r1,fpul float fpul,fr0 add #-80,r2 lds r2,fpul float fpul,fr1 fmul fr0,fr0 fmul fr1,fr1 fadd fr1,fr0 fsqrt fr0 ftrc fr0,fpul sts fpul,r0 rts extu.b r0,r0 .endif SETCONST init_tiledesc: sts.l pr,@-r15 SETS.L #0xa5400000,r2 ta_buffers_size_cmd_list = 512 * 1024 ta_buffers_size_tile_buffer = 64 * [X_SIZE/32] * [Y_SIZE/32] ta_buffers_size_tile_descriptor = 4 * [24 + [6 * [X_SIZE/32] * [Y_SIZE/32]]] SETS.L #cmdlists,r4 SETS.L #tilebuffers,r5 SETS.L #tiledescs,r6 mov.l r2,@r4 SETS.L #ta_buffers_size_cmd_list,r0 add r0,r2 mov.l r2,@(4,r4) add r0,r2 mov.l r2,@r5 SETS.L #ta_buffers_size_tile_buffer,r0 add r0,r2 mov.l r2,@(4,r5) add r0,r2 mov.l r2,@r6 SETS.L #ta_buffers_size_tile_descriptor,r0 add r0,r2 mov.l r2,@(4,r6) SETS.L #tiledesc_cookies,r4 mov.l @(4,r5),r0 mov.l r0,@-r15 mov.l @(4,r6),r0 mov.l r0,@-r15 mov.l @r6,r2 bsr setup_tiledesc mov.l @r5,r3 mov.l r0,@r4 mov.l @r15+,r2 bsr setup_tiledesc mov.l @r15+,r3 mov.l r0,@(4,r4) SETS.L #curbuf,r1 mov #0,r0 lds.l @r15+,pr rts mov.b r0,@r1 setup_tiledesc: ; in tatest terms, this is ta_create_tile_descriptors. ptr is ; r2, buf is r3, w is X_SIZE/32, and h is Y_SIZE/32. No ; registers r0-r9 are important upon return; they all are ; available to us. ; vr = ptr mov r2,r4 ; vr is r4 ; bf = ((unsigned int)buf)&0x007fffff (buf is dead after this) SETS.L #0x007fffff,r0 and r0,r3 ; bf is r3 from here on ; strbase = (((unsigned int)ptr)&0x007fffff)|0x80000000 ; ptr is _not_ dead here, but 0x007fffff is. SETS.L #0x80000000,r7 ; strbase is r7 and r2,r0 or r0,r7 ; for (18 loops) *vr++ = 0 mov #18,r1 mov #0,r0 1: mov.l r0,@r4 dt r1 bf/s 1b add #4,r4 ; *vr++ = 0x10000000 ; *vr++ = 0x80000000 (five times) SETS.L #0x10000000,r1 mov.l r1,@r4 SETS.L #0x80000000,r1 mov.l r1,@(4,r4) mov.l r1,@(8,r4) mov.l r1,@(12,r4) mov.l r1,@(16,r4) mov.l r1,@(20,r4) add #24,r4 SETS.L #X_SIZE/32,r8 ; w is r8 SETS.L #Y_SIZE/32,r9 ; h is r9 ; for (x=0;x>1],r0 lds r0,fpul fsts fpul,fr0 fldi0 fr1 fldi0 fr2 fldi0 fr3 fldi0 fr4 fmov fr0,fr5 fldi0 fr6 fldi0 fr7 fldi0 fr8 fldi0 fr9 ; (ZFAR+ZNEAR)/(ZNEAR-ZFAR), or (100+1)/(1-100), which = ; -1.0202020202020... = s=1, e=127+0, m=(1.)052bf5a814afd... ; This rounds up to 23 fraction bits as 1.052bf6. SETS.L #0x80000000|[[127+0]<<23]|[0x052bf6>>1],r0 lds r0,fpul fsts fpul,fr10 fldi1 fr11 fneg fr11 fldi0 fr12 fldi0 fr13 ; 2*ZFAR*ZNEAR/(ZNEAR-ZFAR), or 2*1*100/(1-100), which = ; -2.020202020202020... = s=1, e=127+1, m=(1.)0295fad40a57eb... ; This rounds down to 23 fraction bits as 1.0295fa. SETS.L #0x80000000|[[127+1]<<23]|[0x0295fa>>1],r0 lds r0,fpul fsts fpul,fr14 fldi1 fr15 ftrv xmtrx,fv0 ftrv xmtrx,fv4 ftrv xmtrx,fv8 ftrv xmtrx,fv12 frchg ; apply_matrix(&translation_matrix) fldi1 fr0 fldi0 fr1 fldi0 fr2 fldi0 fr3 fldi0 fr4 fldi1 fr5 fldi0 fr6 fldi0 fr7 fldi0 fr8 fldi0 fr9 fldi1 fr10 fldi0 fr11 fldi0 fr12 fldi0 fr13 SETS.L #5,r0 lds r0,fpul float fpul,fr14 fldi1 fr15 ftrv xmtrx,fv0 ftrv xmtrx,fv4 ftrv xmtrx,fv8 ftrv xmtrx,fv12 SETS.L #base_matrix+[16*4],r0 fschg .sz 1 fmov dr14,@-r0 fmov dr12,@-r0 fmov dr10,@-r0 fmov dr8,@-r0 fmov dr6,@-r0 fmov dr4,@-r0 fmov dr2,@-r0 fmov dr0,@-r0 fschg .sz 0 SETS.L #rotations+[3*4],r0 SETS.L #0,r1 ; single-float 0.0 mov.l r1,@-r0 mov.l r1,@-r0 rts mov.l r1,@-r0 SETCONST ; Because we do trig with fsca, the most convenient units are ; not radians, but rather something in which a full circle is ; 64K. That's the units we use here. This makes reduction ; modulo "2pi" really really easy. The rotations used here ; are taken from tatest (adapted for 64K rather than 2K). ; The setrot_* functions are entered with the identity matrix ; in fr0..fr15 and the trig argument in fpul. setrot_x: ; fr5 = cos, fr10 = cos, fr6 = -sin, fr9 = sin fsca fpul,fr6 fmov fr7,fr5 fmov fr7,fr10 fldi0 fr7 fmov fr6,fr9 rts fneg fr6 setrot_y: ; fr0 = cos, fr10 = cos, fr2 = sin, fr8 = -sin fsca fpul,fr2 fmov fr2,fr8 fmov fr3,fr0 fmov fr3,fr10 fldi0 fr3 rts fneg fr8 setrot_z: ; fr0 = cos, fr5 = cos, fr1 = -sin, fr4 = sin fsca fpul,fr4 fmov fr5,fr0 fmov fr4,fr1 rts fneg fr1 one_frame: sts.l pr,@-r15 bsr putchar2 mov #'a,r1 bsr update_rotations nop bsr putchar2 mov #'b,r1 bsr apply_rotations nop bsr putchar2 mov #'c,r1 bsr transform_coords nop bsr putchar2 mov #'d,r1 bsr setup_cmd_list nop bsr putchar2 mov #'e,r1 bsr draw_cube nop bsr putchar2 mov #'f,r1 bsr next_frame nop bsr putchar2 mov #'g,r1 lds.l @r15+,pr rts nop update_rotations: SETS.L #rotations,r0 fmov.s @r0+,fr0 fmov.s @r0+,fr1 fmov.s @r0+,fr2 ; 1088/5 = d9.99999999... = s=1, e=127+7, m=(1.)b333333333... ; This rounds up to 23 fraction bits as 1.b33334. SETS.L #[[127+7]<<23]|[0xb33334>>1],r1 lds r1,fpul fsts fpul,fr3 ; 800/7 = 72.492492492... = s=1, e=127+6, m=(1.)c924924924... ; This rounds down to 23 fraction bits as 1.c92492. SETS.L #[[127+6]<<23]|[0xc92492>>1],r1 lds r1,fpul fsts fpul,fr4 ; 1504/9 = a7.1c71c71c... = s=1, e=127+7, m=(1.)4e38e38e38... ; This rounds up to 23 fraction bits as 1.4e38e4. SETS.L #[[127+7]<<23]|[0x4e38e4>>1],r1 lds r1,fpul fsts fpul,fr5 SETS.L #65536,r1 lds r1,fpul float fpul,fr6 fadd fr3,fr0 fadd fr4,fr1 fadd fr5,fr2 fcmp/gt fr0,fr6 bt 1f fsub fr6,fr0 1: fcmp/gt fr1,fr6 bt 1f fsub fr6,fr1 1: fcmp/gt fr2,fr6 bt 1f fsub fr6,fr2 1: fmov.s fr2,@-r0 fmov.s fr1,@-r0 rts fmov.s fr0,@-r0 apply_rotations: sts.l pr,@-r15 SETS.L #setrot_z,r0 mov.l r0,@-r15 ftrc fr2,fpul sts.l fpul,@-r15 SETS.L #setrot_y,r0 mov.l r0,@-r15 ftrc fr1,fpul sts.l fpul,@-r15 SETS.L #setrot_x,r0 mov.l r0,@-r15 ftrc fr0,fpul sts.l fpul,@-r15 SETS.L #base_matrix,r0 fschg .sz 1 fmov @r0+,dr0 fmov @r0+,dr2 fmov @r0+,dr4 fmov @r0+,dr6 fmov @r0+,dr8 fmov @r0+,dr10 fmov @r0+,dr12 fmov @r0+,dr14 fschg .sz 0 frchg SETS.L #3,r2 1: lds.l @r15+,fpul mov.l @r15+,r0 fldi1 fr0 fldi0 fr1 fldi0 fr2 fldi0 fr3 fldi0 fr4 fldi1 fr5 fldi0 fr6 fldi0 fr7 fldi0 fr8 fldi0 fr9 fldi1 fr10 fldi0 fr11 fldi0 fr12 fldi0 fr13 fldi0 fr14 jsr @r0 fldi1 fr15 ftrv xmtrx,fv0 ftrv xmtrx,fv4 ftrv xmtrx,fv8 ftrv xmtrx,fv12 dt r2 bf/s 1b frchg lds.l @r15+,pr rts nop transform_coords: SETS.L #cube_coords,r1 pref @r1 mov r1,r5 add #[3*4]-1,r5 pref @r5 SETS.L #xform_coords,r0 SETS.L #8,r2 SETS.L #4,r3 SETS.L #8,r4 1: add #3*4,r5 pref @r5 fmov.s @r1+,fr0 fmov.s @r1+,fr1 fmov.s @r1+,fr2 fldi1 fr3 ftrv xmtrx,fv0 dt r2 ; fr3 should always be exactly 1 here, but.... fdiv fr3,fr0 fdiv fr3,fr1 fdiv fr3,fr2 fmov.s fr0,@r0 fmov.s fr1,@(r0,r3) fmov.s fr2,@(r0,r4) bf/s 1b add #3*4,r0 rts nop setup_cmd_list: ; In tatest terms, this is ta_set_target, but with args ; computed here based on curbuf rather than being passed in. sts.l pr,@-r15 SETS.L #curbuf,r1 mov.b @r1,r1 SHLL #2,r1 SETS.L #cmdlists,r2 SETS.L #tilebuffers,r3 add r1,r2 mov.l @r2,r2 add r1,r3 mov.l @r3,r3 SETS.L #0x007fffff,r4 and r4,r2 and r4,r3 swap.w r2,r4 swap.w r3,r5 SETS.L #cmdlist_params,r0 SETS.L #cmdlist_param_tilebuf_a,r1 mov.w r3,@(r0,r1) add #2,r1 mov.w r5,@(r0,r1) SETS.L #cmdlist_param_tilebuf_b,r1 mov.w r3,@(r0,r1) add #2,r1 mov.w r5,@(r0,r1) SETS.L #cmdlist_param_cmdlist,r1 mov.w r2,@(r0,r1) add #2,r1 mov.w r4,@(r0,r1) bsr set_params mov r0,r1 lds.l @r15+,pr rts nop SETCONST ; This does not have an exact tatest analog. It corresponds to ; the six draw_face() calls and the ta_commit_end() after ; them. draw_cube: sts.l pr,@-r15 bsr putchar2 mov #'z,r1 SETS.L #cube_faces,r9 SETS.L #6,r8 SETS.L #ta_cmd,r7 SETS.L #0,r6 SETS.L #127<<23,r5 ; single-float 1.0 SETS.L #xform_coords,r4 SETS.L #3*4,r3 1: SETS.L #TA_CMD_POLYGON|TA_CMD_POLYGON_TYPE_OPAQUE|TA_CMD_POLYGON_SUBLIST|TA_CMD_POLYGON_STRIPLENGTH_2|TA_CMD_POLYGON_TEXTURED,r0 mov.l r0,@r7 ; cmd SETS.L #TA_POLYMODE1_Z_ALWAYS|TA_POLYMODE1_CULL_CCW,r0 mov.l r0,@(4,r7) ; mode1 SETS.L #TA_POLYMODE2_BLEND_DEFAULT|TA_POLYMODE2_FOG_DISABLED|TA_POLYMODE2_TEXTURE_CLAMP_U|TA_POLYMODE2_TEXTURE_CLAMP_V|TA_POLYMODE2_BILINEAR_FILTER|TA_POLYMODE2_MIPMAP_D_1_00|TA_POLYMODE2_TEXTURE_REPLACE|TA_POLYMODE2_U_SIZE_256|TA_POLYMODE2_V_SIZE_256,r0 mov.l r0,@(8,r7) ; mode2 bsr putchar mov #'y,r1 mov #6,r10 mov r9,r11 2: mov.b @r11+,r1 bsr putchar add #'0,r1 dt r10 bf 2b bsr putchar mov #'y,r1 SETS.L #TA_TEXTUREMODE_CLUT8,r1 mov.b @(4,r9),r0 SHLL #TA_TEXTUREMODE_CLUTBANK8_SHIFT,r0,r2 or r0,r1 mov.b @(5,r9),r0 SETS.L #textures,r2 SHLL #2,r0 mov.l @(r0,r2),r0 mov r0,r10 mov r1,r11 bsr printhex8 mov r0,r1 bsr putchar mov #'y,r1 mov r10,r0 mov r11,r1 SHXR #TA_TEXTUREMODE_ADDRESS_SHIFT,r0 SETS.L #TA_TEXTUREMODE_ADDRESS_MASK,r2 and r2,r0 or r0,r1 bsr printhex8 mov r1,r11 bsr putchar mov #'y,r1 mov r11,r1 mov.l r1,@(12,r7) ; texture mov.l r6,@(16,r7) ; alpha mov.l r6,@(20,r7) ; red mov.l r6,@(24,r7) ; green bsr commit_ta_cmd mov.l r6,@(28,r7) ; blue SETS.L #TA_CMD_VERTEX,r1 mov.l r1,@r7 ; cmd mov.l r6,@(28,r7) ; ocolour not r6,r1 mov.l r1,@(24,r7) ; colour mov.b @r9,r1 mulu.w r1,r3 sts macl,r0 add r4,r0 mov.l @r0,r2 mov.l r2,@(4,r7) ; x mov.l @(4,r0),r2 mov.l r2,@(8,r7) ; y mov.l @(8,r0),r2 mov.l r2,@(12,r7) ; z mov.l r6,@(16,r7) ; u bsr commit_ta_cmd mov.l r6,@(20,r7) ; v mov.b @(1,r9),r0 mulu.w r0,r3 sts macl,r0 add r4,r0 mov.l @r0,r2 mov.l r2,@(4,r7) ; x mov.l @(4,r0),r2 mov.l r2,@(8,r7) ; y mov.l @(8,r0),r2 mov.l r2,@(12,r7) ; z mov.l r5,@(16,r7) ; u bsr commit_ta_cmd mov.l r6,@(20,r7) ; v mov.b @(2,r9),r0 mulu.w r0,r3 sts macl,r0 add r4,r0 mov.l @r0,r2 mov.l r2,@(4,r7) ; x mov.l @(4,r0),r2 mov.l r2,@(8,r7) ; y mov.l @(8,r0),r2 mov.l r2,@(12,r7) ; z mov.l r6,@(16,r7) ; u bsr commit_ta_cmd mov.l r5,@(20,r7) ; v mov.b @(3,r9),r0 mulu.w r0,r3 sts macl,r0 add r4,r0 mov.l @r0,r2 mov.l r2,@(4,r7) ; x mov.l @(4,r0),r2 mov.l r2,@(8,r7) ; y mov.l @(8,r0),r2 mov.l r2,@(12,r7) ; z mov.l r5,@(16,r7) ; u mov.l r5,@(20,r7) ; v SETS.L #TA_CMD_VERTEX|TA_CMD_VERTEX_EOS,r1 bsr commit_ta_cmd mov.l r1,@r7 ; cmd dt r8 bf/s 1b add #6,r9 ; making this a loop saves only one instruction and adds time. mov.l r6,@r7 mov.l r6,@(4,r7) mov.l r6,@(8,r7) mov.l r6,@(12,r7) mov.l r6,@(16,r7) mov.l r6,@(20,r7) mov.l r6,@(24,r7) bsr commit_ta_cmd mov.l r6,@(28,r7) lds.l @r15+,pr rts nop commit_ta_cmd: ; In tatest terms, this is ta_commit_list(), with the argument ; always being ta_cmd. sts.l pr,@-r15 bsr putchar2 mov #'(,r1 SETS.L #QACR0,r1 SETS.L #STOREQ_BASE+[8*4],r14 SETS.L #[[TA_CMD_BASE>>26]&7]<<2,r13 SETS.L #ta_cmd+[8*4],r12 SETS.L #8,r11 mov.l r1,@-r15 add #-8*4,r12 bsr printhex8 mov.l @r12+,r1 bsr putchar mov #' ,r1 bsr printhex8 mov.l @r12+,r1 bsr putchar mov #' ,r1 bsr printhex8 mov.l @r12+,r1 bsr putchar mov #' ,r1 bsr printhex8 mov.l @r12+,r1 bsr putchar mov #' ,r1 bsr printhex8 mov.l @r12+,r1 bsr putchar mov #' ,r1 bsr printhex8 mov.l @r12+,r1 bsr putchar mov #' ,r1 bsr printhex8 mov.l @r12+,r1 bsr putchar mov #' ,r1 bsr printhex8 mov.l @r12+,r1 mov.l @r15+,r1 mov.l r13,@r1 1: mov.l @r12,r0 dt r11 add #-4,r12 bf/s 1b mov.l r0,@-r14 pref @r14 bsr putchar2 mov #'),r1 lds.l @r15+,pr rts nop pref @r14 next_frame: ; In tatest terms, this is everything in the main loop after ; the call to ta_commit_end(). ; ta_wait_render() sts.l pr,@-r15 bsr putchar2 mov #'1,r1 SETS.L #TA_RENDER_EVENT,r1 SETS.L #TA_RENDER_BIT,r2 1: mov.l @r1,r0 tst r2,r0 bt 1b mov.l r2,@r1 bsr putchar2 mov #'2,r1 ; wait_bovp() SETS.L #VBLANK_REG,r1 SETS.L #VBLANK_VBIT,r2 mov.l r2,@r1 1: mov.l @r1,r0 tst r2,r0 bt 1b mov.l r2,@r1 ; Switch to the previously-rendered screen SETS.L #curbuf,r10 SETS.L #render_buf,r11 mov.b @r10,r0 SHLL #2,r0 mov.l @(r0,r11),r1 SETS.L #0x007fffff,r12 SETS.L #DISPLAY_VRAM,r3 and r12,r1 mov.l r1,@r3 SETS.L #640*2,r0 add r0,r1 mov.l r1,@(4,r3) ; Kick off rendering to the screen we just stopped displaying mov.b @r10,r0 SETS.L #cmdlists,r1 SHLL #2,r0 SETS.L #tiledesc_cookies,r2 mov.l @(r0,r1),r1 mov.l @(r0,r2),r2 xor #4,r0 mov.l @(r0,r11),r3 SETS.L #VIDREG_BASE+0x8138,r4 SETS.L #0x12,r5 SETS.L #0,r6 mov.l @r4,r4 SETS.L #0xa5000000,r0 or r0,r4 add #0x12*4,r4 1: mov.l r6,@-r4 dt r5 bf 1b ; We could use set_params here, but with the number of values ; to store and the need to break longs into two words, it's ; less pain to do it this way. Do we have to do all these in ; exactly this order? I suspect not, but, absent ; documentation, it's hard to tell how much deviation is OK. ; We stick striclty to the order tatest uses. SETS.L #VIDREG_BASE+0x802c,r5 and r12,r2 mov.l r2,@r5 ; 0xa05f802c add #0x8020-0x802c,r5 mov r1,r0 and r12,r0 mov.l r0,@r5 ; 0xa05f8020 add #0x8060-0x8020,r5 and r12,r3 mov.l r3,@r5 ; 0xa05f8060 add #0x808c-0x8060,r5 sub r1,r4 SHLL #1,r4 SETS.L #0x01000000,r0 or r4,r0 mov.l r0,@r5 ; 0xa05f808c add #0x8088-0x808c,r5 SETS.L #0x3e4cccc0,r0 ; "zclip" says tatest mov.l r0,@r5 ; 0xa05f8088 add #0x8068-0x8088,r5 SETS.L #[X_SIZE-1]<<16,r0 ; tatest calls it "clipw" mov.l r0,@r5 ; 0xa05f8068 add #0x806c-0x8068,r5 SETS.L #[Y_SIZE-1]<<16,r0 ; tatest calls it "cliph" mov.l r0,@r5 ; 0xa05f806c add #0x804c-0x806c,r5 SETS.L #[X_SIZE*2]>>3,r0 ; tatest calls it "modulo" mov.l r0,@r5 ; 0xa05f804c add #0x8048-0x804c,r5 SETS.L #TA_PIXFMT_RGB565|TA_PIXFMT_DITHER,r0 ; tatest calls it "pixfmt" mov.l r0,@r5 ; 0xa05f8048 add #0x8014-0x8048,r5 SETS.L #0xffffffff,r0 ; tatest says "Launch!" mov.l r0,@r5 ; 0xa05f8014 ; curbuf = ! curbuf mov.b @r10,r0 tst r0,r0 bt/s 1f add #1,r0 mov #0,r0 lds.l @r15+,pr 1: rts mov.b r0,@r10 SETCONST printhex8: mov #8,r0 printhexN: mov.l r4,@-r15 mov r0,r4 add #-8,r0 neg r0,r0 SHLL #2,r0 shld r0,r1 mov.l r3,@-r15 mov.l r2,@-r15 sts.l pr,@-r15 mova 9f,r0 mov r0,r3 mov r1,r2 1: mov r2,r0 SHLR #28,r0,r1 SHLL #4,r2 add r3,r0 bsr putchar mov.b @r0,r1 dt r4 bf 1b lds.l @r15+,pr mov.l @r15+,r2 mov.l @r15+,r3 rts mov.l @r15+,r4 .align 4 9: .ascii "0123456789abcdef" .align 2 putchar2: sts.l pr,@-r15 bsr putchar mov.l r1,@-r15 mov.l @r15+,r1 lds.l @r15+,pr putchar: 1: mov.w @(SCFDR2-SCIF_BASE,gbr),r0 SHXR #SCFDR2_TX_SHIFT,r0 and #SCFDR2_TX_MASK,r0 cmp/eq #16,r0 bt 1b mov r1,r0 mov.b r0,@(SCFTDR2-SCIF_BASE,gbr) 1: mov.w @(SCFDR2-SCIF_BASE,gbr),r0 SHXR #SCFDR2_TX_SHIFT,r0 tst #SCFDR2_TX_MASK,r0 bf 1b rts nop putstr: 1: mov.w @(SCFDR2-SCIF_BASE,gbr),r0 SHXR #SCFDR2_TX_SHIFT,r0 and #SCFDR2_TX_MASK,r0 cmp/eq #16,r0 bt 1b mov.b @r1+,r0 tst r0,r0 bt 1f bra 1b mov.b r0,@(SCFTDR2-SCIF_BASE,gbr) 1: ; don't bother waiting for drain here; we do a putchar call, ; which will drain everything, after all putstr calls and ; before anything for which it matters. rts nop nbgetchar: mov.w @(SCFDR2-SCIF_BASE,gbr),r0 SHXR #SCFDR2_RX_SHIFT,r0,r1 tst #SCFDR2_RX_MASK,r0 bt 1f mov.b @(SCFRDR2-SCIF_BASE,gbr),r0 extu.b r0,r1 mov.w @(SCLSR2-SCIF_BASE,gbr),r0 mov #0,r0 mov.w r0,@(SCLSR2-SCIF_BASE,gbr) rts mov r1,r0 1: rts mov #-1,r0 SETCONST ; Not sure we actually need to align the VBR; the only reason I ; have to suspect we might is that it's the kind of thing I've ; seen relatively often before - interrupt/trap vector tables ; often need to be aligned, not infrequently to a remarkably ; strict boundary. I see no indication in the manuals that ; the SH requires _any_ alignment, but it's easy to do and ; definitely won't hurt anything. (No explicit indication, ; that is. It is implicit in the execution of code at ; VBR+0x100, VBR+0x400, and VBR+0x600 that VBR must be even.) .align 0x10000 ; Exception handling consists of: ; - Save PC and SR in SPC and SSR ; - Set SR bit BL to 1 (block exceptions/interrupts) ; - Set SR bit MD to 1 (privileged mode) ; - Set SR bit RB to 1 (r0-r7 bank 1) ; - Write code to EXPEVT or INTEVT ; - Set PC to vector addr, resume execution intvec = . . = intvec + 0x100 SETS.L #0x100,r2 SETS.L #EXPEVT,r0 mov.l @r0,r3 SETS.L #INTEVT,r0 SETS.L #regdump,r1 jmp @r1 mov.l @r0,r4 SETCONST . = intvec + 0x400 SETS.L #0x400,r2 SETS.L #EXPEVT,r0 mov.l @r0,r3 SETS.L #INTEVT,r0 SETS.L #regdump,r1 jmp @r1 mov.l @r0,r4 SETCONST . = intvec + 0x600 SETS.L #0x600,r2 SETS.L #EXPEVT,r0 mov.l @r0,r3 SETS.L #INTEVT,r0 SETS.L #regdump,r1 jmp @r1 mov.l @r0,r4 SETCONST . = intvec + 0x1000 crash_msg_0: .asciz (13,10,10)"FATAL TRAP"(13,10)"R0 " crash_msg_1: .asciz " R1 " crash_msg_2: .asciz " R2 " crash_msg_3: .asciz " R3 " crash_msg_4: .asciz (13,10)"R4 " crash_msg_5: .asciz " R5 " crash_msg_6: .asciz " R6 " crash_msg_7: .asciz " R7 " crash_msg_8: .asciz (13,10)"R8 " crash_msg_9: .asciz " R9 " crash_msg_10: .asciz " R10 " crash_msg_11: .asciz " R11 " crash_msg_12: .asciz (13,10)"R12 " crash_msg_13: .asciz " R13 " crash_msg_14: .asciz " R14 " crash_msg_15: .asciz " R15 " crash_msg_gbr: .asciz (13,10)"GBR " crash_msg_sr: .asciz " SR " crash_msg_pc: .asciz " PC " crash_msg_mach: .asciz (13,10)"MACH" crash_msg_macl: .asciz " MACL" crash_msg_pr: .asciz " PR " crash_msg_vec: .asciz (13,10)"vector" crash_msg_expevt: .asciz " EXPEVT" crash_msg_intevt: .asciz " INTEVT" crash_msg_done: .asciz (13,10) crash_msg_equal: .asciz " = " .align 4 crash_msgs: .long crash_msg_0 .long crash_msg_1 .long crash_msg_2 .long crash_msg_3 .long crash_msg_4 .long crash_msg_5 .long crash_msg_6 .long crash_msg_7 .long crash_msg_8 .long crash_msg_9 .long crash_msg_10 .long crash_msg_11 .long crash_msg_12 .long crash_msg_13 .long crash_msg_14 .long crash_msg_15 .long crash_msg_gbr .long crash_msg_sr .long crash_msg_pc .long crash_msg_mach .long crash_msg_macl .long crash_msg_pr .long crash_msg_vec .long crash_msg_expevt .long crash_msg_intevt .long 0 .align 2 regdump: mov r15,r5 SETS.L #intstacktop,r15 mov.l r4,@-r15 mov.l r3,@-r15 mov.l r2,@-r15 sts.l pr,@-r15 sts.l macl,@-r15 sts.l mach,@-r15 stc.l spc,@-r15 stc.l ssr,@-r15 stc.l gbr,@-r15 mov.l r5,@-r15 mov.l r14,@-r15 mov.l r13,@-r15 mov.l r12,@-r15 mov.l r11,@-r15 mov.l r10,@-r15 mov.l r9,@-r15 mov.l r8,@-r15 stc.l r7_bank,@-r15 stc.l r6_bank,@-r15 stc.l r5_bank,@-r15 stc.l r4_bank,@-r15 stc.l r3_bank,@-r15 stc.l r2_bank,@-r15 stc.l r1_bank,@-r15 stc.l r0_bank,@-r15 SETS.L #SCIF_BASE,r14 SETS.L #crash_msgs,r9 SETS.L #putstr,r8 SETS.L #printhex8,r7 SETS.L #putchar,r6 1: mov.l @r9+,r1 tst r1,r1 bt 1f jsr @r8 nop SETS.L #crash_msg_equal,r1 jsr @r8 nop jsr @r7 mov.l @r15+,r1 bra 1b nop 1: SETS.L #crash_msg_done,r1 jsr @r8 nop jsr @r6 mov #0,r1 SETS.L #0xa0000000,r0 ; hard-reset vector jmp @r0 nop SETCONST .align 4 .space 0x1000 intstacktop = . .list push off ; tatest's code is included here for reference. ; ; Makefile: ; AS = sh-elf-as -little ; LD = sh-elf-ld -EL ; CC = sh-elf-gcc -ml -m4-single-only -mhitachi ; ; OBJS = startup.o main.o matrix.o ta.o video.o ; ; ; tatest.srec : $(OBJS) ; $(CC) -o $@ -Wl,--oformat,srec,-Ttext=0x8c010000 -nostartfiles -nostdlib $(OBJS) -lgcc -lc -lgcc ; ; startup.o : startup.s ; ; main.o : main.c video.h ta.h matrix.h ; ; matrix.o : matrix.s ; ; ta.o : ta.c ta.h ; ; video.o : video.c video.h ; ; main.c ; #include "video.h" ; #include "ta.h" ; #include "matrix.h" ; ; ; /* ; * Hardware 3D example by marcus ; * ; * This example creates a texture mapped cube ; * using the tile accelerator hardware and the ; * built in matrix multiplication feature of ; * the SH4. It was inspired by Dan's 3dtest ; * program of course, but this one is more ; * "clean", and does real 3D. :-) ; * ; * ; */ ; ; ; void atexit() { } ; ; ; /** 3D operations **/ ; ; ; /* coordinates for the cube */ ; ; float coords[8][3] = { ; { -1.0, -1.0, -1.0 }, ; { 1.0, -1.0, -1.0 }, ; { -1.0, 1.0, -1.0 }, ; { 1.0, 1.0, -1.0 }, ; { -1.0, -1.0, 1.0 }, ; { 1.0, -1.0, 1.0 }, ; { -1.0, 1.0, 1.0 }, ; { 1.0, 1.0, 1.0 }, ; }; ; ; ; /* transformed coordinates */ ; ; float trans_coords[8][3]; ; ; ; /* matrices for transforming world coordinates to ; screen coordinates (with perspective) */ ; ; #define XCENTER 320.0 ; #define YCENTER 240.0 ; ; #define COT_FOVY_2 1.73 /* cot(FOVy / 2) */ ; #define ZNEAR 1.0 ; #define ZFAR 100.0 ; ; #define ZOFFS 5.0 ; ; ; float screenview_matrix[4][4] = { ; { YCENTER, 0.0, 0.0, 0.0 }, ; { 0.0, YCENTER, 0.0, 0.0 }, ; { 0.0, 0.0, 1.0 , 0.0 }, ; { XCENTER, YCENTER, 0.0, 1.0 }, ; }; ; ; float projection_matrix[4][4] = { ; { COT_FOVY_2, 0.0, 0.0, 0.0 }, ; { 0.0, COT_FOVY_2, 0.0, 0.0 }, ; { 0.0, 0.0, (ZFAR+ZNEAR)/(ZNEAR-ZFAR), -1.0 }, ; { 0.0, 0.0, 2*ZFAR*ZNEAR/(ZNEAR-ZFAR), 1.0 }, ; }; ; ; float translation_matrix[4][4] = { ; { 1.0, 0.0, 0.0, 0.0 }, ; { 0.0, 1.0, 0.0, 0.0 }, ; { 0.0, 0.0, 1.0, 0.0 }, ; { 0.0, 0.0, ZOFFS, 1.0 }, ; }; ; ; ; /* sinus and cosinus table for rotations */ ; ; #define SIN(x) (sinus_tab[(x)&2047]) ; #define COS(x) (sinus_tab[((x)+512)&2047]) ; ; float sinus_tab[] = { ; 0.0000000, 0.0030680, 0.0061359, 0.0092038, 0.0122715, 0.0153392, 0.0184067, 0.0214741, ; 0.0245412, 0.0276081, 0.0306748, 0.0337412, 0.0368072, 0.0398729, 0.0429383, 0.0460032, ; 0.0490677, 0.0521317, 0.0551952, 0.0582583, 0.0613207, 0.0643826, 0.0674439, 0.0705046, ; 0.0735646, 0.0766239, 0.0796824, 0.0827403, 0.0857973, 0.0888536, 0.0919090, 0.0949635, ; 0.0980171, 0.1010699, 0.1041216, 0.1071724, 0.1102222, 0.1132710, 0.1163186, 0.1193652, ; 0.1224107, 0.1254550, 0.1284981, 0.1315400, 0.1345807, 0.1376201, 0.1406582, 0.1436950, ; 0.1467305, 0.1497645, 0.1527972, 0.1558284, 0.1588582, 0.1618864, 0.1649131, 0.1679383, ; 0.1709619, 0.1739839, 0.1770042, 0.1800229, 0.1830399, 0.1860552, 0.1890687, 0.1920804, ; 0.1950903, 0.1980984, 0.2011046, 0.2041090, 0.2071114, 0.2101118, 0.2131103, 0.2161068, ; 0.2191012, 0.2220936, 0.2250839, 0.2280721, 0.2310581, 0.2340420, 0.2370236, 0.2400030, ; 0.2429802, 0.2459550, 0.2489276, 0.2518978, 0.2548657, 0.2578311, 0.2607941, 0.2637547, ; 0.2667128, 0.2696683, 0.2726214, 0.2755718, 0.2785197, 0.2814649, 0.2844076, 0.2873475, ; 0.2902847, 0.2932192, 0.2961509, 0.2990798, 0.3020059, 0.3049293, 0.3078497, 0.3107671, ; 0.3136818, 0.3165934, 0.3195020, 0.3224077, 0.3253103, 0.3282098, 0.3311063, 0.3339997, ; 0.3368899, 0.3397769, 0.3426607, 0.3455413, 0.3484187, 0.3512928, 0.3541635, 0.3570310, ; 0.3598951, 0.3627557, 0.3656130, 0.3684668, 0.3713172, 0.3741641, 0.3770074, 0.3798472, ; 0.3826835, 0.3855161, 0.3883450, 0.3911704, 0.3939921, 0.3968100, 0.3996242, 0.4024347, ; 0.4052413, 0.4080442, 0.4108432, 0.4136383, 0.4164296, 0.4192169, 0.4220003, 0.4247797, ; 0.4275551, 0.4303265, 0.4330938, 0.4358571, 0.4386162, 0.4413713, 0.4441222, 0.4468688, ; 0.4496113, 0.4523496, 0.4550836, 0.4578133, 0.4605387, 0.4632598, 0.4659765, 0.4686888, ; 0.4713967, 0.4741002, 0.4767992, 0.4794937, 0.4821838, 0.4848692, 0.4875502, 0.4902265, ; 0.4928982, 0.4955653, 0.4982277, 0.5008854, 0.5035384, 0.5061867, 0.5088302, 0.5114689, ; 0.5141028, 0.5167318, 0.5193560, 0.5219753, 0.5245897, 0.5271991, 0.5298036, 0.5324032, ; 0.5349976, 0.5375871, 0.5401715, 0.5427508, 0.5453250, 0.5478941, 0.5504580, 0.5530167, ; 0.5555702, 0.5581185, 0.5606616, 0.5631993, 0.5657318, 0.5682590, 0.5707808, 0.5732971, ; 0.5758082, 0.5783138, 0.5808140, 0.5833087, 0.5857979, 0.5882816, 0.5907597, 0.5932323, ; 0.5956993, 0.5981607, 0.6006165, 0.6030666, 0.6055110, 0.6079498, 0.6103828, 0.6128101, ; 0.6152316, 0.6176473, 0.6200572, 0.6224613, 0.6248595, 0.6272518, 0.6296383, 0.6320187, ; 0.6343933, 0.6367618, 0.6391245, 0.6414810, 0.6438316, 0.6461760, 0.6485144, 0.6508467, ; 0.6531729, 0.6554928, 0.6578067, 0.6601143, 0.6624158, 0.6647110, 0.6669999, 0.6692826, ; 0.6715590, 0.6738290, 0.6760927, 0.6783501, 0.6806010, 0.6828456, 0.6850837, 0.6873153, ; 0.6895406, 0.6917593, 0.6939715, 0.6961772, 0.6983763, 0.7005688, 0.7027547, 0.7049341, ; 0.7071068, 0.7092729, 0.7114322, 0.7135849, 0.7157308, 0.7178701, 0.7200025, 0.7221282, ; 0.7242471, 0.7263592, 0.7284644, 0.7305627, 0.7326543, 0.7347389, 0.7368166, 0.7388874, ; 0.7409512, 0.7430080, 0.7450578, 0.7471006, 0.7491364, 0.7511652, 0.7531868, 0.7552014, ; 0.7572089, 0.7592092, 0.7612024, 0.7631884, 0.7651673, 0.7671390, 0.7691033, 0.7710606, ; 0.7730104, 0.7749531, 0.7768885, 0.7788165, 0.7807373, 0.7826506, 0.7845566, 0.7864552, ; 0.7883464, 0.7902302, 0.7921066, 0.7939755, 0.7958369, 0.7976909, 0.7995373, 0.8013762, ; 0.8032075, 0.8050314, 0.8068476, 0.8086562, 0.8104572, 0.8122506, 0.8140363, 0.8158144, ; 0.8175848, 0.8193476, 0.8211026, 0.8228498, 0.8245893, 0.8263211, 0.8280451, 0.8297613, ; 0.8314697, 0.8331702, 0.8348629, 0.8365477, 0.8382247, 0.8398938, 0.8415549, 0.8432083, ; 0.8448536, 0.8464909, 0.8481203, 0.8497418, 0.8513552, 0.8529606, 0.8545580, 0.8561473, ; 0.8577287, 0.8593019, 0.8608670, 0.8624240, 0.8639728, 0.8655136, 0.8670462, 0.8685707, ; 0.8700870, 0.8715951, 0.8730950, 0.8745866, 0.8760701, 0.8775453, 0.8790123, 0.8804709, ; 0.8819213, 0.8833633, 0.8847971, 0.8862225, 0.8876396, 0.8890483, 0.8904487, 0.8918407, ; 0.8932243, 0.8945995, 0.8959663, 0.8973246, 0.8986745, 0.9000160, 0.9013489, 0.9026733, ; 0.9039893, 0.9052967, 0.9065957, 0.9078861, 0.9091680, 0.9104413, 0.9117060, 0.9129622, ; 0.9142098, 0.9154487, 0.9166791, 0.9179008, 0.9191139, 0.9203182, 0.9215140, 0.9227011, ; 0.9238795, 0.9250492, 0.9262102, 0.9273626, 0.9285061, 0.9296409, 0.9307670, 0.9318843, ; 0.9329928, 0.9340926, 0.9351835, 0.9362656, 0.9373390, 0.9384035, 0.9394592, 0.9405061, ; 0.9415441, 0.9425732, 0.9435934, 0.9446049, 0.9456074, 0.9466009, 0.9475856, 0.9485614, ; 0.9495282, 0.9504861, 0.9514350, 0.9523750, 0.9533060, 0.9542281, 0.9551412, 0.9560453, ; 0.9569404, 0.9578264, 0.9587035, 0.9595715, 0.9604306, 0.9612805, 0.9621214, 0.9629533, ; 0.9637761, 0.9645898, 0.9653944, 0.9661900, 0.9669765, 0.9677538, 0.9685221, 0.9692813, ; 0.9700313, 0.9707721, 0.9715039, 0.9722265, 0.9729400, 0.9736443, 0.9743394, 0.9750254, ; 0.9757021, 0.9763697, 0.9770281, 0.9776773, 0.9783174, 0.9789482, 0.9795698, 0.9801822, ; 0.9807853, 0.9813792, 0.9819639, 0.9825393, 0.9831055, 0.9836624, 0.9842101, 0.9847485, ; 0.9852777, 0.9857975, 0.9863081, 0.9868094, 0.9873014, 0.9877841, 0.9882576, 0.9887217, ; 0.9891765, 0.9896220, 0.9900582, 0.9904851, 0.9909027, 0.9913108, 0.9917098, 0.9920993, ; 0.9924796, 0.9928504, 0.9932120, 0.9935641, 0.9939070, 0.9942405, 0.9945646, 0.9948793, ; 0.9951847, 0.9954808, 0.9957674, 0.9960447, 0.9963126, 0.9965711, 0.9968203, 0.9970601, ; 0.9972904, 0.9975114, 0.9977230, 0.9979253, 0.9981181, 0.9983016, 0.9984756, 0.9986402, ; 0.9987954, 0.9989413, 0.9990777, 0.9992048, 0.9993224, 0.9994306, 0.9995294, 0.9996188, ; 0.9996988, 0.9997694, 0.9998306, 0.9998823, 0.9999247, 0.9999576, 0.9999812, 0.9999953, ; 1.0000000, 0.9999953, 0.9999812, 0.9999576, 0.9999247, 0.9998823, 0.9998306, 0.9997694, ; 0.9996988, 0.9996188, 0.9995294, 0.9994306, 0.9993224, 0.9992048, 0.9990777, 0.9989413, ; 0.9987954, 0.9986402, 0.9984756, 0.9983016, 0.9981181, 0.9979253, 0.9977230, 0.9975114, ; 0.9972904, 0.9970601, 0.9968203, 0.9965711, 0.9963126, 0.9960447, 0.9957674, 0.9954808, ; 0.9951847, 0.9948793, 0.9945645, 0.9942405, 0.9939070, 0.9935641, 0.9932119, 0.9928504, ; 0.9924795, 0.9920993, 0.9917098, 0.9913108, 0.9909026, 0.9904851, 0.9900582, 0.9896220, ; 0.9891765, 0.9887217, 0.9882576, 0.9877841, 0.9873014, 0.9868094, 0.9863081, 0.9857975, ; 0.9852777, 0.9847485, 0.9842101, 0.9836624, 0.9831055, 0.9825393, 0.9819639, 0.9813792, ; 0.9807853, 0.9801821, 0.9795697, 0.9789482, 0.9783174, 0.9776773, 0.9770281, 0.9763697, ; 0.9757021, 0.9750254, 0.9743394, 0.9736443, 0.9729399, 0.9722265, 0.9715039, 0.9707721, ; 0.9700313, 0.9692813, 0.9685221, 0.9677538, 0.9669765, 0.9661900, 0.9653944, 0.9645898, ; 0.9637761, 0.9629532, 0.9621214, 0.9612805, 0.9604305, 0.9595715, 0.9587035, 0.9578264, ; 0.9569403, 0.9560452, 0.9551411, 0.9542281, 0.9533060, 0.9523750, 0.9514350, 0.9504861, ; 0.9495282, 0.9485614, 0.9475856, 0.9466009, 0.9456073, 0.9446048, 0.9435934, 0.9425732, ; 0.9415441, 0.9405060, 0.9394592, 0.9384035, 0.9373389, 0.9362656, 0.9351835, 0.9340925, ; 0.9329928, 0.9318842, 0.9307669, 0.9296409, 0.9285061, 0.9273625, 0.9262102, 0.9250492, ; 0.9238795, 0.9227011, 0.9215140, 0.9203182, 0.9191139, 0.9179008, 0.9166790, 0.9154487, ; 0.9142097, 0.9129622, 0.9117060, 0.9104413, 0.9091680, 0.9078861, 0.9065957, 0.9052967, ; 0.9039893, 0.9026733, 0.9013488, 0.9000159, 0.8986744, 0.8973246, 0.8959662, 0.8945994, ; 0.8932243, 0.8918407, 0.8904487, 0.8890483, 0.8876396, 0.8862225, 0.8847970, 0.8833633, ; 0.8819212, 0.8804708, 0.8790122, 0.8775452, 0.8760700, 0.8745866, 0.8730949, 0.8715951, ; 0.8700870, 0.8685707, 0.8670462, 0.8655136, 0.8639728, 0.8624240, 0.8608670, 0.8593018, ; 0.8577286, 0.8561473, 0.8545580, 0.8529606, 0.8513551, 0.8497418, 0.8481203, 0.8464909, ; 0.8448535, 0.8432082, 0.8415549, 0.8398938, 0.8382246, 0.8365477, 0.8348628, 0.8331701, ; 0.8314695, 0.8297611, 0.8280451, 0.8263211, 0.8245893, 0.8228498, 0.8211025, 0.8193475, ; 0.8175848, 0.8158144, 0.8140363, 0.8122506, 0.8104572, 0.8086562, 0.8068475, 0.8050313, ; 0.8032075, 0.8013761, 0.7995372, 0.7976908, 0.7958369, 0.7939754, 0.7921065, 0.7902302, ; 0.7883464, 0.7864552, 0.7845565, 0.7826505, 0.7807371, 0.7788164, 0.7768885, 0.7749531, ; 0.7730105, 0.7710605, 0.7691033, 0.7671389, 0.7651672, 0.7631884, 0.7612024, 0.7592092, ; 0.7572088, 0.7552013, 0.7531868, 0.7511651, 0.7491363, 0.7471005, 0.7450577, 0.7430079, ; 0.7409511, 0.7388873, 0.7368165, 0.7347388, 0.7326542, 0.7305627, 0.7284643, 0.7263591, ; 0.7242470, 0.7221281, 0.7200025, 0.7178701, 0.7157308, 0.7135849, 0.7114322, 0.7092728, ; 0.7071068, 0.7049341, 0.7027547, 0.7005688, 0.6983762, 0.6961771, 0.6939714, 0.6917592, ; 0.6895405, 0.6873153, 0.6850836, 0.6828455, 0.6806009, 0.6783500, 0.6760926, 0.6738289, ; 0.6715589, 0.6692825, 0.6669998, 0.6647109, 0.6624156, 0.6601144, 0.6578067, 0.6554929, ; 0.6531729, 0.6508467, 0.6485144, 0.6461760, 0.6438316, 0.6414810, 0.6391244, 0.6367618, ; 0.6343933, 0.6320187, 0.6296382, 0.6272517, 0.6248595, 0.6224612, 0.6200571, 0.6176472, ; 0.6152315, 0.6128100, 0.6103827, 0.6079497, 0.6055110, 0.6030664, 0.6006163, 0.5981606, ; 0.5956991, 0.5932323, 0.5907598, 0.5882816, 0.5857978, 0.5833086, 0.5808139, 0.5783138, ; 0.5758082, 0.5732971, 0.5707807, 0.5682589, 0.5657318, 0.5631993, 0.5606615, 0.5581185, ; 0.5555702, 0.5530166, 0.5504579, 0.5478939, 0.5453249, 0.5427507, 0.5401714, 0.5375869, ; 0.5349975, 0.5324030, 0.5298035, 0.5271990, 0.5245895, 0.5219753, 0.5193560, 0.5167318, ; 0.5141028, 0.5114688, 0.5088301, 0.5061866, 0.5035384, 0.5008854, 0.4982276, 0.4955652, ; 0.4928981, 0.4902264, 0.4875501, 0.4848692, 0.4821837, 0.4794937, 0.4767991, 0.4741001, ; 0.4713966, 0.4686887, 0.4659764, 0.4632596, 0.4605386, 0.4578131, 0.4550834, 0.4523494, ; 0.4496114, 0.4468689, 0.4441222, 0.4413713, 0.4386162, 0.4358571, 0.4330938, 0.4303265, ; 0.4275551, 0.4247797, 0.4220002, 0.4192168, 0.4164295, 0.4136382, 0.4108431, 0.4080441, ; 0.4052412, 0.4024346, 0.3996241, 0.3968099, 0.3939919, 0.3911703, 0.3883449, 0.3855159, ; 0.3826833, 0.3798470, 0.3770072, 0.3741639, 0.3713172, 0.3684669, 0.3656130, 0.3627557, ; 0.3598951, 0.3570310, 0.3541635, 0.3512927, 0.3484187, 0.3455413, 0.3426607, 0.3397768, ; 0.3368898, 0.3339996, 0.3311062, 0.3282098, 0.3253102, 0.3224076, 0.3195019, 0.3165933, ; 0.3136816, 0.3107670, 0.3078495, 0.3049291, 0.3020058, 0.2990797, 0.2961507, 0.2932190, ; 0.2902847, 0.2873475, 0.2844076, 0.2814649, 0.2785197, 0.2755718, 0.2726213, 0.2696683, ; 0.2667127, 0.2637546, 0.2607941, 0.2578310, 0.2548656, 0.2518978, 0.2489275, 0.2459550, ; 0.2429801, 0.2400029, 0.2370235, 0.2340418, 0.2310580, 0.2280719, 0.2250838, 0.2220935, ; 0.2191011, 0.2161066, 0.2131101, 0.2101119, 0.2071114, 0.2041090, 0.2011046, 0.1980984, ; 0.1950903, 0.1920804, 0.1890686, 0.1860551, 0.1830398, 0.1800229, 0.1770042, 0.1739838, ; 0.1709618, 0.1679382, 0.1649130, 0.1618863, 0.1588580, 0.1558283, 0.1527971, 0.1497644, ; 0.1467303, 0.1436949, 0.1406581, 0.1376200, 0.1345805, 0.1315398, 0.1284979, 0.1254550, ; 0.1224107, 0.1193652, 0.1163186, 0.1132709, 0.1102222, 0.1071724, 0.1041216, 0.1010698, ; 0.0980171, 0.0949634, 0.0919089, 0.0888535, 0.0857972, 0.0827402, 0.0796823, 0.0766238, ; 0.0735644, 0.0705044, 0.0674438, 0.0643825, 0.0613206, 0.0582581, 0.0551951, 0.0521315, ; 0.0490675, 0.0460030, 0.0429381, 0.0398730, 0.0368072, 0.0337412, 0.0306748, 0.0276081, ; 0.0245412, 0.0214741, 0.0184067, 0.0153392, 0.0122715, 0.0092037, 0.0061358, 0.0030679, ; -0.0000001, -0.0030681, -0.0061360, -0.0092039, -0.0122717, -0.0153393, -0.0184069, -0.0214742, ; -0.0245414, -0.0276083, -0.0306750, -0.0337414, -0.0368074, -0.0398731, -0.0429382, -0.0460032, ; -0.0490677, -0.0521317, -0.0551952, -0.0582583, -0.0613208, -0.0643827, -0.0674440, -0.0705046, ; -0.0735646, -0.0766239, -0.0796825, -0.0827404, -0.0857974, -0.0888536, -0.0919091, -0.0949636, ; -0.0980173, -0.1010700, -0.1041218, -0.1071726, -0.1102224, -0.1132711, -0.1163188, -0.1193654, ; -0.1224109, -0.1254552, -0.1284981, -0.1315400, -0.1345807, -0.1376201, -0.1406582, -0.1436951, ; -0.1467305, -0.1497646, -0.1527972, -0.1558284, -0.1588582, -0.1618865, -0.1649132, -0.1679384, ; -0.1709620, -0.1739840, -0.1770043, -0.1800230, -0.1830400, -0.1860553, -0.1890688, -0.1920806, ; -0.1950905, -0.1980986, -0.2011048, -0.2041092, -0.2071116, -0.2101121, -0.2131103, -0.2161068, ; -0.2191012, -0.2220936, -0.2250839, -0.2280721, -0.2310581, -0.2340420, -0.2370237, -0.2400031, ; -0.2429802, -0.2459551, -0.2489277, -0.2518979, -0.2548658, -0.2578312, -0.2607942, -0.2637548, ; -0.2667129, -0.2696685, -0.2726215, -0.2755720, -0.2785199, -0.2814651, -0.2844077, -0.2873476, ; -0.2902849, -0.2932191, -0.2961509, -0.2990798, -0.3020059, -0.3049293, -0.3078496, -0.3107672, ; -0.3136818, -0.3165934, -0.3195021, -0.3224078, -0.3253103, -0.3282099, -0.3311064, -0.3339998, ; -0.3368900, -0.3397770, -0.3426608, -0.3455414, -0.3484188, -0.3512929, -0.3541637, -0.3570311, ; -0.3598952, -0.3627559, -0.3656132, -0.3684670, -0.3713174, -0.3741640, -0.3770074, -0.3798472, ; -0.3826834, -0.3855161, -0.3883451, -0.3911704, -0.3939921, -0.3968100, -0.3996243, -0.4024347, ; -0.4052414, -0.4080442, -0.4108433, -0.4136384, -0.4164297, -0.4192170, -0.4220004, -0.4247798, ; -0.4275552, -0.4303266, -0.4330940, -0.4358572, -0.4386164, -0.4413714, -0.4441223, -0.4468690, ; -0.4496115, -0.4523496, -0.4550836, -0.4578133, -0.4605387, -0.4632598, -0.4659765, -0.4686888, ; -0.4713968, -0.4741003, -0.4767993, -0.4794938, -0.4821838, -0.4848693, -0.4875503, -0.4902266, ; -0.4928983, -0.4955654, -0.4982278, -0.5008855, -0.5035385, -0.5061868, -0.5088303, -0.5114690, ; -0.5141029, -0.5167320, -0.5193562, -0.5219755, -0.5245897, -0.5271991, -0.5298036, -0.5324031, ; -0.5349976, -0.5375871, -0.5401715, -0.5427508, -0.5453250, -0.5478941, -0.5504580, -0.5530168, ; -0.5555703, -0.5581186, -0.5606617, -0.5631995, -0.5657319, -0.5682591, -0.5707809, -0.5732973, ; -0.5758083, -0.5783139, -0.5808141, -0.5833088, -0.5857980, -0.5882817, -0.5907599, -0.5932325, ; -0.5956993, -0.5981607, -0.6006165, -0.6030666, -0.6055111, -0.6079498, -0.6103829, -0.6128101, ; -0.6152316, -0.6176473, -0.6200573, -0.6224613, -0.6248596, -0.6272519, -0.6296383, -0.6320188, ; -0.6343934, -0.6367620, -0.6391246, -0.6414812, -0.6438317, -0.6461762, -0.6485145, -0.6508468, ; -0.6531730, -0.6554930, -0.6578069, -0.6601145, -0.6624158, -0.6647110, -0.6669999, -0.6692826, ; -0.6715590, -0.6738290, -0.6760927, -0.6783501, -0.6806011, -0.6828456, -0.6850837, -0.6873154, ; -0.6895406, -0.6917593, -0.6939716, -0.6961772, -0.6983764, -0.7005689, -0.7027549, -0.7049342, ; -0.7071069, -0.7092730, -0.7114323, -0.7135850, -0.7157310, -0.7178702, -0.7200027, -0.7221282, ; -0.7242471, -0.7263592, -0.7284644, -0.7305628, -0.7326543, -0.7347389, -0.7368166, -0.7388874, ; -0.7409512, -0.7430080, -0.7450578, -0.7471007, -0.7491364, -0.7511652, -0.7531869, -0.7552015, ; -0.7572088, -0.7592092, -0.7612023, -0.7631884, -0.7651672, -0.7671389, -0.7691033, -0.7710605, ; -0.7730104, -0.7749531, -0.7768884, -0.7788165, -0.7807372, -0.7826506, -0.7845566, -0.7864552, ; -0.7883465, -0.7902303, -0.7921066, -0.7939755, -0.7958369, -0.7976909, -0.7995373, -0.8013762, ; -0.8032076, -0.8050314, -0.8068476, -0.8086563, -0.8104573, -0.8122507, -0.8140364, -0.8158145, ; -0.8175849, -0.8193476, -0.8211026, -0.8228499, -0.8245894, -0.8263212, -0.8280452, -0.8297614, ; -0.8314698, -0.8331703, -0.8348630, -0.8365479, -0.8382249, -0.8398939, -0.8415551, -0.8432084, ; -0.8448538, -0.8464911, -0.8481205, -0.8497419, -0.8513554, -0.8529605, -0.8545579, -0.8561473, ; -0.8577285, -0.8593018, -0.8608669, -0.8624239, -0.8639728, -0.8655136, -0.8670462, -0.8685707, ; -0.8700870, -0.8715951, -0.8730950, -0.8745866, -0.8760701, -0.8775453, -0.8790122, -0.8804709, ; -0.8819213, -0.8833634, -0.8847972, -0.8862225, -0.8876396, -0.8890484, -0.8904487, -0.8918408, ; -0.8932244, -0.8945996, -0.8959663, -0.8973246, -0.8986745, -0.9000160, -0.9013489, -0.9026734, ; -0.9039894, -0.9052969, -0.9065958, -0.9078862, -0.9091681, -0.9104414, -0.9117061, -0.9129623, ; -0.9142098, -0.9154488, -0.9166791, -0.9179009, -0.9191140, -0.9203184, -0.9215142, -0.9227012, ; -0.9238797, -0.9250494, -0.9262103, -0.9273627, -0.9285060, -0.9296408, -0.9307669, -0.9318842, ; -0.9329928, -0.9340925, -0.9351835, -0.9362656, -0.9373390, -0.9384035, -0.9394592, -0.9405060, ; -0.9415441, -0.9425732, -0.9435934, -0.9446048, -0.9456073, -0.9466009, -0.9475856, -0.9485614, ; -0.9495282, -0.9504861, -0.9514350, -0.9523751, -0.9533061, -0.9542281, -0.9551412, -0.9560453, ; -0.9569404, -0.9578264, -0.9587035, -0.9595715, -0.9604306, -0.9612805, -0.9621214, -0.9629533, ; -0.9637761, -0.9645898, -0.9653945, -0.9661900, -0.9669765, -0.9677539, -0.9685221, -0.9692813, ; -0.9700313, -0.9707722, -0.9715040, -0.9722266, -0.9729400, -0.9736443, -0.9743394, -0.9750254, ; -0.9757022, -0.9763698, -0.9770282, -0.9776773, -0.9783173, -0.9789482, -0.9795697, -0.9801821, ; -0.9807853, -0.9813792, -0.9819639, -0.9825393, -0.9831055, -0.9836624, -0.9842101, -0.9847485, ; -0.9852777, -0.9857975, -0.9863081, -0.9868094, -0.9873014, -0.9877841, -0.9882576, -0.9887217, ; -0.9891765, -0.9896221, -0.9900582, -0.9904851, -0.9909027, -0.9913109, -0.9917098, -0.9920993, ; -0.9924796, -0.9928504, -0.9932120, -0.9935641, -0.9939070, -0.9942405, -0.9945646, -0.9948794, ; -0.9951847, -0.9954808, -0.9957674, -0.9960447, -0.9963126, -0.9965712, -0.9968203, -0.9970601, ; -0.9972905, -0.9975115, -0.9977231, -0.9979253, -0.9981181, -0.9983016, -0.9984756, -0.9986402, ; -0.9987954, -0.9989413, -0.9990777, -0.9992048, -0.9993224, -0.9994306, -0.9995294, -0.9996188, ; -0.9996988, -0.9997694, -0.9998306, -0.9998823, -0.9999247, -0.9999576, -0.9999812, -0.9999953, ; -1.0000000, -0.9999953, -0.9999812, -0.9999576, -0.9999247, -0.9998823, -0.9998306, -0.9997694, ; -0.9996988, -0.9996188, -0.9995294, -0.9994306, -0.9993224, -0.9992048, -0.9990777, -0.9989413, ; -0.9987954, -0.9986402, -0.9984756, -0.9983015, -0.9981181, -0.9979253, -0.9977230, -0.9975114, ; -0.9972904, -0.9970601, -0.9968203, -0.9965711, -0.9963126, -0.9960447, -0.9957674, -0.9954807, ; -0.9951847, -0.9948793, -0.9945645, -0.9942404, -0.9939069, -0.9935641, -0.9932119, -0.9928504, ; -0.9924795, -0.9920993, -0.9917098, -0.9913109, -0.9909027, -0.9904851, -0.9900582, -0.9896220, ; -0.9891765, -0.9887217, -0.9882576, -0.9877841, -0.9873014, -0.9868094, -0.9863081, -0.9857975, ; -0.9852777, -0.9847485, -0.9842101, -0.9836624, -0.9831055, -0.9825393, -0.9819639, -0.9813792, ; -0.9807853, -0.9801821, -0.9795697, -0.9789482, -0.9783173, -0.9776773, -0.9770281, -0.9763697, ; -0.9757021, -0.9750253, -0.9743394, -0.9736442, -0.9729399, -0.9722264, -0.9715039, -0.9707721, ; -0.9700312, -0.9692812, -0.9685220, -0.9677538, -0.9669764, -0.9661899, -0.9653944, -0.9645897, ; -0.9637760, -0.9629532, -0.9621213, -0.9612804, -0.9604304, -0.9595714, -0.9587034, -0.9578263, ; -0.9569402, -0.9560453, -0.9551412, -0.9542281, -0.9533061, -0.9523751, -0.9514350, -0.9504861, ; -0.9495282, -0.9485614, -0.9475856, -0.9466009, -0.9456073, -0.9446048, -0.9435934, -0.9425732, ; -0.9415441, -0.9405060, -0.9394592, -0.9384035, -0.9373390, -0.9362656, -0.9351835, -0.9340925, ; -0.9329928, -0.9318842, -0.9307669, -0.9296408, -0.9285060, -0.9273624, -0.9262102, -0.9250492, ; -0.9238794, -0.9227011, -0.9215140, -0.9203182, -0.9191138, -0.9179007, -0.9166790, -0.9154486, ; -0.9142097, -0.9129621, -0.9117059, -0.9104412, -0.9091679, -0.9078860, -0.9065956, -0.9052966, ; -0.9039891, -0.9026732, -0.9013487, -0.9000158, -0.8986743, -0.8973244, -0.8959661, -0.8945993, ; -0.8932241, -0.8918408, -0.8904487, -0.8890484, -0.8876396, -0.8862225, -0.8847971, -0.8833634, ; -0.8819213, -0.8804709, -0.8790122, -0.8775453, -0.8760701, -0.8745866, -0.8730950, -0.8715951, ; -0.8700870, -0.8685707, -0.8670462, -0.8655136, -0.8639728, -0.8624239, -0.8608669, -0.8593017, ; -0.8577285, -0.8561473, -0.8545579, -0.8529605, -0.8513551, -0.8497417, -0.8481203, -0.8464909, ; -0.8448535, -0.8432081, -0.8415549, -0.8398937, -0.8382246, -0.8365476, -0.8348628, -0.8331701, ; -0.8314695, -0.8297611, -0.8280449, -0.8263209, -0.8245891, -0.8228496, -0.8211023, -0.8193473, ; -0.8175846, -0.8158142, -0.8140361, -0.8122504, -0.8104570, -0.8086560, -0.8068473, -0.8050311, ; -0.8032076, -0.8013762, -0.7995373, -0.7976909, -0.7958369, -0.7939755, -0.7921066, -0.7902302, ; -0.7883464, -0.7864552, -0.7845566, -0.7826506, -0.7807372, -0.7788165, -0.7768884, -0.7749531, ; -0.7730104, -0.7710605, -0.7691033, -0.7671388, -0.7651672, -0.7631884, -0.7612023, -0.7592091, ; -0.7572088, -0.7552013, -0.7531867, -0.7511650, -0.7491363, -0.7471005, -0.7450576, -0.7430078, ; -0.7409510, -0.7388872, -0.7368164, -0.7347387, -0.7326541, -0.7305626, -0.7284642, -0.7263590, ; -0.7242469, -0.7221280, -0.7200023, -0.7178698, -0.7157306, -0.7135847, -0.7114320, -0.7092726, ; -0.7071065, -0.7049338, -0.7027545, -0.7005686, -0.6983760, -0.6961769, -0.6939712, -0.6917593, ; -0.6895406, -0.6873154, -0.6850837, -0.6828456, -0.6806010, -0.6783501, -0.6760927, -0.6738290, ; -0.6715590, -0.6692826, -0.6669999, -0.6647109, -0.6624157, -0.6601143, -0.6578066, -0.6554928, ; -0.6531728, -0.6508466, -0.6485143, -0.6461759, -0.6438315, -0.6414809, -0.6391243, -0.6367618, ; -0.6343932, -0.6320186, -0.6296381, -0.6272517, -0.6248593, -0.6224611, -0.6200570, -0.6176472, ; -0.6152315, -0.6128099, -0.6103826, -0.6079496, -0.6055108, -0.6030664, -0.6006163, -0.5981605, ; -0.5956991, -0.5932321, -0.5907595, -0.5882813, -0.5857976, -0.5833084, -0.5808137, -0.5783135, ; -0.5758079, -0.5732969, -0.5707805, -0.5682586, -0.5657315, -0.5631990, -0.5606613, -0.5581186, ; -0.5555703, -0.5530168, -0.5504580, -0.5478941, -0.5453250, -0.5427508, -0.5401715, -0.5375871, ; -0.5349976, -0.5324031, -0.5298036, -0.5271991, -0.5245897, -0.5219753, -0.5193560, -0.5167317, ; -0.5141027, -0.5114688, -0.5088301, -0.5061865, -0.5035383, -0.5008853, -0.4982276, -0.4955651, ; -0.4928981, -0.4902264, -0.4875500, -0.4848691, -0.4821836, -0.4794936, -0.4767991, -0.4741000, ; -0.4713965, -0.4686886, -0.4659763, -0.4632596, -0.4605385, -0.4578131, -0.4550833, -0.4523493, ; -0.4496111, -0.4468686, -0.4441219, -0.4413710, -0.4386159, -0.4358568, -0.4330935, -0.4303262, ; -0.4275548, -0.4247794, -0.4219999, -0.4192165, -0.4164292, -0.4136380, -0.4108432, -0.4080442, ; -0.4052414, -0.4024347, -0.3996242, -0.3968100, -0.3939921, -0.3911704, -0.3883451, -0.3855160, ; -0.3826834, -0.3798472, -0.3770074, -0.3741640, -0.3713171, -0.3684668, -0.3656129, -0.3627557, ; -0.3598950, -0.3570309, -0.3541634, -0.3512926, -0.3484186, -0.3455412, -0.3426606, -0.3397768, ; -0.3368897, -0.3339995, -0.3311062, -0.3282097, -0.3253101, -0.3224075, -0.3195018, -0.3165932, ; -0.3136815, -0.3107669, -0.3078494, -0.3049290, -0.3020057, -0.2990796, -0.2961506, -0.2932189, ; -0.2902844, -0.2873472, -0.2844072, -0.2814646, -0.2785194, -0.2755715, -0.2726210, -0.2696680, ; -0.2667124, -0.2637543, -0.2607937, -0.2578307, -0.2548653, -0.2518979, -0.2489277, -0.2459551, ; -0.2429802, -0.2400031, -0.2370236, -0.2340420, -0.2310581, -0.2280721, -0.2250839, -0.2220936, ; -0.2191012, -0.2161068, -0.2131103, -0.2101118, -0.2071113, -0.2041089, -0.2011046, -0.1980983, ; -0.1950902, -0.1920803, -0.1890686, -0.1860550, -0.1830398, -0.1800228, -0.1770041, -0.1739837, ; -0.1709617, -0.1679381, -0.1649129, -0.1618862, -0.1588579, -0.1558282, -0.1527970, -0.1497643, ; -0.1467302, -0.1436948, -0.1406580, -0.1376199, -0.1345804, -0.1315397, -0.1284978, -0.1254547, ; -0.1224104, -0.1193649, -0.1163183, -0.1132706, -0.1102219, -0.1071721, -0.1041213, -0.1010695, ; -0.0980168, -0.0949631, -0.0919086, -0.0888532, -0.0857969, -0.0827403, -0.0796825, -0.0766239, ; -0.0735646, -0.0705046, -0.0674439, -0.0643826, -0.0613207, -0.0582583, -0.0551952, -0.0521317, ; -0.0490676, -0.0460031, -0.0429382, -0.0398729, -0.0368072, -0.0337411, -0.0306747, -0.0276081, ; -0.0245411, -0.0214740, -0.0184066, -0.0153391, -0.0122714, -0.0092036, -0.0061357, -0.0030678, ; }; ; ; /* rotation functions */ ; ; void rotate_x(int n) ; { ; static float matrix[4][4] = { ; { 1.0, 0.0, 0.0, 0.0 }, ; { 0.0, 1.0, 0.0, 0.0 }, ; { 0.0, 0.0, 1.0, 0.0 }, ; { 0.0, 0.0, 0.0, 1.0 }, ; }; ; matrix[1][1] = matrix[2][2] = COS(n); ; matrix[1][2] = -(matrix[2][1] = SIN(n)); ; apply_matrix(&matrix); ; } ; ; void rotate_y(int n) ; { ; static float matrix[4][4] = { ; { 1.0, 0.0, 0.0, 0.0 }, ; { 0.0, 1.0, 0.0, 0.0 }, ; { 0.0, 0.0, 1.0, 0.0 }, ; { 0.0, 0.0, 0.0, 1.0 }, ; }; ; matrix[0][0] = matrix[2][2] = COS(n); ; matrix[2][0] = -(matrix[0][2] = SIN(n)); ; apply_matrix(&matrix); ; } ; ; void rotate_z(int n) ; { ; static float matrix[4][4] = { ; { 1.0, 0.0, 0.0, 0.0 }, ; { 0.0, 1.0, 0.0, 0.0 }, ; { 0.0, 0.0, 1.0, 0.0 }, ; { 0.0, 0.0, 0.0, 1.0 }, ; }; ; matrix[0][0] = matrix[1][1] = COS(n); ; matrix[0][1] = -(matrix[1][0] = SIN(n)); ; apply_matrix(&matrix); ; } ; ; ; ; /** Texture operations **/ ; ; ; /* setup a table for easy twiddling of texures. ; (palette based textures can't be non-twiddled) */ ; ; int twiddletab[1024]; ; ; void init_twiddletab() ; { ; int x; ; for(x=0; x<1024; x++) ; twiddletab[x] = (x&1)|((x&2)<<1)|((x&4)<<2)|((x&8)<<3)|((x&16)<<4)| ; ((x&32)<<5)|((x&64)<<6)|((x&128)<<7)|((x&256)<<8)|((x&512)<<9); ; } ; ; ; /* generate a nice(?) Mandelbrot / Julia fractal to use as ; texture. return value is number of iterations (0-255) to ; use as colour index in a palette. */ ; ; unsigned char compute_texture(int x, int y, int julia) ; { ; /* Ok, ok, so single precision floats are not exactly the ; optimal thing to use for computing fractals, but I'm not ; trying to get any points for correct mathematics here, only ; a cheap way to get some textures for my code :) */ ; float c_re = (x-128)*(1.0/16384)-1.313747; ; float c_im = (y-128)*(1.0/16384)-0.073227; ; float z_re = 0.0; ; float z_im = 0.0; ; int n=-1; ; ; if(julia) { ; z_re = c_re; ; z_im = c_im; ; c_re = -1.313747; ; c_im = -0.073227; ; } ; ; do { ; float tmp_r = z_re; ; z_re = z_re*z_re - z_im*z_im + c_re; ; z_im = 2*tmp_r*z_im + c_im; ; } while(++n<255 && z_re*z_re+z_im*z_im<=2.0); ; ; return n; ; } ; ; ; /** Palette operations **/ ; ; /* some nice palettes to use for the fractal textures */ ; ; unsigned int red_pal[] = { ; 0xff000000,0xff3c3c3c,0xff413c3c,0xff493c3c,0xff4d3838,0xff553838,0xff593434,0xff613434, ; 0xff653030,0xff6d3030,0xff712c2c,0xff792c2c,0xff822828,0xff862828,0xff8e2424,0xff922424, ; 0xff9a2020,0xff9e2020,0xffa61c1c,0xffaa1c1c,0xffb21818,0xffb61818,0xffbe1414,0xffc71414, ; 0xffcb1010,0xffd31010,0xffd70c0c,0xffdf0c0c,0xffe30808,0xffeb0808,0xffef0404,0xfff70404, ; 0xffff0000,0xffff0400,0xffff0c00,0xffff1400,0xffff1c00,0xffff2400,0xffff2c00,0xffff3400, ; 0xffff3c00,0xffff4500,0xffff4d00,0xffff5500,0xffff5d00,0xffff6500,0xffff6d00,0xffff7500, ; 0xffff7d00,0xffff8600,0xffff8e00,0xffff9600,0xffff9e00,0xffffa600,0xffffae00,0xffffb600, ; 0xffffbe00,0xffffc700,0xffffcf00,0xffffd700,0xffffdf00,0xffffe700,0xffffef00,0xfffff700, ; 0xffffff00,0xffffff04,0xffffff0c,0xffffff14,0xffffff1c,0xffffff24,0xffffff2c,0xffffff34, ; 0xffffff3c,0xffffff45,0xffffff4d,0xffffff55,0xffffff5d,0xffffff65,0xffffff6d,0xffffff75, ; 0xffffff7d,0xffffff86,0xffffff8e,0xffffff96,0xffffff9e,0xffffffa6,0xffffffae,0xffffffb6, ; 0xffffffbe,0xffffffc7,0xffffffcf,0xffffffd7,0xffffffdf,0xffffffe7,0xffffffef,0xfffffff7, ; 0xffffffff,0xffffffff,0xfffffbfb,0xfffffbf7,0xfffff7f3,0xfffff7ef,0xfffff3eb,0xfffff3e7, ; 0xffffefe3,0xffffefdf,0xffffebdb,0xffffebd7,0xffffe7d3,0xffffe7cf,0xffffe3cb,0xffffe3c7, ; 0xffffdfc3,0xffffdfbe,0xffffdbba,0xffffdbb6,0xffffd7b2,0xffffd7ae,0xffffd3aa,0xffffd3a6, ; 0xffffcfa2,0xffffcf9e,0xffffcb9a,0xffffcb96,0xffffc792,0xffffc78e,0xffffc38a,0xffffc386, ; 0xffffbe82,0xffffba7d,0xffffba79,0xffffb675,0xffffb671,0xffffb26d,0xffffb269,0xffffae65, ; 0xffffae61,0xffffaa5d,0xffffaa59,0xffffa655,0xffffa651,0xffffa24d,0xffffa249,0xffff9e45, ; 0xffff9e41,0xffff9a3c,0xffff9a38,0xffff9634,0xffff9630,0xffff922c,0xffff9228,0xffff8e24, ; 0xffff8e20,0xffff8a1c,0xffff8a18,0xffff8614,0xffff8610,0xffff820c,0xffff8208,0xffff7d04, ; 0xffff7900,0xffff7900,0xffff7500,0xffff7100,0xffff6d00,0xffff6900,0xffff6500,0xffff6100, ; 0xffff5d00,0xffff5900,0xffff5500,0xffff5100,0xffff4d00,0xffff4900,0xffff4500,0xffff4100, ; 0xffff3c00,0xffff3c00,0xffff3800,0xffff3400,0xffff3000,0xffff2c00,0xffff2800,0xffff2400, ; 0xffff2000,0xffff1c00,0xffff1800,0xffff1400,0xffff1000,0xffff0c00,0xffff0800,0xffff0400, ; 0xffff0000,0xffff0000,0xfffb0000,0xfff70000,0xfff70000,0xfff30000,0xffef0000,0xffeb0000, ; 0xffeb0000,0xffe70000,0xffe30000,0xffe30000,0xffdf0000,0xffdb0000,0xffd70000,0xffd70000, ; 0xffd30000,0xffcf0000,0xffcf0000,0xffcb0000,0xffc70000,0xffc30000,0xffc30000,0xffbe0000, ; 0xffba0000,0xffba0000,0xffb60000,0xffb20000,0xffae0000,0xffae0000,0xffaa0000,0xffa60000, ; 0xffa20000,0xffa20000,0xff9e0404,0xff9a0404,0xff960808,0xff920808,0xff8e0c0c,0xff8e0c0c, ; 0xff8a1010,0xff861010,0xff821414,0xff7d1414,0xff791818,0xff791818,0xff751c1c,0xff711c1c, ; 0xff6d2020,0xff692020,0xff652424,0xff652424,0xff612828,0xff5d2828,0xff592c2c,0xff552c2c, ; 0xff513030,0xff513030,0xff4d3434,0xff493434,0xff453838,0xff413838,0xff3c3c3c,0xff3c3c3c, ; }; ; ; unsigned int blue_pal[] = { ; 0xff000000,0xff000000,0xff000004,0xff00000c,0xff000010,0xff000018,0xff000020,0xff000024, ; 0xff00002c,0xff000030,0xff000038,0xff000041,0xff000045,0xff00004d,0xff000051,0xff000059, ; 0xff000061,0xff000065,0xff00006d,0xff000075,0xff000079,0xff000082,0xff000086,0xff00008e, ; 0xff000096,0xff00009a,0xff0000a2,0xff0000a6,0xff0000ae,0xff0000b6,0xff0000ba,0xff0000c3, ; 0xff0000cb,0xff0004cb,0xff000ccb,0xff0010cf,0xff0018cf,0xff001cd3,0xff0024d3,0xff0028d3, ; 0xff0030d7,0xff0038d7,0xff003cdb,0xff0045db,0xff0049db,0xff0051df,0xff0055df,0xff005de3, ; 0xff0065e3,0xff0069e3,0xff0071e7,0xff0075e7,0xff007deb,0xff0082eb,0xff008aeb,0xff008eef, ; 0xff0096ef,0xff009ef3,0xff00a2f3,0xff00aaf3,0xff00aef7,0xff00b6f7,0xff00bafb,0xff00c3fb, ; 0xff00cbff,0xff04cbff,0xff0ccbff,0xff14cfff,0xff1ccfff,0xff24d3ff,0xff2cd3ff,0xff34d3ff, ; 0xff3cd7ff,0xff45d7ff,0xff4ddbff,0xff55dbff,0xff5ddbff,0xff65dfff,0xff6ddfff,0xff75e3ff, ; 0xff7de3ff,0xff86e3ff,0xff8ee7ff,0xff96e7ff,0xff9eebff,0xffa6ebff,0xffaeebff,0xffb6efff, ; 0xffbeefff,0xffc7f3ff,0xffcff3ff,0xffd7f3ff,0xffdff7ff,0xffe7f7ff,0xffeffbff,0xfff7fbff, ; 0xffffffff,0xfffbffff,0xfff7ffff,0xfff3ffff,0xffebffff,0xffe7ffff,0xffe3ffff,0xffdbffff, ; 0xffd7ffff,0xffd3ffff,0xffcbffff,0xffc7ffff,0xffc3ffff,0xffbaffff,0xffb6ffff,0xffb2ffff, ; 0xffaaffff,0xffa6ffff,0xffa2ffff,0xff9effff,0xff96ffff,0xff92ffff,0xff8effff,0xff86ffff, ; 0xff82ffff,0xff7dffff,0xff75ffff,0xff71ffff,0xff6dffff,0xff65ffff,0xff61ffff,0xff5dffff, ; 0xff55ffff,0xff51ffff,0xff4dffff,0xff49ffff,0xff41ffff,0xff3cffff,0xff38ffff,0xff30ffff, ; 0xff2cffff,0xff28ffff,0xff20ffff,0xff1cffff,0xff18ffff,0xff10ffff,0xff0cffff,0xff08ffff, ; 0xff00ffff,0xff00fbff,0xff00f7ff,0xff00f3ff,0xff00ebff,0xff00e7ff,0xff00e3ff,0xff00dbff, ; 0xff00d7ff,0xff00d3ff,0xff00cbff,0xff00c7ff,0xff00c3ff,0xff00baff,0xff00b6ff,0xff00b2ff, ; 0xff00aaff,0xff00a6ff,0xff00a2ff,0xff009eff,0xff0096ff,0xff0092ff,0xff008eff,0xff0086ff, ; 0xff0082ff,0xff007dff,0xff0075ff,0xff0071ff,0xff006dff,0xff0065ff,0xff0061ff,0xff005dff, ; 0xff0055ff,0xff0051ff,0xff004dff,0xff0049ff,0xff0041ff,0xff003cff,0xff0038ff,0xff0030ff, ; 0xff002cff,0xff0028ff,0xff0020ff,0xff001cff,0xff0018ff,0xff0010ff,0xff000cff,0xff0008ff, ; 0xff0000ff,0xff0000fb,0xff0000f7,0xff0000f3,0xff0000ef,0xff0000eb,0xff0000e7,0xff0000e3, ; 0xff0000df,0xff0000db,0xff0000d7,0xff0000d3,0xff0000cf,0xff0000cb,0xff0000c7,0xff0000c3, ; 0xff0000be,0xff0000ba,0xff0000b6,0xff0000b2,0xff0000ae,0xff0000aa,0xff0000a6,0xff0000a2, ; 0xff00009e,0xff00009a,0xff000096,0xff000092,0xff00008e,0xff00008a,0xff000086,0xff000082, ; 0xff00007d,0xff000079,0xff000075,0xff000071,0xff00006d,0xff000069,0xff000065,0xff000061, ; 0xff00005d,0xff000059,0xff000055,0xff000051,0xff00004d,0xff000049,0xff000045,0xff000041, ; 0xff00003c,0xff000038,0xff000034,0xff000030,0xff00002c,0xff000028,0xff000024,0xff000020, ; 0xff00001c,0xff000018,0xff000014,0xff000010,0xff00000c,0xff000008,0xff000000,0xff000000, ; }; ; ; unsigned int purplish_pal[] = { ; 0xff000000,0xff9208e7,0xff9208e3,0xff9608e3,0xff9a04df,0xff9e04df,0xff9e04db,0xffa204db, ; 0xffa600d7,0xffaa00d7,0xffaa00d3,0xffae00cf,0xffb200cf,0xffb600cb,0xffb600c7,0xffba00c7, ; 0xffbe00c3,0xffbe00be,0xffc300be,0xffc700ba,0xffc700b6,0xffcb00b6,0xffcf00b2,0xffcf00ae, ; 0xffd300aa,0xffd700aa,0xffd700a6,0xffdb04a2,0xffdb049e,0xffdf049e,0xffdf049a,0xffe30896, ; 0xffe30892,0xffe70892,0xffe7088e,0xffeb0c8a,0xffeb0c86,0xffef0c82,0xffef1082,0xffef107d, ; 0xfff31479,0xfff31475,0xfff31475,0xfff71871,0xfff7186d,0xfff71c69,0xfffb1c65,0xfffb2065, ; 0xfffb2061,0xfffb245d,0xffff2859,0xffff2859,0xffff2c55,0xffff2c51,0xffff304d,0xffff344d, ; 0xffff3449,0xffff3845,0xffff3c45,0xffff3c41,0xffff413c,0xffff453c,0xffff4538,0xffff4934, ; 0xffff4d34,0xffff4d30,0xffff512c,0xffff552c,0xffff5928,0xffff5928,0xfffb5d24,0xfffb6120, ; 0xfffb6520,0xfffb651c,0xfff7691c,0xfff76d18,0xfff77118,0xfff37514,0xfff37514,0xfff37914, ; 0xffef7d10,0xffef8210,0xffef820c,0xffeb860c,0xffeb8a0c,0xffe78e08,0xffe79208,0xffe39208, ; 0xffe39608,0xffdf9a04,0xffdf9e04,0xffdb9e04,0xffdba204,0xffd7a600,0xffd7aa00,0xffd3aa00, ; 0xffcfae00,0xffcfb200,0xffcbb600,0xffc7b600,0xffc7ba00,0xffc3be00,0xffbebe00,0xffbec300, ; 0xffbac700,0xffb6c700,0xffb6cb00,0xffb2cf00,0xffaecf00,0xffaad300,0xffaad700,0xffa6d700, ; 0xffa2db04,0xff9edb04,0xff9edf04,0xff9adf04,0xff96e308,0xff92e308,0xff92e708,0xff8ee708, ; 0xff8aeb0c,0xff86eb0c,0xff82ef0c,0xff82ef10,0xff7def10,0xff79f314,0xff75f314,0xff75f314, ; 0xff71f718,0xff6df718,0xff69f71c,0xff65fb1c,0xff65fb20,0xff61fb20,0xff5dfb24,0xff59ff28, ; 0xff59ff28,0xff55ff2c,0xff51ff2c,0xff4dff30,0xff4dff34,0xff49ff34,0xff45ff38,0xff45ff3c, ; 0xff41ff3c,0xff3cff41,0xff3cff45,0xff38ff45,0xff34ff49,0xff34ff4d,0xff30ff4d,0xff2cff51, ; 0xff2cff55,0xff28ff59,0xff28ff59,0xff24fb5d,0xff20fb61,0xff20fb65,0xff1cfb65,0xff1cf769, ; 0xff18f76d,0xff18f771,0xff14f375,0xff14f375,0xff14f379,0xff10ef7d,0xff10ef82,0xff0cef82, ; 0xff0ceb86,0xff0ceb8a,0xff08e78e,0xff08e792,0xff08e392,0xff08e396,0xff04df9a,0xff04df9e, ; 0xff04db9e,0xff04dba2,0xff00d7a6,0xff00d7aa,0xff00d3aa,0xff00cfae,0xff00cfb2,0xff00cbb6, ; 0xff00c7b6,0xff00c7ba,0xff00c3be,0xff00bebe,0xff00bec3,0xff00bac7,0xff00b6c7,0xff00b6cb, ; 0xff00b2cf,0xff00aecf,0xff00aad3,0xff00aad7,0xff00a6d7,0xff04a2db,0xff049edb,0xff049edf, ; 0xff049adf,0xff0896e3,0xff0892e3,0xff0892e7,0xff088ee7,0xff0c8aeb,0xff0c86eb,0xff0c82ef, ; 0xff1082ef,0xff107def,0xff1479f3,0xff1475f3,0xff1475f3,0xff1871f7,0xff186df7,0xff1c69f7, ; 0xff1c65fb,0xff2065fb,0xff2061fb,0xff245dfb,0xff2859ff,0xff2859ff,0xff2c55ff,0xff2c51ff, ; 0xff304dff,0xff344dff,0xff3449ff,0xff3845ff,0xff3c45ff,0xff3c41ff,0xff413cff,0xff453cff, ; 0xff4538ff,0xff4934ff,0xff4d34ff,0xff4d30ff,0xff512cff,0xff552cff,0xff5928ff,0xff5928ff, ; 0xff5d24fb,0xff6120fb,0xff6520fb,0xff651cfb,0xff691cf7,0xff6d18f7,0xff7118f7,0xff7514f3, ; 0xff7514f3,0xff7914f3,0xff7d10ef,0xff8210ef,0xff820cef,0xff860ceb,0xff8a0ceb,0xff8e08e7, ; }; ; ; void init_palette() ; { ; unsigned int (*palette)[4][256] = (unsigned int (*)[4][256])0xa05f9000; ; int n; ; ; for(n = 0; n<256; n++) { ; (*palette)[0][n] = red_pal[n]; ; (*palette)[1][n] = blue_pal[n]; ; (*palette)[2][n] = purplish_pal[n]; ; } ; } ; ; ; /*** Misc support functions */ ; ; ; /* Wait for the bottom of the view port ( = screen. Amiga terminology :) */ ; ; void wait_bovp() ; { ; volatile unsigned int *vblreg = (volatile unsigned int *)(void*)0xa05f6900; ; *vblreg = 0x08; ; while (!(*vblreg & 0x08)) ; ; *vblreg = 0x08; ; } ; ; ; /* Flip display buffer */ ; ; void set_display_addr(void *ptr) ; { ; volatile unsigned int *reg = (volatile unsigned int *)(void*)0xa05f8050; ; unsigned int addr = ((unsigned int)ptr)&0x007fffff; ; reg[0] = addr; ; reg[1] = addr+640*2; ; } ; ; ; ; /* Draw a textured polygon for one of the faces of the cube */ ; ; void draw_face(float *p1, float *p2, float *p3, float *p4, void *tex, int pal) ; { ; struct polygon_list mypoly; ; struct packed_colour_vertex_list myvertex; ; ; mypoly.cmd = ; TA_CMD_POLYGON|TA_CMD_POLYGON_TYPE_OPAQUE|TA_CMD_POLYGON_SUBLIST| ; TA_CMD_POLYGON_STRIPLENGTH_2|TA_CMD_POLYGON_TEXTURED; ; mypoly.mode1 = TA_POLYMODE1_Z_ALWAYS|TA_POLYMODE1_CULL_CCW; ; mypoly.mode2 = ; TA_POLYMODE2_BLEND_DEFAULT|TA_POLYMODE2_FOG_DISABLED| ; TA_POLYMODE2_TEXTURE_CLAMP_U|TA_POLYMODE2_TEXTURE_CLAMP_V| ; TA_POLYMODE2_BILINEAR_FILTER|TA_POLYMODE2_MIPMAP_D_1_00| ; TA_POLYMODE2_TEXTURE_REPLACE|TA_POLYMODE2_U_SIZE_256|TA_POLYMODE2_V_SIZE_256; ; mypoly.texture = ; TA_TEXTUREMODE_CLUT8|TA_TEXTUREMODE_CLUTBANK8(pal)| ; TA_TEXTUREMODE_ADDRESS(tex); ; mypoly.alpha = mypoly.red = mypoly.green = mypoly.blue = 0.0; ; ta_commit_list(&mypoly); ; ; myvertex.cmd = TA_CMD_VERTEX; ; myvertex.colour = 0xffffffff; ; myvertex.ocolour = 0; ; ; myvertex.x = p1[0]; ; myvertex.y = p1[1]; ; myvertex.z = p1[2]; ; myvertex.u = 0.0; ; myvertex.v = 0.0; ; ta_commit_list(&myvertex); ; ; myvertex.x = p2[0]; ; myvertex.y = p2[1]; ; myvertex.z = p2[2]; ; myvertex.u = 1.0; ; myvertex.v = 0.0; ; ta_commit_list(&myvertex); ; ; myvertex.x = p3[0]; ; myvertex.y = p3[1]; ; myvertex.z = p3[2]; ; myvertex.u = 0.0; ; myvertex.v = 1.0; ; ta_commit_list(&myvertex); ; ; myvertex.x = p4[0]; ; myvertex.y = p4[1]; ; myvertex.z = p4[2]; ; myvertex.u = 1.0; ; myvertex.v = 1.0; ; myvertex.cmd |= TA_CMD_VERTEX_EOS; ; ta_commit_list(&myvertex); ; } ; ; ; /* Quick memory clear */ ; ; #define QACR0 (*(volatile unsigned int *)(void *)0xff000038) ; #define QACR1 (*(volatile unsigned int *)(void *)0xff00003c) ; ; void store_q_clear(void *ptr, int cnt) ; { ; unsigned int *d = (unsigned int *)(void *) ; (0xe0000000 | (((unsigned long)ptr) & 0x03ffffc0)); ; /* Set store queue memory area as desired */ ; QACR0 = ((((unsigned int)ptr)>>26)<<2)&0x1c; ; QACR1 = ((((unsigned int)ptr)>>26)<<2)&0x1c; ; /* Fill both store queues with zeroes */ ; d[0] = d[1] = d[2] = d[3] = d[4] = d[5] = d[6] = d[7] = ; d[8] = d[9] = d[10] = d[11] = d[12] = d[13] = d[14] = d[15] = 0; ; /* Write them as many times necessary */ ; cnt>>=5; ; while(cnt--) { ; asm("pref @%0" : : "r" (d)); ; d += 8; ; } ; /* Wait for both store queues to complete */ ; d = (unsigned int *)0xe0000000; ; d[0] = d[8] = 0; ; } ; ; ; ; /* Define space for the display command list, and the tile work area */ ; ; #define MAX_H_TILE (640/32) ; #define MAX_V_TILE (480/32) ; ; struct ta_buffers { ; char cmd_list[2][512*1024]; ; char tile_buffer[2][64*MAX_H_TILE*MAX_V_TILE]; ; int tile_descriptor[2][24+6*MAX_H_TILE*MAX_V_TILE]; ; }; ; ; ; /** main **/ ; ; int main (int argc, char **argv) ; { ; struct ta_buffers *bufs = (struct ta_buffers *)(void *)0xa5400000; ; void *vram = (void *)0xa5000000; ; unsigned short *tex[2]; ; void *tiles[2]; ; int i, j; ; int curbuf=0; ; ; /* Clear all VRAM */ ; store_q_clear((void *)0xa4000000, 8*1024*1024); ; ; /* Set up PowerVR display and tile accelerator hardware */ ; init_pvr(); ; init_video(check_cable(), 1, 2); ; ; /* Create palettes and twidding table for textures */ ; init_palette(); ; init_twiddletab(); ; ; /* Just allocate space for the two 256x256x8 bit textures manually */ ; tex[0] = (unsigned short *)(void *)0xa4400000; ; tex[1] = (void*)(((char *)tex[0])+256*256); ; ; /* Create the textures. Unfortunatly, it's not possible to do byte ; writes to the texture memory. So for these 8bpp textures, we have ; to write two pixels at a time. Fortunatelty, the twiddling algorithm ; (palette based textures can not be non-twiddled) keeps horizontally ; adjacent pixel pairs together, so it's not a real problem. */ ; for(i=0; i<256; i++) ; for(j=0; j<256; j+=2) { ; /* Texture 0 = Mandelbrot */ ; tex[0][twiddletab[i]|(twiddletab[j]>>1)] = ; compute_texture(i, j, 0) | (compute_texture(i, j+1, 0)<<8); ; /* Texture 1 = Julia */ ; tex[1][twiddletab[i]|(twiddletab[j]>>1)] = ; compute_texture(i, j, 1) | (compute_texture(i, j+1, 1)<<8); ; } ; ; /* Create two sets of tile descriptors, to do double buffering */ ; ; tiles[0] = ta_create_tile_descriptors(bufs->tile_descriptor[0], ; bufs->tile_buffer[0], ; 640/32, 480/32); ; ; tiles[1] = ta_create_tile_descriptors(bufs->tile_descriptor[1], ; bufs->tile_buffer[1], ; 640/32, 480/32); ; curbuf = 0; ; ; for(i = 0; ; i++) { ; ; /* Set up the hardware transformation in the ; SH4 with the transformations we need to do */ ; clear_matrix(); ; apply_matrix(&screenview_matrix); ; apply_matrix(&projection_matrix); ; apply_matrix(&translation_matrix); ; rotate_x(i*34/5); ; rotate_y(i*25/7); ; rotate_z(i*47/9); ; ; /* Apply the transformation to all the coordinates, and normalize the ; resulting homogenous coordinates into normal 3D coordinates again. */ ; transform_coords(coords, trans_coords, 8); ; ; /* Set up the command list compiler to use the right set of buffers */ ; ta_set_target(bufs->cmd_list[curbuf], ; bufs->tile_buffer[curbuf], 640/32, 480/32); ; ; /* Draw the 6 faces of the cube */ ; draw_face(trans_coords[0], trans_coords[1], trans_coords[2], ; trans_coords[3], tex[0], 0); ; draw_face(trans_coords[1], trans_coords[5], trans_coords[3], ; trans_coords[7], tex[0], 1); ; draw_face(trans_coords[4], trans_coords[5], trans_coords[0], ; trans_coords[1], tex[0], 2); ; draw_face(trans_coords[5], trans_coords[4], trans_coords[7], ; trans_coords[6], tex[1], 0); ; draw_face(trans_coords[4], trans_coords[0], trans_coords[6], ; trans_coords[2], tex[1], 1); ; draw_face(trans_coords[2], trans_coords[3], trans_coords[6], ; trans_coords[7], tex[1], 2); ; ; /* Mark the end of the command list */ ; ta_commit_end(); ; ; /* Wait for the previous render to complete, and ; the raster beam to go off screen */ ; ta_wait_render(); ; wait_bovp(); ; ; /* Switch to the previously rendered screen */ ; set_display_addr((curbuf? vram+1280*480 : vram)); ; ; /* Start rendering the new command list to the screen ; that was just swapped out */ ; ta_begin_render(bufs->cmd_list[curbuf], ; tiles[curbuf], (curbuf? vram : vram+1280*480), ; 1280, TA_PIXFMT_RGB565|TA_PIXFMT_DITHER, 640, 480); ; ; /* Next time, use the alternate set of buffers */ ; curbuf ^= 1; ; ; } ; /* NOTREACHED */ ; return 0; ; } ; ; matrix.h ; extern void clear_matrix(); ; extern void apply_matrix(float (*matrix)[4][4]); ; extern void transform_coords(float (*src)[3], float (*dest)[3], int n); ; ; matrix.s ; ! SH4 matrix operations ; ! ; ! The matrix is kept in the XMTRX register set between calls ; ; ; .globl _clear_matrix, _apply_matrix, _transform_coords ; ; .text ; ; ; ! Initialize the matrix to the identity matrix ; ! ; ! no args ; ; _clear_matrix: ; fldi0 fr0 ; fldi0 fr1 ; fldi1 fr2 ; fldi0 fr3 ; fldi0 fr4 ; fldi1 fr5 ; fschg ; fmov dr2,xd0 ; fmov dr0,xd2 ; fmov dr4,xd4 ; fmov dr0,xd6 ; fmov dr0,xd8 ; fmov dr2,xd10 ; fmov dr0,xd12 ; fmov dr4,xd14 ; rts ; fschg ; ; ; ; ! Multiply another matrix to the current matrix ; ! ; ! r4 = pointer to the other matrix (4 * 4 floats) ; ; _apply_matrix: ; fmov.s @r4+,fr0 ; fmov.s @r4+,fr1 ; fmov.s @r4+,fr2 ; fmov.s @r4+,fr3 ; ftrv xmtrx,fv0 ; fmov.s @r4+,fr4 ; fmov.s @r4+,fr5 ; fmov.s @r4+,fr6 ; fmov.s @r4+,fr7 ; ftrv xmtrx,fv4 ; fmov.s @r4+,fr8 ; fmov.s @r4+,fr9 ; fmov.s @r4+,fr10 ; fmov.s @r4+,fr11 ; ftrv xmtrx,fv8 ; fmov.s @r4+,fr12 ; fmov.s @r4+,fr13 ; fmov.s @r4+,fr14 ; fmov.s @r4+,fr15 ; ftrv xmtrx,fv12 ; fschg ; fmov dr0,xd0 ; fmov dr2,xd2 ; fmov dr4,xd4 ; fmov dr6,xd6 ; fmov dr8,xd8 ; fmov dr10,xd10 ; fmov dr12,xd12 ; fmov dr14,xd14 ; rts ; fschg ; ; ; ! Multiply a set of 3D vectors with the matrix ; ! (vectors are extended to 4D homogenous coordinates by ; ! setting W=1), and then normalize the resulting ; ! vectors before storing them in the result array ; ! ; ! r4 = pointer to a source set of 3D vectors (n * 3 floats) ; ! r5 = pointer to a destination set of 3D vectors ( - " - ) ; ! r6 = number of vectors to transform ; ; _transform_coords: ; pref @r4 ; mov r5,r0 ; mov #4,r1 ; mov r4,r3 ; mov #8,r2 ; add #32,r3 ; .loop: ; fmov.s @r4+,fr0 ; fmov.s @r4+,fr1 ; fmov.s @r4+,fr2 ; fldi1 fr3 ; pref @r3 ; ftrv xmtrx,fv0 ; dt r6 ; fdiv fr3,fr0 ; fmov.s fr0,@r0 ; fdiv fr3,fr1 ; fmov.s fr1,@(r0,r1) ; fdiv fr3,fr2 ; add #4*3,r3 ; fmov.s fr2,@(r0,r2) ; bf/s .loop ; add #4*3,r0 ; rts ; nop ; ; .end ; ; startup.s ; ! Generic startup ; ! ; ! Enable cache, clear bss and init floating point ops ; ; ; .globl start ; ; .text ; ; start: ; stc sr,r0 ; or #0xf0,r0 ; ldc r0,sr ; ! First, make sure to run in the P2 area ; mov.l setup_cache_addr,r0 ; mov.l p2_mask,r1 ; or r1,r0 ; jmp @r0 ; nop ; setup_cache: ; ! Now that we are in P2, it's safe ; ! to enable the cache ; mov.l ccr_addr,r0 ; mov.w ccr_data,r1 ; mov.l r1,@r0 ; ! After changing CCR, eight instructions ; ! must be executed before it's safe to enter ; ! a cached area such as P1 ; mov.l initaddr,r0 ! 1 ; mov #0,r1 ! 2 ; nop ! 3 ; nop ! 4 ; nop ! 5 ; nop ! 6 ; nop ! 7 ; nop ! 8 ; jmp @r0 ! go ; mov r1,r0 ; ; ; ! Clear BSS section ; init: ; mov.l bss_start_addr,r0 ; mov.l bss_end_addr,r2 ; mov #3,r1 ; add r1,r0 ; add r1,r2 ; not r1,r1 ; and r1,r0 ; and r1,r2 ; sub r0,r2 ; shlr r2 ; shlr r2 ; mov #0,r1 ; .loop: dt r2 ; mov.l r1,@r0 ; bf/s .loop ; add #4,r0 ; mov #0,r2 ; mov #0,r1 ; ! Set up floating point ops, and jump to main ; lds r1,fpscr ; mov.l mainaddr,r0 ; jmp @r0 ; mov r1,r0 ; ; ; .align 2 ; mainaddr: ; .long _main ; initaddr: ; .long init ; bss_start_addr: ; .long __bss_start ; bss_end_addr: ; .long _end ; p2_mask: ; .long 0xa0000000 ; setup_cache_addr: ; .long setup_cache ; ccr_addr: ; .long 0xff00001c ; ccr_data: ; .word 0x090b ; ; ; .end ; ; ta.c ; #include "ta.h" ; ; ; /* Functions to send a list (the basic command unit of the TA) to the ; command list compiler. ta_commit_list sends a 32-byte list, and ; ta_commit_list2 sends a 64-byte list. */ ; ; #define QACR0 (*(volatile unsigned int *)(void *)0xff000038) ; #define QACR1 (*(volatile unsigned int *)(void *)0xff00003c) ; ; void ta_commit_list(void *src) ; { ; unsigned int *s = (unsigned int *)src; ; unsigned int *d = (unsigned int *)0xe0000000; ; QACR0 = ((0xb0000000>>26)<<2)&0x1c; ; d[0] = *s++; ; d[1] = *s++; ; d[2] = *s++; ; d[3] = *s++; ; d[4] = *s++; ; d[5] = *s++; ; d[6] = *s++; ; d[7] = *s++; ; asm("pref @%0" : : "r" (d)); ; } ; ; void ta_commit_list2(void *src) ; { ; unsigned int *s = (unsigned int *)src; ; unsigned int *d = (unsigned int *)0xe0000000; ; QACR0 = ((0xb0000000>>26)<<2)&0x1c; ; QACR1 = ((0xb0000000>>26)<<2)&0x1c; ; d[0] = *s++; ; d[1] = *s++; ; d[2] = *s++; ; d[3] = *s++; ; d[4] = *s++; ; d[5] = *s++; ; d[6] = *s++; ; d[7] = *s++; ; asm("pref @%0" : : "r" (d)); ; d[8] = *s++; ; d[9] = *s++; ; d[10] = *s++; ; d[11] = *s++; ; d[12] = *s++; ; d[13] = *s++; ; d[14] = *s++; ; d[15] = *s++; ; asm("pref @%0" : : "r" (d+8)); ; } ; ; ; /* Send the special end of list command */ ; ; void ta_commit_end() ; { ; unsigned int words[8] = { 0 }; ; ta_commit_list(words); ; } ; ; ; /* Set up buffers and descriptors for a tilespace */ ; ; void *ta_create_tile_descriptors(void *ptr, void *buf, int w, int h) ; { ; /* each tile desriptor is 6 words. In addition, there's a 24 word header */ ; /* so, there are 24+6*w*h words stored at ptr. */ ; ; /* each tile uses 64 bytes of buffer space. So buf must point to */ ; /* 64*w*h bytes of data */ ; ; int x, y; ; unsigned int *vr = ptr; ; unsigned int bf = ((unsigned int)buf)&0x007fffff; ; unsigned int strbase = (((unsigned int)ptr)&0x007fffff)|0x80000000; ; ; for (x=0; x<18; x++) ; *vr++ = 0; ; *vr++ = 0x10000000; ; *vr++ = 0x80000000; ; *vr++ = 0x80000000; ; *vr++ = 0x80000000; ; *vr++ = 0x80000000; ; *vr++ = 0x80000000; ; for (x=0; x>3; ; regs[0x048/4] = pixfmt; ; regs[0x014/4] = 0xffffffff; /* Launch! */ ; } ; ; ta.h ; /* Pixel formats for ta_begin_render() (should be same as the screens) */ ; ; #define TA_PIXFMT_RGB555 0 ; #define TA_PIXFMT_RGB565 1 ; #define TA_PIXFMT_ARGB4444 2 ; #define TA_PIXFMT_ARGB1555 3 ; #define TA_PIXFMT_RGB888 5 ; #define TA_PIXFMT_ARGB8888 6 ; ; #define TA_PIXFMT_DITHER 8 ; ; ; ; /* TA commands... */ ; ; ; /* Command: User clip */ ; ; struct user_clip_list { ; unsigned int cmd; ; int not_used[3]; ; float xmin, ymin, xmax, ymax; ; }; ; ; #define TA_CMD_USERCLIP 0x20000000 ; ; ; /* Command: Polygon / Modifier volume */ ; ; struct polygon_list { ; unsigned int cmd; ; unsigned int mode1; ; unsigned int mode2; ; unsigned int texture; ; float alpha, red, green, blue; /* used with intensity type colour */ ; }; ; ; struct modifier_list { ; unsigned int cmd; ; unsigned int instruction; ; int not_used[6]; ; }; ; ; ; #define TA_CMD_POLYGON 0x80000000 ; #define TA_CMD_MODIFIER 0x80000000 ; #define TA_CMD_POLYGON_TYPE_OPAQUE (0<<24) ; #define TA_CMD_MODIFIER_TYPE_OPAQUE (1<<24) ; #define TA_CMD_POLYGON_TYPE_TRANSPARENT (2<<24) ; #define TA_CMD_MODIFIER_TYPE_TRANSPARENT (3<<24) ; #define TA_CMD_POLYGON_TYPE_PUNCHTHRU (4<<24) ; #define TA_CMD_POLYGON_SUBLIST 0x00800000 ; #define TA_CMD_POLYGON_STRIPLENGTH_1 (0<<18) ; #define TA_CMD_POLYGON_STRIPLENGTH_2 (1<<18) ; #define TA_CMD_POLYGON_STRIPLENGTH_4 (2<<18) ; #define TA_CMD_POLYGON_STRIPLENGTH_6 (3<<18) ; #define TA_CMD_POLYGON_USER_CLIP_INSIDE 0x00020000 ; #define TA_CMD_POLYGON_USER_CLIP_OUTSIDE 0x00030000 ; #define TA_CMD_POLYGON_AFFECTED_BY_MODIFIER 0x00000080 ; #define TA_CMD_POLYGON_CHEAP_SHADOW_MODIFIER 0x00000000 ; #define TA_CMD_POLYGON_NORMAL_MODIFIER 0x00000040 ; #define TA_CMD_POLYGON_PACKED_COLOUR (0<<4) ; #define TA_CMD_POLYGON_FLOAT_COLOUR (1<<4) ; #define TA_CMD_POLYGON_INTENSITY (2<<4) ; #define TA_CMD_POLYGON_PREVFACE_INTENSITY (3<<4) ; #define TA_CMD_POLYGON_TEXTURED 0x00000008 ; #define TA_CMD_POLYGON_SPECULAR_HIGHLIGHT 0x00000004 ; #define TA_CMD_POLYGON_GOURAUD_SHADING 0x00000002 ; #define TA_CMD_POLYGON_16BIT_UV 0x00000001 ; ; #define TA_POLYMODE1_Z_NEVER (0<<29) ; #define TA_POLYMODE1_Z_LESS (1<<29) ; #define TA_POLYMODE1_Z_EQUAL (2<<29) ; #define TA_POLYMODE1_Z_LESSEQUAL (3<<29) ; #define TA_POLYMODE1_Z_GREATER (4<<29) ; #define TA_POLYMODE1_Z_NOTEQUAL (5<<29) ; #define TA_POLYMODE1_Z_GREATEREQUAL (6<<29) ; #define TA_POLYMODE1_Z_ALWAYS (7<<29) ; #define TA_POLYMODE1_CULL_SMALL (1<<27) ; #define TA_POLYMODE1_CULL_CCW (2<<27) ; #define TA_POLYMODE1_CULL_CW (3<<27) ; #define TA_POLYMODE1_NO_Z_UPDATE 0x04000000 ; ; #define TA_POLYMODE2_BLEND_DEFAULT (0x20<<24) ; #define TA_POLYMODE2_FOG_TABLE (0<<22) ; #define TA_POLYMODE2_FOG_VERTEX (1<<22) ; #define TA_POLYMODE2_FOG_DISABLED (2<<22) ; #define TA_POLYMODE2_FOG_TABLE2 (3<<22) ; #define TA_POLYMODE2_CLAMP_COLOURS 0x00200000 ; #define TA_POLYMODE2_ENABLE_ALPHA 0x00100000 ; #define TA_POLYMODE2_DISABLE_TEXTURE_TRANSPARENCY 0x00080000 ; #define TA_POLYMODE2_TEXTURE_FLIP_U 0x00080000 ; #define TA_POLYMODE2_TEXTURE_FLIP_V 0x00040000 ; #define TA_POLYMODE2_TEXTURE_CLAMP_U 0x00020000 ; #define TA_POLYMODE2_TEXTURE_CLAMP_V 0x00010000 ; #define TA_POLYMODE2_TRILINEAR_FILTER 0x00004000 ; #define TA_POLYMODE2_BILINEAR_FILTER 0x00002000 ; #define TA_POLYMODE2_MIPMAP_D_0_25 (1<<8) ; #define TA_POLYMODE2_MIPMAP_D_0_50 (2<<8) ; #define TA_POLYMODE2_MIPMAP_D_0_75 (3<<8) ; #define TA_POLYMODE2_MIPMAP_D_1_00 (4<<8) ; #define TA_POLYMODE2_MIPMAP_D_1_25 (5<<8) ; #define TA_POLYMODE2_MIPMAP_D_1_50 (6<<8) ; #define TA_POLYMODE2_MIPMAP_D_1_75 (7<<8) ; #define TA_POLYMODE2_MIPMAP_D_2_00 (8<<8) ; #define TA_POLYMODE2_MIPMAP_D_2_25 (9<<8) ; #define TA_POLYMODE2_MIPMAP_D_2_50 (10<<8) ; #define TA_POLYMODE2_MIPMAP_D_2_75 (11<<8) ; #define TA_POLYMODE2_MIPMAP_D_3_00 (12<<8) ; #define TA_POLYMODE2_MIPMAP_D_3_25 (13<<8) ; #define TA_POLYMODE2_MIPMAP_D_3_50 (14<<8) ; #define TA_POLYMODE2_MIPMAP_D_3_75 (15<<8) ; #define TA_POLYMODE2_TEXTURE_REPLACE (0<<6) ; #define TA_POLYMODE2_TEXTURE_MODULATE (1<<6) ; #define TA_POLYMODE2_TEXTURE_DECAL (2<<6) ; #define TA_POLYMODE2_U_SIZE_8 (0<<3) ; #define TA_POLYMODE2_U_SIZE_16 (1<<3) ; #define TA_POLYMODE2_U_SIZE_32 (2<<3) ; #define TA_POLYMODE2_U_SIZE_64 (3<<3) ; #define TA_POLYMODE2_U_SIZE_128 (4<<3) ; #define TA_POLYMODE2_U_SIZE_256 (5<<3) ; #define TA_POLYMODE2_U_SIZE_512 (6<<3) ; #define TA_POLYMODE2_U_SIZE_1024 (7<<3) ; #define TA_POLYMODE2_V_SIZE_8 (0<<0) ; #define TA_POLYMODE2_V_SIZE_16 (1<<0) ; #define TA_POLYMODE2_V_SIZE_32 (2<<0) ; #define TA_POLYMODE2_V_SIZE_64 (3<<0) ; #define TA_POLYMODE2_V_SIZE_128 (4<<0) ; #define TA_POLYMODE2_V_SIZE_256 (5<<0) ; #define TA_POLYMODE2_V_SIZE_512 (6<<0) ; #define TA_POLYMODE2_V_SIZE_1024 (7<<0) ; ; #define TA_TEXTUREMODE_MIPMAP 0x80000000 ; #define TA_TEXTUREMODE_VQ_COMPRESSION 0x40000000 ; #define TA_TEXTUREMODE_ARGB1555 (0<<27) ; #define TA_TEXTUREMODE_RGB565 (1<<27) ; #define TA_TEXTUREMODE_ARGB4444 (2<<27) ; #define TA_TEXTUREMODE_YUV422 (3<<27) ; #define TA_TEXTUREMODE_BUMPMAP (4<<27) ; #define TA_TEXTUREMODE_CLUT4 (5<<27) ; #define TA_TEXTUREMODE_CLUT8 (6<<27) ; #define TA_TEXTUREMODE_CLUTBANK8(n) ((n)<<25) /* 0-3 */ ; #define TA_TEXTUREMODE_CLUTBANK4(n) ((n)<<21) /* 0-63 */ ; #define TA_TEXTUREMODE_TWIDDLED 0x00000000 ; #define TA_TEXTUREMODE_NON_TWIDDLED 0x04000000 ; #define TA_TEXTUREMODE_ADDRESS(a) ((((unsigned long)(void*)(a))&0x7fffff)>>3) ; ; /* Command: Vertex */ ; ; struct packed_colour_vertex_list { ; unsigned int cmd; ; float x, y, z, u, v; ; unsigned int colour, ocolour; ; }; ; ; /* other vertex types are available... */ ; ; ; #define TA_CMD_VERTEX 0xe0000000 ; #define TA_CMD_VERTEX_EOS 0x10000000 /* end of strip */ ; ; ; ; extern unsigned int ta_set_target(void *cmdlist, void *tilebuf, int w, int h); ; extern void *ta_create_tile_descriptors(void *ptr, void *buf, int w, int h); ; extern void ta_wait_render(); ; extern void ta_begin_render(void *cmdlist, void *tiles, ; void *scrn, int modulo, int pixfmt, ; int clipw, int cliph); ; extern void ta_commit_list(void *list); ; extern void ta_commit_list2(void *list); ; extern void ta_commit_end(); ; ; video.c ; #include "video.h" ; ; ; /* Initialize the PVR subsystem to a known state */ ; ; /* These values mainly from Dans 3dtest program... */ ; ; static unsigned int three_d_params[] = { ; 0x80a8, 0x15d1c951, /* M (Unknown magic value) */ ; 0x80a0, 0x00000020, /* M */ ; 0x8008, 0x00000000, /* TA out of reset */ ; 0x8048, 0x00000009, /* alpha config */ ; 0x8068, 0x02800000, /* pixel clipping x */ ; 0x806c, 0x01e00000, /* pixel clipping y */ ; 0x8110, 0x00093f39, /* M */ ; 0x8098, 0x00800408, /* M */ ; 0x804c, 0x000000a0, /* display align (640*2)/8 */ ; 0x8078, 0x3f800000, /* polygon culling (1.0f) */ ; 0x8084, 0x00000000, /* M */ ; 0x8030, 0x00000101, /* M */ ; 0x80b0, 0x007f7f7f, /* Fog table color */ ; 0x80b4, 0x007f7f7f, /* Fog vertex color */ ; 0x80c0, 0x00000000, /* color clamp min */ ; 0x80bc, 0xffffffff, /* color clamp max */ ; 0x8080, 0x00000007, /* M */ ; 0x8074, 0x00000001, /* cheap shadow */ ; 0x807c, 0x0027df77, /* M */ ; 0x8008, 0x00000001, /* TA reset */ ; 0x8008, 0x00000000, /* TA out of reset */ ; 0x80e4, 0x00000000, /* stride width */ ; 0x6884, 0x00000000, /* Disable all interrupt events */ ; 0x6930, 0x00000000, ; 0x6938, 0x00000000, ; 0x6900, 0xffffffff, /* Clear all pending int events */ ; 0x6908, 0xffffffff, ; 0x6930, 0x002807ec, /* Re-enable some events */ ; 0x6938, 0x0000000e, ; 0x80b8, 0x0000ff07, /* fog density */ ; 0x80b4, 0x007f7f7f, /* fog vertex color */ ; 0x80b0, 0x007f7f7f, /* fog table color */ ; 0x8108, 0x00000003 /* 32bit palette */ ; }; ; ; static unsigned int scrn_params[] = { ; 0x80e8, 0x00160000, /* screen control */ ; 0x8044, 0x00800000, /* pixel mode (vb+0x11) */ ; 0x805c, 0x00000000, /* Size modulo and display lines (vb+0x17) */ ; 0x80d0, 0x00000100, /* interlace flags */ ; 0x80d8, 0x020c0359, /* M */ ; 0x80cc, 0x001501fe, /* M */ ; 0x80d4, 0x007e0345, /* horizontal border */ ; 0x80dc, 0x00240204, /* vertical position */ ; 0x80e0, 0x07d6c63f, /* sync control */ ; 0x80ec, 0x000000a4, /* horizontal position */ ; 0x80f0, 0x00120012, /* vertical border */ ; 0x80c8, 0x03450000, /* set to same as border H in 80d4 */ ; 0x8068, 0x027f0000, /* (X resolution - 1) << 16 */ ; 0x806c, 0x01df0000, /* (Y resolution - 1) << 16 */ ; 0x804c, 0x000000a0, /* display align */ ; 0x8118, 0x00008040, /* M */ ; 0x80f4, 0x00000401, /* anti-aliasing */ ; 0x8048, 0x00000009, /* alpha config */ ; 0x7814, 0x00000000, /* More interrupt control stuff (so it seems)*/ ; 0x7834, 0x00000000, ; 0x7854, 0x00000000, ; 0x7874, 0x00000000, ; 0x78bc, 0x4659404f, ; 0x8040, 0x00000000 /* border color */ ; }; ; ; static void set_regs(unsigned int *values, int cnt) ; { ; volatile unsigned char *regs = (volatile unsigned char *)(void *)0xa05f0000; ; unsigned int r, v; ; ; while(cnt--) { ; r = *values++; ; v = *values++; ; *(volatile unsigned int *)(regs+r) = v; ; } ; } ; ; void init_pvr() ; { ; volatile unsigned int *vbl = (volatile unsigned int *)(void *)0xa05f810c; ; ; set_regs(three_d_params, sizeof(three_d_params)/sizeof(three_d_params[0])/2); ; while (!(*vbl & 0x01ff)); ; while (*vbl & 0x01ff); ; set_regs(scrn_params, sizeof(scrn_params)/sizeof(scrn_params[0])/2); ; } ; ; ; /* Set up video registers to the desired ; video mode ; ; cabletype (0=VGA, 2=RGB, 3=Composite) ; pixel mode (0=RGB555, 1=RGB565, 3=RGB888) ; res (0 = 320 x 240, 1 = 640 x 240, 2 = 640 x 480) */ ; ; void init_video(int cabletype, int mode, int res) ; { ; volatile unsigned int *videobase=(volatile unsigned int *)(void*)0xa05f8000; ; static int bppshifttab[]= { 1,1,0,2 }; ; int shift, lines, modulo, words_per_line, vpos; ; int laceoffset=0, voffset=0; ; unsigned int videoflags, attribs; ; unsigned int hvcounter = (res<2? 0x01060359 : 0x020c0359); ; ; mode &= 3; ; shift = bppshifttab[mode]; ; ; videobase[8/4]=0; ; videobase[0x40/4]=0; ; ; /* Select pixel clock and colour mode */ ; mode = (mode<<2)|1; ; lines = 240; ; if(!(cabletype&2)) { ; ; /* VGA mode */ ; ; if(res < 2) ; mode |= 2; /* doublescan */ ; ; hvcounter = 0x020c0359; ; ; lines <<= 1; ; mode |= 0x800000; /* fast pixel clock */ ; } ; videobase[0x44/4]=mode; ; ; /* Set video base address. Short fields will be offset by ; 640 pixels, regardless of horizontal resolution. */ ; videobase[0x50/4]=0; ; videobase[0x54/4]=640< skip 320 pixels to keep modulo at 640 pixels */ ; modulo += words_per_line; ; } else { ; if(res!=1) ; /* NTSC lores -> skip 320 pixels to keep modulo at 640 pixels */ ; /* _or_ NTSC hires -> skip every other line due to interlace */ ; modulo += words_per_line; ; ; if(res==2) ; /* interlace mode */ ; videoflags |= 1<<4; ; ; /* enable NTSC */ ; videoflags |= 1<<6; ; } ; ; /* Write screen size and modulo */ ; videobase[0x5c/4]=(((modulo<<10)+lines-1)<<10)+words_per_line-1; ; ; /* Enable video (lace, NTSC) */ ; videobase[0xd0/4]=videoflags; ; ; /* Screen and border position */ ; ; if(!(cabletype&2)) ; /* VGA */ ; voffset += 36; ; else ; voffset += 18; ; ; vpos=(voffset<<16)|(voffset+laceoffset); ; ; videobase[0xf0/4]=vpos; /* V start */ ; videobase[0xdc/4]=vpos+lines; /* start and end border */ ; videobase[0xec/4]=0xa4; /* Horizontal pos */ ; videobase[0xd8/4]=hvcounter; /* HV counter */ ; videobase[0xd4/4]=0x007e0345; /* Horizontal border */ ; ; /* Select horizontal pixel doubling for lowres */ ; if(res==0) ; attribs=((22<<8)+1)<<8; ; else ; attribs=22<<16; ; videobase[0xe8/4]=attribs; ; ; /* Set up vertical blank event */ ; vpos = 260; ; if(!(cabletype&2)) ; vpos = 510; ; videobase[0xcc/4]=(0x21<<16)|vpos; ; ; /* Select RGB/CVBS */ ; if(cabletype&1) ; mode = 3; ; else ; mode = 0; ; *(volatile unsigned int *)(void*)0xa0702c00 = mode << 8; ; ; return; ; } ; ; ; /* Check type of video cable connected */ ; ; int check_cable() ; { ; volatile unsigned int *porta = (unsigned int *)0xff80002c; ; ; /* PORT8 and PORT9 is input */ ; *porta = (*porta & ~0xf0000) | 0xa0000; ; ; /* Return PORT8 and PORT9 */ ; return ((*(volatile unsigned short *)(porta+1))>>8)&3; ; } ; ; video.h ; extern void init_pvr(); ; extern void init_video(int cabletype, int mode, int res); ; extern int check_cable(); .list pop