Not sure this is robust, it only works within the limited numerical range of PGFMath, and clearly I've gone for something a bit more over-the-top than the requirements.
EDIT: following Daniels example of the bitset package the code has been updated to be a bit more like that.
\documentclass[border=5pt]{standalone} \usepackage{tikz} \newcount\bitcount \tikzset{ zeros/.style={ draw=black, insert path={ (-\nbit-1/2, -1/2) rectangle ++(1,1) } }, ones/.style={ draw=black, fill=gray, insert path={ (-\nbit-1/2, -1/2) rectangle ++(1,1) } }, max bits/.store in=\maxbits, max bits=0 } \newcommand\dispbyte[2][]{% \begingroup% \tikzset{#1}% \pgfmathsetcount\bitcount{#2}% \pgfmathparse{int(\maxbits)}\let\maxbits=\pgfmathresult% \pgfmathloop% \ifnum\bitcount>0\relax% \ifodd\bitcount% \expandafter\def\csname bit\pgfmathcounter\endcsname{1}% \else% \expandafter\let\csname bit\pgfmathcounter\endcsname=\relax% \fi% \divide\bitcount by2\relax% \repeatpgfmathloop% \pgfmathparse{int(\maxbits>\pgfmathcounter?\maxbits+1:\pgfmathcounter+1)}% \let\nbits=\pgfmathresult% \pgfmathloop% \ifnum\pgfmathcounter=\nbits\relax% \else% \let\nbit=\pgfmathcounter% \expandafter\ifx\csname bit\pgfmathcounter\endcsname\relax% \path [zeros]; \else% \path [ones]; \fi% \repeatpgfmathloop% \endgroup% } \begin{document} \begin{tikzpicture}[x=10pt, y=10pt] \foreach \d [count=\c from 0, evaluate={\x=floor(\c/8)*8; \y=-mod(\c,8);}] in {% 0x7f,0x49,0x08,0x08,0x08,0x08,0x08,0x1c, 0x00,0x00,0x08,0x00,0x18,0x08,0x08,0x1c, 0x08,0x08,0x10,0x12,0x14,0x28,0x24,0x22, 0x7f,0x02,0x04,0x08,0x08,0x10,0x20,0x7f}{ \dispbyte[max bits=8,shift={(\x,\y)}]{\d} } \foreach \d [count=\c from 0, evaluate={\x=floor(\c/8)*8; \y=-mod(\c,8);}] in {% 0x7f,0x49,0x08,0x08,0x08,0x08,0x08,0x1c, 0x00,0x00,0x08,0x00,0x18,0x08,0x08,0x1c, 0x08,0x08,0x10,0x12,0x14,0x28,0x24,0x22, 0x7f,0x02,0x04,0x08,0x08,0x10,0x20,0x7f}{ \dispbyte[zeros/.style={}, ones/.style={ fill=gray, insert path={ (-\nbit-3/8, -3/8) rectangle ++(0.75,0.75) } },shift={(\x,\y-9)}]{\d} } \foreach \d [count=\c from 0, evaluate={\x=floor(\c/8)*8; \y=-mod(\c,8);}] in {% 0x7f,0x49,0x08,0x08,0x08,0x08,0x08,0x1c, 0x00,0x00,0x08,0x00,0x18,0x08,0x08,0x1c, 0x08,0x08,0x10,0x12,0x14,0x28,0x24,0x22, 0x7f,0x02,0x04,0x08,0x08,0x10,0x20,0x7f}{ \dispbyte[max bits=8, zeros/.style={ fill=black, insert path={ (-\nbit, 0) circle [radius=0.5] } }, ones/.style={ fill=orange, insert path={ (-\nbit, 0) circle [radius=0.5] } },shift={(\x,\y-18)}]{\d} } \end{tikzpicture} \end{document}

bitsetpackage by Heiko Oberdiek. It provides the abstraction of bitsets of various lenght, which can be initialized from a hex value by\bitsetSetHex. Individual bits can be tested (\bitsetGet) or all set lists transformed into a comma-separated list (\bitsetGetSetBitList)to be then iterated with, e.g.,\foreach.\foreachyou just have to expand it first, e.g., with\edef. I have now posted this as an answer.