ぴゅう太でTMS9918を表示してみる

そういえばSGDKを使ってMEGA DRIVEで、TMS9918を表示するプログラムを開発してました。

http://d.hatena.ne.jp/tanam/20140827/1409150993

f:id:tanam:20160118000706p:image:w360

Z80をTMS9995で書き直してみました。対比させながら書いてみたらZ80よりすっきり書けました!

***************************************************************
* This is a "Hello World" program for TMS9995 and TMS9918 VDP.
*
* Z80 version of Hello World was written by Timo "NYYRIKKI" Soilamaa
* 17.10.2001
*
* TMS9995 version of Hello World was written by TANAM
* 17.01.2016
*
***************************************************************

DATAP   EQU >e000 * PYUTA VDP Data port
CMDP    EQU >e002 * PYUTA VDP Command port

        AORG >8000

***************************************************************
* cartridge header
***************************************************************

        data >5555
        b    @START

CHARS
* H     8006
        byte >88,>88,>88,>F8,>88,>88,>88,>00
* e
        byte >00,>00,>70,>88,>F8,>80,>70,>00
* l
        byte >60,>20,>20,>20,>20,>20,>70,>00
* o
        byte >00,>00,>70,>88,>88,>88,>70,>00
* W
        byte >88,>88,>88,>A8,>A8,>D8,>88,>00
* r
        byte >00,>00,>B0,>C8,>80,>80,>80,>00
* d
        byte >08,>08,>68,>98,>88,>98,>68,>00
CHARS_END

ORDER
        byte >1,>2,>3,>3,>4,>0,>5,>4,>6,>3,>7,>0
ORDER_END

***************************************************************
* Program starts here:
***************************************************************
START
        limi 0      * We don't know, how interrupts works in this system, so we disable them.
        lwpi >f030  * Set workspace to my area

* Let's set VDP write address to #0000
* LD C,CMDP
* XOR A
* OUT (C),A
        li   R0,>0040
        movb R0,@CMDP

* LD A,40H
* OUT (C),A
        swpb R0
        movb R0,@CMDP

* Now let's clear first 16Kb of VDP memory
* LD HL,3FFFH
        li   R1,>3fff

* LD C,DATAP
* LD A,0
* OUT (C),A
        swpb R0
CLEAR   movb R0,@DATAP

* DEC HL
* LD A,H
* OR L
        NOP * Let's wait 8 clock cycles just in case VDP is not quick enough.
        NOP
        dec  R1

* JR NZ,CLEAR
        joc  CLEAR

* Now it is time to set up VDP registers:
*----------------------------------------
* Register 0 to #0
*
* Set mode selection bit M3 (maybe also M4 & M5) to zero and 
* disable external video & horizontal interrupt

* LD C,CMDP
* OUT (C),A
        li   R0,>0080
        movb R0,@CMDP

* LD A,80H
* OUT (C),A
        swpb R0
        movb R0,@CMDP

*---------------------------------------- 
* Register 1 to #50
*
* Select 40 column mode, enable screen and disable vertical interrupt

* LD A,50H
* OUT (C),A
        li   R0,>5081
        movb R0,@CMDP

* LD A,81H
* OUT (C),A
        swpb R0
        movb R0,@CMDP

*---------------------------------------- 
* Register 2 to #0
*
* Set pattern name table to #0000

* XOR A
* OUT (C),A
        li   R0,>0082
        movb R0,@CMDP

* LD A,82H
* OUT (C),A
        swpb R0
        movb R0,@CMDP

*---------------------------------------- 
* Register 3 is ignored as 40 column mode does not need color table
*
*---------------------------------------- 
* Register 4 to #1
* Set pattern generator table to #800

* LD A,1H
* OUT (C),A
        li   R0,>0184
        movb R0,@CMDP

* LD A,84H
* OUT (C),A
        swpb R0
        movb R0,@CMDP

*---------------------------------------- 
* Registers 5 (Sprite attribute) & 6 (Sprite pattern) are ignored 
* as 40 column mode does not have sprites
*---------------------------------------- 
* Register 7 to #F0
* Set colors to white on black

* LD A,F0H
* OUT (C),A
        li   R0,>f087
        movb R0,@CMDP

* LD A,87H
* OUT (C),A
        swpb R0
        movb R0,@CMDP

*----------------------------------------
* Let's set VDP write address to #808 so, that we can write
* character set to memory
* (No need to write SPACE it is clear char already)

* LD A,8
* OUT (C),A
        li   R0,>0848
        movb R0,@CMDP

* LD A,48H
* OUT (C),A
        swpb R0
        movb R0,@CMDP

* Let's copy character set

* LD HL,CHARS
* LD B, CHARS_END-CHARS
        li   R0,CHARS
        li   R1,CHARS_END-CHARS

* LD A,(HL)
* LD C,DATAP
* OUT (C),A
COPYCHA movb *R0,@DATAP

* INC HL
        inc  R0
        NOP * Let's wait 8 clock cycles just in case VDP is not quick enough.
        NOP
* DJNZ COPYCHARS
        dec  R1
        joc  COPYCHA

* Let's set write address to start of name table

* LD C,CMDP
* XOR A
* OUT (C),A
        li   R0,>0040
        movb R0,@CMDP

* LD A,40H
* OUT (C),A
        swpb R0
        movb R0,@CMDP

* Let's put characters to screen

* LD HL,ORDER
* LD B,ORDER_END-ORDER
        li   R0,ORDER
        li   R1,ORDER_END-ORDER

* LD A,(HL)
* LD C,DATAP
* OUT (C),A
COPYORD movb *R0,@DATAP

* INC HL
        inc  R0
        NOP * Let's wait 8 clock cycles just in case VDP is not quick enough.
        NOP

* DJNZ COPYORDER
        dec  R1
        joc  COPYORD * >80f2

HALT
        b    @HALT
        END