libbgi: переворот экрана акселератором (gfx_copy_page + _bgi_flip_rows_raw)

Первый шаг L9-INVERT.  Разведка железа закрыта экспериментом: Port_Y можно
менять между read- и write-триггером, если перед вторым OUT стоит STOP —
приём уже был в проде в _bgi_scroll_cols_raw (указал пользователь), так что
обходной путь через ОЗУ-буфер не понадобился.

- _bgi_flip_rows_raw: построчная копия video->video с реверсом Port_Y
  приёмника (DI/EI бандами по 16 строк, размер блока армируется в каждой
  скобке, убывающий y1 держится SMC-ячейкой);
- gfx_copy_page(area, GFX_COPY_DIRECT|GFX_COPY_VFLIP): копия области из
  неактивной страницы в активную; банк 0x50, то есть приёмник обновляется и
  в VRAM, и в ОЗУ-копии — иначе heal восстанавливал бы старый фон;
- tests/pageflip: 5/5 PASS в MAME (прямая, vflip, рамка, широкая 320 двумя
  проходами, источник цел).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-12 16:38:10 +03:00
parent 52b43b3d81
commit 7fe4c25ad1
8 changed files with 454 additions and 1 deletions
+11
View File
@@ -320,4 +320,15 @@ typedef struct {
void gfx_scroll_h(const gfx_rect_t *area, int16_t dx, gfx_rect_t *dirty);
void gfx_scroll_v(const gfx_rect_t *area, int16_t dy, gfx_rect_t *dirty);
/* Копия области из НЕактивной страницы в активную: прямая или с
* ПЕРЕВОРОТОМ ПО ВЕРТИКАЛИ (строка area->y + i -> area->y + h - 1 - i).
* Банк на время копии — 0x50, то есть приёмник обновляется И в VRAM, и в
* ОЗУ-копии (иначе heal целевой страницы восстанавливал бы старый фон).
* Источником служит ОЗУ-копия, поэтому переносится ЧИСТЫЙ фон — спрайты,
* нарисованные банком без тени, не копируются.
* Горизонтального зеркала нет: accel копирует блок только вперёд. */
#define GFX_COPY_DIRECT 0
#define GFX_COPY_VFLIP 1
void gfx_copy_page(const gfx_rect_t *area, uint8_t mode);
#endif