Page 1 of 2
GenCartVic/cc65
Posted: Wed Nov 16, 2011 7:57 am
by Harry Potter
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?
Posted: Fri Apr 15, 2016 6:46 am
by HarryP2
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?
Posted: Sat Apr 16, 2016 12:35 am
by tlr
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?
Posted: Sat Apr 16, 2016 2:07 am
by srowe
I'm guessing you know that you provide
- a cold start routine
- a warm start routine
The cold start routine is called quite early in the boot process and there's no equivalent of the RAMTAS, IOINIT routines that the C64 has. The KERNAL code that is run for a normal BASIC start is
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
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.
Re: GenCartVic How-To Help?
Posted: Sat Apr 16, 2016 4:25 am
by HarryP2
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?
Posted: Sat Apr 16, 2016 4:30 am
by HarryP2
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.
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.
Re: GenCartVic How-To Help?
Posted: Sat Apr 16, 2016 4:36 am
by srowe
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?
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.
Re: GenCartVic How-To Help?
Posted: Sat Apr 16, 2016 4:47 am
by HarryP2
srowe wrote: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?
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.
What you describe are
exactly my symptoms. Now, I thank you for your input.
I'll try it now.
Re: GenCartVic How-To Help?
Posted: Sat Apr 16, 2016 4:52 am
by HarryP2
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?
Posted: Sat Apr 16, 2016 5:08 am
by groepaz
There's a slight lack of details in your post
for example "i screwed up the crt0 and now things dont work as expected"
Re: GenCartVic How-To Help?
Posted: Sat Apr 16, 2016 5:38 am
by HarryP2
Okay. I tried the vector on an old copy. Same problem.
Following is the crt0.s file I'm using:
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
And the .cfg:
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__;
}
Does this help?
Re: GenCartVic How-To Help?
Posted: Sat Apr 16, 2016 5:45 am
by Mike
...
Re: GenCartVic How-To Help?
Posted: Wed Apr 20, 2016 11:48 am
by brain
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
Re: GenCartVic How-To Help?
Posted: Wed Apr 20, 2016 5:42 pm
by HarryP2
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?
Posted: Wed Apr 20, 2016 8:33 pm
by brain
That would be very helpful.
Jim