среда, 8 мая 2013 г.

Rainbow Fuji

Another attempt to repeat the famous Atari rainbow Logo.
Here I'm trying to use PL65 internal assembler and GRAPHICS library.

At first, we need to draw Atari Fuji, thus we need to convert Polar to Decart and so we need INTEGER algorithm for Square Root calculation.
(Not float. Sic! No one really needs semipicsels!)

Something from Internet:
Let's begin to substruct ALL INCREASING INTEGER ODD NUMBERS, while the result is not negative...
And the quantity of steps will be the square root.

SQRT(32)=5
32-1=31 -> 31-3=28 -> 28-5=23 -> 23-7=16 -> 16-9=7 -> 7-11<0
   1          2          3          4          5

The PL65 Code of Sqrt() Function (in MATH.LIB):

! -----------------------------------
! Calculating Square Root from Integer
! On entry INP contains input Integer
! On exit OUT contains SQRT, OUT+1 contains Reminder
FUNC Sqrt(INT INP)
  INT OUT
BEGIN
  STX XSAVE
  LDY #$01; STY OUT; DEY; STY OUT+1
:again
  SEC
  LDA INP
  TAX
  SBC OUT STA INP
  LDA INP+1 SBC OUT+1 STA INP+1
  BCC nomore
  INY
  LDA OUT ADC #$01 STA OUT
  BCC again
  INC OUT+1 BNE again
:nomore STY OUT STX OUT+1
  LDX XSAVE
END OUT

Really, OUT is a temporary accumulative varyable ...

1 - The hard rule of PL65 is:
Using 6502 X-register in any way without it's previous saving will kill software stack pointer of PL65!!! (and your beloved program...)
THUS: Save X to XSAVE before!!! And restore it from XSAVE after ...

2 - When we ADC 1 with CARRY being previously set we adds CARRY value too!
Thus in fact we adds 2! And our numbers stay odd anyway!

3 - Using ; - sign in assembler part of PL65 prevents compiler from mixing for example assembler ;AND operator with high level PL65 AND statement!

The next assembler part is rainbow effect itself.

The Code!
! =================================
! ALOGO.PRG
! Draws Fuji with Raibow effect
! CopyLEFT (C) 2013 EZsoft
! Uses MATH.LIB & PEEKPOKE.LIB !!!
! =================================
INCLUDE D:MATH.LIB
INCLUDE D:PEEKPOKE.LIB
INCLUDE D:GRAPHICS.LIB
! -----------------------------------
! Draws rectangle Canvas
PROC Canvas(BYTE Col INT X0,X1 BYTE Y0,Y1)
BEGIN
  COLOR=Col
  PLOT(X0,Y1) DRAW(X1,Y1) DRAW(X1,Y0) DRAW(X0,Y0)
  POKE(765,3) ! Color of canvas frame
  GFILL(X0,Y1)
END
! -----------------------------------
! Draws ATARI Fuji Logo
PROC Fuji(BYTE Col)
  BYTE T,B INT R
BEGIN
  COLOR=Col T=20 B=76
  FOR R=80 TO 84 DO
    PLOT(R,T) DRAW(R,B) PLOT(160-R,T) DRAW(160-R,B)
  NEXT
 
  FOR R=86 TO 115 DO
    IF R>90 THEN T=43+Sqrt(626-(116-R)*(116-R)) ENDIF
    B=45+Sqrt(962-(116-R)*(116-R))
    PLOT(R,T) DRAW(R,B) PLOT(160-R,T) DRAW(160-R,B)
  NEXT
END
! -----------------------------------
! The famous Atari Rainbow effect
PROC Rainbow()
BEGIN
  REPEAT
    LDA $D200 ! POT0
    ADC $14   ! RTCLOK+2
    STA $D017 ! COLPF1
    LDA $D40B ! VCOUNT
    SBC $14   ! RTCLOK+2
    STA $D01A ! COLBK
    STA $D40A ! WSYNC
  UNTIL (PEEK(764)=28)
END
! -----------------------------------
! Main program
MAIN()
  BYTE Col INT X0,X1 BYTE Y0,Y1
BEGIN
  GRAPHICS(7+16)
  POKE(708,28) POKE(709,52) POKE(710,0) POKE(712,148)
  Col=1 X0=35 X1=125 Y0=12 Y1=85
  Canvas(Col,X0,X1,Y0,Y1)
  Col=2
  Fuji(Col)
  Rainbow()
END

It works!