May 25, 2025

Sun 3/60 -- Boot ROM source files

No, unfortunately we have not located source code for the boot ROM.

However, Dan sent me several interesting files, apparently from the SunOS 4.1.1 sources.

cpu.addrs.h		SS411/reva/sys/stand/mon/sun3
cpu.map.h		SS411/reva/sys/stand/mon/sun3
sunmon.h		SS411/reva/sys/stand/mon/sun3
interreg.h		SS411/reva/sys/sun3
sunromvec.h		SS411/reva/sys/stand/mon/h
srt0.s			SS411/reva/sys/boot/sun3
map.s			SS411/reva/sys/boot/lib/sun3
standalloc.c
The directory sys/stand/mon/sun3 has a Makefile with this interesting section.
I don't find many of these files in my 4.1.1 sources, so they are perhaps part of the lost ROM source code.
FILES= blts.s cmp.s cpu.map.s db.s patt.s romvec.s space.s \
    trap.s asm_linkage.h assym.h cpu.addrs.h cpu.buserr.h \
    cpu.map.h cpu.misc.h dpy.h keyboard.h m68vectors.h \
    machdep.h memerr.h memreg.h structconst.h sunmon.h
There is plenty of interesting stuff in the "boot" and "stand" directories.
The following directory seems to have basic driver code for every device and controller that Sun supported:
SS411/reva/sys/boot/lib/common

sunromvec.h

This file has the following very helpful section. I had worked out some of these things by studying the disassmbled ROM and was pleased that my conclusions match these labels and comments. Having labels for the many others I had not yet worked out is very useful.

This file has many other useful insights.

struct sunromvec {
  char               *v_initsp;        /* Initial Stack Pointer for hardware.*/
  void               (*v_startmon)();  /* Initial PC for hardware.           */

  int                *v_diagberr;      /* Bus error handler for diagnostics. */
  /*
   * Configuration information passed to standalone code and UNIX.
   */
  struct   bootparam **v_bootparam;    /* Information for boot-strapped pgm. */
  unsigned int       *v_memorysize;    /* Total physical memory in bytes.    */
  /*
   * Single character input and output.
   */
  unsigned char      (*v_getchar)();   /* Get a character from input source. */
  void               (*v_putchar)();   /* Put a character to output sink.    */
  int                (*v_mayget)();    /* Maybe get a character, or "-1".    */
  int                (*v_mayput)();    /* Maybe put a character, or "-1".    */
  unsigned char      *v_echo;          /* Should "getchar" echo input?       */
  unsigned char      *v_insource;      /* Current source of input.           */
  unsigned char      *v_outsink;       /* Currrent output sink.              */
  /*
   * Keyboard input and frame buffer output.
   */
  int                (*v_getkey)();    /* Get next key if one is available.  */
  void               (*v_initgetkey)();/* Initialization for "getkey".       */
  unsigned int       *v_translation;   /* Keyboard translation selector.     */
  unsigned char      *v_keybid;        /* Keyboard ID byte.                  */
  int                *v_screen_x;      /* V2: Screen x pos (R/O).            */
  int                *v_screen_y;      /* V2: Screen y pos (R/O).            */
  struct keybuf      *v_keybuf;        /* Up/down keycode buffer.            */

  char               *v_mon_id;        /* Revision level of the monitor.     */
  /*
   * Frame buffer output and terminal emulation.
   */
  void               (*v_fwritechar)();/* Write a character to frame buffer. */
  int                *v_fbaddr;        /* Address of frame buffer.           */
  char               **v_font;         /* Font table for frame buffer.       */
  void               (*v_fwritestr)(); /* Quickly write a string to frame    *
                                        * buffer.                            */
  /*
   * Re-boot interface routine.  Resets and re-boots system.  No return.
   */
  void               (*v_boot_me)();   /* For example, boot_me("xy()vmunix").*/
  /*
   * Command line input and parsing.
   */
  unsigned char      *v_linebuf;       /* The command line buffer.           */
  unsigned char      **v_lineptr;      /* Current pointer into "linebuf".    */
  int                *v_linesize;      /* Length of current command line.    */
  void               (*v_getline)();   /* Get a command line from user.      */
  unsigned char      (*v_getone)();    /* Get next character from "linebuf". */
  unsigned char      (*v_peekchar)();  /* Peek at next character without     *
                                        * advancing pointer.                 */
  int                *v_fbthere;       /* Is there a frame buffer or not?    *
                                        * 1=yes.                             */
  int                (*v_getnum)();    /* Grab hex number from command line. */
  /*
   * Phrase output to current output sink.
   */
  int                (*v_printf)();    /* Similar to Kernel's "printf".      */
  void               (*v_printhex)();  /* Format N digits in hexadecimal.    */

  unsigned char      *v_leds;          /* RAM copy of LED register value.    */
  void               (*v_set_leds)();  /* Sets LEDs and RAM copy             */
  /*
   * The nmi related information.
   */
  void               (*v_nmi)();       /* Address for the Sun-4 level 14     *
                                        * interrupt vector.                  */
  void               (*v_abortent)();  /* Entry for keyboard abort.          */
  int                *v_nmiclock;      /* Counts in milliseconds.            */

  int                *v_fbtype;        /* Frame buffer type: see */

  /*
   * Assorted other things.
   */
  unsigned int       v_romvec_version; /* Version number of "romvec".        */
  struct   globram   *v_gp;            /* Monitor's global variables.        */
  struct zscc_device *v_keybzscc;      /* Address of keyboard in use.        */
  int                *v_keyrinit;      /* Millisecs before keyboard repeat.  */
  unsigned char      *v_keyrtick;      /* Millisecs between repetitions.     */
  unsigned int       *v_memoryavail;   /* V1: Size of usable main memory.    */
  long               *v_resetaddr;     /* where to jump on a RESET trap.     */
  void               (*v_exit_to_mon)();/* Exit from user program.           */
  unsigned char      **v_memorybitmap; /* V1: Bit map of main memory or NULL.*/
#ifndef sun3x
  void               (*v_setcxsegmap)();/* Set segment in any context.       */
#endif sun3x
  void               (**v_vector_cmd)();/* V2: Handler for the 'w' (vector)  *
                                        * command.                           */
#if defined(sun4) || defined(sun4c)
  unsigned long      *v_exp_trap_signal;/* V3: Location of the expected trap *
                                        * signal.  Was trap expected or not? */
  unsigned long      *v_trap_vector_table_base; /* V3: Address of the TRAP   *
                                        * VECTOR TABLE which exists in RAM.  */
#endif sun4 || sun4c
#ifdef sun4c
  struct physmemory  *v_physmemory; /* ptr to memory list */
  unsigned int       *v_monmemory;  /* memory taken by monitor */
  struct config_ops  *v_config_ops; /* configuration operations */
#endif sun4c
/* XXX - does sun4m really need this too? */
#if defined(sun3x) || defined(sun4m)
  int                **v_lomemptaddr;    /* address of low memory ptes      */
  int                **v_monptaddr;      /* address of debug/mon ptes       */
  int                **v_dvmaptaddr;     /* address of dvma ptes            */
  int                **v_monptphysaddr;  /* Physical Addr of the KADB PTE's */
  int                **v_shadowpteaddr;  /* addr of shadow cp of DVMA pte's */
  struct physmemory  *v_physmemory;      /* Ptr to memory list for Hydra    */
#endif sun3x || sun4m
  int                dummy1z;
  int                dummy2z;
  int                dummy3z;
  int                dummy4z;
};

/*
 * The possible values for "*romp->v_insource" and "*romp->v_outsink" are
 * listed below.  These may be extended in the future.  Your program should
 * cope with this gracefully (e.g. by continuing to vector through the ROM
 * I/O routines if these are set in a way you don't understand).
 */
#define INKEYB    0 /* Input from parallel keyboard. */
#define INUARTA   1 /* Input or output to Uart A.    */
#define INUARTB   2 /* Input or output to Uart B.    */
#define INUARTC   3 /* Input or output to Uart C.    */
#define INUARTD   4 /* Input or output to Uart D.    */
#define OUTSCREEN 0 /* Output to frame buffer.       */
#define OUTUARTA  1 /* Input or output to Uart A.    */
#define OUTUARTB  2 /* Input or output to Uart B.    */
#define OUTUARTC  3 /* Input or output to Uart C.    */
#define OUTUARTD  4 /* Input or output to Uart D.    */

/*
 * Structure set up by the boot command to pass arguments to the booted program.
 */
struct bootparam {
  char            *bp_argv[8];     /* String arguments.                     */
  char            bp_strings[100]; /* String table for string arguments.    */
  char            bp_dev[2];       /* Device name.                          */
  int             bp_ctlr;         /* Controller Number.                    */
  int             bp_unit;         /* Unit Number.                          */
  int             bp_part;         /* Partition/file Number.                */
  char            *bp_name;        /* File name.  Points into "bp_strings". */
  struct boottab  *bp_boottab;     /* Points to table entry for device.     */
};

/*
 * This table entry describes a device.  It exists in the PROM.  A pointer to
 * it is passed in "bootparam".  It can be used to locate ROM subroutines for
 * opening, reading, and writing the device.  NOTE: When using this interface,
 * only ONE device can be open at any given time.  In other words, it is not
 * possible to open a tape and a disk at the same time.
 */
struct boottab {
  char           b_dev[2];        /* Two character device name.          */
  int            (*b_probe)();    /* probe(): "-1" or controller number. */
  int            (*b_boot)();     /* boot(bp): "-1" or start address.    */
  int            (*b_open)();     /* open(iobp): "-"1 or "0".            */
  int            (*b_close)();    /* close(iobp): "-"1 or "0".           */
  int            (*b_strategy)(); /* strategy(iobp, rw): "-1" or "0".    */
  char           *b_desc;         /* Printable string describing device. */
  struct devinfo *b_devinfo;      /* Information to configure device.    */
};