I'm posting this here so someone like Kerm (hint hint wink wink) can remember to put it on the wiki or something. Also I guess it might be useful to some of you. I'm like 99% sure this stuff works, but as always it might not, so use at your own risk. It originally came from https://github.com/unknownloner/wiki/blob/master/ti84cse/HalfRes.md.

Half-res mode on the CSE

Half res mode is an LCD mode which results in a halved horizontal resolution. This can also be used for double buffering, because one can write to the left side of the screen while displaying the right side or vice versa.

Entering half-res mode takes 4 steps:
  1. Enable interlacing
  2. Enable partial images 1 and 2
  3. Position the source areas of both partial images on top of each other, and make them 160 pixels in size.
  4. Set the output destinations of the partial images to be 160 pixels apart.


Enabling Interlacing
To enable interlacing, set bit 10 of LCD register 01h

Code:
ld a,01h
out (10h),a
out (10h),a
ld a,%00000100  ;bit 10 set
out (11h),a
xor a           ;a = 0 for low bits
out (11h),a

To disable interlacing, set LCD register 01h back to 0000h

Code:
ld a,01h
out (10h),a
out (10h),a
xor a
out (11h),a
out (11h),a

Enable partial images
Partial images are enabled by setting bits 12 and 13 of lcd register
07h for partial images 1 and 2 respectively.

Code:
ld a,07h
out (10h),a
out (10h),a
ld a,%00110000  ;Enable both partial images
out (11h),a
ld a,%00110011  ;Default values for low bits
out (11h),a

To disable, reset bits 12 and 13

Code:
ld a,07h
out (10h),a
out (10h),a
ld a,%00000001  ;Disable both partial images
out (11h),a
ld a,%00110011  ;Default values for low bits
out (11h),a

Set partial image positions
The partial image display positions are controlled by LCD registers
80h and 83h. Their starting lines are controlled by 81h and 84h, and
their ending lines are controlled by 82h and 85h. When using half-res mode, set the display position of image 1 to 0, and set the display position of image 2 to 160.

The start and end lines of both images should be identical. For example, to display the left half of the screen, set the start lines to 0 and the end lines to 159. To display the right half, set the start lines to 160 and the end lines to 319. In other words, to display a section of the screen starting at 'N', set the start lines to N and the end lines to N + 159.

This code will set up the display positions, and then set the start and end lines to display the left half of the screen.

Code:
ld a,80h        ;Img 1 disp position
out (10h),a
out (10h),a
xor a           ;Display position of first img = 0
out (11h),a
out (11h),a

ld a,83h        ;Img 2 disp position
out (10h),a
out (10h),a
xor a           ;MSB should be 0 since 160 < 256
out (11h),a
ld a,160        ;Display position of second img = 160
out (11h),a

ld c,11h        ;Used later to simplify some register setting code

ld a,81h        ;Img 1 start line
out (10h),a
out (10h),a
xor a
out (11h),a
out (11h),a

ld a,84h        ;Img 2 start line
out (10h),a
out (10h),a
xor a
out (11h),a
out (11h),a

ld de, 159      ;End lines for partial images

ld a,82h        ;Img 1 end line
out (10h),a
out (10h),a
out (c),d
out (c),e

ld a, 85h       ;Img 2 end line
out (10h),a
out (10h),a
out (c),d
out (c),e
Optimize time!

Code:

real(0,1,1

Wink
zeldaking wrote:
Optimize time!

Code:

real(0,1,1

Wink




Wink
Hahaha very funny zeldaking Smile.

Nice work Unknown, it is important that this information be stored somewhere accessible.

One note is that it might be a good idea to manipulate the bits while preserving the rest of each register. This would require reading the contents of each register and manipulating the bits before outputting again however.
Quick question: By simply changing the start and end positions of image 1 and image 2, does this swap the GRAM addresses? Or do I need to do that in a different manner?

EDIT: Kind of figured it out, seems like this code displays the right half:


Code:
   ld a,81h        ;Img 1 start line
   out (10h),a
   out (10h),a
   xor a
   out (11h),a
   ld a,160
   out (11h),a

   ld a,84h        ;Img 2 start line
   out (10h),a
   out (10h),a
   xor a
   out (11h),a
   ld a,160
   out (11h),a

   ld de, 319      ;End lines for partial images


And this code the left half:


Code:
   ld a,81h        ;Img 1 start line
   out (10h),a
   out (10h),a
   xor a
   out (11h),a
   out (11h),a

   ld a,84h        ;Img 2 start line
   out (10h),a
   out (10h),a
   xor a
   out (11h),a
   out (11h),a

   ld de, 159      ;End lines for partial images


Is there a better way? I am shooting for double buffering; how would I go about updating the LCD if I am using my left side as the buffer?
That's exactly how I've been doing my double buffering, to my knowledge there's no better way.

You might think that the LCD display offset would do it, but the LCD display offset doesn't do anything when you're using full screen partial images like half-res mode does.

You have to switch off between sides you're drawing to. Display the left side while drawing on the right, then swap and display the right while drawing on the left, and so on.

That's also what xLIBC does, it just hides the fact that it's adding an offset to all your draw commands based on which buffer you're currently drawing to
Ah, okay. So it is constantly switching rather than updating a single side. That makes things pretty interesting, but useful! Thanks! Smile
  
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 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