ヨコハマ忘年会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;
}

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

ちょっとだけDirectX11その2

表題の書籍のサンプルプログラムをSharpDXで書いてみる。

f:id:tanam:20210206092224p:plain

using System;
using SharpDX;
using SharpDX.D3DCompiler;
using SharpDX.Direct3D;
using SharpDX.Direct3D11;
using SharpDX.DXGI;
using SharpDX.Windows;
using Buffer = SharpDX.Direct3D11.Buffer;
using Device = SharpDX.Direct3D11.Device;

namespace Sankaku
{
    /// <summary>
    ///   SharpDX port of SharpDX-MiniTri Direct3D 11 Sample
    /// </summary>
    internal static class Program
    {
        [STAThread]
        private static void Main()
        {
            var form = new RenderForm("SharpDX - Direct3D 11 サンプル Sankaku01");

            // SwapChain description
            var desc = new SwapChainDescription()
            {
                BufferCount = 1,
                ModeDescription =
                                   new ModeDescription(640, 480,
                                                       new Rational(60, 1), Format.R8G8B8A8_UNorm),
                IsWindowed = true,
                OutputHandle = form.Handle,
                SampleDescription = new SampleDescription(1, 0),
                SwapEffect = SwapEffect.Discard,
                Usage = Usage.RenderTargetOutput
            };

            // Create Device and SwapChain
            Device device;
            SwapChain swapChain;
            Device.CreateWithSwapChain(DriverType.Hardware, DeviceCreationFlags.None, desc, out device, out swapChain);
            var context = device.ImmediateContext;

            // Ignore all windows events
//            var factory = swapChain.GetParent<Factory>();
//            factory.MakeWindowAssociation(form.Handle, WindowAssociationFlags.IgnoreAll);

            // New RenderTargetView from the backbuffer
            var backBuffer = Texture2D.FromSwapChain<Texture2D>(swapChain, 0);
            var renderView = new RenderTargetView(device, backBuffer);

            // Compile Vertex and Pixel shaders
            var vertexShaderByteCode = ShaderBytecode.CompileFromFile("MiniTri.fx", "VS", "vs_4_0", ShaderFlags.None, EffectFlags.None);
            var vertexShader = new VertexShader(device, vertexShaderByteCode);

            var pixelShaderByteCode = ShaderBytecode.CompileFromFile("MiniTri.fx", "PS", "ps_4_0", ShaderFlags.None, EffectFlags.None);
            var pixelShader = new PixelShader(device, pixelShaderByteCode);

            // Layout from VertexShader input signature
            var layout = new InputLayout(
                device,
                ShaderSignature.GetInputSignature(vertexShaderByteCode),
                new[]
                    {
                        new InputElement("POSITION", 0, Format.R32G32B32A32_Float, 0, 0),
                        new InputElement("COLOR", 0, Format.R32G32B32A32_Float, 16, 0)
                    });

            // Instantiate Vertex buiffer from vertex data
            //            var vertices = Buffer.Create(device, BindFlags.VertexBuffer, new[]
            //                                  {
            //                                      new Vector4(0.0f, 0.5f, 0.5f, 1.0f), new Vector4(1.0f, 0.0f, 0.0f, 1.0f),
            //                                      new Vector4(0.5f, -0.5f, 0.5f, 1.0f), new Vector4(0.0f, 1.0f, 0.0f, 1.0f),
            //                                      new Vector4(-0.5f, -0.5f, 0.5f, 1.0f), new Vector4(0.0f, 0.0f, 1.0f, 1.0f)
            //                                  });

            var vertices = Buffer.Create(device, BindFlags.VertexBuffer, new[]
                                  {
                                      new Vector4(0.0f, 1.5f, 0.5f, 2.0f), new Vector4(1.0f, 1.0f, 1.0f, 2.0f),
                                      new Vector4(1.0f, -1.0f, 0.5f, 2.0f), new Vector4(1.0f, 1.0f, 1.0f, 2.0f),
                                      new Vector4(-1.0f, -1.0f, 0.5f, 2.0f), new Vector4(1.0f, 1.0f, 1.0f, 2.0f)
                                  });
            
            // Prepare All the stages
            context.InputAssembler.InputLayout = layout;
            context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList;
            context.InputAssembler.SetVertexBuffers(0, new VertexBufferBinding(vertices, 32, 0));
            context.VertexShader.Set(vertexShader);
            context.Rasterizer.SetViewport(new Viewport(0, 0, 640, 480, 0.0f, 1.0f));
            context.PixelShader.Set(pixelShader);
            context.OutputMerger.SetTargets(renderView);

            // Main loop
            RenderLoop.Run(form, () =>
            {
                context.ClearRenderTargetView(renderView, new Color(0.0f, 0.5f, 0.7f, 1.0f));
                context.Draw(3, 0);
                swapChain.Present(0, PresentFlags.None);
            });

            // Release all resources
            vertexShaderByteCode.Dispose();
            vertexShader.Dispose();
            pixelShaderByteCode.Dispose();
            pixelShader.Dispose();
            vertices.Dispose();
            layout.Dispose();
            renderView.Dispose();
            backBuffer.Dispose();
            context.ClearState();
            context.Flush();
            device.Dispose();
            context.Dispose();
            swapChain.Dispose();
//            factory.Dispose();
        }
    }
}

第二種電気工事士の資格に挑戦してみる その5

ついに第二種電気工事士の資格取得しました!

さっそく免状交付のために、神奈川県電気工事工業組合本部事務局に行ってきました。

  • 受験用写真 800円
  • 免許用写真 800円
  • 住民票 300円
  • 神奈川県収入証紙 5300円