Jump to content
IGNORED

cc65 C-compiler can now create carts directly


Recommended Posts

I had some spare time this week and decided to do something nice for the Lynx. I added a capability to create cart images directly to the cc65 compiler and also wrote a tutorial of how to use it. This small tutorial is how to create a cart that just prints "Hello World" on the screen. The only tool you need to do this is the latest cc65 snapshot (23rd of December 2010) and a text editor. You can find these pre-compiled at the cc65.org site.

post-2099-129308118568_thumb.png

 

The process is described in Wookies web site at Writing and running your first code

post-2099-129308121226_thumb.png

 

I also added some other small tutorials like:

Setting up ComLynx on cc65 C-projects.

Using collision detection in a cc65 project.

 

I still plan to write some tutorials on how to create interruptors (like a real time clock), how to do exclusive-or sprites for great effects, cart access using cc65 and eeprom access using cc65.

Edited by karri
  • Like 1
  • 2 months later...

Great news! :) my anniversary day ;)

But your cc65 C-compiler is not release ?

 

No. It is still only in the daily builds. Besides I also hope to have time to add support for all block sizes before the next release date.

 

--

Karri

Great news! :) my anniversary day ;)

But your cc65 C-compiler is not release ?

 

No. It is still only in the daily builds. Besides I also hope to have time to add support for all block sizes before the next release date.

 

--

Karri

 

Today I finally got Wookies boot technique to work with the cc65 compiler. Here is the first Hello World application compiled with it. This boots almost instantly on the Lynx and it has no title screen anymore.

 

In addition to faster boot this also frees all RAM for the application. You can now use the code space from $0200 to $bc37 for your code. The end of the ram from $bc38 to $fff7 goes for two screen buffers and the last 8 bytes are for interrupt vectors.

 

Oh. And you can set __BLOCKSIZE__ to 512, 1024 or 2048 for creating cart images for 128k, 256k or 512k ROM's in the lynx.cfg file.

--

Karri

hello.zip

Edited by karri

In addition to faster boot this also frees all RAM for the application. You can now use the code space from $0200 to $bc37 for your code. The end of the ram from $bc38 to $fff7 goes for two screen buffers and the last 8 bytes are for interrupt vectors.

 

It should have been C038 - not BC38.

 

So the RAM map is

0000 - 00FF ZP variables

0100 - 01FF machine stack

0200 - A057 free space

A058 - C037 free space or collision detection buffer

C039 - E017 free space or 2nd screen buffer for dual buffer applications

E018 - FFF7 primary screen buffer

FFF8 - FFFF Lynx hw vectors

  • 4 weeks later...

 

Oh. And you can set __BLOCKSIZE__ to 512, 1024 or 2048 for creating cart images for 128k, 256k or 512k ROM's in the lynx.cfg file.

 

 

I constantly forget to ask, but I have a question regarding your 1.1 template which I am using for my project. Can I create a 512k ROM from that template? I'm currently around 170kb, but am constantly adding graphics. Would be a shame to hit 256k to find out that is the limit for the configuration of that template.

 

Oh. And you can set __BLOCKSIZE__ to 512, 1024 or 2048 for creating cart images for 128k, 256k or 512k ROM's in the lynx.cfg file.

 

 

I constantly forget to ask, but I have a question regarding your 1.1 template which I am using for my project. Can I create a 512k ROM from that template? I'm currently around 170kb, but am constantly adding graphics. Would be a shame to hit 256k to find out that is the limit for the configuration of that template.

 

My template did not have a working encrypter bootloader for 2048 byte blocks carts. So you will get problems.

 

The new version should not have problems with 2048 byte blocks as the bootloader does not care about block sizes anymore.

 

So what you should do to convert is to grab the latest snapshot.

 

Pick the file $(CC65_HOME)/cfg/lynx.cfg

 

Add there your own segments so that it has the same content as your template cfg file.

 

Change the __BOOTLOADER__ variable to 2048.

 

The you probably have to delete everything from directory.s except the directory stuff itself and replace DEFDIR segment with your real directory.

 

After this the Make file should use the standard bootloader, standard lnx-header and your own directory structure.

 

But you need to delete yout title sprite from the directory entries.

 

If needed I can help with changes...

--

Regards,

 

Karri

Thanks for the fast reply! Good to know what I'm dealing with. So in order to do that, I need to get the latest cc65 running.

 

I got one other question regarding the template. I recently got a modified flashcard from Lynxman replacing the 93C46 with a 93C66 chip. But it looks like the functions in the template are 93C46 specific? Haven't been able to read/write words yet.

 

Sounds like quite some changes that need to be made.. too bad I need to focus on my thesis and put the work on side-projects to a minimum.. don't know exactly when I could get around this.

Edited by Ninjabba

Thanks for the fast reply! Good to know what I'm dealing with. So in order to do that, I need to get the latest cc65 running.

 

I got one other question regarding the template. I recently got a modified flashcard from Lynxman replacing the 93C46 with a 93C66 chip. But it looks like the functions in the template are 93C46 specific? Haven't been able to read/write words yet.

 

Sounds like quite some changes that need to be made.. too bad I need to focus on my thesis and put the work on side-projects to a minimum.. don't know exactly when I could get around this.

 

The best thing would be to create many different eeprom drivers for different chips. They can all be linked into the same library.

 

On top of the library you add one export statement like this:

 

.export __93C46__: absolute = 1

_lynx_eeprom_read:

 

or

 

.export __93C66__: absolute = 1

_lynx_eeprom_read:

 

Later when you want to compile your code for a cart with a 93C46 chip you just add this to your config file.

 

SYMBOLS {
   __93C46__: type = import;
}

 

In this way your code can use the same routines lynx_eeprom_read(cell) and you do not have to bother about the chip type.

 

--

Karri

Thanks for the fast reply! Good to know what I'm dealing with. So in order to do that, I need to get the latest cc65 running.

 

I got one other question regarding the template. I recently got a modified flashcard from Lynxman replacing the 93C46 with a 93C66 chip. But it looks like the functions in the template are 93C46 specific? Haven't been able to read/write words yet.

 

Sounds like quite some changes that need to be made.. too bad I need to focus on my thesis and put the work on side-projects to a minimum.. don't know exactly when I could get around this.

 

The best thing would be to create many different eeprom drivers for different chips. They can all be linked into the same library.

 

On top of the library you add one export statement like this:

 

.export __93C46__: absolute = 1

_lynx_eeprom_read:

 

or

 

.export __93C66__: absolute = 1

_lynx_eeprom_read:

 

Later when you want to compile your code for a cart with a 93C46 chip you just add this to your config file.

 

SYMBOLS {
   __93C46__: type = import;
}

 

In this way your code can use the same routines lynx_eeprom_read(cell) and you do not have to bother about the chip type.

 

--

Karri

 

That sounds easy to do. I'm going to look into this tomorrow. Hopefully I can report positive results :)

Thanks for the fast reply! Good to know what I'm dealing with. So in order to do that, I need to get the latest cc65 running.

 

I got one other question regarding the template. I recently got a modified flashcard from Lynxman replacing the 93C46 with a 93C66 chip. But it looks like the functions in the template are 93C46 specific? Haven't been able to read/write words yet.

 

Sounds like quite some changes that need to be made.. too bad I need to focus on my thesis and put the work on side-projects to a minimum.. don't know exactly when I could get around this.

 

The best thing would be to create many different eeprom drivers for different chips. They can all be linked into the same library.

 

On top of the library you add one export statement like this:

 

.export __93C46__: absolute = 1

_lynx_eeprom_read:

 

or

 

.export __93C66__: absolute = 1

_lynx_eeprom_read:

 

Later when you want to compile your code for a cart with a 93C46 chip you just add this to your config file.

 

SYMBOLS {
   __93C46__: type = import;
}

 

In this way your code can use the same routines lynx_eeprom_read(cell) and you do not have to bother about the chip type.

 

--

Karri

 

That sounds easy to do. I'm going to look into this tomorrow. Hopefully I can report positive results :)

 

The cc65 supports only 93C46 today. But if you know how to write the 93C66 driver we can add it into the cc65 library like this.

 

--

Karri

The cc65 supports only 93C46 today. But if you know how to write the 93C66 driver we can add it into the cc65 library like this.

 

I browsed through my old emails and found out that Sage sent me codes for 93C46, 93C66 and 93C86 chips. So I believe it would make sense to add support for all these chips into the standard cc65 library.

 

It may take a few days to implement these.

 

--

Regards,

 

Karri

The cc65 supports only 93C46 today. But if you know how to write the 93C66 driver we can add it into the cc65 library like this.

 

I browsed through my old emails and found out that Sage sent me codes for 93C46, 93C66 and 93C86 chips. So I believe it would make sense to add support for all these chips into the standard cc65 library.

 

It may take a few days to implement these.

 

--

Regards,

 

Karri

 

I tried to do a few things yesterday, but it wasn't working out.. I honestly have no clue what to do when it comes to assembly. Having those drivers would be great!

Hi,

 

I am currently judging a dancing competition in Lyon and had some spare time this morning. Here is Sage's eeprom driver slightly modified to compile on the Lynx.

 

I do not know if it works correctly as I have no means of testing it.

 

I also dont't understand the French. I arrived yesterday in the afternoon and all restaurants around Brignais are closed. Even the restaurant at the hotel. Then I am told that I need a reservation in order to eat in the evening and the first table is available at 22:00 in the night. At 19:00 there are hundreds of people in the line for both restaurants. Why on earth can you not serve food between 14:00 and 19:00 like they do in the rest of the world?

 

--

Karri

(living on peanuts and waiting for breakfast...)

 

;***************
; EEPROM-routines
; for 93C66 (4096bit => 512 16-bit words)
;
; created : 11.05.95
; last modified :
; 
; 16.02.96      leaner (thanks to Harry)
; 12.03.96      test for busy after write and erase (well, Harry ) )
; 22.08.97      ported to ra65 for use with cc65
; 02.12.97	added xref for the new ra65
;     2010      93c66 support B. Spruck
;
; (c) 1995..97 Bastian Schick
; CS    = A7 (18)
; CLK   = A1 (11)
; DI/DO = AUDIN (32)
;
;And now how to contact the EEPROM :
;
;CARD
;PORT               ----\/----      93C66(SMD too)
;(18)  A7   --------| CS     |- +5V
;(11)  A1   --------| CLK    |- NC
;               +---| DI     |- NC
;(32) AUDIN ----+---| DO     |- GND
;                   ----------

.export		__93C66__: absolute=1
     	.export		_lynx_eeread
       .export		_lynx_eewrite
     	.import		popax
       .importzp	ptr1

       .include	"lynx.inc"

; -------------------
; EEPROM command list
EE_C_WRITE      =    $14
EE_C_READ       =    $18
EE_C_ERASE      =    $1C
EE_C_EWEN       =    $13
EE_C_EWEN2      =    $FF   ;; C0 schould be enough
EE_C_EWDS       =    $10
EE_C_EWDS2      =    $00

;**************
; read 16bit Wort from address A
_lynx_eeread:
sta ptr1
stx ptr1+1
ldx #EE_C_READ
jsr EE_Send11Bit
jsr EE_Read16Bit
lda ptr1
ldx ptr1+1
rts

;***************
; reads EEPROM-word to ptr1
; A,Y destroyed
EE_Read16Bit:
lda #$a
sta IODIR	; set AUDIN to Input
clc
stz ptr1
stz ptr1+1
ldy #15
EEloop1:
; CLK = 1
stz RCART0
stz RCART0
; CLK = 0
stz RCART0
stz RCART0

lda IODAT
and #$10	; mask bit
adc #$f0	; C=1 if A=$10
rol ptr1
rol ptr1+1	; shifts 0 to Carry
dey
bpl EEloop1

ldx #$1a
stx IODIR	; set AUDIN for output
;EE_SET_CS_LOW

ldx #3
stx SYSCTL1
dex
stx SYSCTL1

rts

;***************
; write word at address A
_lynx_eewrite:
sta ptr1
stx ptr1+1
ldx #EE_C_EWEN
lda #EE_C_EWEN2
jsr EE_Send11Bit
jsr popax
sta ptr1
stx ptr1+1
ldx #EE_C_WRITE
jsr EE_Send11Bit
jsr EE_Send16Bit

EE_wait:
; EE_SET_CS_HIGH

ldx #63
EEloop:
stz RCART0
stz RCART0
dex
bpl EEloop

lda #$0A
sta IODIR	; AUDIN to input
lda #$10
EE_wait1:
bit IODAT	; Until ready :D0-read is /D0-written
beq EE_wait1
lda #$1a	; AUDIN to output
sta IODIR
ldx #EE_C_EWDS
lda #EE_C_EWDS2
;	bra EE_Send11Bit ; fall into
;***************
; send A via I2C
; A,Y destroyed
EE_Send11Bit:
; EE_SET_CS_LOW
ldy #3
sty SYSCTL1
dey
sty SYSCTL1
; EE_SET_CS_HIGH

ldy #63
EEloop2:
stz RCART0
stz RCART0
dey
bpl EEloop2

pha
txa   ;; Ok erstmal x abarbeiten und A sichern
ldy #2 ; 3 times
EEloop3:
tax
and #$10
ora #$b
sta IODAT
; CLK = 1
stz RCART0
stz RCART0
; CLK = 0
stz RCART0
stz RCART0
txa
rol A
dey
bpl EEloop3

ldy #7 ; 8 times
pla  ;; jetzt kommt a an die reihe

ror A
ror A
ror A           ; bit 7 at pos. 4
EEloop4:
tax
and #$10

ora #$b
sta IODAT
; CLK = 1
stz RCART0
stz RCART0
; CLK = 0
stz RCART0
stz RCART0
txa
rol A
dey
bpl EEloop4
rts
;***************
; send I2Cword to EEPROM
; A,Y detroyed
EE_Send16Bit:
lda ptr1+1

ror A
ror ptr1
ror A
ror ptr1
ror A
ror ptr1

ldy #15
EEloop5:
tax
and #$10
ora #$b
sta IODAT
; CLK = 1
stz RCART0
stz RCART0
; CLK = 0
stz RCART0
stz RCART0
txa
rol ptr1
rol A
dey
bpl EEloop5

; EE_SET_CS_LOW
ldx #3
stx SYSCTL1
dex
stx SYSCTL1
rts

Edited by karri

Hi,

 

I am currently judging a dancing competition in Lyon and had some spare time this morning. Here is Sage's eeprom driver slightly modified to compile on the Lynx.

 

I do not know if it works correctly as I have no means of testing it.

 

I also dont't understand the French. I arrived yesterday in the afternoon and all restaurants around Brignais are closed. Even the restaurant at the hotel. Then I am told that I need a reservation in order to eat in the evening and the first table is available at 22:00 in the night. At 19:00 there are hundreds of people in the line for both restaurants. Why on earth can you not serve food between 14:00 and 19:00 like they do in the rest of the world?

 

--

Karri

(living on peanuts and waiting for breakfast...)

 

 

Thanks for the driver! I'm going to try it out later today.

 

Sounds crazy to travel all of Europe to end up in a place where nobody sells food. Best to get some french bread and cheese to survive those hours in between. Have a good time there though!

It looks like the erase function is missing here? I tried using the one from the 93C46, but can't figure out how to rewrite it to have it working.

 

Erase is obsolete for these newer chips.

 

It should work if you define

 

unsigned int _fastcall_ lynx_eeread(unsigned int addr);
void _fastcall_ lynx_eewrite(unsigned int addr, unsigned int val);

 

--

Karri

Thanks for the clarification. Hope you had some more luck with the French kitchen btw.. they are famous for their food :)

 

Good to know I can ignore the erase for this chip. But in your template (version 1.1) there is a dependency on erase in eeprom.s.

 

L0024:	jsr     boolne
jsr     tosanda0
cmp     #$00
beq     L0017
ldy     #$04
lda     (sp),y
jsr     _lnx_eeprom_erase

 

Removing this will give an out-of-bound error in eeprom.s when compiling.. any ideas how to solve this?

Hi,

 

I am currently judging a dancing competition in Lyon

[...]

I also dont't understand the French. I arrived yesterday in the afternoon and all restaurants around Brignais are closed. Even the restaurant at the hotel. Then I am told that I need a reservation in order to eat in the evening and the first table is available at 22:00 in the night. At 19:00 there are hundreds of people in the line for both restaurants. Why on earth can you not serve food between 14:00 and 19:00 like they do in the rest of the world?

Maybe because we never eat before 19:00, even at home ?

In fact, you should have been able to find a fast food, they usually are open the whole day, or buy some food in a supermarket. I guess that restaurant were full because of the dancing contest ?

 

Hope you enjoy the trip, apart this inconvenient.

 

Did you try to contact Rygar ? He is not far away from Lyon IIRC.

In fact, you should have been able to find a fast food, they usually are open the whole day, or buy some food in a supermarket. I guess that restaurant were full because of the dancing contest ?

 

Hope you enjoy the trip, apart this inconvenient.

 

Did you try to contact Rygar ? He is not far away from Lyon IIRC.

 

I did find a place selling ham, cheese, etc and sat in the grass with a friend.

 

I did not meet Rygar as I have no idea where in France the Lynx enthusiasts live. And my time schedule was too tight for travel outside Lyon.

 

Perhaps I should find out.

--

Regards,

 

Karri

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...