program AcidFX; {$N+} uses Dos, Crt, Graph; var DefInt8: Pointer; Tick: Word; { Процедура обработки Int 8 (IRQ0) } procedure Int8; interrupt; begin Inc(Tick); if Tick and 3 = 0 then asm pushf { вызов стандартного обработчика каждый 4 тик } call DefInt8 end else asm mov al,20h { сброс PIC } out 20h,al end; end; { Инициализация таймера } procedure InitTimer; begin GetIntVec(8, DefInt8); SetIntVec(8, @Int8); Port[$43] := $36; { режим работы: канал 0 - генератор меандера } Port[$40] := $40; { младший байт коэффициента деления канала 0 } Port[$40] := 0; { младший байт коэффициента деления канала 0 } { частота таймера ~= 72.83 Гц - в 4 раза выше стандартной } end; { Финализация таймера } procedure DoneTimer; begin SetIntVec(8, DefInt8); Port[$43] := $36; Port[$40] := 0; Port[$40] := 0; end; const MaxRadius = 100; const gd: Integer = EGA; gm: Integer = EGAHI; var nt: Word; Page, ym, xm, x, y, r, dr, k1, k2, k3: Integer; a, k: Double; procedure SetCoef; begin k1 := 1 + Random(20); k2 := 1 + Random(20); k3 := 1 + Random(20); end; begin Randomize; InitGraph(gd, gm, 'd:\lang\bp\bgi'); InitTimer; xm := GetMaxX; ym := GetMaxY; Page := 0; a := 0; r := 0; dr := 1; SetCoef; repeat nt := Tick + 1; SetActivePage(Page); Page := Page xor 1; SetVisualPage(Page); ClearViewport; x := MaxRadius; while x < xm - MaxRadius do begin k := x / xm; y := MaxRadius + Round(Sin(a + k1 * k) * r); MoveTo(x + Round(Sin(a + k2 * k) * r), y); LineTo(x + Round(Cos(a + k3 * k) * r), ym - y); Inc(x, 16); end; Inc(r, dr); if r < 0 then begin r := 0; dr := 1; SetCoef; end else if r > MaxRadius then begin r := MaxRadius; dr := -1; end; a := a + 0.1; while Tick < nt do; until KeyPressed; ReadKey; DoneTimer; CloseGraph; end.