Beam Racer Forum

Full Version: VASYL & access to system bus
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Hi,
I would like to understand how VAYSL behaves when accessing the system bus (for example when it executes a MOV towards a VIC register) and how it can "halt" the CPU as mentioned in the FAQ.

Another point: according to the Instruction's doc., MOV will be delayed in case VIC is fetching data (e.g. badline or sprite). Is it the same for XFER (in the documentation is not mentioned)?

Thanks.
(2020-09-30, 09:03 AM)abbruzze Wrote: [ -> ]I would like to understand how VAYSL behaves when accessing the system bus (for example when it executes a MOV towards a VIC register) and how it can "halt" the CPU as mentioned in the FAQ.

Another point: according to the Instruction's doc., MOV will be delayed in case VIC is fetching data (e.g. badline or sprite). Is it the same for XFER (in the documentation is not mentioned)?

Any write to VIC-II register will be postponed until the access is physically possible, i.e. until VIC-II is willing to listen to us. This means that XFER, MOV and BADLINE can stall while they are waiting for AEC line to go up.

Once VIC-II is available, BeamRacer will first separate system and local buses (address and data, see https://docs.beamracer.net/lib/exe/detai...iagram.png). On the local side, the write proceeds as usual - first with a write to the address bus and VIC-II CS and RW lines getting asserted, followed by a write to the data bus.

6510 continues unimpeded on the system bus side, and if it does not want anything from VIC/VASYL IO address space, it will not lose any cycles. However, if it accesses $d000-$d3ff, it will be halted until VASYL is done writing to VIC-II, which may be arbitrarily long (e.g. if the display list makes a sequence of VIC-II writes in successive cycles). BTW, technically the 6510's RDY line is going HIGH at the beginning of every stopped cycle and stays there until VASYL completes its instruction fetch and determines what it will be doing later in the cycle, at which point RDY may go LOW again. But I believe this is irrelevant from the viewpoint of an emulator (correct me if I am wrong).

Now, if the 6510 was trying to make a write access, it naturally won't stop immediately, but merrily push forward. BeamRacer cannot use VIC-II's approach of asserting RDY ahead of time, because display lists are dynamic and VASYL only finds out what needs to happen once it fetches and decodes its current instruction. It cannot let the CPU make the access either, because that would mean postponing display list's write access and likely result in a visual glitch.

So what happens is that 6510 is allowed to continue, and the writes by the CPU and by VASYL happen concurrently. The system and local buses are isolated, so VASYL write gets to VIC-II, while CPU write gets recorded by BeamRacer and preserved for future use. When the time comes for the CPU to run again, it will need to wait one more cycle, during which the previously recorded write access is replayed to VIC/VASYL.

In other words, VASYL writes always have priority over CPU writes.
(2020-09-30, 09:05 PM)laubzega Wrote: [ -> ]
(2020-09-30, 09:03 AM)abbruzze Wrote: [ -> ]I would like to understand how VAYSL behaves when accessing the system bus (for example when it executes a MOV towards a VIC register) and how it can "halt" the CPU as mentioned in the FAQ.

Another point: according to the Instruction's doc., MOV will be delayed in case VIC is fetching data (e.g. badline or sprite). Is it the same for XFER (in the documentation is not mentioned)?

Any write to VIC-II register will be postponed until the access is physically possible, i.e. until VIC-II is willing to listen to us. This means that XFER, MOV and BADLINE can stall while they are waiting for AEC line to go up.

Once VIC-II is available, BeamRacer will first separate system and local buses (address and data, see https://docs.beamracer.net/lib/exe/detai...iagram.png). On the local side, the write proceeds as usual - first with a write to the address bus and VIC-II CS and RW lines getting asserted, followed by a write to the data bus.

6510 continues unimpeded on the system bus side, and if it does not want anything from VIC/VASYL IO address space, it will not lose any cycles. However, if it accesses $d000-$d3ff, it will be halted until VASYL is done writing to VIC-II, which may be arbitrarily long (e.g. if the display list makes a sequence of VIC-II writes in successive cycles). BTW, technically the 6510's RDY line is going HIGH at the beginning of every stopped cycle and stays there until VASYL completes its instruction fetch and determines what it will be doing later in the cycle, at which point RDY may go LOW again. But I believe this is irrelevant from the viewpoint of an emulator (correct me if I am wrong).

Now, if the 6510 was trying to make a write access, it naturally won't stop immediately, but merrily push forward. BeamRacer cannot use VIC-II's approach of asserting RDY ahead of time, because display lists are dynamic and VASYL only finds out what needs to happen once it fetches and decodes its current instruction. It cannot let the CPU make the access either, because that would mean postponing display list's write access and likely result in a visual glitch.

So what happens is that 6510 is allowed to continue, and the writes by the CPU and by VASYL happen concurrently. The system and local buses are isolated, so VASYL write gets to VIC-II, while CPU write gets recorded by BeamRacer and preserved for future use. When the time comes for the CPU to run again, it will need to wait one more cycle, during which the previously recorded write access is replayed to VIC/VASYL.

In other words, VASYL writes always have priority over CPU writes.

Thanks for your clarifications: I already figured out the problem with CPU writes. I will (if possible) try to resolve this scenario after all others will be ok.
Anyway, now I have I doubt about BADLINE. 
Below what I understood so far (wihout AEC handling):
  1. it doesn't wait for condition, after the beam check the VASYL will execute the next instruction

  2. if the target raster is reached that raster line becomes a badline

  3. Otherwise, all the other rasters between become non-badline. So, for example: VIC is on raster 100, VASYL executes BADLINE 2 => raster 100 and 101 become non-badline while raster 102 becomes a badline.
Now, if the execution continues with the next instruction, does it mean that VASYL remembers that it has to force a badline or a non-badline according to raster line target (as I do in the emulator) ?
Where, in this process, AEC signal is checked ?

Thanks in advance.
Quote:Anyway, now I have I doubt about BADLINE. 
Below what I understood so far (wihout AEC handling):
  1. it doesn't wait for condition, after the beam check the VASYL will execute the next instruction


  2. if the target raster is reached that raster line becomes a badline


  3. Otherwise, all the other rasters between become non-badline. So, for example: VIC is on raster 100, VASYL executes BADLINE 2 => raster 100 and 101 become non-badline while raster 102 becomes a badline.
Now, if the execution continues with the next instruction, does it mean that VASYL remembers that it has to force a badline or a non-badline according to raster line target (as I do in the emulator) ?
Where, in this process, AEC signal is checked ?

BADLINE is actually very simple to implement:

BADLINE ARG

is equivalent to

R = PEEK($D012) ; RASTER
C = PEEK($D011) ; CR1
MOV $D011, (C & $f8) | ((R & $07) + ARG) & $07)

(I hope this mix of BASIC, C and Vasylese is not too eye-searing Wink).


That is, it changes VIC-II YSCROLL to a value that will cause the badline to occur after ARG rasterlines. This also means that all earlier lines (if there are any), will be non-badlines.

There is no extra waiting or anything else happening, beyond what is needed to execute a successful MOV.
Quote:Now, if the execution continues with the next instruction, does it mean that VASYL remembers that it has to force a badline or a non-badline according to raster line target
There isn't anything VASYL would need to remember. It sets the correct conditions for VIC to execute a badline at given position and VIC does the rest.
(2020-10-01, 05:45 PM)laubzega Wrote: [ -> ]
Quote:Anyway, now I have I doubt about BADLINE. 
Below what I understood so far (wihout AEC handling):
  1. it doesn't wait for condition, after the beam check the VASYL will execute the next instruction


  2. if the target raster is reached that raster line becomes a badline


  3. Otherwise, all the other rasters between become non-badline. So, for example: VIC is on raster 100, VASYL executes BADLINE 2 => raster 100 and 101 become non-badline while raster 102 becomes a badline.
Now, if the execution continues with the next instruction, does it mean that VASYL remembers that it has to force a badline or a non-badline according to raster line target (as I do in the emulator) ?
Where, in this process, AEC signal is checked ?

BADLINE is actually very simple to implement:

BADLINE ARG

is equivalent to

R = PEEK($D012) ; RASTER
C = PEEK($D011) ; CR1
MOV $D011, (C & $f8) | ((R & $07) + ARG) & $07)

(I hope this mix of BASIC, C and Vasylese is not too eye-searing Wink).


That is, it changes VIC-II YSCROLL to a value that will cause the badline to occur after ARG rasterlines. This also means that all earlier lines (if there are any), will be non-badlines.

There is no extra waiting or anything else happening, beyond what is needed to execute a successful MOV.
Thank you very much. I don't know why but at the beginning of this new emulation I decided to "force" the badline commands from VASYL with a stupid flag...
Of course, modifying yscroll (BeamRacer does exactly this) is the simplest and natural way.
Ok, the AEC signal is of course checked while writing to $D011.
Now, fld & fli demo seems to work properly.

Thanks to laubzega & silverdr for your support.
You are welcome.

One clarification though: the actual PEEKs are not performed as part of BADLINE, since VASYL knows the current state of these registers at all times. No need to waste bus cycles trying to read them from VIC.
I just tried kernal64 BeamRacer branch, works pretty well!!! Good job abbruzze!
(2020-10-03, 01:30 PM)shazz Wrote: [ -> ]I just tried kernal64 BeamRacer branch, works pretty well!!! Good job abbruzze!
Happy to hear this: the actual Kernal64's implementation has BeamRacer already "installed" in it. In one of the next I will add an entry in the Settings->I/O menù for BeamReacer installation.
Expanded explanation of bus activities during write access collisions is now available in the docs: https://docs.beamracer.net/doku.php?id=c...510_writes