Hello,
I'm starting a thread (which should probably be pinned) where you can post code and have it optimized by anyone with spare time. I'll start with this:

Code:
Sleep:
   ld a, 2
   out (10h), a ; Disable LCD
   di ; And interrupts, for now
   im 1 ; interrupt mode 1, for cleanliness
   ei ; Enable interrupting when ON is pressed
   ld a, 1h
   out (03h), a ; ON
   halt ; and halt :)
   ld a, 0Bh ; Reset the interrupts
   out (03h), a
   ld a, 3
   out (10h), a ; Enable the screen
   ret
The main optimization I have for you is that LD A,1 can be DEC A because A was previously 2. Also, you don't need to DI before changing the interrupt mode (and I'm not sure changing the interrupt mode is even needed here, so I took it out)

Code:
Sleep:
ld a,2
out ($10),a
dec a
out (3),a
ei  ;Do this only if interrupts might be disabled when calling this routine
halt
ld a,$0B
out (3),a
ld a,3
out ($10),a
ret
Thank you!
calc84maniac wrote:
The main optimization I have for you is that LD A,1 can be DEC A because A was previously 2. Also, you don't need to DI before changing the interrupt mode (and I'm not sure changing the interrupt mode is even needed here, so I took it out)
Well, it depends if the calculator is in IM 2 and the user's interrupt doesn't trigger on the [ON] key, no? Unless I'm imagining things?
*bump* Though I am loath to re-use this thread, I have some TI-84+CSE sprite routines that need to be hella optimized. Who has the time and inclination to take a look? I can provide more details about inputs, outputs, and functionality as needed.


Code:
DrawSprite_CommonPreface:
   ld   h,0
   ld   a,$50      ; set minimum Y
   call   Write_Display_Control
   ld   a,$20      ; set current Y
   call   Write_Display_Control
   
   ex de,hl
   ld c,(hl)      ;width
   inc hl
   ld a,(hl)      ;height
   inc hl

; At this point we have finished vertical clipping and set the Y register
; A = height of the sprite (excluding rows clipped out)
; HL -> pixel data of first pixel of first row to draw
; IX -> color table
; B = X coordinate
; C = width of sprite in bytes
   ld   (SpriteHeight),a
   
   ld   a,c
   ld   (SpriteWidth),a
   
   ex de,hl
   push bc
      ld l,b         ; set minimum X
      ld h,0
      add   hl,hl
      ld a,$52
      call Write_Display_Control
      ld a,$21      ; set current X
      call Write_Display_Control
      pop bc
   ret

; ix -> palette, b = x, l = y, de -> sprite   
DrawSprite_1Bit:
   call DrawSprite_CommonPreface
   
   ld   a,b      ; set maximum X
   add   a,c
   add a,c
   add a,c
   add a,c
   ld   l,a
   ld   h,0
   add   hl,hl
   dec   hl
   ld   a,$53
   call   Write_Display_Control
   
   ld   a,$22
   out   ($10),a
   out   ($10),a   
   
   ld a,(SpriteHeight)
   ld b,a
Draw_Sprite_1Bit_PackedLoop:
   push bc
      ld a,(SpriteWidth)
      ld b,a
Draw_Sprite_1Bit_PackedLine:   ; PAD's fixed-palette version: 134 clocks per loop, 67 clocks per pixel
                  ; My variable-palette version; 435 clocks per loop, 109 clocks per pixels
      push bc                  ;11
         ld b,8*3
         ld a,(de)            ;7
Draw_Sprite_1Bit_PackedLine_Bit:
         rlc a
         ld c,a            
         push ix
            pop hl
         and 1
         jr z,Draw_Sprite_1Bit_PackedLine_BitLow
         inc hl
         inc hl
Draw_Sprite_1Bit_PackedLine_BitLow:
         ld a,c
         ld c,$11
         outi               ;16
         outi               ;16
         djnz Draw_Sprite_1Bit_PackedLine_Bit
         inc   de               ;6
         pop bc               ;10
      djnz   Draw_Sprite_1Bit_PackedLine ;13 if jump taken
      pop   bc                  ;10
   djnz   Draw_Sprite_1Bit_PackedLoop   ;13 if jump taken
   ret

; ix -> palette, b = x, l = y, de -> sprite   
DrawSprite_2Bit:
   call DrawSprite_CommonPreface
   
   ld   a,b      ; set maximum X
   add   a,c
   add a,c
   ld   l,a
   ld   h,0
   add   hl,hl
   dec   hl
   ld   a,$53
   call   Write_Display_Control
   
   ld   a,$22
   out   ($10),a
   out   ($10),a   
   
   ld a,(SpriteHeight)
   ld   b,a
draw_packed_loop_2bit:
   push   bc
      ld a,(SpriteWidth)
      ld   b,a
draw_packed_line_2bit:   ; PAD's fixed-palette version: 134 clocks per loop, 67 clocks per pixel
                  ; My variable-palette version; 435 clocks per loop, 109 clocks per pixels
      push bc                  ;11
         ld   a,(de)            ;7
         rra                  ;4
         rra                  ;4
         rra                  ;4
         rra                  ;4
         rra                  ;4
         and   %110            ;7
         push ix               ;11
            pop hl            ;10
         ld c,a               ;4
         ld b,0               ;7
         add hl,bc            ;11
         ld c,$11
         outi               ;16
         outi               ;16
         ld   a,(de)            ;7
         rra                  ;4
         rra                  ;4
         rra                  ;4
         and   %110            ;7
         push ix               ;11
            pop hl            ;10
         ld c,a               ;4
         ld b,0               ;7
         add hl,bc            ;11
         ld c,$11
         outi               ;16
         outi               ;16
         ld   a,(de)            ;7
         rra                  ;4
         and   %110            ;7
         push ix               ;11
            pop hl            ;10
         ld c,a               ;4
         ld b,0               ;7
         add hl,bc            ;11
         ld c,$11
         outi               ;16
         outi               ;16
         ld   a,(de)            ;7
         rla                  ;4
         and   %110            ;7
         push ix               ;11
            pop hl            ;10
         ld c,a               ;4
         ld b,0               ;7
         add hl,bc            ;11
         ld c,$11
         outi               ;16
         outi               ;16
         inc   de               ;6
         pop bc               ;10
      djnz   draw_packed_line_2bit ;13 if jump taken
      pop   bc                  ;10
   djnz   draw_packed_loop_2bit   ;13 if jump taken
   ret

DrawSprite_4Bit_Enlarge:
   call DrawSprite_CommonPreface
   
   ld   a,b      ; set maximum X
   add   a,c
   add a,c      ; double width for 2x enlargement
   ld   l,a
   ld   h,0
   add   hl,hl
   dec   hl
   ld   a,$53
   call Write_Display_Control
   
   ld   a,$22
   out   ($10),a
   out   ($10),a   
   
   ld a,(SpriteHeight)
   ld b,a
Draw_Sprite_4Bit_Enlarge_PackedLoop:
   push bc
      push de
         call Draw_Sprite_4Bit_Enlarge_PackedLine_Sub
         pop de
      call Draw_Sprite_4Bit_Enlarge_PackedLine_Sub
      pop   bc                  ;10
   djnz Draw_Sprite_4Bit_Enlarge_PackedLoop      ;13 if jump taken
   ret

Draw_Sprite_4Bit_Enlarge_PackedLine_Sub:
   ld a,(SpriteWidth)
   ld b,a
Draw_Sprite_4Bit_Enlarge_PackedLine:
   push bc                  ;11
      ld   a,(de)            ;7
      rra                  ;4
      rra                  ;4
      rra                  ;4
      and   %11110            ;7
      push ix               ;11
         pop hl            ;10
      ld c,a               ;4
      ld b,0               ;7
      add hl,bc            ;11
      ld c,$11
      outi               ;16
      outi               ;16      ;First pixel copy
      dec hl
      dec hl
      outi               ;16
      outi               ;16      ;Second pixel copy
      ld   a,(de)            ;7
      rla                  ;4
      and   %11110            ;7
      push ix               ;11
         pop hl            ;10
      ld c,a               ;4
      ld b,0               ;7
      add hl,bc            ;11
      ld c,$11
      outi               ;16
      outi               ;16      ;First pixel copy
      dec hl
      dec hl
      outi               ;16
      outi               ;16      ;Second pixel copy
      inc   de               ;6
      pop bc               ;10
   djnz Draw_Sprite_4Bit_Enlarge_PackedLine   ;13 if jump taken
   ret
   
; ix -> palette, b = x, l = y, de -> sprite   
DrawSprite_4Bit:
   call DrawSprite_CommonPreface
   
   ld   a,b      ; set maximum X
   add   a,c
   ld   l,a
   ld   h,0
   add   hl,hl
   dec   hl
   ld   a,$53
   call Write_Display_Control
   
   ld   a,$22
   out   ($10),a
   out   ($10),a   
   
   ld a,(SpriteHeight)
   ld b,a
Draw_Sprite_4Bit_PackedLoop:
   push bc
      ld a,(SpriteWidth)
      ld b,a
Draw_Sprite_4Bit_PackedLine:      ; PAD's fixed-palette version: 134 clocks per loop, 67 clocks per pixel
                  ; My variable-palette version; 234 clocks per loop, 117 clocks per pixels
      push bc                  ;11
         ld   a,(de)            ;7
         rra                  ;4
         rra                  ;4
         rra                  ;4
         and   %11110            ;7
         push ix               ;11
            pop hl            ;10
         ld c,a               ;4
         ld b,0               ;7
         add hl,bc            ;11
         ld c,$11
         outi               ;16
         outi               ;16
         ld   a,(de)            ;7
         rla                  ;4
         and   %11110            ;7
         push ix               ;11
            pop hl            ;10
         ld c,a               ;4
         ld b,0               ;7
         add hl,bc            ;11
         ld c,$11
         outi               ;16
         outi               ;16
         inc   de               ;6
         pop bc               ;10
      djnz Draw_Sprite_4Bit_PackedLine   ;13 if jump taken
      pop   bc                  ;10
   djnz Draw_Sprite_4Bit_PackedLoop      ;13 if jump taken
   ret
*bump* Many thanks to Runer112, who I understand is working hard to optimize and improve my work. Here's another optimization challenge for you all: tr1p1ea's color line routine. Ideally, we'd find a way to remove the shadow register and iy dependencies:

http://pastebin.com/NAnvXDaw
Well here is a mod of the above, which makes this routine even more of a hack Smile.

http://pastebin.com/wc08k3rz

It uses some RAM instead of shadow regs & IY. However as suggested by Runer, you could always have the user push the arguments onto the stack before the call instead.
tr1p1ea : I have one quick optimisation for you, turn lines 231 to 233 into those two :
Code:
  ld hl, (linecolor)
  call setLCDregister
You wrote a routine, why not using it ? You do a pop hl after it either case, so no need to preserve HL.
Also, at the start of drawPixel (198-201), couldn't you do something like "ld a,h \ or d \ ret m"?

Also, perhaps 202-206 could be "ld bc,-320 \ add hl,bc \ ret c \ sbc hl,bc" and the same idea for the next set.

And it doesn't seem like you use iy anywhere ("iy = colour") Wink

I also wonder if you wouldn't gain a bit of time with out (c),reg8. I don't know if you need a delay between writes, but that way you could do "out (c),h \ out (c),l".

And if the LCD registers get updated automatically, perhaps you could save some time in the line drawing routine by not updating them every time you draw a new pixel. I don't know if you can choose whether to update vertically or horizontally, but perhaps you could take advantage of that (alternating between the two modes) two save some time and not have to reset (recalibrate?) the LCD every time.
I already tried out (c), reg8 ; at best case you loose 1 byte and 9 cycles.
But if you load c outside of the routine you'll save 6 cycles every call. It'd be faster with the second call.
matre: Im not really sure what you mean with your first point. setLCDRegister writes to the LCD Registers and lineColour is the value to write to LCD *Data*. Also HL is actually the X value for the line routine, which is why its preserved.

chickendude: The routine posted before this one uses IY etc, this routine is an 'interrupt-safe' conversion of that routine, which is why it isnt present.

That said, C could be used to hold $10 and instead of using A to retrieve the colour data, it could be loaded into HL prior.
  
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 1
» All times are UTC - 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