1964js/coffee/dma_le.coffee
2018-07-11 10:53:30 -04:00

177 lines
No EOL
6.7 KiB
CoffeeScript

###1964js - JavaScript/HTML5 port of 1964 - N64 emulator
Copyright (C) 2012 Joel Middendorf
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.###
#jslint devel: true
#globals consts, C1964jsEmulator
#console.log(message);
"use strict"
class C1964jsDmaLE
constructor: (memory, interrupts, pif) ->
@startTime = 0
@memory = memory
@interrupts = interrupts
@pif = pif
@audio = undefined
copyCartToDram: (pc, isDelaySlot) ->
end = @memory.getInt32(@memory.piUint8Array, consts.PI_WR_LEN_REG, @memory.piUint32Array)
to = @memory.getInt32(@memory.piUint8Array, consts.PI_DRAM_ADDR_REG, @memory.piUint32Array)
from = @memory.getInt32(@memory.piUint8Array, consts.PI_CART_ADDR_REG, @memory.piUint32Array)
log dec2hex(pc) + ": pi dma write " + (end + 1) + " bytes from " + dec2hex(from) + " to " + dec2hex(to)
end &= 0x00ffffff
to &= 0x00ffffff
transfer = end
remaining = -1
#end+1 is how many bytes will be copied.
if (from & 0x10000000) isnt 0
from &= 0x0fffffff
#the ROM buffer size could be less than the amount requested
#because the file is not padded with zeros.
if from + end + 1 > @memory.rom.byteLength
transfer = @memory.rom.byteLength - from - 1
remaining = end - transfer
`const d = this.memory.u8`
`const r = this.memory.romUint8Array`
if ((to & 3) is 0) and ((from & 3) is 0)
while transfer >= 0
d[to] = r[from]
to++
from++
--transfer
else
while transfer >= 0
d[to^3] = r[from^3]
to++
from++
--transfer
#if (remaining !== -1)
# alert('doh!' + remaining);
else
`const d = this.memory.u8`
while end-- >= 0
d[to^3] = @memory.lb(from)
from++
to++
# clrFlag(spReg1Uint8Array, SP_STATUS_REG, SP_STATUS_HALT);
@interrupts.clrFlag @memory.piUint8Array, consts.PI_STATUS_REG, consts.PI_STATUS_IO_BUSY | consts.PI_STATUS_DMA_BUSY
@interrupts.triggerPIInterrupt pc, isDelaySlot
return
copyDramToCart: (pc, isDelaySlot) ->
alert "copyDramToCart"
copySiToDram: (pc, isDelaySlot) ->
end = 63 #read 64 bytes. Is there an si_wr_len_reg?
to = @memory.getInt32(@memory.siUint8Array, consts.SI_DRAM_ADDR_REG, @memory.siUint32Array)
from = @memory.getInt32(@memory.siUint8Array, consts.SI_PIF_ADDR_RD64B_REG, @memory.siUint32Array)
throw Error "Unhandled: SI_DRAM_ADDR_RD64B_REG = " + from if from isnt 0x1FC007C0
log "si dma write " + (end + 1) + " bytes from " + dec2hex(from) + " to " + dec2hex(to)
end &= 0x00ffffff
to &= 0x0fffffff
from &= 0x0000ffff
@pif.processPif()
while end >= 0
@memory.u8[to^3] = @memory.pifUint8Array[from^3]
to++
from++
--end
@interrupts.setFlag @memory.siUint8Array, consts.SI_STATUS_REG, consts.SI_STATUS_INTERRUPT
@interrupts.triggerSIInterrupt pc, isDelaySlot
return
copyDramToAi: (pc, isDelaySlot) ->
length = @memory.getInt32(@memory.aiUint8Array, consts.AI_LEN_REG, @memory.aiUint32Array)
from = @memory.getInt32(@memory.aiUint8Array, consts.AI_DRAM_ADDR_REG, @memory.aiUint32Array)
#log('ai dma write ' + length + ' bytes from ' + dec2hex(from));
length &= 0x00ffffff
from &= 0x0fffffff
if @audio is `undefined`
@audio = new C1964jsAudio()
if @audio.processAudio(@memory, from, length) is false
@interrupts.clrFlag @memory.aiUint8Array, consts.AI_STATUS_REG, consts.AI_STATUS_FIFO_FULL
@interrupts.triggerAIInterrupt 0, false
else
@interrupts.setFlag @memory.aiUint8Array, consts.AI_STATUS_REG, consts.AI_STATUS_FIFO_FULL
return
copyDramToSi: (pc, isDelaySlot) ->
end = 63 #read 64 bytes. Is there an si_rd_len_reg?
to = @memory.getInt32(@memory.siUint8Array, consts.SI_PIF_ADDR_WR64B_REG, @memory.siUint32Array)
from = @memory.getInt32(@memory.siUint8Array, consts.SI_DRAM_ADDR_REG, @memory.siUint32Array)
throw Error "Unhandled: SI_DRAM_ADDR_RD64B_REG = " + from if to isnt 0x1FC007C0
log "si dma read " + (end + 1) + " bytes from " + dec2hex(from) + " to " + dec2hex(to)
end &= 0x00ffffff
to &= 0x0000ffff
from &= 0x0fffffff
while end >= 0
@memory.pifUint8Array[to^3] = @memory.u8[from^3]
to++
from++
--end
#@pif.processPif()
@interrupts.setFlag @memory.siUint8Array, consts.SI_STATUS_REG, consts.SI_STATUS_INTERRUPT
@interrupts.triggerSIInterrupt pc, isDelaySlot
return
copySpToDram: (pc, isDelaySlot) ->
alert "todo: copySpToDram"
return
copyDramToSp: (pc, isDelaySlot) ->
end = @memory.getInt32(@memory.spReg1Uint8Array, consts.SP_RD_LEN_REG, @memory.spReg1Uint32Array)
to = @memory.getInt32(@memory.spReg1Uint8Array, consts.SP_MEM_ADDR_REG, @memory.spReg1Uint32Array)
from = @memory.getInt32(@memory.spReg1Uint8Array, consts.SP_DRAM_ADDR_REG, @memory.spReg1Uint32Array)
log "sp dma read " + (end + 1) + " bytes from " + dec2hex(from) + " to " + dec2hex(to)
end &= 0x00000FFF
to &= 0x00001fff
from &= 0x00ffffff
if ((to & 3) is 0) and ((from & 3) is 0)
while end >= 0
@memory.spMemUint8Array[to] = @memory.u8[from]
to++
from++
--end
else
while end >= 0
@memory.spMemUint8Array[to^3] = @memory.u8[from^3]
to++
from++
--end
@memory.setInt32 @memory.spReg1Uint8Array, consts.SP_DMA_BUSY_REG, 0, @memory.spReg1Uint32Array
alert "hmm..todo: an sp fp status flag is blocking from continuing" if @memory.getInt32(@memory.spReg1Uint8Array, consts.SP_STATUS_REG, @memory.spReg1Uint32Array) & (consts.SP_STATUS_DMA_BUSY | consts.SP_STATUS_IO_FULL | consts.SP_STATUS_DMA_FULL)
@interrupts.clrFlag @memory.spReg1Uint8Array, consts.SP_STATUS_REG, consts.SP_STATUS_DMA_BUSY
@interrupts.setFlag @memory.spReg1Uint8Array, consts.SP_STATUS_REG, consts.SP_STATUS_HALT
return
#hack for now
#triggerDPInterrupt(0, false);
#hack global space until we export classes properly
#node.js uses exports; browser uses this (window)
root = exports ? self
root.C1964jsDmaLE = C1964jsDmaLE
root.log = (message) ->
"use strict"
return