Vic20 5k memory

Basic and Machine Language

Moderator: Moderators

User avatar
beamrider
Vic 20 Scientist
Posts: 1448
Joined: Sun Oct 17, 2010 2:28 pm
Location: UK

Re: Vic20 5k memory

Post by beamrider »

johncl wrote:Btw, anyone know whats in $03fc-$03ff? Those last bytes after the cassette buffer. Looks like room for 2 pointers or something?
Unused - it tells you in "Compute's Mapping the Vic" that I mentioned above...
johncl
Vic 20 Amateur
Posts: 58
Joined: Sat Dec 22, 2007 3:17 am

Re: Vic20 5k memory

Post by johncl »

Indeed, I downloaded that one just now and see it goes into some detail on each memory location. Just what I was looking for.
User avatar
buzbard
Vic 20 Devotee
Posts: 213
Joined: Sun Jul 03, 2005 9:10 am

Re: Vic20 5k memory

Post by buzbard »

$3fc - $3ff is unused.
If you havent already done so, go to bombjack and grab a copy of "Mapping the VIC", it's probably the most valuable book you could find for programming the VIC20.

[EDIT: Little slow with that one] lol.
Ray..
johncl
Vic 20 Amateur
Posts: 58
Joined: Sat Dec 22, 2007 3:17 am

Re: Vic20 5k memory

Post by johncl »

Hehe, I am probably the slow one as I totally missed beamriders book tip there (I thought it was another Compute book which I was also being tipped about elsewhere).

Going over the tables now and will do some more tests tomorrow. Possibly setting the cursor thing to a non-zero value will also not update the other bytes that is changed when its blinking? Will have to test that.

Also I saw there were some interesting places where it stored the screen offset locations based on where the cursor was so I immediately thought that the ROM surely contains a table for this, and indeed I found it at $edfd ! So there is the 22x mul table so I dont have to add my own. Juhu, a few bytes saved. ;)

I also spotted on address $8270 a possibly useful bit pattern list that can be used for masks or tests. Contains 01,02,04,08,10,20,40,80. Ofc this areas contains the ROM charset so what I really found was a petscii symbol. :) - I wonder if there are other ROM chars that are useful like this. Naturally $826c contains these in the opposite direction.
johncl
Vic 20 Amateur
Posts: 58
Joined: Sat Dec 22, 2007 3:17 am

Re: Vic20 5k memory

Post by johncl »

Memory Map Sleuthing Part 2

Image

Thanks to the tip from buzbard I changed the code to write 1 in each location (as we could also see if anything reset some to zero as well). This naturally then disabled the hardware cursor, but it also meant that memory positions 205 (cursor counting) and 207 (blink status) is untouched. Although not seen from either of my pictures, position 206 is also being changed in my first test (it was just being changed to the same value it had so I did not detect a change), as that stores the char under the cursor. This is also not touched when the cursor is not blinking. I am sure I could have figured all this out by reading the ROM code but its fun to just experiment. :)

Furthermore locations 243-244 ($f3-$f4) which are "Pointer to the current physical screen lines color map area" are silenced when there is no cursor blinking so those can likely also be used then.

When reading through the Mapping the VIC yesterday evening I had a hunch that 192 CASI which reflects tape motor status could also be updated by the Kernal, and indeed it sets this to a zero, so this is another memory spot to avoid (which I missed in my first test as that set everything to zero in the first place).

One should also note that the end 9 bytes of the stack isn't used the moment basic jumps into your own code. $01f6-$01f7 contains the address that the basic sys address jumps to and the bytes behind to the end is the Basic/Kernal using before this entry. So its likely wise to do a ldx #$ff and txs at the start of your own code to move the stack pointer to the bottom since we wont be returning to basic. That gives you a bit longer contiguous free memory available at $0100 up to max depth that stack is used. The Kernal itself seems only to go 8 bytes deep so thats not very much lost. Depending on the depth of your JSRs you can safely use most of the stack as free memory really (I already have an intended use for it in my game).

As a sidenote I learned from the "Mapping the VIC" book how to detect memory expansions too as the system sets the locations 43-44 ($2b-$2c) to point to where basic programs start depending on unexpanded, 3k or 8k/more. Reading $2c and check for $10 (unexpanded), $04 (3k) or $12 (8k+) should be enough it seems. So it should be fairly easy to load extra stuff then depending on availability of ram which is what I intend to do in the game. Really beginning to enjoy coding for the Vic20 now. :)
User avatar
beamrider
Vic 20 Scientist
Posts: 1448
Joined: Sun Oct 17, 2010 2:28 pm
Location: UK

Re: Vic20 5k memory

Post by beamrider »

Good work.

Incidentaly, there's a kernel dissasembly here...

http://www.mdawson.net/vic20chrome/vic2 ... sembly.txt

where you can see what is being done in the IRQ routine - "update the clock, flash the cursor, control the cassette and scan the keyboard"
User avatar
Mike
Herr VC
Posts: 4832
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Re: Vic20 5k memory

Post by Mike »

One remark to your empirical method: you can't really expect that the ROM code still shows the same behaviour regarding zeropage usage, when you overwrite most of its workspace.

However, there is a simple rule regarding the general usage of the ZP: the BASIC interpreter uses $00..$8F, the KERNAL uses $90..$FA. As I wrote earlier, $FB..$FE are completely free, $03..$06 are initialised to pointers to float <-> INT conversions (but not used within BASIC), and are also effectively free.

If your program doesn't use any routines of BASIC, that means $00..$8F are free to use for your own programs and you can still use all routines of the KERNAL and won't get any problems. When you use addresses $90..$FA, be prepared that any KERNAL functions could mess up values there, or be messed up by unexpected values put there by your own program, depending on which functions are being called. Therefore, the addresses which are relevant to and shared between tape and RS232 functions are usually the best bet for own (temporary) storage.
johncl wrote:As a sidenote I learned from the "Mapping the VIC" book how to detect memory expansions too as the system sets the locations 43-44 ($2b-$2c) to point to where basic programs start depending on unexpanded, 3k or 8k/more. Reading $2c and check for $10 (unexpanded), $04 (3k) or $12 (8k+) should be enough it seems... [...]
On occasions, you might also find other values there. Actually, the BASIC start address isn't directly set here, rather these values are taken from another set of workspace variables initialised by the RAMTAS routine during reset:

Code: Select all

$0281-$0282/641-642     Pointer: Bottom of Memory for Operating System
$0283-$0284/643-644     Pointer: Top of Memory for Operating System
Then a routine in the BASIC cold start initialises the BASIC RAM, copies $0281/$0282 into $2B/$2C and $0283/$0284 into $37/$38, sets the byte before the BASIC start to zero and executes NEW, which also sets all other relevant pointers in the zeropage and writes another two zero bytes to indicate end of program.

Now, a utility program can enter the reset sequence, but skip RAMTAS. Instead, the BASIC cold start can be executed with 641..644 to the user's liking, and that's the preferred method to unexpand the VIC-20. With a RAM expansion inserted, just enter:

Code: Select all

POKE642,16:POKE644,30:POKE648,30:SYS64818
...and you get 3583 BYTES FREE - until the next hard reset or power cycle. :)
johncl
Vic 20 Amateur
Posts: 58
Joined: Sat Dec 22, 2007 3:17 am

Re: Vic20 5k memory

Post by johncl »

Ah thanks. Yes indeed, and that ROM routine at $eabf is what $0314-$0315 points to, and where one often wedge your own routine in to extend features (that then needs to jump to $eabf at the end).

Again sorry for my "noobness", but when looking in the "Mapping the VIC" book I read a bit about the VIA1 and VIA2 where it seems you can change the IRQ enable at $911e and $912e to possibly turn off all interrupts altogether so that these bytes in zero page is actually never touched? I found another post by Mike who say (quote) "...the interrupt vectors are fixed in the VIC-20 and are always routed to the following routines in the KERNAL: ..." (in a thread about digis here).

So it sounded to me that it was not possible to avoid these, although seeing you can redirect $0314,$0315 it really seems you can avoid that $eabf ROM routine being executed. Naturally this would mean to go completely barebone with regards to keyboard input reading then as well, although perhaps its possible to call those ROM routines that scan the keyboard ($eb1e, routine just after this one) at least but not do the screen editor, cursor, cassette and clock stuff. I guess I could try that out by copying the vital bits of the ROM there and only call the keyboard thing to test this.

It dawns on me that I might have started this digging in the wrong end, haha. :oops:

Seeing that Mike has replied too, I am sure you might be the one to enlighten me on this. :)

About tape and serial bytes, if you don't call any Kernal routines that do tape and serial things, I guess these are not really touched? Or can you trigger things happening in the Kernal if you modify these bytes, and it tries to do stuff on the tape/serial interfaces? I wouldnt want to trigger unexpected things on real hardware while I happily make things work in the emulator.

I just want to make it clear that I don't intend to return to basic and I neither use any Kernal routines (or I only use them before the zero page and all that is cleared/used). So that is the starting point for my memory hunt here. I basically just want to get to as much as I can of the available RAM.
User avatar
Mike
Herr VC
Posts: 4832
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Re: Vic20 5k memory

Post by Mike »

johncl wrote:[...] I read a bit about the VIA1 and VIA2 where it seems you can change the IRQ enable at $911e and $912e to possibly turn off all interrupts altogether so that these bytes in zero page is actually never touched? [...] I just want to make it clear that I don't intend to return to basic and I neither use any Kernal routines (or I only use them before the zero page and all that is cleared/used). So that is the starting point for my memory hunt here. I basically just want to get to as much as I can of the available RAM.
If you turn off all interrupt sources and never call any ROM code, then you can use the entire RAM.
johncl
Vic 20 Amateur
Posts: 58
Joined: Sat Dec 22, 2007 3:17 am

Re: Vic20 5k memory

Post by johncl »

Fantastic, and thanks for clearing that! I just tested writing my own IRQ routine for the $0314,$0315 vector and see that the complete zero page is all available now! But I guess just turning off this would then be a better solution. Except that I will likely use this for a music player.
User avatar
beamrider
Vic 20 Scientist
Posts: 1448
Joined: Sun Oct 17, 2010 2:28 pm
Location: UK

Re: Vic20 5k memory

Post by beamrider »

I just tried not vectoring to the KERNEL IRQ (apart from a call to update the jiffy clock) after my own handler as I don't need keyboard, cursor etc.

Seems to yield a small performance boost too!

At the end of my handler code I have this..

Code: Select all

JSR $FFEA ;update jiffy clock
JMP $EB15  ;finish IRQ
johncl
Vic 20 Amateur
Posts: 58
Joined: Sat Dec 22, 2007 3:17 am

Re: Vic20 5k memory

Post by johncl »

Great! :)

Btw, since the keyboard scan stuff is somewhat complicated it might be wise to just use the Kernal routine than write your own, even though it likely does a bit more than you would need in a game (which basically only needs the value in $c5). Here is my code if someone wants to free up as much zero page as possible while still having keyboard scan working:

Code: Select all

// Simple IRQ for $0314,$0315 that only calls Kernal keyboard scan routine (but no cursor, cassette and clock stuff)
// These bytes in zero page are modified by the keyboard Kernal routine: 197 ($c5), 198 ($c6), 203 ($cb), 245 ($f5), 246 ($f6)
// And these in second page must also be avoided: $0289-$0291
irq:
	// add e.g. your music player here
	jmp $eb12

// entry point for your game (e.g. sys from basic)
begin:
	sei
	lda #<irq
	sta $0314
	lda #>irq
	sta $0315
	ldx #$ff
	txs	// reset stack back to bottom
	inx
	stx $0289	// set keyboard buffer size to 0
	cli
	// rest of your fantastic game here :)
Edit: Fixed the silly copy paste of exact code from kernal by just jumping there (as indicated by beamrider).
Edit2: Somehow managed to scissor out an important ldx #$ff in there...

Alternatively you can just set $0314 and $0315 to point to $eb12 if you don't need to do anything yourself in this irq.
Last edited by johncl on Fri Nov 21, 2014 7:32 am, edited 3 times in total.
User avatar
beamrider
Vic 20 Scientist
Posts: 1448
Joined: Sun Oct 17, 2010 2:28 pm
Location: UK

Re: Vic20 5k memory

Post by beamrider »

Cool, btw you could achieve the same result by just 'jmp' ing to $eb12 in the kernal, which has identical code to those 8 lines at the end of your IRQ handler (unless you are a purist of course :wink: )
johncl
Vic 20 Amateur
Posts: 58
Joined: Sat Dec 22, 2007 3:17 am

Re: Vic20 5k memory

Post by johncl »

Haha, you were quicker than me, I just discovered that myself and was going to fix it. :) Copy-Paste is an old habit hard to shake off. ;)
johncl
Vic 20 Amateur
Posts: 58
Joined: Sat Dec 22, 2007 3:17 am

Re: Vic20 5k memory

Post by johncl »

Hehe, couldnt resist optimizing this further if you don't need your own IRQ:

Code: Select all

	sei
	lda #$12
	sta $0314
	inc $0315
	stx $0289	// set keyboard buffer size to 0 - X is always 0 on entry here! (read from $030d)
	dex
	txs	// reset stack back to bottom
	cli
I checked the ROM disassembly and saw that page 0,2,3 are always zeroed out, and among these are $030d which is the what the kernal sets the X register on the SYS command. :) - Hence we can zero out the buffer size, "dex" it and set stack at end. Also $0315 already points to $ea so we can just increment it by one, leaving only the #$12 we need to store in $0314.

Voila! And we made the code completely unreadable! :D

Btw, the at "Number of characters in the keyboard buffer at $277" that is normally updated in 198 ($c6) doesnt budge when you set the size down to zero so there is another byte freed. ;)
Post Reply