[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: And now, from the author of the DOS Disk post, a post that actually relates to this newsgroup.



Jon Bettencourt writes ...
> 
> Is there any way to compile an Applesoft BASIC file to machine language?
> Either a BIN file or a SYS file; BIN would probably be easier to do. I
> tried the Beagle BASIC Compiler, but it seems to only compile COM files,
> which, when transfered to another disk, result in Integer BASIC files.
> Here is the short program I want to compile:
> 
> 10 FOR X = 8192 TO 16383 : R = INT(RND(1)*256) : POKE X,R : NEXT X
> 
> It fills page 1 of Hi-Res graphics with TV static. This happens very
> slowly. I know it can be done faster, after all there is a routine to
> clear the screen.
> 
 ....

     A fast way to fill the hires screen with random garbage? What a cool project!

     Did some experimenting. This BASIC routine will do it reasonably fast (for
plain BASIC):


 10 E = 9999:M = 8192:P = 255:Q = 127:K = 49152: I =  PEEK (49236) +  
    PEEK (49239) +  PEEK (49234) +  PEEK (49232)
 20  FOR I = 1 TO E: POKE M +  RND (1) * M, RND (1) * P: 
    POKE M +  RND (1) * M, RND (1) * Q: NEXT I: GOTO 20



     As you say, you can do it much faster in machine code. The routine below does
CALLs to the Random Number generator in the Applesoft BASIC ROM:


STATIC.BIN ASM

                2    DO_RND   EQU   $EFAE
                3    RDKEY    EQU   $C000
                4    CLRKEY   EQU   $C010
                5             ORG   $1F00
                6
1F00: 20 AE EF  7    STATIC   JSR   DO_RND
1F03: A0 00     8             LDY   #$00
1F05: A5 CD     9             LDA   $CD
1F07: 85 06     10            STA   $06
1F09: A5 CC     11            LDA   $CC
1F0B: 29 3F     12            AND   #$3F
1F0D: 09 20     13            ORA   #$20
1F0F: 85 07     14            STA   $07
1F11: A5 CB     15            LDA   $CB
1F13: 91 06     16            STA   ($06),Y
1F15: A5 CC     17            LDA   $CC
1F17: 85 06     18            STA   $06
1F19: A5 CD     19            LDA   $CD
1F1B: 29 3F     20            AND   #$3F
1F1D: 09 20     21            ORA   #$20
1F1F: 85 07     22            STA   $07
1F21: A5 CA     23            LDA   $CA
1F23: 91 06     24            STA   ($06),Y
1F25: A5 CB     25            LDA   $CB
1F27: 85 06     26            STA   $06
1F29: A5 CA     27            LDA   $CA
1F2B: 29 3F     28            AND   #$3F
1F2D: 09 20     29            ORA   #$20
1F2F: 85 07     30            STA   $07
1F31: A5 CD     31            LDA   $CD
1F33: 91 06     32            STA   ($06),Y
1F35: A5 CA     33            LDA   $CA
1F37: 85 06     34            STA   $06
1F39: A5 CB     35            LDA   $CB
1F3B: 29 3F     36            AND   #$3F
1F3D: 09 20     37            ORA   #$20
1F3F: 85 07     38            STA   $07
1F41: A5 CC     39            LDA   $CC
1F43: 91 06     40            STA   ($06),Y
1F45: AD 00 C0  41            LDA   RDKEY
1F48: 85 06     42            STA   $06
1F4A: 10 B4     43            BPL   STATIC
1F4C: AD 10 C0  44            LDA   CLRKEY
1F4F: 20 AE EF  45            JSR   DO_RND
1F52: A5 06     46            LDA   $06
1F54: C9 8D     47            CMP   #$8D
1F56: D0 A8     48            BNE   STATIC
1F58: 60        49            RTS


     Once it's BLOADed, you just turn on the hires screen and CALL 7936 ($1F00).
For example:

50 HGR: I = PEEK (49234): CALL 7936

Note: Line 50 clears the screen to Black so that you can see the screen fill up.
 You can turn on full page hires (for Hires Page 1) without changing the screen 
with  I =  PEEK (49236) +  PEEK (49239) +  PEEK (49234) +  PEEK (49232)


     What the routine does is CALL the RND routine at $EFAE and use the 4-byte
result at $00CA - $00CD to pick the screen byte address and the value to write.
Since CALLing the RND routine is relatively time consuming, the routine uses the 4
bytes to generate several addresses and bytes to write per CALL. (Even so, not all
possible combinations are employed in order to keep down the length of the
routine.)

     The end of the routine does a check for a keypress. If there is one, the
routine does a throwaway CALL to RND in order to jiggle the sequence and, then
checks to see if the keypress was RETURN. If it was, the routine exits. Otherwise,
it continues writing to the screen.

     On a 1MHz Apple II+, you get a moderately 'crinkly' display-- just a fair "TV
static demo". At 4MHz on a IIc+, you get much closer; and, on a 10MHz IIgs, the TV
static simulation is pretty good.


     An interesting discovery while experimenting with different routines is that
you cannot make do using just a couple bytes from the RND output to generate
addresses. (At least not the ones I tried.)  It turns out that the values cycle
without covering all addresses and you end up with a static looking display full of
holes that never get written to. (At first, when the screen froze, I thought the
program had bombed!)


     Since, obviously, everyone will want to see TV static on his/her own Apple II
screen, a demo program (in .shk and on .dsk) has been uploaded to the November
issue of GS WorldView. It's at ...

http://www.grin.net/~cturley/gsezine/GS.WorldView/Nov99/Graphics/TVstatic/ .




Rubywand