MC-10でアセンブラやってみる その1

TRS-80 MC-10 & MCX32-SDでMC6801アセンブラの勉強をはじめる。

https://github.com/gregdionne/tasm6801/tree/master/tutorial

まずは学研TVボーイのゲームを逆アセンブルしました。

http://yama.ath.cx/maserati/romrom/04/04.htm

>dasmx -a -c6801 -e0xF000 -o0xF000 frogger.bin

DASMx object code disassembler
==============================
(c) Copyright 1996-2003   Conquest Consultants
Version 1.40 (Oct 18 2003)

CPU: Motorola 6801 (6801/6803 family)
Source file length: 4096 bytes
Pass 1...
Pass 2...

実行アドレスを変更して動作確認していきます。

>tasm.exe frogger10.txt
>type frogger10.txt

    org $8000

    clra
    staa    $0001
    staa    $0017
    coma
    staa    $0005
    ldaa    #$7F
    staa    $0000
    ldaa    #$0F
    staa    $0002
    lds #$00FF
    sei
    clra
    jsr LF9E5
LF018:

f:id:tanam:20211206001738p:plain

f:id:tanam:20211206001802p:plain

f:id:tanam:20211206001838p:plain

学研TV BOYエミュレータをつくる その6

TV BOYエミュレータを更新しました。とりあえず遊ぶためにパッチを当てます。

  • 市街戦200X年(ふつうに遊べる!)
  • ミスターボム(ふつうに遊べる!)
  • エキサイトインベーダー(ふつうに遊べる!)NEW
  • ロボタンウォーズ(ふつうに遊べる!)NEW
  • 地対空大作戦(サウンドが鳴らない)
  • フロッガーサウンドが鳴らない)NEW

ソースコード差分は以下になります。

takeda-toshiya.my.coocan.jp

void MEMORY::open_cart(const _TCHAR* file_path)
{
    FILEIO* fio = new FILEIO();
    if(fio->Fopen(file_path, FILEIO_READ_BINARY)) {
        fio->Fread(rom, sizeof(rom), 1);
        fio->Fclose();
        // EXCITE INVADER
        if (rom[0x0f3c]==0x96 && rom[0x0f3d]==0x02) {
            rom[0x0f3c]=0x86;
            rom[0x0f3d]=0x81;
        }
        // ROBOTAN WARS
        if (rom[0x06f0]==0x96 && rom[0x06f1]==0x19) {
            rom[0x06f0]=0x86;
            rom[0x06f1]=0x10;
        }
        inserted = true;
    }
    delete fio;
}
#ifdef _TVBOY
    // FROGGER
    if( total_icount % 2400 == 1 && d_mem->read_data8(0xfff4)==0xfa && d_mem->read_data8(0xfff5)==0xd7) {
        wai_state &= ~HD6301_SLP;
        if(!(CC & 0x10)) {
            TAKE_OCI;
        }
    }
#endif
    // check interrupt
    if(int_state & NMI_REQ_BIT) {
:

ヨコハマ忘年会2021

ファミコン以外のマイナーゲーム機、インテレビジョン、アルカディア、アタリ2800、光速船、TVボーイ、バーチャルボーイワンダースワンぴゅう太 etcなどで遊ぶイベントです。

ハッシュタグ(2021/12/18)

学研TV BOYエミュレータをつくる その5

TV BOYエミュレータを更新しました。求む!エミュレータ開発者。

ソフトは6種類(各3,800円)が発売されたそうです。

  • 市街戦200X年(ふつうに遊べる!)
  • ミスターボム(ふつうに遊べる!)
  • エキサイトインベーダー(ゲーム開始直後フリーズ)
  • ロボタンウォーズ(ゲーム開始後キー入力できない)
  • 地対空大作戦(サウンドが鳴らない)
  • フロッガー(タイトルでフリーズ)

ソースコード差分は以下になります。

takeda-toshiya.my.coocan.jp

/*
    GAKKEN TV BOY Emulator 'yaTVBOY'

    Author : tanam
    Date   : 2020.06.13

    [ memory ]
*/

#include "memory.h"

#define SET_BANK(s, e, w, r) { \
    int sb = (s) >> 10, eb = (e) >> 10; \
    for(int i = sb; i <= eb; i++) { \
        if((w) == wdmy) { \
            wbank[i] = wdmy; \
        } else { \
            wbank[i] = (w) + 0x400 * (i - sb); \
        } \
        if((r) == rdmy) { \
            rbank[i] = rdmy; \
        } else { \
            rbank[i] = (r) + 0x400 * (i - sb); \
        } \
    } \
}

void MEMORY::initialize()
{
    memset(rom, 0xff, sizeof(rom));
    memset(rdmy, 0xff, sizeof(rdmy));   
    // set memory map
    SET_BANK(0x0000, 0x0fff, ram,  ram );
    SET_BANK(0x1000, 0x1fff, vram, vram);
    SET_BANK(0x2000, 0xefff, wdmy, rdmy);
    SET_BANK(0xf000, 0xffff, wdmy, rom );
    // register event
//  register_event_by_clock(this, 0, 256, true, NULL);
    register_event_by_clock(this, 0, 4096, true, NULL);
    event = false;
    inserted = false;
}

void MEMORY::reset()
{
    memset(ram, 0, sizeof(ram));
    for (int i=0; i<sizeof(vram); i++) {
        vram[i]=rand() % 256;
    }
    d_vdp->write_signal(SIG_MC6847_AS,     0x00, 0x08);
    d_vdp->write_signal(SIG_MC6847_AG,     0x10, 0x10);
    d_vdp->write_signal(SIG_MC6847_CSS,    0x20, 0x20);
    d_vdp->write_signal(SIG_MC6847_GM,     0x00, 0x02);
    d_vdp->write_signal(SIG_MC6847_GM,     0x01, 0x01);
    d_vdp->write_signal(SIG_MC6847_INTEXT, 0x00, 0x04);
    shot1 = shot2 = up = down = left = right = 0;
}

void MEMORY::write_data8(uint32_t addr, uint32_t data)
{
    addr &= 0xffff;
    if(addr >= 0x80 && addr < 0x100) {
        d_cpu->ram[addr-0x80]=data;
    }
    if(addr == 0x2000) {
        d_vdp->write_signal(SIG_MC6847_AS,     data, 0x08);
        d_vdp->write_signal(SIG_MC6847_AG,     data, 0x10);
        d_vdp->write_signal(SIG_MC6847_CSS,    data, 0x20);
        d_vdp->write_signal(SIG_MC6847_GM,     data << 1, 0x02);
        d_vdp->write_signal(SIG_MC6847_GM,     data >> 1, 0x01);
        d_vdp->write_signal(SIG_MC6847_INTEXT, data, 0x04);
        return;
    }
    wbank[addr >> 10][addr & 0x3ff] = data;
}

uint32_t MEMORY::read_data8(uint32_t addr)
{
    addr &= 0xffff;
    if(addr >= 0x80 && addr < 0x100) {
        return d_cpu->ram[addr-0x80];
    }
    return rbank[addr >> 10][addr & 0x3ff];
}

void MEMORY::write_signal(int id, uint32_t data, uint32_t mask)
{
    d_cpu->write_signal(SIG_MC6801_PORT_2, 0x1E, 0x1E);
    if (shot2==1 && (d_cpu->port[0].wreg & 0x01)==1) {
        d_cpu->write_signal(SIG_MC6801_PORT_2, 0x00, 0x04);
    }
    if (shot1==1 && (d_cpu->port[0].wreg & 0x01)==1) {
        d_cpu->write_signal(SIG_MC6801_PORT_2, 0x00, 0x02);
    }

//  if (event) return; // speed down
    
    if (down==1 && (d_cpu->port[0].wreg & 0x01)==0) {
         d_cpu->write_signal(SIG_MC6801_PORT_2, 0x00, 0x04);
        // frogger
        if (rom[0x0ff4]==0xfa && rom[0x0ff5]==0xd7) down =0;
    }
    if (up==1 && (d_cpu->port[0].wreg & 0x01)==0) {
        d_cpu->write_signal(SIG_MC6801_PORT_2, 0x00, 0x02);
        // frogger
        if (rom[0x0ff4]==0xfa && rom[0x0ff5]==0xd7) up =0;
    }
    if (left==1 && (d_cpu->port[0].wreg & 0x01)==0) {
        d_cpu->write_signal(SIG_MC6801_PORT_2, 0x00, 0x08);
        // frogger
        if (rom[0x0ff4]==0xfa && rom[0x0ff5]==0xd7) left =0;
    }
    if (right==1 && (d_cpu->port[0].wreg & 0x01)==0) {
        d_cpu->write_signal(SIG_MC6801_PORT_2, 0x00, 0x10);
        // frogger
        if (rom[0x0ff4]==0xfa && rom[0x0ff5]==0xd7) right =0;
    }
}

void MEMORY::event_callback(int event_id, int err)
{
    if (event)  {
        d_cpu->write_signal(SIG_CPU_IRQ, 1, 1);
        event = false;
    } else {
        d_cpu->write_signal(SIG_CPU_IRQ, 0, 1);
        event = true;
    }
}

void MEMORY::key_down(int code)
{
    if (code==0x20) {
        shot1 =1;
    }
    if (code==0x11) {
        shot2 =1;
    }
    if (code==0x25) {
        left =1;
    }
    if (code==0x26) {
        up =1;
    }
    if (code==0x27) {
        right =1;
    }
    if (code==0x28) {
        down =1;
    }
}

void MEMORY::key_up(int code)
{
    if (code==0x20) {
        shot1 =0;
    }
    if (code==0x11) {
        shot2 =0;
    }
    if (code==0x25) {
        left =0;
    }
    if (code==0x26) {
        up =0;
    }
    if (code==0x27) {
        right =0;
    }
    if (code==0x28) {
        down =0;
    }
}

void MEMORY::open_cart(const _TCHAR* file_path)
{
    FILEIO* fio = new FILEIO();
    if(fio->Fopen(file_path, FILEIO_READ_BINARY)) {
        fio->Fread(rom, sizeof(rom), 1);
        fio->Fclose();
        inserted = true;
    }
    delete fio;
}

void MEMORY::close_cart()
{
    memset(rom, 0xff, sizeof(rom));
    inserted = false;
}

#define STATE_VERSION   1

bool MEMORY::process_state(FILEIO* state_fio, bool loading)
{
    if(!state_fio->StateCheckUint32(STATE_VERSION)) {
        return false;
    }
    if(!state_fio->StateCheckInt32(this_device_id)) {
        return false;
    }
    state_fio->StateArray(ram, sizeof(ram), 1);
    state_fio->StateArray(vram, sizeof(vram), 1);
    return true;
}

MC6847で遊ぼう会(シモキタ)

MC6847搭載機で遊ぶイベントです。

  • NEC PC-6001
  • SANYO PHC-25
  • GAKKEN TV BOY
  • TANDY TRS-80 COCO
  • TANDY TRS-80 MC-10

ハッシュタグ(2021/6/26)

FP技能士3級に挑戦してみた!

老後の資金計画のために、FP技能士2級資格をとろうと思いまずは問題集を買いました。しかしよくよく調べると、最初からFP技能士2級を受験する事はできないそうです。

仕方がないのでYouTubeと過去問で勉強して3級から受験しようと思います。

www.youtube.com

過去問を繰り返しといて、毎回60点とれるようになれば合格すると思います。

fp3-siken.com

YouTubeの授業と対策サイトの過去問で合格しました!来年は簿記に挑戦したいと思います。

www.youtube.com

www.youtube.com

www.youtube.com

www.youtube.com

www.youtube.com

www.youtube.com