nkeynes@185: /** nkeynes@561: * $Id$ nkeynes@185: * nkeynes@185: * PVR support code nkeynes@185: * nkeynes@185: * Copyright (c) 2006 Nathan Keynes. nkeynes@185: * nkeynes@185: * This program is free software; you can redistribute it and/or modify nkeynes@185: * it under the terms of the GNU General Public License as published by nkeynes@185: * the Free Software Foundation; either version 2 of the License, or nkeynes@185: * (at your option) any later version. nkeynes@185: * nkeynes@185: * This program is distributed in the hope that it will be useful, nkeynes@185: * but WITHOUT ANY WARRANTY; without even the implied warranty of nkeynes@185: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the nkeynes@185: * GNU General Public License for more details. nkeynes@185: */ nkeynes@185: nkeynes@185: #include "lib.h" nkeynes@185: #include "pvr.h" nkeynes@185: nkeynes@185: #define PVR_BASE 0xA05F8000 nkeynes@185: #define PVR_RESET (PVR_BASE+0x008) nkeynes@185: #define TA_INIT (PVR_BASE+0x144) nkeynes@185: #define TA_TILESTART (PVR_BASE+0x124) nkeynes@185: #define TA_OBJSTART (PVR_BASE+0x128) nkeynes@185: #define TA_TILEEND (PVR_BASE+0x12C) nkeynes@185: #define TA_OBJEND (PVR_BASE+0x130) nkeynes@185: #define TA_TILEPOSN (PVR_BASE+0x134) nkeynes@185: #define TA_OBJPOSN (PVR_BASE+0x138) nkeynes@185: #define TA_SIZE (PVR_BASE+0x13C) nkeynes@185: #define TA_TILECFG (PVR_BASE+0x140) nkeynes@213: #define TA_REINIT (PVR_BASE+0x160) nkeynes@185: #define TA_PLISTSTART (PVR_BASE+0x164) nkeynes@185: nkeynes@213: #define RENDER_START (PVR_BASE+0x014) nkeynes@213: #define RENDER_POLYBASE (PVR_BASE+0x020) nkeynes@213: #define RENDER_TILEBASE (PVR_BASE+0x02C) nkeynes@213: #define RENDER_MODE (PVR_BASE+0x048) nkeynes@213: #define RENDER_SIZE (PVR_BASE+0x04C) nkeynes@213: #define RENDER_ADDR1 (PVR_BASE+0x060) nkeynes@213: #define RENDER_ADDR2 (PVR_BASE+0x064) nkeynes@213: #define RENDER_HCLIP (PVR_BASE+0x068) nkeynes@213: #define RENDER_VCLIP (PVR_BASE+0x06C) nkeynes@213: #define RENDER_NEARCLIP (PVR_BASE+0x078) nkeynes@213: #define RENDER_FARCLIP (PVR_BASE+0x088) nkeynes@213: #define RENDER_BGPLANE (PVR_BASE+0x08C) nkeynes@213: nkeynes@213: #define DISPLAY_MODE (PVR_BASE+0x044) nkeynes@213: #define DISPLAY_ADDR1 (PVR_BASE+0x050) nkeynes@213: #define DISPLAY_ADDR2 (PVR_BASE+0x054) nkeynes@213: #define DISPLAY_SIZE (PVR_BASE+0x05C nkeynes@185: nkeynes@185: void ta_dump_regs( FILE *f ) nkeynes@185: { nkeynes@185: fprintf( stderr, "TA Object start[128]: %08X posn[138]: %08X end[130]: %08X\n", nkeynes@185: long_read(TA_OBJSTART), long_read(TA_OBJPOSN), long_read(TA_OBJEND) ); nkeynes@185: fprintf( stderr, "TA OPB start[124]: %08X posn[134]: %08X end[12c]: %08X init: %08X\n", nkeynes@185: long_read(TA_TILESTART), long_read(TA_TILEPOSN), long_read(TA_TILEEND), nkeynes@185: long_read(TA_PLISTSTART) ); nkeynes@185: fprintf( stderr, "TA Tilesize: %08X config: %08X\n", long_read(TA_SIZE), long_read(TA_TILECFG) ); nkeynes@185: } nkeynes@185: nkeynes@190: nkeynes@190: void ta_init( struct ta_config *config ) nkeynes@190: { nkeynes@190: long_write( PVR_RESET, 1 ); nkeynes@190: long_write( PVR_RESET, 0 ); nkeynes@190: nkeynes@190: long_write( TA_SIZE, config->grid_size ); nkeynes@190: long_write( TA_OBJSTART, config->obj_start & 0x00FFFFFF ); nkeynes@190: long_write( TA_OBJEND, config->obj_end & 0x00FFFFFF ); nkeynes@190: long_write( TA_TILESTART, config->tile_start & 0x00FFFFFF ); nkeynes@190: long_write( TA_TILEEND, config->tile_end & 0x00FFFFFF ); nkeynes@190: long_write( TA_PLISTSTART, config->plist_start & 0x00FFFFFF ); nkeynes@190: long_write( TA_TILECFG, config->ta_cfg ); nkeynes@190: long_write( TA_INIT, 0x80000000 ); nkeynes@190: } nkeynes@190: nkeynes@213: void ta_reinit( ) nkeynes@213: { nkeynes@213: long_write( TA_REINIT, 0x80000000 ); nkeynes@213: } nkeynes@213: nkeynes@185: int pvr_get_objbuf_size( ) nkeynes@185: { nkeynes@185: return long_read( TA_OBJPOSN ) - long_read( TA_OBJSTART ); nkeynes@185: } nkeynes@185: nkeynes@213: int pvr_get_objbuf_posn( ) nkeynes@213: { nkeynes@213: return long_read( TA_OBJPOSN ); nkeynes@213: } nkeynes@213: nkeynes@190: int pvr_get_plist_posn( ) nkeynes@190: { nkeynes@190: unsigned int addr = long_read( TA_TILEPOSN ) << 2; nkeynes@190: return addr; nkeynes@190: } nkeynes@190: nkeynes@185: void pvr_dump_objbuf( FILE *f ) nkeynes@185: { nkeynes@185: unsigned int start = long_read( TA_OBJSTART ); nkeynes@185: unsigned int posn = long_read( TA_OBJPOSN ); nkeynes@185: unsigned int end = long_read( TA_OBJEND ); nkeynes@185: char *buf; nkeynes@185: unsigned int length; nkeynes@185: if( start < posn ) { nkeynes@185: buf = (char *)(0xA5000000+start); nkeynes@185: length = posn-start; nkeynes@185: } else { nkeynes@185: buf = (char *)(0xA5000000+end); nkeynes@185: length = start-posn; nkeynes@185: } nkeynes@185: nkeynes@185: fprintf( f, "Obj buffer: %08X - %08X - %08X\n", start, posn, end ); nkeynes@185: fwrite_dump( f, buf, length ); nkeynes@185: } nkeynes@185: nkeynes@185: void pvr_dump_tilebuf( FILE *f ) nkeynes@185: { nkeynes@185: unsigned int start = long_read( TA_TILESTART ); nkeynes@185: unsigned int posn = long_read( TA_TILEPOSN ); nkeynes@185: unsigned int end = long_read( TA_TILEEND ); nkeynes@185: char *buf; nkeynes@185: unsigned int length; nkeynes@185: if( start < posn ) { nkeynes@185: buf = (char *)(0xA5000000+start); nkeynes@185: length = posn-start; nkeynes@185: } else { nkeynes@185: buf = (char *)(0xA5000000+end); nkeynes@185: length = start-posn; nkeynes@185: } nkeynes@185: nkeynes@185: fprintf( f, "Tile buffer: %08X - %08X - %08X\n", start, posn, end ); nkeynes@185: fwrite_dump( f, buf, length ); nkeynes@185: } nkeynes@185: nkeynes@213: static int ta_tile_sizes[4] = { 0, 32, 64, 128 }; nkeynes@213: #define TILE_SIZE(cfg, tile) ta_tile_sizes[((((cfg->ta_cfg) >> (4*tile))&0x03))] nkeynes@213: #define TILE_ENABLED(cfg, tile) ((((cfg->ta_cfg) >> (4*tile))&0x03) != 0) nkeynes@213: void pvr_compute_tilematrix_addr( int *tile_ptrs, struct ta_config *config ) { nkeynes@213: int tile_sizes[5], i; nkeynes@213: int hsegs = (config->grid_size & 0xFFFF)+1; nkeynes@213: int vsegs = (config->grid_size >> 16) + 1; nkeynes@213: for( i=0; i<5; i++ ) { nkeynes@213: tile_sizes[i] = TILE_SIZE(config,i); nkeynes@213: } nkeynes@213: tile_ptrs[0] = config->tile_start; nkeynes@213: tile_ptrs[1] = tile_ptrs[0] + (hsegs*vsegs*tile_sizes[0]); nkeynes@213: tile_ptrs[2] = tile_ptrs[1] + (hsegs*vsegs*tile_sizes[1]); nkeynes@213: tile_ptrs[3] = tile_ptrs[2] + (hsegs*vsegs*tile_sizes[2]); nkeynes@213: tile_ptrs[4] = tile_ptrs[3] + (hsegs*vsegs*tile_sizes[3]); nkeynes@213: } nkeynes@213: nkeynes@213: static uint32_t *pvr_compute_tile_ptrs( uint32_t *target, struct ta_config *config, int x, int y ) nkeynes@213: { nkeynes@213: int i; nkeynes@213: int cfg = config->ta_cfg; nkeynes@213: int hsegs = (config->grid_size & 0xFFFF)+1; nkeynes@213: int vsegs = (config->grid_size >> 16) + 1; nkeynes@213: int tilematrix = config->tile_start; nkeynes@213: for( i=0; i<5; i++ ) { nkeynes@213: if( cfg & 0x03 ) { nkeynes@213: int tile_size = ta_tile_sizes[cfg&0x03]; nkeynes@213: *target++ = tilematrix + (((y*hsegs)+x)*tile_size); nkeynes@213: tilematrix += hsegs*vsegs*tile_size; nkeynes@213: } else { nkeynes@213: *target++ = 0x80000000; nkeynes@213: } nkeynes@213: cfg = cfg >> 4; nkeynes@213: } nkeynes@213: return target; nkeynes@213: } nkeynes@213: nkeynes@213: void pvr_build_tilemap1( uint32_t addr, struct ta_config *config, uint32_t control_word ) nkeynes@213: { nkeynes@213: uint32_t *dest = (uint32_t *)(PVR_VRAM_BASE+addr); nkeynes@213: int w = (config->grid_size & 0x0000FFFF) + 1; nkeynes@213: int h = (config->grid_size >> 16) + 1; nkeynes@213: nkeynes@213: int x,y; nkeynes@213: memset( (char *)(dest-18), 0, 18*4 ); nkeynes@213: *dest++ = 0x10000000; nkeynes@213: *dest++ = 0x80000000; nkeynes@213: *dest++ = 0x80000000; nkeynes@213: *dest++ = 0x80000000; nkeynes@213: *dest++ = 0x80000000; nkeynes@213: *dest++ = 0x80000000; nkeynes@213: for( x=0; xgrid_size & 0x0000FFFF) + 1; nkeynes@213: int h = (config->grid_size >> 16) + 1; nkeynes@213: nkeynes@213: int x,y; nkeynes@213: *dest++ = 0x10000000; nkeynes@213: *dest++ = 0x80000000; nkeynes@213: *dest++ = 0x80000000; nkeynes@213: *dest++ = 0x80000000; nkeynes@213: *dest++ = 0x80000000; nkeynes@213: *dest++ = 0x80000000; nkeynes@213: for( x=0; xwidth; nkeynes@213: switch( config->mode & 0x07 ) { nkeynes@213: case 4: nkeynes@213: modulo *= 3; /* ??? */ nkeynes@213: break; nkeynes@213: case 5: nkeynes@213: case 6: nkeynes@213: modulo *= 4; nkeynes@213: break; nkeynes@213: default: nkeynes@213: modulo *= 2; nkeynes@213: } nkeynes@213: return modulo; nkeynes@213: } nkeynes@213: nkeynes@213: void render_start( struct render_config *config ) nkeynes@213: { nkeynes@213: int modulo = get_line_size( config ); nkeynes@213: long_write( RENDER_POLYBASE, config->polybuf ); nkeynes@213: long_write( RENDER_TILEBASE, config->tilemap ); nkeynes@213: long_write( RENDER_ADDR1, config->render_addr ); nkeynes@213: long_write( RENDER_SIZE, modulo >> 3 ); nkeynes@213: long_write( RENDER_ADDR2, config->render_addr + modulo ); /* Not used? */ nkeynes@213: long_write( RENDER_HCLIP, (config->width - 1) << 16 ); nkeynes@213: long_write( RENDER_VCLIP, (config->height - 1) << 16 ); nkeynes@213: long_write( RENDER_MODE, config->mode ); nkeynes@213: float_write( RENDER_FARCLIP, config->farclip ); nkeynes@213: float_write( RENDER_NEARCLIP, config->nearclip ); nkeynes@213: long_write( RENDER_START, 0xFFFFFFFF ); nkeynes@213: } nkeynes@213: nkeynes@213: void display_render( struct render_config *config ) nkeynes@213: { nkeynes@213: long_write( DISPLAY_ADDR1, config->render_addr ); nkeynes@213: long_write( DISPLAY_ADDR2, config->render_addr + get_line_size(config) ); nkeynes@213: } nkeynes@213: nkeynes@185: /************** Stolen from TATEST *************/ nkeynes@185: nkeynes@185: static unsigned int three_d_params[] = { nkeynes@185: 0x80a8, 0x15d1c951, /* M (Unknown magic value) */ nkeynes@185: 0x80a0, 0x00000020, /* M */ nkeynes@185: 0x8008, 0x00000000, /* TA out of reset */ nkeynes@185: 0x8048, 0x00000009, /* alpha config */ nkeynes@185: 0x8068, 0x02800000, /* pixel clipping x */ nkeynes@185: 0x806c, 0x01e00000, /* pixel clipping y */ nkeynes@185: 0x8110, 0x00093f39, /* M */ nkeynes@185: 0x8098, 0x00800408, /* M */ nkeynes@185: 0x804c, 0x000000a0, /* display align (640*2)/8 */ nkeynes@185: 0x8078, 0x3f800000, /* polygon culling (1.0f) */ nkeynes@185: 0x8084, 0x00000000, /* M */ nkeynes@185: 0x8030, 0x00000101, /* M */ nkeynes@185: 0x80b0, 0x007f7f7f, /* Fog table color */ nkeynes@185: 0x80b4, 0x007f7f7f, /* Fog vertex color */ nkeynes@185: 0x80c0, 0x00000000, /* color clamp min */ nkeynes@185: 0x80bc, 0xffffffff, /* color clamp max */ nkeynes@185: 0x8080, 0x00000007, /* M */ nkeynes@185: 0x8074, 0x00000001, /* cheap shadow */ nkeynes@185: 0x807c, 0x0027df77, /* M */ nkeynes@185: 0x8008, 0x00000001, /* TA reset */ nkeynes@185: 0x8008, 0x00000000, /* TA out of reset */ nkeynes@185: 0x80e4, 0x00000000, /* stride width */ nkeynes@185: 0x6884, 0x00000000, /* Disable all interrupt events */ nkeynes@185: 0x6930, 0x00000000, nkeynes@185: 0x6938, 0x00000000, nkeynes@185: 0x6900, 0xffffffff, /* Clear all pending int events */ nkeynes@185: 0x6908, 0xffffffff, nkeynes@185: 0x6930, 0x002807ec, /* Re-enable some events */ nkeynes@185: 0x6938, 0x0000000e, nkeynes@185: 0x80b8, 0x0000ff07, /* fog density */ nkeynes@185: 0x80b4, 0x007f7f7f, /* fog vertex color */ nkeynes@185: 0x80b0, 0x007f7f7f, /* fog table color */ nkeynes@185: 0x8108, 0x00000003 /* 32bit palette */ nkeynes@185: }; nkeynes@185: nkeynes@185: static unsigned int scrn_params[] = { nkeynes@185: 0x80e8, 0x00160000, /* screen control */ nkeynes@185: 0x8044, 0x00800000, /* pixel mode (vb+0x11) */ nkeynes@185: 0x805c, 0x00000000, /* Size modulo and display lines (vb+0x17) */ nkeynes@185: 0x80d0, 0x00000100, /* interlace flags */ nkeynes@185: 0x80d8, 0x020c0359, /* M */ nkeynes@185: 0x80cc, 0x001501fe, /* M */ nkeynes@185: 0x80d4, 0x007e0345, /* horizontal border */ nkeynes@185: 0x80dc, 0x00240204, /* vertical position */ nkeynes@185: 0x80e0, 0x07d6c63f, /* sync control */ nkeynes@185: 0x80ec, 0x000000a4, /* horizontal position */ nkeynes@185: 0x80f0, 0x00120012, /* vertical border */ nkeynes@185: 0x80c8, 0x03450000, /* set to same as border H in 80d4 */ nkeynes@185: 0x8068, 0x027f0000, /* (X resolution - 1) << 16 */ nkeynes@185: 0x806c, 0x01df0000, /* (Y resolution - 1) << 16 */ nkeynes@185: 0x804c, 0x000000a0, /* display align */ nkeynes@185: 0x8118, 0x00008040, /* M */ nkeynes@185: 0x80f4, 0x00000401, /* anti-aliasing */ nkeynes@185: 0x8048, 0x00000009, /* alpha config */ nkeynes@185: 0x7814, 0x00000000, /* More interrupt control stuff (so it seems)*/ nkeynes@185: 0x7834, 0x00000000, nkeynes@185: 0x7854, 0x00000000, nkeynes@185: 0x7874, 0x00000000, nkeynes@185: 0x78bc, 0x4659404f, nkeynes@185: 0x8040, 0x00000000 /* border color */ nkeynes@185: }; nkeynes@185: nkeynes@185: static void set_regs(unsigned int *values, int cnt) nkeynes@185: { nkeynes@185: volatile unsigned char *regs = (volatile unsigned char *)(void *)0xa05f0000; nkeynes@185: unsigned int r, v; nkeynes@185: nkeynes@185: while(cnt--) { nkeynes@185: r = *values++; nkeynes@185: v = *values++; nkeynes@185: *(volatile unsigned int *)(regs+r) = v; nkeynes@185: } nkeynes@185: } nkeynes@185: nkeynes@185: int pvr_check_cable() nkeynes@185: { nkeynes@185: volatile unsigned int *porta = (unsigned int *)0xff80002c; nkeynes@185: nkeynes@185: /* PORT8 and PORT9 is input */ nkeynes@185: *porta = (*porta & ~0xf0000) | 0xa0000; nkeynes@185: nkeynes@185: /* Return PORT8 and PORT9 */ nkeynes@185: return ((*(volatile unsigned short *)(porta+1))>>8)&3; nkeynes@185: } nkeynes@185: void pvr_init_video(int cabletype, int mode, int res) nkeynes@185: { nkeynes@185: volatile unsigned int *videobase=(volatile unsigned int *)(void*)0xa05f8000; nkeynes@185: static int bppshifttab[]= { 1,1,0,2 }; nkeynes@185: int shift, lines, modulo, words_per_line, vpos; nkeynes@185: int laceoffset=0, voffset=0; nkeynes@185: unsigned int videoflags, attribs; nkeynes@185: unsigned int hvcounter = (res<2? 0x01060359 : 0x020c0359); nkeynes@185: nkeynes@185: mode &= 3; nkeynes@185: shift = bppshifttab[mode]; nkeynes@185: nkeynes@185: videobase[8/4]=0; nkeynes@185: videobase[0x40/4]=0; nkeynes@185: nkeynes@185: /* Select pixel clock and colour mode */ nkeynes@185: mode = (mode<<2)|1; nkeynes@185: lines = 240; nkeynes@185: if(!(cabletype&2)) { nkeynes@185: nkeynes@185: /* VGA mode */ nkeynes@185: nkeynes@185: if(res < 2) nkeynes@185: mode |= 2; /* doublescan */ nkeynes@185: nkeynes@185: hvcounter = 0x020c0359; nkeynes@185: nkeynes@185: lines <<= 1; nkeynes@185: mode |= 0x800000; /* fast pixel clock */ nkeynes@185: } nkeynes@185: videobase[0x44/4]=mode; nkeynes@185: nkeynes@185: /* Set video base address. Short fields will be offset by nkeynes@185: 640 pixels, regardless of horizontal resolution. */ nkeynes@185: videobase[0x50/4]=0; nkeynes@185: videobase[0x54/4]=640< skip 320 pixels to keep modulo at 640 pixels */ nkeynes@185: modulo += words_per_line; nkeynes@185: } else { nkeynes@185: if(res!=1) nkeynes@185: /* NTSC lores -> skip 320 pixels to keep modulo at 640 pixels */ nkeynes@185: /* _or_ NTSC hires -> skip every other line due to interlace */ nkeynes@185: modulo += words_per_line; nkeynes@185: nkeynes@185: if(res==2) nkeynes@185: /* interlace mode */ nkeynes@185: videoflags |= 1<<4; nkeynes@185: nkeynes@185: /* enable NTSC */ nkeynes@185: videoflags |= 1<<6; nkeynes@185: } nkeynes@185: nkeynes@185: /* Write screen size and modulo */ nkeynes@185: videobase[0x5c/4]=(((modulo<<10)+lines-1)<<10)+words_per_line-1; nkeynes@185: nkeynes@185: /* Enable video (lace, NTSC) */ nkeynes@185: videobase[0xd0/4]=videoflags; nkeynes@185: nkeynes@185: /* Screen and border position */ nkeynes@185: nkeynes@185: if(!(cabletype&2)) nkeynes@185: /* VGA */ nkeynes@185: voffset += 36; nkeynes@185: else nkeynes@185: voffset += 18; nkeynes@185: nkeynes@185: vpos=(voffset<<16)|(voffset+laceoffset); nkeynes@185: nkeynes@185: videobase[0xf0/4]=vpos; /* V start */ nkeynes@185: videobase[0xdc/4]=vpos+lines; /* start and end border */ nkeynes@185: videobase[0xec/4]=0xa4; /* Horizontal pos */ nkeynes@185: videobase[0xd8/4]=hvcounter; /* HV counter */ nkeynes@185: videobase[0xd4/4]=0x007e0345; /* Horizontal border */ nkeynes@185: nkeynes@185: /* Select horizontal pixel doubling for lowres */ nkeynes@185: if(res==0) nkeynes@185: attribs=((22<<8)+1)<<8; nkeynes@185: else nkeynes@185: attribs=22<<16; nkeynes@185: videobase[0xe8/4]=attribs; nkeynes@185: nkeynes@185: /* Set up vertical blank event */ nkeynes@185: vpos = 260; nkeynes@185: if(!(cabletype&2)) nkeynes@185: vpos = 510; nkeynes@185: videobase[0xcc/4]=(0x21<<16)|vpos; nkeynes@185: nkeynes@185: /* Select RGB/CVBS */ nkeynes@185: if(cabletype&1) nkeynes@185: mode = 3; nkeynes@185: else nkeynes@185: mode = 0; nkeynes@185: *(volatile unsigned int *)(void*)0xa0702c00 = mode << 8; nkeynes@185: nkeynes@185: return; nkeynes@185: } nkeynes@185: nkeynes@185: void pvr_init() nkeynes@185: { nkeynes@185: volatile unsigned int *vbl = (volatile unsigned int *)(void *)0xa05f810c; nkeynes@185: nkeynes@185: set_regs(three_d_params, sizeof(three_d_params)/sizeof(three_d_params[0])/2); nkeynes@185: while (!(*vbl & 0x01ff)); nkeynes@185: while (*vbl & 0x01ff); nkeynes@185: set_regs(scrn_params, sizeof(scrn_params)/sizeof(scrn_params[0])/2); nkeynes@185: pvr_init_video(pvr_check_cable(), 1, 2); nkeynes@185: } nkeynes@185: nkeynes@306: void draw_grid( unsigned short *addr, unsigned short colour ) nkeynes@306: { nkeynes@306: int x,y; nkeynes@306: unsigned int linesize = 640; nkeynes@306: for( x=0; x<640; x+=32 ) { nkeynes@306: for( y=0; y<480; y++ ) { nkeynes@306: addr[(linesize*y) + x] = colour; nkeynes@306: } nkeynes@306: } nkeynes@306: for( y=0; y<480; y+=32 ) { nkeynes@306: for( x=0; x<640; x++ ) { nkeynes@306: addr[(linesize*y) + x] = colour; nkeynes@306: } nkeynes@306: } nkeynes@320: } nkeynes@306: nkeynes@320: void draw_grid_24( unsigned char *addr, unsigned int colour ) nkeynes@320: { nkeynes@320: int x,y; nkeynes@320: char r = (colour >> 16) & 0xFF; nkeynes@320: char g = (colour >> 8) & 0xFF; nkeynes@320: char b = (colour & 0xFF); nkeynes@320: unsigned int linesize = 640*3; nkeynes@320: for( x=0; x<640; x+=32 ) { nkeynes@320: for( y=0; y<480; y++ ) { nkeynes@320: int a = (linesize*y)+x * 3; nkeynes@320: addr[a++] = r; nkeynes@320: addr[a++] = g; nkeynes@320: addr[a++] = b; nkeynes@320: } nkeynes@320: } nkeynes@320: for( y=0; y<480; y+=32 ) { nkeynes@320: for( x=0; x<640; x++ ) { nkeynes@320: int a = (linesize*y)+x * 3; nkeynes@320: addr[a++] = r; nkeynes@320: addr[a++] = g; nkeynes@320: addr[a++] = b; nkeynes@320: } nkeynes@320: } nkeynes@306: }