// SH2A monitor monitor.c // Copyright Bitcraft Co.Ltd 2011.5.4 // All rights reserved. // //#include "iodefine.h" // gcc に移行準備のため、iodefine.h は使わない //#include #include "sh7262.h" // 追加ファイル SH7262の内部I/Oアドレス設定 #include "monitor.h" // 追加ファイル。モニタで使う定数や、プロトタイプ宣言など int combuf2f; char combuf[COLUMN]; // コマンド入力バッファー char combuf2[COLUMN]; // 前回のコマンド記憶 int combuf2f; // 前回のコマンドを有効にするフラグとポインタ union param32 param[16]; // 引数格納 int sdversion; // SD card V1 or V2 int ts,te; // 時間測定 int encrc; // 1で、CRC 計算を有効にする。 unsigned char *sddbuf; unsigned char response[16]; // unsigned char csdbuf[24]; // unsigned char cidbuf[24]; // union param32 cmdbuf[3]; // CMD 格納 // モニタ用RS232CのBIOS // 1文字送信 void putcon(int c) { while(1) { if(*SCFSR3 & 0x20) break; } *SCFTDR3 = (char)c; *SCFSR3 &= 0xFFDF; } // 1文字受信するまで待つ int getcon(void) { unsigned int read; while(1) { if(*SCFSR3 & 0x2) break; } read = *SCFRDR3; *SCFSR3 &= 0xFFFD; return read; } // 1文字受信したかのチェック //モニタを実行中、処理を中断したい場合、処理のループ内で呼び出す。 // 1 をリターンすると、getcon() で受信文字を確かめ、中断か、否かを判定。 int statcon(void) { int stat; stat = *SCFSR3; *SCFSR3 = stat & 0x0063; if(stat & 2) return 1; return 0; } // 以下、最後までが、モニタの本体。 // デバッグ用整数書式出力、cprintf,csprintf は、最後に置く。 void cprintf();// printf の簡易版。整数、文字列のみ int csprintf();// sprintf の簡易版。整数、文字列のみ int mainmoni (int mode) // mode は割り込みなどの場合に使う予定 { int ret,spacef; char *comp,c;//*cp; // int coma; int i,j,l; // int *lsp,*ldp; // int pret; encrc=1; combuf2f=0; combuf2[0] = 0; putscon("\r\nCustom Monitor 2011.7.8\r\n"); while(1) { LOOP: putscon("SH2A-Bug>"); ret=getscon(combuf,COLUMN-1,0); if(ret == 0) { if(combuf2[0]) // 前回のコマンド記憶の先頭 { combuf2f = 1; ret = getscon(combuf,COLUMN - 1,0); if(ret == -1) { crlf(); goto LOOP; } spacef = cpynstr(combuf2,combuf,COLUMN); // コマンド記憶 } } else { if(ret == -1) { crlf(); goto LOOP; } spacef = cpynstr(combuf2,combuf,COLUMN); // memory command } comp=combuf; c= *comp; // コマンド解析。最初の1文字で判定し、続く引数(ヘキサ限定)をチェック。 if((spacef & 0x1000) == 0) switch(c) { // メモリダンプ。モトローラSレコードのダンプも選択できる。( dsx,y ) case 'd': j=0; comp++; param[2].l32 = 0; if((*comp=='S')||(*comp=='s')) // モトローラSレコードでダンプするオプション判定。 { j |= 1; comp++; } if(*comp ==0)// 引数なしは、前回ダンプしたアドレスの次をダンプする。 { l = param[1].l32 - param[0].l32 + 1; l &= 0xfffffffe; param[0].l32 += l; param[1].l32 += l; } else { if((i=argck(&comp,param,1))== -1) { paramer(); break; } if(i==1) { param[1].l32=param[0].l32+0x7f; } } dumpm(param,j); break; // メモリのコピー case 'm': j=0; comp++; if((*comp=='W')||(*comp=='w')) { j=1; comp++; } else if((*comp=='L')||(*comp=='l')) { j=2; comp++; } param[3].l32 = 0x11;// ソース、デスティネーションアドレス更新 if((i=argck(&comp,param,3)) < 3) { paramer(); break; } ts = *CMCNT0; movem(param,(long)j); te = *CMCNT0; break; // メモリの比較。ここでは、バイト単位のみ // case 'V': case 'v': comp++; if((i=argck(&comp,param,3)) != 3) { paramer(); break; } ts = *CMCNT0; verify(param); te = *CMCNT0; break; // いわゆる、フィルメモリ。s コマンドで代用可能なので、割愛。 /* case 'F':// フィルメモリ comp++; if((i=argck(&comp,param,5)) != 5) { paramer(); break; } ts = *CMCNT0; fillp(param); te = *CMCNT0; break; */ // 4バイトまでのデータ列をメモリにあるかを検索。 case 'f': comp++; if((i=argck(&comp,param,4)) != 4) { paramer(); break; } ts = *CMCNT0; findp(param); te = *CMCNT0; break; // 任意番地をサブルーチン形式で呼び出す。 case 'g': comp++; if((i=argck(&comp,param,1))== -1) { paramer(); break; } ts = *CMCNT0; ret = param[0].ppoint(); // ret = gosub((union param32)param[0].l32);// アセンブラ呼び出しの場合 te = *CMCNT0; cprintf("\r\nret= %08lX",ret); break; // ホストから送られてくるモトローラSレコード形式のヘキサデータを、アドレス指定でメモリにロード // 元のアドレス情報に、バイアス値を加算できる。 // case 'L': case 'l': j=0; comp++; if((i=argck(&comp,param,1))== -1) { paramer(); break; } crlf(); srload(param,1); break; // メモリ(I/O)を、バイト、ワード、ロング単位を指定して、インタラクティブに表示、変更。 // 引数の指示で、フィルメモリなどもできる。 case 's': j=0; comp++; if((*comp=='N')||(*comp == 'n'))// このオプションは、元のメモリ(I/O)を読まずに変更。 { j=4; comp++; } if((*comp=='W')||(*comp=='w'))// 16ビット単位 { j |= 1; comp++; } else if((*comp=='L')||(*comp=='l'))// 32ビット単位 { j |= 2; comp++; } // デフォルトの引数オプションを初期設定 param[2].l32 = 1; param[3].l32 = 0; param[4].l32 = 0; param[5].l32 = 0; param[6].l32 = 0; // param[7].l32 = 0; if((i=argck(&comp,param,1))== -1) { paramer(); break; } ts = *CMCNT0;// インタラクティブの場合は、あまり意味がない。 setmemo(param,j,i); te = *CMCNT0; break; // case 'D':// dhry stone テスト // l = dhrymain(); // cprintf("\r\nTimer HEX = %lX,",l); // l *= 2133; // l /= 100; // cprintf("%d μs",l); // break; case 'S': j = 0; comp++; if(*comp == 'i') { comp++; ret = sdctl(param,3); encrc = 0; mmcclk(0); cprintf("\r\nstop CRC check( dscrc ), SPI speed 24MHz ( clkspeed 0 )"); break; } if(*comp == 'r') { comp++; ret = argck(&comp,param,3); if(ret < 3) { putscon("\r\nSr start,memory,sectors"); break; } if(param[2].l32 > 0x400) { putscon("\r\nsectors must lower 0x401"); break; } ret = sdctl(param,1); break; } if(*comp == 'w') { comp++; ret = argck(&comp,param,3); if(ret < 3) { putscon("\r\nSr start,memory,sectors"); break; } if(param[2].l32 > 0x400) { putscon("\r\nsectors must lower 0x401"); break; } ret = sdctl(param,2); break; } if(*comp == 'R') { comp++; param[3].l32 = 0x20;// default 32 sector ret = argck(&comp,param,3); if(ret < 3) { putscon("\r\nSr start,memory,sectors"); break; } if(param[2].l32 > 0x400) { putscon("\r\nsectors must lower 0x401"); break; } ret = sdctl(param,4); break; } break; /* case 'S':// エラトステネスのふるいで、素数を求めたときの実行時間 ts = *CMCNT0; ret = sievemain(); te = *CMCNT0; cprintf("sieve=%ld ",ret); l=te-ts; cprintf("\r\nTimer HEX = %lX,",l); l *= 2133; l /= 100; cprintf(" time = %ld μs",l); break; */ case 'T': l=te-ts; cprintf("\r\nTimer HEX = %lX, ",l); l *= 2133; l /= 100; cprintf("%ld μs",l); crlf(); break; case 'i': j = 0; comp++; if(*comp == 'i') { j = 1; comp++; } param[0].l32 = 0; if((i=argck(&comp,param,1))== -1) { paramer(); break; } if(j) param[0].l32 = -1; switch(param[0].l32) { case -1: l = initmmc(0); cprintf("\r\ninit_spiport return = %04X",l); break; case 0: case 1: case 8: l = mmcout(param[0].l32); cprintf("\r\noutcmd_spdlow return = %04X",l); break; case 0xFF: l = mmcout(0xff); cprintf("\r\noutspi_spdlow return = %04X",l); break; } break; default: // 未定義コマンド cprintf("default"); break; } else { ret = checkcommand(combuf,param,ret); // ckeck command SD CARD etc. if(ret != NOTFOUND) { crlf(); execcommand(param,ret);// control SD card } } crlf(); } return 0; } int checkcommand(char *cp,union param32 *param,int len) // len: command length { int ret; ret = cmpstr(cp,"mmcinit"); if((ret & 0x7f) == 7) // 7 chars { return MMCINIT; } ret = cmpstr(cp,"dscrc"); if((ret & 0x7f) == 5) // 5 chars { return DSCRC; } ret = cmpstr(cp,"encrc"); if((ret & 0x7f) == 5) // 5 chars { return ENCRC; } ret = cmpstr(cp,"clkspeed"); if((ret & 0x7f) == 8) // 8 chars { cp = &cp[9]; ret = argck(&cp,param,1); if(ret != 1) { putscon("\r\nclkspeed 3b or lower"); return -1; } return CLKSPEED; } ret = cmpstr(cp,"crc7"); if((ret & 0x7f) == 4) // 8 chars { cp = &cp[5]; ret = argck(&cp,param,2); if(ret < 2) { putscon("\r\ncrc7 addr,byte"); return -1; } return CRC7; } ret = cmpstr(cp,"crc16"); if((ret & 0x7f) == 5) // 8 chars { cp = &cp[6]; ret = argck(&cp,param,2); if(ret < 2) { putscon("\r\ncrc16 addr,byte"); return -1; } return CRC16; } ret = cmpstr(cp,"checksects"); if((ret & 0x7f) == 10) // 8 chars { cp = &cp[11]; param[3].l32 = 1;// byte ret = argck(&cp,param,3); if(ret < 3) { putscon("\r\nchecksects start,sects,data"); return -1; } return CHECKSECTS; } ret = cmpstr(cp,"Si"); // automatic setup SD card // cprintf("ret = %d ",ret); if((ret & 0x7f) == 2) // 2 chars { return MMCREADY; } ret = cmpstr(cp,"Sr "); // read SD card. start sector,memory,sectors if((ret & 0x7f) == 3) // 3 chars Sr 0,400000,1 { if(len < 13) { putscon("\r\nex. Sr 0,400000,1"); // address >= 0x400000 return -1; } cp = &cp[3]; ret = argck(&cp,param,3); if(ret != 3) { putscon("\r\nSr start,memory,sectors"); return -1; } if(param[2].l32 > 0x400) { putscon("\r\nsectors must lower 0x401"); return -1; } // if((param[1].l32 + param[2].l32*0x200) return MMCREAD; } ret = cmpstr(cp,"SR "); // read SD card. start sector,memory,sectors if((ret & 0x7f) == 3) // 3 chars Sr 0,400000,1 { if(len < 13) { putscon("\r\nex. Sr 0,400000,1"); // address >= 0x400000 return -1; } cp = &cp[3]; param[3].l32 = 0x20;// default 32 sector ret = argck(&cp,param,3); if(ret < 3) { putscon("\r\nSr start,memory,sectors"); return -1; } if(param[2].l32 > 0x400)// 1024 sector ==> 512kbyte { putscon("\r\nsectors must lower 0x401"); return -1; } // if((param[1].l32 + param[2].l32*0x200) return MMCREADM; } ret = cmpstr(cp,"Sw "); // write SD card. start sector,memory,sectors if((ret & 0x7f) == 3) // 3 chars { if(len < 8) { putscon("\r\nex. Sw 0,0,1"); return -1; } cp = &cp[3]; ret = argck(&cp,param,3); if(ret != 3) { putscon("\r\nSr start,memory,sectors"); return -1; } if(param[2].l32 > 0x400) { putscon("\r\nsectors must lower 0x401"); return -1; } return MMCWRITE; } ret = cmpstr(cp,"cmd "); // CMD if((ret & 0x7f) == 4) // 4 chars { cp = &cp[4]; ret = argck(&cp,param,1); switch(param[0].l32) { case 0: param[1].l32 = 0; return CMD0; break; case 0x1: return CMD1; break; case 0x9: return CMD9; break; case 0x10: return CMD10; break; case 0x17: return CMD17; break; case 0x23: if((param[0].l32 > 0xFFFF) || (param[0].l32 < 0)) param[0].l32=1; return CMD23; break; case 0x24: if(ret >= 3) param[3].l32=1; else param[3].l32=0; return CMD24; break; case 8: param[1].l32 = 0; return CMD8; break; case 0x58: return CMD58; break; case 0x41: param[0].l32 = 0x69; return ACMD41; break; } } return NOTFOUND; } long execcommand(union param32 *param,int cmdcode) // control SD card { int ret; int n,mark,i,k,multi,j,block; char dbuf[12]; unsigned char *cp; cp = &cmdbuf[0].uc8[3]; switch(cmdcode) { case MMCINIT: // restart power ON sequence initmmc(1); sdversion = 0; break; case ENCRC: encrc = 1; break; case DSCRC: encrc = 0; break; case CLKSPEED: mmcclk(param[0].l32); break; case CRC7: ret = crc7c(param[0].ucpoint,param[1].l32); cprintf("CRC7 = %02X",ret & 0xFF); break; case CRC16: ret = crc16c(param[0].ucpoint,param[1].l32); cprintf("CRC16 = %04X",ret & 0xFFFF); break; case MMCREADY: // setup SD card ready ret = sdctl(param,3); break; case CMD0: cmdbuf[0].uc8[3] = 0x40; cmdbuf[1].l32 = 0; if(encrc) cmdbuf[2].uc8[0] = crc7c(&cmdbuf[0].uc8[3],5); // 0x95 else cmdbuf[2].uc8[0] = 0x95; mmccs(0); for(i=0;i<6;i++) mmcout(cp[i]); for(n=0;n<9;n++) { ret = mmcout(0xff); if((ret & 0x80) == 0) break; } mmccs(1); mmcout(0xff); putscon("response = "); // hex8b((char)ret); cprintf("%02X",ret); break; case CMD1: cmdbuf[0].uc8[3] = 0x41; cmdbuf[1].l32 = 0; if(encrc) cmdbuf[2].uc8[0] = crc7c(&cmdbuf[0].uc8[3],5); // 0x95 else cmdbuf[2].uc8[0] = 0x95; mmccs(0); for(i=0;i<6;i++) mmcout(cp[i]); for(n=0;n<9;n++) { ret = mmcout(0xff); if((ret & 0x80) == 0) break; } mmccs(1); mmcout(0xff); putscon("response = "); // hex8b((char)ret); cprintf("%02X",ret); break; case CMD8: cmdbuf[0].uc8[3] = 0x48; cmdbuf[1].l32 = 0x1aa; if(encrc) cmdbuf[2].uc8[0] = crc7c(&cmdbuf[0].uc8[3],5); // else cmdbuf[2].uc8[0] = 0x95; mmccs(0); for(i=0;i<6;i++) mmcout(cp[i]); for(n=0;n<9;n++) { ret = mmcout(0xff); if((ret & 0x80) == 0) { response[0] = ret; break; } } for(n=1;n<6;n++) { ret = mmcout(0xff); response[n] = ret; } mmccs(1); mmcout(0xff); putscon("response = "); // hex8b(response[0]); cprintf("%02X",response[0]); putscon(" card interface = "); for(ret = 1;ret<7;ret++) { n = response[ret]; // hex8b(n & 0xff); cprintf("%02X",n & 0xff); putcon(' '); } break; case CMD9: cmdbuf[0].uc8[3] = 0x49; cmdbuf[1].l32 = 0x0; if(encrc) cmdbuf[2].uc8[0] = crc7c(&cmdbuf[0].uc8[3],5); // 0xaf else cmdbuf[2].uc8[0] = 0x95; mmccs(0); for(i=0;i<6;i++) mmcout(cp[i]); for(n=0;n<9;n++) { ret = mmcout(0xff); if((ret & 0x80) == 0) { csdbuf[0] = ret; break; } } for(n=1;n<23;n++) { ret = mmcout(0xff); csdbuf[n] = ret; } mmccs(1); mmcout(0xff); putscon("response = "); // hex8b(csdbuf[0]); cprintf("%02X",csdbuf[0]); cprintf("\r\ndata 00 FF xx .. FE CSD[127:120] CSD[119:112] ... crc7 crc16 FF"); putscon("\r\nCSD = "); mark = 0; for(ret = 0;ret<23;ret++) { n = csdbuf[ret]; n &= 0xFF; // printf("%02X ",n & 0xff); // hex8b(n); cprintf("%02X",n); putcon(' '); if((n == 0xFE)&&(mark == 0)) { mark = ret + 1; } } if((csdbuf[mark] & 0xC0) == 0x40) { putscon("\r\nCSD Version 2.0"); sdversion |= 0xC; ret = csdbuf[mark + 7]; ret <<= 8; n = csdbuf[mark + 8]; n &= 0xFF; ret |= n; ret <<= 8; n = csdbuf[mark + 9]; n &= 0xFF; ret |= n; ret++; ret >>= 1; putscon(" 0x"); if(ret & 0xFFFF0000) { // hex32b(ret); cprintf("%08lX",ret); } else // hex16b((short)(ret & 0xFFFF)); cprintf("%04X",(short)(ret & 0xFFFF)); putscon(" MB "); // d32kzs(dbuf,k,5); cprintf("%5ld",(short)(ret & 0xFFFF)); // dbuf[5]=0; // putscon(dbuf); } else if((csdbuf[mark] & 0xC0) == 0x0) { putscon("\r\nCSD Version 1.0"); sdversion |= 0x8; k = ((csdbuf[mark+9]) & 0x3) << 1; k |= ((csdbuf[mark+10]) & 0x80) >> 7; k = 1 << (k+2); i = (csdbuf[mark+5]) & 0xF; // READ_BL_LEN i = 1 << i; i *= k; k = ((csdbuf[mark+6]) & 3) << 10; k |= ((csdbuf[mark+7]) & 0xFF) << 2; k |= (((csdbuf[mark+8])>>6) & 3); k++; // printf("C_SIZE = %3X + 1 = %d x %d\n",k,k+1,i); putscon(" C_SIZE = 0x"); if(k & 0xFFFF0000) // hex32b(k); cprintf("%08lX",k); else // hex16b((short)k); cprintf("%04X",k); putscon(" x 0x"); i >>= 10; if(i & 0xFFFF0000) // hex32b(i); cprintf("%08lX",i); else // hex16b((short)i); cprintf("%04X",i); putscon(" kB "); // d32kzs(dbuf,i*k,7); cprintf("%7ld",i*k); // dbuf[7]=0; // putscon(dbuf); putscon(" kB "); } cprintf("\r\nCSD data address = %lX",&csdbuf[0]); break; case CMD10: cmdbuf[0].uc8[3] = 0x4a; cmdbuf[1].l32 = 0x0; if(encrc) cmdbuf[2].uc8[0] = crc7c(&cmdbuf[0].uc8[3],5); // 0xaf else cmdbuf[2].uc8[0] = 0x95; mmccs(0); for(i=0;i<6;i++) mmcout(cp[i]); for(n=0;n<9;n++) { ret = mmcout(0xff); if((ret & 0x80) == 0) { cidbuf[0] = ret; break; } } for(n=1;n<23;n++) { ret = mmcout(0xff); cidbuf[n] = ret; } mmccs(1); mmcout(0xff); cprintf("data 00 FF xx .. FE CID[127:120] CID[119:112] ... crc7 crc16 FF\r\n"); putscon("CID = "); for(ret = 0;ret<23;ret++) { n = cidbuf[ret]; // printf("%02X ",n & 0xff); // hex8b(n & 0xff); cprintf("%02X ",n & 0xff); // putcon(' '); } cprintf("\r\nCID data address=%lX",&cidbuf[0]); break; case CMD58: cmdbuf[0].uc8[3] = 0x7a; cmdbuf[1].l32 = 0x0; if(encrc) cmdbuf[2].uc8[0] = crc7c(&cmdbuf[0].uc8[3],5); // 0xaf else cmdbuf[2].uc8[0] = 0x95; mmccs(0); for(i=0;i<6;i++) mmcout(cp[i]); for(n=0;n<9;n++) { ret = mmcout(0xff); if((ret & 0x80) == 0) { response[0] = ret; break; } } for(n=1;n<7;n++) { ret = mmcout(0xff); response[n] = ret; } mmccs(1); mmcout(0xff); putscon("OCR = "); for(ret = 0;ret<7;ret++) { n = response[ret]; // hex8b(n & 0xff); cprintf("%02X ",n & 0xff); // putcon(' '); } if(response[1] & 0x40) { sdversion |= 2; } break; case ACMD41: cmdbuf[0].uc8[3] = 0x77; // 0x37 = 55 cmdbuf[1].l32 = 0x0; if(encrc) cmdbuf[2].uc8[0] = crc7c(&cmdbuf[0].uc8[3],5); // else cmdbuf[2].uc8[0] = 0x95; mmccs(0); for(i=0;i<6;i++) mmcout(cp[i]); for(n=0;n<10;n++) { ret = mmcout(0xff); if((ret & 0x80) == 0) { response[0] = ret; break; } } mmcout(0xff); cmdbuf[0].uc8[3] = 0x69; // ACMD41 cmdbuf[1].l32 = 0x40FF8000; if(encrc) cmdbuf[2].uc8[0] = crc7c(&cmdbuf[0].uc8[3],5); // else cmdbuf[2].uc8[0] = 0x95; for(i=0;i<6;i++) mmcout(cp[i]); for(n=0;n<10;n++) { ret = mmcout(0xff); if((ret & 0x80) == 0) { response[1] = ret; break; } } mmccs(1); mmcout(0xff); putscon("response 55 = ");cprintf("%02X",response[0]);// hex8b(response[0]); putscon(" response 41 = ");cprintf("%02X",response[1]);// hex8b(response[1]); if(response[0] == 0) sdversion |= 1; // printf("ack 55 = %02X ack41 = %02X",csdbuf[0],csdbuf[1]); break; case CMD17: cmdbuf[0].uc8[3] = 0x51; // CMD17 cmdbuf[1].l32 = param[1].l32; if(encrc) cmdbuf[2].uc8[0] = crc7c(&cmdbuf[0].uc8[3],5); // else cmdbuf[2].uc8[0] = 0x95; mmccs(0); for(i=0;i<6;i++) mmcout(cp[i]); for(n=0;n<9;n++) { ret = mmcout(0xff); if((ret & 0x80) == 0) { response[0] = ret; break; } } for(n=0;;n++) { ret = mmcout(0xff); ret &= 0xFF; if(ret != 0xFF) { response[1] = ret; break; } if(statcon()) { if(getcon() == 3) { putscon("STOP by console"); return 1; } } } for(n=0;n<516;n++) { ret = mmcout(0xff); sddbuf[n] = ret; } mmccs(1); mmcout(0xff); putscon("read buffer address ="); // hex32b((long)(&sddbuf[0])); cprintf("%08lX",(long)(&sddbuf[0])); crlf(); for(ret = 0;ret<516;ret++) { n = sddbuf[ret]; // printf("%02X ",n & 0xff); // if((lines & 0xF) == 0xF) // crlf(); } ret = crc16c(&sddbuf[0],512); // printf(" calc crc16 = %04X",(short)(ret & 0xFFFF)); putscon("return crc16 = "); // hex8b(sddbuf[512]); cprintf("%02X",sddbuf[512]); // hex8b(sddbuf[513]); cprintf("%02X",sddbuf[513]); putscon(" calc crc16 = "); // hex16b((short)(ret & 0xFFFF)); cprintf("%04X",ret); putscon("\r\nresponse = "); // hex8b(response[0]); cprintf("%02X",response[0]); // hex8b(response[1]); cprintf("%02X",response[1]); break; case MMCREAD: ret = sdctl(param,1); break; case CMD23: cmdbuf[0].uc8[3] = 0x57; if((param[1].l32 & 0xFFFF) == 0) param[1].l32 = 1; cmdbuf[1].l32 = param[1].l32 & 0xFFFF; if(encrc) cmdbuf[2].uc8[0] = crc7c(&cmdbuf[0].uc8[3],5); // 0x95 else cmdbuf[2].uc8[0] = 0x95; mmccs(0); for(i=0;i<6;i++) mmcout(cp[i]); for(n=0;n<9;n++) { ret = mmcout(0xff); if((ret & 0x80) == 0) break; } mmccs(1); mmcout(0xff); putscon("response = "); // hex8b((char)ret); cprintf("%02X",ret); break; case MMCREADM: ret = sdctl(param,4); break; case CMD24: param[2].ucpoint = sddbuf; cmdbuf[0].uc8[3] = 0x58; // CMD24 // if(sdversion & 4) cmdbuf[1].l32 = param[0].l32; // else // cmdbuf[1].l32 = param[0].l32 * 0x200; if(encrc) cmdbuf[2].uc8[0] = crc7c(&cmdbuf[0].uc8[3],5); // else cmdbuf[2].uc8[0] = 0x95; if(encrc) { mark = crc16c(¶m[2].ucpoint[0],512); if(param[3].l32 == 1) mark ^= 0xFFFF; // CRC16 error } else mark = 0; mmccs(0); for(i=0;i<6;i++) mmcout(cp[i]); for(n=0;n<9;n++) { ret = mmcout(0xff); if((ret & 0xFF) == 0) { response[0] = ret; break; } } mmcout(0xfe); // start for(n=0;n<512;n++) { ret = mmcout(*param[2].cpoint++); } mmcout(mark>>8); // crc16 mmcout(mark); // crc16 for(n=0;n<9;n++) { ret = mmcout(0xff); if((ret & 0xFF) != 0xFF) { response[1] = ret; response[10] = ret; break; } } for(n=0;;n++) { ret = mmcout(0xff); ret &= 0xff; if(ret == 0xff) // レスポンスが0xFFになるまで待つ break; if(statcon()) { if(getcon() == 3) { putscon("CMD24 STOP by console"); return 1; } } } mmccs(1); mmcout(0xff); putscon("write buffer address ="); // hex32b((long)(&sddbuf[0])); cprintf("%08lX",(long)(&sddbuf[0])); if((response[1] & 0xF) != 5) { putscon("\r\nrespons error = "); // hex8b(response[1]); cprintf("%02X",response[1]); return 1; } response[8] = (mark>>8); // save crc response[9] = (mark); putscon("\r\ncommand response = "); // hex8b(response[0]); cprintf("%02X",response[0]); putscon(" wait ready count = 0x"); // hex32b(n); cprintf("%08lX",n); putscon(" write response = "); // hex8b(response[1]); cprintf("%02X",response[1]); if(param[3].l32) { putscon("\r\ncorrect crc16 = "); // hex16b(mark ^ 0xFFFF); cprintf("%04X",mark ^ 0xFFFF); putscon(" send crc16 = "); // hex16b(mark); cprintf("%04X",mark); } break; case MMCWRITE: ret = sdctl(param,2); break; case CHECKSECTS: checksects(param); break; default: return -1; } } // セクタのデータに、1〜4バイトの文字列があるかを探す。 int checksects(union param32 *param) { unsigned char chkbuf[512]; union param32 paramt[8]; int i,j,ret,count; int pat1,pat2,pat3,pat4; unsigned char *cp; int mode; mode = param[2].l32; if((mode <= 0)||(mode >4)) mode = 1;// byte paramt[0].l32 = param[0].l32; pat4 = param[3].l32 & 0xFF; // LSB pat3 = (param[3].l32 >> 8) & 0xFF; pat2 = (param[3].l32 >> 16) & 0xFF; pat1 = (param[3].l32 >> 24) & 0xFF;// MSB for(i=0;i>8); // crc16 mmcout(mark); // crc16 for(n=0;n<9;n++) { ret = mmcout(0xff); if((ret & 0xFF) != 0xFF) { response[1] = ret; response[10] = ret; break; } } for(n=0;;n++) { ret = mmcout(0xff); ret &= 0xff; if(ret == 0xff) break; if(statcon()) { if(getcon() == 3) { putscon("CMD24 STOP by console"); return 1; } } } mmccs(1); mmcout(0xff); if((response[1] & 0xF) != 5) { putscon("respons error = "); // hex8b(response[1]); cprintf("%02X",response[1]); return 1; } // if(sdversion & 4) param[0].l32++; // SDHC // else // param[0].l32 += 0x200; // normal SD response[8] = (mark>>8); response[9] = (mark); } te = *CMCNT0; break; case 3: // poweron init initmmc(1); // power ON sequence sdversion = 0; // CMD0 cmdbuf[0].uc8[3] = 0x40; cmdbuf[1].l32 = 0; if(encrc) cmdbuf[2].uc8[0] = crc7c(&cmdbuf[0].uc8[3],5); // 0x95 else cmdbuf[2].uc8[0] = 0x95; mmccs(0); for(i=0;i<6;i++) mmcout(cp[i]); for(n=0;n<9;n++) { ret = mmcout(0xff); if((ret & 0x80) == 0) break; } mmccs(1); mmcout(0xff); putscon("\r\nCMD0 response = "); // CMD8 // hex8b((char)ret); cprintf("%02X",ret); cmdbuf[0].uc8[3] = 0x48; cmdbuf[1].l32 = 0x1aa; // if(encrc) cmdbuf[2].uc8[0] = crc7c(&cmdbuf[0].uc8[3],5); // 0x87 // else // cmdbuf[2].uc8[0] = 0x95;// dummy mmccs(0); for(i=0;i<6;i++) mmcout(cp[i]); for(n=0;n<9;n++) { ret = mmcout(0xff); if((ret & 0x80) == 0) { response[0] = ret; break; } } for(n=1;n<6;n++) { ret = mmcout(0xff); response[n] = ret; } mmccs(1); mmcout(0xff); putscon("\r\nCMD8 response = "); // hex8b(response[0]); cprintf("%02X",response[0]); putscon(" card interface = "); for(ret = 1;ret<7;ret++) { n = response[ret]; // hex8b(n & 0xff); cprintf("%02X",n & 0xFF); putcon(' '); } // CMD58 for(k=0;k<2;k++) { cmdbuf[0].uc8[3] = 0x7a; cmdbuf[1].l32 = 0x0; if(encrc) cmdbuf[2].uc8[0] = crc7c(&cmdbuf[0].uc8[3],5); // 0xaf else cmdbuf[2].uc8[0] = 0x95; mmccs(0); for(i=0;i<6;i++) mmcout(cp[i]); for(n=0;n<9;n++) { ret = mmcout(0xff); if((ret & 0x80) == 0) { response[0] = ret; break; } } for(n=1;n<7;n++) { ret = mmcout(0xff); response[n] = ret; } mmccs(1); mmcout(0xff); putscon("\r\nCMD58 response = "); // hex8b(response[0]); cprintf("%02X",response[0]); putscon(" OCR = "); for(ret = 1;ret<7;ret++) { n = response[ret]; // hex8b(n & 0xff); cprintf("%02X",n & 0xff); putcon(' '); } if(response[1] & 0x40) { sdversion |= 2; } if(response[0] == 1) break; } // ACMD41 ( CMD55,ACMD41 ) for(k=0;k<1000;k++) { cmdbuf[0].uc8[3] = 0x77; // 0x37 = 55 cmdbuf[1].l32 = 0x0; if(encrc) cmdbuf[2].uc8[0] = crc7c(&cmdbuf[0].uc8[3],5); // else cmdbuf[2].uc8[0] = 0x95; mmccs(0); for(i=0;i<6;i++) mmcout(cp[i]); for(n=0;n<10;n++) { ret = mmcout(0xff); if((ret & 0x80) == 0) { response[0] = ret; break; } } mmcout(0xff); cmdbuf[0].uc8[3] = 0x69; // ACMD41 cmdbuf[1].l32 = 0x40FF8000; if(encrc) cmdbuf[2].uc8[0] = crc7c(&cmdbuf[0].uc8[3],5); // else cmdbuf[2].uc8[0] = 0x95; for(i=0;i<6;i++) mmcout(cp[i]); for(n=0;n<10;n++) { ret = mmcout(0xff); if((ret & 0x80) == 0) { response[1] = ret; break; } } mmccs(1); mmcout(0xff); if(response[0] == 0) { putscon("\r\nACMD41 response 55 = ");cprintf("%02X",response[0]);// hex8b(response[0]); putscon(" response 41 = ");cprintf("%02X",response[1]);// hex8b(response[1]); sdversion |= 1; putscon(" ACMD41 count = "); // d32kzs(dbuf,k,3); cprintf("%d",k); // dbuf[3]=0; // putscon(dbuf); putscon(" ("); // k *= 2; // d32kzs(dbuf,k,5); cprintf("%ld",k); // putscon(dbuf); putscon(" ms )"); break; } waittim0(46); // 21.3us x 46 = 1ms } // CMD58 cmdbuf[0].uc8[3] = 0x7a; cmdbuf[1].l32 = 0x0; if(encrc) cmdbuf[2].uc8[0] = crc7c(&cmdbuf[0].uc8[3],5); // 0xaf else cmdbuf[2].uc8[0] = 0x95; mmccs(0); for(i=0;i<6;i++) mmcout(cp[i]); for(n=0;n<9;n++) { ret = mmcout(0xff); if((ret & 0x80) == 0) { response[0] = ret; break; } } for(n=1;n<7;n++) { ret = mmcout(0xff); response[n] = ret; } mmccs(1); mmcout(0xff); putscon("\r\nCMD58 response = "); // hex8b(response[0]); cprintf("%02X",response[0]); putscon(" OCR = "); for(ret = 1;ret<7;ret++) { n = response[ret]; // hex8b(n & 0xff); cprintf("%02X",n & 0xff); putcon(' '); } if(response[1] & 0x40) { sdversion |= 2; } // CMD9 ( get CSD ) cmdbuf[0].uc8[3] = 0x49; cmdbuf[1].l32 = 0x0; if(encrc) cmdbuf[2].uc8[0] = crc7c(&cmdbuf[0].uc8[3],5); // 0xaf else cmdbuf[2].uc8[0] = 0x95; mmccs(0); for(i=0;i<6;i++) mmcout(cp[i]); for(n=0;n<9;n++) { ret = mmcout(0xff); if((ret & 0x80) == 0) { csdbuf[0] = ret; break; } } for(n=1;n<23;n++) { ret = mmcout(0xff); csdbuf[n] = ret; } mmccs(1); mmcout(0xff); putscon("\r\nCMD9 response = "); // hex8b(response[0]); cprintf("%02X",response[0]); putscon("\r\n CSD = "); mark = 0; for(ret = 0;ret<23;ret++) { n = csdbuf[ret]; n &= 0xFF; // cprintf("%02X ",n & 0xff); // hex8b(n); cprintf("%02X",n); putcon(' '); if((n == 0xFE)&&(mark == 0)) { mark = ret + 1; } } if((csdbuf[mark] & 0xC0) == 0x40) { putscon("\r\n CSD Version 2.0"); sdversion |= 0xC; ret = csdbuf[mark + 7]; ret <<= 8; n = csdbuf[mark + 8]; n &= 0xFF; ret |= n; ret <<= 8; n = csdbuf[mark + 9]; n &= 0xFF; ret |= n; ret++; ret >>= 1; putscon(" 0x"); if(ret & 0xFFFF0000) { // hex32b(ret); cprintf("%08lX",ret); } else // hex16b((short)(ret & 0xFFFF)); cprintf("%04X",ret); putscon(" MB "); // d32kzs(dbuf,ret,5); cprintf("%5ld",ret); // dbuf[5]=0; // putscon(dbuf); putscon(" MB"); } else if((csdbuf[mark] & 0xC0) == 0x0) { putscon("\r\n CSD Version 1.0"); sdversion |= 0x8; k = ((csdbuf[mark+9]) & 0x3) << 1; k |= ((csdbuf[mark+10]) & 0x80) >> 7; k = 1 << (k+2); i = (csdbuf[mark+5]) & 0xF; // READ_BL_LEN i = 1 << i; i *= k; k = ((csdbuf[mark+6]) & 3) << 10; k |= ((csdbuf[mark+7]) & 0xFF) << 2; k |= (((csdbuf[mark+8])>>6) & 3); k++; // printf("C_SIZE = %3X + 1 = %d x %d\n",k,k+1,i); putscon(" C_SIZE = 0x"); if(k & 0xFFFF0000) // hex32b(k); cprintf("%08lX",k); else // hex16b((short)k); cprintf("%04X",k); putscon(" x 0x"); i >>= 10; if(i & 0xFFFF0000) // hex32b(i); cprintf("%08lX",i); else // hex16b((short)i); cprintf("%04X",i); putscon(" kB "); // d32kzs(dbuf,i*k,7); cprintf("%7ld",k*i); // dbuf[7]=0; // putscon(dbuf); putscon(" kB "); } break; case 4: // read multi sectors MMCREADM ts = *CMCNT0; multi = param[3].l32; if(multi <= 0) multi = 0x20; block = param[2].l32 / multi; for(j=0;j= COLUMN-1)combuf2f=0; return c2; } else { combuf2f=0; return getcon(); } } else return getcon(); } int getscon(char *cp,int cn,int f) { int n,n2; char c; int s; // int i; // int insf; n=0; n2=0; // insf=1; *cp=0; while(n <= cn) { c=getcon_combuf2(); // c=getcon(); if(c =='\3') { return(-1); } if(c==0xd) // CR { cp[n2]='\0'; return(n2); } /* if(c == 'O'-0x40) // ctrl O { insf ^= 1; if(insf & 1) { for(i=0;i<=n;i++) putcon(0x8); putcon('>'); for(i=0;i n) { for(i=n;i 0)) { n--; putcon(0x8); // back space code } */ /* if((c == 'D'-0x40) && (n2 > n)) { putcon(cp[n++]); // edit point char } */ if(((c=='\10') || (c==0x7f)) && (n)) { if(n == n2) { cp[n--]='\0'; n2--; putcon(0x8); // back space code putcon(0x20); // space code putcon(0x8); // back space code } /* else if((n2 > n) && (n)) { n--; putcon(0x8); /// back space code for(i=n;i= 0x20) && ((c & 0x7f) < 0x7f)) { if(n == n2) { cp[n++]=c; s=c; putcon(s); if(n > n2)n2=n; } /* else if(n2 > n) { if(insf) { for(i=n2-1;i>=n;i--) { cp[i+1]= cp[i]; } cp[n] = c; for(i=n;i=n) { return(count); } else { return(-1); } } else { if(c != ',') return(-1); } } } void paramer(void) { putscon("\r\nPARAMETER ERROR !\r\n"); } // cprintf を使わないヘキサ出力 /* void hex8b(long l) { putcon(hex(l>>4)); putcon(hex(l)); } void hex16b(long l) { putcon(hex(l>>12)); putcon(hex(l>>8)); putcon(hex(l>>4)); putcon(hex(l)); } void hex32b(long l) { hex16b(l>>16); hex16b(l); } */ char htol(long *lp,char **cp) { char c; char *p; long l; short s; p= *cp; l=0l; while(1) { c= *p++; // hex32b(c); s = chex(c); // hex32b(s); if(s== -1) { *lp = l; *cp = p; return(c); } l <<= 4; l |= s; } } // メモリコピー // ソースとデスティネーションのアドレス更新オプションがある。 // param[3].l32 は、指定無ければ0x11で、両方更新する。 // 0x10 ソースアドレスを更新し、デスティネーションアドレスは固定。 // 0x1 デスティネーションアドレスを更新し、ソースアドレスは固定。 // 0x0 どちらのアドレスも固定。 // この機能は、周辺回路で、特定のアドレスのレジスタにアクセスすると、 // 内部のメモリバッファーに、順番に読み(書き)だすような場合に有効。 void movem(union param32 *param,long ll) { register long l; volatile char *s,*d; volatile short *sp; volatile long *lp,*ldp; volatile short *dp; int upf; l=param[2].l32; upf = param[3].l32; if(ll==0) { s=param[0].cpoint; d=param[1].cpoint; switch(upf) { case 0x1: while(l--) *d++ = *s; break; case 0x10: while(l--) *d = *s++; break; case 0: while(l--) *d = *s; break; default: while(l--) *d++ = *s++; break; } } else if(ll==1) { sp=param[0].spoint; dp=param[1].spoint; switch(upf) { case 0x1: while(l--) *dp++ = *sp; break; case 0x10: while(l--) *dp = *sp++; break; case 0: while(l--) *dp = *sp; break; default: while(l--) *dp++ = *sp++; break; } } else if(ll==2) { lp=param[0].lpoint; ldp=param[1].lpoint; switch(upf) { case 0x1: while(l--) *ldp++ = *lp; break; case 0x10: while(l--) *ldp = *lp++; break; case 0: while(l--) *ldp = *lp; break; default: while(l--) *ldp++ = *lp++; break; } } } void findp(union param32 *param) { register long bytec; register long l; register char *s,*d; /* register char c1,c2;*/ register short count; short shot; long ld; short lfn; s=param[0].cpoint; d=param[1].cpoint; bytec=param[2].l32; l=param[3].l32; if(bytec==0)return; if(bytec==1)l &= 0xffl; if(bytec==2)l &= 0xffffl; if(bytec==3)l &= 0xffffffl; lfn=0; crlf(); while(s != d) { ld=0; for(count=0;count=8) { lfn=0; crlf(); } if(statcon()) { if(getcon()==3)return; if(getcon()==3)return; } } s++; } } void dumpmt(void) { putscon("\r\nADDR 0 1 2 3 4 5 6 7 8 9 A B C D E F ascii\r\n"); } int dumpm(union param32 *param,int mode) { unsigned char *cp; // short *sp; int i,sum,ls; unsigned int s,sjf,l; union param32 u; unsigned char sbuf[16]; char c2; unsigned long len; // short sbuf[8]; if(param[0].ul32 > param[1].ul32) return 0; len = param[1].ul32 - param[0].ul32 + 1; cp=param[0].ucpoint; // sp=param[0].spoint; sjf=0; ls=0; if(mode==1) // dsxxxx { crlf(); u.ucpoint=param[0].ucpoint; while(1) { l = u.ul32; // if(hiki==3) l += param[2].l32; if(u.ul32 & 0xf) { if(param[1].ul32 >= (u.ul32 | 0xf)) { ls = (0x10 - (u.ul32 & 0xf)); // putscon("S3"); // hex8b(ls + 5); cprintf("S3%02X",ls + 5); sum = (0xff - ls - 5); } else { ls = param[1].ul32 - u.ul32 + 1; // putscon("S3"); // hex8b(ls + 5); cprintf("S3%02X",ls + 5); sum = (0xff - ls - 5); } } else if(param[1].ul32 >= (u.ul32 + 16)) { sum=0xEA; /* FF-15 */ ls = 16; putscon("S315"); } else { ls = param[1].ul32 - u.ul32 + 1; // putscon("S3"); // hex8b(ls + 5); cprintf("S3%02X",ls + 5); sum = (0xff - ls - 5); } cprintf("%08lX",l); // hex32b(l); sum -= (l >> 24) & 0xff; sum -= (l >> 16) & 0xff; sum -= (l >> 8) & 0xff; sum -= l & 0xff; for(i=0;i param[1].ul32) break; if(u.ul32 < param[0].ul32) break; if(statcon()) if(getcon()==3)break; } putscon("S70500000000FA\r\n"); } else { param[0].l32 &= 0xfffffff0l; param[1].l32 &= 0xffffffffl; dumpmt(); while(1) { { // hex32b((long)cp); spacen(1); cprintf("%08lX ",(long)cp); for(i=0;i<16;i++) { s= *cp++; sbuf[i++]=s; // hex8b(s); cprintf("%02X",s); s= *cp++; sbuf[i]=s; // hex8b(s); cprintf("%02X",s); spacen(1); if(statcon()) { c2=getcon(); if((c2==3) || (c2==0xd))return(-1); c2=getcon(); if((c2==3) || (c2==0xd))return(-1); } } len -= 0x10; putcon('['); /* '[' */ s = ls; for(i=0;i<16;) { if(sjf) { s = sbuf[i++]; if(i==16) { sjf=0; break; } s <<= 8; sum = sbuf[i++]; sum &= 0xff; s |= sum; if(cksjis(s)) { putcon(s>>8); putcon((char)s); // i++; } else { ckasci(s>>8); sjf=0; // i++; } } else { s <<= 8; sum = sbuf[i++]; sum &= 0xff; s |= sum; if(cksjis(s)) { putcon(s>>8); putcon((char)s); sjf=1; } else { if(i==1) { putcon(' '); } else ckasci(s>>8); } } } if(sjf==0) ckasci(s); ls=s; putcon(']'); u.ucpoint=cp; if((u.ul32 > param[1].ul32) || (len <=0)) { return 0; } u.ucpoint=cp; if((u.l32 & 0xf)==0) { crlf(); if((u.l32 & 0xff)==0) dumpmt(); } } } /* cprintf("%08lX",(long)sp); spacen(1); for(i=0;i<8;i++) { s= *sp++; sbuf[i]=s; cprintf("%04X",s); spacen(1); if(statcon()) { if(getcon()==3)return; if(getcon()==3)return; } } putcon(0x2a); // '*' for(i=0;i<8;i++) { s=sbuf[i]; ckasci(s >> 8); ckasci(s); } putcon(0x2a); if(sp >= param[1].spoint) { return; } u.spoint=sp; if((u.l32 & 0xf)==0) { crlf(); if((u.l32 & 0xff)==0) dumpmt(); } */ } } int cksjis(unsigned int s) { int i; i = s>>8; i &= 0xff; if(((i>= 0x81) && (i<= 0x9f)) || ((i>= 0xE0) && (i<= 0xEF))) { s &= 0xff; if((s >= 0x40) && (s <= 0x7e)) return 1; if((s >= 0x80) && (s <= 0xfc)) return 1; } return 0; } // 多機能セットメモリコマンド s // // 引数の数により、3種類の機能を選べる。 // 引数1 s1c009000 (enter) など。 // 0x1C009000 番地から、1個単位に変更データを入力して、アドレスを進める。 // 引数2 s1c009000,6f (enter) など。 // 0x1c009000 番地を、バイトで、0x6Fに書き換える。 // 引数3以上 // 0x1c009000,i,n,u,b,a,d (enter) n 以降は、入力がなければ、それぞれ、1,0,0,0,0,0 に初期化されている。 // i: 最初に書くデータの値。データ初期値 // n: 書き換える総データ個数 // u: 1個書いた後にデータを i=i+u とする。 // b: 以降の a,d の設定に有効で、0 の場合は、無効になる。 // 0以外は、指定個数アドレスをUPしながら書いた後、データ初期値を、i=i+d とする。 // このとき、カレントアドレスを、a だけ加算する。 // 引数3以上、例1  // SH2A-Bug>s1c009000,1,10,1,2  これは、s1c009000,1,10,1,2,0,0 と同じ。 // SH2A-Bug>d1c009000 // ADDR 0 1 2 3 4 5 6 7 8 9 A B C D E F ascii // 1C009000 0102 0102 0102 0102 0102 0102 0102 0102 [ ................] // 1C009010 0000 0000 0000 0000 0000 0000 0000 0000 [ ................] // // 引数3以上、例2 // SH2A-Bug>s1c009000,61,10,2,4,3,5 // SH2A-Bug>d1c009000 // ADDR 0 1 2 3 4 5 6 7 8 9 A B C D E F ascii // 1C009000 6163 6567 0000 0066 686A 6C00 0000 6B6D [ aceg...fhjl...km] // 1C009010 6F71 0000 0070 7274 7600 0000 0000 0000 [ oq...prtv.......] // 1C009020 0000 0000 0000 0000 0000 0000 0000 0000 [ ................] // // 引数3以上、例3 // SH2A-Bug>sw1c009000,3030,4,0101,1,7,0202 // SH2A-Bug>d1c009000 // ADDR 0 1 2 3 4 5 6 7 8 9 A B C D E F ascii // 1C009000 3030 0000 0000 0000 0000 0000 0000 0000 [ 00..............] // 1C009010 3232 0000 0000 0000 0000 0000 0000 0000 [ 22..............] // 1C009020 3434 0000 0000 0000 0000 0000 0000 0000 [ 44..............] // 1C009030 3636 0000 0000 0000 0000 0000 0000 0000 [ 66..............] // 1C009040 0000 0000 0000 0000 0000 0000 0000 0000 [ ................] // // いわゆる、フィルメモリコマンド。0x1c009000 番地からワード値0x1234を0x10個書く。 // SH2A-Bug>sw1c009000,1234,10 // SH2A-Bug>d1c009000 // ADDR 0 1 2 3 4 5 6 7 8 9 A B C D E F ascii // 1C009000 1234 1234 1234 1234 1234 1234 1234 1234 [ .4.4.4.4.4.4.4.4] // 1C009010 1234 1234 1234 1234 1234 1234 1234 1234 [ .4.4.4.4.4.4.4.4] // 1C009020 0000 0000 0000 0000 0000 0000 0000 0000 [ ................] int setmemo(union param32 *param,int wf,int argc) { char *cp; short *sp; long *lp; // short s,j; /* union param32 u;*/ char buf[16]; long l,i,updatea,updated; char *c; int wof; wof=0; if(wf & 4) { wof=1; wf &= 3; } if(wf==1) { // param[0].l32 &= 0xfffffffel; // ワードアライメントはしない。強制的にアドレスエラートラップ可能 sp=param[0].spoint; } else if(wf==2) { // param[0].l32 &= 0xfffffffcl;// ロングワードアライメントはしない lp=param[0].lpoint; } else { cp=param[0].cpoint; } if(argc >= 2) { // param[2] count param[3] update param[4] address segment param[5] adjust address update param[6] data update // default param[2].l32 = 1; // param[3].l32 = 0; // param[4].l32 = 0x0; // param[5].l32 = 0; // param[6].l32 = 0; updatea = param[4].l32; updated = param[1].l32; while(param[2].l32--) { switch(wf) { case 0: *cp++ = (char)updated; break; case 1: *sp++ = (short)updated; break; case 2: *lp++ = (long)updated; break; } updated = updated + param[3].l32; updatea--; if(updatea == 0) { updatea = param[4].l32; cp = &cp[param[5].l32]; sp = &sp[param[5].l32]; lp = &lp[param[5].l32]; param[1].l32 += param[6].l32; updated = param[1].l32; } } } if(argc == 1) while(1) { crlf(); if(wf==1) { cprintf("%08lX",(long)sp); // hex32b((long)sp); } else if(wf==2) { cprintf("%08lX",(long)lp); // hex32b((long)lp); } else { cprintf("%08lX",(long)cp); // hex32b((long)cp); } putcon('='); if(wof==0) { if(wf==1) { cprintf("%04X",*sp); // hex16b(*sp); } else if(wf==2) { cprintf("%08lX",*lp); } else { cprintf("%02X",(short)*cp & 0xff); } } putcon(' '); i=getscon(buf,15,1); if(i == -1)return(0); if(i>15) { if((i=='R')||(i=='r')) { if(wf==1) { sp--; } else if(wf==2) { lp--; } else { cp--; } } else if(((i=='X')||(i=='x'))&&(wof==1)) { if(wf==1) { cprintf("%04X",*sp); } else if(wf==2) { cprintf("%08lX",*lp); } else { cprintf("%02X",(short)*cp & 0xff); } putcon(' '); } else /* 'N' */ { if(wf==1) { sp++; } if(wf==2) { lp++; } else { cp++; } } } else { c=buf; if(*c == '.')break; htol(&l,&c); i=l; if(wf==1) { *sp++ = i; } else if(wf==2) { *lp++ = i; } else { *cp++ = i; } } } return 0; } int verify(union param32 *param) { register long l; register char *s,*d; register char c1,c2; short shot; s=param[0].cpoint; d=param[1].cpoint; l=param[2].l32; while(l--) { c1= *s; c2= *d; if(c1 != c2) { crlf(); cprintf("%08lX=",(long)s); // putcon('='); shot=c1; cprintf("%02X ",shot & 0xff); // spacen(1); cprintf("%08lX=",(long)d); // putcon('='); shot=c2; cprintf("%02X",shot & 0xff); if(statcon()) { if(getcon()==3)return(0); if(getcon()==3)return(0); } } s++; d++; } return(0); } int cmpstr(char *d,char *s) { register long n; register char c1,c2; for(n=0;n c2) { return(1); } if(c1 < c2) { return(-1); } if((c1 == 0) && (c2 == 0)) { return(0); } if((c1 == 0) || (c2 == 0)) break; } return(1); } void srload(union param32 *param,int m) { /* extern short ring0v; extern short ring0r; */ char *cp,*cpb; // char *rp; register long l; register int i,j,k,sm; int ii,flag; long len; // char (*func)(); len=0; flag=0; // if(m==1) // func = (char (*)())getcon; // len=0; flag=0; SRLDL: if((i=getcon()) ==3) goto SRLDE; if(i != 'S')goto SRLDL; if((i=getcon())==3) goto SRLDE; if(i == '9') goto SRLDE; if(i == '8') goto SRLDE; if(i == '7') goto SRLDE; if(i == '0') goto SRLDL; if(i == '5') goto SRLDL; if((i >= '1') && (i <= '3')) { j=(i & 3)+1; /* dly(10);*/ if((i=getcon()) ==3) goto SRLDE; k=chex(i); /* dly(10);*/ if((i=getcon()) ==3) goto SRLDE; i=chex(i); k= k*16 + i; if(k==0) { i='9'; goto SRLDE; } sm = 0xFF; sm -= k; k--; l=0; while(j--) { /* dly(10);*/ if((i=getcon()) ==3) goto SRLDE; ii=chex(i); /* dly(10);*/ if((i=getcon()) ==3) goto SRLDE; ii = ii*16 +chex(i); sm -= ii; l = (l << 8) + ii; k--; } cp = param[0].cpoint; cp = &cp[l]; if(flag==0) { flag=1; cpb=cp; /* putscon("start loading address = ");*/ /* hex32b((long)cp);*/ /* crlf(); */ } while(k--) { /* dly(10);*/ if((i=getcon()) ==3) goto SRLDE; ii=chex(i); /* dly(10);*/ if((i=getcon()) ==3) goto SRLDE; ii = ii*16 + chex(i); sm -= ii; *cp++ = ii; len++; } /* dly(10);*/ if((i=getcon()) ==3) goto SRLDE; ii=chex(i); /* dly(10);*/ if((i=getcon()) ==3) goto SRLDE; ii = ii*16+ chex(i); if((sm & 0xFF) != (ii & 0xff)) { putscon("check sum error !! "); cprintf("%04X %04X",(short)sm,(short)ii);//cprintf(" %04X",(short)ii); // hex16b((short)ii); /* printf("sm=%x ii=%x",sm,ii);*/ i = -2; goto SRLDE; } goto SRLDL; } else { putscon("S1~S3 abarble\r\n"); return; } SRLDE: /* s0icls();*/ if(i == -1) { // putscon("BREAK BY CONSOLE !!\r\n"); return; } if(i == -2) { putscon("SUM CHECK ERROR\r\n"); return; } if((i == '9')||(i == '8')||(i == '7')) { for(j=26-(i & 0xf)*2;j>0;j--) getcon(); putscon("start loading address = "); cprintf("%08lX",(long)cpb); // crlf(); putscon("\r\nEND. bytes loaded = "); cprintf("%08lX\r\n",len); // crlf(); return; } putscon("????? S load stop\r\n"); return; } void spacen(int n) { while(n--) { putcon(0x20); } } int cpynstr(char *d,char *s,int n) { register char c; int l; int spacef,i; l = 0; spacef = 0; for(i=0;i= 'a') && (c <= 'z'))c -= ' '; if((c >= '0') && (c <= '9'))return(c & 0xf); if((c >= 'A') && (c <= 'F'))return(c -= 0x37); return(-1); } int hex(int i) { i &= 0xF; if(i>9) i+=7; i+=0x30; return(i); } void ckasci(int s) { s &= 0xff; if(((s >= 0x20) && ( s <= 0x7e))) // || ((s >= 0xa0) && ( s <= 0xfe))) { putcon(s); } else { putcon(0x2e); } } // f==0 ではstrlen とほぼ同じ。長さ制限が80文字で、終了文字指定。 int cstrlen(char *cp,char f) { long i; for(i=0;i= '0') && (c <= '9')) { if(c=='0') { zs=0; i++; c = fmt[i]; } if((c >= '1') && (c <= '9')) { keta=c & 0xf; i++; c = fmt[i]; if((c >= '0') && (c <= '9')) { keta *= 10; keta += c & 0xf; i++; c = fmt[i]; } } else zs=1; } if((c == 'l') || (c == 'L')) { siz=4; i++; c = fmt[i]; } if((c == 'x') || (c == 'X')) { if(c == 'x') lower = 1; else lower = 0; c='x'; } else if((c == 'd') || (c == 'D')) { c='d'; } if(c == 'c') { *dp++ = l; wlen++; } else if(c == 's') { cp = (char *)l; while(*cp) { *dp++ = *cp++; wlen++; if(wlen >= (COLUMN -1))break; } } else { if(siz==2) l &= 0xFFFF; if(keta>10)keta=10; cb[10]=0; if(c == 'x') { cb[0]=' '; cb[1]=' '; for(j=9;j>=2;j--) { s = hex((int)l); if((lower) && (s > '9')) s |= ' ';// 英小文字 cb[j]=s; l >>= 4; } } else { for(j=9;j>=0;j--) { s = (unsigned long)l%10; cb[j]=s | '0'; l = (unsigned long)l/10; } } for(j=0;j<9;j++) { c = cb[j]; if(c == '0') { if(zs) cb[j]=' '; } else if(c != ' ') break; } if(keta < (10-j)) keta=10-j; if((wlen + keta) >= (COLUMN -1)) return wlen; for(j=10-keta;j<10;j++) *dp++ = cb[j]; wlen += keta; } } else { *dp++ = c; wlen++; } if(wlen >= (COLUMN -1))return wlen; } return wlen; }