; This is just tatest.s with some additional rotations so the cube ; tumbles less predictably. ; Debugging flags. Set these to 1 to turn on various debugging output. ; set_params debug_set_params = 0 ; rendering cycle kickoff debug_start_render = 0 ; texture setup debug_texture = 0 ; TA command commits debug_ta_commit = 0 ; This is designed to be serial-line downloaded to cdcode. ; ; This matters mostly in the interfaces it means we expect. In ; particular, we are not called with a bsr/jsr; we are entered with a ; jmp, and our return-to address, to the extent that we have one, is ; in r11, not pr. We also expect registers set up the way cdcode sets ; them; in particular, we expect r15 to be set to point to a stack, ; 8c010000 (or a little below that if cdcode happens to have anything ; on the stack), and r14 set to the SCIF's base address. If we return ; to cdcode, it expects those two, and r11 and r10, to be preserved. ; It doesn't mind if we trash r12/r13, but we preserve them too. ; ; Our memory map: ; ; [8c000000,8c010000) Stack (r15 set by cdcode) ; [8c010000,8c01????) cdcode ; [8c020000,8c0?????) Us ; ; Our entry point is 8c020000. We don't set an entry point here with ; .entry because then send-s would jump to us directly, and I'd rather ; do that manually. ; 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 ; mostly 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 SHORT_FRAME_OFFSET = X_SIZE*2 ; X_SIZE pixels * 2 bytes/pixel COT_FOVY = 0f1.73 ZNEAR = 0f1 ZFAR = 0f100 . = 0x8c020000 .sz any .pr any 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. rotations: .space 6*4 ; Scene corner coordinates. .align 4 vertex_coords: .long -0f1, -0f1, -0f1 ; 0 = (-1,-1,-1) .long -0f1, -0f1, 0f1 ; 1 = (-1,-1,+1) .long -0f1, 0f1, 0f1 ; 2 = (-1,+1,+1) .long -0f1, 0f1, -0f1 ; 3 = (-1,+1,-1) .long 0f1, 0f1, -0f1 ; 4 = (+1,+1,-1) .long 0f1, 0f1, 0f1 ; 5 = (+1,+1,+1) .long 0f1, -0f1, 0f1 ; 6 = (+1,-1,+1) .long 0f1, -0f1, -0f1 ; 7 = (+1,-1,-1) n_vertex_coords = [. - vertex_coords] / [3*4] xform_coords: .space n_vertex_coords*3*4 ; Coordinate numbers of the various faces' corners, with ; palette numbers and texture numbers. .macro face v1,v2,v3,v4,pal,tex .byte $(v2),$(v1),$(v3),$(v4), $(pal), $(tex) .endm scene_faces: face 0, 1, 2, 3, 0, 0 face 0, 7, 6, 1, 1, 0 face 0, 3, 4, 7, 2, 0 face 5, 6, 7, 4, 0, 1 face 5, 4, 3, 2, 1, 1 face 5, 2, 1, 6, 2, 1 n_scene_faces = [. - scene_faces] / 6 ; 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, 0f1.0 ; polygon culling 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 .sz 0 .pr 0 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 1: bsr one_frame nop 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: .if debug_set_params sts.l pr,@-r15 .endif ; 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 .if debug_set_params mov.l r0,@-r15 mov.l r1,@-r15 sts.l pr,@-r15 bsr putchar mov #'*,r1 bsr printhex8 mov.l @(8,r15),r1 bsr putchar mov #'=,r1 bsr printhex8 mov r4,r1 bsr putchar mov #13,r1 bsr putchar mov #10,r1 lds.l @r15+,pr mov.l @r15+,r1 mov.l @r15+,r0 .endif bra 1b mov.l r4,@r0 1: .if debug_set_params lds.l @r15+,pr .endif 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 #0x000007ff,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 @IS_SB[PDTRA-PCTRA] 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 #0x5,r3 ; 5/6/5 2bpp, 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 #SHORT_FRAME_OFFSET,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/2],r4 ; longs of (16bpp) pixel data per scanline 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 add #0xd0-0x5c,r2 mov.l r3,@r2 ; 0xa05f80d0, video encapsulation SETS.L #0x007e0345,r8 ; doesn't make sense per doc add #0xd4-0xd0,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 SETS.L #0f1.313747,r3 lds r3,fpul fsts fpul,fr5 fsub fr5,fr1 SETS.L #0f0.073227,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 r4,@-r15 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 @(8,r15),r4 mov.l r0,@r4 mov.l @r15+,r2 bsr setup_tiledesc mov.l @r15+,r3 mov.l @r15+,r4 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>26]&7]<<2,r13 SETS.L #ta_cmd,r12 SETS.L #8,r11 .if debug_ta_commit mov.l r1,@-r15 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 add #-8*4,r12 mov.l @r15+,r1 .endif mov.l r13,@r1 mov r14,r10 1: mov.l @r12+,r0 dt r11 mov.l r0,@r14 bf/s 1b add #4,r14 .if debug_ta_commit pref @r10 bsr putchar2 mov #'),r1 lds.l @r15+,pr .endif rts .if debug_ta_commit nop .endif pref @r10 next_frame: .if debug_start_render sts.l pr,@-r15 .endif ; In tatest terms, this is everything in the main loop after ; the call to ta_commit_end(). ; ta_wait_render() 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 ; 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 #SHORT_FRAME_OFFSET,r0 add r0,r1 mov.l r1,@(4,r3) ; Kick off rendering to the screen we just stopped displaying ; In tatest terms, this is ta_begin_render. mov.b @r10,r0 ; curbuf SETS.L #cmdlists,r1 SHLL #2,r0 SETS.L #tiledesc_cookies,r2 mov.l @(r0,r1),r1 ; cmdlist mov.l @(r0,r2),r2 ; tiles xor #4,r0 mov.l @(r0,r11),r3 ; scrn 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 ; taend 1: mov.l r6,@r4 dt r5 bf/s 1b add #4,r4 add #-0x12*4,r4 ; 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 .if debug_start_render bsr 9f mov r2,r0 .endif mov.l r2,@r5 ; 0xa05f802c add #0x8020-0x802c,r5 mov r1,r0 and r12,r0 .if debug_start_render bsr 9f nop .endif mov.l r0,@r5 ; 0xa05f8020 add #0x8060-0x8020,r5 and r12,r3 .if debug_start_render bsr 9f mov r3,r0 .endif mov.l r3,@r5 ; 0xa05f8060 add #0x808c-0x8060,r5 sub r1,r4 SHLL #1,r4 SETS.L #0x01000000,r0 or r4,r0 .if debug_start_render bsr 9f nop .endif mov.l r0,@r5 ; 0xa05f808c add #0x8088-0x808c,r5 SETS.L #0x3e4cccc0,r0 ; tatest says "zclip" .if debug_start_render bsr 9f nop .endif mov.l r0,@r5 ; 0xa05f8088 add #0x8068-0x8088,r5 SETS.L #[X_SIZE-1]<<16,r0 ; tatest calls it "clipw" .if debug_start_render bsr 9f nop .endif mov.l r0,@r5 ; 0xa05f8068 add #0x806c-0x8068,r5 SETS.L #[Y_SIZE-1]<<16,r0 ; tatest calls it "cliph" .if debug_start_render bsr 9f nop .endif mov.l r0,@r5 ; 0xa05f806c add #0x804c-0x806c,r5 SETS.L #[X_SIZE*2]>>3,r0 ; tatest calls it "modulo" .if debug_start_render bsr 9f nop .endif mov.l r0,@r5 ; 0xa05f804c add #0x8048-0x804c,r5 SETS.L #TA_PIXFMT_RGB565|TA_PIXFMT_DITHER,r0 ; tatest calls it "pixfmt" .if debug_start_render bsr 9f nop .endif mov.l r0,@r5 ; 0xa05f8048 add #0x8014-0x8048,r5 SETS.L #0xffffffff,r0 ; tatest says "Launch!" .if debug_start_render bsr 9f nop .endif mov.l r0,@r5 ; 0xa05f8014 ; curbuf = ! curbuf mov.b @r10,r0 tst r0,r0 bt/s 1f add #1,r0 mov #0,r0 1: .if debug_start_render lds.l @r15+,pr .endif rts mov.b r0,@r10 .if debug_start_render 9: ; about to mov.l r0,@r5; print it ; must preserve all input registers except pr mov.l r0,@-r15 mov.l r1,@-r15 sts.l pr,@-r15 bsr printhex8 mov r5,r1 bsr putchar mov #'=,r1 bsr printhex8 mov.l @(8,r15),r1 bsr putchar mov #13,r1 bsr putchar mov #10,r1 lds.l @r15+,pr mov.l @r15+,r1 rts mov.l @r15+,r0 .endif 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