Anyone dares beat this ? SINE 66 bytes only 8080-compatibe

Post your FreeBASIC source, examples, tips and tricks here. Please don’t post code without including an explanation.
Post Reply
DOS386
Posts: 798
Joined: Jul 02, 2005 20:55

Anyone dares beat this ? SINE 66 bytes only 8080-compatibe

Post by DOS386 »

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
My sine calculation core hogs just 66 bytes and uses only 8-bit integer 8080-compatible instructions :-)
marcov
Posts: 3504
Joined: Jun 16, 2005 9:45
Location: Netherlands
Contact:

Re: Anyone dares beat this ? SINE 66 bytes only 8080-compati

Post by marcov »

DOS386 wrote:

Code: Select all


     mov   edi, [RR32]
     Call  ww0
 
...
ww0: pop   esi       '' Hot stuff must get POPE'd
     Xor   ebx, ebx  '' ZER
My sine calculation core hogs just 66 bytes and uses only 8-bit integer 8080-compatible instructions :-)
Never knew a 8080 could do i386 registers.

But I don't use x86 (or predecessors) for embedded work, so it is a challenge I pass on with pleasure.
DOS386
Posts: 798
Joined: Jul 02, 2005 20:55

Re: Anyone dares beat this ? SINE 66 bytes only 8080-compati

Post by DOS386 »

marcov wrote:Never knew a 8080 could do i386 registers.
YES it does :-D ... oops maybe it indeed doesn't, but it's irrelevant here and you are missing the point, since the 32-bit registers in my example are used only for interaction with FB code, and 8 bits are sufficient in my calculation core.
marcov
Posts: 3504
Joined: Jun 16, 2005 9:45
Location: Netherlands
Contact:

Re: Anyone dares beat this ? SINE 66 bytes only 8080-compati

Post by marcov »

DOS386 wrote:
marcov wrote:Never knew a 8080 could do i386 registers.
YES it does :-D ... oops maybe it indeed doesn't, but it's irrelevant here and you are missing the point, since the 32-bit registers in my example are used only for interaction with FB code, and 8 bits are sufficient in my calculation core.
So let me get this clear. The FB parts are not relevant? So what is exactly the relevance of this post to this forum?

/me hauls a bottle of wine, and dances on the grave of all his pre Athlon computers.
relsoft
Posts: 1767
Joined: May 27, 2005 10:34
Location: Philippines
Contact:

Post by relsoft »

Last time I checked FB would only run on a 486 and onwards CPU. What's the point of coding an only 8080 sinegen algo when you still have to use it on a non 8080 processor?

You'd probably use less bytes by using the FPU.

BTW, you don't have to use a table to generate sine values.
Richard
Posts: 3096
Joined: Jan 15, 2007 20:44
Location: Australia

Post by Richard »

@DOS386
So which of the following are rules to this dare / challenge.
1. must only use 8080 instructions.
2. must use a minimum number of bytes.
3. speed is not important.
4. generate first quadrant of sine only.
5. input is a byte representing 0 = 0, 255 = 90.000 degrees ?
6. output is a byte mapped 0 = 0, 255 = 1.000 ?
7. accuracy, output within one lsb of the correct value.
Please be more specific, or do you plan to move the goal posts later?
MichaelW
Posts: 3500
Joined: May 16, 2006 22:34
Location: USA

Post by MichaelW »

What does the “8080-compatible” refer to?
Richard
Posts: 3096
Joined: Jan 15, 2007 20:44
Location: Australia

Post by Richard »

The first 8 bit microprocessor was the Intel 8008, followed soon after by an improvement, the 8080. The 8080 op-codes were then used in the 16 bit 8086 for compatibility with earlier software and on it goes. Those single byte op-codes are in every Pentium today. An 8 bit bus version of the 16bit 8086 processor, called the 8088 was used for the first IBM PC. The Zilog Z80 executed 8080 code plus some extra op-codes of their own. 8080 code still runs on the PC today, only now it runs just a little bit faster.
MichaelW
Posts: 3500
Joined: May 16, 2006 22:34
Location: USA

Post by MichaelW »

The 8080 had a different register set than the 8086/8088.
marcov
Posts: 3504
Joined: Jun 16, 2005 9:45
Location: Netherlands
Contact:

Post by marcov »

MichaelW wrote:The 8080 had a different register set than the 8086/8088.
Now that you mentioned, afaik yes.

(from wikipedia)
Registers
The processor had seven 8-bit registers, (A, B, C, D, E, H, and L) where A was the 8-bit accumulator and the other six could be used as either byte-registers or as three 16-bit register pairs (BC, DE, HL) depending on the particular instruction. Some instructions also enabled HL to be used as (a limited) 16-bit accumulator. It also had a 16-bit stack pointer to memory (replacing the 8008's internal stack), and a 16-bit program counter.
So I think 8088 was meant. And the 8088 afaik has 16-bits regs. It is just not fast with it.
Richard
Posts: 3096
Joined: Jan 15, 2007 20:44
Location: Australia

Post by Richard »

We are talking here about 30 years ago. Obviously a 16 bit 8086 needs longer registers than an 8 bit 8080 processor. The 8086 also added segment registers so that it could address a phenomenal whole megabyte, just in case the ridiculously large 64k of address space of the 8080 might some day prove to be insufficient.

As the registers increased in length the old 8080 registers names were not reused but were “extended” so that legacy assembly code retained the same functionality with very few changes needed. Because of this a macro assembler could change the 8080 names to 8086 names without confusion. All 8080 registers map into the 8086 register set and on through the x86 series.

The 8080 A was extended to 16 bit AX in the 8086. AH was new, A became AL.
The 8080 HL pair translated to the 8086 BX pair. H=BH, L=BL
The 8080 BC pair translated to the 8086 CX pair. B=CH, C=CL
The 8080 DE pair translated to the 8086 DX pair. D=DH, E=DL

So for example; the 8086 BX (= BH&BL) have nothing to do with the old 8080 B register. Assembly code that referred to the B register of the 8080 now refer to the CH register of the 8086.

DOS386’s code uses the x86 register names so as to be compatible with the FreeBASIC in-line assembler. Since it is an 8 bit algorithm it is not surprising that it could be assembled for any 8 bit Intel processor. I think the claim to 8080 compatibility comes from the use of 8 bit assembly operations that were originally supported by the 8080 assembly code.
DOS386
Posts: 798
Joined: Jul 02, 2005 20:55

Post by DOS386 »

Richard wrote:uses the x86 register names so as to be compatible with the FreeBASIC in-line assembler. Since it is an 8 bit algorithm it is not surprising that it could be assembled for any 8 bit Intel processor. I think the claim to 8080 compatibility comes from the use of 8 bit assembly operations that were originally supported by the 8080 assembly code.
Right ... could compile for any Intel or NON-Intel 8-bit CPU :-)

> 1. must only use 8080 instructions.

8-bit registers + math.

> 2. must use a minimum number of bytes.

Right.

> 3. speed is not important.

It's good IMHO.

> 4. generate first quadrant of sine only.

The other 3 can be mirrored, and > 360 deg MOD'ed or AND'ed.

> 5. input is a byte representing 0 = 0, 255 = 90.000 degrees ?
> 6. output is a byte mapped 0 = 0, 255 = 1.000 ?

Right.

> 7. accuracy, output within one lsb of the correct value.

Accurancy is sufficient for the purpose of drawing to screen of reasonable resolution. I wouldn't put up with such for drilling a tunnel of several 10 Km length, however.
Post Reply