// Вывод символа в 19 видеорежиме
// DI - x
// BX - y
// CH - color
// CL - код символа
:void fastcall Write19(DI,BX,CH,CL)
{
 $push DS

  // Рассчитываем смещение левого верхнего угла символа
  BX<<=6; DI+=BX; BX<<=2; DI+=BX;


  $push ES,BP
    // Сохраняем цвет и код символа на стеке
    $push CX
     // Узнаем адрес видео фонта 8x8 (ES:BP)
     AX=1130h; BH=3; $int 10h
    // Восстанавливаем цвет и код символа из стека
    $pop AX
    DS=ES; SI=AL<<3; SI+=BP;
  $pop BP,ES

  // Рисуем символ
  DH=8;
  loop(DH){
    // Считываем линию символа
    $lodsb
    DL=8;
    loop(DL){
      $rol AL,1
      IF (CARRYFLAG) ESBYTE[DI]=AH;
      DI++;
    }
    DI+=320-8;
  }

 $pop DS
}



// Вывод строки в 19 видеорежиме
// DI - x
// BX - y
// CH - color
// DS:SI - string offset
:void fastcall WriteStr19(DI,BX,CH,SI)
{
 loop(){
  $lodsb
  IF (AL==0) BREAK;
  $push DI,BX,CX,SI
   Write19(DI,BX,CH,AL);
  $pop SI,CX,BX,DI
  DI+=8;
 }
}



// Вывод DWord-овского значения с ограничением разрядка
:void fastcall WriteDWordNDigits19(SI,BX,CH,EAX,EDI)
{
 $push BP,DS

  BP=CH;           // color
  $push BX $pop DS // y

  EBX=10;   // Сколько раз делим
  CX=BX;
  loop(CX){
    EDX=0;
    $div EBX
    $push DX // Сохраняем остаток на стеке
  }
  CL=10; CX-=DI;
  WHILE (CX>0){
    CX--;
    $pop AX  // Отбрасываем лишние знаки
  }

  AX=BP; CH=AL;    // color
  $push DS $pop BX // y
  loop(DI){
    $pop AX
    AL+=48;
    $push DI,SI,BX,CX
     Write19(SI,BX,CH,AL);
    $pop CX,BX,SI,DI
    SI+=8;
  }

 $pop DS,BP
}




