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

コロナの影響で2020年度上期試験はなくなりました。筆記試験の勉強について自分なりにまとめてみました。

https://www.shiken.or.jp/examination/e-construction02.html

 

まずは前提知識がまったくないので、資格取得した友人のおすすめの参考書を購入しました。1900円(税別)かかりました。

www.amazon.co.jp

 

第二種電気工事士は筆記試験と技能試験があるのですが、まずはホーザンの技能試験対策の動画を見て候補問題をひととおりやってみました。

電工試験の虎_ホーザン - YouTube

筆記試験が受かってから勉強するという人もいますが、あえて技能試験の勉強を先にやる事で、工具や材料や複線図についての知識がついて、筆記試験の内容が理解しやすくなります。

 

つぎに参考書は置いておいて、ホーザンの筆記試験対策の動画を何回も何回も見て知識を蓄積しました。最初はまったく分かりませんが、繰り返し見る事でだんだん分かるようになります。

 

そして直前の2週間前くらいから参考書を読んで、巻末の過去問を解き始めました。あまり早くに解くと忘れてしまうかもと思い、あえて試験直前にやってみました。

 

2020年度 第二種電気工事士(下期)筆記試験 解答速報で確認したところ44/50でした!(30が合格ライン)

ARCADE1UP SF2JAMMAその2

Street Fighter Control Deckの電源スイッチを利用したくなりました。電源のGNDをPIN35につないで、JAMMAのGND(1)をPIN36につなげばOKでした。

結線図

SF2

JAMMA

       SF2        JAMMA    GP25B13A-R1B
                  5V(3)       5V
                  -5V(5)      -5V
                  12V(6)      12V
PIN 1  P2 Up      P2 Up(V)
PIN 2  P2 Down    P2 Down(W)
PIN 3  P2 Left    P2 Left(X)
PIN 4 P2 Right   P2 Right(Y)
PIN 5 P2 A       P2 Button 1(Z)
PIN 6 P2 D       P2 Button 4(c)
PIN 7 P2 B       P2 Button 2(a)
PIN 8  P2 E       P2 Button 5(d)
PIN 9  P2 C       P2 Button 3(b)
PIN10  P2 F       P2 Button 6(e)
PIN11  P2 Start   P2 Start(U)
PIN12  P1 Start   P1 Start(17)
PIN13  NC         NC                          
PIN14  GND        GND(f)
PIN15  NC         NC
PIN16  NC         NC
PIN17  NC         NC
PIN18  NC         NC
PIN19 P1 Up      P1 Up(18)
PIN20 P1 Down    P1 Down(19)
PIN21 P1 Left    P1 Left(20)
PIN22 P1 Right   P1 Right(21)
PIN23 P1 A       P1 Button 1(22)
PIN24  P1 D       P1 Button 4(25)
PIN25  P1 B       P1 Button 2(23)
PIN26  P1 E       P1 Button 5(26)
PIN27  P1 C       P1 Button 3(24)
PIN28  P1 F       P1 Button 6(27)
PIN29  GND        NC
PIN30  GND        NC
PIN31  GND        NC
PIN32  GND        NC
PIN33  NC         NC
PIN34  NC         NC
PIN35  Power      NC      GND
PIN36  Power      GND(1)  NC
PIN37  VOL_A      NC
PIN38  VOL_B      Coin A(16)
PIN39  Speaker    Sperker(10)
PIN40  Speaker    Sperker(L)

ARCADE1UP SF2JAMMA

ARCADE1UPでJAMMA基板を遊びたい。

https://arcade1up.com/collections/parts/products/street-fighter-control-deck

ACアダプタ

https://www.mouser.jp/datasheet/2/260/GP25B-SPEC-1291644.pdf

  • GP25B13A-R1B $28.96

ヤフオク

  • 56ピンJAMMAコネクタ

秋月電子通商

  • 2×20(40P)両端コネクタ付IDCリボンケーブル(フラットケーブル) 200円
  • 基板取付用DINソケット(メス) 5P 60円
  • 耐熱電子ワイヤー 2m×7色 外径1.55mm(UL3265 AWG20) 650円

aitendo

  • IDCソケット(40P) [FM01] 40円

結線図

SF2

JAMMA

       SF2        JAMMA    GP25B13A-R1B
                  GND(1)      GND
                  5V(3)       5V
                  -5V(5)      -5V
                  12V(6)      12V
PIN 1  P2 Up      P2 Up(V)
PIN 2  P2 Down    P2 Down(W)
PIN 3  P2 Left    P2 Left(X)
PIN 4 P2 Right   P2 Right(Y)
PIN 5 P2 A       P2 Button 1(Z)
PIN 6 P2 D       P2 Button 4(c)
PIN 7 P2 B       P2 Button 2(a)
PIN 8  P2 E       P2 Button 5(d)
PIN 9  P2 C       P2 Button 3(b)
PIN10  P2 F       P2 Button 6(e)
PIN11  P2 Start   P2 Start(U)
PIN12  P1 Start   P1 Start(17)
PIN13  NC         NC                          
PIN14  GND        GND(f)
PIN15  NC         NC
PIN16  NC         NC
PIN17  NC         NC
PIN18  NC         NC
PIN19 P1 Up      P1 Up(18)
PIN20 P1 Down    P1 Down(19)
PIN21 P1 Left    P1 Left(20)
PIN22 P1 Right   P1 Right(21)
PIN23 P1 A       P1 Button 1(22)
PIN24  P1 D       P1 Button 4(25)
PIN25  P1 B       P1 Button 2(23)
PIN26  P1 E       P1 Button 5(26)
PIN27  P1 C       P1 Button 3(24)
PIN28  P1 F       P1 Button 6(27)
PIN29  GND        NC
PIN30  GND        NC
PIN31  GND        NC
PIN32  GND        NC
PIN33  NC         NC
PIN34  NC         NC
PIN35  Power      NC
PIN36  Power      NC
PIN37  VOL_A      NC
PIN38  VOL_B      Coin A(16)
PIN39  Speaker    Sperker(10)
PIN40  Speaker    Sperker(L)

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

SBC6303ルーズキットを利用してROM(F000-FFFF)をダンプしてみました。カートリッジの3(EXTAL)に直接クリスタルオシレーターをつないで、P20/P21/P22をGNDにつないで、残りの端子はSBC6303にそのまま結線。そのままだとアドレス(F800-FFFF)が被るため、LILBUGの27C256のCEをGNDにつないで異なるアドレス(9800-9FFF)で実行しました。

f:id:tanam:20200718002137p:plain

f:id:tanam:20200718002149p:plain

f:id:tanam:20200718002159p:plain

f:id:tanam:20200718002208p:plain

f:id:tanam:20200718002219p:plain

f:id:tanam:20200718002231p:plain


これからエミュレータで対応していきます。

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

Cコンパイラ開発顛末記 小窓次郎 | 組み込み業界独り言からCコンパイラ(C3PO)をダウンロードして、TVボーイでMC6847を表示するプログラムを開発して行きます。

f:id:tanam:20200606161047p:plain

VRAM($1000-$17FF)、ROM($F000-$FFFF)の想定で書いていきます。

hello.c
int memset(p, x, y)
char	*p;
char	x;
int	y;
{
	int i;
	for (i=0; i<y; i++,p++) {
		*p=x;
	}
	return 0;
}

int main()
{
	char *p;
	char *q;
	p="HELLO WORLD";
	q=0x2000;
	*q=0x20;
	memset(0x1000, ' ', 0x800);
	for (q=0x1000; *p != 0; q++, p++) {
		*q = *p;
	}
	return 0;
}

MS-DOSで開発します。

>msdos C3PO.EXE HELLO
>notepad hello.src

hello.srcを編集してhello.txtで保存します。DOS用8ビットCPUクロスアセンブラでSレコード形式を作成します。

>msdos X6801.EXE hello

6801 Cross Assembler Version 3.12
   Copyright(C) Arcpit Co.,LTD.1990. All rights reserved.

Object Filename [HELLO.S] :
Source Listting [NUL.LST] :
Cross Reference [NUL.CRF] :
Symbol Table [NUL.MAP] :
^L                                     2020- 6- 7 6801 Assembler  Page    1
                                                      File:HELLO.TXT

    1                   ;       INCLUDE 630X.LIB
    2                   ;
    3                   ;***** C3PO for 6301/3 version 3.06c MSDOS ***** Nishiy
    4                   ; *** Copyright (c) S.Nishiyama Mar 14 1992
    5                   ;***          1 int memset(p, x, y)
    6                   ;***          2 char    *p;
    7                   ;***          3 char    x;
    8                   ;***          4 int     y;
    9                   ;***          5 {
   10                   ;***          6         int i;
   11                   ;***          7         for (i=0; i<y; i++,p++) {
   12                   ;       CSEG
   13                   ;       GLOBAL  _memset
   14 F000                         ORG      $F000
   15 00FF              STACK      EQU      $FF
   16 F000 8E00FF       START      LDS      #STACK
   17 F003 2035                    BRA      _main
   18 F005              _memset:
   19 F005 3C                      PSHX
   20 F006 30                      TSX
   21 F007 37                      PSHB
   22 F008 36                      PSHA
   23 F009 34                      DES
   24 F00A 34                      DES
   25 F00B 4F                      CLRA
   26 F00C 5F                      CLRB
   27 F00D 30                      TSX
   28 F00E ED00                    STD      0,X
   29 F010              L3:
   30 F010 EC08                    LDD      8,X
   31 F012 A300                    SUBD     0,X
   32 F014 2F19                    BLE      L2
   33                   ;***          8                 *p=x;
   34 F016 4F                      CLRA
   35 F017 E605                    LDAB     5,X
   36 F019 EE02                    LDX      2,X
   37 F01B E700                    STAB     0,X
   38 F01D 30                      TSX
   39                   ;***          9         }
   40                   ;***         10         return 0;
   41 F01E              L4:
   42 F01E EC00                    LDD      0,X
   43 F020 C30001                  ADDD     #1
   44 F023 ED00                    STD      0,X
   45 F025 EC02                    LDD      2,X
   46 F027 C30001                  ADDD     #1
   47 F02A ED02                    STD      2,X
   48 F02C 7EF010                  JMP      L3
   49 F02F              L2:
   50 F02F 4F                      CLRA
   51 F030 5F                      CLRB
   52                   ;***         11 }
   53 F031 7EF034                  JMP      L1
   54 F034              L1:
   55 F034 31                      INS
   56 F035 31                      INS
   57 F036 31                      INS
   58 F037 31                      INS
^L                                     2020- 6- 7 6801 Assembler  Page    2
                                                      File:HELLO.TXT

   59 F038 38                      PULX
   60 F039 39                      RTS
   61                   ;** Local value mapping information
   62                   ;** i   EQU     0
   63                   ;** y   EQU     8
   64                   ;** x   EQU     5
   65                   ;** p   EQU     2
   66                   ;* Function 
   67                   ;* Executive step count 8
   68                   ;* Used stack size ===6 Byte===
^L                                     2020- 6- 7 6801 Assembler  Page    3
                                                      File:HELLO.TXT

   70                   ;***         12
   71                   ;***         13 int main()
   72                   ;***         14 {
   73                   ;***         15         char *p;
   74                   ;***         16         char *q;
   75                   ;***         17         p="HELLO WORLD";
   76                   ;       GLOBAL  _main
   77 F03A              _main:
   78 F03A 3C                      PSHX
   79 F03B 30                      TSX
   80 F03C 34                      DES
   81 F03D 34                      DES
   82 F03E 34                      DES
   83 F03F 34                      DES
   84 F040 3C                      PSHX
   85 F041 30                      TSX
   86 F042 CCF093                  LDD      #S0
   87 F045 ED04                    STD      4,X
   88                   ;***         18         q=0x2000;
   89 F047 CC2000                  LDD      #8192
   90 F04A ED02                    STD      2,X
   91                   ;***         19         *q=0x20;
   92 F04C EE02                    LDX      2,X
   93 F04E C620                    LDAB     #$20
   94 F050 E700                    STAB     0,X
   95 F052 30                      TSX
   96                   ;***         20         memset(0x1000, ' ', 0x800);
   97 F053 CC0800                  LDD      #2048
   98 F056 37                      PSHB
   99 F057 36                      PSHA
  100 F058 CE0020                  LDX      #32
  101 F05B 05                      ASLD
  102 F05C BDF005                  JSR      _memset
  103 F05F 31                      INS
  104 F060 31                      INS
  105 F061 30                      TSX
  106                   ;***         21         for (q=0x1000; *p != 0; q++, p+
  107 F062 CC1000                  LDD      #4096
  108 F065 ED02                    STD      2,X
  109 F067              L7:
  110 F067 EE04                    LDX      4,X
  111 F069 4F                      CLRA
  112 F06A E600                    LDAB     0,X
  113 F06C 30                      TSX
  114 F06D 271B                    BEQ      L6
  115                   ;***         22                 *q = *p;
  116 F06F EE04                    LDX      4,X
  117 F071 E600                    LDAB     0,X
  118 F073 30                      TSX
  119 F074 EE02                    LDX      2,X
  120 F076 E700                    STAB     0,X
  121 F078 30                      TSX
  122                   ;***         23         }
  123                   ;***         24         return 0;
  124 F079              L8:
  125 F079 EC02                    LDD      2,X
  126 F07B C30001                  ADDD     #1
  127 F07E ED02                    STD      2,X
^L                                     2020- 6- 7 6801 Assembler  Page    4
                                                      File:HELLO.TXT

  128 F080 EC04                    LDD      4,X
  129 F082 C30001                  ADDD     #1
  130 F085 ED04                    STD      4,X
  131 F087 7EF067                  JMP      L7
  132 F08A 20FE         L6:        BRA      L6
  133                   ;***         25 }
  134 F08C 7EF08F                  JMP      L5
  135 F08F              L5:
  136 F08F 38                      PULX
  137 F090 35                      TXS
  138 F091 38                      PULX
  139 F092 39                      RTS
  140                   ;** Local value mapping information
  141                   ;** q   EQU     2
  142                   ;** p   EQU     4
  143                   ;* Function 
144 ;* Executive step count 12 145 ;* Used stack size ===14 Byte=== ^L 2020- 6- 7 6801 Assembler Page 5 File:HELLO.TXT 147 ;*** 26 148 F093 S0: 149 F093 48454C4C4F20 FCB 72,69,76,76,79,32,87,79 574F 150 F09B 524C4400 FCB 82,76,68,0 151 ;* Direct page size 0 152 ;* Global segment size 0 153 ;* Character size 12 154 ;* Executive step count 20 155 ;* Error count 0 156 FFFE ORG $FFFE 157 FFFE F000 FDB START 158 0000 END ^L 2020- 6- 7 6801 Assembler Page 6 File:HELLO.TXT SYMBOL TABLE: L1 F034 L2 F02F L3 F010 L4 F01E L5 F08F L6 F08A L7 F067 L8 F079 S0 F093 STACK 00FF START F000 _main F03A _memset F005 ^L 2020- 6- 7 6801 Assembler Page 7 File:HELLO.TXT 0 Error(s) detected. LINES : 158 LABELS : 13 LAST PROGRAM ADDRESS : $FFFD LAST DATA ADDRESS : $0000

SRecord 1.64でhello.sをhello.binに変換します。

>srec_cat hello.S -offset -0xF000 -o hello.bin -binary

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

世にも珍しいVCSじゃない方のTV BOYエミュレータです。

www.youtube.com

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

vm.h

// GAKKEN TV BOY
#ifdef _TVBOY
#include "tvboy/tvboy.h"
#endif

tvboy.h

/*
	GAKKEN TV BOY Emulator 'yaTVBOY'

	Author : tanam
	Date   : 2020.06.13

	[ virtual machine ]
*/

#ifndef _TVBOY_H_
#define _TVBOY_H_

#define DEVICE_NAME		"GAKKEN TV BOY"
#define CONFIG_NAME		"tvboy"

// device informations for virtual machine
#define FRAMES_PER_SEC		60
#define LINES_PER_FRAME		262
#define CPU_CLOCKS		3579545 / 4
#define SCREEN_WIDTH		256
#define SCREEN_HEIGHT		192

#define HAS_MC6801
#define MC6847_VRAM_INV		0x40

// device informations for win32
#define USE_CART		1
#define USE_SOUND_VOLUME	2
#define USE_DEBUGGER
#define USE_STATE

#include "../../common.h"
#include "../../fileio.h"
#include "../vm_template.h"

#ifdef USE_SOUND_VOLUME
static const _TCHAR *sound_device_caption[] = {
	_T("PCM"),
};
#endif

class EMU;
class DEVICE;
class EVENT;

class MC6847;
class MC6800;
class PCM1BIT;

class MEMORY;

class VM : public VM_TEMPLATE
{
protected:
//	EMU* emu;
	
	// devices
	EVENT* event;
	
	MC6847* vdp;
	MC6800* cpu;
	PCM1BIT* pcm;

	MEMORY* memory;
	
public:
	// ----------------------------------------
	// initialize
	// ----------------------------------------
	
	VM(EMU* parent_emu);
	~VM();
	
	// ----------------------------------------
	// for emulation class
	// ----------------------------------------
	
	// drive virtual machine
	void reset();
	void run();
	double get_frame_rate()
	{
		return FRAMES_PER_SEC;
	}
	
#ifdef USE_DEBUGGER
	// debugger
	DEVICE *get_cpu(int index);
#endif
	
	// draw screen
	void draw_screen();
	
	// sound generation
	void initialize_sound(int rate, int samples);
	uint16_t* create_sound(int* extra_frames);
	int get_sound_buffer_ptr();
#ifdef USE_SOUND_VOLUME
	void set_sound_device_volume(int ch, int decibel_l, int decibel_r);
#endif
	
	// user interface
	void open_cart(int drv, const _TCHAR* file_path);
	void close_cart(int drv);
	bool is_cart_inserted(int drv);

	// notify key
	void key_down(int code, bool repeat);
	void key_up(int code);

	bool is_frame_skippable();
	
	void update_config();
	bool process_state(FILEIO* state_fio, bool loading);
	
	// ----------------------------------------
	// for each device
	// ----------------------------------------
	
	// devices
	DEVICE* get_device(int id);
//	DEVICE* dummy;
//	DEVICE* first_device;
//	DEVICE* last_device;
};

#endif

tvboy.cpp

/*
	GAKKEN TV BOY Emulator 'yaTVBOY'

	Author : tanam
	Date   : 2020.06.13

	[ virtual machine ]
*/

#include "tvboy.h"
#include "../../emu.h"
#include "../device.h"
#include "../event.h"

#include "../mc6847.h"
#include "../mc6800.h"
#include "../pcm1bit.h"

#ifdef USE_DEBUGGER
#include "../debugger.h"
#endif

#include "memory.h"

// ----------------------------------------------------------------------------
// initialize
// ----------------------------------------------------------------------------

VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu)
{
	// create devices
	first_device = last_device = NULL;
	dummy = new DEVICE(this, emu);	// must be 1st device
	event = new EVENT(this, emu);	// must be 2nd device
	
	vdp = new MC6847(this, emu);
	cpu = new MC6800(this, emu);
	
	memory = new MEMORY(this, emu);
	memory->set_context_cpu(cpu);
	memory->set_context_vdp(vdp);

	pcm = new PCM1BIT(this, emu);

	cpu->set_context_port1(pcm, SIG_PCM1BIT_SIGNAL, 0x20, 0);
	cpu->set_context_port1(pcm, SIG_PCM1BIT_SIGNAL, 0x40, 0);
	cpu->set_context_port1(memory, SIG_MEMORY_PORT_1, 0x0F, 0);

	// set contexts
	event->set_context_cpu(cpu);
	event->set_context_sound(pcm);
	
	vdp->set_vram_ptr(memory->get_vram(), 0x800);
	vdp->set_context_cpu(cpu);
		
	// cpu bus
	cpu->set_context_mem(memory);
#ifdef USE_DEBUGGER
	cpu->set_context_debugger(new DEBUGGER(this, emu));
#endif
	pcm = new PCM1BIT(this, emu);

	// initialize all devices
	for(DEVICE* device = first_device; device; device = device->next_device) {
		device->initialize();
	}
}

VM::~VM()
{
	// delete all devices
	for(DEVICE* device = first_device; device;) {
		DEVICE *next_device = device->next_device;
		device->release();
		delete device;
		device = next_device;
	}
}

DEVICE* VM::get_device(int id)
{
	for(DEVICE* device = first_device; device; device = device->next_device) {
		if(device->this_device_id == id) {
			return device;
		}
	}
	return NULL;
}

// ----------------------------------------------------------------------------
// drive virtual machine
// ----------------------------------------------------------------------------

void VM::reset()
{
	// reset all devices
	for(DEVICE* device = first_device; device; device = device->next_device) {
		device->reset();
	}
}

void VM::run()
{
	event->drive();
}

// ----------------------------------------------------------------------------
// debugger
// ----------------------------------------------------------------------------

#ifdef USE_DEBUGGER
DEVICE *VM::get_cpu(int index)
{
	if(index == 0) {
		return cpu;
	}
	return NULL;
}
#endif

// ----------------------------------------------------------------------------
// draw screen
// ----------------------------------------------------------------------------

void VM::draw_screen()
{
	vdp->draw_screen();
}

// ----------------------------------------------------------------------------
// notify key
// ----------------------------------------------------------------------------

void VM::key_down(int code, bool repeat)
{
	memory->key_down(code);
}

void VM::key_up(int code)
{
	memory->key_up(code);
}

// ----------------------------------------------------------------------------
// soud manager
// ----------------------------------------------------------------------------

void VM::initialize_sound(int rate, int samples)
{
	// init sound manager
	event->initialize_sound(rate, samples);
	pcm->initialize_sound(rate, 8000);
}

uint16_t* VM::create_sound(int* extra_frames)
{
	return event->create_sound(extra_frames);
}

int VM::get_sound_buffer_ptr()
{
	return event->get_sound_buffer_ptr();
}

#ifdef USE_SOUND_VOLUME
void VM::set_sound_device_volume(int ch, int decibel_l, int decibel_r)
{
	if(ch == 0) {
		pcm->set_volume(0, decibel_l, decibel_r);
	}
}
#endif

// ----------------------------------------------------------------------------
// user interface
// ----------------------------------------------------------------------------

void VM::open_cart(int drv, const _TCHAR* file_path)
{
	if(drv == 0) {
		memory->open_cart(file_path);
		reset();
	}
}

void VM::close_cart(int drv)
{
	if(drv == 0) {
		memory->close_cart();
		reset();
	}
}

bool VM::is_cart_inserted(int drv)
{
	if(drv == 0) {
		return memory->is_cart_inserted();
	} else {
		return false;
	}
}

bool VM::is_frame_skippable()
{
	return event->is_frame_skippable();
}

void VM::update_config()
{
	for(DEVICE* device = first_device; device; device = device->next_device) {
		device->update_config();
	}
}

#define STATE_VERSION	3

bool VM::process_state(FILEIO* state_fio, bool loading)
{
	if(!state_fio->StateCheckUint32(STATE_VERSION)) {
		return false;
	}
	for(DEVICE* device = first_device; device; device = device->next_device) {
		const char *name = typeid(*device).name() + 6; // skip "class "
		int len = strlen(name);
		
		if(!state_fio->StateCheckInt32(len)) {
			return false;
		}
		if(!state_fio->StateCheckBuffer(name, len, 1)) {
			return false;
		}
		if(!device->process_state(state_fio, loading)) {
			return false;
		}
	}
	return true;
}

memory.h

/*
	GAKKEN TV BOY Emulator 'yaTVBOY'

	Author : tanam
	Date   : 2020.06.13

	[ memory ]
*/

#ifndef _MEMORY_H_
#define _MEMORY_H_

#include "../vm.h"
#include "../../emu.h"
#include "../device.h"
#include "../mc6800.h"
#include "../mc6847.h"

#define SIG_MEMORY_PORT_1	0

class MEMORY : public DEVICE
{
private:
	MC6800 *d_cpu;
	MC6847 *d_vdp;

	uint8_t rom[0x1000];
	uint8_t ram[0x1000];
	uint8_t vram[0x1000];
	
	uint8_t wdmy[0x400];
	uint8_t rdmy[0x400];
	uint8_t* wbank[64];
	uint8_t* rbank[64];

	int shot1;
	int shot2;
	int up;
	int down;
	int left;
	int right;
	bool event;
	bool inserted;
	
public:
	MEMORY(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu)
	{
		set_device_name(_T("Memory Bus"));
	}
	~MEMORY() {}
	
	// common functions
	void initialize();
	void reset();
	void write_data8(uint32_t addr, uint32_t data);
	uint32_t read_data8(uint32_t addr);
	void write_signal(int id, uint32_t data, uint32_t mask);
	void event_callback(int event_id, int err);
	bool process_state(FILEIO* state_fio, bool loading);
	// unique functions
	void key_down(int code);
	void key_up(int code);
	void set_context_cpu(MC6800* device)
	{
		d_cpu = device;
	}
	void set_context_vdp(MC6847* device)
	{
		d_vdp = device;
	}
	void open_cart(const _TCHAR* file_path);
	void close_cart();
	bool is_cart_inserted()
	{
		return inserted;
	}
	uint8_t* get_vram()
	{
		return vram;
	}
};

#endif

memory.cpp

/*
	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);
	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==1) {
		d_cpu->write_signal(SIG_MC6801_PORT_2, 0x00, 0x04);
	}
	if (down==1 && d_cpu->port[0].wreg==2) {
		d_cpu->write_signal(SIG_MC6801_PORT_2, 0x00, 0x04);
	}
	if (shot1==1 && d_cpu->port[0].wreg==1) {
		d_cpu->write_signal(SIG_MC6801_PORT_2, 0x00, 0x02);
	}
	if (up==1 && d_cpu->port[0].wreg==2) {
		d_cpu->write_signal(SIG_MC6801_PORT_2, 0x00, 0x02);
	}
	if (left==1 && d_cpu->port[0].wreg==2) {
		d_cpu->write_signal(SIG_MC6801_PORT_2, 0x00, 0x08);
	}
	if (right==1 && d_cpu->port[0].wreg==2) {
		d_cpu->write_signal(SIG_MC6801_PORT_2, 0x00, 0x10);
	}
}

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;
}

mc6800.h

/*
	Skelton for retropc emulator

	Origin : MAME 0.142
	Author : Takeda.Toshiya
	Date   : 2011.04.23-

	[ MC6800 ]
*/

#ifndef _MC6800_H_ 
#define _MC6800_H_

#include "vm.h"
#include "../emu.h"
#include "device.h"

#if defined(HAS_MC6801) || defined(HAS_HD6301)
#define SIG_MC6801_PORT_1	0
#define SIG_MC6801_PORT_2	1
#define SIG_MC6801_PORT_3	2
#define SIG_MC6801_PORT_4	3
#define SIG_MC6801_PORT_3_SC1	4
#define SIG_MC6801_PORT_3_SC2	5
#define SIG_MC6801_SIO_RECV	6

class FIFO;
#endif

#ifdef USE_DEBUGGER
class DEBUGGER;
#endif

class MC6800 : public DEVICE
{
private:
	DEVICE *d_mem;
#ifdef USE_DEBUGGER
	DEBUGGER *d_debugger;
	DEVICE *d_mem_stored;
#endif
	
	pair32_t pc;
	uint16_t prevpc;
	pair32_t sp;
	pair32_t ix;
	pair32_t acc_d;
	pair32_t ea;
	
	uint8_t cc;
	int wai_state;
	int int_state;
	
#ifdef USE_DEBUGGER
	uint64_t total_icount;
	uint64_t prev_total_icount;
#endif
	int icount;
	bool one_more_insn;
	
	uint32_t RM(uint32_t Addr);
	void WM(uint32_t Addr, uint32_t Value);
	uint32_t RM16(uint32_t Addr);
	void WM16(uint32_t Addr, pair32_t *p);
	
#if defined(HAS_MC6801) || defined(HAS_HD6301)
	// data
//	struct {
//		uint8_t wreg;
//		uint8_t rreg;
//		uint8_t ddr;
//		uint8_t latched_data;
//		bool latched;
		// output signals
//		outputs_t outputs;
//		bool first_write;
//	} port[4];
	
	uint8_t p3csr;
	bool p3csr_is3_flag_read;
	bool sc1_state;
	bool sc2_state;
	
	// timer
	pair32_t counter;
	pair32_t output_compare;
	pair32_t timer_over;
	uint8_t tcsr;
	uint8_t pending_tcsr;
	uint16_t input_capture;
#ifdef HAS_HD6301
	uint16_t latch09;
#endif
	uint32_t timer_next;
	
	// serial i/o
	outputs_t outputs_sio;
	FIFO *recv_buffer;
	uint8_t trcsr, rdr, tdr;
	bool trcsr_read_tdre, trcsr_read_orfe, trcsr_read_rdrf;
	uint8_t rmcr;
	int sio_counter;
	
	// memory controller
	uint8_t ram_ctrl;
//	uint8_t ram[128];
	
	uint32_t mc6801_io_r(uint32_t offset);
	void mc6801_io_w(uint32_t offset, uint32_t data);
#endif
	void increment_counter(int amount);
	
	void run_one_opecode();
	void enter_interrupt(uint16_t irq_vector);
	void insn(uint8_t code);
	
	void aba();
	void abx();
	void adca_di();
	void adca_ex();
	void adca_im();
	void adca_ix();
	void adcb_di();
	void adcb_ex();
	void adcb_im();
	void adcb_ix();
	void adda_di();
	void adda_ex();
	void adda_im();
	void adda_ix();
	void addb_di();
	void addb_ex();
	void addb_im();
	void addb_ix();
	void addd_di();
	void addd_ex();
	void addd_im();
	void addd_ix();
	void adx_ex();
	void adx_im();
	void aim_di();
	void aim_ix();
	void nim_ix();
	void anda_di();
	void anda_ex();
	void anda_im();
	void anda_ix();
	void andb_di();
	void andb_ex();
	void andb_im();
	void andb_ix();
	void asl_ex();
	void asl_ix();
	void asla();
	void aslb();
	void asld();
	void asr_ex();
	void asr_ix();
	void asra();
	void asrb();
	void bcc();
	void bcs();
	void beq();
	void bge();
	void bgt();
	void bhi();
	void bita_di();
	void bita_ex();
	void bita_im();
	void bita_ix();
	void bitb_di();
	void bitb_ex();
	void bitb_im();
	void bitb_ix();
	void ble();
	void bls();
	void blt();
	void bmi();
	void bne();
	void bpl();
	void bra();
	void brn();
	void bsr();
	void bvc();
	void bvs();
	void cba();
	void clc();
	void cli();
	void clr_ex();
	void clr_ix();
	void clra();
	void clrb();
	void clv();
	void cmpa_di();
	void cmpa_ex();
	void cmpa_im();
	void cmpa_ix();
	void cmpb_di();
	void cmpb_ex();
	void cmpb_im();
	void cmpb_ix();
	void cmpx_di();
	void cmpx_ex();
	void cmpx_im();
	void cmpx_ix();
	void com_ex();
	void com_ix();
	void coma();
	void comb();
	void daa();
	void dec_ex();
	void dec_ix();
	void deca();
	void decb();
	void des();
	void dex();
	void eim_di();
	void eim_ix();
	void xim_ix();
	void eora_di();
	void eora_ex();
	void eora_im();
	void eora_ix();
	void eorb_di();
	void eorb_ex();
	void eorb_im();
	void eorb_ix();
	void illegal();
	void inc_ex();
	void inc_ix();
	void inca();
	void incb();
	void ins();
	void inx();
	void jmp_ex();
	void jmp_ix();
	void jsr_di();
	void jsr_ex();
	void jsr_ix();
	void lda_di();
	void lda_ex();
	void lda_im();
	void lda_ix();
	void ldb_di();
	void ldb_ex();
	void ldb_im();
	void ldb_ix();
	void ldd_di();
	void ldd_ex();
	void ldd_im();
	void ldd_ix();
	void lds_di();
	void lds_ex();
	void lds_im();
	void lds_ix();
	void ldx_di();
	void ldx_ex();
	void ldx_im();
	void ldx_ix();
	void lsr_ex();
	void lsr_ix();
	void lsra();
	void lsrb();
	void lsrd();
	void mul();
	void neg_ex();
	void neg_ix();
	void nega();
	void negb();
	void nop();
	void oim_di();
	void oim_ix();
	void oim_ix_mb8861();
	void ora_di();
	void ora_ex();
	void ora_im();
	void ora_ix();
	void orb_di();
	void orb_ex();
	void orb_im();
	void orb_ix();
	void psha();
	void pshb();
	void pshx();
	void pula();
	void pulb();
	void pulx();
	void rol_ex();
	void rol_ix();
	void rola();
	void rolb();
	void ror_ex();
	void ror_ix();
	void rora();
	void rorb();
	void rti();
	void rts();
	void sba();
	void sbca_di();
	void sbca_ex();
	void sbca_im();
	void sbca_ix();
	void sbcb_di();
	void sbcb_ex();
	void sbcb_im();
	void sbcb_ix();
	void sec();
	void sei();
	void sev();
	void slp();
	void sta_di();
	void sta_ex();
	void sta_im();
	void sta_ix();
	void stb_di();
	void stb_ex();
	void stb_im();
	void stb_ix();
	void std_di();
	void std_ex();
	void std_im();
	void std_ix();
	void sts_di();
	void sts_ex();
	void sts_im();
	void sts_ix();
	void stx_di();
	void stx_ex();
	void stx_im();
	void stx_ix();
	void suba_di();
	void suba_ex();
	void suba_im();
	void suba_ix();
	void subb_di();
	void subb_ex();
	void subb_im();
	void subb_ix();
	void subd_di();
	void subd_ex();
	void subd_im();
	void subd_ix();
	void swi();
	void tab();
	void tap();
	void tba();
	void tim_di();
	void tim_ix();
	void tmm_ix();
	void tpa();
	void tst_ex();
	void tst_ix();
	void tsta();
	void tstb();
	void tsx();
	void txs();
	void undoc1();
	void undoc2();
	void wai();
	void xgdx();
	void cpx_di();
	void cpx_ex();
	void cpx_im();
	void cpx_ix();
	
public:
	MC6800(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu)
	{
#ifdef USE_DEBUGGER
		total_icount = prev_total_icount = 0;
#endif
#if defined(HAS_MC6801) || defined(HAS_HD6301)
		for(int i = 0; i < 4; i++) {
			initialize_output_signals(&port[i].outputs);
			port[i].wreg = port[i].rreg = 0;//0xff;
		}
		initialize_output_signals(&outputs_sio);
#endif
#if defined(HAS_MC6801)
		set_device_name(_T("MC6801 MPU"));
#elif defined(HAS_HD6301)
		set_device_name(_T("HD6301 MPU"));
#else
		set_device_name(_T("MC6800 MPU"));
#endif
	}
	~MC6800() {}
	
	// common functions
	uint8_t ram[128];
	struct {
		uint8_t wreg;
		uint8_t rreg;
		uint8_t ddr;
		uint8_t latched_data;
		bool latched;
		outputs_t outputs;
		bool first_write;
	} port[4];

	void initialize();
#if defined(HAS_MC6801) || defined(HAS_HD6301)
	void release();
#endif
	void reset();
	int run(int clock);
	void write_signal(int id, uint32_t data, uint32_t mask);
	uint32_t get_pc()
	{
		return prevpc;
	}
	uint32_t get_next_pc()
	{
		return pc.w.l;
	}
#ifdef USE_DEBUGGER
	bool is_cpu()
	{
		return true;
	}
	bool is_debugger_available()
	{
		return true;
	}
	void *get_debugger()
	{
		return d_debugger;
	}
	uint32_t get_debug_prog_addr_mask()
	{
		return 0xffff;
	}
	uint32_t get_debug_data_addr_mask()
	{
		return 0xffff;
	}
	void write_debug_data8(uint32_t addr, uint32_t data);
	uint32_t read_debug_data8(uint32_t addr);
	// implement 16bit/32bit functions because this cpu is big endian
	void write_debug_data16(uint32_t addr, uint32_t data);
	uint32_t read_debug_data16(uint32_t addr);
	void write_debug_data32(uint32_t addr, uint32_t data);
	uint32_t read_debug_data32(uint32_t addr);
	bool write_debug_reg(const _TCHAR *reg, uint32_t data);
	bool get_debug_regs_info(_TCHAR *buffer, size_t buffer_len);
	int debug_dasm(uint32_t pc, _TCHAR *buffer, size_t buffer_len);
#endif
	bool process_state(FILEIO* state_fio, bool loading);
	
	// unique functions
	void set_context_mem(DEVICE* device)
	{
		d_mem = device;
	}
#ifdef USE_DEBUGGER
	void set_context_debugger(DEBUGGER* device)
	{
		d_debugger = device;
	}
#endif
#if defined(HAS_MC6801) || defined(HAS_HD6301)
	void set_context_port1(DEVICE* device, int id, uint32_t mask, int shift)
	{
		register_output_signal(&port[0].outputs, device, id, mask, shift);
	}
	void set_context_port2(DEVICE* device, int id, uint32_t mask, int shift)
	{
		register_output_signal(&port[1].outputs, device, id, mask, shift);
	}
	void set_context_port3(DEVICE* device, int id, uint32_t mask, int shift)
	{
		register_output_signal(&port[2].outputs, device, id, mask, shift);
	}
	void set_context_port4(DEVICE* device, int id, uint32_t mask, int shift)
	{
		register_output_signal(&port[2].outputs, device, id, mask, shift);
	}
	void set_context_sio(DEVICE* device, int id)
	{
		register_output_signal(&outputs_sio, device, id, 0xff);
	}
#endif
};

#endif

SBC6303用にMC6847アダプタをつくる

SBC6303にMC6847(1000-17FF/4000-57FF)をつないでビデオ出力したい。 https://vintagechips.wordpress.com/2018/04/26/sbc6303%E3%83%AB%E3%83%BC%E3%82%BA%E3%82%AD%E3%83%83%E3%83%88/

Address  A15 A14 A13 A12 A11| /CS /CE O14 O13 O12 O11 RAM
>0000    0   0   0   0   0  |  1  1   -   -   -   -
>0800    0   0   0   0   1  |  1  1   -   -   -   -
>1000    0   0   0   1   0  |  1  0   0   0   0   0  >00000
>1800    0   0   0   1   1  |  1  0   0   0   0   1  >00800
>2000    0   0   1   0   0  |  0  1   -   -   -   -
>2800    0   0   1   0   1  |  1  1   -   -   -   -
>3000    0   0   1   1   0  |  1  1   -   -   -   -
>3800    0   0   1   1   1  |  1  1   -   -   -   -
>4000    0   1   0   0   0  |  1  0   0   0   0   0  >00000
>4800    0   1   0   0   1  |  1  0   0   0   0   1  >00800
>5000    0   1   0   1   0  |  1  0   0   0   1   0  >01000
>5800    0   1   0   1   1  |  1  0   0   0   1   1  >01800
>6000    0   1   1   0   0  |  1  1   -   -   -   -
>6800    0   1   1   0   1  |  1  1   -   -   -   -
>7000    0   1   1   1   0  |  1  1   -   -   -   -
>7800    0   1   1   1   1  |  1  1   -   -   -   -
>8000    1   0   0   0   0  |  1  1   -   -   -   -
>8800    1   0   0   0   1  |  1  1   -   -   -   -
>9000    1   0   0   1   0  |  1  1   -   -   -   -
>9800    1   0   0   1   1  |  1  1   -   -   -   -
>A000    1   0   1   0   0  |  1  1   -   -   -   -
>A800    1   0   1   0   1  |  1  1   -   -   -   -
>B000    1   0   1   1   0  |  1  1   -   -   -   -
>B800    1   0   1   1   1  |  1  1   -   -   -   -
>C000    1   1   0   0   0  |  1  1   -   -   -   -
>C800    1   1   0   0   1  |  1  1   -   -   -   -
>D000    1   1   0   1   0  |  1  1   -   -   -   -
>D800    1   1   0   1   1  |  1  1   -   -   -   -
>E000    1   1   1   0   0  |  1  1   -   -   -   -
>E800    1   1   1   0   1  |  1  1   -   -   -   -
>F000    1   1   1   1   0  |  1  1   -   -   -   -
>F800    1   1   1   1   1  |  1  1   -   -   -   -
;
; TITLE SBC6303 VDG ADAPTER
; PATTERN A REVISION 1.1
; AUTHOR TANAM1972
; COMPANY PARALLEL COMPUTER INC
; DATE 6/13/20

CHIP TVBOY GAL22V10D

NC NC NC NC A8 A9 A10 A11 A12 A13 A14 GND
A15 NC NC NC I11 I12 I13 I14 CE CS NC VCC

EQUATIONS

I11 = A11

I12 = A14 * A12

I13 = GND

I14 = GND

CE = A15 + A13 + /A14 * /A12

CS = A15 + A14 + /A13 + A12 + A11

回路図

       SBC6303 24HC245        HM62256 MC6847 74LS174  GAL22V10D
PIN 1  /RD     DIR1
PIN 2  /WR                     /WE
PIN 3  D0      D0      IO0     IO0    IO0     D0
PIN 4 D1      D1      IO1     IO1    IO1     D1
PIN 5 D2      D2      IO2     IO2    IO2     D2
PIN 6 D3      D3      IO3     IO3    IO3     D3
PIN 7 D4      D4      IO4     IO4    IO4     D4
PIN 8  D5      D5      IO5     IO5    IO5     D5
PIN 9  D6      D6      IO6     IO6    IO6/INV
PIN10  D7      D7      IO7     IO7    IO7/AS
PIN11  A0      A0      O0      O0     O0
PIN12  A1      A1      O1      O1     O1
PIN13  A2      A2      O2      O2     O2                                
PIN14  A3      A3      O3      O3     O3
PIN15  A4      A4      O4      O4     O4
PIN16  A5      A5      O5      O5     O5
PIN17  A6      A6      O6      O6     O6
PIN18  A7      A7      O7      O7     O7
PIN19 A8      A8      O8      O8     O8
PIN20 A9      A9      O9      O9     O9
PIN21 A10     A10     O10     O10    O10
PIN22 A11     I11     O11     O11    O11            A11     I11
PIN23 A12     I12     O12     O12    O12            A12     I12
PIN24  A13     A13     O13     O13                   A13     I13
PIN25  A14     A14     O14     O14                   A14     I14
PIN26  A15                                           A15
PIN27  RW
PIN28  E
PIN29  /IRQ                          /HS
PIN30  /RES
PIN31  P10
PIN32  P11
PIN33  P12
PIN34  P13
PIN35  P14
PIN36  P15
PIN37  P16
PIN38  P17
PIN39  VCC    DIR23           VCC    VCC     VCC    VCC
PIN40  GND              GND/CE/OE    GND  GND/MR    GND
                                     GM2     Q0
                                     AG      Q1
                                     CSS     Q2
                                     GM1     Q3
                                     GM0     Q4
                                 INT/EXT     Q5
              G123                   /MS                    CE
                                             CP             CS
                                     CHB
                                     B
                                     A
                                     Y
                                    /FS
                                    /RP