void complete_list_with_error(uint8_t hostid, bool halted, bool xact_err) { //------------- Async List -------------// ehci_registers_t* const regs = get_operational_register(hostid); ehci_qhd_t *p_qhd = (ehci_qhd_t*) regs->async_list_base; do { complete_1st_qtd_with_error(p_qhd, halted, xact_err); p_qhd = (ehci_qhd_t*) align32(p_qhd->next.address); }while(p_qhd != get_async_head(hostid)); // stop if loop around //------------- Period List -------------// for(uint8_t i=1; i <= EHCI_FRAMELIST_SIZE; i *= 2) { ehci_link_t *head = get_period_head(hostid, i); while(!head->terminate) { uint32_t queue_type = head->type; head = (ehci_link_t*) align32(head->address); if ( queue_type == EHCI_QUEUE_ELEMENT_QHD) { complete_1st_qtd_with_error((ehci_qhd_t*) head, halted, xact_err); } } } regs->usb_sts = EHCI_INT_MASK_ERROR; hcd_isr(hostid); }
//--------------------------------------------------------------------+ // PIPE CLOSE //--------------------------------------------------------------------+ void test_interrupt_close(void) { pipe_hdl = hcd_pipe_open(dev_addr, &desc_ept_interrupt_out, TUSB_CLASS_HID); p_int_qhd = qhd_get_from_pipe_handle(pipe_hdl); //------------- Code Under TEST -------------// TEST_ASSERT_EQUAL(TUSB_ERROR_NONE, hcd_pipe_close(pipe_hdl) ); TEST_ASSERT(p_int_qhd->is_removing); TEST_ASSERT( align32(period_head_arr->next.address) != (uint32_t) p_int_qhd ); TEST_ASSERT_EQUAL_HEX( (uint32_t) period_head_arr, align32(p_int_qhd->next.address ) ); TEST_ASSERT_EQUAL(EHCI_QUEUE_ELEMENT_QHD, p_int_qhd->next.type); }
void test_bulk_xfer_double(void) { //------------- Code Under Test -------------// TEST_ASSERT_STATUS( hcd_pipe_xfer(pipe_hdl_bulk, xfer_data, sizeof(xfer_data), false) ); TEST_ASSERT_STATUS( hcd_pipe_xfer(pipe_hdl_bulk, data2, sizeof(data2), true) ); ehci_qtd_t* p_head = p_qhd_bulk->p_qtd_list_head; ehci_qtd_t* p_tail = p_qhd_bulk->p_qtd_list_tail; //------------- list head -------------// TEST_ASSERT_NOT_NULL(p_head); verify_qtd(p_head, xfer_data, sizeof(xfer_data)); TEST_ASSERT_EQUAL_HEX(p_qhd_bulk->qtd_overlay.next.address, p_head); TEST_ASSERT_EQUAL(EHCI_PID_IN, p_head->pid); TEST_ASSERT_FALSE(p_head->next.terminate); TEST_ASSERT_FALSE(p_head->int_on_complete); //------------- list tail -------------// TEST_ASSERT_NOT_NULL(p_tail); verify_qtd(p_tail, data2, sizeof(data2)); TEST_ASSERT_EQUAL_HEX( align32(p_head->next.address), p_tail); TEST_ASSERT_EQUAL(EHCI_PID_IN, p_tail->pid); TEST_ASSERT_TRUE(p_tail->next.terminate); TEST_ASSERT_TRUE(p_tail->int_on_complete); }
void check_int_endpoint_link(ehci_qhd_t *p_prev, ehci_qhd_t *p_qhd) { //------------- period list check -------------// TEST_ASSERT_EQUAL_HEX((uint32_t) p_qhd, align32(p_prev->next.address)); TEST_ASSERT_FALSE(p_prev->next.terminate); TEST_ASSERT_EQUAL(EHCI_QUEUE_ELEMENT_QHD, p_prev->next.type); }
void test_interrupt_256ms_close(void) { tusb_descriptor_endpoint_t int_edp_interval = desc_ept_interrupt_out; int_edp_interval.bInterval = 9; pipe_hdl = hcd_pipe_open(dev_addr, &int_edp_interval, TUSB_CLASS_HID); p_int_qhd = qhd_get_from_pipe_handle(pipe_hdl); //------------- Code Under TEST -------------// TEST_ASSERT_EQUAL(TUSB_ERROR_NONE, hcd_pipe_close(pipe_hdl) ); TEST_ASSERT(p_int_qhd->is_removing); TEST_ASSERT( align32(get_period_head(hostid, 8)->address) != (uint32_t) p_int_qhd ); TEST_ASSERT_EQUAL_HEX( (uint32_t) get_period_head(hostid, 8), align32(p_int_qhd->next.address ) ); TEST_ASSERT_EQUAL(EHCI_QUEUE_ELEMENT_QHD, p_int_qhd->next.type); }
static ucell *aligncell(ucell *v) { if (pc_cellsize==2) return align16(v); if (pc_cellsize==4) return align32(v); #if PAWN_CELL_SIZE>=64 if (pc_cellsize==8) return align64(v); #endif assert(0); }
static inline u32 dispatch_t150(t150 a151, t18 a152) { switch (a151) { case FUN_ENUM_align32: return align32(a152); default: return min_u32(a152); } }
bool complete_all_qtd_in_async(ehci_qhd_t *head) { ehci_qhd_t *p_qhd = head; do { complete_qtd_in_qhd(p_qhd); p_qhd = (ehci_qhd_t*) align32(p_qhd->next.address); }while(p_qhd != head); // stop if loop around return true; }
void complete_qtd_in_qhd(ehci_qhd_t *p_qhd) { if ( !p_qhd->qtd_overlay.halted ) { while(!p_qhd->qtd_overlay.next.terminate) { ehci_qtd_t* p_qtd = (ehci_qtd_t*) align32(p_qhd->qtd_overlay.next.address); p_qtd->active = 0; p_qtd->total_bytes = 0; p_qhd->qtd_overlay = *p_qtd; } } }
bool complete_all_qtd_in_period(ehci_link_t *head) { while(!head->terminate) { uint32_t queue_type = head->type; head = (ehci_link_t*) align32(head->address); if ( queue_type == EHCI_QUEUE_ELEMENT_QHD) { complete_qtd_in_qhd( (ehci_qhd_t*) head ); } } return true; }
void complete_1st_qtd_with_error(ehci_qhd_t* p_qhd, bool halted, bool xact_err) { if ( !p_qhd->qtd_overlay.halted ) { if(!p_qhd->qtd_overlay.next.terminate) // TODO add active check { ehci_qtd_t* p_qtd = (ehci_qtd_t*) align32(p_qhd->qtd_overlay.next.address); p_qtd->active = 0; p_qtd->halted = halted ? 1 : 0; p_qtd->xact_err = xact_err ? 1 : 0; p_qhd->qtd_overlay = *p_qtd; } } }
SC_FUNC int assemble(FILE *fout,FILE *fin) { AMX_HEADER hdr; AMX_FUNCSTUB func; int numpublics,numnatives,numoverlays,numlibraries,numpubvars,numtags; int padding; long nametablesize,nameofs; char line[512]; char *instr,*params; int i,pass,size; int16_t count; symbol *sym; symbol **nativelist; constvalue *constptr; cell mainaddr; char nullchar; #if !defined NDEBUG /* verify that the opcode list is sorted (skip entry 1; it is reserved * for a non-existant opcode) */ { #define MAX_OPCODE 176 unsigned char opcodearray[MAX_OPCODE+1]; assert(opcodelist[1].name!=NULL); memset(opcodearray,0,sizeof opcodearray); for (i=2; i<(sizeof opcodelist / sizeof opcodelist[0]); i++) { assert(opcodelist[i].name!=NULL); assert(stricmp(opcodelist[i].name,opcodelist[i-1].name)>0); /* also verify that no opcode number appears twice */ assert((int)opcodelist[i].opcode<=MAX_OPCODE); assert(opcodelist[i].opcode==0 || opcodearray[(int)opcodelist[i].opcode]==0); opcodearray[(int)opcodelist[i].opcode] += 1; } /* for */ } #endif writeerror=FALSE; nametablesize=sizeof(int16_t); numpublics=0; numnatives=0; numpubvars=0; numoverlays=0; mainaddr=-1; /* count number of public and native functions and public variables */ for (sym=glbtab.next; sym!=NULL; sym=sym->next) { int match=0; if (sym->ident==iFUNCTN) { if ((sym->usage & uNATIVE)!=0 && (sym->usage & uREAD)!=0 && sym->index>=0) match=++numnatives; if ((sym->usage & uPUBLIC)!=0 && (sym->usage & uDEFINE)!=0) match=++numpublics; if (pc_overlays>0 && (sym->usage & uNATIVE)==0 && (sym->usage & (uREAD | uPUBLIC))!=0 && (sym->usage & uDEFINE)!=0) { if (strcmp(sym->name,uENTRYFUNC)!=0) ++numoverlays; /* there is no stub function for state entry functions */ if (sym->states!=NULL) { /* for functions with states, write an overlay block for every implementation */ statelist *stlist; for (stlist=sym->states->next; stlist!=NULL; stlist=stlist->next) ++numoverlays; } /* if */ } /* if */ if (strcmp(sym->name,uMAINFUNC)==0) { assert(sym->vclass==sGLOBAL); mainaddr=(pc_overlays>0) ? sym->index : sym->addr; } /* if */ } else if (sym->ident==iVARIABLE) { if ((sym->usage & uPUBLIC)!=0 && (sym->usage & (uREAD | uWRITTEN))!=0) match=++numpubvars; } /* if */ if (match) { char alias[sNAMEMAX+1]; assert(sym!=NULL); if ((sym->usage & uNATIVE)==0 || !lookup_alias(alias,sym->name)) { assert(strlen(sym->name)<=sNAMEMAX); strcpy(alias,sym->name); } /* if */ nametablesize+=(int)strlen(alias)+1; } /* if */ } /* for */ assert(numnatives==ntv_funcid); /* count number of libraries */ numlibraries=0; if (pc_addlibtable) { for (constptr=libname_tab.next; constptr!=NULL; constptr=constptr->next) { if (constptr->value>0) { assert(strlen(constptr->name)>0); numlibraries++; nametablesize+=(int)strlen(constptr->name)+1; } /* if */ } /* for */ } /* if */ /* count number of public tags */ numtags=0; for (constptr=tagname_tab.next; constptr!=NULL; constptr=constptr->next) { if ((constptr->value & PUBLICTAG)!=0) { assert(strlen(constptr->name)>0); numtags++; nametablesize+=(int)strlen(constptr->name)+1; } /* if */ } /* for */ /* adjust the number of overlays by the special overlays */ if (pc_overlays>0) for (i=0; i<ovlFIRST; i++) if (pc_ovl0size[i][1]!=0) numoverlays++; /* pad the header to sc_dataalign * => thereby the code segment is aligned * => since the code segment is padded to a sc_dataalign boundary, the data segment is aligned * => and thereby the stack top is aligned too */ assert(sc_dataalign!=0); padding= (int)(sc_dataalign - (sizeof hdr + nametablesize) % sc_dataalign); if (padding==sc_dataalign) padding=0; /* write the abstract machine header */ memset(&hdr, 0, sizeof hdr); if (pc_cellsize==2) hdr.magic=(unsigned short)AMX_MAGIC_16; else if (pc_cellsize==4) hdr.magic=(unsigned short)AMX_MAGIC_32; else if (pc_cellsize==8) hdr.magic=(unsigned short)AMX_MAGIC_64; hdr.file_version=CUR_FILE_VERSION; hdr.amx_version=MIN_AMX_VERSION; hdr.flags=(short)(sc_debug & sSYMBOLIC); if (sc_debug==0) hdr.flags|=AMX_FLAG_NOCHECKS; if (pc_memflags & suSLEEP_INSTR) hdr.flags|=AMX_FLAG_SLEEP; if (pc_overlays>0) hdr.flags|=AMX_FLAG_OVERLAY; if (pc_cryptkey!=0) hdr.flags|=AMX_FLAG_CRYPT; hdr.defsize=sizeof(AMX_FUNCSTUB); hdr.publics=sizeof hdr; /* public table starts right after the header */ hdr.natives=hdr.publics + numpublics*sizeof(AMX_FUNCSTUB); hdr.libraries=hdr.natives + numnatives*sizeof(AMX_FUNCSTUB); hdr.pubvars=hdr.libraries + numlibraries*sizeof(AMX_FUNCSTUB); hdr.tags=hdr.pubvars + numpubvars*sizeof(AMX_FUNCSTUB); hdr.overlays=hdr.tags + numtags*sizeof(AMX_FUNCSTUB); hdr.nametable=hdr.overlays + numoverlays*sizeof(AMX_OVERLAYINFO); hdr.cod=hdr.nametable + nametablesize + padding; hdr.dat=(int32_t)(hdr.cod + code_idx); hdr.hea=(int32_t)(hdr.dat + glb_declared*pc_cellsize); hdr.stp=(int32_t)(hdr.hea + pc_stksize*pc_cellsize); hdr.cip=(int32_t)(mainaddr); hdr.size=hdr.hea; pc_writebin(fout,&hdr,sizeof hdr); /* dump zeros up to the rest of the header, so that we can easily "seek" */ nullchar='\0'; for (nameofs=sizeof hdr; nameofs<hdr.cod; nameofs++) pc_writebin(fout,&nullchar,1); nameofs=hdr.nametable+sizeof(int16_t); /* write the public functions table */ count=0; for (sym=glbtab.next; sym!=NULL; sym=sym->next) { if (sym->ident==iFUNCTN && (sym->usage & uPUBLIC)!=0 && (sym->usage & uDEFINE)!=0) { assert(sym->vclass==sGLOBAL); /* in the case of overlays, write the overlay index rather than the address */ func.address=(uint32_t)((pc_overlays>0) ? sym->index : sym->addr); func.nameofs=nameofs; #if BYTE_ORDER==BIG_ENDIAN align32(&func.address); align32(&func.nameofs); #endif pc_resetbin(fout,hdr.publics+count*sizeof(AMX_FUNCSTUB)); pc_writebin(fout,&func,sizeof func); pc_resetbin(fout,nameofs); pc_writebin(fout,sym->name,(int)strlen(sym->name)+1); nameofs+=(int)strlen(sym->name)+1; count++; } /* if */ } /* for */ /* write the natives table */ /* The native functions must be written in sorted order. (They are * sorted on their "id", not on their name). A nested loop to find * each successive function would be an O(n^2) operation. But we * do not really need to sort, because the native function id's * are sequential and there are no duplicates. So we first walk * through the complete symbol list and store a pointer to every * native function of interest in a temporary table, where its id * serves as the index in the table. Now we can walk the table and * have all native functions in sorted order. */ if (numnatives>0) { nativelist=(symbol **)malloc(numnatives*sizeof(symbol *)); if (nativelist==NULL) error(103); /* insufficient memory */ #if !defined NDEBUG memset(nativelist,0,numnatives*sizeof(symbol *)); /* for NULL checking */ #endif for (sym=glbtab.next; sym!=NULL; sym=sym->next) { if (sym->ident==iFUNCTN && (sym->usage & uNATIVE)!=0 && (sym->usage & uREAD)!=0 && sym->index>=0) { assert(sym->index < numnatives); nativelist[(int)sym->index]=sym; } /* if */ } /* for */ count=0; for (i=0; i<numnatives; i++) { char alias[sNAMEMAX+1]; sym=nativelist[i]; assert(sym!=NULL); if (!lookup_alias(alias,sym->name)) { assert(strlen(sym->name)<=sNAMEMAX); strcpy(alias,sym->name); } /* if */ assert(sym->vclass==sGLOBAL); func.address=0; func.nameofs=nameofs; #if BYTE_ORDER==BIG_ENDIAN align32(&func.address); align32(&func.nameofs); #endif pc_resetbin(fout,hdr.natives+count*sizeof(AMX_FUNCSTUB)); pc_writebin(fout,&func,sizeof func); pc_resetbin(fout,nameofs); pc_writebin(fout,alias,(int)strlen(alias)+1); nameofs+=(int)strlen(alias)+1; count++; } /* for */ free(nativelist); } /* if */ /* write the libraries table */ if (pc_addlibtable) { count=0; for (constptr=libname_tab.next; constptr!=NULL; constptr=constptr->next) { if (constptr->value>0) { assert(strlen(constptr->name)>0); func.address=0; func.nameofs=nameofs; #if BYTE_ORDER==BIG_ENDIAN align32(&func.address); align32(&func.nameofs); #endif pc_resetbin(fout,hdr.libraries+count*sizeof(AMX_FUNCSTUB)); pc_writebin(fout,&func,sizeof func); pc_resetbin(fout,nameofs); pc_writebin(fout,constptr->name,(int)strlen(constptr->name)+1); nameofs+=(int)strlen(constptr->name)+1; count++; } /* if */ } /* for */ } /* if */ /* write the public variables table */ count=0; for (sym=glbtab.next; sym!=NULL; sym=sym->next) { if (sym->ident==iVARIABLE && (sym->usage & uPUBLIC)!=0 && (sym->usage & (uREAD | uWRITTEN))!=0) { assert((sym->usage & uDEFINE)!=0); assert(sym->vclass==sGLOBAL); func.address=(uint32_t)sym->addr; func.nameofs=nameofs; #if BYTE_ORDER==BIG_ENDIAN align32(&func.address); align32(&func.nameofs); #endif pc_resetbin(fout,hdr.pubvars+count*sizeof(AMX_FUNCSTUB)); pc_writebin(fout,&func,sizeof func); pc_resetbin(fout,nameofs); pc_writebin(fout,sym->name,(int)strlen(sym->name)+1); nameofs+=(int)strlen(sym->name)+1; count++; } /* if */ } /* for */ /* write the public tagnames table */ count=0; for (constptr=tagname_tab.next; constptr!=NULL; constptr=constptr->next) { if ((constptr->value & PUBLICTAG)!=0) { assert(strlen(constptr->name)>0); func.address=(uint32_t)(constptr->value & TAGMASK); func.nameofs=nameofs; #if BYTE_ORDER==BIG_ENDIAN align32(&func.address); align32(&func.nameofs); #endif pc_resetbin(fout,hdr.tags+count*sizeof(AMX_FUNCSTUB)); pc_writebin(fout,&func,sizeof func); pc_resetbin(fout,nameofs); pc_writebin(fout,constptr->name,(int)strlen(constptr->name)+1); nameofs+=(int)strlen(constptr->name)+1; count++; } /* if */ } /* for */ /* write the "maximum name length" field in the name table */ assert(nameofs==hdr.nametable+nametablesize); pc_resetbin(fout,hdr.nametable); count=sNAMEMAX; #if BYTE_ORDER==BIG_ENDIAN align16(&count); #endif pc_writebin(fout,&count,sizeof count); /* write the overlay table */ if (pc_overlays>0) { AMX_OVERLAYINFO info; #if !defined NDEBUG int count=0; #endif pc_resetbin(fout,hdr.overlays); /* first the special overlay(s) for the return point(s) */ for (i=0; i<ovlFIRST; i++) { if (pc_ovl0size[i][1]!=0) { info.offset=pc_ovl0size[i][0]; info.size=pc_ovl0size[i][1]; #if BYTE_ORDER==BIG_ENDIAN align32(&info.offset); align32(&info.size); #endif pc_writebin(fout,&info,sizeof info); #if !defined NDEBUG count++; #endif } /* if */ } /* for */ /* now all real overlay functions */ for (sym=glbtab.next; sym!=NULL; sym=sym->next) { if (sym->ident==iFUNCTN && (sym->usage & uNATIVE)==0 && (sym->usage & (uREAD | uPUBLIC))!=0 && (sym->usage & uDEFINE)!=0) { assert(sym->vclass==sGLOBAL); assert(strcmp(sym->name,uENTRYFUNC)==0 || sym->index==count++);/* overlay indices must be in sequential order */ assert(strcmp(sym->name,uENTRYFUNC)==0 || sym->addr<sym->codeaddr); /* write the overlay for the stub function first */ if (strcmp(sym->name,uENTRYFUNC)!=0) { /* there is no stub function for state entry functions */ info.offset=(int32_t)sym->addr; info.size=(uint32_t)(sym->codeaddr - sym->addr); #if BYTE_ORDER==BIG_ENDIAN align32(&info.offset); align32(&info.size); #endif pc_writebin(fout,&info,sizeof info); } /* if */ if (sym->states!=NULL) { /* for functions with states, write an overlay block for every implementation */ statelist *stlist; for (stlist=sym->states->next; stlist!=NULL; stlist=stlist->next) { assert(stlist->label==count++); info.offset=(int32_t)stlist->addr; info.size=(int32_t)(stlist->endaddr - stlist->addr); #if BYTE_ORDER==BIG_ENDIAN align32(&info.offset); align32(&info.size); #endif pc_writebin(fout,&info,sizeof info); } /* for */ } /* if */ } /* if */ } /* for */ } /* if */ pc_resetbin(fout,hdr.cod); /* First pass: relocate all labels */ /* This pass is necessary because the code addresses of labels is only known * after the peephole optimization flag. Labels can occur inside expressions * (e.g. the conditional operator), which are optimized. */ lbltab=NULL; if (sc_labnum>0) { cell codeindex=0; /* address of the current opcode similar to "code_idx" */ /* only very short programs have zero labels; no first pass is needed * if there are no labels */ lbltab=(cell *)malloc(sc_labnum*sizeof(cell)); if (lbltab==NULL) error(103); /* insufficient memory */ memset(lbltab,0,sc_labnum*sizeof(cell)); pc_resetasm(fin); while (pc_readasm(fin,line,sizeof line)!=NULL) { stripcomment(line); instr=skipwhitespace(line); /* ignore empty lines */ if (*instr=='\0') continue; if (tolower(*instr)=='l' && *(instr+1)=='.') { int lindex=(int)hex2ucell(instr+2,NULL); assert(lindex>=0 && lindex<sc_labnum); assert(lbltab[lindex]==0); /* should not already be declared */ lbltab[lindex]=codeindex; } else { /* get to the end of the instruction (make use of the '\n' that fgets() * added at the end of the line; this way we will *always* drop on a * whitespace character) */ for (params=instr; *params!='\0' && !isspace(*params); params++) /* nothing */; assert(params>instr); i=findopcode(instr,(int)(params-instr)); assert(opcodelist[i].name!=NULL); assert(opcodelist[i].opt_level<=pc_optimize || pc_optimize==0 && opcodelist[i].opt_level<=1); if (opcodelist[i].segment==sIN_CSEG) codeindex+=opcodelist[i].func(NULL,skipwhitespace(params),opcodelist[i].opcode,codeindex); } /* if */ } /* while */ } /* if */ /* Second pass (actually 2 more passes, one for all code and one for all data) */ for (pass=sIN_CSEG; pass<=sIN_DSEG; pass++) { cell codeindex=0; /* address of the current opcode similar to "code_idx" */ pc_resetasm(fin); while (pc_readasm(fin,line,sizeof line)!=NULL) { stripcomment(line); instr=skipwhitespace(line); /* ignore empty lines and labels (labels have a special syntax, so these * must be parsed separately) */ if (*instr=='\0' || tolower(*instr)=='l' && *(instr+1)=='.') continue; /* get to the end of the instruction (make use of the '\n' that fgets() * added at the end of the line; this way we will *always* drop on a * whitespace character) */ for (params=instr; *params!='\0' && !isspace(*params); params++) /* nothing */; assert(params>instr); i=findopcode(instr,(int)(params-instr)); assert(opcodelist[i].name!=NULL); assert(opcodelist[i].opt_level<=pc_optimize || pc_optimize==0 && opcodelist[i].opt_level<=1); if (opcodelist[i].segment==pass) codeindex+=opcodelist[i].func(fout,skipwhitespace(params),opcodelist[i].opcode,codeindex); } /* while */ } /* for */ if (lbltab!=NULL) { free(lbltab); #if !defined NDEBUG lbltab=NULL; #endif } /* if */ assert(hdr.size==pc_lengthbin(fout)); if (!writeerror && (sc_debug & sSYMBOLIC)!=0) append_dbginfo(fout); /* optionally append debug file */ if (writeerror) error(101,"disk full"); /* adjust the header (for Big Endian architectures) */ size=(int)hdr.cod; /* save, the value in the header may need to be swapped */ #if BYTE_ORDER==BIG_ENDIAN align32(&hdr.size); align16(&hdr.magic); align16(&hdr.flags); align16(&hdr.defsize); align32(&hdr.publics); align32(&hdr.natives); align32(&hdr.libraries); align32(&hdr.pubvars); align32(&hdr.tags); align32(&hdr.nametable); align32(&hdr.cod); align32(&hdr.dat); align32(&hdr.hea); align32(&hdr.stp); align32(&hdr.cip); pc_resetbin(fout,0); pc_writebin(fout,&hdr,sizeof hdr); #endif /* return the size of the header (including name tables, but excluding code * or data sections) */ return size; }
static void append_dbginfo(FILE *fout) { AMX_DBG_HDR dbghdr; AMX_DBG_LINE dbgline; AMX_DBG_SYMBOL dbgsym; AMX_DBG_SYMDIM dbgidxtag[sDIMEN_MAX]; int index,dim,dbgsymdim; const char *str,*prevstr,*name,*prevname; ucell codeidx,previdx; constvalue *constptr; char symname[2*sNAMEMAX+16]; int16_t id1,id2; ucell address; /* header with general information */ memset(&dbghdr, 0, sizeof dbghdr); dbghdr.size=sizeof dbghdr; dbghdr.magic=AMX_DBG_MAGIC; dbghdr.file_version=CUR_FILE_VERSION; dbghdr.amx_version=MIN_AMX_VERSION; /* first pass: collect the number of items in various tables */ /* file table */ previdx=0; prevstr=NULL; prevname=NULL; for (index=0; (str=get_dbgstring(index))!=NULL; index++) { assert(str!=NULL); assert(str[0]!='\0' && str[1]==':'); if (str[0]=='F') { codeidx=hex2ucell(str+2,&name); if (codeidx!=previdx) { if (prevstr!=NULL) { assert(prevname!=NULL); dbghdr.files++; dbghdr.size+=(int32_t)(sizeof(AMX_DBG_FILE)+strlen(prevname)); } /* if */ previdx=codeidx; } /* if */ prevstr=str; prevname=skipwhitespace(name); } /* if */ } /* for */ if (prevstr!=NULL) { assert(prevname!=NULL); dbghdr.files++; dbghdr.size+=(int32_t)(sizeof(AMX_DBG_FILE)+strlen(prevname)); } /* if */ /* line number table */ for (index=0; (str=get_dbgstring(index))!=NULL; index++) { assert(str!=NULL); assert(str[0]!='\0' && str[1]==':'); if (str[0]=='L') { dbghdr.lines++; dbghdr.size+=sizeof(AMX_DBG_LINE); } /* if */ } /* for */ /* symbol table */ for (index=0; (str=get_dbgstring(index))!=NULL; index++) { assert(str!=NULL); assert(str[0]!='\0' && str[1]==':'); if (str[0]=='S') { dbghdr.symbols++; str=strchr(str+2,':'); assert(str!=NULL); name=skipwhitespace(str+1); str=strchr(name,' '); assert(str!=NULL); assert((int)(str-name)<sizeof symname); strlcpy(symname,name,(int)(str-name)+1); dbghdr.size+=(int32_t)(sizeof(AMX_DBG_SYMBOL)+strlen(symname)); if ((prevstr=strchr(name,'['))!=NULL) while ((prevstr=strchr(prevstr+1,':'))!=NULL) dbghdr.size+=sizeof(AMX_DBG_SYMDIM); } /* if */ } /* for */ /* tag table */ for (constptr=tagname_tab.next; constptr!=NULL; constptr=constptr->next) { assert(strlen(constptr->name)>0); dbghdr.tags++; dbghdr.size+=(int32_t)(sizeof(AMX_DBG_TAG)+strlen(constptr->name)); } /* for */ /* automaton table */ for (constptr=sc_automaton_tab.next; constptr!=NULL; constptr=constptr->next) { assert(constptr->index==0 && strlen(constptr->name)==0 || strlen(constptr->name)>0); dbghdr.automatons++; dbghdr.size+=(int32_t)(sizeof(AMX_DBG_MACHINE)+strlen(constptr->name)); } /* for */ /* state table */ for (constptr=sc_state_tab.next; constptr!=NULL; constptr=constptr->next) { assert(strlen(constptr->name)>0); dbghdr.states++; dbghdr.size+=(int32_t)(sizeof(AMX_DBG_STATE)+strlen(constptr->name)); } /* for */ /* pass 2: generate the tables */ #if BYTE_ORDER==BIG_ENDIAN align32((uint32_t*)&dbghdr.size); align16(&dbghdr.magic); align16(&dbghdr.flags); align16(&dbghdr.files); align16(&dbghdr.lines); align16(&dbghdr.symbols); align16(&dbghdr.tags); align16(&dbghdr.automatons); align16(&dbghdr.states); #endif writeerror |= !pc_writebin(fout,&dbghdr,sizeof dbghdr); /* file table */ previdx=0; prevstr=NULL; prevname=NULL; for (index=0; (str=get_dbgstring(index))!=NULL; index++) { assert(str!=NULL); assert(str[0]!='\0' && str[1]==':'); if (str[0]=='F') { codeidx=hex2ucell(str+2,&name); if (codeidx!=previdx) { if (prevstr!=NULL) { assert(prevname!=NULL); #if BYTE_ORDER==BIG_ENDIAN align32(&previdx); #endif writeerror |= !pc_writebin(fout,&previdx,sizeof(uint32_t)); writeerror |= !pc_writebin(fout,prevname,(int)strlen(prevname)+1); } /* if */ previdx=codeidx; } /* if */ prevstr=str; prevname=skipwhitespace(name); } /* if */ } /* for */ if (prevstr!=NULL) { assert(prevname!=NULL); #if BYTE_ORDER==BIG_ENDIAN align32(&previdx); #endif writeerror |= !pc_writebin(fout,&previdx,sizeof(uint32_t)); writeerror |= !pc_writebin(fout,prevname,(int)strlen(prevname)+1); } /* if */ /* line number table */ for (index=0; (str=get_dbgstring(index))!=NULL; index++) { assert(str!=NULL); assert(str[0]!='\0' && str[1]==':'); if (str[0]=='L') { dbgline.address=(uint32_t)hex2ucell(str+2,&str); dbgline.line=(int32_t)hex2ucell(str,NULL); #if BYTE_ORDER==BIG_ENDIAN align32(&dbgline.address); align32(&dbgline.line); #endif writeerror |= !pc_writebin(fout,&dbgline,sizeof dbgline); } /* if */ } /* for */ /* symbol table */ for (index=0; (str=get_dbgstring(index))!=NULL; index++) { assert(str!=NULL); assert(str[0]!='\0' && str[1]==':'); if (str[0]=='S') { dbgsym.address=(uint32_t)hex2ucell(str+2,&str); dbgsym.tag=(int16_t)hex2ucell(str,&str); str=skipwhitespace(str); assert(*str==':'); name=skipwhitespace(str+1); str=strchr(name,' '); assert(str!=NULL); assert((int)(str-name)<sizeof symname); strlcpy(symname,name,(int)(str-name)+1); dbgsym.codestart=(uint32_t)hex2ucell(str,&str); dbgsym.codeend=(uint32_t)hex2ucell(str,&str); dbgsym.ident=(char)hex2ucell(str,&str); dbgsym.vclass=(char)hex2ucell(str,&str); dbgsym.dim=0; str=skipwhitespace(str); if (*str=='[') { while (*(str=skipwhitespace(str+1))!=']') { dbgidxtag[dbgsym.dim].size=(uint32_t)hex2ucell(str,&str); dbgsym.dim++; } /* while */ } /* if */ dbgsymdim = dbgsym.dim; #if BYTE_ORDER==BIG_ENDIAN align32(&dbgsym.address); align16(&dbgsym.tag); align32(&dbgsym.codestart); align32(&dbgsym.codeend); align16(&dbgsym.dim); #endif writeerror |= !pc_writebin(fout,&dbgsym.address,sizeof dbgsym.codeend); writeerror |= !pc_writebin(fout,&dbgsym.tag,sizeof dbgsym.tag); writeerror |= !pc_writebin(fout,&dbgsym.codestart,sizeof dbgsym.codeend); writeerror |= !pc_writebin(fout,&dbgsym.codeend,sizeof dbgsym.codeend); writeerror |= !pc_writebin(fout,&dbgsym.ident,sizeof dbgsym.ident); writeerror |= !pc_writebin(fout,&dbgsym.vclass,sizeof dbgsym.vclass); writeerror |= !pc_writebin(fout,&dbgsym.dim,sizeof dbgsym.dim); writeerror |= !pc_writebin(fout,symname,(int)strlen(symname)+1); for (dim=0; dim<dbgsymdim; dim++) { #if BYTE_ORDER==BIG_ENDIAN align16(&dbgidxtag[dim].tag); align32(&dbgidxtag[dim].size); #endif writeerror |= !pc_writebin(fout,&dbgidxtag[dim].tag,sizeof dbgidxtag[dim].tag); writeerror |= !pc_writebin(fout,&dbgidxtag[dim].size,sizeof dbgidxtag[dim].size); } /* for */ } /* if */ } /* for */ /* tag table */ for (constptr=tagname_tab.next; constptr!=NULL; constptr=constptr->next) { assert(strlen(constptr->name)>0); id1=(int16_t)(constptr->value & TAGMASK); #if BYTE_ORDER==BIG_ENDIAN align16(&id1); #endif writeerror |= !pc_writebin(fout,&id1,sizeof id1); writeerror |= !pc_writebin(fout,constptr->name,(int)strlen(constptr->name)+1); } /* for */ /* automaton table */ for (constptr=sc_automaton_tab.next; constptr!=NULL; constptr=constptr->next) { assert(constptr->index==0 && strlen(constptr->name)==0 || strlen(constptr->name)>0); id1=(int16_t)constptr->index; address=(ucell)constptr->value; #if BYTE_ORDER==BIG_ENDIAN align16(&id1); align32(&address); #endif writeerror |= !pc_writebin(fout,&id1,sizeof id1); writeerror |= !pc_writebin(fout,&address,sizeof(uint32_t)); writeerror |= !pc_writebin(fout,constptr->name,(int)strlen(constptr->name)+1); } /* for */ /* state table */ for (constptr=sc_state_tab.next; constptr!=NULL; constptr=constptr->next) { assert(strlen(constptr->name)>0); id1=(int16_t)constptr->value; id2=(int16_t)constptr->index; address=(ucell)constptr->value; #if BYTE_ORDER==BIG_ENDIAN align16(&id1); align16(&id2); #endif writeerror |= !pc_writebin(fout,&id1,sizeof id1); writeerror |= !pc_writebin(fout,&id2,sizeof id2); writeerror |= !pc_writebin(fout,constptr->name,(int)strlen(constptr->name)+1); } /* for */ delete_dbgstringtable(); }
static void* main_thread_function(void*) { u32 level, real_heap_size; // hope the parms are all set by now COM_InitArgv(parms_number, parms_array); _CPU_ISR_Disable(level); heap = (char *)align32(SYS_GetArena2Lo()); real_heap_size = heap_size - ((u32)heap - (u32)SYS_GetArena2Lo()); if ((u32)heap + real_heap_size > (u32)SYS_GetArena2Hi()) { _CPU_ISR_Restore(level); Sys_Error("heap + real_heap_size > (u32)SYS_GetArena2Hi()"); } else { SYS_SetArena2Lo(heap + real_heap_size); _CPU_ISR_Restore(level); } VIDEO_SetBlack(TRUE); // Initialise the Host module. quakeparms_t parms; memset(&parms, 0, sizeof(parms)); parms.argc = com_argc; parms.argv = com_argv; parms.basedir = QUAKE_WII_BASEDIR; parms.memsize = real_heap_size; parms.membase = heap; if (parms.membase == 0) { Sys_Error("Heap allocation failed"); } memset(parms.membase, 0, parms.memsize); Host_Init(&parms); #if TIME_DEMO Cbuf_AddText("map start\n"); Cbuf_AddText("wait\n"); Cbuf_AddText("timedemo demo1\n"); #endif #if TEST_CONNECTION Cbuf_AddText("connect 192.168.0.2"); #endif SYS_SetResetCallback(reset_system); SYS_SetPowerCallback(shutdown_system); VIDEO_SetBlack(FALSE); // Run the main loop. u64 last_time = gettime(); for (;;) { if (want_to_reset) Sys_Reset(); if (want_to_shutdown) Sys_Shutdown(); // Get the frame time in ticks. const u64 current_time = gettime(); const u64 time_delta = current_time - last_time; const double seconds = time_delta * (0.001f / TB_TIMER_CLOCK); last_time = current_time; // Run the frame. Host_Frame(seconds); }; // Quit (this code is never reached). Sys_Quit(); return 0; }
size_t head_len, block_len, tail_len; // process small block if ( size < 32 ) { ptr8 = (uint8_t *)data; for ( i = 0; i < size; ++i ) ptr8[i] = getNext() >> 23; // use high 8 bits of 31-bit word return; } // arrange to 32-bit boundary ptr8 = (uint8_t *)data; head_len = align32(data); size -= head_len; for ( i = 0; i < head_len; ++i ) { ptr8[i] = getNext() >> 23; // use high 8 bits of 31-bit word } // We must take in account that generator makes 31bit values. Therefore we // have to add one bit to each word. Generation of 2 values for each 32bit // word doubles the work. To avoid this we'll generate only 1 extra word for // each 8 words and unroll the main cycle. ptr32 = (uint32_t *)(ptr8 + head_len); block_len = (size >> 5) << 3; // in 32bit words, multiply of 8 words size -= block_len << 2;