Code: Select all
DATA " The sine and the sin !!! "
DATA " (CL) 2008-Oct-20 by DOS386 "
REM Compile with FreeBASIC 0.20 or newer
'' ########## JUNK DEFINE'S ##########
#define incv(A) A=A+1
#define decv(A) A=A-1
#define addv(A,B) A=A+B
#define subv(A,B) A=A-B
#define CALLSUB
type UINT64 as ULONGINT
type UINT32 as UINTEGER
type UINT8 as UBYTE
type PUINT8P as UBYTE PTR
'' ########## GLOBAL DIM'S ##########
DIM AS STRING QQ
DIM AS UINT32 RR32, SS32, TT32
DIM AS UINT8 AA8
DIM AS PUINT8P ZZ
'' ########## SUB'S ##########
SUB PLOT (BYVAL XX AS UINT32, BYVAL YY AS UINT32)
PSET (XX,YY)
PSET (XX-1,YY+1)
PSET (XX-1,YY-1)
PSET (XX,YY+1)
PSET (XX,YY-1)
PSET (XX-1,YY)
PSET (XX+1,YY)
PSET (XX+1,YY-1)
PSET (XX+1,YY+1)
END SUB '' PLOT
'' ########## MAIN ##########
'' Welcome junk, hog memory
? : READ QQ : ? QQ : READ QQ : ? QQ : SLEEP 800
ZZ=ALLOCATE(256)
IF (ZZ=0) THEN ASM INT3 '' Everything can fail :-(
RR32=CAST(UINT32,ZZ)
ASM
'' The cheapest sine in the universe: 66 bytes, 8080-compatible !!!
'' Brews output sine table of 256 values
'' 0 represents "sin(0)=0"
'' 255 represents "sin(90)=1" , not "sin(89.xxx)=0.999yyy"
mov edi, [RR32]
call ww0
'' ------
'' Magic input sine table: 32 values covering output indexes 1 to 255
'' Index 0 NOT included, one bit is wasted at table END
.byte 171,86,171,85,106,170,170,169,84,165,37,36,72,136,130,8
.byte 1,31,251,255,125,238,237,181,171,82,169,36,136,132,8,0
ww0: pop esi '' Hot stuff must get POPE'd
xor ebx, ebx '' ZERO'ize BL and BH
'' AL is picked input byte, temporarily also output byte as BL
'' BL is output value, grows non linearilly from 0 to 255
'' BH is output index, increments from 0 to 255
ww1: xchg al, bl
stosb '' Write
xchg al, bl
test bh, 7 '' Lowest 3 bits
jnz ww2 '' Don't pick byte
lodsb '' Pick byte
ww2: inc bh
jz ww3 '' Done !
shl al, 1 '' Pick bit
adc bl, 0 '' Add one (or ZERO ???)
cmp bh, 140 '' BH >?= 140 ??? JAE=JNB=JNC
adc bl, 0 '' Add one (or ZERO ???)
jmp short ww1 '' 256 passes
'' ------------
ww3: '' Imaginary NOPE here :-D
END ASM
'' Set mode
SCREENRES 800,600,32
IF (SCREENPTR=0) THEN ASM INT3 '' Everything can fail :-(
PAINT (0,0),RGB(40,80,120) '' Sort of blue
SLEEP 2400
'' Draw box + line
'' 800-510 = 290 | 290/2 = 145 | 799-145 = 654
'' 600-510 = 90 | 90/2 = 45 | 599- 45 = 554 or 555 ...
COLOR RGB(255,255,255)
LINE (145,45)-(654,555),,B '' Omit color
LINE (144,44)-(655,556),,B '' Omit color
LINE (654,300)-(145,300)
'' Draw red sinusoid, shrink horizontal size by 2
COLOR RGB(200,150,100)
SS32=0 '' Runs from 0 to 255
DO
AA8=PEEK(RR32+SS32) : TT32=CAST(UINT32,AA8)
CALLSUB PLOT (145+(SS32 SHR 1),300-TT32)
CALLSUB PLOT (399-(SS32 SHR 1),300-TT32)
CALLSUB PLOT (400+(SS32 SHR 1),300+TT32)
CALLSUB PLOT (654-(SS32 SHR 1),300+TT32)
IF (SS32=255) THEN EXIT DO
incv(SS32)
LOOP
'' Draw green sinusoid, shrink vertical size by 2
COLOR RGB(50,200,100)
SS32=0 '' Runs from 0 to 255
DO
AA8=PEEK(RR32+SS32) SHR 1 : TT32=CAST(UINT32,AA8)
CALLSUB PLOT (145+SS32,300-TT32)
CALLSUB PLOT (654-SS32,300-TT32)
IF (SS32=255) THEN EXIT DO
incv(SS32)
LOOP
'' Wait keypress, give up
SLEEP : SCREEN 0 : ? : ? QQ : ?
END