Need help working something out.

Discussion about ZX80 / ZX81 Software
Moggy
Posts: 3231
Joined: Wed Jun 18, 2008 2:00 pm

Need help working something out.

Post by Moggy »

An appeal to the gurus out there to help this silly Moggy :oops: with a bit of code.

The problem.

Imagine a REM statement containing a mixture of 800 zeros and ones. I am needing a simple bit of code to count all the zeros in the REM or the ones it doesn't matter which and put that total into an address which I then can retrieve via BASIC.

I can do this in BASIC but it's just too slow.

The REM containing the data will be at 16514 so something to scan from that address 800 bytes onward then dump the total into memory. would be great.

Google has not been my friend so any help would be gratefully appreciated.

Many thanks in advance. :D
User avatar
XavSnap
Posts: 1940
Joined: Sat May 10, 2008 4:23 pm
Location: 'Zx81 France' Fb group.

Re: Need help working something out.

Post by XavSnap »

This code in ASM ?

Code: Select all

1 REM 0101010111001000111110000101001010
5 LET I=0
8 FAST
10 FOR A=16514 TO 4E4
20 LET D= PEEK A
30 LET I= I+(D = 29)
40 IF D<>118 THEN NEXT A
45 SLOW
50 PRINT "1=";I,"0=";A-16514-I
Xavier ...on the Facebook groupe : "Zx81 France"(fr)
dr beep
Posts: 2060
Joined: Thu Jun 16, 2011 8:35 am
Location: Boxmeer

Re: Need help working something out.

Post by dr beep »

ld hl,16513
ld bc,0
loop:
inc hl
ld a,(hl)
cp 29
jr nz,cont
inc bc
cont:
cp 118
jr nz,loop
ret
User avatar
XavSnap
Posts: 1940
Joined: Sat May 10, 2008 4:23 pm
Location: 'Zx81 France' Fb group.

Re: Need help working something out.

Post by XavSnap »

:lol:
You win Dr Beep !

[edit1: :evil: it's the same code… !!! :mrgreen: ]
[edit2: I use CP(HL) instead of LD A,(HL)…

BASIC:

Code: Select all

1 REM \
01010101110010001111100001010010100100011111000011\
01010101110010001111100001010010100100011111000011\
01010101110010001111100001010010100100011111000011\
01010101110010001111100001010010100100011111000011\
01010101110010001111100001010010100100011111000011\
01010101110010001111100001010010100100011111000011\
01010101110010001111100001010010100100011111000011\
01010101110010001111100001010010100100011111000011\
01010101110010001111100001010010100100011111000011\
01010101110010001111100001010010100100011111000011\
01010101110010001111100001010010100100011111000011\
01010101110010001111100001010010100100011111000011\
01010101110010001111100001010010100100011111000011\
01010101110010001111100001010010100100011111000011\
01010101110010001111100001010010100100011111000011\
01010101110010001111100001010010100100011111000011
5 LET I=0
8 FAST
10 FOR A=16514 TO 4E4
20 LET D= PEEK A
30 LET I= I+(D = 29)
40 IF D<>118 THEN NEXT A
45 SLOW
50 PRINT "1=";I,"0=";A-16514-I
ASM:

Code: Select all

.ORG 16514 ; Or another something else… 

	LD HL,16514 ; REM with "0" and "1"
	LD BC,0	; ReSET '1' counter

M_LOOP:
	LD A,29 ; "1"
	CP (HL)
	JR NZ,Go_NXT ; IS it a "1" character. "0">Go_NXT
	INC BC
Go_NXT:
	INC HL
	LD A,118 ; End of line.
	CP (HL)
	JR Nz,M_LOOP ; 
	RET
.end

Code: Select all

     1  REM [HEX:\
1C,1D,1C,1D,1C,1D,1C,1D,\
1D,1D,1C,1C,1D,1C,1C,1C,\
1D,1D,1D,1D,1D,1C,1C,1C,\
1C,1D,1C,1D,1C,1C,1D,1C,\
1D,1C,1C,1D,1C,1C,1C,1D,\
1D,1D,1D,1D,1C,1C,1C,1C,\
1D,1D,1C,1D,1C,1D,1C,1D,\
1C,1D,1D,1D,1C,1C,1D,1C,\
1C,1C,1D,1D,1D,1D,1D,1C,\
1C,1C,1C,1D,1C,1D,1C,1C,\
1D,1C,1D,1C,1C,1D,1C,1C,\
1C,1D,1D,1D,1D,1D,1C,1C,\
1C,1C,1D,1D,1C,1D,1C,1D,\
1C,1D,1C,1D,1D,1D,1C,1C,\
1D,1C,1C,1C,1D,1D,1D,1D,\
1D,1C,1C,1C,1C,1D,1C,1D,\
1C,1C,1D,1C,1D,1C,1C,1D,\
1C,1C,1C,1D,1D,1D,1D,1D,\
1C,1C,1C,1C,1D,1D,1C,1D,\
1C,1D,1C,1D,1C,1D,1D,1D,\
1C,1C,1D,1C,1C,1C,1D,1D,\
1D,1D,1D,1C,1C,1C,1C,1D,\
1C,1D,1C,1C,1D,1C,1D,1C,\
1C,1D,1C,1C,1C,1D,1D,1D,\
1D,1D,1C,1C,1C,1C,1D,1D,\
1C,1D,1C,1D,1C,1D,1C,1D,\
1D,1D,1C,1C,1D,1C,1C,1C,\
1D,1D,1D,1D,1D,1C,1C,1C,\
1C,1D,1C,1D,1C,1C,1D,1C,\
1D,1C,1C,1D,1C,1C,1C,1D,\
1D,1D,1D,1D,1C,1C,1C,1C,\
1D,1D,1C,1D,1C,1D,1C,1D,\
1C,1D,1D,1D,1C,1C,1D,1C,\
1C,1C,1D,1D,1D,1D,1D,1C,\
1C,1C,1C,1D,1C,1D,1C,1C,\
1D,1C,1D,1C,1C,1D,1C,1C,\
1C,1D,1D,1D,1D,1D,1C,1C,\
1C,1C,1D,1D,1C,1D,1C,1D,\
1C,1D,1C,1D,1D,1D,1C,1C,\
1D,1C,1C,1C,1D,1D,1D,1D,\
1D,1C,1C,1C,1C,1D,1C,1D,\
1C,1C,1D,1C,1D,1C,1C,1D,\
1C,1C,1C,1D,1D,1D,1D,1D,\
1C,1C,1C,1C,1D,1D,1C,1D,\
1C,1D,1C,1D,1C,1D,1D,1D,\
1C,1C,1D,1C,1C,1C,1D,1D,\
1D,1D,1D,1C,1C,1C,1C,1D,\
1C,1D,1C,1C,1D,1C,1D,1C,\
1C,1D,1C,1C,1C,1D,1D,1D,\
1D,1D,1C,1C,1C,1C,1D,1D,\
1C,1D,1C,1D,1C,1D,1C,1D,\
1D,1D,1C,1C,1D,1C,1C,1C,\
1D,1D,1D,1D,1D,1C,1C,1C,\
1C,1D,1C,1D,1C,1C,1D,1C,\
1D,1C,1C,1D,1C,1C,1C,1D,\
1D,1D,1D,1D,1C,1C,1C,1C,\
1D,1D,1C,1D,1C,1D,1C,1D,\
1C,1D,1D,1D,1C,1C,1D,1C,\
1C,1C,1D,1D,1D,1D,1D,1C,\
1C,1C,1C,1D,1C,1D,1C,1C,\
1D,1C,1D,1C,1C,1D,1C,1C,\
1C,1D,1D,1D,1D,1D,1C,1C,\
1C,1C,1D,1D,1C,1D,1C,1D,\
1C,1D,1C,1D,1D,1D,1C,1C,\
1D,1C,1C,1C,1D,1D,1D,1D,\
1D,1C,1C,1C,1C,1D,1C,1D,\
1C,1C,1D,1C,1D,1C,1C,1D,\
1C,1C,1C,1D,1D,1D,1D,1D,\
1C,1C,1C,1C,1D,1D,1C,1D,\
1C,1D,1C,1D,1C,1D,1D,1D,\
1C,1C,1D,1C,1C,1C,1D,1D,\
1D,1D,1D,1C,1C,1C,1C,1D,\
1C,1D,1C,1C,1D,1C,1D,1C,\
1C,1D,1C,1C,1C,1D,1D,1D,\
1D,1D,1C,1C,1C,1C,1D,1D,\
1C,1D,1C,1D,1C,1D,1C,1D,\
1D,1D,1C,1C,1D,1C,1C,1C,\
1D,1D,1D,1D,1D,1C,1C,1C,\
1C,1D,1C,1D,1C,1C,1D,1C,\
1D,1C,1C,1D,1C,1C,1C,1D,\
1D,1D,1D,1D,1C,1C,1C,1C,\
1D,1D,1C,1D,1C,1D,1C,1D,\
1C,1D,1D,1D,1C,1C,1D,1C,\
1C,1C,1D,1D,1D,1D,1D,1C,\
1C,1C,1C,1D,1C,1D,1C,1C,\
1D,1C,1D,1C,1C,1D,1C,1C,\
1C,1D,1D,1D,1D,1D,1C,1C,\
1C,1C,1D,1D,1C,1D,1C,1D,\
1C,1D,1C,1D,1D,1D,1C,1C,\
1D,1C,1C,1C,1D,1D,1D,1D,\
1D,1C,1C,1C,1C,1D,1C,1D,\
1C,1C,1D,1C,1D,1C,1C,1D,\
1C,1C,1C,1D,1D,1D,1D,1D,\
1C,1C,1C,1C,1D,1D,1C,1D,\
1C,1D,1C,1D,1C,1D,1D,1D,\
1C,1C,1D,1C,1C,1C,1D,1D,\
1D,1D,1D,1C,1C,1C,1C,1D,\
1C,1D,1C,1C,1D,1C,1D,1C,\
1C,1D,1C,1C,1C,1D,1D,1D,\
1D,1D,1C,1C,1C,1C,1D,1D,\
 ]
     2  REM [HEX:\
21,82,40,01,00,00,3E,1D,\
BE,20,01,03,23,3E,76,BE,\
20,F4,C9 ]

    10 LET N=USR 17320
    20 PRINT "1=";N,"0=";800-N
counter.zip
(1.8 KiB) Downloaded 169 times
Last edited by XavSnap on Fri Nov 06, 2020 9:50 pm, edited 1 time in total.
Xavier ...on the Facebook groupe : "Zx81 France"(fr)
Moggy
Posts: 3231
Joined: Wed Jun 18, 2008 2:00 pm

Re: Need help working something out.

Post by Moggy »

Many many thanks gentlemen you have really helped more than you will ever know. :ugeek:

Again please accept my sincere gratitude. :D
User avatar
XavSnap
Posts: 1940
Joined: Sat May 10, 2008 4:23 pm
Location: 'Zx81 France' Fb group.

Re: Need help working something out.

Post by XavSnap »

Dr Beep codes are better, and faster…
I had to get two CP(HL) per value … it's a shame.

Use the A register with the CP $xx can buffer it.
Xavier ...on the Facebook groupe : "Zx81 France"(fr)
User avatar
zsolt
Posts: 214
Joined: Wed Apr 20, 2011 11:43 am
Location: Fót, Hungary

Re: Need help working something out.

Post by zsolt »

Hi,

Here are my solutions:

- for the original 800 characters (BASIC)

Code: Select all

 1 REM                     ; the 800 characters
10 LET C=-22400            ; the counter 800 * code "0"
20 FOR A=16514 TO 17313    ; the address loop (800 step)
30 LET C=C+PEEK A          ; set counter
40 NEXT A
50 PRINT "1=";C,"0=";800-C ; the results
- and the length independent faster/shorter (16 bytes) MC

Code: Select all

	ld hl,16514	; 1st byte in REM
	ld bc,0		; the counter
	ld a,29		; code of "1"
count_1:
	cp (hl)		; test byte
	jr nz,not_1	; skip if not "1"

	inc bc		; else set counter
not_1:
	inc hl		; set byte pointer
	jr nc,count_1	; test again until "N/L"

	ret		; 
Did you mean a big string instead of REM?

Code: Select all

 1 DIM A$(N)               ; the 800 characters
10 LET C=-28*N             ; the counter 800 * code "0"
20 FOR I=1 TO N            ; the loop (800 step)
30 LET C=C+CODE A$(I)      ; set counter
40 NEXT I
50 PRINT "1=";C,"0=";N-C ; the results
IDK, if it is better, but shorter. :mrgreen:

Regards,
Zsolt
ZX81 (8K), ENTERPRISE 128, [ZX SPECTRUM (48K,+,+128K,+2,+2A), TS1000, TS1500, TS2068, Cambridge Z88, PRIMO A64 (red)]
User avatar
XavSnap
Posts: 1940
Joined: Sat May 10, 2008 4:23 pm
Location: 'Zx81 France' Fb group.

Re: Need help working something out.

Post by XavSnap »

Hi Zsolt,
Thanks for your point of view.

In cas of "0" : PEEK A=28
In cas of "1" : PEEK A=29

Code: Select all

1 REM                     ; the 800 characters
10 LET C=-22400            ; the counter 800 * code "0"
20 FOR A=16514 TO 17313    ; the address loop (800 step)
30 LET C=C+PEEK A-28          ; set counter
40 NEXT A
50 PRINT "1=";C,"0=";800-C ; the results
In ASM:
Nice "nc"...

:ugeek:

We also can use a loop using DE=800, DEC DE , D OR E=0 for the end.

Code: Select all

	ld hl,16514	; 1st byte in REM
	ld bc,0		; the counter
	ld de,800
	ld a,29		; code of "1"
count_1:
	cp (hl)		; test byte
	jr nz,not_1	; skip if not "1"

	inc bc		; else set counter
not_1:
	inc hl		; set byte pointer
	dec de
	ld a,d
	or e
	jr nz,count_1
	ret		; 
Xavier ...on the Facebook groupe : "Zx81 France"(fr)
User avatar
XavSnap
Posts: 1940
Joined: Sat May 10, 2008 4:23 pm
Location: 'Zx81 France' Fb group.

Re: Need help working something out.

Post by XavSnap »

Near the Zsolt Basic routine:

Code: Select all

	ld hl,16514	; 1st byte in REM
	ld bc,0		; the counter
	ld de,800
	
count_1:
	ld a,(hl)		; test byte
	sub 28
	jr z,not_1
	inc bc		; else set counter (or BC=BC+A, but it's too long...PUSH HL HL=1 ADD HL,BC POP HL...)
	
not_1:
	inc hl		; set byte pointer
	dec de
	ld a,d
	or e
	jr nz,count_1	; test again until bc=0
	ret		; 
.end
Xavier ...on the Facebook groupe : "Zx81 France"(fr)
User avatar
zsolt
Posts: 214
Joined: Wed Apr 20, 2011 11:43 am
Location: Fót, Hungary

Re: Need help working something out.

Post by zsolt »

XavSnap wrote: Sat Nov 07, 2020 2:02 am...
In cas of "0" : PEEK A=28
In cas of "1" : PEEK A=29

Code: Select all

10 LET C=-22400            ; the counter 800 * code "0"
...
30 LET C=C+PEEK A-28          ; set counter

50 PRINT "1=";C,"0=";800-C ; the results
The "-28" in line 30 is not necessary, it happens in line 10
;)
ZX81 (8K), ENTERPRISE 128, [ZX SPECTRUM (48K,+,+128K,+2,+2A), TS1000, TS1500, TS2068, Cambridge Z88, PRIMO A64 (red)]
Post Reply