Page 1 of 1

Where to put the code? !!!

Posted: Thu Dec 28, 2017 9:18 pm
by EVX
Hi there, I've been back tinkering with C= for a few years now, part time. I have a question about where to put a machine language program in order to operate correctly. The circuit is from the Vic20 Interfacing Bluebook. "Voice Output". I've breadboarded the hardware and I'm not sure where to put this code. The code samples a microphone and stores the data from some point to an end point. I have a 16k expansion cartridge I plan on using, but where should these routines go?!

Thanks much, looking forward to getting this going!

-EVX

Re: Where to put the code? !!!

Posted: Fri Dec 29, 2017 2:56 am
by Kakemoms
The code is only 67 bytes, so you could easily put it in the tape buffer.

Re: Where to put the code? !!!

Posted: Fri Dec 29, 2017 3:01 am
by srowe
Welcome to Denial.

Finding a location can be tricky and depends on the amount of code. For very small programs the tape buffer is a good choice (if you load and save from a disk). Otherwise you can lower the top of BASIC memory and use that. This ties the code to a specific expanded RAM configuration though.

You change the top of BASIC as follows:

Code: Select all

POKE 51,lsb:POKE 52,msb
POKE 55,lsb:POKE 56,msb
CLR
where 'lsb' is the least significant byte of the address (usually 0) and 'msb' is the most significant byte. Your 16K expansion runs from 8192 ($2000) to 24575 ($5FFF) so to reserve 4K use

Code: Select all

POKE 51,0:POKE 52,80
POKE 55,0:POKE 56,80
CLR
Your code can be written to 20480 ($5000) now and won't be touched by BASIC.

Re: Where to put the code? !!!

Posted: Fri Dec 29, 2017 5:46 am
by Mike
At least the code is fully relocatable, so it doesn't matter that much where you put the code. The tape buffer ($033C..$03FB, 192 bytes), as suggested by Kakemoms, is a possible candidate ...
Kakemoms wrote:The code is only 67 bytes, so you could easily put it in the tape buffer.
... as is, for that matter, the free area of $02A1..$02FF (the so-called 'program indirects', 95 bytes).
srowe wrote:You change the top of BASIC as follows:

Code: Select all

POKE 51,lsb:POKE 52,msb
POKE 55,lsb:POKE 56,msb
CLR
The ZP-addresses 51 and 52 are automatically set from 55/56 when doing a CLR. ;) Note the pointer in 55/56 addresses the first byte in memory *not* used by BASIC.


@EVX: Welcome to Denial! :mrgreen:

Re: Where to put the code? !!!

Posted: Fri Dec 29, 2017 11:16 am
by eslapion
@EVX
Welcome to Denial and happy new year but ... shouldn't this be in the 'programming' section ?

(mod: indeed)

Re: Where to put the code? !!!

Posted: Fri Dec 29, 2017 1:07 pm
by srowe
Mike wrote: The ZP-addresses 51 and 52 are automatically set from 55/56 when doing a CLR. ;) Note the pointer in 55/56 addresses the first byte in memory *not* used by BASIC.
I was just repeating the steps from "VIC Revealed" but you're right the routine first copies MEMSIZ to FRETOP so the the POKEs to 51,52 are unnecessary.

Re: Where to put the code? !!!

Posted: Fri Dec 29, 2017 4:10 pm
by Kakemoms
Sorry, I forgot to ask how much Vic-20 coding you know.

Also, if you don't want to be bothered with load/save of ML code, you could put the code in Basic DATA statements and put it to whichever location you want (once you run the basic program):

Code: Select all

10 for a=0 to 66:read b:poke 900+a,b:next
20 data 169,1,189,18,145,...
In case you want to put it in the cassette buffer (invoke it with SYS 900).
Or if you want to use hex values for the ML code while punching it in:

Code: Select all

10 b$="a901bd1291"
20 fora=0 to len(b$)/2-1:b=16*asc(mid$(b$,a*2+1,1)):c=asc(mid$(b$,a*2+2,1))
30 poke 900+a,(cand15)+(band240)+(((band1024)+(cand64))/7.11):next
I.e. you just punch in the code from your sheet into the string in line 10, and off you go. Its slower to run, but faster to punch. :)

(I keep the code here in lower case so you can copy and paste it into VICE for simple testing.)

Re: Where to put the code? !!!

Posted: Fri Dec 29, 2017 9:15 pm
by Kweepa
Very nice hex->ascii conversion!
I removed 9 characters:

Code: Select all

10 b$="a901bd1291"
20 fora=1 to len(b$)step2:b=16*asc(mid$(b$,a,1)):c=asc(mid$(b$,a+1,1))
30 poke 900+a/2,(band240)+(cand15)+((band1024)+(cand64))/7.1:next
I would love to have something shorter (and slightly less ugly with all the ANDs and the repeated MID$s)...

Hmm, this is a fair bit shorter (10-ish bytes) but requires GOSUBS:

Code: Select all

10 b$="a901bd1291"
20 fora=1tolen(b$):gosub99:c=b:a=a+1:gosub99:poke 900+a/2,16*c+b:next:end
99 b=asc(mid$(b$,a,1)):b=(band15)+(band64)/7.1:return

Re: Where to put the code? !!!

Posted: Sat Dec 30, 2017 3:55 am
by Mike
Here's my preferred solution for reading in hex data:

Code: Select all

1 DEFFNB4(X)=X-48+(X>57)*7
2 FORI=0TO27:READBY$
3 BY=16*FNB4(ASC(BY$))+FNB4(ASC(RIGHT$(BY$,1)))
4 POKE673+I,BY:NEXT
5 SYS673:END
6 DATA A2,00,BD,AF,02,20,D2,FF
7 DATA E8,E0,0E,D0,F5,60,48,45
8 DATA 4C,4C,4F,2C,20,57,4F,52
9 DATA 4C,44,21,0D

Re: Where to put the code? !!!

Posted: Sat Dec 30, 2017 10:13 am
by Kakemoms
Many good versions.

I think I like the gosub version since its compact and efficient. If strings are too long, one can divide them up into data statements

Code: Select all

5 s=0
10 read b$:t=len(b$):if t=1 then end
20 fora=1tot:gosub99:c=b:a=a+1:gosub99:poke 899+(a+s)/2,16*c+b:next:s=s+t:goto 10
99 b=asc(mid$(b$,a,1)):b=(band15)+(band64)/7.1:return
100 data "a901bd1291"
101 data "a900858ba91e","e"
If you are short on memory, you can put the code into start of basic. Overwriting your own basic program is not recommended unless you also move the start of basic. E.g. (for unexpanded Vic-20 basic starts at 4096):

Code: Select all

1 data "a901bd1291a900858ba91e"
2 data "a900858ba91e"
50 data "e"
95 s=0:u=10
96 read b$:t=len(b$):if t=1 then goto 100
97 poke 43,(u+t)and255:poke44,(4096+u+t)/256:fora=1tot:gosub99:c=b:a=a+1:gosub99
98 poke4095+(a+s)/2,16*c+b:next:s=s+t:u=u+9+t:goto96
99 b=asc(mid$(b$,a,1)):b=(band15)+(band64)/7.1:return
100 print "main program starts!"
This is less straight-forward since you have to move start of basic to second line while writing over first line (but after having read the data statement), and so on.. On unexpanded, this puts the ML program at SYS 4096.

Re: Where to put the code? !!!

Posted: Sat Dec 30, 2017 3:13 pm
by Kweepa
Very nice!
Mike's is obviously the cleanest and easiest to read, but it suffers from bloat if there is more than about 20 bytes.
I managed to squeeze a hybrid into a single line (if you use a couple of abbreviations):

Code: Select all

1 b$="a901bd1291"
2 fora=1tolen(b$):n=asc(mid$(b$,a,1)):b=16*b+n-48+(n>57)*7:poke899.6+a/2,b:m=1-m:b=b*m:next
Or for multiline strings

Code: Select all

1 p=900
2 read b$:t=len(b$):if t=1 then end
3 fora=1tot:n=asc(mid$(b$,a,1)):b=16*b+n-48+(n>57)*7:pokep,b:p=p+m:m=1-m:b=b*m:next:goto2
100 data a901bd1291
101 data a900858ba91e,e

Re: Where to put the code? !!!

Posted: Sat Dec 30, 2017 3:27 pm
by Mike
Kweepa wrote:Mike's is obviously the cleanest and easiest to read, but it suffers from bloat if there is more than about 20 bytes. [...]
If you take a look at quite a few of my other programs - when I include (machine code) data, I almost always write them in decimal. That way, they can be written to memory by a simple FOR ... READ ... POKE ... NEXT loop. I'm not that much concerned about any bloat at that stage. If I think it's unfeasible to provide the data in type-in form, I add them either as extra file or 'bury' them within the object file.

That being said, the OP merely asked for a free place where to put the machine code. I'd presume he actually knows how to get the hex data into memory. Only such constructions like dividing by 7.1 in an inherently integer-based algorithm just made my toes curl. :lol:

Re: Where to put the code? !!!

Posted: Sat Dec 30, 2017 5:13 pm
by Kakemoms
Just made a small ML program that loads a basic program "programpart1" from disk and runs it (SYS828). It can also load another program "programpart2" & run it (SYS831).

Code: Select all

1 p=828
2 read b$:t=len(b$):if t=1 then sys828
3 fora=1tot:n=asc(mid$(b$,a,1)):b=16*b+n-48+(n>57)*7:pokep,b:p=p+m:m=1-m:b=b*m:next:gO2
10 data"4c42034c5603a98985bba90385bc206b032059c62033c520aec7a99585bba903"
11 data"85bc206b032059c62033c520aec760a90185b8a90885baa90c85b7a90085b985"
12 data"0aa201a01020d5ff862d842e6050524f4752414d504152543150524f4752414d5041525432","e"
Its about 100 bytes of ML in three lines, so quite compact!

Re: Where to put the code? !!!

Posted: Sun Dec 31, 2017 10:02 am
by Floopy
EVX wrote:Hi there, I've been back tinkering with C=
So far there is C+C# C++ and now C=
:P

Re: Where to put the code? !!!

Posted: Wed Jan 03, 2018 3:11 am
by wimoos
My favorite location for relocatable code is at the end of the Basic program, as described in http://sleepingelephant.com/ipw-web/bul ... ble#p65698

Regards,

Wim.