pryogene's Profile User Rating: -----

Reputation: 44 Craftsman
Group:
Contributors
Active Posts:
692 (0.32 per day)
Joined:
30-June 09
Profile Views:
14,787
Last Active:
User is offline May 11 2015 03:00 PM
Currently:
Offline

Previous Fields

Country:
GB
OS Preference:
Windows
Favorite Browser:
Chrome
Favorite Processor:
Intel
Favorite Gaming Platform:
PC
Your Car:
Who Cares
Dream Kudos:
250

Latest Visitors

Icon   pryogene I AM LEIF, HARBINGER OF PUNS

Posts I've Made

  1. In Topic: What is this byte pattern?

    Posted 31 Mar 2015

    View Postvividexstance, on 31 March 2015 - 10:25 AM, said:

    Could you post the smallest yet most complete program? For example, the header files and the file that contains the main() function.


    In working on putting that together for you, I figured out the problem.

    Rookie array sizing mistake, apparently. My array, scrndata, was 4x smaller than it should've been. Fixing that initialiser corrected my problem.

    Interestingly, though, when running the GBGraphicsX module on its own, the error never occurred. How curious.
  2. In Topic: What is this byte pattern?

    Posted 31 Mar 2015

    #include "GBGraphicsX.h"
    
    #include "GBMemory.h"
    
    GBGraphicsX::GBGraphicsX() {
    
    	Reset();
    
    }
    
    GBGraphicsX::GBGraphicsX(GBMemory* mmu) {
    
    	this->mmu = mmu;
    
    	Reset();
    
    }
    GBGraphicsX::~GBGraphicsX() { 
    
    	fprintf(stdout, "GPU Died");
    }
    
    void GBGraphicsX::Prepare(GBMemory* mmu) {
    
    	this->mmu = mmu;
    
    }
    
    void GBGraphicsX::Reset() {
    
    	int i = 0;
    
    	for (i = 0; i < VRAM_SIZE; i++) {
    
    		vram[i] = 5;
    		reg[i] = 5;
    
    	}
    
    	for (i = 0; i < 160; i++) {
    
    		oam[i] = 0;
    
    	}
    
    	for (i = 0; i < 4; i++) {
    
    		palette.bg[i] = 255;
    		palette.obj0[i] = 255;
    		palette.obj1[i] = 255;
    
    	}
    
    	for (i = 0; i < (144 * 160); i++) {
    
    		// assume black
    		scrndata[i] = 0;
    
    	}
    
    	for (int x = 0; x < 512; x++) {
    
    		for (int y = 0; y < 8; y++) {
    
    			for (int z = 0; z < 8; z++) {
    
    				tilemap[x][y][z] = 0;
    
    			}
    
    		}
    
    	}
    
    	curline = 0;
    
    	fprintf(stdout, "%x", &curline);
    
    	curscan = 0;
    	linemode = 2;
    	modeclocks = 0;
    	yscroll = 0;
    	xscroll = 0;
    	raster = 0;
    	ints = 0;
    
    	lcdon = 0;
    	bgon = 0;
    	objon = 0;
    	winon = 0;
    
    	objsize = 0;
    
    	for (i = 0; i < 160; i++) {
    
    		scanrow[i] = 0;
    
    	}
    
    	for (i = 0; i < 40; i++) {
    
    		objdata[i].y = -16;
    		objdata[i].x = -8;
    		objdata[i].tile = 0;
    		objdata[i].palette = 0;
    		objdata[i].yflip = 0;
    		objdata[i].xflip = 0;
    		objdata[i].prio = 0;
    		objdata[i].num = 0;
    
    		objdatasorted[i].y = -16;
    		objdatasorted[i].x = -8;
    		objdatasorted[i].tile = 0;
    		objdatasorted[i].palette = 0;
    		objdatasorted[i].yflip = 0;
    		objdatasorted[i].xflip = 0;
    		objdatasorted[i].prio = 0;
    		objdatasorted[i].num = 0;
    
    	}
    
    	bgtilebase = 0x0000;
    	bgmapbase = 0x1800;
    	wintilebase = 0x1800;
    
    }
    
    uint8_t GBGraphicsX::Read(uint16_t address) {
    
    	int gpu_address = address - 0xFF40;
    
    	switch (address & 0xF000) {
    
    	case 0x8000 : case 0x9000 : 
    		return vram[address - 0x8000];
    
    	default:
    
    		switch (gpu_address) {
    
    		case 0 : 
    			return (lcdon ? 0x80 : 0) |
    				(bgtilebase == 0x0000 ? 0x10 : 0) |
    				(bgmapbase == 0x1C00 ? 0x08 : 0) |
    				(objsize ? 0x04 : 0) |
    				(objon ? 0x02 : 0) |
    				(bgon ? 0x01 : 0);
    
    		case 1 : 
    			return ( curline == raster  ? 4 : 0 ) | linemode;
    
    		case 2 :
    			return yscroll;
    
    		case 3 :
    			return xscroll;
    
    		case 4 :
    			fprintf(stdout, "\nLCDC Y-COORD STATUS: %d\n", curline);
    			return curline;
    
    		case 5 :
    			return raster;
    
    		default:
    			return reg[gpu_address];
    
    		}
    	}
    
    }
    
    void GBGraphicsX::Write(uint16_t address, uint8_t data) {
    
    	int gpu_address = address - 0xFF40;
    	reg[gpu_address] = data;
    
    	switch (address & 0xF000) {
    
    	case 0x8000 : case 0x9000 : case 0xA000 :
    		vram[address - 0x8000] = data;
    
    	default:
    
    		switch (gpu_address) {
    
    		case 0:
    			lcdon = (data & 0x80) ? 1 : 0;
    			bgtilebase = (data & 0x10) ? 0x0000 : 0x0800;
    			bgmapbase = (data & 0x08) ? 0x1C00 : 0x1800;
    			objsize = (data & 0x04) ? 1 : 0;
    			objon = (data & 0x02) ? 1 : 0;
    			bgon = (data & 0x01) ? 1 : 0;
    			break;
    		case 2:
    			yscroll = data;
    			break;
    		case 3:
    			xscroll = data;
    			break;
    		case 4:
    			curline = 0; // resets on write attempt
    		case 5:
    			raster = data;
    			break;
    		case 6:
    			int v;
    			for (int i = 0; i < 160; i++) {
    				v = (*mmu).Read((data << 8) + i);
    				oam[i] = v;
    				UpdateOAM(0xFE00 + i, v);
    			}
    			break;
    		case 7:
    			for (int i = 0; i < 4; i++) {
    				switch ((data >> (i * 2)) & 3) {
    				case 0: palette.bg[i] = 255; break;
    				case 1: palette.bg[i] = 192; break;
    				case 2: palette.bg[i] = 96;  break;
    				case 3: palette.bg[i] = 0;   break;
    				}
    			}
    			break;
    		case 8:
    			for (int i = 0; i < 4; i++) {
    				switch ((data >> (i * 2)) & 3) {
    				case 0: palette.obj0[i] = 255; break;
    				case 1: palette.obj0[i] = 192; break;
    				case 2: palette.obj0[i] = 96;  break;
    				case 3: palette.obj0[i] = 0;   break;
    				}
    			}
    			break;
    		case 9:
    			for (int i = 0; i < 4; i++) {
    				switch ((data >> (i * 2)) & 3) {
    				case 0: palette.obj1[i] = 255; break;
    				case 1: palette.obj1[i] = 192; break;
    				case 2: palette.obj1[i] = 96;  break;
    				case 3: palette.obj1[i] = 0;   break;
    				}
    			}
    			break;
    		}
    	}
    }
    
    std::string GBGraphicsX::AsString() {
    
    	return "GBGraphicsX: Experimental GPU module";
    
    }
    
    void GBGraphicsX::CheckLine(uint8_t mClock) {
    
    	modeclocks += mClock;
    
    	switch (linemode) {
    
    	case 0: // hblank
    		if (modeclocks >= 51) {
    			if (curline == 143) {
    				linemode = 1;
    #ifdef NACL
    				OSS output_data_builder;
    				output_data_builder << "{ ";
    				for (int i = 0; i < (140 * 160); i++) {
    
    					output_data_builder << scrndata[i] << ", ";
    
    				}
    				output_data_builder << "}";
    
    				(*instance).PostMessage(pp::Var(output_data_builder.str()));
    #endif
    				// MMU interupt flag OR 0x01
    			} else {
    				linemode = 2;
    			}
    			curline++;
    			curscan += 640;
    			modeclocks = 0;
    		}
    		break;
    	case 1: // vblank
    		if (modeclocks >= 114) {
    			modeclocks = 0;
    			curline++;
    			if (curline > 153) {
    				curline = 0;
    				curscan = 0;
    				linemode = 2;
    			}
    		}
    		break;
    	case 2: // oam-r
    		if (modeclocks >= 20) {
    			modeclocks = 0;
    			linemode = 3;
    		}
    		break;
    	case 3:
    		if (modeclocks >= 43) {
    			modeclocks = 0;
    			linemode = 0;
    			if (lcdon) {
    
    				if (bgon) {
    
    					int linebase = curscan,
    						mapbase = bgmapbase + ((((curline + yscroll) & 0xFF)>>3)<<5),
    						y = (curline + yscroll) & 7,
    						x = xscroll & 7,
    						t = (xscroll >> 3) & 31,
    						w = 160;
    
    					if (bgtilebase) {
    
    						int tile = vram[mapbase + t];
    						if (tile < 128) 
    							tile = 256 + tile;
    
    						int tilerow[8] = { tilemap[tile][y][0], tilemap[tile][y][1],
    							tilemap[tile][y][2], tilemap[tile][y][3],
    							tilemap[tile][y][4], tilemap[tile][y][5],
    							tilemap[tile][y][6], tilemap[tile][y][7], };
    
    						do {
    							scanrow[160-x] = tilerow[x];
    							scrndata[linebase + 3] = palette.bg[tilerow[x]];
    							x++;
    							if (x == 8) {
    								t = (t+1) & 31;
    								x = 0;
    								tile = vram[mapbase + t];
    								if (tile < 128) {
    									tile = 256 + tile;
    								}
    								tilerow[0] = tilemap[tile][y][0];
    								tilerow[1] = tilemap[tile][y][1];
    								tilerow[2] = tilemap[tile][y][2];
    								tilerow[3] = tilemap[tile][y][3];
    								tilerow[4] = tilemap[tile][y][4];
    								tilerow[5] = tilemap[tile][y][5];
    								tilerow[6] = tilemap[tile][y][6];
    								tilerow[7] = tilemap[tile][y][7];
    							}
    							linebase += 4;
    						} while (w--);
    					} else {
    						int tilerow[8] = { tilemap[vram[mapbase + t]][y][0], tilemap[vram[mapbase + t]][y][1],
    							tilemap[vram[mapbase + t]][y][2], tilemap[vram[mapbase + t]][y][3],
    							tilemap[vram[mapbase + t]][y][4], tilemap[vram[mapbase + t]][y][5],
    							tilemap[vram[mapbase + t]][y][6], tilemap[vram[mapbase + t]][y][7], };
    						do {
    
    							scanrow[160 - x] = tilerow[x];
    							scrndata[linebase + 3] = palette.bg[tilerow[x]];
    							x++;
    							if (x == 8) {
    								t = (t+1) & 31;
    								x = 0;
    								tilerow[0] = tilemap[vram[mapbase + t]][y][0];
    								tilerow[1] = tilemap[vram[mapbase + t]][y][1];
    								tilerow[2] = tilemap[vram[mapbase + t]][y][2];
    								tilerow[3] = tilemap[vram[mapbase + t]][y][3];
    								tilerow[4] = tilemap[vram[mapbase + t]][y][4];
    								tilerow[5] = tilemap[vram[mapbase + t]][y][5];
    								tilerow[6] = tilemap[vram[mapbase + t]][y][6];
    								tilerow[7] = tilemap[vram[mapbase + t]][y][7];
    							}
    							linebase += 4;
    						} while (--w);
    					}
    
    				}
    
    				if (objon) {
    					int count = 0;
    					if (objsize) {
    						for (int i = 0; i < 40; i++) {
    							// wastes time
    						}
    					} else {
    						int tilerow[8], pal[4], x, linebase = curscan;
    						ObjectData obj;
    						for (int i = 0; i < 40; i++) {
    							obj = objdatasorted[i];
    							if (obj.y <= curline && (obj.y + 8) > curline) {
    								if (obj.yflip) {
    									tilerow[0] = tilemap[obj.tile][7-(curline - obj.y)][0];
    									tilerow[1] = tilemap[obj.tile][7-(curline - obj.y)][1];
    									tilerow[2] = tilemap[obj.tile][7-(curline - obj.y)][2];
    									tilerow[3] = tilemap[obj.tile][7-(curline - obj.y)][3];
    									tilerow[4] = tilemap[obj.tile][7-(curline - obj.y)][4];
    									tilerow[5] = tilemap[obj.tile][7-(curline - obj.y)][5];
    									tilerow[6] = tilemap[obj.tile][7-(curline - obj.y)][6];
    									tilerow[7] = tilemap[obj.tile][7-(curline - obj.y)][7];
    								} else {
    									tilerow[0] = tilemap[obj.tile][(curline - obj.y)][0];
    									tilerow[1] = tilemap[obj.tile][(curline - obj.y)][1];
    									tilerow[2] = tilemap[obj.tile][(curline - obj.y)][2];
    									tilerow[3] = tilemap[obj.tile][(curline - obj.y)][3];
    									tilerow[4] = tilemap[obj.tile][(curline - obj.y)][4];
    									tilerow[5] = tilemap[obj.tile][(curline - obj.y)][5];
    									tilerow[6] = tilemap[obj.tile][(curline - obj.y)][6];
    									tilerow[7] = tilemap[obj.tile][(curline - obj.y)][7];
    								}
    
    								if (obj.palette) {
    									pal[0] = palette.obj1[0];
    									pal[1] = palette.obj1[1];
    									pal[2] = palette.obj1[2];
    									pal[3] = palette.obj1[3];
    								} else {
    									pal[0] = palette.obj0[0];
    									pal[1] = palette.obj0[1];
    									pal[2] = palette.obj0[2];
    									pal[3] = palette.obj0[3];
    								}
    
    								linebase = (curline * 160 + obj.x) * 4;
    
    								if (obj.xflip) {
    									for (x = 0; x < 8; x++) {
    										if (obj.x + x >= 0 && obj.x + x < 160) {
    											if (tilerow[7-x] && (obj.prio || !scanrow[x])) {
    												scrndata[linebase+3] = pal[tilerow[7-x]];
    											}
    										}
    										linebase += 4;
    									}
    								} else {
    									for (x = 0; x < 8; x++) {
    										if (obj.x + x >= 0 && obj.x + x < 160) {
    											if (tilerow[x] && (obj.prio || !scanrow[x])) {
    												scrndata[linebase + 3] = pal[tilerow[x]];
    											}
    										}
    										linebase += 4;
    									}
    								}
    								count++;
    								if (count > 10)
    									break;
    							}
    						}
    					}
    				}
    			}
    		}
    	}
    }
    
    void GBGraphicsX::UpdateTile(int address, int val) {
    
    	int saddr = address;
    
    	if (address & 1) { 
    
    		saddr--;
    		address--;
    
    	}
    
    	int tile = ( address >> 4 ) & 511;
    	int y = ( address >> 1 ) & 7;
    	int sx;
    
    	for (int x = 0; x < 8; x++ ) {
    
    		sx = 1 << ( 7 - x );
    		tilemap[tile][y][x] = (vram[saddr] & sx ? 1 : 0) | (vram[saddr + 1] & sx ? 2 : 0);
    
    	}
    
    }
    
    void GBGraphicsX::UpdateOAM(int address, int val) {
    
    	address -= 0xFE00;
    
    	int obj = address >> 2;
    
    	if (obj < 40) {
    
    		switch (address & 3) {
    
    		case 0: 
    			objdata[obj].y = val - 16;
    			break;
    
    		case 1:
    			objdata[obj].x = val - 8;
    			break;
    
    		case 2:
    			if (objsize) 
    				objdata[obj].tile = val & 0xFE;
    			else
    				objdata[obj].tile = val;
    			break;
    
    		case 3:
    			objdata[obj].palette = val & 0x10 ? 1 : 0;
    			objdata[obj].xflip = val & 0x20 ? 1 : 0;
    			objdata[obj].yflip = val & 0x40 ? 1 : 0;
    			objdata[obj].prio = val & 0x80 ? 1 : 0;
    			break;
    
    		}
    
    	}
    
    	for (int i = 0; i < 40; i++) {
    
    		objdatasorted[i] = objdata[i];
    
    	}
    
    	// sort the data
    
    //std::sort(objdatasorted, objdatasorted + 40);
    
    }
    
    


    In each cycle of the loop:
    The current value of curline is obtained (Read(0xFF04))
    The checkline function is called.
    It is compared against the value 0x90
    The checkline function is called.
    If it is not 0x90, continue looping.
    The checkline function is called.

    The curline value starts at 0x23 and crashes after being 0x28 for 9 cycles.

    It's a consistent error, and the byte pattern is always the same. Also I just realised it's the MSB being overwritten.

    [edit] Actually, I tell a lie. on the read that the "memory corruption" occurs, immediately after it tries to read curline at a completely different location (I think, need to test that theory because it could be something else...)

    [edit2] A-HA! When the access violation occurs, it reads the memory at the address, but with an FF in the MSB. [b] So, if curline is located at 0x00583ADC, the access violation occurs at 0xFF583ADC


    [edit3] Exploring the memory *after* the access violation shows that, besides the 0xFF MSB patten, the memory is still intact. The object doesn't appear to have been dissolved for any reason. It's just the byte pattern being applied rather consistently. Also only over members of the class....
  3. In Topic: Overloaded Operator killing a pointer

    Posted 29 Mar 2015

    View Postjimblumberg, on 29 March 2015 - 11:20 AM, said:

    Quote

    I've noted that they appear to be killing my pointers eventually.

    What pointers are you talking about? I don't see any pointers, other than *this being used.

    Jim


    Sorry, should have really stuck that in there.

    Throughout the lifetime of my program there are 5 pointers to a GBPairedRegister, stored in an array called rp.

    One of these is subject to a loop where its contents are decremented each time (among other ops not concerning it).

    After roughly 8k cycles of that loop, the pointer appears to be dead. When I prevented the += and -= from operating on "*this", the problem went away.

    So, my question is, what am I doing wrong. From everything I've read I can't see that I actually am.

    If it were a scope issue, the other 4 gbpr' would die too.
  4. In Topic: Break a switch into multiple files

    Posted 10 Feb 2015

    View Postpryogene, on 09 February 2015 - 10:35 AM, said:

    ...I'm posting rather than running the idea through a compiler as I'm away from my workstations for a couple of days (just in case anyone suggests that) ...



    View Postjimblumberg, on 09 February 2015 - 01:32 PM, said:

    Quote

    Though, to my original question: is breaking a switch statement up into groups of case statements in headers compiler legal?

    I suggest you try it and find out.

    Jim


    I usually just brush over this sort of thing, but that's easily the least helpful response I've had on DiC. I wouldn't have asked if I had access to my tools to try it. Appreciate all the help nonetheless.

    (Edit) neg. rep'd for an answer seemingly disregarding the original post.
  5. In Topic: Break a switch into multiple files

    Posted 9 Feb 2015

    I'm not entirely sure how I missed that guide, but that was and will be incredibly helpful.

    I can ignore most of it, since the Game Boy Z80 doesn't implement the DD/ED/FD extensions, just the base and CB ext. ops. Being able to mask and branch down to just a couple of parameterized functions won't necessarily be as maintainable, but with some good commenting it'll definitely be more readable.

    Though, to my original question: is breaking a switch statement up into groups of case statements in headers compiler legal?

My Information

Member Title:
The Leafiest of the Leif's
Age:
22 years old
Birthday:
February 5, 1993
Gender:
Location:
Wolverhampton, UK
Interests:
Interesting things. Interestingly.
Full Name:
Leif Walker-Grant
Years Programming:
9
Programming Languages:
Experienced: C#, VB, (X)HTML, JScript, PHP, XAML, ASP, VBScript, C++/C, Java.
Some Knowledge: Actionscript, Lua.
Designed himself: SkySkrypt Object Markup Extensions (for Project 'Skylark')

Contact Information

E-mail:
Private
MSN:
MSN  leaffyleif@live.co.uk
Website URL:
Website URL  http://www.3six.co.uk
Skype:
Skype  leaffylebrindille
Facebook:
http://www.facebook.com/leif.walker-grant
Twitter:
leaffydesign

Friends

Comments

pryogene has no profile comments yet. Why not say hello?