上から下へスクロール
画面のチラつきはある
main.c
#include <conio.h>
#include <time.h>
#include <video/tms99x8.h>
#include "asm.h"
void scrollDown();
void put_line();
void wait(unsigned int ms);
// スクロール位置
unsigned int scrollY = 0;
char mapRow = 0;
// 背景マップデータ
unsigned char mapData[24][32];
void main()
{
vdp_set_mode(mode_1);
vdp_color(VDP_INK_WHITE, VDP_INK_BLACK, VDP_INK_DARK_BLUE);
clrscr();
for (int r = 0; r < 24; r++)
{
for (int c = 0; c < 32; c++)
{
mapData[r][c] = 'A' + r;
}
}
for (int c = 0; c < 32; c++)
{
int addr = 0x1800 + c;
vdp_vpoke(addr, mapData[23][c]);
}
for (int r = 1; r < (24 + 1); r++)
{
for (int c = 0; c < 32; c++)
{
int addr = 0x1800 + 32 * r + c;
vdp_vpoke(addr, mapData[r - 1][c]);
}
}
mapRow = 23;
while (1)
{
scrollDown();
wait(80);
}
}
// 毎フレーム呼び出すスクロール処理
void scrollDown()
{
scrollY--;
vdp_set_reg(23, scrollY & 0x07);
if ((scrollY & 0x07) == 0x07)
{
name_table_copy();
put_line();
}
}
// VRAMに1ライン分のタイルを書き込む
void put_line()
{
if (--mapRow < 0)
{
mapRow = 23;
}
// 上端
for (int x = 0; x < 32; x++)
{
vdp_vpoke(0x1800 + x, mapData[mapRow][x]);
}
}
void wait(unsigned int ms)
{
clock_t c1 = clock();
while (1000 * (clock() - c1) / CLOCKS_PER_SEC < ms)
{
}
}
asm.h
void name_table_copy();
asm.c
void name_table_copy(){
#asm
di
ld hl, 0x1AE0 + 31 ; コピー元開始アドレス
ld de, 0x1B00 + 31 ; コピー先開始アドレス
ld bC, 0x0300
loop:
; vram読み込み
ld a, l
out(0x99), a
ld a, h
out(0x99), a
nop ; 表示乱れ防止のため
in a, (0x98)
push af
; vram書き込み
ld a, e
out(0x99), a
ld a, d
or 0x40 ; 書き込みモード設定
out(0x99), a
pop af
out(0x98), a ; 書き込み
dec hl
dec de
dec bc
ld a, b
or c
jr nz, loop
ei
#endasm
}
.ビルドコマンド
zcc +msx -subtype=rom -create-app main.c asm.c -o main.rom