NESASMのBG描きこみルーチンについて

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
KEYONN_

NESASMのBG描きこみルーチンについて

#1

投稿記事 by KEYONN_ » 15年前

ファミコンソフトをC言語で作るのは実用的ではないと思いまして、ファミコンのアセンブリ言語を
使っています。そこで問題が生じました。以下のC言語で実装したBG描きこみルーチンを
6502のアセンブリ言語で実装しようとしたらエラーが出てしまいました。
どうすればエラーを回避し、思い通りの結果が期待できるでしょうか?
どうかみなさまお力を貸してください。

あと、アセンブリ言語でもこの掲示板に書き込むのは適切だったでしょうか…?
他に有名なアセンブリ言語の掲示板を知らないので良かったらそちらも教えていただくと嬉しいです。


void DrawBG(unsigned char x,unsigned char y,unsigned char number)
{
  int adr;
  adr = (y-1)*32+x;
  *(char*)0x2006 = 0x20+adr/256;
  *(char*)0x2006 = adr;

  *(char*)0x2007 = number;
}
C言語で記述するとこうなるのですが、NESASMというファミコン用のアセンブラでこうなるように
記述してみたのですが、エラーが出てしまいます。

Sum EQU $0010
Count EQU $0011
AA EQU $0012
B EQU $0013
A2 EQU $0014
B2 EQU $0015
Sum2 EQU $0016
ADR EQU $0017
XX EQU $0018
YY EQU $0019
NUM EQU $0020

Div:
lda AA
sta Sum
lda #$00
sta Count
lda Sum
loop:
inc Count
sbc B
bne loop
rts
Mul:
lda #$00
sta Sum2
loop2:
ldx B2
adc A2
dex
bne loop2
sta Sum2
rts
wrtBG:
lda YY
dec a
lda YY
sta A2
lda #32
sta B2
jsr mul
lda Sum2
adc XX
sta ADR
lda ADR
sta AA
lda #256
sta B
jsr div
lda Count
adc #$20
sta $2006
lda ADR
sta $2006
lda NUM
sta $2007
rts

エラーは次のとおりです。

Microsoft (R) KKCFUNC バージョン 1.10
Copyright (C) Microsoft Corp. 1991,1993. All rights reserved.

KKCFUNC が組み込まれました.

マイクロソフトかな漢字変換 バージョン 2.51
(C)Copyright Microsoft Corp. 1992-1993
NES Assembler (v2.0)

#[1] PUTSTRING.ASM
131 03:0038 jsr mul
Undefined symbol in operand field!
137 03:004A lda #256
Incorrect immediate value!
139 03:004D jsr div
Undefined symbol in operand field!
# 3 ERROR(s)

C:\DOCUME~1\HP\デスク~1\PUTSTR~1>

たかぎ

Re:NESASMのBG描きこみルーチンについて

#2

投稿記事 by たかぎ » 15年前

ざっとしか見ていませんが...

> 131 03:0038 jsr mul
> Undefined symbol in operand field!
> 139 03:004D jsr div
> Undefined symbol in operand field!

この二つは、単にシンボルの大文字・小文字がそろっていないだけでは?

> 137 03:004A lda #256
> Incorrect immediate value!

ldaのオペランドに指定できるイミディエイト値は8ビットなので、256だと大きすぎます。

このアセンブリ言語のコードをどうやって得たのかわかりませんが、ぱっと見ただけでもいろいろ怪しいところがあります。
そもそも乗除算は必要ありませんし、個々の命令の使い方もおかしいところだらけです。
(キャリーフラグを放置したままadcとか...)

KEYONN_

Re:NESASMのBG描きこみルーチンについて

#3

投稿記事 by KEYONN_ » 15年前

>このアセンブリ言語のコードをどうやって得たのかわかりませんが、
>ぱっと見ただけでもいろいろ怪しいところがあります。
>そもそも乗除算は必要ありませんし、個々の命令の使い方もおかしいところだらけです。
>(キャリーフラグを放置したままadcとか...)
すみません。。ファミコンのアセンブリ言語やるの久しぶりなもので…私が書いたコードです。


> 131 03:0038 jsr mul
> Undefined symbol in operand field!
> 139 03:004D jsr div
> Undefined symbol in operand field!

>この二つは、単にシンボルの大文字・小文字がそろっていないだけでは?
そうですね。ありがとうございます。


> 137 03:004A lda #256
> Incorrect immediate value!

>ldaのオペランドに指定できるイミディエイト値は8ビットなので、256だと大きすぎます。
256だと大きすぎる場合、どうすれば実装すればいいでしょうか?

たかぎ

Re:NESASMのBG描きこみルーチンについて

#4

投稿記事 by たかぎ » 15年前

> >ldaのオペランドに指定できるイミディエイト値は8ビットなので、256だと大きすぎます。
> 256だと大きすぎる場合、どうすれば実装すればいいでしょうか?

この256は、adr/256の除数ですよね。
adrのアドレスはADRだと思いますが、1バイト分しか確保されていないようです(直後はXXなので)。それでよいのでしょうか?
そうではなく、ADRとADR+1の2バイトでadrを表現するのであれば、256で割るということは上位1バイトを取ればよいので、割り算なんかしなくても、

lda ADR+1

で済むはずですね。

KEYONN_

Re:NESASMのBG描きこみルーチンについて

#5

投稿記事 by KEYONN_ » 15年前

>たかぎさん

256を割らなくても、+1すればいいという事でしょうか?
アセンブリソースコードを次のように直してみたのですが、
やはりBGに書き込めませんでした。
何が駄目だったのでしょうか?

wrtBG:
lda YY
dec a
clc
asl a
asl a
asl a
asl a
asl a
clc
adc XX
sta ADR
clc
lda ADR+1
clc
adc #$20
sta $2006
lda ADR
sta $2006
lda NUM
sta $2007
rts

KEYONN_

Re:NESASMのBG描きこみルーチンについて

#6

投稿記事 by KEYONN_ » 15年前

ADR+1の意味がよく分からないです。 画像

KEYONN_

Re:NESASMのBG描きこみルーチンについて

#7

投稿記事 by KEYONN_ » 15年前

もしかして、僕はものすごい勘違いをしてますか?
ビット演算系は、かなり不得意なので、丁寧に教えてください。
(アセンブリ言語向いてないかも)

たかぎ

Re:NESASMのBG描きこみルーチンについて

#8

投稿記事 by たかぎ » 15年前

レジスタが8ビットしかないことを再認識してください。

> ADR+1の意味がよく分からないです。

変数adrの値は、ADR+0, ADR+1の2バイトに格納されるはずですね。
6502はリトルエンディアンですので、ADR+0に下位8ビット、ADR+1に上位8ビットが入ります。
16ビットの値を256で割るということは、上位8ビットだけを取り出せばよいので、ADR+1を読めばよいことになります。

KEYONN_

Re:NESASMのBG描きこみルーチンについて

#9

投稿記事 by KEYONN_ » 15年前

>レジスタが8ビットしかないことを再認識してください。

> ADR+1の意味がよく分からないです。

>変数adrの値は、ADR+0, ADR+1の2バイトに格納されるはずですね。
>6502はリトルエンディアンですので、ADR+0に下位8ビット、ADR+1に上位8ビットが入ります。
>16ビットの値を256で割るということは、上位8ビットだけを取り出せばよいので、
>ADR+1を読めばよいことになります。
分かりました。ありがとうございます。

あと、計算式で32倍するところがあるのですが、これはどう実装すればいいでしょうか?
32倍の限界はレジスタが8ビットしかないので、7*32までしか出来ません。

たかぎ

Re:NESASMのBG描きこみルーチンについて

#10

投稿記事 by たかぎ » 15年前

> あと、計算式で32倍するところがあるのですが、これはどう実装すればいいでしょうか?

5ビット分左シフトします。
ただし、シフト対象は16ビットにしなければなりません。
下位ビットに対してはASL命令で、上位8ビットに対してはROL命令でシフトしてください。

KEYONN_

Re:NESASMのBG描きこみルーチンについて

#11

投稿記事 by KEYONN_ » 15年前

ソースを書いてみたらこうなったのですが、何がいけなかったのでしょうか?

wrtBG:
lda YY
dec a
clc
sta N
rol N+1
rol N+1
rol N+1
rol N+1
rol N+1
asl N
asl N
asl N
asl N
asl N
clc
lda N
adc XX
sta ADR
sta ADR+1
clc
adc #$20
sta ADR
sta $2006
lda ADR+1
clc
adc #32
sta $2006
lda NUM
sta $2007
rts

たかぎ

Re:NESASMのBG描きこみルーチンについて

#12

投稿記事 by たかぎ » 15年前

もう少し命令セットの解説をよく読んで、レジスタやフラグの振る舞いを把握するようにしてください。

rol N+1
rol N+1
rol N+1
rol N+1
rol N+1
asl N
asl N
asl N
asl N
asl N

上はどういう意図なのか、説明していただけますか?

KEYONN_

Re:NESASMのBG描きこみルーチンについて

#13

投稿記事 by KEYONN_ » 15年前

ネットカフェから書き込みます。

rol a+1がエラーでうまくいかなかったのでNという変数をでっちあげ

sta N
rol N+1
rol N+1
rol N+1
rol N+1
rol N+1
asl N
asl N
asl N
asl N
asl N
としました。

たかぎ

Re:NESASMのBG描きこみルーチンについて

#14

投稿記事 by たかぎ » 15年前

シフトに入る前にclcを行っていますから、初期の時点でキャリーフラグは0、Nにはstaでストアした値、N+1は不定です。
N、N+1およびキャリーの状態を追っていくと...
C N        N+1
sta N    0 ABCDEFGH IJKLMNOP
rol N+1  I ABCDEFGH JKLMNOP0
rol N+1  J ABCDEFGH KLMNOP0I
rol N+1  K ABCDEFGH LMNOP0IJ
rol N+1  L ABCDEFGH MNOP0IJK
rol N+1  M ABCDEFGH NOP0IJKL
asl N    A BCDEFGH0 NOP0IJKL
asl N    B CDEFGH00 NOP0IJKL
asl N    C DEFGH000 NOP0IJKL
asl N    D EFGH0000 NOP0IJKL
asl N    E FGH00000 NOP0IJKL
上のようになります。ここで、A~Pは各ビットの初期値で状況に依存します。
このように、命令を実行する度に、各ビットがどうなるのかを追っていくことが大切です。
画像

閉鎖

“C言語何でも質問掲示板” へ戻る