Assembly code to generate a crt0 for Doors CS programs with SDCC (should be assembled with sdasz80):


Code:
    ;; Generic crt0.s for a Z80
        .module crt0
        .globl  _main
   .globl  _Description
   .globl  _Icon
   .globl  _ALE
    .area _HEADER (ABS)
   
    .org    0x9D93
    .db 0xBB, 0x6D
    xor d
    ret
    jr init
    .dw _Description
    .db #0x07,#0x00
    .dw _Icon
    .dw _ALE
init:
    ld (saved_sp), sp  ; save stack pointer
    di

        ;; Initialise global variables
        call    gsinit
    call    _main
    jp  _exit

    ;; Ordering of segments for the linker.
    .area   _HOME
    .area   _CODE
        .area   _GSINIT
        .area   _GSFINAL
       
    .area   _DATA
        .area   _BSS
        .area   _HEAP

        .area   _CODE
__clock::
;   ld  a,#2
;        rst     0x08
    ret
   
_exit::
    ld sp, (saved_sp)      ;restore stack pointer
    ld iy, #0x89F0
    ei
    ret
saved_sp:
    .ds 2

        .area   _GSINIT
gsinit::   

        .area   _GSFINAL
        ret

Build with

Code:
sdasz80 -o -s ti83p_dcs.s


And an example C program (using the ti83p.lib library provided by TISDCC):

Code:
#include <ti83p.h>
#define NULL 0x0000
__at NULL const int ALE;
volatile const char Description[9] = "TestProg";
volatile const char Icon[32] = {0xFF,0xFF,0x80,0x01,
            0x80,0x01,0x80,0x01,
            0x80,0x01,0x80,0x01,
            0x80,0x01,0x80,0x01,
            0x80,0x01,0x80,0x01,
            0x80,0x01,0x80,0x01,
            0x80,0x01,0x80,0x01,
            0x80,0x01,0xFF,0xFF};

void main(void) {
  unsigned char c;
  ClrScrnFull();
  while((c=GetKey()) != GkEnter) {
    DispInt(c);
   NewLine();
  }
  ClrScrnFull();
  HomeUp();
  PutS("Hello World");
  NewLine();
}


Build it with the following command line (allocates variables at AppBackupScreen = 0x9872):

Code:
sdcc -mz80 --no-std-crt0 --code-loc 0x9DAE --data-loc 0x9872 -L ../lib -I ../include -DTI83P -DION -Wl../startup/ti83p_dcs.rel ti83p.lib test_dcs.c && makebin -p -s 65536 test_dcs.ihx test_dcs.bin && cutbin test_dcs.bin 0x9d93 test_dcs_small.bin && wabbit test_dcs_small.bin TESTDCS.8xp


(wabbit is wabbitsign, makebin comes with sdcc, and cutbin is a little python script I just wrote).

Source for cutbin:

Code:
#!/usr/bin/env python

import sys

datah = open(sys.argv[1],'r')
ba = bytearray(datah.read())
datah.close()

ba = ba[int(sys.argv[2],16):]

datah = open(sys.argv[3],'w')
datah.write(ba)
datah.close()
If anyone knows what ALEs are or how to use them, you should be able to modify the C code to contain an appropriate array of ALE names instead of hard coding the symbol to a null pointer.

http://dcs.cemetech.net/index.php?title=ASM_Header#Normal_Header
There seems to be more and more talk of C with z80--I was under the impression that this results in terrible code, is that no longer the case?
merthsoft wrote:
There seems to be more and more talk of C with z80--I was under the impression that this results in terrible code, is that no longer the case?
I was just about to ask the exact same question. If it's actually feasible to write games and programs for Doors CS in C now and have them fit inside the 8KB limit, that would be a massive step upwards. Particularly with the TI-84 Plus C Silver Edition coming soon.
It has been possible for a while. You just need to know your limitations, that's all. I _did_ post a guide to using SDCC with TIOS Razz
It's been possible for, like, ever. We're not asking about the possibility, but rather the feasibility and the quality of the code that would be produced. My interest is in how good the code is for someone who's neither a great C nor z80 programmer.
Being a good C programmer is probably requisite. One of the motivations for the LLVM stuff AHelper and I've been looking at, is because a lot of the optimizations in SDCC are the result of hand tweaking, and LLVM is designed to have powerful optimizing capabilities and static code analysis.
So if we can get most (or all) of the Ti Z80 Asm BCALLS into one C include file, C might actually take off as a semi-major programming language for the Ti 83/4/+/BE/SE calcs?
GinDiamond wrote:
So if we can get most (or all) of the Ti Z80 Asm BCALLS into one C include file, C might actually take off as a semi-major programming language for the Ti 83/4/+/BE/SE calcs?

I think it could - you just need a lot of optimizations. I wonder if such a program could be compiled as a multi-page App - in that case, I think that C might even overtake ASM as the weapon of choice.
Compynerd255 wrote:
I think it could - you just need a lot of optimizations. I wonder if such a program could be compiled as a multi-page App - in that case, I think that C might even overtake ASM as the weapon of choice.


Well, I wouldn't hold my breath anytime soon...
it seems like there are a few different ways to write the Hello World program in C (whereas there is really only one "right" way to write it in say, TI-BASIC or Axe or Z80 Asm)

But yeah, I think that if C really does become optimized for the ti z80, then we might get alot of new programmers
I've tried looking at the tutorials and resources for these things, and I'm just really confused at the process involved, with what I need to do and how I need to run and build things - especially since I'm a Windows user, and this seems suited to Linux use. Is there a coherent, updated set of resources somewhere that I can get to for building TIOS programs in C?
Quote:
I wonder if such a program could be compiled as a multi-page App - in that case, I think that C might even overtake ASM as the weapon of choice.

Yes, it can, if you know what you're doing.
Quote:
I've tried looking at the tutorials and resources for these things, and I'm just really confused at the process involved, with what I need to do and how I need to run and build things - especially since I'm a Windows user, and this seems suited to Linux use. Is there a coherent, updated set of resources somewhere that I can get to for building TIOS programs in C?

Works the same anywhere.

* Write code
* Compile code to (typically relocatable) object files
* Link object files into machine code
* Put machine code into a TI file format.

For a simple compiling test on Windows (assuming you have all of the necessary tools):

Code:
sdcc -mz80 --no-std-crt0 --code-loc 0x9DAE --data-loc 0x9872 -L ../lib -I ../include -DTI83P -DION -Wl../startup/ti83p_dcs.rel ti83p.lib test_dcs.c
makebin -p -s 65536 test_dcs.ihx test_dcs.bin
cutbin test_dcs.bin 0x9d93 test_dcs_small.bin
wabbit test_dcs_small.bin TESTDCS.8xp
Thanks very much, Elf. I got all the right tools and got something compiled, but it crashed my emulator. Sad Hopefully I can see if there's anything wrong with my build process.

Is the cutbin program that comes with TISDCC defective? I'm not using the program itself, but I did snarf its lib, like you directed, and its cutbin, which you did not.

EDIT: It isn't cutbin at all - the program header looks fine, and the icon looks coherent - a 16x16 square. In fact, the sample program runs all the way to pressing Enter, and then WabbitEmu gets thrown into the debugger and is running at the beginning of memory. When I reset the calculator and turn it back on, "Hello World" does appear on the screen, and then I get the RAM Cleared message.

EDIT 2: And the error has to do with the compilation process itself. I tried commenting out all of the code inside main() and still got the error. I think that the call stack must be set incorrectly, and it's not jumping back to the right spot. Also, I noticed that DispInt(char) looks wrong - it has two or three digits each on separate lines.

EDIT 3: Here's my C source:
Code:

#include <ti83p.h>
#define NULL 0x0000
__at NULL const int ALE; 
volatile const char Description[23] = "A Program for the Eyes";
volatile const char Icon[32] =
           {0xFF,0xFF,0x80,0x01,
            0x80,0x01,0x80,0x01,
            0x80,0x01,0x80,0x01,
            0x80,0x01,0x80,0x01,
            0x80,0x01,0x80,0x01,
            0x80,0x01,0x80,0x01,
            0x80,0x01,0x80,0x01,
            0x80,0x01,0xFF,0xFF};

void main(void) {
}

... and the ASM file it generates:

Code:

;--------------------------------------------------------
; File Created by SDCC : free open source ANSI-C Compiler
; Version 3.2.0 #8008 (Jul  6 2012) (MINGW32)
; This file was generated Wed Dec 12 08:01:45 2012
;--------------------------------------------------------
   .module helloworld
   .optsdcc -mz80
   
;--------------------------------------------------------
; Public variables in this module
;--------------------------------------------------------
   .globl _main
   .globl _Icon
   .globl _Description
   .globl _ALE
;--------------------------------------------------------
; special function registers
;--------------------------------------------------------
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
   .area _DATA
;--------------------------------------------------------
; absolute external ram data
;--------------------------------------------------------
   .area _DABS (ABS)
;--------------------------------------------------------
; global & static initialisations
;--------------------------------------------------------
   .area _HOME
   .area _GSINIT
   .area _GSFINAL
   .area _GSINIT
;--------------------------------------------------------
; Home
;--------------------------------------------------------
   .area _HOME
   .area _HOME
;--------------------------------------------------------
; code
;--------------------------------------------------------
   .area _CODE
;helloworld.c:17: void main(void) {
;   ---------------------------------
; Function main
; ---------------------------------
_main_start::
_main:
;helloworld.c:32: }
   ret
_main_end::
_ALE   =   0x0000
_Description:
   .ascii "A Program for the Eyes"
   .db 0x00
_Icon:
   .db #0xFF   ; -1
   .db #0xFF   ; -1
   .db #0x80   ; -128
   .db #0x01   ;  1
   .db #0x80   ; -128
   .db #0x01   ;  1
   .db #0x80   ; -128
   .db #0x01   ;  1
   .db #0x80   ; -128
   .db #0x01   ;  1
   .db #0x80   ; -128
   .db #0x01   ;  1
   .db #0x80   ; -128
   .db #0x01   ;  1
   .db #0x80   ; -128
   .db #0x01   ;  1
   .db #0x80   ; -128
   .db #0x01   ;  1
   .db #0x80   ; -128
   .db #0x01   ;  1
   .db #0x80   ; -128
   .db #0x01   ;  1
   .db #0x80   ; -128
   .db #0x01   ;  1
   .db #0x80   ; -128
   .db #0x01   ;  1
   .db #0x80   ; -128
   .db #0x01   ;  1
   .db #0x80   ; -128
   .db #0x01   ;  1
   .db #0xFF   ; -1
   .db #0xFF   ; -1
   .area _CODE
   .area _CABS (ABS)

Does that look right to you?
I should also say that I'm using DCS 7 beta 2, and my calc is running 2.53 MP. And it's definitely the C program - a pure ASM program (Invalid Tangram) works just fine).

EDIT 4: And as if all those addendums weren't enough, here's a Windows batch file I wrote to compile my program (note that it's named helloworld.c and that ti83p_dcs.rel is in the same directory as my source:

Code:
echo off
@echo ------------------------
@echo Compiling...
@echo ------------------------
sdcc -mz80 --no-std-crt0 --code-loc 0x9DAE --data-loc 0x9872 -L ../lib -I ../include -DTI83P -DION -Wl./ti83p_dcs.rel ti83p.lib helloworld.c

if ERRORLEVEL=1 goto fail
goto package

:package
@echo Compile succeeded! Packaging...
@echo ------------------------
makebin -p -s 65536 helloworld.ihx helloworld.bin
cutbin helloworld.bin helloworld_small.bin 0x9d93
wabbit helloworld_small.bin HELLO.8xp
goto end

:fail
@echo ------------------------
@echo Compile Failed!
@echo Fix the errors above and try again.
@echo ------------------------
goto end

:end
pause


EDIT 5: In fooling with the WabbitEmu debugger some, I noticed that it never appears to even reach the ret at the end of the program - I set breakpoints on all the rets in the 100 or so bytes after 0x9d9e, where the program starts, and none of them were hit. Which seems to me as if the stack is being messed up somewhere.
* bump *

Hi, I edited my last post with my issues. Do you see anything that could be the cause of my calc crashing when I try this?

EDIT: Eureka! I found it! (But I have no idea what to do about it...)
This is the important part of the assembly source (what it should be):

Code:
init:
    ld (saved_sp), sp  ; save stack pointer
    di

        ;; Initialise global variables
        call    gsinit
    call    _main
    jp  _exit     
_exit::
    ld sp, (saved_sp)      ;restore stack pointer
    ld iy, #0x89F0
    ei
    ret
saved_sp:
    .ds 2

gsinit::     
        ret

And here's how that code ends up getting compiled - and compiled very wrongly:

Code:
9DA1:  ld ($9DB9), sp
9DA5:  di
9DA6:  call $9DF3 ; call gsinit
9DA9:  call $9DBB ; call main
9DAC:  jp $C9AF ; jp _exit, SHOULD be jp $9DAF
9DAF:  ld sp,($9DB9) ; exit code...
9DB3:  ld iy,$89F0
9DB7:  ei
9DB8:  ret
9DB9: .dw $FFC3 ; (saved_sp)
...
9DBB:  ret ; main
...
9DF3:  ret ; gsinit

For some reason, SDCC is writing the wrong address for the jump instruction, causing the >$C000 check to trigger and the calculator to reset. Is there a way I can fix this, or is this a bug in SDCC?

EDIT 2: And I fixed it! Instead of doing a "jp exit", do a "jr exit"! Because "_exit" is typically really close to the label that jumps there (since the description and icon are pointed to), it should work. However, it seems that there is thus a bug in how SDCC writes jp instructions, because the code is now:

Code:
9DAC: jr $9DAF
9DAE: ret ; which corresponds to a "ret" under __clock::
9DAF: ; exit code

It appears that SDCC is only writing the LSB for absolute jump instructions, not both the LSB and the MSB. Thus, the stray "ret" that appears so easily now was meshed into the jp instruction, causing the processor to enter never-never land. Bug report time! Smile
Make sure you have the newest version of SDCC, not the one that comes with the tisdcc package on ticalc.org. iirc, I installed mine off of MacPorts, and haven't had any of the problems you're describing.
I am using the newest version for Windows (SDCC 3.2.0a for Win32). The command "sdcc --version" outputs:

Code:
SDCC : mcs51/gbz80/z80/z180/r2k/r3ka/ds390/pic16/pic14/TININative/ds400/hc08/s08 3.2.0 #8008 (Jul  6 2012) (MINGW32)

I'll try reinstalling, just in case anything is wrong here.

EDIT: Same problem. I don't even need to run it in order to tell because the jp version is exactly the same size as the jr version, even though it should be one byte larger.

EDIT 2: And it appears that the bug is in sdasz80, not sdcc itself. I just wrote a program with a huge while(1) loop that forced sdcc to write an unconditional jp instruction, and it wrote both bytes just fine. I think that sdas makes a mistake in writing the rel file from the crt0.
Oh, and I can't help but admire how smart of a compiler sdcc appears to be - I filled up the loop by writing complex math expressions, but if I didn't use the result later, it would exclude the code from the program.

EDIT 3: OK, now that my build environment is somewhat working, I tried to add functions to ti83p.lib so that I could get cracking. However, it appears that SDCC has changed significantly since the lib was compiled: I'm getting lots of syntax errors such as tokens not being recognized and such. Should I just start from scratch?
So I compiled the first bit of assembly code on the topic (the one thats supposed to replace crt0.s?) and it compiled to ti83p_dcs.sys

Is that correct?
  
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