Digital Research
This commit is contained in:
2020-11-06 18:50:37 +01:00
parent 621ed8ccaf
commit 31738079c4
8481 changed files with 1888323 additions and 0 deletions

View File

@@ -0,0 +1,168 @@
*****************************************************************
* *
* Usual filename: BDOS.S *
* Adapted by: Timothy M. Benson *
* Control: 5 May 83 15:25 (TMB) *
* *
* initiate program execution *
* *
*****************************************************************
*
.globl _GO
.globl _STEP
.globl _BDOS
.globl _GETSSP
.text
*
*
_GO: movem.l d0-d7/a0-a5,regsave save register variables
movem.l a6/a7,asave
move.w #22,d0 set up illegal trap vector
move.w #iltv,d1
move.w d1,thvnum
move.l #th,d2
trap #3
move.l d0,savev
*
move.l 4(a7),a0 addr of state save area
*
move.w #62,d0 get supervisor mode
trap #2
move.l a7,realssp
*
move.l (a0),pctr pc to start at
move.w 12(a0),status starting status
move.l 4(a0),a1 set up stack pointers
move a1,usp user stack pointer
move.l 8(a0),a7 supervisor stack pointer
movem.l 14(a0),d0-d7/a0-a6 set up other registers
move.l pctr,-(a7) set up for rte
and.w #$7FFF,status
move.w status,-(a7)
rte begin executing
*
* trap handling for _GO and _STEP
*
th: move.w (a7)+,status grab info from sys stack
move.l (a7)+,pctr
move.l a7,savessp
move.l realssp,a7
move.l a0,savea0
move.l usp,a0
move.l a0,saveusp
move.l savea0,a0
andi $5fff,sr
movem.l a6/a7,bsave save regs
move.l asave+4,a7 get old regs
move.l 4(a7),a6
move.l pctr,(a6)
move.l saveusp,4(a6)
move.l savessp,8(a6)
move.w status,12(a6)
and.w #$7FFF,12(a6)
movem.l d0-d7/a0-a5,14(a6)
move.w #22,d0
move.w thvnum,d1
move.l savev,d2
trap #3
move.l bsave,70(a6)
move.l bsave+4,74(a6)
btst #5,status
beq wasusr
move.l savessp,74(a6)
wasusr: move.l asave,a6
movem.l regsave,d0-d7/a0-a5
rts back to SID proper
*
*
*****************************************************************
* *
* execute one user instruction (trace or notrace) *
* *
*****************************************************************
*
_STEP: movem.l d0-d7/a0-a5,regsave save registers
movem.l a6/a7,asave save registers
*
move.w #62,d0 get supervisor mode
trap #2
move.l a7,realssp
*
move.w #22,d0
move.w #trv,d1
move.w d1,thvnum
move.l #th,d2
trap #3
move.l d0,savev Save previous trace exception pointer.
*
move.l asave+4,a0 caller's stack ptr
move.l 4(a0),a0 address of cpu state save area
move.l (a0),pctr starting pc
move.w 12(a0),d0 status
ori.w #$8000,d0 set trace bit
move.w d0,status starting status
move.l 4(a0),a1 user stack pointer
move.l a1,usp
move.l 8(a0),a7 system stack pointer
movem.l 14(a0),d0-d7/a0-a6 registers
move.l pctr,-(a7) set up for rte
move.w status,-(a7)
rte
*
.bss
*
asave: .ds.l 2
bsave: .ds.l 2
regsave: .ds.l 14
realssp: .ds.l 1
savessp: .ds.l 1
saveusp: .ds.l 1
savea0: .ds.l 1
iltv = $4 illegal instruction vector number
trv = $9 trace exception vector number
*
savev: .ds.l 1
thvnum: .ds.w 1
*
setexp = 61
setsup = 62
*
pctr: .ds.l 1
status: .ds.w 1
*
*
.text
*
*****************************************************************
* *
* BDOS Call Subroutine -- C Callable *
* *
*****************************************************************
*
_BDOS: move.w 4(a7),d0
move.l d1,saved1
move.l 6(a7),d1
trap #2
move.l saved1,d1
rts
*
.bss
*
saved1: .ds.l 1
*
.text
*
*****************************************************************
* *
* GETSSP -- supplies system stack pointer to C *
* *
*****************************************************************
*
_GETSSP: move.w #62,d0
trap #2
move.l a7,d0
andi #$5fff,sr
rts
*
.end

View File

@@ -0,0 +1,47 @@
/****************************************************************/
/* */
/* Define BDOS Function Codes */
/* */
/****************************************************************/
#define SYSRESET 0
#define CONIN 1
#define CONOUT 2
#define READIN 3
#define PUNOUT 4
#define LISTOUT 5
#define DCONIO 6
#define GETIOB 7
#define SETIOB 8
#define PRNTSTR 9
#define READBUF 10
#define CONSTAT 11
#define GETVER 12
#define RESETDSK 13
#define SELDSK 14
#define OPEN 15
#define CLOSE 16
#define SRCHFST 17
#define SRCHNXT 18
#define DELETE 19
#define READSEQ 20
#define WRITSEQ 21
#define MAKEFILE 22
#define RENAME 23
#define GTLOGIN 24
#define CURDSK 25
#define SETDMA 26
#define WRTPROT 28
#define GETROV 29
#define SETATTR 30
#define GETDPB 31
#define USERCD 32
#define READRND 33
#define WRITRND 34
#define FILESIZ 35
#define SETRND 36
#define RESTDRV 37
#define WRANDZF 40
#define GETFREE 46
#define DBIOSCL 50
#define PGMLOAD 59

View File

@@ -0,0 +1,12 @@
d:cp68 $1.c $1.i
$2d:pip b:=$1.c
$2era $1.c
d:c068 $1.i $1.ic $1.st
$2era $1.i
d:c168 $1.ic $1.s -ld
$2era $1.ic
$2era $1.st
d:as68 -l -u -f b: -s b: $1.s
$2d:pip b:=$1.s
$2era $1.s
$2dir

View File

@@ -0,0 +1,138 @@
/********************************************************/
/* */
/* Stuff to INCLUDE in DDT-68K */
/* */
/********************************************************/
#define MAXBP 10 /* max breakpoints allowed */
#define ILLEGAL 0x4AFC /* ILLEGAL instruction */
#define BDOSCALL 0x4E42 /* TRAP #2 instruction */
#define BIOSCALL 0x4E43 /* TRAP #3 instruction */
#define BUFLEN 85 /* command buffer length */
#define GETSEP getsep(&cx)
struct bytestr { char memb; };
struct wordstr { int memw; };
struct longstr { long meml; };
/****************************************************************/
/* */
/* Define the CPU Status Structure and Related Tables */
/* */
/****************************************************************/
struct cpustate {
long pc;
long usp;
long ssp;
int status;
long dreg[8];
long areg[8];
};
#define TRACE 0x8000
#define SUPER 0x2000
#define INTMSK 0x0700
#define EXTEND 0x0010
#define NEG 0x0008
#define ZERO 0x0004
#define OFLOW 0x0002
#define CARRY 0x0001
/****************************************************************/
/* */
/* Define FCB Structure */
/* */
/****************************************************************/
struct fcb {
char dr; /* drive code */
char fn[8]; /* file name */
char t[3]; /* file type */
char ex; /* extent */
char s1; /* used by sys */
char s2; /* used by sys */
char rc; /* rec count */
char d[16]; /* used by sys */
char cr; /* curr rec no */
char r[3]; /* rand rec no */
};
/****************************************************************/
/* */
/* Base Page Structure */
/* */
/****************************************************************/
struct basepage {
long lowtpa; /* low address of tpa */
long hightpa; /* high address of tpa */
long csstart; /* start of code seg */
long cslen; /* length of code seg */
long dsstart; /* start of data seg */
long dslen; /* length of data seg */
long bsstart; /* start of bss seg */
long bslen; /* length of bss seg */
long freelen; /* free mem after bss */
long reserved[5];
struct fcb fcb2;
struct fcb fcb1;
char comtail[0x80];
};
/************************************************************************/
/* */
/* Define a structure for holding information about the most */
/* recently loaded program or file */
/* */
/************************************************************************/
struct value {
int kind; /* 0 => none, 1 => pgm, 2 => file */
long textbase; /* if kind==2 then use textseg for file */
long textlen;
long database;
long datalen;
long bssbase;
long bsslen;
long bpa;
long initstk;
};
/************************************************************************/
/* */
/* Define the Load Program Parameter Block */
/* */
/************************************************************************/
struct lpb {
struct fcb *fcbaddr;
long tpabase;
long tpatop;
long *bpaddr;
long stkinit;
int flags;
};
/****************************************************************/
/* */
/* Some Forward Function Definitions */
/* */
/****************************************************************/
char *readcom();
char hexchar();
short int getform();
long int GETSSP();
/**/

View File

@@ -0,0 +1,75 @@
/*
Copyright 1981
Alcyon Corporation
8474 Commerce Av.
San Diego, Ca. 92121
*/
#define NUMSS 1 /*number of special symbols*/
#define SSRG 0 /*max symbol offset to display symbolically*/
#define LSTENT 12
struct symtab {
char syname[8];
char *syval;
};
struct {
int hiword;
int loword;
};
char *symbuf; /*start of symbol table*/
char *esymbuf; /*end of symbol table*/
int *symptr;
int errflg;
/* the following definitions must not be changed -- esp. the order */
int symlen;
int symct;
char ssymbol[8];
int ssymflg;
char *ssymval;
/* end of order dependant declarations */
char *dot;
char *tdot;
int dotinc;
char *sdot; /* symbolic operand temporary dot */
int textsym;
#define TEXTS 01000
#define DATAS 02000
#define BSSS 0400
#define ABSS 03400
char tsym[10];
char fsymbol[10];
int seffadr, sefaflg; /* effective address search variables */
int ssval[NUMSS]; /* special symbol values */
int instr; /* holds instruction first word */
#define BYTE 0
#define WORD 1
#define LONG 2
/* flags for symbols */
# define SYDF 0100000 /* defined */
# define SYEQ 0040000 /* equated */
# define SYGL 0020000 /* global - entry or external */
# define SYER 0010000 /* equated register */
# define SYXR 0004000 /* external reference */
# define SYDA 0002000 /* DATA based relocatable */
# define SYTX 0001000 /* TEXT based relocatable */
# define SYBS 0000400 /* BSS based relocatable */
struct { /* NOT PORTABLE !!!!!! */
char hibyte;
char lobyte;
};
#define AREG0 8
#define PC 16
char lbuf[40];

View File

@@ -0,0 +1,18 @@
e:vax stdio.h r
e:vax optab.h r
e:vax bdos.s r
e:vax sid05.c r
e:vax sid03.c r
e:vax siddef.h r
e:vax lgcdef.h r
e:vax sid04.c r
e:vax sidload.s r
e:vax bdosfunc.h r
e:vax sidfun.c r
e:vax disas.h r
e:vax cetacean.sub r
e:vax panacea.sub r
e:vax sid68k.c r
e:vax sid68k.dok r
e:vax ddtinc.h r
e:vax up5.sub r

View File

@@ -0,0 +1,69 @@
/********************************************************/
/* */
/* Usual filename: LGCDEF.H */
/* Put ' #include "lgcdef.h" ' at head of each */
/* separately compiled module containing */
/* code added to DDT68K to give SID68K. */
/* Remarks: General purpose symbol definitions */
/* for use by C-programmers in Languages. */
/* Author: Timothy M. Benson */
/* Last modified: 27 January 1983 */
/* */
/********************************************************/
/* Lower-case and mixed-case */
#define begin {
#define end }
#define otherwise else
#define and &&
#define or ||
#define If if( /* Note mixed case */
#define then )
/* Upper-case */
#define ADDR &
#define AND &
#define ANDEQ &=
#define ANDWITH &=
#define AT ->
#define BEGIN {
#define BLOCK {
#define CASE case
#define COMP ~
#define DCR -=
#define DECBY -=
#define DEFAULT default
#define DO do
#define DOFALSE :
#define DOTRUE ?
#define ELSE else
#define END }
#define EQ ==
#define FALSE 0
#define GE >=
#define GT >
#define IF if
#define IGNORE continue
#define INC +=
#define INCBY +=
#define LE <=
#define LT <
#define NE !=
#define NOT !
#define OR |
#define OREQ |=
#define ORWITH |=
#define SHL <<
#define SHLBY <<=
#define SHLR <<=
#define SHR >>
#define SHRBY >>=
#define SHRR >>=
#define TRUE 1
#define UNBLOCK }
#define VAL *
#define WHILE while
#define XOR ^
#define XORWITH ^=

View File

@@ -0,0 +1,38 @@
$ set noon
$ num
SID03.c
SID03.lis
$ num
SID04.c
SID04.lis
$ num
SID05.c
SID05.lis
$ num
SID68K.c
SID68K.lis
$ num
SIDFUN.c
SIDFUN.lis
$ as68 -l -u -p BDOS.S >bdos.lis
$ del bdos.o;
$ as68 -l -u -p SIDLOAD.S >sidload.lis
$ del sidload.o;
$ num
DDTINC.h
DDTINC.lst
$ num
DISAS.h
DISAS.lst
$ num
LGCDEF.h
LGCDEF.lst
$ num
OPTAB.h
OPTAB.lst
$ num
SIDDEF.h
SIDDEF.lst
$ num
STDIO.h
STDIO.lst

View File

@@ -0,0 +1,12 @@
Directory DRB0:[STEVE.CPM68K.V102.SID]
BDOSFUNC.H;1
DDTINC.H;1
DISAS.H;1
LGCDEF.H;1
OPTAB.H;1
SIDDEF.H;1
STDIO.H;1
Total of 7 files.

View File

@@ -0,0 +1,50 @@
$1cp68 SID03.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic SID03.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -l -u -f $1 -s 0$1 SID03.s
era SID03.s
$1cp68 SID04.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic SID04.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -l -u -f $1 -s 0$1 SID04.s
era SID04.s
$1cp68 SID05.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic SID05.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -l -u -f $1 -s 0$1 SID05.s
era SID05.s
$1cp68 SID68K.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic SID68K.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -l -u -f $1 -s 0$1 SID68K.s
era SID68K.s
$1cp68 SIDFUN.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic SIDFUN.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -l -u -f $1 -s 0$1 SIDFUN.s
era SIDFUN.s
$1as68 -l -u -f $1 -s 0$1 BDOS.S
$1as68 -l -u -f $1 -s 0$1 SIDLOAD.S
$1lo68 -r -o sid.rel -s sidload.o
$1lo68 -r -o sid68k.68k -s sid68k.o sid03.o sid04.o sid05.o sidfun.o bdos.o

View File

@@ -0,0 +1,147 @@
/* struct for optab */
struct optbl {
int inmsk;
int invalu;
int infmt;
char *innam;
};
#define MAXFMT 28
#define OPENT 4 /* # words per line in optab */
struct optbl optab[]
{
0xf1c0, 0xc1c0, 5, "muls",
0xf1c0, 0xc0c0, 5, "mulu",
0xf1f0, 0xc100, 4, "abcd",
0xfff8, 0x4840, 13, "swap",
0xf100, 0xc100, 12, "exg",
0xfff8, 0x54c8, 11, "dbcc",
0xfff8, 0x55c8, 11, "dbcs",
0xfff8, 0x57c8, 11, "dbeq",
0xfff8, 0x51c8, 11, "dbra",
0xfff8, 0x5cc8, 11, "dbge",
0xfff8, 0x5ec8, 11, "dbgt",
0xfff8, 0x52c8, 11, "dbhi",
0xfff8, 0x5fc8, 11, "dble",
0xfff8, 0x53c8, 11, "dbls",
0xfff8, 0x5dc8, 11, "dblt",
0xfff8, 0x5bc8, 11, "dbmi",
0xfff8, 0x56c8, 11, "dbne",
0xfff8, 0x5ac8, 11, "dbpl",
0xfff8, 0x50c8, 11, "dbt",
0xfff8, 0x58c8, 11, "dbvc",
0xfff8, 0x59c8, 11, "dbvs",
0xffc0, 0x54c0, 25, "scc",
0xffc0, 0x55c0, 25, "scs",
0xffc0, 0x57c0, 25, "seq",
0xffc0, 0x51c0, 25, "sf\040",
0xffc0, 0x5cc0, 25, "sge",
0xffc0, 0x5ec0, 25, "sgt",
0xffc0, 0x52c0, 25, "shi",
0xffc0, 0x5fc0, 25, "sle",
0xffc0, 0x53c0, 25, "sls",
0xffc0, 0x5dc0, 25, "slt",
0xffc0, 0x5bc0, 25, "smi",
0xffc0, 0x56c0, 25, "sne",
0xffc0, 0x5ac0, 25, "spl",
0xffc0, 0x50c0, 25, "st\040",
0xffc0, 0x58c0, 25, "svc",
0xffc0, 0x59c0, 25, "svs",
0xf1f0, 0xd100, 4, "addx",
0xf1f0, 0xd140, 4, "addx",
0xf1f0, 0xd180, 4, "addx",
0xf000, 0xd000, 1, "add",
0xff00, 0x0600, 2, "addi",
0xf100, 0x5000, 17, "addq",
0xf000, 0xc000, 1, "and",
0xff00, 0x0200, 2, "andi",
0xf018, 0xe000, 8, "as",
0xfec0, 0xe0c0, 8, "as",
0xff00, 0x6000, 6, "bra",
0xff00, 0x6400, 6, "bcc",
0xff00, 0x6500, 6, "bcs",
0xff00, 0x6700, 6, "beq",
0xff00, 0x6c00, 6, "bge",
0xff00, 0x6e00, 6, "bgt",
0xff00, 0x6200, 6, "bhi",
0xff00, 0x6f00, 6, "ble",
0xff00, 0x6300, 6, "bls",
0xff00, 0x6d00, 6, "blt",
0xff00, 0x6b00, 6, "bmi",
0xff00, 0x6600, 6, "bne",
0xff00, 0x6a00, 6, "bpl",
0xff00, 0x6800, 6, "bvc",
0xff00, 0x6900, 6, "bvs",
0xff00, 0x6100, 6, "bsr",
0xff00, 0x0c00, 2, "cmpi",
0xf1f8, 0x0108, 21, "movep",
0xf1f8, 0x0148, 21, "movep",
0xf1f8, 0x0188, 21, "movep",
0xf1f8, 0x01c8, 21, "movep",
0xf1c0, 0x0140, 7, "bchg",
0xffc0, 0x0840, 7, "bchg",
0xf1c0, 0x0180, 7, "bclr",
0xffc0, 0x0880, 7, "bclr",
0xf0c0, 0x00c0, 7, "bset",
0xffc0, 0x08c0, 7, "bset",
0xf1c0, 0x0100, 7, "btst", /* fix to Belton's code */
0xffc0, 0x0800, 7, "btst",
0xf1c0, 0x4180, 5, "chk",
0xff00, 0x4200, 24, "clr",
0xf1f8, 0xb108, 10, "cmpm",
0xf1f8, 0xb148, 10, "cmpm",
0xf1f8, 0xb188, 10, "cmpm",
0xf1c0, 0xb0c0, 5, "cmpa",
0xf1c0, 0xb1c0, 5, "cmpa",
0xf100, 0xb100, 23, "eor",
0xf000, 0xb000, 5, "cmp",
0xf1c0, 0x81c0, 5, "divs",
0xf1c0, 0x80c0, 5, "divu",
0xff00, 0x0a00, 2, "eori",
0xfe38, 0x4800, 27, "ext",
0xffc0, 0x4ec0, 9, "jmp",
0xffc0, 0x4e80, 9, "jsr",
0xf1c0, 0x41c0, 15, "lea",
0xfff8, 0x4e50, 19, "link",
0xf018, 0xe008, 8, "ls",
0xfec0, 0xe2c0, 8, "ls",
0xf000, 0x1000, 3, "move",
0xf000, 0x2000, 3, "move",
0xf000, 0x3000, 3, "move",
0xfff0, 0x4e60, 28, "move", //move usp
0xf9c0, 0x40c0, 26, "move", //special moves
0xfb80, 0x4880, 20, "movem",
0xf100, 0x7000, 22, "moveq",
0xffc0, 0x4800, 25, "nbcd",
0xff00, 0x4400, 24, "neg",
0xff00, 0x4000, 24, "negx",
0xffff, 0x4e71, 0, "nop",
0xff00, 0x4600, 24, "not",
0xf000, 0x8000, 1, "or",
0xff00, 0x0000, 2, "ori",
0xffc0, 0x4840, 9, "pea",
0xffff, 0x4e70, 0, "reset",
0xfec0, 0xe6c0, 8, "ro", //rotate memory
0xfec0, 0xe4c0, 8, "rox",
0xf018, 0xe018, 8, "ro", //rotate
0xf018, 0xe010, 8, "rox",
0xffff, 0x4e73, 0, "rte",
0xffff, 0x4e77, 0, "rtr",
0xffff, 0x4e75, 0, "rts",
0xf1f0, 0x8100, 4, "sbcd",
0xffff, 0x4e72, 14, "stop",
0xf1f0, 0x9100, 4, "subx",
0xf1f0, 0x9140, 4, "subx",
0xf1f0, 0x9180, 4, "subx",
0xf000, 0x9000, 1, "sub",
0xff00, 0x0400, 2, "subi",
0xf100, 0x5100, 17, "subq",
0xffc0, 0x4ac0, 25, "tas",
0xfff0, 0x4e40, 18, "trap",
0xffff, 0x4e76, 0, "trapv",
0xff00, 0x4a00, 24, "tst",
0xfff8, 0x4e58, 13, "unlk",
0, 0, 0, "*unknown instruction*"
};

View File

@@ -0,0 +1 @@
d:lo68 -r -f b: -o sid68k.68k -x 01.o 02.o 03.o 04.o 05.o 09.o d:clib

View File

@@ -0,0 +1,612 @@
/************************************************/
/* */
/* Usual filename: SID03.C */
/* Remarks: Second C module for SID68K */
/* Author: Timothy M. Benson */
/* Control: 19 MAY 83 16:52 (TMB) */
/* */
/************************************************/
#include "lgcdef.h"
#include "siddef.h"
#include "ddtinc.h"
#include "stdio.h"
#include "bdosfunc.h"
#include "disas.h"
gocmd(cx,statep,nulist) /* begin executing (optional breakpoints) */
char *cx;
struct cpustate *statep;
int **nulist;
{
extern U16 pkawnt[HMPPTS];
extern U16 *plocus[HMPPTS];
extern U16 ancien[HMPPTS];
extern int minus; /* 1 => no intermediate display */
int nbp;
long brkpt[MAXBP];
short brkwd[MAXBP];
long newpc;
long x;
int i;
short itsapp; /* 1 => ILLEGAL identified as pass point */
short mor; /* 1 => nonzero pass count, so GO again */
union asis BEGIN
long i32;
char *p8;
int *p16;
END strand; /* General purpose pointer */
int jetsam; /* Place to save word after system call */
deblank(&cx);
newpc = statep->pc;
if (gethex(&cx, &x)) newpc = x;
nbp = 0;
while ( GETSEP ) {
if (nbp >= MAXBP) {bad(); return;}
else { if (gethex(&cx,&x)) brkpt[nbp++]=x;
else {bad(); return;}
}
}
if ( ! nomore(cx) ) {bad(); return(0);}
statep->pc = newpc;
/* Repeatedly set up pass points, break points, GO, restore */
/* after break, restore after pass, process pass point if */
/* applicable, continuing until pass point with count of one */
/* is encountered or until break point is encountered. */
for (mor = 1; mor and NOT keyhit();) BEGIN
stick(); /* Set up pass points */
for (i=0; i<nbp; i++) {
/* Set break points, saving previous contents. */
brkwd[i]=(brkpt[i])->memw;
brkpt[i]->memw = ILLEGAL;
}
GO(statep);
/* Restore previous contents at break points. */
for (i=0; i<nbp; i++) brkpt[i]->memw = brkwd[i];
yank(); /* Restore original contents at pass points. */
newpc = statep AT pc;
/* Determine if pass point */
for(i=0,itsapp=0; i LT HMPPTS and NOT itsapp; i++) BLOCK
strand.p16 = plocus[i];
If pkawnt[i] and strand.i32 EQ newpc then begin
itsapp = 1;
i--;
end
UNBLOCK
strand.i32 = newpc;
If *strand.p16 EQ ILLEGAL then BLOCK
showstate(statep);
stout("\nEncountered the ILLEGAL instruction\n");
goto trotz;
UNBLOCK
If itsapp then BLOCK
If pkawnt[i] EQ (U16) 1 or NOT minus then begin
shopas(i);
showstate(statep);
end
If ancien[i] NE BDOSCALL and ancien[i] NE BIOSCALL
then STEP(statep);
else begin /* Execute system call normally */
strand.i32 = newpc + 2;
jetsam = *strand.p16;
*strand.p16 = ILLEGAL;
GO(statep);
*strand.p16 = jetsam;
end
newpc = statep AT pc;
If pkawnt[i] GT (U16) 1 then --pkawnt[i];
otherwise begin
mor = 0;
showstate(statep);
end
UNBLOCK
otherwise BLOCK
mor = 0;
showstate(statep);
UNBLOCK
END
trotz:
*nulist = statep AT pc;
} /* end of go command */
/************************************************/
/* H alone: Spill symbol table */
/* Ha format: Print hex, ASCII, symbols */
/* Ha,b format: Do arithmetic */
/************************************************/
hexmath(cx)
char *cx;
{
extern struct lmhedr *caput;
extern int omega;
extern int scope;
long a, b;
deblank(&cx);
If nomore(cx) then BEGIN
If omega GE 0 then deluge(caput AT sump,omega);
else stout("\nNo symbols\n");
END
otherwise BEGIN
If gethex(&cx,&a) and nomore(cx) then BLOCK
putchar('\n');
puthexl(a);
putchar(' ');
If qotbyt(a) then putchar(' ');
spell(a,caput AT sump,scope,'b','h');
putchar('\n');
UNBLOCK
else If GETSEP && gethex(&cx,&b) && nomore(cx) then BLOCK
putchar('\n');
puthexl(a+b);
putchar(' ');
puthexl(a-b);
putchar('\n');
UNBLOCK
else bad();
END
}
incomtl(cx, valuep)
char *cx;
struct value *valuep;
{ /* process command tail */
register char *p;
register char *q;
register char nc;
register struct basepage *bpp;
if ( (valuep->kind) != 1 ) {bad(); return;} /* no pgm loaded */
bpp = valuep->bpa;
p = cx + 1;
q = &(bpp->comtail[1]);
nc = 0;
while (*p) { *q++ = *p++; nc += 1;}
*q = *p;
bpp->comtail[0] = nc;
if ( parse(&cx, &(bpp->fcb1), " ") && GETSEP )
parse(&cx, &(bpp->fcb2), " ");
}
disasm(cx,dap)
char *cx;
char **dap;
{ /* display memory in assembly format */
extern struct lmhedr *caput;
extern int scope;
char *s; /* start address */
char *f; /* end address */
register short int deflt;
register short int nl;
/* parse command and extract parameters */
deblank(&cx);
if ( ! gethex(&cx, &s) ) { /* get start address */
if (nomore(cx)) s = *dap; /* or use default */
else {bad(); return(0);} /* junk on the line */
}
if ( s & 1) { bad(); return(0);} /* must use even address */
if ( GETSEP ) { /* get end address */
if ( gethex(&cx, &f) ) deflt=0; /* got it */
else { bad(); return(0); }
}
else { f = s; deflt = 1; } /* not there, use def */
if((!nomore(cx)) || (s>f)) {bad(); return(0);} /* junk or nonsense */
/* now do the display */
nl = 0;
while ( (s<=f) || (deflt && (nl<12)) ) {
if ( keyhit() ) return;
If caput then nl INCBY
spell((U32) s,caput AT sump,scope,'m','v');
putchar(' ');
putchar(' ');
puthexl(s); putchar(' ');
dot = s;
pinstr();
putchar('\n');
s += dotinc;
nl++;
*dap = s;
} /* end of loop through instructions */
} /* end disassembly */
movemem(cx)
char *cx;
{ /* move memory block */
char *s; /* start address */
char *f; /* end address */
char *d; /* destination address */
/* parse command and extract parameters */
deblank(&cx);
if ( gethex(&cx, &s) ); /* get start address */
else {bad(); return(0);} /* not there, error */
if ( GETSEP && gethex(&cx, &f) ); /* get end address */
else { bad(); return(0); } /* not there, error */
if ( GETSEP && gethex(&cx, &d) ); /* get dest address */
else { bad(); return(0); }
if ((!nomore(cx)) || (s>f) ) /* test for junk or nonsense */
{ bad(); return(0); }
/* now do the moving */
for ( ; s <= f; s++, d++ ) d->memb = s->memb;
} /* end of movemem */
readfl(cx, basep, valuep, dap)
char *cx;
struct basepage *basep;
struct value *valuep;
char **dap;
{ /* read a file into memory */
struct fcb fcb1;
long lotpa;
long hitpa;
long curdma;
int endofile;
deblank(&cx);
if ( parse(&cx, &fcb1, " ") && nomore(cx))
{
if ( (BDOS(OPEN, &fcb1) & 0xffL) == 0xffL) /* open failed */
{
stout("Cannot open file\n");
return;
}
fcb1.cr = 0;
lotpa = basep->lowtpa;
hitpa = basep;
curdma = lotpa;
endofile = 0;
while ( (! endofile) && (curdma+128 <= hitpa) )
{
/* read a sector */
BDOS(SETDMA, curdma);
endofile = (BDOS(READSEQ, &fcb1) & 0xffL);
curdma += 128;
}
if ( ! endofile ) stout("\nFile too big -- read truncated.\n");
valuep->kind = 2;
valuep->textbase = lotpa;
valuep->textlen = curdma - lotpa - 128;
showvals(valuep);
*dap = lotpa;
}
else bad(); /* parsing error */
}
setmem(cx)
char *cx;
{
/* set memory */
register short int format; /* 1=byte, 2=word, 4=long word */
char *s; /* start address */
long v; /* value to stuff into memory */
char buf[BUFLEN]; /* input buffer */
char *bx; /* points into buf */
short int nc; /* num of hex digits input */
/* parse command and extract parameters */
format = getform(&cx);
if ( gethex(&cx, &s) ); /* get start address */
else {bad(); return(0);} /* not there, error */
if ( (format != 1) && (s & 1) ) /* must be even address, error */
{bad(); return(0);}
if (!nomore(cx)) { bad(); return(0); } /* test for junk */
/* now do the stuffing */
for ( ; ; s += format ) {
puthexl(s); putchar(' ');
switch ( format ) {
case 1: puthexb(s->memb);
break;
case 2: puthexw(s->memw);
break;
case 4: puthexl(s->meml);
break;
} /* end of switch */
putchar(' ');
*buf = BUFLEN - 2;
BDOS ( READBUF, buf );
putchar('\n');
buf[2+(nc=buf[1])] = 0;
if ( nc > 0 ) {
if ( buf[2] == '.' ) {return(0);}
for ( bx = &buf[1] ; *++bx ; ) *bx = toupper(*bx) ;
bx = &buf[1];
if ( gethex( &bx, &v ) );
else { bad(); return(0); }
while ( (*++bx) == 0x20 ) ; /* skip blanks */
if ( (*bx != 0) || /* test for bad input */
( (format == 1) && ((v>255L) || (v<0)) ) ||
( (format == 2) && ((v>65535L) || (v<0)) ) )
{ bad(); return(0); }
/* stuff the value */
switch ( format ) {
case 1 : s->memb = (char)v ;
if ( (s->memb ^ v) & 0x0ffL ) badram(s);
break;
case 2 : s->memw = (short int)v ;
if ( (s->memw ^ v) & 0x0ffffL ) badram(s);
break;
case 4 : s->meml = (long)v ;
if ( s->meml ^ v ) badram(s);
break;
} /* end of switch */
} /* end of nc > 0 */
} /* end of for */
} /* end of setmem */
trace(cx, statep, dap, tr)
char *cx;
struct cpustate *statep;
char **dap;
int tr;
{ /* trace program execution for n steps */
extern U16 pkawnt[HMPPTS];
extern U16 *plocus[HMPPTS];
extern U16 ancien[HMPPTS];
extern int minus; /* 1 => no intermediate display */
extern int omega; /* If negative, SID thinks no symbols */
int iota; /* Place to keep true value of "omega" */
/* while kidding oneself */
short itsapp; /* 1 => ILLEGAL identified as pass point */
union asis32 BEGIN
long i32;
char *p8;
U16 *p16;
END strand; /* General purpose pointer */
/**temp** Watch this: "strand" declared "*strand" elsewhere and */
/**temp** seems to work. Not sure why it works there, so it may */
/**temp** not work here. */
int jetsam; /* Place to save word after system call */
long nsteps;
register int underw; /* 1 => trace without call */
int oxbow; /* 0 => trace; otherwise it = length */
register int inst;
register long addr;
int jt; /* General purpose loop index */
short mor; /* 1 => not finished with GO */
int kt; /* Loop index for GO */
iota = omega; /* Save true value of "omega" */
deblank(&cx);
underw = vecina(&cx,'W');
if ( ! gethex(&cx, &nsteps)) nsteps = 1;
if ( ! nomore(cx) ) {bad(); return;}
/* Warning: Let there be no explicit returns here to end */
/* of function, lest symbols be accidentally zapped. */
If tr and minus then omega = -1;
while(nsteps--) {
inst = (addr = (statep->pc))->memw;
If inst EQ ILLEGAL then BEGIN
showstate(statep);
stout("\nEncountered the ILLEGAL instruction\n");
goto reject;
END
/* GO thru traps, ignoring pass points */
If (inst & 0xFFF0) EQ 0x4E40 then BEGIN
inst = (addr INCBY 2) AT memw;
addr AT memw = ILLEGAL;
GO(statep);
addr AT memw = inst;
goto refuse;
END
If underw and ((inst & 0xFF00) EQ 0x6100
or (inst & 0xFFC0) EQ 0x4E80) then BEGIN
If NOT (inst & 0x00FF) then oxbow = 4; /* Long BSR */
else If (inst & 0xFF00) EQ 0x6100 then oxbow = 2;
/* Short BSR */
else BLOCK /* JSR */
inst ANDWITH 0x003F;
If inst GE 0x0038 then begin
If inst EQ 0x0039 then oxbow = 6;
otherwise oxbow = 4;
end
else begin
inst ANDWITH 0x0038;
If inst EQ 0x0010 then oxbow = 2;
otherwise oxbow = 4;
end
UNBLOCK
END
otherwise oxbow = 0;
strand.i32 = addr;
for(jt=0,itsapp=0;jt LT HMPPTS and NOT itsapp;jt++)
If pkawnt[jt] and strand.p16 EQ plocus[jt] then BEGIN
itsapp = 1;
jt--;
END
If itsapp then BEGIN
If pkawnt[jt] GT (U16) 1 then --pkawnt[jt];
otherwise nsteps = 0;
If NOT nsteps or NOT tr and NOT minus then BLOCK
shopas(jt);
showstate(statep);
UNBLOCK
END
If oxbow then BEGIN
inst = (addr INCBY oxbow) AT memw;
addr AT memw = ILLEGAL;
STEP(statep);
for (mor=1;mor;) BLOCK
stick();
GO(statep);
yank();
If (strand.i32 = statep AT pc) EQ addr then mor = 0;
otherwise begin
for(kt=0,itsapp=0;kt LT HMPPTS and NOT itsapp;kt++)
If pkawnt[kt] and strand.p16 EQ plocus[kt] then {
itsapp = 1;
kt--;
}
If itsapp and pkawnt[kt] GT (U16) 1 then --pkawnt[kt];
else {mor = 0; nsteps = 0;}
If *strand.p16 EQ ILLEGAL then {
showstate(statep);
stout("\nEncountered the ILLEGAL instruction\n");
addr AT memw = inst;
goto reject;
}
If NOT nsteps or NOT tr and NOT minus then {
shopas(kt);
showstate(statep);
}
STEP(statep);
If keyhit() then {mor = 0; nsteps = 0; tr = 0;}
end
UNBLOCK
addr AT memw = inst;
END
otherwise STEP(statep);
refuse:
if (tr) showstate(statep);
if ( keyhit() ) nsteps = 0;
}
if ( ! tr ) showstate(statep);
reject:
*dap = statep->pc;
omega = iota; /* Reenable symbols. */
}
vcmd(cx, valuep)
char *cx;
struct value *valuep;
{/* display start and end of stuff loaded with R or E commands */
if (nomore(cx)) showvals(valuep);
otherwise bad();
}
wrtfile(cx, valuep)
char *cx;
struct value *valuep;
{ /* write memory contents to disk */
struct fcb fcb1;
long s;
long f;
deblank(&cx);
if ( ! parse(&cx, &fcb1, " ") ) {bad(); return;}
if ( nomore(cx) ) /* use default start and end */
{
if ( (valuep->kind) != 2 ) {bad(); return;}
s = valuep->textbase;
f = s + valuep->textlen - 1;
}
else /* try to parse s & f values */
{
if ( ( ! GETSEP ) || ( ! gethex(&cx, &s) ) ||
( ! GETSEP ) || ( ! gethex(&cx, &f) ) ||
( ! nomore(cx) ) ) {bad(); return;}
}
BDOS(DELETE, &fcb1);
if ( (BDOS(MAKEFILE, &fcb1) & 0xffL) == 0xffL )
{
stout("Cannot create file.\n");
return;
}
fcb1.cr = 0;
while ( s <= f )
{
BDOS(SETDMA, s);
if ( BDOS(WRITSEQ, &fcb1) & 0xffL )
{
stout("File write error.\n");
s = f + 1;
}
s += 128;
}
BDOS(CLOSE, &fcb1);
}
int dummy(s)
char *s;
{
stout("\n\nUnimplemented Function: ");
stout(s);
stout("\n\n");
}
shopas(jsh) /* Display pass-point data */
int jsh;
{
extern U16 pkawnt[HMPPTS];
extern U16 *plocus[HMPPTS];
putchar('\n');
puthexw(pkawnt[jsh]);
stout(" PASS ");
puthexl(plocus[jsh]);
putchar('\n');
}
stick() /* Set pass points, saving original contents. */
{
extern U16 pkawnt[HMPPTS];
extern U16 *plocus[HMPPTS];
extern U16 ancien[HMPPTS];
int kst;
for (kst=0; kst LT HMPPTS; kst++)
If pkawnt[kst] then BLOCK
ancien[kst] = *plocus[kst];
*plocus[kst] = ILLEGAL;
UNBLOCK
}
yank() /* Restore original contents at pass points. */
{
extern U16 pkawnt[HMPPTS];
extern U16 *plocus[HMPPTS];
extern U16 ancien[HMPPTS];
int kya;
for (kya=0; kya LT HMPPTS; kya++)
If pkawnt[kya] then *plocus[kya] = ancien[kya];
}

View File

@@ -0,0 +1,575 @@
/************************************************/
/* */
/* Usual filename: SID04.C */
/* Remarks: Third C module for SID68k */
/* Author: Timothy M. Benson */
/* Control: 9 MAY 83 13:59 (TMB) */
/* */
/************************************************/
#include "lgcdef.h"
#include "siddef.h"
#include "ddtinc.h"
#include "stdio.h"
#include "bdosfunc.h"
#include "disas.h"
putchar(x)
register char x;
{
BDOS(CONOUT, (long)x);
if (x == '\n') BDOS(CONOUT, (long)'\r');
}
int stout(s) /* write a string */
register char *s;
{
register int nc;
nc = 0;
while ( *s ) { putchar( *s++ ); nc++; }
return(nc);
}
/************************************************/
/* Starting at byte after **cpp get longest */
/* possible hex number from string or evaluate */
/* longest possible symbol. */
/* Fill in *np with value found. Return # of */
/* digits if hex, 8 if symbol, or 0 if invalid. */
/* Leave **cpp pointing to next position after */
/* chars processed. */
/************************************************/
gethex(cpp,np)
char **cpp;
long *np;
{
/**temp** This function extensively modified for SID */
extern struct lmhedr *caput;
extern int omega;
extern int nomo;
union ambig BLOCK /* Machine dependent */
long all32;
int last16[2];
char last8[4];
UNBLOCK triad;
register char *cp;
U16 *d16; /* For '@' values */
U32 *d32; /* For '!' values */
char *deixis; /* For '=' values */
long n;
register int nd;
char px; /* . = @ ! */
register char qu;
px = *(*cpp + 1);
If px EQ '.' or px EQ '=' or px EQ '@' or px EQ '!' then BEGIN
cp = ++*cpp; /* Locate prefix */
++*cpp; /* Skip prefix */
while((qu = *++cp) and qu NE ' ' and qu NE ',' and qu NE '+'
and qu NE '-' and qu NE '/' and qu NE '*')
; /* Find char after supposed name */
If nd = 8 * (omega GE 0
and (1 EQ indica((int)(cp - *cpp),*cpp
,caput AT sump,'B',&n,&nomo))) then
If px NE '=' and px NE '.' and n AND 1L then nd = 0;
otherwise BLOCK
triad.all32 = 0;
switch (px) begin
case '.':
triad.all32 = n;
break;
case '=':
deixis = n;
triad.last8[3] = *deixis;
break;
case '@':
d16 = n;
triad.last16[1] = *d16;
break;
case '!':
d32 = n;
triad.all32 = *d32;
break;
end
n = triad.all32;
UNBLOCK
END
otherwise for (n=0, nd=0, cp = *cpp;
ishex(*++cp);
nd++, n=(n<<4)+hexval(*cp));
*cpp = --cp;
*np = n;
return(nd);
}
int ishex ( c )
register char c;
{
return ( ( ('0'<=c) && (c<='9') ) || ( ('A'<=c) && (c<='F') ) );
}
int hexval ( c )
register char c;
{
if ( ('0'<=c) && (c<='9') ) return ( c-'0');
else return ( 10 + c - 'A' );
}
char hexchar(n)
register char n;
{
return ( n<10 ? '0'+n : 'A'+n-10 );
}
int puthex(n, i, zs)
register long n;
register int i;
register int zs;
{
register char d;
while ( i >= 4 )
{
i -= 4;
d = hexchar( (char)((n>>i) & 0xf) );
if ( d != '0' ) zs = 0;
if ( (! zs) || (! i) ) putchar(d);
}
}
int puthexl(n) /* write a long integer in hex */
long n;
{
puthex(n, 32, 0);
}
int puthexw(n) /* write an integer in hex */
short int n;
{
puthex((long)n, 16, 0);
}
puthexb(n) /* write a byte in hex */
char n;
{
puthex((long)n, 8, 0);
}
int putbyte(c) /* write an ascii byte. if not printable, write '.' */
register char c;
{
char d[2];
d[1] = 0;
d[0] = ( ( (c < 0x20) || (c > 0x7E) ) ? '.' : c );
stout(d);
}
bad()
{
stout("?\n");
}
badram(a)
long a;
{
stout("Bad or non-existent RAM at ");
puthexl(a);
putchar('\n');
}
nomore(cx)
char *cx;
{
++cx;
while (*cx)
{
if (*cx != ' ') return(0);
else ++cx;
}
return(1);
}
getsep(cxp)
register char **cxp;
{
register char *cx;
cx = (*cxp) + 1;
if ((*cx != ' ') && (*cx != ',')) return(0);
while ( *cx == ' ' ) ++cx;
if ( ! *cx ) return(0);
if ( *cx != ',' ) {*cxp = --cx; return(1);}
++cx;
while ( *cx == ' ' ) ++cx;
*cxp = --cx;
return(1);
}
deblank(cxp)
register char **cxp;
{
++*cxp;
while ( **cxp == ' ' ) ++*cxp;
--*cxp;
}
short int getform(cxp)
register char **cxp;
{
register char *cx;
register short int format;
cx = *cxp;
if ( *++cx == 'W' ) format = 2;
else if ( *cx == 'L' ) format = 4;
else { format = 1; cx--; }
*cxp = cx;
deblank(cxp);
return(format);
}
parse(cxp, fcbp, dtp)
register char **cxp;
struct fcb *fcbp;
char *dtp;
{
/* parse a filename into an fcb */
register char *cx;
register char c;
register int n;
fcbp->ex = 0;
fcbp->cr = 0;
cx = *cxp;
c = *++cx;
if ( ! (isalpha(c) || isdigit(c) || iswild(c))) return(0);
if ( *(cx+1) == ':' ) {fcbp->dr = c - 'A' + 1; cx += 2; }
else fcbp->dr = 0;
n = 0;
c = *cx;
while (isalpha(c) || isdigit(c) || iswild(c)) {
if ( n >= 8 ) return(0);
if(c == '*')
{
while(n < 8)
fcbp->fn[n++] = '?';
c = *++cx;
break;
}
fcbp->fn[n++] = c;
c = *++cx;
}
while ( n < 8 ) fcbp->fn[n++] = ' ';
for (n = 0; n < 3; ++n) {
if (*dtp) fcbp->t[n] = *dtp++;
else fcbp->t[n] = ' ';
}
if (*cx != '.') {*cxp = --cx; return(1);}
n = 0;
c = *++cx;
while ( isalpha(c) || isdigit(c) || iswild(c)) {
if ( n >= 3 ) return(0);
if(c == '*')
{
while(n < 3)
fcbp->t[n++] = '?';
c = *++cx;
break;
}
fcbp->t[n] = c;
++n;
c = *++cx;
}
while ( n < 3 ) fcbp->t[n++] = ' ';
*cxp = --cx;
return(1);
} /* end of parse fcb */
int keyhit()
{
if ( BDOS(CONSTAT, 0L) & 0xFFFFL ) {
BDOS(CONIN, 0L);
return(1);
}
else return(0);
}
showvals(vp)
register struct value *vp;
{
register int i, j;
register long * lp;
switch ( vp->kind )
{
case 0: stout("\nERROR, no program or file loaded.\n");
break;
case 1: /* do program vals */
for ( i = 0; i < 2; ++i )
{
lp = &(vp->textbase);
lp += i;
for (j = 0; j < 3; ++j)
{
switch ( j )
{
case 0: stout("text "); break;
case 1: stout("data "); break;
case 2: stout("bss "); break;
}
switch ( i )
{
case 0: stout(" base "); break;
case 1: stout(" length"); break;
}
stout(" = ");
puthexl(*lp);
lp += 2;
stout(" ");
}
putchar('\n');
}
stout("base page address = ");
puthexl(vp->bpa);
stout(" initial stack pointer = ");
puthexl(vp->initstk);
break; /* end of program values */
case 2: /* do file values */
stout("Start = ");
puthexl(vp->textbase);
stout(" End = ");
puthexl((vp->textbase)+(vp->textlen)-1L);
break;
}
putchar('\n');
} /* end of showvals */
/**/
/****************************************************************/
/* */
/* Examine/Alter CPU Registers */
/* */
/****************************************************************/
examine(cx, statep)
char *cx;
struct cpustate *statep;
{
if (nomore(cx)) showstate(statep);
else if (*++cx == 'D') pdareg('D', cx, statep->dreg);
else if (*cx == 'A') pdareg('A', cx, statep->areg);
else if (cmp("PC",--cx)) pregl("PC", &(statep->pc));
else if (cmp("USP",cx)) { if (pregl("USP",&(statep->usp)) &&
((statep->status & SUPER) == 0 ))
statep->areg[7] = statep->usp;
}
else if (cmp("SSP",cx)) { if (pregl("SSP",&(statep->ssp)) &&
(statep->status & SUPER) )
statep->areg[7] = statep->ssp;
}
else if (cmp("ST", cx)) { pregw("ST",&(statep->status) );
if ( statep->status & SUPER) statep->areg[7] = statep->ssp;
else statep->areg[7] = statep->usp;
}
else bad();
if ( statep->status & SUPER) statep->ssp = statep->areg[7];
else statep->usp = statep->areg[7];
}
showstate(statep)
register struct cpustate *statep;
{
/**temp** Next several lines added recently */
extern int scope;
extern struct lmhedr *caput;
/**temp** End of added stuff */
register short int status;
stout("PC="); puthexl(statep->pc); putchar(' ');
stout("USP="); puthexl(statep->usp); putchar(' ');
stout("SSP="); puthexl(statep->ssp); putchar(' ');
stout("ST="); puthexw(status = statep->status);
stout("=>");
if (status & TRACE) stout("TR ");
if (status & SUPER) stout("SUP ");
stout("IM="); putchar(((status & INTMSK)>>8)+'0');
if (status & EXTEND) stout(" EXT");
if (status & NEG) stout(" NEG");
if (status & ZERO) stout(" ZER");
if (status & OFLOW) stout(" OFL");
if (status & CARRY) stout(" CRY");
putchar('\n');
preglrow('D', statep->dreg); /* D registers */
preglrow('A', statep->areg); /* A registers */
dot = statep -> pc;
spell(statep AT pc,caput AT sump,scope,'m','h');
/* Label, if any */
pinstr(); /* disassembled instruction */
putchar('\n');
}
pdareg(da, cx, rp) /* print data or address register contents */
char da;
register char *cx;
long *rp;
{
char str[3];
if ( ('0' <= *++cx) && (*cx <= '7') && nomore(cx) ) {
str[0] = da;
str[1] = *cx;
str[2] = 0;
pregl(str, rp + *cx - '0');
}
else bad();
}
pregl(rname, regp) /* print register contents as long */
char *rname;
long *regp;
{
return( preg(rname, regp, 4) );
}
pregw(rname, regp) /* print register contents as word */
char *rname;
long *regp;
{
return( preg(rname, regp, 2) );
}
preg(rname, regp, size) /* print register contents */
register char *rname;
register long *regp;
register int size;
{
char buf[BUFLEN];
register short int nc;
long int newval;
char *bp;
register int modify;
modify = 0;
stout(rname);
putchar('=');
switch(size)
{
case 1 : puthexb(regp->memb);
break;
case 2 : puthexw(regp->memw);
break;
case 4 : puthexl(regp->meml);
break;
}
putchar(' ');
*buf = BUFLEN-2;
BDOS(READBUF, buf);
putchar('\n');
if ((nc=buf[1])>0) {
buf[nc+2]=0;
bp = buf + 1;
while (*++bp) *bp = toupper(*bp);
bp = buf + 1;
if (gethex(&bp, &newval) && nomore(bp)) {
switch(size)
{
case 1 : regp->memb = (char)(newval & 0xffL);
break;
case 2 : regp->memw = (int)(newval & 0xffffL);
break;
case 4 : regp->meml = newval;
break;
}
modify = 1;
}
else if ( ! nomore(buf+1) ) bad();
}
return(modify);
}
preglrow(ch, rowp)
char ch;
long *rowp;
{
register int n;
putchar(ch);
putchar(' ');
for (n=0; n<8; n++) {
putchar(' ');
puthexl(*rowp++);
if (n==3) putchar(' ');
}
putchar('\n');
}
tryflags(cx, statep)
register char *cx;
register struct cpustate *statep;
{
bad();
}
cmp(str, ctl)
register char *str;
register char *ctl;
{
while (*str && (*str++ == *++ctl)) ;
if ( ( ! *str) && nomore(ctl) ) return(1);
else return(0);
}

View File

@@ -0,0 +1,771 @@
/************************************************/
/* */
/* Usual filename: SID05.C */
/* Remarks: Fourth C module for SID68K */
/* Adapted by: Timothy M. Benson */
/* Control: 11 MAY 83 11:31 (TMB) */
/* */
/************************************************/
/*
Copyright 1981
Alcyon Corporation
8474 Commerce Av.
San Diego, Ca. 92121
*/
#include "lgcdef.h"
#include "siddef.h"
#include "ddtinc.h"
#include "optab.h"
#include "stdio.h"
#include "bdosfunc.h"
#include "disas.h"
int noin();
int inf1();
int inf2();
int inf3();
int inf4();
int inf5();
int inf6();
int inf7();
int inf8();
int inf9();
int inf10();
int inf11();
int inf12();
int inf13();
int inf14();
int inf15();
int inf16();
int inf17();
int inf18();
int inf19();
int inf20();
int inf21();
int inf22();
int inf23();
int inf24();
int inf25();
int inf26();
int inf27();
int inf28();
/* print an instruction in assembler format */
pinstr()
{
/**temp** Next several lines added recently */
extern struct lmhedr *caput;
extern int scope;
extern char ref;
extern long inhalt;
/**temp** End of added stuff */
register struct optbl *p;
register short int reg;
/**temp** Next several lines added recently */
ref = '\0'; /* Mark "not in use" */
/**temp** End of added stuff */
sdot=dot+2; /* next word address */
dotinc = 2;
instr=dot->memw; /* instruction in binary */
p = &optab;
while(1) { /* last table entry matches anything */
if((instr&(p->inmsk)) == p->invalu)
break; /* found it */
p++;
}
stout(p->innam); /* print mnemonic */
if(p->infmt>=0 && p->infmt<=MAXFMT) {
if(p->infmt) {
switch ( p->infmt) { /* call proper funct */
case 0 : noin(); break; case 1 : inf1(); break;
case 2 : inf2(); break; case 3 : inf3(); break;
case 4 : inf4(); break; case 5 : inf5(); break;
case 6 : inf6(); break; case 7 : inf7(); break;
case 8 : inf8(); break; case 9 : inf9(); break;
case 10 : inf10(); break; case 11 : inf11(); break;
case 12 : inf12(); break; case 13 : inf13(); break;
case 14 : inf14(); break; case 15 : inf15(); break;
case 16 : inf16(); break; case 17 : inf17(); break;
case 18 : inf18(); break; case 19 : inf19(); break;
case 20 : inf20(); break; case 21 : inf21(); break;
case 22 : inf22(); break; case 23 : inf23(); break;
case 24 : inf24(); break; case 25 : inf25(); break;
case 26 : inf26(); break; case 27 : inf27(); break;
case 28 : inf28(); break;
}
}
putchar(' ');
/**temp** Next line added recently */
If ref then spell((U32)inhalt,caput AT sump,scope,ref,'H');
return;
}
putchar('?');
return;
}
noin()
{
stout("illegal instruction format #\n");
return;
}
inf1()
{
register reg,mode;
reg = ((instr&0xe00)>>9);
if((instr&0xc0) == 0xc0) { /* adda or suba */
putchar('a');
mode=WORD;
if((instr&0x1c0)==0x1c0) { /* long opmode */
mode = LONG;
stout(".l");
}
reg =+ 8;
}
else {
mode = (instr&0xc0)>>6;
prsize(mode);
}
putchar(' ');
if(reg>7 || (instr&0x100)==0) {
prtop(instr&077,mode);
putchar(',');
prtreg(reg);
}
else {
prtreg(reg);
putchar(',');
prtop(instr&077,mode); /* destination */
}
}
/* move instruction */
inf3()
{
register size;
register i;
i = instr&0x3000; /* size field */
if(i==0x1000)
size = BYTE;
else if(i==0x3000)
size = WORD;
else if(i==0x2000)
size = LONG;
else
badsize();
prsize(size);
putchar(' ');
prtop(instr&077,size);
putchar(',');
i = ((instr&07000)>>9) | ((instr&0700)>>3);
prtop(i,size);
}
/* immediate instructions */
inf2()
{
register size;
size = (instr&0xc0)>>6;
prsize(size);
putchar(' ');
primm(size);
putchar(',');
switch(instr)
{
case 0x027c:
case 0x0a7c:
case 0x007c: stout("sr");
break;
case 0x023c:
case 0x0a3c:
case 0x003c: stout("ccr");
break;
default : prtop(instr&077,size);
}
}
/* abcd, addx, sbcd, subx */
inf4()
{
register size,i;
size = (instr&0xc0)>>6;
prsize(size);
putchar(' ');
i = (instr&0xe00)>>9;
if(instr&8) {
paripd(instr&7); putchar(','); paripd(i);
}
else {
pdr(instr&7); putchar(','); pdr(i);
}
}
/* chk, cmp, cmpa, div, mul */
inf5()
{
register i,size,arg;
arg = 0;
i = instr&0xf000;
size = (instr&0x1c0)>>6;
if(i==0xb000) { /* cmp or cmpa */
if(size==3 || size==7) { /* cmpa */
arg++;
size =>> 1;
if(size==3)
size = 2;
}
prsize(size);
}
else
size = WORD;
putchar(' ');
prtop(instr&077,size);
putchar(',');
i = (instr&0xe00)>>9;
if(arg) /* cmpa */
par(i);
else
prtreg(i);
}
prsize(amode)
{
if(amode==BYTE)
stout(".b");
else if(amode==LONG)
stout(".l");
else if(amode!=WORD)
badsize();
}
badsize()
{
stout("\n**illegal size field\n");
}
prtreg(areg)
{
register reg;
reg = areg;
if(reg>7) {
par(reg-8);
}
else {
pdr(reg);
}
}
/* print an operand symbolically */
prtop(adrtype,asize)
{
register short int reg,mode,defer;
long la;
register long p;
mode = (adrtype&070)>>3;
reg = adrtype&7;
switch(mode) {
case 0: /* D reg direct */
pdr(reg);
return;
case 1: /* A reg direct */
par(reg);
return;
case 2: /* A indirect */
pari(reg);
return;
case 3: /* A+ */
paripi(reg);
return;
case 4: /* -(An) */
paripd(reg);
return;
case 5: /* d(an) */
prdisp();
pari(reg);
return;
case 6: /* d(An,Ri) */
prindex(reg);
return;
case 7:
la = 0;
switch(reg) {
case 1: /* xxx.L */
la.hiword = sdot->memw;
sdot =+ 2;
dotinc =+ 2;
la.loword = sdot->memw;
sdot =+ 2;
dotinc =+ 2;
putchar('$');
hexlzs(la);
return;
case 0: /* xxx.W */
p = sdot->memw;
if(p&0x8000)
p =| 0xffff0000; /* sign extend like hard */
sdot =+ 2;
dotinc =+ 2;
hexlzs(p);
return;
case 2: /* d(PC) */
prdisp();
stout("(PC)");
return;
case 3: /* d(PC,Ri) */
prindex(PC);
return;
case 4:
primm(asize);
return;
}
}
}
prdisp()
{
register short int i;
i = sdot->memw;
sdot =+ 2;
dotinc =+ 2;
putchar('$'); hexwzs(i);
}
prindex(areg)
{
register short int i;
i = sdot->memw;
sdot =+ 2;
dotinc =+ 2;
putchar('$');
hexbzs((char)i&0xFF);
putchar('(');
if(areg==PC)
stout("PC,");
else
{par(areg); putchar(',');}
prtreg((i>>12)&0xf);
if(i&0x800)
stout(".l");
putchar(')');
}
primm(asize)
{
long l1;
l1 = 0;
if(asize == LONG) {
l1.hiword = sdot->memw;
sdot =+ 2;
dotinc =+ 2;
}
l1.loword = sdot->memw;
sdot =+ 2;
dotinc =+ 2;
stout("#$");
hexlzs(l1);
}
/* branches & bsr */
inf6()
{
register short int i;
register char *p;
i = instr.lobyte;
if(i) {
p = sdot + i;
}
else {
p = sdot + sdot->memw;
sdot =+ 2;
dotinc =+ 2;
}
stout(" $");
hexlzs(p);
}
/* bchg, bclr, bset, btst */
inf7()
{
putchar(' ');
if(instr&0x100) { /* bit # dynamic */
prtreg((instr&0xe00)>>9);
}
else {
primm(WORD);
}
putchar(',');
prtop(instr&077,WORD);
}
/* shifts and rotates */
inf8()
{
register i,size;
if(instr&0x100)
putchar('l');
else
putchar('r');
size = (instr&0xc0)>>6;
if(size != 3) {
prsize(size);
putchar(' ');
i = (instr&0xe00)>>9;
if(instr&0x20) { /* bit # in reg */
prtreg(i);
}
else {
if(i==0)
i = 8;
putchar('#');
hexbzs(i);
}
putchar(',');
prtreg(instr&7);
}
else {
putchar(' ');
prtop(instr&077,WORD);
}
}
/* jmp, jsr, pea */
inf9()
{
putchar(' ');
prtop(instr&077,WORD);
}
/* cmpm */
inf10()
{
register i;
prsize((instr&0xc0)>>6);
i = (instr&0xe00)>>9;
putchar(' ');
paripi(instr&7); putchar(','); paripi(i);
}
/* dbcc */
inf11()
{
register char *p;
putchar(' ');
prtreg(instr&7);
putchar(',');
p = sdot + sdot->memw;
sdot =+ 2;
dotinc =+ 2;
hexlzs(p);
}
/* exg */
inf12()
{
register rx,ry,i;
rx = (instr&0xe00)>>9;
ry = instr&7;
i = instr&0xf8;
if(i==0x48) { /* exg a regs */
rx =+ AREG0;
ry =+ AREG0;
}
else if(i==0x88) { /* exg a reg & d reg */
ry =+ AREG0;
}
putchar(' ');
prtreg(rx);
putchar(',');
prtreg(ry);
}
/* swap & unlk */
/* called by ext (format 27) */
inf13()
{
putchar(' ');
prtreg(instr&0xf);
}
/* stop */
inf14()
{
putchar(' ');
primm(WORD);
}
/* lea */
inf15()
{
putchar(' ');
prtop(instr&077,WORD);
putchar(',');
prtreg(((instr&0xe00)>>9)+AREG0);
}
/* not used */
inf16()
{
stout("unknown opcode");
}
/* addq, subq */
inf17()
{
register i;
prsize((instr&0xc0)>>6);
i = (instr&0xe00)>>9;
if(i==0) i = 8;
stout(" #$"); hexbzs((char) i); putchar(',');
prtop(instr&077,WORD);
}
/* trap */
inf18()
{
stout(" #$"); hexbzs((char)(instr&0xf));
}
/* link */
inf19()
{
putchar(' ');
par(instr&7);
stout(",#$"); hexwzs(sdot->memw);
sdot =+ 2;
dotinc =+ 2;
}
short int regmsk0[] {0100000,040000,020000,010000,04000,02000,01000,0400,0200,
0100,040,020,010,4,2,1};
short int regmsk1[] {1,2,4,010,020,040,0100,0200,0400,01000,02000,04000,010000,
020000,040000,0100000};
/* movem */
inf20()
{
if(instr&0x40)
stout(".l");
putchar(' ');
if (instr & 0x0400) /* test for mem->reg xfer */
{
prtop(instr & 077, WORD);
putchar(',');
putrlist(regmsk1);
}
else /* must be reg->mem */
{
if ( (instr & 070) == 040 ) putrlist(regmsk0); /* predec */
else putrlist(regmsk1);
putchar(',');
prtop(instr & 077, WORD);
}
}
putrlist(ap)
short int *ap;
{
register short int i,mask,*p;
register short int j;
mask = sdot->memw;
sdot =+ 2;
dotinc =+ 2;
p = ap;
j = -1;
for(i=0; i<16; i++) {
if(mask&*p++) {
if(j==0)
putchar('/');
if(j != 1) {
prtreg(i);
putchar('-');
}
j = 1;
}
else if(j==1) {
prtreg(i-1);
j = 0;
}
}
if(j==1)
stout("A7");
}
/* movep */
inf21()
{
register i,j;
if(instr&0x40)
stout(".l");
putchar('\t');
i = instr&0x180;
if(i==0x180) {
prtreg((instr&0xe00)>>9);
putchar(',');
}
j = sdot->memw;
hexwzs(j); pari(instr&7);
if(i==0x100) {
putchar(',');
prtreg((instr&0xe00)>>9);
}
sdot =+ 2;
dotinc =+ 2;
}
/* moveq */
inf22()
{
stout(" #$"); hexbzs((char)(instr&0xff)); putchar(',');
prtreg((instr&0xe00)>>9);
}
/* eor */
inf23()
{
prsize((instr&0xc0)>>6);
putchar(' ');
prtreg((instr&0xe00)>>9);
putchar(',');
prtop(instr&077,WORD);
}
/* clr, neg, negx, not, tst */
inf24()
{
prsize((instr&0xc0)>>6);
inf25();
}
/* scc, nbcd, tas */
inf25()
{
putchar(' ');
prtop(instr&077,WORD);
}
/* move SR & CCR */
inf26()
{
register i;
i = instr&0x600;
if(i==0) {
stout(" SR,");
}
else
putchar(' ');
prtop(instr&077,WORD);
if(i==0x400)
stout(",CCR");
else if(i==0x600)
stout(",SR");
}
/* ext */
inf27()
{
if((instr&0x1c0)==0xc0)
stout(".l");
inf13();
}
/* move USP */
inf28()
{
register i;
i = instr&7;
if(instr&8) { /* USP to An */
stout(".l USP,"); par(i);
}
else {
stout(".l "); par(i); stout(",USP");
}
}
/* some utilities for printing addresses */
pdr(r)
short int r;
{
putchar('D'); putchar(hexchar(r));
}
par(r)
short int r;
{
putchar('A'); putchar(hexchar(r));
}
pdri(r)
short int r;
{
putchar('('); pdr(r); putchar(')');
}
pari(r)
short int r;
{
putchar('('); par(r); putchar(')');
}
paripd(r)
short int r;
{
putchar('-'); pari(r);
}
paripi(r)
short int r;
{
pari(r); putchar('+');
}
hexlzs(n) /* write a long integer in hex */
long n;
{
extern long inhalt;
extern char ref;
inhalt = n;
ref = 'm'; /* Let ref => possible symbol */
puthex(n,32,1);
}
int hexwzs(n) /* write an integer in hex */
short int n;
{
puthex((long)n, 16, 1);
}
int hexbzs(n) /* write a byte as a hex integer */
char n;
{
puthex((long)n, 8, 1);
}

View File

@@ -0,0 +1,460 @@
/********************************************************/
/* */
/* Usual filename: SID68K.C */
/* Remarks: Main C module for SID68K */
/* Author: Timothy M. Benson */
/* Control: 19 MAY 83 18:01 (TMB) */
/* */
/********************************************************/
#include "lgcdef.h"
#include "siddef.h"
#include "ddtinc.h"
#include "stdio.h"
#include "bdosfunc.h"
#include "disas.h"
/**temp** For now, let symbol table preceded by load module */
/**temp** header be physically located in SID. May later */
/**temp** allocate it dynamically. */
struct lmhedr klops;
/**temp** And here's a pointer to it: */
struct lmhedr *caput = NULL; /* Symbol table--known globally */
long inhalt; /* Possible symbol value discovered during dissasembly */
int nomo = -1; /* Index to last symbol found by name */
int omega = -1; /* Index to last symbol in symbol table:*/
/* Negative value => no symbols */
char ref; /* Symbols for disassembly: */
/* '\0' => none */
/* 'm' => text, data, or bss */
/**temp** Setting of 'a' not currently in use */
/* 'a' => other */
int scope = 0; /* If zero, find all; otherwise find first */
int minus; /* 1 => "-" in effect; 0 => "-" not in effect */
U16 pkawnt[HMPPTS]; /* Pass counts (0 => not in use) */
U16 *plocus[HMPPTS]; /* Values of pass points */
U16 ancien[HMPPTS]; /* Previous contents at pass point */
main(bpptr)
struct basepage *bpptr;
{
char combuf[BUFLEN];
char *cx;
char *dispaddr; /* current display address */
char *listaddr; /* current disassembly addr*/
struct cpustate state; /* state of user program registers */
struct value curvals; /* values relating to current file or pgm */
register int i; /* workhorse integer */
/* phony machine state initialization */
for (i=0; i<8; i++) {state.dreg[i]=0L; state.areg[i]=0L;}
state.pc = 0x0;
state.usp = 0x00001000L;
state.areg[7]=state.usp;
state.ssp = GETSSP();
state.status = 0x0000;
dispaddr = 0;
listaddr = 0;
curvals.kind = 0; /* no current file or program */
zappas(); /* Purge pass points */
init(bpptr, &state, &curvals, &dispaddr, &listaddr, &bpptr);
while ( 1 ) {
while ( ! (cx = readcom(combuf)) );
If *cx EQ '-' then BEGIN
minus = 1;
++cx;
END
otherwise minus = 0;
switch ( *cx ) {
/* one case for each possible command */
case 'D' : display(cx, &dispaddr);
break;
case 'E' : ecmd(cx, bpptr, &state, &curvals,
&dispaddr, &listaddr, &bpptr);
break;
case 'F' : fillmem(cx);
break;
case 'G' : gocmd(cx,&state,&listaddr);
break;
case 'H' : hexmath(cx);
break;
case 'I' : incomtl(cx, &curvals);
break;
case 'K' : koax(cx);
break;
case 'L' : disasm(cx, &listaddr);
break;
case 'M' : movemem(cx);
break;
case 'P' : passpt(cx);
break;
case 'R' : readfl(cx, bpptr, &curvals, &dispaddr);
break;
case 'S' : setmem(cx);
break;
case 'T' : trace(cx, &state, &listaddr, (int)1);
break;
case 'U' : trace(cx, &state, &listaddr, (int)0);
break;
case 'V' : vcmd(cx, &curvals);
break;
case 'W' : wrtfile(cx, &curvals);
break;
case 'X' : examine(cx, &state);
break;
default : stout("Unknown Command\n\n");
break;
}; /* end of switch on comx */
}; /* end of while loop */
} /* end of function main */
init(basep, statep, valuep, dap, lap, bppa)
struct basepage *basep;
struct cpustate *statep;
struct value *valuep;
char **dap;
char **lap;
long *bppa;
{
/* if program file argument, then load it */
/* set up trap vectors */
/* initialize tables */
stout("\nSID-68K Nonrelease: -4.8 20 May 1983\n");
stout("Copyright 1982,1983 Digital Research\n\n");
if (basep->fcb1.fn[0] != ' ')
loadpgm(&(basep->fcb1),basep,statep,valuep,dap,lap,bppa);
}
char *readcom(buf) /* read one command line, return command type */
register char *buf;
{
register char *cx;
register short int i,nc;
do {
stout("\r\r-"); /* prompt */
*buf = BUFLEN-3;
BDOS(READBUF, buf); /* get command line */
putchar('\n');
} while ( ( nc=buf[1]) == 0 );
buf[2+nc] = 0;
for ( cx = &buf[2]; *cx; *cx=toupper(*cx), cx++);
for ( cx= &buf[2], i=0 ; iswhite(*cx) && (i<nc) ; cx++ , i++ );
return( (i==nc) ? NULL : cx );
}
clean()
{
/* restore trap vectors */
}
display(cx, dap)
char *cx;
char **dap;
{
/* display memory in hex and ascii */
short int format; /* 1=byte, 2=word, 4=long word */
char *s; /* start address */
char *f; /* end address */
char *i; /* working variable */
char *j; /* ditto */
short int c; /* column number */
/* parse command and extract parameters */
format = getform(&cx);
if ( ! gethex(&cx, &s) ) { /* get start address */
if ( nomore(cx) ) s = *dap; /* or use default */
else { bad(); return(0); } /* junk on the line */
}
if ( (format != 1) && (s & 1) ) s += 1; /* force even */
if ( GETSEP ) {if ( ! gethex(&cx, &f) ) {bad(); return;} }
else f = s + (12*16-1); /* not there, use def */
if ( ! nomore(cx) ) {bad(); return;} /* rest of line must be empty */
/* now do the display */
f = f - format + 1; /* first byte of last chunk to print */
for ( ; s <= f ; s += 16 ) { /* one line per pass */
if ( keyhit() ) return;
puthexl(s); putchar(' '); putchar(' '); c = 10;
for ( i=s, j=min(s+15,f);
i <= j;
i += format ) {
switch ( format ) {
case 1 : puthexb(i->memb);
break;
case 2 : puthexw(i->memw);
break;
case 4 : puthexl(i->meml);
break;
} /* end of switch */
putchar(' ');
c += (2*format+1);
} /* end of loop across line */
while ( c++ < 60 ) putchar(' ');
for ( i=s, j=min(s+15,f); i<=j ; i++ ) putbyte(*i);
putchar('\n');
} /* end of loop through lines */
*dap = f + format;
} /* end display */
ecmd(cx, basep, statep, valuep, dap, lap, bppa)
char *cx;
struct basepage *basep;
struct cpustate *statep;
struct value *valuep;
char **dap;
char **lap;
long *bppa;
{
/* Load the program named in the command */
struct fcb pgmfcb;
deblank(&cx);
if (parse(&cx, &pgmfcb, "68K") && nomore(cx))
loadpgm ( &pgmfcb, basep, statep, valuep, dap, lap, bppa);
else bad();
}
loadpgm(fcbp, basep, statep, valuep, dap, lap, bppa)
struct fcb *fcbp;
struct basepage *basep;
struct cpustate *statep;
struct value *valuep;
char **dap;
char **lap;
long *bppa;
{ /* load a program for execution */
extern int omega;
struct lpb pgmlpb;
int loaderr;
struct basepage *newbp;
long *stkptr;
int i;
/* open program file */
while(1)
{
if ( (BDOS(OPEN, fcbp) & 0xffL) == 0x0FFL )
{
if(fcbp->t[0] != ' ')
{ /* open failed */
stout("Cannot open program file\n");
return;
}
else
{
fcbp->t[0] = '6';
fcbp->t[1] = '8';
fcbp->t[2] = 'K';
}
}
else
break;
}
/* set up lpb */
pgmlpb.fcbaddr = fcbp;
pgmlpb.tpabase = basep->lowtpa;
pgmlpb.tpatop = basep;
pgmlpb.flags = 0;
/* now do program load */
loaderr = (int)(BDOS(PGMLOAD, &pgmlpb) & 0x0FFFFL);
switch ( loaderr ) {
case 0: { /* successful */
newbp = pgmlpb.bpaddr;
valuep->kind = 1;
valuep->textbase = newbp->csstart;
valuep->textlen = newbp->cslen;
valuep->database = newbp->dsstart;
valuep->datalen = newbp->dslen;
valuep->bssbase = newbp->bsstart;
valuep->bsslen = newbp->bslen;
valuep->bpa = newbp;
valuep->initstk = pgmlpb.stkinit;
statep->pc = newbp->csstart;
stkptr = pgmlpb.stkinit;
(*--stkptr) = newbp;
(*--stkptr) = *--bppa;
statep->usp = stkptr;
statep->areg[7]= stkptr;
statep->status = 0;
*dap = newbp->csstart;
*lap = newbp->csstart;
newbp->fcb1.dr = 0;
newbp->fcb2.dr = 0;
for ( i = 0; i < 11; ++i) {
newbp->fcb1.fn[i] = ' ';
newbp->fcb2.fn[i] = ' ';
}
newbp->fcb1.cr = 0;
newbp->fcb2.cr = 0;
newbp->fcb1.ex = 0;
newbp->fcb2.ex = 0;
}
break; /* end case 0 -- success */
case 1: { stout("Insufficient memory or bad file header\n");
return;
}
break;
case 2: { stout("Read error\n");
return;
}
break;
case 3: { stout("Bad relocation bits\n");
return;
}
break;
default: { stout("Unknown program load error\n");
return;
}
break;
} /* end switch */
zappas(); /* Delete all pass points */
omega = simz(fcbp,valuep AT textbase);
/* Load symbol table */
showvals(valuep);
} /* end loadpgm */
fillmem(cx)
char *cx;
{
/* fill memory with constant */
register short int format; /* 1=byte, 2=word, 4=long word */
char *s; /* start address */
char *f; /* end address */
long v; /* value to stuff into memory */
/* parse command and extract parameters */
format = getform(&cx);
if ( gethex(&cx, &s) ); /* get start address */
else {bad(); return(0);} /* not there, error */
if ( (format != 1) && (s & 1) ) /* must be even address, error */
{bad(); return(0);}
if ( GETSEP && gethex(&cx, &f) ); /* get end address */
else { bad(); return(0); } /* not there, error */
if ( GETSEP && gethex(&cx, &v) ); /* get value to stuff */
else { bad(); return(0); }
if ( ! nomore(cx) ) {bad(); return;} /* rest of line must be empty */
if ((s>f) || /* test for junk or nonsense */
( (format == 1) && ((v > 255L) || (v < 0)) ) ||
( (format == 2) && ((v > 65535L) || (v < 0)) ) )
{ bad(); return(0); }
/* now do the stuffing */
for ( ; (s+format) <= (f+1); s += format )
{
switch ( format ) {
case 1 : s->memb = (char)v;
if ((s->memb ^ (char)v) & 0xFF) badram(s);
break;
case 2 : s->memw = (short int)v ;
if ((s->memw ^ (short int)v) & 0xFFFF) badram(s);
break;
case 4 : s->meml = (long)v ;
if ( s->meml != v ) badram(s);
break;
} /* end of switch */
} /* end of for */
} /* end of fillmem */

View File

@@ -0,0 +1,86 @@
SID-68K 20 MAY 1983
(For internal DRI use)
Please refer bugs, complaints, questions, and suggestions to
Tim Benson at ext. 6092.
1. Much like DDT-68K (see CP/M-68K Programmer's Guide) with
the following enhancements:
a. Symbols
b. W-option on T- and U-commands
c. Pass points (P-command)
These operate much as in SID-86 and CP/M SID (see manuals).
2. For now, to run SID-68K you need SID.68K and SID68K.68K, the
latter on default drive. Just say SID [file-spec].
3. Symbols are loaded automatically if present in a load module that
is loaded at start-up or with the E-command. For now, symbol table
is an array of fixed size with room for up to 2000 symbol entries.
For a listing of symbols, type H. If you need to look at symbol
table, type K (the K-command "edit symbol table", which otherwise
doesn't work yet).
You may use a symbol reference wherever a Hex specification could
be used. For example, if _main is a symbol, then
H._main prints value of symbol
H=_main prints byte at addr given by value of symbol
H@_main prints word at addr given by value of symbol
H!_main prints long at addr given by value of symbol.
The disassembler only prints such symbols as refer to addrs in the
text, data, and bss segments, but any symbol is recognized when you
are typing in SID commands.
4. The P-command works just as in SID-86 (see manual).
5. The G-, T-, and U-commands work much as in SID-86 (see manual).
However, a TRAP instruction will not be traced thru, even if the
W-option is not specified. Note that the "-" prefix works with
these commands (see manual). For now, a hyphen preceding any other
SID command is ignored.
6. Pass points behave much as in SID-86. The following exceptions
are noteworthy:
a. When a pass-point is encountered, you get a message,
and both "before" and "after" state displays.
b. If your program contains the ILLEGAL instruction,
and if SID encounters it under Go, Trace, and Untrace,
you get an error message, and the command is aborted.
c. SID will not "see" any pass points between the time
an attempt is made to Trace or Untrace thru a TRAP
and the time when control returns to the instruction
following the TRAP (if it ever does).
d. DO NOT set a pass point in the middle of an instruction--
result is undefined.
e. A break point that is set the same as a pass point
is treated as a pass point; in effect, it is ignored.
MAJOR KNOWN BUGS
Please report any bugs OTHER THAN the following:
1. Some machine instructions are disassembled incorrectly.
Examples:
IN HEX GIVEN AS SHOULD BE
4AFC xxxx tas #xxxx illegal ...
000A 3202 ori.b #$3202,A2 *unknown instruction*
4CF9 0018 0000 06C0
movem.L $180000,D3-D3/D6-D7/A1-A2
movem.L $6C0,D3-D4
(In the MOVEM instruction, the disassembler takes the LAST word
to be the register mask--it should take the SECOND word, which may
or may not be last.)
2. In D- and L-commands, if you give addr via a symbol reference
and symbol does not exist, then you should get "?", but you don't.
3. G-command, inter al., is not protected in any way against
odd-numbered addresses in the command line.
4. If the bss segment in a load module is too large, attempting
to load it can wipe out SID altogether.
3 JUN 83 17:21 (TMB)

View File

@@ -0,0 +1,65 @@
/********************************************************/
/* */
/* Usual filename: SIDDEF.H */
/* Put ' #include "siddef.h" ' at head of each */
/* separately compiled module containing */
/* code added to DDT68K to give SID68K. */
/* Remarks: Definitions and declarations */
/* specific to SID68K. */
/* Author: Timothy M. Benson */
/* Control: 12 MAY 83 15:36 (TMB) */
/* */
/********************************************************/
typedef long U32;
typedef unsigned int U16;
#define HMPPTS 32 /* # pass points allowed */
#define SAYMAX stout("32\n"); /* (Must agree with preceding line */
#define HMSYMS 2000 /* Maximum number of symbols in symbol table */
/**temp** This is a temporary value.*/
#define CONTIG 0x601A /* First word of contiguous load modules */
#define DISCON 0x601B /* First word of noncontiguous load modules */
#define TLONG 0x0080 /* Flag for entry in long-names string table */
#define GONE 0x0040 /* Flag indicating hidden symbol */
#define SEGREF 0x0700 /* Text, data, or bss relative */
#define IS & /* (Sometimes reads well) */
#define TREL 0x0200 /* (sic) Text relative */
#define DREL 0x0400 /* (sic) Data relative */
#define BREL 0x0100 /* Bss relative */
/************************************************/
/* */
/* Structure of symbol table entry */
/* */
/************************************************/
struct asymbl BEGIN
char namae[8];
U16 symtyp;
U32 symval;
END;
/************************************************/
/* */
/* Structure of load module header */
/* followed by symbol table */
/* */
/************************************************/
/* Using type definitions to ensure lengths of 16 and 32 bits,
unsigned if allowed, alignment on even address, no gaps. */
struct lmhedr BEGIN
U16 lmkind; /* 0x601A => contiguous; 0x601B => noncontiguous */
U32 lmtlen; /* Number of bytes in text segment */
U32 lmdlen; /* Number of bytes in data segment */
U32 padlen; /* Number of bytes in bss segment */
U32 symlen; /* Number of bytes in symbol table */
U32 nought; /* Filler: Should be zero */
U32 tceps; /* Start of text */
U16 rflagb; /* 0 => relocation; nonzero => no relocation */
U32 dceps; /* Start of data */
U32 bceps; /* Start of bss */
struct asymbl sump[HMSYMS]; /* Symbol table per se */
char filler[128];
END;

View File

@@ -0,0 +1,569 @@
/********************************************************/
/* */
/* Usual filename: SIDFUN.C */
/* Remarks: Functions specific to SID68K */
/* Author: Timothy M. Benson */
/* Control: 19 MAY 83 17:36 (TMB) */
/* */
/********************************************************/
#include "lgcdef.h"
#include "siddef.h"
#include "ddtinc.h"
#include "stdio.h"
#include "bdosfunc.h"
#include "disas.h"
/************************************************/
/* Load and initialize symbol table, returning */
/* int sized index to last valid symbol aut */
/* negative error code. */
/************************************************/
simz(fcbp,hwer)
struct fcb *fcbp;
long hwer;
{
/**temp** Next line to be deleted eventually */
extern struct lmhedr klops;
extern struct lmhedr *caput;
extern int nomo;
U32 rano(); /* Returns second argument incremented by one */
struct asymbl *icon;
int goods; /* # symbol bytes in first symbol record */
int i;
int irate; /* Zero iff no input errors */
int junk; /* # bytes preceding symbols in first symbol record */
register long kount; /* Scratch loop counter */
char *oint; /* Scratch byte pointer */
U32 randy; /* Current random record number */
int zulu; /* Index to last symbol in current table */
/**temp** Next line to be replaced eventually by dynamic allocation */
caput = &klops;
randy = 0;
BDOS(SETDMA,caput);
rano(fcbp,&randy);
irate = BDOS(OPEN,fcbp) AND 0xFFFFFFFCL;
irate ORWITH (int) BDOS(READRND,fcbp);
caput AT tceps = hwer;
If caput AT lmkind EQ CONTIG then BEGIN
caput AT dceps = caput AT tceps;
caput AT dceps INCBY caput AT lmtlen;
caput AT bceps = caput AT dceps;
caput AT bceps INCBY caput AT lmdlen;
randy = 28; /* # bytes in contiguous header */
END
otherwise randy = 36; /* # bytes in noncontiguous header */
If NOT(caput AT symlen) then BEGIN
stout("No symbols\n");
/**temp** Need to allot space for added symbols */
/**temp** Need to deallocate extra space */
nomo = -1;
return(-1);
END
randy INCBY caput AT lmtlen + caput AT lmdlen;
/* I.e., compute # bytes preceding symbols */
junk = randy % 128;
goods = 128 - junk;
randy /= 128;
oint = caput AT sump;
icon = oint; /* Save addr of symbol table. */
BDOS(SETDMA,icon);
randy = rano(fcbp,&randy);
irate ORWITH (int) BDOS(READRND,fcbp);
/* Move wanted info to head of array. */
for (i = 0; i LT goods; i++) *oint++ = *(oint + junk);
/* Now oint points to icon + goods. */
zulu = HMSYMS * sizeof(struct asymbl);
If caput AT symlen GT zulu then BEGIN
kount = (zulu - goods) / 128;
If (zulu - goods) % 128 then ++kount;
zulu = HMSYMS - 1;
END
otherwise BEGIN
kount = (caput AT symlen - goods) / 128;
If (caput AT symlen - goods) % 128 then ++kount;
zulu = caput AT symlen / sizeof(struct asymbl) - 1;
END
/**temp** May want to compute end of symbol table here */
/**temp** and/or deallocate unused storage */
while (kount-- GT 0) BEGIN
BDOS(SETDMA,oint);
randy = rano(fcbp,&randy);
If (i = BDOS(READRND,fcbp)) then
If i EQ 1 or i EQ 4 then kount = 0;
else irate ORWITH i;
oint INCBY 128;
END
If irate then BEGIN
stout("Symbol table disaster\n");
return(-1);
END
/**temp** When symbol table allocated dynamically, make */
/**temp** sure zulu still reflects subscript of */
/**temp** last symbol at this point in program */
If caput AT lmkind EQ CONTIG then
for(i = 0; i LE zulu; i++)
If (icon+i) AT symtyp IS SEGREF then
(icon+i) AT symval INCBY caput AT tceps;
/**temp** May later need different test for full symbol table */
If zulu GE HMSYMS - 1 then stout("Symbol table full\n");
return(zulu);
}
/************************************************/
/* Install random record number in fcb and */
/* return next higher random record number */
/************************************************/
U32 rano(fcbp,rand)
struct fcb *fcbp;
union slimy BLOCK
U32 recno;
char tail[4];
UNBLOCK *rand;
{
int i;
for (i = 0; i LE 2; i++)
fcbp AT r[i] = rand AT tail[i+1];
return(rand AT recno + 1);
}
deluge(tabula,zulu)
struct asymbl tabula[];
register int zulu;
{
register int i;
register int j;
register char litt;
register int reply;
U16 simbl;
for(i = 0, reply = 2; i LE zulu and reply; i++) BEGIN
putchar('\n');
puthexw(i);
putchar('(');
If (simbl = tabula[i].symtyp) IS TREL then putchar('T');
else If simbl IS DREL then putchar('D');
else If simbl IS BREL then putchar('B');
else putchar('A');
stout(")(");
If simbl IS GONE then putchar('H');
otherwise putchar('V');
stout("): ");
puthexl(tabula[i].symval);
stout(" = ");
/**temp** Call to kobold in next line may need parameters */
If simbl IS TLONG then kobold();
otherwise for(j = 0; j LT 8; j++)
If litt = tabula[i].namae[j] then putchar(litt);
else putchar(' ');
If reply EQ 2 then reply = 1;
otherwise If NOT (i % 10) then reply = pause();
END
putchar('\n');
}
kobold()
{
/* Will handle printing long symbols here; for now print message */
stout("** Long COBOL-style symbol **");
}
pause()
{
register char mor;
stout("\n Continue listing? (y/n)");
mor = getchar();
mor = toupper(mor);
putchar('\n');
return(mor NE 'N');
}
/****************************************************************/
/* For a given numerical value, find and print corresponding */
/* symbols in indicated table, with certain options. Return */
/* int number of symbols found. */
/****************************************************************/
spell(value,table,scope,class,orient)
U32 value;
struct asymbl table[];
int scope; /* If zero, then find all; otherwise find first. */
char class; /* 'm' implies only want segment references. */
char orient; /* 'h' or 'H' horizontal, anything else vertical: */
/* If 'H' then prefix '.'; if 'h' then append ':'.*/
{
extern int omega;
int hmany; /* Counter for # of symbols with given value */
register int i;
char it; /* Hold char while deciding what to do. */
register int j;
register U16 simbol; /* Hold symtyp here for inspection. */
hmany = 0; /* Alcyon compiler does not allow this */
/* to be initialized in declaration: */
/* I protest! */
for(i = 0; i LE omega; i++) BEGIN
If table[i].symval NE value then IGNORE;
simbol = table[i].symtyp;
If class EQ 'm' and NOT (simbol IS SEGREF)
then IGNORE;
/* I.e. ignore e.g. stack references */
If simbol IS GONE then IGNORE;
/* I.e. ignore hidden symbol */
/* Next line is dummy call to routine to handle long symbols */
If simbol IS TLONG then roam();
If orient EQ 'H' then putchar('.');
for(j = 0; j LT 8 and (it = table[i].namae[j]); j++)
putchar(it);
If orient NE 'H' then putchar(':');
If orient EQ 'H' or orient EQ 'h' then putchar(' ');
otherwise putchar('\n');
hmany++;
If scope then break;
END
If hmany and orient EQ 'h' then putchar('\n');
return(hmany);
}
roam()
{
/* dummy routine: will later handle symbols longer than 8 chars */
}
/************************************************/
/* For given string of given length find first */
/* corresponding symbol table entry, updating */
/* value and putting subscript at *whence. */
/* Return int 1 if found, 0 if not found, */
/* -1 if the bizarre happens, and -2 if an */
/* attempt is made to utilize a feature not */
/* yet implemented. */
/************************************************/
indica(leqth,logos,tesoro,phylum,value,whence)
int leqth;
char logos[]; /* String containing name */
struct asymbl tesoro[]; /* Short symbol table */
char phylum; /* Type of symbol wanted */
U32 *value; /* Place to stick value if and when found */
int *whence; /* Place to stick subscript to symbol table */
{
extern int omega;
register int i; /* To sweep symbol table */
register int j; /* To sweep string */
register short match; /* 1 iff strings equivalent */
register char nxch; /* Next char in logos */
U16 symbol; /* Type of last symbol considered */
for(i = 0; i LE omega; i++) BEGIN
symbol = tesoro[i].symtyp;
switch(phylum) BLOCK
case 'M': /* Address value wanted */
If NOT (symbol IS SEGREF) then IGNORE;
break;
case 'A': /* Nonaddress numerical value wanted */
If symbol IS SEGREF then IGNORE;
break;
case 'B':
break; /* Accept any kind of symbol */
default:
return(-1); /* This shouldn't happen */
UNBLOCK
If symbol IS GONE then IGNORE;
/**temp** Call in next statement will require parameters. */
/**temp** For now just returns (int) -2. */
If symbol IS TLONG then return(trek());
for(j = 0, match = 1; j LT 8 and match; j++) BLOCK
If j LT leqth then nxch = logos[j];
otherwise nxch = '\0';
If nxch NE toupper(tesoro[i].namae[j]) then match = 0;
UNBLOCK
If match then BLOCK
*whence = i;
*value = tesoro[i].symval;
return(1);
UNBLOCK
END
return(0);
}
trek()
{
/* dummy routine: will later handle symbols longer than 8 chars */
return(-2);
}
/****************************************/
/* K command: Play with symbol table */
/****************************************/
koax(cx)
char *cx;
{
extern struct lmhedr *caput;
extern int omega;
extern int main();
struct asymbl *galaxy;
int seqno; /* Subscript to symbol table */
long spot; /* Symbol value input */
char task;
char uppr; /* For entering new name */
galaxy = caput AT sump;
If nomore(cx) then BEGIN
stout("SID begins at: ");
puthexl(main);
putchar('\n');
stout("Symbol table at: ");
puthexl(galaxy);
putchar('\n');
If omega LT 0 then BLOCK
stout("No symbols");
If caput then begin
stout("; file header at: ");
puthexl(caput);
end
putchar('\n');
UNBLOCK
return;
END
deblank(&cx);
task = *++cx;
switch(task) BEGIN
case 'A':
/* Add a symbol; e.g. KAname,value,type */
/* where name is converted to upper case and */
/* comma after it is obligatory, as is value. */
If nomore(cx) then BLOCK bad(); return; UNBLOCK
otherwise BLOCK
If omega GE HMSYMS then begin
stout("\nSymbol table full\n");
return;
end
deblank(&cx);
uppr = *++cx;
If uppr EQ ',' then begin bad(); return; end
++omega;
for(seqno = 0; seqno LT 8; seqno++) begin
(galaxy+omega) AT namae[seqno] = uppr;
If *++cx NE ',' and uppr then uppr = *cx;
else uppr = '\0';
end
cx--;
If NOT (getsep(&cx) and gethex(&cx,&spot)) then begin
omega--;
bad();
return;
end
(galaxy+omega) AT symval = spot;
If getsep(&cx) and gethex(&cx,&spot) then
seqno = (int)spot;
else seqno = 0xA700; /* Default symbol type */
If NOT nomore(cx) then begin
omega--;
bad();
return;
end
(galaxy+omega) AT symtyp = seqno;
UNBLOCK
break;
case 'H': /* Hide symbols */
/* KH hide symbol most recently sought by name*/
/* KHvalue hide first symbol with given value */
/* KH*value hide symbol with sequence number equal */
/* to given value, if in range */
seqno = findsn(cx,omega,galaxy);
If seqno LT 0 then begin bad(); return; end
otherwise (galaxy+seqno) AT symtyp ORWITH GONE;
break;
case 'R': /* Recover hidden symbols */
/* KR recover all hidden symbols */
/* KRvalue recover first symbol with given value */
/* KR*value recover symbol with sequence number */
/* equal to given value, if in range */
If nomore(cx) then
for(seqno = 0; seqno LE omega; seqno++)
(galaxy+seqno) AT symtyp ANDWITH ~GONE;
otherwise BLOCK
seqno = findsn(cx,omega,galaxy);
If seqno LT 0 then begin bad(); return; end
else (galaxy+seqno) AT symtyp ANDWITH ~GONE;
UNBLOCK
break;
default:
bad();
return;
break;
END
putchar('\n');
}
/************************************************/
/* Find serial number of symbol entry, parsing */
/* rest of command line */
/************************************************/
findsn(spear,zedd,arcade)
char *spear; /* Scanner for command line */
int zedd; /* Highest symbol table subscript */
struct asymbl *arcade; /* Addr of symbol table */
{
extern int nomo; /* Last entry sought by name */
int ix; /* To sweep symbol table */
int script; /* Int subscript to be returned */
long werth; /* Numerical value of symbol */
script = -1; /* Preset to illegal value */
If nomore(spear) then script = nomo;
otherwise BLOCK
deblank(&spear);
If *(spear+1) EQ '*' then begin
++spear;
If gethex(&spear,&werth) and nomore(spear) then
script = (int) werth;
end
else If gethex(&spear,&werth) and nomore(spear)
then for(ix = 0; ix LE zedd and script LT 0; ix++)
If (arcade+ix) AT symval EQ werth then script = ix;
UNBLOCK
If script GT zedd then script = -1;
return(script);
}
passpt(pcx)
char *pcx;
{
extern U16 pkawnt[HMPPTS];
extern U16 *plocus[HMPPTS];
extern U16 ancien[HMPPTS];
extern int minus;
extern int omega;
extern int scope;
extern struct lmhedr *caput;
int jp;
int reply; /* Operator's response */
int plain; /* plain iff no tail */
char *nupt; /* Value of new pass point */
/* N.b.: "char" required so bitwise "&" */
/* will work properly. */
long cntdn; /* New pass count (initially long) */
cntdn = 1; /* Set to default pass count */
If NOT (plain = nomore(pcx)) then BEGIN
If NOT gethex(&pcx,&nupt) then goto chide;
/* Warning: The following bitwise "&" statement */
/* requires nupt to be declared "char" pointer.*/
If nupt & 1 then BLOCK
stout("\nNo change--Address must be even!\n");
return;
UNBLOCK
If getsep(&pcx) then If NOT gethex(&pcx,&cntdn)
or minus then goto chide;
If NOT nomore(pcx) then goto chide;
END
If NOT cntdn then goto chide;
If minus then BEGIN
If plain then zappas();
else BLOCK
for (jp = 0; jp LT HMPPTS; jp++)
If pkawnt[jp] and plocus[jp] EQ nupt then begin
pkawnt[jp] = 0;
minus = 0;
end
If minus then goto chide;
UNBLOCK
END
otherwise BEGIN
If plain then BLOCK
for(jp=0,reply=1;jp LT HMPPTS and reply;jp++) begin
If pkawnt[jp] then {
If ++minus GT 16 and jp LT HMPPTS then BEGIN
reply = pause();
minus = 0;
END
If reply then BEGIN
putchar('\n');
puthexw(pkawnt[jp]);
stout(" ");
puthexl(plocus[jp]);
stout(" ");
If omega GE 0 then
spell((U32) plocus[jp],caput AT sump
,scope,'m','H');
END
}
end
putchar('\n');
UNBLOCK
else BLOCK
for (jp = 0; jp LT HMPPTS; jp++)
If pkawnt[jp] and plocus[jp] EQ nupt then begin
If pkawnt[jp] EQ cntdn then stout("\nAlready set\n");
otherwise pkawnt[jp] = cntdn;
return;
end
minus = 1;
for (jp = 0; jp LT HMPPTS; jp++)
If NOT pkawnt[jp] then begin
pkawnt[jp] = (U16) cntdn;
plocus[jp] = nupt;
jp = HMPPTS;
minus = 0;
end
If minus then begin
stout("\nToo many pass points--limit is: ");
SAYMAX
end
UNBLOCK
END
return;
chide:
bad();
}
qotbyt(nnnn)
long nnnn;
{
If nnnn LT 0x20 or nnnn GT 0x7E then return(0);
putchar('\'');
BDOS(CONOUT,nnnn);
putchar('\'');
return(1);
}
vecina(cxp,sought)
char **cxp;
char sought;
{
/* Check if next char in command is a specified char, advancing */
/* pointer if it is. */
++*cxp;
If **cxp EQ sought then return(1);
--*cxp;
return(0);
}
zappas()
{
extern U16 pkawnt[HMPPTS];
int jz;
for (jz = 0; jz LT HMPPTS; jz++) pkawnt[jz] = 0;
}

View File

@@ -0,0 +1,196 @@
*****************************************************************
* *
* Usual filename: SIDLOAD.S *
* SID Loader -- This program loads SID68K at the top of *
* the TPA, hands it its command tail, and passes control *
* to it. *
* Last modified 28 January 1983 *
* *
**temp** Later revise symbol and comment usage to reflect *
**temp** SID rather than DDT *
*
*****************************************************************
*
.text
*
start: move.l (a7)+,ccprtn * save stacked info
move.l (a7)+,bpaddr
*
lea mystack+$80,a7 * switch to local stack
*
move.l bpaddr,a0 * copy base page to local area
lea localbp,a1
move.l #$100,d0 * count of bytes to move
bsr copy * branch to subroutine
*
move.w #32,d0 * get the current user # and save it
move.l #$ff,d1 * d1 = 255
trap #2 * call the bdos
move.l d0,d3 * d3 holds current user #
*
move.l bpaddr,a0 * get drive for DDT1
move.b $24(a0),ddt1fcb * and stuff into FCB
move.w #openf,d0 * open file DDT1.68K
move.l #ddt1fcb,d1 * get address of fcb
trap #2 * call the bdos
cmpi.b #$ff,d0 * check for failure
bne openok * if not then go ahead
*
tst d3 * check if we are on user 0
beq loadfail * if so then we have failed
*
move.w #32,d0 * if not then switch to user 0
clr.l d1 * d1 = 0
trap #2 * call the bdos
*
move.w #openf,d0 * try the open again
move.l #ddt1fcb,d1 * address of fcb
trap #2 * call the bdos
cmpi.b #$ff,d0 * check for errors
beq loadfail * error, load failed
*
openok: move.w #setdma,d0 * set up to read pgm header
move.l #dskbuf,d1 * dma address
trap #2 * call the bdos
*
move.w #readseq,d0 * read the header
move.l #ddt1fcb,d1 * address of fcb
trap #2 * call the bdos
cmpi.w #0,d0 * check for errors
bne loadfail * error, load failed
*
lea dskbuf,a0
move.l tsize(a0),d0 * compute size of DDT1.68K
add.l dsize(a0),d0 * by adding component sizes
add.l bsize(a0),d0
add.l #$1000,d0 * fake stack size since Belton doesnt
add.l #bplen+fudge,d0
*
cmpi.w #goodmgc,magic(a0) * must be $601A
bne loadfail
*
tst.w rlbflg(a0) * must be 0
bne loadfail
*
lea localbp,a0
lea lpb,a1
lea ddt1fcb,a2
move.l a2,lpbfcb(a1)
move.l bphitpa(a0),d1 * set up lpb and load pgm
move.l d1,lpbhitpa(a1)
sub.l d0,d1
bclr.l #0,d1
move.l d1,lpblotpa(a1)
clr.w lpbcf(a1)
clr.b ddt1fcb+fcbcr
move.w #pgmldf,d0 * now do load
move.l a1,d1
trap #2
tst.w d0
bne loadfail * load has failed
*
move.l d3,d1 * restore the old user 0
move.w #32,d0 * get bdos function #
trap #2 * call the bdos
*
* set up for ddt execution
*
move.l lpbbpa(a1),a2 * addr of new bp
move.l bplotpa(a0),bplotpa(a2) * copy tpa lower bound
move.l lpbdusp(a1),a7 * default user stack ptr
move.l a2,-(a7) * stack new bp address
move.l ccprtn,-(a7) * stack ccp rtn address
move.l bpcsstrt(a2),-(a7) * stack entry to ddt1
lea bpfcb2(a0),a0 * copy parsed fcb's &
lea bpfcb2(a2),a1 * command tail to new bp
move.l #bplen-bpfcb2,d0
bsr copy
rts * exit to ddt1
*
* BDOS Function Code Equates
*
prstrng = 9
openf = 15
closef = 16
readseq = 20
setdma = 26
bioscall= 50
pgmldf = 59
*
*
* Local Variables etc.
*
mystack: .ds.l $20 * local stack
*
fudge = $10
*
bplen = $100
localbp: .ds.l bplen * local copy of base page
bplotpa = 0
bphitpa = 4
bpcsstrt= 8
bpcslen = $C
bpdsstrt= $10
bpdslen = $14
bpbsstrt= $18
bpbslen = $1C
bpfcb2 = $38
bpfcb1 = $5C
*
ccprtn: .ds.l 1 * return addr in CCP
bpaddr: .ds.l 1 * base page address
*
ddt1fcb: .dc.b 0 * FCB for DDT1.68K
.dc.b 'SID68K 68K' File name and type.
.dc.b 0 * extent
.dc.b 0,0 * s1, s2
.dc.b 0 * rc
.ds.b 16 * d0 ... dn
.dc.b 0 * cr
.ds.b 0,0,0 * random record number
*
.even
*
fcbcr = 32
*
dskbuf: .ds.w 64 * used to hold pgm header
magic = 0 * offsets in pgm header
tsize = 2
dsize = 6
bsize = 10
stksize = 18
rlbflg = 26
*
goodmgc = $601A * legal value for magic number
*
*
*
lpb: .ds.w 11 * loader parameter block
lpbfcb = 0
lpblotpa= 4
lpbhitpa= 8
lpbbpa = 12
lpbdusp = 16
lpbcf = 20
*
*
* Copy Bytes from (a0)+ to (a1)+ for d0
*
copy: subi.l #1,d0
bmi copyxit
copylp: move.b (a0)+,(a1)+
dbf d0,copylp
copyxit: rts
*
*
* Can't Load DDT1.68K, Print Error Message
*
loadfail: move.w #prstrng,d0
move.w #loaderr,d1
trap #2
move.l ccprtn,-(a7)
rts
loaderr: .dc.b 13,10,'Cannot load DDT1.68K.',13,10,'$'
*
*
.end

View File

@@ -0,0 +1,72 @@
/************************************************************************/
/* */
/* File I/O Definitions */
/* */
/* The definitions in this section are used by the run-time */
/* package to provide an interface between CP/M-68K I/O and */
/* standard C I/O. */
/* */
/************************************************************************/
/****************************************************************************/
/* Miscellaneous Definitions: */
/****************************************************************************/
#define FAILURE (-1) /* Function failure return val */
#define SUCCESS (0) /* Function success return val */
#define YES 1 /* "TRUE" */
#define NO 0 /* "FALSE" */
#define FOREVER for(;;) /* Infinite loop declaration */
#define NULL 0 /* Null pointer value */
#define EOF (-1) /* EOF Value */
#define TRUE (1) /* Function TRUE value */
#define FALSE (0) /* Function FALSE value */
#define BUFSIZE 128 /* # bytes in a buffer */
/**/
/****************************************************************************/
/* */
/* M A C R O S */
/* ----------- */
/* */
/* Define some stuff as macros .... */
/* */
/****************************************************************************/
#define getchar() ((char) BDOS(CONIN, 0)) /* Get character from console */
/**/
#define isalpha(c) (islower(c)||isupper(c)) /* true if "c" a letter */
#define isdigit(c) ('0' <= (c) && (c) <= '9') /* Ascii only!! */
#define iswhite(c) ((c) <= 040 || 0177<= (c)) /* Is control / funny char */
#define iswild(c) ((c) == '*' || (c) == '?') /* true if a wildcard char */
/**/
#define islower(c) ('a' <= (c) && (c) <= 'z') /* Ascii only!! */
#define isupper(c) ('A' <= (c) && (c) <= 'Z') /* Ascii only!! */
/**/
#define tolower(c) (isupper(c) ? ((c)+040):(c)) /* translate to lower case */
#define toupper(c) (islower(c) ? ((c)-040):(c)) /* translate to upper case */
/**/
#define abs(x) ((x) < 0 ? -(x) : (x)) /* Absolute value function */
#define max(x,y) (((x) > (y)) ? (x) : (y)) /* Max function */
#define min(x,y) (((x) < (y)) ? (x) : (y)) /* Min function */
/**/
/************************************************************************/
/* */
/* BDOS Procedure Declaration */
/* */
/************************************************************************/
long BDOS();
/***/

View File

@@ -0,0 +1,18 @@
e:vax stdio.h s
e:vax optab.h s
e:vax bdos.s s
e:vax sid05.c s
e:vax sid03.c s
e:vax siddef.h s
e:vax lgcdef.h s
e:vax sid04.c s
e:vax sidload.s s
e:vax bdosfunc.h s
e:vax sidfun.c s
e:vax disas.h s
e:vax cetacean.sub s
e:vax panacea.sub s
e:vax sid68k.c s
e:vax sid68k.dok s
e:vax ddtinc.h s
e:vax up5.sub s

View File

@@ -0,0 +1,23 @@
$ set noon
$ vsend BDOS.S
$ vsend BDOSFUNC.H
$ vsend CETACEAN.SUB
$ vsend DDTINC.H
$ vsend DISAS.H
$ vsend DOWN5.SUB
$ vsend LGCDEF.H
$ vsend LIST.COM
$ vsend MAKE.SUB
$ vsend OPTAB.H
$ vsend PANACEA.SUB
$ vsend SID03.C
$ vsend SID04.C
$ vsend SID05.C
$ vsend SID68K.C
$ vsend SID68K.DOK
$ vsend SIDDEF.H
$ vsend SIDFUN.C
$ vsend SIDLOAD.S
$ vsend STDIO.H
$ vsend UP5.SUB
$ vsend done