Jump to content
IGNORED

Glorious People's small c compiler


dhe

Recommended Posts

Couple of software notes,

  CROM (C ROM - or having your c libraries persistent in the 8K module space, leaving 32K for c code) - can be found in this thread.

  

 

  After much digging I did find what I believe to be Winkler's source to 5.0 (not 5.1) - if nothing else, it should give me a better understand of how the c compiler works.

 

 

c99rel5.dsk

  • Like 2
Link to comment
Share on other sites

The difference between names and *names seems to be the first generates just generates a string of data.

The second generates the same data, but is referenced by a label and offset, which makes sense, you would need some way to get at a particular data element.

 

>> Plain Names <<
*char names[5] = {
NAMES*    "DAN",
*    "STEVE",
*    "BILL",
*    "GREG"
*};
 BYTE 68,65,78,0,83,84,69,86,69,0,66,73
 BYTE 76,76,0,71,82,69,71,0

>> *names <<
*char *names[5] = {
NAMES*    "DAN",
 DATA C$47
*    "STEVE",
 DATA C$47+4
*    "BILL",
 DATA C$47+10
*    "GREG"
 DATA C$47+15
*};
 BSS 2
C$47 BYTE 68,65,78,0,83,84,69,86,69,0,66,73
 BYTE 76,76,0,71,82,69,71,0
* 

>> Two Deminsional Array <<
*char *names[5][10] = {
NAMES*    "DAN",
 DATA C$47
*    "STEVE",
 DATA C$47+4
*    "BILL",
 DATA C$47+10
*    "GREG"
 DATA C$47+15
*};
 BSS 92
C$47 BYTE 68,65,78,0,83,84,69,86,69,0,66,73
 BYTE 76,76,0,71,82,69,71,0
* 

 

I was a bit surprised at the third example, I kind of expected the first element to generate:

byte 68,65,78,0,0,0,0,0,0,0

Reserving enough space so edits could be made to that array, up to 9 chars.

 

@Tursi it would seem the compiler doesn't appreciate &name

image.png.66e67c732583aef5a88505acef0a5f76.png

 

 

I can game the system, by entering my own fix width strings, I'll have to see now, if I can modify elements in this array.

 

*char *names[5] = {
NAMES*    "DAN      ",
 DATA C$47
*    "STEVE    ",
 DATA C$47+10
*    "BILL     ",
 DATA C$47+20
*    "GREG     ",
 DATA C$47+30
*    "JEFF     "
 DATA C$47+40
*};
C$47 BYTE 68,65,78,32,32,32,32,32,32,0,83,84
 BYTE 69,86,69,32,32,32,32,0,66,73,76,76
 BYTE 32,32,32,32,32,0,71,82,69,71,32,32
 BYTE 32,32,32,0,74,69,70,70,32,32,32,32
 BYTE 32,0

 

 

d.

  • Like 1
Link to comment
Share on other sites

Bug in the c99 compiler.

 

I was wanting to study a bit the code c99 generated in relationship to arrays of strings.

 

The code compiled, assembled and run, but for study, I said - yes, include c source code, that's where my troubles began.

 

Running assembler resulted in SYNTAX error.

 

The first was an easy fix,


 

9qGmF9cipUU2cgk02eUG1TdQodvLZ8xFR_zZ_NIWoXNlBnS_9oPCG7QLAfBIJvNPXoEJtmxLalH1q-CGEtgMAI7aD8Hrgp-VKNmnqspZUMWtw8hxsU7g7w9q9iL-NKFEppjBnZ0B

 

WujpliPdlVbBGywGp_Z-9n84Uyv7SwWfkM8yMCYFoX4s7YAVoWig5nQax7wnNjD_c2WjHe4y5jbCVzhwlCbFYHW0elomtQh5hSaDkgqAR0XU-S8TrSKyXR83ujLFnHW2eZ04BBeJ

Looks like STRINGFNS is to long - putting comment on one line, and stncmp… on another fixed.

*stncmp - fixed.

 

What about 742?

Goes away also, if no c source included in assembler code.

 

With no source included:

9mnFFfmr4H5GMSFJxAjRbIksl9OWNtgF1r8uKXTbztjZz_O_NRKoO8KCYEpA5eK9CTtoihMUM4NJJg2aNgjZbKGMoVjgMje2DR9L5_1PFfyLT9Q0AYQPXKMkpHGqNPIBvMQaLlV4

 

With source:

 

k6I0fBS3Iqj8dMQPPCplxzmUrollrPrl7yWrFui9c8xSdlX4jn8jVh5N2x6XCAdXu1uMVOhuFH-5niuwYnGCJQqkKvw4AeqU35Lk59xL64EDoZ0fh5jasj_1xkLyHrriZADjILD5

 

Ideally we would have had a line, like 502 above, and something like

* "DAN",

But it got muddled, probably a challenge with not doing multiple passes.

 

So I can still include the source as a debug tool, just not for compile and run...

 

 

 

Link to comment
Share on other sites

  • 3 weeks later...

So, I ran into a wall with TCIO file library. So compared to many hours spent trying to get file i/o going with TCIO, I fired up TICodeEd + RXB + Classic99 and was able to get coding running in about 30 minutes.

I was also having trouble with string arrays, again multi-hours with c99 and no workey. Opened up three windows on a linux machine – one with a simple makefile, one ./a.out and a third with vim. Between makefiles -Wall and vim Syntax highlighting, had the code debugged in about 15 minutes.

Tool chains make a difference – who knew?

As sometimes happens with projects, things take interesting turns. I noticed a couple of articles on whtech by a guy named Donald L. Mahler. He wrote ccolumn for the Boston Computer Society for about six years. His columns where very practical. One of the principals of CaDD was a stalwart member of the Boston Computer Society and had all the past newsletters. BSC had an interesting arrangement. They had a newsletter that was passed out at the meeting and a newsletter that was contributed to the BCS as a whole, that was the one printed and mailed to other User Groups. So to have the whole enchilada – you had to go to the meetings and get the newsletter.

I’ve been helping convert scanned code from the BCS newsletters to working examples. It’s been challenging. Sometimes when the code was published in the newsletters, depending on when the newsletter was written it was for older versions of Clint’s compiler. That had to be upgraded. Sometimes, when it was formatted for the newsletter, characters were changed and lost. Then other times when the newsletters were scanned and converted to text more translations were done. So I start out with more of a suggestion of the working code.

I had a program that was about 80 lines, turned into a single paragraph! ?

We are up to February 1988 and have 81 pages of tutorial. I think when finished this will be the most comprehensive c99 tutorial ever. He is definitely the Bruce Harrison of c99. When Micropendium folded, they had published 76 articles by Bruce. He had 7 more articles in the pipeline. His Art of Assembly book covers 666 pages.

I also found Clint’s code to do a disk catalog in the BCS library, I tried to do a disk catalog under TP99 and couldn’t get that working.  It took some effort to drag the v3 code into the v5 world, but I got it done. I’ve been getting better at using a combination of compiler error codes, assembler error codes, hoping into the assembly source to find out what is unhappy, using string/grep to find what library contains a routine I’m looking for etc.

In at least one worker's dwelling, the glorious peoples small compiler produces on for the people!
 
DSK2.CFIO
DSK2.TCIO
DSK2.FLOAT
DSK2.CSUP
DSK2.PRINTF
DSK4.CAT;O
/*
** Read a directory from disk
**
** Author: Tom Bentley
** 207 - 324 Cambridge ST. N.
** Ottawa, ON K1R 7B5
** Canada
**
** Date: May 5, 1986
**
** required libraries:
** - tcio
** - float
** - printf
** - csup
*/
 
#include "DSK2.STDIO"
#include "DSK2.TCIO;H"
#include "DSK2.FLOAT;H"
 /* #include "dsk1.printfio" */
 
external printf();
 
char buff[255];
char typs[40] = {"Dis/Fix","Dis/Var","Int/Fix","Int/Var","Program"};
char dir[6] = {"DSKx."};
 
int eof;
int fp;
 
main()
{
  int fp,rec,eof,size,typ,b_ptr;
  char str[20],drive,prot,i;
  float f1[FLOATLEN],f2[FLOATLEN],res[FLOATLEN];
  rec = 0;
  puts("Drive Number ?");
  drive = getchar();
  dir[3] = drive;
  fp=topen(dir,INPUT+RELATIVE+INTERNAL+FIXED,0);
  if(fp<1)
    printf("I/O Error = %d\n",fp);
  else
  {
    /* get disk name and stats */
    putchar(12); /* clear screen */
    tread(buff,RELSEQ,fp,&size);
    b_ptr = buff;
    get_name(&b_ptr,str);
    printf("Directory= %s Diskname= %s\n",dir,str);
    get_num(&b_ptr,str,f1); /* dummy record type */
    get_num(&b_ptr,str,f1); /* total sectors on disk */
    get_num(&b_ptr,str,f2); /* available sectors */
    printf("Available= %s ",str);
    fexp(f1,"-",f2,res);
    printf("Used= %s\n\n",ftos(res,str,0,0,0));
    puts(" Filename Size Type P\n");
    puts("---------- ---- ---------- -\n");
    while(1)
    {
      poll(1);
      eof=tread(buff,RELSEQ,fp,&size);
      if(eof) break;
        b_ptr = buff;
      if(!get_name(&b_ptr,str)) break;
        printf("%-10s ",str); /* file name */
      get_num(&b_ptr,str,f1); /* file type */
      typ=ftoi(f1);
      if(typ < 0)
      {
        prot = 'Y';
        typ = -typ;
      }
      else
        prot = ' ';
      --typ;
      get_num(&b_ptr,str,f1); /* sectors allocated for file */
      printf("%4s %-7s",str,&typs[typ*8]);
      get_num(&b_ptr,str,f1); /* bytes per record */
      if(typ != 4)
        printf("%3s",str);
      else
        printf(" ");
      printf(" %c\n",prot);
    } /* end of while(1) */
  }  /* end of else */
  tclose(fp);
} /* end of main */
 
/*
** get name of disk or file
*/
get_name(buff,t)
int *buff;
char *t;
{
  char *b;
  int j,siz;
  b = *buff;
  j=siz=*b++;
  *buff = *buff + j + 1;
  while(j--)
    *t++ = *b++;
  *t = '\000'; /* null terminate */
  return(siz);
}
 
get_num(buff,t,f)
int *buff;
char *t;
float *f;
{
  char *b;
  b = *buff;
  ++b;
  fcpy(b,f);
  ftos(b,t,0,0,0);
  *buff = *buff + 9;
}
 
 

 

  • Like 5
Link to comment
Share on other sites

c99 in the NEWS! (Tongue in check).

 

"We all know Linux is written in C," writes ZDNet. "What you may not know is that it's written in a long-outdated C dialect: The 1989 version of the C language standard, C89."

But that's about to change, explains long-time Slashdot reader UnknowingFool: Linus Torvalds has decided that Linux will move to the C11 standard starting with kernel 5.18.... Linux had planned to move to a newer standard eventually with C99 being the next version. However a recent patch to a security problem revealed that there could be problems with C99.

In order to patch a potential security problem with Linux's linked-list primitive speculative-execution functions, it was found that C99 would require the iterator must be declared outside the loop which would expose it to another security problem. Since C99 was not very popular, it was agreed to skip it and use C11. Backwards compatibility with most compilers like gcc should allow for an easily transition of most of the code.

ZDNet adds that "This isn't as big a transition as it may seem. C89 still has almost universal support. Because any C compiler is backward compatible with earlier versions, you won't have any trouble compiling or running a C89 program. So, a C11 compliant compiler won't have any trouble with any C89 legacy code."
 
  • Like 1
Link to comment
Share on other sites

I read this too.  It will be interesting to see how that goes.

 

I am fascinated by the discussions in the C community about "nasal demons" (un-specified behaviour).

This has crossed into discussions on comp.lang.forth because GForth is written with GCC and with each compiler change there were problems.

This has lead to the possibility of abandoning C to make GForth. 

It seems the endless pursuit of performance enhancements versus predicability is the issue from what I understand of the conversation. (limited knowledge of C here) 

 

Link to comment
Share on other sites

It's the right answer for all projects... even if the warnings /are/ known to be safe, you should turn them off one by one for the specific code block you determined, rather than get people used to ignoring them. I've worked on so many projects that just flood the screen with warnings - how would you ever find a real one, or a new one?

 

The drive to resolve undefined behavior in C rubs me the wrong way for some reason. The reason things were defined as undefined behavior was not to shrug and say "idunno", but to leave it open to architecture-specific implementation and warn the programmer not to do that. But it seems that telling the programmer something is a bad practice these days isn't acceptable, so instead the language must change. Probably I'm getting old. ;)

 

  • Like 2
Link to comment
Share on other sites

44 minutes ago, Tursi said:

It's the right answer for all projects... even if the warnings /are/ known to be safe, you should turn them off one by one for the specific code block you determined, rather than get people used to ignoring them. I've worked on so many projects that just flood the screen with warnings - how would you ever find a real one, or a new one?

 

The drive to resolve undefined behavior in C rubs me the wrong way for some reason. The reason things were defined as undefined behavior was not to shrug and say "idunno", but to leave it open to architecture-specific implementation and warn the programmer not to do that. But it seems that telling the programmer something is a bad practice these days isn't acceptable, so instead the language must change. Probably I'm getting old. ;)

 

When you say it that way it makes a lot more sense to me.

 

The ANSI Forth standard was purposely not an "implementation spec" in order to accommodate all current or future implementations.

However this leads to a lot of arguments on what it "really" means.

 

I know very little about the unspefied behaviour  (I thought the term "nasal demons" was genius) except what I have read over time about GForth and the build team's frustrations with GCC verions.

I know they push the envelope pretty hard to make the C compiler do their bidding so could be a case of:

 

"Doctor it hurts when I do this." 

Doc says" Then don't do that!" 

 

 

 

Link to comment
Share on other sites

1 hour ago, TheBF said:

"Doctor it hurts when I do this." 

Doc says" Then don't do that!" 

That was the original intent, yes. Remember that C was originally intended as an easier way to write cross-platform assembly. ;)

 

But, on the other hand, I also believe "we've always done it that way" isn't a good excuse, so I suppose I should accept it. Just wish they'd keep the meddling in C++ and leave my C alone. ;)

 

 

  • Like 1
Link to comment
Share on other sites

Today's mis-adventure with the GPSCC(TM).

 

I've noticed an undocumented feature before with screen blanking.  When running a long running program the screen will blank. And would not re-enable with a key stroke.

 

I thought I could work around that, by putting a poll(); inside the main loop.

 

That partially works, as long as you are willing to press the any key every few seconds, the screen will not blank, but once the screen blanks, no amount of any key pressing will get the screen back.

 

I verified this behavior by looking at VREG 1.  At the start of the run, VREG 1 is set to F0 1111 0000. Once the screen blanks, VREG = B0 1011 0000 which would be correct according to the E/A manual.

 

   "Bit 1 Blank enable/disable. A value of 0 causes the active display (the entire screen) to be blank,and a value of 1 allows display on the screen. With a value of 0, the screen only shows the border color."
 
  I tested my theory by changing the VREG value back to F0, both while the program was running and when it had finished, by entering vr1=f0 in the debugger. Which brought the screen back under both cases.
 
  Looks like I need to mix some assembler in my c99 code to get the desired behavior....
 
image.thumb.png.56472a0b75b042e22278405986cbc92e.png
 
 
 
 
  • Like 1
Link to comment
Share on other sites

The screen blank is done by the console interrupt routine. The address >83D6 (word) increments by 2 every frame - if it reaches 0, then the screen blanks. Every time KSCAN detects a key, it resets it to 0.

 

Because the blank routine looks for /exactly/ zero, you can set it to an odd value (like >0001) and the screen will never blank. You can also CLR it yourself at any important point in your program to prevent the screen blank from occurring.

 

You should be able to do this in C with code like so:

 

volatile unsigned int *pBlank = (volatile unsigned int*)0x83c6;

...

*pBlank = 0;  // reset screen timeout

...

*pBlank = 1;  // make the blank never happen ;)

c99 probably won't support the volatile flag, but since it doesn't optimize it doesn't need it. Hopefully the rest works fine.

 

For modern C code there should be a const in there too, to tell the compiler the address of the pointer won't ever change, but I can't be bothered to look it up where it goes right now ;)

 

 

Edited by Tursi
  • Like 2
  • Thanks 1
Link to comment
Share on other sites

@tursi I found a number of different ways on modern compilers to do the pointer to a memory address, I could not find any incantation that would be accepted by GPSCC. As a test I just slammed in:

 

#asm
 movb >1,@>83c6
#endasm
 
That made the code run as I needed. Then I was thinking, have I ever seen c99 code that did direct access of a memory location, and I remembered B. Lucid of the Huggers UG did a good amount of c99 with the MBP A/D card. I looked around and came up with code from the master himself for reading code directly from memory. I now just need to get a few and see if I can get direct memory to memory r/w to work, without resorting to #asm!

 

I found the for(;;) - interesting, had not see that before, and I like the way he deals with the left hand byte.

 


/**************************************************************************
 * This c99 program shows how to access the MBP kit with this language.   *
 * It was developed using Edition 2 : 86/04/01 of c99 developed by        *
 * Clint Pulley. c99 is available from:                                   *
 *  Clint Pulley                                                          *
 *  38 Townsend Avenue                                                    *
 *  Burlington, Ontario                                                   *
 *                                                                        *
 * The MBP Clock/Calendar - Analog to Digital Converter Kit is            *
 * available from:                                                        *
 *  Disk Only Software                                                    *
 *  P.O. Box 4170                                                         *
 *  Rockville, MD 20850                                                   *
 *                                                                        *
 **************************************************************************/
 
#define  MOADD   -31154        /* hardware address of month  */
#define  DATEADD -31156        /*     "       "     " date   */
#define  DAYADD  -31158        /*     "       "     " day    */
#define  HOURADD -31160        /*     "       "     " hour   */
#define  MINADD  -31162        /*     "       "     " minute */
#define  SECADD  -31164        /*     "       "     " second */
 
extern printf();
 
 
 
main()
{
  int mbp[6];       /* data vector */
  int *mbpptr;      /* vector pointer */
  int temp;
 
  putchar(12);
  for(;;)           /* loop forever   */
{
  mbpptr = MOADD;   /* G        */
  mbp[0] = *mbpptr; /*  E  D    */
  mbpptr = DATEADD; /*   T  A   */
  mbp[1] = *mbpptr; /*       T  */
  mbp[2] = 86;      /*        A */
  mbpptr = HOURADD;
  mbp[3] = *mbpptr;
  mbpptr = MINADD;
  mbp[4] = *mbpptr;
  mbpptr = SECADD;
  mbp[5] = *mbpptr;
 
  for(temp=0;temp<6;++temp)
    {
    mbp[temp] = mbp[temp] & 255;  /* good data only in right hand byte */
/*  printf("mbp[%d] = %d\n",temp,mbp[temp]); */
    }
 
  for (temp=0;temp<6;++temp)      /* convert data from binary coded decimal */
   if (temp !=2 )                 /*      to integer                        */
     mbp[temp] = BCDtoINT(mbp[temp]);
 
  locate(8,10);
  printf ("%d/%d/%d\n\n",mbp[0],mbp[1],mbp[2]); /* print date */
  locate(12,10);
  printf ("%d:%d:%d\n\n\n",mbp[3],mbp[4],mbp[5]);  /* print time */
}
}  /* end of main */
 
BCDtoINT(x)  /* function to convert BCD to integer */
int x;
{
  x = x - 6*(x/16);
  return(x);
}

 

 

Link to comment
Share on other sites

31 minutes ago, dhe said:

@tursi I found a number of different ways on modern compilers to do the pointer to a memory address, I could not find any incantation that would be accepted by GPSCC. As a test I just slammed in:

 

#asm
 movb >1,@>83c6
#endasm
 
That made the code run as I needed. Then I was thinking, have I ever seen c99 code that did direct access of a memory location

 

It's just another pointer, that you initialize yourself. ;) Like I said, it should have worked if you dropped the word 'volatile'. I don't have any idea what GPSCC is.

 

Your MOVB won't work like you expect - you can't move immediate values on the 9900. You're actually moving the most significant byte of Register 1 with that command - whatever it may be. Furthermore, since >83D6 is a word counter, you should use MOV and not MOVB to ensure you're updating both bytes of it. As-is, it'll still be an even value and eventually blank.

 

To force it to '1' will require two instructions on the 9900, unless you have a >0001 somewhere else in your program you can reference:

 

#asm

  LI R0,>0001

  MOV R0,@>83D6

#endasm

 

Mind you, this assumes that it's safe to change the value of R0 - depends on the C compiler.

 

To do it in one instruction, you need a word >0001 somewhere you can access. Most programs have one somewhere, but if you get flexible and don't mind relying on the TI ROM being present, the first odd value in the ROM is a >020F at >002C, and that will work fine:

 

#asm

  MOV @>002C,@>83D6

#endasm

 

Remember, you need to reload the value after a KSCAN in case it detected a keypress and cleared it back to zero. For that reason, programs that use KSCAN probably should disregard the odd-number-trick and just use CLR as part of their main processing, say once a frame:

 

#asm

  CLR @>83D6

#endasm

 

Each CLR will give you 3-5 minutes before the blank happens, so that's lots of time to hit it again. ;)

 

Link to comment
Share on other sites

42 minutes ago, dhe said:

I found the for(;;) - interesting, had not see that before, and I like the way he deals with the left hand byte.

The masking and the way this is accesses the various memory addresses is kind of rough, it suggests working around compiler limitations. If you want bytes, you would normally specific a char *, though maybe the registers need to be accessed as words. I don't know the hardware.

 

I wouldn't use a single pointer and change the address for each one, though, that doubles the work being done. I'd either define the addresses inline (ie: mbp[0] = *((int*)MOADD); ), or access the pointer as an array, since the addresses are consecutive in memory. (ie: mbpptr=SECADD; mbp[0]=mbptr[5]; mbp[1]=mbptr[4];, etc)... or better still, define the mdpptr and use the defines as indexes instead of raw addresses. ;) But again, it's possible the compiler generated incorrect code and forced that as a workaround.

 

It's been many years since I put c99 away, and I'm not entirely sure that's even what you're using now that you mention a different one. ;)

 

All that said, for(;;) is my favorite way to define an infinite loop. It doesn't throw warnings like while(1) (constant condition on compilers that check) and is pretty clear in its intent once you recognize it. It's also nice to take away how that reveals that any of the three parts of a for command are optional. Though when I was younger I was fond of defining a char pointer named hell and doing 'while (hell != "frozen")'... very wasteful though ;)

 

 

 

  • Like 2
Link to comment
Share on other sites

As I understand it the source code for this compiler is no longer available?

 

I makes me wonder if it would be worthwhile to try rebuilding Small C from source.

I remember studying an old version of Small C for DOS, 20 years ago and it seems pretty understandable.

Probably a ton of work just the same to make it reliable but in the end the compiler would be understood better no?

Some of the GCC ASM code could be used to guide the brave person who tries it I should think.

 

And of course I just checked and someone on the inter-web has "re-constituted" Small C.

https://github.com/ncb85/SmallC-85

 

The notes claim that you just need to change the codexxxx.c  file and all will be well.  :) 

Is this a crazy idea?

 

  • Like 1
Link to comment
Share on other sites

  This week I finished up DLM (Donald L Mahler's) Column from 0189 Boston Computer Societies Newsletter.

  The original can be found here: http://ftp.whtech.com/user groups/Boston Computer Society/bcsmeeting8901.pdf

 

  A couple of times I've hit code that was impossible to compile.

 

  In the above example he defines two arrays:

    int list1[10], list2[10]    <- well and good.

    but then he proceeds to use an array named able {le sigh}.

 

  Many of DLM's columns are direct copies or modifications from a book called Introduction to C, by Paul M. Chirlian. This book is probably thee best book to use as a companion for c99. Mr. Chirlian wrote a number of books on computers and electronics used for college classes. The book is early enough that it doesn't use advanced features that came along later. In addition, since he didn't know what hardware or compiler the student would be used with, he kept to the most common of denominator. Mr. Chirlian is also good at explaining how things work.

 

   I'm very glad I purchased this book, because it allowed me to glance at the code and figure out, in Chirlian, the arrays were called able and baker, I guess he felt he would improve upon them by calling them list1 and list2. Also, the original code, just prints "sum=" a number and then a bunch of numbers that don't match the sum, potentially leaving the user confused. I went ahead and printed out list1 and list2 with each of their elements as the example code was trying to show taking a populated array list1, and modifying and populating array list2 from array list1 and using arrays + functions. The sum printed was the sum of the original array list1, the numbers printed was each element of list2.

 

  On to the next column.  

 

 

  • Like 1
Link to comment
Share on other sites

When looking at the Master's code to directly access the MBP A<>D card, I saw the negative address, I always get tripped up on that so I used GCC to write a shop tool to do address conversions.
 
The two interesting things I learned while writing the code was casting.
      b = (short signed int)hex_input;      
      // cast as a short signed int
 
the other was this neat little hack to convert from a  char to an int.
      mychoice2 = mychoice_char - '0';   // convert single char to int!!
 
Donald L. Mahler is finished. Stopped at 137 pages. Unfortunately towards the end of 1989 Peter Hoddie left the Boston Computer Society, and it wasn't long after that things kind of fell apart. But, good work was done and I learned a lot from it.
 
    @tursi has been kind enough to release some of his older code, and it's well worth studying.
 

My BBS is here - it's mostly c99 with some assembly: https://harmlesslion.com/software/bbs

Nightmare on Elm St - TI BASIC - is here: https://github.com/tursilion/elmstreet  (website not updated yet)

Super Space Acer is here - it's mostly c99 but is being updated: https://harmlesslion.com/software/spaceacer

     A big hat tip, with appreciation to @tursi. 

 

I've sung the praise of -Wall, then I found -Wextra !

cleardot.gif
// dhe ldom 03092022
#include <stdio.h>
#include <stdbool.h>    // true defined here

/* Basic Terminal Handling */
/* for linux/gcc           */
#define clear() printf("\033[H\033[J")
#define gotoxy(x,y) printf("\033[%d;%dH", (y), (x))

/* Global Vars */

  int mychoice1;
//  int mychoice2;
  int mychoice2;
  char mychoice_char;
 
// gcc likes functions declared before use.

int Ftypechoice(int choice)
{
  while(true)
  {
    gotoxy(5,8);
    printf("**** Address Finder ****");
    gotoxy(5,10);
    printf("1. Enter a decimal address. \n");
    gotoxy(5,11);
    printf("2. Enter a hexadecimal address. \n");
    gotoxy(5,12);
    printf("Choice:");
    mychoice_char=getchar();
    mychoice2 = mychoice_char - '0';   // convert single char to int!!
//    scanf("%d",&mychoice2);
    if ((mychoice2 == 1) || (mychoice2 == 2)) break; // valid value move along
    printf("\n invalid input \n\n");
  }  // end while loop  
  return(0);
}

int main(void)
{
  short unsigned int hex_input=0;
  int dec_input=0;
  int b=0;   // temp var for manipulation

   clear();
 
   Ftypechoice(mychoice2);
 
  gotoxy(5,14);
 
// accept value in dec
  if (mychoice2 == 1)
  {
    printf("Enter Decimal Address:");
    scanf("%d", &dec_input);
    gotoxy(5,15);
    printf("%d", dec_input);
    
    if (dec_input<0)    // case of a negative number.
    {
         b=dec_input+65536;
         gotoxy(5,15);
         printf("Value as Unsigned Int: %d",b);
         gotoxy(5,16);
         printf("         Value in Hex: %hx",b);
    }

    if (dec_input>32767)  // case of number needing negating.
    {
      b=dec_input-65536;
      gotoxy(5,15);
      printf("Value as a Signed Int: %d",b);
      gotoxy(5,16);
      printf("         Value in Hex: %hx",b);
    }
    
     
    if ((dec_input > 0) && (dec_input < 32768))
    // case of number in natural state
    {
      b=dec_input;
      gotoxy(5,15);
      printf("Value in decimal is the same in all cases: %d",b);
      gotoxy(5,16);
      printf("                             Value in Hex: %hx",b);
    
    }
   
    if (dec_input == 0)  // case of number being zero
    {
       gotoxy(5,15);
       printf("Value in all cases: 0000\n");
    }
   } /* end if mychoice = 1 */
 
 
// accept value in hex  
  if (mychoice2 == 2)
  {
    printf("Enter Hexadecimal Address:");
    scanf("%hx", &hex_input);

      b = (short signed int)hex_input;      
      // cast as a short signed int
      
      gotoxy(5,15);  
      printf("  Value as Signed Int: %d",b);
      gotoxy(5,16);
      printf("Value as Unsigned Int: %d",hex_input);
      
  } /* end if mychoice = 2 */

   gotoxy(0,20);  // makes exit of program look more natural.
   return(0);     // return 0; also works, but return(0); is prefered.

} /* end of main */



//  From php3055 = poking data with LOAD
//  The address is a numerical expression or variable from -32768 through 32767.
//  Addresses from 0 through 32767 represent >0000 through >7FFF.
//  Addresses from -32768 through -1 represent >8000 through >FFFF
//  expressed in two's-complement form. To access an address above 32767,
//  subtract 65536 from it.The values, which can be repeated,
//  are decimal numbers which specify the byte values to be
//  loadedstarting at the address specified. For example,
//  the statement:
//  CALL LOAD(-16384,255,21)
//  places the values >FF and >15 in the bytes starting at address >C000.

 

 
  • Like 1
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...