Unexpanded VIC 20 Memory
Moderator: Moderators
- Mike
- Herr VC
- Posts: 4841
- Joined: Wed Dec 01, 2004 1:57 pm
- Location: Munich, Germany
- Occupation: electrical engineer
Hi, Legacy, you proceed as follows:
- First copy+paste the DATA loader of MINIGRAFIK 4.02 into VICE. This is the most recent version to date.
- SAVE this program as "LOADER" onto a *.d64 image.
- RUN the program. The file "MINIGRAFIK" is written on disk. This is the actual BASIC extension. Up to here, these steps need only be done once.
- LOAD the file "MINIGRAFIK", and RUN it. The VIC shows the start screen again, with slightly less memory available than before. MINIGRAFIK is now active.
There is no need to memorize a certain SYS address to start the extension, as it is already contained in the program. The correct SYS shows up, when you LIST it before starting. This SYS is executed for you, when you type RUN+Return.
Michael
P.S.: Since we're now clearly off-topic, we should continue the discussion about MINIGRAFIK in the thread 'Hires Graphics', o.k.?
- First copy+paste the DATA loader of MINIGRAFIK 4.02 into VICE. This is the most recent version to date.
- SAVE this program as "LOADER" onto a *.d64 image.
- RUN the program. The file "MINIGRAFIK" is written on disk. This is the actual BASIC extension. Up to here, these steps need only be done once.
- LOAD the file "MINIGRAFIK", and RUN it. The VIC shows the start screen again, with slightly less memory available than before. MINIGRAFIK is now active.
There is no need to memorize a certain SYS address to start the extension, as it is already contained in the program. The correct SYS shows up, when you LIST it before starting. This SYS is executed for you, when you type RUN+Return.
Michael
P.S.: Since we're now clearly off-topic, we should continue the discussion about MINIGRAFIK in the thread 'Hires Graphics', o.k.?
Earlier on I made a promise to upload a few DASM example files. Hopefully I will find some time in the upcoming weekend to do so.
Apart from very simple examples, I will catch on to what Mike wrote in the other thread, take a medium advanced Basic program and rewrite it line by line to machine code. It was the way I once moved into a new level of programming. Previously I barely knew the instructions and what they did on their own. To use them to form a larger program was hard for me, until one day I took the task to convert one of my own Basic programs line by line. Since both programming languages are imperative anyway, usually you don't lose any efficiency that way. There is always room for optimizations afterwards.
If anybody has a particular Basic listing on up to 30-40 lines or so, please give a shout. Otherwise I'll try to come up with something myself.
Apart from very simple examples, I will catch on to what Mike wrote in the other thread, take a medium advanced Basic program and rewrite it line by line to machine code. It was the way I once moved into a new level of programming. Previously I barely knew the instructions and what they did on their own. To use them to form a larger program was hard for me, until one day I took the task to convert one of my own Basic programs line by line. Since both programming languages are imperative anyway, usually you don't lose any efficiency that way. There is always room for optimizations afterwards.
If anybody has a particular Basic listing on up to 30-40 lines or so, please give a shout. Otherwise I'll try to come up with something myself.
Anders Carlsson
I'm trying to convert this BASIC program into ML(DASM) , sofar I have line 60 down pat , maybe we can figure out the rest together ? I dont really want to sort data, but if you think it will help my graphics skills then might as well, I guess it wont hurt to learn how to sort stuff, may come in handy someday.
***OPERATION VALENTINE***
***OPERATION VALENTINE***
Code: Select all
60 print"clr/red":poke36879,8
70 for t = 0 to 43 step .25
80 a = int(10+9*sin(t))
90 print tab(a);
100 print chr$(115)
110 next t :goto 70
Right, and in this case, SIN is incremented in very tiny steps
t = 0.25 A = 10.0098
t = 0.5 a = 10.0392
t = 0.75 a = 10.0883
t = 1.0 a = 10.1570
t = 1.25 a = 10.2454
t = 1.50 a = 10.3533
t = 1.75 a = 10.4809
t = 2.00 a = 10.6281
t = 3.00 a = 11.4130
t = 5.00 a = 13.9220
Im just not sure how to implement a FOR ...NEXT loop, with .25 and not have it be that fast, I was working on double imbeded loops that would slow down process to actually make it look animated, but still in experimentation.
And how to get the whole program running as a whole is still a mystery, I know it would contain several subroutines to accomplish each task, each returning a value, but program logic is still a mystery. -noob
t = 0.25 A = 10.0098
t = 0.5 a = 10.0392
t = 0.75 a = 10.0883
t = 1.0 a = 10.1570
t = 1.25 a = 10.2454
t = 1.50 a = 10.3533
t = 1.75 a = 10.4809
t = 2.00 a = 10.6281
t = 3.00 a = 11.4130
t = 5.00 a = 13.9220
Im just not sure how to implement a FOR ...NEXT loop, with .25 and not have it be that fast, I was working on double imbeded loops that would slow down process to actually make it look animated, but still in experimentation.
And how to get the whole program running as a whole is still a mystery, I know it would contain several subroutines to accomplish each task, each returning a value, but program logic is still a mystery. -noob
Transform the code to this:Legacy wrote:Im just not sure how to implement a FOR ...NEXT loop, with .25...
Code: Select all
60 print"clr/red":poke36879,8
70 for t = 0 to 172
80 a = int(10+9*sin(t/4))
90 print tab(a);
100 print chr$(115)
110 next t :goto 70
This works but you'll have to change the syntax for DASM.
Lee.
Code: Select all
; draw an animated sin wave of red hearts that scrolls up a black screen
; this requires an unexpanded VIC
; variables
LAB_09 = $09 ; saved TAB() count
LAB_A2 = $A2 ; jiffy clock low byte
; hardware addresses
LAB_900F = $900F ; screen/border colour
; Vic ROM routines
LAB_CAD7 = $CAD7 ; print CR/LF
LAB_CB42 = $CB42 ; go output [CURSOR RIGHT]
LAB_CB47 = $CB47 ; print the character
LAB_E55F = $E55F ; clear the screen
LAB_E581 = $E581 ; home the cursor
LAB_E912 = $E912 ; set the colour
.ORG $0FFF ; load address - 2
; .prg file header
.word Begin ; set the load address
; BASIC program header, 2009 SYS 4110
Begin
.word nextline ; next line pointer
.word $07D9 ; 2009
.byte $9E ; SYS
.byte " 4110" ; [SPACE] and the value of entry as a string
.byte $00 ; end of line marker
nextline
.word $0000 ; BASIC end of text
; the code
entry
JSR LAB_E55F ; clear the screen
JSR LAB_E581 ; home the cursor
LDA #$08 ; set black/black
STA LAB_900F ; set the screen/border colour
LDA #$1C ; set [RED]
JSR LAB_E912 ; set the colour
init_loop
LDX #sinend-sintab ; set the table length
loop
LDA sintab-1,X ; get the TAB() count from the sin table
STA LAB_09 ; save the TAB() count
tab_loop
JSR LAB_CB42 ; go output [CURSOR RIGHT]
DEC LAB_09 ; decrement the TAB() count
BNE tab_loop ; loop if more to do
LDA #$73 ; set the character
JSR LAB_CB47 ; print the character
JSR LAB_CAD7 ; print CR/LF
; now slow the whole thing down a bit by waiting for the jiffy clock, first wait for not
; xxxx xx00 in case we got back here in less than one jiffy. it will on the short lines
LDA #$03 ; set the mask for 4 jiffies
jiffy_loop
BIT LAB_A2 ; mask the jiffy clock low byte
BEQ jiffy_loop ; loop until the jiffy byte is not xxxx xx00
; now wait for the jiffy count to get back to xxxx xx00
jiffy_loop2
BIT LAB_A2 ; mask the jiffy clock low byte
BNE jiffy_loop2 ; loop until the jiffy byte is xxxx xx00
DEX ; decrement the table index
BNE loop ; loop if more to do
BEQ init_loop ; else go start the loop again, branch always
; now the table of precalculated sin values. this table completes one cycle in 24 lines
; which is just over one screen height. if you want a longer or shorter sinewave just
; change the table
sintab
.byte $0A,$0D,$0F,$11,$12,$13
.byte $13,$13,$12,$11,$0F,$0D
.byte $0A,$07,$05,$03,$02,$01
.byte $01,$01,$02,$03,$05,$07
sinend
I see the BASIC ROM address' $CB42 $CB47 - which are labeled as output cursor right($CB42), and print character($CB47). I'm referring to the chart for BASIC ROM on Zimmers http://www.zimmers.net/cbmpics/cbm/vic/rommap.txt but it doesn't have these address' listed.
Is one Jiffy one clock cycle for 6502, I was hoping for an assembly routine that would slow down the cycles, but it seems that the clock is being synchronized with the vertical frequency of the system (pal/ntsc)
Also, this program is just calling BASIC ROM routines, not really doing the routines in Machine Language, is any speed/cycles/memory being lost due to this?
Is one Jiffy one clock cycle for 6502, I was hoping for an assembly routine that would slow down the cycles, but it seems that the clock is being synchronized with the vertical frequency of the system (pal/ntsc)
Also, this program is just calling BASIC ROM routines, not really doing the routines in Machine Language, is any speed/cycles/memory being lost due to this?
One jiffy clock is 1/60th of a second.
The routine entry points into the BASIC ROM are points that I've discovered for myself by disassembling the ROMs.
If you look at the code at $CAD7, print [CR][LF] it does ..
.. so it was no stretch to work out that loading A with the character to print and calling $CB47 would print it.
Also looking at the code before $CB47 you have ..
.. which saves loading A with the $1D in my code.
Lee.
The routine entry points into the BASIC ROM are points that I've discovered for myself by disassembling the ROMs.
If you look at the code at $CAD7, print [CR][LF] it does ..
Code: Select all
LDA #$0D ; set [CR]
JSR LAB_CB47 ; print the character
...
LDA #$0A ; set [LF]
JSR LAB_CB47 ; print the character
Also looking at the code before $CB47 you have ..
Code: Select all
LAB_CB42
LDA #$1D ; set [CURSOR RIGHT]
...
; print character
LAB_CB47
Lee.
Yes, $FFD2 is the common routine to call and will work both if you print to screen, file (disk/tape), printer or perhaps even RS-232 (modem).
$FFD2: JMP ($0326) ; jumps to the address pointed at $0326-27
Usually $0326 points to $F27A:
At $E742 further checks are done, handling logical lines and so on. It is not really meaningful to go into, just assume it will work.
$FFD2: JMP ($0326) ; jumps to the address pointed at $0326-27
Usually $0326 points to $F27A:
Code: Select all
F27A PHA ; save accumulator
F27B LDA $9A ; current output device
F27D CMP #$03 ; check if it's the screen
F27F BNE $F285 ; if not, jump
F281 PLA ; restore accumulator
F282 JMP $E742
Anders Carlsson