Login [Register]
Don't have an account? Register now to chat, post, use our tools, and much more.
Not bad at all! Your opcodes are shouting at me, though. Wink You can save zero bytes and a lot of cycles by switching:


Code:
    LD B, 17                            ;Seventeen bytes to advance, including the 0 
IncrementDE: 
    INC DE 
    DJNZ IncrementDE   
to

Code:
    ld hl,17                            ;Seventeen bytes to advance, including the 0 
    add hl,de
    ex de,hl
What do you mean by:
KermMartian wrote:
Your opcodes are shouting at me though

I really don't understand what you mean there. What I do understand is the optimisation code, and I'll fix it.Razz
I think Kerm is referring to your use of uppercase mnemonics (INC DE) whereas most people seem to prefer lowercase (inc de) these days.
Ah, I get it. That's what he meant by "shouting"XD.
arriopolis wrote:
Ah, I get it. That's what he meant by "shouting"XD.


I prefer shouting instructions IMHO Smile
Based on the examples in the official Texas Instruments documentation, it appears that programmers within TI also (at least used to) write in uppercase mnemonics, but the convention in the community is generally lowercase for some reason, so yes, I was noting the uppercaseness of your mnemonics. Smile At least you're using mnemonics instead of trying to make life hard for yourself with hEx.
Lol. Mimas also uses uppercase mnemonics...
Edit: Also, I found a routine for clipping large sprites....

Code:

;--------------------------------
;Clip Big Sprite
;by James Montelongo
;MAX SIZE: 64x64
;ix - Sprite
;b  - height
;c  - width in bytes
;d  - x
;e  - y
ClipBigSprite:
; Early out, Check if its even remotely on screen
   ld a,e
   cp 64
   ret p
   add a,b
   ret m
   ret z
   ld a,d
   cp 96
   ret p
   ld a,c
   add a,a
   add a,a
   add a,a
   add a,d
   ret m
   ret z
   ld a,e
   or a
   jp p,Check_clip_bottom
   neg
   push de
   ld hl,0
   ld d,l
   ld e,a
   bit 2,c
   jr z,$+2+1
   add hl,de
   add hl,hl   
   bit 1,c
   jr z,$+2+1
   add hl,de
   add hl,hl   
   bit 0,c
   jr z,$+2+1
   add hl,de
   pop de
   ex de,hl
   add ix,de      ;Here you can save the top offset
   ex de,hl
   ld e,0
   neg
   add a,b
   ld b,a
Check_clip_bottom:
   ld a,e
   add a,b
   sub 64
   jp m,Check_clip_Left
   neg
   add a,b
   ld b,a
Check_clip_Left: ; at this point you may want to save b
   xor a
   ld (bigskip),a
   ld a,Clipleftsize
   ld (Do_Clipleft),a
   ld a,d
   or a
   jp p,Check_clip_right
   cpl
   and $F8
   rra
   rra
   rra
   ex de,hl      ;save the clipped left offset
   ld e,a
   ld d,0
   add ix,de
   ld (bigskip),a
   ex de,hl
   inc a
   neg
   add a,c
   ld c,a
   xor a
   ld (Do_Clipleft),a
   ld a,d
   and $07
   ld d,a
Check_clip_right:
   ld a,Cliprightsize
   ld (Do_Clipright),a
   ld a,c
   add a,a
   add a,a
   add a,a
   add a,d
   sub 96
   jp m,Check_clip_middle
   and $F8
   rra
   rra
   rra
   ld l,a
   ld a,(bigskip)
   add a,l
   inc a
   ld (bigskip),a
   neg
   add a,c
   ld c,a
   xor a
   ld (Do_Clipright),a
Check_clip_middle: ; This is where C should be saved.
   xor a
   ld (Do_ClipMiddle),a
   ld a,c
   or a
   jp nz,dontskipmiddle
   ld a,ClipMiddlesize
   ld (Do_ClipMiddle),a
dontskipmiddle:
   ld l,e
   ld a,d   
   ld h,0
   ld d,h
   add hl,hl
   add hl,de
   add hl,hl
   add hl,hl
   ld e,a
   and $07
   xor 7
   ld (BigRot1),a
   ld (BigRot2),a
   ld (BigRot3),a
   add a,a
   ld (clipbigrot1),a
   ld a,$ff
clipbigrot1 = $+1
   jr $
   srl a
   srl a
   srl a
   srl a
   srl a
   srl a
   srl a
   srl e
   srl e
   srl e
   add hl,de
   ld de,gbuf
   add hl,de ; This is where gbuf offset should be saved.
   ld d,a
   cpl
   ld e,a ;masks should be saved to
BigSpriteRow:
   push bc
   push hl
   ld b,c
Do_Clipleft = $+1
   jr Clipleft
   ld a,(ix)
   inc ix
BigRot1 = $+1
   jr $
   rrca
   rrca
   rrca
   rrca
   rrca
   rrca
   rrca
BigMask0:
   and e
   or (hl)
   ld (hl),a
Clipleft:
Clipleftsize = Clipleft-(Do_Clipleft+1)
Do_ClipMiddle = $+1
   jr $+2
BigSpriteloop:
   ld a,(ix)
   inc ix
BigRot2 = $+1
   jr $
   rrca
   rrca
   rrca
   rrca
   rrca
   rrca
   rrca
   ld c,a
BigMask1:
   and d
   or (hl)
   ld (hl),a
   inc hl
   ld a,c
BigMask2:
   and e
   or (hl)
   ld (hl),a
   djnz BigSpriteloop
ClipMiddle:
ClipMiddlesize = ClipMiddle-(Do_ClipMiddle+1)
Do_ClipRight = $+1
   jr ClipRight
   ld a,(ix)
BigRot3 = $+1
   jr $
   rrca
   rrca
   rrca
   rrca
   rrca
   rrca
   rrca
BigMask3:
   and d
   or (hl)
   ld (hl),a
ClipRight:
Cliprightsize = ClipRight-(Do_ClipRight+1)
   pop hl
   ld bc,12 ;width of the screen
   add hl,bc
bigskip = $+1
   ld bc,0
   add ix,bc
   pop bc
   djnz BigSpriteRow
   ret
Yup, that's a good one,although it has a few small optimizations possible.
This post is relevant to debugging Arrio's Menu routine (from http://cemete.ch/p=142948#149248). It looks to me like the bcalls() or the flag manipulation are the two primary suspects for what's going wrong.
I tried re-setting the AppAutoScroll flag, but that's not the problem.
arriopolis wrote:
I tried re-setting the AppAutoScroll flag, but that's not the problem.
Is it possible that your program is accidentally overwriting some memory? Actually, do you have source for your minimal example with just the menu in it that I could test out and try to examine?
Here's the code you can examine.
It simply runs the menu and quits. It doesn't even check the option selected.Smile

Code:
.nolist
#include    "ti83plus.inc"
#define    ProgStart    $9D95
.list
.org    ProgStart - 2
    .db    t2ByteTok, tAsmCmp
;Flags:
;Asm_flag1: 0: RES = Output of menu in C
;              SET = Output of menu in L
;           1: RES = Display the first 8 lines of text in the mainscreen
;              SET = Display the last 8 lines of text in the mainscreen
;           2: RES = Van has not been entered yet
;              SET = Van has already been entered
;           3: RES = HelpMenu is off
;              SET = HelpMenu is on
MainMenu:
    CALL Menu
    .DB "      Mol:      ", 0   ;The menutitle (16 characters and a 0)
    .DB 4         ;The number of options
    .DB "Rekenschema   "   ;The first option
    .DB "Berekenen     "   ;The second option
    .DB "Credits       "        ;The fourth option
    .DB "Afsluiten     "   ;The third option
    RET
;-------------------------------------------------------------------------------------------

----------------------------------------
Menu:
;This routine will make a menu, almost the same as the TI-basic one.
;The screen will be cleared after this routine has been completed.
;INPUT: The text via the code stream.
;OUTPUT:
;    If bit 0, (IY + Asm_flag1) is reset, the output is in C
;    If bit 0, (IY + Asm_flag1) is set, the output is in L
    RES AppAutoScroll, (IY + AppFlags)   ;Keep the screen from rolling
    b_call(_ClrLCDFull)      ;Clear the screen
    CALL TextInverseOn      ;Set textinverse
    ld hl, $0000      ;Set cursor to (0,0)
    ld (CurRow), hl
    POP HL         ;Pop the address of the menutitle
    LD D, H         ;Store HL into DE
    LD E, L
    b_call(_PutS)      ;Display the menutitle
    CALL TextInverseOff      ;Reset textinverse
    LD B, 17         ;Seventeen bytes to advance, including the 0
IncrementDE:
    INC DE
    DJNZ IncrementDE

;Drawing the text
    LD HL, $0201      ;Load the cursor for the first string
    LD (CurRow), HL
    LD HL, CurCol      ;Load the address of the cursor in HL
    EX DE, HL         ;Load the address of the number of rows to be drawn into HL
    LD C, (HL)         ;Load that number into C
    PUSH BC         ;Save C, because we are going to need it once more
    INC HL         ;Load the address of the first character of the first option

in the menu
    LD B, 14         ;14 characters per string
DisplayText:
    LD A, (HL)         ;Load the first character of the string into A
    b_call(_PutC)      ;Display the character, and advance the cursor
    INC HL         ;Set the address for the next character
    DJNZ DisplayText      ;Repeat this 14 times
    EX DE, HL         ;HL = Address of cursor, DE = Address of MenuText
    LD (HL), 2         ;Set (CurCol) to 2
    EX DE, HL         ;HL = Address of MenuText, DE = Address of cursor
    LD B, 14         ;14 characters again.
    DEC C         ;Decline number of times to repeat this
    JR NZ, DisplayText      ;If the number of times to repeat this <> 0, repeat this
    POP BC         ;Restore C, the number of options in the menu
    PUSH HL         ;Store the address to jump to after the procedure has ended
    ld b, c         ;Store the number of options into B
    ld h, b         ;Save this number in h

;Drawing the numbers next
DrawNumbersComplete:
    ld c, 1                     ;C keeps track of the current option selected
DrawNumbersSet:
    ld b, h         ;Restore the number of numbers to be drawn into b.
    xor a         ;Reset CurCol to 0
    ld (CurCol), A
    ld l, $31         ;load the hexvalue of "1" in L
    ld de, CurRow      ;load the address of CurRow in DE
    ld a, 1         ;A keeps track of the current row to be drawn
DrawNumbers:
    ld (DE), a         ;CorRow now equals the number to be drawn
    cp c         ;If C = A
    CALL Z, TextInverseOn   ;Textinverse = on
    cp c         ;If C <> A
    CALL NZ, TextInverseOff   ;Textinverse = off
    PUSH AF         ;Save A because it is needed to display characters
    ld a, l         ;load the ASCII code of the number into A
    b_call(_PutC)      ;Display the character, and advance the cursor
    ld a, Lcolon      ;load the ASCII code of the ":" into A
    b_call(_PutMap)      ;Display the character, not advance the cursor
    xor a         ;Reset CurCol
    ld (CurCol), a
    inc hl         ;Incline the number, because the numbers are placed right

behind each other in ROM
    POP AF         ;Recover A
    inc A         ;Incline the row
    DJNZ DrawNumbers      ;Repeat this, the number of times of the number of options

UserInput:
    RES 0, (IY + Asm_Flag1)   ;Resets the flag
    PUSH HL         ;Save HL temporarely, because b_call(_getKey) messes it up
    b_call(_getKey)      ;Gets the key pressed, and saves it in A
    POP HL         ;Restore HL
    CP kDown         ;If down is pressed...
    JR Z, InclineMenu      ;Incline C
    CP kUP         ;If up is pressed...
    JR Z, DeclineMenu      ;Decline C
    CP kEnter         ;If enter is pressed...
    RET Z         ;Exit the procedure
    SET 0, (IY + Asm_Flag1)   ;Sets the flag
    LD L, 1         ;L will save the option selected, if it was accessed by a

number key
    LD B, H         ;Load the number of options into B
    LD E, 7         ;7 keys to check max
    LD D, k1         ;Load the address of the first key into D
CheckForNumber:
    CP D         ;Substract D (only modifying flags)
    RET Z         ;Exit the procedure if the right key is met
    DEC B         ;Decline B
    JR Z, UserInput      ;If 0, go to the userinput
    INC L         ;Incline L
    INC D         ;Incline D
    DEC E         ;Decline E
    JR NZ, CheckForNumber   ;Repeat this until either B or E met 0
    JR UserInput      ;Go to userinput

InclineMenu:
    INC C
    LD A, C
    DEC A
    CP H
    JP Z, DrawNumbersComplete
    JP DrawNumbersSet
DeclineMenu:
    DEC C
    JP NZ, DrawNumbersSet
    LD C, H
    JP DrawNumbersSet

TextInverseOn:
    SET TextInverse, (IY + TextFlags)
    RET
TextInverseOff:
    RES TextInverse, (IY + TextFlags)
    RET
.end
.end
Oddly enough, I'm having a hard time replicating the bug. I did this:

1) Deleted the three appvars: DCS7, DCS7b, and FLDSV7
2) Opened Doors CS. Clicked through the splashscreen and intro help.
3) Ran your program (from RAM!). Pressed down, enter.
4) Returned to the DCS desktop with no corruption.

Any thoughts?
I've really got no idea why this doesn't work, or actually why it does. It might be something in the compiling process? What if I'd send you the compiled program?
arriopolis wrote:
I've really got no idea why this doesn't work, or actually why it does. It might be something in the compiling process? What if I'd send you the compiled program?
It's certainly worth a try. Smile I've PMed you my email address on IRC.
Sorry for not sending the program. There's only 1 reason why I didn't send it yet, which is because I found the answer. If you run my program and exit it by scrolling down to option 4, the textinverse flag is still set. This caused those strange pixels to be drawn.
If you exit it with pressing "4", the textinverse flag will NOT be set, so everything is displayed normally again.
arriopolis wrote:
Sorry for not sending the program. There's only 1 reason why I didn't send it yet, which is because I found the answer. If you run my program and exit it by scrolling down to option 4, the textinverse flag is still set. This caused those strange pixels to be drawn.
If you exit it with pressing "4", the textinverse flag will NOT be set, so everything is displayed normally again.
Ohhhh, the weird Doors CS desktop is just text inverted. Very Happy How did I not think of that? Smile
Here are some useful routines from KnightOS, using Spasm as an assembler:

SortableStringCompare
Compares two zero-delimited strings alphabetically for sorting.
Inputs:
HL: String 1
DE: String 2
Outputs:
Z: String 1 is alphabetically first
NZ: String 2 is alphabetically first
Destroys:
None


Code:
; Inputs:   HL and DE point to string
; Outputs:    Z: HL is alphabetically first
;         NZ: DE is alphabetically first
SortableStringCompare:
   push hl
   push de
   push bc
   ld c, a
   
SortableStringCompare_Loop:
      ld a, (hl)
      cp 'b'
      jr c, _
      sub 'a'-'A' ; Case insensitive
_:      ld b, a
      or a
      jr z, SortableStringCompare_HL ; They are equal, or HL is shorter
      ld a, (de)
      cp 'b'
      jr c, _
      sub 'a'-'A'
_:      or a
      jr z, SortableStringCompare_DE ; DE is shorter
      cp b
      jr c, SortableStringCompare_DE
      inc hl \ inc de
      jr SortableStringCompare_Loop
   
SortableStringCompare_HL:
   cp a
   jr _
SortableStringCompare_DE:
   or 1
_:
   ld a, c
   pop bc
   pop de
   pop hl
   ret


GetBatteryLevel
Gets an accurate battery level on non-TI-83+ devices.
Inputs:
None
Outputs:
B: Battery level (0-4)
Destroys:
None


Code:
; Outputs:   B: Value from 0-4 indicating battery level (0 is critical)
GetBatteryLevel:
   push af
#ifndef CPU15 ; If on TI-73 or TI-83+
   in a, (2)
   and 1
   ld b, a
   pop af
   ret
#else
   ld b, 0
   ld a, %00000110
   out (6), a
   in a, (2)
   bit 0, a
   jr z, GetBatteryLevel_Done
   
   ld b, 1
   ld a, %01000110
   out (6), a
   in a, (2)
   bit 0, a
   jr z, GetBatteryLevel_Done
   
   ld b, 2
   ld a, %10000110
   out (6), a
   in a, (2)
   bit 0, a
   jr z, GetBatteryLevel_Done
   
   ld b, 3
   ld a, %11000110
   out (6), a
   in a, (2)
   bit 0, a
   jr z, GetBatteryLevel_Done
   
   ld b, 4
GetBatteryLevel_Done:
   ld a, %110
   out (6), a
   pop af
   ret
#endif
That's some of the ugliest code I've ever seen. You need to seriously learn bitmath already. I also made the device type checking dynamic so you don't need to compile a different version for the TI-83+.

GetBatteryLevel
Gets an accurate battery level on non-TI-83+ devices.
Inputs:
None
Outputs:
B: Battery level (0-4)
Destroys:
None


Code:
; Outputs:   B: Value from 0-4 indicating battery level (0 is critical)
GetBatteryLevel:
   push af
   in a, (2)
   rlca ;Roll bit 7 into carry.
   jr c, GetBatteryLevel_Not3Plus
   in a, (2)
   and 1
   ld b, a
   pop af
   ret
GetBatteryLevel_Not3Plus:
   ld b,3
GetBatteryLevelLoop:
   ld a,b
   sla a
   sla a
   sla a
   sla a
   sla a
   sla a
   or %00000110
   out (6), a
   in a, (2)
   bit 0, a
   jr z, GetBatteryLevel_Done
   djnz GetBatteryLevelLoop
   ld b,4
GetBatteryLevel_Done:
   ld a, %110
   out (6), a
   pop af
   ret
I compile different versions on purpose, this is an OS and I can guarantee what model this code will run on. I do need to get better at bit math, though.
  
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 4 of 8
» 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

 

Advertisement