goutdump.s
1.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
/*
goutdump.s
SETA のマクロコードを参考に実装した. fifo のバッファリング処理
*/
.name return_adrs, $21
.name dma_top, $19
#define dma_end outp
.name fifo_end, $20
#define tmp2 fifo_end
#define outp_top fifo_end
.name out_size, $18 # 呼び出し側で必要なサイズを代入しておく.
.name tmp, $6 # ただし outsz から RSP_OUTPUT_END を引いた値
.ent OutputOpen
OutputOpen_End:
jr return
OutputOpen:
add tmp, outp, out_size # 空き容量チェック
blez tmp, OutputOpen_End # 空きがあるなら終了
add return_adrs, zero, return
lw dma_top, RSP_STATE_FIFO_OUTP(rsp_state)
lw fifo_end, RSP_STATE_FIFO_BUF_END(rsp_state) # fifo end
addi out_size, outp, -RSP_OUTPUT_OFFSET
add dma_end, dma_top, out_size
sub tmp2, fifo_end, dma_end # tmp = 残りのバッファサイズ
mfc0 tmp, CMD_CURRENT # CurrentFit 用に先読みする
bgez tmp2, CurrentFit # tmp >=0 なら追加で出力可能
WrapBuffer:
mfc0 tmp, CMD_STATUS
lw dma_top, RSP_STATE_FIFO_BUF_TOP(rsp_state)
/* Delay */
andi tmp, tmp, 0x0400 # DPC_STATUS_START_VALID
bne tmp, zero, WrapBuffer
AdvanceCurrent:
mfc0 tmp, CMD_CURRENT
/* Delay */
/* Delay */
beq tmp, dma_top, AdvanceCurrent
add dma_end, dma_top, out_size # データの最後
mtc0 dma_top, CMD_START # スタートの再設定
# これから DMA 転送する領域に CMD_CURRENT がないかどうかの判定
CurrentFit0:
mfc0 tmp, CMD_CURRENT
CurrentFit:
sub tmp2, dma_top, tmp
bgez tmp2, OpenDMA # CURRENT が dma_top より前なら JUMP
sub tmp2, dma_end, tmp
bgez tmp2, CurrentFit0 # CURRENT が dma_end より前なら LOOP
OpenDMA:
addi outp_top, zero, RSP_OUTPUT_OFFSET
addi $17, zero, 1
jal DMAproc
addi out_size, out_size, -1
jal DMAwait
sw dma_end, RSP_STATE_FIFO_OUTP(rsp_state)
mtc0 dma_end, CMD_END
jr return_adrs
addi outp, zero, RSP_OUTPUT_OFFSET
.end OutputOpen
.unname return_adrs
.unname dma_top
.unname fifo_end
.unname out_size
.unname tmp
#undef dma_end
#undef tmp2
#undef outp_top