page0099
をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
単語検索
|
最終更新
|
ヘルプ
]
開始行:
* OSECPU-ASKA入門 #0016
-(by [[K]], 2013.07.08)
** (0) はじめに
-以下の記事はosecpu118dのWindows版を前提にしています。他...
--ちなみに[[page0074]]を読めばrev2の最新版が見つかります。
~
-もくじ
--[[page0087]]: #0010
--[[page0088]]: #0011
--[[page0089]]: #0012
--[[page0093]]: #0013
--[[page0095]]: #0014
--[[page0098]]: #0015
--[[page0099]]: #0016
** (1) メモリ(配列変数)を使う
-OSECPU-ASKAでは配列変数のことを「メモリ」といいます。そ...
-一例として、メモリを使ってちょっとした絵を描いてみます。
#include "osecpu_ask.h"
#define L_invader LOCAL(0)
LOCALLABELS(1);
do {
Int32s c:R00, x:R01, y:R02, i:R03;
VPtr p:P01;
PLIMM(p, L_invader);
for (y = 0; y != 16; y++) {
for (x = 0; x != 32; x++) {
i = y * 32 + x;
PALMEM0(32, c, T_UINT1, p, i);
c *= 2; // これで0か2になる. ちなみに2は...
api_drawPoint(MODE_COL3, c, x, y);
}
}
}
DAT_SA(L_invader, T_UINT1, 32 * 16);
D1B(0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0...
D1B(0,0,0,0, 0,0,0,0, 0,0,0,0, 1,1,1,1, 1,1,1,1, 0,0...
D1B(0,0,0,0, 0,0,0,0, 0,1,1,1, 1,1,1,1, 1,1,1,1, 1,1...
D1B(0,1,0,0, 0,0,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1...
D1B(0,1,0,1, 1,1,1,1, 1,1,0,0, 1,1,1,1, 1,1,1,1, 0,0...
D1B(0,1,0,1, 1,1,1,1, 1,1,0,0, 1,1,1,1, 1,1,1,1, 0,0...
D1B(0,1,0,1, 1,1,1,1, 1,1,0,0, 1,1,1,1, 1,1,1,1, 0,0...
D1B(0,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1...
D1B(0,0,0,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1...
D1B(0,0,0,1, 1,1,1,1, 1,1,1,0, 0,0,0,0, 0,0,0,0, 0,1...
D1B(0,0,0,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1...
D1B(0,0,0,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1...
D1B(0,0,0,0, 0,0,0,0, 1,1,0,0, 0,0,0,0, 0,0,0,0, 0,0...
D1B(0,0,1,0, 0,0,0,0, 1,1,0,0, 0,0,0,0, 0,0,0,0, 0,0...
D1B(0,0,1,1, 1,1,1,1, 1,1,0,0, 0,0,0,0, 0,0,0,0, 0,0...
D1B(0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0...
DAT_END();
-これを実行するとインベーダの絵が出てきます。これを例にい...
~
-最初の#defineは関数を作った時と同じ構文です。こうやって...
-データを宣言しているのは、末尾にあるDAT_SA()...DAT_END()...
-DAT_SA(ラベル名, 型名, データの個数); という記述になりま...
--使える型名は以下の通りです。
---T_SINT1, T_UINT1
---T_SINT2, T_UINT2
---T_SINT4, T_UINT4
---T_SINT8, T_UINT8
---T_SINT12, T_UINT12
---T_SINT16, T_UINT16
---T_SINT20, T_UINT20
---T_SINT24, T_UINT24
---T_SINT28, T_UINT28
---T_SINT32, T_UINT32
--T_SINT32はInt32sに相当します。
-ここで使っているT_UINT1というのは、1ビットの符号なしの整...
-D1Bというのは、データを記述するための命令でData1Bitの略...
-結局、これはC言語で言うところの、
int invader[32 * 16] = { 0, 0, 0, 0,... };
-とほぼ同じです。違うのは1ビットの配列だというところだけ...
-注意点としては、総ビット数は8の倍数になっている必要があ...
-VPtr p:P01; :
--これは、変数pの宣言で、P01レジスタを割り当てています。P...
--RxxはいつもInt32s型でしたが、PxxはいつもVPtr型になりま...
-PLIMM(p, L_invader); :
--この命令で p = L_invader; になります。こうやってPxxレジ...
-PALMEM0(32, c, T_UINT1, p, i);
--C言語風に言えば、 c = p[i]; ということです。
--最初の32は「この処理を32ビットでおこなえ」という意味で...
--T_UINT1はpの型です。iはレジスタ変数である必要があって、...
--なおMEM0は「メモ」ではなく、「メム・ゼロ」です。つまり...
-do { ... } の末尾にapi_end();を置いてもいいですが、置か...
** (2) メモリに書き込む&mallocを使う
-以下のプログラムは、999までの素数を表示するプログラムで...
#include "osecpu_ask.h"
do {
VPtr p:P01;
Int32s i:R00, j:R01, v:R02;
// 初期化.
api_malloc(p, T_UINT1, 1000);
v = 0;
for (i = 0; i != 1000; i++) {
PASMEM0(32, v, T_UINT1, p, i);
}
// 倍数に印をつけていく.
v = 1;
for (i = 2; i != 1000; i++) {
for (j = i * 2; ; j += i) {
if (j >= 1000) break;
PASMEM0(32, v, T_UINT1, p, j);
}
}
// 素数の表示.
for (i = 2; i != 1000; i++) {
PALMEM0(32, v, T_UINT1, p, i);
if (v == 0) {
api_putStringDec('\1 ', i, 3, 1);
}
}
}
-初期値をDAT_SA()構文で設定する必要がない場合、上記の例の...
-PASMEM0()はPALMEM0の読み書きを逆転させたもので、メモリに...
-しかし当然ながら、型に収まらない値を書いてはいけません。...
--これはセキュリティ上の問題というよりも単なるバグという...
----
-ここで少しセキュリティ上のポイントを紹介しておこうと思い...
-(a) このプログラムで、初期化処理のPASMEM0をコメントアウ...
-(b) if (j >= 1000) break; の部分をコメントアウトしたらど...
** (3) つづく
-(工事中)
* こめんと欄
#comment
終了行:
* OSECPU-ASKA入門 #0016
-(by [[K]], 2013.07.08)
** (0) はじめに
-以下の記事はosecpu118dのWindows版を前提にしています。他...
--ちなみに[[page0074]]を読めばrev2の最新版が見つかります。
~
-もくじ
--[[page0087]]: #0010
--[[page0088]]: #0011
--[[page0089]]: #0012
--[[page0093]]: #0013
--[[page0095]]: #0014
--[[page0098]]: #0015
--[[page0099]]: #0016
** (1) メモリ(配列変数)を使う
-OSECPU-ASKAでは配列変数のことを「メモリ」といいます。そ...
-一例として、メモリを使ってちょっとした絵を描いてみます。
#include "osecpu_ask.h"
#define L_invader LOCAL(0)
LOCALLABELS(1);
do {
Int32s c:R00, x:R01, y:R02, i:R03;
VPtr p:P01;
PLIMM(p, L_invader);
for (y = 0; y != 16; y++) {
for (x = 0; x != 32; x++) {
i = y * 32 + x;
PALMEM0(32, c, T_UINT1, p, i);
c *= 2; // これで0か2になる. ちなみに2は...
api_drawPoint(MODE_COL3, c, x, y);
}
}
}
DAT_SA(L_invader, T_UINT1, 32 * 16);
D1B(0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0...
D1B(0,0,0,0, 0,0,0,0, 0,0,0,0, 1,1,1,1, 1,1,1,1, 0,0...
D1B(0,0,0,0, 0,0,0,0, 0,1,1,1, 1,1,1,1, 1,1,1,1, 1,1...
D1B(0,1,0,0, 0,0,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1...
D1B(0,1,0,1, 1,1,1,1, 1,1,0,0, 1,1,1,1, 1,1,1,1, 0,0...
D1B(0,1,0,1, 1,1,1,1, 1,1,0,0, 1,1,1,1, 1,1,1,1, 0,0...
D1B(0,1,0,1, 1,1,1,1, 1,1,0,0, 1,1,1,1, 1,1,1,1, 0,0...
D1B(0,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1...
D1B(0,0,0,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1...
D1B(0,0,0,1, 1,1,1,1, 1,1,1,0, 0,0,0,0, 0,0,0,0, 0,1...
D1B(0,0,0,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1...
D1B(0,0,0,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1...
D1B(0,0,0,0, 0,0,0,0, 1,1,0,0, 0,0,0,0, 0,0,0,0, 0,0...
D1B(0,0,1,0, 0,0,0,0, 1,1,0,0, 0,0,0,0, 0,0,0,0, 0,0...
D1B(0,0,1,1, 1,1,1,1, 1,1,0,0, 0,0,0,0, 0,0,0,0, 0,0...
D1B(0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0...
DAT_END();
-これを実行するとインベーダの絵が出てきます。これを例にい...
~
-最初の#defineは関数を作った時と同じ構文です。こうやって...
-データを宣言しているのは、末尾にあるDAT_SA()...DAT_END()...
-DAT_SA(ラベル名, 型名, データの個数); という記述になりま...
--使える型名は以下の通りです。
---T_SINT1, T_UINT1
---T_SINT2, T_UINT2
---T_SINT4, T_UINT4
---T_SINT8, T_UINT8
---T_SINT12, T_UINT12
---T_SINT16, T_UINT16
---T_SINT20, T_UINT20
---T_SINT24, T_UINT24
---T_SINT28, T_UINT28
---T_SINT32, T_UINT32
--T_SINT32はInt32sに相当します。
-ここで使っているT_UINT1というのは、1ビットの符号なしの整...
-D1Bというのは、データを記述するための命令でData1Bitの略...
-結局、これはC言語で言うところの、
int invader[32 * 16] = { 0, 0, 0, 0,... };
-とほぼ同じです。違うのは1ビットの配列だというところだけ...
-注意点としては、総ビット数は8の倍数になっている必要があ...
-VPtr p:P01; :
--これは、変数pの宣言で、P01レジスタを割り当てています。P...
--RxxはいつもInt32s型でしたが、PxxはいつもVPtr型になりま...
-PLIMM(p, L_invader); :
--この命令で p = L_invader; になります。こうやってPxxレジ...
-PALMEM0(32, c, T_UINT1, p, i);
--C言語風に言えば、 c = p[i]; ということです。
--最初の32は「この処理を32ビットでおこなえ」という意味で...
--T_UINT1はpの型です。iはレジスタ変数である必要があって、...
--なおMEM0は「メモ」ではなく、「メム・ゼロ」です。つまり...
-do { ... } の末尾にapi_end();を置いてもいいですが、置か...
** (2) メモリに書き込む&mallocを使う
-以下のプログラムは、999までの素数を表示するプログラムで...
#include "osecpu_ask.h"
do {
VPtr p:P01;
Int32s i:R00, j:R01, v:R02;
// 初期化.
api_malloc(p, T_UINT1, 1000);
v = 0;
for (i = 0; i != 1000; i++) {
PASMEM0(32, v, T_UINT1, p, i);
}
// 倍数に印をつけていく.
v = 1;
for (i = 2; i != 1000; i++) {
for (j = i * 2; ; j += i) {
if (j >= 1000) break;
PASMEM0(32, v, T_UINT1, p, j);
}
}
// 素数の表示.
for (i = 2; i != 1000; i++) {
PALMEM0(32, v, T_UINT1, p, i);
if (v == 0) {
api_putStringDec('\1 ', i, 3, 1);
}
}
}
-初期値をDAT_SA()構文で設定する必要がない場合、上記の例の...
-PASMEM0()はPALMEM0の読み書きを逆転させたもので、メモリに...
-しかし当然ながら、型に収まらない値を書いてはいけません。...
--これはセキュリティ上の問題というよりも単なるバグという...
----
-ここで少しセキュリティ上のポイントを紹介しておこうと思い...
-(a) このプログラムで、初期化処理のPASMEM0をコメントアウ...
-(b) if (j >= 1000) break; の部分をコメントアウトしたらど...
** (3) つづく
-(工事中)
* こめんと欄
#comment
ページ名: