;--------------------------------------------------------------------------- ; Freeload cassette loader program v5.0, last update 24.12.1988 ; ; Cassette loader for Rainbow Isands ; ; Copyright 1984-1989, Paul Hughes ; ; Ported to DASM 09/11/04 by Paulie. ;--------------------------------------------------------------------------- processor 6502 mac SKW ; 6510 SKW - Skip Word instruction dc.b $0c endm ;---- TRUE EQU 1 ;conditional stuff FALSE EQU 0 YES EQU TRUE NO EQU FALSE RESETVECS EQU NO ;should the IO vectors get reset GAMESTART EQU $080D ;game start here ONEVAL EQU $37 ;the value that DDR A is set to SCREENCOL EQU 0 ;screen colour when bitmap is on BORCUL EQU 0 ;border colour when bitmap is on LOAD_FLAG EQU 2 ;load in progress flag MESS EQU $FE ;indirect address of scrolling text FILE_COUNTER EQU $0100+3 ;which file we are up to MUSIC_TRIGGER EQU $0101+3 ;music triggering flag SCROLL_TRIGGER EQU $0102+3 ;scroll triggering flag SMOOTH_X EQU $0103+3 ;smooth x position for hardware STACK_LOAD EQU $0112 ;loader's position on stack REFRESH EQU $B4A3 ;Jon's sound refresh TUNE EQU $B43E ;Jon's tune initialise LOADER_MAX EQU $0C40 ;maximum address of loader ;---- seg code ORG $0800 START LDX #$FF ;reset the stack TXS INX STX $D020 ;screen & borders black STX $D021 STX FILE_COUNTER ;reset the file counter STX MUSIC_TRIGGER ;switch music off STX SCROLL_TRIGGER ;switch scrolling off STX SMOOTH_X ;reset smooth x position TXA BLANK_ATTR STA $D800,X ;blank the attributes STA $D900,X STA $DA00,X STA $DB00,X INX BNE BLANK_ATTR LDX #$27 SET_LINES LDA #1 STA $D800+23*40,X ;set attributes for scrolling LDA #7 STA $D800+22*40,X ;set attributes for dividers STA $D800+24*40,X LDA #$40 ;print dividers STA $0400+22*40,X STA $0400+24*40,X LDA #$20 STA $0400+23*40,X DEX BPL SET_LINES ;---- LOAD_D000 JSR CHECKSTOP LDX LOAD_FLAG ;$4000 relocating up to $D000 BEQ LOAD_D000 INX STX LOAD_FLAG JSR RELOCATE ;relocate code to $D000 ;---- JSR ANTIEXPERT ;check for the Expert cartridge JSR DUMP_STACK ;initialise the stack loader LDA #SCROLL_TEXT STA MESS+1 JSR SCROLL_ON ;switch the scroll on ;---- WAIT_FILES JSR MAIN_SYNC ;sync FREELOAD to flyback LDA MUSIC_TRIGGER BEQ NO_MUSIC JSR REFRESH ;play Jon's music if required NO_MUSIC LDA SCROLL_TRIGGER BEQ NO_SCROLL LDA #$C8 ;do block scroll if required STA $D016 JSR BLOCK_SCROLL NO_SCROLL JSR CHECKSTOP ;check for the tape being stopped JSR OVERLAP ;wait for any raster overlapping LDX LOAD_FLAG ;see if the file has loaded yet BEQ WAIT_FILES INX ;yes, reset the flag STX LOAD_FLAG LDX FILE_COUNTER LDA FILE_TRIGGERS,X ;see if anything is required to happen BEQ NO_TRIGGER ASL ;yes TAX LDA ROUT_LOOKUP,X ;do any routines required STA JUMPVEC_1+1 LDA ROUT_LOOKUP+1,X STA JUMPVEC_1+2 JUMPVEC_1 JSR $AAAA ;self modified NO_TRIGGER INC FILE_COUNTER ;bump the file counter JMP WAIT_FILES ;----------------------------------------------------------------------------- FILE_TRIGGERS dc.b 00 ;overload (A) dc.b 02 ;music (C) dc.b 00 ;colour ram (D) dc.b 00 ;screen colour (E) dc.b 01 ;bitmap (F) dc.b 03 ;code (G) dc.b 04 ;code (H) dc.b 00 ;code (I) dc.b 00 ;code (J) dc.b 05 ;overload (A) ROUT_LOOKUP dc.w ROUT_LOOKUP ;dummy dc.w BITMAP_ON ;01 (this also turns the scroll off) dc.w TUNE_ON ;02 dc.w BITMAP_OFF ;03 dc.w TUNE_OFF ;04 dc.w FIRE_UP_STACK ;05 dc.w SCROLL_ON ;06 dc.w SCROLL_OFF ;07 ;----------------------------------------------------------------------------- ;raster sync bits... MAIN_SYNC LDA $D012 ;wait for blanking period CMP #$10 BCC MAIN_SYNC RTS ;---- OVERLAP LDA $D012 ;check for raster overlap CMP #$E2 BCC OVERLAP ;i.e Jon's music taking too long ! LDA SCROLL_TRIGGER BEQ OVERLAP_2 JSR SMOOTH_SCROLL ;do smooth scroll if required OVERLAP_2 LDA $D012 CMP #$08 BCS OVERLAP_2 RTS ;----------------------------------------------------------------------------- CLEAR_BITMAP LDA #>$E000 ;clear out the Bitmap area STA $21 LDA #0 STA $20 TAY CLEARBM LDA #0 STA ($20),Y INC $20 BNE NO_CARRY INC $21 NO_CARRY LDA $20 CMP #<$FF40 BNE CLEARBM LDA $21 CMP #>$FF40 BNE CLEARBM LDA #SCREENCOL ;setup the Bitmap colours STA $D021 LDA #BORCUL STA $D020 RTS ;----------------------------------------------------------------------------- SMOOTH_SCROLL LDA #0 ;do the hardware x scroll ORA SMOOTH_X STA $D016 RTS ;---- BLOCK_SCROLL LDA SMOOTH_X ;alter the smooth X SEC SBC #2 AND #7 STA SMOOTH_X BCC DO_BLOCK RTS DO_BLOCK LDX #0 ;shunt line 23 across SHIFT_LINE LDA $0401+23*40,X STA $0400+23*40,X INX CPX #$27 BNE SHIFT_LINE LDY #0 PRINT_CHAR LDA (MESS),Y ;print the new message byte BEQ WRAP_MESS AND #$3F STA $0427+23*40 INC MESS BNE 1$ INC MESS+1 1$ RTS ;---- WRAP_MESS LDA #SCROLL_TEXT STA MESS+1 JMP PRINT_CHAR ;----------------------------------------------------------------------------- BITMAP_ON LDA #$C0 ;switch bitmap on STA $DD00 LDA #$3F STA $DD02 LDA #$28 ;colour @ $C800, bitmap @ $E000 STA $D018 LDA #$3B ;bitmap on STA $D011 LDA #$D8 ;multi colour on STA $D016 LDX #0 ;Copy up to colour ram FILL_COL LDA $4000,X STA $D800,X LDA $4100,X STA $D900,X LDA $4200,X STA $DA00,X LDA $4300,X STA $DB00,X INX BNE FILL_COL JMP SCROLL_OFF ;switch the scroll off ;----------------------------------------------------------------------------- BITMAP_OFF LDA #$97 ;switch the Bitmap off STA $DD00 LDA #$1B ;bitmap off STA $D011 LDA #$C8 ;multi colour off STA $D016 LDA #$D2 ;reset char and screen memory STA $D018 LDX #0 TXA BLACK_OUT STA $D800,X ;blank the attributes STA $D900,X STA $DA00,X STA $DB00,X STA $D021 INX BNE BLACK_OUT RTS ;----------------------------------------------------------------------------- SCROLL_ON LDA #1 ; STA SCROLL_TRIGGER ; RTS SKW ;----------------------------------------------------------------------------- SCROLL_OFF LDA #0 STA SCROLL_TRIGGER RTS ;----------------------------------------------------------------------------- TUNE_ON LDX #1 STX MUSIC_TRIGGER DEX JMP TUNE ;----------------------------------------------------------------------------- TUNE_OFF LDA #0 STA MUSIC_TRIGGER LDX #$18 ;clear SID chip CLR_SID STA $D400,X DEX BPL CLR_SID RTS ;----------------------------------------------------------------------------- FIRE_UP_STACK PLA PLA ;tidy the stack JSR DUMP_STACK ;re-dump the stack JMP STACK_LOAD ;fire-Up the stack loader. ;----------------------------------------------------------------------------- ; DUMP_STACK - Dumps data on the stack ; DUMP_STACK LDX #0 ; Copy final loader to the stack COPSTACK LDA START_STACK,X STA STACK_LOAD,X INX CPX #END_STACK-START_STACK BNE COPSTACK RTS ;----------------------------------------------------------------------------- ; STARTSTACK - Stack load controller for final files ; START_STACK LDX #1 ;2 final files to load WAIT_FILE LDA 1 ;check the C2N's stop key AND #$10 BEQ NO_STOP LDA #>$0C00 ;blast the memory ! STA $FC LDA #0 STA $FB TAY CLRLOOP STA ($FB),Y INY BNE CLRLOOP INC $FC BNE CLRLOOP NO_STOP LDY LOAD_FLAG BEQ WAIT_FILE INY STY LOAD_FLAG DEX BPL WAIT_FILE ;---- SEI ;stop the interrupts LDA $D016 ;reset screen X AND #$F8 STA $D016 LDA #$1B ;centralise Y STA $D011 LDA #$7F ;unlatch spurious NMI's STA $DC0D STA $DD0D LDA $DC0D LDA $DD0D LDA #ONEVAL STA 1 #IF RESETVECS=TRUE JSR $FD15 #ENDIF GAMEADDR JMP GAMESTART ;jump to the game END_STACK NOP ;----------------------------------------------------------------------------- CHECKSTOP LDA 1 ;check the C2N's stop key AND #$10 BEQ NOSTOP ;all clear LDA #>$0C00 STA $FC LDA #0 STA $FB TAY CLEAR STA ($FB),Y ;steam the memory if stopped INY BNE CLEAR INC $FC JMP CLEAR NOSTOP RTS ;exit ;------------------------------------------------------------------------- SCROLL_TEXT dc.b "NOW LOADING RAINBOW ISLANDS ... COPYRIGHT 1990, OCEAN " dc.b "SOFTWARE ... PROGRAMMED BY GRAFTGOLD LTD ... " dc.b "PLEASE NOTE THAT ALL THE LEVEL DATA IS ON SIDE 2 OF " dc.b "THIS CASSETTE ... WHEN THE PROGRAM PROMPTS YOU TO LOAD " dc.b "LEVEL ONE, ENSURE THAT YOU REWIND SIDE B BACK TO THE " dc.b "BEGINNING ... ",0 ;---- ;PAULS_MES dc.b "HELLO HACKER! PAUL H HERE AGAIN," ; dc.b "HAVE A NICE DAY !" ;------------------------------------------------------------------------- ; RELOCATE - Relocates code from $4000 to $D000 ; RELOCATE SEI LDA #$30 STA 1 ;relocate code LDY #0 LDX #$10 TLOP LDA $4000,Y TO STA $D000,Y INY BNE TLOP INC TLOP+2 INC TO+2 DEX BNE TLOP LDA #$35 STA 1 CLI LDA #$60 ;self modifying CLI to RTS STA $02D4 JMP $02A7 ;re-initialise the loader ;--------------------------------------------------------------------------- ; The all new "Intelligent" EXPERT detector Paul Hughes (27/10/1987) ; Stops V2.8 - V2.11 Expert software & new V3.0 with back-up RAM ZP EQU $FD ANTIEXPERT LDA #<$1000 STA ZP LDA #>$1000 STA ZP+1 HUNT LDY #0 GETABYTE LDA (ZP),Y STA TEMP ;test for a 5 Byte repetition INY CMP (ZP),Y BNE NEXT INY CMP (ZP),Y BNE NEXT INY CMP (ZP),Y BNE NEXT INY CMP (ZP),Y BNE NEXT LDA #<$1000 STA ZP ;checksum that repeated byte LDA #>$1000 STA ZP+1 LDY #0 COUNTIT LDA (ZP),Y CMP TEMP BEQ PLUSIT INY BNE COUNTIT JMP CHECKIT PLUSIT INC CHECKSUM INY BNE COUNTIT JMP CHECKIT NEXT LDA ZP ;check out a page of memory CMP #<$1100 BNE NODONE LDA ZP+1 CMP #>$1100 BNE NODONE JMP ALLOK NODONE INC ZP ;test next byte BNE NOC INC ZP+1 NOC JMP HUNT CHECKIT LDA CHECKSUM ;test the checksum CMP #140 BCS GOTYA ;speaks for itself (!) ALLOK RTS ;memory configured correctly ;---------------------------------------- GOTYA LDX #0 ;ooops!, take that Expert out TXA KILLMEM STA $0800,X ;play havoc with the memory !!!!! STA $0200,X STA $0300,X STA GAMEADDR+1 ;screw up the gamestart address STA GAMEADDR+2 STA $D020 STA $D021 INX BNE KILLMEM LDX #GOTYA-ANTIEXPERT-1 KILLTHIS STA ANTIEXPERT,X ;kill the Expert detector DEX BPL KILLTHIS SEI ;stop all interrupts LDA #35 ;cassette motor off, ROMS OUT STA 1 LDA #0 ;crack up ! STA $D020 STA $D021 HANG JMP HANG ;looks pretty infinite to me (!) TEMP dc.b 0 CHECKSUM dc.b $FF ;must start @ $FF ! ;---- ; CET == Conditional Error Trap - if the expression evaluated is true assembler aborts, echoing ; the given message. :PH ; CET @>LOADER_MAX," * WARNING * LOADER OVERLOADING $0C40 " #if . > LOADER_MAX ECHO " * WARNING * LOADER OVERLOADING $0C40 " END #endif ;---- ;----------------------------------------------------------------------------- ;The end, fini, that's all cock, thatsyalot, no more, terminate, STOP !