3 deleted 9 characters in body
source | link
         00 C0        .WORD $C000       ; load address
.C:c000  A9 27        LDA #$27          ; counter for newlines (39)
.C:c002  85 FB        STA $FB
.C:c004  A2 00        LDX #$00          ; index for run-length data
.C:c006  86 FC        STX $FC
.C:c008  A2 04        LDX #$04          ; index for "blocks" (counting down)
.C:c00a   .blockloop:
.C:c00a  CA           DEX
.C:c00b  10 01        BPL .continue     ; block index underflow -> done
.C:c00d  60           RTS
.C:c00e   .continue:
.C:c00e  BC 70 C0     LDY .lseqlens,X   ; load length of next block to Y
.C:c011  BD 74 C0     LDA .chars,X      ; load character of next block to A
.C:c014   .outloop:
.C:c014  20 D2 FF     JSR $FFD2         ; output character
.C:c017  C6 FB        DEC $FB           ; decrement newline counter
.C:c019  D0 0B        BNE .skipnl
.C:c01b  48           PHA               ; newline needed -> save accu
.C:c01c  A9 27        LDA #$27          ; restore newline counter
.C:c01e  85 FB        STA $FB
.C:c020  A9 0D        LDA #$0D          ; load newline character
.C:c022  20 D2 FF     JSR $FFD2         ; output character
.C:c025  68           PLA               ; restore accu
.C:c026   .skipnl:
.C:c026  88           DEY               ; decrement repeat counter
.C:c027  D0 EB        BNE .outloop      ; repeat until 0
.C:c029  E0 02        CPX #$02          ; check for block index of text part
.C:c02b  D0 DD        BNE .blockloop    ; not in text part -> repeat
.C:c02d   .textpart:
.C:c02d  48           PHA               ; save accu
.C:c02e  A5 FC        LDA $FC           ; load index for run-length data
.C:c030  4A           LSR A             ; and shift right
.C:c031  A8           TAY               ; -> to Y register
.C:c032  B9 4A C0     LDA .seqlens,Y    ; load run-length data
.C:c035  90 04        BCC .lownibble    ; carry clear from shift -> low nibble
.C:c037  4A           LSR A             ; shift high nibble into low nibble
.C:c038  4A           LSR A
.C:c039  4A           LSR A
.C:c03a  4A           LSR A
.C:c03b   .lownibble:
.C:c03b  29 0F        AND #$0F          ; mask low nibble
.C:c03d  F0 08        BEQ .textdone     ; run-length zero? then text block done
.C:c03f  E6 FC        INC $FC           ; increment index for run-length data
.C:c041  A8           TAY               ; run-length to y-register
.C:c042  68           PLA               ; restore accu
.C:c043  49 09        EOR #$09          ; toggle between '8' and '1'
.C:c045  D0 CD        BNE .outloop      ; and back to output loop
.C:c047   .textdone:
.C:c047  68           PLA               ; restore accu
.C:c048  D0 C0        BNE .blockloop    ; back to loop for next block
.C:c04a   .seqlens:
.C:c04a  28 38 36 36  .BYTE $28,$38,$36,$36
.C:c04e  52 12 52 12  .BYTE $52,$12,$52,$12
.C:c052  42 12 42 22  .BYTE $42,$12,$42,$22
.C:c056  52 12 52 12  .BYTE $52,$12,$52,$12
.C:c05a  72 82 28 28  .BYTE $52,$82,$28,$28
.C:c05e  72 32 14 82  .BYTE $72,$32,$14,$82
.C:c062  82 72 42 22  .BYTE $82,$72,$42,$22
.C:c066  82 82 42 12  .BYTE $82,$82,$42,$12
.C:c06a  42 22 82 92  .BYTE $42,$22,$82,$92
.C:c06e  36 06        .BYTE $36,$06
.C:c070   .lseqlens:
.C:c070  27 50 4F 9C  .BYTE $27,$50,$4F,$9C
.C:c074   .chars:
.C:c074  33 31 31 37  .BYTE $33,$31,$31,$37"3117"
         00 C0        .WORD $C000       ; load address
.C:c000  A9 27        LDA #$27          ; counter for newlines (39)
.C:c002  85 FB        STA $FB
.C:c004  A2 00        LDX #$00          ; index for run-length data
.C:c006  86 FC        STX $FC
.C:c008  A2 04        LDX #$04          ; index for "blocks" (counting down)
.C:c00a   .blockloop:
.C:c00a  CA           DEX
.C:c00b  10 01        BPL .continue     ; block index underflow -> done
.C:c00d  60           RTS
.C:c00e   .continue:
.C:c00e  BC 70 C0     LDY .lseqlens,X   ; load length of next block to Y
.C:c011  BD 74 C0     LDA .chars,X      ; load character of next block to A
.C:c014   .outloop:
.C:c014  20 D2 FF     JSR $FFD2         ; output character
.C:c017  C6 FB        DEC $FB           ; decrement newline counter
.C:c019  D0 0B        BNE .skipnl
.C:c01b  48           PHA               ; newline needed -> save accu
.C:c01c  A9 27        LDA #$27          ; restore newline counter
.C:c01e  85 FB        STA $FB
.C:c020  A9 0D        LDA #$0D          ; load newline character
.C:c022  20 D2 FF     JSR $FFD2         ; output character
.C:c025  68           PLA               ; restore accu
.C:c026   .skipnl:
.C:c026  88           DEY               ; decrement repeat counter
.C:c027  D0 EB        BNE .outloop      ; repeat until 0
.C:c029  E0 02        CPX #$02          ; check for block index of text part
.C:c02b  D0 DD        BNE .blockloop    ; not in text part -> repeat
.C:c02d   .textpart:
.C:c02d  48           PHA               ; save accu
.C:c02e  A5 FC        LDA $FC           ; load index for run-length data
.C:c030  4A           LSR A             ; and shift right
.C:c031  A8           TAY               ; -> to Y register
.C:c032  B9 4A C0     LDA .seqlens,Y    ; load run-length data
.C:c035  90 04        BCC .lownibble    ; carry clear from shift -> low nibble
.C:c037  4A           LSR A             ; shift high nibble into low nibble
.C:c038  4A           LSR A
.C:c039  4A           LSR A
.C:c03a  4A           LSR A
.C:c03b   .lownibble:
.C:c03b  29 0F        AND #$0F          ; mask low nibble
.C:c03d  F0 08        BEQ .textdone     ; run-length zero? then text block done
.C:c03f  E6 FC        INC $FC           ; increment index for run-length data
.C:c041  A8           TAY               ; run-length to y-register
.C:c042  68           PLA               ; restore accu
.C:c043  49 09        EOR #$09          ; toggle between '8' and '1'
.C:c045  D0 CD        BNE .outloop      ; and back to output loop
.C:c047   .textdone:
.C:c047  68           PLA               ; restore accu
.C:c048  D0 C0        BNE .blockloop    ; back to loop for next block
.C:c04a   .seqlens:
.C:c04a  28 38 36 36  .BYTE $28,$38,$36,$36
.C:c04e  52 12 52 12  .BYTE $52,$12,$52,$12
.C:c052  42 12 42 22  .BYTE $42,$12,$42,$22
.C:c056  52 12 52 12  .BYTE $52,$12,$52,$12
.C:c05a  72 82 28 28  .BYTE $52,$82,$28,$28
.C:c05e  72 32 14 82  .BYTE $72,$32,$14,$82
.C:c062  82 72 42 22  .BYTE $82,$72,$42,$22
.C:c066  82 82 42 12  .BYTE $82,$82,$42,$12
.C:c06a  42 22 82 92  .BYTE $42,$22,$82,$92
.C:c06e  36 06        .BYTE $36,$06
.C:c070   .lseqlens:
.C:c070  27 50 4F 9C  .BYTE $27,$50,$4F,$9C
.C:c074   .chars:
.C:c074  33 31 31 37  .BYTE $33,$31,$31,$37
         00 C0        .WORD $C000       ; load address
.C:c000  A9 27        LDA #$27          ; counter for newlines (39)
.C:c002  85 FB        STA $FB
.C:c004  A2 00        LDX #$00          ; index for run-length data
.C:c006  86 FC        STX $FC
.C:c008  A2 04        LDX #$04          ; index for "blocks" (counting down)
.C:c00a   .blockloop:
.C:c00a  CA           DEX
.C:c00b  10 01        BPL .continue     ; block index underflow -> done
.C:c00d  60           RTS
.C:c00e   .continue:
.C:c00e  BC 70 C0     LDY .lseqlens,X   ; load length of next block to Y
.C:c011  BD 74 C0     LDA .chars,X      ; load character of next block to A
.C:c014   .outloop:
.C:c014  20 D2 FF     JSR $FFD2         ; output character
.C:c017  C6 FB        DEC $FB           ; decrement newline counter
.C:c019  D0 0B        BNE .skipnl
.C:c01b  48           PHA               ; newline needed -> save accu
.C:c01c  A9 27        LDA #$27          ; restore newline counter
.C:c01e  85 FB        STA $FB
.C:c020  A9 0D        LDA #$0D          ; load newline character
.C:c022  20 D2 FF     JSR $FFD2         ; output character
.C:c025  68           PLA               ; restore accu
.C:c026   .skipnl:
.C:c026  88           DEY               ; decrement repeat counter
.C:c027  D0 EB        BNE .outloop      ; repeat until 0
.C:c029  E0 02        CPX #$02          ; check for block index of text part
.C:c02b  D0 DD        BNE .blockloop    ; not in text part -> repeat
.C:c02d   .textpart:
.C:c02d  48           PHA               ; save accu
.C:c02e  A5 FC        LDA $FC           ; load index for run-length data
.C:c030  4A           LSR A             ; and shift right
.C:c031  A8           TAY               ; -> to Y register
.C:c032  B9 4A C0     LDA .seqlens,Y    ; load run-length data
.C:c035  90 04        BCC .lownibble    ; carry clear from shift -> low nibble
.C:c037  4A           LSR A             ; shift high nibble into low nibble
.C:c038  4A           LSR A
.C:c039  4A           LSR A
.C:c03a  4A           LSR A
.C:c03b   .lownibble:
.C:c03b  29 0F        AND #$0F          ; mask low nibble
.C:c03d  F0 08        BEQ .textdone     ; run-length zero? then text block done
.C:c03f  E6 FC        INC $FC           ; increment index for run-length data
.C:c041  A8           TAY               ; run-length to y-register
.C:c042  68           PLA               ; restore accu
.C:c043  49 09        EOR #$09          ; toggle between '8' and '1'
.C:c045  D0 CD        BNE .outloop      ; and back to output loop
.C:c047   .textdone:
.C:c047  68           PLA               ; restore accu
.C:c048  D0 C0        BNE .blockloop    ; back to loop for next block
.C:c04a   .seqlens:
.C:c04a  28 38 36 36  .BYTE $28,$38,$36,$36
.C:c04e  52 12 52 12  .BYTE $52,$12,$52,$12
.C:c052  42 12 42 22  .BYTE $42,$12,$42,$22
.C:c056  52 12 52 12  .BYTE $52,$12,$52,$12
.C:c05a  72 82 28 28  .BYTE $52,$82,$28,$28
.C:c05e  72 32 14 82  .BYTE $72,$32,$14,$82
.C:c062  82 72 42 22  .BYTE $82,$72,$42,$22
.C:c066  82 82 42 12  .BYTE $82,$82,$42,$12
.C:c06a  42 22 82 92  .BYTE $42,$22,$82,$92
.C:c06e  36 06        .BYTE $36,$06
.C:c070   .lseqlens:
.C:c070  27 50 4F 9C  .BYTE $27,$50,$4F,$9C
.C:c074   .chars:
.C:c074  33 31 31 37  .BYTE "3117"
2 deleted 861 characters in body
source | link

6502 machine code (C64), 142142 122 bytes

00 C0 A9 27 85 FB A9A2 2000 8586 FC A9A2 0004 85CA FD10 A001 9C60 A9BC 3770 C0 BD 74 C0 20 D2 FF C6  
FB D0 0B 48
  A9 27 85 FB A9 0D 20 D2 FF 68 88 D0 EB 48 24 FC 70 0D 30 2F F0 36 06 FC A0 4F
68 A9E0 3102 D0 D9DD 48 A5 FDFC 4A A8 B0 07  
B9 664A C0 29 0F D0 07 B9 6690 C004 4A 4A 4A 4A E6
FD A8 68 49 09 C029 000F D0F0 BB08 06E6 FC A0 50 D0 B5A8 68 06 FC49 A009 27D0 A9CD 3368 D0 AC 68C0 60
28 38  
36 36 52 12 52 12 42 12 42 22 52 12 52 12 72 82 28 28 72 32 14 82 82 72
  42 22  
82 82 42 12 42 22 82 92 36 06 27 50 4F 9C 33 31 31 37

Online demoOnline demo

  • -20 bytes with better implementation of same method and data tables for large blocks as well.
         00 C0        .WORD $C000       ; load address
.C:c000  A9 27        LDA #$27          ; counter for newlines (39)
.C:c002  85 FB        STA $FB
.C:c004  A9 20        LDA #$20          ; current state (20 - to second block,
.C:c006  85 FC        STA $FC           ; 40 - to "text", 80 to last block)
.C:c008  A9 00        LDA #$00          ; index for run-length data
.C:c00a  85 FD        STA $FD
.C:c00c  A0 9C        LDY #$9C          ; length of first block
.C:c00e  A9 37        LDA #$37          ; and character ('7')
.C:c010   .outloop:
.C:c010  20 D2 FF     JSR $FFD2         ; output character
.C:c013  C6 FB        DEC $FB           ; decrement newline counter
.C:c015  D0 0B        BNE .skipnl
.C:c017  48           PHA               ; newline needed -> save accu
.C:c018  A9 27        LDA #$27          ; restore newline counter
.C:c01a  85 FB        STA $FB
.C:c01c  A9 0D        LDA #$0D          ; load newline character
.C:c01e  20 D2 FF     JSR $FFD2         ; output character
.C:c021  68           PLA               ; restore accu
.C:c022   .skipnl:
.C:c022  88           DEY               ; decrement repeat counter
.C:c023  D0 EB        BNE .outloop      ; repeat until 0
.C:c025  48           PHA               ; save accu
.C:c026  24 FC        BIT $FC           ; check state
.C:c028  70 0D        BVS .textpart     ; bit 6 set -> go to text part
.C:c02a  30 2F        BMI .bottom       ; bit 7 set -> go to last part
.C:c02c  F0 36        BEQ .done         ; if zero, we're done
.C:c02e  06 FC        ASL $FC           ; advance state (shift left)
.C:c030  A0 4F        LDY #$4F          ; length of second block
.C:c032  68           PLA               ; restore accu
.C:c033  A9 31        LDA #$31          ; and character ('1')
.C:c035  D0 D9        BNE .outloop      ; back to output loop
.C:c037   .textpart:
.C:c037  A5 FD        LDA $FD           ; load index for run-length data
.C:c039  4A           LSR A             ; and shift right
.C:c03a  A8           TAY               ; -> to y register
.C:c03b  B0 07        BCS .highnibble   ; carry set from shift, then branch
.C:c03d  B9 66 C0     LDA .seqlens,Y    ; load run-length data
.C:c040  29 0F        AND #$0F          ; and use low nibble
.C:c042  D0 07        BNE .nextseq
.C:c044   .highnibble:
.C:c044  B9 66 C0     LDA .seqlens,Y    ; load run-length data
.C:c047  4A           LSR A             ; and use high nibble by shifting
.C:c048  4A           LSR A
.C:c049  4A           LSR A
.C:c04a  4A           LSR A
.C:c04b   .nextseq:
.C:c04b  E6 FD        INC $FD           ; increment index for run-length data
.C:c04d  A8           TAY               ; run-length to y register
.C:c04e  68           PLA               ; restore accu
.C:c04f  49 09        EOR #$09          ; toggle between '8' and '1'
.C:c051  C0 00        CPY #$00          ; for length zero, textpart is done
.C:c053  D0 BB        BNE .outloop      ; else back to output loop
.C:c055  06 FC        ASL $FC           ; advance state (shift left)
.C:c057   .textdone:
.C:c057  A0 50        LDY #$50          ; counter for bottom '1' block
.C:c059  D0 B5        BNE .outloop      ; back to output loop
.C:c05b   .bottom:
.C:c05b  68           PLA               ; restore accu
.C:c05c  06 FC        ASL $FC           ; advance state (shift left)
.C:c05e  A0 27        LDY #$27          ; counter for last block
.C:c060  A9 33        LDA #$33          ; and character ('3')
.C:c062  D0 AC        BNE .outloop      ; back to output loop
.C:c064   .done:
.C:c064  68           PLA               ; restore accu
.C:c065  60           RTS               ; done
.C:c066   .seqlens:
.C:c066  28 38 36 36  .BYTE $28,$38,$36,$36
.C:c06a  52 12 52 12  .BYTE $52,$12,$52,$12
.C:c06e  42 12 42 22  .BYTE $42,$12,$42,$22
.C:c072  52 12 52 12  .BYTE $52,$12,$52,$12
.C:c076  72 82 28 28  .BYTE $52,$82,$28,$28
.C:c07a  72 32 14 82  .BYTE $72,$32,$14,$82
.C:c07e  82 72 42 22  .BYTE $82,$72,$42,$22
.C:c082  82 82 42 12  .BYTE $82,$82,$42,$12
.C:c086  42 22 82 92  .BYTE $42,$22,$82,$92
.C:c08a  36 06        .BYTE $36,$06
.C:c004  A2 00        LDX #$00          ; index for run-length data
.C:c006  86 FC        STX $FC
.C:c008  A2 04        LDX #$04          ; index for "blocks" (counting down)
.C:c00a   .blockloop:
.C:c00a  CA           DEX
.C:c00b  10 01        BPL .continue     ; block index underflow -> done
.C:c00d  60           RTS
.C:c00e   .continue:
.C:c00e  BC 70 C0     LDY .lseqlens,X   ; load length of next block to Y
.C:c011  BD 74 C0     LDA .chars,X      ; load character of next block to A
.C:c014   .outloop:
.C:c014  20 D2 FF     JSR $FFD2         ; output character
.C:c017  C6 FB        DEC $FB           ; decrement newline counter
.C:c019  D0 0B        BNE .skipnl
.C:c01b  48           PHA               ; newline needed -> save accu
.C:c01c  A9 27        LDA #$27          ; restore newline counter
.C:c01e  85 FB        STA $FB
.C:c020  A9 0D        LDA #$0D          ; load newline character
.C:c022  20 D2 FF     JSR $FFD2         ; output character
.C:c025  68           PLA               ; restore accu
.C:c026   .skipnl:
.C:c026  88           DEY               ; decrement repeat counter
.C:c027  D0 EB        BNE .outloop      ; repeat until 0
.C:c029  E0 02        CPX #$02          ; check for block index of text part
.C:c02b  D0 DD        BNE .blockloop    ; not in text part -> repeat
.C:c02d   .textpart:
.C:c02d  48           PHA               ; save accu
.C:c02e  A5 FC        LDA $FC           ; load index for run-length data
.C:c030  4A           LSR A             ; and shift right
.C:c031  A8           TAY               ; -> to Y register
.C:c032  B9 4A C0     LDA .seqlens,Y    ; load run-length data
.C:c035  90 04        BCC .lownibble    ; carry clear from shift -> low nibble
.C:c037  4A           LSR A             ; shift high nibble into low nibble
.C:c038  4A           LSR A
.C:c039  4A           LSR A
.C:c03a  4A           LSR A
.C:c03b   .lownibble:
.C:c03b  29 0F        AND #$0F          ; mask low nibble
.C:c03d  F0 08        BEQ .textdone     ; run-length zero? then text block done
.C:c03f  E6 FC        INC $FC           ; increment index for run-length data
.C:c041  A8           TAY               ; run-length to y-register
.C:c042  68           PLA               ; restore accu
.C:c043  49 09        EOR #$09          ; toggle between '8' and '1'
.C:c045  D0 CD        BNE .outloop      ; and back to output loop
.C:c047   .textdone:
.C:c047  68           PLA               ; restore accu
.C:c048  D0 C0        BNE .blockloop    ; back to loop for next block
.C:c04a   .seqlens:
.C:c04a  28 38 36 36  .BYTE $28,$38,$36,$36
.C:c04e  52 12 52 12  .BYTE $52,$12,$52,$12
.C:c052  42 12 42 22  .BYTE $42,$12,$42,$22
.C:c056  52 12 52 12  .BYTE $52,$12,$52,$12
.C:c05a  72 82 28 28  .BYTE $52,$82,$28,$28
.C:c05e  72 32 14 82  .BYTE $72,$32,$14,$82
.C:c062  82 72 42 22  .BYTE $82,$72,$42,$22
.C:c066  82 82 42 12  .BYTE $82,$82,$42,$12
.C:c06a  42 22 82 92  .BYTE $42,$22,$82,$92
.C:c06e  36 06        .BYTE $36,$06
.C:c070   .lseqlens:
.C:c070  27 50 4F 9C  .BYTE $27,$50,$4F,$9C
.C:c074   .chars:
.C:c074  33 31 31 37  .BYTE $33,$31,$31,$37

6502 machine code (C64), 142 bytes

00 C0 A9 27 85 FB A9 20 85 FC A9 00 85 FD A0 9C A9 37 20 D2 FF C6 FB D0 0B 48
 A9 27 85 FB A9 0D 20 D2 FF 68 88 D0 EB 48 24 FC 70 0D 30 2F F0 36 06 FC A0 4F
68 A9 31 D0 D9 A5 FD 4A A8 B0 07 B9 66 C0 29 0F D0 07 B9 66 C0 4A 4A 4A 4A E6
FD A8 68 49 09 C0 00 D0 BB 06 FC A0 50 D0 B5 68 06 FC A0 27 A9 33 D0 AC 68 60
28 38 36 36 52 12 52 12 42 12 42 22 52 12 52 12 72 82 28 28 72 32 14 82 82 72
 42 22 82 82 42 12 42 22 82 92 36 06

Online demo

         00 C0        .WORD $C000       ; load address
.C:c000  A9 27        LDA #$27          ; counter for newlines (39)
.C:c002  85 FB        STA $FB
.C:c004  A9 20        LDA #$20          ; current state (20 - to second block,
.C:c006  85 FC        STA $FC           ; 40 - to "text", 80 to last block)
.C:c008  A9 00        LDA #$00          ; index for run-length data
.C:c00a  85 FD        STA $FD
.C:c00c  A0 9C        LDY #$9C          ; length of first block
.C:c00e  A9 37        LDA #$37          ; and character ('7')
.C:c010   .outloop:
.C:c010  20 D2 FF     JSR $FFD2         ; output character
.C:c013  C6 FB        DEC $FB           ; decrement newline counter
.C:c015  D0 0B        BNE .skipnl
.C:c017  48           PHA               ; newline needed -> save accu
.C:c018  A9 27        LDA #$27          ; restore newline counter
.C:c01a  85 FB        STA $FB
.C:c01c  A9 0D        LDA #$0D          ; load newline character
.C:c01e  20 D2 FF     JSR $FFD2         ; output character
.C:c021  68           PLA               ; restore accu
.C:c022   .skipnl:
.C:c022  88           DEY               ; decrement repeat counter
.C:c023  D0 EB        BNE .outloop      ; repeat until 0
.C:c025  48           PHA               ; save accu
.C:c026  24 FC        BIT $FC           ; check state
.C:c028  70 0D        BVS .textpart     ; bit 6 set -> go to text part
.C:c02a  30 2F        BMI .bottom       ; bit 7 set -> go to last part
.C:c02c  F0 36        BEQ .done         ; if zero, we're done
.C:c02e  06 FC        ASL $FC           ; advance state (shift left)
.C:c030  A0 4F        LDY #$4F          ; length of second block
.C:c032  68           PLA               ; restore accu
.C:c033  A9 31        LDA #$31          ; and character ('1')
.C:c035  D0 D9        BNE .outloop      ; back to output loop
.C:c037   .textpart:
.C:c037  A5 FD        LDA $FD           ; load index for run-length data
.C:c039  4A           LSR A             ; and shift right
.C:c03a  A8           TAY               ; -> to y register
.C:c03b  B0 07        BCS .highnibble   ; carry set from shift, then branch
.C:c03d  B9 66 C0     LDA .seqlens,Y    ; load run-length data
.C:c040  29 0F        AND #$0F          ; and use low nibble
.C:c042  D0 07        BNE .nextseq
.C:c044   .highnibble:
.C:c044  B9 66 C0     LDA .seqlens,Y    ; load run-length data
.C:c047  4A           LSR A             ; and use high nibble by shifting
.C:c048  4A           LSR A
.C:c049  4A           LSR A
.C:c04a  4A           LSR A
.C:c04b   .nextseq:
.C:c04b  E6 FD        INC $FD           ; increment index for run-length data
.C:c04d  A8           TAY               ; run-length to y register
.C:c04e  68           PLA               ; restore accu
.C:c04f  49 09        EOR #$09          ; toggle between '8' and '1'
.C:c051  C0 00        CPY #$00          ; for length zero, textpart is done
.C:c053  D0 BB        BNE .outloop      ; else back to output loop
.C:c055  06 FC        ASL $FC           ; advance state (shift left)
.C:c057   .textdone:
.C:c057  A0 50        LDY #$50          ; counter for bottom '1' block
.C:c059  D0 B5        BNE .outloop      ; back to output loop
.C:c05b   .bottom:
.C:c05b  68           PLA               ; restore accu
.C:c05c  06 FC        ASL $FC           ; advance state (shift left)
.C:c05e  A0 27        LDY #$27          ; counter for last block
.C:c060  A9 33        LDA #$33          ; and character ('3')
.C:c062  D0 AC        BNE .outloop      ; back to output loop
.C:c064   .done:
.C:c064  68           PLA               ; restore accu
.C:c065  60           RTS               ; done
.C:c066   .seqlens:
.C:c066  28 38 36 36  .BYTE $28,$38,$36,$36
.C:c06a  52 12 52 12  .BYTE $52,$12,$52,$12
.C:c06e  42 12 42 22  .BYTE $42,$12,$42,$22
.C:c072  52 12 52 12  .BYTE $52,$12,$52,$12
.C:c076  72 82 28 28  .BYTE $52,$82,$28,$28
.C:c07a  72 32 14 82  .BYTE $72,$32,$14,$82
.C:c07e  82 72 42 22  .BYTE $82,$72,$42,$22
.C:c082  82 82 42 12  .BYTE $82,$82,$42,$12
.C:c086  42 22 82 92  .BYTE $42,$22,$82,$92
.C:c08a  36 06        .BYTE $36,$06

6502 machine code (C64), 142 122 bytes

00 C0 A9 27 85 FB A2 00 86 FC A2 04 CA 10 01 60 BC 70 C0 BD 74 C0 20 D2 FF C6 
FB D0 0B 48 A9 27 85 FB A9 0D 20 D2 FF 68 88 D0 EB E0 02 D0 DD 48 A5 FC 4A A8 
B9 4A C0 90 04 4A 4A 4A 4A 29 0F F0 08 E6 FC A8 68 49 09 D0 CD 68 D0 C0 28 38 
36 36 52 12 52 12 42 12 42 22 52 12 52 12 72 82 28 28 72 32 14 82 82 72 42 22 
82 82 42 12 42 22 82 92 36 06 27 50 4F 9C 33 31 31 37

Online demo

  • -20 bytes with better implementation of same method and data tables for large blocks as well.
         00 C0        .WORD $C000       ; load address
.C:c000  A9 27        LDA #$27          ; counter for newlines (39)
.C:c002  85 FB        STA $FB
.C:c004  A2 00        LDX #$00          ; index for run-length data
.C:c006  86 FC        STX $FC
.C:c008  A2 04        LDX #$04          ; index for "blocks" (counting down)
.C:c00a   .blockloop:
.C:c00a  CA           DEX
.C:c00b  10 01        BPL .continue     ; block index underflow -> done
.C:c00d  60           RTS
.C:c00e   .continue:
.C:c00e  BC 70 C0     LDY .lseqlens,X   ; load length of next block to Y
.C:c011  BD 74 C0     LDA .chars,X      ; load character of next block to A
.C:c014   .outloop:
.C:c014  20 D2 FF     JSR $FFD2         ; output character
.C:c017  C6 FB        DEC $FB           ; decrement newline counter
.C:c019  D0 0B        BNE .skipnl
.C:c01b  48           PHA               ; newline needed -> save accu
.C:c01c  A9 27        LDA #$27          ; restore newline counter
.C:c01e  85 FB        STA $FB
.C:c020  A9 0D        LDA #$0D          ; load newline character
.C:c022  20 D2 FF     JSR $FFD2         ; output character
.C:c025  68           PLA               ; restore accu
.C:c026   .skipnl:
.C:c026  88           DEY               ; decrement repeat counter
.C:c027  D0 EB        BNE .outloop      ; repeat until 0
.C:c029  E0 02        CPX #$02          ; check for block index of text part
.C:c02b  D0 DD        BNE .blockloop    ; not in text part -> repeat
.C:c02d   .textpart:
.C:c02d  48           PHA               ; save accu
.C:c02e  A5 FC        LDA $FC           ; load index for run-length data
.C:c030  4A           LSR A             ; and shift right
.C:c031  A8           TAY               ; -> to Y register
.C:c032  B9 4A C0     LDA .seqlens,Y    ; load run-length data
.C:c035  90 04        BCC .lownibble    ; carry clear from shift -> low nibble
.C:c037  4A           LSR A             ; shift high nibble into low nibble
.C:c038  4A           LSR A
.C:c039  4A           LSR A
.C:c03a  4A           LSR A
.C:c03b   .lownibble:
.C:c03b  29 0F        AND #$0F          ; mask low nibble
.C:c03d  F0 08        BEQ .textdone     ; run-length zero? then text block done
.C:c03f  E6 FC        INC $FC           ; increment index for run-length data
.C:c041  A8           TAY               ; run-length to y-register
.C:c042  68           PLA               ; restore accu
.C:c043  49 09        EOR #$09          ; toggle between '8' and '1'
.C:c045  D0 CD        BNE .outloop      ; and back to output loop
.C:c047   .textdone:
.C:c047  68           PLA               ; restore accu
.C:c048  D0 C0        BNE .blockloop    ; back to loop for next block
.C:c04a   .seqlens:
.C:c04a  28 38 36 36  .BYTE $28,$38,$36,$36
.C:c04e  52 12 52 12  .BYTE $52,$12,$52,$12
.C:c052  42 12 42 22  .BYTE $42,$12,$42,$22
.C:c056  52 12 52 12  .BYTE $52,$12,$52,$12
.C:c05a  72 82 28 28  .BYTE $52,$82,$28,$28
.C:c05e  72 32 14 82  .BYTE $72,$32,$14,$82
.C:c062  82 72 42 22  .BYTE $82,$72,$42,$22
.C:c066  82 82 42 12  .BYTE $82,$82,$42,$12
.C:c06a  42 22 82 92  .BYTE $42,$22,$82,$92
.C:c06e  36 06        .BYTE $36,$06
.C:c070   .lseqlens:
.C:c070  27 50 4F 9C  .BYTE $27,$50,$4F,$9C
.C:c074   .chars:
.C:c074  33 31 31 37  .BYTE $33,$31,$31,$37
1
source | link

6502 machine code (C64), 142 bytes

00 C0 A9 27 85 FB A9 20 85 FC A9 00 85 FD A0 9C A9 37 20 D2 FF C6 FB D0 0B 48
A9 27 85 FB A9 0D 20 D2 FF 68 88 D0 EB 48 24 FC 70 0D 30 2F F0 36 06 FC A0 4F
68 A9 31 D0 D9 A5 FD 4A A8 B0 07 B9 66 C0 29 0F D0 07 B9 66 C0 4A 4A 4A 4A E6
FD A8 68 49 09 C0 00 D0 BB 06 FC A0 50 D0 B5 68 06 FC A0 27 A9 33 D0 AC 68 60
28 38 36 36 52 12 52 12 42 12 42 22 52 12 52 12 72 82 28 28 72 32 14 82 82 72
42 22 82 82 42 12 42 22 82 92 36 06

Online demo

Usage: sys49152


Explanation

This also uses the lengths of the 1 and 8 sequences in the middle part; as they're all shorter than 16, two of them are encoded per byte.

Commented disassembly listing:

         00 C0        .WORD $C000       ; load address
.C:c000  A9 27        LDA #$27          ; counter for newlines (39)
.C:c002  85 FB        STA $FB
.C:c004  A9 20        LDA #$20          ; current state (20 - to second block,
.C:c006  85 FC        STA $FC           ; 40 - to "text", 80 to last block)
.C:c008  A9 00        LDA #$00          ; index for run-length data
.C:c00a  85 FD        STA $FD
.C:c00c  A0 9C        LDY #$9C          ; length of first block
.C:c00e  A9 37        LDA #$37          ; and character ('7')
.C:c010   .outloop:
.C:c010  20 D2 FF     JSR $FFD2         ; output character
.C:c013  C6 FB        DEC $FB           ; decrement newline counter
.C:c015  D0 0B        BNE .skipnl
.C:c017  48           PHA               ; newline needed -> save accu
.C:c018  A9 27        LDA #$27          ; restore newline counter
.C:c01a  85 FB        STA $FB
.C:c01c  A9 0D        LDA #$0D          ; load newline character
.C:c01e  20 D2 FF     JSR $FFD2         ; output character
.C:c021  68           PLA               ; restore accu
.C:c022   .skipnl:
.C:c022  88           DEY               ; decrement repeat counter
.C:c023  D0 EB        BNE .outloop      ; repeat until 0
.C:c025  48           PHA               ; save accu
.C:c026  24 FC        BIT $FC           ; check state
.C:c028  70 0D        BVS .textpart     ; bit 6 set -> go to text part
.C:c02a  30 2F        BMI .bottom       ; bit 7 set -> go to last part
.C:c02c  F0 36        BEQ .done         ; if zero, we're done
.C:c02e  06 FC        ASL $FC           ; advance state (shift left)
.C:c030  A0 4F        LDY #$4F          ; length of second block
.C:c032  68           PLA               ; restore accu
.C:c033  A9 31        LDA #$31          ; and character ('1')
.C:c035  D0 D9        BNE .outloop      ; back to output loop
.C:c037   .textpart:
.C:c037  A5 FD        LDA $FD           ; load index for run-length data
.C:c039  4A           LSR A             ; and shift right
.C:c03a  A8           TAY               ; -> to y register
.C:c03b  B0 07        BCS .highnibble   ; carry set from shift, then branch
.C:c03d  B9 66 C0     LDA .seqlens,Y    ; load run-length data
.C:c040  29 0F        AND #$0F          ; and use low nibble
.C:c042  D0 07        BNE .nextseq
.C:c044   .highnibble:
.C:c044  B9 66 C0     LDA .seqlens,Y    ; load run-length data
.C:c047  4A           LSR A             ; and use high nibble by shifting
.C:c048  4A           LSR A
.C:c049  4A           LSR A
.C:c04a  4A           LSR A
.C:c04b   .nextseq:
.C:c04b  E6 FD        INC $FD           ; increment index for run-length data
.C:c04d  A8           TAY               ; run-length to y register
.C:c04e  68           PLA               ; restore accu
.C:c04f  49 09        EOR #$09          ; toggle between '8' and '1'
.C:c051  C0 00        CPY #$00          ; for length zero, textpart is done
.C:c053  D0 BB        BNE .outloop      ; else back to output loop
.C:c055  06 FC        ASL $FC           ; advance state (shift left)
.C:c057   .textdone:
.C:c057  A0 50        LDY #$50          ; counter for bottom '1' block
.C:c059  D0 B5        BNE .outloop      ; back to output loop
.C:c05b   .bottom:
.C:c05b  68           PLA               ; restore accu
.C:c05c  06 FC        ASL $FC           ; advance state (shift left)
.C:c05e  A0 27        LDY #$27          ; counter for last block
.C:c060  A9 33        LDA #$33          ; and character ('3')
.C:c062  D0 AC        BNE .outloop      ; back to output loop
.C:c064   .done:
.C:c064  68           PLA               ; restore accu
.C:c065  60           RTS               ; done
.C:c066   .seqlens:
.C:c066  28 38 36 36  .BYTE $28,$38,$36,$36
.C:c06a  52 12 52 12  .BYTE $52,$12,$52,$12
.C:c06e  42 12 42 22  .BYTE $42,$12,$42,$22
.C:c072  52 12 52 12  .BYTE $52,$12,$52,$12
.C:c076  72 82 28 28  .BYTE $52,$82,$28,$28
.C:c07a  72 32 14 82  .BYTE $72,$32,$14,$82
.C:c07e  82 72 42 22  .BYTE $82,$72,$42,$22
.C:c082  82 82 42 12  .BYTE $82,$82,$42,$12
.C:c086  42 22 82 92  .BYTE $42,$22,$82,$92
.C:c08a  36 06        .BYTE $36,$06