Login [Register]
Don't have an account? Register now to chat, post, use our tools, and much more.
Please post any useful ASM routines here, citing the original author if it isn't you. Follow the format.

Wow, that worked! Thanks for the help, Tari. For anyone else, here's the routine.

RunBASICProgram
Originally made by Dan E. Bugfixes and optimizations by Kerm Martian. This routine allows you to run BASIC programs from an App.
Inputs
Op1 = name of variable to parse [eg program to run]
You also need to define three bytes of saveRAM, homeSaveA (1 byte) and homeSaveHL (2 bytes).

Outputs
Program is parsed and run. Any homescreen hooks present before the routine are called are restored.
b = 0 for an error, errorcode otherwise.

Destroyed:
All

Code:

Code:
_SetHomeHook equ 4FABh
_ClrHomeHook equ 4FAEh
apiFlg2 equ 41
sysHookFlg equ 52
appInpPrmptInit equ 0
appInpPrmptDone equ 1
appWantHome equ 4

_saveCmdShadow equ 4573h
_saveShadow equ 4576h
_rstrShadow equ 4579h

cmdExec equ 6
cmdFlags equ 12
cxExtApps equ 058h

RunBASICProgram:
   in a,(2)
   rla
   sbc a,a
   out (20h),a
   xor    a
   ld     (HomeSaveA),a
   bit    appWantHome,(iy+sysHookFlg)
   jr     z,NoHookToSave
   ld     hl,(9B8Ch)
   ld     (HomeSaveHL),hl
   ld     a,(9B8Eh)
   ld     (HomeSaveA),a
NoHookToSave:
   in     a,(6)
   ld     hl,HookAddr
   bcall(_SetHomeHook)
   set    progExecuting,(iy+newDispF)
   set    cmdExec,(iy+cmdFlags)
   AppOnErr(ErrorHandler)
   bcall(_ParseInp)
   AppOffErr
   xor a
ErrorHandler:
   push af
   bcall(_ReloadAppEntryVecs)
   res    progExecuting,(iy+newDispF)
   res    cmdExec,(iy+cmdFlags)
   pop bc
FinishCont:
   push bc
   bcall(_ClrHomeHook)
   bcall(_ForceFullScreen)
   res AppWantHome,(iy+sysHookFlg)
   pop bc
RestoreHookStuff:
   push bc
   ld     a,(HomeSaveA)
   or     a
   pop bc
   ret    z
   push bc
   ld     a,(HomeSaveA)
   ld     hl,(HomeSaveHL)
   bcall(_SetHomeHook)
   set AppWantHome,(iy+sysHookFlg)
   pop bc
   ret
       
HookAddr:
   add    a,e
   cp     3
   ret nz
   bit    appInpPrmptDone,(iy+apiFlg2)
   res    appInpPrmptDone,(iy+apiFlg2)
   ld b,0
   jr     z,FinishCont
   bcall(_ReloadAppEntryVecs)
   ld     hl,appvecs
   bcall(_AppInit)
   or     1
   ld     a,cxExtApps
   ld     (cxCurApp),a
   ret
appvecs:
   .dw     dummyret
   .dw     saveshad
   .dw     putway
   .dw     rdisp
   .dw     dummyret
   .dw     dummyret
rdisp:
   bcall(_RstrShadow)
dummyret:
   ret
saveshad:
   bcall(_SaveShadow)
   ret
putway:
   xor    a
   ld     (currLastEntry),a
   bit    appInpPrmptInit,(iy+apiFlg2)
   jr     nz,aipi
   bcall(_ClrHomeHook)
   bcall(_ForceFullScreen)
aipi:
   bcall(_ReloadAppEntryVecs)
   bcall(_PutAway)
   ld b,0
   jr     RestoreHookStuff
Somehow I missed this topic (I guess when I was on vacation).

Ultimate Arrow Key Input
Worked out by a combination of myself and DarkerLiner in response to a BASIC programmer wanting to be able to detect multiple arrow keypresses. Detects all 16 possible combinations and returns them in a useful form.

Inputs
Nothing

Outputs
a =
-------------------------------------
0 = %0000 = no arrows pressed
1 = %0001 = down
2 = %0010 = left
3 = %0011 = left + down
4 = %0100 = right
5 = %0101 = right + down
6 = %0110 = right + left
7 = %0111 = right + left + down
8 = %1000 = up
9 = %1001 = up + down
10 = %1010 = up + left
11 = %1011 = up + left + down
12 = %1100 = up + right
13 = %1101 = up + right + down
14 = %1110 = up + right + left
15 = %1111 = all four keys pressed

Destroyed
A

Code:
Code:
getArrowKeys:
  ld a,$FE
  out (1),a
  nop
  nop
  in a,(1)
  cpl
  ret
Heh, nice one.

Masked Sprite Routine
This is a routine by me, modified from IonPutSprite.

Inputs:
ix = b-byte mask
ix+b = b-byte sprite
a,l = x and y as with IonPutSprite
b= height of sprite

Outputs:
Sprite masked to screen

Destroyed:
All

Code:

Code:
iPutSpriteMask:
   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
iPutSpriteLoop1Mask:
   ld   d,(ix)
   ld   e,$FF
   ld   a,c
   or   a
   jr   z,iPutSpriteSkip1Mask
iPutSpriteLoop2Mask:
   srl   d
   rr   e
   set 7,d
   dec   a
   jr   nz,iPutSpriteLoop2Mask
iPutSpriteSkip1Mask:
   ld   a,(hl)
   and   d
   ld   (hl),a
   inc   hl
   ld   a,(hl)
   and   e
   ld   (hl),a
   push ix
   dec hl
   ld de,8
   add ix,de
iPutSpriteLoop1AND:
   ld   d,(ix)
   ld   e,$00
   ld   a,c
   or   a
   jr   z,iPutSpriteSkip1AND
iPutSpriteLoop2AND:
   srl   d
   rr   e
   dec   a
   jr   nz,iPutSpriteLoop2AND
iPutSpriteSkip1AND:
   ld   a,(hl)
   xor   d
   ld   (hl),a
   inc   hl
   ld   a,(hl)
   xor   e
   ld   (hl),a

   pop ix
   ld   de,$0B
   add   hl,de
   inc   ix
   djnz   iPutSpriteLoop1Mask
   ret
Fast Vertical Line

Input:
a

Output:
Vertical line at a

Destroys:
af,bc,de,hl


Code:
 ld hl,plotsscreen
 ld d,0
 ld e,a
 srl e
 srl e
 srl e
 add hl,de
 and $07
 ld b,a
 inc b
 ld a,1
vertloop1:
 rrca
 djnz vertloop1
 ld c,a
 ld b,64
 ld e,12
vertloop2:
 ld a,c
 or (hl)
 ld (hl),a
 add hl,de
 djnz vertloop2
 ret
Fast Horizontal Line
Optimized version of calc84maniac's fast horizontal line. Considering A cannot be more than 63 (last row), 63*3 still fits in 8 bits, so we can just use a, as it goes faster.

Input:
a

Output:
Horizontal line at a

Destroys:
bc,hl


Code:
 ld l,a
 ld h,0
 add a,a     
 add a,l       
 ld l,a                     
 add hl,hl     
 add hl,hl     
 ld bc,plotsscreen
 add hl,bc
 ld b,12
horizloop:
 ld (hl),%11111111
 inc hl
 djnz horizloop
 ret


Chipmaster: Since this is a more optimized version of calc84maniac's routine, this is going to stay. calc84maniac will receive credit when a final list is compiled.
PutSprite10

PutSprite8 I modified to PutSprite10. Might be useless for you, but if you have some slightly larger than 8 sprites, then you can use PutSprite10. As it is faster than PutSprite16 and allows you not to destroy shadow registers too, and run interrupts during, and smaller. So if you have unconventional sprite size...

Input:
L=Y coordinates
A=X coordinates
b=height of sprite
ix=sprite location. IX+1 being the other 2 bits

Output:
IX=data after the sprite's data

Destroyed
b


Code:
putsprite_10_bits:
   ld   e,l
   ld   h,00h
   ld   d,h
   add   hl,de
   add   hl,de
   add   hl,hl
   add   hl,hl
   ld   e,a
   and   07h
   ld   c,a
   srl   e
   srl   e
   srl   e
   add   hl,de
   ld   de,plotSScreen
   add   hl,de
putSprite10Loop1:
   ld   d,(ix)
   ld   e,(ix+1)        ;modified this
   ld   a,c
   or   a
   jr   z,putSprite10Skip1
putSprite10Loop2:
   srl   d
   rr   e
   dec   a
   jr   nz,putSprite10Loop2
putSprite10Skip1:
   push    af    ;save carry. Will be 0 if bit
                ;was not destroyed or
                ;if you skipped loop2
   ld   a,(hl)
   xor   d
   ld   (hl),a
   inc   hl
   ld   a,(hl)
   xor   e
   ld   (hl),a
   pop af
   jr     nc,putSprite10skip3
   ld     a,(hl)
   xor   %10000000
   ld     (hl),a
putSprite10skip3:
   ld   de,0Bh
   add   hl,de
   inc   ix
   inc   ix                             ;added this
   djnz   putSprite10Loop1
   ret


Chipmaster: I have cleaned up the topic as many suggested. I also fixed up the formatting. From now on, can we try to keep to this format, and please only post if you have code to offer or suggestions to code already posted. Please don't be discouraged if your comments get deleted, it's nothing against you, but when this topic is done, it would be nice if we can have a continuous stream of routines.
Masked Sprite routine
This is a routine by me, as a response to Kerm's routine


Code:

    push ix
    dec hl
    ld de,8
    add ix,de
iPutSpriteLoop1AND:


Quote:
Inputs:
ix = b-byte mask
ix+b = b-byte sprite
a,l = x and y as with IonPutSprite
b= height of sprite


According to your code, it allows only 8-byte high sprites.

I have made a routine that does exactly the same, with the same base (Joe Wingbermuehle's Ion putSprite), and the same inputs.

Inputs:
a = X coordinate
b = Y coordinate
b= height of sprite
ix = sprite address
ix+b = mask address (same length as sprite, please)

Outputs:
Mask and then sprite displayed at specified location on the graph buffer

Destroys:
-AF, BC, DE, HL, IX, DE', HL' (shadow registers)

Improvements from Kerm's DCS version:
-Permits any height sprite
-4 bytes less
-Faster


Code:
PutMask:
   ld   e,l
   ld   h,000h
   ld   d,h
   add   hl,de
   add   hl,de
   add   hl,hl
   add   hl,hl
   ld   e,a
   and   007h
   ld   c,a
   srl   e
   srl   e
   srl   e
   add   hl,de
   ld   de,plotSScreen
   add   hl,de
   ld a,b               
   exx                   
   ld d,0             
   ld e,a
   push IX
   pop HL
   add hl,de
   ex de,hl               
   exx                   
putMaskLoop1:
   ld   d,(ix)
   ld   e,00h
   exx
   ld      h,0FFh
   ld      a,(de)
   ld      l,a
   inc de
   exx
   ld   a,c
   or   a
   jr   z,putMaskSkip1
putMaskLoop2:
   srl   d
   rr   e
   exx
   SCF
   rr l
   rr h
   exx
   dec   a
   jr   nz,putMaskLoop2
putMaskSkip1:
   ld   a,(hl)
   exx
   and l
   exx
   or   d
   ld   (hl),a
   inc   hl
   ld   a,(hl)
   exx
   and     h
   exx
   or   e
   ld   (hl),a
   ld   de,00Bh
   add   hl,de
   inc   ix
   djnz   putMaskLoop1
   ret
32 Bit division
Inputs: dehl=32-bit dividend, c=8-bit divisor (Or is it the other way around?)
Outputs: dehl=32-bit quotient, a=remainder, c=unchanged, b=0
Cycles: Ranges from about 1,900 to 2,000
Size: 17 bytes

Code:
div32bit:
 ld b,32
 xor a
divloop:
 add hl,hl
 rl e
 rl d
 rla
 cp c
 jr c,divlbl
 inc l
 sub c
divlbl:
 djnz divloop
 ret
Fallen Ghost: if you're sure your version is debugged, I'll use it instead of mine in DCS.
I use it in StarCalc for the cursor. As far as I have used it, it did not wrong me. Smile
the faster multiplication you can get....



Mult_A_D:
LD E,A
SUB D
LD H,MULTAB/256
LD L,A
LD C,(HL)
INC H
LD B,(HL)
LD A,E
ADD A,D
LD L,A
LD E,(HL)
DEC H
LD L,(HL)
LD H,E
OR A
SBC HL,BC
RET


MULTAB:
.DB 0, 0, 1, 2, 4, 6, 9, 12, 16, 20
.DB 25, 30, 36, 42, 49, 56, 64, 72, 81, 90
.DB 100, 110, 121, 132, 144, 156, 169, 182, 196, 210
.DB 225, 240, 0, 16, 33, 50, 68, 86, 105, 124
.DB 144, 164, 185, 206, 228, 250, 17, 40, 64, 88
.DB 113, 138, 164, 190, 217, 244, 16, 44, 73, 102
.DB 132, 162, 193, 224, 0, 32, 65, 98, 132, 166
.DB 201, 236, 16, 52, 89, 126, 164, 202, 241, 24
.DB 64, 104, 145, 186, 228, 14, 57, 100, 144, 188
.DB 233, 22, 68, 114, 161, 208, 0, 48, 97, 146
.DB 196, 246, 41, 92, 144, 196, 249, 46, 100, 154
.DB 209, 8, 64, 120, 177, 234, 36, 94, 153, 212
.DB 16, 76, 137, 198, 4, 66, 129, 192

.DB 0, 192, 129, 66, 4, 198, 137, 76, 16, 212
.DB 153, 94, 36, 234, 177, 120, 64, 8, 209, 154
.DB 100, 46, 249, 196, 144, 92, 41, 246, 196, 146
.DB 97, 48, 0, 208, 161, 114, 68, 22, 233, 188
.DB 144, 100, 57, 14, 228, 186, 145, 104, 64, 24
.DB 241, 202, 164, 126, 89, 52, 16, 236, 201, 166
.DB 132, 98, 65, 32, 0, 224, 193, 162, 132, 102
.DB 73, 44, 16, 244, 217, 190, 164, 138, 113, 88
.DB 64, 40, 17, 250, 228, 206, 185, 164, 144, 124
.DB 105, 86, 68, 50, 33, 16, 0, 240, 225, 210
.DB 196, 182, 169, 156, 144, 132, 121, 110, 100, 90
.DB 81, 72, 64, 56, 49, 42, 36, 30, 25, 20
.DB 16, 12, 9, 6, 4, 2, 1, 0

.DB 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
.DB 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
.DB 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
.DB 0, 0, 1, 1, 1, 1, 1, 1, 1, 1
.DB 1, 1, 1, 1, 1, 1, 2, 2, 2, 2
.DB 2, 2, 2, 2, 2, 2, 3, 3, 3, 3
.DB 3, 3, 3, 3, 4, 4, 4, 4, 4, 4
.DB 4, 4, 5, 5, 5, 5, 5, 5, 5, 6
.DB 6, 6, 6, 6, 6, 7, 7, 7, 7, 7
.DB 7, 8, 8, 8, 8, 8, 9, 9, 9, 9
.DB 9, 9, 10, 10, 10, 10, 10, 11, 11, 11
.DB 11, 12, 12, 12, 12, 12, 13, 13, 13, 13
.DB 14, 14, 14, 14, 15, 15, 15, 15

.DB 16, 15, 15, 15, 15, 14, 14, 14, 14, 13
.DB 13, 13, 13, 12, 12, 12, 12, 12, 11, 11
.DB 11, 11, 10, 10, 10, 10, 10, 9, 9, 9
.DB 9, 9, 9, 8, 8, 8, 8, 8, 7, 7
.DB 7, 7, 7, 7, 6, 6, 6, 6, 6, 6
.DB 5, 5, 5, 5, 5, 5, 5, 4, 4, 4
.DB 4, 4, 4, 4, 4, 3, 3, 3, 3, 3
.DB 3, 3, 3, 2, 2, 2, 2, 2, 2, 2
.DB 2, 2, 2, 1, 1, 1, 1, 1, 1, 1
.DB 1, 1, 1, 1, 1, 1, 1, 0, 0, 0
.DB 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
.DB 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
.DB 0, 0, 0, 0, 0, 0, 0, 0
Sure, lookup tables are faster, but they're huge. If you wanted, you could use such tables for every operations that wasn't adding or subtracting, but would you?
The Tari wrote:
Sure, lookup tables are faster, but they're huge. If you wanted, you could use such tables for every operations that wasn't adding or subtracting, but would you?
Seconded. That may be fast, but it's over 300 bytes.
yap but when space is not a requirement and we need speed, we can implement sutch algorithm like in my 3d engine... if you look well it will take exactly 100cycles for executing... all operations in the part of -64 to 64 by two operands... i have another version of this one that uses from -127 to 128...
MD5 calculation
Inputs: hl=start of data, bc=length of data
Outputs: MD5 hash is 16 bytes at MD5hash ($8292)

Code:
calcmd5:
 push hl
 push bc
 bcall md5init    ;$808D
 pop bc
 pop hl
 bcall md5update  ;$8090
 bcall md5final   ;$8018
 ret

Thanks to wikiti for the md5 info.
Yeah, thats not a useful routine either. Delete that crap, its just a bcall. Anybody can look up how to use bcalls, thats not something unique, cool, or useful
I had no idea ti included md5 in the calc o.O

weird. Razz
simple the MD5 is a protection sheme that ti implemented to verify if the OS we are transmitting to the calculator is from ti or not... that's the main reason althought they have implemented it on other stuff's....
Well those bcalls are UNDOCUMENTED, and it took me a long time to find them, so I'm doing all of you a favor and giving it to you. Smile
Undocumented, you say? Smile
http://wikiti.denglend.net/index.php?title=Category:83Plus:BCALLs:By_Name:Cryptography
  
Register to Join the Conversation
Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.

» Go to Registration page
Page 1 of 7
» All times are GMT - 5 Hours
 
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum