.nolist
#include ion.inc
.list

pic = saferam1
_CreatePict = 4333h
PICOBJ = 07h
lcdinstport = 10h
lcddataport = 11h
tPic1 = 00h         
tVarPict = 60h
FindSym = 42F1h
_ErrUndefined = 44B6h

#ifdef TI83P
    .org progstart-2
    .db $BB,$6D
#else
    .org progstart
#endif
     ret
     jr nc,begining

    .db "Andy's Drawing",0

begining:
  bcall(_indicatoroff)
  bcall(_clrlcdfull)
  bcall(_homeup)
  ld a,48
  ld (X),a
  ld a,32
  ld (Y),a 
  ld a,1
  ld (temp),a
  call sprite
  
Main:
    ld       a,$FF
    out      (1),a
    ld       a,0bfh
    out      (1),a
    in       a,(1)
    cp       223
    call     z,spriteon
    cp       127
    jp       z,exit
    cp       254
    jp       z,nextbrush
    cp       253
    jp       z,previous
    cp       191
    call     z,eraseron
    cp       251
    jp       z,clearscreenthing
    cp       247
    call     z,recallpic
    cp       239
    call     z,storepic
    ld       a,$FF
    out      (1),a
    ld       a,$FE
    out      (1),a
    in       a,(1)
    bit      0,a
    jp       z,move_down
    bit      1,a
    jr       z,move_left
    bit      2,a
    jr       z,move_right
    bit      3,a
    jp       z,move_up
    jr       main

Clearscreenthing:
 bcall(_cleargbuf)
 bcall(_clrlcdfull)
 call sprite
 jp main

nextbrush:
 ld a,(temp)
 cp 6
 jp z,next2
 ld a,(temp)
 inc a
 ld (temp),a
 call delay
 jp main

next2:
 ld a,1
 ld (temp),a
 call delay
 jp main
previous:
 ld a,(Temp)
 cp 1
 jp z,pre2
 ld a,(temp)
 dec a
 ld (temp),a
 call delay
 jp main
pre2:
 ld a,6
 ld (temp),a
 call delay
 jp main
move_left:
    ld       a,$FF
    out      (1),a
    ld       a,$FE
    out      (1),a
    in       a,(1)
    bit      0,a
    jp       z,downleft
    bit      3,a
    jp       z,upleft
    call     left
    jp main

move_right:
    ld       a,$FF
    out      (1),a
    ld       a,$FE
    out      (1),a
    in       a,(1)
    bit      0,a
    jp       z,downright
    bit      3,a
    jp       z,upright
    call       right
    jp main

move_up:
    ld       a,$FF
    out      (1),a
    ld       a,$FE
    out      (1),a
    in       a,(1)
    bit      1,a
    jp       z,upleft
    bit      2,a
    jp       z,upright
    call       up
    jp main
 
move_down:
    ld       a,$FF
    out      (1),a
    ld       a,$FE
    out      (1),a
    in       a,(1)
    bit      1,a
    jp       z,downleft
    bit      2,a
    jp       z,downright
    call       down
    jp main


double: 
 ld hl,(pic)
 ld bc,768
 ld de,plotSScreen
 ldir
 ret
         
up:
    call sprite
    ld a,(Y)
    dec a
    ld (Y),a
    call boundaryy
    call sprite
    ret

down:
    call sprite
    ld a,(Y)
    inc a
    ld (Y),a
    call boundaryy
    call sprite
    ret

right:
    call sprite
    ld a,(X)
    inc a
    ld (X),a
    call boundaryx
    call sprite
    ret

Left:
    call sprite
    ld a,(X)
    dec a
    ld (X),a
    call boundaryx
    call sprite
    ret

upright:
   call up
   call right
   jp main

Upleft:
  call up
  call left
  jp main

Downright:
  call down
  call right
  jp main

Downleft:
 call down
 call left
 jp main

boundaryx:
 ld a,(X)
 cp 0
 call z,changeone
 cp 95
 call z,changetwo
 ret

changeone:
 ld a,1
 ld (X),a
 ret

changetwo:
 ld a,94
 ld (X),a
 ret

boundaryy:
 ld a,(Y)
 cp 0
 call z,changeoney
 cp 63
 call z,changetwoy
 ret

changeoney:
 ld a,1
 ld (Y),a
 ret

changetwoy:
 ld a,62
 ld (Y),a
 ret

spriteon:
 ld a,(temp)
 cp 1
 call z,spriteon1
 cp 2
 call z,spriteon2
 cp 3
 call z,spriteon3
 cp 4
 call z,spriteon4

spriteon_2:
 ld a,(temp)
 cp 5
 call z,spriteon5
 cp 6
 call z,spriteon6
 ret

Eraseron:
 ld a,(temp)
 cp 1
 call z,eraseron1
 cp 2
 call z,eraseron2
 cp 3
 call z,eraseron3
 cp 4
 call z,eraseron4

eraseron_2:
 ld a,(temp)
 cp 5
 call z,load
 cp 6
 call z,load
 ret
 
load
 ld a,1
 ld (Temp),a
 ret

spriteon1:
    call sprite
    ld b,1				
    ld a,(Y)
    ld l,a
    ld a,(X)					
    ld ix,pixel		
    call PutSprite			
    call ionfastcopy
    ld hl,PLOTSsCREEN
    ld de,(pic)
    ld bc,768
    ldir
    call double
    call sprite
    ret		

spriteon2:
    call sprite
    ld b,3				
    ld a,(Y)
    ld l,a
    ld a,(X)					
    ld ix,pixel2	
    call PutSprite			
    call ionfastcopy
    ld hl,PLOTSsCREEN
    ld de,(pic)
    ld bc,768
    ldir
    call double
    call sprite
    ret		

spriteon3:
    call sprite
    ld b,4			
    ld a,(Y)
    ld l,a
    ld a,(X)					
    ld ix,pixel3		
    call PutSprite			
    call ionfastcopy
    ld hl,PLOTSsCREEN
    ld de,(pic)
    ld bc,768
    ldir
    call double
    call sprite
    ret		

spriteon4:    
    call sprite
    ld b,5				
    ld a,(Y)
    ld l,a
    ld a,(X)					
    ld ix,pixel4		
    call PutSprite			
    call ionfastcopy
    ld hl,PLOTSsCREEN
    ld de,(pic)
    ld bc,768
    ldir
    call double
    call sprite
    ret		

spriteon5:    
    call sprite
    ld b,5				
    ld a,(Y)
    ld l,a
    ld a,(X)					
    ld ix,pixel5		
    call PutSprite			
    call ionfastcopy
    ld hl,PLOTSsCREEN
    ld de,(pic)
    ld bc,768
    ldir
    call double
    call sprite
    ret		

spriteon6:    
    call sprite
    ld b,7			
    ld a,(Y)
    ld l,a
    ld a,(X)					
    ld ix,pixel6		
    call PutSprite			
    call ionfastcopy
    ld hl,PLOTSsCREEN
    ld de,(pic)
    ld bc,768
    ldir
    call double
    call sprite
    ret		

sprite:    
    ld b,8				
    ld a,(Y)						
    ld l,a
    ld a,(X)					
    ld ix,dot			
    call ionPutSprite			
    call ionfastcopy
    ret		
	
eraseron1:
    call sprite
    ld b,1				
    ld a,(Y)
    ld l,a
    ld a,(X)					
    ld ix,pixel	
    call PutSprite			
    call ionfastcopy
    ld b,1				
    ld a,(Y)
    ld l,a
    ld a,(X)					
    ld ix,pixel
    call ionPutSprite			
    call ionfastcopy
    ld hl,PLOTSsCREEN
    ld de,(pic)
    ld bc,768
    ldir
    call double
    call sprite
    ret		

eraseron2:
    call sprite
    ld b,2				
    ld a,(Y)
    ld l,a
    ld a,(X)					
    ld ix,eraser2	
    call PutSprite			
    call ionfastcopy
    ld b,2				
    ld a,(Y)
    ld l,a
    ld a,(X)					
    ld ix,eraser2	
    call ionPutSprite			
    call ionfastcopy
    ld hl,PLOTSsCREEN
    ld de,(pic)
    ld bc,768
    ldir
    call double
    call sprite
    ret	

eraseron3:
    call sprite
    ld b,5				
    ld a,(Y)
    ld l,a
    ld a,(X)					
    ld ix,eraser3	
    call PutSprite			
    call ionfastcopy
    ld b,5				
    ld a,(Y)
    ld l,a
    ld a,(X)					
    ld ix,eraser3	
    call ionPutSprite			
    call ionfastcopy
    ld hl,PLOTSsCREEN
    ld de,(pic)
    ld bc,768
    ldir
    call double
    call sprite
    ret		

eraseron4:
    call sprite
    ld b,8				
    ld a,(Y)
    ld l,a
    ld a,(X)					
    ld ix,eraser4	
    call PutSprite			
    call ionfastcopy
    ld b,8				
    ld a,(Y)
    ld l,a
    ld a,(X)					
    ld ix,eraser4
    call ionPutSprite			
    call ionfastcopy
    ld hl,PLOTSsCREEN
    ld de,(pic)
    ld bc,768
    ldir
    call double
    call sprite
    ret		
		
dot:
 .db %11110000
 .db %11101000
 .db %11000100
 .db %10000010
 .db %01000101
 .db %00101010
 .db %00010100
 .db %00001000

Pixel:
 .db %10000000

pixel2:
 .db %01000000
 .db %11100000
 .db %01000000

pixel3:
 .db %01100000
 .db %11110000
 .db %11110000
 .db %01100000

pixel6:
 .db %00111000
 .db %01111100
 .db %11111110
 .db %11111110
 .db %11111110
 .db %01111100
 .db %00111000

pixel4:
 .db %00100000
 .db %00100000
 .db %11111000
 .db %00100000
 .db %00100000


pixel5:
 .db %00100000
 .db %01110000
 .db %11111000
 .db %01110000
 .db %00100000


eraser4:
 .db %11111111
 .db %11111111
 .db %11111111
 .db %11111111
 .db %11111111
 .db %11111111
 .db %11111111
 .db %11111111

eraser3:
 .db %11111000
 .db %11111000
 .db %11111000
 .db %11111000
 .db %11111000

eraser2:
 .db %11000000
 .db %11000000

putSprite:
	ld	e,l
	ld	h,$00
	ld	d,h
	add	hl,de
	add	hl,de
	add	hl,hl
	add	hl,hl
	ld	e,a
	and	$07
	ld	c,a
	srl	e
	srl	e
	srl	e
	add	hl,de
	ld	de,gbuf
	add	hl,de
putSpriteLoop1:
sl1:	ld	d,(ix)
	ld	e,$00
	ld	a,c
	or	a
	jr	z,putSpriteSkip1
putSpriteLoop2:
	srl	d
	rr	e
	dec	a
	jr	nz,putSpriteLoop2
putSpriteSkip1:
	ld	a,(hl)
	or	d
	ld	(hl),a
	inc	hl
	ld	a,(hl)
	or	e
	ld	(hl),a
	ld	de,$0B
	add	hl,de
	inc	ix
	djnz	putSpriteLoop1
	ret

storepic:
        ld hl,(pic)
        ld bc,768
        ld de,plotSScreen
        ldir
	bcall(_zeroop1)   ; load var name
	ld hl,picname     
	ld de,op1         
	ld bc,3          
	ldir              
	bcall(_chkfindsym)  ; look it up
	jp nc,load_data   ; skip to loaddata if exists.
	bcall(_createpict)  ; else create pic
load_data:
	inc de            ; skip 1st length byte
	inc de            ; skip 2nd length byte
	ld hl,gbuf        ; pic data
	ld bc,756         ; pic size
	ldir              ; copy data
        bcall(_clrlcdfull)
        bcall(_cleargbuf)
	ld	a,3
	ld	(CURROW),a		; current row				
	ld	a,1				
	ld	(CURCOL),a		; current column
	ld	hl,txtsto
	bcall(_puts)
	call waitkey
        ld hl,(pic)
        ld bc,768
        ld de,plotSScreen
        ldir
        call sprite
      	ret
txtsto:
	.db "Stored To PIC1",0
picname:
; Recall our tokens class...?
	.db picobj,tvarpict,tpic1
WaitKey:
	ei
WaitKeyLoop:
	halt
	bcall(_getcsc)
	or a
	jr z,WaitKeyLoop
        ret
delay: 
 ld b,25
Wait:
 ei
 halt
 djnz wait
 ret

recallpic:
        bcall(_zeroop1)
	ld	hl,picname			;load pointer to my pic1 data into hl
	ld	de,op1			;load pointer to Op1 into de
	ld	bc,3			;bytes to copy from hl to de
	ldir				;copy them
	bcall(_chkfindsym)		;look pic1 up
	jp	nc,loadasdf			;if not found, produce error
        ret
loadasdf:
	inc	de			;
	inc	de			;The first two bytes of a pic are pretty meaningless
	ld	(pic1loc),de		;Load the pointer to the actuall pic1 data into (pic1
        ld	hl,(pic1loc)		;load pointer to pic1 into hl
	ld	de,plotsscreen		;load pointer to the graph buffer into de
	ld	bc,756		;bytes to copy (it isn't 768 because pics don't take up the whole screen)
	ldir				;copy it
	call ionfastcopy
        call sprite
        ret

pic1loc:
	.db $00,$00			;where I stored the pointer to pic1
exit:
  ret
Temp:
 .db 0
X:
 .db 0
Y:
 .db 0
.end
END