1/*
2;  mipsel.r3000-ps1.asm -- ps1/exe program entry & decompressor
3;
4;  This file is part of the UPX executable compressor.
5;
6;  Copyright (C) 1996-2020 Markus Franz Xaver Johannes Oberhumer
7;  Copyright (C) 1996-2020 Laszlo Molnar
8;  Copyright (C) 2002-2020 Jens Medoch
9;  All Rights Reserved.
10;
11;  UPX and the UCL library are free software; you can redistribute them
12;  and/or modify them under the terms of the GNU General Public License as
13;  published by the Free Software Foundation; either version 2 of
14;  the License, or (at your option) any later version.
15;
16;  This program is distributed in the hope that it will be useful,
17;  but WITHOUT ANY WARRANTY; without even the implied warranty of
18;  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19;  GNU General Public License for more details.
20;
21;  You should have received a copy of the GNU General Public License
22;  along with this program; see the file COPYING.
23;  If not, write to the Free Software Foundation, Inc.,
24;  59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25;
26;  Markus F.X.J. Oberhumer              Laszlo Molnar
27;  <markus@oberhumer.com>               <ezerotven+github@gmail.com>
28;
29;  Jens Medoch
30;  <jssg@users.sourceforge.net>
31;
32*/
33
34            .set    mips1
35            .set    noreorder
36            .set    noat
37            .altmacro
38
39
40#include "arch/mips/r3000/macros.ash"
41#include "arch/mips/r3000/bits.ash"
42
43/*
44=============
45============= none
46=============
47*/
48
49.if (PS1)
50    SZ_REG = 4
51.else
52    SZ_REG = 8
53.endif
54
55.macro mCDBOOT s
56    .if (\s == 1)
57        REG_SZ = (5*SZ_REG)
58        CDBOOT = 1
59    .else
60        REG_SZ = (6*SZ_REG)
61        CDBOOT = 0
62    .endif
63.endm
64
65.macro  regs    _w, sz, reg
66             \_w     pc,SZ_REG*0(\reg)
67             \_w     src,SZ_REG*1(\reg)
68             \_w     cnt,SZ_REG*2(\reg)
69             \_w     a3,SZ_REG*3(\reg)
70             \_w     ra,SZ_REG*4(\reg)
71            REG_SZ = (5*SZ_REG)
72    .if (\sz == 1)
73             \_w     tmp,SZ_REG*5(\reg)
74            REG_SZ = (6*SZ_REG)
75    .endif
76.endm
77
78.macro  push    sz = 0, reg = sp
79    .if (PS1)
80             regs    sw,\sz,\reg
81    .else
82             regs    sd,\sz,\reg
83    .endif
84.endm
85
86.macro  pop     ok = 0, reg = sp
87    .if (PS1)
88             regs    lw,\ok,\reg
89    .else
90             regs    ld,\ok,\reg
91    .endif
92.endm
93
94.macro  SysFlushCache
95    .if (PS1)
96            PRINT ("SYSCALL PS1")
97            li      t2,160
98            jalr    ra,t2
99            li      t1,68
100    .else
101            PRINT ("SYSCALL PS2")
102            move    a0, zero
103            li      v1, 100
104            syscall
105    .endif
106.endm
107
108/*
109.macro  EnterCriticalSection
110            li      a0, 1
111            syscall
112.endm
113
114
115.macro  ExitCriticalSection
116            li      a0, 2
117            syscall
118.endm
119*/
120
121#define CLzmaDecoderState   a0   /* CLzmaDecoderState */
122#define inStream            a1
123#define inSize              a2
124#define pinSizeprocessed    a3  /*  *inSizeprocessed */
125
126#define outStream           t0
127#define outSize             t1
128#define poutSizeProcessed   t2
129
130#define dst_save            0*SZ_REG
131#define outSizeProcessed    1*SZ_REG
132#define inSizeProcessed     2*SZ_REG
133
134            lzma_args_sz =  4*SZ_REG
135
136/*
137=============
138============= ENTRY POINT cd-boot
139=============
140*/
141            mCDBOOT 1
142
143section     cdb.start
144            la      t0,PSVR         // prepare to compute value
145            subu    t0,s0,t0        // get stored header offset in mem
146            jr      t0
147            subiu   sp,REG_SZ       // prep to adjust stack
148
149section     cdb.entry
150            push                    // push used regs
151            la      src,CPDO        // load compressed data offset
152
153section     cdb.start.lzma
154            la      t0,PSVR         // prepare to compute value
155            subu    t0,s0,t0        // get stored header offset in mem
156            ori     tmp,zero,%lo(ldr_sz+REG_SZ)  // size of decomp. routine
157            jr      t0
158            subu    sp,tmp          // adjust the stack with this size
159
160section     cdb.entry.lzma
161            push    1               // push used regs
162            addiu   src,t0,lzma_cpr // load compressed data offset
163            addiu   dst,sp,REG_SZ
164
165section     cdb.lzma.cpr
166            la      src,CPDO        // load compressed data offset
167
168section     cdb.dec.ptr
169            la      dst,DECO        // load decompress data offset
170
171section     cdb.dec.ptr.hi
172            lui     dst,%hi(DECO)
173
174section     cdb.exit
175            SysFlushCache
176            pop                     // pop used regs with marker for entry
177            j       entry
178            addiu   sp,REG_SZ
179
180
181/*
182=============
183============= ENTRY POINT console
184=============
185*/
186
187            mCDBOOT 0
188
189section     con.start
190            li      tmp,%lo(ldr_sz+REG_SZ)  // size of decomp. routine
191            subu    sp,tmp          // adjust the stack with this size
192            push    1               // push used regs
193            addiu   pc,sp,REG_SZ    // get offset for decomp. routine
194            move    dst,pc
195            la      src,DCRT        // load decompression routine's offset
196
197section     con.mcpy
198            ori     cnt,zero,%lo(ldr_sz)    // amount of removed zero's at eof
1991:          lw      var,0(src)      // memcpy
200            subiu   cnt,4
201            sw      var,0(dst)
202            addiu   src,4
203            bnez    cnt,1b
204            addiu   dst,4
205
206section     lzma.prep
207            addiu   pc,dst,%lo(lzma_init_off)
208
209section     con.padcd
210            addiu   src,%lo(PAD)     // pointer compressed data
211
212section     dec.ptr
213            lui     dst,%hi(DECO)    // load decompress data offset
214            jr      pc
215            addiu   dst,%lo(DECO)
216
217section     dec.ptr.hi
218            jr      pc
219            lui     dst,%hi(DECO)
220
221section     con.entry
222
223section     con.exit
224            SysFlushCache
225            pop     1                // pop used regs with marker for entry
226            j       entry
227            addu    sp,tmp
228
229
230/*
231=============
232============= ENTRY POINT bss
233=============
234*/
235            mCDBOOT 0
236
237section     bss.cdb.start.lzma
238            la      t0,PSVR          // prepare to compute value
239            subu    t0,s0,t0         // get stored header offset in mem
240            la      var,wrkmem-REG_SZ
241            jr      t0
242            move    tmp,sp
243
244section     bss.cdb.entry.lzma
245            push    1,var            // push used regs
246            move    sp,var
247            addiu   src,t0,lzma_cpr  // compressed lzma decoder offset
248            addiu   dst,sp,REG_SZ
249
250section     bss.con.start
251            la      var,wrkmem-REG_SZ
252            move    tmp,sp
253            push    1,var            // push used regs
254            move    sp,var
255            addiu   pc,sp,REG_SZ     // get offset for decomp. routine
256            move    dst,pc
257            la      src,DCRT         // load decompression routine's offset
258
259section     bss.exit
260            SysFlushCache
261            pop     1                // pop used regs with marker for entry
262            j       entry
263            move    sp,tmp
264
265
266// =============
267
268section     memset.short
269            ori     cnt,zero,%lo(SC) // amount of removed zero's at eof
2701:          sw      zero,0(dst)
271            subiu   cnt,1
272            bnez    cnt,1b
273            addiu   dst,4
274
275section     memset.long
276            ori     cnt,zero,%lo(SC) // amount of removed zero's at eof
277            sll     cnt,3            // (cd mode 2 data sector alignment)
2781:          sw      zero,0(dst)
279            subiu   cnt,1
280            bnez    cnt,1b
281            addiu   dst,4
282
283
284/*
285=============
286============= DECOMPRESSION
287=============
288*/
289
290#include "arch/mips/r3000/nrv2b_d.ash"
291#include "arch/mips/r3000/nrv2d_d.ash"
292#include "arch/mips/r3000/nrv2e_d.ash"
293
294
295// ========== cd-boot
296
297            UCL_init    8,0,1
298section     nrv2b.8bit
299            build nrv2b, full
300section     nrv2d.8bit
301            build nrv2d, full
302section     nrv2e.8bit
303            build nrv2e, full
304
305            UCL_init    32,0,1
306section     nrv2b.32bit
307            build nrv2b, full
308section     nrv2d.32bit
309            build nrv2d, full
310section     nrv2e.32bit
311            build nrv2e, full
312
313// ========== console-run
314
315            UCL_init    8,1,0
316section     8bit.sub
317            build 0, sub_only, gb8_e
318
319            UCL_init    32,1,0
320section     32bit.sub
321            build 0, sub_only, gb32_e
322
323section     nrv2b.small
324            build nrv2b, without_sub
325section     nrv2d.small
326            build nrv2d, without_sub
327section     nrv2e.small
328            build nrv2e, without_sub
329
330section     nrv.done
331decomp_done:
332
333section     decompressor.start
334decompressor:
335
336section     lzma.init
337            li      tmp,%lo(lzma_stack_adjust-lzma_args_sz)
338            addu    sp,tmp
339/*
340            move    var,sp
3411:
342            sw      zero,0(var)
343            addiu   tmp,4
344            bnez    tmp,1b
345            addiu   var,4
346*/
347            addiu   src,2
348            la      inSize,lzma_c_len
349            la      outSize,lzma_u_len
350
351            addu    poutSizeProcessed,sp,outSizeProcessed
352            addiu   pinSizeprocessed,sp,inSizeProcessed
353
354            la      tmp,lzma_properties
355            sw      dst,dst_save(sp)
356            addiu   CLzmaDecoderState,sp,lzma_args_sz
357            bal     decompressor
358            sw      tmp,0(CLzmaDecoderState)
359            lw      dst,dst_save(sp)
360            lw      outSize,outSizeProcessed(sp)
361            li      tmp,%lo(lzma_stack_adjust-lzma_args_sz)
362            addu    dst,outSize
363            subu    sp,tmp
364
365#include    "arch/mips/r3000/lzma_d.S"
366
367#include    "include/header.S"
368
369/* vim:set ts=8 sw=8 et: */
370