CPCWiki forum

General Category => Programming => Topic started by: EgoTrip on 19:58, 21 March 13

Title: Basic BASIC compression
Post by: EgoTrip on 19:58, 21 March 13
Say I have a 2D array (DIM arr(16,16) that reads data into arr(a1,a2). The a1,a2 values are boolean.


Instead of having a DATA 1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0 and 15 other lines, I could have lines of  DATA &AA,&AA,etc which would save a lot of memory.


What is the best way to read each line from 2 hexadecimal numbers into the array? I am stuck converting them back.
Title: Re: Basic BASIC compression
Post by: TFM on 20:41, 21 March 13
You save space on the expenses of speed. I always do the opposite  :)
Title: Re: Basic BASIC compression
Post by: EgoTrip on 21:48, 21 March 13
Thanks for the helpful post.  ::)
Title: Re: Basic BASIC compression
Post by: db6128 on 22:00, 21 March 13
Disclaimer: untested, rusty BASIC skills, rusty brain, crazy brain, check out how I avoided using GOTO, and so on


numberOfBools%=10
DIM bool%(numberOfBools%)
boolsRead%=0
WHILE boolsRead%<numberOfBools%
  READ byte%
  FOR bit%=0 TO 7
    IF byte% AND 2↑bit% THEN bool%(boolsRead%)=1 ELSE bool%(boolsRead%)=0
    REM The ELSE... may be unnecessary: I cannot remember whether or not BASIC clears DIMensioned memory to 0
    boolsRead%=boolsRead%+1
    IF boolsRead%=numberOfBools% THEN bit%=8
  NEXT bit%
WEND
Title: Re: Basic BASIC compression
Post by: redbox on 16:28, 22 March 13
Quote from: EgoTrip on 19:58, 21 March 13
Instead of having a DATA 1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0 and 15 other lines, I could have lines of  DATA &AA,&AA,etc which would save a lot of memory.
What is the best way to read each line from 2 hexadecimal numbers into the array? I am stuck converting them back.

It's easy in assembler, using the BIT function.  This checks if a bit of a number (&AA, which is %10101010) is set or not.  Result is returned to the zero flag.


            org &4000

            ld    hl,table_compressed    ; location of compressed table
            ld    ix,table_expanded    ; location of expanded table buffer

            ld     b,2            ; number of bytes in compressed table

loop:            ld    a,(hl)            ; get byte from compressed table
            ld    c,a            ; put it in C to check it

            bit    7,c            ; check bit 7
            call    nz,bit_set        ; bit is set (i.e. 1)
            call    z,bit_not_set        ; bit is not set (i.e. 0)
            bit    6,c
            call    nz,bit_set       
            call    z,bit_not_set       
            bit    5,c
            call    nz,bit_set       
            call    z,bit_not_set       
            bit    4,c
            call    nz,bit_set       
            call    z,bit_not_set       
            bit    3,c
            call    nz,bit_set       
            call    z,bit_not_set       
            bit    2,c
            call    nz,bit_set       
            call    z,bit_not_set       
            bit    1,c
            call    nz,bit_set       
            call    z,bit_not_set       
            bit    0,c
            call    nz,bit_set       
            call    z,bit_not_set   

            inc     hl            ; increase compressed table address by 1

            djnz    loop            ; loop back if not finished

            ret   

bit_set:        ld    a,1            ; load A with 1
            ld    (ix),a            ; put byte into expanded table buffer
            inc    ix            ; increase expenaded table address by 1
            ret

bit_not_set:        ld    a,0
            ld    (ix),a
            inc    ix
            ret

table_compressed:    defb &aa,&aa

table_expanded:        defs 16


Assemble and CALL &4000 in BASIC.  Expanded table resides at &4061.

Title: Re: Basic BASIC compression
Post by: TFM on 17:59, 22 March 13
Quote from: EgoTrip on 21:48, 21 March 13
Thanks for the helpful post.  ::)
Well as Redbox told, it would be easy in assembler, but in Basic, I got no idea.
Title: Re: Basic BASIC compression
Post by: SRS on 12:28, 27 March 13
Ok, if I got you right - why not use bin$ ?

Quick'n Dirty ->


10 DIM b%(16,16)
20 L%=1
30 FOR loop%=1 TO 16
40 READ hd%:b$=BIN$(hd%):PRINT HEX$(hd%);" is ";b$;" is ";
50 FOR i%=1 TO 8:b%(i%,l%)=VAL(MID$(b$,i%,1)):PRINT b%(i%,l%);:NEXT
60 PRINT
70 READ hd%:b$=BIN$(hd%):PRINT HEX$(hd%);" is ";b$;" is ";
80 FOR i%=1 TO 8:b%(i%+8,l%)=VAL(MID$(b$,i%,1)):PRINT b%(i%,l%);:NEXT
90 l%=l%+1
100 PRINT CHR$(13)
110 NEXT loop%
120 DATA &aa,&cc,&12,&aa,&aa,&aa,&aa,&aa,&aa,&aa,&aa,&aa,&aa,&aa,&aa,&ff
130 DATA &aa,&cc,&12,&aa,&aa,&aa,&aa,&bb,&fc,&dd,&12,&cc,&12,&aa,&aa,&aa[attachimg=1][attach=2]
Title: Re: Basic BASIC compression
Post by: ralferoo on 14:14, 27 March 13
What SRS said, but you probably want BIN$(value,8) if you're using byte data...
Title: Re: Basic BASIC compression
Post by: db6128 on 15:59, 27 March 13
I started using string functions but decided that was ugly and went for arithmetic instead. Which I presume also has the advantage of being at least a bit faster. Anyway, I still haven't tested my code. Has anyone else? :P
Title: Re: Basic BASIC compression
Post by: ralferoo on 16:00, 27 March 13
Quote from: db6128 on 15:59, 27 March 13
I started using string functions but decided that was ugly and went for arithmetic instead. Which I presume also has the advantage of being at least a bit faster. Anyway, I still haven't tested my code. Has anyone else? :P

FOR i=1 TO 8
IF (x AND 128) THEN blah ELSE blah
x = x * 2
NEXT
Title: Re: Basic BASIC compression
Post by: arnoldemu on 18:37, 27 March 13
My contribution:


10 restore 1000
11 REM LOOP OVER BYTES
15 for i=0 to 3: REM number of bytes of data you have
16 REM READ BYTE
20 read a%
21 REM FOR EACH BYTE LOOP 8 TIMES (1 BIT PER TRUE/FALSE)
30 b%=&80:for b=0 to 8
31 REM GET BIT USING "MASK"
40 v% = a% AND b%
41 REM IF RESULT==0 THEN FALSE ELSE TRUE
50 if v%<>0 THEN PRINT "TRUE" ELSE PRINT "FALSE"
51 REM ADJUST "MASK"
50 b%=b%/2
60 NEXT
70 NEXT
80 data &88,&44,&22: REM your bit data, bit 7 to bit 0 (left to right as you would define a udg)
Title: Re: Basic BASIC compression
Post by: EgoTrip on 19:18, 27 March 13
Thanks for the help, I decided against this method in the end as it was tricky to get working, but I will come back to this if I decide to do a sequel.
Title: Re: Basic BASIC compression
Post by: db6128 on 02:13, 28 March 13
Quote from: ralferoo on 16:00, 27 March 13

FOR i=1 TO 8
IF (x AND 128) THEN blah ELSE blah
x = x * 2
NEXT

I wrote my own method already, without needing a temporary variable by using a loop from 0 to 7 over powers of 2. The code is up there. I just meant I had not been able to test it and was asking whether anyone had given it a try.
Powered by SMFPacks Menu Editor Mod