;The best libraries in the world! ; ; For the new TSE flash application ; ; By Michael Vincent, Alex Roper ; ; ;We'll put the jumps below near the start of the flash app, they'll ; become the entry points #define tempbyte saferam1+2 ;These are temp and never used at the same time #define tempword saferam1 #define smallinputlen saferam1 #define smallinputmax saferam1+1 jp LibRandom jp LibputSprite jp LiblargeSprite jp LibgetPixel jp LibFastCopy jp Libdetect jp Libdecompress jp LibDirectInput jp LibAppVersion jp LibSetPixel jp LibFastCopyS jp LibDelay jp LibPixelOnHL jp LibPixelOff jp LibPixelXor jp LibPixelTest jp LibPixelOffHL jp LibPixelXorHL jp LibPixelTestHL jp LibCenterText jp LibPutSprite8 jp LibFastCopyB jp LibVputsc jp LibScrollD7 jp LibCompStrs jp LibNextStr jp LibDisp3Spaces jp LibVputA jp LibCompStrsN jp LibGetChecksum jp LibMultHE jp LibMultHL jp LibCpHLDE jp LibDelProg jp LibCpHLBC jp LibArcProg jp LibSwapRam jp LibSendbytetios jp LibPointOnC jp LibPointOffC jp LibPointXorC jp LibVnewline jp LibRand127 jp LibLargeSpriteHL jp LibVatSwap jp LibInvertScreen jp LibROMVersion jp LibShiftScreen jp LibScnClr jp LibUninvtxt jp LibInvtxt jp LibDisPause jp LibDispPauseCsc jp LibCSCPause jp LibLenStr jp LibLibCall jp LibGetCalcID jp LibCheckBatteries jp LibTextDecompress jp LibPicDecompress jp LibDispCPic jp LibSetVPuts jp LibDisprlel jp LibDispCompTextP jp LibDispCompTextV jp LibGetnext jp LibGettext LibRand127: ld b,128 LibRandom: push hl push de ld hl,(randData) ld a,r ld d,a ld e,(hl) add hl,de add a,l xor h ld (randData),hl sbc hl,hl ld e,a ld d,h randomLoop: add hl,de djnz randomLoop ld a,h pop de pop hl ret LibputSprite: 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) xor d ld (hl),a inc hl ld a,(hl) xor e ld (hl),a ld de,$0B add hl,de inc ix djnz putSpriteLoop1 ret LibLargeSpriteHL: ld a,h LiblargeSprite: di ex af,af' ld a,c push af ex af,af' 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 largeSpriteLoop1: push hl largeSpriteLoop2: ld d,(ix) ld e,$00 ld a,c or a jr z,largeSpriteSkip1 largeSpriteLoop3: srl d rr e dec a jr nz,largeSpriteLoop3 largeSpriteSkip1: ld a,(hl) xor d ld (hl),a inc hl ld a,(hl) xor e ld (hl),a inc ix ex af,af' dec a push af ex af,af' pop af jr nz,largeSpriteLoop2 pop hl pop af push af ex af,af' ld de,$0C add hl,de djnz largeSpriteLoop1 pop af ret LibgetPixel: ld d,$00 ld h,d ld l,e add hl,de add hl,de add hl,hl add hl,hl ld de,gbuf add hl,de ld b,$00 ld c,a and %00000111 srl c srl c srl c add hl,bc ld b,a inc b ld a,%00000001 getPixelLoop: rrca djnz getPixelLoop ret LibFastCopy: ;Tested, approved di ld a,$80 ; 7 out ($10),a ; 11 ld hl,plotsscreen-12-(-(12*64)+1) ; 10 ld a,$20 ; 7 ld c,a ; 4 inc hl ; 6 waste dec hl ; 6 waste fastCopyAgain: ld b,64 ; 7 inc c ; 4 ld de,-(12*64)+1 ; 10 out ($10),a ; 11 add hl,de ; 11 ld de,10 ; 10 fastCopyLoop: add hl,de ; 11 inc hl ; 6 waste inc hl ; 6 waste inc de ; 6 ld a,(hl) ; 7 out ($11),a ; 11 dec de ; 6 djnz fastCopyLoop ; 13/8 ld a,c ; 4 cp $2B+1 ; 7 jr nz,fastCopyAgain ; 10/1 ret ; 10 Libdetect: ld de,(ptemp) bcall(_cphlde) ld a,(hl) jr nz,detectContinue inc a ret detectContinue: push hl and $01 jr nz,detectSkip dec hl dec hl dec hl ; hl->lsb ptr ld e,(hl) dec hl ld d,(hl) dec hl ; hl->page ld a,(hl) or a push af ld h,d ld l,e ; hl & de->program jr z,detectNoMove push hl bcall(_memfree) ld bc,64 sbc hl,bc pop hl jr c,detectNotEnough ld de,($9820) push ix push hl push de bcall(_flashToRam) pop hl push hl pop ix ld a,10 add a,(ix+9) ld e,a ld d,0 ; de=flash offset add hl,de ex (sp),hl add hl,de pop de ex de,hl ; hl-temp, de-perm pop ix detectNoMove: inc de inc de ld c,(hl) inc hl ld b,(hl) inc hl ; hl->data in ram push bc push ix pop bc detectCheck: ld a,(bc) or a jr z,detectFound cp (hl) inc bc inc de inc hl jr z,detectCheck detectBad: pop bc detectNotEnough: pop af detectSkip: pop hl ld bc,-6 add hl,bc ld b,(hl) dec hl detectNameLoop2: dec hl djnz detectNameLoop2 jr detect detectFound: pop hl ; hl=size, de->data pop af ; a=page, f=(or a) jr z,detectInRam push de ; data push af push hl bcall(_enoughRam) pop bc jr c,detectBad pop af pop hl ld de,($9820) ; tempMem push de bcall(_flashToRam) pop de detectInRam: ; de->data in RAM pop hl ; hl->vat location ld bc,-6 add hl,bc ld b,(hl) inc b detectNameLoop1: dec hl djnz detectNameLoop1 ex de,hl xor a ret Libdecompress: di decompressLoop: push bc ld a,(hl) ex af,af' ld a,c ld b,8 cp 1 jr z,dcmp1 ld b,4 cp 3 jr z,dcmp1 ld b,2 dcmp1: push bc ld a,c ld b,1 cp 1 jr z,dcmp2 inc b cp 3 jr z,dcmp2 ld b,4 dcmp2: ex af,af' dcmp3: rlca djnz dcmp3 ld b,a ex af,af' ld a,b and c ld (de),a inc de pop bc djnz dcmp1 inc hl pop bc djnz decompressLoop ret LibDirectInput: ld b,a ld a,$ff out (1),a ld a,b out (1),a in a,(1) ret LibAppVersion: ;Tested, approved ld hl,1*256+1 xor a ret LibSetPixel: call LibgetPixel or (hl) ld (hl),a ret LibFastCopyS: ;Tested, approved push af push bc push de push hl call LibFastCopy pop hl pop de pop bc pop af ret LibDelay: ;Tested, approved ei delayhalt: halt djnz delayhalt ret LibPixelOnHL: ld a,h ld e,l call LibgetPixel or (hl) ld (hl),a ret LibPixelOffHL: ld a,h ld e,l LibPixelOff: call LibgetPixel cpl and (hl) ld (hl),a ret LibPixelXorHL: ld a,h ld e,l LibPixelXor: call LibgetPixel xor (hl) ld (hl),a ret LibPixelTestHL: ld a,h ld e,l LibPixelTest: call LibgetPixel and (hl) ret LibCenterText: push hl ld (penrow),a xor a ld (tempbyte),a centerloop: ld a,(hl) or a jr z,centerloopover push hl ld h,0 ld l,a add hl,hl add hl,hl add hl,hl bcall(_sfont_len) ld b,a ld a,(tempbyte) add a,b ld (tempbyte),a pop hl inc hl jr centerloop centerloopover: ld a,(tempbyte) ld b,a ld a,48 sra b sub b ld (pencol),a pop hl bcall(_vputs) ret LibPutSprite8: ld b,8 jp LibputSprite LibFastCopyB: ;Tested, approved di ld a,$80 ; 7 out ($10),a ; 11 ld bc,767 add hl,bc ld a,$20 ; 7 ld c,a ; 4 inc hl ; 6 waste dec hl ; 6 waste fastCopyAgainB: ld b,64 ; 7 inc c ; 4 ld de,-(12*64)+1 ; 10 out ($10),a ; 11 add hl,de ; 11 ld de,10 ; 10 fastCopyLoopB: add hl,de ; 11 inc hl ; 6 waste inc hl ; 6 waste inc de ; 6 ld a,(hl) ; 7 out ($11),a ; 11 dec de ; 6 djnz fastCopyLoopB ; 13/8 ld a,c ; 4 cp $2B+1 ; 7 jr nz,fastCopyAgainB ; 10/1 ret LibVputsC: ld a,(iy+20) push af push hl set 7,(iy+20) bcall(_vputs) pop hl res 7,(iy+20) bcall(_vputs) pop af ld (iy+20),a ret LibScrollD7: ld de,plotsscreen+767 ld hl,plotsscreen+767-85 ld bc,768-84 lddr ld b,84 ld hl, plotsscreen+767 xor a clrloop: ld (hl), a dec hl djnz clrloop ret LibCompStrs: ld a,(de) ld c,(hl) or a jr z,comparegood cp c jr nz,comparefailed inc hl inc de jr LibCompStrs comparegood: xor a ret comparefailed: ld a,1 or a ret LibNextStr: ld bc,-1 xor a cpir ret LibDisp3Spaces: ld a,$20 bcall(_vputmap) ld a,$20 bcall(_vputmap) ld a,$20 bcall(_vputmap) ret LibVPutA: ld b,a ld a,(iy+20) push af set 7,(iy+20) ld a,b push af bcall(_vputmap) pop af res 7,(iy+20) bcall(_vputmap) pop af ld (iy+20),a ret LibCompStrsN: ld a,(de) ld c,(hl) cp c jr nz,comparehasfailed inc hl inc de djnz LibCompStrsN xor a ret comparehasfailed: ld a,1 or a ret LibGetChecksum: ex de,hl ld hl,0 checksum_loop: ld a,(de) push de ld d,0 ld e,a add hl,de pop de inc de dec bc ld a,b or c jr nz,checksum_loop ret LibCpHLDE: bcall(_cphlde) ;Can't get easier than this! :) ret MovHLVATToOP1: ;Internal use. Converts MirageOS's HL pointer ; to VAT entry into a program name in OP1 bcall(_zeroop1) ld de,op1 ld a,(hl) and $1ff ld (de),a ld bc,-6 add hl,bc ld a,(hl) ld b,a ld de,op1+1 dec hl loadnameintoop1: ld a,(hl) ld (de),a dec hl inc de djnz loadnameintoop1 ret LibDelProg: call MovHLVATToOP1 bcall(_chkfindsym) bcall(_delvararc) ret LibCpHLBC: push de push bc ld d,b ld e,c bcall(_cphlde) pop bc pop de ret LibArcProg: call MovHLVATToOP1 AppOnErr(arc_err) bcall(_Arc_UnArc) AppOffErr() arc_err: ret LibSwapRam: push bc ld a,(de) ld c,(hl) ld (de),c ld (hl),a inc hl inc de pop bc dec bc ld a,b or c jr nz,LibSwapRam ret LibSendbytetios: AppOnErr(linkerr) bcall(_sendabyte) AppOffErr() xor a linkerr: ld a,1 or a ret LibGetbytetios: AppOnErr(linkerr) bcall(_recabyteio) AppOffErr() ld b,a xor a ld a,b ret LibPointOnC: push af cp 95 jr nc,clippedohno ld a,e cp 63 jr nc,clippedohno pop af call LibgetPixel or (hl) ld (hl),a ret clippedohno: pop af ret LibPointOffC: push af cp 95 jr nc,clippedohno ld a,e cp 63 jr nc,clippedohno pop af call LibgetPixel cpl and (hl) ld (hl),a ret LibPointXorC: push af cp 95 jr nc,clippedohno ld a,e cp 63 jr nc,clippedohno pop af call LibgetPixel xor (hl) ld (hl),a ret LibVnewline: xor a ld (pencol),a ld a,(penrow) add a,7 cp 58 jr c,noscrolldown call LibScrollD7 ld a,56 ld (penrow),a noscrolldown: ld (penrow),a ret LibVatSwap: ret LibInvertScreen: :Tested, approved (lightning fast!) ld b,192 ld hl,plotsscreen invertloop: ;I unrolled the loop here to speed it up. ld a,(hl) cpl ld (hl),a inc hl ld a,(hl) cpl ld (hl),a inc hl ld a,(hl) cpl ld (hl),a inc hl ld a,(hl) cpl ld (hl),a inc hl djnz invertloop ret LibROMVersion: ;Tested, approved bcall(_getbasever) ld h,a ld l,b ret LibGenerateSound: ;Tested, approved di ld e,$D0 beepl1: ld a,c beepl2: dec a jr nz,beepl2 ld a,e xor %00000011 ld e,a out (0),a djnz beepl1 ei ret LibShiftScreen: ;Tested, approved add a,$40 push af inc hl dec hl pop af push af \ pop af out ($10),a ret LibMultHE: ;Tested, Approved (also h=0 bug caught) ld l,e LibMultHL: ;Tested, Approved (also h=0 bug caught) push bc push af push de xor a cp h jr z,lib_multhl_itszero ;The bcall can't handle h as 0 bcall(_HTimesL) Lib_multhl_zero_reentry: pop de pop af pop bc ret Lib_multhl_itszero: ld hl,$0000 jr lib_multhl_zero_reentry LibScnClr: ;Tested, Approved xor a ld (currow),a ld (curcol),a ld (pencol),a ld (penrow),a bcall(_GrBufClr) bcall(_ClrLCDFull) ret LibUninvtxt: ;Tested, Approved res textInverse, (iy+textFlags) ret LibInvtxt: ;Tested, Approved ld a, (iy+textflags) ld b, 8 xor b ld (iy+textflags), a ret LibDisPause: ;Tested, Approved bcall(_PutS) bcall(_GetKey) ret LibDisPauseCsc: ;Tested, Approved bcall(_PutS) LibCSCPause: ;Tested, Approved bcall(_GetCSC) or a jr z,LibCSCPause ret LibLenStr: ;Tested, Approved xor a push hl LibLenStr_loop: cp (hl) jr z,LibLenStr_done inc hl jr LibLenStr_loop LibLenStr_done: pop de sbc hl,de ld a,l ret Lib_Pop3Ret: ;Not for user use, for other calls use pop hl pop hl pop hl ret LibLibCall: push af rst 20h bcall(_chkfindsym) ret c ex de,hl inc hl inc hl inc hl inc hl inc hl ld de,extlibdetect ld b,6 call LibCompStrsN or a ret nz pop af ld b,a ld de,3 libgothrough: add hl,de djnz libgothrough jp (hl) extlibdetect: .db $DD,$E3,$DD,$E5,$C9 LibGetCalcID: ;Tested and approved push hl ld hl,IDListname rst 20h rst 10h jr c,idlistnotfound ex de,hl inc hl inc hl inc hl inc hl pop de ld bc,7 ldir dec de ld h,d ld l,e dec hl ld c,(hl) ld a,(de) ld (hl),a ld a,c ld (de),a xor a ret idlistnotfound: ld a,1 pop hl or a ret IdListname: .db $01,$5D,$40,$00 LibCheckBatteries: ;Tested and approved bit 5,(iy+$18) ret LibTextDecompress: ;Tested and approved! ld a,(hl) or a jr z,finisheddecomp cp $81 jr c,Normalchar sub $81 push hl push de ld hl,txttable ld d,0 sla a ld e,a add hl,de ld a,(hl) ld b,a inc hl ld a,(hl) pop de pop hl inc de ld (de),a dec de ld a,b ld (de),a inc de inc hl \ inc de jr LibTextDecompress Normalchar: ld (de),a inc de \ inc hl jr LibTextDecompress finisheddecomp: xor a ld (de),a ret txttable: .db "is","nt","he","ei","et","ea","ay","as","or","nd" .db "it","er","in","on","pa","ar","um","el","e.","ic" .db "e!","ey","ss","mm","en","ll","ro","od","hi","go" .db "at","to","ad","am","an","ax","be","by","cc","co" .db "s.","g.","t:","do","ha","he","hp","id","if","me" .db "io","se","op","sh","ng","wa","xt","ta","..","ib" .db "rt","e?","r.","pi","ma","th","Mi","Bu","Ex","Fi" .db "Te","Ca","lc","ul","li","br","Al","ex","Ro","pe" .db "r.","Er","nc","e ","s ","r ","Da","n ","En","gl" .db "de","Ja","n ","Ko","va","cs","te","st","Th","lo" .db "Se","He" LibPicDecompress: ;Tested, approved ld bc,0 ld (tempword),bc jr picdecomploop picdecompstart: inc hl picdecomploop: ld a,(hl) cp $91 jr z,isrun ld (de),a inc de \ inc hl ld bc,(tempword) inc bc ld (tempword),bc ld a,(tempword+1) cp 3 jr nz,picdecomploop ret isrun: inc hl ld a,(hl) inc hl ld c,(hl) ld b,c push hl ld hl,(tempword) runfillloop: ld (de),a inc de inc hl djnz runfillloop ld (tempword),hl pop hl ld a,(tempword+1) cp 3 jr nz,picdecompstart ret LibDispCPic: ;Tested, approved ld de,plotsscreen call LibPicDecompress jp LibFastCopy LibSetVPuts: ld (pencol),de bcall(_vputs) ret LibDisprlel: ;Tested, approved ld (tempword),bc jr picdecomploop2 picdecompstart2: inc hl picdecomploop2: ld a,(hl) cp $91 jr z,isrun2 ld (de),a inc de \ inc hl ld bc,(tempword) dec bc ld (tempword),bc ld a,b or c jr nz,picdecomploop2 ret isrun2: inc hl ld a,(hl) inc hl ld c,(hl) ld b,c push hl ld hl,(tempword) runfillloop2: ld (de),a inc de dec hl djnz runfillloop2 ld (tempword),hl pop hl ld bc,(tempword) ld a,b or c jr nz,picdecompstart2 ret LibDispCompTxtP: ;Tested and approved! (destroys OP4-OP6) ld de,OP4 call LibDecompressText ld hl,OP4 bcall(_puts) ret LibDispCompTxtV: ;Tested and approved! (destroys OP4-OP6) ld de,OP4 call LibTextDecompress ld hl,OP4 bcall(_vputs) ret LibGetnext: ;Tested, approved ld bc,(pTemp) or a sbc hl,bc jr c,nextvatentryover jr z,nextvatentryover add hl,bc ld de,-6 add hl,de ld a,(hl) ld d,0 ld e,a or a sbc hl,de dec hl ret nextvatentryover: xor a ret LibGettext: xor a ld (smallinputlen),a ld a,b ld (smallinputmax),a ld a,(pencol) ld (tempbyte),a push hl call XORSmallCursor pop ix smallinputloop: ei \ halt bcall(_getcsc) or a jr z,smallinputloop cp skEnter jp z,smallinputdone cp skLeft jr z,smallinputbackspace cp skClear jr z,smallinputrestart ld d,0 ld e,a in a,(4) bit 3,a jr z,altkeyboard ld hl,chartable-10 jr consmalli altkeyboard: ld hl,chartable2-10 consmalli: add hl,de ld a,(hl) or a jr z,smallinputLoop ld (ix),a inc ix push ix push af call XORSmallCursor pop af bcall(_vputmap) call XORSmallCursor pop ix ld hl,smallinputlen inc (hl) ld a,(smallinputmax) ld b,a ld a,(smallinputlen) cp b jr nz,smallinputloop jr smallinputdone smallinputbackspace: ld a,(smallinputlen) or a jr z,smallinputLoop dec a ld (smallinputlen),a call XORSmallCursor dec ix ld a,(pencol) sub 4 ld (pencol),a push af push ix ld a,$06 bcall(_vputmap) ld a,$06 bcall(_vputmap) pop ix pop af ;dec a ld (pencol),a call XORSmallCursor jp smallinputloop smallinputdone: call XORSmallCursor res onInterrupt,(iy+onFlags) ret smallinputrestart: ld a,(smallinputlen) or a jp z,smallinputloop call XORSmallCursor ld a,(smallinputlen) ld b,a simovbackix: dec ix djnz simovbackix ld a,(tempbyte) ld b,a ld a,(pencol) sub b ld a,b ld (pencol),a push ix siclrloop: ld a,$20 push bc bcall(_vputmap) pop bc djnz siclrloop pop ix ld a,(tempbyte) ld (pencol),a call XORSmallCursor xor a ld (smallinputlen),a jp smallinputloop XORSmallCursor: push ix ld a,(penrow) ld b,a ld a,63 sub b ld c,a sub 5 ld e,a ld a,(pencol) ld b,a ld d,b ld h,2 bcall(_iline) pop ix ret .db 0,0,0,0,0,0,0,0,0,0,0 chartable: .db 0,"WRMH",0 .db 0,0,0,"VQLG",0,0,0,"ZUPKFC" .db 0,0,"YTOJEBX",0,"XSNIDA" .db 0,0,0,0,0,0,0,0,0,0,0,0 .db 0,0,0,0,0,0,0,0 chartable2: .db 0,0,0,0,0,0 .db 0,0,"369",0,0,0,0,0,"258",0,0,0 .db 0,"0147",0,0,0,0,0,0,0,0,0,0,0 .db 0,0,0,0,0,0,0,0,0,0,0,0 .db 0,0,0,0,0,0,0,0 sfontwidthtable: ;first entry is for $01 .db 5,3,3,3,3,3,5 .db 3,3,3,3,3,3,3,4 .db 3,4,3,3,4,4,3,4 .db 5,4,3,3,4,5,3,3 .db 1,1,3,5,5,3,4,1 .db 2,2,5,3,2,3,1,3 .db 3,3,3,3,3,3,3,3 .db 3,3,1,2,3,3,3,3 .db 5,3,3,3,3,3,3,3 .db 3,3,3,3,3,3,3,3 .db 3,3,3,3,3,3,3,3 .db 3,3,3,3,3,2,3,3 .db 2,3,3,3,3,3,2,3 .db 3,1,3,3,2,5,3,3 .db 3,3,3,2,2,3,3,5 .db 3,3,4,3,1,3,4,3 .db 3,2,3,3,3,3,3,3 .db 3,3,4,4,4,4,4,4 .db 4,4,4,4,3,3,3,3 .db 3,3,3,3,3,3,3,3 .db 3,3,5,5,5,5,5,5 .db 5,5,3,3,3,3,4,4 .db 4,4,3,3,4,4,2,2 ;ends at $B7