Skip to content

Instantly share code, notes, and snippets.

@Alikberov
Created October 10, 2023 15:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Alikberov/a694af6c8e3581041cab6e6f0f8b4c39 to your computer and use it in GitHub Desktop.
Save Alikberov/a694af6c8e3581041cab6e6f0f8b4c39 to your computer and use it in GitHub Desktop.
HCMS-201X / HCMS-231X / HCMS-235X / IPV72A-4/5X7 / ИПВ72А-4/5X7 emulator
<html>
<head>
<title>ИПВ72А-4/5x7</title>
<meta http-equiv="refresh" content="300; url=https://www.jameco.com/Jameco/Products/ProdDS/1548828.pdf">
<script>
var hIPV;
var ctx;
var mtx;
var mask = 0;
var data = 0;
var tick = 0;
var time = 0;
var delay = 0;
var speed = 1; // ...?speed=1
var fading = -1; // ...?fade=1
var stream = [ // ...?stream=D1_8E-6E-4E_1F-7F-5F_15-75-55_1F-7F-5F_15-75-55_1B-7B-5B_0E-6E-4E
// 12 10 8 5 4 3 2 1
// DI \C EN Y5 Y4 Y3 Y2 Y1
// D7_D6_D5_D4_D3_D2_D1_D0
// -----------------------
// 1 1 0 <-- Prepare display start
// 1 0 0 <-- Strobe first line
// 0 1 1 <-- Display line
// 0 1 0 <-- Prepare next line
// 0 0 0 <-- Strobe next line
// 0 1 1 <-- Display line
// 0 1 0 <-- Prepare next line
// 0 0 0 <-- Strobe next line
0xD1,
0x91, 0x71, 0x51,
0x11, 0x71, 0x51,
0x11, 0x71, 0x51,
0x1F, 0x7F, 0x5F,
0x11, 0x71, 0x51,
0x11, 0x71, 0x51,
0x11, 0x71, 0x51,
0x1F, 0x7F, 0x5F,
0x10, 0x70, 0x50,
0x10, 0x70, 0x50,
0x1E, 0x7E, 0x5E,
0x10, 0x70, 0x50,
0x10, 0x70, 0x50,
0x1F, 0x7F, 0x5F,
0x10, 0x70, 0x50,
0x10, 0x70, 0x50,
0x10, 0x70, 0x50,
0x10, 0x70, 0x50,
0x10, 0x70, 0x50,
0x10, 0x70, 0x50,
0x1F, 0x7F, 0x5F,
0x0E, 0x6E, 0x4E,
0x11, 0x71, 0x51,
0x11, 0x71, 0x51,
0x11, 0x71, 0x51,
0x11, 0x71, 0x51,
0x11, 0x71, 0x51,
0x0E, 0x6E, 0x4E
];
function main() {
const user_stream = window.location.href.match(/stream=([0-9_A-F+-]+)/i);
const user_speed = window.location.href.match(/speed=(\d+)/i);
const user_fade = window.location.href.match(/fade=(\d+)/i);
const pins = "Y1 Y2 Y3 Y4 Y5 CH DO EN +5 C 0V DI".split(/\s+/);
hIPV = document.getElementById("IPV");
ctx = hIPV.getContext("2d");
ctx.clearRect(0, 0, hIPV.width, hIPV.height);
mtx = ctx.getImageData(0, 0, 400, 128);
for(var i = 0; i < mtx.data.length; i += 4) {
mtx.data[i] = 255;
mtx.data[i + 1] = 0;
mtx.data[i + 2] = 0;
mtx.data[i + 3] = 0;
}
ctx.fillStyle = "white";
ctx.fillRect(0, 0, 208, 256);
ctx.strokeStyle = "black";
ctx.beginPath();
ctx.lineWidth = 2;
ctx.rect(108, 7, 88, 240);
ctx.rect(148, 94, 40, 75);
ctx.rect(158, 130, 10, 20);
ctx.moveTo(128, 7);
ctx.lineTo(128, 247);
ctx.rect(7, 7, 20, 160);
for(var i = 0; i < 7; ++ i) {
ctx.moveTo(108, 28 + (i + 4) * 20);
ctx.lineTo(128, 28 + (i + 4) * 20);
ctx.moveTo(7, 28 + i * 20);
ctx.lineTo(27, 28 + i * 20);
}
ctx.stroke();
ctx.beginPath();
ctx.lineWidth = 1;
for(var i = 0; i < 12; ++ i) {
ctx.moveTo(88, 16 + i * 20);
ctx.lineTo(108, 16 + i * 20);
ctx.textAlign = "right";
ctx.strokeText(String(i + 1), 104, 12 + i * 20);
ctx.textAlign = "left";
ctx.strokeText(pins[i], 110, 20 + i * 20);
}
ctx.strokeText("4x", 132, 135);
ctx.textAlign = "center";
ctx.strokeText("5x7", 168, 115);
for(var i = 0; i < 8; ++ i) {
ctx.moveTo(27, 16 + i * 20);
ctx.lineTo(88, 16 + (i < 5 ? i : (i - 5) * 2 + 7) * 20);
ctx.strokeText(`D${i}`, 17, 20 + i * 20);
}
ctx.stroke();
if(user_stream) {
stream = [];
for(const data of user_stream[1].split(/[-_+]+/))
stream.push(parseInt(data, 16));
}
if(user_speed)
speed = parseInt(user_speed[1]);
if(user_fade)
fading = -parseInt(user_fade[1]);
show();
}
function show() {
var digit;
var x, y;
var p, err;
var fire;
for(digit = 0; digit < 4; ++ digit) {
err = [-1, 0, 1/4, 1.4][digit];
for(y = 0; y < 7; ++ y) {
for(x = 0; x < 5; ++ x) {
fire = ((data >> (4 - x)) & 1) > 0 && ((mask >> (digit * 7 + y)) & 1) > 0 && (data & 0x20) > 0 ? 255 : fading;
p = (100 * digit + 12 * 400 * y + x * 12 + 8 + Math.floor(err * y)) * 4;
mtx.data[p + 3] += fire;
mtx.data[p + 3 + 4] += fire;
mtx.data[p + 3 + 8] += fire;
mtx.data[p + 3 + 12] += fire;
mtx.data[p + 3 + 16] += fire;
mtx.data[p + 3 + 20] += fire;
mtx.data[p + 3 + 24] += fire;
mtx.data[p + 3 + 1600] += fire;
mtx.data[p + 3 + 1600 + 4] += fire;
mtx.data[p + 3 + 1600 + 8] += fire;
mtx.data[p + 3 + 1600 + 12] += fire;
mtx.data[p + 3 + 1600 + 16] += fire;
mtx.data[p + 3 + 1600 + 20] += fire;
mtx.data[p + 3 + 1600 + 24] += fire;
mtx.data[p + 3 + 3200] += fire;
mtx.data[p + 3 + 3200 + 4] += fire;
mtx.data[p + 3 + 3200 + 8] += fire;
mtx.data[p + 3 + 3200 + 12] += fire;
mtx.data[p + 3 + 3200 + 16] += fire;
mtx.data[p + 3 + 3200 + 20] += fire;
mtx.data[p + 3 + 3200 + 24] += fire;
mtx.data[p + 3 + 4800] += fire;
mtx.data[p + 3 + 4800 + 4] += fire;
mtx.data[p + 3 + 4800 + 8] += fire;
mtx.data[p + 3 + 4800 + 12] += fire;
mtx.data[p + 3 + 4800 + 16] += fire;
mtx.data[p + 3 + 4800 + 20] += fire;
mtx.data[p + 3 + 4800 + 24] += fire;
mtx.data[p + 3 + 6400] += fire;
mtx.data[p + 3 + 6400 + 4] += fire;
mtx.data[p + 3 + 6400 + 8] += fire;
mtx.data[p + 3 + 6400 + 12] += fire;
mtx.data[p + 3 + 6400 + 16] += fire;
mtx.data[p + 3 + 6400 + 20] += fire;
mtx.data[p + 3 + 6400 + 24] += fire;
mtx.data[p + 3 + 8000] += fire;
mtx.data[p + 3 + 8000 + 4] += fire;
mtx.data[p + 3 + 8000 + 8] += fire;
mtx.data[p + 3 + 8000 + 12] += fire;
mtx.data[p + 3 + 8000 + 16] += fire;
mtx.data[p + 3 + 8000 + 20] += fire;
mtx.data[p + 3 + 8000 + 24] += fire;
}
}
}
ctx.putImageData(mtx, 236, 76);
for(var z = 0; z < 2; ++ z) {
ctx.strokeStyle = ["blue", "red"][z];
ctx.fillStyle = ["grey", "silver"][z];
ctx.beginPath();
for(var i = 0; i < 8; ++ i) {
if(((data >> i) & 1) == z) {
ctx.moveTo(27, 16 + i * 20);
ctx.lineTo(88, 16 + (i < 5 ? i : (i - 5) * 2 + 7) * 20);
ctx.fillRect(8, 8.5 + i * 20, 18, 17.5);
ctx.strokeText(`D${i}`, 17, 20 + i * 20);
}
}
ctx.stroke();
}
if(tick == 1 && (data & 0x40) == 0)
mask = ((mask & 0x07FFFFFF) << 1) | ((data & 0x80) >> 7);
tick = (data & 0x40) >> 6;
data = stream[time];
if(-- delay < 0) {
delay = speed;
if(++ time >= stream.length)
time = 0;
}
requestAnimationFrame(show);
}
</script>
<style>
body {
margin :0 0 0 0;
}
canvas {
background-image:url('https://optochip.org/docum/store/factory/series/140509/1487235592-2-4687.jpg');
background-position: 178px -34px;
background-size :77%;
}
</style>
</head>
<body>
<canvas id=IPV width=640 height=256></canvas>
<script>setTimeout(main, 1);</script>
</body>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment