N88-BASIC、アセンブラ、Cでポインター (2回目)

2023/1/14(土)
N88-BASIC、アセンブラ、Cでポインター (2回目)
 
C言語にポインターが存在する意味が
 
文字列中のアルファベットの小文字を
大文字に変換するプログラムを作ることで
 
何となく分かるようにするシリーズです
 
 
今回はN88-BASIC(VL,XL,NL-BASIC)で
アドレスを使用したプログラムの紹介です
アセンブラでプログラムする足ががりです
 
PC-88(XL-BASIC),PC-98(NL-BASIC),VL-BASIC
でメモリー内容が異なりますので
その3パターンに対応しています
 
blg~.zip中のptr002.basです
 
200 ON N88 + 1 GOSUB *XL, *NL, *VL
240 FOR I=1 TO N
250   B = PEEK(P)
260   IF ASC("a") <= B AND B <= ASC("z") THEN POKE P, B - C
270   P = P + 1
280 NEXT
 
プログラムと解説を交互に書きました
 
200 ON N88 + 1 GOSUB *XL, *NL, *VL
  各機種ごとに違う読み方で文字数N,アドレスPを設定
240 FOR I=1 TO N
250   B = PEEK(P)
   アドレスPの内容をBに入れる
260   IF ASC("a") <= B AND B <= ASC("z") THEN POKE P, B - C
   Bが"a"~"z"なら、アドレスP内にB-C("A"~"Z")を入れる
270   P = P + 1
   Pを1増やす
280 NEXT
  文字数N分繰返す
 
PEEK(P)はアドレスPのメモリーを読む
POKE P,DはアドレスPのメモリーにDを書く
という命令です(Dは0~&HFF)

このアドレスを入れる変数Pを
C言語ではポインターと呼んでいます

以下
メモリーのアドレス(16進数)
(BASICでは16進数は&Hを付けて表す)
とその内容を
アドレス:内容
0000:XX
と書く事にして説明しています
 

12abを入力すると
 
アドレス:内容
B100:"1"
B101:"2"
B102:"a"
B103:"b"
が入ったとすると
Nに4、Pに&HB100を代入しています
 
繰返しでP=&HB102の時
B = PEEK(P)でBは"a"となるので
POKE P, B - C
でB102:"A"に変わります
 
結果は
12AB
になる
 
 
以下、N,Pを設定する*XL,*NL,*VLサブルーチン
の解説です
 
310 '--- N88-BASIC(PC-8801) or XL-BASIC
320 *XL
330 P = VARPTR(A$)
340 N = PEEK(P)
350 P = PEEK(P+1) + PEEK(P+2) * &H100
360 RETURN
 
P = VARPTR(A$)はA$の情報が入ったアドレスがPに入る
Pが&HB000なら
B000:文字数
B001:文字列が入っているアドレスの下位バイト
B002:文字列が入っているアドレスの上位バイト
となっているので
 
上記12abの例の場合
B000:04
B001:00
B002:B1
なので
Nに4、Pに&HB100を入れています
 
 
 
370 '--- N88-BASIC(86)(PC-98) or NL-BASIC
380 *NL
390 DEF SEG = VARPTR(A$, 1)
400 P = VARPTR(A$)
410 N = PEEK(P)
420 I = PEEK(P+1)
430 P = PEEK(P+2) + PEEK(P+3) * &H100
440 IF I THEN DEF SEG = SEGPTR(7)
450 RETURN
 
A$の情報が入ったオフセットとセグメントは
VARPTR(A$) or VARPTR(A$, 0)、とVARPTR(A$, 1)
で得られます
VARPTR(A$)  :&H0000 … オフセット
VARPTR(A$, 1):&H0B00 … セグメント
とすると
アドレスは&HB000(セグメント×&H10+オフセット)
になります
DEF SEG = &H0B00でセグメントの指定
POKE &H0001,Dでアドレス&HB001にDを入れる
という使い方になります
 
P = VARPTR(A$)でPが&H0000でセグメントが&HB00なら
B000:文字数
B001:0:同じセグメント、0以外:SEGPTR(7)のセグメント
B001:文字列が入っているオフセットの下位バイト
B002:文字列が入っているオフセットの上位バイト
となっているので
 
上記12abの例の場合
B000:04
B001:00
B002:00
B003:01
なので
Nに4、Pに&H0100を入れています
 
440 IF I THEN DEF SEG = SEGPTR(7)
はB001:00以外ならセグメントをSEGPTR(7)している
 
 
460 '--- VL-BASIC
470 *VL
480 P = VARPTR(A$)
490 N = PEEK(P)
500 P = P + 1
510 RETURN
P = VARPTR(A$)はA$の情報が入ったアドレスがPに入る
Pが&H0B0FFなら、上記12abの例の場合
0B0FF:文字数4
0B100:"1"
0B101:"2"
0B102:"a"
0B103:"b"
となっているので
Nに4、Pに&H0B0FF + 1(&HB100)を入れています
VL-BASICの仕様はオリジナルなので
PC-9801に合わせるか迷っている所なので
あまり使わない方が良いかもしれません
 
 
VL,NL,XL-BASICとblg~.zip(ptr002.bas)は
以下のリンクからダウンロードできます

https://ulprojectmail.blogspot.com
Readme.txtを読んで遊んで下さい














 

このブログの人気の投稿

NEWS

N88-BASICでゲーム (1回目)