
;---------------------------------------------------------------------------
;       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         ;initialise the scrolling text
               STA MESS
               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         ;reset the message
               STA 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 !



