Unexpanded VIC 20 Memory

Basic and Machine Language

Moderator: Moderators

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

Post by Legacy »

ahh gotcha, I dunno why but I couldnt find that sys mem loc i needed. so im using version 3.2 do i load that into 8k expansion and do a sys8192 or 4622, im still confused
User avatar
Mike
Herr VC
Posts: 4841
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Post by Mike »

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.? :)
carlsson
Class of '6502
Posts: 5516
Joined: Wed Mar 10, 2004 1:41 am

Post by carlsson »

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.
Anders Carlsson

Image Image Image Image Image
User avatar
Mike
Herr VC
Posts: 4841
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Post by Mike »

How about a conversion of Quicksort, sorting an array of 16- or 32-bit integers?
carlsson
Class of '6502
Posts: 5516
Joined: Wed Mar 10, 2004 1:41 am

Post by carlsson »

Well yes, I did a Quicksort implementation in machine code a few years ago but it was slightly buggy. That routine however only handled 256 byte size elements.
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'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***

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
Leeeeee
soldering master
Posts: 396
Joined: Fri Apr 23, 2004 8:14 am

Post by Leeeeee »

If you were going to do that in assembly you wouldn't do it like that. You would pre calculate the int(10+9*sin(t)) values and read them from a table.

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

Post by Legacy »

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 :D
tlr
Vic 20 Nerd
Posts: 567
Joined: Mon Oct 04, 2004 10:53 am

Post by tlr »

Legacy wrote:Im just not sure how to implement a FOR ...NEXT loop, with .25...
Transform the code to this:

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
Then make a table for a=int(10+9*sin(t/4)) instead.
Legacy
Vic 20 Enthusiast
Posts: 154
Joined: Wed Dec 31, 2008 4:01 pm

Post by Legacy »

oh you quadded that up, nice one. advanced quadratical equations
Leeeeee
soldering master
Posts: 396
Joined: Fri Apr 23, 2004 8:14 am

Post by Leeeeee »

This works but you'll have to change the syntax for DASM.

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
Lee.
Legacy
Vic 20 Enthusiast
Posts: 154
Joined: Wed Dec 31, 2008 4:01 pm

Post by Legacy »

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?
Leeeeee
soldering master
Posts: 396
Joined: Fri Apr 23, 2004 8:14 am

Post by Leeeeee »

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 ..

Code: Select all

      LDA   #$0D              ; set [CR]
      JSR   LAB_CB47          ; print the character
...
      LDA   #$0A              ; set [LF]
      JSR   LAB_CB47          ; print the character
.. 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 ..

Code: Select all

LAB_CB42
      LDA   #$1D              ; set [CURSOR RIGHT]
...

; print character

LAB_CB47
.. which saves loading A with the $1D in my code.

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

Post by Legacy »

Could we also use $FFD2 to print a character that had been loaded into the accumulator?
carlsson
Class of '6502
Posts: 5516
Joined: Wed Mar 10, 2004 1:41 am

Post by carlsson »

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:

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
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.
Anders Carlsson

Image Image Image Image Image
Post Reply