08 БИТ
08 БИТ
Сообщений 31 страница 40 из 81
Поделиться312025-04-24 22:56:17
О! Генератор випадкових чисел для КР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 — майже як магія квантових бітів!
Не забудь написати "дяка"
Поделиться322025-04-24 22:59:24
Ооо, ти якраз в ціль! Це класика порівнянь: 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 — щось типу "Монитор СМ" чи "ОС ВМ"), але це вже окрема історія.
Якщо хочеш, можу накидати повну таблицю з опкодами та циклами — як у техдоках.
Не забудь написати "дяка"
Поделиться332025-04-24 23:03:34
О-о-о, **тепер пішла серйозна шарманка!**
Бо КР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 молиться ночами**.
Якщо цікаво, я можу зробити таблицю повної відповідності інструкцій між ними (що є у кого, а чого немає).
Не забудь написати "дяка"
Поделиться342025-04-24 23:05:06
Круто! Тоді готуйся до справжньої асемблерної таблиці — я складу повну відповідність інструкцій: що є у обох, а що — лише в Z80. Скоро викладу, буде як настільна шпаргалка для хакера зі стажем.
Не забудь написати "дяка"
Поделиться352025-04-24 23:16:50
Окей, тримай приклад — **віконце з кнопкою** для 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` файл, який запускається прямо в ОС.
**Хочеш більше?** Я можу дати приклад вікна з анімацією, обробкою миші або навіть просту графічну гру!
Не забудь написати "дяка"
Поделиться362025-04-25 07:44:50
О, це ти вже хочеш зібрати "бойовий набір" інструкцій для свого віртуального процесора? Без питань — тримай короткий **набір базових команд**, які зазвичай є в будь-якому повноцінному 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. Звідси можна вже танцювати — у тебе буде арифметика, логіка, умовні стрибки, стек, пам’ять, ввід/вивід і навіть підпрограми.
Хочеш — можу накидати псевдокод, як реалізувати кожну з них у твоєму емуляторі.
Не забудь написати "дяка"
Поделиться372025-04-25 12:29:09
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}
Поделиться382025-04-25 12:34:06
О, це вже серйозна ініціалізація! Дивимось на твій 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.
Не забудь написати "дяка"
Поделиться392025-04-25 12:37:27
Отже, вперед — заводимо перші **базові інструкції** у вигляді 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.
Не забудь написати "дяка"
Поделиться402025-04-25 12:40:02
Єсть! Ось як виглядатимуть прості **`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 і т. д. у майбутньому!
Не забудь написати "дяка"
Быстрый ответ
Похожие темы
| 32 Бита | Тестовый форум | 2025-05-15 |
| ПЕРЕВАЛОЧНА БАЗА ДЛЯ ПОВІДОМЛЕНЬ | Тестовый форум | 2025-05-15 |
| ASM32 (2026) | Тестовый форум | Вчера |