# 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`