Monday, 6 April 2015

Z80 Size Programming Challenge #4

The fourth Z80 challenge for the ZX Spectrum was issued last week:

Back to something simple for the next challenge, a diagonal fade-to-white CLS. Write the shortest code to wipe the screen by increasing the ink colour of each character until it reaches white.

The clear should start at the top left and move one character across the screen per frame. The initial screen can be assumed to be monochrome — black text, white background, flash off, bright off. There's no need to clear the screen bitmap. Here's a demonstration of the clear in slow motion:

Target: under 50 bytes.

The deadline is Monday 6th April, midday (GMT).

  1. Your program shouldn't rely on the initial contents of registers.
  2. Programs must halt between frames. The HALT is included in the size.
  3. No RAM/ROM other than the attribute memory should be written to.
  4. Programs must return. The RET instruction is included in the size.
  5. So everyone has a fair chance comment with the code size not code.
  6. There are no prizes, just the chance to show off your coding skills.

Final Results

Congratulations to everyone who entered and Arcadiy Gobuzov who claimed first place with a solution in 26 bytes. Most of the solutions use LDDR to move the attribute data with anonymous and Ralph Becket being the two exceptions. Here are the final results:

CoderSize
Arcadiy Gobuzov26
ub880d27
Bohumil Novacek27
anonymous27
Adrian Brown27
John Metcalf27
Ralph Becket30
Jim Bagley31
Paul Rhodes31

Winning Entry

Here's Arcadiy's winning entry in 26 bytes:

        xor a ; if comment then 25, but exit if a==56 on start
loop:        
        ld hl,#5ADF   ;
        cp (hl)       ;
        ld bc,#02E0   ; 23 lines of attributes
        ld de,#5AFF   ; 
        lddr          ; move down attributes
        ld c,e        ; e = #1F
        add hl,bc     ;
        lddr          ; roll upper line of attributes to right
        halt
        ret z
        ld a,(de)     ; de = first address of attibutes
        cp #3F        ;
        adc a,c       ; add 0 or 1 (carry)
        ld (de),a     ; now a in range [38..3f]
        jr loop

Here's my own solution in 27 bytes. Unfortunately I missed the final CP (HL) to squeeze out the last byte:

fadetowhite:
        ld de,23295 ; 90 255
        ld a,(de)
        cp 63
        ret z
        ld hl,23263 ; 90 223
        ld bc,736   ;  2 224
        halt
        lddr
        ld c,e
        add hl,bc
        lddr
        ld a,(de)
        cp 63
        adc a,c
        ld (de),a
        jr fadetowhite

Here's an alternative — a fade-to-black wipe (from white ink, black paper, no bright, no flash) in 25 bytes:

fadetoblack:
        ld de,23295 ; 90 255
        ld a,(de)
        or a
        ret z
        ld hl,23263 ; 90 223
        ld bc,736   ;  2 224
        halt
        lddr
        ld c,e
        add hl,bc
        lddr
        ld a,(de)
        add a,l
        sbc a,l
        ld (de),a
        jr fadetoblack

12 comments:

  1. Just a quick update, I've received two entries so far:

    32 bytes - Ralph Becket
    31 bytes - Jim Bagley

    ReplyDelete
  2. I've received another couple of entries this evening. Here's the leaderboard so far:

    29 bytes - Bohumil Novacek
    under 31 bytes - Arcadiy Gobuzov
    31 bytes - Jim Bagley
    32 bytes - Ralph Becket

    ReplyDelete
  3. progStart EQU C400
    ORG C400
    C400:163F LD D, 3F
    C402: label LOOP_KROK
    C402:76 HALT
    C403:210058 LD HL, 5800
    C406:1E18 LD E, 18
    C408: label LOOP_RADEK
    C408:0620 LD B, 20
    C40A: label LOOP_SLOUPEC
    C40A:7B LD A, E
    C40B:80 ADD A, B
    C40C:92 SUB D
    C40D:C607 ADD A, 07
    C40F:3001 JR NC, C412
    C411:34 INC (HL)
    C412: label PRESKOC
    C412:23 INC HL
    C413:10F5 DJNZ C40A
    C415:1D DEC E
    C416:20F0 JR NZ, C408
    C418:15 DEC D
    C419:20E7 JR NZ, C402
    C41B:C9 RET
    Emiting raw binary from C400 to C41B

    ReplyDelete
  4. ; pasmo -d chalenge1.asm chalenge.bin > test.asm ; ./bin2tap chalenge.bin


    progStart equ $C400 ; 50176
    org progStart

    LD D,$3F ; 2, 24+32+6

    LOOP_KROK:

    HALT ; 1
    LD HL,$5800 ; 3 HL ukazuje na prvni atribut
    LD E,$18 ; 2 E = 24 radku

    LOOP_RADEK:
    LD B,$20 ; 2 B = 32 sloupce
    ; ---------------------- 10

    LOOP_SLOUPEC: ;

    LD A,E ; 1
    ADD A,B ; 1 A = 56..2
    SUB D ; 1 Carry flag
    ; JR NC,PRESKOC ; 2
    ADD A,7 ; 2 je A v rozsahu 0..6?
    JR NC, PRESKOC ; 2
    INC (HL) ; 1
    ; ---------------------- 8

    PRESKOC:
    INC HL ; 1
    DJNZ LOOP_SLOUPEC ; 2

    DEC E ; 1
    JR NZ,LOOP_RADEK ; 2

    DEC D ; 1
    JR NZ,LOOP_KROK ; 2
    RET ; 1
    ; ---------------------- 10

    ReplyDelete
  5. Here's another update:

    under 28 bytes - Arcadiy Gobuzov
    27 bytes - Bohumil Novacek
    28 bytes - ub880d
    28 bytes - anonymous
    30 bytes? - Ralph Becket
    31 bytes - Jim Bagley

    ReplyDelete
  6. ; pasmo -d chalenge6.asm chalenge.bin > test.asm ; ./bin2tap chalenge.bin
    progStart equ $C400 ; 50176
    org progStart

    DB $16 ; 1 LD D, HALT = $76 > 24+32+7

    LOOP_KROK:

    HALT ; 1
    LD HL,$5800 ; 3 HL ukazuje na prvni atribut
    LD E,24 ; 2 E = 24 radku

    LOOP_RADEK:
    LD B,$20 ; 2 B = 32 sloupcu

    LOOP_SLOUPEC: ;

    LD A,B ; 1
    ADD A,E ; 1
    SUB D ; 1
    ADD A,$07 ; 2 je A v rozsahu 0..6?

    JR NC, PRESKOC ; 2
    INC (HL) ; 1

    PRESKOC:
    INC HL ; 1
    DJNZ LOOP_SLOUPEC ; 2

    DEC E ; 1
    JR NZ,LOOP_RADEK ; 2

    DEC D ; 1
    JR NZ,LOOP_KROK ; 2
    RET ; 1
    ; ---------------------- 27

    ReplyDelete
    Replies
    1. Nice work, thanks. Who should I credit it to, or should I leave it as anonymous?

      Delete
    2. Anonymous.

      Delete
  7. it was base of 3sc

    ReplyDelete
  8. Miloš Bazelides

    ReplyDelete
  9. progStart equ $C400 ; 50176
    org progStart

    DB $0E ; 1 LD C,$76=HALT

    LOOP_KROK:
    HALT ; 1
    LD HL,$5800 ; 3 HL ukazuje na prvni atribut
    LD D,$E8 ; 2 D = -24, ( E = -32 (ale az po prvnim pruchodu))

    DEC C ; 1
    RET Z ; 1

    LOOP_SCREEN:
    ;----------------------- 9

    LD A,E ; 1
    OR $E0 ; 2 111S SSSS
    LD E,A ; 1 E -32..-1
    ADD A,D ; 1
    JR NC,LOOP_KROK ; 2 E je vzdy zaporny, D muze byt i nula

    ADD A,C ; 1
    CP $07 ; 2 je A v rozsahu 0..6?
    JR NC, PRESKOC ; 2
    INC (HL) ; 1

    PRESKOC:
    INC HL ; 1
    INC DE ; 1

    JR LOOP_SCREEN ; 2
    ;----------------------- 17

    ReplyDelete
  10. progStart equ $873E ; 34622
    org progStart

    INC HL ; 1
    INC (HL) ; 1
    LOOP:

    HALT ; 1
    LD HL,$5ADF ; 3
    LD DE,$5AFF ; 3
    LD BC,$02E0 ; 3 736 = 32*23
    LDDR ; 2 LD (DE),(HL) => scroll o radek nize, zespoda nahoru
    ; ---------------------- 14
    ; BC = 0
    ; HL = $57FF
    ; DE = $581F
    LD C,E ; 1
    ADD HL,BC ; 1
    ; HL = $581E
    LDDR ; 2 LD (DE),(HL) => horni radek scroll doprava, zprava doleva
    ; BC = 0
    ; HL = $57FF
    ; DE = $5800

    DEC A ; 1
    RET Z ; 1

    DB $FA ; 1 JP M, ...

    ENTER_ROUTINE:
    LD A,$87 ; 2 $3E87
    JR LOOP ; 2

    ; ---------------------- 11

    ReplyDelete

Note: only a member of this blog may post a comment.