#pragma once #include "stdafx.h" #include "BaseControlDevice.h" #include "IBarcodeReader.h" #include "CPU.h" class DatachBarcodeReader : public BaseControlDevice, public IBarcodeReader { private: vector _data; int32_t _insertCycle = 0; uint64_t _newBarcode = 0; uint32_t _newBarcodeDigitCount = 0; protected: void StreamState(bool saving) override { BaseControlDevice::StreamState(saving); uint32_t dataSize = (uint32_t)_data.size(); Stream(dataSize); if(!saving) { _data.resize(dataSize); } ArrayInfo data{ _data.data(), dataSize }; Stream(_insertCycle, _newBarcode, _newBarcodeDigitCount, data); } bool IsRawString() override { return true; } public: DatachBarcodeReader() : BaseControlDevice(BaseControlDevice::MapperInputPort) { } void InternalSetStateFromInput() override { if(_newBarcodeDigitCount > 0) { string barcodeText = std::to_string(_newBarcode); //Pad 8 or 13 character barcode with 0s at start barcodeText.insert(0, _newBarcodeDigitCount - barcodeText.size(), '0'); SetTextState(barcodeText); _newBarcode = 0; _newBarcodeDigitCount = 0; } } void OnAfterSetState() override { if(GetRawState().State.size() > 0) { InitBarcodeData(); } } uint8_t GetOutput() { int32_t elapsedCycles = CPU::GetCycleCount() - _insertCycle; int32_t bitNumber = elapsedCycles / 1000; if(bitNumber < (int32_t)_data.size()) { return _data[bitNumber]; } else { return 0; } } void InputBarcode(uint64_t barcode, uint32_t digitCount) override { _newBarcode = barcode; _newBarcodeDigitCount = digitCount; } void InitBarcodeData() { _insertCycle = CPU::GetCycleCount(); static const uint8_t prefixParityType[10][6] = { { 8,8,8,8,8,8 },{ 8,8,0,8,0,0 }, { 8,8,0,0,8,0 },{ 8,8,0,0,0,8 }, { 8,0,8,8,0,0 },{ 8,0,0,8,8,0 }, { 8,0,0,0,8,8 },{ 8,0,8,0,8,0 }, { 8,0,8,0,0,8 },{ 8,0,0,8,0,8 } }; static const uint8_t dataLeftOdd[10][7] = { { 8,8,8,0,0,8,0 },{ 8,8,0,0,8,8,0 }, { 8,8,0,8,8,0,0 },{ 8,0,0,0,0,8,0 }, { 8,0,8,8,8,0,0 },{ 8,0,0,8,8,8,0 }, { 8,0,8,0,0,0,0 },{ 8,0,0,0,8,0,0 }, { 8,0,0,8,0,0,0 },{ 8,8,8,0,8,0,0 } }; static const uint8_t dataLeftEven[10][7] = { { 8,0,8,8,0,0,0 },{ 8,0,0,8,8,0,0 }, { 8,8,0,0,8,0,0 },{ 8,0,8,8,8,8,0 }, { 8,8,0,0,0,8,0 },{ 8,0,0,0,8,8,0 }, { 8,8,8,8,0,8,0 },{ 8,8,0,8,8,8,0 }, { 8,8,8,0,8,8,0 },{ 8,8,0,8,0,0,0 } }; static const uint8_t dataRight[10][7] = { { 0,0,0,8,8,0,8 },{ 0,0,8,8,0,0,8 }, { 0,0,8,0,0,8,8 },{ 0,8,8,8,8,0,8 }, { 0,8,0,0,0,8,8 },{ 0,8,8,0,0,0,8 }, { 0,8,0,8,8,8,8 },{ 0,8,8,8,0,8,8 }, { 0,8,8,0,8,8,8 },{ 0,0,0,8,0,8,8 } }; string barcode = GetTextState(); vector code; for(uint8_t i = 0; i < barcode.size(); i++) { code.push_back(barcode[i] - '0'); } _data.clear(); for(uint32_t i = 0; i < 33; i++) { _data.push_back(8); } _data.push_back(0); _data.push_back(8); _data.push_back(0); uint32_t sum = 0; if(barcode.size() == 13) { for(uint32_t i = 0; i < 6; i++) { bool odd = prefixParityType[code[0]][i] != 0; for(uint32_t j = 0; j < 7; j++) { _data.push_back(odd ? dataLeftOdd[code[i + 1]][j] : dataLeftEven[code[i + 1]][j]); } } _data.push_back(8); _data.push_back(0); _data.push_back(8); _data.push_back(0); _data.push_back(8); for(uint32_t i = 7; i < 12; i++) { for(uint32_t j = 0; j < 7; j++) { _data.push_back(dataRight[code[i]][j]); } } for(uint32_t i = 0; i < 12; i++) { sum += (i & 1) ? (code[i] * 3) : (code[i] * 1); } } else { for(uint32_t i = 0; i < 4; i++) { for(uint32_t j = 0; j < 7; j++) { _data.push_back(dataLeftOdd[code[i]][j]); } } _data.push_back(8); _data.push_back(0); _data.push_back(8); _data.push_back(0); _data.push_back(8); for(uint32_t i = 4; i < 7; i++) { for(uint32_t j = 0; j < 7; j++) { _data.push_back(dataRight[code[i]][j]); } } for(uint32_t i = 0; i < 7; i++) { sum += (i & 1) ? (code[i] * 1) : (code[i] * 3); } } sum = (10 - (sum % 10)) % 10; for(uint32_t i = 0; i < 7; i++) { _data.push_back(dataRight[sum][i]); } _data.push_back(0); _data.push_back(8); _data.push_back(0); for(uint32_t i = 0; i < 32; i++) { _data.push_back(8); } } uint8_t ReadRAM(uint16_t addr) override { return 0; } void WriteRAM(uint16_t addr, uint8_t value) override { } };