電子ブロック工房:
Deprecated: Function strftime() is deprecated in /home/u109394186/domains/rad51.net/public_html/jeans/jeans/libs/blog.php on line 333
2009年 07月の記事
タイミング回路、再び [デジタル回路]
2009年7月23日
8 bit CPU への移行に伴って、クロック周りの回路を大幅に書き換えた。
まずできたのは、<%media(20090724-clock4.zip|以下のもの)%>。

まずできたのは、<%media(20090724-clock4.zip|以下のもの)%>。

8 bit CPU [CPU]
2009年7月21日
紆余曲折の結果、結局 8 bit のオーソドックスなCPUに落ち着きそう。
仕様は、次のとおり。
version 0.0.6.1
仕様は、次のとおり。
version 0.0.6.1
data line: 8 bits address line: 14 bits (8 bits + 6 bits; 256 x 64) registors X(8), Y(8), F(8), PC(12), SP(8) F: Z, C, S5, S4, S3, S2, S1, S0 (Z, C: zero and carry flags; S: segment registor) stack segment is always 0x3f program can be written from 0x0000 to 0x0fff All 2 byte commands 0x00, 0x01, ... , 0x0f: goto, operand: 12 bits. 0x10, 0x11, ... , 0x1f: call, operand: 12 bits. 0x20, 0x21, ... , 0x27: X=XX, [X]=XX, X=(XX), (XX)=X, Y=XX, [Y]=XX, X=(XX), (XX)=X 0x28, 0x29, ... , 0x2f: (see below) 0x2800 - 0x280f: X=X (NOP), X=Y, X=F, X=SP, reserved, X=[Y], 0x2810 - 0x281f: Y=X, Y=Y, Y=F, Y=SP, Y=[X], reserved, 0x2820 - 0x282f: F=X, F=Y, F=F, SP=SP, F=[X], F=[Y], 0x2830 - 0x283f: SP=X, SP=Y, SP=F, SP=SP, SP=[X], SP=[Y], 0x2880 - 0x288f: [X]=X, [X]=Y, [X]=F, [X]=SP, reserved, reserved, 0x2890 - 0x289f: [Y]=X, [Y]=Y, [Y]=F, [Y]=SP, reserved, reserved, 0x2900 - 0x290f: [SP]=X, [SP]=Y, [SP]=F, 0x2920 - 0x292f: push X, push Y, push F, SP-- 0x2940 - 0x294f: [++SP]=X, [++SP]=Y, [++SP]=F, 0x2960 - 0x296f: [SP+1]=X, [SP+1]=Y, [SP+1]=F, 0x2980 - 0x298f: X=[SP], Y=[SP], F=[SP], 0x29a0 - 0x29af: X=[SP--], Y=[SP--], F=[SP--], 0x29c0 - 0x29cf: pop X, pop Y, pop F, SP++ 0x29e0 - 0x29ef: X=[SP+1], Y=[SP+1], F=[SP+1], 0x30, 0x31, ... , 0x38: (XX)=X+Y, (XX)=X-Y, (XX)=X&Y, (XX)=X|Y, (XX)=X+Y+C, (XX)=X-Y-C, (XX)=X^Y, (XX)=~X 0x38, 0x31, ... , 0x3f: X=++(XX), X=--(XX), reserved x2, Y=++(XX), Y=--(XX), reservedx2 0x40, 0x41, ... , 0x4f: jz, operand: 12 bits. 0x50, 0x51, ... , 0x5f: jc, operand: 12 bits. 0x60, 0x61, ... , 0x6f: jnz, operand: 12 bits. 0x70, 0x71, ... , 0x7f: jnc, operand: 12 bits. 0x80, 0x81, ... , 0x8f: reserved 0x90, 0x91, ... , 0x9f: reserved 0xa0, 0xa1, ... , 0xaf: reserved 0xb0, 0xb1, ... , 0xbf: reserved 0xc0, 0xc1, ... , 0xcf: reserved 0xd0, 0xd1, ... , 0xdf: reserved 0xe0, 0xe1, ... , 0xef: reserved 0xf0, 0xf1, ... , 0xff: reserved (XX) = [3Fh:XX]; used as registors; genelary, F0-FF (16 registors) are used.
pi calculator [PIC]
2009年7月12日
IC16F690をつかった、pi calculatorの完成形。結果は、
3.141592653589793238462643383279502884
となる。
以下は、3.141592653589793238462643まで計算したところ。
本当は、小数点以下36桁まで計算し表示するのだが、その計算に8分強かかる。フルの長さの動画がアップできなかった。
3.141592653589793238462643383279502884
となる。
以下は、3.141592653589793238462643まで計算したところ。
本当は、小数点以下36桁まで計算し表示するのだが、その計算に8分強かかる。フルの長さの動画がアップできなかった。
円周率、小数点以下70桁 [一般的なこと]
2009年7月3日
C++で。
copy関数内で丸めの処理をし、下2桁は表示しないようにしてある。このアルゴリズムだとこの辺が限界らしく、桁数をさらに上げると誤差が出るようだ。PICのpi calculatorにも入れてみよう。
#include "stdafx.h"
#include <stdlib.h>
#define FIG 37
void prt(unsigned char* v1){
unsigned char i;
for (i=0;i<FIG-1;i++) {
if (v1[i]<10) printf("0%d",v1[i]);
else printf("%d",v1[i]);
}
printf("\n");
}
void copy(unsigned char* res, unsigned char* v1){
unsigned char i;
unsigned short t,c=0;
v1[FIG-1]=10*((v1[FIG-1]+5)/10);
for (i=FIG-1;i<FIG;i--) {
t=v1[i]+c;
c=t/100;
if (i) t-=c*100;
res[i]=t;
}
}
void clear(unsigned char* res){
unsigned char i;
for (i=0;i<FIG;i++) res[i]=0;
}
void add(unsigned char* res, unsigned char* v1, unsigned char* v2){
unsigned char cache[FIG];
unsigned char i;
unsigned short t,c=0;
for (i=FIG-1;i<FIG;i--) {
t=v1[i]+v2[i]+c;
c=t/100;
if (i) t-=c*100;
cache[i]=t;
}
copy(res,(unsigned char*)&cache);
}
void mul(unsigned char* res, unsigned char* v1, unsigned char v2){
unsigned char cache[FIG];
unsigned char i;
unsigned short t,c=0;
for (i=FIG-1;i<FIG;i--) {
t=v1[i]*v2+c;
c=t/100;
if (i) t-=c*100;
cache[i]=t;
}
copy(res,(unsigned char*)&cache);
}
void mul(unsigned char* res, unsigned char* v1, unsigned char* v2){
unsigned char cache[FIG*3];
unsigned char* r=&cache[0];
unsigned char* t=&cache[FIG*2];
unsigned char i;
clear(r);
clear(r+FIG);
for (i=FIG-1;i<FIG;i--) {
mul(t,v1,v2[i]);
add(r+i,r+i,t);
}
copy(res,r);
}
void div(unsigned char* res, unsigned char* v1, unsigned char v2){
unsigned char cache[FIG];
unsigned char* r=&cache[0];
unsigned char i;
unsigned short c=0;
for (i=0;i<FIG;i++) {
c=c*100+v1[i];
r[i]=c/v2;
c=c-r[i]*v2;
}
copy(res,r);
}
int _tmain(int argc, _TCHAR* argv[])
{
unsigned char* pi=new unsigned char[FIG];
unsigned char* y=new unsigned char[FIG];
unsigned char* t=new unsigned char[FIG];
clear(pi);
prt(pi);
for (int n=0;n<127;n++) {
clear(y);
y[0]=3;
div(y,y,2*n+1);
for (int x=1;x<=n;x++) {
clear(t);
t[0]=x+n;
div(t,t,x);
div(t,t,16);
mul(y,y,t);
}
add(pi,pi,y);
prt(pi);
}
return 0;
}copy関数内で丸めの処理をし、下2桁は表示しないようにしてある。このアルゴリズムだとこの辺が限界らしく、桁数をさらに上げると誤差が出るようだ。PICのpi calculatorにも入れてみよう。
割り算無しで円周率の計算 [一般的なこと]
2009年7月2日
割り算は少し面倒なので、これを行わずに円周率を計算させる方法を考えてみた。
for ($max=2;$max<=2000000000;$max=$max*sqrt(10)) {
$t=time();
echo intval($max).': '.calc_pi(intval($max))." (".(time()-$t).")\n";
}
function calc_pi($max) {
$total=0;
$max2=$max*$max;
$prev_y=$max-1;
for ($x=0;$x<$max;$x++) {
$max2_x2=$max2-$x*$x;
for ($y=$prev_y;0<=$y;$y--) {
if ($y*$y < $max2_x2) break;
}
$total+=$y+1;
$prev_y=$y;
}
return $total;
}
