Knightmare.asm (12,147 bytes)
2009-05-01 18:09
INCDIR Include:
INCLUDE whdload.i
INCLUDE whdmacros.i
INCLUDE hardware/custom.i
INCLUDE hardware/intbits.i
INCLUDE hardware/dmabits.i
IFD BARFLY
OUTPUT "knightmare.slave"
BOPT O+ ; enable optimizing
BOPT OG+ ; enable optimizing
BOPT ODd- ; disable mul optimizing
BOPT ODe- ; disable mul optimizing
BOPT w4- ; disable 64k warnings
SUPER
ENDC
_rattdos_base equ $00000138
_dir1_offset equ $00080000
_dir2_offset equ $00080400
_savedir_offset equ $00080800
_cmd_jmp equ $4EF9
_cmd_rts equ $4E75
_cmd_moveqrts equ $70004E75
DISABLE_ALL equ $7FFF
ENABLE_DMA equ DMAF_SETCLR|DMAF_MASTER|DMAF_RASTER|DMAF_COPPER
ENABLE_INT equ INTF_SETCLR|INTF_INTEN|INTF_BLIT|INTF_VERTB|INTF_COPER
;============================================================================
_base SLAVE_HEADER ; ws_Security + ws_ID
dc.w 10 ; ws_Version
dc.w WHDLF_NoError ; ws_Flags
dc.l $80000 ; ws_BaseMemSize
dc.l 0 ; ws_ExecInstall
dc.w _start-_base ; ws_GameLoader
dc.w _dir-_base ; ws_CurrentDir
dc.w 0 ; ws_DontCache
dc.b $58 ; ws_keydebug (F9)
dc.b $59 ; ws_keyexit (F10)
_expmem dc.l $81000 ; ws_ExpMem
dc.w slv_name-_base ; ws_name
dc.w slv_copy-_base ; ws_copy
dc.w slv_info-_base ; ws_info
_dir dc.b 'data',0
slv_name dc.b 'Knightmare',0
slv_copy dc.b '1991 Mindscape',0
slv_info dc.b 'Installed by Tony M 17.07.99',10
dc.b 'Adapted to version 1.5 by Rixa',0 ; Rixa: added
even
;============================================================================
_start lea (_resload,pc),a1
move.l a0,(a1)
movea.l a0,a5
lea (lbL000480,pc),a0
move.l (_expmem,pc),d0
move.l d0,(8,a0)
lea (_rattdos_name,pc),a0 ; RaTtDOS $0138-$1137
lea _rattdos_base,a1
jsr (resload_LoadFile,a5)
lea (_knightdir1_name,pc),a0 ; KnightDir1
movea.l (_expmem,pc),a1
adda.l #_dir1_offset,a1
jsr (resload_LoadFile,a5)
lea (_knightdir2_name,pc),a0 ; KnightDir2
movea.l (_expmem,pc),a1
adda.l #_dir2_offset,a1
jsr (resload_LoadFile,a5)
lea (_savedir_name,pc),a0 ; SaveDir
move.l a0,-(sp)
jsr (resload_GetFileSize,a5)
movea.l (sp)+,a0
tst.l d0
bne.w .saveexists
lea (_emptydir_name,pc),a0 ; SaveDir.Empty
.saveexists movea.l (_expmem,pc),a1
adda.l #_savedir_offset,a1
jsr (resload_LoadFile,a5)
;============================================================================
; Patch RATT-DOS
lea (_addrlist,pc),a2
lea (_addrlistptr,pc),a0
move.l a2,(a0)
movea.l (a2)+,a0
move.w #_cmd_jmp,(a0)+
pea (_loadfile_routine,pc)
move.l (sp)+,(a0)
move.w #_cmd_rts,_rattdos_base+$10
movea.l (a2)+,a0
move.w #_cmd_jmp,(a0)+
pea (_savegame_routine,pc)
move.l (sp)+,(a0)
movea.l (a2)+,a0
move.w #_cmd_jmp,(a0)+
pea (_routineX,pc)
move.l (sp)+,(a0)
movea.l (a2)+,a0
move.w #_cmd_rts,(a0)
movea.l (a2)+,a0
move.l #_cmd_moveqrts,(a0)
movea.l (a2)+,a0
move.w #_cmd_jmp,(a0)+
pea (_get_savedir_address,pc)
move.l (sp)+,(a0)
movea.l (a2)+,a0
move.w #_cmd_rts,(a0)
movea.l (a2)+,a0
move.w #_cmd_rts,(a0)
; USP to grow down from first 512K
lea _dir1_offset,a4
lea (-4,a4),sp
move.l sp,usp
; Use rattdos as boot vector(?) and exec base?
lea _rattdos_base,a6
move.l a6,(0).w
move.l a6,(4).w
; stop dma channels, disable interrupts and interrupt
; requests
lea _custom,a5
move.w #DISABLE_ALL,(dmacon,a5)
move.w #DISABLE_ALL,(intena,a5)
move.w #DISABLE_ALL,(intreq,a5)
; Initialize interrupt autovectors:
; Level 1: $000000DC, Level 2-7: $000000D4
init_autovectors
moveq #0,d0
moveq #0,d1
move.w #$D4,d0
move.w #$DC,d1
lea ($64).w,a0
move.l d1,(a0)+
moveq #5,d2
.copyloop move.l d0,(a0)+
dbra d2,.copyloop
; Copy Level 2-7 interrupt handler to address $000000D4 and
; copperlist to $000000DE.
setup_handler_and_copper
lea ($D4).w,a0
lea (_interrupt_handler,pc),a1
moveq #$14,d0
.copyloop move.l (a1)+,(a0)+
dbra d0,.copyloop
; Set copperlist and jump to it
move.l #$DE,(cop1lc,a5)
clr.w (copjmp1,a5)
; Enable DMA and interrupts ($8380,$C070)
move.w #ENABLE_DMA,(dmacon,a5)
move.w #ENABLE_INT,(intena,a5)
; RATT-DOS calls, not examined further
call_rattdos
MOVEA.L #$1138,A0
LEA (lbL000480,PC),A1
JSR ($68,A6) ; RATT-DOS $68
MOVE.W #15,D1
JSR (4,A6) ; RATT-DOS $04
LEA (-$1570,A4),A0
MOVE.L A0,D0
JSR (8,A6) ; RATT-DOS $08
LEA (-$4870,A4),A0
MOVE.L A0,D0
JSR (12,A6) ; RATT-DOS $0C
MOVEQ #6,D0
JSR ($74,A6) ; RATT-DOS $74
MOVEQ #4,D0
MOVE.L #$1384,D5
MOVE.L D5,D1
JSR ($6C,A6) ; RATT-DOS $6C
MOVE.L D0,-(SP)
TST.L D0
BEQ.W _debugit
MOVEA.L D0,A0
MOVEM.L (A0),D0/D2-D4/D6/D7/A1-A4
LEA (_bootfile_name,PC),A5
MOVEQ #7,D5
.copyloop MOVE.L (A5)+,(A0)+
DBRA D5,.copyloop
MOVEA.L (SP),A0
MOVE.L D5,D1
MOVEA.L A0,A5
MOVEA.L A0,A1
JSR ($1C,A6) ; RATT-DOS $1C
MOVE.W #_cmd_jmp,($130,A0)
PEA (_push_functions,PC)
MOVE.L (SP)+,($132,A0)
MOVE.W #_cmd_jmp,($1BC4).L
PEA (_patch_federation,PC)
MOVE.L (SP)+,($1BC6).L
RTS
;============================================================================
; Apparently a loader routine.
; a0 = address
; a1 = filename
_loadfile_routine
movem.l d1-d7/a0-a6,-(sp)
exg a1,a0
cmpi.b #'S',(a0) ; is it a savegame
bne.w .loadit
bsr.w _alter_savegamename ; a0 = real name of savegame
bsr.w _get_savegamesize ; d0 = size of file
tst.l d0
bmi.w .endload ; (or negative for error)
.loadit addq.l #5,a0 ; Skip first 5 letters
movea.l (_resload,pc),a2
jsr (resload_LoadFile,a2)
.endload movem.l (sp)+,d1-d7/a0-a6
rts
;============================================================================
; Apparently a savegame routine.
; a0 = address
; a1 = filename
_savegame_routine
movem.l d1-d7/a0-a6,-(sp)
exg a1,a0 ; a1 = address
cmpi.b #'S',(a0)
bne.w .endsave
bsr.w _update_savedir
bsr.w _alter_savegamename ; a0 = real name of savegame
lea (5,a0),a0 ; Skip first 5 letters
exg d1,d0 ; d0 = size
movea.l (_resload,pc),A2
jsr (resload_SaveFile,A2)
movem.l (sp)+,d1-d7/a0-a6
moveq #0,d0
.endsave rts
;============================================================================
; Write name of the save file into the directory,
; called from _savegame_routine
; a0 - filename
_update_savedir
movem.l d0/d1/a0-a2,-(sp)
move.b (5,a0),d0
cmp.b #'8',d0 ; DEBUG: strange instruction;
; Barfly does a cmip.b
bgt.w .largeidx
subi.b #'1',d0 ; d0 - number of save
move.l #$18,d1
bra.w .calcpos
.largeidx subi.b #'A',d0 ; d0: (greater than '8')
moveq #0,d1
.calcpos andi.l #$FF,d0
mulu.w #$30,d0 ; d0: number of chars
add.l d1,d0 ; +$18 if savegame <= '8' ?
movea.l (_expmem,pc),a2
movea.l a2,a1 ; a1: expmem
adda.l #_savedir_offset+$BC,a2 ; a2: savegame names
adda.l d0,a2 ; a2: forward to right save
move.l #0,(a2) ; zero the previous entry
move.l #0,(4,a2)
move.l #0,(8,a2)
move.b #0,(12,a2)
adda.l #5,a0 ; copy the name
.copyloop move.b (a0)+,d0
beq.w .saveindex
move.b d0,(a2)+
bra.w .copyloop
.saveindex lea (_savedir_name,pc),a0 ; name
adda.l #_savedir_offset,a1 ; address
move.l #$400,d0 ; size
movea.l (_resload,pc),a2
jsr (resload_SaveFile,a2)
movem.l (sp)+,d0/d1/a0-a2
rts
;============================================================================
_get_savedir_address
movea.l (_expmem,pc),a0
adda.l #_savedir_offset,a0
rts
;============================================================================
; I don't really know or remember what this does
_routineX
movem.l d1-d7/a1-a6,-(sp)
movea.l (_addrlistptr,pc),a3
lea ($20,a3),a3
movea.l (a3)+,a4
move.l (_expmem,pc),d1
addi.l #_dir1_offset,d1
cmpi.b #'S',(a0)
bne.w .notsavedir
addi.l #(_savedir_offset-_dir1_offset),d1
BRA.W .notdisk2
.notsavedir cmpi.b #'2',(4,a0)
bne.w .notdisk2
addi.l #(_dir2_offset-_dir1_offset),d1
.notdisk2 move.w (a3)+,d0
move.l d1,(a4,d0.w) ; disk
lea (5,a0),a0 ; filename
move.w (a3)+,d0
move.l a0,(a4,d0.w)
movea.l (a3)+,a1
jsr (a1) ; function
move.w (a3),d0
movea.l (a4,d0.w),a0 ; result address?
moveq #0,d0
movem.l (sp)+,d1-d7/a1-a6
rts
;============================================================================
; replace filename ".....[1-8].*" with "SAVE:SaveGame[1-8]"
; INPUTS: a0 - original filename
; OUTPUTS: a0 - modified filename
; d0 - number of save
;
; called from _loadfile_routine and _savegame_routine
_alter_savegamename
cmpi.b #'1',(5,a0)
blt.w .done
cmpi.b #'8',(5,a0)
bgt.w .done
move.b (5,a0),d0
lea (_savegame_name,pc),a0
move.b d0,(13,a0)
.done rts
;============================================================================
; INPUTS: a0 - name of file (with 5 characters of whatever in beginning)
; OUTPUTS: d0 - size of file
;
; called from _loadfile_routine
_get_savegamesize
movem.l a0/a1,-(sp)
lea (5,a0),a0
movea.l (_resload,pc),a2
jsr (resload_GetFileSize,a2)
tst.l d0
bne.w .done
moveq #-2,d0 ; error
.done movem.l (sp)+,a0/a1
rts
;============================================================================
; The addresses pushed to stack seem to be jumped to with rts. Don't know of
; the first, but the rest are in fed_Bootfile which is loaded to $1148-$24c8.
;
; Minor tweak; FlushCache should not litter so not saving all of d0-d7/a0-a6
; just for it
_push_functions
move.l #$F857B3DF,-(sp)
move.l #$1BB8,-(sp)
move.l #$22D8,-(sp)
move.l #$1BEC,-(sp)
move.l #$1B5E,-(sp)
move.l #$24BC,-(sp)
move.l #$1B44,-(sp)
move.l a2,-(sp) ; Rixa: saving just a2
movea.l (_resload,pc),a2
jsr (resload_FlushCache,a2)
move.l (sp)+,a2 ; Rixa: restoring just a2
rts
;============================================================================
_patch_federation
move.l d0,-(sp)
MOVE.L #$F190,D0 ; Rixa: changed from $F0FE
MOVE.W #$602E,(A3,D0.L) ; Rixa: changed from $6030
move.l (sp)+,d0
JSR ($20,A3)
BRA.W _debugit
;============================================================================
_debugit pea TDREASON_DEBUG
_exit_whdload move.l (_resload,pc),-(sp)
addi.l #resload_Abort,(sp) ; address of resload_Abort
rts ; jump to it
;============================================================================
_resload dc.l 0
_rattdos_name dc.b 'RaTtDOS',0
_knightdir1_name dc.b 'KnightDir1',0
_knightdir2_name dc.b 'KnightDir2',0
_savedir_name dc.b 'SaveDir',0
_emptydir_name dc.b 'SaveDir.Empty',0
_savegame_name dc.b 'SAVE:SaveGame0',0
_bootfile_name dc.b 'fed1:fed_BootFile',0
even
; given as parameter to RATT-DOS call $68
lbL000480 dc.l $80FF0000
dc.l $32320000
dc.l 0
dc.l $80000
dc.l 0
dc.l $80000
dc.l 0
dc.l 0
; interrupt handler is copied to address $D4. Copperlist ends up at $DE.
_interrupt_handler
move.w #$3FFF,_custom+intreq
rte
_copperlist dc.w bplcon0,$0200 ; cmove $0200, bplcon0
dc.w $02FF,$FFFE ; cwait 2,254
dc.w color,$000D ; cmove $000D, color
dc.w $51FF,$FFFE ; cwait 81,254
dc.w color,$0008 ; cmove $0008, color
dc.w $52FF,$FFFE ; cwait 82,254
dc.w color,$0004 ; cmove $0004, color
dc.w $53FF,$FFFE ; cwait 83,254
dc.w color,$0000 ; cmove $0000, color
dc.w $FCFF,$FFFE ; cwait 252,254
dc.w color,$0004 ; cmove $0004, color
dc.w $FDFF,$FFFE ; cwait 253,254
dc.w color,$0008 ; cmove $0008, color
dc.w $FEFF,$FFFE ; cwait 254,254
dc.w color,$000D ; cmove $000D, color
dc.w $FFFF,$FFFE ; cwait 255,254
dc.w color,$000F ; cmove $000F, color
dc.w $FFFF,$FFFE ; cwait 255,254
_addrlistptr dc.l $00000000
_addrlist dc.l $0000024E
dc.l $00000246
dc.l $000002AE ; Rixa: moved from $02AA
dc.l $000007B2 ; Rixa: moved from $07BA
dc.l $000003D6 ; Rixa: moved from $03DE
dc.l $000002DA ; Rixa: moved from $02D6
dc.l $00000386 ; Rixa: moved from $038E
dc.l $0000025A
dc.l $000010AA ; Rixa: moved from $10B0
dc.w $0014
dc.w $003A
dc.l $00000414 ; Rixa: moved from $041C
dc.w $004E