/* Non-blocking read from STDIN. len parameter is max number of bytes to read. If less than this is available, function will quit early and return actual number of bytes read */ int read (char * buf, int len) { int ret = 0; while(ret < len && (MemoryRead(UART_STATUS) & UART_RX_DV_MASK) == UART_RX_DV_MASK) { buf[ret++] = MemoryRead(UART_RX); } return ret; }
/* A blocking delay of approximate milliseconds. */ void Sleep(unsigned int milliseconds) { int m; unsigned int start; for(m = 0; m < milliseconds; m++) { start = MemoryRead(COUNTER2); while((MemoryRead(COUNTER2) - start) < 10000); } }
//Plasma hardware dependent static void OS_ThreadTickToggle(void *arg) { uint32 status, mask, state; //Toggle looking for IRQ_COUNTER18 or IRQ_COUNTER18_NOT state = OS_SpinLock(); status = MemoryRead(IRQ_STATUS) & (IRQ_COUNTER18 | IRQ_COUNTER18_NOT); mask = MemoryRead(IRQ_MASK) | IRQ_COUNTER18 | IRQ_COUNTER18_NOT; mask &= ~status; MemoryWrite(IRQ_MASK, mask); OS_ThreadTick(arg); OS_SpinUnlock(state); }
void HF_UpdateCounterMask(void){ uint32_t m; m = MemoryRead(IRQ_MASK); // read interrupt mask m ^= (IRQ_COUNTER | IRQ_COUNTER_NOT); // toggle timer interrupt mask MemoryWrite(IRQ_MASK, m); // write to irq mask register }
static inline uint16_t NocRead(void){ uint16_t data; data = (uint16_t)MemoryRead(NOC_READ); asm ("nop\nnop\nnop"); return data; }
static inline uint16_t NocStatus(void){ uint16_t status; status = (uint16_t)MemoryRead(NOC_STATUS); asm ("nop\nnop\nnop"); return status; }
/* basic libc abstraction stuff */ void uart_init(uint32_t baud){ uint16_t d; d = (uint16_t)(CPU_SPEED / baud); MemoryWrite(UART_DIVISOR, d); MemoryRead(UART_READ); }
void Executor::ExecMemoryRead(MethodFrame *frame, Insn *insn) { Value &addr_value = frame->reg_values_[insn->src_regs_[0]->id_]; CHECK(addr_value.type_ == Value::NUM); Value &dst_value = frame->reg_values_[insn->dst_regs_[0]->id_]; int addr = addr_value.num_.int_part; MemoryRead(addr, &dst_value.num_); dst_value.type_ = Value::NUM; }
uint32_t HF_InterruptMaskClear(uint32_t mask){ // interrupt vector mask clear uint32_t m, state; state = HF_CriticalBegin(); m = MemoryRead(IRQ_MASK) & ~mask; MemoryWrite(IRQ_MASK, m); HF_CriticalEnd(state); return m; }
//Plasma hardware dependent uint32 OS_InterruptMaskClear(uint32 mask) { uint32 state; state = OS_CriticalBegin(); mask = MemoryRead(IRQ_MASK) & ~mask; MemoryWrite(IRQ_MASK, mask); OS_CriticalEnd(state); return mask; }
void _usleep(uint32_t usec){ volatile uint32_t cur, last, delta, usecs; uint32_t cycles_per_usec; last = MemoryRead(COUNTER); delta = usecs = 0; cycles_per_usec = CPU_SPEED / 1000000; while(usec > usecs){ cur = MemoryRead(COUNTER); if (cur < last) delta += (cur + (CPU_SPEED - last)); else delta += (cur - last); last = cur; if (delta >= cycles_per_usec){ usecs += delta / cycles_per_usec; delta %= cycles_per_usec; } } }
/* * ReadMem - read some memory, using toolhelp or wdebug.386 */ DWORD ReadMem( WORD sel, DWORD off, LPVOID buff, DWORD size ) { DWORD rc; if( WDebug386 ) { rc = CopyMemory( FP_SEG(buff), FP_OFF(buff), sel, off, size ); } else { if( DebugeeTask == NULL ) return( 0 ); rc = MemoryRead( sel, off, buff, size ); } return( rc ); } /* ReadMem */
/* * ReadMem - read some memory, using toolhelp or wdebug.386 */ DWORD ReadMem( WORD sel, DWORD off, LPVOID buff, DWORD size ) { DWORD rc; if( WDebug386 ) { return( CopyMemory386( FP_SEG( buff ), FP_OFF( buff ), sel, off, size ) ); } else { PushAll(); rc = MemoryRead( sel, off, buff, size ); PopAll(); return( rc ); } } /* ReadMem */
int ddr_init (void) { volatile int i, j, k = 0; for (i = 0; i < sizeof (DdrInitData) / sizeof (int); ++i) { MemoryWrite (DDR_BASE + DdrInitData[i], 0); for (j = 0; j < 4; ++j) ++k; } for (j = 0; j < 100; ++j) ++k; k += MemoryRead (DDR_BASE); //Enable DDR return k; }
static void OS_IdleSimulateIsr(void *arg) { uint32 count=0, value; (void)arg; for(;;) { MemoryRead(IRQ_MASK + 4); //calls Sleep(10) #if WIN32 while(OS_InterruptMaskSet(0) & IRQ_UART_WRITE_AVAILABLE) OS_InterruptServiceRoutine(IRQ_UART_WRITE_AVAILABLE, 0); #endif value = OS_InterruptMaskSet(0) & 0xf; if(value) OS_InterruptServiceRoutine(value, 0); ++count; } }
int32_t _getchar(void){ // polled getch() while(!kbhit()) ; return MemoryRead(UART_READ); }
int32_t _kbhit(void){ return MemoryRead(IRQ_CAUSE) & IRQ_UART_READ_AVAILABLE; }
void _putchar(int32_t value){ // polled putchar() while((MemoryRead(IRQ_CAUSE) & IRQ_UART_WRITE_AVAILABLE) == 0); MemoryWrite(UART_WRITE, value); }
/* * 設定コマンド */ static UW set_command(B *command) { INT point=0; B cmd=0; UB b; UH h; UW w, value1, value2; int no, count; BOOL cont; count = sizeof(mon_set) / sizeof(struct SUBCOMMAND_TABLE); if(command[point]){ for(no = 0 ; no < count ; no++){ if(compare_word(mon_set[no].subcommand, command, 0)){ skip_word(command, &point); cmd = mon_set[no].type; break; } } } switch(cmd){ default: /* デフォルト */ cmd = mon_datatype; case MONSET_BYTE: /* バイト単位メモリ設定 */ case MONSET_HALF: /* ハーフ単位メモリ設定 */ case MONSET_WORD: /* ワード単位メモリ設定 */ if(!get_value(command, &point, &value1, HEX_BASE)) value1 = mon_address; value1 = MonAlignAddress(value1); mon_datatype = cmd; do{ printf(" %08lx", (unsigned long)value1); switch(mon_datatype){ case DATA_HALF: if(MemoryRead(value1, &h, 2) == 0) h = -1; printf(" %04x =", h); break; case DATA_WORD: if(MemoryRead(value1, &w, 4) == 0) w = -1; printf(" %08lx =", (unsigned long)w); break; default: if(MemoryRead(value1, &b, 1) == 0) b = -1; printf(" %02x =", b); break; } monitor_getstring(mon_command, &point); if(get_value(mon_command, &point, &value2, HEX_BASE)){ switch(mon_datatype){ case DATA_HALF: h = value2; MemoryWrite(value1, &h, 2); if(MemoryRead(value1, &h, 2) == 0) h = -1; printf(" %04x\n", h); break; case DATA_WORD: w = value2; MemoryWrite(value1, &w, 4); if(MemoryRead(value1, &w, 4) == 0) w = -1; printf(" %08lx\n", (unsigned long)w); break; default: b = value2; MemoryWrite(value1, &b, 1); if(MemoryRead(value1, &b, 1) == 0) b = -1; printf(" %02x\n", b); break; } value1 += mon_datatype; cont = TRUE; } else cont = FALSE; }while(cont || point == 0); putchar('\n'); mon_address = value1; break; case MONSET_COMMAND: /* コマンドモード設定 */ if(get_value(command, &point, &value1, DEC_BASE)){ if(value1 == 1 || value1 == 2){ printf(" set %d command(s) mode !\n", value1); mon_mode = value1; } } printf(" set command mode=%d word(s) !\n", mon_mode); break; case MONSET_SERIAL: /* シリアル設定 */ if(get_value(command, &point, &value1, DEC_BASE)){ if(value1 > 0 && mon_portid != value1){ if(mon_portid != mon_default_portid && mon_portid != CONSOLE_PORTID) syscall(serial_cls_por(mon_portid)); mon_portid = value1; if(mon_portid != mon_default_portid && mon_portid != CONSOLE_PORTID) syscall(serial_opn_por(mon_portid)); syscall(serial_ctl_por(mon_portid, (IOCTL_CRLF | IOCTL_FCSND | IOCTL_FCRCV))); printf(banner, (TMONITOR_PRVER >> 12) & 0x0f, (TMONITOR_PRVER >> 4) & 0xff, TMONITOR_PRVER & 0x0f); } } printf(" set serial port id=%d !\n", mon_portid); break; case MONSET_TASK: /* タスク選択 */ if(get_value(command, &point, &value1, DEC_BASE)){ if(value1 >= TMIN_TSKID && value1 < (TMIN_TSKID+tmax_tskid)) current_tskid = value1; else current_tskid = MONTASK; } else current_tskid = MONTASK; break; case MONSET_IN: /* 入力設定 */ value1 = 0; get_value(command, &point, &value1, DEC_BASE); if(value1 == 1) mon_infile = stdout; else if(value1 == 2) mon_infile = stderr; else mon_infile = stdin; break; } return 0; }
uint32_t HF_ReadCounter(void){ return MemoryRead(COUNTER); }
static trap_elen ReadMemory( addr48_ptr *addr, void *data, trap_elen len ) /************************************************************************/ { return( MemoryRead( addr->offset, addr->segment, data, len ) ); }
int main(int argc, char **argv) { char cDiskName[] = "/dev/sg2"; int fd = open(cDiskName, O_RDWR); if (fd < 0) { printf("Open error: %s, errno=%d (%s)\n", cDiskName, errno, strerror(errno)); return 1; } if (!checkDevice(fd)) { printf("checkDevice fail\n"); return 2; } printf("init ok\n"); DataInfo_t datainfo; int last_addr = 0; DeviceState_t last_state = STATE_INVALIDxx; DI_Status_t last_status = DI_STATUS_INVALIDxx; unsigned scanned_imgs = 0; while (true) { // get state: scanning or idle DeviceState_t state = GetDeviceState(fd); if (state >= STATE_INVALIDxx || state < 0) { return 7; } if (state != last_state) { printf("DeviceState: %d => %s\n", (unsigned)state, state_lut[state]); } // get data info: new data ready or not? if (!GetDeviceDataInfo(fd, &datainfo)) { return 8; } if (datainfo.status < 0 || datainfo.status > 2) { return 9; } if (datainfo.status != last_status || datainfo.addr != last_addr) { dumpDataInfo(&datainfo); } if (datainfo.status != DI_STATUS_NOT_READY) { // there's data for us unsigned imgbufsize = datainfo.width * datainfo.height; if (datainfo.color == DI_COLOR_COLOR) { imgbufsize *= 3; } // image buffer unsigned char *imgbuf = new unsigned char[imgbufsize]; // read data bool ok = MemoryRead(fd, datainfo.addr, imgbuf, imgbufsize); if (ok) { printf("read %d bytes\n", imgbufsize); shuffleBitmap(imgbuf, imgbufsize, datainfo.width, datainfo.height, datainfo.color); int ifd; if (!scanned_imgs) { ifd = open("out.data", O_WRONLY|O_CREAT|O_TRUNC, 0644); } else { ifd = open("out.data", O_WRONLY|O_APPEND); } if (ifd) { write(ifd, imgbuf, imgbufsize); close(ifd); scanned_imgs++; } } else { printf("failed reading data\n"); } delete [] imgbuf; imgbuf = 0; } usleep(20000); last_state = state; last_status = datainfo.status; last_addr = datainfo.addr; } close(fd); printf("all ok\n"); return 0; }
int main(int argc, char* argv[]) { mos6502 cpu(MemoryRead, MemoryWrite); disasm dasm; int SPEED = 100; // % int CPUFREQ = 1000000; // Hz - CPU clock frequency bool HALT = false; // Todo optimize this string buffer size? char str[400]; if (argc < 2) { std::cout << "Filename required!" << std::endl; return 0; } if (rom.loadFromFile(argv[1]) == 0) { std::cout << "Rom invalid!" << std::endl; } std::string caption("CBS6000 Emulator - (C)2015 Koen van Vliet"); sf::RenderWindow window(sf::VideoMode(WINDOW_WIDTH, WINDOW_HEIGHT), caption); sf::RenderWindow dbgwindow(sf::VideoMode(DBGWINDOW_WIDTH, DBGWINDOW_HEIGHT), caption); sf::RenderWindow zpwindow(sf::VideoMode(ZPWINDOW_WIDTH, ZPWINDOW_HEIGHT), caption); window.setFramerateLimit(FPS); dbgwindow.setFramerateLimit(FPS); zpwindow.setFramerateLimit(FPS); if (!term.load("terminal8x16.png",8,16)) { std::cout << "Failed to open bitmap font file!" << std::endl; return 0; } if (!dbgterm.load("terminal8x16.png",8,16)) { std::cout << "Failed to open bitmap font file!" << std::endl; return 0; } if (!dasmterm.load("terminal8x16.png",8,16)) { std::cout << "Failed to open bitmap font file!" << std::endl; return 0; } if (!regterm.load("terminal8x16.png",8,16)) { std::cout << "Failed to open bitmap font file!" << std::endl; return 0; } if (!zpterm.load("terminal8x16.png",8,16)) { std::cout << "Failed to open bitmap font file!" << std::endl; return 0; } int ctile = 177; term.setCursorTile(ctile); dbgterm.setCursorTile(ctile); dbgterm.enableCursor(false); dbgterm.setTextColor(sf::Color::Green); dasmterm.enableCursor(false); dasmterm.setTextColor(sf::Color::Cyan); regterm.enableCursor(false); regterm.setTextColor(sf::Color::White); zpterm.enableCursor(false); zpterm.setTextColor(sf::Color::White); consoleLog("---[Debug console]---"); consoleLog(versionInfo); net.init(); consoleLog("Starting CPU emulation"); // Reset Cpu and internal IO port for the 6510 Direction = 0x00; PortOut = 0x00; cpu.Reset(); bool SHOWDASM = false; while(window.isOpen()) { if (SPEED <= 20) { SHOWDASM = true; } sf::Event event; while (window.pollEvent(event)) { switch (event.type) { case sf::Event::Closed : window.close(); break; case sf::Event::TextEntered: if (event.text.unicode < 128) { char c = (char)event.text.unicode; term.feedChar(c); } break; case sf::Event::KeyPressed : // Increase and decrease the CPU speed if (event.key.code == sf::Keyboard::PageUp) { if (SPEED < 500) { SPEED += 5; } sprintf(str, "%d%% speed", SPEED); consoleLog(str); } if (event.key.code == sf::Keyboard::PageDown) { if (SPEED) { SPEED -= 5; if (SPEED < 0) { SPEED = 0; } sprintf(str, "%d%% speed", SPEED); consoleLog(str); } } // Stop execution if (event.key.code == sf::Keyboard::Delete) { HALT = true; SHOWDASM = true; consoleLog("F8 to continue, F5 to step"); } // Stop/Resume execution if (event.key.code == sf::Keyboard::F8) { if (HALT) { HALT = false; consoleLog("Resumed execution..."); } else { HALT = true; SHOWDASM = true; consoleLog("F8 to continue, F5 to step"); } } // Execute single instruction if (event.key.code == sf::Keyboard::F5) { if (HALT) { cpu.Run(1); SHOWDASM = true; } } if (event.key.code == sf::Keyboard::End) { // Reset Cpu and internal IO port for the 6510 Direction = 0x00; PortOut = 0x00; cpu.Reset(); HALT = false; consoleLog("Reset CPU"); } break; default: break; } } // Run a bunch of instructions if(!HALT) { int IPF = (CPUFREQ * SPEED) /(FPS * AVG_INSTRUCTION_CYCLES * 100); // Instructions per frame cpu.Run(IPF); } if (SHOWDASM) { // Show live disassembly of the memory SHOWDASM = false; // Todo fix pc uint16_t state[6]; uint8_t buff[3]; uint16_t pc; cpu.GetState(state); pc = state[3]; for(int i = 0; i< 9; i++) { uint pc_prev = pc; dasmterm.printString("\r\n"); buff[0] = MemoryRead(pc); buff[1] = MemoryRead(pc+1); buff[2] = MemoryRead(pc+2); pc += 1 + dasm.getDisassembly((char*)str, buff, 1, pc_prev); if(i ==0) dasmterm.printString(">"); else dasmterm.printString(" "); dasmterm.printString(str); } // Display CPU register contents char charA = state[0], charX = state[1], charY = state[2]; if (charA < ' ') { charA = ' '; } if (charX < ' ') { charX = ' '; } if (charY < ' ') { charY = ' '; } sprintf(str,"\r\n" "A: $%02X %03d \'%c\'\r\n" "X: $%02X %03d \'%c\'\r\n" "Y: $%02X %03d \'%c\'\r\n" "PC: $%04X\r\n" "SP: $%02X %03d\r\n" "SR: $%02X, Z: %d, C: %d", state[0], state[0], charA, state[1], state[1], charX, state[2], state[2], charY, state[3], state[4], state[4], state[5], (state[5]>>1) & 1, state[5] & 1); regterm.printString(str); // Show zero page contents zpterm.setTextColor(sf::Color::Cyan); zpterm.printString("\r\n----: -0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F"); zpterm.setTextColor(sf::Color::White); for(int i = 0; i < 16; i++) { uint8_t d; zpterm.printString("\r\n"); sprintf(str, "%04X: ", (uint16_t)(i * 16)); zpterm.printString(str); for(int j = 0; j < 16; j++) { d = MemoryRead(i*16 + j); if (j == 15) sprintf(str,"%02X",d); else sprintf(str,"%02X,",d); if(i*16 + j >= 0x5C && i*16+j < 0x5C+ 0x27) zpterm.setTextColor(sf::Color::Green); zpterm.printString(str); zpterm.setTextColor(sf::Color::White); } for(int j = 0; j < 16; j++) { d = MemoryRead(i*16 + j); if (d < ' ') { d = ' '; } if(i*16 + j >= 0x5C && i*16+j < 0x5C+ 0x27) zpterm.setTextColor(sf::Color::Green); zpterm.Write(d); zpterm.setTextColor(sf::Color::Blue); zpterm.Write(ctile); zpterm.setTextColor(sf::Color::White); } zpterm.setTextColor(sf::Color::Blue); for(int i = 0; i< 86; i++) zpterm.Write(177); zpterm.setTextColor(sf::Color::White); } } // Update the screen window.clear(); dbgwindow.clear(); zpwindow.clear(); net.update(); term.update(); dbgterm.update(); dasmterm.update(); zpterm.update(); regterm.update(); window.draw(term); dbgwindow.draw(dbgterm); zpwindow.draw(zpterm); //if(HALT) //{ dbgwindow.draw(dasmterm); dbgwindow.draw(regterm); //} window.display(); dbgwindow.display(); zpwindow.display(); } return 0; }
/* Blocking write to STDIN */ void writeChar(unsigned char c) { while((MemoryRead(UART_STATUS) & UART_TX_FULL_MASK) > 0); printChar(c); }
/* Blocking read from STDIN */ unsigned char readChar() { while((MemoryRead(UART_STATUS) & UART_RX_DV_MASK) == 0); return (unsigned char)MemoryRead(UART_RX); }
int32_t _getchar(void){ // polled getch() return MemoryRead(DEBUG_ADDR); }
/* interrupt management routines */ uint32_t HF_InterruptStatus(void){ // check interrupt status return MemoryRead(IRQ_STATUS); }
uint32_t HF_InterruptMaskRead(void){ // check interrupt status return MemoryRead(IRQ_MASK); }
static unsigned ReadMemory( addr48_ptr *addr, void *data, unsigned len ) /**********************************************************************/ { return( MemoryRead( addr->offset, addr->segment, data, len ) ); }
Lst::HashTable<Nx::CTexture>* LoadTextureFileFromMemory( void **pp_mem, Lst::HashTable<Nx::CTexture> *p_texture_table, bool okay_to_rebuild_texture_table ) { uint8 *p_data = (uint8*)( *pp_mem ); // Read the texture file version and number of textures. int version, num_textures; MemoryRead( &version, sizeof( int ), 1, p_data ); MemoryRead( &num_textures, sizeof( int ), 1, p_data ); // If allowed, rebuild the texture table to the optimum size, using the same heap as the original table. if( okay_to_rebuild_texture_table ) { uint32 optimal_table_size = num_textures * 2; uint32 test = 2; uint32 size = 1; for( ;; test <<= 1, ++size ) { // Check if this iteration of table size is sufficient, or if we have hit the maximum size. if(( optimal_table_size <= test ) || ( size >= 12 )) { Mem::Allocator::BlockHeader* p_bheader = Mem::Allocator::BlockHeader::sRead( p_texture_table ); Mem::Allocator* p_allocater = p_bheader->mpAlloc; delete p_texture_table; Mem::Manager::sHandle().PushContext( p_allocater ); p_texture_table = new Lst::HashTable<Nx::CTexture>( size ); Mem::Manager::sHandle().PopContext(); break; } } } for( int t = 0; t < num_textures; ++t ) { // Create the engine level texture. NxXbox::sTexture *p_texture = new NxXbox::sTexture; uint32 base_width, base_height, levels, texel_depth, palette_depth, dxt, palette_size; MemoryRead( &p_texture->Checksum, sizeof( uint32 ), 1, p_data ); MemoryRead( &base_width, sizeof( uint32 ), 1, p_data ); MemoryRead( &base_height, sizeof( uint32 ), 1, p_data ); MemoryRead( &levels, sizeof( uint32 ), 1, p_data ); MemoryRead( &texel_depth, sizeof( uint32 ), 1, p_data ); MemoryRead( &palette_depth, sizeof( uint32 ), 1, p_data ); MemoryRead( &dxt, sizeof( uint32 ), 1, p_data ); MemoryRead( &palette_size, sizeof( uint32 ), 1, p_data ); p_texture->BaseWidth = (uint16)base_width; p_texture->BaseHeight = (uint16)base_height; p_texture->Levels = (uint8)levels; p_texture->TexelDepth = (uint8)texel_depth; p_texture->PaletteDepth = (uint8)palette_depth; p_texture->DXT = (uint8)dxt; D3DFORMAT texture_format; if( p_texture->DXT > 0 ) { if(( p_texture->DXT == 1 ) || ( p_texture->DXT == 2 )) { texture_format = D3DFMT_DXT1; } else if( p_texture->DXT == 5 ) { texture_format = D3DFMT_DXT5; } else { Dbg_Assert( 0 ); } } else if( p_texture->TexelDepth == 8 ) { texture_format = D3DFMT_P8; } else if( p_texture->TexelDepth == 16 ) { texture_format = D3DFMT_A1R5G5B5; // Could also be X1R5G5B5; } else if( p_texture->TexelDepth == 32 ) { texture_format = D3DFMT_A8R8G8B8; } else { Dbg_Assert( 0 ); } if( D3D_OK != D3DDevice_CreateTexture( p_texture->BaseWidth, p_texture->BaseHeight, p_texture->Levels, 0, texture_format, 0, &p_texture->pD3DTexture )) { Dbg_Assert( 0 ); } if( palette_size > 0 ) { // Create and lock the palette. if( D3D_OK != D3DDevice_CreatePalette( palette_size == ( 256 * sizeof( D3DCOLOR )) ? D3DPALETTE_256 : D3DPALETTE_32, &p_texture->pD3DPalette )) { Dbg_Assert( 0 ); } else { D3DCOLOR* p_colors; if( D3D_OK != p_texture->pD3DPalette->Lock( &p_colors, 0 )) { Dbg_Assert( 0 ); } else { // Read in palette data. MemoryRead( p_colors, palette_size, 1, p_data ); } } } else { p_texture->pD3DPalette = NULL; } for( uint32 mip_level = 0; mip_level < p_texture->Levels; ++mip_level ) { uint32 texture_level_data_size; MemoryRead( &texture_level_data_size, sizeof( uint32 ), 1, p_data ); D3DLOCKED_RECT locked_rect; if( D3D_OK != p_texture->pD3DTexture->LockRect( mip_level, &locked_rect, NULL, 0 )) { Dbg_Assert( 0 ); } else { MemoryRead( locked_rect.pBits, texture_level_data_size, 1, p_data ); } } // Add this texture to the table. Nx::CXboxTexture *p_xbox_texture = new Nx::CXboxTexture(); p_xbox_texture->SetEngineTexture( p_texture ); p_texture_table->PutItem( p_texture->Checksum, p_xbox_texture ); } return p_texture_table; }