mirror of
https://github.com/SEPPDROID/Digital-Research-Source-Code.git
synced 2025-10-24 17:04:19 +00:00
Upload
Digital Research
This commit is contained in:
168
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102a/sid/bdos.s
Normal file
168
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102a/sid/bdos.s
Normal 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
|
||||
@@ -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
|
||||
@@ -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
|
||||
138
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102a/sid/ddtinc.h
Normal file
138
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102a/sid/ddtinc.h
Normal 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();
|
||||
|
||||
/**/
|
||||
|
||||
75
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102a/sid/disas.h
Normal file
75
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102a/sid/disas.h
Normal 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];
|
||||
@@ -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
|
||||
@@ -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 ^=
|
||||
@@ -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
|
||||
12
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102a/sid/lst.com
Normal file
12
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102a/sid/lst.com
Normal 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.
|
||||
@@ -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
|
||||
147
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102a/sid/optab.h
Normal file
147
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102a/sid/optab.h
Normal 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*"
|
||||
};
|
||||
@@ -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
|
||||
612
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102a/sid/sid03.c
Normal file
612
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102a/sid/sid03.c
Normal 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];
|
||||
}
|
||||
575
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102a/sid/sid04.c
Normal file
575
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102a/sid/sid04.c
Normal 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);
|
||||
}
|
||||
771
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102a/sid/sid05.c
Normal file
771
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102a/sid/sid05.c
Normal 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);
|
||||
}
|
||||
460
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102a/sid/sid68k.c
Normal file
460
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102a/sid/sid68k.c
Normal 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 */
|
||||
@@ -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)
|
||||
@@ -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;
|
||||
569
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102a/sid/sidfun.c
Normal file
569
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102a/sid/sidfun.c
Normal 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;
|
||||
}
|
||||
196
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102a/sid/sidload.s
Normal file
196
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102a/sid/sidload.s
Normal 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
|
||||
72
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102a/sid/stdio.h
Normal file
72
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102a/sid/stdio.h
Normal 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();
|
||||
|
||||
/***/
|
||||
18
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102a/sid/up5.sub
Normal file
18
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102a/sid/up5.sub
Normal 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
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user