Expand description
A dma-bucket is used to organize dma data into groups called buckets.
Each bucket is a linked list of DMA. At DMA time, the buckets are sent in order.
A dma-bucket is a 16 byte thing that lives in the dma-buffer.
buckets live consecutively in the dma-buffer, and can mark the start of a DMA chain
location anywhere.
The bucket doesn't own the data, but rather is a beginning of a linked list of DMA data associated with that bucket
that's stored somewhere else.
At the end, all the buckets are spliced together.
The typical process is:
- empty buckets are allocated with add-buckets
- tags are put somewhere and added to the appropriate bucket with insert-tag, updating last as needed.
- buckets are patched to link to each other with dma-buffer-patch-buckets.
the idea here is that you can build the buckets in whatever order you want, but the buckets
will be DMAd in the bucket allocation order.
Each bucket contains:
a tag, (64-bits), to point to the chain of the bucket
last, a pointer to the last tag of this bucket, so that the bucket can be patched to point to the next.
Each bucket is a linked list of DMA. At DMA time, the buckets are sent in order.
A dma-bucket is a 16 byte thing that lives in the dma-buffer.
buckets live consecutively in the dma-buffer, and can mark the start of a DMA chain
location anywhere.
The bucket doesn't own the data, but rather is a beginning of a linked list of DMA data associated with that bucket
that's stored somewhere else.
At the end, all the buckets are spliced together.
The typical process is:
- empty buckets are allocated with add-buckets
- tags are put somewhere and added to the appropriate bucket with insert-tag, updating last as needed.
- buckets are patched to link to each other with dma-buffer-patch-buckets.
the idea here is that you can build the buckets in whatever order you want, but the buckets
will be DMAd in the bucket allocation order.
Each bucket contains:
a tag, (64-bits), to point to the chain of the bucket
last, a pointer to the last tag of this bucket, so that the bucket can be patched to point to the next.
dma-bucket-insert-tag(arg0: inline-array, arg1: bucket-id, arg2: pointer, arg3: pointer) => pointersource
Add a DMA chain to the bucket
dma-buffer-add-buckets(arg0: dma-buffer, arg1: int) => inline-arraysource
Add count buckets. Each bucket is initialized as empty and won't transfer anything.
dma-buffer-patch-buckets(arg0: inline-array, arg1: int) => inline-arraysource
After adding all data to buckets, call this to stitch together the chains for
count consecutive buckets
count consecutive buckets
Expand description
DMA buffers store data to be sent over DMA.
They are a very simple wrapper around the data.
Typically a dma-buffer will store dma-buckets or other more complicated data structures.
The main display list uses a "chain transfer". In this mode, the DMA system reads dma-tags which
tell it what to transfer next. This can be used to construct linked lists of DMA data.
If the DMA is configured correctly, it is possible to make the first quadword contain
both a dma-tag and a tag for the peripheral. This allows you to have a single quadword
tag that controls both the DMA and peripheral. We call these a "dma-packet" for some reason.
Ex:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
32-bit vifcode ;; 32-bit vifcode ;; 64-bit dma-tag ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
in this case, the vifcodes will be sent to the vif, if
the dma transfer has tte set.
note that the second vifcode can also hold other stuff depending on the mode.
They are a very simple wrapper around the data.
Typically a dma-buffer will store dma-buckets or other more complicated data structures.
The main display list uses a "chain transfer". In this mode, the DMA system reads dma-tags which
tell it what to transfer next. This can be used to construct linked lists of DMA data.
If the DMA is configured correctly, it is possible to make the first quadword contain
both a dma-tag and a tag for the peripheral. This allows you to have a single quadword
tag that controls both the DMA and peripheral. We call these a "dma-packet" for some reason.
Ex:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
32-bit vifcode ;; 32-bit vifcode ;; 64-bit dma-tag ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
in this case, the vifcodes will be sent to the vif, if
the dma transfer has tte set.
note that the second vifcode can also hold other stuff depending on the mode.
dma-buffer: basicsource
dma-gif-packet: structuresource
dma-packet-array: inline-array-classsource
Functions
dma-buffer-add-vu-function(dma-buf: dma-buffer, vu-func: vu-function, flush-path-3: int) => symbolsource
Add DMA tags to load the given VU function. The destination in vu instruction memory
is specific inside the vu-function. This does NOT copy the vu-function into the buffer,
but creates a reference to the existing VU function.
is specific inside the vu-function. This does NOT copy the vu-function into the buffer,
but creates a reference to the existing VU function.
dma-buffer-free(arg0: dma-buffer) => intsource
Get the number of free quadwords, rounded down, between base and end pointers.
dma-buffer-inplace-new(arg0: dma-buffer, arg1: int) => dma-buffersource
Create a dma-buffer in-place. Does not set the type of the dma-buffer object.
dma-buffer-length(arg0: dma-buffer) => intsource
Get length used in quadwords, rounded down
dma-buffer-send(chan: dma-bank, buf: dma-buffer) => nonesource
Send the DMA buffer! DOES NOT TRANSFER TAG, you probably want dma-buffer-send-chain instead.
dma-buffer-send-chain(chan: dma-bank-source, buf: dma-buffer) => nonesource
Send the DMA buffer! Sends the tags
Expand description
Debug tool to print out a DMA list.
vif-disasm-element: structuresource
Variables
*dma-disasm*: symbolsource
*vif-disasm-table*: arraysource
Expand description
Constants/type for the PS2 DMA hardware
There are a number of DMA channels.
The PS2 supports several types of DMA, including simple chunk transfer and more complicated
"chain" transfers, where the hardware can follow a linked data-structure.
The code is organized into dma, dma-buffer, and dma-bucket
- dma interacts with the hardware and actually sends the DMA data.
- dma-buffer is memory management for the data to be sent
- dma-bucket is organization of all the frame's DMA data in the correct order
There are a number of DMA channels.
The PS2 supports several types of DMA, including simple chunk transfer and more complicated
"chain" transfers, where the hardware can follow a linked data-structure.
The code is organized into dma, dma-buffer, and dma-bucket
- dma interacts with the hardware and actually sends the DMA data.
- dma-buffer is memory management for the data to be sent
- dma-bucket is organization of all the frame's DMA data in the correct order
dma-bank-control: structuresource
dma-bank-spr: dma-bank-sourcesource
dma-bank-vif: dma-bank-sourcesource
dma-bucket: structuresource
dma-chcr: uint32source
dma-ctrl: uint32source
dma-enable: uint32source
dma-sqwc: uint32source
dma-tag: uint64source
vif-mask: uint32source
vif-stcycl-imm: uint16source
vif-tag: uint32source
vif-unpack-imm: uint16source
vu-stat: uint64source
Functions
dma-count-until-done(bank: dma-bank, count: pointer) => intsource
Very similar to above, but won't change count if dma is already done.
dma-send-no-scratch(bank: dma-bank, madr: uint32, qwc: uint32) => nonesource
Send from main memory. Wait for dma to be ready, flush the cache, and go!
dma-sync-fast(bank: dma-bank) => nonesource
Wait for dma to finish.
dma-sync-with-count(bank: dma-bank, count: pointer) => intsource
Sync, and 'count' how many iterations of checking for done.
This 'count' is often refered to as the 'wait'
This 'count' is often refered to as the 'wait'
Variables
GIF_DMA_BANK: unknownsource
SPR_FROM_BANK: unknownsource
SPR_TO_BANK: unknownsource
VIF0_DMA_BANK: unknownsource
VIF1_DMA_BANK: unknownsource
VU0_DATA_MEM_MAP: unknownsource
VU1_DATA_MEM_MAP: unknownsource
Functions
clear-vu0-mem() => nonesource
Set the vu0 data memory to 0xabadbeef. This uses the slow EE mapping of VU memory.
Will crash on PC Port.
Will crash on PC Port.
clear-vu1-mem() => nonesource
Set the vu1 data memory to 0xabadbeef. This uses the slow EE mapping of VU memory.
Will crash on PC Port.
Will crash on PC Port.
dma-initialize() => nonesource
Due to a bug in the PS2 hardware, you must always disable the DMAtag mismatch
error. This is done here.
error. This is done here.
dma-send(arg0: dma-bank, madr: uint, qwc: uint) => nonesource
Send DMA given an address and a quadword count.
The madr can be in main memory or scratchpad.
This is appropriate for VIF0/GIF transfers.
It can be used for VIF1, but will do VIF -> madr, which is probably
not what you want.
The madr can be in main memory or scratchpad.
This is appropriate for VIF0/GIF transfers.
It can be used for VIF1, but will do VIF -> madr, which is probably
not what you want.
dma-send-chain(arg0: dma-bank-source, tadr: uint) => nonesource
Send DMA! tadr should be a tag address, possibly in spad ram.
This is useful for sending to VIF.
Tag transfer is enabled, and DIR is set so a VIF1 transfer
goes from tadr -> VIF.
This is useful for sending to VIF.
Tag transfer is enabled, and DIR is set so a VIF1 transfer
goes from tadr -> VIF.
dma-send-chain-no-flush(arg0: dma-bank-source, arg1: uint) => nonesource
Send DMA chain! But don't flush the cache, so be careful here. TTE enable.
dma-send-chain-no-tte(arg0: dma-bank-source, arg1: uint) => nonesource
Send DMA chain! TTE bit is not set, don't transfer tags.
This is never used.
This is never used.
dma-send-from-spr(madr: uint, sadr: uint, qwc: uint, sync: symbol) => nonesource
Transfer from spr.
dma-send-from-spr-no-flush(madr: uint, sadr: uint, qwc: uint, sync: symbol) => nonesource
Transfer from spr, don't flush the cache.
dma-send-to-spr(sadr: uint, madr: uint, qwc: uint, sync: symbol) => nonesource
Transfer data to spr
dma-send-to-spr-no-flush(sadr: uint, madr: uint, qwc: uint, sync: symbol) => nonesource
Transfer to spr. Doesn't flush the cache first, so be careful.
dma-sync-crash(arg0: dma-bank) => nonesource
Wait for DMA to finish for a while, then crash if we can't.
This function is unused.
This function is unused.
dma-sync-hang(bank: dma-bank) => nonesource
Hang here until the dma transfer is completed.
This is worse than the dma-sync-fast because it ends
up spamming the DMA bank register more often, and reduces
the speed of the DMA transfer.
This function is unused.
This is worse than the dma-sync-fast because it ends
up spamming the DMA bank register more often, and reduces
the speed of the DMA transfer.
This function is unused.
dump-vu1-mem() => nonesource
Print VU1 memory to runtime stdout.
Will crash on PC Port.
Will crash on PC Port.
dump-vu1-range(start: uint, total-count: uint) => symbolsource
Print part of VU1 memory to runtime stdout.
Will crash on PC Port.
Will crash on PC Port.
reset-vif1-path() => nonesource
When things go wrong, totally reset vif1.
symlink2() => nonesource
symlink2 is a handwritten assembly version of the v2 linking routine.
it is not ported because the OpenGOAL linker has its own implementation already.
it is not ported because the OpenGOAL linker has its own implementation already.
symlink3() => nonesource
symlink3 is a handwritten assembly version of the v3 linking routine.
OpenGOAL uses a different format for v3, customized for x86-64, so this is not
needed. The C++ implementation is plenty fast enough
OpenGOAL uses a different format for v3, customized for x86-64, so this is not
needed. The C++ implementation is plenty fast enough
ultimate-memcpy(dst: pointer, src: pointer, size-bytes: uint) => nonesource
The Fastest Memory Copy, for larger transfers.
Memory is copied in ascending order, in 4 kB blocks.
The size should be a multiple of 16 bytes.
Memory is copied in ascending order, in 4 kB blocks.
The size should be a multiple of 16 bytes.