上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
--.--.-- -- l スポンサー広告 l top
以前ichigojamで動かしてみた100均電子ピアノをなんとかマイコン抜きでオルゴールにしようと考えていまして、ようやくある程度できましたので記事とします。

最初は基板を取り出して細工しようと思っていたのですが、それをやるとキー接点がなかなかうまくできないので、結局ケースのままとして、もとからある鍵盤を活用としました。

こんな感じです。板に丸ピンを刺して楽譜とし、100均電子ピアノにガイドをつけて板の上で動かすと丸ピンで鍵盤が押されます。
板も含めてすべて100均で売っているものです。DAISOさんの取り揃えには感心します。



工作過程と動作は動画をご覧ください。


100均アイテム縛りにしましたので夏休み工作っぽくて時期的に良いかな、と(^^;。


スポンサーサイト
2016.08.14 Sun l 100円ショップ工作 l コメント (2) l top
先週末秋葉原に行った際にAITNDOのFMラジオモジュールFM577-4Pを購入してきました。



I2Cで割と簡単に操作できそうでしたのでICHIGOJAMにつないで実験中です。


aitendoによるとこのモジュール電源は5Vですが、乗っているDSPラジオとアンプICは3Vでも動作できるものでしたので、
ichigojamの3.3Vで動かしています。

このモジュールはTEA5767というチップを乗せています。データシートはこちらです。

このチップのレジスタ構成はちょっと変わっていて、レジスタは5個固定で、レジスタアドレスに相当するものがありません。
どういうことかというと、通常はI2Cではデバイスアドレス、レジスタアドレス、データ1、データ2、。。。
という書き込みをするところ、このチップはデバイスアドレス、データ1、データ2、。。。データ5、となります。
ICHIGOJAMのI2CW命令は、デバイスアドレス、レジスタアドレス、レジスタデータの3パラメータ構成なので少し悩みましたが、結局以下のコードで設定できることがわかりました。

10 POKE #700,#27,#72,#00,#3E,#00
20 A=I2CW(#60,#700,1,#701,4)
30 SLEEP


固定周波数82.5MHzで設定するコードです。詳細は後日解説します。

問題はなぜ30行にSLEEPがいるのか、です。

最初10行と20行だけで動かしてみたのところ、ひどい雑音とかすかな音楽が聞こえてきました。
どうやらI2C設定はできていて、周波数か他の設定が間違っているのだな、と思って
設定値を確認してみたのですが、特におかしいところがない。。。。。

色々試している中で。たまたまCLSで画面を消去すると状態が良くなることがわかりました。
これはノイズ影響だな、と思ってLCDモニタの電源を切ってみても変わりない。。。

次にichigojamのCPUを強制的にリセット状態にすると著しく改善することがわかりました。
どうやらCPU動作のノイズによる模様です。
リセット状態のままでおけないのでSLEEPにしたところやはり改善したので30行に追加しました。

いかしやっぱり画面表示して選局とかしたいのでSLEEPのままとも行きません。
次回はノイズ観測と対策を打ってみたいと思います。



2016.07.26 Tue l ICHIGOJAM l コメント (0) l top
どうやらワイヤフレームで3D表示っぽいことができるようになりました。

その前に苦労した自由ラインルーチンについてはこちらをご覧ください。)



■ワイヤフレーム3Dルーチンは以下です。これを実行すると、#700-#7FFに書き込まれます。

1 poke#700,240,181,133,36,137,176,3,145,36,1,14,25,3,156,164,70,58,73,97,68,6,145,0,36,49,95,4,145,2,36,49,95,5,145,4,36,49,95,140,70,0,41,4,218,75
2 poke#72d,66,27,4,27,20,156,70,84,224,4,156,90,67,97,70,97,67,64,37,84,17,73,17,9,27,67,67,9,4,5,152,9,12,1,145,97,70,65,67,88,17,73,17,9,26
3 poke#75a,9,4,9,12,82,0,91,0,18,4,27,4,2,145,18,20,27,20,145,17,8,4,0,12,7,145,1,0,31,49,9,4,9,12,62,41,35,216,153,17,12,4,36,12,39
4 poke#787,0,23,55,63,4,63,12,46,47,26,216,151,17,127,16,7,151,31,39,9,1,185,67,7,159,127,24,169,33,9,1,127,24,3,153,207,25,2,33,100,0,12,64,1,57
5 poke#7b4,8,64,32,67,129,64,8,0,128,33,73,66,8,67,57,120,1,67,57,112,1,153,138,24,2,153,1,61,203,24,18,4,27,4,45,4,18,20,27,20,45,12,197,209,6
6 poke#7e1,155,6,54,4,154,5,152,158,66,1,208,99,70,146,231,0,32,9,176,240,188,2,188,8,71,192,70,200,8,0,0


■使い方
  [40]-[99]に3ワード単位で描画したいラインのX,Y,Z座標を書き込んで、
  CLSののちに#700をコールすると一気に描画されます。

  [40+3*N] : X座標をー31~+31の範囲で入れます。
  [40+3*N+1] : Y座標をー31~+31の範囲で入れます。
  [40+3*N+2] : Z座標を絶対値0~100くらいで入れます。数字が大きいほど近くなります。
          
  Z座標に線の切れ目を示す仕掛けが入っています。マイナスをつけるとそこが線の区切りになります。
  逆に正の数だと区切りをつけずに一筆書きで描画します。
  例えば [40]=0:[41]=0:[42]=-10 : [43]=10:[44]=0:[45]=10: [46]=10:[47]=10:[48]=10 : [49]=20:[50]=20:[51]=10:
       では(X,Y,Z) = (0,0,10)-(10,0,10)-(10,10,10)-(20,20,10)を一筆書きでつなぎます。
それにたいして [40]=0:[41]=0:[42]=-10 : [43]=10:[44]=0:[45]=10: [46]=10:[47]=10 :[48]= -10 : [49]=20:[50]=20:[51]=10:
       だと(X,Y,Z) = (0,0,10)-(10,0,10) と (10,10,10)-(20,20,10)の2本の線を書きます。
   線分データ量を減らして、自由度を上げるためにこうしています。
   この方式のため、最初の座標のZ([42]は必ずマイナスとしてください。

■制限
  [40]-[99]は使えません。

■デモ3パターンを作ったので動画にしました。



「スポンサードリンク」

style="display:block"
data-ad-client="ca-pub-0620260288102702"
data-ad-slot="9773401572"
data-ad-format="auto">



■デモプログラム1 :回転する3角形

10 CLS:T=0:S=0:[0]=10:[1]=8:[2]=5:[3]=0:[4]=-5:[5]=-8:[6]=-10:[7]=-8:[8]=-5:[9]=0:[10]=5:[11]=8
30 [12]=0:[13]=5:[14]=8:[15]=10:[16]=8:[17]=5:[18]=0:[19]=-5:[20]=-8:[21]=-10:[22]=-8:[23]=-5
40 FORE=40TO99:[E]=-1:NEXT
50 K=24:[K]=RND(32)-16:[K+1]=RND(24)-12:[K+2]=5:[K+3]=RND(8)
70 FORD=5TO50
80 J=40:K=24:X=[K]:Y=[K+1]:Z=[K+2]:C=[K+3]:IFS=0GSB500ELSEGSB600
90 Z=D*2
100 [K+2]=Z:[K+3]=(C+1)%12
110 CLS:A=USR(#700,0)
135 WAIT 2
140 NEXT
150 T=T+1:IFT>3T=0:S=1-S
170 GOTO 50
500 H=0:I=0:GSB1000:[J]=X+V:[J+1]=Y-5:[J+2]=-(z+W)
520 H=10:I=0:GSB1000:[J+3]=X+V:[J+4]=Y+5:[J+5]=z+W
530 H=-10:I=0:GSB1000:[J+6]=X+V:[J+7]=Y+5:[J+8]=z+W
540 H=0:I=0:GSB1000:[J+9]=X+V:[J+10]=Y-5:[J+11]=z+W
550 RTN
600 H=0:I=-5:GSB1000:[J]=X+V:[J+1]=Y+W:[J+2]=-Z
610 H=10:I=5:GSB1000:[J+3]=X+V:[J+4]=Y+W:[J+5]=z
620 H=-10:I=5:GSB1000:[J+6]=X+V:[J+7]=Y+W:[J+8]=z
630 H=0:I=-5:GSB1000:[J+9]=X+V:[J+10]=Y+W:[J+11]=z
650 RTN
1000 V=(H*[C]-I*[12+C])/10
1010 W=(H*[12+C]+I*[C])/10
1020 RTN


■デモプログラム2 :回転する角錐

10 CLS:[0]=10:[1]=8:[2]=5:[3]=0:[4]=-5:[5]=-8:[6]=-10:[7]=-8:[8]=-5:[9]=0:[10]=5:[11]=8
30 [12]=0:[13]=5:[14]=8:[15]=10:[16]=8:[17]=5:[18]=0:[19]=-5:[20]=-8:[21]=-10:[22]=-8:[23]=-5
40 FORE=40TO99:[E]=-1:NEXT
50 FORE=0TO1:K=24+E*4:[K]=RND(32)-16:[K+1]=RND(24)-12:[K+2]=5+E*30:[K+3]=RND(8):NEXT
70 FORD=5TO50
80 FORE=0TO1:J=40+E*24:K=24+E*4:X=[K]:Y=[K+1]:Z=[K+2]:C=[K+3]:GSB500
90 Z=Z+2:IFZ>100Z=20
100 [K+2]=Z:[K+3]=(C+1)%12:NEXT
110 CLS:A=USR(#700,0)
135 WAIT 2
140 NEXT:GOTO50
500 H=0:I=-4:GSB1000:[J]=X+V:[J+1]=Y+W:[J+2]=-Z
510 H=4:I=4:GSB1000:[J+3]=X+V:[J+4]=Y+W:[J+5]=Z
520 H=-4:I=4:GSB1000:[J+6]=X+V:[J+7]=Y+W:[J+8]=Z
530 H=0:I=-4:GSB1000:[J+9]=X+V:[J+10]=Y+W:[J+11]=Z
540 H=0:I=0:GSB1000:[J+12]=X+V:[J+13]=Y+W:[J+14]=Z+8
550 H=4:I=4:GSB1000:[J+15]=X+V:[J+16]=Y+W:[J+17]=Z
560 H=0:I=0:GSB1000:[J+18]=X+V:[J+19]=Y+W:[J+20]=-(Z+8)
570 H=-4:I=4:GSB1000:[J+21]=X+V:[J+22]=Y+W:[J+23]=Z:RTN
1000 V=(H*[C]-I*[12+C])/10:W=(H*[12+C]+I*[C])/10:RTN



■デモプログラム3 :キー操作できる立方体
 
 これは上下左右キーでXY方向移動、1・2キーでZ方向移動、3・4キーで回転ができます。

10 CLS:[0]=10:[1]=8:[2]=5:[3]=0:[4]=-5:[5]=-8:[6]=-10:[7]=-8:[8]=-5:[9]=0:[10]=5:[11]=8
30 [12]=0:[13]=5:[14]=8:[15]=10:[16]=8:[17]=5:[18]=0:[19]=-5:[20]=-8:[21]=-10:[22]=-8:[23]=-5
40 FORE=40TO99:[E]=-1:NEXT:C=0:X=0:Y=0:Z=40
100 GSB500:K=INKEY():IFK=51C=C-1:IFC<0C=11
110 IFK=52C=C+1:IFC>11C=0
120 IFK=28ANDX>-32:X=X-1
130 IFK=29ANDX<32:X=X+1
140 IFK=30ANDY>-32:Y=Y-1
150 IFK=31ANDY<32:Y=Y+1
160 IFK=49ANDZ>20:Z=Z-2
170 IFK=50ANDZ<100:Z=Z+2
180 CLS:?"X:";X;" Y:";Y;" Z:";Z;" R:";C:A=USR(#700,0):WAIT2:GOTO100
500 H=-10:I=-10:GSB1000:[40]=X+V:[41]=Y-3:[42]=-(z+W):[55]=X+V:[56]=Y+3:[57]=Z+W
510 H=10:I=-10:GSB1000:J=43:GSB700:H=10:I=10:GSB1000:J=46:GSB700
520 H=-10:I=10:GSB1000:J=49:GSB700:H=-10:I=-10:GSB1000:J=52:GSB700
530 H=10:I=-10:GSB1000:J=70:GSB710:H=10:I=10:GSB1000:J=76:GSB710
540 H=-10:I=10:GSB1000:J=82:GSB710:RTN
700 [J]=X+V:[J+1]=Y-3:[J+2]=z+W:[J+15]=X+V:[J+16]=Y+3:[J+17]=Z+W:RTN
710 [J]=X+V:[J+1]=Y-3:[J+2]=-(z+W):[J+3]=X+V:[J+4]=Y+3:[J+5]=Z+W:RTN
1000 V=(H*[C]-I*[12+C])/10:W=(H*[12+C]+I*[C])/10:RTN


■マシン語ルーチンのソースコード

1行目の<と>は全角になっていますが、お使いになる場合は半角に変えてください。
(FC2ブログ文字化け対策)

#include <stdint.h>
#define VRAM_ADR 0x900 // 画面
#define WORK_ADR 0x800

uint16_t stars(uint16_t c, uint8_t* m_p, uint8_t* f_p)
{
int16_t p,x0,y0,z0,x1,y1,z1,i,x,y,xp,yp,dx,dy,w;
uint8_t c1;
int16_t* w_p = m_p + WORK_ADR; // 変数アドレス獲得
uint8_t* v_p = m_p + VRAM_ADR; // 画面アドレス獲得

p=40;
// x1=0;y1=0;z1=0; //********* メモリ節約のため初期化しない。最初のデータをZ<0とすること。
while (p<100) { //***** 配列[40]-[99]を使用
x0 = x1; y0=y1; z0=z1;
x1 = w_p[p++];y1 = w_p[p++];z1= w_p[p++];
if (z1<0) {
z1 = -z1; //***** Zがマイナスは一筆書きの切れ目を意味する
}else{
dx = ((x1*z1)>>5) - ((x0*z0)>>5); //***** 3D-2D変換後のX座標始点と終点の差分を計算
dy = ((y1*z1)>>5) - ((y0*z0)>>5); //***** 3D-2D変換後のY座標始点と終点の差分を計算
x = ( (x0*z0) << 1); //***** 3D-2D変換後の始点X座標 ((x0*z0)>>5) <<6) 画面座標の64倍
y = ( (y0*z0) << 1); //***** 3D-2D変換後の始点X座標((x0*z0)>>5) <<6) 画面座標の64倍
for (i=0;i<64;i++) { //64回dx、dy加算で線を引く
xp=x>>6; //画面座標にする
yp=y>>6; // 画面座標にする
w=((yp&0xfffe) <<4) + (xp>>1) + 384+16; //*** 変換した座標に対応するVRAMアドレス計算
c1= ( 1 <<( ( ( xp&1) | (yp&1)<<1) ) ) | 0x80; //*********** セミグラフィックキャラ計算
if ( (xp>-32)&&(xp<32)&&(yp>-24)&&(yp<24) ) {v_p[w] |= c1;}
x += dx;
y += dy;
}
}
}
return 0;
}


マシン語256B、BASIC1KBでも結構いろいろできるものです。

それではまたです。

2016.07.02 Sat l ICHIGOJAM l コメント (0) l top
キャラクタ3Dがまあまあ動いたので気をよくして、次は「ワイヤフレーム3Dいってみよう!」ということにしました。

「まずはラインルーチンから」と考えたところで、はたと困りました。

普通にブレゼンハムのアルゴリズムを考えたのですが、これって傾きが1未満と1以上で描画を分けるのですよね。つまり2倍のコードが必要なわけです。始点と終点のX,Y大小関係も考慮が必要です。
これまでの経験上、これはichigojam用としてはメモリが足りないだろう、とわかります。

どうしたものかなあ、と考えていたところ、通勤中の電車内でひらめきました。

  ・ichigojamのセミグラフィックを64x64しかないのを逆手に取り、その範囲にあったアルゴリズムにします。

   ・描画する座標x,yそれぞての始点と終点の差分を取りdx、dyとします。 
   ・描画座標は64倍で計算します。
   ・64倍された始点座標にdx、dyを加算していくと、64回加算でちょうど終点座標の64倍になります。
   ・その加算過程の座標を1/64してドットをうつと、始点から終点にいたる線が描画されます。

これは普通に縦横数百PIXEL以上の画面では演算回数が多くなりすぎて使えないでしょう。
また、短い線だと同じPIXELに何回も無駄に書きます。(極端な話長さ1piexlの線でも同じところに64回点を打ちます。)
64x64しかないから画面でマシン語だから使えるアルゴリズムです。

帰宅して早速C言語にしてみました。

最初の行の<と>は全角ですが、使用する場合は半角の<と>変えてください。
FC2ブログ文字化けを防ぐためにこうしています。


#include <stdint.h>
#define VRAM_ADR 0x900
#define WORK_ADR 0x800

uint16_t stars(uint16_t c, uint8_t* m_p, uint8_t* f_p)
{
int16_t p,x0,y0,x1,y1,i,x,y,xp,yp,dx,dy,w;
uint8_t c1;
int16_t* w_p = m_p + WORK_ADR;
uint8_t* v_p = m_p + VRAM_ADR;

p=0;
while (p<4) {
x0 = w_p[p++];y0 = w_p[p++];
x1 = w_p[p++];y1 = w_p[p++];
dx = x1 - x0;
dy = y1 - y0;
x = x0 << 6;
y = y0 << 6;
for (i=0;i<64;i++) {
xp=x>>6;
yp=y>>6;
w=((yp&0xfffe) <<4) + (xp>>1) + 384+16; //*** 変換した座標に対応するVRAMアドレス計算
c1= ( 1 <<( ( ( xp&1) | (yp&1)<<1) ) ) | 0x80; //*********** セミグラフィックキャラ計算
if ((xp>-32)&&(xp<32)&&(yp>-24)&&(yp<24)&&((v_p[w]&0x70)==0) ) {v_p[w] |= c1;}
x += dx;
y += dy;
}
}
return 0;
}


で、BASICでは以下のコードでテストしてみました。

10 cls
20 for i=-5to5
25 cls
30 [0]=31:[1]=-i:[2]=-31:[3]=i
40 a=usr(#700,0)
45 wait 10
50 next
100 for i=-5to5
110 cls
120 [0]=-i:[1]=-i:[2]=i:[3]=i
130 a=usr(#700,0)
140 wait 10
150 next
200 for i=-5to5
210 cls
220 [0]=-i-5:[1]=-i+5:[2]=i:[3]=i*2
230 a=usr(#700,0)
240 wait 10
250 next


意図通りに線が描画されます。傾きも始点・終点位置関係も問題なしです。

いけるようなので明日はZ座標を導入して3Dのラインを書けるようにします。

その次はいよいよワイヤフレーム3Dです。

それではまたです。


2016.06.29 Wed l ICHIGOJAM l コメント (0) l top
最近少し早く帰れるようになったので趣味の方のプログラムがはかどります。

ichigojamマシン語活用でわかってきたことを応用して、汎用的に使えるマシン語3Dルーチンを作ってみました。

BASIC領域をあまり消費せずに高速で3D風表示ができますので、シューティングゲーム等にも使えると思います。
実は昔のPC8001用3Dゲーム「OLION」というのを意識して作ってみました。

あまりメジャーじゃなかった感じだし、正直やってみてあまり面白くはなかった(^^; ような記憶ですが、
最初に画面を見た時の「おお3Dだ!」という感動だけは覚えています。

■概要
  18個までの文字をX,Y,Z座標指定で3D空間に配置してコールすることで文字を2D変換して表示できます。
  以下のような表示ができます。




■使い方
  下の「マシン語書き込みプログラム」を実行します。これにより、#700-#82Fの空間にルーチンが格納されます。
  配列変数[24]-[99]に配列4個一文字で文字コードとX,Y,Z座標を
   [24] = 文字コードです。ichigojamの固定キャラクタ番号を#01-#FFで指定します。
       #00で指定するとその文字および以下XYZは無視されます。
   [25] = x座標を -32~+32で入れます。
   [26] = Y座標を -32~+32で入れます。
   [27] = Z座標を 0~100くらいで入れます。0が最遠で数字が大きいほど近くなります。
   以下同様に[24+N*4]~[24+N*4+3]に表示したい文字情報を入れます。
    (Nは0以上18以下です。これで配列[100]までを使い切ります。)
   
   その後CLSで画面消去したのちにA=USR(#700,0)でコールすると各文字を3D-2D変換して表示します。

■制限
  プログラムのお尻が配列領域まではみ出しています。このため配列[0]~[23]は使用・書き換え禁止です。
  書き換えてコールすると暴走します。CLVも使用できません。

■マシン語書き込みプログラム
  以下をロードして実行します。


1 poke#700,240,181,144,32,70,76,143,176,0,1,12,146,8,24,131,34,12,25,18,1,5,144,9,148,139,24,25,136,157,136,201,4,9,12,90,136,6,149,216,136,0,41,7,209,9
2 poke#72d,159,8,51,187,66,242,209,15,176,240,188,2,188,8,71,0,4,18,4,0,20,18,20,4,50,132,70,96,70,80,67,53,78,10,144,8,34,72,28,12,156,9,4,9,20
3 poke#75a,97,92,6,157,0,4,0,12,1,144,3,145,48,4,41,4,9,20,0,20,64,24,7,28,96,70,120,67,64,17,4,4,36,12,33,28,23,49,9,4,9,12,2,145,1
4 poke#787,33,140,67,200,37,36,5,109,4,100,25,103,70,1,64,36,12,127,66,73,0,7,148,11,151,10,152,8,145,8,33,68,17,37,28,31,53,45,4,45,12,62,45,33,216
5 poke#7b4,2,157,46,45,30,216,37,4,7,159,45,20,109,16,125,25,45,4,5,159,45,20,125,25,0,149,45,120,4,149,4,159,112,37,47,66,14,209,3,157,1,39,61,64,60
6 poke#7e1,64,8,159,60,67,165,64,128,39,44,28,127,66,4,157,60,67,0,159,44,67,60,112,3,156,1,57,11,157,100,8,9,4,3,148,9,12,64,25,0,41,204,209,113,28
7 poke#80e,1,58,14,4,18,4,54,12,18,12,0,209,135,231,1,153,152,231,200,8,0,0,252,255,0,0


■サンプルソフト
  動きは動画でご確認ください。



10 CLS
20 FORI=6TO24:J=I*4:[J]=0:[J+1]=I*6-50:[J+2]=I*2-20:[J+3]=0:NEXT
30 [24]=#49:[28]=#63:[32]=#68:[36]=#69:[40]=#67:[44]=#6F:[48]=#6A:[52]=#61:[56]=#6D
40 T=50:GOSUB1000
50 FORI=6TO24:J=I*4:[J]=0:NEXT
60 [24]=#33:[25]=10:[26]=5:[27]=10:[28]=#44:[29]=16:[30]=5:[31]=10
70 [32]=#33:[33]=-16:[34]=-5:[35]=40:[36]=#44:[37]=-10:[38]=-5:[39]=40
75 [40]=#33:[41]=-16:[42]=10:[43]=0:[44]=#44:[45]=-10:[46]=10:[47]=0
80 T=100:GOSUB 1000
90 FORI=6TO24:J=I*4:[J]=0:NEXT
100 FORI=6TO10:J=I*4:[J]=#FF:[J+1]=RND(32)-16:[J+2]=RND(32)-16:[J+3]=RND(10)*4:NEXT
110 T=200:GOSUB 1000
200 FORI=6TO24:J=I*4:[J]=0:NEXT
210 FORI=6TO10:J=I*4:[J]=#F1:[J+1]=RND(32)-16:[J+2]=RND(32)-16:[J+3]=RND(10)*4:NEXT
220 T=200:GOSUB 1000
230 GOTO 20
1000 FORI=0TO T
1010 FORJ=0TO9:K=J*4+24:[K+3]=[K+3]+1
1012 IF [K]=#F1 [K+1]=[K+1]+RND(3)-1
1015 IF[K+3]>60 [K+3]=0
1016 NEXT
1020 CLS
1030 A=USR(#700,0)
1050 NEXT
1060 RTN


■3Dルーチンソースコード
  以下をコンパイルしてマシン語書き込みプログラムを生成しています。
  何やってるのかできるだけわかるようにコメントつけました。

  できれば#700~#7FFに収めようと努力したのですができませんでした。
  範囲チェックを外せば入るのですが、暴走が恐ろしくてできません。


2016/06/29PM8追記:1行目の#includeの次は全角の<>で挟まれていますが、
         半角の<と>に置き換えてください。
         FC2ブログは半角の<と>で挟まれているとおかしな文字化けをするみたいです。
2016/06/30AM6追記:ソースコード誤り訂正。
    誤:#define WORK_ADR 0x0830 → 正:#define WORK_ADR 0x0800



#include <stdint.h>
#define VRAM_ADR 0x0900
#define WORK_ADR 0x0800

uint16_t stars(uint16_t c, uint8_t* m_p, uint8_t* f_p)
{
int16_t x,y,z,w,ca,x0,y0,x1,y1,i;
uint8_t c0,c1;
//********** 実アドレスゲット *********
int16_t* w_p = m_p + WORK_ADR; //******** 変数領域
uint8_t* v_p = m_p + VRAM_ADR; //******** VRAM領域

i = 24;
while(i<100) { //**** 文字数分LOOP
//******************** ca:キャラクタデータアドレス, X,Y,Z:3次元座標 *******************
ca = w_p[i++]*8; x = w_p[i++]; y = w_p[i++]; z =w_p[i++];
//********************* 一文字 8x8 DOT表示ループ **********************************************
if (ca !=0) { //***** キャラクタ00の場合は何もしない
for (y0=-4;y0<4;y0++) { //*** キャラクタ縦8行分LOOP **********************
c0 = f_p[ca++]; //*** キャラクタデータ1行分を取り出す**************
for (x0=-4;x0<4;x0++) { //*** キャラクタ横8桁分LOOP **********************
x1 =((x-x0)*z)>>5; //*** X座標を3D-2D変換
y1 = ((y+y0)*z)>>5; //*** Y座標を3D-2D変換
w=((y1&0xfffe) <<4) + (x1>>1) + 384+16; //*** 変換した座標に対応するVRAMアドレス計算
c1= ( (c0&1) <<( ( ( x1&1) | (y1&1)<<1) ) ) | 0x80; //*********** セミグラフィックキャラ計算
//**** VRAM領域内で空白またはセミグラフィックキャラなら書き込み
if ((x1>-32)&&(x1<32)&&(y1>-24)&&(y1<24)&&((v_p[w]&0x70)==0) ) {v_p[w] |= c1;}
c0 >>= 1; //***** 次のPIXELを計算
}
}
}
}
}




それではまたです。
2016.06.28 Tue l ICHIGOJAM l コメント (0) l top
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。