#include "ti83plus.inc"
.org	$9D93				;address to which TI-OS loads the program
	.db	$BB,$6D			;identifies to TI-OS that this is an asm program

 ld hl,SAVESSCREEN
 ld de,$0000		; Hint: top left corner is at 0,0 and the bottom right at 95,63
 ld hl,$1008
 ld ix,SAVESSCREEN
 call DrawLine
 ld hl,SAVESSCREEN
 call FlipScreen
 call bcall(_getkey)
 ret

FlipScreen:		; Copies the screen at HL to the LCD in ~52000 cycles (ION FastCopy)
 di
 ld a,$80
 out ($10),a
 ld de,755
 add hl,de
 ld a,$20
 ld c,a
 inc hl
 dec hl
FS_column:
 ld b,64
 inc c
 ld de,-767
 out ($10),a
 add hl,de
 ld de,10
FS_inner:
 add hl,de
 inc hl
 inc hl
 inc de
 ld a,(hl)
 out ($11),a
 dec de
 djnz FS_inner
 ld a,c
 cp $2c
 jp nz,FS_column
 ret

DrawLine:		; This routine draws an unclipped line on an IX-pointed screen from (d,e) to (h,l)
 ld a,h			; Calculating delta X and swapping points if negative
 sub d			; (Lines are always drawn from left to right)
 jp nc,DL_okaydx
 ex de,hl
 neg
DL_okaydx:
 push af		; Saving DX (it will be popped into DE below)
 ld b,0			; Calculating the position of the first pixel to be drawn
 ld c,d			; IX+=D/8+E*12 (actually E*4+E*4+E*4)
 srl c
 srl c
 srl c
 add ix,bc
 ld c,e
 sla c
 sla c
 add ix,bc
 add ix,bc
 add ix,bc
 ld a,d			; Calculating the starting pixel mask
 ld c,$80
 and 7
 jp z,DL_okaymask
DL_calcmask:
 srl c
 dec a
 jp nz,DL_calcmask
DL_okaymask:
 ld a,l			; Calculating delta Y and negating the Y increment if necessary
 sub e			; This is the last instruction for which we need the original data
 ld hl,12
 jp nc,DL_okaydy
 ld hl,-12
 neg
DL_okaydy:
 pop de			; Recalling DX
 ld e,a			; D=DX, E=DY
 cp d
 jp c,DL_horizontal	; Line is rather horizontal than vertical
 ld (DL_VLinc+1),hl	; Modifying y increment
 push ix		; Loading IX to HL for speed; we don't need the old value of HL any more
 pop hl
 ld b,e			; Pixel counter
 inc b
 srl a			; Setting up gradient counter (A=E/2)
 ld (DL_HLinc+1),sp	; Backing up SP to a safe place
 di			; Interrupts are undesirable when we play around with SP :)
DL_VLinc:
 ld sp,0		; This value is replaced by +/- 12
DL_Vloop:
 ex af,af'		; Saving A to alternative register
 ld a,(hl)
 or c			; Writing pixel to current position
 ld (hl),a
 ex af,af'		; Recalling A (faster than push-pop, and there's no need for SP)
 add hl,sp
 sub d			; Handling gradient
 jp nc,DL_VnoSideStep
 rrc c			; Rotating mask
 jp nc,DL_VnoByte	; Handling byte boundary
 inc hl
DL_VnoByte:
 add a,e
DL_VnoSideStep:
 djnz DL_Vloop
 ld sp,(DL_HLinc+1)
 ret
DL_horizontal:
 ld (DL_HLinc+1),hl	; Modifying y increment
 push ix		; Loading IX to HL for speed; we don't need the old value of HL any more
 pop hl
 ld b,d			; Pixel counter
 inc b
 ld a,d			; Setting up gradient counter
 srl a
 ld (DL_VLinc+1),sp	; Backing up SP to a safe place
 di			; Interrupts again...
DL_HLinc:
 ld sp,0		; This value is replaced by +/- 12
DL_Hloop:
 ex af,af'		; Saving A to alternative register
 ld a,(hl)
 or c			; Writing pixel to current position
 ld (hl),a
 ex af,af'		; Recalling A
 rrc c			; Rotating mask
 jp nc,DL_HnoByte	; Handling byte boundary
 inc hl
DL_HnoByte:
 sub e			; Handling gradient
 jp nc,DL_HnoSideStep
 add hl,sp
 add a,d
DL_HnoSideStep:
 djnz DL_Hloop
 ld sp,(DL_VLinc+1)
 ret