Redneck Engineering
BCD-Clock
 .
Index

BCD-Clock implementation with JavaScript


function runBCDClock(domElement) {
// domElement has to be set to the output domElement when the function
// is called the first time
if (!(runBCDClock.domElement || (runBCDClock.domElement = domElement))) return;
var t, ms, h, m, s, ii, bin, bcd, tmp, byt, out;
// get the time in milliseconds since 1970-01-01 00:00:00
ms = new Date().getTime();
// get time of day in seconds
t = parseInt(ms / 1000) % 86400;
// get the milliseconds till the next second and set the next timeout
setTimeout(runBCDClock, 1000 - (ms %= 1000));
bin = bcd = 0;
// split time into hours minutes and seconds
bin |= (h = parseInt(t / 3600)) << 16;
bin |= (m = parseInt(t / 60 % 60)) << 8;
bin |= (s = parseInt(t % 60));
tmp = bin;
ii = 3;
while (ii--)
// separate the 3rd byte (1. pass: hours, 2.:minutes, 3.:seconds)
byt = (tmp & 0x00ff0000) >> 16
,
// and for the next pass (if any) shift the source 1 byte to left
ii && (tmp <<= 8)
,
// shift the result one byte left (if somethig to shift)
// in th next step we write the bcd in the lowermost byte
// after the third pass the 1st byte is shiftet to the 3rd
bcd && (bcd <<= 8)
,
(
// the low nibble receives the remainder of divison by ten
// that's the right digit of decimal number
bcd |= (parseInt(byt % 10))
,
// the high nibble recieves the result of integer division by ten
// as you assume, that's the left digit (of a 2-digit) decimal number
bcd |= (parseInt(byt / 10) << 4)
)
;
// at this point we have the bcd-code of the current time in 'bcd'
// 'bin' is the original binary match
// now we prepare the output
out = '<div>';
// initialize the loop counter (each bit one pass) and the bit mask
// for and-testing (bit is set or not)
// we start with bit 23 (bit 0 is the rightmost)
tmp = 1 << (ii = 23);
do
// test bit and set the append somethig to the output buffer
out += bcd & tmp ? 'o' : '.'
,
// at the end of the line (after six bits) this remainder is zero ...
ii % 6
// ... if not so...
? (
// shift the bitmask to the next nibble
(tmp >>= 4)
,
// after two nibbles (one bcd) append a space (ASCII 160  )
ii % 2
||
(out += '\xa0')
)
// ... if so ...
: (
// append a line feed
(out += '<br>\n')
,
// and shift the bitmask to the next bit in the high nibble of byte 3
tmp <<= 19
)
; while (ii--);
out += '</div>';

// append some information
// why \xa0 instead of  ?
// for debugging reasons, in an alert-box it looks better
runBCDClock.domElement.hasClass('showbcdinfo')
? (
out += '<span>',
out += '\xa0 time:\xa0 ',
out += ('0' + h + ':').slice(-3),
out += ('0' + m + ':').slice(-3),
out += ('0' + s + '<br>').slice(-6),
out += '\xa0 dword: ',
out += ('00000000' + t.toString(16) + '<br>').slice(-12),
out += '\xa0 bin:\xa0\xa0 ',
out += ('00000000' + bin.toString(16) + '<br>').slice(-12),
out += '\xa0 bcd:\xa0\xa0 ',
out += ('00000000' + bcd.toString(16)).slice(-8),
out += '</span>'
)
: (
// to avoid problems with the css-float we add these line-breaks
// TODO: check
out += '<br><br><br><br>'
);
// fill the dom-element
runBCDClock.domElement.setHTML(out);
}