64ce6339eb
- docs/new/ — сводные справочники (архитектура, BIOS, DSS, память, графика, акселератор, IRQ, порты, ввод, звук, известные баги); - docs/Original/ — первоисточники, из которых они собраны (BIOS, Estex DSS, мануалы, описание акселератора), + Форум.doc/.docx в reference; - libbgi/common/gfx_scroll_h.c — обход бага скролла при ширине >256 (правка автора: шаг банды 255 и продвижение указателей на cw; старый вариант с 256 оставлен закомментированным с TODO); - удалён applications/PoP/roomtest/hang_variants.png — рабочая раскладка из разбора позы виса, в репозитории ей не место. Большие архивы (docs/extra ~568 МБ, docs/sources с вложенными git-репо ~68 МБ) в коммит НЕ включены — см. обсуждение. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
198 lines
8.5 KiB
Markdown
198 lines
8.5 KiB
Markdown
# 8. Ввод-вывод
|
||
|
||
## 8.1 Клавиатура и мышь
|
||
|
||
Клавиатура и мышь вынесены в отдельный документ: `09-input.md`.
|
||
|
||
Сводная информация по портам и прерываниям — `09-input.md §§9.1–9.6`.
|
||
|
||
## 8.2 Звук
|
||
|
||
Звуковая подсистема (AY-3-8910, COVOX, COVOX-Blaster, бипер) вынесена
|
||
в отдельный документ: `10-sound.md`.
|
||
|
||
Сводная карта звуковых портов: `11-ports.md §11.6`.
|
||
|
||
## 8.3 Дисковая подсистема
|
||
|
||
### 8.3.1 FDD (WD1793 / КР1818ВГ93)
|
||
|
||
Контроллер дисковода — стандартный Beta Disk Interface (WD1793).
|
||
Аппаратное перенаправление `#1F → #0F` (см. §8.4).
|
||
|
||
**Регистры (по данным MAME sprinter.cpp):**
|
||
|
||
| Z80-адрес | Регистр |
|
||
|-----------|---------|
|
||
| `#0F` | Status (чт) / Command (зп) |
|
||
| `#1F` | —//— (аппаратный ремап на `#0F`) |
|
||
| `#3F` | Track |
|
||
| `#5F` | Sector |
|
||
| `#7F` | Data |
|
||
| `#FF` | Drive Control (выбор дисковода) |
|
||
|
||
**Противоречие: адресация регистров ВГ93.**
|
||
> - [IvanMak.txt:1270–1274]: 4 регистра + `#FF` — управление дисководом.
|
||
> - [Parinov.txt:963]: 3 регистра (data-регистр `#7F` пропущен).
|
||
>
|
||
> MAME реализует полный набор по IvanMak: Status/Command (`#0F`), Track (`#3F`),
|
||
> Sector (`#5F`), Data (`#7F`). Data-регистр важен — через него читаются/пишутся
|
||
> сектора. Parinov, вероятно, упустил его.
|
||
|
||
**Turbo-режим FDD (DCP 0x16/0x17, биты):**
|
||
- Бит 0 = скорость (0=норм, 1=турбо)
|
||
- Бит 1 = отключение FDD [sprinter.cpp:914–920]
|
||
|
||
### 8.3.2 HDD (IDE/ATA)
|
||
|
||
Два ATA-интерфейса: первичный и вторичный. Доступ — через DCP-декодер
|
||
(внутренние коды 0x20–0x2b).
|
||
|
||
**Регистры ATA CS0 (по sprinter.cpp):**
|
||
|
||
| DCP код | Z80-адрес (старш.) | Регистр |
|
||
|---------|-------------------|---------|
|
||
| 0x20 | `#xx50` | Data (16-bit через защёлку байтов) |
|
||
| 0x21 | `#xx51` | Error (чт) / Features (зп) |
|
||
| 0x22 | `#xx52` | Sector Count |
|
||
| 0x23 | `#xx53` | Sector Number |
|
||
| 0x24 | `#xx54` | Cylinder Low |
|
||
| 0x25 | `#xx55` | Cylinder High |
|
||
| 0x26 | `#xx56` | Device/Head |
|
||
| 0x27 | `#xx57` | Status (чт) / Command (зп) |
|
||
| 0x28 | `#xx58` | Alt Status (чт) / Device Control (зп) (CS1) |
|
||
| 0x2a | HDD1 select (вторичный) |
|
||
| 0x2b | HDD2 select (первичный) |
|
||
|
||
**16-битный data-порт:** MAME реализует защёлку байтов: чтение `#xx50`
|
||
возвращает младший байт (bit8=0), затем старший (bit8=1) [sprinter.cpp:958–972].
|
||
|
||
**Противоречие: HDD — разные адреса для чтения и записи.**
|
||
> - [IvanMak.txt:1366]: кратко: «#xx50..#xx55 – порты HDD»
|
||
> - [Parinov.txt:958–959]: таблица с разными адресами для R/W:
|
||
> `0050h` (чт) / `0150h` (зп) — data, `4053h` (чт) / `4153h` (зп) — status/command.
|
||
>
|
||
> MAME использует единую карту DCP-кодов (0x20–0x28) без разделения R/W.
|
||
> Parinov описывает реальное поведение на Sprinter-2, где адресная линия A8
|
||
> управляет направлением — это внешняя особенность конкретной ППЛМ-прошивки.
|
||
> IvanMak упрощает до базовых DCP-кодов.
|
||
|
||
Доступ к IDE открыт в режиме Sprinter-ZX, в режимах Pentagon/Scorpion — закрыт.
|
||
|
||
### 8.3.3 CMOS (Dallas DS12887A)
|
||
|
||
Микросхема DS12887A (RTC + 114 байт NV RAM). Совместима с MC146818A.
|
||
Доступ через DCP-коды 0x1c–0x1e.
|
||
|
||
| Z80-адрес | DCP код | Функция |
|
||
|-----------|---------|---------|
|
||
| `#DFBD` | 0x1d | Запись адреса регистра CMOS |
|
||
| `#FFBD` | 0x1c | Чтение данных из выбранного регистра |
|
||
| `#BFBD` | 0x1e | Запись данных в выбранный регистр |
|
||
|
||
При отсутствии микросхемы CMOS эмулируется BIOS [BIOS_v3.txt:308–310].
|
||
|
||
**Карта регистров RTC (совместимо с MC146818A):**
|
||
|
||
| Рег. | Назначение | Формат |
|
||
|------|-----------|--------|
|
||
| 0x00 | Секунды | BCD |
|
||
| 0x01 | Секунды (будильник) | BCD |
|
||
| 0x02 | Минуты | BCD |
|
||
| 0x03 | Минуты (будильник) | BCD |
|
||
| 0x04 | Часы | BCD |
|
||
| 0x05 | Часы (будильник) | BCD |
|
||
| 0x06 | День недели (1=воскресенье) | BCD |
|
||
| 0x07 | Число | BCD |
|
||
| 0x08 | Месяц | BCD |
|
||
| 0x09 | Год | BCD |
|
||
| 0x0a | Регистр A (UIP, divider, rate) | биты |
|
||
| 0x0b | Регистр B (SET, PIE, AIE, UIE, SQWE, DM, 24/12, DSE) | биты |
|
||
| 0x0c | Регистр C (IRQF, PF, AF, UF) | биты (чт) |
|
||
| 0x0d | Регистр D (VRT) | биты (чт) |
|
||
| 0x0e–0x7f | 114 байт NV RAM | пользовательские |
|
||
|
||
---
|
||
|
||
## 8.4 Джойстик
|
||
|
||
**Два Kempston-совместимых джойстика** [sprinter.cpp:1106–1175]:
|
||
|
||
- **JOY1** — через CIO_DTRB (DCP 0x15, совмещён с Beta state при чтении)
|
||
- **JOY2** — через PIO PB
|
||
|
||
**Формат данных (Kempston):**
|
||
|
||
| Бит | Кнопка |
|
||
|:---:|--------|
|
||
| 0 | Вправо |
|
||
| 1 | Влево |
|
||
| 2 | Вниз |
|
||
| 3 | Вверх |
|
||
| 4 | Fire |
|
||
| 5 | — |
|
||
| 6 | — |
|
||
| 7 | — |
|
||
|
||
**Противоречие: джойстик #1F vs #0F.**
|
||
> - [IvanMak.txt:1344]: «#1F,#0F — RD_KEMPS — порт джойстика.
|
||
> В Sprinter-1 порт #1F аппаратно переадресуется на порт #0F.»
|
||
> - [IvanMak.txt:861–868]: команды `OUT (#1F),A` не срабатывают
|
||
> из-за перенаправления. Надо использовать `LD BC,#1F : OUT (C),A`.
|
||
>
|
||
> В Sprinter-1 включено аппаратное перенаправление `#1F → #0F`,
|
||
> из-за чего `IN A,(#1F)` не читает джойстик. MAME подтверждает:
|
||
> на Sp2000 (`m_cnf` bit 0) перенаправление отключается
|
||
> [sprinter.cpp:1106]. Ремап действует только на запись: при OUT
|
||
> порт `#1F` маппится на `#0F` через DCP [sprinter.cpp:1080].
|
||
|
||
JOY2 читается через PIO port A [sprinter.cpp:1136–1140].
|
||
|
||
---
|
||
|
||
## 8.5 Параллельный порт (принтер)
|
||
|
||
Centronics-совместимый через ППЛМ. BIOS-функции печати: 082h–08Ch
|
||
(см. `02-bios.md`).
|
||
|
||
---
|
||
|
||
## 8.6 Шина ISA
|
||
|
||
Два 8-битных ISA-слота на частоте X_SP/5 (~7 МГц). Доступ — через
|
||
DCP-декодер и страницы памяти.
|
||
|
||
**Управляющие порты ISA (DCP 0xD0–0xDF, 0xF8–0xFF):**
|
||
|
||
| Бит | Назначение |
|
||
|:---:|-----------|
|
||
| 2 | 0 = ISA memory access, 1 = ISA I/O access |
|
||
| 1 | Выбор слота (0 = slot 0, 1 = slot 1) |
|
||
|
||
Адресное расширение: `m_isa_addr_ext` (запись через DCP 0x1b) — биты
|
||
расширения адреса для ISA-циклов [sprinter.cpp:1032–1039].
|
||
|
||
**Memory-маппинг ISA:** При pg3 & 0xF9 == 0xD0 (бит 10 окна W3 = 1,
|
||
BANK_ISA_MASK) обращения к окну W3 (`#C000–#FFFF`) направляются на ISA-шину
|
||
вместо RAM [sprinter.cpp:178–181, 530–532]. Длина — 16 КБ.
|
||
|
||
**I/O-доступ к ISA:** через тот же DCP-декодер. Устройства устанавливают
|
||
сигнал `m_io_input_wait` = true при совпадении адреса.
|
||
|
||
> **Примечание:** В MAME есть TODO: «ISA memory slots» — ISA memory-циклы
|
||
> пока не эмулируются [sprinter.cpp:576]. На реальном Sprinter поддержка
|
||
> зависит от прошивки ППЛМ.
|
||
|
||
Слот 0 обычно занят ZX-Bus-адаптером [sprinter.cpp:26].
|
||
|
||
---
|
||
|
||
## 8.7 Кросс-ссылки
|
||
|
||
- BIOS-функции: `02-bios.md`
|
||
- Клавиатура, мышь: `09-input.md`
|
||
- Звук: `10-sound.md`
|
||
- Порты: `11-ports.md`
|
||
- Акселератор: `06-accel.md`
|
||
- Прерывания: `07-irq.md`
|