First of all, there is a very detailed discussion of asynchronous dual-port operation in the application note "Understanding Asynchronous Dual-Port RAMs " In the appnote, there is a detailed description about simultaneous access.
All asynchronous dual-ports come with arbitration logic and BUSY signals to handle situations where both ports are trying to access the same memory location. If one port is accessing a certain memory location, and the other port tries to access the same location more than tPS (port set-up priority) later, then the second port will receive a BUSY signal no matter what type of access it is trying to do. The following is a break down of what would occur:
First port reading, second port reading:
If both ports are trying to read from the same memory location, the first port is completely unaffected (the data in the memory will be driven on the data lines). The second port will receive a BUSY signal, but it will still be able to read the data.
First port reading, second port writing:
If the second port is trying to write into the same location, again it will receive a BUSY signal. This time it will be prevented from writing until the BUSY signal goes away which happens when the first port is no longer reading from that memory location. So in this situation, the BUSY signal impedes the write operation.
First port writing, second port reading:
If the second port is trying to read, it will receive a BUSY signal, but still be allowed to read the data. There is no guarantee as to what data is being read in this situation, though. It could be the old data, the new data, or some combination of both. To be safe, in these situations the second port should take the BUSY signal as an "invalid" signal and re-request the read after the BUSY signal goes away.
First port writing, second port writing:
In this situation, the second port will receive a BUSY signal and the write operation will be impeded. The first port will be able to successfully write into the memory location.
The four situations above are for the case where there is definitely one port that gains access to the memory location before the other port. The timing constraint that defines this is tPS. If both ports try to access the same memory location within tPS or less of each other (defined as a simultaneous access), then the arbitration logic on the device will declare a winner and a loser. The losing port receives a BUSY signal and the scenarios above are played out. There is no way to predict which port wins, however. This is why when multiple dual-ports are used in width expansion, there has to be a single master device and all of the other devices are slaves. The master decides who wins arbitration and sends a BUSY output. The slaves have BUSY inputs that come from the master and the slave devices adhere to the master's decision. Otherwise there is the chance that one device picks a different winning port than another device. This is described further in the Knowledge Base article "BUSY signals when cascading asynchronous dual-ports".