home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Format CD 26
/
amigaformatcd26.iso
/
-screenplay-
/
hd_installers
/
totalfootb2hd
/
totalhd.s
< prev
Wrap
Text File
|
1998-03-09
|
12KB
|
481 lines
;/* Total Football - Fastram loader (HD Installer)
* ----------------------------------------------
* Requirements: 3MB of free continious fastram available (for the 3
* mirrored game disks)
*
* This source code is provided here so that;
*
* 1) Domark may possibly learn from it ... hehehe :)
* 2) Other people (assembly coders) can fix all these types of game to work
* from hard-disk with ease...
*
* This source is fully freeware! do what you wish with it!
*
* Even use it in commercial games if you want.. go on see if I care!
*
*/
_custom = $DFF000
intena = $9A
color = $180
dmacon = $96
fmode = $1fc
bplcon3 = $106
AbsExecBase = $4
MaxLocMem = $3E
MaxExtMem = $4E
AttnFlags = $128
tv_UserIntVects = $100
tv_TrapInstrVects = $80
_LVOSupervisor = -30
_LVOOldOpenLibrary = -408
_LVOFindTask = $FFFFFEDA
_LVOWaitPort = $FFFFFE80
_LVOGetMsg = $FFFFFE8C
_LVOReplyMsg = $FFFFFE86
_LVOForbid = $FFFFFF7C
_LVOPermit = $FFFFFF76
_LVOOpen = $FFFFFFE2
_LVORead = $FFFFFFD6
_LVOClose = $FFFFFFDC
pr_CLI = $AC
pr_MsgPort = $5C
MODE_OLDFILE = $3ED
CACRF_CopyBack = $80000000 * Enable Copyback mode (`040+)
CACRF_EnableE = $40000000 * Enable External Caches
CACRF_WriteAllocate = $00002000 * Enable Write Allocate (`030+)
CACRF_DBE = $00001000 * Data Burst (`030+)
CACRF_ClearD = $00000800 * Flush Data Cache (`030+)
CACRF_FreezeD = $00000200 * Freeze Data Cache (`030+)
CACRF_EnableD = $00000100 * Enable Data Cache (`030+)
CACRF_IBE = $00000010 * Inst Burst (`030+)
CACRF_ClearI = $00000008 * Flush Inst Cache (`020+)
CACRF_FreezeI = $00000002 * Freeze Inst Cache (`020+)
CACRF_EnableI = $00000001 * Enable Inst Cache (`020+)
* Enable Instruction-cache()
* Enable Data-cache()
* Enable Write-allocate()
section fastram,code_f
*-------------- handle a workbench startup..
HD_Install: move.l d0,d7 ;save CLI params len
move.l a0,a5 ;save CLI params ptr
suba.l a1,a1 ;clear a1
move.l 4.w,a6 ;get execbase
jsr _LVOFindTask(a6) ;find *THIS* task
move.l d0,a4 ;get task ptr
move.l d7,d0 ;restore CLI params len
move.l a5,a0 ;restore CLI params ptr
tst.l pr_CLI(a4) ;did we originate from CLI?
bne.s ProgStart ;yes...call our program
lea pr_MsgPort(a4),a0 ;from wb.. handle wb_startup
move.l a0,a4
jsr _LVOWaitPort(a6) ;wait for a message
move.l a4,a0
jsr _LVOGetMsg(a6) ;then get it
move.l d0,-(sp)
bsr.s ProgStart
move.l d0,d7 ;save CLI Return code
move.l 4.w,a6
jsr _LVOForbid(a6)
move.l (sp)+,a1
jsr _LVOReplyMsg(a6)
move.l d7,d0 ;exit code
rts
ProgStart move.l 4.w,a6
lea DOSName(pc),a1 * lib name in a1
jsr _LVOOldOpenLibrary(a6) * try to open library
move.l d0,_DOSBase * store lib base
beq.w bad_file * cleanup and quit if fail
*-------------- load disk 1 mirror into fastram..
lea disk1.txt(pc),a0
lea diskdata+901120*0,a1
bsr RealLoadDOSFile
tst.l d0
bne.w bad_file
*-------------- load disk 2 mirror into fastram..
lea disk2.txt(pc),a0
lea diskdata+901120*1,a1
bsr RealLoadDOSFile
tst.l d0
bne.w bad_file
*-------------- load disk 3 mirror into fastram..
lea disk3.txt(pc),a0
lea diskdata+901120*2,a1
bsr RealLoadDOSFile
tst.l d0
bne.w bad_file
*-------------- now take over machine now..
move.l 4.w,a6
lea Caches(pc),a5
jmp _LVOSupervisor(a6) * enter supervise mode!
*-------------- turn off all dma, interrupts, etc.
Caches: move.w #$7FFF,$dff096 * no dmacon
move.w #$7FFF,$dff09a * no intena
move.w #$7FFF,$dff09c * no intreq
*-------------- patch AGA hardware to reset to defaults (null)
move.w #$0,_custom+fmode * no AGA 64-bit fetchmodes..
move.w #$0,_custom+bplcon3 * no extra bitplane control
*-------------- turn OFF cpu caches.. (sob!)
move.l #CACRF_FreezeI+CACRF_FreezeD+CACRF_WriteAllocate,d0
movec d0,cacr
*-------------- reset vectorbase to zeropage
moveq #0,d0
movec d0,vbr
*-------------- init our fastram loader..
lea diskdata,a0 * disk image`s buffer
lea blockmem,a1 * 512 Bytes fastram buffer
jsr InitDOSLoad
*-------------- load in the game loader..
* NB:
* ---
* All these lame and dirty absolute addresses are needed because the original
* game is address relocated to $19268 in chipram!! ARRRGG!!!!! Wake up DOMARK!
*
lea chipload.txt(pc),a0
lea $19268,a1
jsr fastload
*-------------- re-direct he game`s hardware disk loader to our fastram loader
move.l (AbsExecBase).l,a6
lea ($4000).l,sp * set absolute stack (doh!)
lea (tv_UserIntVects).l,a0
move.w (AttnFlags,a6),($2F6,a0) * total football`s main
move.l (MaxLocMem,a6),($2F8,a0) * loader expect`s at these
move.l (MaxExtMem,a6),($2FC,a0) * low memory addresses to
move.l #$480,$400.w * have these variables
move.l #$880,$404.w * which is pretty lame eh!
lea $19268,a0 * a0.l = base of game loader
move.w #$4e75,$2500(a0) * no drive select grinds
* patched to simply "RTS"
move.w #$4ef9,$25e6(a0) * patch loader to "JMP" to the
move.l #fastload,$25e6+2(a0) * address of our 'fastload'
move.w #$600e,$23e0(a0) * skip past disk select checks
* patched to "BRA.S"..
jmp (a0) * jump into the game!
cnop 0,4
RealLoadDOSFile:
move.l a1,a4
move.l a0,d1
move.l #MODE_OLDFILE,d2 * open mode
move.l _DOSBase,a6
jsr _LVOOpen(a6) * open file
move.l d0,d6 * save filehandle
beq.s err * open error result?
move.l d6,d1 * filehandle
move.l a4,d2 * buffer
move.l #901120,d3 * l = length read
jsr _LVORead(a6) * call Read/Write
move.l d0,d2 * save read length
beq.s err
move.l d6,d1 * filebuffer
jsr _LVOClose(a6) * Close File
moveq #0,d0
rts
err: moveq #-1,d0
rts
bad_file: move.w #$f00,$dff180 * red flash of screen..
moveq #5,d0 * exit to dos.. (warn)
rts
_DOSBase dc.l 0
DOSName: dc.b 'dos.library',0
even
chipload.txt: dc.b 'chipram.exe',0
even
disk1.txt: dc.b 'total:total1',0
disk2.txt: dc.b 'total:total2',0
disk3.txt: dc.b 'total:total3',0
cnop 0,4
fastload: movem.l d0-a6,-(sp)
moveq #0,d0 * d0.w = disk to load from
bsr.b LoadDOSFile
movem.l (sp)+,d0-a6
movem.l d0-a6,-(sp)
moveq #1,d0 * d0.w = disk to load from
bsr.b LoadDOSFile
movem.l (sp)+,d0-a6
movem.l d0-a6,-(sp)
moveq #2,d0 * d0.w = disk to load from
bsr.b LoadDOSFile
movem.l (sp)+,d0-a6
moveq #0,d0
rts
* FASTRAM AmigaDOSFile Loader
* ---------------------------
* $Inputs: a0.l = filename
* a1.l = load buffer
* d0.w = number of disk to load from..
*
* $Outputs: d0.l = resultcode
*
error = 0 * 0-1 (.W)
disk_number = 1 * 1-2 (.W)
load_address = 2 * 2-6 (.L)
LoadBase: bra.b LoadDOSFile * 00 jump table..
bra.w InitDOSLoad * 01
cnop 0,4 * quad aligned..
LoadDOSFile: movem.l d2-d7/a0-a4/a6,-(a7)
move.l a0,a6
move.l a1,a5
move.l a5,-(sp)
bsr.b Find_file
move.l (sp)+,d1
sub.l a5,d1
moveq #0,d0 * d0.l = result code..
move.b (a2),d0
neg.l d1 * d1.l = load length..
movem.l (a7)+,d2-d7/a0-a4/a6
rts
cnop 0,4
Find_file lea variables(pc),a2
move.b d0,disk_number(a2)
move.l a5,load_address(a2)
clr.b (a2)
move.l blockbuff_ptr(pc),a0 * get disk's root dir.
move.w #880,d0
bsr.w Get_block
tst.b (a2)
bne.w file_eror
find_files_root_dir_loop
move.l a6,a4
moveq #0,d0
dir_loop move.b (a4),d7 * find file's root dir
beq.s root_dir
cmpi.b #"/",d7 * and get length of subdir name
beq.s oblique * if required.
addq.w #1,a4
addq.w #1,d0
bra.b dir_loop
cnop 0,4
oblique move.w d0,d7 * d0 = dir name length
move.w d0,d6
subq.w #1,d7
bsr.w hash_name * hash dir name into d0
move.l $18(a0,d0.w*4),d0 * header block for this hash
beq.w file_not_found
get_dir_header bsr.w Get_block
tst.b (a2)
bne.w file_eror
bsr.w compare_names
tst.w d7
beq.s next_in_chain
addq.w #1,a4
move.l a4,a6
bra.b find_files_root_dir_loop
cnop 0,4
next_in_chain move.l $1f0(a0),d0
bne.b get_dir_header
bra.b file_not_found
cnop 0,4
root_dir move.w d0,d7 * length of file name
move.w d0,d6
subq.w #1,d7
bsr.b hash_name
move.l $18(a0,d0.w*4),d0 * header block number for this hash
beq.b file_not_found
get_header bsr.w Get_block
tst.b (a2)
bne.b file_eror
bsr.w compare_names
tst.w d7
bne.s correct_file_header
move.l $1f0(a0),d0 * any more in hash chain?
bne.b get_header
bra.b file_not_found
cnop 0,4
correct_file_header
cmpi.l #-3,$1fc(a0) * make sure its a file header
beq.s file_header
move.b #2,(a2) * not a file header-error
bra.b file_eror
cnop 0,4
file_header move.l load_address(a2),a5
move.l $144(a0),d6 * length of file.
subq.l #1,d6
transfer_loop move.l $10(a0),d0 * next block location
beq.b file_not_found
bsr.w Get_block
tst.b (a2)
bne.b file_eror
lea $18(a0),a3 * 1st data longword in dos_block
moveq #(488/4)-1,d7
make_file subq.l #4,d6
bmi.s last_bytes
move.l (a3)+,(a5)+
dbf d7,make_file
bra.b transfer_loop
cnop 0,4
last_bytes addq.w #4,d6
lb_loop move.b (a3)+,(a5)+
dbf d6,lb_loop
rts
cnop 0,4
file_not_found move.b #3,(a2) * file not found-error
file_eror rts
cnop 0,4
hash_name move.l a6,a3
hash_loop moveq #0,d2 * hash file name at a6
move.b (a3)+,d2 * length-1 in d7.
cmpi.b #$60,d2
bls.s capital
cmpi.b #$7a,d2
bhi.s capital
subi.b #$20,d2
capital mulu #13,d0
add.l d2,d0
andi.l #$7ff,d0
dbf d7,hash_loop
divu #72,d0
swap d0 * d0=hash number
rts
cnop 0,4
compare_names moveq #0,d7
cmp.b $1b0(a0),d6 * d6=length of name being tested
bne.s name_fail
move.w d6,d5
move.l a6,a3
lea $1b1(a0),a5
subq.w #1,d5
comp_loop move.b (a3)+,d1 * Case desensitize filename
move.b (a5)+,d2 * compare.
andi.b #$df,d1
andi.b #$df,d2
cmp.b d1,d2
dbne d5,comp_loop
tst.w d5
bpl.s name_fail
moveq #1,d7
name_fail rts
* a0.l block buffer
* d0.w block number required ($0 - $6df)
disktable: dc.l 901120*0 * disk 0
dc.l 901120*1 * disk 1
dc.l 901120*2 * disk 2
dc.l 901120*3 * disk 3
cnop 0,4
Get_block movem.l a0-a6/d0-d7,-(a7)
andi.l #$ffff,d0
cmpi.w #$6df,d0 * check range
bls.b blk_in_range
move.b #1,(a2)
bra.w No_reload
cnop 0,4
blk_in_range: move.w d0,d1
swap d0
clr.w d0
swap d0
mulu #512,d0
move.l a0,a1
moveq #0,d2
move.b disk_number(a2),d2
add.w d2,d2
add.w d2,d2
move.l diskdata_ptr(pc),a0 * disk base
add.l disktable(pc,d2.w),a0 * offset to correct disk..
add.l d0,a0 * offset to correct position..
nop ;make copy on longword ...
movem.l (a0)+,d1-d7/a2-a6 * get data into regs
movem.l d1-d7/a2-a6,(a1) * push it into memory..
movem.l (a0)+,d1-d7/a2-a6 * get data into regs
movem.l d1-d7/a2-a6,48*1(a1) * push it into memory..
movem.l (a0)+,d1-d7/a2-a6 * get data into regs
movem.l d1-d7/a2-a6,48*2(a1) * push it into memory..
movem.l (a0)+,d1-d7/a2-a6 * get data into regs
movem.l d1-d7/a2-a6,48*3(a1) * push it into memory..
movem.l (a0)+,d1-d7/a2-a6 * get data into regs
movem.l d1-d7/a2-a6,48*4(a1) * push it into memory..
movem.l (a0)+,d1-d7/a2-a6 * get data into regs
movem.l d1-d7/a2-a6,48*5(a1) * push it into memory..
movem.l (a0)+,d1-d7/a2-a6 * get data into regs
movem.l d1-d7/a2-a6,48*6(a1) * push it into memory..
movem.l (a0)+,d1-d7/a2-a6 * get data into regs
movem.l d1-d7/a2-a6,48*7(a1) * push it into memory..
movem.l (a0)+,d1-d7/a2-a6 * get data into regs
movem.l d1-d7/a2-a6,48*8(a1) * push it into memory..
movem.l (a0)+,d1-d7/a2-a6 * get data into regs
movem.l d1-d7/a2-a6,48*9(a1) * push it into memory..
movem.l (a0)+,d1-d7/a2 * get data into regs
movem.l d1-d7/a2,48*10(a1) * push it into memory..
No_reload movem.l (a7)+,a0-a6/d0-d7
rts
InitDOSLoad: lea diskdata_ptr(pc),a2
move.l a0,(a2)
move.l a1,blockbuff_ptr-diskdata_ptr(a2)
rts
diskdata_ptr: ds.l 1
blockbuff_ptr ds.l 1
variables ds.b 8
section fastmemblock,bss_f * force into fastram!
blockmem: ds.b 512
diskdata: ds.b 901120*3 * 3 disks of fastram
* buffers