starting with elias-gamma

The place for codemasters or beginners to talk about programming any language for the Spectrum.
C.Born
Manic Miner
Posts: 239
Joined: Sat Dec 09, 2017 4:09 pm

Re: starting with elias-gamma

Post by C.Born »

back to that single main question about direction inside memory
so
i write a single elias value in memory on a fresh cleared location,

its the value 1
that delivers a single bit without leading 0

is this single bit stored on
bit 0 %00000001
or
bit 7 %10000000

its very much "navel staren" but you have to know once you extract the values later ...
eg what does the decompressor of zx0 expect ??
:(
C.Born
Manic Miner
Posts: 239
Joined: Sat Dec 09, 2017 4:09 pm

Re: starting with elias-gamma

Post by C.Born »

it seems to work and trying on the first 2K of the ROM gives a bit shorter result then 2k, BUT elias-gamma=0 and/or Golomb=255 are avoided, so, those are omitted and Not part of the result.
is it now "ready" for a zx0 step?? with settings its 148 bytes, and as bin probably around 125 bytes
the view on screen is per byte reversed since i start with BIT0 %00000001
any reaction is welcome,
whats the next step ??

Code: Select all

; should be Elias, but now alias ...
; to be INCLUDEd as ASM

; #INCLUDE alias-0050.asm

; pasmo -d --bin alias-0050.asm alias-0050.bin alias-0050.symbol

; pasmo -d --tapbas --name alias-0050 alias-0050.asm alias-0050.tap alias-0050.symbol

; tape    equ  0



; an elias-gamma format Z80 routine 
; DE holds SOURCE, hl holds DESTINY


; IF tape       ; for TEST purpose only

source        equ 0        ; lets elias the ROM
destiny       equ 16384    ; lets dump the string on screen
length        equ 2048      ; lets try some more

here          equ 25000    ; 16k rules, leave some stack

              org here
              di                  ; EXX used, avoid ROM troubles
              exx
              push hl             ; save sysvar
              ld bc,length
              ld de,source
              ld hl,destiny


elias:        push bc
              ld a,(golomb)
              ld c,a              ; c=0 or 1

              push de
              ld a,(de)           ; elias source
              add a,c
              jp z,done     ; on elias = 0 or golomb=255 (255+1)


              ld b,8
              ld c,1              ; gamma 1st %00000001
count0        rrc c               ;  > c gamma 1st=%10000000
              sla a               ; c<7-6543210-<0  %xxxx0000
              jr c,gammafound
              djnz count0         ; will b=0 happen , nope
gammafound    equ $               ; b=2^(b-1) value and c is gammabit position
                                  ; a holds remains after the gamma bit
                                  ; a= %xxxxxxx0 to %00000000

              ld (remains),a      ; every bit AFTER the gamma bit

              ld a,b
              ld (gammabit),a     ;   1 to 8 , position as value

              ld a,c              ;                         87654321
              ld (lastgamma),a    ;   position inside byte %0000000x

; set a bit at a time, just keep counting, start at BIT 0, BYTE 0
; for NOW this is the first step for the first bit of the first eliasgamma of the eliasgammabitstring 
; starting at 0bit,0byte

              ld a,b
              dec a
              jr z,done
              dec b

              ld a,(bits)         ; be sure the ONCE_PRESET=1 is correct
              cpl                 ; first write 0 with AND %xxxx0xxx
              ld c,a              ; c has now a single 0 bit
              ld a,(hl)           ; byte destiny

set0          and c               ; first FIX bit in A reg into an 0
              rlc c               ; then rotate bit c
              jr c,notyet         ; c has a single 0 bit giving NC
              ld (hl),a           ; store result
              inc hl              ; 8 bits in a row FIXED what ever the counter mentions
              ld a,(hl)           ; next byte to fixed
notyet        dec b
              jr c,bdone
              jr nz,set0

bdone         ld (hl),a           ; store 000 in destiny
              ld a,c
              cpl                 ; back to %00001000
              ld c,a
              ld a,(hl)
              or c                ; fix bit '1' gamma bit
              rlc c               ; rotate bit for next free bit
              jr nc,noty
              ld (hl),a           ; store '001' in  destiny
              inc hl
              ld a,(hl)           ; store '001' in  destiny
noty          equ $


              ld a,c              ; 
              ld (bits),a         ; fixed bit position in c
              cpl
              ld e,a

              ld a,(gammabit)    ;
              ld b,a              ; counter in b

              ld a,(remains)      ;
              ld d,a              ; last bits to be fixed, 0 and 1

              ld a,(hl)           ; store in a

bitz          sla d
              jr nc,fix0

fix1          or c         ; set a '1'
              rlc e
              rlc c
              jr checkhl

fix0          and e        ; set a '0'
              rlc e
              rlc c

checkhl       jr nc,ntyt
              ld (hl),a
              inc hl
              ld a,(hl)
ntyt          dec b
              jr c,bbdone
              jr nz,bitz

bbdone        ld a,c
              ld (bits),a


done          pop de             ;  source adres
              inc de             ; real adres
;              ex de,hl
;              inc (hl)          ; source2 adres with calc result
;              ex de,hl

              pop bc
              dec bc             ; source counter

              ld a,b
              or c
              jp nz,elias


              pop hl             ; fetch sysvar
              exx
              ei
              ret



lastgamma     defb 0              ; starting with bit 0

golomb        defb 0              ; use value elias0 on golomb=1 OR not on golomb=0

remains       defb 0

gammabit      defb 0              ; b = number

bits          defb 1              ; b=next free bit POSITION in the string from 1 to 8 %87654321

source2 defw 1

END here
C.Born
Manic Miner
Posts: 239
Joined: Sat Dec 09, 2017 4:09 pm

Re: starting with elias-gamma

Post by C.Born »

and 1 bit better, again
it stil laks some thing

Code: Select all

; an elias-gamma format Z80 routine 
; DE holds SOURCE, hl holds DESTINY

; LATER to be INCLUDEd as ASM

; #INCLUDE Elias-0062.asm

; pasmo -d --bin Elias-0062.asm Elias-0062.bin Elias-0062.symbol

; pasmo -d --tapbas --name Elias-0062 Elias-0062.asm Elias-0062.tap Elias-0062.symbol


;  10 CLEAR 25499: LOAD ""CODE 
;  40 BORDER 4: CLS : GO SUB 200: RANDOMIZE USR 25500
;  50 PAUSE 0: RANDOMIZE USR 25627
; 150 STOP 
; 200 LET x=0: FOR g=1 TO 8: FOR f=1 TO 32: LET x=NOT x: PRINT  BRIGHT x;" ";: NEXT f: LET x=NOT x: NEXT g
; 210 RETURN 


source        equ 0        ; lets elias the ROM

destiny       equ 16384    ; lets dump the string on screen

length        equ 2048     ; lets try some more then 1 byte


here          equ 25500    ; 16k rules, leave some stack

              org here

              di
              exx
              push hl             ; save sysvar

              ld bc,length
              ld de,source
              ld hl,destiny

elias:        push bc
              ld a,(golomb)
              ld c,a              ; c=0 or 1

              push de
              ld a,(de)           ; elias source
              add a,c
              jr z,done           ; on elias = 0 or golomb=255 (255+1)

              ld b,8
              ld c,1              ; gamma 1st %00000001
count0        rrc c               ;  > c gamma 1st=%10000000
              sla a               ; c<7-6543210-<0  %xxxx0000
              jr c,gammafound
              djnz count0         ; will b=0 happen , nope
gammafound    equ $               ; b=2^(b-1) value and c is gammabit position
                                  ; a holds remains after the gamma bit
                                  ; a= %xxxxxxx0 to %00000000

              ld (remains),a      ; every bit AFTER the gamma bit

              ld a,b
              ld (gammabit),a     ;   1 to 8 , position as value

              ld a,c              ;                         87654321
              ld (lastgamma),a    ;   position inside byte %0000000x

; set a bit at a time, just keep counting, start at BIT 0, BYTE 0
; for NOW this is the first step for the first bit of the first eliasgamma of the eliasgammabitstring 
; starting at 0bit,0byte

             ; ld a,(lastgamma)
              call mirrad         ; return with d set

              ld a,(gammabit)     ;
              ld b,a              ; counter in b
              call setbits        ; b and d are set now


              ld a,(remains)      ;
              ld d,a              ; last bits to be fixed, 0 and 1
              sla d               ; purge gamma bit

              ld a,(gammabit)     ;
              ld b,a              ; counter in b
;              dec b
;              jr z,done

              call setbits


done          pop de              ;  source adres
              inc de              ; real adres

              pop bc
              dec bc              ; source counter

              ld a,b
              or c
              jr nz,elias

              pop hl              ; fetch sysvar
              exx
              ei
              ret



setbits:
; d = bitrow  b = counter
; (hl) = destiny
; uses a,b,c,d,e,(hl)

              ld a,(bits)
              ld c,a
              cpl
              ld e,a

              ld a,(hl)           ; fetch DESTINY BYTE in a
bitz          sla d               ; purge data bits
              jr nc,fix0

fix1          or c                ; set a '1'
              rlc e
              rlc c
              jr checkhl

fix0          and e               ; set a '0'
              rlc e
              rlc c

checkhl       jr nc,ntyt          ; c/nc from C
              ld (hl),a
              inc hl
              ld a,(hl)
ntyt          dec b
              jr c,bbdone
              jr nz,bitz

bbdone        ld a,c
              ld (bits),a
              ret


; MIRROR BYTE A in D
; needs A set, delivers D
; uses A,B,D
mirrad:       ld b,8
mkd           sla a         ; a to be mirrord
              rr d          ; carry IN a 1 or 0
              djnz mkd      ; always 8 bits
              ret           ; return with D set

mirrorscreen:
              ld hl,destiny
              ld de,length
nextmirror    ld a,(hl)
              call mirrad
              ld (hl),d
              inc hl
              dec de
              ld a,d
              or e
              jr nz,nextmirror
              ret

; Elias value elias+1
golomb        defb 0              ; use value elias0 on golomb=1 OR not on golomb=0


lastgamma     defb 0              ; starting with bit 0
remains       defb 0
gammabit      defb 0              ; b = number
bits          defb 1              ; b=next free bit POSITION in the string from 1 to 8 %87654321

source2 defb 1,2,3,4,5,6,7,8,9,10
sourc2end equ $
length2 equ sourc2end-source2



END here
C.Born
Manic Miner
Posts: 239
Joined: Sat Dec 09, 2017 4:09 pm

Re: starting with elias-gamma

Post by C.Born »

and back to the board since now i do miss some, but what?

source2 defb 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15

; eliasgamma string with 1 to 15 should be 84 bits from which 32 set
; 1 010 011 00100 00101 00110 00111 0001000 0001001 0001010 0001011 0001100 0001101 0001110 0001111

this string is NOT happening (anymore?)
; 10100110010000101001100011100010000001001000101000010110001100000110100011100001111

Code: Select all

; an elias-gamma format Z80 routine 
; DE holds SOURCE, hl holds DESTINY

; LATER to be INCLUDEd as ASM or BIN

; Eliasgammaloop-0068
; pasmo -d --bin Eliasgammaloop-0068.asm Eliasgammaloop-0068.bin Eliasgammaloop-0068.symbol

; pasmo -d --tapbas --name Elias-0068 Eliasgammaloop-0068.asm Eliasgammaloop-0068.tap Eliasgammaloop-0068.symbol

;  10 CLEAR 25499: LOAD ""CODE 
;  40 BORDER 4: CLS : GO SUB 200: RANDOMIZE USR 25500
;  50 PAUSE 0: RANDOMIZE USR mirrorscreen
; 150 STOP 
; 200 LET x=0: FOR g=1 TO 8: FOR f=1 TO 32: LET x=NOT x: PRINT  BRIGHT x;" ";: NEXT f: LET x=NOT x: NEXT g
; 210 RETURN 


;source        equ 0        ; lets elias the ROM
;length        equ 2048     ; lets try some more then 1 byte


destiny       equ 16384    ; lets dump the string on screen

here          equ 25500    ; 16k rules, leave some stack


              org here

              di
              exx
              push hl             ; save sysvar

              ld bc,length2
              ld de,source2
              ld hl,destiny

eliasloop     push bc             ; store counter
              push de             ; store source

              call elias          ; MIND HL WILL raise per BIT, should be

              pop de              ; 
              inc de              ; raise source adres

              pop bc
              dec bc              ; source counter
              ld a,b
              or c
              jr nz,eliasloop
              ld b,h
              ld c,l
              pop hl              ; fetch sysvar
              push bc
              exx
              pop bc              ; last adres of destiny
              ei
              ret



; HL= destiny, DE=source
elias:        ld a,(golomb)
              ld c,a              ; c=0 or 1

              ld a,(de)           ; elias source
              add a,c
              jr z,done           ; on elias = 0 or golomb=255 (255+1)

              ld b,8
              ld c,1              ; gamma 1st %00000001
count0        rrc c               ;  > c gamma 1st=%10000000
              sla a               ; c<7-6543210-<0  %xxxx0000
              jr c,gammafound
              djnz count0         ; will b=0 happen , nope
gammafound    equ $               ; b=2^(b-1) value and c is gammabit position
                                  ; a holds remains after the gamma bit
                                  ; a= %xxxxxxx0 to %00000000

              ld (remains),a      ; every bit AFTER the gamma bit
              ld a,b
              ld (gammabit),a     ;   1 to 8 , position as value
              ld a,c              ;                         87654321
              ld (lastgamma),a    ;   position inside byte %0000000x

; set a bit at a time, just keep counting, start at BIT 0, BYTE 0
; for NOW this is the first step for the first bit of the first eliasgamma of the eliasgammabitstring 
; starting at 0bit,0byte

             ; ld a,(lastgamma)
              call mirrad         ; return with d set

              ld a,(gammabit)     ;
              ld b,a              ; counter in b
              call setbits        ; b and d are set now

              ld a,(remains)      ;
              ld d,a              ; last bits to be fixed, 0 and 1
              sla d               ; purge gamma bit

              ld a,(gammabit)     ;
              ld b,a              ; counter in b, 1 to much or ends on the NEXT free BIT

              call setbits        ; b and d SET, is the position set correct
done          equ $
              ret


setbits:
; d = bitrow  b = counter
; (hl) = destiny
; uses a,b,c,d,e,(hl)

              ld a,(bits)
              ld c,a
              cpl
              ld e,a

              ld a,(hl)           ; fetch DESTINY BYTE in a
bitz          sla d               ; purge data bits
              jr nc,fix0

fix1          or c                ; set a '1'
              rlc e
              rlc c
              jr checkhl

fix0          and e               ; set a '0'
              rlc e
              rlc c

checkhl       jr nc,ntyt          ; c/nc from C
              ld (hl),a
              inc hl
              ld a,(hl)
ntyt          dec b
              jr c,bbdone
              jr nz,bitz

bbdone        ld a,c
              ld (bits),a
              ret


; MIRROR BYTE A in D
; needs A set, delivers D
; uses A,B,D
mirrad:       ld b,8
mkd           sla a         ; a to be mirrord
              rr d          ; carry IN a 1 or 0
              djnz mkd      ; always 8 bits
              ret           ; return with D set

mirrorscreen:
              ld hl,16384
              ld de,6144
nextmirror    ld a,(hl)
              call mirrad
              ld (hl),d
              inc hl
              dec de
              ld a,d
              or e
              jr nz,nextmirror
              ret

; Elias value elias+1
golomb        defb 0              ; use value elias0 on golomb=1 OR not on golomb=0


lastgamma     defb 0              ; starting with bit 0
remains       defb 0
gammabit      defb 0              ; b = number
bits          defb 1              ; b=next free bit POSITION in the string from 1 to 8 %87654321

source2 defb 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
sourc2end equ $
length2 equ sourc2end-source2

;  eliasgamma string with 1 to 15 should be 84 bits from which 32 set
;  1 010 011 00100 00101 00110 00111 0001000 0001001 0001010 0001011 0001100 0001101 0001110 0001111
;  10100110010000101001100011100010000001001000101000010110001100000110100011100001111


END here
User avatar
Einar Saukas
Bugaboo
Posts: 3158
Joined: Wed Nov 15, 2017 2:48 pm

Re: starting with elias-gamma

Post by Einar Saukas »

I wrote this code in C some time ago:

Code: Select all

void write_classic_elias_gamma(int value) {
    int i = 1;
    while ((i <<= 1) <= value)
        write_bit(0);
    while (i >>= 1)
        write_bit(value & i);
}
Same algorithm, more user friendly listing:

Code: Select all

void write_classic_elias_gamma(int value) {
    int i = 2;
    while (i <= value) {
        write_bit(0);
        i = 2*i;
    }
    do {
        i = i/2;
        write_bit(value & i);
    } while (i > 1);
}
It may help you to have a reference.


PS: Function write_bit must produce 0 if argument is zero, 1 if argument is not zero.
C.Born
Manic Miner
Posts: 239
Joined: Sat Dec 09, 2017 4:09 pm

Re: starting with elias-gamma

Post by C.Born »

Einar Saukas wrote: Tue Apr 23, 2024 10:56 pm I wrote this code in C some time ago:

Code: Select all

void write_classic_elias_gamma(int value) {
    int i = 1;
    while ((i <<= 1) <= value)
        write_bit(0);
    while (i >>= 1)
        write_bit(value & i);
}
Same algorithm, more user friendly listing:

Code: Select all

void write_classic_elias_gamma(int value) {
    int i = 2;
    while (i <= value) {
        write_bit(0);
        i = 2*i;
    }
    do {
        i = i/2;
        write_bit(value & i);
    } while (i > 1);
}
It may help you to have a reference.


PS: Function write_bit must produce 0 if argument is zero, 1 if argument is not zero.
thank you, in C every thing is ordered at the background just like with basic.
but in asm most should be assimple as the c shows. i do some double or forget one step, i just have a look again later. cheers
C.Born
Manic Miner
Posts: 239
Joined: Sat Dec 09, 2017 4:09 pm

Re: starting with elias-gamma

Post by C.Born »

in C you dont have to concider that DEC B does NOT influence the carry
User avatar
ParadigmShifter
Manic Miner
Posts: 673
Joined: Sat Sep 09, 2023 4:55 am

Re: starting with elias-gamma

Post by ParadigmShifter »

Well use the C as a guide. Of course a decent optimising compiler knows tricks involving inc, dec, carry and such but I don't know if the C compiler for Z80 has a decent optimiser or not.

DEC does set the S flag so you can JP M instead where you would normally get a carry via SUB 1. (In 8 bit DEC anyway, 16 bit DEC preserves all flags).

EDIT: You can of course use inline ASM in C anyway if you want the benefits(?) of parameter passing (consult docs as to how parameters are passed to functions first of course, different calling conventions are available as well (maybe fastcall or something?). And there should be C vs. Pascal calling conventions available too if you do need to use stack for params (Pascal args are pushed to stack in the opposite order to C functions, which is why you can't have a varargs function in Pascal but you can in C).
C.Born
Manic Miner
Posts: 239
Joined: Sat Dec 09, 2017 4:09 pm

Re: starting with elias-gamma

Post by C.Born »

the pupuse is an pure Z80 eliasgamma

and i have to WRITE the final result, aswell , ....
one ld (hl),a to few, now repaired and working, pheew
! :roll:

Code: Select all

; an elias-gamma format Z80 routine 
; DE holds SOURCE, hl holds DESTINY

; LATER to be INCLUDEd as ASM or BIN

; Eliasgammaloop-0076
; pasmo -d --tapbas --name Elias-0076 Eliasgammaloop-0076.asm Eliasgammaloop-0076.tap Eliasgammaloop-0076.symbol
; pasmo -d --bin Eliasgammaloop-0076.asm Eliasgammaloop-0076.bin Eliasgammaloop-0076.symbol

;  10 CLEAR 25499: LOAD ""CODE 
;  40 BORDER 4: CLS : RANDOMIZE USR 25500
;  50 RANDOMIZE USR mirrorscreen


;source        equ 0        ; lets elias the ROM
;length        equ 2048     ; lets try some more then 1 byte


destiny       equ 16384    ; lets dump the string on screen (and then mirror screen per byte)

here          equ 25500    ; 16k rules, leave some stack


              org here

              di
              exx
              push hl             ; save sysvar

              ld a,1              ; set start position on bit0
              ld (bits),a

              ld bc,length2
              ld de,source2
              ld hl,destiny

eliasloop     push bc             ; store counter
              push de             ; store source

              call elias          ; MIND HL WILL raise per BIT, should be

              pop de              ; 
              inc de              ; raise source adres

              pop bc
              dec bc              ; source counter
              ld a,b
              or c
              jr nz,eliasloop
              ld b,h
              ld c,l              ; store last used destiny adres
              pop hl              ; fetch sysvar
              push bc             ; save last destiny on stack
              exx                 ; set sysvar
              pop bc              ; fetch adres for "LET ad=USR elias"
              ei
              ret



; HL= destiny, DE=source
elias:        ld a,(golomb)
              ld c,a              ; c=0 or 1

              ld a,(de)           ; elias source
              add a,c
              jr z,done           ; on elias = 0 or golomb=255 (elias254+1)


              ld b,8
              ld c,1              ; gamma 1st %00000001
count0        rrc c               ;  > c gamma 1st=%10000000
              sla a               ; c<7-6543210-<0  %xxxx0000
              jr c,gammafound
              djnz count0         ; will b=0 happen , nope
gammafound    equ $               ; b=2^(b-1) value and c is gammabit position
                                  ; a holds remains after the gamma bit
                                  ; a= %xxxxxxx0 to %00000000

              ld (remains),a      ; every bit AFTER the gamma bit
              ld a,b
              ld (gammabit),a     ;   1 to 8 , position as value
              ld a,c              ;                         87654321
;              ld (lastgamma),a    ;   position inside byte %0000000x

; set a bit at a time, just keep counting, start at BIT 0, BYTE 0
; for NOW this is the first step for the first bit of the first eliasgamma of the eliasgammabitstring 
; starting at 0bit,0byte

             ; ld a,(lastgamma)
mird          call mirrad         ; return with d set, b=0

              ld a,(gammabit)     ;
              ld b,a              ; counter in b

              call setbits        ; b and d are set now

rems          ld a,(remains)      ;
              ld d,a              ; last bits to be fixed, 0 and 1

              ld a,(gammabit)     ;
              ld b,a              ; counter in b, 1 to much or ends on the NEXT free BIT
              dec a
              jr z,done
              dec b
              call setbits        ; b and d SET, is the position set correct

done          equ $
              ret


; d = bitrow  b = counter
; (hl) = destiny
; uses a,b,c,d,e,(hl)
setbits       ld a,(bits)
              ld c,a         ;%0000x000
              cpl
              ld e,a         ;%xxxx0xxx

              ld a,(hl)           ; fetch DESTINY BYTE in a

bitz          sla d               ; purge data bits
              jr nc,fix0

fix1          or c                ; set a '1'
              jr checkce

fix0          and e               ; set a '0'

checkce       rlc e
              rlc c
              jr nc,ntyt          ; c/nc from C
              ld (hl),a           ; bits = %00000001
              inc hl
              ld a,(hl)

ntyt          djnz bitz

bbdone        ld (hl),a
              ld a,c              ; c moved at least 1 position
              ld (bits),a         ; store 1st free bit
              ret


; MIRROR BYTE A in D
; needs A set, delivers D
; uses A,B,D
mirrad:       ld b,8
mkd           sla a         ; a to be mirrord
              rr d          ; carry IN a 1 or 0
              djnz mkd      ; always 8 bits
              ret           ; return with D set

mirrorscreen:
              ld hl,16384
              ld de,6144
nextmirror    ld a,(hl)
              call mirrad
              ld (hl),d
              inc hl
              dec de
              ld a,d
              or e
              jr nz,nextmirror
              ret

; Elias value elias+1
golomb        defb 0              ; use value elias0 on golomb=1 OR not on golomb=0


;lastgamma     defb 0              ; starting with bit 0
remains       defb 0
gammabit      defb 0              ; b = number
bits          defb 1              ; b=next free bit POSITION in the string from 1 to 8 %87654321

source2 defb 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
sourc2end equ $
length2 equ sourc2end-source2

;  eliasgamma string with 1 to 15 should be 84 bits from which 32 set
;  1 010 011 00100 00101 00110 00111 0001000 0001001 0001010 0001011 0001100 0001101 0001110 0001111
;  10100110010000101001100011100010000001001000101000010110001100000110100011100001111


END here

thr reduced file apear 94 bytes

Code: Select all

; pasmo -d --bin EliasGamma.asm EliasGamma.bin EliasGamma.symbol

; HL= destiny, DE=source
; needs, Golomb, remains, gammabit, bits
elias:        ld a,(golomb)
              ld c,a              ; c=0 or 1

              ld a,(de)           ; elias source
              add a,c
              jr z,done           ; on elias = 0 or golomb=255 (elias254+1)


              ld b,8
              ld c,1              ; gamma 1st %00000001
count0        rrc c               ;  > c gamma 1st=%10000000
              sla a               ; c<7-6543210-<0  %xxxx0000
              jr c,gammafound
              djnz count0         ; will b=0 happen , nope
gammafound    equ $               ; b=2^(b-1) value and c is gammabit position
                                  ; a holds remains after the gamma bit
                                  ; a= %xxxxxxx0 to %00000000

              ld (remains),a      ; every bit AFTER the gamma bit
              ld a,b
              ld (gammabit),a     ;   1 to 8 , position as value

              ld a,c              ;

mirrad:       ld b,8
mkd           sla a         ; a to be mirrord
              rr d          ; carry IN a 1 or 0
              djnz mkd      ; always 8 bits

              ld a,(gammabit)     ;
              ld b,a              ; counter in b

              call setbits        ; b and d are set now

rems          ld a,(remains)      ;
              ld d,a              ; last bits to be fixed, 0 and 1

              ld a,(gammabit)     ;
              ld b,a              ; counter in b, 1 to much or ends on the NEXT free BIT
              dec b
              jr z,done
              call setbits        ; b and d SET, is the position set correct

done          equ $
              ret


; d = bitrow  b = counter
; (hl) = destiny
; uses a,b,c,d,e,(hl)
setbits       ld a,(bits)
              ld c,a         ;%0000x000
              cpl
              ld e,a         ;%xxxx0xxx

              ld a,(hl)           ; fetch DESTINY BYTE in a

bitz          sla d               ; purge data bits
              jr nc,fix0

fix1          or c                ; set a '1'
              jr checkce

fix0          and e               ; set a '0'

checkce       rlc e
              rlc c
              jr nc,ntyt          ; c/nc from C
              ld (hl),a           ; bits = %00000001
              inc hl
              ld a,(hl)

ntyt          djnz bitz

bbdone        ld (hl),a
              ld a,c              ; c moved at least 1 position
              ld (bits),a         ; store 1st free bit
              ret

remains       defb 0
gammabit      defb 0              ; b = number
bits          defb 1              ; b=next free bit POSITION in the string from 1 to 8 %87654321
golomb        defb 0              ; use value elias0 on golomb=1 OR not on golomb=0
C.Born
Manic Miner
Posts: 239
Joined: Sat Dec 09, 2017 4:09 pm

Re: starting with elias-gamma

Post by C.Born »

down to 82 bytes for the single eliasgamma

Code: Select all


; pasmo -d --bin EliasGamma.asm EliasGamma.bin EliasGamma.symbol

; HL= destiny, DE=source
; needs, Golomb, Bits

elias:        ld a,(golomb)
              ld c,a              ; c=0 or 1

              ld a,(de)           ; elias source
              add a,c
              jr z,done           ; on elias = 0 or golomb=255 (elias254+1)

              ld b,8
              ld c,1              ; gamma 1st %00000001
count0        rrc c               ;  > c gamma 1st=%10000000
              sla a               ; c<7-6543210-<0  %xxxx0000
              jr c,gammafound
              djnz count0         ; will b=0 happen , nope
gammafound    equ $               ; b=2^(b-1) value and c is gammabit position
                                  ; a holds remains after the gamma bit
                                  ; a= %xxxxxxx0 to %00000000
              push bc
              push af

              ld a,c              ;
              ld b,8
mkd           sla a         ; a to be mirrord
              rr d          ; carry IN a 1 or 0
              djnz mkd      ; always 8 bits

              pop af
              pop bc
              push bc
              push af

              call setbits        ; b and d are set now
                 
              pop af
              pop bc

              ld d,a              ; last bits to be fixed, 0 and 1
              dec b
              jr z,done
              call setbits        ; b and d SET, is the position set correct

done          equ $
              ret


; d = bitrow  b = counter
; (hl) = destiny
; uses a,b,c,d,e,(hl)
setbits       ld a,(bits)
              ld c,a         ;%0000x000
              cpl
              ld e,a         ;%xxxx0xxx

              ld a,(hl)           ; fetch DESTINY BYTE in a

bitz          sla d               ; purge data bits
              jr nc,fix0

fix1          or c                ; set a '1'
              jr checkce

fix0          and e               ; set a '0'

checkce       rlc e
              rlc c
              jr nc,ntyt          ; c/nc from C
              ld (hl),a           ; bits = %00000001
              inc hl
              ld a,(hl)

ntyt          djnz bitz

              ld (hl),a
              ld a,c              ; c moved at least 1 position
              ld (bits),a         ; store 1st free bit
              ret

bits          defb 1              ; b=next free bit POSITION in the string from 1 to 8 %87654321
golomb        defb 0              ; use value elias0 on golomb=1 OR not on golomb=0

and it needs the main loop ofcourse

Code: Select all


; an elias-gamma format Z80 routine 
; DE holds SOURCE, hl holds DESTINY



; Eliasgammaloop   ; NEEDS EliasGamma.asm

; pasmo -d --tapbas --name Eliasgamma Eliasgammaloop.asm Eliasgammaloop.tap Eliasgammaloop.symbol

;  10 CLEAR 25499: LOAD ""CODE 
;  40 BORDER 4: CLS: RANDOMIZE USR 25500
;  50 RANDOMIZE USR mirrorscreen

;source        equ 0        ; lets elias the ROM
;length        equ 2048     ; lets try some more then 1 byte


destiny       equ 16384    ; lets dump the string on screen (and then mirror screen per byte)

here          equ 25500    ; 16k rules, leave some stack


              org here

              di
              exx
              push hl             ; save sysvar

              ld a,1              ; set start position on bit0
              ld (bits),a

              ld bc,length2
              ld de,source2
              ld hl,destiny

eliasloop     push bc             ; store counter
              push de             ; store source

              call elias          ; MIND HL WILL raise per BIT, should be

              pop de              ; 
              inc de              ; raise source adres

              pop bc
              dec bc              ; source counter
              ld a,b
              or c
              jr nz,eliasloop
              ld b,h
              ld c,l              ; store last used destiny adres
              pop hl              ; fetch sysvar
              push bc             ; save last destiny on stack
              exx                 ; set sysvar
              pop bc              ; fetch adres for "LET ad=USR elias"
              ei
              ret


INCLUDE EliasGamma.asm


mirrorscreen:
              ld hl,16384
              ld de,6144
nextmirror    ld a,(hl)
              ld b,8
mks           sla a         ; a to be mirrord
              rr d          ; carry IN a 1 or 0
              djnz mks      ; always 8 bits
              ld (hl),d
              inc hl
              dec de
              ld a,d
              or e
              jr nz,nextmirror
              ret


source2 defb 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
sourc2end equ $
length2 equ sourc2end-source2

;  eliasgamma string with 1 to 15 is 84 bits from which 32 set
;  1 010 011 00100 00101 00110 00111 0001000 0001001 0001010 0001011 0001100 0001101 0001110 0001111
;  10100110010000101001100011100010000001001000101000010110001100000110100011100001111


END here

C.Born
Manic Miner
Posts: 239
Joined: Sat Dec 09, 2017 4:09 pm

Re: starting with elias-gamma

Post by C.Born »

i added 1 byte to wipe the old contence of (hl),much better!
and changed the label from "notyet" ntyt to "next b" nexb,

Code: Select all

checkce       rlc e
              rlc c
              jr nc,nexb          ; c/nc from C
              ld (hl),a           ; bits = %00000001
              inc hl              ; new destiny byte
              xor a               ;
              ld (hl),a           ; wipe old data first
nexb          djnz bitz
C.Born
Manic Miner
Posts: 239
Joined: Sat Dec 09, 2017 4:09 pm

Re: starting with elias-gamma

Post by C.Born »

about interlaced eliasgamma
is the Zeta-Xi-Code what you refer to?
https://github.com/einar-saukas/Zeta-Xi-Code

Code: Select all

Number N      Number N+1   Bits  Classic Elias Gamma Code          Interlaced Elias Gamma Code
0             1              1   1                                 1
1-2           2-3            3   01x                               0x1
3-6           4-7            5   001xx                             0x0x1
7-14          8-15           7   0001xxx                           0x0x0x1
15-30         16-31          9   00001xxxx                         0x0x0x0x1
31-62         32-63         11   000001xxxxx                       0x0x0x0x0x1
63-126        64-127        13   0000001xxxxxx                     0x0x0x0x0x0x1
127-254       128-255       15   00000001xxxxxxx                   0x0x0x0x0x0x0x1
255-510       256-511       17   000000001xxxxxxxx                 0x0x0x0x0x0x0x0x1
511-1022      512-1023      19   0000000001xxxxxxxxx               0x0x0x0x0x0x0x0x0x1
1023-2046     1024-2047     21   00000000001xxxxxxxxxx             0x0x0x0x0x0x0x0x0x0x1
2047-4094     2048-4095     23   000000000001xxxxxxxxxxx           0x0x0x0x0x0x0x0x0x0x0x1
4095-8190     4096-8191     25   0000000000001xxxxxxxxxxxx         0x0x0x0x0x0x0x0x0x0x0x0x1
8191-16382    8192-16383    27   00000000000001xxxxxxxxxxxxx       0x0x0x0x0x0x0x0x0x0x0x0x0x1
16383-32766   16384-32767   29   000000000000001xxxxxxxxxxxxxx     0x0x0x0x0x0x0x0x0x0x0x0x0x0x1
32767-65534   32768-65535   31   0000000000000001xxxxxxxxxxxxxxx   0x0x0x0x0x0x0x0x0x0x0x0x0x0x0x1
User avatar
Einar Saukas
Bugaboo
Posts: 3158
Joined: Wed Nov 15, 2017 2:48 pm

Re: starting with elias-gamma

Post by Einar Saukas »

There are more options in the Zeta-Xi Code link but uou can ignore them.

This table you copied is all you need.
C.Born
Manic Miner
Posts: 239
Joined: Sat Dec 09, 2017 4:09 pm

Re: starting with elias-gamma

Post by C.Born »

Einar Saukas wrote: Sun Apr 28, 2024 2:02 am There are more options in the Zeta-Xi Code link but uou can ignore them.

This table you copied is all you need.
Ok, then i need the R1 format up to 8 bits , for now ?zx0 is 8bits only?

Code: Select all

0             1              1   1                                 1
1-2           2-3            3   01x                               0x1
3-6           4-7            5   001xx                             0x0x1
7-14          8-15           7   0001xxx                           0x0x0x1
15-30         16-31          9   00001xxxx                         0x0x0x0x1
31-62         32-63         11   000001xxxxx                       0x0x0x0x0x1
63-126        64-127        13   0000001xxxxxx                     0x0x0x0x0x0x1
127-254       128-255       15   00000001xxxxxxx                   0x0x0x0x0x0x0x1
it forms a nice partern with al lot off equal 2bits parts, 00 and 01
do you half them in to 0 and 1 only, or thus that give counting promblems?
it always end with an' 1' and almost always starts with a '0' except for the single VALUE 1
well, first give it a try to have a double gamma wrench
cheers
C.Born
Manic Miner
Posts: 239
Joined: Sat Dec 09, 2017 4:09 pm

Re: starting with elias-gamma

Post by C.Born »

first interlaced attempt, seems close but i dont know

usr 25648 for mirror bytes on screen

Code: Select all

; ElIntGam-005
; save as ElIntGam.asm to INCLUDE in EliasGammaCode.asm or other loops
; pasmo -d --bin ElIntGam-005.asm ElIntGam-005.bin ElIntGam-005.symbol

; Interlaced Elias-gamma
;https://github.com/einar-saukas/Zeta-Xi-Code

;Interlaced (8bit r1 nivo only)
;Number N      Number N+1   Bits  Classic Elias Gamma Code          Interlaced Elias Gamma Code
;0             1              1   1                                 1
;1-2           2-3            3   01x                               0x1
;3-6           4-7            5   001xx                             0x0x1
;7-14          8-15           7   0001xxx                           0x0x0x1
;15-30         16-31          9   00001xxxx                         0x0x0x0x1
;31-62         32-63         11   000001xxxxx                       0x0x0x0x0x1
;63-126        64-127        13   0000001xxxxxx                     0x0x0x0x0x0x1
;127-254       128-255       15   00000001xxxxxxx                   0x0x0x0x0x0x0x1

;  eliasgamma string with 1 to 15 is 84 bits from which 32 set
;  1 010 011 00100 00101 00110 00111 0001000 0001001 0001010 0001011 0001100 0001101 0001110 0001111
;  10100110010000101001100011100010000001001000101000010110001100000110100011100001111
;  interlaced
;  1 001 011 00001 00011 01001 01011 0000001 0000011 0001001 0001011 0100001 0100011 0101001 0101011
;  10010110000100011010010101100000010000011000100100010110100001010001101010010101011


; HL= destiny, DE=source
; needs, Golomb, Bits

seed equ 23670

elias:        ld a,(golomb)
              ld c,a              ; c=0 or 1

              ld a,(de)           ; elias source
              add a,c
              jr z,done           ; on elias = 0 or golomb=255 (elias254+1)

              ld b,8
              ld c,1              ; gamma 1st %00000001
count0        rrc c               ;  > c gamma 1st=%10000000
              sla a               ; c<7-6543210-<0  %xxxx0000
              jr c,gammafound
              djnz count0         ; will b=0 happen , nope
gammafound    equ $               ; b=2^(b-1) value and c is gammabit position
                                  ; a holds remains after the gamma bit
                                  ; a= %xxxxxxx0 to %00000000
              push bc
              push af

              ld a,c              ;
              ld b,8
mkd           sla a         ; a to be mirrord
              rr d          ; carry IN  1 or 0
              djnz mkd      ; always 8 bits

              pop af
              pop bc

              call Interlace_bits        ; b and d are set now

done          equ $
              ret


; d = bitrow  b = counter, a=remains
; (hl) = destiny
; uses a,a' ,b,c,d,e,(hl)

Interlace_bits
              ex af,af'      ; remains is in a'

              ld a,(bits)

              ld c,a         ; %0000x000
              cpl
              ld e,a              ; %xxxx0xxx

              ld a,(hl)           ; fetch DESTINY BYTE in a

bitz0         sla d               ; purge data '0' bits
              jr nc,fix0

fix1          or c                ; set a '1'
              jr checkce

fix0          and e               ; set a '0'

checkce       rlc e
              rlc c
              jr nc,nexb          ; c/nc from C
              ld (hl),a           ; bits = %00000001
              inc hl              ; new destiny byte
              xor a               ;
              ld (hl),a           ; wipe old data first
nexb          equ $

              push de             ; save d, e remains equal=problem
              ex af,af'
              ld d,a
              sla a       ; a must shift as much as d
              ex af,af'   ;
bitz1         sla d       ; purge data '0' bits
              jr nc,fix_0

fix_1          or c                ; set a '1'
              jr check_ce

fix_0          and e               ; set a '0'

check_ce      rlc e
              rlc c
              jr nc,nex_b          ; c/nc from C
              ld (hl),a           ; bits = %00000001
              inc hl              ; new destiny byte
              xor a               ;
              ld (hl),a           ; wipe old data first
nex_b          equ $

              push af
              ld a,e
              ld (seed),a
              pop af

              pop de    ; pop old d, better store 'd' it self ??

              push af
              ld a,(seed)
              ld e,a       ; restore BIT POSITION in e
              pop af


              djnz bitz0
              ld (hl),a

              ld a,c              ; c moved at least 1 position
              ld (bits),a         ; store 1st free bit
              ret

bits          defb 1              ; b=next free bit POSITION in the string from 1 to 8 %87654321
golomb        defb 0              ; use value elias0 on golomb=1 OR not on golomb=0

and the loop is renamed to Code

Code: Select all

; an Elias Gamma Code Z80 routine
; DE holds SOURCE, HL holds DESTINY, BC returns to basic with last adres of destiny

; EliasGammaCode_001   ; NEEDS EliasGamma.asm or ElIntGam.asm

; pasmo -d --tapbas --name Eliasgamma EliasGammaCode_001.asm EliasGammaCode_001.tap EliasGammaCode_001.symbol

;  10 CLEAR 25499: LOAD ""CODE 
;  40 BORDER 4: CLS: RANDOMIZE USR 25500
;  50 RANDOMIZE USR mirrorscreen

; source        equ 0        ; lets elias the ROM
; length        equ 2048     ; lets try some more then 1 byte

;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
interlaced equ 1    ; writes a different Elias type !!


destiny       equ 16384    ; lets dump the string on screen (and then mirror screen per byte)

here          equ 25500    ; 16k rules, leave some stack


              org here

              di
              exx
              push hl             ; save sysvar

              ld a,1              ; set start position on bit0
              ld (bits),a

              ld bc,length2
              ld de,source2
              ld hl,destiny

eliasloop     push bc             ; store counter
              push de             ; store source

              call elias          ; MIND HL WILL raise per BIT, should be

              pop de              ; 
              inc de              ; raise source adres

              pop bc
              dec bc              ; source counter
              ld a,b
              or c
              jr nz,eliasloop
              ld b,h
              ld c,l              ; store last used destiny adres
              pop hl              ; fetch sysvar
              push bc             ; save last destiny on stack
              exx                 ; set sysvar
              pop bc              ; fetch adres for "LET ad=USR elias"
              ei
              ret

IF interlaced=1
INCLUDE ElIntGam.asm
ENDIF

IF interlaced=0
INCLUDE EliasGamma.asm
ENDIF

mirrorscreen:
              ld hl,16384
              ld de,6144
nextmirror    ld a,(hl)
              ld b,8
mks           sla a         ; a to be mirrord
              rr d          ; carry IN a 1 or 0
              djnz mks      ; always 8 bits
              ld (hl),d
              inc hl
              dec de
              ld a,d
              or e
              jr nz,nextmirror
              ret


source2 defb 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
sourc2end equ $
length2 equ sourc2end-source2

;  eliasgamma string with 1 to 15 is 84 bits from which 32 set
;  1 010 011 00100 00101 00110 00111 0001000 0001001 0001010 0001011 0001100 0001101 0001110 0001111
;  10100110010000101001100011100010000001001000101000010110001100000110100011100001111


END here
User avatar
Einar Saukas
Bugaboo
Posts: 3158
Joined: Wed Nov 15, 2017 2:48 pm

Re: starting with elias-gamma

Post by Einar Saukas »

C.Born wrote: Sun Apr 28, 2024 2:02 pm zx0 is 8bits only?
No, it uses 16 bits in Elias Gamma coding.
C.Born
Manic Miner
Posts: 239
Joined: Sat Dec 09, 2017 4:09 pm

Re: starting with elias-gamma

Post by C.Born »

i wrote an DEF FN entry, it works nice with the classic eliasgamma included

it needs its own DEF FN statement in basic, ofcourse
EliasDEF.bas

Code: Select all

   1 DEF FN p(a)=PEEK a+256*PEEK (a+SGN PI)
   5 DEF FN a(s,d,l,g)=USR el
  10 CLEAR VAL "25499": LET el=FN p(VAL "23730")+SGN PI: LOAD ""CODE el
  15 LET b=NOT PI: LET b$=""
  20 FOR f=SGN PI TO CODE " ": LET b$=b$+CHR$ VAL "19"+CHR$ b+" ": LET b=NOT b: NEXT f
  25 IF LEN b$ < VAL "97" THEN LET b=NOT b: GO TO VAL "20"
  30 BORDER INT PI: CLS : PRINT b$
  37 LET s=VAL"0": LET d=VAL"16384": LET l=VAL "2048": LET g=VAL"1"
  40 LET last=FN a(s,d,l,g)
  45 SAVE "elias$" CODE d,last-d

Code: Select all

; a.d. 2024 Chris Born

; an Elias Gamma Code Z80 routine
; DE holds SOURCE, HL holds DESTINY, BC returns to basic with last adres of destiny

; Elias Gamma ENCoding
; https://en.wikipedia.org/wiki/Elias_gamma_coding

; EliasGammaCode_005   ; NEEDS EliasGamma.asm or ElIntGam.asm

; pasmo -d --tap --name Eliasgamma EliasGammaCode_005.asm EliasGammaCode_005.tap EliasGammaCode_005.symbol
; cat Eliasbas.tap EliasGammaCode_005.tap > EGC_005.tap


; BASIC LOADER with DEF FN ENTRY for variables FROM BASIC into MC
;  Eliasbas.bas
;   1 DEF FN p(a)=PEEK a+256*PEEK (a+SGN PI)
;   5 DEF FN a(s,d,l,g)=USR el
;  10 CLEAR VAL "25499": LET el=FN p(VAL "23730")+SGN PI: LOAD ""CODE el
;  15 LET b=NOT PI: LET b$=""
;  20 FOR f=SGN PI TO CODE " ": LET b$=b$+CHR$ VAL "19"+CHR$ b+" ": LET b=NOT b: NEXT f
;  25 IF LEN b$ < VAL "97" THEN LET b=NOT b: GO TO VAL "20"
;  30 BORDER INT PI: CLS : PRINT b$
;  37 LET s=VAL"0": LET d=VAL"16384": LET l=VAL "2048": LET g=VAL"1"
;  40 LET last=FN a(s,d,l,g)
;  45 SAVE "elias$" CODE d,last-d
;  50 RANDOMIZE USR mirrorscreen


;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
interlaced equ 0    ; writes a different Elias type !!


destiny       equ 16384    ; lets dump the string on screen (and then mirror screen per byte)

here          equ 25500    ; 16k rules, leave some stack

DEF_ADR       equ 23563    ; sysvar


              org here

              di
              exx
              push hl           ; save sysvar

              ld hl,(DEF_ADR)   ; hl = actual RAM location in BASIC listing at position off the DEF FN
              ld bc,4           ;
              add hl,bc         ; adres+4
              ld e,(hl)         ;
              inc hl            ; adres+4+1
              ld d,(hl)         ;
              push de

              ld c,7            ;
              add hl,bc         ; adres+4+1+7
              ld e,(hl)         ;
              inc hl            ; adres+4+1
              ld d,(hl)         ;
              push de

              add hl,bc         ; adres+4+1+7+1+7
              ld e,(hl)         ;
              inc hl            ; adres+4+1
              ld d,(hl)         ;
              push de

              add hl,bc         ; adres+4+1+7+1+7+1+7
              ld a,(hl)         ;
              ld (golomb),a     ; set Elias+1

              ld a,1
              ld (bits),a       ; preset bits position with 1

              pop bc            ;   ld bc,length
              pop hl            ;   ld hl,destiny
              pop de            ;   ld de,source

eliasloop     push bc             ; store counter
              push de             ; store source

              call elias          ; MIND HL WILL raise per BIT, should be

              pop de              ; 
              inc de              ; raise source adres

              pop bc
              dec bc              ; source counter
              ld a,b
              or c
              jr nz,eliasloop
              ld b,h
              ld c,l              ; store last used destiny adres
              pop hl              ; fetch sysvar
              push bc             ; save last destiny on stack
              exx                 ; set sysvar
              pop bc              ; fetch adres for "LET ad=USR elias"
              ei
              ret

bits          defb 1              ; b=next free bit POSITION in the string from 1 to 8 %87654321
golomb        defb 0              ; use value elias0 on golomb=1 OR not on golomb=0


IF interlaced=1
INCLUDE ElIntGam.asm
ENDIF

IF interlaced=0
INCLUDE EliasGamma.asm
ENDIF

mirrorscreen:
              ld hl,16384
              ld de,6144
nextmirror    ld a,(hl)
              ld b,8
mks           sla a         ; a to be mirrord
              rr d          ; carry IN a 1 or 0
              djnz mks      ; always 8 bits
              ld (hl),d
              inc hl
              dec de
              ld a,d
              or e
              jr nz,nextmirror
              ret

END here

;source2 defb 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
;sourc2end equ $
;length2 equ sourc2end-source2

;  eliasgamma string with 1 to 15 is 84 bits from which 32 set
;  1 010 011 00100 00101 00110 00111 0001000 0001001 0001010 0001011 0001100 0001101 0001110 0001111
;  10100110010000101001100011100010000001001000101000010110001100000110100011100001111



C.Born
Manic Miner
Posts: 239
Joined: Sat Dec 09, 2017 4:09 pm

Re: starting with elias-gamma

Post by C.Born »

a little more smooth loop now giving data length for the DEF
i wonder i i should migrate the loading of the elias source to this loop routine, then the golomb has to be done there to, saving bytes in both included routines, but making them depending, a little.

Code: Select all

; a.d. 2024 Chris Born

; an Elias Gamma Code Z80 routine
; DE holds SOURCE, HL holds DESTINY, BC returns to basic with data length

; Elias Gamma ENCoding
; https://en.wikipedia.org/wiki/Elias_gamma_coding

; EliasGammaCode_007   ; NEEDS EliasGamma.asm or ElIntGam.asm

; pasmo -d --tap --name Eliasgamma EliasGammaCode_007.asm EliasGammaCode_007.tap EliasGammaCode_007.symbol
; cat EliasDEF.tap EliasGammaCode_007.tap > EGC_007.tap


; BASIC LOADER with DEF FN ENTRY for variables FROM BASIC into MC
; EliasDEF.bas
;   5 DEF FN a(s,d,l,g)=USR el: DEF FN p(a)=PEEK a+256*PEEK (a+SGN PI)
;  10 CLEAR VAL "25499": LET el=FN p(VAL "23730")+SGN PI: LOAD ""CODE el
;  30 LET s=VAL"0": LET d=VAL"16384": LET l=VAL "2048": LET g=VAL"1"
;  40 LET dat=FN a(s,d,l,g)
;  45 SAVE "elias$" CODE d,dat

; DEF FN a(
; s,   source
; d,   destiny
; l,   sourcelength
; g    Golomb  0 or 1
; )=USR el

;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
interlaced   equ 0    ; writes a different Elias type !!

mirrorscreen equ 0    ; extra routine to mirror per byte



here          equ 25500    ; 16k rules, leave some stack

DEF_ADR       equ 23563    ; sysvar


              org here

              di
              exx
              push hl             ; save sysvar

              ld hl,(DEF_ADR)     ; hl = actual RAM location in BASIC listing at position off the DEF FN
              ld bc,4             ;
              add hl,bc           ; adres+4
              ld e,(hl)           ;
              inc hl              ; adres+4+1
              ld d,(hl)           ;
              push de

              ld c,7              ;
              add hl,bc           ; adres+4+1+7
              ld e,(hl)           ;
              inc hl              ; adres+4+1
              ld d,(hl)           ;
              push de

              add hl,bc           ; adres+4+1+7+1+7
              ld e,(hl)           ;
              inc hl              ; adres+4+1
              ld d,(hl)           ;
              push de

              add hl,bc           ; adres+4+1+7+1+7+1+7
              ld a,(hl)           ;
              ld (golomb),a       ; set Elias+1

              ld a,1
              ld (bits),a         ; preset bits position with 1

              pop bc              ;   ld bc,length  (of the source)
              pop hl              ;   ld hl,destiny
              pop de              ;   ld de,source

              push hl             ; store destiny START on stack

eliasloop     push bc             ; store counter
              push de             ; store source




              call elias          ; MIND HL WILL raise per BIT, should be

              pop de              ; 
              inc de              ; raise source adres

              pop bc
              dec bc              ; source counter
              ld a,b
              or c
              jr nz,eliasloop
              ld b,h
              ld c,l              ; store last used destiny adres

              pop de              ; detch destinySTART
              pop hl              ; fetch sysvar
              push bc             ; save last destiny on stack
              push de
              exx                 ; set sysvar

              pop bc              ; destinySTART
              pop hl              ; fetch adres for "LET ad=USR elias"
              and a
              sbc hl,bc
              ld b,h
              ld c,l              ; store data length in BC as return
              
              ei
              ret

bits          defb 1              ; b=next free bit POSITION in the string from 1 to 8 %87654321
golomb        defb 0              ; use value elias0 on golomb=1 OR not on golomb=0


IF interlaced=0
   INCLUDE EliasGamma.asm
;  classic eliasgamma string with 1 to 15 is 84 bits from which 32 set
;  1 010 011 00100 00101 00110 00111 0001000 0001001 0001010 0001011 0001100 0001101 0001110 0001111
;  10100110010000101001100011100010000001001000101000010110001100000110100011100001111
ENDIF


IF interlaced=1
   INCLUDE ElIntGam.asm
;  interlaced eliasgamma string with 1 to 15 is 84 bits from which 32 set
;  1 001 011 00001 00011 01001 01011 0000001 0000011 0001001 0001011 0100001 0100011 0101001 0101011
;  10010110000100011010010101100000010000011000100100010110100001010001101010010101011
ENDIF


IF mirrorscreen
INCLUDE mirrorscreen.asm
ENDIF

END here
and i separated that mirror thing

Code: Select all

; pasmo -d --bin mirrorscreen.asm mirrorscreen.bin mirrorscreen.symbol

; NO ORG NEEDED

mirrorscreen:
              ld hl,16384
              ld de,6144
nextmirror    ld a,(hl)
              ld b,8
mks           sla a         ; a to be mirrord
              rr d          ; carry IN a 1 or 0
              djnz mks      ; always 8 bits
              ld (hl),d
              inc hl
              dec de
              ld a,d
              or e
              jr nz,nextmirror
              ret
Post Reply