; Z80asm
; 'convertor' for nwAYv (wav2ay)
; Chris Born 2018, Rotterdam

;sox -V -D mozarts15a.wav -r 9560 -b 8 -e unsigned -c1 moz%1n.raw trim 0 4 : newfile : restart

; WAV is cut in RAW BLOCKS off 4 seconds each

; raw wave (from sox) converted from 8bit to 4bit value
;https://en.wikipedia.org/wiki/Audio_bit_depth
; and stored per 2 samples>> %xxxxyyyy
; 2 bytes become 1 !!
; so 10KB becomes 5kb and together they need 15kb OR
; if you DO overwrite the source then 'destiny' is best 10 bytes UNDER the source
; top-length = 65535-39000 = 26535-10-routine= 26000 as ORG ??

          org 26000
          length equ 38240 ; workvalue

          di  ; some speed is nice


src equ $+1
          ld de,source   ; adres off the RAW file
des equ $+1
          ld hl,destiny  ; eg 16384, max AY file =6912 bytes when on SCREEN 
lng equ $+1
          ld bc,length   ; length off RAW eg 6912+6912=13kb dont overwrite the source, or be sure you do !!!

; 1 step= 2 bytes RAW
          xor a         ; reset carry flag
          rr b          ; move bit 0 in carry
          rr c          ; move carry in bit 7
                        ; bc=length is divided by 2

          adc a,c         ; add carry (0 or 1 ) to length
          ld c,a
          ld (hl),c     ; lsb ,store AY_length at begin off file
          inc hl
          ld (hl),b     ; msb , length
          inc hl        ; 2 bytes done

          push hl       ;st1 ay adres
          push bc

next        push bc     ; st3

          call compare  ; first sampledigit, counted in low digit part %00001111
          ld c,(hl)     ; %0000.1111

;--- 9 byte to make 4bits decent last bits , $0f instead of $nf
;exx
;            pop bc      ; st2
;          dec bc
;          ld a,b
;          or c
;          jr z,ppb
;            push bc
;exx
;---
          call compare  ; make/count 2nd sample digit AGAIN iN LOW digit
          ld a,(hl)     ; %0000.1111     
          rlca          ; %0001.1110
          rlca          ; %0011.1100
          rlca          ; %0111.1000
          rlca          ; %1111.0000
          or c          ; %1111.1111
          ld (hl),a     ; (hl)=yx
          inc hl        ; next destiny adres

            pop bc      ; st2
          dec bc
          ld a,b
          or c
          jr nz,next

ppb       pop bc        ; ay len
          pop hl        ; st0 ay destiny

          ld d,h        ; 
          ld e,l        ; DE now source_rle

          add hl,bc     ; destiny_rle
          inc hl        ; extra space destiny_rle
          inc hl        ; extra space destiny_rle

        push hl         ; store start adres  RLE for saving data block, later popped in BC
          inc hl        ; skip 2 bytes for length storage
          inc hl        ; LET des=d+2

          call simpRLE_8  ; is bc set??

; hl is at end of rle_data , de at end ay_source, but not used anymore
        pop de          ; start adres off RLE data - 2
        xor a           ; reset flags
        sbc hl,de       ; hl =length rle
        ex de,hl        ; hl=start_rle-2 , de= length
        ld (hl),e
        inc hl
        ld (hl),d
        inc hl          ; hl= begin rle_data

push de
pop bc    

;add hl,de   ; hl is 2 bytes above end off file!!        
;ex de,hl
;ld hl,23670 ; sysvar SEED as temp storage, easily overwritten by BASIC commands...
;ld (hl),e
;inc hl
;ld (hl),d

          ei ; enable future
          ret ; back to basic,  bc holds rle_data length if all went well....
              ; SEED holds NEXT USABLE ADRES above 'mc_rle'

; which CURVE is best ? a sinusoid seems nice...
; n+(n+1)  total=(0+1)+(1+2)+(2+3)+(3+4)+(4+5)+(5+6)+(6+7)+(7+8)+(8+9)+(9+10)+(10+11)+(11+12)+(12+13)+(13+14)+(14+15)+(15+16)=256 in 16 steps

; n+(n+1)  total= 1+ 3+ 5 + 7 + 9+ 11+ 13+ 15+ 17+ 19+ 21+ 23+ 25+ 27+ 29+ 31 =256 in 16 steps
; now used total=2+3+2+3+4+5+10+11+16+24+23+28+30+36+39+20=256 steps in 16 steps
; (hl) = 0
; 8 to 4 bit conversion as by Chris Born

; hl=destiny, de is source, ix= 8bit wave_table with 15 values, value 0+1 is already 'done' by init.
compare   ld ix,gasman
          xor a
          ld (hl),a     ; make destiny start 0, step 1
          ld a,(de)     ; source byte
          ld b,15       ; (de)0 = (hl)0 = first off 16 steps, so b=15 for left values

cpix      cp (ix+0)     ; 0,1         = 2 steps
          jr c,done_2   ; if 2 is biggest carry is set
          inc (hl)      ; (hl)=1 , 4 bit value
          inc ix        ; next 8bit curve value
          djnz cpix     ;

done_2:   inc de        ; move SOURCE 1 adres up
          ret           ; (HL) max raised to 15 = 1 digit


; bc=length , de= source ,(hl)= sample (hl+1)=counter
simpRLE_8:

rle1   push bc
          ld a,(de)     ; sample source_ay
          ld b,a        ; store to compare later

          ld (hl),b     ; save sample at destiny_rle
          inc hl        ; des+1 to counter
          xor a         ;
          inc a         ; 1 sample found at least...
          ld (hl),a     ; LET cnt=1 destiny2+1

go120     inc de        ; nxt=nxt+1
          ld a,(de)     ; peek (source+nxt), next sample
          cp b          ; '1st' sample
          jr nz,nxt     ; if a not b make nxt set

          inc (hl)      ; same sample found
          jr z,nxt      ; if 256 equal samples found, make next set off 2 bytes
ld a,b
ex af,af'
         pop bc        ; FILE length counter
          dec bc
          ld a,b
          or c
          jr z,ant      ; END of wav found
         push bc       ; save new length on stack
ex af,af'
ld b,a    
          jr go120      ; keep counting equal samples

nxt       inc hl        ; des+1+1 = next sample storage byte
       pop bc
          dec bc        ; length counter
          ld a,b
          or c
          jr nz,rle1    ; if more samples, continue

ant       ret

; sound curves axe 16x255
gasman: defb 2,5,7,10,14,19,29,40,56,80,103,131,161,197,236 ; defb 2,3,2,3,4,5,10,11,16,24,23,28,30,36,39,20
;crisis: defb 2,5,10,17,26,37,50,65,82,101,122,145,170,197,226 ; defb 1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31
; MIND THAT THE DESTINY in this case IS JUST BELOW THE SOURCE
; MEANING THE SOURCE IS OVER WRITTEN, BUT ASWELL CAN BE LARGE!

destiny   equ ant+10  ; 10 bytes buffer between source and destiny, 

source    equ ant+20  

the       end





; the other raw 2 ay calc
; 8 to 4 bit conversion as by Chris Born
; n+(n+1)  total=(0+1)+(1+2)+(2+3)+(3+4)+(4+5)+(5+6)+(6+7)+(7+8)+(8+9)+(9+10)+(10+11)+(11+12)+(12+13)+(13+14)+(14+15)+(15+16)=256 in 16 steps
; n+(n+1)  total= 1+ 3+ 5 + 7 + 9+ 11+ 13+ 15+ 17+ 19+ 21+ 23+ 25+ 27+ 29+ 31 =256 in 16 steps

; 1+ 1= 2 
; 1+ 1+ 3= 5
; 1+ 1+ 3+ 5=10
; 1+ 1+ 3+ 5+ 7=17
; 1+ 1+ 3+ 5+ 7+ 9= 26
; 1+ 1+ 3+ 5+ 7+ 9+ 11= 37
; 1+ 1+ 3+ 5+ 7+ 9+ 11+ 13= 50
; 1+ 1+ 3+ 5+ 7+ 9+ 11+ 13+ 15= 65
; 1+ 1+ 3+ 5+ 7+ 9+ 11+ 13+ 15+ 17= 82
; 1+ 1+ 3+ 5+ 7+ 9+ 11+ 13+ 15+ 17+ 19=101
; 1+ 1+ 3+ 5+ 7+ 9+ 11+ 13+ 15+ 17+ 19+ 21=122
; 1+ 1+ 3+ 5+ 7+ 9+ 11+ 13+ 15+ 17+ 19+ 21+ 23=145
; 1+ 1+ 3+ 5+ 7+ 9+ 11+ 13+ 15+ 17+ 19+ 21+ 23+ 25=170
; 1+ 1+ 3+ 5+ 7+ 9+ 11+ 13+ 15+ 17+ 19+ 21+ 23+ 25+ 27=197
; 1+ 1+ 3+ 5+ 7+ 9+ 11+ 13+ 15+ 17+ 19+ 21+ 23+ 25+ 27+ 29=226
; 1+ 1+ 3+ 5+ 7+ 9+ 11+ 13+ 15+ 17+ 19+ 21+ 23+ 25+ 27+ 29+ 31=257

compare_2 xor a
          ld (hl),a     ; make destiny start 0
          ld a,(de)     ; source byte
          cp 2          ; 0,1         = 2 steps
          jr c,done_2   ; if 2 is biggest carry is set
          inc (hl)      ; (hl)=1
          cp 5          ; 2,3,4       =  3 steps
          jr c,done_2   ;
          inc (hl)      ; (hl)=2
          cp 10         ; 5,..,9     =  5 steps
          jr c,done_2   ;
          inc (hl)      ; (hl)=3
          cp 17         ; 10,..,16    =  7 steps
          jr c,done_2   ;
          inc (hl)      ; (hl)=4
          cp 26         ; 17,..,25    =  9 steps
          jr c,done_2   ;
          inc (hl)      ; (hl)=5
          cp 37         ; 26,..,36    =  11 steps
          jr c,done_2   ;
          inc (hl)      ; (hl)=6
          cp 50         ; 37,..,49    = 13 steps
          jr c,done_2   ;
          inc (hl)      ; (hl)=7
          cp 65         ; 50,..,64    = 15 steps
          jr c,done_2   ;
          inc (hl)      ; (hl)=8
          cp 82         ; 65,..,81    = 17 steps
          jr c,done_2   ;
          inc (hl)      ; (hl)=9
          cp 101        ; 82,..,100    = 19 steps
          jr c,done_2   ;
          inc (hl)      ; (hl)=10  A
          cp 122        ; 101,...,121  = 21 steps
          jr c,done_2   ;
          inc (hl)      ; (hl)=11  B
          cp 145        ; 122,...,144 = 23 steps
          jr c,done_2   ;
          inc (hl)      ; (hl)=12  C
          cp 170        ; 145,...,169 = 25 steps
          jr c,done_2   ;
          inc (hl)      ; (hl)=13  D 
          cp 197        ; 170,...,196 = 27 steps
          jr c,done_2   ;
          inc (hl)      ; (hl)=14  E 
          cp 226        ; 197,...,225 = 29 steps
          jr c,done_2   ;
          inc (hl)      ; (hl)=15  F 
                        ; 236,...,255 = 31 steps

done_2:    inc de        ; move SOURCE 1 adres up
          ret           ; (HL) max raised to 15 = 1 digit

; original 8 to 4 bit conversion as by gasman&karl
compare_1   xor a  
          ld (hl),a     ; make destiny start 0
          ld a,(de)     ; source byte
          cp 2          ; 0,1   = 2 steps
          jr c,done1    ; if 2 is biggest carry is set
          inc (hl)      ; (hl)=1
          cp 5          ; 2,3,4       =  3 steps
          jr c,done1    ;
          inc (hl)      ; (hl)=2
          cp 7          ; 5,6         =  2 steps
          jr c,done1    ;
          inc (hl)      ; (hl)=3
          cp 10         ; 7,8,9       =  3 steps
          jr c,done1    ;
          inc (hl)      ; (hl)=4
          cp 14         ; 10,..,13    =  4 steps
          jr c,done1    ;
          inc (hl)      ; (hl)=5
          cp 19         ; 14,..,18    =  5 steps
          jr c,done1    ;
          inc (hl)      ; (hl)=6
          cp 29         ; 19,..,28    = 10 steps
          jr c,done1    ;
          inc (hl)      ; (hl)=7
          cp 40         ; 29,..,39    = 11 steps
          jr c,done1    ;
          inc (hl)      ; (hl)=8
          cp 56         ; 40,..,55    = 16 steps
          jr c,done1    ;
          inc (hl)      ; (hl)=9
          cp 80         ; 56,..,79    = 24 steps
          jr c,done1    ;
          inc (hl)      ; (hl)=10  A
          cp 103        ; 80,...,102  = 23 steps
          jr c,done1    ;
          inc (hl)      ; (hl)=11  B
          cp 131        ; 103,...,130 = 28 steps
          jr c,done1    ;
          inc (hl)      ; (hl)=12  C
          cp 161        ; 131,...,160 = 30 steps
          jr c,done1    ;
          inc (hl)      ; (hl)=13  D 
          cp 197        ; 161,...,196 = 36 steps
          jr c,done1    ;
          inc (hl)      ; (hl)=14  E 
          cp 236        ; 197,...,235 = 39 steps
          jr c,done1    ;
          inc (hl)      ; (hl)=15  F 
                        ; 236,...,255 = 20 steps


done1:    inc de        ; move SOURCE 1 adres up
          ret           ; (HL) max raised to 15 = 1 digit


;1020 LET a=PEEK (src+nxt): POKE des,a
;1040 LET cnt=cnt+1: POKE des+1,cnt
;1050 LET nxt=nxt+1: IF PEEK (src+nxt)=a AND cnt<255 AND nxt < lng-1 THEN GO TO 1040
;1060 IF nxt < lng-1 THEN LET des=des+2: LET cnt=0: GO TO 1020
;1065 LET sz=des-(d+2): RANDOMIZE sz: POKE d,PEEK 23670: POKE d+1,PEEK 23671: REM poke size
;1080 IF sz>=lng THEN BEEP 1,1: PRINT #0; FLASH 1;"RESULT IS LONGER THEN ORIGINAL"
