Page 1 of 2

Need help working something out.

Posted: Fri Nov 06, 2020 1:58 pm
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

Re: Need help working something out.

Posted: Fri Nov 06, 2020 8:19 pm
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

Re: Need help working something out.

Posted: Fri Nov 06, 2020 9:22 pm
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

Re: Need help working something out.

Posted: Fri Nov 06, 2020 9:23 pm
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 184 times

Re: Need help working something out.

Posted: Fri Nov 06, 2020 9:42 pm
by Moggy
Many many thanks gentlemen you have really helped more than you will ever know. :ugeek:

Again please accept my sincere gratitude. :D

Re: Need help working something out.

Posted: Fri Nov 06, 2020 9:47 pm
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.

Re: Need help working something out.

Posted: Sat Nov 07, 2020 12:21 am
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

Re: Need help working something out.

Posted: Sat Nov 07, 2020 2:02 am
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		; 

Re: Need help working something out.

Posted: Sat Nov 07, 2020 2:27 am
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

Re: Need help working something out.

Posted: Sat Nov 07, 2020 9:50 am
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
;)