knightmare-test.asm (13,612 bytes)
2009-09-04 22:28
;*-------------------------------------------------------------------
; :program. knightmare.asm
; :Contents. Slave for "Knightmare" from Mindscape
; :Author. Tony McGarry and Tom Meades
; :Original. v1
; :Version. $Id: Knightmare.asm 1.0 95.09.2008 18:00:00 Tom Exp Tom $
; :History. 23.07.1999 orignal slave by Tony McGarry
; 25.02.2008 slave resourcing started by Tom Meades
; :Requires. -
; :Copyright. Public Domain
; :Language. 68000 Assembler
; :Translator. Devpac 3.14, Barfly 2.9
; :To Do. Support my english version of knightmare. Different
; : RattDos file to patch all other files the same.
;-------------------------------------------------------------------*
INCDIR Includes:
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
;================================================================
CHIPMEMSIZE = $80000
FASTMEMSIZE = $81000
NUMDRIVES = 1
WPDRIVES = %0000
;================================================================
BASEMEM = CHIPMEMSIZE
EXPMEM = FASTMEMSIZE
;================================================================
_base SLAVE_HEADER ;ws_Security + ws_ID
dc.w 10 ;ws_Version
dc.w WHDLF_NoError ;ws_Flags
dc.l BASEMEM ;ws_BaseMemSize
dc.l 0 ;ws_ExecInstall
dc.w ws_gameloader-_base ;ws_GameLoader
dc.w _data-_base ;ws_CurrentDir
dc.w 0 ;ws_DontCache
_keydebug dc.b $58 ;ws_keydebug
_exitkey dc.b $59 ;ws_keyexit
_expmem dc.l EXPMEM ;ws_ExpMem
dc.w _name-_base ;ws_name
dc.w _copy-_base ;ws_copy
dc.w _info-_base ;ws_info
;================================================================
IFD BARFLY
DOSCMD "DATE >T:date"
ENDC
_data dc.b "data",0
_name dc.b "Knightmare",0
_copy dc.b "1991 Mindscape",0
_info dc.b "Installed by Tony McGarry and Tom Meades",10
dc.b "Version 1.1 "
IFD BARFLY
INCBIN "T:date"
ENDC
dc.b 0
even
;====================================================================
START ; A0 = Resident loader
;====================================================================
ws_gameloader
LEA (_resload,PC),A1
MOVE.L A0,(A1)
MOVEA.L A0,A5
LEA (_rattdos_par,PC),A0
MOVE.L (_expmem,PC),D0
MOVE.L D0,(8,A0)
LEA (_rattdos_name,PC),A0 ;RaTtDOS $0138-$1137
LEA ($138).L,A1 ;RaTtDos Base
JSR (resload_LoadFile,A5)
LEA (_knightdir1_name,PC),A0 ;KnightDir1
MOVEA.L (_expmem,PC),A1
ADDA.L #$80000,A1 ;KnightDir1 offset
JSR (resload_LoadFile,A5)
LEA (_knightdir2_name,PC),A0 ;KnightDir2
MOVEA.L (_expmem,PC),A1
ADDA.L #$80400,A1 ;KnightDir2 offset
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 #$80800,A1 ;SaveDir offset
JSR (resload_LoadFile,A5)
;====================================================================
;patch RatTDos
LEA (_addrlist,PC),A2
LEA (_addrlistptr,PC),A0
MOVE.L A2,(A0)
MOVEA.L (A2)+,A0
MOVE.W #$4EF9,(A0)+ ; replace with jump instruction
PEA (_loadfile_routine,PC)
MOVE.L (SP)+,(A0)
MOVE.W #$4E75,($148).L ; replace with jump instruction at RaTtDOS base + $10
MOVEA.L (A2)+,A0
MOVE.W #$4EF9,(A0)+ ; replace with jump instruction
PEA (_savegame_routine,PC)
MOVE.L (SP)+,(A0)
MOVEA.L (A2)+,A0
MOVE.W #$4EF9,(A0)+ ; replace with jump instruction
PEA (_unknown_routine,PC)
MOVE.L (SP)+,(A0)
MOVEA.L (A2)+,A0
MOVE.W #$4E75,(A0) ;replace with rts instruction
MOVEA.L (A2)+,A0
MOVE.L #$70004E75,(A0) ; move rts instruction
MOVEA.L (A2)+,A0
MOVE.W #$4EF9,(A0)+ ; replace with jump instruction
PEA (_get_savedir_address,PC)
MOVE.L (SP)+,(A0)
MOVEA.L (A2)+,A0
MOVE.W #$4E75,(A0) ; replace with rts instruction
MOVEA.L (A2)+,A0
MOVE.W #$4E75,(A0) ; replace with rts instruction
LEA ($80000).L,A4 ; dir1_offset
LEA (-4,A4),SP
MOVE.L SP,USP
LEA ($138).L,A6
MOVE.L A6,(0).W
MOVE.L A6,(4).W
;stop dma channels, disable interrupts and interrupt requests
LEA (_custom).L,A5
MOVE.W #$7FFF,(dmacon,A5)
MOVE.W #$7FFF,(intena,A5)
MOVE.W #$7FFF,(intreq,A5)
;Initalise 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 #$8380,(dmacon,A5) ; DMAF_SETCLR|DMAF_MASTER|DMAF_RASTER|DMAF_COPPER
MOVE.W #$C070,(intena,A5) ; INTF_SETCLR|INTF_INTEN|INTF_BLIT|INTF_VERTB|INTF_COPER
; RATtDOS calls, not examined further
call_rattdos
MOVEA.L #$1138,A0
LEA (_rattdos_par,PC),A1
JSR ($68,A6) ; RATtDOS $68
MOVE.W #15,D1
JSR (4,A6) ; RaTtDOS $04
LEA (-$1570,A4),A0
MOVE.L A0,D0
JSR (8,A6) ; RaTtDOS $08
LEA (-$4870,A4),A0
MOVE.L A0,D0
JSR (12,A6) ; RaTtDOS $0C
MOVEQ #6,D0
JSR ($74,A6) ; RaTtDOS $74
MOVEQ #4,D0
MOVE.L #$1384,D5
MOVE.L D5,D1
JSR ($6C,A6) ; RaTtDOS $6C
MOVE.L D0,-(SP)
TST.L D0
BEQ.W _debug
MOVEA.L D0,A0
MOVEM.L (A0),D0/D2-D4/D6/D7/A1-A4
LEA (_bootfile_name,PC),A5 ; bootfile name
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) ; RaTtDOS $1C
MOVE.W #$4EF9,($130,A0) ; replace with jump instruction
PEA (_push_functions,PC)
MOVE.L (SP)+,($132,A0)
MOVE.W #$4EF9,($1BC4).L ; replace with jump instruction
PEA (_patch_federation,PC)
MOVE.L (SP)+,($1BC6).L
RTS
;============================================================================
;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 .loadfile
BSR.W _alter_savegamename ; a0 = real name of savegame
BSR.W _get_savegamesize ; d0 = size of file
TST.L D0
BMI.W .endload
.loadfile 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
;============================================================================
;savegame routine a0=address a1=filename
_savegame_routine MOVEM.L D1-D7/A0-A6,-(SP)
EXG A1,A0
CMPI.B #$53,(A0)
BNE.W .endsave
BSR.W _update_savedir
BSR.W _alter_savegamename ; a0 = real name of savegame
LEA (5,A0),A0 ; skip first 5 characters
EXG D1,D0 ; d0 = file size
MOVEA.L (_resload,PC),A2
JSR (resload_SaveFile,A2)
MOVEM.L (SP)+,D1-D7/A0-A6
MOVEQ #0,D0
.endsave RTS
;============================================================================
; a0= filename
_update_savedir MOVEM.L D0/D1/A0-A2,-(SP)
MOVE.B (5,A0),D0
CMP.B #'8',D0
BGT.W .largeid
SUBI.B #'1',D0 ; d0 = number of the save
MOVE.L #$18,D1
BRA.W .calcpos
.largeid SUBI.B #$41,D0 ; d0: (Greater than '8')
MOVEQ #0,D1
.calcpos ANDI.L #$FF,D0
MULU.W #$30,D0 ; d0 = number of characters
ADD.L D1,D0 ; +18$ if savegame <= '8'
MOVEA.L (_expmem,PC),A2
MOVEA.L A2,A1 ; a1 = expmem
ADDA.L #$808BC,A2 ; savedir_offset + $BC, a2 = save games names
ADDA.L D0,A2 ; forward to right save
MOVE.L #0,(A2) ; zero 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
ADDA.L #$80800,A1 savedir offset 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 #$80800,A0 ; savedir offset
RTS
;=============================================================================
_unknown_routine 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 #$80000,D1 ; dir1 offset
CMPI.B #'S',(A0)
BNE.W .notsavedir
ADDI.L #$800,D1 ; savedir offset - dir1 offset
BRA.W .notdisk2
.notsavedir CMPI.B #$32,(4,A0)
BNE.W .notdisk2
ADDI.L #$400,D1 ; dir2 offset - dir1 offset
.notdisk2 MOVE.W (A3)+,D0
MOVE.L D1,(A4,D0.W) ; disk number
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
;============================================================================
_alter_savegamename CMPI.B #'1',(5,A0)
BLT.W .finished
CMPI.B #'8',(5,A0)
BGT.W .finished
MOVE.B (5,A0),D0
LEA (_savegame_name,PC),A0
MOVE.B D0,(13,A0)
.finished RTS
;==============================================================
; Input a0= name of file
; Output d0= size of file
_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 .finished
MOVEQ #-2,D0
.finished MOVEM.L (SP)+,A0/A1
RTS
;==============================================================
_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)
MOVEM.L D0-D7/A0-A6,-(SP)
MOVEA.L (_resload,PC),A2
JSR (resload_FlushCache,A2) ; Flush caches
MOVEM.L (SP)+,D0-D7/A0-A6
RTS
;==============================================================
_patch_federation MOVEM.L D0-D7/A0-A6,-(SP)
MOVE.L #$F190,D0 ;1.4 $F0FE
MOVE.W #$602E,(A3,D0.L) ;1.4 $6030
MOVEM.L (SP)+,D0-D7/A0-A6
JSR ($20,A3)
BRA.W _debug
;==============================================================
_debug PEA TDREASON_DEBUG
MOVE.L (_resload,PC),-(SP)
ADDI.L #resload_Abort,(SP) ; address of resload_Abort
RTS
;===========================================
_resload dc.l 0 ;address of resident loader
_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
;===========================================
; parameter list to RaTtDOS call $68
_rattdos_par
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
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 ; wait 82,254
dc.w color,$0004 ; cmove $0004,color
dc.w $53FF,$FFFE ; wait 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,$0004 ; cmove $0004,color
dc.w $FDFF,$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 ;1.4 $2AA
dc.l $000007B2 ;1.4 $7BA
dc.l $000003D6 ;1.4 $3DE
dc.l $000002DA ;1.4 $2D6
dc.l $00000386 ;1.4 $38E
dc.l $0000025A
dc.l $000010AA ;1.4 10B0
dc.w $0014
dc.w $003A
dc.l $00000414 ;1.4 $41C
dc.w $004E