GenCartVic How-To Help?
Moderator: Moderators
-
- Vic 20 Newbie
- Posts: 10
- Joined: Thu Dec 25, 2008 8:11 am
GenCartVic/cc65
Hi. Harry Potter here. A couple years ago, I published on the cc65 contribs site a library called GenCartVic. It allows a programmer to create cartridge-based Vic-20 programs using cc65. It uses the keral start-up code and, therefore, can be used for applications. If you're interested, try it out.
GenCartVic How-To Help?
Hi! I'm wondering in maybe I'm approaching the issue the wrong way. If I wanted to create a cartridge-based application for the Vic20 that uses the kernal, how do I go about doing that?
Re: GenCartVic How-To Help?
There's a slight lack of details in your post, but: Just write a $a000 cartridge header + a small startup routine replicating the initial parts of the kernal reset routine found at $fd22, then go on with your code.
Re: GenCartVic How-To Help?
I'm guessing you know that you provide
followed by a jump to the BASIC cold start vector.
The warm start routine is called with .A, .X and .Y (top) on the stack, you must not use RTI to exit your routine. The KERNAL routine at $FF56 can restore the registers and return.
- a cold start routine
- a warm start routine
Code: Select all
FRESTOR = $FD52
INITMEM = $FD8D
INITVIA = $FDF9
INITSK = $E518
JSR INITMEM ; initialise and test RAM
JSR FRESTOR ; restore default I/O vectors
JSR INITVIA ; initialise I/O registers
JSR INITSK ; initialise hardware
CLI ; enable interrupts
The warm start routine is called with .A, .X and .Y (top) on the stack, you must not use RTI to exit your routine. The KERNAL routine at $FF56 can restore the registers and return.
Re: GenCartVic How-To Help?
Swore: I thank you for your input. Now, I'm wondering if I am doing the warm-start wrong. Will the wrong warm-start address cause the symptoms? How do I write the warm-start routine?
Re: GenCartVic How-To Help?
I do that. The problem is when I use cc65's puts() routine. When I use it, I experience the problems. When I use my CBMSimpleIO library instead, I don't, and I'm wondering why. Now, cc65's puts() function seems to open some files (screen and keyboard) upon initialization.tlr wrote:There's a slight lack of details in your post, but: Just write a $a000 cartridge header + a small startup routine replicating the initial parts of the kernal reset routine found at $fd22, then go on with your code.
Re: GenCartVic How-To Help?
Depends what your symptoms are. A bogus warm start routine could be called on the jiffy timer expiry and cause the system to lockup. If you're not needing to intercept STOP/RESTORE you could try using the normal routine at $FEC7.HarryP2 wrote:Now, I'm wondering if I am doing the warm-start wrong. Will the wrong warm-start address cause the symptoms? How do I write the warm-start routine?
Re: GenCartVic How-To Help?
What you describe are exactly my symptoms. Now, I thank you for your input. I'll try it now.srowe wrote:Depends what your symptoms are. A bogus warm start routine could be called on the jiffy timer expiry and cause the system to lockup. If you're not needing to intercept STOP/RESTORE you could try using the normal routine at $FEC7.HarryP2 wrote:Now, I'm wondering if I am doing the warm-start wrong. Will the wrong warm-start address cause the symptoms? How do I write the warm-start routine?
Re: GenCartVic How-To Help?
I just realized: I can't access the source code:it's on a floppy, and my laptop's USB floppy drive is broken. I have to go to my mother's house and pick up a working one.
Re: GenCartVic How-To Help?
for example "i screwed up the crt0 and now things dont work as expected"There's a slight lack of details in your post
I'm just a Software Guy who has no Idea how the Hardware works. Don't listen to me.
Re: GenCartVic How-To Help?
Okay. I tried the vector on an old copy. Same problem. Following is the crt0.s file I'm using:
And the .cfg:
Does this help?
Code: Select all
;
; Startup code for cc65 (Vic20 version)
;
.export _exit
.export __STARTUP__ : absolute = 1 ; Mark as startup
.import initlib, donelib, callirq
.import zerobss, push0
.import _main
.import RESTOR, BSOUT, CLRCH
.import __INTERRUPTOR_COUNT__
.import __RAM_START__, __RAM_SIZE__ ; Linker generated
.import __DATA_LOAD__, __DATA_RUN__, __DATA_SIZE__
.import _puts, _cgetc, _memcpy, pushax
.include "zeropage.inc"
.include "vic20.inc"
PLOT=$FFF0
; ------------------------------------------------------------------------
; Place the startup code in a special segment.
.segment "STARTUP"
.word $A000 ;Cartridge load address
.word Crt0_Init ;Address of start-up code
.word $FEC7;Crt0_Start ;I don't know.
.byte $41,$30,$C3,$C2,$CD ;ROM present signature
;--------------------------------------------------------------------
;Startup code:
Crt0_Init:
sei
cld
ldx #$ff
txs
;Run kernal setup routines.
jsr $FD8D
jsr $FD52
jsr $FDF9
jsr $E518
cli
;Set up BASIC env.
jsr $E3A4
;Set up stack.
;Clear bss.
; Save system stuff and setup the stack
lda #<$1E00
sta sp
lda #>$1E00
sta sp+1 ; Set argument stack ptr
;jsr zerobss
;Copy read/write data to RAM.
lda #<__DATA_RUN__
ldx #>__DATA_RUN__
jsr pushax
lda #<__DATA_LOAD__
ldx #>__DATA_LOAD__
jsr pushax
lda #<__DATA_SIZE__
ldx #>__DATA_SIZE__
;jsr pushax
jsr _memcpy
;jsr CLRCH
; Switch to second charset
lda #14
jsr BSOUT
;ldx #0
;ldy #0
;clc
;jsr PLOT
;lda #65
;jsr $FFD2
; Clear the BSS data
;jsr zerobss
;Call constructors.
;jsr initlib
; If we have IRQ functions, chain our stub into the IRQ vector
lda #<__INTERRUPTOR_COUNT__
beq NoIRQ1
lda IRQVec
ldx IRQVec+1
sta IRQInd+1
stx IRQInd+2
lda #<IRQStub
ldx #>IRQStub
sei
sta IRQVec
stx IRQVec+1
cli
; Call module constructors
NoIRQ1: jsr initlib
; Push arguments and call main()
;jsr callmain
jsr push0
jsr push0
jsr _main
; Back from main (This is also the _exit entry). Run module destructors
_exit: jsr donelib
; Reset the IRQ vector if we chained it.
;pha ; Save the return code on stack
lda #<__INTERRUPTOR_COUNT__
beq NoIRQ2
lda IRQInd+1
ldx IRQInd+2
sei
sta IRQVec
stx IRQVec+1
cli
NoIRQ2:
; Place the program return code into ST
;pla
;sta ST
;End and restart.
;Print end message.
lda #<EndMsg
ldx #>EndMsg
jsr _puts
;Wait for key.
jsr _cgetc
;Restart.
jmp ($FFFC) ;Kernal reset vector
; ------------------------------------------------------------------------
; The IRQ vector jumps here, if condes routines are defined with type 2.
IRQStub:
cld ; Just to be sure
jsr callirq ; Call the functions
jmp IRQInd ; Jump to the saved IRQ vector
; ------------------------------------------------------------------------
; Data
.data
IRQInd: jmp $0000
.rodata
;End message.
EndMsg:
.byt 147,"Your program ended.",13
.byt "Press any key to", 13
.byt "restart.",0
Code: Select all
SYMBOLS {
__STACKSIZE__: value = $200, type = weak; # 512-byte stack
}
MEMORY {
ZP: start = $0002, size = $001A, type = rw, define = yes;
#RAM: start = $0200, size = $0200, define = yes;
RAM: start = $1000, size = $0C00, define = yes;
ROM: start = $9FFE, size = $2002, define = yes, file = %O,
fill=yes;
}
SEGMENTS {
STARTUP: load = ROM, type = ro;
LOWCODE: load = ROM, type = ro, optional = yes;
INIT: load = ROM, type = ro, define = yes, optional = yes;
CODE: load = ROM, type = ro;
RODATA: load = ROM, type = ro;
DATA: load = ROM, run = RAM, type = rw, define = yes;
#ZPSAVE: load = RAM, type = bss;
BSS: load = RAM, type = bss, define = yes;
HEAP: load = RAM, type = bss, optional = yes; # must sit just below stack
ZEROPAGE: load = ZP, type = zp;
}
FEATURES {
CONDES: segment = INIT,
type = constructor,
label = __CONSTRUCTOR_TABLE__,
count = __CONSTRUCTOR_COUNT__;
CONDES: segment = RODATA,
type = destructor,
label = __DESTRUCTOR_TABLE__,
count = __DESTRUCTOR_COUNT__;
CONDES: segment = RODATA,
type = interruptor,
label = __INTERRUPTOR_TABLE__,
count = __INTERRUPTOR_COUNT__;
}
- Mike
- Herr VC
- Posts: 4839
- Joined: Wed Dec 01, 2004 1:57 pm
- Location: Munich, Germany
- Occupation: electrical engineer
Re: GenCartVic How-To Help?
...
Last edited by Mike on Sat Apr 23, 2016 8:03 am, edited 1 time in total.
Re: GenCartVic How-To Help?
I've been following this (and related) threads for some time, as I am a C developer and I have not had any luck getting cc65 to produce a valid $a000 cart image. I even had Oliver (I think that's his name) who maintains the compiler try to help, but neither of us could get the simple "hello world" to work.
SO, is there a working hellow world $a000 cart image project I could peruse? I was using 2.14 of cc65, as I recall, and I was able to get c64 cart images to compile fine
I also created (or maybe I borrowed some code, not sure) and successfully created a working 8kB VIC app image and then extended it to be a 16kB image. But. both fo those relied on loading into start of RAM and running from there,
Jim
SO, is there a working hellow world $a000 cart image project I could peruse? I was using 2.14 of cc65, as I recall, and I was able to get c64 cart images to compile fine
I also created (or maybe I borrowed some code, not sure) and successfully created a working 8kB VIC app image and then extended it to be a 16kB image. But. both fo those relied on loading into start of RAM and running from there,
Jim
Re: GenCartVic How-To Help?
Well, my cartridge cfg. seems to work with CBMSimpleIO but not the stdio library. Also, I've at one time been able to start working on a Vic20 game cartridge library but dumped it fearing cc65 C would be too slow for it and the Vic20 didn't have enough memory for that type of game. I can try to look for the CRT0.S file for the latter if you're interested.
Re: GenCartVic How-To Help?
That would be very helpful.
Jim
Jim