view README @ 16:3d69c66b2610

arch: last fixup, now things seem to work as expected
author Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
date Fri, 08 Apr 2011 09:44:57 -0400
parents 5d9f272f4db6
children 175279b7d3d7
line wrap: on
line source

This README will help you figure out what this minimal system does.  In
short, it doesn't do a whole lot.  Making it do something useful is up to
you.

You can safely ignore:
	ipl/*
	scripts/*
	src/io.c

You can put your code in src/ and your include files in include/.  If you
add any .c files, you'll have to add them to the OBJS line in the Makefile.

Building
--------

First, you should make sure that the cross building tools are in your path.
For example, my system has /opt/cross/bin in $PATH.

In the top level directory, you simply run `make'.

Running
-------

Go into the hercules directory, and run:

$ hercules -f herc.cnf

Then, in another terminal, run:

$ telnet 127.0.0.1 3270

Hercules is the emulator for the system that you are developing for (x86 is
awful to develop for in a stand-alone way).

Now, in the Hercules window, you can type:

==> ipl c

That tells it to start executing whatever program is on device 0x000c.  This
happens to be whatever got compiled before.  (IPL stands for Initial Program
Load.)  Once you tell the emulator to run your code, you can interact with
your code in the telnet session.

If at any point you see a message in the Hercules window about the
processor stopping due to a SIGP or a "disabled wait state" you have a bug
in your code.

The Internals
-------------

After the init code runs, it calls the start function in src/init.c.  It
takes one argument, which specifies the amount of memory you have.  If, for
example, it it given 1048576, you know that addresses 0...1048575 are valid.
Note that unlike the standard C/C++ application environment, you can
load from/store to any of those addresses.  Accessing a NULL pointer will
NOT result in a SIGSEGV or a similar death of the program.  There are a few
ranges of memory that you should know about.

      0...   8191  hw state area (the hw stores status info here, do not touch)
   8192...
       ...1048575  the stack
1048576...         the code & globals

In English, the first 8k is used by the hardware to store important state.
You will not need to read/modify this state.  The code starts at 1MB, and
takes up whatever amount of space is necessary for it.  The stack starts at
1MB and grows downward.  You can do whatever you want with the unused
memory.  (My suggestion is to assume that the code + globals will not take
more than say 512kB, the stack no more than 512kB, and then think of the
layout as:

  0k...  8k  hw state
  8k...512k  free
512k...  1M  stack
  1M...1.5M  code + globals
1.5M...      free

That's my suggestion.  It's not the only way to do this, but it's simple to
think about.)

There are 2 more functions that you are provided:

int putline(char *buf, int len)
	prints len characters pointed to by buf;  it returns -1 if the
	length is invalid, or the length once the I/O completes


int getline(char *buf, int len)
	reads a line of text and saves up to len characters at buf; it
	returns -1 if the length is invalid, or the number of bytes put into
	buf