; Virtual Calc
; v1.00
; Source code by Michael Vincent (michael@detacheds.com)
; Web: www.detacheds.com
;
; (C) 2001 by Michael Vincent. If you can understand it, you may learn from this source. :)
;
.nolist
#include "asm.inc"
.list
.org $4000
.db 080h,0Fh
.db 00h,00h,00h,00h 
.db 080h,012h
.db 1,4
.db 080h,021h
.db 01h
.db 080h,031h
.db 01h
.db 080h,048h
.db "VCalc   "
.db 080h,081h
.db 01h
.db 080h,090h
.db 003h,026h,009h,004h,004h,06fh,01bh,080h
.db 002h ,00dh ,040h                             
.db 0a1h ,06bh ,099h ,0f6h ,059h ,0bch ,067h 
.db 0f5h ,085h ,09ch ,009h ,06ch ,00fh ,0b4h ,003h ,09bh ,0c9h 
.db 003h ,032h ,02ch ,0e0h ,003h ,020h ,0e3h ,02ch ,0f4h ,02dh 
.db 073h ,0b4h ,027h ,0c4h ,0a0h ,072h ,054h ,0b9h ,0eah ,07ch 
.db 03bh ,0aah ,016h ,0f6h ,077h ,083h ,07ah ,0eeh ,01ah ,0d4h 
.db 042h ,04ch ,06bh ,08bh ,013h ,01fh ,0bbh ,093h ,08bh ,0fch 
.db 019h ,01ch ,03ch ,0ech ,04dh ,0e5h ,075h 
.db 80h,7Fh
.db 0,0,0,0    ;Length=0, N/A
	ld hl,AppVectors
	bcall(404Bh)
	bcall(_clrlcdfull)
	set bufferonly,(iy+plotflags)
	set textwrite,(iy+sgrflags)
	bcall(_grbufclr)
	ld hl,Title
	ld de,plotsscreen
	ld bc,132
	ldir
 	ld hl,Splash_DS
 	ld de,plotsscreen+(12*49)
 	ld bc,60
 	ldir
	ld hl,54*256+5
	ld (pencol),hl
	ld hl,Splash_Web
	call vputstring
	ld hl,Splash_W
	ld de,9872h
	ld bc,4
	ldir
	ld hl,9872h
	ld de,55*256+5
	bcall(_displayimage)
	ld hl,13*256+18
	ld (pencol),hl
	ld hl,Title_Junk
	call vputstring
	ld de,25*256+12
	ld (pencol),de
	call vputstring
	ld de,36*256+27
	ld (pencol),de
	call vputstring
	bcall(_grbufcpy)
	res bufferonly,(iy+plotflags)
	res textwrite,(iy+sgrflags)
	bcall(_getkey)
	res onInterrupt,(iy+onFlags)
	cp 40h
	jp z,exitapp
	in a,(2)
	bit 7,a
	jp z,CalcVersion
	bcall(_getbasever)
	ld d,a
	ld e,b
	ld hl,010Dh
	or a
	sbc hl,de
	jp c,ROMVersion
	bit 5,(iy+34h)
	jr z,Install
	res 5,(iy+34h)
	bcall(_clrlcdfull)
	ld hl,0
	ld (currow),hl
	ld hl,Uninstalled
	call putstring
	ld de,1*256+7
	ld (currow),de
	call putstring
	bcall(_getkey)
	res onInterrupt,(iy+onFlags)
	jp exitapp
AppTitle:
	.db "Virtual Calc",0
Install:
	ld hl,Hook
	in a,(6)
	bcall(4F66h)	;rawkeyhook
	xor a
	ld ($FE70),a
	ld a,$87
	ld ($FE71),a
	di
	ld a,85h
	out (7),a
	ld hl,$C000
	ld de,$8000
	ld bc,$4000
	ldir
	ld a,81h
	out (7),a
	ld hl,Copier1
	ld de,9872h
	ld bc,Copier1_End-Copier1
	ldir
	jp 9872h
Install_Copy:
	ld a,86h
	out (7),a
	ld hl,$9000
	call SaveDisplay
	ld ($B000),sp
	ld a,81h
	out (7),a
	ei
	bcall(_clrlcdfull)
	ld hl,0
	ld (currow),hl
	ld hl,Installed
	call putstring
	bcall(_getkey)
	res onInterrupt,(iy+onFlags)
	jr exitapp
exitapp:
	bcall(_grbufclr)
	bjump(_jforcecmdnochar)
	;Memory map
	;Page 82h - lower of calc 1
	;Page 83h - upper of calc 1
	;Page 84h - lower of calc 2
	;Page 85h - upper of calc 2
	;Page 86h - 4000h, LCD of calc 1
	;Page 86h - 5000h, LCD of calc 2
	;Page 86h - 6000h, SP of calc 1
	;Page 86h - 7000h, SP of calc 2
Copier1:
	in a,(6)
	push af
	ld a,84h
	out (6),a
	ld hl,8000h
	ld de,4000h
	ld bc,4000h
	ldir
	pop af
	out (6),a
	jp Install_Copy
Copier1_End:
Hook:
	add a,e
	cp $45
	ret nz
	in a,(4)
	bit 3,a
	jp nz,Hook_No
	res onInterrupt,(iy+onFlags)
	di
	ld a,1
	out (20h),a
	ld a,($FE70)
	or a
	jp nz,Hook_2
	;Calc 1 is active, save it, then swap to calc 2.
	inc a
	ld ($FE70),a
	ld a,83h
	out (7),a
	ld hl,$C000
	ld de,$8000
	ld bc,$4000
	ldir
	ld bc,4000h
	ld hl,8000h
Hook1_Copy_Loop:
	ld a,81h
	out (7),a
	ld e,(hl)
	ld a,82h
	out (7),a
	ld (hl),e
	inc hl
	dec bc
	ld a,b
	or c
	jr nz,Hook1_Copy_Loop
	ld a,86h
	out (7),a
	ld hl,8000h
	call SaveDisplay
	ld ($A000),sp
	;calc 1 now backed up.
	;now copy calc 2 to normal RAM
	ld a,85h
	out (7),a
	ld hl,8000h
	ld de,$C000
	ld bc,4000h
	ldir
	ld a,84h
	out (7),a
	ld bc,4000h
	ld hl,8000h
Hook1_Copy1_Loop:
	ld a,84h
	out (7),a
	ld e,(hl)
	ld a,81h
	out (7),a
	ld (hl),e
	inc hl
	dec bc
	ld a,b
	or c
	jr nz,Hook1_Copy1_Loop
	;Both pages now copied back...
	ld a,86h
	out (7),a
	ld hl,$9000
	call CopyLayer
	ld sp,($8000+$3000)
	ld a,81h
	out (7),a
	ld a,1
	ld ($FE70),a
	ei
	ld a,($FE71)
	or a
	ret z
	xor a
	ld ($FE71),a
	bjump(_jforcecmdnochar)
Hook_2:
	;Calc 2 is active, save it, then swap to calc 1.
	xor a
	ld ($FE70),a
	ld a,85h
	out (7),a
	ld hl,$C000
	ld de,$8000
	ld bc,4000h
	ldir
	ld bc,4000h
	ld hl,8000h
Hook2_Copy_Loop:
	ld a,81h
	out (7),a
	ld e,(hl)
	ld a,84h
	out (7),a
	ld (hl),e
	inc hl
	dec bc
	ld a,b
	or c
	jr nz,Hook2_Copy_Loop
	ld a,86h
	out (7),a
	ld hl,9000h
	call SaveDisplay
	ld ($B000),sp
	;calc 2 saved, load calc 1!
	ld a,83h
	out (7),a
	ld hl,8000h
	ld de,$C000
	ld bc,4000h
	ldir
	ld bc,4000h
	ld hl,8000h
Hook2_Copy1_Loop:
	ld a,82h
	out (7),a
	ld e,(hl)
	ld a,81h
	out (7),a
	ld (hl),e
	inc hl
	dec bc
	ld a,b
	or c
	jr nz,Hook2_Copy1_Loop
	ld a,86h
	out (7),a
	ld hl,$8000
	call CopyLayer
	ld sp,($8000+$2000)
	ld a,81h
	out (7),a
	xor a
	ld ($FE70),a
	ei
	xor a
	ret
Hook_No:
	ld a,$45
	or a
	ret
SaveDisplay:
	ld b,64
	ld a,$07
	out ($10),a
	ld a,$80-1
Slayerloop1:
	push bc
	ld b,$0C
	inc a
	ld (9872h),a
	call lcddelay
	out ($10),a
	call lcddelay
	ld a,$20
	out ($10),a
	call lcddelay
	in a,($11)
Slayerloop2:
	call lcddelay
	in a,($11)
	ld (hl),a
	inc hl
	djnz Slayerloop2
	pop bc
	ld a,(9872h)
	djnz Slayerloop1
	ld a,$05
	call lcddelay
	out ($10),a
	ret
CopyLayer:
	ld b,64
	ld a,$07
	out ($10),a
	ld a,$80-1
layerloop1:
	push bc
	ld b,$0C
	inc a
	ld (9872h),a
	call lcddelay
	out ($10),a
	call lcddelay
	ld a,$20
	out ($10),a
layerloop2:
	ld a,(hl)
	call lcddelay
	out ($11),a
	inc hl
	djnz layerloop2
	pop bc
	ld a,(9872h)
	djnz layerloop1
	ld a,$05
	call lcddelay
	out ($10),a
	ret
lcddelay:
	push af
lcddelayloop:
	in a,(2)
	and 2
	jr z,lcddelayloop
	pop af
	ret
Uninstalled:
	.db "VCalc disabled.",0
	.db "Press any key",0
Installed:
	.db "VCalc installed."
	.db "                "
	.db "To switch       "
	.db "between states, "
	.db "press ON+MODE   "
	.db "                "
	.db "                "
	.db " Press any key",0
putstring:
	ld a,(hl)
	inc hl
	or a
	ret z
	bcall(_putc)
	jr putstring
vputstring:
	ld a,(hl)
	inc hl
	or a
	ret z
	bcall(_vputmap)
	jr vputstring
ROMVersion:
	bcall(_clrlcdfull)
	ld hl,0
	ld (currow),hl
	ld hl,ROMERR
	call putstring
	ld de,1*256+7
	ld (currow),de
	call putstring
	bcall(_getkey)
	res onInterrupt,(iy+onFlags)
	jp exitapp
ROMERR:
	.db "Incompatible    "
	.db "with this ROM   "
	.db "version.",0
	.db "Press any key",0
CalcVersion:
	bcall(_clrlcdfull)
	ld hl,0
	ld (currow),hl
	ld hl,CalcERR
	call putstring
	ld de,1*256+7
	ld (currow),de
	call putstring
	bcall(_getkey)
	res onInterrupt,(iy+onFlags)
	jp exitapp
CalcERR:
	.db "A TI-83+ Silver "
	.db "Edition is      "
	.db "required to run "
	.db "VCalc.",0
	.db "Press any key",0
Splash_DS:
	.db $07,$3D,$E6,$3B,$5E,$E0,$E6,$63,$5E,$F3,$38,$E0
	.db $06,$B0,$CD,$63,$58,$D1,$8D,$63,$4C,$66,$B5,$80
	.db $06,$B8,$CF,$63,$DC,$D0,$CD,$63,$4C,$66,$B4,$C0
 	.db $06,$B0,$CD,$63,$58,$D0,$6D,$63,$4C,$66,$B4,$60
	.db $07,$3C,$CD,$3B,$5E,$E1,$C6,$79,$8C,$F3,$35,$C0
Splash_W:
	.db 1,16
	.db %10001000,%00100000
Splash_Web:
	.db "web: www.detacheds.com",0
Pause:
	ei \ halt
	djnz Pause
Dummy:
	ret
Title:
	.db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
	.db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
 	.db $00,$00,$C6,$00,$00,$00,$00,$1E,$00,$00,$00,$00
	.db $00,$00,$C6,$00,$00,$00,$00,$3E,$00,$00,$00,$00
	.db $00,$00,$C6,$DE,$7B,$67,$30,$70,$73,$0F,$00,$00
	.db $00,$00,$C6,$DF,$7B,$6F,$B0,$60,$FB,$1F,$00,$00
	.db $00,$00,$6C,$DB,$33,$6D,$B0,$60,$DB,$18,$00,$00
	.db $00,$00,$6C,$DE,$33,$6F,$B0,$60,$FB,$18,$00,$00
	.db $00,$00,$6C,$DF,$33,$6F,$B0,$70,$FB,$18,$00,$00
	.db $00,$00,$38,$DB,$33,$ED,$BC,$3E,$DB,$DF,$00,$00
 	.db $00,$00,$38,$DB,$31,$CD,$BC,$1E,$DB,$CF,$00,$00
Title_Junk:
	.db "By: Michael Vincent",0
	.db "Version 1.0 - 08/18/01",0
	.db "Press Any Key",0
AppVectors:
	.dw Dummy
	.dw Dummy
	.dw AppPutAway
	.dw Dummy
	.dw Dummy
	.dw Dummy
	.db appTextSaveF
AppPutAway:
	res bufferonly,(iy+plotflags)
	res textwrite,(iy+sgrflags)
	bcall(_grbufclr)
	bcall($4C36)
	ld (iy+textflags),0
	bit monabandon,(iy+monflags)
	jr nz,TurnOff
	ld a,%00001011
	out (3),a
	bcall(4978h)
	set 3,(iy+9)
	ei
	bjump(_jforcecmdnochar)
TurnOff:
	bjump(403Ch)
.end
