As explained in more detail HERE,
the SDL is a serial link between the Type 4 process board and the revised
Op Panel (the one with 2 LEDs and
power switch on the left side).
The link is controlled via the two least significant bits of port E1h.
Bit 0 drives the DISPLAY_STROBE line and bit 1 then controls the DISPLAY_RESET
line.
See the code snippets down below for more information.
Assembler (IDA)
Register si points to the text string. The string should be 8 bytes long.
mov bx, si
add bx, 7
next_char:
mov cl, [bx]
mov ah, ch
shl ch, 5
rol cx, 3
loop:
in al, 0E1h
and al, 11111110b
out 0E1h, al
or al, 00000001b
out 0E1h, al
loop loop
or al, 00000010b
out 0E1h, al
and al, 11111110b
out 0E1h, al
or al, 00000001b
out 0E1h, al
and al, 11111101b
out 0E1h, al
mov ch, ah
inc ch
dec bx
cmp bx, si
jnb short next_char
C (Borland Turbo C)
The string can be up to 8 characters long. Shorter strings will not fill the
entire display, longer strings will be truncated.
#define LED_POS_NUM 8
#define CHAR_BIT 8
unsigned short rotl16( unsigned short val, unsigned int c )
{
const unsigned int mask = ( CHAR_BIT * sizeof( val ) - 1 );
c &= mask;
return ( val << c ) | ( val >> ( ( -c ) & mask ) );
}
int SDL_send( char * str )
{
int num;
unsigned short int n = 0;
int val = 0;
int i;
if ( str == NULL )
return 0;
num = strlen( str );
if ( num == 0 )
return 0;
if ( num > LED_POS_NUM )
num = LED_POS_NUM;
for ( i = 0; i < num; i++ )
{
n = ( i << 8 );
n <<= 5;
n |= str[ num - 1 - i ];
n = rotl16( n, 3 );
while ( n > 0 )
{
val = inportb( 0xE1 );
val &= 0xFE;
outportb( 0xE1, val );
val |= 0x01;
outportb( 0xE1, val );
n--;
}
val |= 0x02;
outportb( 0xE1, val );
val &= 0xFE;
outportb( 0xE1, val );
val |= 0x01;
outportb( 0xE1, val );
val &= 0xFD;
outportb( 0xE1, val );
}
return num;
}
|