	.nolist		
	#include "ion.inc"
	.list		
#ifdef TI83P		
	.org progstart-2
	.db $BB,$6D

APD_BUF   = $86EC
MUL_HL = $4276

#else		
	.org progstart

APD_BUF   = $8265
MUL_HL = $4382

#endif		
		xor a	
		jr nc,Start
progdesc:	.db "SubHunt v1.4",0
AuthorTxt:
 .db "Programmed by:",0
 .db "Sam Heald",0
HighTxt:
 .db "HighScore:  "
HighName:
 .db "SAM",0

TEXT_MEM = APD_BUF+450

string = TEXT_MEM
boatx  = TEXT_MEM+6
boaty  = TEXT_MEM+7
numlb  = TEXT_MEM+8
numrb  = TEXT_MEM+9
score  = TEXT_MEM+10
Bcounter = TEXT_MEM+12  ;counter for bullet drop speed
BWLcounter = TEXT_MEM+13 ;delay after firing a bullet from left
BWRcounter = TEXT_MEM+16 ;delay after firing a bullet from right
level = TEXT_MEM+14
temp = TEXT_MEM+15
yourHP = TEXT_MEM+17
temp3 = TEXT_MEM+18
eCounter1 = TEXT_MEM+19
eCounter2 = TEXT_MEM+20
eCounter3 = TEXT_MEM+21
shipsmax  = TEXT_MEM+22
shipsleft = TEXT_MEM+23
numhit    = TEXT_MEM+24
detonated = TEXT_MEM+25

ebullet1x = TEXT_MEM+26  ;storage for sub bullet coords
ebullet1y = TEXT_MEM+27  


enemies = APD_BUF          ;Enemy sprites
TEXT_MEM2 = APD_BUF+600


homingb1x = TEXT_MEM2+80
homingb1y = TEXT_MEM2+81


enemy1x = TEXT_MEM2         ;storage for enemy coords
enemy1y = TEXT_MEM2+1
bullet1x = TEXT_MEM2+20        ;storage for bullet coords
bullet1y = TEXT_MEM2+21
bullet6y = TEXT_MEM2+31

enemy1hp  = TEXT_MEM2+50    ;storage for hp
enemy1s  = TEXT_MEM2+60   ;storage for speed
enemy1d  = TEXT_MEM2+70


Start:
 ld hl,APD_BUF
 ld (hl),0
 ld de,APD_BUF+1
 ld bc,767
 ldir

 ld a,2
 ld (Bcounter),a

 ld	hl,$0624
 ld	(boatx),hl
 dec h \ ld l,h
 ld	(numlb),hl

Title:
 call PutBoat
 bcall(_copygbuf)

 ld hl,ProgDesc
 ld de,$191B
 call DZM

 ld de,$2015
 call DZM

 ld de,$271F
 call DZM

 ld de,$2E0A
 call DZM

 ld hl,(Highscore)
 ld e,$43
 ld b,5
 call DM_HL_DECI

 call InitLevel
 call Main
CheckHigh:
 call PutBoat
 bcall(_copygbuf)
 ld hl,$0064
Highscore = $-2
 ld de,(score)
 bcall(_cphlde)
 ret nc
 ld hl,Highscore
 ld (hl),e
 inc hl
 ld (hl),d

 ld hl,HiScr
 ld de,$1714
 call DZM

 ld de,$1E15
 call DZM


 ld hl, $0605
 ld (currow),hl
 	ld	hl,HighName
	push	hl
	ld	b,3
space_loop:
	ld	(hl), ' '
	inc	hl
	djnz	space_loop
	pop	ix
	bcall(_getcsc)		;to reset the key buffer (8000h)
enter_name_loop:
	bcall(_getcsc)		;to reset the key buffer (8000h)
	cp	$38
	jr	z,backup
	sub	9
	ret   z
	jr	c,enter_name_loop
	ld	hl,chartable-1
	ld	e,a
	ld	d,0
	add	hl,de
	ld	a,3
	cp	b
	jr	z,enter_name_loop
	ld	a,(hl)
	or	a
	jr	z,enter_name_loop
	ld	(ix),a
	bcall(_putc)
	inc	b
	inc	ix
	jr	enter_name_loop
backup:
	xor	a
	cp	b
	jr	z,enter_name_loop
	dec	b
	dec	ix
	ld	a,' '
	ld	(ix),a
	ld	hl,curcol
	dec	(hl)
	bcall(_putc)
	dec	(hl)
	jr	enter_name_loop


TestCounters:
 ld a,(hl)
 sub 1
 jr nc,TestDone
 ld a,b
TestDone:
 ld (hl),a
 ret

Main:

 ld hl,eCounter3
 ld b,1
 call TestCounters

 dec hl 
 ld b,2
 call TestCounters

 dec hl
 ld b,3
 call TestCounters

 ld a,(level)
 cp 7
 jr nc,ThisBtoC
 ld a,6
ThisBtoC:
 ld b,a
 ld a,255
 call RANDOM
 cp b
 call c,NewEnemy

 call PutBoat
 call MoveEnemies
 call MoveBullets
 call ScanBullets

 ld a,(yourHP)
 cp 3
 jp nc,Dead
 bcall(_copygbuf)
 ld a,(detonated)
 or a
 call nz,BigDelay  ;Wait a little while if there is an explosion onscreen
 xor a
 ld (detonated),a  ;This zero, whether something has exploded or not

 ld a,(shipsleft)
 or a
 call z,LevelUp

 ld a,(boatx)
 ld c,a

OTH_ARROW:                    ;Thank you Usgard!!!
        LD      A,$fe
        OUT     ($01),A ; Port 1 Keypad
        NOP \ NOP \ NOP \ NOP     
        IN      A,($01) ; Port 1 Keypad
        LD      B,A
        LD      A,$ff
        IN      A,($01) ; Port 1 Keypad
        LD      A,B
        LD      A,$bf
        OUT     ($01),A ; Port 1 Keypad
        IN      A,($01) ; Port 1 Keypad
        OR      $0f
        AND     B

 bit 2,a
 call z,MoveR
 bit 1,a
 call z,MoveL

 ld b,a

 ld a,c
 ld (boatx),a

 ld a,b

 bit 7,a
 jr z,Pause


 ld hl,BWLcounter
 ld a,(hl)
 or a
 jr z,NotRecentlyFiredL
 dec (hl)
 jr RRR

NotRecentlyFiredL:
 ld a,b
 bit 5,a
 push bc
 call z,FireL
 pop bc
RRR:
 ld hl,BWRcounter 
 ld a,(hl)
 or a
 jr z,NotRecentlyFiredR
 dec (hl)
 jr FinishLoop2

NotRecentlyFiredR
 ld a,b
 bit 6,a
 call z,FireR 
FinishLoop2:
 bcall(_getcsc)
 cp 15
 ret z
FinishLoop
 jp Main

Pause:
  DI                  ; disable interrupts
  LD  A, 01           ; bit 3 = lcd status
  OUT ($03), A        ; bit 0 = ON-interrupt status
  EI                  ; enable interrupts
  HALT                ; wait for ON (that's the only interrupt)
  jr FinishLoop

FireR:
 ld a,(Bcounter)
 cp 2
 ret nz

 ld a,(numrb)
 or a
 ret z
 dec a
 ld (numrb),a

 ld a,6
 ld (BWRcounter),a

StartRB:
 ld hl,bullet6y
 ld c,22
 jr StartB

 
ThisBullet:	
 ld a,(boaty)
 add a,8
 ld (hl),a
 dec hl
 ld a,(boatx)
 add a,c
 ld (hl),a
 ret 

 
FireL:
 ld a,(Bcounter)
 cp 2
 ret nz

 ld a,(numlb)
 or a
 ret z
 dec a
 ld (numlb),a

 ld a,6
 ld (BWLcounter),a

StartLB:
 ld hl,bullet1y
 ld c,0
StartB:
 ld b,5
WhichB1:
 ld a,(hl)
 or a
 jr z,ThisBullet
 inc hl
 inc hl
 djnz WhichB1
 ret


MoveR:
 ld b,a
 ld a,c
 cp 73-1
 ld a,b
 ret z
 inc c
 ret

MoveL:
 ld b,a
 ld a,c
 or a
 ld a,b
 ret z		
 dec c
 ret 


CopyA:
 ld b,12 
CALoop:
 ld a,c
 or (hl)
 ld (hl),a
 inc hl
 djnz CALoop
 ret

PutBoat:
 bcall(_cleargbuf)
 ld a,(boatx)
 ld b,a

 ld a,(yourHP)
 ld c,a
 ld a,(boaty)
 add a,c
 ld c,a

 ld hl,Boat
 call PutSprite2
ShowTop:
 ld hl,GRAPH_MEM+(12*14)
 ld c,%10000000
 call CopyA


 ld hl,GRAPH_MEM+(12*15)
 ld c,%01111111
 call CopyA

 set 3,(iy+5)
 set 7,(iy+$14)
 ld hl,TopText
 ld de,$0000
 call DZM
 res 3,(iy+5)

 ld hl,(score)
 ld de,$0031
 ld b,5
 call DM_HL_DECI

 ld a,(level)
 ld l,a
 ld h,0
 ld de,$0056
 call DM_HL_DECI2

 res 7,(iy+$14)

 ld hl,GRAPH_MEM+12
 ld de,GRAPH_MEM
 ld bc,72
 ldir
 
 ld hl,GRAPH_MEM+60
 ld (hl),$ff
 ld de,GRAPH_MEM+61
 ld bc,11
 ldir

 ld hl,Bombs

 ld a,(numlb)
 or a
 jr z,otherside
 ld bc,$2D01
leflop:
 call PutSprite
 dec b
 dec b
 dec b
 dec a
 jr nz, leflop

otherside
 ld a,(numrb)
 or a
 ret z
 ld bc,$4601
rightlop:
 call PutSprite
 inc b
 inc b
 inc b
 dec a
 jr nz, rightlop
 ret


MoveBullets:
 ld hl,Bcounter
 dec (hl)

 ld hl,Code_MoveBullets	;* Modify source and call the double routine
 ld (_TO_MODIFY_1+1),hl
 ld de,Bombs
 ld hl,bullet1y
 ld b,10
 call MoveSomeBullets		

MoveEBullets:
 ld hl,Code_MoveEBullets	;* Modify source and call the double routine
 ld (_TO_MODIFY_1+1),hl
 ld de,EBomb
 ld hl,ebullet1y
 ld b,30
 call MoveSomeBullets

MoveHBullets:
 ld hl,Code_MoveHBullets	;* Modify source and call the double routine
 ld (_TO_MODIFY_1+1),hl
 ld de,EBomb2
 ld hl,homingb1y
 ld b,15
 call MoveSomeBullets		

 ld hl,Bcounter
 ld a,(hl)
 or a
 ret nz
 ld a,2
 ld (hl),a
 ret 

MoveEnemies:
 ld a,8
 ld bc,enemy1s
 ld de,enemy1y
 ld hl,enemies
EMovLoop:
 push af
 push bc
 ld a,(de)
 or a
 jr z,SkipE
 push bc
 ld a,85
 call RANDOM
 call z,FireShot
CheckSpeed:
 pop bc
 ld a,(bc)
 ld bc,eCounter1
 or a
 jr z,CheckIt
 inc bc
 dec a
 jr z,CheckIt
 dec a
 jr nz,SpeedNow
 inc bc
CheckIt:
 ld a,(bc)
 or a
 jr nz,SkipE2
SpeedNow:
 dec de

 ld a,(HL)
 or a
 jr nz,GoRight

 ld a,(de)
 inc a
 cp 95
 jr z,ShipGone
 ld (de),a
 inc de
 jr SkipE2

GoRight:
 ld a,(de)
 dec a
 cp -15
 jr z,ShipGone
 ld (de),a
 inc de

SkipE2:
 push de
 push hl
 ld a,(de)
 ld c,a
 dec de
 ld a,(de)
 ld b,a
 inc hl
 call PutSprite3
 pop hl
 pop de

SkipE:
 ld bc,17
 add hl,bc

 pop bc
 inc bc
 inc de
 inc de

 pop af
 dec a
 jr nz,EMovLoop
 ret

ShipGone:
 pop bc
 push hl 
 ld h,b
 ld l,c
 ld bc,10
 add hl,bc
 ld (hl),0

 ld hl,shipsleft
 dec (hl)
 pop hl

 inc de
 xor a
 ld (de),a
 push bc
 jr SkipE

FireShot:
 push hl
 ld a,(level)
 cp 8
 jr c,SimpleFire
 ld a,5
 call RANDOM
 jr nz,SimpleFire
 ld hl,homingb1y
 ld b,15
 jr FLoop

SimpleFire
 ld hl,ebullet1y
 ld b,30
FLoop:
 ld a,(hl)
 or a
 jr z,EGood
 inc hl
 inc hl
 djnz FLoop
FDone
 pop hl
 ret     ;None availible

EGood:
 ld a,(de)
 ld (hl),a
 dec de
 dec hl
 ld a,(de)
 add a,7
 ld (hl),a
 inc de
 jr FDone

NewEnemy:
 ld a,8            ;15 enemies max
 ld hl,enemy1y     ;Y coordinate used to determine if enemy already out there
 ld de,enemies     ; DE = Pointer to enemy sprites
 ld bc,enemy1hp    ; BC = Pointer to enemy HP and enemy speed
SearchEmpty:
 push af           ;Save the no. of loops remaining
 ld a,(hl)         ;Load Y coord to A
 or a              ;Activate Z or NZ flag
 jr z,NoE          ;If Y = 0, then there's no enemy in this slot

 inc bc            ;Go to next HP entry

 ld a,e
 add a,17
 ld e,a
 ld a,d
 adc a,0
 ld d,a

 pop af            ;Restore loop counter

 inc hl
 inc hl             ;Go to next set of enemy coords
 dec a              ;Decrease A
 jr nz,SearchEmpty  ;If not zero, then keep looping
 ret                ;none empty then screen full and return

NoE:
 pop af             ;Pop the loop counter

 ld a,(shipsmax)
 or a
 ret z
 dec a
 ld (shipsmax),a


 push de            ;Save the sprite pointer
 push hl            ;Save Y coord

 ld h,b
 ld l,c            ;Load BC to HL
 ld de,10
 add hl,de         ;Add 10 to BC to get the enemy speed data

 ld a,4
 call RANDOM       ;Get a random # between 0-3
 ld (hl),a         ;Load that to current enemy speed

 push hl
 ld de,10
 add hl,de         ;Now DE points to enemy depth
 ex de,hl
 pop hl
 
 add a,3  		 ;Increase that number three times (3-6)
 ld h,a            ;Load that to H

 push bc

 push af
TestDepth:
 pop af
 ld a,8
 call RANDOM  ;random number (0-7)  ;8 different depths
 push af      ;Save AF
 inc a        ;So zero isn't an option
 ld c,a
 ld b,8
 ld ix,enemy1d
CheckDepths:
 ld a,(ix)
 cp c
 jr z,TestDepth
 inc ix
 djnz CheckDepths
 ld a,c
 ld (de),a

 inc a
 ld l,a               ;Load A to L
 call MUL_HL2          ;Multiply H*L = HL
 ld a,l               ;Load HL to A
 pop hl     		;* pop AF as HL (H=A)
 pop bc
 ld (bc),a            ;Load A to the enemy HP pointer

 ld l,6               ;Load 6 to L
 call MUL_HL2          ;HL = H*L
 ld de,16
 add hl,de 
 ld a,l               ;Load answer to A

 pop hl               ;Restore Y coord pointer
 ld (hl),a            ;Sub depth stored!  got that? ;)

 dec hl               ;Decrease HL to point to current X coord

 ld a,(bc)            ;Load enemy HP to A

SetESprite:
 set 7,(iy+$14)  ;Write to graph_mem
 set 3,(iy+5)  ;Write inverse text
 push af          ;Save enemy HP pointer
 push hl          ;Save X coord pointer
 bcall(_cleargbuf) ;Clear Graph_mem, and trash all registers
 ld a,2 
 call RANDOM          ;Random number (0-1)
 ld (temp),a          ;Load it to temp space for use later (I'm tired of PUSH/POP's ;)
 pop hl	           ; do some stuff before GoRight2 and GoLeft2
 ld de,$0004           ;
 jr nz,GoLeft2        ;If 1, then ship moves left

GoRight2:               ;If zero, then go here
 ld (hl),-15              ;set coords
 pop af                 ;Restore enemyHP
 ld l,a                 ;Load enemy HP to A
 ld h,d			;Load 0 to HL
 inc e			;Write to these coords
 call DM_HL_DECI2       ;Use Mardell's DM_HL_DECI routine

 ld hl,SubRight
 jr PutNumber           ;Now copy the stuff to the right place


GoLeft2:
 ld (hl),95
 pop af         ;Pop enemyHP

 ld l,a       ;Load enemyHP to L
 ld h,d	  ; Load zero to H
 call DM_HL_DECI2  ;Mardell's DECI routine

 ld hl,SubLeft

PutNumber:
 res 3,(iy+5)  
 res 7,(iy+$14) ;restore flags
 ld bc,$0000
 call PutSprite3   ;Right the appropriate sprite to the screen
 ld a,(temp)       ;hehe, finally the temp data is used
 pop de            ;Pop the sprite pointer
 ld (de),a         ;Load the sprite direction to the sprite data (used for movement routines)
 inc de            ;Go to actual sprite data
 ld hl,GRAPH_MEM   ;Copy first byte of first 8 lines of graph_mem 
 call copy_G_A     ;Do it

 ld de,8           ;Sprite pointer switched to HL by copy_G_A      
 add hl,de         ;Increase that by 8
 ex de,hl          ;Switch HL and DE

 ld hl,GRAPH_MEM+1   ;Now copy second byte of graph_mem
copy_G_A: 
 push de            ;Save SpritePointer
 ld b,8             ;8 lines to copy
cclop
 ld a,(hl)          ;ld (HL) to A
 ld (de),a          ;ld A to (de)
 inc de             ;Increase DE once
 push de            ;Save DE
 ld de,12
 add hl,de          ;Increase HL 12 times to get to the next row
 pop de             ;Restore DE
 djnz cclop         ;Decrease B, if not zero then loop 
 pop hl             ;Restore SpritePointer as HL
 ret                ;The x,y coords are set, the sprite is copied,

MUL_HL2:
 push bc 	
 bcall(MUL_HL)   ;This is just in case this bcall corrupts some registers other
 pop bc
 ret 

ScanBullets:
 ld a,10
 ld hl,bullet1x
ScanLoop:
 ld ix,enemy1hp
 ld de,enemy1x
 ld b,8
 push af
ScanLoop2:
 push de
 push hl
 push bc
 ld a,(hl)
 inc a
 ld b,a
 ld a,(de)
 cp 230
 jr nc,CheckNeg    ;If the enemy coord<0, then the carry will never be set.
 sub b
 jr z,CheckY
 jr nc,SkipThisE
 add a,18
 jr c,CheckY

SkipThisE:
 pop bc
 pop hl
 pop de

 inc de
 inc de
 inc ix
 djnz ScanLoop2
 inc hl
 inc hl
 pop af
 dec a
 jr nz,ScanLoop
 ret

CheckNeg:
 sub b
 jr z,CheckY
 add a,18
 jr nc,SkipThisE
CheckY:
 inc hl
 ld b,(hl) \ dec b
 inc de
 ld a,(de)
 sub b
 jr z,HitSub
 jr nc,SkipThisE
 add a,7
 jr c,HitSub
 jr SkipThisE

HitSub:
 ld c,(hl)
 xor a
 ld (de),a
 ld (hl),70
 dec hl
 ld b,(hl)

 dec c
 dec c
 dec c
 dec c

 dec b
 dec b
 ld hl,Explode
 push ix
 call PutSprite
 pop ix
 ld d,a
 ld a,(ix)
 ld e,a
 ld hl,(score)
 add hl,de
 ld (score),hl

 push ix
 pop hl
 ld de,20
 add hl,de
 ld (hl),0

 ld hl,shipsleft
 dec (hl)

 ld hl,numhit
 inc (hl)

 ld hl,detonated
 inc (hl)
 jr SkipThisE


Dead:
 ld b,58
DeadLoop:
 push bc
 ld hl,yourHP
 inc (hl)
 call PutBoat
 bcall(_copygbuf)
 call BiggerDelay
 pop bc
 djnz DeadLoop
 ret

LevelUp:
 ld hl,(level)
 ld h,5
 call MUL_HL2
 ld a,l

 ld hl,(numhit)
 ld h,100
 call MUL_HL2

 bcall(_divhlbya)

 ld a,l
 cp 100
 ld de,$2019
 jr z,YouDaMan
 call DM_HL_DECI2

AllGood:
 ld de,$191D
 ld hl,LevelDone
 call DZM

 ld de,$2021
 call DZM

InitLevel:
 ld a,(level)
 inc a
 ld (level),a
 cp 16
 jr z,Won
 ld l,a
 ld h,5
 call MUL_HL2
 ld a,l
 ld (shipsmax),a
 ld (shipsleft),a
 xor a
 ld (numhit),a
OTH_PAUSE:
 bcall(_getcsc)
 cp 9
 ret z
 cp 15
 jr nz,OTH_PAUSE
 inc sp
 inc sp
 ret


Won:
 ld de,$1E04
 ld hl,YouWin
 call DZM
 inc sp
 inc sp
 ret

YouDaMan:
 ld b,3
 ld e,$15
 call DM_HL_DECI

 ld de,$2707
 ld hl,Perfect
 call DZM

 ld hl,(score)
 ld de,100
 add hl,de
 ld (score),hl
 jr AllGood


;------------------------------------------------------------------------------------
; MoveSomeBullets: used by MoveBullets and MoveEBullets
; 	address of sprite Bombs or EBomb in DE
;	address of Code_MoveBullets or Code_MoveEBullets stored in _TO_MODIFY_1+1
;	hl contains address bullet1y or ebullet1y
:------------------------------------------------------------------------------------
MoveSomeBullets:
MovBLoop:
 push bc
 push hl
 ld a,(hl)
 or a
 jr z,SkipB
 ld a,(Bcounter)
 or a
 jr nz,NoMove

_TO_MODIFY_1:
 call $0000		;* will be Code_MoveBullets or Code_MoveEBullets
 jr nc,SkipB		;* function returns nc when Detonate or ClearB executed
NoMove:
 ld c,(hl)
 dec hl
 ld b,(hl)

 ex de,hl
 call PutSprite
 ex de,hl
SkipB:
 pop hl			
 inc hl
 inc hl
 pop bc
 djnz MovBLoop
 ret

;------------------------------------------------------------------------------------
; 'Plugin' code for MoveSomeBullets
;   returns carry if ClearB is not executed
;           not-carry if clearB is not executed
:------------------------------------------------------------------------------------
Code_MoveBullets:
 inc (hl)	; Increase Y coords of current bullet
 ld a,(hl)
 cp 64
 ret c
ClearB:
 xor a
 ld (hl),a
 ld a,b

 ld bc,numlb
 cp 6
 jr nc,ResetL	
ResetR:
 inc bc
ResetL:
 ld a,(bc)
 inc a
 ld (bc),a
 or a
 ret

Code_MoveHBullets:
 dec hl
 ld a,(hl)
 ld b,a
 ld a,(boatx)
 add a,10
 sub b
 jr z,NoWhere
 jr c,ShiftLeft
ShiftRight:
 inc (hl)
 inc (hl)
ShiftLeft:
 dec (hl)
NoWhere:
 inc hl
;------------------------------------------------------------------------------------
; 'Plugin' code for MoveSomeBullets
;   returns not-carry if Detonate is not executed
;           carry if Detonate is executed
:------------------------------------------------------------------------------------
Code_MoveEBullets:
 dec (hl)      ; Increase Y coords of current bullet
 ld a,(hl)
 cp 12
 scf
 ret nz

Detonate: 
 ld c,a
 xor a 
 ld (hl),a 	
 dec hl
 ld b,(hl)
 ld hl,Explode2
 call PutSprite
 ld hl,detonated
 inc (hl)
 ld c,b
CheckLop:
 ld a,(boatx)
 inc a
 sub c
 jr z,hitBoat
 jr nc,EndDetonate
 add a,19
 jr c,hitBoat
 jr EndDetonate
hitBoat:
 ld hl,yourHP
 inc (hl)
EndDetonate:
 or a
 ret 

;Misc Routines

BiggerDelay:
 call BigDelay
BigDelay:
 ei
 halt
 halt
 halt
 halt
 halt
 ret

PutSprite3:
 push hl
 push de
 call PutSprite
 call NextSprite
 jr Pop_N_Ret2

PutSprite2:
 call PutSprite
 call NextSprite
NextSprite:
 ld de,8
 add hl,de
 ld a,e
 add a,b
 ld b,a


;----------------------------------------------------------------------------
;[ PutSprClpXOR ] [ABCDEFIX]                      [ 139 bytes ] [ CrASH_Man ]
;----------------------------------------------------------------------------
; Draws a sprite using only XOR data, with clipping
;
; parameters: HL -> sprite, (B,C) = coordinates
; returns:    Puts sprite in GRAPH_MEM
;

PutSprite:
 PUSH HL
 push de
 PUSH BC
 push af
 CALL PutSprClpXOR
 pop af
Pop_N_Ret:
 POP BC
Pop_N_Ret2:
 pop de
 POP HL
 RET


RANDOM:
 push hl
 push de 
 push bc
 ld b,a 	; Create a Random number
 ld hl,(APD_BUF+750)
 ld a,r
 ld d,a
 ld e,(hl)
 add hl,de
 add a,l
 xor h
 ld (APD_BUF+750),hl
 ld hl,0
 ld e,a
 ld d,h
randl:
 add hl,de
 djnz	randl
 ld a,h
 or a
 jr Pop_N_Ret
	

PutSprClpXOR:
   XOR  A
__XChange_1:    LD   DE, 8     ; D = 0, E = Height

                OR   C                            ; If C < 0
                JP   M, _SCX_NoBotClp             ; No bottom clip.

                LD   A, $3F                       ; Is C is offscreen?
                SUB  C
                RET  C

__XChange_2:    CP   8-1       ; If C + 7 < 64
                JR   NC, _SCX_NoVertClp           ; No vertical clip.
                INC  A
                LD   E, A
                JR   _SCX_NoVertClp               ; Height = 64 - C

_SCX_NoBotClp:
__XChange_3:    CP   -(8-1)    ; Is C is offscreen?
                RET  C

                ADD  A, E                         ; Find how many lines
                LD   C, A                         ; to actually draw
                SUB  E

                NEG
                LD   E, A
                ADD  HL, DE                       ; Move HL down
                LD   E, C                         ; by -C lines
                LD   C, D

_SCX_NoVertClp: PUSH HL                           ; IX -> Sprite
                POP  IX

                LD   A, $77                       ; OP code for
                LD   (_SCX_OPchg_1), A            ;   LD   (HL), A
                LD   (_SCX_OPchg_2), A

                XOR  A                            ; Is B > 0?
                OR   B
                JP   M, _SCX_NoRightClp

                CP   89                           ; Is B < 89?
                JR   C, _SCX_ClpDone
                CP   96
                RET  NC

                LD   HL, _SCX_OPchg_1             ; Modify LD to NOP
                JR   _SCX_ClpModify

_SCX_NoRightClp:CP   -7                           ; Is B is offscreen?
                RET  C

                LD   HL, _SCX_OPchg_2             ; Modify LD to NOP
_SCX_ClpModify: LD   (HL), D

_SCX_ClpDone:   LD   B, D
                LD   H, B
                LD   L, C
                ADD  HL, BC                       ; HL = Y * 12
                ADD  HL, BC
                ADD  HL, HL
                ADD  HL, HL

                LD   C, A                         ; HL = Y*12 + X/8
                SRA  C
                SRA  C
                SRA  C
                INC  C

                ADD  HL, BC
                LD   BC, GRAPH_MEM
                ADD  HL, BC

                LD   B, E                         ; B = number of rows

                CPL
                AND  %00000111                    ; find number of
                LD   E, A                         ; instructions to jump
                ADD  A, E
                ADD  A, E
                LD   (_SCX_OPchg_3 + 1), A        ; 3 * (7 - number)

                LD   DE, 13

_SCX_LineLoop:  LD   C, (IX)
                XOR  A
_SCX_OPchg_3:   JR   _SCX_OPchg_3                 ; modify

                RR   C
                RRA
                RR   C
                RRA
                RR   C
                RRA
                RR   C
                RRA
                RR   C
                RRA
                RR   C
                RRA
                RR   C
                RRA

                XOR  (HL)                         ; XOR with background
_SCX_OPchg_1:   LD   (HL), A                      ; Write
                DEC  HL                           ; HL -> next 8 pixels

                LD   A, C
                XOR  (HL)                         ; XOR with background
_SCX_OPchg_2:   LD   (HL), A                      ; Write
                ADD  HL, DE                       ; HL -> next row

                INC  IX                           ; Increment to next data
                DJNZ _SCX_LineLoop
                RET

DM_HL_DECI2:
 ld b,2
DM_HL_DECI:
 ld (pencol),de

 ld de,string+5
 xor a
 ld (de),a
RepUnp:
 dec de
 bcall(_divhlby10)
 add a,48
 ld (de),a
 djnz RepUnp
 ex de,hl
 jr DZM2


DZM:
 ld (pencol),de
DZM2:
 bcall(_vputs)
 ret


Bombs:
 .db %11000000
 .db %11000000
 .db %00000000
 .db %00000000
 .db %00000000
 .db %00000000
 .db %00000000
 .db %00000000


EBomb:
 .db %10100000
 .db %01000000
 .db %10100000
 .db %00000000
 .db %00000000
 .db %00000000
 .db %00000000
 .db %00000000

EBomb2:
 .db %01000000
 .db %01000000
 .db %10100000
 .db %00000000
 .db %00000000
 .db %00000000
 .db %00000000
 .db %00000000

Explode:
 .db %01110000
 .db %11011000
 .db %10101000
 .db %11011000
 .db %01110000
 .db %00000000
 .db %00000000
 .db %00000000

Explode2:
 .db %10101010
 .db %01010100
 .db %00111000
 .db %00000000
 .db %00000000
 .db %00000000
 .db %00000000

Boat:
 .db %00000000
 .db %00000100
 .db %00000010
 .db %00000111
 .db %11111111
 .db %01111111
 .db %00111111
 .db %00011111

 .db %01100110
 .db %01100110
 .db %11111111
 .db %11111111
 .db %11111111
 .db %11111111
 .db %11111111
 .db %11111111

 .db %00000000
 .db %00010000
 .db %00100111
 .db %11000100
 .db %11111110
 .db %11111100
 .db %11111000
 .db %11110000


SubRight:
 .db %00000111
 .db %10111000
 .db %11111000
 .db %11111000
 .db %11111000
 .db %10111000
 .db %00000000
 .db %00000000

 .db %11111000
 .db %00000110
 .db %00000111
 .db %00000111
 .db %00000111
 .db %00000110
 .db %00000000
 .db %00000000

SubLeft:
 .db %00001111
 .db %01110000
 .db %11110000
 .db %11110000
 .db %11110000
 .db %01110000
 .db %00000000
 .db %00000000

 .db %11110000
 .db %00001101
 .db %00001111
 .db %00001111
 .db %00001111
 .db %00001101
 .db %00000000
 .db %00000000


HiScr:  .db "A New High Score!",0
        .db "Enter your name",0

TopText:
 .db "  SubHunt  ",0

LevelDone:
 .db "Level Done!",0
 .db "% Destroyed",0

Perfect:
 .db "Perfect! 100 point bonus!",0

YouWin:
 .db "Congratulations! You Won!",0

chartable:
         .db      ":WRMH0"
         .DB      0,"?",5Bh,"VQLG!",0,".ZUPKFC"	;5Bh is theta
         .DB      "> YTOJEB<",0,"XSNIDA"
         .DB      0,"54321",0,0

.end


