Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@blackystardust
Copy link
Contributor

Added apple-IIe fast chip accelerator code and documentation.

For the testcode I needed some way of timing the speed at which loops of code are executed, to clearly show the difference in speed, and I wanted the code to work irrespective of the DOS used.

During my research I found out that for the apple-IIe and enhanced apple-IIe the VBL flag at $c019 can be used for this, for the apple-IIgs that same flag can be used except that it is inverted, for the apple-IIc a VBL irq routine could be used, and for the apple-II+ either a mouse card or some other kind of clock card is needed.

Since this particular accelerator only works on the apple-IIe and enhanced apple-IIe I only implemented the apple-IIe timing code, once I get to other apple-II accelerators I will implement the other timing code(s).

This is my first time coding for an apple-II, and I might need help from other apple-II people for things I cannot find out about other apple-II accelerators that I have planned.

dey
bne unlock_loop
sta FASTCHIP_ENABLE_REG ; enable the Fast Chip
ldy FASTCHIP_ENABLE_REG ; bit 7 will be high when enabled
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What value is read from that location if no card is plugged into that slot?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm unsure, but the detection code from the user manual is as follows:

LDY #$6A ; Load Unlock Value
STY $C06A ; Send to the FASTChip //e
STY $C06A ;
STY $C06A ;
STY $C06A ;
STY $C06B ; Enable FASTChip //e
LDY $C06B ; Is FASTChip //e enabled?
BMI EXIST ; Jmp if FASTChip //e exist.

So it's completely based on that.

Copy link
Contributor

@groessler groessler May 7, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are aware that your code changes the timing of the writes to $C06A. Are you sure that this is not harmful?
Do you have hardware to test the code? IMO it's a mood point to write accelerators for hardware you don't have. It's a gamble whether it will work on the real thing...
Just my 2¢

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I must admit that I fully agree with @groessler:

  • Replacing the four consecutive absolute writes with a loop seems to indicate that you are not experienced with the way such things tend to work in the Apple II.

  • Your remark "So it's completely based on that." seems to indicate that you don't have a FastChipIIe available for testing. At least as far as I know we have never merged untested hardware-related code to cc65 so far.

If there would be a clear, precise documentation and/or known-to-work example program(s) for the hardware in question one might think about merging hardware-ralted code nevertheless but I certainly don't see this with the FastChipIIe :-(

In contrast http://www.a2heaven.com/webshop/resources/pdf_document/18/82/c.pdf section 'FASTChip //e Programmer's Reference' and section 'Programming Hints' contradict each other in my opinion. Especially the term unlocked vs enabled are ambiguous. Intuitively I'd say that unlocked means that the configuration registers are generally protected from accidental change by requiring to be unlocked first. But then one would lock them after being done with changing the configuration. But this perspective doesn't match the 'Programming Hints' :-(

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, if untested hardware code is not accepted then I'm done. I don't even have a c64 or c128, so there will be no further contributions from me.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, sorry if again have no clue but my understanding is that your are a long-term contributor to VICE. And my understanding is that VICE emulates all the hardware you have contributed code for to cc65. And that you have tested your contributions with those VICE emulations. Isn‘t that correct?

My position: If there‘s no code at all for a given hardware in cc65 then code only tested with „some“ popular emulation maybe has issues with the real hardware but after all it works at least for others using the same emulation - and it‘s for sure better than nothing. If however, someone want‘s to change/extend/fix existing hardware-related code in cc65 it should be tested on real hardware to avoid regressions on real hardware.

To my knowledge there‘s no FastChipIIe emulation available and (as said) the available docs are rather bad and there‘s no example code and there‘s no hardware schematics / firmware soure code available. So your FastChipIIe contribution seems to fall into a pretty different category then your past CBM contributions.

Or am I missing the point?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

VICE has a repository of test programs which are tested against both emulation and real hardware.

Some of the code that I added to VICE was based on documentation about the actual hardware, and in most cases later verified by actual hardware owners to work as expected, sometimes not working as expected and therefor fixes were needed.

When writing emulation you need to start somewhere, even if it is just guess work based on the documentation, later tests done on the real hardware will then drive the emulation towards a matching behavior, however, if you don't even start on the emulation before having the actual hardware usually no incentive/motivation will be present for people to compare/test the emulation with the actual hardware.

In the case of drivers (which the code for cc65 is) imo you should be able to go by the documentation and/or other software that 'drives' the actual hardware, if an existing piece of code (like the setup/configuration disk of the hardware) drives the hardware you should be able to use a similar piece of code without needing to have the hardware. Maybe I'm too naive in this regard.

Maybe the code should be labeled experimental, and/or comments that the code is based on drivers for the actual hardware, and/or api documentation and no tests have been done on actual hardware, makes me wonder though, has for example the apple II machine detection code been tested on a macintosh iie option card, and ifnot, why is it in cc65 ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, @blackystardust, I didn't want to put you off. It's just that I have some prior experiences with emulators which didn't work like the real thing.

So, until someone has the accelerator board and can test it, I suggest that you use the detection code "as is", i.e. just 4 subsequent STYs or STAs.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand the suggestion, I was trying to minimize the code size, and based on the documentation I didn't see any timing constraints.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Given the overall quality of the programmers documentation it doesn‘t mean anything that the documentation doesn‘t mention constraints.

  • As mentioned before there are other places in the Apple II world where such constraints apply without being explictly documented.



; generic accelerator speeds for translation to/from Fast Chip speed values
accel_speed_table:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Constant data blocks like these usually are put into the .rodata segment. It isn't required, of course; but, I think that it's nice to be able to look at a map file, and see how much space is used by various categories of objects.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the hint, will change it in my next commit.

#include <target.h>
#include <peekpoke.h>

#if defined(__APPLE2__) || defined(__APPLE2ENH__)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The apple2enh target defines __APPLE2__ also. Therefore, it's the only macro that you need to test here and below.

beq check_slot
cmp #$31 ; Apple IIe enhanced
beq check_slot
cmp #$40 ; Apple IIe Option Card
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see the FastChipIIe being compatible with https://en.wikipedia.org/wiki/Apple_IIe_Card ;-))

cmp #$40 ; Apple IIe Option Card
bne not_found

check_slot:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

check_slot is a bad name (tm) here - and likely the reason why @greg-king5 asked a "wrong" question below.

The usual way slot cards work in the Apple II is that each slot has an individual range of I/O addresses assigned. These ranges are $C080-$C08F for slot 0, $C090-$09F for slot 1 etc. So to "check slots" for a card would mean to access all the different I/O address ranges in a loop. But here there's neither a loop nor access to $C080-$C0FF.

The FastChipIIe works differently than most slot cards. It doesn't rely on the logic decribed above but rather fully monitors the 6502 bus activities. Therefore it

  • places its I/O ports in a slot-independent location ($C06x)
  • can emulate a RamFactor card in a slot it isn't physically placed in
  • ...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand, the CPU on that card is in control and therefor controls the memory map available to the CPU.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What I wrote doesn‘t relate to the fact that the card in question is an accelerator with its own CPU. Rather the Apple II „offers“ some built-in address decoding to slot cards to

  • allow them to decode only 4 address bits
  • allow them to co-operate without address conflicts

However, the card in question doesn‘t make use of that „offer“.

@blackystardust
Copy link
Contributor Author

I'm more than willing to make all the changes needed/suggested, but if this pr will not make it into cc65 because of not having the hardware and it being based on the described api instead then it's useless to make the changes and this pr can just be closed.

However, how many of the following has been tested on actual hardware and not just taken from a document describing how to detect it:

index: .byte $B3, $00 ; Apple ][
.byte $B3, $1E, $00 ; Apple ][+
.byte $B3, $1E, $00 ; Apple /// (emulation)
.byte $B3, $C0, $00 ; Apple //e
.byte $B3, $C0, $DD, $BE, $00 ; Apple //e Option Card
.byte $B3, $C0, $00 ; Apple //e (enhanced)
.byte $B3, $C0, $BF, $00 ; Apple //c
.byte $B3, $C0, $BF, $00 ; Apple //c (3.5 ROM)
.byte $B3, $C0, $BF, $00 ; Apple //c (Mem. Exp.)
.byte $B3, $C0, $BF, $00 ; Apple //c (Rev. Mem. Exp.)
.byte $B3, $C0, $BF, $00 ; Apple //c Plus

@oliverschmidt
Copy link
Contributor

However, how many of the following has been tested on actual hardware and not just taken from a document describing how to detect it: [...]

I must admit that I start to think that you WANT to misunderstand me. But nevertheless, trying to clarify... I wrote:

"If there would be a clear, precise documentation and/or known-to-work example program(s) for the hardware in question one might think about merging hardware-ralted code [...]"

The code you refer to with your statement above

  • is based on http://www.1000bit.it/support/manuali/apple/technotes/misc/tn.misc.02.html which from my pov fully complies to my documentation requirement.

  • checks for firmware locations and given that emulators use the original firmware there's no difference between emulation and actual hardware.

  • is written by me and and worked correctly on all emulators representing different machines.

Then I wrote:

"[...] nevertheless but I certainly don't see this with the FastChipIIe :-("

What I refer to with that statement is especially this section:

DISABLE_FASTCHIP_IIE
 LDY #$A6 ; Load Lock value
 STY $C06A ; Save to FASTChip //e
 RTS

How do you interpret disable? I think disable needs to be interpreted as turning of the functionality of the card. Meaning that the machine behaves as if the card isn't present aka running at 1MHz. But if you interpret it that way then your card detection code turns the card off, doesn't it?

Now you could say that this is likely just a single error in the documentation. And that it needs to be interpreted as LOCK_FASTCHIP_IIE meaning that only the access to the configuration registers is "sealed" again. As far as I understand that's the thought behind the code in this PR.

But then I point you at

$C06B    Write Any hex byte written will enable FASTChip //e

So if that is true how IS the card actually disabled? Is the section mentioned above not an error in the documentation after all?

Okay, so let's presume that interpretation, then the question is: How do you detect the card without changing its current state? The only place in the documentation saying Jmp if FASTChip //e is installed unconditionally enables the card before.

Do you see by now the problems I have with the documentation?

To summarize:

  • Chris' statement on only having hardware-related code in cc65 which has been tested on actual hardware was his personal statement clearly marked with "my 2 cents".
  • I should have maybe made clearer that my perspective as project maintainer differs from that. I think all code in cc65 should have been successfully run at least once (on hardware or on emulator). Simply to avoid basic logic errors in the code. I don't like it when someone says "I found a bug in cc65 which clearly shows that this code can never ever have worked in the first place".
  • I'm willing to deviate from that for code driving exotic hardware if there's trustworthy documentation and/or believed-to-work sample code.

To move forward with this PR I suggest to either get in touch with the manufacturer of the card (who afaik is happy to answer questions) and clarify the aspects in question or to get in touch with an owner of the card and ask him to test the code. Does that make sense?

@blackystardust
Copy link
Contributor Author

sent out an email, I'll let you know of any results.

Let me get something clear though, because I might be misunderstanding, if there is a working piece of code for hardware that I am coding for and it is using the same methods that my code uses then it would be considered 'correct' ?

@oliverschmidt
Copy link
Contributor

Sorry for the delayed response ... been away the last days...

sent out an email, I'll let you know of any results.

Great! Thanks for taking care :-)

if there is a working piece of code for hardware that I am coding for and it is using the same methods that my code uses then it would be considered 'correct' ?

In general 'yes'. However, regarding the accelerator topic I see a general problem:

Given code tends to implement the following two "APIs":

  • Turn the accelerator on if it exists. Don't crash or hang if it doesn't exist. Maybe return success in one way or another.

  • Turn the accelerator off if it exists. Don't crash or hang if it doesn't exist. No return value.

And starting from such code I don't see a clean way to implement the APIs you defined.

@oliverschmidt
Copy link
Contributor

I haven't checked any details myself but maybe this thread (62 posts) is of interest to you: https://groups.google.com/d/msg/comp.sys.apple2/e-2Lx-CR1dM/ND2dLoVnAQAJ

@oliverschmidt
Copy link
Contributor

sent out an email, I'll let you know of any results.

Did you receive an answer? Was it helpful in one way or another?

If that path counter-intuitively doesn't work I could try to get in touch with an owner of a FASTChip and ask him if he'd be willing to run some test programs prepared by you...

@blackystardust
Copy link
Contributor Author

@oliverschmidt

I got a reply, he told me he would test it when he got time, but sofar he hasn't given me any results yet.

I would appreciate it if you could have it tested by any-1 you know that has the cart.

Personally I'm currently in the process of cleaning up VICE, and won't have time to look into cc65 till I'm done with that.

@oliverschmidt
Copy link
Contributor

Ah, maybe a bit of a misunderstanding. So you asked him to test a program? I thought you'd ask him to clarify the ambiguous section in his docs.

Even if the test program says that it successfully changes the speed that still doesn't mean that it works really as designed. From the FASTChip docs it seems - as discussed in detail - that the device might have a locked vs. unlocked state. And in that case it would be desirable to re-lock it after changing the speed in order to make sure that it isn't reconfigured unintentionally by "some" program doing "some" stray port access.

@oliverschmidt
Copy link
Contributor

So with regards to asking an owner of the card (not cart ;-) for help. That would require from my perspective another type of test program, one that explicitly tries to understand those strange "lock" thingy in the doc...

@blackystardust
Copy link
Contributor Author

The code does lock it after changing the speed, and the test program uses a 'raster timer' to measure how long a loop takes, so if the loop takes less cycles then the speed has increased.

He said he would look at my code and test when he has time, not sure if he has forgotten or not.

Either way I currently don't have time to spend on cc65, so maybe after I'm done with VICE I'll get back to cc65.

@oliverschmidt
Copy link
Contributor

the test program uses a 'raster timer' to measure how long a loop takes, so if the loop takes less cycles then the speed has increased.

For sure - that wasn't my point.

Either way I currently don't have time to spend on cc65, so maybe after I'm done with VICE I'll get back to cc65.

I understand - I'm not pushing anything, I'm only trying to avoid misunderstandings and clarify expectations.

The code does lock it after changing the speed

At least as far as I understand the current test program doesn't check if that was successful - e.g. by trying to change some setting and testing that this fails as expected. Don't get me wrong: I think that this type of test is a lot of work and I don't consider it desirable to spend the time to create it. That's the very reason why I prefer drivers written based on full understanding rather than based on empiric tests. And that's the reason why I consider it more attractive to reach out to the manufacturer than to an owner.

@mrdudz mrdudz added libs need info / extra work More info and/or extra is needed from the OP to proceed labels Feb 11, 2022
@mrdudz mrdudz marked this pull request as draft June 14, 2025 01:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement libs need info / extra work More info and/or extra is needed from the OP to proceed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants