Unexpanded VIC 20 Memory

Basic and Machine Language

Moderator: Moderators

User avatar
Kweepa
Vic 20 Scientist
Posts: 1315
Joined: Fri Jan 04, 2008 5:11 pm
Location: Austin, Texas
Occupation: Game maker

Post by Kweepa »

So I was digging through the Whack source code and I notice that Aleksi stores some nybbles at $9400-$95FF on the unexpanded VIC.

Is it common knowledge that there's a whole spare 512x4bit block? I'd assumed that the hardware rerouted memory access when you insert an 8k expansion. Does anyone know why the hardware is designed this way? It seems ludicrously wasteful! But I'm loving the info. Extra memory! Yay!
carlsson
Class of '6502
Posts: 5516
Joined: Wed Mar 10, 2004 1:41 am

Post by carlsson »

Yes, it is rather well known. I'm using those 512 bytes quite frequently in my games when I want to store colour-ish data not visible to the player.

Also remember you may expand the screen to cover more than 512 bytes. In that case the 1K of nybbles comes handy. Generally PAL screens can grow bigger than NTSC ones can.
Anders Carlsson

Image Image Image Image Image
User avatar
Kweepa
Vic 20 Scientist
Posts: 1315
Joined: Fri Jan 04, 2008 5:11 pm
Location: Austin, Texas
Occupation: Game maker

Post by Kweepa »

Ah yes, that makes sense. Thanks.
I'm still not clear on why in the unexpanded/3k expanded VICs colour starts at $9600 rather than colour always starting at $9400. Crazy!
Legacy
Vic 20 Enthusiast
Posts: 154
Joined: Wed Dec 31, 2008 4:01 pm

Post by Legacy »

In an unexpanded VIC 20 the 512 locations in memory from $9600-$97ff are used as the colour RAM, whereas if an *K expansion RAM is fitted, the block $9400-$95ff is used instead. In either case the locations used are only four bits in size instead of the usual eight bits in size.
The different locations are used to hold the appropriate foreground colour
for each character area of the display on the TV screen. There is, therefore,
a direct correspondence between the locations of the video RAM, the character table and the colour RAM.
taken from

Lance Ewing (PAL user)
http://www.fpgaarcade.com/resources/6561.txt

Code: Select all

1 rem for pal systems, for ntsc use 4 instead of 12

10 fori=12to77step.5
20 poke36864,i
30 fort=1to 25:next
40 next
50 fori=77to12step-.5
60 poke36864,i
70 fort=1to25:next
80 next i
run

carlsson
Class of '6502
Posts: 5516
Joined: Wed Mar 10, 2004 1:41 am

Post by carlsson »

I think the screen matrix and colour memory addressing both read the "lowest" bit from 36866:

$1000 = $9400, $1200 = $9600
$1400 = $9400, $1600 = $9600
$1800 = $9400, $1A00 = $9600
$1C00 = $9400, $1E00 = $9600

It means even on an unexpanded machine, if you move the screen back to start at $1C00 = 7168, the colour memory will follow back to $9400.
Anders Carlsson

Image Image Image Image Image
Legacy
Vic 20 Enthusiast
Posts: 154
Joined: Wed Dec 31, 2008 4:01 pm

Post by Legacy »

Legacy wrote:Ok so back to the 1.3 demo:

1 REM VIC VERSION
800 FOR AD=864TO885:READDA:POKEAD,DA:NEXTAD
805 PRINT"SYS 864 TO ACTIVATE"
810 DATA 160, 0, 169, 1, 153, 0
820 DATA 30, 153, 0, 31, 169, 6
830 DATA 153, 0, 150, 153, 0, 151
840 DATA 200, 208, 237, 96
I believe I have a better understanding of this program now, it is written with BASIC Tokens and executed from memory byte 864. From just looking at it I can see there is some PRINT tokens and some STEP tokens.

I recall seeing a program online where COMMODORE + IBM = pi (symbol) . It was a brain teaser and there was also a contest to see who could create the most innovative clear screen routine and another article on creating a 3d star field, and now I never bookmarked the page and I've forgotten where it can be found. Can anyone assist me on finding this web page, I believe it may have Jim Brain on it as well, but not sure about that. Thank you
User avatar
Kweepa
Vic 20 Scientist
Posts: 1315
Joined: Fri Jan 04, 2008 5:11 pm
Location: Austin, Texas
Occupation: Game maker

Post by Kweepa »

Legacy wrote: I believe I have a better understanding of this program now, it is written with BASIC Tokens and executed from memory byte 864. From just looking at it I can see there is some PRINT tokens and some STEP tokens.
Not quite...
It's a machine code program which can be readily hand disassembled:

Code: Select all

LDY #0
LDA #1
STA $1E00,Y ; write 1 to the upper and lower pages of the screen memory
STA $1F00,Y
LDA #6
STA $9600,Y ; write 6 (blue) to the upper and lower pages of the color memory
STA $9700,Y
INY
BNE -19
RTS
Legacy
Vic 20 Enthusiast
Posts: 154
Joined: Wed Dec 31, 2008 4:01 pm

Post by Legacy »

I have put that code through dasm and there seems to be an error:

Code: Select all

------- FILE basicasm.asm LEVEL 1 PASS 1
      1  0000					      processor	6502
      2  0000 ????
      3  034e					      org	$034e
      4  034e
      5  034e		       a0 00		      LDY	#0
      6  0350		       a9 01		      LDA	#1
      7  0352		       99 00 1e 	      STA	$1E00,Y	; write 1 to the upper and lower pages of the screen memory
      8  0355		       99 00 1f 	      STA	$1F00,Y
      9  0358		       a9 06		      LDA	#6
     10  035a		       99 00 96 	      STA	$9600,Y	; write 6 (blue) to the upper and lower pages of the color memory
     11  035d		       99 00 97 	      STA	$9700,Y
     12  0360		       c8		      INY
basicasm.asm (13): error: Branch out of range (-886 bytes).
     13  0361		       d0 8a		      BNE	-19
     14  0363		       60		      rts
It seems like the instructions are one byte too long for it's intended purpose. The initial listing says it should goto 885 , the branch is not functional. I don't know how to fix this

d0 8a is actualy 208, 138 not 208,238 d0.... ED = 238 which means the BNE statement is wrong. The accumulator will never reach -19, is that added for a loop? I recompiled with -18 and -17 and everytime the branch is still out of range even though it falls within the specified bytes in memory (885 for -18)How did you find out the assembly code, this is what i tried doing :

Code: Select all

#processor 6502

	org $034e	                 ;846 (cass buffer)

	.byte $a0 $00 $a9 $01 $99 $00 $1e $99 $00 $1f $a9 $06
	.byte $99 $00 $96 $99 $00 $97 $c8 $d0 $ed $60
It didnt do what I thought it would
User avatar
Kweepa
Vic 20 Scientist
Posts: 1315
Joined: Fri Jan 04, 2008 5:11 pm
Location: Austin, Texas
Occupation: Game maker

Post by Kweepa »

Two problems:
The 864 = $360, not $34e (= 846)
I wrote the branch as an offset. The compiler expects it to be an absolute address or a label. Try this:

Code: Select all

LDY #0
LOOP:
LDA #1
STA $1E00,Y ; write 1 to the upper and lower pages of the screen memory
STA $1F00,Y
LDA #6
STA $9600,Y ; write 6 (blue) to the upper and lower pages of the color memory
STA $9700,Y
INY
BNE LOOP
RTS
Legacy
Vic 20 Enthusiast
Posts: 154
Joined: Wed Dec 31, 2008 4:01 pm

Post by Legacy »

Eureka!

Code: Select all

------- FILE basicasm.asm LEVEL 1 PASS 1
      1  0000					      processor	6502
      2  0000 ????
      3  0360					      org	$0360
      4  0360
      5  0360		       a0 00		      LDY	#0
      6  0362		       a9 01	   loop     LDA	#1
      7  0364		       99 00 1e 	      STA	$1E00,Y
      8  0367		       99 00 1f 	      STA	$1F00,Y
      9  036a		       a9 06		      LDA	#6
     10  036c		       99 00 96 	      STA	$9600,Y
     11  036f		       99 00 97 	      STA	$9700,Y
     12  0372		       c8		      INY
     13  0373		       d0 ed		      BNE	loop
     14  0375		       60		      RTS
That works, but how did you get those decimal numbers into hex and translate it into a program? According to my Assembly program the instructions are loaded into 0360 (i changed it) so it should just execute number after number?Or maybe I'm thinking of when you write hex as basic tokens at the beginning of BASIC RAM 4096. I still don't understand how you got that assembly program out of
810 DATA 160, 0, 169, 1, 153, 0
820 DATA 30, 153, 0, 31, 169, 6
830 DATA 153, 0, 150, 153, 0, 151
840 DATA 200, 208, 237, 96
Did you use Vicmon, I don't know how that operates I just use vice and dasm and just now have experimented with the list output file to get the actual register values i know A9 = load accumulator and a couple others. So I guess you know how to write an assembly program from just looking at the numbers in the DATA statements, calculating their hex format and formulate the proper assembly code... nice skills!
Legacy
Vic 20 Enthusiast
Posts: 154
Joined: Wed Dec 31, 2008 4:01 pm

Post by Legacy »

I found a couple places in memory that aren't really covered:

$0334-$033B 820-827
$03FC-$03FF 1020-1023

These areas are directly before and after the Cassette buffer $033C-$03FB , is this Free For All territory?
carlsson
Class of '6502
Posts: 5516
Joined: Wed Mar 10, 2004 1:41 am

Post by carlsson »

Yes, my annotated combined VIC/64 memory map lists those areas as unused.
Anders Carlsson

Image Image Image Image Image
Legacy
Vic 20 Enthusiast
Posts: 154
Joined: Wed Dec 31, 2008 4:01 pm

VIC Revealed - Nick Hampshire

Post by Legacy »

Nick talks about writing machine code and asks us to consider the following program, writing the first 256 characters on the screen, well here she is, and I even came up with my own conventions :

Code: Select all

;fill first page screen ram with first 256 characters, dasm/unexpanded

#processor 6502
	org $1001
	dc.b $0b,$10,$0a,$00,$9e,$34,$31,$30,$39,$00,$00,$00
	org $100d

main	
	ldy #$00	        ;y index 0
	lda #$00	        ;accumulator 
.1
	sta $1e00,y        ;7680,0 -absolute indexed
	clc
	adc #$01            ;0+1 = 1
	iny                 ;next screen mem
	bne .1		        ;put 256 chars in 256 mem locs

	lda #$06	         ;add some color to the screen
.2			            ;y is returned as 0 from first loop
	sta $9600,y
	iny
	bne .2		        ;repeat if y!=0
	
	jsr main	        ;do it again
Ok well I did steal a little from the valentine program, but I figured out how to add to the accumulato -yay!
carlsson
Class of '6502
Posts: 5516
Joined: Wed Mar 10, 2004 1:41 am

Re: VIC Revealed - Nick Hampshire

Post by carlsson »

Nice. Now you may want to consider some optimizations:

Code: Select all

#processor 6502
   org $1001
.byte $0b,$10,$0a,$00,$9e,$34,$31,$30,$39,$00,$00,$00

main:
  ldy #$00
loop$:
  tya ; transfer Y reg to A
  sta $1e00,y
  lda #$06
  sta $9600,y
  iny
  bne loop$

wait:
  jmp wait
As you see, two loops combined into one. However if your intent was not to fill colour memory at the same time as screen memory, you may just as well keep the two separate like you did.

TYA and its reverse TAY (see also TXA and TAX) are handy instructions to transfer the content of the X and Y registers to/from the accumulator. In your program you want to print a different character at each screen position so instead of counting A separately you can just reuse the Y value.

I'm not sure why you would want to JSR main at the end, in particular since you are likely to run out of spack space after a while.

By the way, if you use DASM there are a few home-made macros you might want to take part of. In particular it is great to have a macro to generate the Basic SYS stub you have added by hand at the beginning.
Anders Carlsson

Image Image Image Image Image
Legacy
Vic 20 Enthusiast
Posts: 154
Joined: Wed Dec 31, 2008 4:01 pm

Post by Legacy »

I see, so when we load Y index with 0 the value doesn't change when the contents are transferred into the accumulator, there is no need to add new instructions and the Wait loop is just a continuous loop at the end of the program instead of executing the main loop, the last instructions are still kept intact because the program has never moved forward. That will definitely help in the future when writing multi-routine programs.

Ok, but what about lda #6 , wouldnt that change the contents and bring accumulator out of synch with the Y index register? Oh I guess not because when Y is increased INY then Y goes to 1 and the contents are transferred back into the accumulator, very clever!
Post Reply