Jump to content
IGNORED

CC65 EMD driver


Recommended Posts

If you use cc65 you probably know that some of the other platforms have Extended Memory drivers. These are loadable modules like the joystick and TGI drivers. The 8-bit target has all the other bits, but no EM driver... well I finally got off my ass and wrote one for 130XE compatible memory upgrades.

 

Remember this is a cross platform API, not something optimized specifically for the Atari. If you're writing games (or anything) with cc65 targeted at the Atari, you are better off twiddling portb yourself. To make this work I had to stick a small routine in the stack... since you can't be sure where code that will bank out $4000 may be located with the standard linker config. I'm sure I won't win any ABBUC awards with this piece of code, so feel free to optimize or rework it (just post it here if you do-for all the cc65 community to use!)

 

atari-samples.zip: linker config files to make the overlay demos work in the cc65\samples directory. Edit overlaydemo.c to load "overdemo.1, overdemo.2 and overdemo3" first! Multidemo should work as is.

 

atari130xe-emd.zip: the source and complied emd driver.

 

emtest.atr: all the files compiled already for you to test out in an emulator.

atari-samples.zip

atari130xe-emd.zip

emtest.atr

Edited by Shawn Jefferson
  • Like 3
Link to comment
Share on other sites

Replying to myself again... :)

 

I wrote another driver, this time for the RAM under the OS on XL/XE systems. It works, but during the emtest.xex program there is considerable screen flicker. I'm assuming this is because I'm turning off interrupts at $D40E, and then back on... any way to avoid that? Also, there's no shadow of NMIEN ($D40E) is there?

 

source and compiled emd driver included in zip file

atrxlromemd.zip

emtest.atr

Edited by Shawn Jefferson
Link to comment
Share on other sites

Just wrote an email to the cc65 list :)

Then found this topic and teh easy to get files. I try them out and have a look at your mentioned "flickering"

 

AFAIK there is no shadow for NMIEN. It might be possible to check where the DLI-vector points to. If it is not to an RTI then it might be save to set the 7th bit as well.

Link to comment
Share on other sites

Shawn: hope I'm understanding the issue correctly, but set up a wrapper for the interrupt handlers so they bank the OS ROM back in when a VBI or whatever is triggered.

 

.proc IntHand
bit nmist
bpl NotDLI
jmp (vdslst)
NotDLI
pha
txa
pha
lda #> [ExitInt.NMI]
pha
lda #< [ExitInt.NMI]
pha
tsx
lda $0105,x ; perhaps this should be $100 - works for some reason, though
pha
cld
pha
txa
pha
tya
pha
lda $d301
sta pbsave
ora #1
sta $d301
sta nmires
jmp (vvblki)
.endp
;
.proc IRQHand
pha
lda #> [ExitInt.IRQ]
pha
lda #< [ExitInt.IRQ]
pha
php
lda $d301
sta pbsave
ora #1
sta $d301
jmp (vimirq)
.endp
;
.proc ExitInt
NMI
pla
tax
IRQ
lda pbsave
sta $d301
pla
rti
.endp
;
.proc Initialize ; consider clearing out pages 4-6 here
lda #0
sta nmien
sei
lda $d301
and #$fe ; switch out ROM
sta banktab ; save this value
sta $d301
lda #< IntHand
sta $fffa
lda #> IntHand
sta $fffb
lda #< IRQHand
sta $fffe
lda #> IRQHand
sta $ffff
lda #96
sta nmien
cli
rts
.endp
;

 

The above is more or less the way Turbo Basic does it, and I use this code in several projects. With this stuff in place, you can switch the OS in and out freely without worrying about interrupts or screen corruption.

Link to comment
Share on other sites

Does anyone know why the screen flickers in the first place? Too many missed interrupts or something?

 

So, if I'm understanding this correctly... I can set the interrupt vectors in the RAM under the OS, and just leave NMIEN alone in the emd driver... since any interrupts will go to this interrupt handler and will be serviced correctly (since before the interrupt is handled we're just turning the OS back on...) ???

 

What does "NMI" do in the ExitInt procedure?

 

Really I should probably change the OS RAM driver not to jump through $100, but I already had that framework from the other driver... in version 2 I guess! ;)

Edited by Shawn Jefferson
Link to comment
Share on other sites

Looks like it is a label. Its address gets pushed on the stack so that the exits thru this code and set PORTB.

Will have a closer look at it tomorrow. Its an interesting idea.

 

This kind of flicker I can't determine now. I thought it would be the flickering caused by temporarily removing the OS-charset definitions. As you can see in "HAR'em" while loading.

Well, you can see it when it is distributed by ABBUC ;)

 

In the case no one answers to that I will have a look with Altirra at it.

Link to comment
Share on other sites

Does anyone know why the screen flickers in the first place? Too many missed interrupts or something?

 

Creature's right, of course, about the OS character set. This didn't occur to me yesterday. I've never encountered this because I've always been using custom character sets. I'd suggest making a copy of the OS character set in RAM in exactly the same address space during the INIT routine. You can perhaps get away without all these interrupt handlers if you do that??? However, it's generally regarded as good practice not to disable the system interrupts for prolonged periods of time.

 

So, if I'm understanding this correctly... I can set the interrupt vectors in the RAM under the OS, and just leave NMIEN alone in the emd driver... since any interrupts will go to this interrupt handler and will be serviced correctly (since before the interrupt is handled we're just turning the OS back on...) ???

 

In the example I've provided, the OS ROM is turned off and left off, and any subsequent calls to the OS (for example to CIOV) have to turn it back on again first. Using this approach, you don't need to access the shadow RAM indirectly anyway - you can just treat it like regular RAM in most respects. However, you won't want to do this if you need to preserve compatibility with the CC65 library's OS calls (which won't bank the OS in first), so you'll want to turn the OS ROM back on again. The state of the OS ROM enable bit is therefore indeterminate on entry into the interrupt handler (bit 0 of PORTB will only be clear if your XMS handler is busy transferring data when the interrupt occured), so you'll need to add code to cache the current state of PORTB and restore it when the interrupt code has finished.

 

What does "NMI" do in the ExitInt procedure?

 

NMI and IRQ are local labels (this was all lifted directly from the GUI source code). You can access local labels in MADS by referencing the procedure name, followed by a period, followed by the local label. You'll need to use a simpler labelling method for other assemblers.

Edited by flashjazzcat
Link to comment
Share on other sites

BTW, just confirmed it's the charset.

As your loop is enabling/disabling the ROM all the time it of course disables the ROM when the raster beam is in the visible area.

And when ANTIC fetches the char-definition at exactly that point, it reads your test data from the $e400 area.

So, there is nothing happening with IRQ's missed. If you cannot stand the flicker for aesthetic reasons, do as the jazzy cat suggested.

 

If you want to see for yourself, start your emdtest in Altirra, hit F8 and enter "ba w $d301" in the command line.

Then hold down F8 and wait till the yellow line is visible and keep holding down F8.

 

Said it before and will say it again: I have no clue how I debugged without Altirra the last 20 years. :)

Edited by Creature XL
Link to comment
Share on other sites

Makes perfect sense of course. ANTIC is still drawing the screen. I think I will copy the character set during INIT maybe... and bypass the character set space in the driver... hmm, this driver is more complicated than I thought it would be. Might as well rewrite it not to use the stack too, no real need for that in this driver since main RAM will always be there and code calling the driver won't be potentially banked out.

 

Thanks guys!

Link to comment
Share on other sites

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