Login
Search for:


Previous | Next

From: TLC (all posts)
Date: 1998-05-19
Subject: Re: Tape loading, and others
Hi!

>> Turbo loaders are usually a custom format thats loaded first... it'll
>> be a bugger to get this for all the diff loaders... won't it?
> Well, I guess this number is under 20, (I'm just guessing :) ),
> and this can be solved with a well specified external config file format.
> I'm thinking about a descriptor language here. Levente, I hope
> that you will do that converter you mentioned, with this kind of external
> format specification. It would allow to make it support every format
> one might think of, and would allow tinkering with it :) ...

Well, you won't believe since when am I thinking about this stuff. Last year I tried to write such stuff, but I ended up in an 80x86 ASM routine which could detect whether a signal is originated from a Plus/4,C64 or Vic-20 (or it also detected the main C64 turbo load type). All this ran in realtime from a datassette plugged to the LPT.

As you can see, my goal is not specific to the normal tape format and not even to Plus/4. I wanted to have a stuff which helped one to archive complete tapes into PC tape image files (either .t64, or some others).
I also think that those additional datas which come from the custom file format, title screen while loading or other loaded data should be stored somewhere (even if I must define a new image format) in the image.
I aim as original archived stuff as possible (e.q. one should be able to restore the whole tape record from the archived image, even if the game was equipped with a custom loader (like novaload and anothers).

The problem you spoke of is real. One can't simply collect all different turbo formats.

But, well, Mike's words also made me think of some matters (like your CCIR doc in the FLI thing) :-). So now I have an other idea of making such stuff. His work proved that indeed, it's possible to load custom file formats even into a PC emulator (even if he didn't realise the batched archiving possibility relations of it).

The solution: to partly emulate a Commodore, by a 6502 core and the timers, ports (at least the ones involved in this business) and the other usual things. If you provide the right kernal code, you have a core which is able to load some data blocks from a digitized tape.

Then you can build your archiver stuff up onto this. In short, whatever you want and if you handle this core well, it will do everything.

What is possible? ...Of course, loading regular blocks and detect if they are header or data. Load whatever block if the tape buffer has the right code for it. Make exact copies of whatever data the core loaded. Also,
pass the task of recognizing any timing params, appear or whatever a custom loader is, and save these informations to the image.

I guess it is the real solution to archive original stuffs in themselves without actually cracking them.

(Speaking of the things outside of the core, an other task is to customize the usually poor quality of a PC-card digitized sample. Everything is possible using digital filters and such routines (provided that the sample has the appropriate signal to noise ratio, but well... let's suppose that a 1 bit digital sample __should be able to be picked out of a stream digitized with 8 bits :-)). ...I guess, this stuff could be even less picky to bad head adjustment in overall than the original datassette was. Also, it would be easy to equalize the 'RPM' of the virtual datassette too, if we know that we stay at a header and if we know the exact frq of the header signal).

..Phew, anybody starting to code the archiver? :-)

> Rachy:
> I guess you came later to the list, and missed the TED cycle mapping
> posting. If you need that, mail me, and I can send it. It contains infos
> which should enable emulators to correctly run the $ff1e $ff1d defenders.
> For this type of defenders to work, both the CPU and the TED emulation
> must be cycle perfectly syncronized because $ff1e changes in every cycle.
> Also interrupt startup position and time must be correct as these
> defenders using IRQ for startup.

Are you speaking of TLC's defender V2.0? :-) (...Actually, Lavina should still have a copy of it (and actually, I do not :-( )).

Mike, I guess you should give a try to my Outrun Demo (dated around 1992
March). It was equipped with this code protector. Illegal opcodes, cycle exact startpoint (with IRQ), filling all TED registers and the stack in one loop, then starting decoding the main program block using $ff1d, $ff1e and the other timers (without actually initializing except the one in the loop), all this in twiee clock mode and screen enabled :-). If it runs with no problems, well... then I must assume your emulator must really have something to do with an original Plus/4 :-).

Levente

Ps. I typed in my timing measurements of the TED. Here it comes, please check if it contains bugs.



Timing of 8360 TED in C-16 / C-116 / Plus/4
By Levente Harsfalvi, V0.98B ,'??-'98

This diag shows TED's tasks and CPU cycles related to the bus cycles of the Plus/4.

What I'm referring as 'bus cycle' is the one which is the part of the bus timing during which one memory operation (R/W) is done. I decided to relate everything to the bus cycles and describe if they're owned by the TED or the CPU.

For visuality, I used a cycle-counter from 0 to 56, so it counts the character places of a screenline rather than directly the bus cycles#,
0 to 113. Note that it does not make a real difference, since two bus cycles are done while one character is displayed. The '#1' and '#2' lines indicate that the first and the second bus cycle of the current character place is actually owned by whom.

This ownership, you may know from C64 and VIC-II, depends on the actual tasks of the videochip. In C64, the maximum bus cycles the processor can have is half the bus cycles done on a scanline. 6502 derivative procs use the bus in just one phase of their clock, the another phase is free. This phase is actually made free - with some other logic - to the VIC-II for it's graphic data fetch, also organizing the memory logic and the system bus to allow two memory operations while one processorcycle. So in normal operation,
either of these two bus cycles is owned by the CPU and the another by the VIC, thus making the maximum of half these cycles available for the CPU. This division is done whether the VIC actually uses the another bus cycle or not.

When the VIC needs more data from the system bus, ie. when it fetches character pointer data from the memory (or, equal is the color memory data for bitmaps), it can stop the CPU by certain tricks, thus freeing the processor's own bus cycles and making use of them. It means, in some time all bus cycles are owned by the VIC and none of them by the CPU.

The third possible state, eg all cycles owned by the processor was not possible on C64 and VIC-II. Though, it seems to make sense, since the videochip doesn't need it's bus cycles all times, eg on the borders where it doesn't have to communicate with the memory at all. Since these computers have no caching scheme implemented, the more data the processor can fetch from the memory, the faster the CPU works. But how should it be done, if the proc definitely doesn't want to use those free bus cycles at all?

This is the issue which is realised in the Plus/4 with TED and the 7501/8501
CPU. Since the TED is responsible for the bus timing and most of the system lines, the designers implemented this feature into the TED.

It means, when the TED is not about to use the bus, it frees the bus for the CPU. Since it also uses some tricks to make the processor use the freed bus cycles, it'll make it also run twice as fast as it would be. The task is actually done by modifying the _clock signal of the _processor, giving one clock cycle for one bus cycle each. (So from the processor's side, since it's a 6502 derivative proc it'll still skip each half cycle phase of it's own clock signal, but now it's farely enough to catch all bus cycles since it's clock signal was doubled).

(Since the CPU core must also calculate faster, this also needs a faster,
about 2Mhz core for the 8501. But this should be a question of the semiconductor manufacturing technology only, not the architecture of the
2Mhz core).

This matter also reveals the thing that Commodore improved none of their NMOS design since they started the work with the 65xx family (maybe, since they bought MOSTEK); they just optimized the load of their bus system, but this bus in it's own is still mostly the same which is used in C64, Vic-20
and the others. Two bytes data at about 1Mhz clock cycle each, this may have been introduced with the earliest Commodore PET's.

Used symbols in the diag:

Orig: (= Origin)
-:None of either busmasters are active.
T:The bus cycle is owned by the CPU P:The bus cycle is owned by the CPU p:Bus pending, CPU can finish write cycles.

Task:
G: TED graphic fetch P: TED color data / character pointer / bitmap color data fetch r: TED is refreshing memory
-: TED / proc is inactive (rather, it's outputs are high). That means, if
TED is inactive (but the cycle is not owned by either component), it seems
to output $ffff as address, and also seems to catch the resulting data
from the bus.
X: Processor memory cycle x: Processor memory cycle, bus pending (RDY low), write cycles are possible

Miscellaneous:
[: Start of the border area
]: End of the above
{: Start of 40 chars wide screen area
}: End of the above

(Note: character area seems to end a bus cycle (= half a character) later than character place# 51.)

--------------[---{--------------------------------------}---]------
CharPlace|000000000011111111112222222222333333333344444444445555555|
count # |012345678901234567890123456789012345678901234567890123456|


$ff1e: 1:|CCCDDDDE0000111122223333444455556666777788889999AAAABBBBC|
|48C048C0048C048C048C048C048C048C048C048C048C048C048C048C0|
2:|CCCDDDDE0000111122223333444455556666777788889999AAAABBBBC|
|6AE26AE226AE26AE26AE26AE26AE26AE26AE26AE26AE26AE26AE26AE2|



Border (no transparent DMA by the TED). Twiee clock enabled.
109 cycles available for the CPU.
--------------[---{--------------------------------------}---]------
CharPlace|000000000011111111112222222222333333333344444444445555555|
count # |012345678901234567890123456789012345678901234567890123456|


Orig: 1: |PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPTTTTTPPPPPP|
2: |PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP|
-------------------------------------------------------------------|
Tasks:1: |XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXRRRRRXXXXXX|
2: |XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX|



Border (no transparent DMA by the TED). Single clock.
57 cycles available for the CPU.
--------------[---{--------------------------------------}---]------
CharPlace|000000000011111111112222222222333333333344444444445555555|
count # |012345678901234567890123456789012345678901234567890123456|


Orig: 1: |----------------------------------------------TTTTT------|
2: |PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP|
-------------------------------------------------------------------|
Tasks:1: |----------------------------------------------RRRRR------|
2: |XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX|



Character area, no transparent DMA by the TED. Twiee clock enabled.
65 cycles available for the CPU.
--------------[---{--------------------------------------}---]------
CharPlace|000000000011111111112222222222333333333344444444445555555|
count # |012345678901234567890123456789012345678901234567890123456|


Orig: 1: |PP----TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTPPPPPP|
2: |PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP|
-------------------------------------------------------------------|
Tasks:1: |XX----GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGRRRRRXXXXXX|
2: |XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX|



Character area, no transparent DMA by the TED. Single clock.
57 cycles available for the CPU.
--------------[---{--------------------------------------}---]------
CharPlace|000000000011111111112222222222333333333344444444445555555|
count # |012345678901234567890123456789012345678901234567890123456|


Orig: 1: |------TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT------|
2: |PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP|
-------------------------------------------------------------------|
Tasks:1: |------GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGRRRRR------|
2: |XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX|



Character area, 'bad line' (transparent DMA by the TED). Twiee clock enabled.
22+<0..3> cycles available for the CPU.
--------------[---{--------------------------------------}---]------
CharPlace|000000000011111111112222222222333333333344444444445555555|
count # |012345678901234567890123456789012345678901234567890123456|


Orig: 1: |PP----TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTPPPPPP|
2: |PPpppTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTPPPPPPPPPPPP|
-------------------------------------------------------------------|
Tasks:1: |XX----GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGRRRRRXXXXXX|
2: |XXxxxPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPXXXXXXXXXXXX|



Character area, 'bad line' (transparent DMA by the TED). Single clock.
14+<0..3> cycles available for the CPU.
--------------[---{--------------------------------------}---]------
CharPlace|000000000011111111112222222222333333333344444444445555555|
count # |012345678901234567890123456789012345678901234567890123456|


Orig: 1: |PP----TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTPPPPPP|
2: |PPpppTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTPPPPPPPPPPPP|
-------------------------------------------------------------------|
Tasks:1: |------GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGRRRRR------|
2: |XXxxxPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPXXXXXXXXXXXX|



Well, that's it.

As credits, I must mention that most of the idea for this diag was actually obtained from the VIC and 6502 timing ideas of Marko Makela,
Andreas Boose and Christian Bauer. Thanks, guys!

Copyright © Plus/4 World Team, 2001-2024. Support Plus/4 World on Patreon