Advertisement
Guest User

28-byte BASIC sine generator

a guest
Dec 19th, 2013
347
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. table   = $0400     ;; The output is a set of negated (phase-shifted by 180°)
  2.             ;; sines between -128 and +127.
  3.             ;; Preferably a low page. Must be paged aligned!
  4.  
  5. loop    lda #<index ;; Load 5-byte float at 'index' into FAC, the fraction of
  6.     ldy #>index ;; which is stepped between -0/256..-255/256.
  7.     jsr $bba2   ;; However an integer bias is also added in order to fix
  8.             ;; the exponent and make hence it possible to increment the
  9.             ;; fraction as a normal binary byte, e.g. a version of the
  10.             ;; classic x86 float-to-int conversion trick.
  11.    
  12.     jsr $e277   ;; Now calculate sine of FAC. Except skip the initial part
  13.             ;; of the BASIC function which divides by 2*PI to get
  14.             ;; a fraction out of radians since we've already got one.
  15.             ;; The integer bias is taken care by BASIC since sin()
  16.             ;; is supposed to be periodic.
  17.  
  18.     lda #<bias  ;; Convert the output in FAC from a float in -1..+1 to a
  19.     ldy #>bias  ;; fixed-point value in -128..+127 at the LSB of the
  20.     jsr $b867   ;; mantissa by employing the same trick as before of
  21.     lda $65     ;; adding a high integer bias.
  22.  
  23. index   .byte $88   ;; This is both a float *and* a piece of code. The exponent
  24.     sta table   ;; ($88 corresponds to 2^8) fixes our 8-bit fraction as the
  25.             ;; second byte of the mantissa and the STA address' LSB
  26.             ;; (don't forget that BASIC floats are big-endian!). And $88
  27.             ;; when interpreted as code corresponds to a harmless DEY.
  28.             ;; Note that the STA's opcode is an integer part which only
  29.             ;; has the effect of negating the index (the sign bit is set).
  30.             ;; However the table address' high byte and the subsequent
  31.             ;; INC opcode *do* serve as a small offset, shifting the
  32.             ;; result by up to one index value. Some might even argue
  33.             ;; that placing the table at $8000 would produce the 'proper'
  34.             ;; rounding.
  35.     inc *-2
  36.     bne loop
  37.  
  38. bias    = $befa     ;; A float with an exponent of $99 (2^25) and an LSB of
  39. ;;  .byte $99   ;; zero is used to convert the output to binary. Such byte
  40. ;;  .byte $02   ;; sequences can be found in six places in the BASIC/Kernal
  41. ;;  .byte $01   ;; ROMs, at $befa/$bf04/$bf09/$fd53/$fd56/$ff38.
  42. ;;  .byte $a9   ;; A version with an LSB of $80 would have been useful to
  43. ;;  .byte $00   ;; create unsigned output (e.g. between $00 and $ff with the
  44.             ;; origin at $80) but unfortunately doesn't seem to exist.
  45.             ;; Values with different exponents and offsets might be found
  46.             ;; to better suit your particular application.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement