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