/* * p1_sys.c — отсутствующие в libc сырые ESTEX wrappers для проб P1. * * ABI SDCC __sdcccall(1): int возвращается в DE, uint8_t — в A. Каждый RST * сохраняет IX, потому что IX callee-saved. Ошибка ESTEX (CF=1, код в A) * проходит через общий libc-хелпер __errno_set. */ #include #include "p1_platform.h" uint8_t p1_exec_exit_code; /* ESTEX DSKINFO $03: * A=disk (0xFF=current) * out: A=sectors/cluster, HL=total clusters, * DE=free clusters, BC=bytes/sector. */ int p1_disk_info(uint8_t disk, P1DiskInfo *out) __naked { (void)disk; (void)out; __asm ;; A = disk, DE = out. push ix push de ld c, #0x03 rst #0x10 jr c, _p1_di_error ;; Забрать out в IX, пока все выходные регистры DSS ещё целы. pop ix ld 0 (ix), a ld 1 (ix), l ld 2 (ix), h ld 3 (ix), e ld 4 (ix), d ld 5 (ix), c ld 6 (ix), b pop ix ld de, #0 ret _p1_di_error: pop de ; снять сохранённый out pop ix call __errno_set ld de, #-1 ret __endasm; } /* ESTEX EXEC $40. path_mode: 0 — короткое имя/PATH, 1 — передан путь. * На успехе код дочерней программы сохраняется в p1_exec_exit_code. */ int p1_exec(uint8_t path_mode, const char *path) __naked { (void)path_mode; (void)path; __asm ;; A = path_mode, DE = path. Такой порядок не оставляет 8-битный ;; второй аргумент на стеке в ABI SDCC. push ix ld b, a ex de, hl ld c, #0x40 rst #0x10 pop ix jr c, _p1_exec_error ld (_p1_exec_exit_code), a ld de, #0 ret _p1_exec_error: call __errno_set ld de, #-1 ret __endasm; } /* ESTEX WAIT $42 возвращает код последней завершившейся программы в A. */ uint8_t p1_wait_code(void) __naked { __asm push ix ld c, #0x42 rst #0x10 pop ix ret __endasm; } /* ESTEX WINREST $5A: * D=row, E=col, H=height, L=width, B=physical page, * IX=0xC000+offset. * * Раскладка аргументов подтверждена существующим tests/winrest и mdview2: * A=row, L=col, стек +2 height, +3 width, +4 page, +5..6 offset. */ void p1_winrest(uint8_t row, uint8_t col, uint8_t height, uint8_t width, uint8_t page, uint16_t offset) __naked { (void)row; (void)col; (void)height; (void)width; (void)page; (void)offset; __asm ld iy, #2 add iy, sp ld d, a ld e, l push ix ld l, 3 (iy) ld h, 4 (iy) ld bc, #0xC000 add hl, bc push hl pop ix ld h, 0 (iy) ld a, 1 (iy) ld l, a ld a, 2 (iy) ld b, a ld c, #0x5A di rst #0x10 ei pop ix ;; Снять 5 стековых байтов height,width,page,offset. pop hl inc sp inc sp inc sp inc sp inc sp jp (hl) __endasm; }