lda #$00 sta SCROLLPOS ... Mainloop: jsr Get5Bit ... Get5Bit: ldy SCROLLPOS lda scrolltext,y // Do magic // if necessary increase Y and store in SCROLLPOS .. rts scrolltext: (5-bit data packed into 8-bit bytes here)
get5bits: lda #$00 sta TMPBYTE1 ldx BITCOUNT ldy #$05 !loop: cpx #$08 bne !skip+ sty TMPBYTE3 ldy SCROLLPOS iny sty SCROLLPOS lda scrolltext,y sta TMPBYTE2 ldy TMPBYTE3 ldx #$00 !skip: asl TMPBYTE2 rol TMPBYTE1 inx dey bne !loop- stx BITCOUNT lda TMPBYTE1 rts
dec CHARCOUNT bpl :++ ldy #4 ldx scrolltextPos : lda scrolltext,x sta buffer,y inx dey bpl :- stx scrollTextPos lda #7 sta CHARCOUNT : ldy #4 lda #0 : rol buffer,y asl dey bpl :- rts
Now simply store bit0 bitpacked into byte0, bit1 bitpacked into byte1 etc.
Init sta .ptr+1 stx .ptr+2 lda #$80 sta buf rts Get5 lda #8 .1 asl buf bne .3 pha .ptr lda $1234 inc .ptr+1 bne .2 inc .ptr+2 .2 rol sta buf pla .3 rol bcc .1 rts
dec charCount bpl !+ ldx #4 ldy scrollTextPos !loop: lda scrollText,y sta buffer,x iny dex bpl !loop- sty scrollTextPos lda #7 sta charCount !: ldx #4 lda #0 !loop: asl buffer,x rol dex bpl !loop-
.macro packText(str) { .for (var i=0; i<str.size(); i=i+8) { .for (var byteNo=0; byteNo<5; byteNo++) { .var res = 0 .for (var bitNo=0; bitNo<8; bitNo++) { .var chrVal = 0 + str.charAt(i + 7 - bitNo) .var bitVal = chrVal & [$10 >> byteNo] .if (bitVal != 0) .eval bitVal = 1 .eval res = res | [bitVal << bitNo] } .by res } } }
pos4: lsr prev ror pos1: lsr prev ror pos6: lsr prev ror pos3: lsr prev ror pos0: lsr pos5: lsr pos2: lsr pos7: and #%00011111 rts
.zeropage ptr5bit: .res 2 ; pointer the byte _before_ your 5-bit compressed data, no page crossings. ; However, initializing this to $c0ff will start reading from $c000 offset: .res 1 ; initialize to 0 in your setup prev: .res 1 ; no init needed, holds the previous byte we're shifting from .code get5bit: ldy #0 ; seek to eliminate this from the caller lda offset adc #$03 and #$07 sta offset beq :+++ ; if offset = 0, skip all the shifting tax cpx #3 ; if offset >= 3, then we're spanning bytes (the =3 case makes sure we inc between spans) lda (zp),y bcc :++ ; not spanning bytes, just LSR the current byte sta prev ; shove the current byte into prev for byte-spanning inc zp lda (zp),y : lsr prev ; shift from the prior byte as much as needed ror dex cpx #2 bne :- : lsr ; shift up to the last 3 bytes within the current byte dex bpl :- and #%00011111 :rts