Add full compiler toolchain, libc, examples and reference docs
First substantive commit: the entire Sprinter C compiler tree on top of
the bare README+gitignore initial commit.
What's in here:
bin/sprinter-cc — driver script invoking SDCC + linker + mkexe
libc/ — Sprinter-specific libc layer over ESTEX/BIOS
(conio, gfx, io, mem, stdio + headers)
runtime/ — crt0 variants (default/small/banked/minimal)
+ heap + bank trampolines
toolchain/ — mkexe (SprintEXE packer, C + tests)
examples/ — 30 demo programs (gfx, file I/O, env, time, …)
lib/Makefile — builds the libc archive (sprinter.lib)
docs/ — converted Sprinter manuals + asm reference samples
third_party/ — solid-c reference compiler dump + sdcc setup script
release_docs/ — packaging / release notes
gitignore overhaul:
• Drop dangerous blanket patterns: *.asm (would hide docs/samples/*.asm)
and *.exe (case-insensitive match was hiding third_party/solid-c/*.EXE
on macOS APFS). Replaced with examples/*/*.{asm,exe,…} and lib/*.lib.
• Restore tracking of toolchain/mkexe/tests/{one,big}.bin — those are
INPUT fixtures, not build outputs.
• Collapse the duplicated SDCC/C/Sdcc sections into one section per
concern (build outputs / vendored / OS-junk).
• Add .sprinter-cc-*/, build/ (catches lib/build/ too), .claude/.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Executable
+308
@@ -0,0 +1,308 @@
|
||||
|
||||
PAGE_0: equ 82h ; порт 0 окна = addr 0000h
|
||||
PAGE_1: equ 0A2h ; порт 1 окна = 4000h
|
||||
PAGE_2: equ 0C2h ; порт 2 окна = 8000h
|
||||
PAGE_3: equ 0E2h ; порт 3 окна = 0c000h
|
||||
|
||||
SIO_CONTROL_A: EQU 19h
|
||||
SIO_DATA_REG_A: EQU 18h
|
||||
SIO_CONTROL_B: EQU 1Bh
|
||||
SIO_DATA_REG_B: EQU 1Ah
|
||||
CTC_CH0: equ 10h
|
||||
CTC_CH1: equ 11h
|
||||
CTC_CH2: equ 12h
|
||||
CTC_CH3: equ 13h
|
||||
|
||||
RGMOD equ 0c9h
|
||||
|
||||
; ....
|
||||
|
||||
; Запомним текущий видео-режим
|
||||
LD C, DSS.GetVMod
|
||||
RST 10h
|
||||
LD HL, GetVMod_Error_Message
|
||||
;JR C, PutError
|
||||
LD C, A
|
||||
LD (.Current_VMod), BC
|
||||
|
||||
; Запрос памяти
|
||||
|
||||
; сохраним текущие значения страниц
|
||||
IN A, (PAGE_1)
|
||||
LD (SavePage1), A
|
||||
IN A, (PAGE_3)
|
||||
LD (SavePage3), A
|
||||
|
||||
; Настройка прерываний CTC и SIO
|
||||
LD HL, IM2_Empty : LD (0FDFFh), HL
|
||||
|
||||
LD (0FD10h), hl
|
||||
LD (0FD12h), hl
|
||||
LD (0FD14h), hl
|
||||
LD (0FD16h), hl
|
||||
LD (0FD18h), hl
|
||||
LD (0FD1Ah), hl
|
||||
LD (0FD1Ch), hl
|
||||
LD (0FD1Eh), hl
|
||||
|
||||
LD HL, IM2_VShandler : LD (0FD06h), HL
|
||||
|
||||
LD A, I
|
||||
LD (.SaveInterrupt), A
|
||||
LD A, 0FDh
|
||||
DI
|
||||
LD I, A
|
||||
IM 2
|
||||
|
||||
.Sync:
|
||||
EI
|
||||
HALT
|
||||
DI
|
||||
IN A, (SIO_CONTROL_A)
|
||||
BIT 0, A ; 0-bit, байт пришел ?
|
||||
JR Z, .EndSync ; да, это прерывание от клавиатуры
|
||||
CALL Keyboard.PS2_Scan
|
||||
JR .Sync
|
||||
.EndSync:
|
||||
|
||||
LD B, 5
|
||||
.loopSync:
|
||||
DJNZ .loopSync
|
||||
|
||||
; Настройка CTC
|
||||
LD A, 057h : OUT (CTC_CH2), A
|
||||
LD A, 112 : OUT (CTC_CH2), A
|
||||
LD A, 0d7h : OUT (CTC_CH3), A
|
||||
LD A, 160 : OUT (CTC_CH3), A
|
||||
LD A, 0 : OUT (CTC_CH0), A
|
||||
|
||||
; Настройка SIO
|
||||
LD A, 1 : OUT (SIO_CONTROL_A), A
|
||||
LD A, 18h : OUT (SIO_CONTROL_A), A
|
||||
LD A, 2 : OUT (SIO_CONTROL_B), A
|
||||
LD A, 10h : OUT (SIO_CONTROL_B), A
|
||||
|
||||
LD HL, IM2_Keyhandler
|
||||
LD (0FDFFh), HL
|
||||
|
||||
LD (0FD10h), hl
|
||||
LD (0FD12h), hl
|
||||
LD (0FD14h), hl
|
||||
LD (0FD16h), hl
|
||||
LD (0FD18h), hl
|
||||
LD (0FD1Ah), hl
|
||||
LD (0FD1Ch), hl
|
||||
LD (0FD1Eh), hl
|
||||
|
||||
|
||||
Loop:
|
||||
; основаной цикл
|
||||
; ................
|
||||
|
||||
LD A, (Keyboard.KeyFlags)
|
||||
BIT 7, A
|
||||
JR NZ, .Key_ESC
|
||||
|
||||
|
||||
JP Loop
|
||||
|
||||
.Key_ESC: ; Выход
|
||||
|
||||
DI
|
||||
; Восстановим прерывания и CTC
|
||||
LD A, 057h : OUT (CTC_CH3), A
|
||||
LD A, 160 : OUT (CTC_CH3), A
|
||||
|
||||
; Восстановим SIO
|
||||
LD A, 1 : OUT (SIO_CONTROL_A), A
|
||||
LD A, 0 : OUT (SIO_CONTROL_A), A
|
||||
LD A, 2 : OUT (SIO_CONTROL_B), A
|
||||
LD A, 10h : OUT (SIO_CONTROL_B), A
|
||||
|
||||
.SaveInterrupt+*: LD A, 0
|
||||
LD I, A
|
||||
IM 1
|
||||
EI
|
||||
|
||||
CALL Keyboard.PS2_Clear_Buf
|
||||
|
||||
; Восстанавливаем страницы памяти
|
||||
LD A,(SavePage1)
|
||||
OUT (PAGE_1), A
|
||||
LD A,(SavePage3)
|
||||
OUT (PAGE_3), A
|
||||
|
||||
; Освободим память запрошенную память
|
||||
|
||||
; возвращаем текстовый режим
|
||||
.Current_VMod+*: LD BC, 0
|
||||
LD A, C
|
||||
LD C, DSS.SetVMod
|
||||
RST 10h
|
||||
|
||||
.Exit:
|
||||
.ExitCode+*: LD B, 0
|
||||
LD C, DSS.Exit
|
||||
RST 10h
|
||||
JR $
|
||||
|
||||
UpdateMechanics:
|
||||
LD A, (Keyboard.KeyFlags)
|
||||
OR A
|
||||
RET Z
|
||||
BIT 3, A
|
||||
JR NZ, .Key_UP
|
||||
BIT 2, A
|
||||
JR NZ, .Key_DOWN
|
||||
RET
|
||||
|
||||
.Key_DOWN:
|
||||
; ...
|
||||
.Key_UP:
|
||||
; ...
|
||||
RET
|
||||
|
||||
|
||||
IM2_Empty:
|
||||
EI
|
||||
RETI
|
||||
|
||||
IM2_Keyhandler:
|
||||
PUSH AF, BC, DE, HL
|
||||
EXX
|
||||
EX AF, AF
|
||||
PUSH AF, BC, DE, HL, IX, IY
|
||||
IN A, (SIO_CONTROL_A)
|
||||
BIT 0, A ; 0-bit, байт пришел ?
|
||||
CALL NZ, Keyboard.PS2_Scan ; да, это прерывание от клавиатуры
|
||||
.SkipClearKeyFlags:
|
||||
POP IY, IX, HL, DE, BC, AF
|
||||
EX AF, AF
|
||||
EXX
|
||||
POP HL, DE, BC, AF
|
||||
EI
|
||||
RETI
|
||||
|
||||
IM2_VShandler:
|
||||
PUSH AF, BC, DE, HL
|
||||
EXX
|
||||
EX AF, AF
|
||||
PUSH AF, BC, DE, HL, IX, IY
|
||||
|
||||
.NeedChangePage+*: LD A, 0 ; 1 - нужно переключить экран
|
||||
OR A
|
||||
JR Z, .skip
|
||||
|
||||
.NumberScreen+*: LD B, 0 ; 0/1 - номер экрана, который в данный момент выводится
|
||||
; Переключаем экран
|
||||
IN A, (RGMOD)
|
||||
AND 0feh
|
||||
OR B
|
||||
XOR 1
|
||||
OUT (RGMOD), A
|
||||
AND 1
|
||||
LD (.NumberScreen), A
|
||||
|
||||
XOR A
|
||||
LD (.NeedChangePage), A
|
||||
.skip:
|
||||
CALL UpdateMechanics ; Возможно нужно перенести из прерывания
|
||||
|
||||
; Расчет FPS
|
||||
; ..........
|
||||
|
||||
POP IY, IX, HL, DE, BC, AF
|
||||
EX AF, AF
|
||||
EXX
|
||||
POP HL, DE, BC, AF
|
||||
EI
|
||||
RETI
|
||||
|
||||
; очистка буфера клавиатуры
|
||||
; Портит регистры AF
|
||||
Keyboard.PS2_Clear_Buf:
|
||||
IN a, (SIO_CONTROL_A)
|
||||
BIT 0, a
|
||||
RET Z
|
||||
IN A, (SIO_DATA_REG_A)
|
||||
JR PS2_Clear_Buf
|
||||
|
||||
; Из PS/2 возвращает в Keyboard.KeyFlags нажатые клавиши:
|
||||
; бит кнопка
|
||||
; 0 - RIGHT
|
||||
; 1 - LEFT
|
||||
; 2 - DOWN
|
||||
; 3 - UP
|
||||
; 4 - SPACE
|
||||
; 5 - none
|
||||
; 6 - ENTER
|
||||
; 7 - ESC
|
||||
; Портит регистры AF, BC, DE, HL
|
||||
Keyboard.PS2_Scan:
|
||||
LD HL, .KeyStatus
|
||||
LD DE, 0c686h ; D - код команды SET 0, (HL) / E - код команды RES 0, (HL)
|
||||
.Loop
|
||||
IN a, (SIO_CONTROL_A)
|
||||
BIT 0, a
|
||||
RET Z
|
||||
IN A, (SIO_DATA_REG_A)
|
||||
CP 0E0h
|
||||
JR NZ, .kh1
|
||||
SET 7, (HL) ; // двойной сканкод
|
||||
JR .Loop
|
||||
|
||||
.kh1:
|
||||
CP 0F0h
|
||||
JR NZ, .kh2
|
||||
SET 6, (HL) ; // отпускание клавиши
|
||||
JR .Loop
|
||||
|
||||
.kh2:
|
||||
BIT 7, A ; автоповтор?
|
||||
JR Z, .kh3
|
||||
LD (HL), 0
|
||||
JR .Loop
|
||||
|
||||
.kh3:
|
||||
LD B, 8
|
||||
BIT 6, (HL)
|
||||
LD C, D ; С - код команды SET 0, (HL)
|
||||
JR Z, .KeyPress
|
||||
.KeyRelease:
|
||||
LD C, E ; С - код команды RES 0, (HL)
|
||||
.KeyPress:
|
||||
LD (HL), 0
|
||||
PUSH HL
|
||||
INC HL
|
||||
.KeyPressLoop:
|
||||
CP (HL)
|
||||
JR Z, .SetKey
|
||||
INC HL
|
||||
DJNZ .KeyPressLoop
|
||||
POP HL
|
||||
JR .Loop
|
||||
.SetKey:
|
||||
LD A, B
|
||||
DEC A
|
||||
CPL
|
||||
RLA
|
||||
RLA
|
||||
RLA
|
||||
AND 00111000b
|
||||
OR C
|
||||
LD (.CodeSet + 1), A ; Изменяем команду по .CodeSet
|
||||
POP HL
|
||||
DEC HL
|
||||
.CodeSet: SET 0, (HL)
|
||||
INC HL
|
||||
JR .Loop
|
||||
|
||||
.KeyFlags: DB 0
|
||||
.KeyStatus: DB 0
|
||||
.KeysArray: DB 74h, 6bh, 72h, 75h, 29h, 00h, 5ah, 76h
|
||||
|
||||
Keyboard.KeyFlags: EQU .KeyFlags
|
||||
|
||||
SavePage1: DB 0
|
||||
SavePage3: DB 0
|
||||
|
||||
Reference in New Issue
Block a user