Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

C128 Z80 - Interrupts, docu needed

85 views
Skip to first unread message

Sven Paepke

unread,
Jun 3, 2004, 9:10:07 PM6/3/04
to
Hi,

Does anyone have information about the handling of interrupts under the Z80?
I would like to know which interrupts are being handled (VIC,SID,CIA,???),
and whether these are handled by the Z80 or the 8510?

What I want to find out is
- whether I have to poll the keyboard, or is there an interrupt routine I
can hook into?
- Same for the VIC raster interrupts - can I use them under Z80?

Any documentation, sample code etc. would be appreciated!

Thanks.


Regards,
Sven


David Evans

unread,
Jun 3, 2004, 9:56:58 PM6/3/04
to
In article <PZPvc.4814$rz4....@news-server.bigpond.net.au>,

Sven Paepke <spae...@bigpond.net.au> wrote:
>Hi,
>
>Does anyone have information about the handling of interrupts under the Z80?
>I would like to know which interrupts are being handled (VIC,SID,CIA,???),
>and whether these are handled by the Z80 or the 8510?
>

Have you tracked down "The Switcheroo Pivot" in The Transactor,
Volume 7, Issue 03, November 1986? It may provide some insight.

--
David Evans dfe...@bbcr.uwaterloo.ca
Ph.D. Candidate, Computer/Synth Junkie http://bbcr.uwaterloo.ca/~dfevans/
University of Waterloo "Default is the value selected by the composer
Ontario, Canada overridden by your command." - Roland TR-707 Manual

Sven Paepke

unread,
Jun 4, 2004, 9:46:32 AM6/4/04
to
Thanks David.

The code is interesting for the switch between Z80 and 8502(8510). But it
does not answer my question regarding the handling of interrupts when the
Z80 is running. Unfortunately, I can't find the actual article on the
Internet. C.S. Bruce hasn't scanned this particular article yet.

If you have any other ideas/sources for info - please let me know.

Regards,
Sven

"David Evans" <dfe...@bcr10.uwaterloo.ca> wrote in message
news:c9okta$7vd$1...@rumours.uwaterloo.ca...

Matthew Montchalin

unread,
Jun 4, 2004, 4:25:58 PM6/4/04
to
On Fri, 4 Jun 2004, Sven Paepke wrote:
|The code is interesting for the switch between Z80 and 8502(8510). But it
|does not answer my question regarding the handling of interrupts when the
|Z80 is running. Unfortunately, I can't find the actual article on the
|Internet. C.S. Bruce hasn't scanned this particular article yet.
|
|If you have any other ideas/sources for info - please let me know.

If anybody ever COULD use the Z80 to serve an interrupt generated by a
6526 or a 6567 (a CIA chip or a VIC-II chip), we would have heard of it
by now. I doubt you can find a trace from a CIA or a VIC-II that runs
up to the Z80 interrupt pin, so if that is true, that answers your
question. It also would explain why the Z80 always had to switch over
to 8502 mode to do all of the I/O stuff. The 8502 likes to have stuff
mapped to memory, and all of the I/O handlers were already written in
that mode, so that might be why we never see anybody use a Z80 to do
I/O.

Maciej Witkowiak

unread,
Jun 4, 2004, 5:08:29 PM6/4/04
to
Sven Paepke wrote:
> If you have any other ideas/sources for info - please let me know.

C128's CP/M sources should be helpful.

ytm

--
Najlepsza sygnatura to brak sygnatury.

bud

unread,
Jun 5, 2004, 2:47:24 AM6/5/04
to

'Lo Matthew:

Group: comp.sys.cbm Date: Fri, Jun 4, 2004, 1:25pm (CDT-2) From:
mmon...@OregonVOS.net (Matthew Montchalin)

script:

>If anybody ever COULD use the Z80
>to serve an interrupt generated by a
>6526 or a 6567 (a CIA chip or a
>VIC-II chip), we would have heard of
>it by now. I doubt you can find a trace
>from a CIA or a VIC-II that runs up to
>the Z80 interrupt pin, so if that is true,
>that answers your question. It also
>would explain why the Z80 always had
>to switch over to 8502 mode to do all
>of the I/O stuff. The 8502 likes to have
>stuff mapped to memory, and all of the
>I/O handlers were already written in
>that mode, so that might be why we
>never see anybody use a Z80 to do I/O.

If this is correct, then it confirms my suspicion that the Z80 on the
128 is handled in the same manner as the Z80 cart for the 64. The main
difference being that the 128 has it built-in.

CBM didn't feel like re-inventing the wheel for the Z80, since they
already had a proven "good enough" (I/O) system.

Makes sense to me.

salaam,
dowcom

--
To e-mail me, add the character zero to "dowcom". i.e.:
dowcom(zero)(at)webtv(dot)net.

http://community.webtv.net/dowcom/DOWCOMSAMSTRADGUIDE

MSWindows is television,… Linux is radar.

Peter van Merkerk

unread,
Jun 5, 2004, 6:37:25 AM6/5/04
to
bud wrote:
>
> 'Lo Matthew:
>
> Group: comp.sys.cbm Date: Fri, Jun 4, 2004, 1:25pm (CDT-2) From:
> mmon...@OregonVOS.net (Matthew Montchalin)
>
> script:
>
>
>>If anybody ever COULD use the Z80
>>to serve an interrupt generated by a
>>6526 or a 6567 (a CIA chip or a
>>VIC-II chip), we would have heard of
>>it by now. I doubt you can find a trace
>
>>from a CIA or a VIC-II that runs up to
>
>>the Z80 interrupt pin, so if that is true,
>>that answers your question. It also
>>would explain why the Z80 always had
>>to switch over to 8502 mode to do all
>>of the I/O stuff. The 8502 likes to have
>>stuff mapped to memory, and all of the
>>I/O handlers were already written in
>>that mode, so that might be why we
>>never see anybody use a Z80 to do I/O.
>
>
> If this is correct,

It is not; a quick peek at the schematic of the C128 reveils that the
interupt input of the Z80 is connected to the IRQ input of the 8502. So
in theory (I haven't tested it myself) the Z80 can handle any interrupt
that the 8502 can handle (with the exception of the NMI which is
hardwired to +5 volt on the Z80).

The reason that all I/O stuff is done in 8502 mode, is that otherwise
you would have to duplicate the I/O routines; if the Z80 did all I/O by
itself the ROM you not only need I/O routines for the 8502 but also the
Z80. Also the 8502 routines were tested and proven. So the way I/O is
implemented on the C128 not only saved ROM space, but also design and
test effort.

--
Peter van Merkerk
peter.van.merkerk(at)dse.nl

Matthew Montchalin

unread,
Jun 5, 2004, 6:09:07 PM6/5/04
to
<whether there is a trace from the 6567 to the Z80 IRQ pin>

On Sat, 5 Jun 2004, bud wrote:
|If this is correct, then it confirms my suspicion that the Z80 on the
|128 is handled in the same manner as the Z80 cart for the 64. The main
|difference being that the 128 has it built-in.
|
|CBM didn't feel like re-inventing the wheel for the Z80, since they
|already had a proven "good enough" (I/O) system.

But what if someone solders a line from the 6567 to the Z80 interrupt
pin? Or ... um ... whatever the Z80 uses for IRQ input ... you might
be able to put together some really mind-blowing IRQ servers on the
Z80 side of reality, now would that be cool or what?!

But even if there were a way of flagging an IRQ 'active' state, how would
the Z80 be able to return the favor and turn it back off again without
flipping back to 8502 mode? The 6567 isn't mapped into Z80 addressing
space, is it?

bud

unread,
Jun 6, 2004, 3:21:11 AM6/6/04
to

'Lo Matthew:

Group: comp.sys.cbm Date: Sat, Jun 5, 2004, 3:09pm (CDT-2) From:
mmon...@OregonVOS.net (Matthew Montchalin)

script:

>But what if someone solders a line from

>the 6567 to the Z80 interrupt pin?

According to Peter, Commodore did. (Well, indirectly.)

> The 6567 isn't mapped into Z80
>addressing space, is it?

I can't see why it would be.

Group: comp.sys.cbm Date: Sat, Jun 5, 2004, 12:37pm (CDT+7) From:
mer...@deadspam.com (Peter van Merkerk)

script:

>>If this is correct,
>
>It is not; a quick peek at the schematic
>of the C128 reveils that the interupt
>input of the Z80 is connected to the

>IRQ input of the 8502. …
(snip)


>
>The reason that all I/O stuff is done in
>8502 mode, is that otherwise you would
>have to duplicate the I/O routines; if the
>Z80 did all I/O by itself the ROM you not
>only need I/O routines for the 8502 but
>also the Z80. Also the 8502 routines
>were tested and proven. So the way
>I/O is implemented on the C128 not
>only saved ROM space, but also design
>and test effort.

I may not have said it explicitly enough. That is at least what I
implied. It worked for the 64, there seems no reason to have changed it
for the 128.

Sven Paepke

unread,
Jun 7, 2004, 9:19:01 AM6/7/04
to
Thanks for the info guys.

But maybe I should make it clear that I am fully aware of what Commodore did
(i.e. use 8502 and already written ROM routines for I/Os). I once (late
1980's) wrote my own VDC graphics library in Z80 assembler for use with
Turbo Pascal under CP/M. Initially I started off using the 8502 routines for
VDC access. When I found this too slow, I re-coded the routines under Z80.

My question is, whether somebody has information/examples/ideas on whether
it is possible to handle interrupts under Z80. After I read the message
regarding the wire between 8502-IRQ and Z80-INT, I went back to the
schematics (C128/C128D Service Manual) and tried to figure out which
interrupts could possibly be available to the Z80. But because I am not that
familiar with electronics, I could not make sense out of it. Also, the
service manual talks about the Z80 and 8502 sharing the data bus, with the
Z80 actually disappearing from the data bus for parts of a cycle. During
this time the VIC and other MOS chips "rule" the data bus. Unfortunately,
all of this is not clear to me. It is possible that that means the Z80 is
pre-empted by other chips and effectively never sees any interrupts from VIC
or CIA?. What I effectively want (if possible at all) is, to handle VIC, CIA
interrupts (VIC pin8 is connect to IRQ, so are CIA pin21 IRQ, Z80 pin16 INT,
8502 pin3 IRQ) using Z80 code.

Maybe my questions are a bit naive, and I may also be missing parts of the
picture. So if you can help me to clarify my understanding, that would be
appreciated. I will be trying a few things anyway:
- CIA keyboard events (CIA#1, port B)
- CIA SDR events
- VIC raster interrupts, sprite collisions with sprite or background

Once I have some results I will report here if anyone is interested.

My ultimate goal is to write some (fast) code which would let me make full
use of the capabilities of VIC and SID under CP/M+, without having to switch
back and forth between the processors. How about a demo with heaps of
sprites under Z80?! Let's see what comes out of it.

Regards,
Sven

===========================


"bud" <dow...@webtv.net> wrote in message
news:9383-40C...@storefull-3116.bay.webtv.net...

'Lo Matthew:

Group: comp.sys.cbm Date: Sat, Jun 5, 2004, 3:09pm (CDT-2) From:
mmon...@OregonVOS.net (Matthew Montchalin)

script:

>But what if someone solders a line from
>the 6567 to the Z80 interrupt pin?

According to Peter, Commodore did. (Well, indirectly.)

> The 6567 isn't mapped into Z80
>addressing space, is it?

I can't see why it would be.

Group: comp.sys.cbm Date: Sat, Jun 5, 2004, 12:37pm (CDT+7) From:
mer...@deadspam.com (Peter van Merkerk)

script:

>>If this is correct,
>
>It is not; a quick peek at the schematic
>of the C128 reveils that the interupt
>input of the Z80 is connected to the

>IRQ input of the 8502. .


(snip)
>
>The reason that all I/O stuff is done in
>8502 mode, is that otherwise you would
>have to duplicate the I/O routines; if the
>Z80 did all I/O by itself the ROM you not
>only need I/O routines for the 8502 but
>also the Z80. Also the 8502 routines
>were tested and proven. So the way
>I/O is implemented on the C128 not
>only saved ROM space, but also design
>and test effort.

I may not have said it explicitly enough. That is at least what I
implied. It worked for the 64, there seems no reason to have changed it
for the 128.

salaam,
dowcom

--
To e-mail me, add the character zero to "dowcom". i.e.:
dowcom(zero)(at)webtv(dot)net.

http://community.webtv.net/dowcom/DOWCOMSAMSTRADGUIDE

MSWindows is television,. Linux is radar.


Peter van Merkerk

unread,
Jun 7, 2004, 2:50:59 PM6/7/04
to
Sven Paepke wrote:
> Thanks for the info guys.
>
> But maybe I should make it clear that I am fully aware of what Commodore did
> (i.e. use 8502 and already written ROM routines for I/Os). I once (late
> 1980's) wrote my own VDC graphics library in Z80 assembler for use with
> Turbo Pascal under CP/M. Initially I started off using the 8502 routines for
> VDC access. When I found this too slow, I re-coded the routines under Z80.
>
> My question is, whether somebody has information/examples/ideas on whether
> it is possible to handle interrupts under Z80. After I read the message
> regarding the wire between 8502-IRQ and Z80-INT, I went back to the
> schematics (C128/C128D Service Manual) and tried to figure out which
> interrupts could possibly be available to the Z80. But because I am not that
> familiar with electronics, I could not make sense out of it. Also, the
> service manual talks about the Z80 and 8502 sharing the data bus, with the
> Z80 actually disappearing from the data bus for parts of a cycle. During
> this time the VIC and other MOS chips "rule" the data bus. Unfortunately,
> all of this is not clear to me. It is possible that that means the Z80 is
> pre-empted by other chips and effectively never sees any interrupts from VIC
> or CIA?.

I don't believe this is the case because if it were true, why would
Commodore have bothered to connect the INT line of the Z80? It is true
that the Z80 can be forced to release the bus (just like the 8502) in
favor of the VIC chip. There can be only one controlling the bus at a
time, and at set times the VIC needs to read data from memory to be able
to generate a video signal. Since the video signal needs to be generated
at a fixed rate, the reading of data by the VIC chip cannot be postponed
or slowed down. The VIC chip is also to blame for the fact that the Z80
effectively only runs at 2 MHz.

The interrupt handling of the Z80 can be a bit different that the 8502;
interrupt modes 0 & 2 expect an interrupt vector on the databus,
something a C128 cannot provide. But the Z80 has also a interrupt mode
1...read on...

> What I effectively want (if possible at all) is, to handle VIC, CIA
> interrupts (VIC pin8 is connect to IRQ, so are CIA pin21 IRQ, Z80 pin16 INT,
> 8502 pin3 IRQ) using Z80 code.

Note that a long, long time ago I did a very little bit of Z80
programming on the C128 (just to prove to myself I could do it) and that
did not involve interrupts, so I cannot say for sure that it can be
done. But looking at the schematic I can see no reason why interrupts
cannot be handled by the Z80. However since the MOS chips don't put an
interrupt vector on the data bus only mode 1 interrupts are possible
(jumps to 0038H) on a C128.

> Maybe my questions are a bit naive, and I may also be missing parts of the
> picture. So if you can help me to clarify my understanding, that would be
> appreciated. I will be trying a few things anyway:
> - CIA keyboard events (CIA#1, port B)
> - CIA SDR events
> - VIC raster interrupts, sprite collisions with sprite or background
>
> Once I have some results I will report here if anyone is interested.

It would be interesting to know if it can be done. Unfortunately I lack
the time (it is has been too long ago to pick things up quickly) to do
this experiment myself. I sincerely hope you figure this one out. I'm
sorry I can't be of more use to you.

> My ultimate goal is to write some (fast) code which would let me make full
> use of the capabilities of VIC and SID under CP/M+, without having to switch
> back and forth between the processors. How about a demo with heaps of
> sprites under Z80?! Let's see what comes out of it.

It would be interesting to see what comes out of this experiment, keep
us posted!

Good luck!

Pekka Takala

unread,
Jun 8, 2004, 10:45:25 AM6/8/04
to

I _think_ that the cia actually gives interrupts for the z80, but it just
in CP/M releases itself and tada- the 8502 does the interrupt routine and
acknowledges it. After that the z80 is turned back on and then z80 on -> a
RTI (or whatever in z80) does the rest.

Imagine a average program in CP/M, for example Wordstar or something. Just
polling is just not sane, but if they use interrupts they can read the
keyboard in sane rate. The z80 is not a multitasking cpu nor is 8502 so
interrupts are a must to be able to do something without HUGE guesses of
hardware (imagine cp/m). So the cp/m runs with z80, and when interrupt
comes the z80 switches the 8502 on, 8502 serves interrupt and changes over
to z80. This makes use of reliable code tested for years to be used in as
many places as possible.

And in another example here they actually write data to video chip using
z80. So the vic chip in c128 is accessible also with z80 and that means
that we can also acknowledge the interrupts. The z80 runs at 2 mhz, and is
slower than a 6502 in 1 mhz mode. To gain about same speed the z80 needs
to run at 4 mhz speed. That is also a reason to not use the z80 for i/o,
because it is so much slower. Even memory copying with z80 using the
memory copy command is slower than memory copying with 8502 using a loop,
because 8502 commands are faster and cycles-per-byte rate is smaller (not
to mention 65816 memory block copy command- 7 cycles per byte, on a scpu
you can copy the graph screen in 8192 1 mhz cycles.... of course reading
from memory expansion is slower, but not so slow...)

Sven Paepke

unread,
Jun 9, 2004, 10:50:58 AM6/9/04
to
So you think it is not worth the while? I thought the Z80 runs at 4MHz
(thats the clock the VIC generates for it) apart from the cycles the VIC
needs to read the video memory, during this time the clock goes back to
1MHz. That means for approx 3/4 of a machine cycle the Z80 runs at 4MHz, and
for the remainder it runs at 1Mhz. Which makes for approx 3Mhz on average.

My thinking was that the switching Z80->8502->Z80 is very time consuming and
avoiding it could potentially increase the speed of some I/Os dramatically.
Also, I have this dream of programming a sprite demo using the Z80. Reason?
No reason. Just to find out whether it is possible.

Re the relative speed of the processors: If you count the cycles it takes
the Z80 and the 8502 to do something, there are no great differences. The
8502 excels when it comes to indexed and indirect addressing, the Z80 has
block copy and block compare and a few more registers. All in all they are
not so different in their overall performance. But the Z80 runs at 4Mhz (for
the best part of each cycle) in the C128. And this is why I am so interested
in using it.

Anyway, I am working on a few tests. Over the next couple days I'll find out
what works and what doesn't. I'll report back here once I am done.

Thanks for the help!!

Regards,
Sven


"Pekka Takala" <pekka....@pp.inet.fi> wrote in message
news:pan.2004.06.08....@pp.inet.fi...

Cameron Kaiser

unread,
Jun 9, 2004, 2:45:09 PM6/9/04
to
"Sven Paepke" <spae...@bigpond.net.au> writes:

>So you think it is not worth the while? I thought the Z80 runs at 4MHz
>(thats the clock the VIC generates for it) apart from the cycles the VIC
>needs to read the video memory, during this time the clock goes back to
>1MHz. That means for approx 3/4 of a machine cycle the Z80 runs at 4MHz, and
>for the remainder it runs at 1Mhz. Which makes for approx 3Mhz on average.

No. According to pp 575-6 of the 128 PRG, the Z80, while it is a 4MHz part,
is only being driven half the time for an effective speed of 2MHz (the VIC-
IIe only generates clocks for it when it's actively on the bus), generating
something like this (ASCII art warning):

System clock -____________________--------------------____________________--
Z80 clock _-----_____-----_________________________-----_____-----_______

[...]


>Re the relative speed of the processors: If you count the cycles it takes
>the Z80 and the 8502 to do something, there are no great differences. The
>8502 excels when it comes to indexed and indirect addressing, the Z80 has
>block copy and block compare and a few more registers. All in all they are
>not so different in their overall performance. But the Z80 runs at 4Mhz (for
>the best part of each cycle) in the C128. And this is why I am so interested
>in using it.

This is controversial (naturally), and I would also point out that there are
many instructions on the Z80 that require additional cycles to execute
compared to the 8502 (an even more onerous penalty when the processor is only
effectively being driven at half speed).

--
Cameron Kaiser * cka...@floodgap.com * posting with a Commodore 128
personal page: http://www.armory.com/%7Espectre/
** Computer Workshops: games, productivity software and more for C64/128! **
** http://www.armory.com/%7Espectre/cwi/ **

Matthew Montchalin

unread,
Jun 10, 2004, 1:13:03 AM6/10/04
to
Cameron Kaiser wrote:
|>Re the relative speed of the processors: If you count the cycles it takes
|>the Z80 and the 8502 to do something, there are no great differences. The
|>8502 excels when it comes to indexed and indirect addressing, the Z80 has
|>block copy and block compare and a few more registers. All in all they are
|>not so different in their overall performance. But the Z80 runs at 4Mhz (for
|>the best part of each cycle) in the C128. And this is why I am so interested
|>in using it.
|
|This is controversial (naturally), and I would also point out that there
|are many instructions on the Z80 that require additional cycles to execute
|compared to the 8502 (an even more onerous penalty when the processor is
|only effectively being driven at half speed).

We don't hear much about burnt out Z80 chips on a C-128.

Does 'under-clocking' them give them longer lifespans?

Matthew Montchalin

unread,
Jun 10, 2004, 1:16:20 AM6/10/04
to
Sven Paepke wrote:
|My thinking was that the switching Z80->8502->Z80 is very time consuming and
|avoiding it could potentially increase the speed of some I/Os dramatically.
|Also, I have this dream of programming a sprite demo using the Z80. Reason?
|No reason. Just to find out whether it is possible.

Be sure to post the source code.

Though it may make no difference to the 'C' people trolling comp.sys.cbm,
it may be highly enriching to the rest of us.

Sven Paepke

unread,
Jun 11, 2004, 11:31:18 AM6/11/04
to
So far no joy. Whatever I do, the machine hangs ... Not even a simple VIC
raster interrupt would work. It seems that the computer immediately gets
stuck when you set the VIC IMR (register #26, to enable interrupts). I have
no explanation so far ...
Also, I tried to hook into the routine at $F21C, this is where RST 8 points
in bank 0, and also the vector for IM 2 (via vector in $FC00-$FCFF all $FD).
No joy either. After that I tried $E55A (this is where RST 8 points to in
bank 1), no joy.

So far, I am not sure whether there is a problem with my routine (it is
quite simple though), or if it is a more fundamental problem with Z80
interrupts in general. I'll keep you posted if I make any progress.

regards,
Sven


"Matthew Montchalin" <mmon...@OregonVOS.net> wrote in message
news:Pine.LNX.4.44.040609...@lab.oregonvos.net...

Peter van Merkerk

unread,
Jun 11, 2004, 11:54:22 AM6/11/04
to
"Sven Paepke" <spae...@bigpond.net.au> wrote in message
news:afkyc.4432$sj4....@news-server.bigpond.net.au...

> So far no joy. Whatever I do, the machine hangs ... Not even a simple VIC
> raster interrupt would work. It seems that the computer immediately gets
> stuck when you set the VIC IMR (register #26, to enable interrupts). I
have
> no explanation so far ...
> Also, I tried to hook into the routine at $F21C, this is where RST 8
points
> in bank 0, and also the vector for IM 2 (via vector in $FC00-$FCFF all
$FD).
> No joy either. After that I tried $E55A (this is where RST 8 points to in
> bank 1), no joy.

Which interrupt mode (0, 1 or 2) of the Z80 are you using?

Sven Paepke

unread,
Jun 12, 2004, 10:57:09 AM6/12/04
to
I have tried both, IM1 and IM2. IM0 cannot work, as the VIC or CIA can't put
a command on the bus for the handling of the interrupt. I also tried without
setting the interrupt mode myself (I still don't know what is the standard
IM mode under CP/M. Is there any way to find out?)

The C128 goes to nirvana the very moment the first interrupt kicks in. I
don't know why. Here is the interrupt routine I use. It should simply change
the VIC frame colour every time an interrupt occurs:

NEW_INT: DI ; disable interrupts
PUSH BC
PUSH AF
LD BC,VIC+25 ; read IRR
IN A,(C)
OUT (C),A ; acknowledge
AND %10000000 ; VIC generated interrupt?
JP Z,NO_VIC_INT ; no, then continue
LD BC,VIC+32
IN A,(C)
INC A
OUT (C),A
NOT_VIC_INT: POP AF
POP BC
JP OLD_INT ; continue with normal routine

Any suggestions?

Regards,
Sven


"Peter van Merkerk" <mer...@deadspam.com> wrote in message
news:2iu2tfF...@uni-berlin.de...

Peter van Merkerk

unread,
Jun 12, 2004, 4:22:55 PM6/12/04
to
Sven Paepke wrote:
> I have tried both, IM1 and IM2. IM0 cannot work, as the VIC or CIA can't put
> a command on the bus for the handling of the interrupt. I also tried without
> setting the interrupt mode myself (I still don't know what is the standard
> IM mode under CP/M. Is there any way to find out?)
>
> The C128 goes to nirvana the very moment the first interrupt kicks in. I
> don't know why. Here is the interrupt routine I use. It should simply change
> the VIC frame colour every time an interrupt occurs:
>
> NEW_INT: DI ; disable interrupts
> PUSH BC
> PUSH AF
> LD BC,VIC+25 ; read IRR
> IN A,(C)
> OUT (C),A ; acknowledge
> AND %10000000 ; VIC generated interrupt?
> JP Z,NO_VIC_INT ; no, then continue
> LD BC,VIC+32
> IN A,(C)
> INC A
> OUT (C),A
> NOT_VIC_INT: POP AF
> POP BC
> JP OLD_INT ; continue with normal routine
>
> Any suggestions?

Use IM1, IM2 expects the low byte of the interrupt handler to be put on
the data bus which is something that won't happen on a C128 (there could
be anything on the data bus when an interrupt occures). Before the C128
goes to nirvana, does the border color change?

Sven Paepke

unread,
Jun 12, 2004, 5:41:30 PM6/12/04
to

"Peter van Merkerk" <mer...@deadspam.com> wrote in message
news:2j16vsF...@uni-berlin.de...

> Use IM1, IM2 expects the low byte of the interrupt handler to be put on
> the data bus which is something that won't happen on a C128 (there could

Yes, this is why the area between $FC00 and $FCFF is filled with the byte
$FD. Together with the HI byte from the I register (which is $FD as well)
any data on the bus will lead to a jump to $FDFD, which is where the JP to
the actual interrupt handler occurs.

> be anything on the data bus when an interrupt occures). Before the C128
> goes to nirvana, does the border color change?

No, it does not change at all.

At the moment, I am trying to trace where the interrupts actually come from
and in which bank (although that should not matter, as my code runs in the
common area). My concern is that I have not patched all possible pieces of
code which can execute before we get to $FDFD. I.e. the RST 8 points to
different code in bank 0 and bank 1.

>
> --
> Peter van Merkerk
> peter.van.merkerk(at)dse.nl

Thanks for helping me Peter!

Regards,
Sven


Sven Paepke

unread,
Jun 13, 2004, 8:40:41 AM6/13/04
to
Peter,

It works now. I was too stupid to write relocatable code, so the interrupt
routine got lost in bank1 ...

I'll now play around with this routine, let's see whether I can come up with
something useful :-)

Thanks again! Your questions got me on the right track.

Regards,
Sven

"Peter van Merkerk" <mer...@deadspam.com> wrote in message

news:2j16vsF...@uni-berlin.de...

> ...


> Use IM1, IM2 expects the low byte of the interrupt handler to be put on
> the data bus which is something that won't happen on a C128 (there could
> be anything on the data bus when an interrupt occures). Before the C128
> goes to nirvana, does the border color change?
>
> --
> Peter van Merkerk
> peter.van.merkerk(at)dse.nl

> ...


Alvin

unread,
Jun 13, 2004, 2:53:49 PM6/13/04
to
"Sven Paepke" <spae...@bigpond.net.au> wrote in message
news:<eMKyc.12230$sj4....@news-server.bigpond.net.au>...

> "Peter van Merkerk" <mer...@deadspam.com> wrote in message
> news:2j16vsF...@uni-berlin.de...
>
> > Use IM1, IM2 expects the low byte of the interrupt handler to be put on
> > the data bus which is something that won't happen on a C128 (there could
> Yes, this is why the area between $FC00 and $FCFF is filled with the byte
> $FD. Together with the HI byte from the I register (which is $FD as well)
> any data on the bus will lead to a jump to $FDFD, which is where the JP to
> the actual interrupt handler occurs.

And if the peripheral id read is $ff? -- and it likely is
if the bus is left to float. You will need a 257 byte
vector table from $FC00 through $FD00, all containing $FD.
The I register should be loaded with $FC as it forms the
most significant byte of the vector table's address.

For what it's worth, interrupts are already disabled when
an interrupt routine first runs.

Alvin

Peter van Merkerk

unread,
Jun 13, 2004, 6:06:08 PM6/13/04
to
Sven Paepke wrote:
> Peter,
>
> It works now.

That is great news!

> I was too stupid to write relocatable code, so the interrupt
> routine got lost in bank1 ...

Please don't feel bad about it. It is an easy mistake to make and
difficult to track down. The end result is you succeeded where very few
have gone before; you should be proud of yourself!

> I'll now play around with this routine, let's see whether I can come up with
> something useful :-)

I look forward hearing about it!

> Thanks again! Your questions got me on the right track.

I'm glad I could be of some help to you.

Have fun!

Sven Paepke

unread,
Jun 14, 2004, 5:05:12 AM6/14/04
to
Thanks Alvin,

That's exactly what C= did: an area completely filled with the byte $FD from
$FC00 to $FCFF (in the common area). With the I register set to $FD, all IM2
interrupts go there and join the IM1 interrupts which point to the same
address. Not really neat or fast, but it works.

Regards,
Sven

"Alvin" <A9...@hotmail.com> wrote in message
news:1a3493d2.0406...@posting.google.com...

Alvin

unread,
Jun 14, 2004, 10:25:23 AM6/14/04
to
"Sven Paepke" <spae...@bigpond.net.au> wrote in message news:<cTdzc.26539$sj4....@news-server.bigpond.net.au>...

> That's exactly what C= did: an area completely filled with the byte $FD from
> $FC00 to $FCFF (in the common area). With the I register set to $FD, all IM2
> interrupts go there and join the IM1 interrupts which point to the same
> address. Not really neat or fast, but it works.

This is definitely not right -- you're sure you
didn't misread something :-)? The I register must
be $FC in this scheme. The peripheral provides
an identifier which is combined with the I register
to form the address $FCxx. Then the interrupt routine
address is read from $FCxx/FCxx+1 and jumped to.

Using a 256 byte table rather than a 257 byte one
is a common rookie mistake. On a 6502, things
tend to wrap on 256-byte pages but on the z80
they don't, so a peripheral providing an id of
$ff in this scheme will cause an address lookup
from $FCFF/$FD00. Zilog never talks about this
in their documentation because the IM2 scheme
requires peripheral ids to be even so that ISR
addresses don't overlap in the table pointed at
by I. This means the largest id a peripheral is
*supposed* to provide is $fe, causing a table
lookup from $FCFE/$FCFF. But with nothing providing
an id in the C64, you have to account for the
possibility of $ff.

If you have this running with I=$FD and
the table at $FCxx, there must be other
memory banking shenanigans going on.

Alvin

Sven Paepke

unread,
Jun 15, 2004, 6:52:47 AM6/15/04
to
Alvin,

You got me here, of course the I register has to be (and is when you try it
out) $FC and not $FD. And as you pointed out, the table is 257 bytes long
($FC00..$FD01).

Thanks for pointing this one out!

Regards,
Sven

"Alvin" <A9...@hotmail.com> wrote in message

news:1a3493d2.04061...@posting.google.com...

Sven Paepke

unread,
Jun 25, 2004, 11:03:55 AM6/25/04
to
If there is still anybody reading this thread, here is a quick update on the
progress:

In general, interrupt handling appears to be under control and quite
straight forward. Once I was pointed into the right direction (thanks to
everyone for the help!), I got the initial routine to work. This routine did
nothing special, just cycled the VIC border color once for each interrupt
(does not care what caused the interrupt). The routine works stable, even
through floppy access. That was the proof of concept. Tick in the box. :)

At the moment, I am struggling with parsing the command line in Assembler.
Found syslib.lbr and may be using some of the routines from it. Great
library, well documented. If anyone wants to understand Z80 CP/M coding in
assembler - read the documentation for syslib.lbr!

Current project: I am trying to re-code a 6502 example for running 5 copies
of the VIC (using raster IRQs), but using the Z80. You can define up to 5
raster lines which trigger interrupts, and completely re-program the VIC.
There are some challenges (like the location of the HIRES screen and sprites
etc). At the moment, I try to do this under CP/M. Later, I may want to
eliminate the OS and run it as a demo straight from disk without having to
boot an operating system. Only condition is that I have it run Z80. Don't
ask WHY? The simple answer is BECAUSE I THINK IT CAN BE DONE. No real
purpose to be honest.

Another challenge is to move the interrupt code into Bank 0 (this is where
interrupts normally execute as far as I know). The code is getting too big
for the unused areas in the common area from $E000 to $FFFF. I can't afford
bank switches during an interrupt - not enough time to waste - so I need to
move the code into free space in bank 0. The information from Herne
(www.herne.com/cpm.htm) regarding the C128 memory map under CP/M is
outstanding! Also some of their tools (e.g. the C128 CP/M Hacker's Toolkit).
They put most of their internal documents regarding CP/M programming on the
C128 into the public domain. Thanks Herne! Also, the Z80 manual from the
ZILOG website is very helpful, as it contains information on the timing of
Z80 commands. Very useful: http://www.zilog.com/docs/z80/um0080.pdf

Besides these challenges, my brain activity was severely impeded by a cold
and a flu in the past 2 weeks, so progress was s .. l .. o .. w .. I hope to
have a working example for 5 VICs (allows additional sets of sprites or
split screens with HIRES, Multicolor, Text) soon. Besides that, I got hold
of a commented listing of an early version of Rob Hubbard's music routine.
Wouldn't it be nice to do this on the Z80????

I guess I have to start counting available cycles during an interrupt as
well. At the moment I have no idea how many cycles (Z80) we have available
per rasterline for instance. Any suggestions on techniques for finding out
would be appreciated! And how many of these cycles are actually "stolen" by
CP/M??? Questions ... Ultimately, I would love to have Rob Hubbard's music
routine + a couple of sprites (>8, where is the limit???) running on the
C128 under Z80 in form of a demo. But that will probably take a lot more
time to achieve! Any volunteers who want to work on it with me?


Regards,
Sven from Oz


"Alvin" <A9...@hotmail.com> wrote in message

news:1a3493d2.04061...@posting.google.com...

0 new messages