File:  [Isaki's NoNo m68k/m88k emulator] / nono / vm / dipsw.cpp
Revision 1.1.1.4 (vendor branch): download - view: text, annotated - select for diffs
Wed Apr 29 17:05:42 2026 UTC (2 months, 3 weeks ago) by root
Branches: MAIN, Isaki
CVS tags: v027, v026, v025, v024, v023, HEAD
nono 1.3.0

//
// nono
// Copyright (C) 2022 nono project
// Licensed under nono-license.txt
//

//
// DIPSW
//

#include "dipsw.h"
#include "config.h"
#include "mainapp.h"

//
// DIPSW 共通クラス
//

// コンストラクタ
DipswDevice::DipswDevice(int size_)
	: inherited(OBJ_DIPSW)
{
	dipsw.resize(size_);
}

// デストラクタ
DipswDevice::~DipswDevice()
{
}

// 値を設定。true/false の意味は機種依存。
void
DipswDevice::Set(uint n, bool val)
{
	assertmsg(n < dipsw.size(),
		"n=%u size=%zu: out of range", n, dipsw.size());

	dipsw[n] = val;
}

// 値を取得。true/false の意味は機種依存。
bool
DipswDevice::Get(uint n) const
{
	assertmsg(n < dipsw.size(),
		"n=%u size=%zu: out of range", n, dipsw.size());

	return dipsw[n];
}

// 位置を設定。pos は 0 が上、1 が下。
void
DipswDevice::SetPosition(uint n, uint pos)
{
	bool val;

	if (upside == true) {
		val = (pos == 0) ? true : false;
	} else {
		val = (pos == 0) ? false : true;
	}
	Set(n, val);
}

// 位置を取得。戻り値は 0 が上、1 が下。
int
DipswDevice::GetPosition(uint n) const
{
	bool val = Get(n);
	int pos;

	if (upside == true) {
		pos = (val ? 0 : 1);
	} else {
		pos = (val ? 1 : 0);
	}
	return pos;
}


//
// DIPSW (LUNA)
//

// LUNA の DIPSW は #1, #2 にそれぞれ8個、計16個ある。
// DIPSW #1, #2 が設定ファイルの luna-dipsw{1,2} に対応する。
// luna-dipsw{1,2} はいずれも "0"/"1" を8つ並べた文字列であり、
// 先頭が本体表記でいう 1番、末尾側が本体表記でいう 8番に対応する。
// 値は "0" が down、"1" が up を表す。
//
// DipswDevice 内ではこの設定を読み込んで dipsw[0..15] として保持している。
// dipsw[0] が本体表記 #1-1 番、dipsw[15] が本体表記 #2-8 番に対応する。
// 値は false が down("0")、true が up("1") に対応する。

// コンストラクタ
LunaDipswDevice::LunaDipswDevice()
	: inherited(16)
{
	// 上が true の方向。
	upside = true;

	// LUNA-I と LUNA-88K で使いやすいように初期値を変えておく。
	if (gMainApp.IsLUNA1()) {
		gConfig->SetDefault("luna-dipsw1", "11110111");
	} else {
		gConfig->SetDefault("luna-dipsw1", "11111111");
	}

	// DIPSW#2 はユーザ定義(?)なので(今の所?)どちらも共通。
	gConfig->SetDefault("luna-dipsw2", "11111111");
}

// デストラクタ
LunaDipswDevice::~LunaDipswDevice()
{
}

// 初期化
bool
LunaDipswDevice::Init()
{
	const ConfigItem& item1 = gConfig->Find("luna-dipsw1");
	const std::string& str1 = item1.AsString();
	if (str1.size() != 8) {
		item1.Err("must be 8 digits");
		return false;
	}

	const ConfigItem& item2 = gConfig->Find("luna-dipsw2");
	const std::string& str2 = item2.AsString();
	if (str2.size() != 8) {
		item2.Err("must be 8 digits");
		return false;
	}

	for (int i = 0; i < 8; i++) {
		dipsw[i]     = (str1[i] != '0');
		dipsw[i + 8] = (str2[i] != '0');
	}

	// LUNA-I/LUNA-88K とも DIP#1-1 を up(=true) で自動起動。
	bool val;
	const ConfigItem& item_autoboot = gConfig->Find("dipsw-autoboot");
	const std::string& autoboot = item_autoboot.AsString();
	if (autoboot.empty() == false) {
		if (autoboot == "yes") {
			val = true;
		} else if (autoboot == "no") {
			val = false;
		} else {
			item_autoboot.Err();
			return false;
		}
		dipsw[0] = val;
	}

	// LUNA-I/LUNA-88K とも DIP#1-2 を down(=false) でシリアルコンソール。
	const ConfigItem& item_serial = gConfig->Find("dipsw-serial");
	const std::string& serial = item_serial.AsString();
	if (serial.empty() == false) {
		if (serial == "yes") {
			val = false;
		} else if (serial == "no") {
			val = true;
		} else {
			item_serial.Err();
			return false;
		}
		dipsw[1] = val;
	}

	return true;
}


//
// DIPSW (NEWS)
//

// コンストラクタ
NewsDipswDevice::NewsDipswDevice()
	: inherited(8)
{
	// 上が false の方向。
	upside = false;
}

// デストラクタ
NewsDipswDevice::~NewsDipswDevice()
{
}

// 初期化
bool
NewsDipswDevice::Init()
{
	const ConfigItem& item = gConfig->Find("news-dipsw");
	const std::string& str = item.AsString();
	if (str.size() != 8) {
		item.Err("Must be 8 digits");
		return false;
	}
	for (int i = 0; i < 8; i++) {
		dipsw[i] = (str[i] != '0');
	}

	// DIP5 オン(true)で自動起動。
	const ConfigItem& item_autoboot = gConfig->Find("dipsw-autoboot");
	const std::string& autoboot = item_autoboot.AsString();
	if (autoboot.empty() == false) {
		bool val;
		if (autoboot == "yes") {
			val = true;
		} else if (autoboot == "no") {
			val = false;
		} else {
			item_autoboot.Err();
			return false;
		}
		dipsw[4] = val;
	}

	// DIP1,2,3 すべてオフでシリアルコンソール。
	// シリアルコンソールでない場合はビデオカード/モニタを選択しないと
	// いけないが、とりあえず NWB-512 モノクロビデオカード(?) にしとく。
	const ConfigItem& item_serial = gConfig->Find("dipsw-serial");
	const std::string& serial = item_serial.AsString();
	if (serial.empty() == false) {
		if (serial == "yes") {
			dipsw[0] = false;
			dipsw[1] = false;
			dipsw[2] = false;
		} else if (serial == "no") {
			dipsw[0] = false;
			dipsw[1] = false;
			dipsw[2] = true;
		} else {
			item_serial.Err();
			return false;
		}
	}

	return true;
}

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.