📄 l_tos.s
字号:
; l_tos.s -- loader & decompressor for the atari/tos format;; This file is part of the UPX executable compressor.;; Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer; Copyright (C) 1996-2004 Laszlo Molnar; All Rights Reserved.;; UPX and the UCL library are free software; you can redistribute them; and/or modify them 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; see the file COPYING.; If not, write to the Free Software Foundation, Inc.,; 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.;; Markus F.X.J. Oberhumer Laszlo Molnar; <mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>;#define NRV_BB 8#include "../version.h";; see also:; freemint/sys/mint/basepage.h; freemint/sys/mint/mem.h (FILEHEAD); freemint/sys/memory.c (load_region, load_and_reloc); freemint/sys/arch/cpu.S (cpush);;; This file is first preprocessed by cpp, then the a68k assembler; is run and finally the generated object file is translated to a .h file; by a simple perl script. We also maintain compatiblity with the pasm; assembler (which must be started in the emulator window).;#if defined(__A68K__)# define align4 align 0,4# define L(label) \/**/label# define macro(name) name macro# define text section code#elif defined(__ASL__)# define align4 align 4# define L(label) $$/**/label# define macro(name) name macro# define text section code#else# define align4 align 4# define L(label) ./**/label# define macro(name) macro name#endif; defines needed for including ident_[ns].ash#define db dc.b#define dw dc.w#define dd dc.l; basepage offsetsp_lowtpa equ $0 ; .l pointer to self (bottom of TPA)p_hitpa equ $4 ; .l pointer to top of TPA + 1p_tbase equ $8 ; .l base of text segmentp_tlen equ $c ; .l length of text segmentp_dbase equ $10 ; .l base of data segmentp_dlen equ $14 ; .l length of data segmentp_bbase equ $18 ; .l base of BSS segmentp_blen equ $1c ; .l length of BSS segmentp_dta equ $20 ; .l pointer to current DTAp_parent equ $24 ; .l pointer to parent's basepagep_flags equ $28 ; .l memory usage flagsp_env equ $2c ; .l pointer to environment string;; long living registers:; d4 p_tbase - start of text segment; a6 p_bbase - start of decompressed bss segment, this also is the; - end of decompressed text+data; - start of decompressed relocations; - start of dirty bss; ASTACK (a7) - final startup code copied below stack;; /*************************************************************************; // flush cache macros; **************************************************************************/; note:; GEMDOS/XBIOS trashes d0, d1, d2, a0, a1, a2; long Ssystem(S_FLUSHCACHE, base, length) - inside the kernel this; is called `cpush(base, length)'.; returns: d0.l should be either 0 or -32 (== ENOSYS == EINVFN); Available since FreeMiNT 1.15.1 (1999-04-13).;; Note that on a 68060 FreeMiNT just uses `cpusha bc' in all cases,; so we don't bother passing base and length. (info: base would be d4)macro(MINT_FLUSH_CACHE) pea -1 ; length clr.l -(sp) ; base#if 0 move.w #$0016,-(sp) ; S_FLUSHCACHE (22) move.w #$0154,-(sp) ; Ssystem (340)#else move.l #$01540016,-(sp)#endif trap #1 ; GEMDOS lea 12(sp),sp endm; First try `cpusha bc' (68040/68060). If that fails try temporary changing; the cache control register (68030).macro(SUPEXEC_FLUSH_CACHE) pea \@super(pc) move.w #$0026,-(sp) ; Supexec (38) trap #14 ; XBIOS addq.l #6,sp bra \@done; exception handler\@exception: move.l a1,sp ; restore stack (SSP) jmp (a0) ; and continue\@super: move.l ($10),-(sp) move.l ($2c),-(sp) move.l ($f4),-(sp) move.l sp,a1 ; save stack pointer (SSP) ; set exception vectors lea \@exception(pc),a0 move.l a0,($10) move.l a0,($2c) move.l a0,($f4) nop ; flush write pipeline ; try 68040 / 68060 lea \@1(pc),a0 dc.w $f4f8 ; cpusha bc bra \@ret\@1: ; try 68030 lea \@2(pc),a0 dc.l $4e7a0002 ; movec.l cacr,d0 move.l d0,d1 or.w #$0808,d1 dc.l $4e7b1002 ; movec.l d1,cacr dc.l $4e7b0002 ; movec.l d0,cacr;;; bra \@ret\@2:\@ret: move.l (sp)+,($f4) move.l (sp)+,($2c) move.l (sp)+,($10) nop ; flush write pipeline rts\@done: endmmacro(BOTH_FLUSH_CACHE) MINT_FLUSH_CACHE tst.l d0 beq \@done SUPEXEC_FLUSH_CACHE\@done: endm#define ASTACK a7#if 1# define FLUSH_CACHE BOTH_FLUSH_CACHE#elif 0# define FLUSH_CACHE MINT_FLUSH_CACHE#else# undef FLUSH_CACHE#endif; /*************************************************************************; // entry - the text segment of a compressed executable; //; // note: compressed programs never have the F_SHTEXT flag set,; // so we can assume that the text, data & bss segments; // are contiguous in memory; **************************************************************************/#if defined(__ASL__) padding off#endif text dc.b 'UPX1' ; marker for o2bin.plstart: move.l a0,d0 ; a0 is basepage if accessory beq L(l_app) move.l 4(a0),sp ; accessory - get stack bra L(start)L(l_app): move.l 4(sp),d0 ; application - get basepageL(start): movem.l d1-d7/a0-a6,-(sp); ------------- restore original basepage ; we also setup d4 and a6 here, and we prepare a4 move.l d0,a2 ; a2 = basepage addq.l #p_tbase,a2 move.l (a2)+,a6 move.l a6,d4 ; d4 = p_tbase move.l #'up11',(a2) ; p_tlen add.l (a2)+,a6 move.l a6,(a2)+ ; p_dbase move.l #'up12',(a2) ; p_dlen add.l (a2)+,a6 ; a6 = decompressed p_bbase move.l (a2),a4 ; a4 = compressed p_bbase move.l a6,(a2)+ ; p_bbase move.l #'up13',(a2) ; p_blen; ------------- copy data segment (from a4 to a3, downwards) ; a4 (top of compressed data) already initialized above move.l d4,a3 add.l #'up21',a3 ; top of data segment + offset#if defined(SMALL) move.l #'up22',d0 ; (len / 4) ; copy 4 bytes per loopL(loop): move.l -(a4),-(a3) ;;subq.l #1,d0 dc.b 'u1' ; subq.l #1,d0 / subq.w #1,d0 bne L(loop)#else move.l #'up22',d0 ; (len / 160) ; loop1 - use 10 registers to copy 4*10*4 = 160 bytes per loopL(loop1): lea.l -160(a4),a4 movem.l 120(a4),d1-d3/d5-d7/a0-a2/a5 movem.l d1-d3/d5-d7/a0-a2/a5,-(a3) movem.l 80(a4),d1-d3/d5-d7/a0-a2/a5 movem.l d1-d3/d5-d7/a0-a2/a5,-(a3) movem.l 40(a4),d1-d3/d5-d7/a0-a2/a5 movem.l d1-d3/d5-d7/a0-a2/a5,-(a3) movem.l (a4),d1-d3/d5-d7/a0-a2/a5 movem.l d1-d3/d5-d7/a0-a2/a5,-(a3) ;;subq.l #1,d0 dc.b 'u1' ; subq.l #1,d0 / subq.w #1,d0 bne L(loop1) ; loop2 - copy the remaining 4..160 bytes ;;moveq.l #xx,d0 ; ((len % 160) / 4) - 1
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -