;*------------------------------------------------------------------- ; :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