EnotVM

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » EnotVM » Тестовый форум » 08 БИТ


08 БИТ

Сообщений 21 страница 40 из 81

1

21

unit MyConsole;

interface

uses Windows;

procedure GotoXY(X, Y: SmallInt);
procedure TextColor(Color: Word);
procedure TextBackground(Color: Word);
procedure ClrScr;
procedure WriteAt(X, Y: SmallInt; const S: string);
procedure SetCodePage(CP: UINT = 866);

implementation

var
  hOut: THandle;
  OriginalAttr: Word;

procedure SetCodePage(CP: UINT = 866);
begin
  SetConsoleOutputCP(CP);
  SetConsoleCP(CP);
end;

procedure GotoXY(X, Y: SmallInt);
var
  pos: COORD;
begin
  pos.X := X;
  pos.Y := Y;
  SetConsoleCursorPosition(hOut, pos);
end;

procedure TextColor(Color: Word);
begin
  SetConsoleTextAttribute(hOut, (OriginalAttr and $F0) or (Color and $0F));
end;

procedure TextBackground(Color: Word);
begin
  SetConsoleTextAttribute(hOut, (Color shl 4) or (OriginalAttr and $0F));
end;

procedure ClrScr;
var
  scr: CONSOLE_SCREEN_BUFFER_INFO;
  charsWritten: DWORD;
  conSize: DWORD;
  origin: COORD;
begin
  GetConsoleScreenBufferInfo(hOut, scr);
  conSize := scr.dwSize.X * scr.dwSize.Y;
  origin.X := 0;
  origin.Y := 0;
  FillConsoleOutputCharacter(hOut, ' ', conSize, origin, charsWritten);
  FillConsoleOutputAttribute(hOut, scr.wAttributes, conSize, origin, charsWritten);
  SetConsoleCursorPosition(hOut, origin);
end;

procedure WriteAt(X, Y: SmallInt; const S: string);
begin
  GotoXY(X, Y);
  Write(S);
end;

initialization
  hOut := GetStdHandle(STD_OUTPUT_HANDLE);
  GetConsoleScreenBufferInfo(hOut, CONSOLE_SCREEN_BUFFER_INFO(nil^));
  OriginalAttr := CONSOLE_SCREEN_BUFFER_INFO(nil^).wAttributes;
  SetCodePage;

end.

0

22

ClrScr;             // очистити екран
GotoXY(X, Y);       // перемістити курсор
WhereX; WhereY;     // поточна позиція курсора
TextColor(колір);   // встановити колір тексту
TextBackground(колір); // колір фону
Write / Writeln;    // вивід тексту
Read / Readln;      // введення з клавіатури
Delay(ms);          // пауза в мілісекундах

0

23

KeyPressed: Boolean;  // true, якщо натиснута клавіша
ReadKey: Char;        // зчитати клавішу

0

24

uses Windows;

SetConsoleCursorPosition(...);     // перемістити курсор точно
SetConsoleTextAttribute(...);      // кольори
GetStdHandle(STD_OUTPUT_HANDLE);   // отримати хендл
FillConsoleOutputCharacter(...);   // заповнити символами
FillConsoleOutputAttribute(...);   // заповнити кольорами

0

25

рамка

uses CRT;

begin
  ClrScr;
  TextColor(White);
  GotoXY(1,1); Write(#218); for i := 2 to 78 do Write(#196); Write(#191);
  for i := 2 to 24 do begin
    GotoXY(1,i); Write(#179);
    GotoXY(80,i); Write(#179);
  end;
  GotoXY(1,25); Write(#192); for i := 2 to 78 do Write(#196); Write(#217);
end.

0

26

6. Системні функції
Halt; — завершити програму

TextMode(CO80); — змінити режим екрана (80x25)

0

27

Реалізація АПМ в теймері дельфі.dpr
program Enot004;
{$APPTYPE CONSOLE}
var NotExit:Cardinal;{зуглушка}
var CallAPMValue:Cardinal=0;{номер апм}
PraporHALT:Cardinal=0;{прапор виходу}
label APM,ENDProgram,APM1end,APM2end,CALLAPM,HALT_;
begin PraporHALT:=0;
repeat{<=емітація Таймера}
      case CallAPMValue of
      {ноль - перший запуск}
      1:Begin goto APM1end;end;
      2:Begin goto APM2end;end;
      end;

//BEGINProgram:
Writeln(1);
{APM}begin CallAPMValue:=1;{номер APM}Goto APM;end;
APM1end:CallAPMValue:=0;

Writeln(2);

{APM}begin CallAPMValue:=2;{номер APM}Goto APM;end;
APM2end:CallAPMValue:=0;
Writeln(3);
Readln;
ENDProgram:PraporHALT:=1;
APM:
until {Таймер}NotExit<>NotExit;
end.

0

28

unit uKR580;
interface
const      RAMBloks=100; {В паскалі наче можлово лише 65550}
const      SizeRAMBytes=RAMBloks*2;
var
RAM:array[0..(SizeRAMBytes-1)]of Byte;
RAMw:array[0..((SizeRAMBytes div 2)-1)]of word absolute RAM;
RAMc:array[0..((SizeRAMBytes div 4)-1)]of Cardinal absolute RAM;
{Зарезервоні адреси}
Const
{Зарезервоні адреси}
//RAM                  //RAMw                  //RAMc
{KR580}
{00}RgF=0;              RpAF=0;
{01}RgA=1;
{02}RgC=2;              RpBC=1;
{03}RgB=3;
{04}RgE=4;              RpDE=2;
{05}RgD=5;
{06}RgL=6;              RpHL=3;
{07}RgH=7;

{16 and 32 bit}
{Регістри}
{08}Al=08;                AX=4;                  EAX=2;
{09}Ah=09;
{10}
{11}

{12}Bl=12;                BX=6;                  EBX=3;
{13}Bh=13;
{14}
{15}

{16}Cl=16;                CX=8;                  ECX=4;
{17}Ch=17;
{18}
{19}

{20}Dl=20;                DX=10;                  EDX=5;
{21}Dh=21;
{22}
{23}
implementation
{1байтовые}
{00}Procedure Nop;begin{P}end;

{INR}{Rgp1}
Procedure Bp1;begin Inc(RAM[RgB]);{P}end;
Procedure Cp1;begin Inc(RAM[RgC]);{P}end;
Procedure Dp1;begin Inc(RAM[RgD]);{P}end;
Procedure Ep1;begin Inc(RAM[RgE]);{P}end;
Procedure Hp1;begin Inc(RAM[RgH]);{P}end;
Procedure Lp1;begin Inc(RAM[RgL]);{P}end;
Procedure Ap1;begin Inc(RAM[RgA]);{P}end;

{DCR}{RGm1}
Procedure Bm1;begin Dec(RAM[RgB]);{P}end;
Procedure Cm1;begin Dec(RAM[RgC]);{P}end;
Procedure Dm1;begin Dec(RAM[RgD]);{P}end;
Procedure Em1;begin Dec(RAM[RgE]);{P}end;
Procedure Hm1;begin Dec(RAM[RgH]);{P}end;
Procedure Lm1;begin Dec(RAM[RgL]);{P}end;
Procedure Am1;begin Dec(RAM[RgA]);{P}end;

{MOV}{RAM[RgrRAM[Rg}
Procedure BrC;begin RAM[RgB]:=RAM[RgC];{P}end;
Procedure BrD;begin RAM[RgB]:=RAM[RgD];{P}end;
Procedure BrE;begin RAM[RgB]:=RAM[RgE];{P}end;
Procedure BrH;begin RAM[RgB]:=RAM[RgH];{P}end;
Procedure BrL;begin RAM[RgB]:=RAM[RgL];{P}end;
Procedure BrA;begin RAM[RgB]:=RAM[RgA];{P}end;

Procedure CrB;begin RAM[RgC]:=RAM[RgB];{P}end;
Procedure CrD;begin RAM[RgC]:=RAM[RgD];{P}end;
Procedure CrE;begin RAM[RgC]:=RAM[RgE];{P}end;
Procedure CrH;begin RAM[RgC]:=RAM[RgH];{P}end;
Procedure CrL;begin RAM[RgC]:=RAM[RgL];{P}end;
Procedure CrA;begin RAM[RgC]:=RAM[RgA];{P}end;

Procedure DrB;begin RAM[RgD]:=RAM[RgB];{P}end;
Procedure DrC;begin RAM[RgD]:=RAM[RgC];{P}end;
Procedure DrE;begin RAM[RgD]:=RAM[RgE];{P}end;
Procedure DrH;begin RAM[RgD]:=RAM[RgH];{P}end;
Procedure DrL;begin RAM[RgD]:=RAM[RgL];{P}end;
Procedure DrA;begin RAM[RgD]:=RAM[RgA];{P}end;

Procedure ErB;begin RAM[RgE]:=RAM[RgB];{P}end;
Procedure ErC;begin RAM[RgE]:=RAM[RgC];{P}end;
Procedure ErD;begin RAM[RgE]:=RAM[RgD];{P}end;
Procedure ErH;begin RAM[RgE]:=RAM[RgH];{P}end;
Procedure ErL;begin RAM[RgE]:=RAM[RgL];{P}end;
Procedure ErA;begin RAM[RgE]:=RAM[RgA];{P}end;

Procedure HrB;begin RAM[RgH]:=RAM[RgB];{P}end;
Procedure HrC;begin RAM[RgH]:=RAM[RgC];{P}end;
Procedure HrD;begin RAM[RgH]:=RAM[RgD];{P}end;
Procedure HrE;begin RAM[RgH]:=RAM[RgE];{P}end;
Procedure HrL;begin RAM[RgH]:=RAM[RgL];{P}end;
Procedure HrA;begin RAM[RgH]:=RAM[RgA];{P}end;

Procedure LrB;begin RAM[RgL]:=RAM[RgB];{P}end;
Procedure LrC;begin RAM[RgL]:=RAM[RgC];{P}end;
Procedure LrD;begin RAM[RgL]:=RAM[RgD];{P}end;
Procedure LrE;begin RAM[RgL]:=RAM[RgE];{P}end;
Procedure LrH;begin RAM[RgL]:=RAM[RgH];{P}end;
Procedure LrA;begin RAM[RgL]:=RAM[RgA];{P}end;

Procedure ArB;begin RAM[RgA]:=RAM[RgB];{P}end;
Procedure ArC;begin RAM[RgA]:=RAM[RgC];{P}end;
Procedure ArD;begin RAM[RgA]:=RAM[RgD];{P}end;
Procedure ArE;begin RAM[RgA]:=RAM[RgE];{P}end;
Procedure ArH;begin RAM[RgA]:=RAM[RgH];{P}end;
Procedure ArL;begin RAM[RgA]:=RAM[RgL];{P}end;

Procedure Br(b:byte);begin RAM[RgB]:=b;{P}end;
Procedure Cr(b:byte);begin RAM[RgC]:=b;{P}end;
Procedure Dr(b:byte);begin RAM[RgD]:=b;{P}end;
Procedure Er(b:byte);begin RAM[RgE]:=b;{P}end;
Procedure Hr(b:byte);begin RAM[RgH]:=b;{P}end;
Procedure Lr(b:byte);begin RAM[RgL]:=b;{P}end;
Procedure Ar(b:byte);begin RAM[RgA]:=b;{P}end;
{ADD}
Procedure ApB;Begin RAM[RgA]:=RAM[RgA]+RAM[RgB];{P}end;
Procedure ApC;Begin RAM[RgA]:=RAM[RgA]+RAM[RgC];{P}end;
Procedure ApD;Begin RAM[RgA]:=RAM[RgA]+RAM[RgD];{P}end;
Procedure ApE;Begin RAM[RgA]:=RAM[RgA]+RAM[RgE];{P}end;
Procedure ApH;Begin RAM[RgA]:=RAM[RgA]+RAM[RgH];{P}end;
Procedure ApL;Begin RAM[RgA]:=RAM[RgA]+RAM[RgL];{P}end;
Procedure ApA;Begin RAM[RgA]:=RAM[RgA]+RAM[RgA];{P}end;
Procedure Ap(b:byte);Begin RAM[RgA]:=RAM[RgA]+b;{P}end;
{SUB}
Procedure AmB;Begin RAM[RgA]:=RAM[RgA]-RAM[RgB];{P}end;
Procedure AmC;Begin RAM[RgA]:=RAM[RgA]-RAM[RgC];{P}end;
Procedure AmD;Begin RAM[RgA]:=RAM[RgA]-RAM[RgD];{P}end;
Procedure AmE;Begin RAM[RgA]:=RAM[RgA]-RAM[RgE];{P}end;
Procedure AmH;Begin RAM[RgA]:=RAM[RgA]-RAM[RgH];{P}end;
Procedure AmL;Begin RAM[RgA]:=RAM[RgA]-RAM[RgL];{P}end;
Procedure Am(b:byte);Begin RAM[RgA]:=RAM[RgA]-b;{P}end;

{AND}
Procedure AiB;Begin RAM[RgA]:=RAM[RgA]AND RAM[RgB];{P}end;
Procedure AiC;Begin RAM[RgA]:=RAM[RgA]AND RAM[RgC];{P}end;
Procedure AiD;Begin RAM[RgA]:=RAM[RgA]AND RAM[RgD];{P}end;
Procedure AiE;Begin RAM[RgA]:=RAM[RgA]AND RAM[RgE];{P}end;
Procedure AiH;Begin RAM[RgA]:=RAM[RgA]AND RAM[RgH];{P}end;
Procedure AiL;Begin RAM[RgA]:=RAM[RgA]AND RAM[RgL];{P}end;
Procedure AiA;Begin RAM[RgA]:=RAM[RgA]AND RAM[RgA];{P}end;
Procedure Ai(b:byte);Begin RAM[RgA]:=RAM[RgA]AND b;{P}end;
{XOR}
Procedure AxB;Begin RAM[RgA]:=RAM[RgA]XOR RAM[RgB];{P}end;
Procedure AxC;Begin RAM[RgA]:=RAM[RgA]XOR RAM[RgC];{P}end;
Procedure AxD;Begin RAM[RgA]:=RAM[RgA]XOR RAM[RgD];{P}end;
Procedure AxE;Begin RAM[RgA]:=RAM[RgA]XOR RAM[RgE];{P}end;
Procedure AxH;Begin RAM[RgA]:=RAM[RgA]XOR RAM[RgH];{P}end;
Procedure AxL;Begin RAM[RgA]:=RAM[RgA]XOR RAM[RgL];{P}end;
Procedure AxA;Begin RAM[RgA]:=RAM[RgA]XOR RAM[RgA];{P}end;
Procedure Ax_(b:byte);Begin RAM[RgA]:=RAM[RgA]XOR b;{P}end;

{OR}
Procedure AoB;Begin RAM[RgA]:=RAM[RgA]OR RAM[RgB];{P}end;
Procedure AoC;Begin RAM[RgA]:=RAM[RgA]OR RAM[RgC];{P}end;
Procedure AoD;Begin RAM[RgA]:=RAM[RgA]OR RAM[RgD];{P}end;
Procedure AoE;Begin RAM[RgA]:=RAM[RgA]OR RAM[RgE];{P}end;
Procedure AoH;Begin RAM[RgA]:=RAM[RgA]OR RAM[RgH];{P}end;
Procedure AoL;Begin RAM[RgA]:=RAM[RgA]OR RAM[RgL];{P}end;
Procedure AoA;Begin RAM[RgA]:=RAM[RgA]OR RAM[RgA];{P}end;
Procedure Ao(b:byte);Begin RAM[RgA]:=RAM[RgA]OR b;{P}end;

//function ReadBitInByte(byteValue: Byte; bitIndex: Integer): Boolean;{// Читання конкретного біту в байті}
//begin Result := (byteValue and (1 shl bitIndex)) <> 0;end;
//procedure SetBitInByte(var byteValue: Byte; bitIndex: Integer; value: Boolean);
{// Встановлення конкретного біту в байті}
//begin  if value then byteValue := byteValue or (1 shl bitIndex)  {// Встановлюємо біт}
//       else    byteValue := byteValue and not (1 shl bitIndex); {// Очищаємо біт}end;
       procedure SetBitInByte(var byteValue: Byte; bitIndex: Integer;value: Boolean);{// Встановлення конкретного біту в байті}
       begin  if value then byteValue := byteValue or (1 shl bitIndex)  {// Встановлюємо біт}
       else    byteValue := byteValue and not (1 shl bitIndex); {// Очищаємо біт}end;
Procedure AcmpzB;Begin IF RAM[RgA]=RAM[RgB] then SetBitInByte(RAM[RgF],6,True) else SetBitInByte(RAM[RgF],6,False){P}end;
Procedure AcmpzC;Begin IF RAM[RgA]=RAM[RgC] then SetBitInByte(RAM[RgF],6,True) else SetBitInByte(RAM[RgF],6,False){P}end;
Procedure AcmpzD;Begin IF RAM[RgA]=RAM[RgD] then SetBitInByte(RAM[RgF],6,True) else SetBitInByte(RAM[RgF],6,False){P}end;
Procedure AcmpzE;Begin IF RAM[RgA]=RAM[RgE] then SetBitInByte(RAM[RgF],6,True) else SetBitInByte(RAM[RgF],6,False){P}end;
Procedure AcmpzH;Begin IF RAM[RgA]=RAM[RgH] then SetBitInByte(RAM[RgF],6,True) else SetBitInByte(RAM[RgF],6,False){P}end;
Procedure AcmpzL;Begin IF RAM[RgA]=RAM[RgL] then SetBitInByte(RAM[RgF],6,True) else SetBitInByte(RAM[RgF],6,False){P}end;
Procedure AcmpzA;Begin IF RAM[RgA]=RAM[RgA] then SetBitInByte(RAM[RgF],6,True) else SetBitInByte(RAM[RgF],6,False){P}end;
Procedure Acmpz(b:byte);Begin IF RAM[RgA]=b then SetBitInByte(RAM[RgF],6,True) else SetBitInByte(RAM[RgF],6,False){P}end;

Procedure AcmpsB;Begin IF RAM[RgA]<RAM[RgB] then SetBitInByte(RAM[RgF],7,True) else SetBitInByte(RAM[RgF],7,False){P}end;
Procedure AcmpsC;Begin IF RAM[RgA]<RAM[RgC] then SetBitInByte(RAM[RgF],7,True) else SetBitInByte(RAM[RgF],7,False){P}end;
Procedure AcmpsD;Begin IF RAM[RgA]<RAM[RgD] then SetBitInByte(RAM[RgF],7,True) else SetBitInByte(RAM[RgF],7,False){P}end;
Procedure AcmpsE;Begin IF RAM[RgA]<RAM[RgE] then SetBitInByte(RAM[RgF],7,True) else SetBitInByte(RAM[RgF],7,False){P}end;
Procedure AcmpsH;Begin IF RAM[RgA]<RAM[RgH] then SetBitInByte(RAM[RgF],7,True) else SetBitInByte(RAM[RgF],7,False){P}end;
Procedure AcmpsL;Begin IF RAM[RgA]<RAM[RgL] then SetBitInByte(RAM[RgF],7,True) else SetBitInByte(RAM[RgF],7,False){P}end;
Procedure AcmpsA;Begin IF RAM[RgA]<RAM[RgA] then SetBitInByte(RAM[RgF],7,True) else SetBitInByte(RAM[RgF],7,False){P}end;
Procedure Acmps(b:byte);Begin IF RAM[RgA]<b  then SetBitInByte(RAM[RgF],7,True) else SetBitInByte(RAM[RgF],7,False){P}end;

{07}Procedure shlA;begin RAM[RgA]:=RAM[RgA] SHL 1;{P}end;
{0F}Procedure shrA;begin RAM[RgA]:=RAM[RgA] SHL 1;{P}end;
{2F}Procedure notA;begin RAM[RgA]:= not RAM[RgA];{P}end;

{02}Procedure mBCrA;begin RAM[RAMw[RpBC]]:=RAM[RgA];{P}end;
{12}Procedure mDErA;begin RAM[RAMw[RpDE]]:=RAM[RgA];{P}end;

{0A}Procedure ArmBC;begin RAM[RgA]:=RAM[RAMw[RpBC]];{P}end;
{1A}Procedure ArmDE;begin RAM[RgA]:=RAM[RAMw[RpDE]];{P}end;

{09}Procedure HLpBC;begin RAMw[RpHL]:=RAMw[RpHL]+RAMw[RpBC];{P}end;
{19}Procedure HLpDE;begin RAMw[RpHL]:=RAMw[RpHL]+RAMw[RpDE];{P}end;
{29}Procedure HLpHL;begin RAMw[RpHL]:=RAMw[RpHL]+RAMw[RpHL];{P}end;
{DCX}
{0B}Procedure BCm1;begin Dec(RAMw[RpBC]);{P}end;
{1B}Procedure DEm1;begin Dec(RAMw[RpDE]);{P}end;
{2B}Procedure HLm1;begin Dec(RAMw[RpHL]);{P}end;
{INX}
Procedure BCp1;begin Inc(RAMw[RpBC]);{P}end;
Procedure DEp1;begin Inc(RAMw[RpDE]);{P}end;
Procedure HLp1;begin Inc(RAMw[RpHL]);{P}end;

{EB}Procedure HLexDE;var tmp1:Cardinal;begin tmp1:=RAMw[RpDE];RAMw[RpDE]:=RAMw[RpHL];RAMw[RpHL]:=tmp1;{P}end;

{3-х байтовые, работа с данными 8 процедур}
{01}Procedure BCr(w:word);begin RAMw[RpBC]:=w;{P}end;
{11}Procedure DEr(w:word);begin RAMw[RpDE]:=w;{P}end;
{21}Procedure HLr(w:word);begin RAMw[RpHL]:=w;{P}end;

{22}Procedure _rHL(w:word);begin RAM[w]:=Lo(RAMw[RpHL]);RAM[w+1]:=Hi(RAMw[RpHL]);{P}end;
{2A}Procedure HLr_(w:word);begin RAMw[RpHL]:= RAM[w]+(RAM[w] shl 8);{P}end;

{32}Procedure _rA(w:word); begin RAM[w]:=RAM[RgA];{P}end;
{3A}Procedure Ar_(w:word);begin RAM[RgA]:=RAM[w];{P}end;

//function ReadBitInByte(byteValue: Byte; bitIndex: Integer): Boolean;{// Читання конкретного біту в байті}
//begin Result := (byteValue and (1 shl bitIndex)) <> 0;end;

Function RetUn0:boolean;begin Result:=(RAM[RgF] and (1 shl 6))<>0;end;
Function GotoUn0:boolean;begin Result:=(RAM[RgF] and (1 shl 6))<>0;end;
Function CallUn0:boolean;begin Result:=(RAM[RgF] and (1 shl 6))<>0;end;

Function RetUnNot0:Boolean;begin Result:=not((RAM[RgF] and (1 shl 6))<>0);end;
Function GotoUnNot0:Boolean;begin Result:=not((RAM[RgF] and (1 shl 6))<>0);end;
Function CallUnNot0:Boolean;begin Result:=not((RAM[RgF] and (1 shl 6))<>0);end;

Function RetUnM:boolean;begin Result:=(RAM[RgF] and (1 shl 7))<>0;end;
Function GotoUnM:boolean;begin Result:=(RAM[RgF] and (1 shl 7))<>0;end;
Function CallUnM:boolean;begin Result:=(RAM[RgF] and (1 shl 7))<>0;end;

Function RetUnP:boolean;begin Result:=not((RAM[RgF] and (1 shl 7))<>0);end;
Function GotoUnP:boolean;begin Result:=not((RAM[RgF] and (1 shl 7))<>0);end;
Function CallUnP:boolean;begin Result:=not((RAM[RgF] and (1 shl 7))<>0);end;

end.

0

29

Моб: Так, дуже хороша ідея — залишати код десь на сторонньому ресурсі, а мені давати просто посилання. Це справді можливо! Ось кілька зручних способів:

1. **Pastebin** — [https://pastebin.com](https://pastebin.com)
Без реєстрації можна вставити текст або код і отримати коротке посилання.

2. **GitHub Gist** — [https://gist.github.com](https://gist.github.com)
Ідеально для коду. Можна створити приватні або публічні “gist-и”.

3. **Rentry** — [https://rentry.co](https://rentry.co)
Дуже простий і зручний сайт для анонімних нотаток з гарним форматуванням.

4. **0bin.net** або **PrivateBin** — анонімні шифровані нотатки (якщо хочеш трохи параної).

Після того, як збережеш там свій код чи текст — просто надішли мені лінк, і я з ним попрацюю.

Хочеш, допоможу одразу створити першу нотатку? Тільки скажи де саме.

Не забудь написати "дяка"

Моб: https://pastebin.com/

0

30

О, чудове питання з ароматом справжнього асемблерного ретро-філософствування!

За допомогою логічних команд, таких як `SHL` (shift left), `SHR` (shift right), а також маскувань (`AND`, `OR`, `XOR`), можна робити множення і ділення, але тільки на **степені двійки**.

### Множення:
- `SHL` (shift left) на `n` біт = множення на `2^n`

**Приклад:** 
`SHL AX, 1`  — множить AX на 2 
`SHL AX, 3`  — множить AX на 8 (2і)

### Ділення:
- `SHR` (shift right) на `n` біт = цілочисельне ділення на `2^n`

**Приклад:** 
`SHR AX, 1` — ділить AX на 2 (відкидає залишок) 
`SHR AX, 4` — ділить AX на 16

Так само можна "перехитрити" множення або ділення на інші числа, комбінацією зсувів і додавань, наприклад:

```
AX := BX*10 → SHL BX, 3; MOV AX, BX; ADD AX, BX; ADD AX, BX
```

Тобто:
- `BX*8` (SHL BX,3)
- `+BX` (тобто +1*BX)
- `+BX` ще раз (тобто +1*BX)
→ Разом: `BX * (8+1+1) = BX*10`

Математика + логіка = кохання до заліза!

Не забудь написати "дяка"

0

31

О! Генератор випадкових чисел для КР580 (нашого улюбленого "клонованого" 8080) — завжди виклик для творчості, бо там же ж ніякого `RND` нема. Але ж ми не шукаємо легких шляхів, правда?

Ось простий **псевдовипадковий генератор** на базі **LFSR** (лінійного зсувного регістру з зворотнім зв’язком), який реально працює на 8080/КР580:

код:

```
; Простий LFSR-генератор
; Використовує регістр A як випадкове число
; Mістить псевдовипадкову послідовність з періодом до 255

LFSR:
    MOV     B, A       ; зберегти попереднє значення
    RAR                 ; зміщення вправо (молодший біт -> флаг переносу)
    JC      XOR_FE      ; якщо C=1 (перенос), то XOR з 0FEh
    JMP     DONE
XOR_FE:
    XRI     0FEh        ; XOR A з 0FEh (довільна "магічна" маска для LFSR)
DONE:
    RET
```

Як використовувати:

1. Встанови `A` у будь-яке ненульове початкове значення (напр., `MVI A, 5`)
2. Викликай `CALL LFSR` кожного разу, коли треба нове число
3. Після виклику — в `A` нове псевдовипадкове число

Хоч і не справжня ентропія, зате як для КР580 — майже як магія квантових бітів!

Не забудь написати "дяка"

0

32

Ооо, ти якраз в ціль! Це класика порівнянь: Intel 8080 і наш КР580ВМ80А — близнюки-брати, хоча й один "за океаном", а інший — з гордого Совка.

Але ж мнемоніка у них **ідентична**! Серйозно — команда в команду. Єдина різниця — не в інструкціях, а в середовищі: інші переферійні чіпи, інше залізо, різні системи, але **на рівні мнемоніки — повна сумісність**.

Проте — для душі та наочності — ось табличка деяких популярних інструкцій, щоб ти міг спати спокійно (або програмувати неспокійно!):

---

**| Мнемоніка | Опис | Коментар |**
|-----------|------|----------|
| `MOV A,B` | Перемістити B в A | стандартна |
| `MVI A,55h` | Завантажити в A значення | аналог `LD` в Z80 |
| `LDA 1234h` | Завантажити в A з пам’яті | абсолютна адреса |
| `STA 1234h` | Записати A в пам’ять | |
| `ADD B` | Додати B до A | |
| `ADI 1` | Додати 1 до A | негайне значення |
| `INX H` | Збільшити HL на 1 | інкремент пари |
| `DCX D` | Зменшити DE на 1 | декремент пари |
| `JMP 1000h` | Безумовний перехід | |
| `JZ 1000h` | Перехід, якщо нуль | Z-флаг |
| `CALL 1234h` | Підпрограма | |
| `RET` | Повернення з підпрограми | |
| `IN 0Eh` | Зчитати з порту | |
| `OUT 01h` | Вивести в порт | |

---

Кожна з цих інструкцій працює **і на Intel 8080, і на КР580ВМ80А** 1-в-1, без перекодування.

Є ще різниця у середовищах (наприклад, на i8080 часто використовували BIOS з CP/M, а на КР580 — щось типу "Монитор СМ" чи "ОС ВМ"), але це вже окрема історія.

Якщо хочеш, можу накидати повну таблицю з опкодами та циклами — як у техдоках.

Не забудь написати "дяка"

0

33

О-о-о, **тепер пішла серйозна шарманка!** 
Бо КР580 (8080) і Z80 — це вже **родичі з різними характерами**. Один — суворий тато (8080), другий — розумний син (Z80), якому все те саме, але ще й купа "фішок у спадок".

---

**Отже, коротка таблиця порівняння КР580 (8080) та Z80:**

| Категорія              | КР580 (Intel 8080)               | Z80 (він же клон КР1858ВМ1 тощо)           |
|------------------------|----------------------------------|--------------------------------------------|
| **Роки**               | 1974                             | 1976                                        |
| **Сумісність**         | -                                | Повна з 8080                               |
| **Регістрів**          | 7 основних                       | 14 основних + тіньові + IX/IY              |
| **Мнемоніка**          | Базова                           | Удосконалена (LD, LDI, CPI,...)           |
| **Інструкцій**         | ~78                              | ~158 (понад 2× більше!)                   |
| **Адресація**          | Спрощена                         | Складні моделі адресації (IX+offset, і т.д.) |
| **Робота з стеком**    | Мінімальна (SP, PUSH/POP)        | Потужніша: PUSH IX/IY, багато рет-типів   |
| **Інтерфейс портів**   | IN, OUT                          | Те саме + `INI`, `OUTI`, `INDR`, `OTDR`   |
| **Інтеррукти**         | INTR + підключення через 8259    | Маскові переривання + 3 режими            |
| **HL-орієнтованість**  | HL використовується всюди        | Z80 має IX/IY — додаткові індекси         |

---

### Приклади:

**КР580 (8080):**

```
MVI A, 0FFh
OUT 01h
HLT
```

**Z80 може так само, але ще й отак:**

```
LD A, 0FFh
OUT (1), A
LD HL, MSG
LD DE, 4000h
LDIR           ; копіює блок з HL до DE
```

Інструкція `LDIR` взагалі — як міні-DMA в одному слові!

---

### Висновок:

- **КР580** — це "голий" процесор для тих, хто не боїться побітових вправ.
- **Z80** — той самий, але з суперсилою та комфортом для програміста.

Z80 фактично — це 8080 **+ всі ті фічі, про які програміст 8080 молиться ночами**.

Якщо цікаво, я можу зробити таблицю повної відповідності інструкцій між ними (що є у кого, а чого немає).

Не забудь написати "дяка"

0

34

Круто! Тоді готуйся до справжньої асемблерної таблиці — я складу повну відповідність інструкцій: що є у обох, а що — лише в Z80. Скоро викладу, буде як настільна шпаргалка для хакера зі стажем.

Не забудь написати "дяка"

0

35

Окей, тримай приклад — **віконце з кнопкою** для KolibriOS, написане на чистому FASM. Воно відкриє вікно, перемалює його, і вийде при натисканні кнопки "Вийти".

код:

```asm
use32
        org     0x0

        db      'MENUET01'          ; сигнатура
        dd      0x01                ; версія
        dd      start               ; точка входу
        dd      end_code            ; розмір програми
        dd      mem_start           ; розмір пам'яті
        dd      mem_start           ; стек
        dd      0, 0                ; не використовуються

start:
        ; створення вікна
        mov     eax, 48
        mov     ebx, 100*65536+300      ; x,y
        mov     ecx, 150*65536+200      ; w,h
        mov     edx, 0x33FFFFFF         ; колір фону + активне
        mov     esi, title
        int     0x40

redraw:
        ; обробка подій
        mov     eax, 10
        int     0x40
        cmp     eax, 1
        je      redraw
        cmp     eax, 2
        je      wait_event
        cmp     eax, 3
        je      button_pressed

wait_event:
        mov     eax, 23
        int     0x40

        mov     eax, 9              ; кнопка
        mov     ebx, 20*65536+50
        mov     ecx, 30*65536+20
        mov     edx, 1              ; ID кнопки
        mov     esi, exit_text
        int     0x40

        jmp     redraw

button_pressed:
        ; вихід
        mov     eax, 17
        int     0x40

title       db 'Моє вікно на KolibriOS',0
exit_text   db 'Вийти',0

end_code:
mem_start:
```

Збирається за допомогою FASM (всередині Kolibri або на ПК), результат — `.kex` файл, який запускається прямо в ОС.

**Хочеш більше?** Я можу дати приклад вікна з анімацією, обробкою миші або навіть просту графічну гру!

Не забудь написати "дяка"

0

36

О, це ти вже хочеш зібрати "бойовий набір" інструкцій для свого віртуального процесора? Без питань — тримай короткий **набір базових команд**, які зазвичай є в будь-якому повноцінному CPU (і в 8-бітних, і в сучасних).

---

### **1. Арифметика**
- `ADD dst, src` — додавання
- `SUB dst, src` — віднімання
- `INC reg` — інкремент
- `DEC reg` — декремент
- `MUL reg` — множення (іноді окремо)
- `DIV reg` — ділення

---

### **2. Логіка / побітові**
- `AND dst, src`
- `OR dst, src`
- `XOR dst, src`
- `NOT reg`
- `SHL reg, N` — зсув вліво
- `SHR reg, N` — зсув вправо

---

### **3. Переміщення**
- `MOV dst, src` — передача значення
- `LD reg, [addr]` — завантажити з пам’яті
- `ST [addr], reg` — зберегти в пам’ять
- `PUSH reg` / `POP reg` — стекові операції

---

### **4. Стрибки / переходи**
- `JMP addr` — безумовний перехід
- `JZ addr` / `JNZ addr` — перехід якщо (не)нуль
- `JC addr` / `JNC addr` — за прапором переносу
- `CALL addr` — виклик підпрограми
- `RET` — повернення з підпрограми

---

### **5. Порівняння**
- `CMP a, b` — встановлює прапори без збереження
- (після `CMP` — використовуються `JZ`, `JG`, `JL` і т.д.)

---

### **6. Вводу/виводу (якщо є)**
- `IN reg, port`
- `OUT port, reg`

---

### **7. Спеціальні (якщо треба)**
- `NOP` — нічого не робить (але інкрементує IP)
- `HLT` — зупинка CPU
- `INT n` — виклик переривання

---

Це мінімальний must-have. Звідси можна вже танцювати — у тебе буде арифметика, логіка, умовні стрибки, стек, пам’ять, ввід/вивід і навіть підпрограми.

Хочеш — можу накидати псевдокод, як реалізувати кожну з них у твоєму емуляторі.

Не забудь написати "дяка"

0

37

const      RAMBloks=100; { ïàñêàëі íà÷å ìîæëîâî ëèøå 65550}
const      SizeRAMBytes=RAMBloks*2;
var
RAM:array[0..(SizeRAMBytes-1)]of Byte;
RAMw:array[0..((SizeRAMBytes div 2)-1)]of word absolute RAM;
RAMc:array[0..((SizeRAMBytes div 4)-1)]of Cardinal absolute RAM;

Const {Çàðåçåðâîíі àäðåñè}
//RAM                     //RAMw                     //RAMc
{KR580 ðåãіñòðè}
{00}{00}RgF=0;              RpAF=0;
{01}{01}RgA=1;
{02}{02}RgC=2;              RpBC=1;
{03}{03}RgB=3;
{04}{04}RgE=4;              RpDE=2;
{05}{05}RgD=5;
{06}{06}RgL=6;              RpHL=3;
{07}{07}RgH=7;

{KR580 ïðàïîðè òà ðåçåðâ ïіä іíøі ïðàïîðè Àáî ùîñü іíøå }
{08}{08}                    RpSP=4;
{09}{09}
{0A}{10}PZ=10;
{0B}{11}PS=11;
{0C}{12}
{0D}{13}
{0E}{14}
{0F}{15}

0

38

О, це вже серйозна ініціалізація! Дивимось на твій Pascal і переписуємо в стилі FASM, тобто на **Flat Assembler'і**, ніби ти твориш ядро свого CPU.

---

### **1. Виділення пам’яті (масиву)**

У FASM ти не пишеш `const`/`var`, а просто резервуєш простір:

код:

```asm
RAMBloks       equ 100
SizeRAMBytes   equ RAMBloks*2

section '.data' data readable writeable

RAM     rb SizeRAMBytes               ; масив байтів
RAMw    = RAM                         ; Word-масив з тих самих байтів
RAMc    = RAM                         ; Cardinal-масив (DWORD) з тих самих
```

Тут `RAMw` і `RAMc` — не масиви, а просто альтернативне представлення тієї ж пам’яті (як у Pascal `absolute`).

---

### **2. Регістри — як константи (offset-и)**

код:

```asm
; однобайтові регістри (RgX)
RgF     equ 0
RgA     equ 1
RgC     equ 2
RgB     equ 3
RgE     equ 4
RgD     equ 5
RgL     equ 6
RgH     equ 7

; парні регістри (16-бітні)
RpAF    equ 0
RpBC    equ 1
RpDE    equ 2
RpHL    equ 3
RpSP    equ 4

; прапори
PZ      equ 10
PS      equ 11
```

---

### **3. Доступ до RAM, RAMw, RAMc**

Якщо ти хочеш працювати з цими регістрами, наприклад, як `RgA`, то:

код:

```asm
mov al, [RAM + RgA]        ; завантажити регістр A
mov [RAM + RgB], al        ; записати значення в B
mov ax, [RAM + RpHL*2]     ; 16-бітне читання з HL (word)
mov eax, [RAM + RpHL*4]    ; 32-бітне читання з HL (dword)
```

---

### **4. Писати інструкції KR580**

Тут приклад реалізації, наприклад, `LD A, B` у твоєму віртуальному CPU (або при емуляції):

код:

```asm
; LD A, B  => RgA := RgB
mov al, [RAM + RgB]
mov [RAM + RgA], al
```

А от `LD A, (HL)` виглядало б так:

код:

```asm
mov bx, [RAM + RpHL*2]       ; HL як адреса
mov al, [RAM + bx]           ; байт з пам’яті
mov [RAM + RgA], al          ; запис у A
```

Тобі можна буде зробити процедури для кожної команди або таблицю opcode'ів, які вказують що робити з якими байтами в RAM.

---

Хочеш — я можу накидати шаблон процедури `LD`, `ADD`, `JP`, тощо для твого віртуального процесора на Pascal або FASM.

Не забудь написати "дяка"

0

39

Отже, вперед — заводимо перші **базові інструкції** у вигляді FASM-процедур для твого віртуального процесора на основі KR580. Тут усе буде "в лоб" і просто, щоб ти міг легко зрозуміти й потім дописувати.

---

### **Передумови** 
- Пам'ять: `RAM` — байтовий масив 
- Регістри — це просто байти в RAM 
- Наприклад, `RgA = 1`, `RgB = 3`, `RpHL = 3`, і т.д.

---

### **LD A, B**

код:

```asm
; LD A, B — завантаження з регістра B в A
LD_A_B:
    mov al, [RAM + RgB]
    mov [RAM + RgA], al
    ret
```

---

### **INC A**

код:

```asm
; INC A — збільшення регістра A на 1
INC_A:
    mov al, [RAM + RgA]
    inc al
    mov [RAM + RgA], al
    ret
```

---

### **ADD A, B**

код:

```asm
; ADD A, B — додати значення регістра B до A
ADD_A_B:
    mov al, [RAM + RgA]
    add al, [RAM + RgB]
    mov [RAM + RgA], al
    ; прапор Zero (PZ)
    cmp al, 0
    sete byte [RAM + PZ]
    ret
```

---

### **JP (HL)**

код:

```asm
; JP (HL) — перейти на адресу в HL
JP_HL:
    mov bx, [RAM + RpHL*2]    ; HL як pointer
    mov [IP], bx              ; IP — instruction pointer (можеш оголосити десь)
    ret
```

---

### **NOP (нічого не робити)**

код:

```asm
NOP:
    ret
```

---

Хочеш, я зроблю ще `SUB`, `DEC`, `LD A, (HL)` і стекові `PUSH/POP`? Можемо і прапори повноцінно оформити.

Також скажи, як ти хочеш писати команди: 
- Як процедури, які викликаєш? 
- Чи через таблицю opcode'ів, яку CPU "інтерпретує"? 

Бо можна зробити повноцінний цикл, який читає інструкції з пам’яті та виконує, як справжній CPU.

Не забудь написати "дяка"

0

40

Єсть! Ось як виглядатимуть прості **`PUSH`** і **`POP`** в стилі твоєї моделі — пам'ять+регістри в RAM. А щоб не задихатись від повторень — використаємо **макроси**, які FASM просто обожнює (ну або терпить мовчки).

---

### **Оголошення регістрів та стеку** (для нагадування)

код:

```asm
; Стековий вказівник у словах (2 байти)
RpSP    equ 4      ; регістр SP
StackTop equ SizeRAMBytes - 1  ; вершина стеку (можеш зсунути куди зручно)
```

Перед використанням PUSH/POP треба ініціалізувати SP, наприклад:

```asm
mov word [RAM + RpSP*2], StackTop
```

---

### **Макрос PUSH_REG і POP_REG**

код:

```asm
; PUSH_REG <реєстр>
macro PUSH_REG reg_off {
    ; зменшити SP
    mov ax, [RAM + RpSP*2]
    sub ax, 1
    mov [RAM + RpSP*2], ax
    ; записати байт
    mov bl, [RAM + reg_off]
    mov [RAM + ax], bl
}

; POP_REG <реєстр>
macro POP_REG reg_off {
    ; зняти байт
    mov ax, [RAM + RpSP*2]
    mov bl, [RAM + ax]
    mov [RAM + reg_off], bl
    ; збільшити SP
    inc ax
    mov [RAM + RpSP*2], ax
}
```

---

### **Використання:**

код:

```asm
    PUSH_REG RgA      ; зберегти регістр A
    PUSH_REG RgB      ; зберегти регістр B

    POP_REG RgB       ; відновити B
    POP_REG RgA       ; відновити A
```

---

### **Примітка**

Це PUSH/POP на **1 байт**. Якщо хочеш `PUSH RpHL`, тобто word (2 байти) — зроблю макрос `PUSH_WORD` / `POP_WORD`.

---

Хочеш — зроблю ще версії `PUSHW` і `POPW` для пар регістрів (наприклад, `RpHL`, `RpBC`). 
Також можемо прикрутити прапори Z, C і т. д. у майбутньому!

Не забудь написати "дяка"

0

Быстрый ответ

Напишите ваше сообщение и нажмите «Отправить»



Вы здесь » EnotVM » Тестовый форум » 08 БИТ