Gravity.asm (11,137 bytes)
2009-05-02 12:15
;*---------------------------------------------------------------------------
; :Modul. GravityHD.asm
; :Contents. Gravity slave
; :Author. JOTD
; :Original.
; :Version.
; :History.
;
; :Requires. 68000 or higher
; :Copyright. Public Domain
; :Language. 68000 Assembler
; :Translator. Barfly V2.9
; :To Do.
;---------------------------------------------------------------------------*
INCDIR Include:
INCDIR osemu:
INCLUDE whdload.i
INCLUDE whdmacros.i
IFD BARFLY
OUTPUT "Gravity.Slave"
IFND DEBUG
BOPT O+ ;enable optimizing
BOPT OG+ ;enable optimizing
BOPT ODd- ;disable mul optimizing
BOPT ODe- ;disable mul optimizing
ENDC
BOPT w4- ;disable 64k warnings
BOPT wo- ;disable optimizer warnings
SUPER
ENDC
;============================================================================
IFD DEBUG
CHIPMEMSIZE = $FF000
FASTMEMSIZE = $0000
ELSE
CHIPMEMSIZE = $80000
FASTMEMSIZE = $40000
ENDC
NUMDRIVES = 1
WPDRIVES = %1111
DISKSONBOOT
;HDINIT
;HRTMON
;MEMFREE = $100
;NEEDFPU
;SETPATCH
BOOTBLOCK
;============================================================================
slv_Version = 16
slv_Flags = WHDLF_NoError|WHDLF_Examine|WHDLF_EmulDivZero|WHDLF_EmulTrap
slv_keyexit = $5D ; num '*'
INCLUDE kick13.s
;============================================================================
IFND .passchk
DOSCMD "WDate >T:date"
.passchk
ENDC
DECL_VERSION:MACRO
dc.b "2.1"
IFD BARFLY
dc.b " "
INCBIN "T:date"
ENDC
ENDM
dc.b "$","VER: slave "
DECL_VERSION
dc.b $A,$D,0
slv_name dc.b "Gravity"
IFD DEBUG
dc.b " (DEBUG MODE)"
ENDC
dc.b 0
slv_copy dc.b "1989 Imageworks",0
slv_info dc.b "adapted & fixed by CFou! & JOTD",10,10
dc.b "Set CUSTOM1=1 to disable stars background",10,10
dc.b "Version "
DECL_VERSION
dc.b 0
slv_CurrentDir
dc.b 0
EVEN
;============================================================================
_bootblock:
movem.l a0-a2/a6/d0-d1,-(A7)
;get tags
lea (tags,pc),a0
move.l _resload(pc),a2
jsr (resload_Control,a2)
move.l custom1(pc),d0
beq.b .skip
;eat some memory to prevent stars to be displayed
move.l #$10000,d0
move.l #MEMF_CHIP,d1
move.l $4.W,a6
jsr _LVOAllocMem(a6)
.skip
movem.l (a7)+,a0-a2/a6/d0-d1
jsr ($C,a4)
movem.l a0-a2/a6/d0-d1,-(A7)
move.l a0,a1
lea pl_boot(pc),a0
move.l _resload(pc),a2
jsr resload_Patch(a2)
movem.l (a7)+,a0-a2/a6/d0-d1
moveq.l #0,D0
rts
_quit
PEA TDREASON_OK
MOVE.L _resload(PC),-(A7)
add.l #resload_Abort,(a7)
rts
pl_boot
PL_START
PL_PS $A564-$A498,check_copylock ; Rixa: remove this
PL_P $B98E-$A498,end_disk_read ; Rixa: needs change to $148E
PL_END
end_disk_read
movem.l (a7)+,d1-d7/a0-a6 ; stolen
; patch if executable found
movem.l d0-d1/a0-a2,-(a7)
move.l d2,a0 ; start of loaded file
move.w (a0)+,d0
cmp.w #$601A,d0 ; all code chunks start by BRA +$18
bne.b .out
move.l _resload(pc),a2
move.l d2,a1
move.l (a0)+,d0 ; length/signature
cmp.l #$BAE,d0
beq.b .st_replay
cmp.l #$375A,d0
beq.b .code_part_2
cmp.l #$1100C,d0 ; Rixa: Needs change to $11044
beq.b .loader
cmp.l #$5D80,d0
beq.b .in_game_1
cmp.l #$4B1C,d0
beq.b .in_game_2
cmp.l #$1240,d0
beq.b .in_game_3
cmp.l #$C80,d0
beq.b .in_game_4
cmp.l #$5CC,d0
beq.b .in_game_5
bsr _flushcache
;; ILLEGAL ; unknown program
.out
movem.l (a7)+,d0-d1/a0-a2
tst.l d0
rts
.patch
jsr resload_Patch(a2)
bra.b .out
; around $8Cxxx
.in_game_5
.in_game_4
.in_game_3
.in_game_2
.in_game_1
bsr _flushcache
bra.b .out
.loader
pea add_a0(pc)
move.l (a7)+,$80.W
pea trap_1(pc)
move.l (a7)+,$84.W
pea trap_2(pc)
move.l (a7)+,$88.W
pea trap_3(pc)
move.l (a7)+,$8C.W
pea trap_4(pc)
move.l (a7)+,$90.W
patch $100,emulate_sub_d7_to_d4
move.l attnflags(pc),d0
btst #AFB_68010,d0
beq.b .68000
; JOTD: don't do it on 68000 because it would crash badly
lea pl_loader(pc),a0
bra.b .patch
.68000
lea pl_loader_68000(pc),a0
bra.b .patch
.st_replay
pea smc_bra_replay(pc)
move.l (a7)+,$94.W
lea pl_replay(pc),a0
bra.b .patch
.code_part_2
lea pl_code_2(pc),a0
bra.b .patch
pl_replay
PL_START
PL_PS $309EC-$300B6,fix_dbf_replay
PL_L $3067C-$300B6,$4E714E71
PL_W $3085E-$300B6,$4E45
PL_END
; 68010+ only
pl_loader
PL_START
; stack-leak error
PL_PS $174DA-$C558,fix_stackframe_error ; Rixa: needs change to $AFBA
PL_I $17520 ; RTE return: does not happen ; Rixa: needs change to $17558?
PL_NEXT pl_loader_68000
pl_loader_68000
PL_START
; SMC fix
PL_W $1B5F4-$C558,$4E40 ; TRAP #0 to simulate SMC ; Rixa: needs change to $F0D4
PL_W $1B694-$C558,$4E40 ; TRAP #0 to simulate SMC ; Rixa: needs change to $F174
PL_PS $1B896-$C558,smc_link ; Rixa: needs change to $F376
PL_W $18E72-$C558,$4E44 ; Rixa: needs change to $C952
PL_W $18EC2-$C558,$4E44 ; Rixa: needs change to $C9A2
PL_W $18F82-$C558,$4E44 ; Rixa: needs change to $CA62
PL_W $1902C-$C558,$4E44 ; Rixa: needs change to $CB0C
PL_W $19A24-$C558,$4E44 ; Rixa: needs change to $D504
PL_L $1933E-$C558,$4EB80100 ; Rixa: needs change to $CE1E
; copylock check (already disabled BTW)
; if wrong copylock, clicking on the
; buttons during the game has no effect!
PL_L $11CB4-$C558,$4E714E71 ; Rixa: needs to be removed
; 24-bit access fault problem
; game loads a an address register then masks it
; with $FFFFFF sometimes causing 24 bit error
; (but sometimes it is useful)
PL_PS $0E480-$C558,fix_24_bit_d1
PL_PS $0FB42-$C558,fix_24_bit_d0
PL_PS $0FB8E-$C558,fix_24_bit_d0
PL_PS $0FBE4-$C558,fix_24_bit_d0
PL_PS $15E6C-$C558,fix_24_bit_d0 ; Rixa: needs change to $0994C
PL_PS $1860C-$C558,fix_24_bit_d0 ; Rixa: needs change to $0C0EC
PL_PS $1CB64-$C558,fix_24_bit_d0 ; Rixa: needs change to $10644
PL_PS $1CE04-$C558,fix_24_bit_d0 ; Rixa: needs change to $108E4
PL_END
pl_code_2
PL_START
PL_W $62A54-$6009A,$4E42 ; TRAP #2 to simulate SMC
PL_W $629CC-$6009A,$4E41 ; TRAP #1 to simulate SMC
PL_W $62228-$6009A,$4E44
PL_W $628D8-$6009A,$4E44
PL_PS $62A04-$6009A,emulate_sub_d2_d3
; BRA emulation
PL_W $600BA-$6009A,$4E43
PL_W $600BE-$6009A,$4E43
PL_W $600C2-$6009A,$4E43
PL_W $600C6-$6009A,$4E43
PL_W $600CA-$6009A,$4E43
PL_W $600CE-$6009A,$4E43
PL_W $600D2-$6009A,$4E43
PL_END
; the routine in the trap #15 handler is really stoopid:
; it pops SR & return address from supervisor state (SSP) and restores
; it in user state (USP).
; There is not really an immediate stackframe error since the game uses RTR
; instruction, which does not have stackframe check/pop (not like RTE)
;
; BUT the problem is that SSP state is reached using TRAP, and on 68020+ one more
; word is added (stackframe). So SSP value decreases at each call, and ends up
; trashing the code in the title screen, or later.
;
; this is really a vicious bug
fix_stackframe_error
; first, store return address
move.l a0,-(a7)
lea .return_address(pc),a0
move.l 4(a7),(a0)
move.l (a7)+,a0
addq.l #4,a7 ; pop the stack to simulate a JMP below
MOVE (A7)+,-(A0) ;174DA: 311F ; pop/save SR/CCR from SSP
MOVE.L (A7)+,-(A0) ;174DC: 211F ; pop/save return address from SSP
addq.l #2,a7 ; fix remove stackframe if 68020+
MOVE.L A0,-(A7) ;174DE: 2F08
; return to program
move.l .return_address(pc),-(a7)
rts
.return_address:
dc.l 0
smc_bra_replay
movem.l a0,-(a7)
move.l 6(a7),a0 ; return address
cmp.l #$4E714E71,(a0)
movem.l (a7)+,a0
bne.b .jsr
; was BRA: branch
RTE
.jsr
; tricky: first, recover from the RTE
movem.l A0/A1,-(A7)
move.l 10(A7),A0 ; return PC
lea .return_address(pc),a1
move.l a0,(a1) ; save return address for later on
lea .jsr_address(pc),a1
move.l (a0),(a1) ; save jsr address for later on
lea .recov(pc),a1
move.l a1,10(a7) ; change return PC
movem.l (A7)+,A0/A1
rte
.recov
; now we're in user mode: first push return address
move.l .return_address(pc),-(a7)
addq.l #4,(a7) ; skip JSR operand
; then push JSR operand
move.l .jsr_address(pc),-(a7)
; go
rts
.return_address
dc.l 0
.jsr_address
dc.l 0
emulate_sub_d2_d3
move d1,d3
asr #5,d2
asr #5,d3
movem.l d0/a0,-(a7)
move.l 8(a7),a0 ; return address
sub.w (2,A0),d2
sub.w (6,A0),d3
movem.l (a7)+,d0/a0
rts
emulate_sub_d7_to_d4
move 6(a0),d7 ; original
movem.l d0/a0,-(a7)
move.l 8(a7),a0 ; return address
sub.w ($2,A0),d7
sub.w ($12,A0),d6
sub.w ($20,A0),d5
sub.w ($2E,A0),d4
movem.l (a7)+,d0/a0
rts
fix_dbf_replay
move.w #12,d0
.bd_loop1
move.w d0,-(a7)
move.b $dff006,d0 ; VPOS
.bd_loop2
cmp.b $dff006,d0
beq.s .bd_loop2
move.w (a7)+,d0
dbf d0,.bd_loop1
addq.l #4,(a7)
rts
add_a0
move.l a1,-(a7)
move.l 6(a7),a1 ; return address
add.w (a1),a0 ; simulate lea x(a0),a0 (x depends because of smc grrrr)
move.l (a7)+,a1
add.l #2,2(a7) ; skip lea opcode
rte
; < D0: link offset
smc_link
movem.l d0/a0/a1,-(a7)
lea return_address(pc),a0
move.l 12(a7),a1
add.l #10,a1 ; -> leads to adda d0,a6, just after the LINK instruction
move.l a1,(a0)+
ext.l d0
move.l d0,(a0) ; writes required LINK parameter to link_value
movem.l (a7)+,d0/a0/a1
addq.l #4,a7 ; pops up the stack because we're going to LINK
; LINK emulation
move.l a6,-(a7)
move.l a7,a6
add.l link_value(pc),a7
; goto next
move.l return_address(pc),-(a7)
rts
; do not separate return_address from link_value variables!
return_address
dc.l 0
link_value
dc.l 0
DEF_FIX_24_BIT:MACRO
fix_24_bit_d\1:
move.l d7,-(a7)
move.l d\1,d7
rol.l #8,d7
tst.b d7
beq.b .out
cmp.b _expmem(pc),d7
beq.b .out
; not 0 and not expmem MSB: clear it
clr.b d7
ror.l #8,d7
move.l d7,d\1
.out
move.l (a7)+,d7
rts
ENDM
DEF_FIX_24_BIT 0
DEF_FIX_24_BIT 1
trap_1
movem.l d0/a1,-(a7)
move.l 10(a7),a1 ; return address
add.w (a1),a3 ; simulate lea x(a0),a0 (x depends because of smc grrrr)
add.w 4(a1),a4 ; simulate lea x(a0),a0 (x depends because of smc grrrr)
move.w 8(a1),d0
add.w d0,60(a6) ; simulate addi to 60(a6)
move.w (14,a1),d0
add.w d0,62(a6)
movem.l (a7)+,d0/a1
add.l #2+4+6+6,2(a7) ; skip opcodes
rte
; lea a5, add d0, add d1
trap_2
move.l a1,-(a7)
move.l 6(a7),a1 ; return address
add.w (a1),a5 ; simulate lea x(a5),a5 (x depends because of smc grrrr)
add.w (4,a1),d0 ; simulate addi to d0
add.w (8,a1),d1 ; simulate addi to d1
move.l (a7)+,a1
add.l #2+4+4,2(a7) ; skip opcodes
rte
; sub #x,d0, sub #x,d1
trap_4
move.l a1,-(a7)
move.l 6(a7),a1 ; return address
sub.w (a1),d0 ; simulate subi to d0
sub.w (4,a1),d1 ; simulate subi to d1
move.l (a7)+,a1
add.l #2+4,2(a7) ; skip opcodes
rte
; BRA emulation
trap_3
movem.l d0/A0,-(A7)
move.l 10(A7),A0 ; return address
moveq #0,d0
move.w (a0),d0
add.l d0,10(A7) ; RTE -> BRA address
movem.l (A7)+,D0/A0
rte
check_copylock
move.l (a7),a0 ; A568
move.l -80(a0),a0 ; lea $A51A
cmp.w #$4AFC,$E(a0)
bne.b .nocopylock
moveq #0,d0 ; original
;;; move.l #$DD17A129,d0 ; no disk in drive (also one of copylock checksum)
rts
; move.l #$90006,$6198
; move.l #$b6c00000,$619C
.nocopylock
jmp (a0)
tags
dc.l WHDLTAG_ATTNFLAGS_GET
attnflags
dc.l 0
dc.l WHDLTAG_CUSTOM1_GET
custom1
dc.l 0
dc.l 0
;============================================================================
END