distorted text output on a TI-84+

TI-82, TI-83 (plus, silver..), TI-84, TI-85 and TI-86
Post Reply
iliis
New member
Posts: 7
Joined: Tue Mar 10, 2009 10:33 pm

distorted text output on a TI-84+

Post by iliis »

Hello,
(this is my first post here; Thanks a lot for all the effort you put in this project! The z88dk is certainly a great toolset :D)

I got the compiler for my TI-84 Plus to work. Even the graylib runs (tested with mandel.c from the examples).

But printf delivers strange results:

Code: Select all

int main()
{
  clg();
  printf("Hello World");
  getk();
  return 1;
}
comes out as:

Code: Select all

H       r
 e       l
  l       d
   l
    o
      
      W
       o
puts(), puts_cons() and printk() produce the same. :(
However, if i use ansi (zcc +ti8xansi ...) the text appears correct. Unfortunately it's extremly ugly and slow, so I'd rather use the normal fonts.

I'm compiling my code with the following command:

Code: Select all

zcc +ti8x -startup=2 -create-app -Wall -o test main.c
I using z88dk 1.8-rc2 on win32.



Another issue is that i can't create "normal" programs which i can launch with asm(prgmNAME): compiling with -startup=10 (and any other value) always crashes my calculator and clears the RAM, so I'm "stuck" with MirageOS.


I would appreciate any help.
Greetings, illis.
stefano
Well known member
Posts: 2137
Joined: Mon Jul 16, 2007 7:39 pm

Post by stefano »

Well it looks you are at a nice stage, by the way..
The non-ansi mode is based on calls to external functions, mostly the shell ones, so that's probably a first good reason for having problems with the "-startup=10" mode as well as with some of the existing Shells (if I remember well it is tuned for ION, then we rely on the claimed compatibility between the shells).
Then, the TI84+ is quite a new target, it might differ on something from the TI83+.
iliis
New member
Posts: 7
Joined: Tue Mar 10, 2009 10:33 pm

Post by iliis »

Hmm, so there's nothing I can do about?
Unfortunately I have almost no experiences with assembler, but I'm willing to help develop the z88dk :)

(An ot-question: why are you using Small-C as a compiler and not gcc?)
stefano
Well known member
Posts: 2137
Joined: Mon Jul 16, 2007 7:39 pm

Post by stefano »

To be honest there's a lot of work-around you can apply, just they're many..

First you can re-compile the ANSI library to use a larger font, but I guess it won't be your choice, because the resulting code will be bigger and still a bit slow (you might keep the same code size and obtain a muche better readability just enlarging the font size of one pixel). The very compact text has been chosen to keep the same text resolution in characters with all the TI calculator (TI 85 and TI 86 aready use a 4 pixels font).

Second, you can use your custom fputc_cons function. If I'm not wrong, it can even overlap the default one so things might be easy. I'd like to provide a skeleton for it, but I can't do it right now (wanted to point to the source files in CVS but thy're unreachable, hopefully temporairly). Lemme know if you'd like to go into depth.

Third, use another shell

An there are many more, to write a custom I/O function basing on the graphics primitives, to prepare custom functions non overlapping the existing ones, etc..

To start, you might learn how to build the libraries by yourself. (make ti83_clib.lib / copy ti83_clib.lib "c:\program files\z88dk\lib\clibs", but make isn't available by default on windows, so you might look here, and read about the GNU utils: http://www.z88dk.org/wiki/doku.php/inst ... k_binaries ...or to use cygwin).
alvin
Well known member
Posts: 1872
Joined: Mon Jul 16, 2007 7:39 pm

Post by alvin »

iliis wrote:(An ot-question: why are you using Small-C as a compiler and not gcc?)
It's been a long, long time since I looked at gcc, but at that time it was not ideal for targetting small CISC-like cpus. It made assumptions about data sizes that were not suitable, eg, for a z80, and is well-geared for optimizing code on more RISC-like architectures (lots of orthogonal registers, eg). Getting it to generate *good* code for a z80 would be very difficult.
stefano
Well known member
Posts: 2137
Joined: Mon Jul 16, 2007 7:39 pm

Post by stefano »

Quick and dirty hack: how to simply overlap the "put character function" with your own C or assembly code.
In this example I call the ZX Spectrum ROM routine at address 16, which prints character in register A.
You could have to deal with text positioning counters or memory paging tricks before calling the ROM routine in TI84.
It just works, but it is a dirty trick (the original fputc_cons is still in the program block, I think): by the way the non-ansi version of the TI83 fputc_cons routine is very small.

#include <stdio.h>

main()
{
printf("Hello world!\n");
}

fputc_cons (unsigned char c)
{
#asm
pop bc ; Return address
pop hl ; Character value
push hl
push bc

ld a,l
call 16
ret
#endasm
}
iliis
New member
Posts: 7
Joined: Tue Mar 10, 2009 10:33 pm

Post by iliis »

I compiled z88dk from the cvs. It wasn't so difficult as I'm normally using ubuntu for serious work (I just used windows preliminarily because it was runnig at the time...): I just followed the readme (./build.sh; make install; make libs; make install-libs) and copied the content from z88dk/lib to /usr/local/lib/z88dk/lib/ (zcc complained about the missing zcc.cfg).

So far z88dk runs fine, but the problem still exists. However it works with ION! Unfortunately, the text gets printet on the bottom of the screen and \n has no affect at all...

The fputc_cons function from stefano produces no output, neither with MirageOS nor with ION. As I said, I don't know anything about assembler on the TI-84, so I can't help there :(

Which graphic commands should I use for writing my own text-output-function?
stefano
Well known member
Posts: 2137
Joined: Mon Jul 16, 2007 7:39 pm

Post by stefano »

Ok, you're at a very good point.

You can edit libsrc/stdio/ansi/ticalc.inc
Hava a glance at it here: http://z88dk.cvs.sourceforge.net/viewvc ... iew=markup

I.E. for having a slightly larger text in ANSI mode, go to the TI83 section and change char_dots from 3 to 4 (modifying f_ansi_char.asm you can specify an even larger font).
Then, "make clean" / "make ti83ansi_clib.lib"..

The example above works on the Sinclair ZX Spectrum only, sorry it was much easier.. I just wanted to show how to embed some assembler code in the C function.
iliis
New member
Posts: 7
Joined: Tue Mar 10, 2009 10:33 pm

Post by iliis »

Yeah, it works :D (with MirageOS too)
But it's slow as hell ;) (compared to non-ansi or ti-basic)
Thanks a lot, it's at least something I can work with...


EDIT: WTF? This post appears twice. Editing one affects the other one too :/
Last edited by iliis on Sun Mar 15, 2009 9:29 pm, edited 1 time in total.
stefano
Well known member
Posts: 2137
Joined: Mon Jul 16, 2007 7:39 pm

Post by stefano »

So slow ? There's plenty of possible optimizations, I.E. you can modify f_ansi_char to make it update the screen only upon request.
Edit f_ansi_char and replace the last instruction ("jp cpygraph") with a simple "ret" and rebuild the library.
Then add a custom function calling the z88dk service routine called "cpygraph":

void update_screen {
#asm
XREF cpygraph
JP cpygraph
#endasm
}

After printing your text you'll need to call update_screen() to refresh the display.

Another reason for finding it slow might be the type of memory the program runs in, the FLASH memory is much slower, expecially when written: to move some of the variables in another location could help a lot.


Now let's think at the non-ansi version: if I remember well I already noticed that the MirageOS implementation of the "put char" function behaves so strangely, but reading the documentation it seems that the "official" way to print a character seems to be the "vputa" function, at location $412E.
So you could try to edit the "ti_putchar" constant in the above mentioned "ticalc.inc file" and update it with such value (then you'll have to rebuild the non-ansi lib).
Possibly you could call directly the ROM, but the deeper you go the lower compatibility you have.

A very nice feature you could play with is the proportional font of the TI calculators, but normally the graphic coordinates are required (text is somehow "drawn" onto the screen and linefeed and scrolling will have to be handled directly). There is no explicit support for this in the current z88dk libraries, BTW.
iliis
New member
Posts: 7
Joined: Tue Mar 10, 2009 10:33 pm

Post by iliis »

hm... the update_screen-method works, but it somehow doesn't update when the text reaches the end and scrolls up.
changing the ti_putchar constant to $412E in libsrc/stdio/ansi/ticalc/ticalc.inc causes just a blank screen and clears the ram (starting from MirageOS)
stefano
Well known member
Posts: 2137
Joined: Mon Jul 16, 2007 7:39 pm

Post by stefano »

It is strange, I supposed I could trust the docs: have you switched the "startup" parameter correctly ? (-startup=2).
Then, it could be easier to test the assembly portion without recompiling the whole lib; a trick like this should work:

fputc_cons (unsigned char c)
{
#asm
pop bc ; Return address
pop hl ; Character value
push hl
push bc

ld a,l
rst 28
defw $412E ;; .. or whatever

ret
#endasm
}

The "setvputs" MirageOS functions looks interesting, too.. need an example ?
iliis
New member
Posts: 7
Joined: Tue Mar 10, 2009 10:33 pm

Post by iliis »

yes, i compiled it with zcc +ti8x -startup=2 -create-app -Wall -o ptest printtest.c
If i try to compile this (with the command above)

Code: Select all

#include <stdio.h>

main()
{
    printf("Hello world!\n");
}

fputc_cons (unsigned char c)
{
#asm
    pop   bc    ; Return address
    pop   hl    ; Character value
    push  hl
    push  bc
   
    ld    a,l
    rst   28
    defw $412E  ;; .. or whatever
   
    ret
#endasm
}
it fails with

Code: Select all

cp /usr/local/share/z88dk/lib/ti83p_crt0.opt /tmp/tmpXX5eSMs6.opt
cp /tmp/tmpXX5eSMs6.opt /tmp/tmpXX5eSMs6.asm
zcpp -I. -DZ80 -DSMALL_C -DTI8x -D__TI8x__ -DSCCZ80 -I/usr/local/share/z88dk/include  printtest.c /tmp/tmpXXyyqYSL.i
sccz80    -// -startup=2 -Wall  /tmp/tmpXXyyqYSL.i
sccz80:"printtest.c" L:3 Warning:#7:Return type defaults to int
sccz80:"printtest.c" L:8 Warning:#7:Return type defaults to int
sccz80:"printtest.c" L:9 Warning:#43:Function arguments have sign mismatch
copt /usr/local/share/z88dk/lib/z80rules.2 < /tmp/tmpXXyyqYSL.asm > /tmp/tmpXXyyqYSL.op1
copt /usr/local/share/z88dk/lib/z80rules.1 < /tmp/tmpXXyyqYSL.op1 > /tmp/tmpXXyyqYSL.opt
z80asm -eopt -ns -Mo /tmp/tmpXXyyqYSL.opt
1 errors occurred during assembly
Errors in source file printtest.c:
File '/tmp/tmpXXyyqYSL.opt', Module 'PRINTTEST', at line 32, Integer out of range
there isn't even a line 32 in printtest.c!?

An example would be nice, yes :)
However MirageOS isn't so important, because it takes long to start etc. I would prefer the normal shell or ION.
stefano
Well known member
Posts: 2137
Joined: Mon Jul 16, 2007 7:39 pm

Post by stefano »

My fault, probably the error is due to the "int 28", which should be "int $28" or "int 28h".
Warnings are just consequent of the misdeclaration of the input/output types used in the custom fputc_cons: they can be fixed, but shouldn't be much relevant.
Give me a bit of time for a decent example I can test with a ti83_plus emulator, and let's also get rid of MirageOS.. Let's hope the ROM functions map of a TI84 plus is close enough to the ti82 plus one.

-Edit- Forgot to say the line number quoted in the error is referred to the generated assembly code.
iliis
New member
Posts: 7
Joined: Tue Mar 10, 2009 10:33 pm

Post by iliis »

ok, it compiles now, but doesn't display anything and quitting MirageOS clears then clears the ram. (I've finally learnt to make backups XD)
thanks a lot for all the help, i really appreciate it :)
stefano
Well known member
Posts: 2137
Joined: Mon Jul 16, 2007 7:39 pm

Post by stefano »

The promised example.
Changing the constants it should work in the classic TI83 too, but I haven't tested it.
There are two ways to pick the parameters from the stack, but using the IX index makes
the code a bit more readable.

Code: Select all

#include "stdio.h"

setvputs (int x, int y, char *text)
{
#asm
        defc PenCol = $86D7     ; $8252 for a classic TI83
        defc VPuts = $4561      ; $4781 for a classic TI83

        ld      ix,2    ; make the index register..
        add     ix,sp   ; point to the rightmost parameter on stack
        
        ld      l,(ix+0)
        ld      h,(ix+1)        ; text

        ld      d,(ix+2)        ; y

        ld      e,(ix+4)        ; x
        
        ld      (PenCol),de     ; position the "graph text" cursor
        
        rst     $28
        defw    VPuts           ; 'write' the text
#endasm
}


main()
{
        setvputs (27,10,"Hello World !");
        while (getk() != 13) {};
}
Tharis
New member
Posts: 4
Joined: Tue Sep 02, 2008 11:32 pm

Post by Tharis »

I'm sorry to revive this topic, but I'm interested in what happened.

What has been made to correct this issue?


First, regarding the -startup=10, I've tried and it crashes.

Second, the printf and all standard output non-ansi, they have the problem mentioned above.

Another thing is that char_dots changing that didn't work for me.

Finally, this last setvputs works, but I have some question:
- How is the size of the font defined?
- When I have something like the code below, it leaves the previous pixels on, whereas if the incrementing variable is the y position, it doesn't:

Code: Select all

main()
{
        int x = 0;
        while (getk() != 13) {
            setvputs (x++,10,"Hello World !");
        }
}
Last but not least, I want to THANK YOU VERY MUCH!
You have a wonderful and magnificent project.


Regards ;)
stefano
Well known member
Posts: 2137
Joined: Mon Jul 16, 2007 7:39 pm

Post by stefano »

The only thing I'm sure we can fix quickly is the char_dots mod to ansi libraries.
Were you able to recompile the TI81 libs ? Have you copied the resulting binary file under z88dk/lib/clibs ?

I'll be back to try to clarify/solve the remaining points, but it won't be easy, that's why a shells have been developed.
Tharis
New member
Posts: 4
Joined: Tue Sep 02, 2008 11:32 pm

Post by Tharis »

Yes, I recompiled the TI-83+ (8x) and copied it to z88dk/lib/clibs. My calculator is a TI-84+ btw.
Anyway, later when I'm home I'll retry.

Thank You :)
Tharis
New member
Posts: 4
Joined: Tue Sep 02, 2008 11:32 pm

Post by Tharis »

Sorry for the double post.

I recompiled ti83pansi_clib.lib and now I noted between char_dots = 3/4: if it is set to 4 it has a space dot between each letter.

The two screens, first is char_dots = 3, and the second is char_dots = 4:



@stefano, I can use that function setvputs as a printf simple by using sprintf to format the string and then pass the pointer to setvputs, my only problem is the size of the font which is too small. Another thing is that if you use setvputs to print in a loop which increments the x position, it leaves a trail. Like: "Hello World" -> "|Hello World" -> "||Hello World" -> "|||Hello World"


I'm using MirageOS btw.

Another thing, I tried using printf with ION shell and printf doesn't do the newline and prints on bottom. The odd about this is that after I make it print 8 times, it starts printing the newline (still on bottom though).


Regards ;)
Last edited by Tharis on Mon Jan 25, 2010 12:55 am, edited 1 time in total.
stefano
Well known member
Posts: 2137
Joined: Mon Jul 16, 2007 7:39 pm

Post by stefano »

Sadly it looks that the shells implement the putchar in differently and always in a strange way.
Too bad, I was hoping to refer to shells to gain a transparent remapping of the calls to the different ROM versions (it usually works).. maybe I'm just calling putchar in the wrong way. The "setvputs" example was only an example to show how build your own interface to the ROM quickly.
A huge but portable way to solve the problem is to change the ansi output by loading a larger font .. which is your favourite size in dots ?
Tharis
New member
Posts: 4
Joined: Tue Sep 02, 2008 11:32 pm

Post by Tharis »

Height = Ansi + 1
Width = 4 or 5

and a 1-dot space between chars.
Last edited by Tharis on Thu Jan 28, 2010 10:55 pm, edited 1 time in total.
stefano
Well known member
Posts: 2137
Joined: Mon Jul 16, 2007 7:39 pm

Post by stefano »

Then, set char_dots to 5 (or 6), and edit the file {z88dk}/libsrc/stdio/ansi/ticalc/f_ansi_char.asm
at the end, you'll see:

.font
BINARY "stdio/ansi/F4PACK.BIN"

Change the font file to "stdio/ansi/F5.BIN" (or F6.BIN)

Edit /z88dk/libsrc/Makefile, locate the label "ti83ansi_clib.lib:" change the "$(LIBLINKER)" line removing the "-DPACKEDFONT" option:

$(LIBLINKER) -DFORti83 -x$(OUTPUT_DIRECTORY)/ti83ansi_clib @$(LISTFILE_DIRECTORY)/ticansi.lst


Rebuild the library:
make ti83ansi_clib.lib

and copy it back in ../lib/clibs
stefano
Well known member
Posts: 2137
Joined: Mon Jul 16, 2007 7:39 pm

Post by stefano »

Hoping you're still around: I was wrong.
I had time to read the updated documentation for the ti83+/ti84+ calculators family and it looks that many locations are always valid.
So I checked the sources and spotted a stupid bug probably introduced along with a workaround to make the text scroll always correctly.
I still haven't released the patch, but you can fix it by rebuilding the libraries after editing {z88dk}/libsrc/stdio/ansi/ticalc/ticalc.inc..

Move at the constant group "FORti83p" and change two lines as follows:

defc ti_x_text = $844C
defc ti_y_text = $844B
stefano
Well known member
Posts: 2137
Joined: Mon Jul 16, 2007 7:39 pm

Post by stefano »

After SourceForge went back online I could commit the fix, now the lib should be available in the automatically built blocks.
AFAIK at the moment the current z88dk snapshot should be quite consistent.
Post Reply