Programming Challenge

Discussion about ZX80 / ZX81 Software
Lardo Boffin
Posts: 2160
Joined: Sat Nov 26, 2016 2:42 am

Re: Programming Challenge

Post by Lardo Boffin »

kmurta wrote: Fri May 12, 2017 10:25 pm An other option, with 144 bytes in two Basic lines (123 bytes of z80 codes):

Code: Select all

upside:
        ld hl,msg
        ld de,(16396)   ; screen address
        inc de
        ld bc,12
        ldir

rightside:
        ex de,hl
        dec hl
        ld b,4
rsloop:
        push bc
        ld bc,33
        add hl,bc
        ld a,(de)
        ld (hl),a
        inc de
        pop bc
        djnz rsloop

underside:
        ex de,hl
        ld bc,13
        add hl,bc
        dec bc
        lddr

leftside:
        ex de,hl
        inc hl
        ld b,3

lsloop:
        push bc
        ld bc,33
        sbc hl,bc
        ld a,(de)
        ld (hl),a
        dec de
        pop bc
        djnz lsloop

rotatemsg:
        ld hl,msg
        ld d,h
        ld e,l
        ld a,(hl)
        push af
        ld a,(msg+29)
        inc hl
        ld bc,14
        ldir
        ld hl,msg+28
        ld d,h
        ld e,l
        inc de
        ld bc,14
        lddr
        ld (hl),a
        pop af
        ld (de),a

delay:
        ld hl,FRAMES
        ld a,(hl)
        sub 10
dlyloop:
        cp (hl)
        jr nz,dlyloop

        jr upside

msg:    dbzx 'HAPPY BIRTHDAY  OCCEC ELEAFFAR'
rcecco.p
Nice. Reverse the last half of the message so that you can use LDDR for the bottom half of the message and then have a separate function to rearrange the message once per animation loop.

I have got mine down to 158 bytes now but not sure I can do much more than that.
ZX80
ZX81 iss 1 (bugged ROM, kludge fix, normal, rebuilt)
TS 1000 iss 3, ZXPand AY and +, ZX8-CCB, ZX-KDLX & ChromaSCART
Tatung 81 + Wespi
TS 1500 & 2000
Spectrum 16k (iss 1 s/n 862)
Spectrum 48ks plus a DIVMMC future and SPECTRA
Lardo Boffin
Posts: 2160
Joined: Sat Nov 26, 2016 2:42 am

Re: Programming Challenge

Post by Lardo Boffin »

So it occurred to me that if I stuck with my slightly less efficient bottom line message display code (i.e. not using lddr) I could use kmurta's cunning plan of rotating the message but with a much more simplified message rotating function.

Code: Select all

main	
	ld hl,happyBirthday			;load the address of the message
	ld de,(D_FILE)				;load the base of screen memory
	inc de						;increase it by one to bypass the $76
	ld bc,12					;ready for 12 loops
	ldir						;transfer HL to DE 12 times and increase both accordingly
	ex de,hl					;put HL into DE (HL was the message position)
	ld b,4						;prepare to loop 4 times
	dec hl						;decrease HL (screen location) by 1 to step back from the $76 char
rightVertical
	push de						;save the character position
	ld de,13					;load 13 (for the next line)
	add hl,de					;add to HL	
	pop de						;get the message position back
	ld a,(de)					;load the character into A
	ld (hl),a					;save it to HL
	inc de						;increase the character position
	djnz rightVertical			;repeat until B = 0
	dec hl						;decrease HL (screen location) by 1 to step back from the $76 char
	ld b,11						;prepare for 11 loops
lastLine
	ld a,(de)					;load the current character into A
	ld (hl),a					;save to the screen
	dec hl						;decrease the screen position (as we are going backwards)
	inc de						;increase character position
	djnz lastLine				;repeat until B = 0
	ld b,3						;get ready for the left vertical
	inc hl						;increase the screen position by 1 as we have gone 1 too far to the left and wrapped to the line above
leftVertical
	push de						;save the character position
	ld de,13					;load 13 (for the next line)
	sbc hl,de					;subtract it to move up a line in memory
	pop de						;get the character pos back
	ld a,(de)					;load the character
	ld (hl),a					;save it to the screen
	inc de						;next character
	djnz leftVertical			;repeat until B = 0 	
delayCode
	ld   hl,FRAMES         		;fetch timer                 
    	ld   a,(hl)                 ;load into A                        
    	sub  10                		;wait 10 full frames (0.1 of a second)
delayLoop        
	cp  (hl) 					;compare HL to 0
    	jr   nz,delayLoop			;if not 0 then repeat until it is	
shuffleMessage
	ld a, (happyBirthday)		;load the first character of the message
	push af						;save the first character of the message
	ld hl, happyBirthday		;load the address of the message
	inc hl						;increase by one to get the second char
	ld de, happyBirthday		;load the start of the message
	ld bc, 29					;number of times to loop
	ldir						;load HL (char 2) into DE (char 1) and repeat
	pop af						;get char 1 back	
	ld (de),a					;out it at the end of the string
	jr main						;repeat

happyBirthday
		DEFB	_H,_A,_P,_P,_Y,__,_B,_I,_R,_T,_H,_D,_A,_Y,__,_R,_A,_F,_F,_A,_E,_L,_E,__,_C,_E,_C,_C,_O,__
Now in a total of 130 bytes! :lol:

I can't feel any real sense of achievement though as I would have never have thought of rotating the message as opposed to some complex process of extracting the correct character based on rotation phase and character position. Sometimes I guess I overthink things. :oops:
Attachments
hpybrthd.p
(941 Bytes) Downloaded 231 times
ZX80
ZX81 iss 1 (bugged ROM, kludge fix, normal, rebuilt)
TS 1000 iss 3, ZXPand AY and +, ZX8-CCB, ZX-KDLX & ChromaSCART
Tatung 81 + Wespi
TS 1500 & 2000
Spectrum 16k (iss 1 s/n 862)
Spectrum 48ks plus a DIVMMC future and SPECTRA
User avatar
kmurta
Posts: 302
Joined: Tue Sep 01, 2009 5:04 am
Location: Belo Horizonte - BR
Contact:

Re: Programming Challenge

Post by kmurta »

I thing in this too after my post, but I´m very lazy these days :mrgreen:

But you can save more 5 bytes in your ShuffleMessage routine, look at this:

Code: Select all

shuffleMessage:
;        ld a, (happyBirthday)           ;load the first character of the message
;        push af                                         ;save the first character of the message
        ld hl, happyBirthday            ;load the address of the message
        ld d,h
        ld e,l
        ld a,(hl)
        inc hl                                          ;increase by one to get the second char
;        ld de, happyBirthday            ;load the start of the message
        ld bc, 29                                       ;number of times to loop
        ldir                                            ;load HL (char 2) into DE (char 1) and repeat
;        pop af                                          ;get char 1 back
        ld (de),a                                       ;out it at the end of the string
        jr main                                         ;repeat                         
;)
1 x ZX81, 2 x TK85 , 1 TK82C, 1 TK95, 1 x Alphacom 32 printer, 1 x ZXpand
ZeXtender board, Joy81 - Programmable Joystick Controller, Turbo Sound 81
http://zx81.eu5.org
https://toddysoftware.itch.io/
Lardo Boffin
Posts: 2160
Joined: Sat Nov 26, 2016 2:42 am

Re: Programming Challenge

Post by Lardo Boffin »

I thought I was doing well but I can see I still have a lot to learn! This is only my second Z80 program so I don't feel too bad I guess.
ZX80
ZX81 iss 1 (bugged ROM, kludge fix, normal, rebuilt)
TS 1000 iss 3, ZXPand AY and +, ZX8-CCB, ZX-KDLX & ChromaSCART
Tatung 81 + Wespi
TS 1500 & 2000
Spectrum 16k (iss 1 s/n 862)
Spectrum 48ks plus a DIVMMC future and SPECTRA
Post Reply