Печатная машинка в бутсекторе :)
printer.cpp:
#define maxX 79 //Символов в строке
char buf[maxX]; //Буфер строки
char alpha; //Символ (обмен между функциями)
short length; //Длинна строки
short lang; //0-английский, 1 - русский
void TypeChar()
{
__asm__ __volatile__(
"movb $0x0F, %ah;" //Читаем текущие настройки консоли
"int $0x10;"
"movb $0x03, %ah;"
"int $0x10;"
"movb $0x0D, %bl;"
"pushl %eax;"
);
__asm__ __volatile__(
"movl %0, %%ebp;" //Передаём адрес символа alpha
:
:"a"(&alpha)
);
__asm__ __volatile__(
"popl %eax;" //Печатаем символ alpha на консоли
"movw $0x1, %cx;" //1 символ
"movw $0x1301, %ax;"
"int $0x10;"
);
}
void PrintChar()
{
__asm__ __volatile__(
"movw $0x0, %%dx;" //Принтер 0
"movl %0,%%eax;" //Печатем alpha в LPT
"movb (%%eax),%%al;"
"movb $0x0, %%ah;"
"int $0x17;"
:
:"a"(&alpha)
);
}
void DeleteChar()
{
alpha='\b'; //На символ назад
TypeChar();
alpha=' '; //Печатаем пробел (затираем символ)
TypeChar();
alpha='\b'; //На символ назад
TypeChar();
length--; //Затираем символ в buf
}
void ReadChar()
{
__asm__ __volatile__(
"movb $0x10, %%ah;" //Читаем сивол клавиатуры в alpha
"movb %%ah, %0;"
"int $0x16"
:"=a"(alpha)
:
);
}
int main()
{
length=0; //Инициализация
lang=0;
ReadChar();
while ( true )
{
if (alpha == '\r') //Перевод строки
{
for (short i=0; i < length; i++)
{
alpha=buf[i]; //Печаиаем весь buf на принтер
PrintChar();
};
alpha='\r'; //Печатаем перевод строки на консоль и принтер
PrintChar();
TypeChar();
alpha='\n';
PrintChar();
TypeChar();
length=0;
}
else if (alpha == '\t') //Табуляция
{
if (lang == 0) //Переключение языка
{
lang = 1;
}
else
{
lang = 0;
}
}
else if (alpha == '\b') //Backspace
{
DeleteChar(); //Ситраем символ
}
else
{
if (lang == 1)
{
alpha = alpha | 0x80; //koi8-r (работает неправильно)
}
if (length != maxX) //Если не 79 сиволов в строке печатаем символ
{
TypeChar();
buf[length] = alpha;
length++;
}
}
ReadChar();
};
}
printer.sh:
#!/bin/bash
g++ -S -c -nostdlib -o printer.temp printer.cpp
echo ".code16;jmpl \$0x07C0, \$main;" > printer.s
echo ".org 510;.word 0xAA55;" >> printer.temp
sed -i "/data/d" printer.temp
sed -i "/globl/d" printer.temp
sed -i "/section/d" printer.temp
sed -i "/bss/d" printer.temp
cat printer.temp >> printer.s
rm printer.temp
g++ -c -nostdlib -o printer.o printer.s
rm printer.s
objcopy -O binary printer.o printer.bin
echo "" > printer.txt
qemu-system-x86_64 -hda ./printer.bin -parallel file:./printer.txt &
tail -f ./printer.txt