mirror of
https://github.com/SEPPDROID/Digital-Research-Source-Code.git
synced 2025-10-24 08:54:17 +00:00
Upload
Digital Research
This commit is contained in:
408
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/as68/as68.h
Normal file
408
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/as68/as68.h
Normal file
@@ -0,0 +1,408 @@
|
||||
/*
|
||||
Copyright 1981
|
||||
Alcyon Corporation
|
||||
8716 Production Ave.
|
||||
San Diego, Ca. 92121
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <klib.h>
|
||||
#include "machine.h"
|
||||
#include "ctype.h"
|
||||
|
||||
#ifdef PDP11
|
||||
struct {
|
||||
char lobyte;
|
||||
char hibyte;
|
||||
};
|
||||
struct {
|
||||
char *ptrw1;
|
||||
char *ptrw2;
|
||||
};
|
||||
struct {
|
||||
int wd1;
|
||||
int wd2;
|
||||
};
|
||||
struct {
|
||||
int swd1;
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef MC68000
|
||||
struct {
|
||||
char hibyte;
|
||||
char lobyte;
|
||||
};
|
||||
struct {
|
||||
char *ptrw2;
|
||||
};
|
||||
struct {
|
||||
int wd1;
|
||||
int wd2;
|
||||
};
|
||||
struct {
|
||||
int swd1;
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef VAX
|
||||
struct {
|
||||
short wd2;
|
||||
short wd1;
|
||||
};
|
||||
struct {
|
||||
short swd1;
|
||||
};
|
||||
|
||||
struct {
|
||||
char lobyte;
|
||||
char hibyte;
|
||||
};
|
||||
struct {
|
||||
char *ptrw2;
|
||||
};
|
||||
#endif
|
||||
|
||||
/* format of a symbol entry in the main table*/
|
||||
|
||||
# define NAMELEN 8 /*length of name in symbol table*/
|
||||
struct symtab {
|
||||
char name[NAMELEN]; /*symbol name*/
|
||||
short flags; /*bit flags*/
|
||||
char *tlnk; /*table link*/
|
||||
long vl1; /*symbol value*/
|
||||
};
|
||||
|
||||
struct symtab *symtptr;
|
||||
# define STESIZE (sizeof *symtptr) /*byte length of symbol table entry*/
|
||||
|
||||
/* 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 SYRA 0002000 /*DATA based relocatable*/
|
||||
# define SYRO 0001000 /*TEXT based relocatable*/
|
||||
# define SYBS 0000400 /*BSS based relocatable*/
|
||||
# define SYIN 0000200 /*internal symbol -- opcode, directive or equ*/
|
||||
# define SYPC 0000100 /*[vlh]equated using star '*' expression*/
|
||||
# define SYRM 0000040 /*[vlh]register mask equate*/
|
||||
|
||||
/*flags for opcodes and directives*/
|
||||
# define OPDR 0100000 /*0=>opcode, 1=>directive*/
|
||||
# define OPFF 037 /*type of instruction (used as mask)*/
|
||||
|
||||
struct irts {
|
||||
char *irle; /*ptr to last entry in chain*/
|
||||
char *irfe; /*ptr to first entry in chain*/
|
||||
};
|
||||
|
||||
long stlen; /*length of symbol table*/
|
||||
|
||||
/*
|
||||
* intermediate text file
|
||||
* format of the intermediate text for one statement:
|
||||
*
|
||||
* ******************************************************
|
||||
* * it type = ITBS * # it entries * 0
|
||||
* ******************************************************
|
||||
* * absolute line number (long) *
|
||||
* ******************************************************
|
||||
* * it type = ITSY * instr length * 1
|
||||
* ******************************************************
|
||||
* * symbol table pointer for stmt label (long) *
|
||||
* ******************************************************
|
||||
* * it type = ITSY * instr mode length * 2
|
||||
* ******************************************************
|
||||
* * opcode ptr (long) *
|
||||
* ******************************************************
|
||||
* * it type = ITCN * relocation base * 3
|
||||
* ******************************************************
|
||||
* * location counter (pass 1) *
|
||||
* ******************************************************
|
||||
* * it type * relocation flag * 4 - oprnds
|
||||
* ******************************************************
|
||||
* * value (long) *
|
||||
* ******************************************************
|
||||
* .
|
||||
*
|
||||
* .
|
||||
* ******************************************************
|
||||
* * it type * relocation flag * n - oprnds
|
||||
* ******************************************************
|
||||
* * value (long) *
|
||||
* ******************************************************
|
||||
*/
|
||||
|
||||
#define ITOP1 4 /*first it entry for operands*/
|
||||
|
||||
/*
|
||||
* it type meaning
|
||||
* 0 beginning of statement
|
||||
* 1 value is pointer to symbol table
|
||||
* 2 value is a constant
|
||||
* 3 value is a specal char
|
||||
*
|
||||
* relocation flag for opcode it entry is operand length:
|
||||
* 'b' => byte
|
||||
* 'w' => word
|
||||
* 'l' => long
|
||||
*/
|
||||
|
||||
struct it {
|
||||
char itty; /*it type*/
|
||||
char itrl; /*relocation flag or # it entries*/
|
||||
long itop;
|
||||
};
|
||||
|
||||
int mode; /*operand mode (byte, word, long)*/
|
||||
int modelen; /*operand length per mode*/
|
||||
#define BYTE 'b'
|
||||
#define WORD 'w'
|
||||
#define LONG 'l'
|
||||
|
||||
/* parameters that define the main table*/
|
||||
#define SZMT 300 /*initial size of the main table */
|
||||
/*must be large enough to initialize*/
|
||||
#ifdef PDP11
|
||||
#define ICRSZMT 10 /*add to main table when run out*/
|
||||
#else
|
||||
#define ICRSZMT 50 /*add to main table when run out*/
|
||||
#endif
|
||||
int cszmt; /*current size of main table*/
|
||||
char *bmte; /*beginning of main table*/
|
||||
char *emte; /*end of main table*/
|
||||
|
||||
/* intermediate text types*/
|
||||
#define ITBS 0 /*beginning of statement*/
|
||||
#define ITSY 1 /*pointer to symbol table*/
|
||||
#define ITCN 2 /*constant*/
|
||||
#define ITSP 3 /*special*/
|
||||
#define ITRM 4 /*[vlh]register mask!*/
|
||||
#define ITPC 5 /*[vlh]pc relative argument*/
|
||||
|
||||
# define ITBSZ 256 /*size of the it buffer*/
|
||||
short itbuf[ITBSZ]; /*it buffer*/
|
||||
|
||||
#define STMAX 200 /*size of intermediate text buffer*/
|
||||
struct it stbuf[STMAX]; /*holds it for one statement*/
|
||||
|
||||
char sbuf[512]; /*holds one block of source*/
|
||||
|
||||
/*initial reference table for symbols*/
|
||||
# define SZIRT 128
|
||||
char *sirt[SZIRT];
|
||||
|
||||
/*initial reference table to opcodes*/
|
||||
char *oirt[SZIRT];
|
||||
|
||||
/*external symbol table*/
|
||||
#define EXTSZ 512
|
||||
char *extbl[EXTSZ];
|
||||
int extindx; /*index to external symbol table*/
|
||||
char **pexti; /*ptr to external symbol table*/
|
||||
|
||||
int absln; /*absolute line number*/
|
||||
int p2absln; /*pass 2 line number*/
|
||||
int fcflg; /*0=>passed an item. 1=>first char*/
|
||||
int fchr; /*first char in term*/
|
||||
int ifn; /*source file descriptor*/
|
||||
short *pitix; /*ptr to it buffer*/
|
||||
int itwc; /*number of words in it buffer*/
|
||||
struct it *pitw; /*ptr to it buffer next entry*/
|
||||
int itype; /*type of item*/
|
||||
long ival; /*value of item*/
|
||||
char *lblpt; /*label pointer*/
|
||||
char lbt[NAMELEN]; /*holds label name*/
|
||||
char *lmte; /*last entry in main table*/
|
||||
long loctr; /*location counter*/
|
||||
long savelc[4]; /*save relocation counters for 3 bases*/
|
||||
int nite; /*number of entries in stbuf*/
|
||||
struct it *pnite;
|
||||
int lfn; /*loader output file descriptor*/
|
||||
char *opcpt; /*pointer to opcode entry in main table*/
|
||||
int p2flg; /*0=>pass 1 1=>pass 2*/
|
||||
char **pirt; /*entry in initial reference table*/
|
||||
int reloc; /*relocation value returned by expression evaluator (expr)*/
|
||||
int rlflg; /*relocation value of current location counter*/
|
||||
/*relocation values*/
|
||||
# define ABS 0 /*absolute*/
|
||||
# define DATA 1
|
||||
# define TEXT 2
|
||||
# define BSS 3
|
||||
# define EXTRN 4 /*externally defined*/
|
||||
|
||||
#define EOLC '\n' /*end of line character*/
|
||||
#define EOF 0 /*end of file indicator*/
|
||||
#define NULL 0 /* [vlh] character null '\0' */
|
||||
#define TRUE 1 /* [vlh] boolean values */
|
||||
#define FALSE 0 /* [vlh] boolean values */
|
||||
|
||||
int format;
|
||||
int sbuflen; /*number of chars in sbuf*/
|
||||
char *psbuf; /*ptr into sbuf*/
|
||||
int itfn; /*it file number*/
|
||||
char itfnc; /*last char of it file name*/
|
||||
int trbfn; /*temp for text relocation bits*/
|
||||
char trbfnc; /*last char of text rb file*/
|
||||
int dafn; /*file for data stuff*/
|
||||
char dafnc; /*last char of data file*/
|
||||
int drbfn; /*file for data relocation bits*/
|
||||
char drbfnc; /*last char*/
|
||||
int prtflg; /*print output flag*/
|
||||
int undflg; /*make undefined symbols external flag*/
|
||||
|
||||
int starmul; /* * is multiply operator*/
|
||||
|
||||
char *endptr, *addptr;
|
||||
char *orgptr;
|
||||
char *subptr, *addiptr, *addqptr, *subiptr, *subqptr;
|
||||
char *cmpptr, *addaptr, *cmpaptr, *subaptr, *cmpmptr;
|
||||
char *equptr;
|
||||
char *andptr, *andiptr, *eorptr, *eoriptr, *orptr, *oriptr;
|
||||
char *cmpiptr;
|
||||
char *moveptr, *moveqptr;
|
||||
char *exgptr;
|
||||
char *evenptr;
|
||||
char *jsrptr, *bsrptr, *nopptr;
|
||||
char peekc;
|
||||
int numcon[2], numsym[2], indir[2], immed[2], numreg[2];
|
||||
int plevel; /*parenthesis level counter*/
|
||||
int opdix; /*operand index counter*/
|
||||
int p1inlen; /*pass 1 instr length*/
|
||||
int instrlen; /*pass 2 bytes in current instruction*/
|
||||
|
||||
/* effective address mode bits*/
|
||||
#define DDIR 000
|
||||
#define ADIR 010
|
||||
#define INDIRECT 020
|
||||
#define INDINC 030
|
||||
#define DECIND 040
|
||||
#define INDDISP 050
|
||||
#define INDINX 060
|
||||
#define SADDR 070
|
||||
#define LADDR 071
|
||||
#define IMM 074
|
||||
|
||||
#define AREGLO 8
|
||||
#define AREGHI 15
|
||||
|
||||
/* relocation bit definitions:*/
|
||||
#define RBMASK 07 /*tells type of relocation*/
|
||||
#define INSABS 7 /*first word of instr -- absolute*/
|
||||
#define DABS 0 /*data word absolute*/
|
||||
#define TRELOC 2 /* TEXT relocatable*/
|
||||
#define DRELOC 1 /* DATA relocatable*/
|
||||
#define BRELOC 3 /* BSS relocatable*/
|
||||
#define EXTVAR 4 /* ref to external variable*/
|
||||
#define LUPPER 5 /* upper word of long*/
|
||||
#define EXTREL 6 /* external relative mode*/
|
||||
|
||||
/* ptrs to ins[] and rlbits[]*/
|
||||
int *pins;
|
||||
int *prlb;
|
||||
int ins[5]; /*holds instruction words*/
|
||||
|
||||
#define PRTCHLEN 128
|
||||
char prtchars[PRTCHLEN]; /*line buffer for putchar*/
|
||||
char *prtchidx; /*index for putchar*/
|
||||
|
||||
int extflg, extref; /*external in expr*/
|
||||
|
||||
#define CCR 16
|
||||
#define SR 17
|
||||
#define USP 18
|
||||
#define MOVECCR 042300
|
||||
#define MOVESR 043300
|
||||
#define SRMOVE 040300
|
||||
#define MOVEUSP 047140
|
||||
|
||||
struct op {
|
||||
int ea; /* effective address bits*/
|
||||
int len; /* effective address length in bytes*/
|
||||
long con; /*constant or reloc part of operand*/
|
||||
int drlc; /*reloc of con*/
|
||||
int ext; /*external variable #*/
|
||||
int idx; /*index register if any*/
|
||||
int xmod; /*mode of index reg*/
|
||||
} opnd[2];
|
||||
#define OPSTLEN 10
|
||||
#define TREELEN 20
|
||||
struct buf{
|
||||
int fildes;
|
||||
int nunused;
|
||||
char *xfree;
|
||||
char buff[512];
|
||||
};
|
||||
|
||||
struct buf lbuf;
|
||||
struct buf tbuf;
|
||||
struct buf dabuf;
|
||||
struct buf drbuf;
|
||||
|
||||
int nerror; /*# of assembler errors*/
|
||||
int in_err; /*[vlh] don't generate instrlen err if already err state*/
|
||||
int shortadr; /*short addresses if set*/
|
||||
|
||||
#define CLRFOR 24
|
||||
#define CLRVAL 041000
|
||||
|
||||
long itoffset;
|
||||
|
||||
#define LASTCHTFN *tfilptr
|
||||
char *tfilptr; /* -> Changed filename character */
|
||||
#define PC 22
|
||||
|
||||
int equflg; /*doing an equate stmt*/
|
||||
|
||||
#define ANDI 01000
|
||||
#define AND 0140000
|
||||
#define ORI 0
|
||||
#define OR 0100000
|
||||
#define EORI 05000
|
||||
#define EOR 0130000
|
||||
#define MOVE 0
|
||||
|
||||
long lseek();
|
||||
char *sbrk();
|
||||
char *lemt();
|
||||
|
||||
int refpc; /* * referenced in expr*/
|
||||
#define SOH 1
|
||||
|
||||
/* Conditional Assembly variables and constants [vlh] */
|
||||
#define LOW_CA 21 /* [vlh] */
|
||||
#define HI_CA 30 /* [vlh] */
|
||||
|
||||
int ca_true; /* true unless in a false CA*/
|
||||
int ca; /* depth of conditional assembly, none = 0*/
|
||||
int ca_level; /* at what CA depth did CA go false?*/
|
||||
|
||||
/* pass 1 global variables */
|
||||
int numops; /*number of operands*/
|
||||
int inoffset; /*[vlh]offset directive*/
|
||||
int didorg;
|
||||
int initflg; /*initialize flag*/
|
||||
|
||||
/* defines */
|
||||
#define igblk() while(fchr==' ') fchr=gchr()
|
||||
#define ckein() ((pitw >= pnite))
|
||||
|
||||
/* is it an alterable operand */
|
||||
#define memalt(ap) (memea(ap) && altea(ap))
|
||||
#define dataalt(ap) (dataea(ap) && altea(ap))
|
||||
#define altea(ap) ((((ap)->ea&070)!=SADDR || ((ap)->ea&6)==0))
|
||||
|
||||
/* is it the specific type of operand */
|
||||
#define memea(ap) (((ap)->ea&070) >= INDIRECT)
|
||||
#define dataea(ap) (((ap)->ea&070) != ADIR)
|
||||
#define pcea(ap) ((ap)->ea==072 || (ap)->ea==073)
|
||||
#define ckdreg(ap) ((ap)->ea>=0 && (ap)->ea<AREGLO)
|
||||
#define ckareg(ap) ((ap)->ea>=AREGLO && (ap)->ea<=AREGHI)
|
||||
/*
|
||||
* DRI Listing Hacks:
|
||||
*/
|
||||
char *sfname; /* -> Source file name */
|
||||
#define LPP 58 /* # lines / page */
|
||||
int xline; /* Present line # */
|
||||
int xpage; /* Present Page # */
|
||||
415
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/as68/as68.lst
Normal file
415
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/as68/as68.lst
Normal file
@@ -0,0 +1,415 @@
|
||||
1File: AS68.H Page 1
|
||||
1 /*
|
||||
2 Copyright 1981
|
||||
3 Alcyon Corporation
|
||||
4 8716 Production Ave.
|
||||
5 San Diego, Ca. 92121
|
||||
6 */
|
||||
7 #include <stdio.h>
|
||||
8 #include <klib.h>
|
||||
9 #include "machine.h"
|
||||
10 #include "ctype.h"
|
||||
11
|
||||
12 #ifdef PDP11
|
||||
13 struct {
|
||||
14 char lobyte;
|
||||
15 char hibyte;
|
||||
16 };
|
||||
17 struct {
|
||||
18 char *ptrw1;
|
||||
19 char *ptrw2;
|
||||
20 };
|
||||
21 struct {
|
||||
22 int wd1;
|
||||
23 int wd2;
|
||||
24 };
|
||||
25 struct {
|
||||
26 int swd1;
|
||||
27 };
|
||||
28 #endif
|
||||
29
|
||||
30 #ifdef MC68000
|
||||
31 struct {
|
||||
32 char hibyte;
|
||||
33 char lobyte;
|
||||
34 };
|
||||
35 struct {
|
||||
36 char *ptrw2;
|
||||
37 };
|
||||
38 struct {
|
||||
39 int wd1;
|
||||
40 int wd2;
|
||||
41 };
|
||||
42 struct {
|
||||
43 int swd1;
|
||||
44 };
|
||||
45 #endif
|
||||
46
|
||||
47 #ifdef VAX
|
||||
48 struct {
|
||||
49 short wd2;
|
||||
50 short wd1;
|
||||
51 };
|
||||
52 struct {
|
||||
53 short swd1;
|
||||
54 };
|
||||
55
|
||||
56 struct {
|
||||
57 char lobyte;
|
||||
58 char hibyte;
|
||||
59 };
|
||||
1File: AS68.H Page 2
|
||||
60 struct {
|
||||
61 char *ptrw2;
|
||||
62 };
|
||||
63 #endif
|
||||
64
|
||||
65 /* format of a symbol entry in the main table*/
|
||||
66
|
||||
67 # define NAMELEN 8 /*length of name in symbol table*/
|
||||
68 struct symtab {
|
||||
69 char name[NAMELEN]; /*symbol name*/
|
||||
70 short flags; /*bit flags*/
|
||||
71 char *tlnk; /*table link*/
|
||||
72 long vl1; /*symbol value*/
|
||||
73 };
|
||||
74
|
||||
75 struct symtab *symtptr;
|
||||
76 # define STESIZE (sizeof *symtptr) /*byte length of symbol table entry*/
|
||||
77
|
||||
78 /* flags for symbols*/
|
||||
79 # define SYDF 0100000 /*defined*/
|
||||
80 # define SYEQ 0040000 /*equated*/
|
||||
81 # define SYGL 0020000 /*global - entry or external*/
|
||||
82 # define SYER 0010000 /*equated register*/
|
||||
83 # define SYXR 0004000 /*external reference*/
|
||||
84 # define SYRA 0002000 /*DATA based relocatable*/
|
||||
85 # define SYRO 0001000 /*TEXT based relocatable*/
|
||||
86 # define SYBS 0000400 /*BSS based relocatable*/
|
||||
87 # define SYIN 0000200 /*internal symbol -- opcode, directive or equ*/
|
||||
88 # define SYPC 0000100 /*[vlh]equated using star '*' expression*/
|
||||
89 # define SYRM 0000040 /*[vlh]register mask equate*/
|
||||
90
|
||||
91 /*flags for opcodes and directives*/
|
||||
92 # define OPDR 0100000 /*0=>opcode, 1=>directive*/
|
||||
93 # define OPFF 037 /*type of instruction (used as mask)*/
|
||||
94
|
||||
95 struct irts {
|
||||
96 char *irle; /*ptr to last entry in chain*/
|
||||
97 char *irfe; /*ptr to first entry in chain*/
|
||||
98 };
|
||||
99
|
||||
100 long stlen; /*length of symbol table*/
|
||||
101
|
||||
102 /*
|
||||
103 * intermediate text file
|
||||
104 * format of the intermediate text for one statement:
|
||||
105 *
|
||||
106 * ******************************************************
|
||||
107 * * it type = ITBS * # it entries * 0
|
||||
108 * ******************************************************
|
||||
109 * * absolute line number (long) *
|
||||
110 * ******************************************************
|
||||
111 * * it type = ITSY * instr length * 1
|
||||
112 * ******************************************************
|
||||
113 * * symbol table pointer for stmt label (long) *
|
||||
114 * ******************************************************
|
||||
115 * * it type = ITSY * instr mode length * 2
|
||||
116 * ******************************************************
|
||||
117 * * opcode ptr (long) *
|
||||
118 * ******************************************************
|
||||
1File: AS68.H Page 3
|
||||
119 * * it type = ITCN * relocation base * 3
|
||||
120 * ******************************************************
|
||||
121 * * location counter (pass 1) *
|
||||
122 * ******************************************************
|
||||
123 * * it type * relocation flag * 4 - oprnds
|
||||
124 * ******************************************************
|
||||
125 * * value (long) *
|
||||
126 * ******************************************************
|
||||
127 * .
|
||||
128 *
|
||||
129 * .
|
||||
130 * ******************************************************
|
||||
131 * * it type * relocation flag * n - oprnds
|
||||
132 * ******************************************************
|
||||
133 * * value (long) *
|
||||
134 * ******************************************************
|
||||
135 */
|
||||
136
|
||||
137 #define ITOP1 4 /*first it entry for operands*/
|
||||
138
|
||||
139 /*
|
||||
140 * it type meaning
|
||||
141 * 0 beginning of statement
|
||||
142 * 1 value is pointer to symbol table
|
||||
143 * 2 value is a constant
|
||||
144 * 3 value is a specal char
|
||||
145 *
|
||||
146 * relocation flag for opcode it entry is operand length:
|
||||
147 * 'b' => byte
|
||||
148 * 'w' => word
|
||||
149 * 'l' => long
|
||||
150 */
|
||||
151
|
||||
152 struct it {
|
||||
153 char itty; /*it type*/
|
||||
154 char itrl; /*relocation flag or # it entries*/
|
||||
155 long itop;
|
||||
156 };
|
||||
157
|
||||
158 int mode; /*operand mode (byte, word, long)*/
|
||||
159 int modelen; /*operand length per mode*/
|
||||
160 #define BYTE 'b'
|
||||
161 #define WORD 'w'
|
||||
162 #define LONG 'l'
|
||||
163
|
||||
164 /* parameters that define the main table*/
|
||||
165 #define SZMT 300 /*initial size of the main table */
|
||||
166 /*must be large enough to initialize*/
|
||||
167 #ifdef PDP11
|
||||
168 #define ICRSZMT 10 /*add to main table when run out*/
|
||||
169 #else
|
||||
170 #define ICRSZMT 50 /*add to main table when run out*/
|
||||
171 #endif
|
||||
172 int cszmt; /*current size of main table*/
|
||||
173 char *bmte; /*beginning of main table*/
|
||||
174 char *emte; /*end of main table*/
|
||||
175
|
||||
176 /* intermediate text types*/
|
||||
177 #define ITBS 0 /*beginning of statement*/
|
||||
1File: AS68.H Page 4
|
||||
178 #define ITSY 1 /*pointer to symbol table*/
|
||||
179 #define ITCN 2 /*constant*/
|
||||
180 #define ITSP 3 /*special*/
|
||||
181 #define ITRM 4 /*[vlh]register mask!*/
|
||||
182 #define ITPC 5 /*[vlh]pc relative argument*/
|
||||
183
|
||||
184 # define ITBSZ 256 /*size of the it buffer*/
|
||||
185 short itbuf[ITBSZ]; /*it buffer*/
|
||||
186
|
||||
187 #define STMAX 200 /*size of intermediate text buffer*/
|
||||
188 struct it stbuf[STMAX]; /*holds it for one statement*/
|
||||
189
|
||||
190 char sbuf[512]; /*holds one block of source*/
|
||||
191
|
||||
192 /*initial reference table for symbols*/
|
||||
193 # define SZIRT 128
|
||||
194 char *sirt[SZIRT];
|
||||
195
|
||||
196 /*initial reference table to opcodes*/
|
||||
197 char *oirt[SZIRT];
|
||||
198
|
||||
199 /*external symbol table*/
|
||||
200 #define EXTSZ 512
|
||||
201 char *extbl[EXTSZ];
|
||||
202 int extindx; /*index to external symbol table*/
|
||||
203 char **pexti; /*ptr to external symbol table*/
|
||||
204
|
||||
205 int absln; /*absolute line number*/
|
||||
206 int p2absln; /*pass 2 line number*/
|
||||
207 int fcflg; /*0=>passed an item. 1=>first char*/
|
||||
208 int fchr; /*first char in term*/
|
||||
209 int ifn; /*source file descriptor*/
|
||||
210 short *pitix; /*ptr to it buffer*/
|
||||
211 int itwc; /*number of words in it buffer*/
|
||||
212 struct it *pitw; /*ptr to it buffer next entry*/
|
||||
213 int itype; /*type of item*/
|
||||
214 long ival; /*value of item*/
|
||||
215 char *lblpt; /*label pointer*/
|
||||
216 char lbt[NAMELEN]; /*holds label name*/
|
||||
217 char *lmte; /*last entry in main table*/
|
||||
218 long loctr; /*location counter*/
|
||||
219 long savelc[4]; /*save relocation counters for 3 bases*/
|
||||
220 int nite; /*number of entries in stbuf*/
|
||||
221 struct it *pnite;
|
||||
222 int lfn; /*loader output file descriptor*/
|
||||
223 char *opcpt; /*pointer to opcode entry in main table*/
|
||||
224 int p2flg; /*0=>pass 1 1=>pass 2*/
|
||||
225 char **pirt; /*entry in initial reference table*/
|
||||
226 int reloc; /*relocation value returned by expression evaluator (expr)*/
|
||||
227 int rlflg; /*relocation value of current location counter*/
|
||||
228 /*relocation values*/
|
||||
229 # define ABS 0 /*absolute*/
|
||||
230 # define DATA 1
|
||||
231 # define TEXT 2
|
||||
232 # define BSS 3
|
||||
233 # define EXTRN 4 /*externally defined*/
|
||||
234
|
||||
235 #define EOLC '\n' /*end of line character*/
|
||||
236 #define EOF 0 /*end of file indicator*/
|
||||
1File: AS68.H Page 5
|
||||
237 #define NULL 0 /* [vlh] character null '\0' */
|
||||
238 #define TRUE 1 /* [vlh] boolean values */
|
||||
239 #define FALSE 0 /* [vlh] boolean values */
|
||||
240
|
||||
241 int format;
|
||||
242 int sbuflen; /*number of chars in sbuf*/
|
||||
243 char *psbuf; /*ptr into sbuf*/
|
||||
244 int itfn; /*it file number*/
|
||||
245 char itfnc; /*last char of it file name*/
|
||||
246 int trbfn; /*temp for text relocation bits*/
|
||||
247 char trbfnc; /*last char of text rb file*/
|
||||
248 int dafn; /*file for data stuff*/
|
||||
249 char dafnc; /*last char of data file*/
|
||||
250 int drbfn; /*file for data relocation bits*/
|
||||
251 char drbfnc; /*last char*/
|
||||
252 int prtflg; /*print output flag*/
|
||||
253 int undflg; /*make undefined symbols external flag*/
|
||||
254
|
||||
255 int starmul; /* * is multiply operator*/
|
||||
256
|
||||
257 char *endptr, *addptr;
|
||||
258 char *orgptr;
|
||||
259 char *subptr, *addiptr, *addqptr, *subiptr, *subqptr;
|
||||
260 char *cmpptr, *addaptr, *cmpaptr, *subaptr, *cmpmptr;
|
||||
261 char *equptr;
|
||||
262 char *andptr, *andiptr, *eorptr, *eoriptr, *orptr, *oriptr;
|
||||
263 char *cmpiptr;
|
||||
264 char *moveptr, *moveqptr;
|
||||
265 char *exgptr;
|
||||
266 char *evenptr;
|
||||
267 char *jsrptr, *bsrptr, *nopptr;
|
||||
268 char peekc;
|
||||
269 int numcon[2], numsym[2], indir[2], immed[2], numreg[2];
|
||||
270 int plevel; /*parenthesis level counter*/
|
||||
271 int opdix; /*operand index counter*/
|
||||
272 int p1inlen; /*pass 1 instr length*/
|
||||
273 int instrlen; /*pass 2 bytes in current instruction*/
|
||||
274
|
||||
275 /* effective address mode bits*/
|
||||
276 #define DDIR 000
|
||||
277 #define ADIR 010
|
||||
278 #define INDIRECT 020
|
||||
279 #define INDINC 030
|
||||
280 #define DECIND 040
|
||||
281 #define INDDISP 050
|
||||
282 #define INDINX 060
|
||||
283 #define SADDR 070
|
||||
284 #define LADDR 071
|
||||
285 #define IMM 074
|
||||
286
|
||||
287 #define AREGLO 8
|
||||
288 #define AREGHI 15
|
||||
289
|
||||
290 /* relocation bit definitions:*/
|
||||
291 #define RBMASK 07 /*tells type of relocation*/
|
||||
292 #define INSABS 7 /*first word of instr -- absolute*/
|
||||
293 #define DABS 0 /*data word absolute*/
|
||||
294 #define TRELOC 2 /* TEXT relocatable*/
|
||||
295 #define DRELOC 1 /* DATA relocatable*/
|
||||
1File: AS68.H Page 6
|
||||
296 #define BRELOC 3 /* BSS relocatable*/
|
||||
297 #define EXTVAR 4 /* ref to external variable*/
|
||||
298 #define LUPPER 5 /* upper word of long*/
|
||||
299 #define EXTREL 6 /* external relative mode*/
|
||||
300
|
||||
301 /* ptrs to ins[] and rlbits[]*/
|
||||
302 int *pins;
|
||||
303 int *prlb;
|
||||
304 int ins[5]; /*holds instruction words*/
|
||||
305
|
||||
306 #define PRTCHLEN 128
|
||||
307 char prtchars[PRTCHLEN]; /*line buffer for putchar*/
|
||||
308 char *prtchidx; /*index for putchar*/
|
||||
309
|
||||
310 int extflg, extref; /*external in expr*/
|
||||
311
|
||||
312 #define CCR 16
|
||||
313 #define SR 17
|
||||
314 #define USP 18
|
||||
315 #define MOVECCR 042300
|
||||
316 #define MOVESR 043300
|
||||
317 #define SRMOVE 040300
|
||||
318 #define MOVEUSP 047140
|
||||
319
|
||||
320 struct op {
|
||||
321 int ea; /* effective address bits*/
|
||||
322 int len; /* effective address length in bytes*/
|
||||
323 long con; /*constant or reloc part of operand*/
|
||||
324 int drlc; /*reloc of con*/
|
||||
325 int ext; /*external variable #*/
|
||||
326 int idx; /*index register if any*/
|
||||
327 int xmod; /*mode of index reg*/
|
||||
328 } opnd[2];
|
||||
329 #define OPSTLEN 10
|
||||
330 #define TREELEN 20
|
||||
331 struct buf{
|
||||
332 int fildes;
|
||||
333 int nunused;
|
||||
334 char *xfree;
|
||||
335 char buff[512];
|
||||
336 };
|
||||
337
|
||||
338 struct buf lbuf;
|
||||
339 struct buf tbuf;
|
||||
340 struct buf dabuf;
|
||||
341 struct buf drbuf;
|
||||
342
|
||||
343 int nerror; /*# of assembler errors*/
|
||||
344 int in_err; /*[vlh] don't generate instrlen err if already err state*/
|
||||
345 int shortadr; /*short addresses if set*/
|
||||
346
|
||||
347 #define CLRFOR 24
|
||||
348 #define CLRVAL 041000
|
||||
349
|
||||
350 long itoffset;
|
||||
351
|
||||
352 #define LASTCHTFN *tfilptr
|
||||
353 char *tfilptr; /* -> Changed filename character */
|
||||
354 #define PC 22
|
||||
1File: AS68.H Page 7
|
||||
355
|
||||
356 int equflg; /*doing an equate stmt*/
|
||||
357
|
||||
358 #define ANDI 01000
|
||||
359 #define AND 0140000
|
||||
360 #define ORI 0
|
||||
361 #define OR 0100000
|
||||
362 #define EORI 05000
|
||||
363 #define EOR 0130000
|
||||
364 #define MOVE 0
|
||||
365
|
||||
366 long lseek();
|
||||
367 char *sbrk();
|
||||
368 char *lemt();
|
||||
369
|
||||
370 int refpc; /* * referenced in expr*/
|
||||
371 #define SOH 1
|
||||
372
|
||||
373 /* Conditional Assembly variables and constants [vlh] */
|
||||
374 #define LOW_CA 21 /* [vlh] */
|
||||
375 #define HI_CA 30 /* [vlh] */
|
||||
376
|
||||
377 int ca_true; /* true unless in a false CA*/
|
||||
378 int ca; /* depth of conditional assembly, none = 0*/
|
||||
379 int ca_level; /* at what CA depth did CA go false?*/
|
||||
380
|
||||
381 /* pass 1 global variables */
|
||||
382 int numops; /*number of operands*/
|
||||
383 int inoffset; /*[vlh]offset directive*/
|
||||
384 int didorg;
|
||||
385 int initflg; /*initialize flag*/
|
||||
386
|
||||
387 /* defines */
|
||||
388 #define igblk() while(fchr==' ') fchr=gchr()
|
||||
389 #define ckein() ((pitw >= pnite))
|
||||
390
|
||||
391 /* is it an alterable operand */
|
||||
392 #define memalt(ap) (memea(ap) && altea(ap))
|
||||
393 #define dataalt(ap) (dataea(ap) && altea(ap))
|
||||
394 #define altea(ap) ((((ap)->ea&070)!=SADDR || ((ap)->ea&6)==0))
|
||||
395
|
||||
396 /* is it the specific type of operand */
|
||||
397 #define memea(ap) (((ap)->ea&070) >= INDIRECT)
|
||||
398 #define dataea(ap) (((ap)->ea&070) != ADIR)
|
||||
399 #define pcea(ap) ((ap)->ea==072 || (ap)->ea==073)
|
||||
400 #define ckdreg(ap) ((ap)->ea>=0 && (ap)->ea<AREGLO)
|
||||
401 #define ckareg(ap) ((ap)->ea>=AREGLO && (ap)->ea<=AREGHI)
|
||||
402 /*
|
||||
403 * DRI Listing Hacks:
|
||||
404 */
|
||||
405 char *sfname; /* -> Source file name */
|
||||
406 #define LPP 58 /* # lines / page */
|
||||
407 int xline; /* Present line # */
|
||||
408 int xpage; /* Present Page # */
|
||||
222
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/as68/as68init
Normal file
222
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/as68/as68init
Normal file
@@ -0,0 +1,222 @@
|
||||
*/*
|
||||
* Copyright 1981
|
||||
* Alcyon Corporation
|
||||
* 8716 Production Ave.
|
||||
* San Diego, Ca. 92121
|
||||
**/
|
||||
R0: .equ 0,r
|
||||
R1: .equ 1,r
|
||||
R2: .equ 2,r
|
||||
R3: .equ 3,r
|
||||
R4: .equ 4,r
|
||||
R5: .equ 5,r
|
||||
R6: .equ 6,r
|
||||
R7: .equ 7,r
|
||||
R8: .equ 8,r
|
||||
R9: .equ 9,r
|
||||
R10: .equ 10,r
|
||||
R11: .equ 11,r
|
||||
R12: .equ 12,r
|
||||
R13: .equ 13,r
|
||||
R14: .equ 14,r
|
||||
R15: .equ 15,r
|
||||
D0: .equ 0,r
|
||||
D1: .equ 1,r
|
||||
D2: .equ 2,r
|
||||
D3: .equ 3,r
|
||||
D4: .equ 4,r
|
||||
D5: .equ 5,r
|
||||
D6: .equ 6,r
|
||||
D7: .equ 7,r
|
||||
A0: .equ @10,r
|
||||
A1: .equ @11,r
|
||||
A2: .equ @12,r
|
||||
A3: .equ @13,r
|
||||
A4: .equ @14,r
|
||||
A5: .equ @15,r
|
||||
A6: .equ @16,r
|
||||
A7: .equ @17,r
|
||||
USP: .equ 18,r
|
||||
SP: .equ 15,r
|
||||
CCR: .equ 16,r
|
||||
SR: .equ 17,r
|
||||
r0: .equ 0,r
|
||||
r1: .equ 1,r
|
||||
r2: .equ 2,r
|
||||
r3: .equ 3,r
|
||||
r4: .equ 4,r
|
||||
r5: .equ 5,r
|
||||
r6: .equ 6,r
|
||||
r7: .equ 7,r
|
||||
r8: .equ 8,r
|
||||
r9: .equ 9,r
|
||||
r10: .equ 10,r
|
||||
r11: .equ 11,r
|
||||
r12: .equ 12,r
|
||||
r13: .equ 13,r
|
||||
r14: .equ 14,r
|
||||
r15: .equ 15,r
|
||||
d0: .equ 0,r
|
||||
d1: .equ 1,r
|
||||
d2: .equ 2,r
|
||||
d3: .equ 3,r
|
||||
d4: .equ 4,r
|
||||
d5: .equ 5,r
|
||||
d6: .equ 6,r
|
||||
d7: .equ 7,r
|
||||
a0: .equ @10,r
|
||||
a1: .equ @11,r
|
||||
a2: .equ @12,r
|
||||
a3: .equ @13,r
|
||||
a4: .equ @14,r
|
||||
a5: .equ @15,r
|
||||
a6: .equ @16,r
|
||||
a7: .equ @17,r
|
||||
usp: .equ 18,r
|
||||
sp: .equ 15,r
|
||||
ccr: .equ 16,r
|
||||
sr: .equ 17,r
|
||||
.b: .equ 19,r
|
||||
.B: .equ 19,r
|
||||
.w: .equ 20,r
|
||||
.W: .equ 20,r
|
||||
.l: .equ 21,r
|
||||
.L: .equ 21,r
|
||||
pc: .equ 22,r
|
||||
PC: .equ 22,r
|
||||
abcd: .opd 4,@140400
|
||||
add: .opd 1,@150000
|
||||
adda: .opd 15,@150000
|
||||
addi: .opd 2,@003000
|
||||
addq: .opd 17,@050000
|
||||
inc: .opd 16,@050000
|
||||
addx: .opd 27,@150400
|
||||
and: .opd 1,@140000
|
||||
andi: .opd 2,@001000
|
||||
asl: .opd 8,@160400
|
||||
asr: .opd 8,@160000
|
||||
bcc: .opd 6,@062000
|
||||
bcs: .opd 6,@062400
|
||||
beq: .opd 6,@063400
|
||||
bze: .opd 6,@063400
|
||||
bge: .opd 6,@066000
|
||||
bgt: .opd 6,@067000
|
||||
bhi: .opd 6,@061000
|
||||
bhis: .opd 6,@062000
|
||||
bhs: .opd 6,@062000
|
||||
ble: .opd 6,@067400
|
||||
blo: .opd 6,@062400
|
||||
bls: .opd 6,@061400
|
||||
blos: .opd 6,@061400
|
||||
blt: .opd 6,@066400
|
||||
bmi: .opd 6,@065400
|
||||
bne: .opd 6,@063000
|
||||
bnz: .opd 6,@063000
|
||||
bpl: .opd 6,@065000
|
||||
bvc: .opd 6,@064000
|
||||
bvs: .opd 6,@064400
|
||||
bchg: .opd 7,@000100
|
||||
bclr: .opd 7,@000200
|
||||
bra: .opd 6,@060000
|
||||
bt: .opd 6,@060000
|
||||
bset: .opd 7,@000300
|
||||
bsr: .opd 6,@060400
|
||||
btst: .opd 7,@000000
|
||||
chk: .opd 26,@040600
|
||||
clr: .opd 24,@041000
|
||||
cmp: .opd 26,@130000
|
||||
cmpa: .opd 15,@130000
|
||||
cmpi: .opd 2,@006000
|
||||
cmpm: .opd 10,@130410
|
||||
dbcc: .opd 11,@052310
|
||||
dbcs: .opd 11,@052710
|
||||
dblo: .opd 11,@052710
|
||||
dbeq: .opd 11,@053710
|
||||
dbze: .opd 11,@053710
|
||||
dbra: .opd 11,@050710
|
||||
dbf: .opd 11,@050710
|
||||
dbge: .opd 11,@056310
|
||||
dbgt: .opd 11,@057310
|
||||
dbhi: .opd 11,@051310
|
||||
dbhs: .opd 11,@051310
|
||||
dble: .opd 11,@057710
|
||||
dbls: .opd 11,@051710
|
||||
dblt: .opd 11,@056710
|
||||
dbmi: .opd 11,@055710
|
||||
dbne: .opd 11,@053310
|
||||
dbnz: .opd 11,@053310
|
||||
dbpl: .opd 11,@055310
|
||||
dbt: .opd 11,@050310
|
||||
dbvc: .opd 11,@054310
|
||||
dbvs: .opd 11,@054710
|
||||
divs: .opd 5,@100700
|
||||
divu: .opd 5,@100300
|
||||
eor: .opd 23,@130000
|
||||
eori: .opd 2,@005000
|
||||
exg: .opd 12,@140400
|
||||
ext: .opd 13,@044000
|
||||
jmp: .opd 9,@047300
|
||||
jsr: .opd 9,@047200
|
||||
illegal:.opd 0,@045374
|
||||
lea: .opd 30,@040700
|
||||
link: .opd 19,@047120
|
||||
lsr: .opd 8,@160010
|
||||
lsl: .opd 8,@160410
|
||||
move: .opd 3,@000000
|
||||
movea: .opd 3,@000100
|
||||
movem: .opd 20,@044200
|
||||
movep: .opd 21,@000010
|
||||
moveq: .opd 22,@070000
|
||||
muls: .opd 5,@140700
|
||||
mulu: .opd 5,@140300
|
||||
nbcd: .opd 25,@044000
|
||||
neg: .opd 24,@042000
|
||||
negx: .opd 24,@040000
|
||||
nop: .opd 0,@047161
|
||||
not: .opd 24,@043000
|
||||
or: .opd 1,@100000
|
||||
ori: .opd 2,@000000
|
||||
pea: .opd 29,@044100
|
||||
reset: .opd 0,@047160
|
||||
rol: .opd 8,@160430
|
||||
ror: .opd 8,@160030
|
||||
roxl: .opd 8,@160420
|
||||
roxr: .opd 8,@160020
|
||||
rte: .opd 0,@047163
|
||||
rtr: .opd 0,@047167
|
||||
rts: .opd 0,@047165
|
||||
sbcd: .opd 4,@100400
|
||||
scc: .opd 25,@052300
|
||||
shs: .opd 25,@052300
|
||||
scs: .opd 25,@052700
|
||||
slo: .opd 25,@052700
|
||||
seq: .opd 25,@053700
|
||||
sze: .opd 25,@053700
|
||||
sf: .opd 25,@050700
|
||||
sge: .opd 25,@056300
|
||||
sgt: .opd 25,@057300
|
||||
shi: .opd 25,@051300
|
||||
sle: .opd 25,@057700
|
||||
sls: .opd 25,@051700
|
||||
slt: .opd 25,@056700
|
||||
smi: .opd 25,@055700
|
||||
sne: .opd 25,@053300
|
||||
snz: .opd 25,@053300
|
||||
spl: .opd 25,@055300
|
||||
st: .opd 25,@050300
|
||||
svc: .opd 25,@054300
|
||||
svs: .opd 25,@054700
|
||||
stop: .opd 14,@047162
|
||||
sub: .opd 1,@110000
|
||||
suba: .opd 15,@110000
|
||||
subi: .opd 2,@002000
|
||||
subq: .opd 17,@050400
|
||||
dec: .opd 16,@050400
|
||||
subx: .opd 27,@110400
|
||||
swap: .opd 28,@044100
|
||||
tas: .opd 25,@045300
|
||||
trap: .opd 18,@047100
|
||||
trapv: .opd 0,@047166
|
||||
tst: .opd 24,@045000
|
||||
unlk: .opd 13,@047130
|
||||
.end
|
||||
454
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/as68/as68init.c
Normal file
454
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/as68/as68init.c
Normal file
@@ -0,0 +1,454 @@
|
||||
/*
|
||||
Copyright 1981
|
||||
Alcyon Corporation
|
||||
8716 Production Ave.
|
||||
San Diego, Ca. 92121
|
||||
*/
|
||||
|
||||
#include "machine.h"
|
||||
#include "ctype.h"
|
||||
|
||||
#ifdef PDP11
|
||||
struct {
|
||||
char lobyte;
|
||||
char hibyte;
|
||||
};
|
||||
struct {
|
||||
char *ptrw1;
|
||||
char *ptrw2;
|
||||
};
|
||||
struct {
|
||||
int wd1;
|
||||
int wd2;
|
||||
};
|
||||
struct {
|
||||
int swd1;
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef MC68000
|
||||
struct {
|
||||
char hibyte;
|
||||
char lobyte;
|
||||
};
|
||||
struct {
|
||||
char *ptrw2;
|
||||
};
|
||||
struct {
|
||||
int wd1;
|
||||
int wd2;
|
||||
};
|
||||
struct {
|
||||
int swd1;
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef VAX
|
||||
struct {
|
||||
short wd2;
|
||||
short wd1;
|
||||
};
|
||||
struct {
|
||||
short swd1;
|
||||
};
|
||||
|
||||
struct {
|
||||
char lobyte;
|
||||
char hibyte;
|
||||
};
|
||||
struct {
|
||||
char *ptrw2;
|
||||
};
|
||||
#endif
|
||||
|
||||
/* format of a symbol entry in the main table*/
|
||||
|
||||
# define NAMELEN 8 /*length of name in symbol table*/
|
||||
struct symtab {
|
||||
char name[NAMELEN]; /*symbol name*/
|
||||
int flags; /*bit flags*/
|
||||
char *tlnk; /*table link*/
|
||||
long vl1; /*symbol value*/
|
||||
};
|
||||
|
||||
struct symtab *symtptr;
|
||||
# define STESIZE (sizeof *symtptr) /*byte length of symbol table entry*/
|
||||
|
||||
/* 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 SYRA 0002000 /*DATA based relocatable*/
|
||||
# define SYRO 0001000 /*TEXT based relocatable*/
|
||||
# define SYBS 0000400 /*BSS based relocatable*/
|
||||
# define SYIN 0000200 /*internal symbol -- opcode, directive or equ*/
|
||||
# define SYPC 0000100 /*[vlh]equated using star '*' expression*/
|
||||
# define SYRM 0000040 /*[vlh]register mask equate*/
|
||||
|
||||
/*flags for opcodes and directives*/
|
||||
# define OPDR 0100000 /*0=>opcode, 1=>directive*/
|
||||
# define OPFF 037 /*type of instruction (used as mask)*/
|
||||
|
||||
struct irts {
|
||||
char *irle; /*ptr to last entry in chain*/
|
||||
char *irfe; /*ptr to first entry in chain*/
|
||||
};
|
||||
|
||||
long stlen; /*length of symbol table*/
|
||||
|
||||
/*
|
||||
* intermediate text file
|
||||
* format of the intermediate text for one statement:
|
||||
*
|
||||
* ******************************************************
|
||||
* * it type = ITBS * # it entries * 0
|
||||
* ******************************************************
|
||||
* * absolute line number (long) *
|
||||
* ******************************************************
|
||||
* * it type = ITSY * instr length * 1
|
||||
* ******************************************************
|
||||
* * symbol table pointer for stmt label (long) *
|
||||
* ******************************************************
|
||||
* * it type = ITSY * instr mode length * 2
|
||||
* ******************************************************
|
||||
* * opcode ptr (long) *
|
||||
* ******************************************************
|
||||
* * it type = ITCN * relocation base * 3
|
||||
* ******************************************************
|
||||
* * location counter (pass 1) *
|
||||
* ******************************************************
|
||||
* * it type * relocation flag * 4 - oprnds
|
||||
* ******************************************************
|
||||
* * value (long) *
|
||||
* ******************************************************
|
||||
* .
|
||||
* .
|
||||
* .
|
||||
* ******************************************************
|
||||
* * it type * relocation flag * n - oprnds
|
||||
* ******************************************************
|
||||
* * value (long) *
|
||||
* ******************************************************
|
||||
*/
|
||||
|
||||
#define ITOP1 4 /*first it entry for operands*/
|
||||
|
||||
/*
|
||||
* it type meaning
|
||||
* 0 beginning of statement
|
||||
* 1 value is pointer to symbol table
|
||||
* 2 value is a constant
|
||||
* 3 value is a specal char
|
||||
*
|
||||
* relocation flag for opcode it entry is operand length:
|
||||
* 'b' => byte
|
||||
* 'w' => word
|
||||
* 'l' => long
|
||||
*/
|
||||
|
||||
struct it {
|
||||
char itty; /*it type*/
|
||||
char itrl; /*relocation flag or # it entries*/
|
||||
long itop;
|
||||
};
|
||||
|
||||
int mode=0; /*operand mode (byte, word, long)*/
|
||||
int modelen=0; /*operand length per mode*/
|
||||
#define BYTE 'b'
|
||||
#define WORD 'w'
|
||||
#define LONG 'l'
|
||||
|
||||
/* parameters that define the main table*/
|
||||
#define SZMT 300 /*initial size of the main table */
|
||||
/*must be large enough to initialize*/
|
||||
#ifdef PDP11
|
||||
#define ICRSZMT 10 /*add to main table when run out*/
|
||||
#else
|
||||
#define ICRSZMT 50 /*add to main table when run out*/
|
||||
#endif
|
||||
int cszmt=0; /*current size of main table*/
|
||||
char *bmte=0; /*beginning of main table*/
|
||||
char *emte=0; /*end of main table*/
|
||||
|
||||
/* intermediate text types*/
|
||||
#define ITBS 0 /*beginning of statement*/
|
||||
#define ITSY 1 /*pointer to symbol table*/
|
||||
#define ITCN 2 /*constant*/
|
||||
#define ITSP 3 /*special*/
|
||||
#define ITRM 4 /*[vlh]register mask!*/
|
||||
#define ITPC 5 /*[vlh]pc relative argument*/
|
||||
|
||||
# define ITBSZ 256 /*size of the it buffer*/
|
||||
int itbuf[ITBSZ]={0}; /*it buffer*/
|
||||
|
||||
#define STMAX 200 /*size of intermediate text buffer*/
|
||||
struct it stbuf[STMAX]={0}; /*holds it for one statement*/
|
||||
|
||||
char sbuf[512]={0}; /*holds one block of source*/
|
||||
|
||||
/*initial reference table for symbols*/
|
||||
# define SZIRT 128
|
||||
char *sirt[SZIRT]={0};
|
||||
|
||||
/*initial reference table to opcodes*/
|
||||
char *oirt[SZIRT]={0};
|
||||
|
||||
/*external symbol table*/
|
||||
#define EXTSZ 512
|
||||
char *extbl[EXTSZ]={0};
|
||||
int extindx=0; /*index to external symbol table*/
|
||||
char **pexti=0; /*ptr to external symbol table*/
|
||||
|
||||
int absln=0; /*absolute line number*/
|
||||
int p2absln=0; /*pass 2 line number*/
|
||||
int fcflg=0; /*0=>passed an item. 1=>first char*/
|
||||
int fchr=0; /*first char in term*/
|
||||
int ifn=0; /*source file descriptor*/
|
||||
int *pitix=0; /*ptr to it buffer*/
|
||||
int itwc=0; /*number of words in it buffer*/
|
||||
struct it *pitw=0; /*ptr to it buffer next entry*/
|
||||
int itype=0; /*type of item*/
|
||||
long ival=0; /*value of item*/
|
||||
char *lblpt=0; /*label pointer*/
|
||||
char lbt[NAMELEN]={0}; /*holds label name*/
|
||||
char *lmte=0; /*last entry in main table*/
|
||||
long loctr=0; /*location counter*/
|
||||
long savelc[4]={0}; /*save relocation counters for 3 bases*/
|
||||
int nite=0; /*number of entries in stbuf*/
|
||||
struct it *pnite=0;
|
||||
int lfn=0; /*loader output file descriptor*/
|
||||
char *opcpt=0; /*pointer to opcode entry in main table*/
|
||||
int p2flg=0; /*0=>pass 1 1=>pass 2*/
|
||||
char **pirt=0; /*entry in initial reference table*/
|
||||
int reloc=0; /*relocation value returned by expression evaluator (expr)*/
|
||||
int rlflg=0; /*relocation value of current location counter*/
|
||||
/*relocation values*/
|
||||
# define ABS 0 /*absolute*/
|
||||
# define DATA 1
|
||||
# define TEXT 2
|
||||
# define BSS 3
|
||||
# define EXTRN 4 /*externally defined*/
|
||||
|
||||
#define EOLC '\n' /*end of line character*/
|
||||
#define EOF 0 /*end of file indicator*/
|
||||
#define NULL 0 /* [vlh] character null '\0' */
|
||||
#define TRUE 1 /* [vlh] boolean values */
|
||||
#define FALSE 0 /* [vlh] boolean values */
|
||||
|
||||
int format=0;
|
||||
int sbuflen=0; /*number of chars in sbuf*/
|
||||
char *psbuf=0; /*ptr into sbuf*/
|
||||
int itfn=0; /*it file number*/
|
||||
char itfnc=0; /*last char of it file name*/
|
||||
int trbfn=0; /*temp for text relocation bits*/
|
||||
char trbfnc=0; /*last char of text rb file*/
|
||||
int dafn=0; /*file for data stuff*/
|
||||
char dafnc=0; /*last char of data file*/
|
||||
int drbfn=0; /*file for data relocation bits*/
|
||||
char drbfnc=0; /*last char*/
|
||||
int prtflg=0; /*print output flag*/
|
||||
int undflg=0; /*make undefined symbols external flag*/
|
||||
|
||||
int starmul=0; /* * is multiply operator*/
|
||||
|
||||
char *endptr=0, *addptr=0;
|
||||
char *orgptr=0;
|
||||
char *subptr=0, *addiptr=0, *addqptr=0, *subiptr=0, *subqptr=0;
|
||||
char *cmpptr=0, *addaptr=0, *cmpaptr=0, *subaptr=0, *cmpmptr=0;
|
||||
char *equptr=0;
|
||||
char *andptr=0, *andiptr=0, *eorptr=0, *eoriptr=0, *orptr=0, *oriptr=0;
|
||||
char *cmpiptr=0;
|
||||
char *moveptr=0, *moveqptr=0;
|
||||
char *exgptr=0;
|
||||
char *evenptr=0;
|
||||
char *jsrptr=0, *bsrptr=0, *nopptr=0;
|
||||
|
||||
char peekc=0;
|
||||
int numcon[2]=0, numsym[2]=0, indir[2]=0, immed[2]=0, numreg[2]=0;
|
||||
int plevel=0; /*parenthesis level counter*/
|
||||
int opdix=0; /*operand index counter*/
|
||||
int p1inlen=0; /*pass 1 instr length*/
|
||||
int instrlen=0; /*pass 2 bytes in current instruction*/
|
||||
|
||||
/* effective address mode bits*/
|
||||
#define DDIR 000
|
||||
#define ADIR 010
|
||||
#define INDIRECT 020
|
||||
#define INDINC 030
|
||||
#define DECIND 040
|
||||
#define INDDISP 050
|
||||
#define INDINX 060
|
||||
#define SADDR 070
|
||||
#define LADDR 071
|
||||
#define IMM 074
|
||||
|
||||
#define AREGLO 8
|
||||
#define AREGHI 15
|
||||
|
||||
/* relocation bit definitions:*/
|
||||
#define RBMASK 07 /*tells type of relocation*/
|
||||
#define INSABS 7 /*first word of instr -- absolute*/
|
||||
#define DABS 0 /*data word absolute*/
|
||||
#define TRELOC 2 /* TEXT relocatable*/
|
||||
#define DRELOC 1 /* DATA relocatable*/
|
||||
#define BRELOC 3 /* BSS relocatable*/
|
||||
#define EXTVAR 4 /* ref to external variable*/
|
||||
#define LUPPER 5 /* upper word of long*/
|
||||
#define EXTREL 6 /* external relative mode*/
|
||||
|
||||
/* ptrs to ins[] and rlbits[]*/
|
||||
int *pins=0;
|
||||
int *prlb=0;
|
||||
int ins[5]={0}; /*holds instruction words*/
|
||||
|
||||
#define PRTCHLEN 128
|
||||
char prtchars[PRTCHLEN]={0}; /*line buffer for putchar*/
|
||||
char *prtchidx=0; /*index for putchar*/
|
||||
|
||||
int extflg=0, extref=0; /*external in expr*/
|
||||
|
||||
#define CCR 16
|
||||
#define SR 17
|
||||
#define USP 18
|
||||
#define MOVECCR 042300
|
||||
#define MOVESR 043300
|
||||
#define SRMOVE 040300
|
||||
#define MOVEUSP 047140
|
||||
|
||||
struct op {
|
||||
int ea; /* effective address bits*/
|
||||
int len; /* effective address length in bytes*/
|
||||
long con; /*constant or reloc part of operand*/
|
||||
int drlc; /*reloc of con*/
|
||||
int ext; /*external variable #*/
|
||||
int idx; /*index register if any*/
|
||||
int xmod; /*mode of index reg*/
|
||||
} opnd[2]={0};
|
||||
#define OPSTLEN 10
|
||||
#define TREELEN 20
|
||||
struct buf{
|
||||
int fildes;
|
||||
int nunused;
|
||||
char *xfree;
|
||||
char buff[512];
|
||||
};
|
||||
|
||||
struct buf lbuf={0};
|
||||
struct buf tbuf={0};
|
||||
struct buf dabuf={0};
|
||||
struct buf drbuf={0};
|
||||
|
||||
int nerror=0; /*# of assembler errors*/
|
||||
int in_err=0; /*[vlh] don't generate instrlen err if already err state*/
|
||||
int shortadr=0; /*short addresses if set*/
|
||||
|
||||
#define CLRFOR 24
|
||||
#define CLRVAL 041000
|
||||
|
||||
long itoffset=0;
|
||||
|
||||
#define LASTCHTFN tfilname[11]
|
||||
#define PC 22
|
||||
|
||||
int equflg=0; /*doing an equate stmt*/
|
||||
|
||||
#define ANDI 01000
|
||||
#define AND 0140000
|
||||
#define ORI 0
|
||||
#define OR 0100000
|
||||
#define EORI 05000
|
||||
#define EOR 0130000
|
||||
#define MOVE 0
|
||||
|
||||
long lseek();
|
||||
char *sbrk();
|
||||
char *lemt();
|
||||
|
||||
int refpc=0; /* * referenced in expr*/
|
||||
#define SOH 1
|
||||
|
||||
/* Conditional Assembly variables and constants [vlh] */
|
||||
#define LOW_CA 21 /* [vlh] */
|
||||
#define HI_CA 30 /* [vlh] */
|
||||
|
||||
int ca_true=0; /* true unless in a false CA*/
|
||||
int ca=0; /* depth of conditional assembly, none = 0*/
|
||||
int ca_level=0; /* at what CA depth did CA go false?*/
|
||||
|
||||
/* pass 1 global variables */
|
||||
int numops=0; /*number of operands*/
|
||||
int inoffset=0; /*[vlh]offset directive*/
|
||||
int didorg=0;
|
||||
int initflg=0; /*initialize flag*/
|
||||
|
||||
/* defines */
|
||||
#define igblk() while(fchr==' ') fchr=gchr()
|
||||
#define ckein() ((pitw >= pnite))
|
||||
|
||||
/* is it an alterable operand */
|
||||
#define memalt(ap) (memea(ap) && altea(ap))
|
||||
#define dataalt(ap) (dataea(ap) && altea(ap))
|
||||
#define altea(ap) ((((ap)->ea&070)!=SADDR || ((ap)->ea&6)==0))
|
||||
|
||||
/* is it the specific type of operand */
|
||||
#define memea(ap) (((ap)->ea&070) >= INDIRECT)
|
||||
#define dataea(ap) (((ap)->ea&070) != ADIR)
|
||||
#define pcea(ap) ((ap)->ea==072 || (ap)->ea==073)
|
||||
#define ckdreg(ap) ((ap)->ea>=0 && (ap)->ea<AREGLO)
|
||||
#define ckareg(ap) ((ap)->ea>=AREGLO && (ap)->ea<=AREGHI)
|
||||
/*
|
||||
* DRI Listing Hacks:
|
||||
*/
|
||||
char *sfname=0; /* -> Source filename */
|
||||
int xline=0; /* Current line number */
|
||||
int xpage=0; /* Current page number */
|
||||
/*
|
||||
* More Initializations:
|
||||
*/
|
||||
char *tfilname[80] = {0}; /* Temp filename area */
|
||||
char *initfnam[80] = {0}; /* Init filename area */
|
||||
struct it exitm={0};
|
||||
int prcnt=0;
|
||||
int rval=0;
|
||||
int lpflg=0;
|
||||
int lastopr=0;
|
||||
int rlbits[5]={0};
|
||||
int pline=0;
|
||||
int prsp=0;
|
||||
int amode=0;
|
||||
long stlen=0;
|
||||
int udfct=0;
|
||||
int errno=0;
|
||||
int nitleft=0;
|
||||
int hibytflg[4]={0};
|
||||
int hibytw[4]={0};
|
||||
struct it *piop=0;
|
||||
struct it *pitr=0;
|
||||
struct it opstk[OPSTLEN]={0};
|
||||
struct it tree[TREELEN]={0};
|
||||
int chmvq=0;
|
||||
int explmod=0;
|
||||
int ftudp=0;
|
||||
int iop=0;
|
||||
int itr=0;
|
||||
char ldfn[40]={0};
|
||||
int opcval=0;
|
||||
int poslab=0;
|
||||
int symcon=0;
|
||||
char *tfilptr=0;
|
||||
int tlab1=0;
|
||||
#define HDSIZE (sizeof couthd) /**.o file header size*/
|
||||
struct hdr {
|
||||
short ch_magic; /*c.out magic number 060016 = $600E*/
|
||||
long ch_tsize; /*text size*/
|
||||
long ch_dsize; /*data size*/
|
||||
long ch_bsize; /*bss size*/
|
||||
long ch_ssize; /*symbol table size*/
|
||||
long ch_stksize; /*stack size*/
|
||||
long ch_entry; /*entry point*/
|
||||
short ch_rlbflg; /*relocation bits suppressed flag*/
|
||||
} couthd={0};
|
||||
|
||||
#define MAGIC 0x601a /* bra .+26 instruction*/
|
||||
@@ -0,0 +1,462 @@
|
||||
1File: AS68INIT.C Page 1
|
||||
1 /*
|
||||
2 Copyright 1981
|
||||
3 Alcyon Corporation
|
||||
4 8716 Production Ave.
|
||||
5 San Diego, Ca. 92121
|
||||
6 */
|
||||
7
|
||||
8 #include "machine.h"
|
||||
9 #include "ctype.h"
|
||||
10
|
||||
11 #ifdef PDP11
|
||||
12 struct {
|
||||
13 char lobyte;
|
||||
14 char hibyte;
|
||||
15 };
|
||||
16 struct {
|
||||
17 char *ptrw1;
|
||||
18 char *ptrw2;
|
||||
19 };
|
||||
20 struct {
|
||||
21 int wd1;
|
||||
22 int wd2;
|
||||
23 };
|
||||
24 struct {
|
||||
25 int swd1;
|
||||
26 };
|
||||
27 #endif
|
||||
28
|
||||
29 #ifdef MC68000
|
||||
30 struct {
|
||||
31 char hibyte;
|
||||
32 char lobyte;
|
||||
33 };
|
||||
34 struct {
|
||||
35 char *ptrw2;
|
||||
36 };
|
||||
37 struct {
|
||||
38 int wd1;
|
||||
39 int wd2;
|
||||
40 };
|
||||
41 struct {
|
||||
42 int swd1;
|
||||
43 };
|
||||
44 #endif
|
||||
45
|
||||
46 #ifdef VAX
|
||||
47 struct {
|
||||
48 short wd2;
|
||||
49 short wd1;
|
||||
50 };
|
||||
51 struct {
|
||||
52 short swd1;
|
||||
53 };
|
||||
54
|
||||
55 struct {
|
||||
56 char lobyte;
|
||||
57 char hibyte;
|
||||
58 };
|
||||
59 struct {
|
||||
1File: AS68INIT.C Page 2
|
||||
60 char *ptrw2;
|
||||
61 };
|
||||
62 #endif
|
||||
63
|
||||
64 /* format of a symbol entry in the main table*/
|
||||
65
|
||||
66 # define NAMELEN 8 /*length of name in symbol table*/
|
||||
67 struct symtab {
|
||||
68 char name[NAMELEN]; /*symbol name*/
|
||||
69 int flags; /*bit flags*/
|
||||
70 char *tlnk; /*table link*/
|
||||
71 long vl1; /*symbol value*/
|
||||
72 };
|
||||
73
|
||||
74 struct symtab *symtptr;
|
||||
75 # define STESIZE (sizeof *symtptr) /*byte length of symbol table entry*/
|
||||
76
|
||||
77 /* flags for symbols*/
|
||||
78 # define SYDF 0100000 /*defined*/
|
||||
79 # define SYEQ 0040000 /*equated*/
|
||||
80 # define SYGL 0020000 /*global - entry or external*/
|
||||
81 # define SYER 0010000 /*equated register*/
|
||||
82 # define SYXR 0004000 /*external reference*/
|
||||
83 # define SYRA 0002000 /*DATA based relocatable*/
|
||||
84 # define SYRO 0001000 /*TEXT based relocatable*/
|
||||
85 # define SYBS 0000400 /*BSS based relocatable*/
|
||||
86 # define SYIN 0000200 /*internal symbol -- opcode, directive or equ*/
|
||||
87 # define SYPC 0000100 /*[vlh]equated using star '*' expression*/
|
||||
88 # define SYRM 0000040 /*[vlh]register mask equate*/
|
||||
89
|
||||
90 /*flags for opcodes and directives*/
|
||||
91 # define OPDR 0100000 /*0=>opcode, 1=>directive*/
|
||||
92 # define OPFF 037 /*type of instruction (used as mask)*/
|
||||
93
|
||||
94 struct irts {
|
||||
95 char *irle; /*ptr to last entry in chain*/
|
||||
96 char *irfe; /*ptr to first entry in chain*/
|
||||
97 };
|
||||
98
|
||||
99 long stlen; /*length of symbol table*/
|
||||
100
|
||||
101 /*
|
||||
102 * intermediate text file
|
||||
103 * format of the intermediate text for one statement:
|
||||
104 *
|
||||
105 * ******************************************************
|
||||
106 * * it type = ITBS * # it entries * 0
|
||||
107 * ******************************************************
|
||||
108 * * absolute line number (long) *
|
||||
109 * ******************************************************
|
||||
110 * * it type = ITSY * instr length * 1
|
||||
111 * ******************************************************
|
||||
112 * * symbol table pointer for stmt label (long) *
|
||||
113 * ******************************************************
|
||||
114 * * it type = ITSY * instr mode length * 2
|
||||
115 * ******************************************************
|
||||
116 * * opcode ptr (long) *
|
||||
117 * ******************************************************
|
||||
118 * * it type = ITCN * relocation base * 3
|
||||
1File: AS68INIT.C Page 3
|
||||
119 * ******************************************************
|
||||
120 * * location counter (pass 1) *
|
||||
121 * ******************************************************
|
||||
122 * * it type * relocation flag * 4 - oprnds
|
||||
123 * ******************************************************
|
||||
124 * * value (long) *
|
||||
125 * ******************************************************
|
||||
126 * .
|
||||
127 * .
|
||||
128 * .
|
||||
129 * ******************************************************
|
||||
130 * * it type * relocation flag * n - oprnds
|
||||
131 * ******************************************************
|
||||
132 * * value (long) *
|
||||
133 * ******************************************************
|
||||
134 */
|
||||
135
|
||||
136 #define ITOP1 4 /*first it entry for operands*/
|
||||
137
|
||||
138 /*
|
||||
139 * it type meaning
|
||||
140 * 0 beginning of statement
|
||||
141 * 1 value is pointer to symbol table
|
||||
142 * 2 value is a constant
|
||||
143 * 3 value is a specal char
|
||||
144 *
|
||||
145 * relocation flag for opcode it entry is operand length:
|
||||
146 * 'b' => byte
|
||||
147 * 'w' => word
|
||||
148 * 'l' => long
|
||||
149 */
|
||||
150
|
||||
151 struct it {
|
||||
152 char itty; /*it type*/
|
||||
153 char itrl; /*relocation flag or # it entries*/
|
||||
154 long itop;
|
||||
155 };
|
||||
156
|
||||
157 int mode=0; /*operand mode (byte, word, long)*/
|
||||
158 int modelen=0; /*operand length per mode*/
|
||||
159 #define BYTE 'b'
|
||||
160 #define WORD 'w'
|
||||
161 #define LONG 'l'
|
||||
162
|
||||
163 /* parameters that define the main table*/
|
||||
164 #define SZMT 300 /*initial size of the main table */
|
||||
165 /*must be large enough to initialize*/
|
||||
166 #ifdef PDP11
|
||||
167 #define ICRSZMT 10 /*add to main table when run out*/
|
||||
168 #else
|
||||
169 #define ICRSZMT 50 /*add to main table when run out*/
|
||||
170 #endif
|
||||
171 int cszmt=0; /*current size of main table*/
|
||||
172 char *bmte=0; /*beginning of main table*/
|
||||
173 char *emte=0; /*end of main table*/
|
||||
174
|
||||
175 /* intermediate text types*/
|
||||
176 #define ITBS 0 /*beginning of statement*/
|
||||
177 #define ITSY 1 /*pointer to symbol table*/
|
||||
1File: AS68INIT.C Page 4
|
||||
178 #define ITCN 2 /*constant*/
|
||||
179 #define ITSP 3 /*special*/
|
||||
180 #define ITRM 4 /*[vlh]register mask!*/
|
||||
181 #define ITPC 5 /*[vlh]pc relative argument*/
|
||||
182
|
||||
183 # define ITBSZ 256 /*size of the it buffer*/
|
||||
184 int itbuf[ITBSZ]={0}; /*it buffer*/
|
||||
185
|
||||
186 #define STMAX 200 /*size of intermediate text buffer*/
|
||||
187 struct it stbuf[STMAX]={0}; /*holds it for one statement*/
|
||||
188
|
||||
189 char sbuf[512]={0}; /*holds one block of source*/
|
||||
190
|
||||
191 /*initial reference table for symbols*/
|
||||
192 # define SZIRT 128
|
||||
193 char *sirt[SZIRT]={0};
|
||||
194
|
||||
195 /*initial reference table to opcodes*/
|
||||
196 char *oirt[SZIRT]={0};
|
||||
197
|
||||
198 /*external symbol table*/
|
||||
199 #define EXTSZ 512
|
||||
200 char *extbl[EXTSZ]={0};
|
||||
201 int extindx=0; /*index to external symbol table*/
|
||||
202 char **pexti=0; /*ptr to external symbol table*/
|
||||
203
|
||||
204 int absln=0; /*absolute line number*/
|
||||
205 int p2absln=0; /*pass 2 line number*/
|
||||
206 int fcflg=0; /*0=>passed an item. 1=>first char*/
|
||||
207 int fchr=0; /*first char in term*/
|
||||
208 int ifn=0; /*source file descriptor*/
|
||||
209 int *pitix=0; /*ptr to it buffer*/
|
||||
210 int itwc=0; /*number of words in it buffer*/
|
||||
211 struct it *pitw=0; /*ptr to it buffer next entry*/
|
||||
212 int itype=0; /*type of item*/
|
||||
213 long ival=0; /*value of item*/
|
||||
214 char *lblpt=0; /*label pointer*/
|
||||
215 char lbt[NAMELEN]={0}; /*holds label name*/
|
||||
216 char *lmte=0; /*last entry in main table*/
|
||||
217 long loctr=0; /*location counter*/
|
||||
218 long savelc[4]={0}; /*save relocation counters for 3 bases*/
|
||||
219 int nite=0; /*number of entries in stbuf*/
|
||||
220 struct it *pnite=0;
|
||||
221 int lfn=0; /*loader output file descriptor*/
|
||||
222 char *opcpt=0; /*pointer to opcode entry in main table*/
|
||||
223 int p2flg=0; /*0=>pass 1 1=>pass 2*/
|
||||
224 char **pirt=0; /*entry in initial reference table*/
|
||||
225 int reloc=0; /*relocation value returned by expression evaluator (expr)*/
|
||||
226 int rlflg=0; /*relocation value of current location counter*/
|
||||
227 /*relocation values*/
|
||||
228 # define ABS 0 /*absolute*/
|
||||
229 # define DATA 1
|
||||
230 # define TEXT 2
|
||||
231 # define BSS 3
|
||||
232 # define EXTRN 4 /*externally defined*/
|
||||
233
|
||||
234 #define EOLC '\n' /*end of line character*/
|
||||
235 #define EOF 0 /*end of file indicator*/
|
||||
236 #define NULL 0 /* [vlh] character null '\0' */
|
||||
1File: AS68INIT.C Page 5
|
||||
237 #define TRUE 1 /* [vlh] boolean values */
|
||||
238 #define FALSE 0 /* [vlh] boolean values */
|
||||
239
|
||||
240 int format=0;
|
||||
241 int sbuflen=0; /*number of chars in sbuf*/
|
||||
242 char *psbuf=0; /*ptr into sbuf*/
|
||||
243 int itfn=0; /*it file number*/
|
||||
244 char itfnc=0; /*last char of it file name*/
|
||||
245 int trbfn=0; /*temp for text relocation bits*/
|
||||
246 char trbfnc=0; /*last char of text rb file*/
|
||||
247 int dafn=0; /*file for data stuff*/
|
||||
248 char dafnc=0; /*last char of data file*/
|
||||
249 int drbfn=0; /*file for data relocation bits*/
|
||||
250 char drbfnc=0; /*last char*/
|
||||
251 int prtflg=0; /*print output flag*/
|
||||
252 int undflg=0; /*make undefined symbols external flag*/
|
||||
253
|
||||
254 int starmul=0; /* * is multiply operator*/
|
||||
255
|
||||
256 char *endptr=0, *addptr=0;
|
||||
257 char *orgptr=0;
|
||||
258 char *subptr=0, *addiptr=0, *addqptr=0, *subiptr=0, *subqptr=0;
|
||||
259 char *cmpptr=0, *addaptr=0, *cmpaptr=0, *subaptr=0, *cmpmptr=0;
|
||||
260 char *equptr=0;
|
||||
261 char *andptr=0, *andiptr=0, *eorptr=0, *eoriptr=0, *orptr=0, *oriptr=0;
|
||||
262 char *cmpiptr=0;
|
||||
263 char *moveptr=0, *moveqptr=0;
|
||||
264 char *exgptr=0;
|
||||
265 char *evenptr=0;
|
||||
266 char *jsrptr=0, *bsrptr=0, *nopptr=0;
|
||||
267
|
||||
268 char peekc=0;
|
||||
269 int numcon[2]=0, numsym[2]=0, indir[2]=0, immed[2]=0, numreg[2]=0;
|
||||
270 int plevel=0; /*parenthesis level counter*/
|
||||
271 int opdix=0; /*operand index counter*/
|
||||
272 int p1inlen=0; /*pass 1 instr length*/
|
||||
273 int instrlen=0; /*pass 2 bytes in current instruction*/
|
||||
274
|
||||
275 /* effective address mode bits*/
|
||||
276 #define DDIR 000
|
||||
277 #define ADIR 010
|
||||
278 #define INDIRECT 020
|
||||
279 #define INDINC 030
|
||||
280 #define DECIND 040
|
||||
281 #define INDDISP 050
|
||||
282 #define INDINX 060
|
||||
283 #define SADDR 070
|
||||
284 #define LADDR 071
|
||||
285 #define IMM 074
|
||||
286
|
||||
287 #define AREGLO 8
|
||||
288 #define AREGHI 15
|
||||
289
|
||||
290 /* relocation bit definitions:*/
|
||||
291 #define RBMASK 07 /*tells type of relocation*/
|
||||
292 #define INSABS 7 /*first word of instr -- absolute*/
|
||||
293 #define DABS 0 /*data word absolute*/
|
||||
294 #define TRELOC 2 /* TEXT relocatable*/
|
||||
295 #define DRELOC 1 /* DATA relocatable*/
|
||||
1File: AS68INIT.C Page 6
|
||||
296 #define BRELOC 3 /* BSS relocatable*/
|
||||
297 #define EXTVAR 4 /* ref to external variable*/
|
||||
298 #define LUPPER 5 /* upper word of long*/
|
||||
299 #define EXTREL 6 /* external relative mode*/
|
||||
300
|
||||
301 /* ptrs to ins[] and rlbits[]*/
|
||||
302 int *pins=0;
|
||||
303 int *prlb=0;
|
||||
304 int ins[5]={0}; /*holds instruction words*/
|
||||
305
|
||||
306 #define PRTCHLEN 128
|
||||
307 char prtchars[PRTCHLEN]={0}; /*line buffer for putchar*/
|
||||
308 char *prtchidx=0; /*index for putchar*/
|
||||
309
|
||||
310 int extflg=0, extref=0; /*external in expr*/
|
||||
311
|
||||
312 #define CCR 16
|
||||
313 #define SR 17
|
||||
314 #define USP 18
|
||||
315 #define MOVECCR 042300
|
||||
316 #define MOVESR 043300
|
||||
317 #define SRMOVE 040300
|
||||
318 #define MOVEUSP 047140
|
||||
319
|
||||
320 struct op {
|
||||
321 int ea; /* effective address bits*/
|
||||
322 int len; /* effective address length in bytes*/
|
||||
323 long con; /*constant or reloc part of operand*/
|
||||
324 int drlc; /*reloc of con*/
|
||||
325 int ext; /*external variable #*/
|
||||
326 int idx; /*index register if any*/
|
||||
327 int xmod; /*mode of index reg*/
|
||||
328 } opnd[2]={0};
|
||||
329 #define OPSTLEN 10
|
||||
330 #define TREELEN 20
|
||||
331 struct buf{
|
||||
332 int fildes;
|
||||
333 int nunused;
|
||||
334 char *xfree;
|
||||
335 char buff[512];
|
||||
336 };
|
||||
337
|
||||
338 struct buf lbuf={0};
|
||||
339 struct buf tbuf={0};
|
||||
340 struct buf dabuf={0};
|
||||
341 struct buf drbuf={0};
|
||||
342
|
||||
343 int nerror=0; /*# of assembler errors*/
|
||||
344 int in_err=0; /*[vlh] don't generate instrlen err if already err state*/
|
||||
345 int shortadr=0; /*short addresses if set*/
|
||||
346
|
||||
347 #define CLRFOR 24
|
||||
348 #define CLRVAL 041000
|
||||
349
|
||||
350 long itoffset=0;
|
||||
351
|
||||
352 #define LASTCHTFN tfilname[11]
|
||||
353 #define PC 22
|
||||
354
|
||||
1File: AS68INIT.C Page 7
|
||||
355 int equflg=0; /*doing an equate stmt*/
|
||||
356
|
||||
357 #define ANDI 01000
|
||||
358 #define AND 0140000
|
||||
359 #define ORI 0
|
||||
360 #define OR 0100000
|
||||
361 #define EORI 05000
|
||||
362 #define EOR 0130000
|
||||
363 #define MOVE 0
|
||||
364
|
||||
365 long lseek();
|
||||
366 char *sbrk();
|
||||
367 char *lemt();
|
||||
368
|
||||
369 int refpc=0; /* * referenced in expr*/
|
||||
370 #define SOH 1
|
||||
371
|
||||
372 /* Conditional Assembly variables and constants [vlh] */
|
||||
373 #define LOW_CA 21 /* [vlh] */
|
||||
374 #define HI_CA 30 /* [vlh] */
|
||||
375
|
||||
376 int ca_true=0; /* true unless in a false CA*/
|
||||
377 int ca=0; /* depth of conditional assembly, none = 0*/
|
||||
378 int ca_level=0; /* at what CA depth did CA go false?*/
|
||||
379
|
||||
380 /* pass 1 global variables */
|
||||
381 int numops=0; /*number of operands*/
|
||||
382 int inoffset=0; /*[vlh]offset directive*/
|
||||
383 int didorg=0;
|
||||
384 int initflg=0; /*initialize flag*/
|
||||
385
|
||||
386 /* defines */
|
||||
387 #define igblk() while(fchr==' ') fchr=gchr()
|
||||
388 #define ckein() ((pitw >= pnite))
|
||||
389
|
||||
390 /* is it an alterable operand */
|
||||
391 #define memalt(ap) (memea(ap) && altea(ap))
|
||||
392 #define dataalt(ap) (dataea(ap) && altea(ap))
|
||||
393 #define altea(ap) ((((ap)->ea&070)!=SADDR || ((ap)->ea&6)==0))
|
||||
394
|
||||
395 /* is it the specific type of operand */
|
||||
396 #define memea(ap) (((ap)->ea&070) >= INDIRECT)
|
||||
397 #define dataea(ap) (((ap)->ea&070) != ADIR)
|
||||
398 #define pcea(ap) ((ap)->ea==072 || (ap)->ea==073)
|
||||
399 #define ckdreg(ap) ((ap)->ea>=0 && (ap)->ea<AREGLO)
|
||||
400 #define ckareg(ap) ((ap)->ea>=AREGLO && (ap)->ea<=AREGHI)
|
||||
401 /*
|
||||
402 * DRI Listing Hacks:
|
||||
403 */
|
||||
404 char *sfname=0; /* -> Source filename */
|
||||
405 int xline=0; /* Current line number */
|
||||
406 int xpage=0; /* Current page number */
|
||||
407 /*
|
||||
408 * More Initializations:
|
||||
409 */
|
||||
410 char *tfilname[80] = {0}; /* Temp filename area */
|
||||
411 char *initfnam[80] = {0}; /* Init filename area */
|
||||
412 struct it exitm={0};
|
||||
413 int prcnt=0;
|
||||
1File: AS68INIT.C Page 8
|
||||
414 int rval=0;
|
||||
415 int lpflg=0;
|
||||
416 int lastopr=0;
|
||||
417 int rlbits[5]={0};
|
||||
418 int pline=0;
|
||||
419 int prsp=0;
|
||||
420 int amode=0;
|
||||
421 long stlen=0;
|
||||
422 int udfct=0;
|
||||
423 int errno=0;
|
||||
424 int nitleft=0;
|
||||
425 int hibytflg[4]={0};
|
||||
426 int hibytw[4]={0};
|
||||
427 struct it *piop=0;
|
||||
428 struct it *pitr=0;
|
||||
429 struct it opstk[OPSTLEN]={0};
|
||||
430 struct it tree[TREELEN]={0};
|
||||
431 int chmvq=0;
|
||||
432 int explmod=0;
|
||||
433 int ftudp=0;
|
||||
434 int iop=0;
|
||||
435 int itr=0;
|
||||
436 char ldfn[40]={0};
|
||||
437 int opcval=0;
|
||||
438 int poslab=0;
|
||||
439 int symcon=0;
|
||||
440 char *tfilptr=0;
|
||||
441 int tlab1=0;
|
||||
442 #define HDSIZE (sizeof couthd) /**.o file header size*/
|
||||
443 struct hdr {
|
||||
444 short ch_magic; /*c.out magic number 060016 = $600E*/
|
||||
445 long ch_tsize; /*text size*/
|
||||
446 long ch_dsize; /*data size*/
|
||||
447 long ch_bsize; /*bss size*/
|
||||
448 long ch_ssize; /*symbol table size*/
|
||||
449 long ch_stksize; /*stack size*/
|
||||
450 long ch_entry; /*entry point*/
|
||||
451 short ch_rlbflg; /*relocation bits suppressed flag*/
|
||||
452 } couthd={0};
|
||||
453
|
||||
454 #define MAGIC 0x601a /* bra .+26 instruction*/
|
||||
13
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/as68/cout.h
Normal file
13
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/as68/cout.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#define HDSIZE (sizeof couthd) /**.o file header size*/
|
||||
struct hdr {
|
||||
short ch_magic; /*c.out magic number 060016 = $600E*/
|
||||
long ch_tsize; /*text size*/
|
||||
long ch_dsize; /*data size*/
|
||||
long ch_bsize; /*bss size*/
|
||||
long ch_ssize; /*symbol table size*/
|
||||
long ch_stksize; /*stack size*/
|
||||
long ch_entry; /*entry point*/
|
||||
short ch_rlbflg; /*relocation bits suppressed flag*/
|
||||
} couthd;
|
||||
|
||||
#define MAGIC 0x601a /* bra .+26 instruction*/
|
||||
@@ -0,0 +1,14 @@
|
||||
1File: COUT.H Page 1
|
||||
1 #define HDSIZE (sizeof couthd) /**.o file header size*/
|
||||
2 struct hdr {
|
||||
3 short ch_magic; /*c.out magic number 060016 = $600E*/
|
||||
4 long ch_tsize; /*text size*/
|
||||
5 long ch_dsize; /*data size*/
|
||||
6 long ch_bsize; /*bss size*/
|
||||
7 long ch_ssize; /*symbol table size*/
|
||||
8 long ch_stksize; /*stack size*/
|
||||
9 long ch_entry; /*entry point*/
|
||||
10 short ch_rlbflg; /*relocation bits suppressed flag*/
|
||||
11 } couthd;
|
||||
12
|
||||
13 #define MAGIC 0x601a /* bra .+26 instruction*/
|
||||
36
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/as68/ctype.h
Normal file
36
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/as68/ctype.h
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
Copyright 1982
|
||||
Alcyon Corporation
|
||||
8716 Production Ave.
|
||||
San Diego, Ca. 92121
|
||||
*/
|
||||
|
||||
/*char *version "@(#)ctype - Aug 13, 1982";
|
||||
|
||||
Standard routines... */
|
||||
|
||||
#define isspace(c) ((c)==32 || (c)==9 || (c)==13 || (c)==10 ||(c)==12)
|
||||
|
||||
#define isupper(c) ((c)<='Z' && (c)>='A')
|
||||
|
||||
#define islower(c) ((c)<='z' && (c)>='a')
|
||||
|
||||
#define isalpha(c) (isupper((c)) || islower((c)))
|
||||
|
||||
#define isdigit(c) ((c)<='9' && (c)>='0')
|
||||
|
||||
#define isascii(c) ((c) < 0200 && (c) >= 0)
|
||||
|
||||
#define isalnum(c) (isalpha((c)) || isdigit((c)))
|
||||
|
||||
#define iscntrl(c) (((c) < 040 || (c) == 0177) && isascii((c)))
|
||||
|
||||
#define isprint(c) ((c) >= 040 && (c) < 0177)
|
||||
|
||||
#define ispunct(c) (!isalnum((c)) && isprint(c))
|
||||
|
||||
#define toupper(c) (islower((c)) ? (c) & ~32 : (c))
|
||||
|
||||
#define tolower(c) (isupper((c)) ? (c) | 32 : (c))
|
||||
|
||||
#define toascii(c) ((c) & 0177)
|
||||
@@ -0,0 +1,37 @@
|
||||
1File: CTYPE.H Page 1
|
||||
1 /*
|
||||
2 Copyright 1982
|
||||
3 Alcyon Corporation
|
||||
4 8716 Production Ave.
|
||||
5 San Diego, Ca. 92121
|
||||
6 */
|
||||
7
|
||||
8 /*char *version "@(#)ctype - Aug 13, 1982";
|
||||
9
|
||||
10 Standard routines... */
|
||||
11
|
||||
12 #define isspace(c) ((c)==32 || (c)==9 || (c)==13 || (c)==10 ||(c)==12)
|
||||
13
|
||||
14 #define isupper(c) ((c)<='Z' && (c)>='A')
|
||||
15
|
||||
16 #define islower(c) ((c)<='z' && (c)>='a')
|
||||
17
|
||||
18 #define isalpha(c) (isupper((c)) || islower((c)))
|
||||
19
|
||||
20 #define isdigit(c) ((c)<='9' && (c)>='0')
|
||||
21
|
||||
22 #define isascii(c) ((c) < 0200 && (c) >= 0)
|
||||
23
|
||||
24 #define isalnum(c) (isalpha((c)) || isdigit((c)))
|
||||
25
|
||||
26 #define iscntrl(c) (((c) < 040 || (c) == 0177) && isascii((c)))
|
||||
27
|
||||
28 #define isprint(c) ((c) >= 040 && (c) < 0177)
|
||||
29
|
||||
30 #define ispunct(c) (!isalnum((c)) && isprint(c))
|
||||
31
|
||||
32 #define toupper(c) (islower((c)) ? (c) & ~32 : (c))
|
||||
33
|
||||
34 #define tolower(c) (isupper((c)) ? (c) | 32 : (c))
|
||||
35
|
||||
36 #define toascii(c) ((c) & 0177)
|
||||
934
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/as68/dir.c
Normal file
934
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/as68/dir.c
Normal file
@@ -0,0 +1,934 @@
|
||||
/*
|
||||
Copyright 1981
|
||||
Alcyon Corporation
|
||||
8716 Production Ave.
|
||||
San Diego, Ca. 92121
|
||||
*/
|
||||
|
||||
/* Pass 1 and pass 2 directive handling routines */
|
||||
/* code to handle conditional assembly directives */
|
||||
|
||||
#include "as68.h"
|
||||
#include "cout.h"
|
||||
|
||||
long lseek();
|
||||
int p1gi();
|
||||
int p2gi();
|
||||
int igrst();
|
||||
|
||||
/*directive to define an opcode*/
|
||||
hopd()
|
||||
{
|
||||
|
||||
if(!lbt[0]) {
|
||||
xerr(4); /*no label*/
|
||||
return;
|
||||
}
|
||||
setname(); /*move label into main table*/
|
||||
if((lblpt=lemt(oirt,TRUE))!=lmte) {
|
||||
xerr(5); /*opcode redefined*/
|
||||
return;
|
||||
}
|
||||
mmte(); /*make main table entry*/
|
||||
expr(&p1gi); /*get instruction format*/
|
||||
if(itype!=ITCN || ival<0 || ival>OPFF) {
|
||||
xerr(18); /*illegal format specifier*/
|
||||
return;
|
||||
}
|
||||
lblpt->flags =| ival|SYIN; /*remember format*/
|
||||
if(fchr != ',') { /*field separator*/
|
||||
xerr(10);
|
||||
return;
|
||||
}
|
||||
expr(&p1gi); /*get opcode value*/
|
||||
if(itype != ITCN) {
|
||||
xerr(17); /*not a constant*/
|
||||
return;
|
||||
}
|
||||
lblpt->vl1 = ival; /*put value in main table*/
|
||||
igrst(); /*ignore rest of statement-comment*/
|
||||
}
|
||||
|
||||
/* equate directive*/
|
||||
hequ()
|
||||
{
|
||||
if(lbt[0] == 0) {
|
||||
xerr(4); /*no label*/
|
||||
return;
|
||||
}
|
||||
setname();
|
||||
if((lblpt=lemt(sirt,FALSE))!=lmte) { /*aready there*/
|
||||
if(lbt[0] == '~') { /*local symbol*/
|
||||
lblpt = lmte;
|
||||
mmte();
|
||||
}
|
||||
}
|
||||
else
|
||||
mmte();
|
||||
if(lblpt->flags&SYXR) {
|
||||
xerr(29);
|
||||
return;
|
||||
}
|
||||
lblpt->flags =| SYDF|SYEQ; /*defined & equate*/
|
||||
equflg = 1;
|
||||
modelen = 4;
|
||||
expr(&p1gi);
|
||||
equflg = 0;
|
||||
if(itype == ITSY && ival.ptrw2->flags&SYER) {
|
||||
lblpt->flags =| SYER; /*equated register*/
|
||||
ival = ival.ptrw2->vl1;
|
||||
}
|
||||
else if(itype != ITCN) {
|
||||
xerr(7); /*not a constant*/
|
||||
return;
|
||||
}
|
||||
if (inoffset && reloc != ABS) { /* [vlh] */
|
||||
xerr(11);
|
||||
return;
|
||||
}
|
||||
if(initflg) /*doing symbol table initialization*/
|
||||
lblpt->flags =| SYIN; /*internal symbol*/
|
||||
lblpt->vl1 = ival;
|
||||
if(reloc == DATA) /*check relocation*/
|
||||
{
|
||||
lblpt->flags =| SYRA; /*DATA relocatable*/
|
||||
}
|
||||
else if(reloc == TEXT)
|
||||
lblpt->flags =| SYRO; /*TEXT relocatable*/
|
||||
else if(reloc == BSS)
|
||||
lblpt->flags =| SYBS; /*BSS relocatable*/
|
||||
else if(fchr==',' && (fchr=gchr())=='r')
|
||||
lblpt->flags =| SYER; /*equated register*/
|
||||
if (refpc) /*[vlh] flag directive is pc relative */
|
||||
lblpt->flags =| SYPC;
|
||||
igrst();
|
||||
}
|
||||
|
||||
/* process dsect directive*/
|
||||
hdsect()
|
||||
{
|
||||
dorlst(DATA);
|
||||
}
|
||||
|
||||
dorlst(xrtyp)
|
||||
{
|
||||
inoffset = 0; /* [vlh] offset mode terminated my sect directive */
|
||||
chkeven(); /* May need to make pc even */
|
||||
dlabl(); /*define label on old base if there is one*/
|
||||
savelc[rlflg] = loctr; /*save old base relocation*/
|
||||
rlflg = xrtyp;
|
||||
loctr = savelc[xrtyp]; /*set new base relocation ctr*/
|
||||
opitb();
|
||||
stbuf[0].itrl = itwc;
|
||||
wostb();
|
||||
igrst();
|
||||
}
|
||||
|
||||
/*process psect directive*/
|
||||
hpsect()
|
||||
{
|
||||
dorlst(TEXT);
|
||||
}
|
||||
|
||||
hbss()
|
||||
{
|
||||
dorlst(BSS);
|
||||
}
|
||||
|
||||
/*make pc even*/
|
||||
heven()
|
||||
{
|
||||
modelen = 2; /*Try to figure this one out...*/
|
||||
if(loctr&1) { /*have to make it even*/
|
||||
dorlst(rlflg);
|
||||
}
|
||||
else {
|
||||
igrst();
|
||||
}
|
||||
}
|
||||
|
||||
/*process globl directive*/
|
||||
hent()
|
||||
{
|
||||
while(1) {
|
||||
gterm(TRUE); /*get entry symbol*/
|
||||
if(itype!=ITSY) { /*error if not symbol*/
|
||||
xerr(28);
|
||||
return;
|
||||
}
|
||||
if((lblpt=lemt(sirt,FALSE)) == lmte) /*look up in main table*/
|
||||
mmte(); /*not there, make new entry*/
|
||||
else
|
||||
if(lblpt->flags&SYER) /*already there*/
|
||||
uerr(29);
|
||||
lblpt->flags =| SYGL; /*symbol is an entry*/
|
||||
if(lblpt->flags&SYXR) { /*been thru hext code*/
|
||||
lblpt->flags =& ~(SYXR|SYDF); /*reset for init of .comm*/
|
||||
}
|
||||
if (inoffset && reloc != ABS) { /* [vlh] */
|
||||
xerr(11);
|
||||
return;
|
||||
}
|
||||
if(fchr == ',') /*skip ',' between entries*/
|
||||
fchr = gchr();
|
||||
else {
|
||||
igrst(); /*statement finished*/
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*process comm directive*/
|
||||
hext()
|
||||
{
|
||||
gterm(TRUE); /*get external symbol*/
|
||||
if(itype!=ITSY) { /*error if not symbol*/
|
||||
xerr(28);
|
||||
return;
|
||||
}
|
||||
if((lblpt=lemt(sirt,FALSE)) == lmte) /*look up in main table*/
|
||||
mmte(); /*not there, make new entry*/
|
||||
else
|
||||
if(lblpt->flags&SYDF && (lblpt->flags&SYXR)==0) /*already there*/
|
||||
uerr(29);
|
||||
lblpt->flags =| SYXR | SYDF; /*symbol is an external*/
|
||||
mkextidx(lblpt); /*put into external table*/
|
||||
if(fchr == ',') { /*skip ',' between operands*/
|
||||
fchr = gchr();
|
||||
gterm(TRUE);
|
||||
if(itype != ITCN) {
|
||||
xerr(17);
|
||||
return;
|
||||
}
|
||||
lblpt->vl1.wd1 = ival; /* # bytes of storage required*/
|
||||
}
|
||||
else
|
||||
lblpt->vl1.wd1 = 1; /* default # bytes*/
|
||||
igrst();
|
||||
}
|
||||
|
||||
mkextidx(p)
|
||||
struct symtab *p;
|
||||
{
|
||||
|
||||
if(extindx >= EXTSZ) { /*check for overflow of external symbol tbl*/
|
||||
rpterr("overflow of external table\n");
|
||||
endit();
|
||||
}
|
||||
p->vl1.wd2 = pexti - extbl; /* external symbol index #*/
|
||||
*pexti++ = p; /*save external in external table*/
|
||||
extindx++;
|
||||
}
|
||||
|
||||
/* end statement*/
|
||||
hend()
|
||||
{
|
||||
register short i;
|
||||
register int j;
|
||||
|
||||
inoffset = 0; /*[vlh] turn off inoffset mode*/
|
||||
lblpt = 0; /*no label*/
|
||||
opitb(); /*output beginning of statement*/
|
||||
igrst(); /* [vlh] ignore operands */
|
||||
stbuf[0].itrl = itwc; /*number of it entries*/
|
||||
wostb(); /*write out statement buffer*/
|
||||
for(i=0; i<ITBSZ; i++)
|
||||
doitwr(0);
|
||||
if(initflg) {
|
||||
putsymtab();
|
||||
printf("68000 assembler initialized\n");
|
||||
endit();
|
||||
}
|
||||
if((fchr=gchr())!=EOF) {
|
||||
rpterr("end statement not at end of source\n");
|
||||
}
|
||||
savelc[rlflg] = loctr; /*last location on current reloc base*/
|
||||
fixunds(); /*make golbals and maybe undefineds external*/
|
||||
if(!didorg) /*did not assign to location counter*/
|
||||
pass1a(); /*resolve short branches*/
|
||||
pass2(); /*assembler pass 2*/
|
||||
}
|
||||
|
||||
/* define storage given number of bytes*/
|
||||
hds()
|
||||
{
|
||||
dlabl(); /*define label maybe*/
|
||||
if (!inoffset) /* [vlh] */
|
||||
opitb(); /*output it for beginning of statement*/
|
||||
refpc = 0;
|
||||
expr(&p1gi);
|
||||
if(itype!=ITCN) {
|
||||
xerr(17); /*must be constant*/
|
||||
return;
|
||||
}
|
||||
if(reloc != ABS) {
|
||||
xerr(9); /*must be absolute*/
|
||||
return;
|
||||
}
|
||||
if (!inoffset) { /* [vlh] don't generate it if in offset */
|
||||
opitoo(); /*output one operand*/
|
||||
stbuf[0].itrl = itwc;
|
||||
wostb(); /*write out statement buffer*/
|
||||
loctr =+ (ival*modelen);
|
||||
}
|
||||
igrst();
|
||||
}
|
||||
|
||||
/* make pc even if necessary for .dc and .ds */
|
||||
chkeven()
|
||||
{
|
||||
register char *pi;
|
||||
|
||||
if(modelen>1 && loctr&1) {
|
||||
pi = opcpt;
|
||||
opcpt = evenptr;
|
||||
opitb();
|
||||
stbuf[0].itrl = itwc;
|
||||
wostb();
|
||||
opcpt = pi;
|
||||
loctr++;
|
||||
}
|
||||
}
|
||||
|
||||
/* define byte directive*/
|
||||
hdc()
|
||||
{
|
||||
chkeven();
|
||||
hdata(modelen);
|
||||
}
|
||||
|
||||
/*
|
||||
* define bytes or words of data
|
||||
* call with:
|
||||
* 1 => defining bytes
|
||||
* 2 => defining words
|
||||
* 4 => defining long words
|
||||
*/
|
||||
hdata(mul)
|
||||
{
|
||||
dlabl(); /*define label*/
|
||||
opitb(); /*beginning of statement*/
|
||||
numops = 0; /*initialize count for number of operands*/
|
||||
opito(); /*output it for operands*/
|
||||
stbuf[0].itrl = itwc; /* # of it entries*/
|
||||
wostb(); /*write out statement buffer*/
|
||||
loctr =+ numops*mul; /* count by bytes or words*/
|
||||
}
|
||||
|
||||
/* handle org statement*/
|
||||
horg()
|
||||
{
|
||||
register i;
|
||||
|
||||
if(rlflg==TEXT && loctr!=0)
|
||||
didorg++; /*can't do branch optimization as separate pass now*/
|
||||
expr(&p1gi); /*value of new relocation counter*/
|
||||
if(reloc != rlflg && reloc != ABS) {
|
||||
xerr(27);
|
||||
return;
|
||||
}
|
||||
if(ival < loctr) {
|
||||
xerr(40); /*trying to go backwards*/
|
||||
return;
|
||||
}
|
||||
opcpt = orgptr; /*org directive for pass 2*/
|
||||
opitb();
|
||||
opitoo();
|
||||
stbuf[0].itrl = itwc;
|
||||
wostb();
|
||||
loctr = ival;
|
||||
dlabl(); /*define label*/
|
||||
}
|
||||
|
||||
/* Assemble for mask2 (R9M), ignore... */
|
||||
hmask2() /* [vlh] */
|
||||
{
|
||||
igrst();
|
||||
}
|
||||
|
||||
/* Define register list */
|
||||
hreg() /* [vlh] */
|
||||
{
|
||||
int mask;
|
||||
if(lbt[0]==0) {
|
||||
xerr(4); /*no label*/
|
||||
return;
|
||||
}
|
||||
setname(); /*move label into main table*/
|
||||
if((lblpt=lemt(sirt,FALSE))!=lmte) {
|
||||
xerr(5); /*opcode redefined*/
|
||||
return;
|
||||
}
|
||||
if (inoffset)
|
||||
if (reloc != ABS) {
|
||||
xerr(11);
|
||||
return;
|
||||
}
|
||||
mmte(); /*make main table entry*/
|
||||
if ((mask = mkmask()) == -1) {
|
||||
xerr(6);
|
||||
return;
|
||||
}
|
||||
lblpt->flags =| SYDF|SYEQ|SYRM; /* register mask, defined & equated */
|
||||
lblpt->vl1 = mask;
|
||||
igrst();
|
||||
}
|
||||
|
||||
int regmsk[] {0100000,040000,020000,010000,04000,02000,01000,0400,0200,
|
||||
0100,040,020,010,4,2,1};
|
||||
/* make a register mask for the reg routine */
|
||||
mkmask() /* [vlh] */
|
||||
{
|
||||
register int *p, i, j, mask;
|
||||
|
||||
p = ®msk; mask = 0;
|
||||
while ((i = chkreg()) != -1) {
|
||||
if (fchr == '-') {
|
||||
fchr = gchr();
|
||||
if ((j = chkreg()) == -1) {
|
||||
xerr(40);
|
||||
return(-1);
|
||||
}
|
||||
while (i <= j)
|
||||
mask =| p[i++];
|
||||
}
|
||||
else mask =| p[i];
|
||||
if (fchr != '/' && fchr != ',') break; /*[vlh] Signetics fix*/
|
||||
fchr = gchr();
|
||||
}
|
||||
return(mask);
|
||||
}
|
||||
|
||||
/* get a register # from file, return -1 if none or illegal */
|
||||
chkreg() /* [vlh] */
|
||||
{
|
||||
register int i, j;
|
||||
|
||||
i = j = 0;
|
||||
if (fchr == 'a' || fchr == 'A')
|
||||
i = 8;
|
||||
else if (fchr != 'd' && fchr != 'r' && fchr != 'D' && fchr != 'R')
|
||||
return(-1);
|
||||
fchr = gchr();
|
||||
do {
|
||||
j = (j*10) + (fchr - '0');
|
||||
fchr = gchr();
|
||||
} while (isdigit(fchr));
|
||||
if (j < 0 || j > AREGHI) return(-1);
|
||||
i =+ j;
|
||||
if (i >= 0 && i <= AREGHI) return(i);
|
||||
else return(-1);
|
||||
}
|
||||
|
||||
/* Define constant block */
|
||||
hdcb() /* [vlh] */
|
||||
{
|
||||
chkeven(); /* on even boundary if not byte block. */
|
||||
dlabl(); /* define label... */
|
||||
opitb();
|
||||
opito();
|
||||
stbuf[0].itrl = itwc;
|
||||
numops = stbuf[ITOP1].itop;
|
||||
loctr =+ numops * modelen;
|
||||
wostb(); /* write out statement buffer */
|
||||
}
|
||||
|
||||
/* Command line, similar to ds.b */
|
||||
hcomline() /* [vlh] */
|
||||
{
|
||||
dlabl(); /*define label maybe*/
|
||||
modelen = 1; /* byte store... */
|
||||
opitb(); /*output it for beginning of statement*/
|
||||
refpc = 0;
|
||||
expr(&p1gi);
|
||||
if(itype!=ITCN) {
|
||||
xerr(17); /*must be constant*/
|
||||
return;
|
||||
}
|
||||
if(reloc != ABS) {
|
||||
xerr(9); /*must be absolute*/
|
||||
return;
|
||||
}
|
||||
opitoo(); /*output one operand*/
|
||||
stbuf[0].itrl = itwc;
|
||||
wostb(); /*write out statement buffer*/
|
||||
loctr =+ ival;
|
||||
igrst();
|
||||
}
|
||||
|
||||
/* Relocateable id record, ignore */
|
||||
hidnt() /* [vlh] */
|
||||
{
|
||||
igrst();
|
||||
}
|
||||
|
||||
/* Define offsets */
|
||||
hoffset() /* [vlh] */
|
||||
{
|
||||
inoffset = 1;
|
||||
expr(&p1gi); /* get new location counter */
|
||||
if (itype != ITCN) {
|
||||
xerr(17); /* constant required */
|
||||
return;
|
||||
}
|
||||
if (reloc != ABS) {
|
||||
xerr(9); /* must be absolute */
|
||||
return;
|
||||
}
|
||||
loctr = ival;
|
||||
igrst();
|
||||
}
|
||||
|
||||
/* define sections: map to bss, text and data */
|
||||
hsection() /* [vlh] */
|
||||
{
|
||||
inoffset = 0; /* reseting section turns off offset mode */
|
||||
dlabl(); /* define label on old base if there is one */
|
||||
savelc[rlflg] = loctr; /* save old base relocation */
|
||||
opitb(); /* intermediate table... */
|
||||
expr(&p1gi); /* get section # */
|
||||
if (itype != ITCN) {
|
||||
xerr(17); /* must be a constant */
|
||||
return;
|
||||
}
|
||||
if (ival > 15 || ival < 0) {
|
||||
xerr(9); /* proper range 0..15 */
|
||||
return;
|
||||
}
|
||||
if (ival==14) rlflg = DATA;
|
||||
else if (ival==15) rlflg = BSS;
|
||||
else rlflg = TEXT;
|
||||
loctr = savelc[rlflg];
|
||||
stbuf[3].itop = loctr; /* pass 1 location counter */
|
||||
stbuf[3].itrl = rlflg; /* relocation base */
|
||||
stbuf[0].itrl = itwc;
|
||||
wostb();
|
||||
igrst();
|
||||
}
|
||||
|
||||
/* hopt -- ignore, set up assembler options */
|
||||
hopt() /* vlh */
|
||||
{
|
||||
igrst();
|
||||
}
|
||||
|
||||
/**** Second pass directive handling routines ****/
|
||||
|
||||
/* second pass end statement*/
|
||||
send()
|
||||
{
|
||||
register int i;
|
||||
|
||||
savelc[rlflg] = loctr;
|
||||
if(savelc[TEXT]&1) {
|
||||
rlflg = TEXT;
|
||||
outbyte(0,DABS);
|
||||
savelc[TEXT]++;
|
||||
}
|
||||
if(savelc[DATA]&1) {
|
||||
rlflg = DATA;
|
||||
outbyte(0,DABS);
|
||||
savelc[DATA]++;
|
||||
}
|
||||
if(savelc[BSS]&1) {
|
||||
savelc[BSS]++;
|
||||
}
|
||||
|
||||
ival = 0;
|
||||
reloc = ABS;
|
||||
ckeop(9);
|
||||
print(0);
|
||||
cpdata(); /*copy data to loader file*/
|
||||
osymt(); /*output symbol table*/
|
||||
myfflush(&tbuf); /*flush text relocation bits*/
|
||||
cprlbits(); /*copy relocation bits*/
|
||||
myfflush(&lbuf);
|
||||
i = (sizeof couthd.ch_magic) + 3*(sizeof couthd.ch_tsize);
|
||||
if((lseek(lfn,(long)i,0) == -1) || write(lfn,&stlen,4) != 4)
|
||||
rpterr("I/O error on loader output file\n");
|
||||
endit(); /*end*/
|
||||
}
|
||||
|
||||
/*second pass define storage - ds*/
|
||||
sds()
|
||||
{
|
||||
print(0);
|
||||
if(rlflg == TEXT || rlflg==DATA) {
|
||||
expr(&p2gi);
|
||||
if(itype != ITCN) {
|
||||
uerr(13);
|
||||
return;
|
||||
}
|
||||
ival =* modelen;
|
||||
while(ival) {
|
||||
outbyte(0,DABS);
|
||||
loctr++;
|
||||
ival--;
|
||||
}
|
||||
}
|
||||
else
|
||||
loctr =+ stbuf[ITOP1].itop*modelen; /*reserve storage*/
|
||||
}
|
||||
|
||||
/* second pass - define block storage, initialized */
|
||||
sdcb() /* [vlh] */
|
||||
{
|
||||
register int pfg, i, hflg, len;
|
||||
|
||||
expr(&p2gi);
|
||||
if (itype != ITCN || reloc != ABS) {
|
||||
uerr(13); /* must be absolute constant */
|
||||
return;
|
||||
}
|
||||
len = ival;
|
||||
expr(&p2gi);
|
||||
if (modelen==1 && (ival<-128 || ival>=256 || reloc != ABS)) {
|
||||
uerr(20);
|
||||
ival = 0;
|
||||
reloc = ABS;
|
||||
}
|
||||
while (len--) {
|
||||
if (modelen==1) {
|
||||
if (!hflg) {
|
||||
ins[i].hibyte = ival;
|
||||
outbyte(ival.wd2,DABS);
|
||||
hflg++;
|
||||
}
|
||||
else {
|
||||
ins[i++].lobyte = ival;
|
||||
outbyte(ival.wd2,DABS);
|
||||
hflg=0;
|
||||
}
|
||||
goto sdbl2;
|
||||
}
|
||||
else if (modelen==2) {
|
||||
sdbl1:
|
||||
ins[i++] = ival.wd2;
|
||||
outword(ival.wd2, reloc);
|
||||
sdbl2:
|
||||
if (i>3) {
|
||||
instrlen = i*2;
|
||||
print ((pfg++) ? 2 : 1);
|
||||
loctr =+ instrlen;
|
||||
i=0;
|
||||
}
|
||||
}
|
||||
else { /* long word... */
|
||||
ins[i++] = ival.wd1;
|
||||
outword(ival.wd1,LUPPER);
|
||||
goto sdbl1;
|
||||
}
|
||||
}
|
||||
if (i) { /* more printing */
|
||||
instrlen = i*2 - hflg;
|
||||
print ((pfg) ? 2 : 1);
|
||||
loctr =+ instrlen;
|
||||
}
|
||||
}
|
||||
|
||||
/*second pass data*/
|
||||
sdsect()
|
||||
{
|
||||
savelc[rlflg] = loctr;
|
||||
rlflg = DATA;
|
||||
loctr = savelc[DATA];
|
||||
print(0); /*print the new location counter*/
|
||||
}
|
||||
|
||||
/*second pass text*/
|
||||
spsect()
|
||||
{
|
||||
savelc[rlflg] = loctr;
|
||||
rlflg = TEXT;
|
||||
loctr = savelc[TEXT];
|
||||
print(0); /*print the new location counter*/
|
||||
}
|
||||
|
||||
sbss()
|
||||
{
|
||||
savelc[rlflg] = loctr;
|
||||
rlflg = BSS;
|
||||
loctr = savelc[BSS];
|
||||
print(0); /*print the new location counter*/
|
||||
}
|
||||
|
||||
/* make loctr even*/
|
||||
seven()
|
||||
{
|
||||
if(loctr&1) {
|
||||
if(rlflg==TEXT || rlflg==DATA)
|
||||
outbyte(0,DABS);
|
||||
loctr++;
|
||||
}
|
||||
print(0);
|
||||
}
|
||||
|
||||
/* second pass org*/
|
||||
sorg()
|
||||
{
|
||||
long l;
|
||||
|
||||
if(rlflg==TEXT || rlflg==DATA) { /*must put out zeros*/
|
||||
l = stbuf[ITOP1].itop - loctr; /*# zeroes to output*/
|
||||
ins[0] = 0;
|
||||
print(1);
|
||||
while(l > 0) {
|
||||
outbyte(0,DABS);
|
||||
loctr++;
|
||||
l--;
|
||||
}
|
||||
}
|
||||
else { /*BSS*/
|
||||
loctr = stbuf[ITOP1].itop; /*new location counter*/
|
||||
print(0);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
*second pass define data (words or bytes)
|
||||
* call with
|
||||
* 2 => defining words
|
||||
* 1 => defining bytes
|
||||
* 4 => defining long words
|
||||
*/
|
||||
sdata(dtyp)
|
||||
{
|
||||
register pfg,i;
|
||||
register hflg;
|
||||
|
||||
hflg = i = pfg = 0;
|
||||
while(1) {
|
||||
expr(&p2gi); /*evaluate expression*/
|
||||
if(pitw < pnite)
|
||||
pitw--; /*expr passed a token*/
|
||||
if(itype!=ITCN && reloc != EXTRN) { /*must be constant*/
|
||||
uerr(13);
|
||||
ival=0;
|
||||
reloc = ABS;
|
||||
}
|
||||
if(reloc == EXTRN)
|
||||
reloc = (extref<<3)|EXTVAR; /*gen extern reference*/
|
||||
if(dtyp==1) { /*defining a byte*/
|
||||
if(ival<-128 || ival>=256 || reloc!=ABS) { /*not a byte*/
|
||||
uerr(20);
|
||||
ival=0;
|
||||
reloc = ABS;
|
||||
}
|
||||
if(!hflg) {
|
||||
ins[i].hibyte = ival;
|
||||
outbyte(ival.wd2,DABS);
|
||||
hflg++;
|
||||
}
|
||||
else {
|
||||
ins[i++].lobyte = ival;
|
||||
hflg = 0;
|
||||
outbyte(ival.wd2,DABS);
|
||||
}
|
||||
goto sdal2;
|
||||
}
|
||||
else if(dtyp == 2) { /*defining a word*/
|
||||
sdal1:
|
||||
ins[i++] = ival.wd2;
|
||||
outword(ival.wd2, reloc);
|
||||
sdal2:
|
||||
if(i>3) {
|
||||
instrlen = i*2;
|
||||
print ((pfg++) ? 2 : 1);
|
||||
loctr =+ instrlen;
|
||||
i=0;
|
||||
}
|
||||
}
|
||||
else { /*long words*/
|
||||
ins[i++] = ival.wd1;
|
||||
outword(ival.wd1,LUPPER);
|
||||
goto sdal1;
|
||||
}
|
||||
if(!ckeop(15)) /*should be end of operand*/
|
||||
return;
|
||||
pitw++;
|
||||
if(ckein()) {
|
||||
if(hflg) {
|
||||
ins[i++].lobyte = 0;
|
||||
}
|
||||
if(i) { /*more printing*/
|
||||
instrlen = i*2 - hflg;
|
||||
print ((pfg) ? 2 : 1);
|
||||
loctr =+ instrlen;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sdc()
|
||||
{
|
||||
sdata(modelen);
|
||||
}
|
||||
|
||||
ssection() /* [vlh] */
|
||||
{
|
||||
int sect;
|
||||
|
||||
sect = stbuf[3].itrl;
|
||||
if (sect==DATA) sdsect();
|
||||
else if (sect==BSS) sbss();
|
||||
else spsect();
|
||||
}
|
||||
|
||||
/*define word statement*/
|
||||
sdw()
|
||||
{
|
||||
sdata(0); /*defining words*/
|
||||
}
|
||||
/**** Conditional assembly directives ****/
|
||||
|
||||
hifeq() /* [vlh] */
|
||||
{
|
||||
if (!acok()) return;
|
||||
if (ival) {
|
||||
if (ca_true) ca_level = ca;
|
||||
ca_true = 0;
|
||||
}
|
||||
ca++;
|
||||
}
|
||||
|
||||
hifne() /* [vlh] */
|
||||
{
|
||||
if (!acok()) return;
|
||||
if (!ival) {
|
||||
if (ca_true) ca_level = ca;
|
||||
ca_true = 0;
|
||||
}
|
||||
ca++;
|
||||
}
|
||||
|
||||
hiflt() /* [vlh] */
|
||||
{
|
||||
if (!acok()) return;
|
||||
if (ival >= 0) {
|
||||
if (ca_true) ca_level = ca;
|
||||
ca_true = 0;
|
||||
}
|
||||
ca++;
|
||||
}
|
||||
|
||||
hifle() /* [vlh] */
|
||||
{
|
||||
if (!acok()) return;
|
||||
if (ival > 0) {
|
||||
if (ca_true) ca_level = ca;
|
||||
ca_true = 0;
|
||||
}
|
||||
ca++;
|
||||
}
|
||||
|
||||
hifgt() /* [vlh] */
|
||||
{
|
||||
if (!acok()) return;
|
||||
if (ival <= 0) {
|
||||
if (ca_true) ca_level = ca;
|
||||
ca_true = 0;
|
||||
}
|
||||
ca++;
|
||||
}
|
||||
|
||||
hifge() /* [vlh] */
|
||||
{
|
||||
if (!acok()) return;
|
||||
if (ival < 0) {
|
||||
if (ca_true) ca_level = ca;
|
||||
ca_true = 0;
|
||||
}
|
||||
ca++;
|
||||
}
|
||||
|
||||
hifc() /* [vlh] */
|
||||
{
|
||||
if (!cmp_ops()) {
|
||||
if (ca_true) ca_level = ca;
|
||||
ca_true = 0;
|
||||
}
|
||||
ca++;
|
||||
}
|
||||
|
||||
hifnc() /* [vlh] */
|
||||
{
|
||||
if (cmp_ops()) {
|
||||
if (ca_true) ca_level = ca;
|
||||
ca_true = 0;
|
||||
}
|
||||
ca++;
|
||||
}
|
||||
|
||||
hendc() /* [vlh] */
|
||||
{
|
||||
if (!ca) {
|
||||
xerr(25); /* unexpected endc */
|
||||
return;
|
||||
}
|
||||
ca--;
|
||||
if (!ca_true)
|
||||
if (ca_level == ca) ca_true = 1;
|
||||
igrst();
|
||||
}
|
||||
hpage()
|
||||
{
|
||||
opitb(); /* Output beginning */
|
||||
wostb(); /* Write out buffer */
|
||||
igrst(); /* Ignore rest of line */
|
||||
}
|
||||
spage()
|
||||
{
|
||||
print(0); /* Print the directive */
|
||||
xline = LPP; /* Force page on next print */
|
||||
page();
|
||||
}
|
||||
acok()
|
||||
{
|
||||
expr(&p1gi);
|
||||
if (itype != ITCN) {
|
||||
xerr(7); /* must be a constant */
|
||||
return(0);
|
||||
}
|
||||
if (reloc != ABS) {
|
||||
xerr(11); /* must be absolute, no forward references */
|
||||
return(0);
|
||||
}
|
||||
igrst();
|
||||
return(1);
|
||||
}
|
||||
|
||||
cmp_ops()
|
||||
{
|
||||
char str1[25], str2[25];
|
||||
register int len1, len2;
|
||||
|
||||
if (fchr != '\'') { xerr(9); return(0); }
|
||||
len1 = len2 = 0;
|
||||
while (fchr = gchr()) {
|
||||
if (fchr == '\'') break;
|
||||
if (fchr == EOLC) return(0);
|
||||
str1[len1++] = fchr;
|
||||
}
|
||||
if ((fchr=gchr()) != ',') { xerr(9); return; }
|
||||
if ((fchr=gchr()) != '\'') { xerr(10); return;}
|
||||
while (fchr = gchr()) {
|
||||
if (fchr == '\'') break;
|
||||
if (fchr == EOLC) return(0);
|
||||
str2[len2++] = fchr;
|
||||
}
|
||||
igrst();
|
||||
if (len1 != len2) return(0);
|
||||
str1[len1] = str2[len2] = NULL;
|
||||
if (strcmp(str1,str2) == 0) return(1);
|
||||
return(0);
|
||||
}
|
||||
|
||||
strcmp(s,t)
|
||||
register char *s, *t;
|
||||
{
|
||||
for( ; *s == *t; s++, t++ )
|
||||
if( *s == '\0' )
|
||||
return(0);
|
||||
return( *s - *t );
|
||||
}
|
||||
950
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/as68/dir.lis
Normal file
950
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/as68/dir.lis
Normal file
@@ -0,0 +1,950 @@
|
||||
1File: DIR.C Page 1
|
||||
1 /*
|
||||
2 Copyright 1981
|
||||
3 Alcyon Corporation
|
||||
4 8716 Production Ave.
|
||||
5 San Diego, Ca. 92121
|
||||
6 */
|
||||
7
|
||||
8 /* Pass 1 and pass 2 directive handling routines */
|
||||
9 /* code to handle conditional assembly directives */
|
||||
10
|
||||
11 #include "as68.h"
|
||||
12 #include "cout.h"
|
||||
13
|
||||
14 long lseek();
|
||||
15 int p1gi();
|
||||
16 int p2gi();
|
||||
17 int igrst();
|
||||
18
|
||||
19 /*directive to define an opcode*/
|
||||
20 hopd()
|
||||
21 {
|
||||
22
|
||||
23 if(!lbt[0]) {
|
||||
24 xerr(4); /*no label*/
|
||||
25 return;
|
||||
26 }
|
||||
27 setname(); /*move label into main table*/
|
||||
28 if((lblpt=lemt(oirt,TRUE))!=lmte) {
|
||||
29 xerr(5); /*opcode redefined*/
|
||||
30 return;
|
||||
31 }
|
||||
32 mmte(); /*make main table entry*/
|
||||
33 expr(&p1gi); /*get instruction format*/
|
||||
34 if(itype!=ITCN || ival<0 || ival>OPFF) {
|
||||
35 xerr(18); /*illegal format specifier*/
|
||||
36 return;
|
||||
37 }
|
||||
38 lblpt->flags =| ival|SYIN; /*remember format*/
|
||||
39 if(fchr != ',') { /*field separator*/
|
||||
40 xerr(10);
|
||||
41 return;
|
||||
42 }
|
||||
43 expr(&p1gi); /*get opcode value*/
|
||||
44 if(itype != ITCN) {
|
||||
45 xerr(17); /*not a constant*/
|
||||
46 return;
|
||||
47 }
|
||||
48 lblpt->vl1 = ival; /*put value in main table*/
|
||||
49 igrst(); /*ignore rest of statement-comment*/
|
||||
50 }
|
||||
51
|
||||
52 /* equate directive*/
|
||||
53 hequ()
|
||||
54 {
|
||||
55 if(lbt[0] == 0) {
|
||||
56 xerr(4); /*no label*/
|
||||
57 return;
|
||||
58 }
|
||||
59 setname();
|
||||
1File: DIR.C Page 2
|
||||
60 if((lblpt=lemt(sirt,FALSE))!=lmte) { /*aready there*/
|
||||
61 if(lbt[0] == '~') { /*local symbol*/
|
||||
62 lblpt = lmte;
|
||||
63 mmte();
|
||||
64 }
|
||||
65 }
|
||||
66 else
|
||||
67 mmte();
|
||||
68 if(lblpt->flags&SYXR) {
|
||||
69 xerr(29);
|
||||
70 return;
|
||||
71 }
|
||||
72 lblpt->flags =| SYDF|SYEQ; /*defined & equate*/
|
||||
73 equflg = 1;
|
||||
74 modelen = 4;
|
||||
75 expr(&p1gi);
|
||||
76 equflg = 0;
|
||||
77 if(itype == ITSY && ival.ptrw2->flags&SYER) {
|
||||
78 lblpt->flags =| SYER; /*equated register*/
|
||||
79 ival = ival.ptrw2->vl1;
|
||||
80 }
|
||||
81 else if(itype != ITCN) {
|
||||
82 xerr(7); /*not a constant*/
|
||||
83 return;
|
||||
84 }
|
||||
85 if (inoffset && reloc != ABS) { /* [vlh] */
|
||||
86 xerr(11);
|
||||
87 return;
|
||||
88 }
|
||||
89 if(initflg) /*doing symbol table initialization*/
|
||||
90 lblpt->flags =| SYIN; /*internal symbol*/
|
||||
91 lblpt->vl1 = ival;
|
||||
92 if(reloc == DATA) /*check relocation*/
|
||||
93 {
|
||||
94 lblpt->flags =| SYRA; /*DATA relocatable*/
|
||||
95 }
|
||||
96 else if(reloc == TEXT)
|
||||
97 lblpt->flags =| SYRO; /*TEXT relocatable*/
|
||||
98 else if(reloc == BSS)
|
||||
99 lblpt->flags =| SYBS; /*BSS relocatable*/
|
||||
100 else if(fchr==',' && (fchr=gchr())=='r')
|
||||
101 lblpt->flags =| SYER; /*equated register*/
|
||||
102 if (refpc) /*[vlh] flag directive is pc relative */
|
||||
103 lblpt->flags =| SYPC;
|
||||
104 igrst();
|
||||
105 }
|
||||
106
|
||||
107 /* process dsect directive*/
|
||||
108 hdsect()
|
||||
109 {
|
||||
110 dorlst(DATA);
|
||||
111 }
|
||||
112
|
||||
113 dorlst(xrtyp)
|
||||
114 {
|
||||
115 inoffset = 0; /* [vlh] offset mode terminated my sect directive */
|
||||
116 chkeven(); /* May need to make pc even */
|
||||
117 dlabl(); /*define label on old base if there is one*/
|
||||
118 savelc[rlflg] = loctr; /*save old base relocation*/
|
||||
1File: DIR.C Page 3
|
||||
119 rlflg = xrtyp;
|
||||
120 loctr = savelc[xrtyp]; /*set new base relocation ctr*/
|
||||
121 opitb();
|
||||
122 stbuf[0].itrl = itwc;
|
||||
123 wostb();
|
||||
124 igrst();
|
||||
125 }
|
||||
126
|
||||
127 /*process psect directive*/
|
||||
128 hpsect()
|
||||
129 {
|
||||
130 dorlst(TEXT);
|
||||
131 }
|
||||
132
|
||||
133 hbss()
|
||||
134 {
|
||||
135 dorlst(BSS);
|
||||
136 }
|
||||
137
|
||||
138 /*make pc even*/
|
||||
139 heven()
|
||||
140 {
|
||||
141 modelen = 2; /*Try to figure this one out...*/
|
||||
142 if(loctr&1) { /*have to make it even*/
|
||||
143 dorlst(rlflg);
|
||||
144 }
|
||||
145 else {
|
||||
146 igrst();
|
||||
147 }
|
||||
148 }
|
||||
149
|
||||
150 /*process globl directive*/
|
||||
151 hent()
|
||||
152 {
|
||||
153 while(1) {
|
||||
154 gterm(TRUE); /*get entry symbol*/
|
||||
155 if(itype!=ITSY) { /*error if not symbol*/
|
||||
156 xerr(28);
|
||||
157 return;
|
||||
158 }
|
||||
159 if((lblpt=lemt(sirt,FALSE)) == lmte) /*look up in main table*/
|
||||
160 mmte(); /*not there, make new entry*/
|
||||
161 else
|
||||
162 if(lblpt->flags&SYER) /*already there*/
|
||||
163 uerr(29);
|
||||
164 lblpt->flags =| SYGL; /*symbol is an entry*/
|
||||
165 if(lblpt->flags&SYXR) { /*been thru hext code*/
|
||||
166 lblpt->flags =& ~(SYXR|SYDF); /*reset for init of .comm*/
|
||||
167 }
|
||||
168 if (inoffset && reloc != ABS) { /* [vlh] */
|
||||
169 xerr(11);
|
||||
170 return;
|
||||
171 }
|
||||
172 if(fchr == ',') /*skip ',' between entries*/
|
||||
173 fchr = gchr();
|
||||
174 else {
|
||||
175 igrst(); /*statement finished*/
|
||||
176 return;
|
||||
177 }
|
||||
1File: DIR.C Page 4
|
||||
178 }
|
||||
179 }
|
||||
180
|
||||
181 /*process comm directive*/
|
||||
182 hext()
|
||||
183 {
|
||||
184 gterm(TRUE); /*get external symbol*/
|
||||
185 if(itype!=ITSY) { /*error if not symbol*/
|
||||
186 xerr(28);
|
||||
187 return;
|
||||
188 }
|
||||
189 if((lblpt=lemt(sirt,FALSE)) == lmte) /*look up in main table*/
|
||||
190 mmte(); /*not there, make new entry*/
|
||||
191 else
|
||||
192 if(lblpt->flags&SYDF && (lblpt->flags&SYXR)==0) /*already there*/
|
||||
193 uerr(29);
|
||||
194 lblpt->flags =| SYXR | SYDF; /*symbol is an external*/
|
||||
195 mkextidx(lblpt); /*put into external table*/
|
||||
196 if(fchr == ',') { /*skip ',' between operands*/
|
||||
197 fchr = gchr();
|
||||
198 gterm(TRUE);
|
||||
199 if(itype != ITCN) {
|
||||
200 xerr(17);
|
||||
201 return;
|
||||
202 }
|
||||
203 lblpt->vl1.wd1 = ival; /* # bytes of storage required*/
|
||||
204 }
|
||||
205 else
|
||||
206 lblpt->vl1.wd1 = 1; /* default # bytes*/
|
||||
207 igrst();
|
||||
208 }
|
||||
209
|
||||
210 mkextidx(p)
|
||||
211 struct symtab *p;
|
||||
212 {
|
||||
213
|
||||
214 if(extindx >= EXTSZ) { /*check for overflow of external symbol tbl*/
|
||||
215 rpterr("overflow of external table\n");
|
||||
216 endit();
|
||||
217 }
|
||||
218 p->vl1.wd2 = pexti - extbl; /* external symbol index #*/
|
||||
219 *pexti++ = p; /*save external in external table*/
|
||||
220 extindx++;
|
||||
221 }
|
||||
222
|
||||
223 /* end statement*/
|
||||
224 hend()
|
||||
225 {
|
||||
226 register short i;
|
||||
227 register int j;
|
||||
228
|
||||
229 inoffset = 0; /*[vlh] turn off inoffset mode*/
|
||||
230 lblpt = 0; /*no label*/
|
||||
231 opitb(); /*output beginning of statement*/
|
||||
232 igrst(); /* [vlh] ignore operands */
|
||||
233 stbuf[0].itrl = itwc; /*number of it entries*/
|
||||
234 wostb(); /*write out statement buffer*/
|
||||
235 for(i=0; i<ITBSZ; i++)
|
||||
236 doitwr(0);
|
||||
1File: DIR.C Page 5
|
||||
237 if(initflg) {
|
||||
238 putsymtab();
|
||||
239 printf("68000 assembler initialized\n");
|
||||
240 endit();
|
||||
241 }
|
||||
242 if((fchr=gchr())!=EOF) {
|
||||
243 rpterr("end statement not at end of source\n");
|
||||
244 }
|
||||
245 savelc[rlflg] = loctr; /*last location on current reloc base*/
|
||||
246 fixunds(); /*make golbals and maybe undefineds external*/
|
||||
247 if(!didorg) /*did not assign to location counter*/
|
||||
248 pass1a(); /*resolve short branches*/
|
||||
249 pass2(); /*assembler pass 2*/
|
||||
250 }
|
||||
251
|
||||
252 /* define storage given number of bytes*/
|
||||
253 hds()
|
||||
254 {
|
||||
255 dlabl(); /*define label maybe*/
|
||||
256 if (!inoffset) /* [vlh] */
|
||||
257 opitb(); /*output it for beginning of statement*/
|
||||
258 refpc = 0;
|
||||
259 expr(&p1gi);
|
||||
260 if(itype!=ITCN) {
|
||||
261 xerr(17); /*must be constant*/
|
||||
262 return;
|
||||
263 }
|
||||
264 if(reloc != ABS) {
|
||||
265 xerr(9); /*must be absolute*/
|
||||
266 return;
|
||||
267 }
|
||||
268 if (!inoffset) { /* [vlh] don't generate it if in offset */
|
||||
269 opitoo(); /*output one operand*/
|
||||
270 stbuf[0].itrl = itwc;
|
||||
271 wostb(); /*write out statement buffer*/
|
||||
272 loctr =+ (ival*modelen);
|
||||
273 }
|
||||
274 igrst();
|
||||
275 }
|
||||
276
|
||||
277 /* make pc even if necessary for .dc and .ds */
|
||||
278 chkeven()
|
||||
279 {
|
||||
280 register char *pi;
|
||||
281
|
||||
282 if(modelen>1 && loctr&1) {
|
||||
283 pi = opcpt;
|
||||
284 opcpt = evenptr;
|
||||
285 opitb();
|
||||
286 stbuf[0].itrl = itwc;
|
||||
287 wostb();
|
||||
288 opcpt = pi;
|
||||
289 loctr++;
|
||||
290 }
|
||||
291 }
|
||||
292
|
||||
293 /* define byte directive*/
|
||||
294 hdc()
|
||||
295 {
|
||||
1File: DIR.C Page 6
|
||||
296 chkeven();
|
||||
297 hdata(modelen);
|
||||
298 }
|
||||
299
|
||||
300 /*
|
||||
301 * define bytes or words of data
|
||||
302 * call with:
|
||||
303 * 1 => defining bytes
|
||||
304 * 2 => defining words
|
||||
305 * 4 => defining long words
|
||||
306 */
|
||||
307 hdata(mul)
|
||||
308 {
|
||||
309 dlabl(); /*define label*/
|
||||
310 opitb(); /*beginning of statement*/
|
||||
311 numops = 0; /*initialize count for number of operands*/
|
||||
312 opito(); /*output it for operands*/
|
||||
313 stbuf[0].itrl = itwc; /* # of it entries*/
|
||||
314 wostb(); /*write out statement buffer*/
|
||||
315 loctr =+ numops*mul; /* count by bytes or words*/
|
||||
316 }
|
||||
317
|
||||
318 /* handle org statement*/
|
||||
319 horg()
|
||||
320 {
|
||||
321 register i;
|
||||
322
|
||||
323 if(rlflg==TEXT && loctr!=0)
|
||||
324 didorg++; /*can't do branch optimization as separate pass now*/
|
||||
325 expr(&p1gi); /*value of new relocation counter*/
|
||||
326 if(reloc != rlflg && reloc != ABS) {
|
||||
327 xerr(27);
|
||||
328 return;
|
||||
329 }
|
||||
330 if(ival < loctr) {
|
||||
331 xerr(40); /*trying to go backwards*/
|
||||
332 return;
|
||||
333 }
|
||||
334 opcpt = orgptr; /*org directive for pass 2*/
|
||||
335 opitb();
|
||||
336 opitoo();
|
||||
337 stbuf[0].itrl = itwc;
|
||||
338 wostb();
|
||||
339 loctr = ival;
|
||||
340 dlabl(); /*define label*/
|
||||
341 }
|
||||
342
|
||||
343 /* Assemble for mask2 (R9M), ignore... */
|
||||
344 hmask2() /* [vlh] */
|
||||
345 {
|
||||
346 igrst();
|
||||
347 }
|
||||
348
|
||||
349 /* Define register list */
|
||||
350 hreg() /* [vlh] */
|
||||
351 {
|
||||
352 int mask;
|
||||
353 if(lbt[0]==0) {
|
||||
354 xerr(4); /*no label*/
|
||||
1File: DIR.C Page 7
|
||||
355 return;
|
||||
356 }
|
||||
357 setname(); /*move label into main table*/
|
||||
358 if((lblpt=lemt(sirt,FALSE))!=lmte) {
|
||||
359 xerr(5); /*opcode redefined*/
|
||||
360 return;
|
||||
361 }
|
||||
362 if (inoffset)
|
||||
363 if (reloc != ABS) {
|
||||
364 xerr(11);
|
||||
365 return;
|
||||
366 }
|
||||
367 mmte(); /*make main table entry*/
|
||||
368 if ((mask = mkmask()) == -1) {
|
||||
369 xerr(6);
|
||||
370 return;
|
||||
371 }
|
||||
372 lblpt->flags =| SYDF|SYEQ|SYRM; /* register mask, defined & equated */
|
||||
373 lblpt->vl1 = mask;
|
||||
374 igrst();
|
||||
375 }
|
||||
376
|
||||
377 int regmsk[] {0100000,040000,020000,010000,04000,02000,01000,0400,0200,
|
||||
378 0100,040,020,010,4,2,1};
|
||||
379 /* make a register mask for the reg routine */
|
||||
380 mkmask() /* [vlh] */
|
||||
381 {
|
||||
382 register int *p, i, j, mask;
|
||||
383
|
||||
384 p = ®msk; mask = 0;
|
||||
385 while ((i = chkreg()) != -1) {
|
||||
386 if (fchr == '-') {
|
||||
387 fchr = gchr();
|
||||
388 if ((j = chkreg()) == -1) {
|
||||
389 xerr(40);
|
||||
390 return(-1);
|
||||
391 }
|
||||
392 while (i <= j)
|
||||
393 mask =| p[i++];
|
||||
394 }
|
||||
395 else mask =| p[i];
|
||||
396 if (fchr != '/' && fchr != ',') break; /*[vlh] Signetics fix*/
|
||||
397 fchr = gchr();
|
||||
398 }
|
||||
399 return(mask);
|
||||
400 }
|
||||
401
|
||||
402 /* get a register # from file, return -1 if none or illegal */
|
||||
403 chkreg() /* [vlh] */
|
||||
404 {
|
||||
405 register int i, j;
|
||||
406
|
||||
407 i = j = 0;
|
||||
408 if (fchr == 'a' || fchr == 'A')
|
||||
409 i = 8;
|
||||
410 else if (fchr != 'd' && fchr != 'r' && fchr != 'D' && fchr != 'R')
|
||||
411 return(-1);
|
||||
412 fchr = gchr();
|
||||
413 do {
|
||||
1File: DIR.C Page 8
|
||||
414 j = (j*10) + (fchr - '0');
|
||||
415 fchr = gchr();
|
||||
416 } while (isdigit(fchr));
|
||||
417 if (j < 0 || j > AREGHI) return(-1);
|
||||
418 i =+ j;
|
||||
419 if (i >= 0 && i <= AREGHI) return(i);
|
||||
420 else return(-1);
|
||||
421 }
|
||||
422
|
||||
423 /* Define constant block */
|
||||
424 hdcb() /* [vlh] */
|
||||
425 {
|
||||
426 chkeven(); /* on even boundary if not byte block. */
|
||||
427 dlabl(); /* define label... */
|
||||
428 opitb();
|
||||
429 opito();
|
||||
430 stbuf[0].itrl = itwc;
|
||||
431 numops = stbuf[ITOP1].itop;
|
||||
432 loctr =+ numops * modelen;
|
||||
433 wostb(); /* write out statement buffer */
|
||||
434 }
|
||||
435
|
||||
436 /* Command line, similar to ds.b */
|
||||
437 hcomline() /* [vlh] */
|
||||
438 {
|
||||
439 dlabl(); /*define label maybe*/
|
||||
440 modelen = 1; /* byte store... */
|
||||
441 opitb(); /*output it for beginning of statement*/
|
||||
442 refpc = 0;
|
||||
443 expr(&p1gi);
|
||||
444 if(itype!=ITCN) {
|
||||
445 xerr(17); /*must be constant*/
|
||||
446 return;
|
||||
447 }
|
||||
448 if(reloc != ABS) {
|
||||
449 xerr(9); /*must be absolute*/
|
||||
450 return;
|
||||
451 }
|
||||
452 opitoo(); /*output one operand*/
|
||||
453 stbuf[0].itrl = itwc;
|
||||
454 wostb(); /*write out statement buffer*/
|
||||
455 loctr =+ ival;
|
||||
456 igrst();
|
||||
457 }
|
||||
458
|
||||
459 /* Relocateable id record, ignore */
|
||||
460 hidnt() /* [vlh] */
|
||||
461 {
|
||||
462 igrst();
|
||||
463 }
|
||||
464
|
||||
465 /* Define offsets */
|
||||
466 hoffset() /* [vlh] */
|
||||
467 {
|
||||
468 inoffset = 1;
|
||||
469 expr(&p1gi); /* get new location counter */
|
||||
470 if (itype != ITCN) {
|
||||
471 xerr(17); /* constant required */
|
||||
472 return;
|
||||
1File: DIR.C Page 9
|
||||
473 }
|
||||
474 if (reloc != ABS) {
|
||||
475 xerr(9); /* must be absolute */
|
||||
476 return;
|
||||
477 }
|
||||
478 loctr = ival;
|
||||
479 igrst();
|
||||
480 }
|
||||
481
|
||||
482 /* define sections: map to bss, text and data */
|
||||
483 hsection() /* [vlh] */
|
||||
484 {
|
||||
485 inoffset = 0; /* reseting section turns off offset mode */
|
||||
486 dlabl(); /* define label on old base if there is one */
|
||||
487 savelc[rlflg] = loctr; /* save old base relocation */
|
||||
488 opitb(); /* intermediate table... */
|
||||
489 expr(&p1gi); /* get section # */
|
||||
490 if (itype != ITCN) {
|
||||
491 xerr(17); /* must be a constant */
|
||||
492 return;
|
||||
493 }
|
||||
494 if (ival > 15 || ival < 0) {
|
||||
495 xerr(9); /* proper range 0..15 */
|
||||
496 return;
|
||||
497 }
|
||||
498 if (ival==14) rlflg = DATA;
|
||||
499 else if (ival==15) rlflg = BSS;
|
||||
500 else rlflg = TEXT;
|
||||
501 loctr = savelc[rlflg];
|
||||
502 stbuf[3].itop = loctr; /* pass 1 location counter */
|
||||
503 stbuf[3].itrl = rlflg; /* relocation base */
|
||||
504 stbuf[0].itrl = itwc;
|
||||
505 wostb();
|
||||
506 igrst();
|
||||
507 }
|
||||
508
|
||||
509 /* hopt -- ignore, set up assembler options */
|
||||
510 hopt() /* vlh */
|
||||
511 {
|
||||
512 igrst();
|
||||
513 }
|
||||
514
|
||||
515 /**** Second pass directive handling routines ****/
|
||||
516
|
||||
517 /* second pass end statement*/
|
||||
518 send()
|
||||
519 {
|
||||
520 register int i;
|
||||
521
|
||||
522 savelc[rlflg] = loctr;
|
||||
523 if(savelc[TEXT]&1) {
|
||||
524 rlflg = TEXT;
|
||||
525 outbyte(0,DABS);
|
||||
526 savelc[TEXT]++;
|
||||
527 }
|
||||
528 if(savelc[DATA]&1) {
|
||||
529 rlflg = DATA;
|
||||
530 outbyte(0,DABS);
|
||||
531 savelc[DATA]++;
|
||||
1File: DIR.C Page 10
|
||||
532 }
|
||||
533 if(savelc[BSS]&1) {
|
||||
534 savelc[BSS]++;
|
||||
535 }
|
||||
536
|
||||
537 ival = 0;
|
||||
538 reloc = ABS;
|
||||
539 ckeop(9);
|
||||
540 print(0);
|
||||
541 cpdata(); /*copy data to loader file*/
|
||||
542 osymt(); /*output symbol table*/
|
||||
543 myfflush(&tbuf); /*flush text relocation bits*/
|
||||
544 cprlbits(); /*copy relocation bits*/
|
||||
545 myfflush(&lbuf);
|
||||
546 i = (sizeof couthd.ch_magic) + 3*(sizeof couthd.ch_tsize);
|
||||
547 if((lseek(lfn,(long)i,0) == -1) || write(lfn,&stlen,4) != 4)
|
||||
548 rpterr("I/O error on loader output file\n");
|
||||
549 endit(); /*end*/
|
||||
550 }
|
||||
551
|
||||
552 /*second pass define storage - ds*/
|
||||
553 sds()
|
||||
554 {
|
||||
555 print(0);
|
||||
556 if(rlflg == TEXT || rlflg==DATA) {
|
||||
557 expr(&p2gi);
|
||||
558 if(itype != ITCN) {
|
||||
559 uerr(13);
|
||||
560 return;
|
||||
561 }
|
||||
562 ival =* modelen;
|
||||
563 while(ival) {
|
||||
564 outbyte(0,DABS);
|
||||
565 loctr++;
|
||||
566 ival--;
|
||||
567 }
|
||||
568 }
|
||||
569 else
|
||||
570 loctr =+ stbuf[ITOP1].itop*modelen; /*reserve storage*/
|
||||
571 }
|
||||
572
|
||||
573 /* second pass - define block storage, initialized */
|
||||
574 sdcb() /* [vlh] */
|
||||
575 {
|
||||
576 register int pfg, i, hflg, len;
|
||||
577
|
||||
578 expr(&p2gi);
|
||||
579 if (itype != ITCN || reloc != ABS) {
|
||||
580 uerr(13); /* must be absolute constant */
|
||||
581 return;
|
||||
582 }
|
||||
583 len = ival;
|
||||
584 expr(&p2gi);
|
||||
585 if (modelen==1 && (ival<-128 || ival>=256 || reloc != ABS)) {
|
||||
586 uerr(20);
|
||||
587 ival = 0;
|
||||
588 reloc = ABS;
|
||||
589 }
|
||||
590 while (len--) {
|
||||
1File: DIR.C Page 11
|
||||
591 if (modelen==1) {
|
||||
592 if (!hflg) {
|
||||
593 ins[i].hibyte = ival;
|
||||
594 outbyte(ival.wd2,DABS);
|
||||
595 hflg++;
|
||||
596 }
|
||||
597 else {
|
||||
598 ins[i++].lobyte = ival;
|
||||
599 outbyte(ival.wd2,DABS);
|
||||
600 hflg=0;
|
||||
601 }
|
||||
602 goto sdbl2;
|
||||
603 }
|
||||
604 else if (modelen==2) {
|
||||
605 sdbl1:
|
||||
606 ins[i++] = ival.wd2;
|
||||
607 outword(ival.wd2, reloc);
|
||||
608 sdbl2:
|
||||
609 if (i>3) {
|
||||
610 instrlen = i*2;
|
||||
611 print ((pfg++) ? 2 : 1);
|
||||
612 loctr =+ instrlen;
|
||||
613 i=0;
|
||||
614 }
|
||||
615 }
|
||||
616 else { /* long word... */
|
||||
617 ins[i++] = ival.wd1;
|
||||
618 outword(ival.wd1,LUPPER);
|
||||
619 goto sdbl1;
|
||||
620 }
|
||||
621 }
|
||||
622 if (i) { /* more printing */
|
||||
623 instrlen = i*2 - hflg;
|
||||
624 print ((pfg) ? 2 : 1);
|
||||
625 loctr =+ instrlen;
|
||||
626 }
|
||||
627 }
|
||||
628
|
||||
629 /*second pass data*/
|
||||
630 sdsect()
|
||||
631 {
|
||||
632 savelc[rlflg] = loctr;
|
||||
633 rlflg = DATA;
|
||||
634 loctr = savelc[DATA];
|
||||
635 print(0); /*print the new location counter*/
|
||||
636 }
|
||||
637
|
||||
638 /*second pass text*/
|
||||
639 spsect()
|
||||
640 {
|
||||
641 savelc[rlflg] = loctr;
|
||||
642 rlflg = TEXT;
|
||||
643 loctr = savelc[TEXT];
|
||||
644 print(0); /*print the new location counter*/
|
||||
645 }
|
||||
646
|
||||
647 sbss()
|
||||
648 {
|
||||
649 savelc[rlflg] = loctr;
|
||||
1File: DIR.C Page 12
|
||||
650 rlflg = BSS;
|
||||
651 loctr = savelc[BSS];
|
||||
652 print(0); /*print the new location counter*/
|
||||
653 }
|
||||
654
|
||||
655 /* make loctr even*/
|
||||
656 seven()
|
||||
657 {
|
||||
658 if(loctr&1) {
|
||||
659 if(rlflg==TEXT || rlflg==DATA)
|
||||
660 outbyte(0,DABS);
|
||||
661 loctr++;
|
||||
662 }
|
||||
663 print(0);
|
||||
664 }
|
||||
665
|
||||
666 /* second pass org*/
|
||||
667 sorg()
|
||||
668 {
|
||||
669 long l;
|
||||
670
|
||||
671 if(rlflg==TEXT || rlflg==DATA) { /*must put out zeros*/
|
||||
672 l = stbuf[ITOP1].itop - loctr; /*# zeroes to output*/
|
||||
673 ins[0] = 0;
|
||||
674 print(1);
|
||||
675 while(l > 0) {
|
||||
676 outbyte(0,DABS);
|
||||
677 loctr++;
|
||||
678 l--;
|
||||
679 }
|
||||
680 }
|
||||
681 else { /*BSS*/
|
||||
682 loctr = stbuf[ITOP1].itop; /*new location counter*/
|
||||
683 print(0);
|
||||
684 }
|
||||
685 }
|
||||
686
|
||||
687 /*
|
||||
688 *second pass define data (words or bytes)
|
||||
689 * call with
|
||||
690 * 2 => defining words
|
||||
691 * 1 => defining bytes
|
||||
692 * 4 => defining long words
|
||||
693 */
|
||||
694 sdata(dtyp)
|
||||
695 {
|
||||
696 register pfg,i;
|
||||
697 register hflg;
|
||||
698
|
||||
699 hflg = i = pfg = 0;
|
||||
700 while(1) {
|
||||
701 expr(&p2gi); /*evaluate expression*/
|
||||
702 if(pitw < pnite)
|
||||
703 pitw--; /*expr passed a token*/
|
||||
704 if(itype!=ITCN && reloc != EXTRN) { /*must be constant*/
|
||||
705 uerr(13);
|
||||
706 ival=0;
|
||||
707 reloc = ABS;
|
||||
708 }
|
||||
1File: DIR.C Page 13
|
||||
709 if(reloc == EXTRN)
|
||||
710 reloc = (extref<<3)|EXTVAR; /*gen extern reference*/
|
||||
711 if(dtyp==1) { /*defining a byte*/
|
||||
712 if(ival<-128 || ival>=256 || reloc!=ABS) { /*not a byte*/
|
||||
713 uerr(20);
|
||||
714 ival=0;
|
||||
715 reloc = ABS;
|
||||
716 }
|
||||
717 if(!hflg) {
|
||||
718 ins[i].hibyte = ival;
|
||||
719 outbyte(ival.wd2,DABS);
|
||||
720 hflg++;
|
||||
721 }
|
||||
722 else {
|
||||
723 ins[i++].lobyte = ival;
|
||||
724 hflg = 0;
|
||||
725 outbyte(ival.wd2,DABS);
|
||||
726 }
|
||||
727 goto sdal2;
|
||||
728 }
|
||||
729 else if(dtyp == 2) { /*defining a word*/
|
||||
730 sdal1:
|
||||
731 ins[i++] = ival.wd2;
|
||||
732 outword(ival.wd2, reloc);
|
||||
733 sdal2:
|
||||
734 if(i>3) {
|
||||
735 instrlen = i*2;
|
||||
736 print ((pfg++) ? 2 : 1);
|
||||
737 loctr =+ instrlen;
|
||||
738 i=0;
|
||||
739 }
|
||||
740 }
|
||||
741 else { /*long words*/
|
||||
742 ins[i++] = ival.wd1;
|
||||
743 outword(ival.wd1,LUPPER);
|
||||
744 goto sdal1;
|
||||
745 }
|
||||
746 if(!ckeop(15)) /*should be end of operand*/
|
||||
747 return;
|
||||
748 pitw++;
|
||||
749 if(ckein()) {
|
||||
750 if(hflg) {
|
||||
751 ins[i++].lobyte = 0;
|
||||
752 }
|
||||
753 if(i) { /*more printing*/
|
||||
754 instrlen = i*2 - hflg;
|
||||
755 print ((pfg) ? 2 : 1);
|
||||
756 loctr =+ instrlen;
|
||||
757 }
|
||||
758 return;
|
||||
759 }
|
||||
760 }
|
||||
761 }
|
||||
762
|
||||
763 sdc()
|
||||
764 {
|
||||
765 sdata(modelen);
|
||||
766 }
|
||||
767
|
||||
1File: DIR.C Page 14
|
||||
768 ssection() /* [vlh] */
|
||||
769 {
|
||||
770 int sect;
|
||||
771
|
||||
772 sect = stbuf[3].itrl;
|
||||
773 if (sect==DATA) sdsect();
|
||||
774 else if (sect==BSS) sbss();
|
||||
775 else spsect();
|
||||
776 }
|
||||
777
|
||||
778 /*define word statement*/
|
||||
779 sdw()
|
||||
780 {
|
||||
781 sdata(0); /*defining words*/
|
||||
782 }
|
||||
783 /**** Conditional assembly directives ****/
|
||||
784
|
||||
785 hifeq() /* [vlh] */
|
||||
786 {
|
||||
787 if (!acok()) return;
|
||||
788 if (ival) {
|
||||
789 if (ca_true) ca_level = ca;
|
||||
790 ca_true = 0;
|
||||
791 }
|
||||
792 ca++;
|
||||
793 }
|
||||
794
|
||||
795 hifne() /* [vlh] */
|
||||
796 {
|
||||
797 if (!acok()) return;
|
||||
798 if (!ival) {
|
||||
799 if (ca_true) ca_level = ca;
|
||||
800 ca_true = 0;
|
||||
801 }
|
||||
802 ca++;
|
||||
803 }
|
||||
804
|
||||
805 hiflt() /* [vlh] */
|
||||
806 {
|
||||
807 if (!acok()) return;
|
||||
808 if (ival >= 0) {
|
||||
809 if (ca_true) ca_level = ca;
|
||||
810 ca_true = 0;
|
||||
811 }
|
||||
812 ca++;
|
||||
813 }
|
||||
814
|
||||
815 hifle() /* [vlh] */
|
||||
816 {
|
||||
817 if (!acok()) return;
|
||||
818 if (ival > 0) {
|
||||
819 if (ca_true) ca_level = ca;
|
||||
820 ca_true = 0;
|
||||
821 }
|
||||
822 ca++;
|
||||
823 }
|
||||
824
|
||||
825 hifgt() /* [vlh] */
|
||||
826 {
|
||||
1File: DIR.C Page 15
|
||||
827 if (!acok()) return;
|
||||
828 if (ival <= 0) {
|
||||
829 if (ca_true) ca_level = ca;
|
||||
830 ca_true = 0;
|
||||
831 }
|
||||
832 ca++;
|
||||
833 }
|
||||
834
|
||||
835 hifge() /* [vlh] */
|
||||
836 {
|
||||
837 if (!acok()) return;
|
||||
838 if (ival < 0) {
|
||||
839 if (ca_true) ca_level = ca;
|
||||
840 ca_true = 0;
|
||||
841 }
|
||||
842 ca++;
|
||||
843 }
|
||||
844
|
||||
845 hifc() /* [vlh] */
|
||||
846 {
|
||||
847 if (!cmp_ops()) {
|
||||
848 if (ca_true) ca_level = ca;
|
||||
849 ca_true = 0;
|
||||
850 }
|
||||
851 ca++;
|
||||
852 }
|
||||
853
|
||||
854 hifnc() /* [vlh] */
|
||||
855 {
|
||||
856 if (cmp_ops()) {
|
||||
857 if (ca_true) ca_level = ca;
|
||||
858 ca_true = 0;
|
||||
859 }
|
||||
860 ca++;
|
||||
861 }
|
||||
862
|
||||
863 hendc() /* [vlh] */
|
||||
864 {
|
||||
865 if (!ca) {
|
||||
866 xerr(25); /* unexpected endc */
|
||||
867 return;
|
||||
868 }
|
||||
869 ca--;
|
||||
870 if (!ca_true)
|
||||
871 if (ca_level == ca) ca_true = 1;
|
||||
872 igrst();
|
||||
873 }
|
||||
874 hpage()
|
||||
875 {
|
||||
876 opitb(); /* Output beginning */
|
||||
877 wostb(); /* Write out buffer */
|
||||
878 igrst(); /* Ignore rest of line */
|
||||
879 }
|
||||
880 spage()
|
||||
881 {
|
||||
882 print(0); /* Print the directive */
|
||||
883 xline = LPP; /* Force page on next print */
|
||||
884 page();
|
||||
885 }
|
||||
1File: DIR.C Page 16
|
||||
886 acok()
|
||||
887 {
|
||||
888 expr(&p1gi);
|
||||
889 if (itype != ITCN) {
|
||||
890 xerr(7); /* must be a constant */
|
||||
891 return(0);
|
||||
892 }
|
||||
893 if (reloc != ABS) {
|
||||
894 xerr(11); /* must be absolute, no forward references */
|
||||
895 return(0);
|
||||
896 }
|
||||
897 igrst();
|
||||
898 return(1);
|
||||
899 }
|
||||
900
|
||||
901 cmp_ops()
|
||||
902 {
|
||||
903 char str1[25], str2[25];
|
||||
904 register int len1, len2;
|
||||
905
|
||||
906 if (fchr != '\'') { xerr(9); return(0); }
|
||||
907 len1 = len2 = 0;
|
||||
908 while (fchr = gchr()) {
|
||||
909 if (fchr == '\'') break;
|
||||
910 if (fchr == EOLC) return(0);
|
||||
911 str1[len1++] = fchr;
|
||||
912 }
|
||||
913 if ((fchr=gchr()) != ',') { xerr(9); return; }
|
||||
914 if ((fchr=gchr()) != '\'') { xerr(10); return;}
|
||||
915 while (fchr = gchr()) {
|
||||
916 if (fchr == '\'') break;
|
||||
917 if (fchr == EOLC) return(0);
|
||||
918 str2[len2++] = fchr;
|
||||
919 }
|
||||
920 igrst();
|
||||
921 if (len1 != len2) return(0);
|
||||
922 str1[len1] = str2[len2] = NULL;
|
||||
923 if (strcmp(str1,str2) == 0) return(1);
|
||||
924 return(0);
|
||||
925 }
|
||||
926
|
||||
927 strcmp(s,t)
|
||||
928 register char *s, *t;
|
||||
929 {
|
||||
930 for( ; *s == *t; s++, t++ )
|
||||
931 if( *s == '\0' )
|
||||
932 return(0);
|
||||
933 return( *s - *t );
|
||||
934 }
|
||||
505
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/as68/expr.c
Normal file
505
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/as68/expr.c
Normal file
@@ -0,0 +1,505 @@
|
||||
/*
|
||||
Copyright 1981
|
||||
Alcyon Corporation
|
||||
8716 Production Ave.
|
||||
San Diego, Ca. 92121
|
||||
*/
|
||||
|
||||
/* Expression evaluator */
|
||||
|
||||
# include "as68.h"
|
||||
|
||||
/*precedence of operators*/
|
||||
# define PAO 2 /*AND, OR*/
|
||||
# define PPM 2 /*+ -*/
|
||||
# define PMD 3 /** /*/
|
||||
# define PLP 1 /* (*/
|
||||
# define PRP 4 /* )*/
|
||||
# define PEE 0 /* all other special chars*/
|
||||
|
||||
|
||||
/*global integers for this package*/
|
||||
struct it exitm; /*expression item*/
|
||||
int prcnt; /*paren count*/
|
||||
int rval; /*relocation value*/
|
||||
int lpflg;
|
||||
int lastopr; /*last token was operator when set*/
|
||||
|
||||
long gval(); /*get operand value*/
|
||||
|
||||
/*
|
||||
* expression evaluator
|
||||
* call with:
|
||||
* address of function to get input
|
||||
* returns:
|
||||
* item type in itype
|
||||
* item value in ival
|
||||
* relocation flag in reloc:
|
||||
* 0 => absolute
|
||||
* 1 => data
|
||||
* 2 => text
|
||||
* 3 => bss
|
||||
* 4 => external
|
||||
*
|
||||
* The only expressions involving externals which are legal are
|
||||
* external+constant or external-constant
|
||||
*/
|
||||
|
||||
struct it *piop, *pitr;
|
||||
int iop, itr;
|
||||
|
||||
struct it opstk[OPSTLEN]; /*operator stack*/
|
||||
struct it tree[TREELEN]; /*operand stack*/
|
||||
|
||||
expr(iploc)
|
||||
int (*iploc)();
|
||||
{
|
||||
register int i, ipr;
|
||||
|
||||
extflg = starmul = iop = lpflg = 0;
|
||||
piop = &opstk[0];
|
||||
itr = -1; /*tree stack pointer*/
|
||||
pitr = &tree[0];
|
||||
pitr--;
|
||||
/* form end of expression operator*/
|
||||
opstk[0].itty = ITSP; /*special character*/
|
||||
opstk[0].itop.wd2 = '?';
|
||||
lastopr = 1;
|
||||
|
||||
/* get an input item*/
|
||||
while(1) {
|
||||
if(itr >= TREELEN-2) {
|
||||
rpterr("expr tree overflow\n");
|
||||
abort();
|
||||
}
|
||||
if(iop >= OPSTLEN-1) {
|
||||
rpterr("expr opstk overflow\n");
|
||||
abort();
|
||||
}
|
||||
(*iploc)(); /*get an input term*/
|
||||
if (itype==ITPC) return;
|
||||
starmul=0; /* * is location counter*/
|
||||
|
||||
/* special character*/
|
||||
if(itype==ITSP) {
|
||||
ipr = gprc(i=ival.wd2); /*get precedence of character*/
|
||||
if(ipr==PEE) /*end of expression*/
|
||||
break;
|
||||
lastopr = 1;
|
||||
if(ipr==PLP) { /*left paren*/
|
||||
lpflg++;
|
||||
prcnt++;
|
||||
iop++; /*up stack pointer*/
|
||||
piop++;
|
||||
piop->swd1=exitm.swd1; /*put operator on stack*/
|
||||
piop->itop=exitm.itop;
|
||||
continue;
|
||||
}
|
||||
if(ipr==PRP) { /*right paren*/
|
||||
if(lpflg) { exerr(1); return; }
|
||||
starmul = 1; /* * is multiply*/
|
||||
prcnt--; /*down one level*/
|
||||
|
||||
while (piop->itop != '(') { /* top stk is '(' */
|
||||
itr++; /*up tree pointer*/
|
||||
pitr++;
|
||||
pitr->swd1 = piop->swd1; /*move operator*/
|
||||
pitr->itop = piop->itop;
|
||||
iop--; /*reduce operand stack*/
|
||||
piop--;
|
||||
}
|
||||
iop--; /*remove stack*/
|
||||
piop--;
|
||||
continue;
|
||||
}
|
||||
|
||||
while(ipr<=gprc(i=piop->itop.wd2)) { /* >= precedence */
|
||||
itr++;
|
||||
pitr++;
|
||||
pitr->swd1 = piop->swd1; /*move operator*/
|
||||
pitr->itop = piop->itop;
|
||||
iop--; /*reduce operand stack*/
|
||||
piop--;
|
||||
}
|
||||
iop++; /*up operator stack*/
|
||||
piop++;
|
||||
piop->swd1 = exitm.swd1; /*put in operator stack*/
|
||||
piop->itop = exitm.itop;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* symbol or constant*/
|
||||
else {
|
||||
lastopr = lpflg = 0; /*clear flag*/
|
||||
itr++; /*up tree pointer*/
|
||||
pitr++;
|
||||
pitr->swd1 = exitm.swd1; /*put in tree*/
|
||||
pitr->itop = exitm.itop;
|
||||
starmul = 1; /* * is multiply*/
|
||||
continue;
|
||||
}
|
||||
} /* end while(1)... */
|
||||
|
||||
/*output the rest of the operator stack to the tree*/
|
||||
for(i=iop; i>=0; i--) {
|
||||
itr++;
|
||||
pitr++;
|
||||
pitr->swd1 = piop->swd1; /*move operator*/
|
||||
pitr->itop = piop->itop;
|
||||
piop--;
|
||||
}
|
||||
|
||||
collapse();
|
||||
}
|
||||
|
||||
/* collapse the tree into one entry*/
|
||||
collapse()
|
||||
{
|
||||
register int rv1, rv2, topr, i, bos;
|
||||
register long tv1, tv2;
|
||||
|
||||
bos = 0;
|
||||
exct1:
|
||||
if(itr>=3) {
|
||||
piop = &tree[bos];
|
||||
iop = bos;
|
||||
while (iop<=(itr-3+bos) && (piop->itty==ITSP ||
|
||||
(piop+1)->itty==ITSP || (piop+2)->itty!=ITSP)) {
|
||||
iop++;
|
||||
piop++;
|
||||
}
|
||||
if (iop<=(itr-3+bos)) {
|
||||
tv1 = gval(piop); /*get value of first operand*/
|
||||
rv1 = rval; /*relocation value*/
|
||||
tv2 = gval(piop+1);
|
||||
rv2 = rval;
|
||||
topr = (piop+2)->itop; /*operator*/
|
||||
|
||||
/* handle operators */
|
||||
if (topr == '+') {
|
||||
tv1=+ tv2;
|
||||
rv1 = ckrl1(rv1,rv2); /*relocation*/
|
||||
}
|
||||
else if (topr == '-') {
|
||||
tv1 =- tv2;
|
||||
rv1 = ckrl2(rv1,rv2); /*relocation*/
|
||||
}
|
||||
else {
|
||||
switch(topr) { /*operator*/
|
||||
case '/': /* division */
|
||||
tv1 =/ tv2; break;
|
||||
case '*': /* multiplication */
|
||||
tv1 =* tv2; break;
|
||||
case '&': /* logical and */
|
||||
tv1 =& tv2; break;
|
||||
case '!': /* logical or */
|
||||
tv1 =| tv2; break;
|
||||
case '<': /* left shift */
|
||||
tv1 =<< tv2.wd2; break;
|
||||
case '>': /* right shift */
|
||||
tv1 =>> tv2.wd2; break;
|
||||
default: /*invalid operator*/
|
||||
exerr(2); return;
|
||||
}
|
||||
rv1 = ckrl3(rv1,rv2); /* relocation */
|
||||
}
|
||||
|
||||
/*put new value in tree*/
|
||||
if (iop==bos) {
|
||||
bos =+ 2;
|
||||
iop = bos;
|
||||
}
|
||||
piop = &tree[iop];
|
||||
piop->itty = ITCN; /*must be constant*/
|
||||
piop->itop = tv1; /*value*/
|
||||
piop->itrl = rv1; /*relocation value*/
|
||||
|
||||
if (iop != bos) { /* push up the rest of the tree... */
|
||||
i = iop + 2 - bos;
|
||||
pitr = piop+2;
|
||||
for(; i<itr; i++) {
|
||||
piop++;
|
||||
pitr++;
|
||||
piop->swd1 = pitr->swd1;
|
||||
piop->itop = pitr->itop;
|
||||
}
|
||||
}
|
||||
itr =- 2;
|
||||
goto exct1;
|
||||
}
|
||||
}
|
||||
|
||||
/* check for unary minus and unary plus*/
|
||||
if (tree[bos+1].itty!=ITSP && tree[bos].itop.wd2=='?')
|
||||
{ exerr(3); return; }
|
||||
if (tree[bos+1].itty!=ITSP || tree[bos].itty==ITSP) {
|
||||
reloc = ABS;
|
||||
ival = 0;
|
||||
itype = ITCN;
|
||||
return;
|
||||
}
|
||||
|
||||
if(tree[bos+1].itop.wd2!='?') { /*end of statement*/
|
||||
if(tree[bos+1].itop.wd2!='+') { /*ignore unary plus*/
|
||||
if(tree[bos+1].itop.wd2!='-') { /* invalid operator */
|
||||
exerr(4);
|
||||
return;
|
||||
}
|
||||
tree[bos+1].itop = -gval(&tree[bos]);
|
||||
tree[bos+1].itty = ITCN;
|
||||
tree[bos+1].itrl = tree[bos].itrl;
|
||||
bos++;
|
||||
itr--;
|
||||
goto exct1;
|
||||
}
|
||||
}
|
||||
/* send results back to caller*/
|
||||
if ((itype = tree[bos].itty)==ITCN)
|
||||
ival = gval(&tree[bos]);
|
||||
else {
|
||||
ival = tree[bos].itop;
|
||||
if(itype==ITSY && !(ival.ptrw2->flags&SYDF)) { /*undef symbol*/
|
||||
reloc = ABS;
|
||||
ival = 0;
|
||||
itype = ITCN;
|
||||
return;
|
||||
}
|
||||
}
|
||||
get_val(tree[bos].itrl);
|
||||
}
|
||||
|
||||
/*
|
||||
*if defined symbol get value and say constant
|
||||
* except for externals and equated registers
|
||||
*/
|
||||
get_val(reloc_val)
|
||||
int reloc_val;
|
||||
{
|
||||
if(itype==ITSY && (ival.ptrw2->flags&(SYXR|SYER))==0) {
|
||||
if(ival.ptrw2->flags&SYRA) /*get symbol relocation factor*/
|
||||
reloc = DATA;
|
||||
else if(ival.ptrw2->flags&SYRO)
|
||||
reloc = TEXT;
|
||||
else if(ival.ptrw2->flags&SYBS)
|
||||
reloc = BSS;
|
||||
else reloc = ABS;
|
||||
ival = ival.ptrw2->vl1; /*symbol vaue*/
|
||||
itype = ITCN; /*constant*/
|
||||
}
|
||||
else
|
||||
if(itype == ITSY && ival.ptrw2->flags&SYXR) { /*external symbol*/
|
||||
fixext(ival.ptrw2);
|
||||
reloc = EXTRN;
|
||||
}
|
||||
else
|
||||
reloc = reloc_val; /*relocation value of item*/
|
||||
}
|
||||
|
||||
exerr(n) /* [vlh] */
|
||||
int n;
|
||||
{
|
||||
uerr(6);
|
||||
ival = 0;
|
||||
itype = ITCN;
|
||||
reloc = ABS;
|
||||
}
|
||||
|
||||
/*
|
||||
* get precedence of a operator
|
||||
* call with
|
||||
* operator
|
||||
* returns
|
||||
* precedence
|
||||
*/
|
||||
gprc(dprc)
|
||||
{
|
||||
|
||||
switch(dprc) {
|
||||
|
||||
case '+':
|
||||
case '-':
|
||||
case '&': /* and*/
|
||||
case '!': /* or*/
|
||||
case '^': /*exclusive or*/
|
||||
return(PPM);
|
||||
|
||||
case '/':
|
||||
case '*':
|
||||
case '<': /*left shift*/
|
||||
case '>': /*right shift*/
|
||||
return(PMD);
|
||||
|
||||
case '(':
|
||||
if(lastopr)
|
||||
return(PLP);
|
||||
break;
|
||||
|
||||
case ')':
|
||||
if(!prcnt) /*no left parens*/
|
||||
break;
|
||||
return(PRP);
|
||||
|
||||
}
|
||||
return(PEE); /*end of expression*/
|
||||
}
|
||||
|
||||
/*
|
||||
* get value from an it format item
|
||||
* call with
|
||||
* address of it format item
|
||||
* returns
|
||||
* the value
|
||||
* relocation value in rval
|
||||
* calls uerr if it cant get a value
|
||||
*/
|
||||
long gval(avwrd)
|
||||
struct it *avwrd;
|
||||
{
|
||||
register struct it *vwrd;
|
||||
register struct symtab *p;
|
||||
|
||||
vwrd = avwrd;
|
||||
if(vwrd->itty == ITCN) { /*constant*/
|
||||
rval = vwrd->itrl;
|
||||
return(vwrd->itop); /*value*/
|
||||
}
|
||||
if(vwrd->itty != ITSY) {
|
||||
uerr(6);
|
||||
rval = ABS;
|
||||
return(0);
|
||||
}
|
||||
p = vwrd->itop.ptrw2;
|
||||
if(p->flags&SYXR) { /*external reference*/
|
||||
fixext(p);
|
||||
return(0);
|
||||
}
|
||||
if((p->flags&SYDF) != SYDF || (p->flags&SYER)) {
|
||||
uerr(6);
|
||||
rval = ABS;
|
||||
return(0);
|
||||
}
|
||||
rval = (p->flags&SYRA) ? DATA : (p->flags&SYRO) /* reloc of item */
|
||||
? TEXT : (p->flags&SYBS) ? BSS : ABS;
|
||||
return(p->vl1);
|
||||
}
|
||||
|
||||
/*
|
||||
* get items for expression evaluator (pass one)
|
||||
* returns:
|
||||
* item type in itype
|
||||
* item value in ival
|
||||
* item in it format in exitm
|
||||
*/
|
||||
p1gi()
|
||||
{
|
||||
if(fcflg) /*used item so must pass it*/
|
||||
gterm(TRUE);
|
||||
if(!fcflg && ckspc(fchr)==1) {
|
||||
fcflg=1; /*just pass first character*/
|
||||
itype=ITSP; /*special char*/
|
||||
ival=fchr; /*value is the char*/
|
||||
}
|
||||
else { /*get a whole term*/
|
||||
fcflg = 0;
|
||||
gterm(TRUE); /*get a term*/
|
||||
if(itype==ITSY) { /* got a symbol*/
|
||||
ival.ptrw2=lemt(sirt,FALSE); /*look it up in main table*/
|
||||
if(ival.ptrw2==lmte) /*not there before*/
|
||||
mmte(); /*put it in table*/
|
||||
}
|
||||
else
|
||||
if(itype == ITCN)
|
||||
exitm.itrl = reloc;
|
||||
}
|
||||
exitm.itty = itype;
|
||||
exitm.itop = ival;
|
||||
}
|
||||
|
||||
/*
|
||||
* get items for expression evaluator (pass 2)
|
||||
* returns:
|
||||
* item type in itype
|
||||
* item value in ival
|
||||
* item in it format in exitm
|
||||
*/
|
||||
p2gi()
|
||||
{
|
||||
if(pitw==pnite) { /*end of statement*/
|
||||
itype = ITSP;
|
||||
ival = ' '; /*blank*/
|
||||
exitm.itty = itype;
|
||||
exitm.itop = ival;
|
||||
return;
|
||||
}
|
||||
|
||||
if((itype = pitw->itty) == ITPC) { /*vlh*/
|
||||
pitw->itop = loctr;
|
||||
if (p2flg || format==6) itype = pitw->itty = ITCN;
|
||||
}
|
||||
ival = pitw->itop; /*value*/
|
||||
exitm.swd1 = pitw->swd1;
|
||||
exitm.itop = ival;
|
||||
pitw++;
|
||||
}
|
||||
|
||||
/*
|
||||
*check for a special character
|
||||
* call with
|
||||
* character to check
|
||||
* returns:
|
||||
* 0 => character is number or letter
|
||||
*/
|
||||
ckspc(acksc)
|
||||
{
|
||||
register cksc;
|
||||
|
||||
cksc = acksc;
|
||||
if (isalnum(cksc)) return(0);
|
||||
return((index("_~*.@$%\'",cksc) != -1) ? 0 : 1); /*[vlh] compacted*/
|
||||
}
|
||||
|
||||
/* generate new relocation for op + op*/
|
||||
ckrl1(rv1,rv2)
|
||||
{
|
||||
if(rv1==rv2)
|
||||
return(rv1);
|
||||
if(rv1==ABS || rv2==ABS)
|
||||
return(rv1+rv2); /*the one that is not ABS*/
|
||||
uerr(27);
|
||||
return(ABS);
|
||||
}
|
||||
|
||||
/*generate new relocation for op - op*/
|
||||
ckrl2(rv1,rv2)
|
||||
{
|
||||
if(rv2==EXTRN)
|
||||
uerr(26);
|
||||
if(rv1==rv2)
|
||||
return(ABS);
|
||||
if(rv2==ABS)
|
||||
return(rv1+rv2);
|
||||
uerr(27);
|
||||
return(ABS);
|
||||
}
|
||||
|
||||
/*generate new relocation for op /*&|<>^! op*/
|
||||
ckrl3(rv1,rv2)
|
||||
{
|
||||
if(rv1!=ABS || rv2!=ABS)
|
||||
uerr(27);
|
||||
return(ABS);
|
||||
}
|
||||
|
||||
fixext(p)
|
||||
struct symtab *p;
|
||||
{
|
||||
if(extflg)
|
||||
uerr(36); /*two externals in expr*/
|
||||
extflg++;
|
||||
extref = p->vl1.wd2; /*get external #*/
|
||||
rval = EXTRN;
|
||||
itype = ITCN;
|
||||
ival = 0;
|
||||
}
|
||||
|
||||
|
||||
514
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/as68/expr.lis
Normal file
514
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/as68/expr.lis
Normal file
@@ -0,0 +1,514 @@
|
||||
1File: EXPR.C Page 1
|
||||
1 /*
|
||||
2 Copyright 1981
|
||||
3 Alcyon Corporation
|
||||
4 8716 Production Ave.
|
||||
5 San Diego, Ca. 92121
|
||||
6 */
|
||||
7
|
||||
8 /* Expression evaluator */
|
||||
9
|
||||
10 # include "as68.h"
|
||||
11
|
||||
12 /*precedence of operators*/
|
||||
13 # define PAO 2 /*AND, OR*/
|
||||
14 # define PPM 2 /*+ -*/
|
||||
15 # define PMD 3 /** /*/
|
||||
16 # define PLP 1 /* (*/
|
||||
17 # define PRP 4 /* )*/
|
||||
18 # define PEE 0 /* all other special chars*/
|
||||
19
|
||||
20
|
||||
21 /*global integers for this package*/
|
||||
22 struct it exitm; /*expression item*/
|
||||
23 int prcnt; /*paren count*/
|
||||
24 int rval; /*relocation value*/
|
||||
25 int lpflg;
|
||||
26 int lastopr; /*last token was operator when set*/
|
||||
27
|
||||
28 long gval(); /*get operand value*/
|
||||
29
|
||||
30 /*
|
||||
31 * expression evaluator
|
||||
32 * call with:
|
||||
33 * address of function to get input
|
||||
34 * returns:
|
||||
35 * item type in itype
|
||||
36 * item value in ival
|
||||
37 * relocation flag in reloc:
|
||||
38 * 0 => absolute
|
||||
39 * 1 => data
|
||||
40 * 2 => text
|
||||
41 * 3 => bss
|
||||
42 * 4 => external
|
||||
43 *
|
||||
44 * The only expressions involving externals which are legal are
|
||||
45 * external+constant or external-constant
|
||||
46 */
|
||||
47
|
||||
48 struct it *piop, *pitr;
|
||||
49 int iop, itr;
|
||||
50
|
||||
51 struct it opstk[OPSTLEN]; /*operator stack*/
|
||||
52 struct it tree[TREELEN]; /*operand stack*/
|
||||
53
|
||||
54 expr(iploc)
|
||||
55 int (*iploc)();
|
||||
56 {
|
||||
57 register int i, ipr;
|
||||
58
|
||||
59 extflg = starmul = iop = lpflg = 0;
|
||||
1File: EXPR.C Page 2
|
||||
60 piop = &opstk[0];
|
||||
61 itr = -1; /*tree stack pointer*/
|
||||
62 pitr = &tree[0];
|
||||
63 pitr--;
|
||||
64 /* form end of expression operator*/
|
||||
65 opstk[0].itty = ITSP; /*special character*/
|
||||
66 opstk[0].itop.wd2 = '?';
|
||||
67 lastopr = 1;
|
||||
68
|
||||
69 /* get an input item*/
|
||||
70 while(1) {
|
||||
71 if(itr >= TREELEN-2) {
|
||||
72 rpterr("expr tree overflow\n");
|
||||
73 abort();
|
||||
74 }
|
||||
75 if(iop >= OPSTLEN-1) {
|
||||
76 rpterr("expr opstk overflow\n");
|
||||
77 abort();
|
||||
78 }
|
||||
79 (*iploc)(); /*get an input term*/
|
||||
80 if (itype==ITPC) return;
|
||||
81 starmul=0; /* * is location counter*/
|
||||
82
|
||||
83 /* special character*/
|
||||
84 if(itype==ITSP) {
|
||||
85 ipr = gprc(i=ival.wd2); /*get precedence of character*/
|
||||
86 if(ipr==PEE) /*end of expression*/
|
||||
87 break;
|
||||
88 lastopr = 1;
|
||||
89 if(ipr==PLP) { /*left paren*/
|
||||
90 lpflg++;
|
||||
91 prcnt++;
|
||||
92 iop++; /*up stack pointer*/
|
||||
93 piop++;
|
||||
94 piop->swd1=exitm.swd1; /*put operator on stack*/
|
||||
95 piop->itop=exitm.itop;
|
||||
96 continue;
|
||||
97 }
|
||||
98 if(ipr==PRP) { /*right paren*/
|
||||
99 if(lpflg) { exerr(1); return; }
|
||||
100 starmul = 1; /* * is multiply*/
|
||||
101 prcnt--; /*down one level*/
|
||||
102
|
||||
103 while (piop->itop != '(') { /* top stk is '(' */
|
||||
104 itr++; /*up tree pointer*/
|
||||
105 pitr++;
|
||||
106 pitr->swd1 = piop->swd1; /*move operator*/
|
||||
107 pitr->itop = piop->itop;
|
||||
108 iop--; /*reduce operand stack*/
|
||||
109 piop--;
|
||||
110 }
|
||||
111 iop--; /*remove stack*/
|
||||
112 piop--;
|
||||
113 continue;
|
||||
114 }
|
||||
115
|
||||
116 while(ipr<=gprc(i=piop->itop.wd2)) { /* >= precedence */
|
||||
117 itr++;
|
||||
118 pitr++;
|
||||
1File: EXPR.C Page 3
|
||||
119 pitr->swd1 = piop->swd1; /*move operator*/
|
||||
120 pitr->itop = piop->itop;
|
||||
121 iop--; /*reduce operand stack*/
|
||||
122 piop--;
|
||||
123 }
|
||||
124 iop++; /*up operator stack*/
|
||||
125 piop++;
|
||||
126 piop->swd1 = exitm.swd1; /*put in operator stack*/
|
||||
127 piop->itop = exitm.itop;
|
||||
128 continue;
|
||||
129 }
|
||||
130
|
||||
131 /* symbol or constant*/
|
||||
132 else {
|
||||
133 lastopr = lpflg = 0; /*clear flag*/
|
||||
134 itr++; /*up tree pointer*/
|
||||
135 pitr++;
|
||||
136 pitr->swd1 = exitm.swd1; /*put in tree*/
|
||||
137 pitr->itop = exitm.itop;
|
||||
138 starmul = 1; /* * is multiply*/
|
||||
139 continue;
|
||||
140 }
|
||||
141 } /* end while(1)... */
|
||||
142
|
||||
143 /*output the rest of the operator stack to the tree*/
|
||||
144 for(i=iop; i>=0; i--) {
|
||||
145 itr++;
|
||||
146 pitr++;
|
||||
147 pitr->swd1 = piop->swd1; /*move operator*/
|
||||
148 pitr->itop = piop->itop;
|
||||
149 piop--;
|
||||
150 }
|
||||
151
|
||||
152 collapse();
|
||||
153 }
|
||||
154
|
||||
155 /* collapse the tree into one entry*/
|
||||
156 collapse()
|
||||
157 {
|
||||
158 register int rv1, rv2, topr, i, bos;
|
||||
159 register long tv1, tv2;
|
||||
160
|
||||
161 bos = 0;
|
||||
162 exct1:
|
||||
163 if(itr>=3) {
|
||||
164 piop = &tree[bos];
|
||||
165 iop = bos;
|
||||
166 while (iop<=(itr-3+bos) && (piop->itty==ITSP ||
|
||||
167 (piop+1)->itty==ITSP || (piop+2)->itty!=ITSP)) {
|
||||
168 iop++;
|
||||
169 piop++;
|
||||
170 }
|
||||
171 if (iop<=(itr-3+bos)) {
|
||||
172 tv1 = gval(piop); /*get value of first operand*/
|
||||
173 rv1 = rval; /*relocation value*/
|
||||
174 tv2 = gval(piop+1);
|
||||
175 rv2 = rval;
|
||||
176 topr = (piop+2)->itop; /*operator*/
|
||||
177
|
||||
1File: EXPR.C Page 4
|
||||
178 /* handle operators */
|
||||
179 if (topr == '+') {
|
||||
180 tv1=+ tv2;
|
||||
181 rv1 = ckrl1(rv1,rv2); /*relocation*/
|
||||
182 }
|
||||
183 else if (topr == '-') {
|
||||
184 tv1 =- tv2;
|
||||
185 rv1 = ckrl2(rv1,rv2); /*relocation*/
|
||||
186 }
|
||||
187 else {
|
||||
188 switch(topr) { /*operator*/
|
||||
189 case '/': /* division */
|
||||
190 tv1 =/ tv2; break;
|
||||
191 case '*': /* multiplication */
|
||||
192 tv1 =* tv2; break;
|
||||
193 case '&': /* logical and */
|
||||
194 tv1 =& tv2; break;
|
||||
195 case '!': /* logical or */
|
||||
196 tv1 =| tv2; break;
|
||||
197 case '<': /* left shift */
|
||||
198 tv1 =<< tv2.wd2; break;
|
||||
199 case '>': /* right shift */
|
||||
200 tv1 =>> tv2.wd2; break;
|
||||
201 default: /*invalid operator*/
|
||||
202 exerr(2); return;
|
||||
203 }
|
||||
204 rv1 = ckrl3(rv1,rv2); /* relocation */
|
||||
205 }
|
||||
206
|
||||
207 /*put new value in tree*/
|
||||
208 if (iop==bos) {
|
||||
209 bos =+ 2;
|
||||
210 iop = bos;
|
||||
211 }
|
||||
212 piop = &tree[iop];
|
||||
213 piop->itty = ITCN; /*must be constant*/
|
||||
214 piop->itop = tv1; /*value*/
|
||||
215 piop->itrl = rv1; /*relocation value*/
|
||||
216
|
||||
217 if (iop != bos) { /* push up the rest of the tree... */
|
||||
218 i = iop + 2 - bos;
|
||||
219 pitr = piop+2;
|
||||
220 for(; i<itr; i++) {
|
||||
221 piop++;
|
||||
222 pitr++;
|
||||
223 piop->swd1 = pitr->swd1;
|
||||
224 piop->itop = pitr->itop;
|
||||
225 }
|
||||
226 }
|
||||
227 itr =- 2;
|
||||
228 goto exct1;
|
||||
229 }
|
||||
230 }
|
||||
231
|
||||
232 /* check for unary minus and unary plus*/
|
||||
233 if (tree[bos+1].itty!=ITSP && tree[bos].itop.wd2=='?')
|
||||
234 { exerr(3); return; }
|
||||
235 if (tree[bos+1].itty!=ITSP || tree[bos].itty==ITSP) {
|
||||
236 reloc = ABS;
|
||||
1File: EXPR.C Page 5
|
||||
237 ival = 0;
|
||||
238 itype = ITCN;
|
||||
239 return;
|
||||
240 }
|
||||
241
|
||||
242 if(tree[bos+1].itop.wd2!='?') { /*end of statement*/
|
||||
243 if(tree[bos+1].itop.wd2!='+') { /*ignore unary plus*/
|
||||
244 if(tree[bos+1].itop.wd2!='-') { /* invalid operator */
|
||||
245 exerr(4);
|
||||
246 return;
|
||||
247 }
|
||||
248 tree[bos+1].itop = -gval(&tree[bos]);
|
||||
249 tree[bos+1].itty = ITCN;
|
||||
250 tree[bos+1].itrl = tree[bos].itrl;
|
||||
251 bos++;
|
||||
252 itr--;
|
||||
253 goto exct1;
|
||||
254 }
|
||||
255 }
|
||||
256 /* send results back to caller*/
|
||||
257 if ((itype = tree[bos].itty)==ITCN)
|
||||
258 ival = gval(&tree[bos]);
|
||||
259 else {
|
||||
260 ival = tree[bos].itop;
|
||||
261 if(itype==ITSY && !(ival.ptrw2->flags&SYDF)) { /*undef symbol*/
|
||||
262 reloc = ABS;
|
||||
263 ival = 0;
|
||||
264 itype = ITCN;
|
||||
265 return;
|
||||
266 }
|
||||
267 }
|
||||
268 get_val(tree[bos].itrl);
|
||||
269 }
|
||||
270
|
||||
271 /*
|
||||
272 *if defined symbol get value and say constant
|
||||
273 * except for externals and equated registers
|
||||
274 */
|
||||
275 get_val(reloc_val)
|
||||
276 int reloc_val;
|
||||
277 {
|
||||
278 if(itype==ITSY && (ival.ptrw2->flags&(SYXR|SYER))==0) {
|
||||
279 if(ival.ptrw2->flags&SYRA) /*get symbol relocation factor*/
|
||||
280 reloc = DATA;
|
||||
281 else if(ival.ptrw2->flags&SYRO)
|
||||
282 reloc = TEXT;
|
||||
283 else if(ival.ptrw2->flags&SYBS)
|
||||
284 reloc = BSS;
|
||||
285 else reloc = ABS;
|
||||
286 ival = ival.ptrw2->vl1; /*symbol vaue*/
|
||||
287 itype = ITCN; /*constant*/
|
||||
288 }
|
||||
289 else
|
||||
290 if(itype == ITSY && ival.ptrw2->flags&SYXR) { /*external symbol*/
|
||||
291 fixext(ival.ptrw2);
|
||||
292 reloc = EXTRN;
|
||||
293 }
|
||||
294 else
|
||||
295 reloc = reloc_val; /*relocation value of item*/
|
||||
1File: EXPR.C Page 6
|
||||
296 }
|
||||
297
|
||||
298 exerr(n) /* [vlh] */
|
||||
299 int n;
|
||||
300 {
|
||||
301 uerr(6);
|
||||
302 ival = 0;
|
||||
303 itype = ITCN;
|
||||
304 reloc = ABS;
|
||||
305 }
|
||||
306
|
||||
307 /*
|
||||
308 * get precedence of a operator
|
||||
309 * call with
|
||||
310 * operator
|
||||
311 * returns
|
||||
312 * precedence
|
||||
313 */
|
||||
314 gprc(dprc)
|
||||
315 {
|
||||
316
|
||||
317 switch(dprc) {
|
||||
318
|
||||
319 case '+':
|
||||
320 case '-':
|
||||
321 case '&': /* and*/
|
||||
322 case '!': /* or*/
|
||||
323 case '^': /*exclusive or*/
|
||||
324 return(PPM);
|
||||
325
|
||||
326 case '/':
|
||||
327 case '*':
|
||||
328 case '<': /*left shift*/
|
||||
329 case '>': /*right shift*/
|
||||
330 return(PMD);
|
||||
331
|
||||
332 case '(':
|
||||
333 if(lastopr)
|
||||
334 return(PLP);
|
||||
335 break;
|
||||
336
|
||||
337 case ')':
|
||||
338 if(!prcnt) /*no left parens*/
|
||||
339 break;
|
||||
340 return(PRP);
|
||||
341
|
||||
342 }
|
||||
343 return(PEE); /*end of expression*/
|
||||
344 }
|
||||
345
|
||||
346 /*
|
||||
347 * get value from an it format item
|
||||
348 * call with
|
||||
349 * address of it format item
|
||||
350 * returns
|
||||
351 * the value
|
||||
352 * relocation value in rval
|
||||
353 * calls uerr if it cant get a value
|
||||
354 */
|
||||
1File: EXPR.C Page 7
|
||||
355 long gval(avwrd)
|
||||
356 struct it *avwrd;
|
||||
357 {
|
||||
358 register struct it *vwrd;
|
||||
359 register struct symtab *p;
|
||||
360
|
||||
361 vwrd = avwrd;
|
||||
362 if(vwrd->itty == ITCN) { /*constant*/
|
||||
363 rval = vwrd->itrl;
|
||||
364 return(vwrd->itop); /*value*/
|
||||
365 }
|
||||
366 if(vwrd->itty != ITSY) {
|
||||
367 uerr(6);
|
||||
368 rval = ABS;
|
||||
369 return(0);
|
||||
370 }
|
||||
371 p = vwrd->itop.ptrw2;
|
||||
372 if(p->flags&SYXR) { /*external reference*/
|
||||
373 fixext(p);
|
||||
374 return(0);
|
||||
375 }
|
||||
376 if((p->flags&SYDF) != SYDF || (p->flags&SYER)) {
|
||||
377 uerr(6);
|
||||
378 rval = ABS;
|
||||
379 return(0);
|
||||
380 }
|
||||
381 rval = (p->flags&SYRA) ? DATA : (p->flags&SYRO) /* reloc of item */
|
||||
382 ? TEXT : (p->flags&SYBS) ? BSS : ABS;
|
||||
383 return(p->vl1);
|
||||
384 }
|
||||
385
|
||||
386 /*
|
||||
387 * get items for expression evaluator (pass one)
|
||||
388 * returns:
|
||||
389 * item type in itype
|
||||
390 * item value in ival
|
||||
391 * item in it format in exitm
|
||||
392 */
|
||||
393 p1gi()
|
||||
394 {
|
||||
395 if(fcflg) /*used item so must pass it*/
|
||||
396 gterm(TRUE);
|
||||
397 if(!fcflg && ckspc(fchr)==1) {
|
||||
398 fcflg=1; /*just pass first character*/
|
||||
399 itype=ITSP; /*special char*/
|
||||
400 ival=fchr; /*value is the char*/
|
||||
401 }
|
||||
402 else { /*get a whole term*/
|
||||
403 fcflg = 0;
|
||||
404 gterm(TRUE); /*get a term*/
|
||||
405 if(itype==ITSY) { /* got a symbol*/
|
||||
406 ival.ptrw2=lemt(sirt,FALSE); /*look it up in main table*/
|
||||
407 if(ival.ptrw2==lmte) /*not there before*/
|
||||
408 mmte(); /*put it in table*/
|
||||
409 }
|
||||
410 else
|
||||
411 if(itype == ITCN)
|
||||
412 exitm.itrl = reloc;
|
||||
413 }
|
||||
1File: EXPR.C Page 8
|
||||
414 exitm.itty = itype;
|
||||
415 exitm.itop = ival;
|
||||
416 }
|
||||
417
|
||||
418 /*
|
||||
419 * get items for expression evaluator (pass 2)
|
||||
420 * returns:
|
||||
421 * item type in itype
|
||||
422 * item value in ival
|
||||
423 * item in it format in exitm
|
||||
424 */
|
||||
425 p2gi()
|
||||
426 {
|
||||
427 if(pitw==pnite) { /*end of statement*/
|
||||
428 itype = ITSP;
|
||||
429 ival = ' '; /*blank*/
|
||||
430 exitm.itty = itype;
|
||||
431 exitm.itop = ival;
|
||||
432 return;
|
||||
433 }
|
||||
434
|
||||
435 if((itype = pitw->itty) == ITPC) { /*vlh*/
|
||||
436 pitw->itop = loctr;
|
||||
437 if (p2flg || format==6) itype = pitw->itty = ITCN;
|
||||
438 }
|
||||
439 ival = pitw->itop; /*value*/
|
||||
440 exitm.swd1 = pitw->swd1;
|
||||
441 exitm.itop = ival;
|
||||
442 pitw++;
|
||||
443 }
|
||||
444
|
||||
445 /*
|
||||
446 *check for a special character
|
||||
447 * call with
|
||||
448 * character to check
|
||||
449 * returns:
|
||||
450 * 0 => character is number or letter
|
||||
451 */
|
||||
452 ckspc(acksc)
|
||||
453 {
|
||||
454 register cksc;
|
||||
455
|
||||
456 cksc = acksc;
|
||||
457 if (isalnum(cksc)) return(0);
|
||||
458 return((index("_~*.@$%\'",cksc) != -1) ? 0 : 1); /*[vlh] compacted*/
|
||||
459 }
|
||||
460
|
||||
461 /* generate new relocation for op + op*/
|
||||
462 ckrl1(rv1,rv2)
|
||||
463 {
|
||||
464 if(rv1==rv2)
|
||||
465 return(rv1);
|
||||
466 if(rv1==ABS || rv2==ABS)
|
||||
467 return(rv1+rv2); /*the one that is not ABS*/
|
||||
468 uerr(27);
|
||||
469 return(ABS);
|
||||
470 }
|
||||
471
|
||||
472 /*generate new relocation for op - op*/
|
||||
1File: EXPR.C Page 9
|
||||
473 ckrl2(rv1,rv2)
|
||||
474 {
|
||||
475 if(rv2==EXTRN)
|
||||
476 uerr(26);
|
||||
477 if(rv1==rv2)
|
||||
478 return(ABS);
|
||||
479 if(rv2==ABS)
|
||||
480 return(rv1+rv2);
|
||||
481 uerr(27);
|
||||
482 return(ABS);
|
||||
483 }
|
||||
484
|
||||
485 /*generate new relocation for op /*&|<>^! op*/
|
||||
486 ckrl3(rv1,rv2)
|
||||
487 {
|
||||
488 if(rv1!=ABS || rv2!=ABS)
|
||||
489 uerr(27);
|
||||
490 return(ABS);
|
||||
491 }
|
||||
492
|
||||
493 fixext(p)
|
||||
494 struct symtab *p;
|
||||
495 {
|
||||
496 if(extflg)
|
||||
497 uerr(36); /*two externals in expr*/
|
||||
498 extflg++;
|
||||
499 extref = p->vl1.wd2; /*get external #*/
|
||||
500 rval = EXTRN;
|
||||
501 itype = ITCN;
|
||||
502 ival = 0;
|
||||
503 }
|
||||
504
|
||||
505
|
||||
@@ -0,0 +1,39 @@
|
||||
$ num
|
||||
AS68INIT.C
|
||||
AS68INIT.lis
|
||||
$ num
|
||||
DIR.C
|
||||
DIR.lis
|
||||
$ num
|
||||
EXPR.C
|
||||
EXPR.lis
|
||||
$ num
|
||||
MAIN.C
|
||||
MAIN.lis
|
||||
$ num
|
||||
MISC.C
|
||||
MISC.lis
|
||||
$ num
|
||||
PASS1A.C
|
||||
PASS1A.lis
|
||||
$ num
|
||||
PASS2.C
|
||||
PASS2.lis
|
||||
$ num
|
||||
SYMT.C
|
||||
SYMT.lis
|
||||
$ num
|
||||
VERSION.C
|
||||
VERSION.lis
|
||||
$ num
|
||||
AS68.H
|
||||
AS68.lst
|
||||
$ num
|
||||
COUT.H
|
||||
COUT.lst
|
||||
$ num
|
||||
CTYPE.H
|
||||
CTYPE.lst
|
||||
$ num
|
||||
MACHINE.H
|
||||
MACHINE.lst
|
||||
@@ -0,0 +1,10 @@
|
||||
/*
|
||||
* Use this file to determine what kind of machine you want the
|
||||
* Alcyon stuff to run on ....
|
||||
*/
|
||||
/*#define MC68000 1*/ /* 68000 version */
|
||||
/*#define VAX 1*/ /* VAX Version */
|
||||
#define PDP11 1 /* PDP-11 Version*/
|
||||
/*#define CPM 1*/ /* CP/M Operating System*/
|
||||
#define UNIX 1 /* UNIX Operating System*/
|
||||
/*#define VMS 1*/ /* VMS Operating System*/
|
||||
@@ -0,0 +1,10 @@
|
||||
/*
|
||||
* Use this file to determine what kind of machine you want the
|
||||
* Alcyon stuff to run on ....
|
||||
*/
|
||||
#define MC68000 1 /* 68000 version */
|
||||
/*#define VAX 1*/ /* VAX Version */
|
||||
/*#define PDP11 1*/ /* PDP-11 Version*/
|
||||
#define CPM 1 /* CP/M Operating System*/
|
||||
/*#define UNIX 1*/ /* UNIX Operating System*/
|
||||
/*#define VMS 1*/ /* VMS Operating System*/
|
||||
@@ -0,0 +1,10 @@
|
||||
/*
|
||||
* Use this file to determine what kind of machine you want the
|
||||
* Alcyon stuff to run on ....
|
||||
*/
|
||||
/*#define MC68000 1*/ /* 68000 version */
|
||||
#define VAX 1 /* VAX Version */
|
||||
/*#define PDP11 1*/ /* PDP-11 Version*/
|
||||
/*#define CPM 1*/ /* CP/M Operating System*/
|
||||
/*#define UNIX 1*/ /* UNIX Operating System*/
|
||||
#define VMS 1 /* VMS Operating System*/
|
||||
@@ -0,0 +1,11 @@
|
||||
1File: MACHINE.H Page 1
|
||||
1 /*
|
||||
2 * Use this file to determine what kind of machine you want the
|
||||
3 * Alcyon stuff to run on ....
|
||||
4 */
|
||||
5 /*#define MC68000 1*/ /* 68000 version */
|
||||
6 #define VAX 1 /* VAX Version */
|
||||
7 /*#define PDP11 1*/ /* PDP-11 Version*/
|
||||
8 /*#define CPM 1*/ /* CP/M Operating System*/
|
||||
9 /*#define UNIX 1*/ /* UNIX Operating System*/
|
||||
10 #define VMS 1 /* VMS Operating System*/
|
||||
@@ -0,0 +1,10 @@
|
||||
/*
|
||||
* Use this file to determine what kind of machine you want the
|
||||
* Alcyon stuff to run on ....
|
||||
*/
|
||||
/*#define MC68000 1*/ /* 68000 version */
|
||||
#define VAX 1 /* VAX Version */
|
||||
/*#define PDP11 1*/ /* PDP-11 Version*/
|
||||
/*#define CPM 1*/ /* CP/M Operating System*/
|
||||
/*#define UNIX 1*/ /* UNIX Operating System*/
|
||||
#define VMS 1 /* VMS Operating System*/
|
||||
1100
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/as68/main.c
Normal file
1100
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/as68/main.c
Normal file
File diff suppressed because it is too large
Load Diff
1119
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/as68/main.lis
Normal file
1119
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/as68/main.lis
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,68 @@
|
||||
$1stat machine.h=rw
|
||||
$1pip machine.h=machine.68k
|
||||
|
||||
$1cp68 -i 0$1 DIR.c $1x.i
|
||||
$1c068 $1x.i $1x.ic $1x.st
|
||||
era $1x.i
|
||||
era $1x.st
|
||||
$1c168 $1x.ic DIR.s -L
|
||||
$1as68 -f $1 -s 0$1 -l -u DIR.s
|
||||
era dir.s
|
||||
|
||||
$1cp68 -i 0$1 EXPR.c $1x.i
|
||||
$1c068 $1x.i $1x.ic $1x.st
|
||||
era $1x.i
|
||||
era $1x.st
|
||||
$1c168 $1x.ic EXPR.s -L
|
||||
$1as68 -f $1 -s 0$1 -l -u EXPR.s
|
||||
era expr.s
|
||||
|
||||
$1cp68 -i 0$1 MAIN.c $1x.i
|
||||
$1c068 $1x.i $1x.ic $1x.st
|
||||
era $1x.i
|
||||
era $1x.st
|
||||
$1c168 $1x.ic MAIN.s -L
|
||||
$1as68 -f $1 -s 0$1 -l -u MAIN.s
|
||||
era main.s
|
||||
|
||||
$1cp68 -i 0$1 misc.c $1x.i
|
||||
$1c068 $1x.i $1x.ic $1x.st
|
||||
era $1x.i
|
||||
era $1x.st
|
||||
$1c168 $1x.ic MISC.s -L
|
||||
$1as68 -f $1 -s 0$1 -l -u MISC.s
|
||||
era misc.s
|
||||
|
||||
$1cp68 -i 0$1 PASS1A.c $1x.i
|
||||
$1c068 $1x.i $1x.ic $1x.st
|
||||
era $1x.i
|
||||
era $1x.st
|
||||
$1c168 $1x.ic PASS1A.s -L
|
||||
$1as68 -f $1 -s 0$1 -l -u PASS1A.s
|
||||
era pass1a.s
|
||||
|
||||
$1cp68 -i 0$1 PASS2.c $1x.i
|
||||
$1c068 $1x.i $1x.ic $1x.st
|
||||
era $1x.i
|
||||
era $1x.st
|
||||
$1c168 $1x.ic PASS2.s -L
|
||||
$1as68 -f $1 -s 0$1 -l -u PASS2.s
|
||||
era pass2.s
|
||||
|
||||
$1cp68 -i 0$1 STRNCMP.c $1x.i
|
||||
$1c068 $1x.i $1x.ic $1x.st
|
||||
era $1x.i
|
||||
era $1x.st
|
||||
$1c168 $1x.ic STRNCMP.s -L
|
||||
$1as68 -f $1 -s 0$1 -l -u STRNCMP.s
|
||||
era strncmp.s
|
||||
|
||||
$1cp68 -i 0$1 SYMT.c $1x.i
|
||||
$1c068 $1x.i $1x.ic $1x.st
|
||||
era $1x.i
|
||||
era $1x.st
|
||||
$1c168 $1x.ic SYMT.s -L
|
||||
$1as68 -f $1 -s 0$1 -l -u SYMT.s
|
||||
era symt.s
|
||||
|
||||
relink $1
|
||||
1078
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/as68/misc.c
Normal file
1078
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/as68/misc.c
Normal file
File diff suppressed because it is too large
Load Diff
1097
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/as68/misc.lis
Normal file
1097
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/as68/misc.lis
Normal file
File diff suppressed because it is too large
Load Diff
109
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/as68/pass1a.c
Normal file
109
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/as68/pass1a.c
Normal file
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
Copyright 1981
|
||||
Alcyon Corporation
|
||||
8716 Production Ave.
|
||||
San Diego, Ca. 92121
|
||||
*/
|
||||
|
||||
/* reduce long relative branches to short if possible*/
|
||||
|
||||
#include "as68.h"
|
||||
int nitleft;
|
||||
char tfilname[];
|
||||
int p2gi();
|
||||
long lseek();
|
||||
pass1a()
|
||||
{
|
||||
register long reduced;
|
||||
register int i, wsize;
|
||||
register long oldpos,newpos; /* Old and new file seek pointers */
|
||||
register j; /* temp */
|
||||
|
||||
pitix = itbuf;
|
||||
nitleft = 0;
|
||||
reduced = 0; itoffset = 0; stbuf[0].itrl = 0;
|
||||
wsize = 3*sizeof stbuf[0]; /* [vlh] don't calculate many times */
|
||||
close(itfn);
|
||||
LASTCHTFN = itfnc;
|
||||
itfn = openfi(tfilname,2,1); /*open it for update*/
|
||||
while(ristb()) {
|
||||
opcpt = stbuf[2].itop.ptrw2; /*ptr to opcode entry in main tab*/
|
||||
if(!(opcpt->flags&OPDR)) { /*not a directive*/
|
||||
format = (opcpt->flags)&OPFF;
|
||||
p1inlen = stbuf[1].itrl; /*pass 1 instr length guess*/
|
||||
if(((format==6 && p1inlen==4) || opcpt==jsrptr) &&
|
||||
(rlflg=stbuf[3].itrl)==TEXT) {
|
||||
nite = stbuf[0].itrl & 0377;/* # of it entries */
|
||||
pnite = &stbuf[nite].itty; /*ptr to end of stmt*/
|
||||
modelen = stbuf[2].itrl; /*instr mode length*/
|
||||
opdix = ITOP1; /*first operand*/
|
||||
pitw = &stbuf[ITOP1].itty; /*ptr to first operand*/
|
||||
loctr = stbuf[3].itop - reduced;
|
||||
expr(&p2gi);
|
||||
ival =- loctr+2L;
|
||||
if(itype==ITCN && !extflg && reloc!=ABS) {
|
||||
if(format==9) { /*jsr*/
|
||||
i = (ival>= -128 && ival<=127) ? p1inlen-2 :
|
||||
(ival>= -32768 && ival<=32767) ? p1inlen-4 : 0;
|
||||
if (!i)
|
||||
continue;
|
||||
stbuf[2].itop.ptrw2 = bsrptr; /*chng to bsr*/
|
||||
}
|
||||
else if(ival>= -128 && ival<=127) {
|
||||
i = 2; /*[vlh]was 4 for ival=2*/
|
||||
if (!ival) stbuf[2].itop.ptrw2 = nopptr;
|
||||
}
|
||||
else
|
||||
continue;
|
||||
fixsyadr(i);
|
||||
reduced =+ i;
|
||||
stbuf[1].itrl =- i; /*reduced somewhat*/
|
||||
if(!stbuf[1].itrl)
|
||||
stbuf[1].itrl = -1; /*ignore flag*/
|
||||
oldpos=lseek(itfn,0L,1); /* Remember current position */
|
||||
newpos= itoffset -
|
||||
(stbuf[0].itrl*sizeof stbuf[0]);
|
||||
if(lseek(itfn,newpos,0) < 0) {
|
||||
rpterr("seek error on it file\n");
|
||||
abort();
|
||||
}
|
||||
if(write(itfn,&stbuf[0],wsize) != wsize) {
|
||||
rpterr("write error on it file\n");
|
||||
abort();
|
||||
}
|
||||
lseek(itfn,oldpos,0);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(opcpt == endptr) {
|
||||
savelc[TEXT] =- reduced;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* fix all symbol addresses that are text based and greater than loctr*/
|
||||
/* fix means subtract 2 from them*/
|
||||
fixsyadr(al)
|
||||
{
|
||||
register char **sx1, **sx2;
|
||||
register l;
|
||||
|
||||
l = al;
|
||||
/* loop thru symbol initial reference table*/
|
||||
for(sx1= sirt; sx1<&sirt[SZIRT-1]; sx1 =+ 2) {
|
||||
if(*(sx2 = sx1+1)==0) /* this chain is empty*/
|
||||
continue;
|
||||
|
||||
/* symbols on one chain*/
|
||||
sx2 = *sx2; /*first entry on this chain*/
|
||||
while(1) {
|
||||
if((sx2->flags&SYDF || sx2->flags&SYPC) && sx2->flags&SYRO &&
|
||||
sx2->vl1 > loctr) /* [vlh] */
|
||||
sx2->vl1 =- l;
|
||||
if(sx2 == *sx1) /*end of chain*/
|
||||
break;
|
||||
sx2 = sx2->tlnk; /*next entry in chain*/
|
||||
}
|
||||
}
|
||||
}
|
||||
111
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/as68/pass1a.lis
Normal file
111
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/as68/pass1a.lis
Normal file
@@ -0,0 +1,111 @@
|
||||
1File: PASS1A.C Page 1
|
||||
1 /*
|
||||
2 Copyright 1981
|
||||
3 Alcyon Corporation
|
||||
4 8716 Production Ave.
|
||||
5 San Diego, Ca. 92121
|
||||
6 */
|
||||
7
|
||||
8 /* reduce long relative branches to short if possible*/
|
||||
9
|
||||
10 #include "as68.h"
|
||||
11 int nitleft;
|
||||
12 char tfilname[];
|
||||
13 int p2gi();
|
||||
14 long lseek();
|
||||
15 pass1a()
|
||||
16 {
|
||||
17 register long reduced;
|
||||
18 register int i, wsize;
|
||||
19 register long oldpos,newpos; /* Old and new file seek pointers */
|
||||
20 register j; /* temp */
|
||||
21
|
||||
22 pitix = itbuf;
|
||||
23 nitleft = 0;
|
||||
24 reduced = 0; itoffset = 0; stbuf[0].itrl = 0;
|
||||
25 wsize = 3*sizeof stbuf[0]; /* [vlh] don't calculate many times */
|
||||
26 close(itfn);
|
||||
27 LASTCHTFN = itfnc;
|
||||
28 itfn = openfi(tfilname,2,1); /*open it for update*/
|
||||
29 while(ristb()) {
|
||||
30 opcpt = stbuf[2].itop.ptrw2; /*ptr to opcode entry in main tab*/
|
||||
31 if(!(opcpt->flags&OPDR)) { /*not a directive*/
|
||||
32 format = (opcpt->flags)&OPFF;
|
||||
33 p1inlen = stbuf[1].itrl; /*pass 1 instr length guess*/
|
||||
34 if(((format==6 && p1inlen==4) || opcpt==jsrptr) &&
|
||||
35 (rlflg=stbuf[3].itrl)==TEXT) {
|
||||
36 nite = stbuf[0].itrl & 0377;/* # of it entries */
|
||||
37 pnite = &stbuf[nite].itty; /*ptr to end of stmt*/
|
||||
38 modelen = stbuf[2].itrl; /*instr mode length*/
|
||||
39 opdix = ITOP1; /*first operand*/
|
||||
40 pitw = &stbuf[ITOP1].itty; /*ptr to first operand*/
|
||||
41 loctr = stbuf[3].itop - reduced;
|
||||
42 expr(&p2gi);
|
||||
43 ival =- loctr+2L;
|
||||
44 if(itype==ITCN && !extflg && reloc!=ABS) {
|
||||
45 if(format==9) { /*jsr*/
|
||||
46 i = (ival>= -128 && ival<=127) ? p1inlen-2 :
|
||||
47 (ival>= -32768 && ival<=32767) ? p1inlen-4 : 0;
|
||||
48 if (!i)
|
||||
49 continue;
|
||||
50 stbuf[2].itop.ptrw2 = bsrptr; /*chng to bsr*/
|
||||
51 }
|
||||
52 else if(ival>= -128 && ival<=127) {
|
||||
53 i = 2; /*[vlh]was 4 for ival=2*/
|
||||
54 if (!ival) stbuf[2].itop.ptrw2 = nopptr;
|
||||
55 }
|
||||
56 else
|
||||
57 continue;
|
||||
58 fixsyadr(i);
|
||||
59 reduced =+ i;
|
||||
1File: PASS1A.C Page 2
|
||||
60 stbuf[1].itrl =- i; /*reduced somewhat*/
|
||||
61 if(!stbuf[1].itrl)
|
||||
62 stbuf[1].itrl = -1; /*ignore flag*/
|
||||
63 oldpos=lseek(itfn,0L,1); /* Remember current position */
|
||||
64 newpos= itoffset -
|
||||
65 (stbuf[0].itrl*sizeof stbuf[0]);
|
||||
66 if(lseek(itfn,newpos,0) < 0) {
|
||||
67 rpterr("seek error on it file\n");
|
||||
68 abort();
|
||||
69 }
|
||||
70 if(write(itfn,&stbuf[0],wsize) != wsize) {
|
||||
71 rpterr("write error on it file\n");
|
||||
72 abort();
|
||||
73 }
|
||||
74 lseek(itfn,oldpos,0);
|
||||
75 }
|
||||
76 }
|
||||
77 }
|
||||
78 else if(opcpt == endptr) {
|
||||
79 savelc[TEXT] =- reduced;
|
||||
80 return;
|
||||
81 }
|
||||
82 }
|
||||
83 }
|
||||
84
|
||||
85 /* fix all symbol addresses that are text based and greater than loctr*/
|
||||
86 /* fix means subtract 2 from them*/
|
||||
87 fixsyadr(al)
|
||||
88 {
|
||||
89 register char **sx1, **sx2;
|
||||
90 register l;
|
||||
91
|
||||
92 l = al;
|
||||
93 /* loop thru symbol initial reference table*/
|
||||
94 for(sx1= sirt; sx1<&sirt[SZIRT-1]; sx1 =+ 2) {
|
||||
95 if(*(sx2 = sx1+1)==0) /* this chain is empty*/
|
||||
96 continue;
|
||||
97
|
||||
98 /* symbols on one chain*/
|
||||
99 sx2 = *sx2; /*first entry on this chain*/
|
||||
100 while(1) {
|
||||
101 if((sx2->flags&SYDF || sx2->flags&SYPC) && sx2->flags&SYRO &&
|
||||
102 sx2->vl1 > loctr) /* [vlh] */
|
||||
103 sx2->vl1 =- l;
|
||||
104 if(sx2 == *sx1) /*end of chain*/
|
||||
105 break;
|
||||
106 sx2 = sx2->tlnk; /*next entry in chain*/
|
||||
107 }
|
||||
108 }
|
||||
109 }
|
||||
841
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/as68/pass2.c
Normal file
841
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/as68/pass2.c
Normal file
@@ -0,0 +1,841 @@
|
||||
/*
|
||||
Copyright 1981
|
||||
Alcyon Corporation
|
||||
8716 Production Ave.
|
||||
San Diego, Ca. 92121
|
||||
*/
|
||||
|
||||
/*
|
||||
* pass two for the 68000 assembler
|
||||
* Bill Allen
|
||||
* March 1980
|
||||
*/
|
||||
|
||||
#include "as68.h"
|
||||
#include "cout.h" /*c.out header definition & MAGIC*/
|
||||
|
||||
#define MOVEA 0100
|
||||
|
||||
int p2gi();
|
||||
|
||||
extern char tfilname[]; /*name of it file*/
|
||||
extern char initfnam[]; /*name of the initilization file*/
|
||||
int (*p2direct[])();
|
||||
|
||||
int opf1(), opf2(), opf3(), opf4(), opf5(), relbr(), opf7(), opf8();
|
||||
int opf9(), opf11(), opf12(), opf13(), opf15(), opf17(), opf20();
|
||||
int opf21(), opf22(), opf23();
|
||||
|
||||
int (*opfary[])() {
|
||||
0, /*0*/
|
||||
opf1, /*1*/
|
||||
opf2, /*2*/
|
||||
opf3, /*3*/
|
||||
opf4, /*4*/
|
||||
opf5, /*5*/
|
||||
relbr, /*6*/
|
||||
opf7, /*7*/
|
||||
opf8, /*8*/
|
||||
opf9, /*9*/
|
||||
opf4, /*10*/
|
||||
opf11, /*11*/
|
||||
opf12, /*12*/
|
||||
opf13, /*13*/
|
||||
opf9, /*14*/
|
||||
opf15, /*15*/
|
||||
opf17, /*16*/
|
||||
opf17, /*17*/
|
||||
opf13, /*18*/
|
||||
opf11, /*19*/
|
||||
opf20, /*20*/
|
||||
opf21, /*21*/
|
||||
opf22, /*22*/
|
||||
opf23, /*23*/
|
||||
opf9, /*24*/
|
||||
opf9, /*25*/
|
||||
opf5, /*26*/ /* [vlh] cmp, chk, extention verification */
|
||||
opf4, /*27*/ /* [vlh] addx, subx, extension verification */
|
||||
opf13, /*28*/ /* [vlh] swap, extension verification */
|
||||
opf9, /*29*/ /* [vlh] pea, extention verification */
|
||||
opf15 /*30*/ /* [vlh] lea, extension verification */
|
||||
};
|
||||
|
||||
#define LSTFRMT 30
|
||||
|
||||
int f1mode[] {0,0,0100,0,0200};
|
||||
int f2mode[] {0,0,0100,0,0200};
|
||||
int f3mode[] {0,010000,030000,0,020000};
|
||||
int f15mode[] {0,0,0300,0,0700};
|
||||
int f5mode[] {0,0,0100,0,0200};
|
||||
int f5amode[] {0,0,0300,0,0700};
|
||||
int f13mode[] {0,0,0200,0,0300};
|
||||
int f23mode[] {0,0400,0500,0,0600};
|
||||
int rlbits[5]; /*holds relocation bits for instr*/
|
||||
int pline; /*number of last printed line*/
|
||||
int brkln2 077777; /*pass 2 break line number for debugging*/
|
||||
int prsp; /*special print alignment flag*/
|
||||
int amode; /*addressing mode*/
|
||||
int nitleft;
|
||||
/*pass two driver*/
|
||||
pass2()
|
||||
{
|
||||
register short *p;
|
||||
register i;
|
||||
register (*dirop)();
|
||||
|
||||
pitix = itbuf; /* This is init for doitrd*/
|
||||
xline = LPP;
|
||||
nitleft = 0;
|
||||
lbuf.nunused = tbuf.nunused = dabuf.nunused = drbuf.nunused = 512;
|
||||
lbuf.fildes = lfn; /*set buffered io for binary file*/
|
||||
lbuf.xfree = &lbuf.buff[0];
|
||||
tbuf.fildes = trbfn; /*set buffered io for text reloc bits file*/
|
||||
tbuf.xfree = &tbuf.buff[0];
|
||||
dabuf.fildes = dafn; /*set buffered io for data bytes*/
|
||||
dabuf.xfree = &dabuf.buff[0];
|
||||
drbuf.fildes = drbfn; /*set buffered io for data reloc bits*/
|
||||
drbuf.xfree = &drbuf.buff[0];
|
||||
couthd.ch_magic = MAGIC;/*c.out magic number*/
|
||||
if(savelc[TEXT]&1)
|
||||
savelc[TEXT]++; /*make it even*/
|
||||
couthd.ch_tsize = savelc[TEXT]; /*text size*/
|
||||
if(savelc[DATA]&1)
|
||||
savelc[DATA]++; /*make it even*/
|
||||
couthd.ch_dsize = savelc[DATA]; /*data size*/
|
||||
couthd.ch_bsize = savelc[BSS]; /*bss size*/
|
||||
/*symbol table size is not known now -- it is set at end of pass 2*/
|
||||
/* entry point and stack size are zero for now*/
|
||||
p = &couthd;
|
||||
for(i=0; i<HDSIZE/2; i++) {
|
||||
putw(*p++,&lbuf); /*write the file header words*/
|
||||
}
|
||||
savelc[0] = 0; savelc[1] = 0; savelc[2] = 0; savelc[3] = 0;
|
||||
loctr = 0; /*location counter*/
|
||||
rlflg = TEXT; /*TEXT relocatable*/
|
||||
p2flg = 1; /*pass two*/
|
||||
#ifdef UNIX
|
||||
if (lseek(ifn,0L,0) == -1) { /*beginning of source*/
|
||||
rpterr("seek error on source file\n");
|
||||
abort();
|
||||
}
|
||||
#else
|
||||
close(ifn); /* This way for goddamn Whitesmith's */
|
||||
ifn=open(sfname,0,0); /* Re-open the fucking source file */
|
||||
if(ifn < 0) /* Couldn't */
|
||||
{
|
||||
printf("Unable to open file %s\n",sfname);
|
||||
abort();
|
||||
}
|
||||
#endif
|
||||
close(itfn);
|
||||
LASTCHTFN = itfnc;
|
||||
itfn = openfi(tfilname,0); /*open it for reading*/
|
||||
pline = 1; /*no lines printed*/
|
||||
fchr=gchr(); /*get first char*/
|
||||
while(ristb()) { /*pass 2 main loop*/
|
||||
p2absln = stbuf[0].itop; /*line number*/
|
||||
if(p2absln>=brkln2) /*for debugging the assembler*/
|
||||
i=0;
|
||||
opcpt = stbuf[2].itop.ptrw2; /*ptr to opcode entry in main tab*/
|
||||
nite = stbuf[0].itrl & 0377; /*number of it entries*/
|
||||
pnite = &stbuf[nite]; /*ptr to end of stmt*/
|
||||
modelen = stbuf[2].itrl; /*instr mode length*/
|
||||
p1inlen = stbuf[1].itrl; /*pass 1 instr length guess*/
|
||||
opdix = ITOP1; /*first operand*/
|
||||
pitw = &stbuf[ITOP1]; /*ptr to first operand*/
|
||||
prsp = 0; /*special print flag off*/
|
||||
instrlen = 2; /*default for print*/
|
||||
if(opcpt->flags&OPDR) { /*opcode is a directive*/
|
||||
i = opcpt->vl1; /*directive number*/
|
||||
dirop = p2direct[i];
|
||||
(*dirop)(); /*handle directive*/
|
||||
}
|
||||
else {
|
||||
gcist(); /*generate code for one statement*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* generate code for an instruction*/
|
||||
/* call with*/
|
||||
/* intermediate text for instruction in stbuf*/
|
||||
gcist()
|
||||
{
|
||||
register i,j;
|
||||
|
||||
if(stbuf[0].itty != ITBS) /*beginning of statement*/
|
||||
abort();
|
||||
format = (opcpt->flags)&OPFF;
|
||||
in_err = 0; /*[vlh] no error this instruction, yet*/
|
||||
ival = 0; /*initial value for possible operand*/
|
||||
reloc = ABS;
|
||||
instrlen = 2; /*at least 2 bytes*/
|
||||
ins[0] = opcpt->vl1; /*opcode value*/
|
||||
rlbits[0] = INSABS; /*instruction absolute*/
|
||||
pins = &ins[1];
|
||||
prlb = &rlbits[1];
|
||||
if(nite>ITOP1) { /*operands*/
|
||||
if(!format) {
|
||||
uerr(9);
|
||||
}
|
||||
else if(format>LSTFRMT) /* [vlh] was a magic number... */
|
||||
abort();
|
||||
else {
|
||||
(*opfary[format])();
|
||||
}
|
||||
}
|
||||
if (!ckein() && !in_err) /* at end of statement ?? */
|
||||
uerr(6);
|
||||
print(1); /*print source*/
|
||||
|
||||
loctr =+ p1inlen;
|
||||
if (!in_err && p1inlen != instrlen) /* [vlh] 2nd pass error recovery */
|
||||
uerr(38);
|
||||
outinstr(); /*write out instr binary*/
|
||||
}
|
||||
|
||||
/* relative branches*/
|
||||
relbr()
|
||||
{
|
||||
expr(&p2gi);
|
||||
if(extflg) { /*external reference*/
|
||||
instrlen =+ 2; /*long relative*/
|
||||
*pins++ = ival; /*pass constant part*/
|
||||
*prlb++ = (extref<<3)|EXTREL; /*ext ref*/
|
||||
return;
|
||||
}
|
||||
ival =- (loctr+2); /*calc relative offset*/
|
||||
if(itype!=ITCN || reloc != rlflg) {
|
||||
uerr(22); /*invalid relative branch*/
|
||||
ival = 0;
|
||||
}
|
||||
reloc = ABS;
|
||||
if(p1inlen==4) { /*long displacement*/
|
||||
if(ival< (-32768L) || ival > (32767L))
|
||||
uerr(22);
|
||||
instrlen =+ 2;
|
||||
*pins++ = ival;
|
||||
*prlb++ = DABS; /*data absolute*/
|
||||
}
|
||||
else { /*short displacement*/
|
||||
if (ival>127 || ival<-128)
|
||||
uerr(22);
|
||||
ins[0] =| (ival.wd2&0377);
|
||||
}
|
||||
if (!ival) { /* make it a nop */
|
||||
opcpt = nopptr;
|
||||
ins[0] = opcpt->vl1.wd2;
|
||||
pins = &ins[1];
|
||||
if (modelen==4) {
|
||||
*pins++ = opcpt->vl1.wd2;
|
||||
rlbits[1] = INSABS;
|
||||
}
|
||||
}
|
||||
in_err++; /* ignore extra eg. bra *+$d04(pc) vs. bra *+d04 */
|
||||
}
|
||||
|
||||
/* format one -- add, sub, and, or, cmp, etc.*/
|
||||
/* one operand must be a D reg (or A reg dest for add, sub, or cmp)*/
|
||||
opf1()
|
||||
{
|
||||
register int *p;
|
||||
|
||||
if(get2ops())
|
||||
return;
|
||||
if (ins[0]==AND || ins[0]==OR)
|
||||
if (cksprg(&opnd[1],CCR) || cksprg(&opnd[1],SR)) {
|
||||
if (ins[0]==AND) opcpt = andiptr;
|
||||
else opcpt = oriptr;
|
||||
ins[0] = opcpt->vl1.wd2;
|
||||
format = (opcpt->flags)&OPFF;
|
||||
ccr_or_sr();
|
||||
return;
|
||||
}
|
||||
p = f1mode;
|
||||
if(ckdreg(&opnd[1])) { /*destn is D reg*/
|
||||
if((opcpt==andptr||opcpt==orptr)&&ckareg(&opnd[0])) /*A source*/
|
||||
uerr(20);
|
||||
makef1(opnd[1].ea,p[modelen],&opnd[0]); /*make instr*/
|
||||
return;
|
||||
}
|
||||
else if(ckdreg(&opnd[0]) && memalt(&opnd[1])) { /*source is D reg*/
|
||||
if (pcea(&opnd[1])) uerr(10);
|
||||
makef1(opnd[0].ea,p[modelen]+0400,&opnd[1]);
|
||||
return;
|
||||
}
|
||||
else if(ckareg(&opnd[1])) { /*A reg is dstn*/
|
||||
if(opcpt==addptr)
|
||||
opcpt = addaptr;
|
||||
else if(opcpt==cmpptr)
|
||||
opcpt = cmpaptr;
|
||||
else if(opcpt==subptr)
|
||||
opcpt = subaptr;
|
||||
else {
|
||||
uerr(20);
|
||||
return;
|
||||
}
|
||||
format = (opcpt->flags)&OPFF;
|
||||
opnd[1].ea =& 07;
|
||||
p = f15mode;
|
||||
makef1(opnd[1].ea,p[modelen],&opnd[0]); /*make instr*/
|
||||
return;
|
||||
}
|
||||
else if(!makeimm()) /*make an immediate instr*/
|
||||
uerr(20);
|
||||
}
|
||||
|
||||
/* format 2 -- addi, andi, subi, etc*/
|
||||
opf2()
|
||||
{
|
||||
if(get2ops())
|
||||
return;
|
||||
if(ins[0]==ANDI || ins[0]==ORI || ins[0]==EORI) {
|
||||
if(cksprg(&opnd[1],CCR) || cksprg(&opnd[1],SR)) {
|
||||
ccr_or_sr();
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(opnd[0].ea != IMM) {
|
||||
uerr(9);
|
||||
return;
|
||||
}
|
||||
if(!dataalt(&opnd[1]) || pcea(&opnd[1])) {
|
||||
uerr(20);
|
||||
return;
|
||||
}
|
||||
genimm();
|
||||
}
|
||||
|
||||
/*format #3 -- move and movea*/
|
||||
opf3()
|
||||
{
|
||||
register i,j,k;
|
||||
|
||||
if(get2ops())
|
||||
return;
|
||||
if(cksprg(&opnd[1],CCR)) {
|
||||
ins[0] = MOVECCR;
|
||||
opf3l1:
|
||||
if (modelen==1 || modelen==4) uerr(34);
|
||||
if(anysprg(&opnd[0]))
|
||||
uerr(20);
|
||||
ins[0] =| opnd[0].ea;
|
||||
if(!dataea(&opnd[0]))
|
||||
uerr(9);
|
||||
doea(&opnd[0]);
|
||||
return;
|
||||
}
|
||||
if(cksprg(&opnd[1],SR)) {
|
||||
ins[0] = MOVESR;
|
||||
goto opf3l1;
|
||||
}
|
||||
if(cksprg(&opnd[0],SR)) {
|
||||
if (modelen==1 || modelen==4)
|
||||
uerr(34);
|
||||
if(anysprg(&opnd[1]))
|
||||
uerr(20);
|
||||
ins[0] = SRMOVE | opnd[1].ea;
|
||||
if(!dataalt(&opnd[1]) || pcea(&opnd[1]))
|
||||
uerr(10);
|
||||
doea(&opnd[1]);
|
||||
return;
|
||||
}
|
||||
if(cksprg(&opnd[0],USP)) {
|
||||
if (modelen == 1)
|
||||
uerr(34); /* default is word, can't test */
|
||||
if (!ckareg(&opnd[1]))
|
||||
uerr(33);
|
||||
ins[0] = MOVEUSP|8|(opnd[1].ea&7);
|
||||
return;
|
||||
}
|
||||
if(cksprg(&opnd[1],USP)) {
|
||||
if (modelen == 1)
|
||||
uerr(34); /* default is word, can't test */
|
||||
if (!ckareg(&opnd[0]))
|
||||
uerr(33);
|
||||
ins[0] = MOVEUSP|(opnd[0].ea&7);
|
||||
return;
|
||||
}
|
||||
k = ins[0];
|
||||
ins[0] =| f3mode[modelen];
|
||||
ckbytea();
|
||||
ins[0] =| opnd[0].ea; /*source ea*/
|
||||
doea(&opnd[0]);
|
||||
ins[0] =| (opnd[1].ea&7)<<9; /*dest register*/
|
||||
ins[0] =| (opnd[1].ea&070)<<3; /*dest mode*/
|
||||
doea(&opnd[1]);
|
||||
if(k==MOVEA) {
|
||||
if(dataea(&opnd[1]))
|
||||
uerr(20);
|
||||
}
|
||||
else if((pcea(&opnd[1]) && dataea(&opnd[1])) || opnd[1].ea==IMM)
|
||||
uerr(20);
|
||||
}
|
||||
|
||||
/* format 4 -- abcd, sbcd */
|
||||
/* format 10 -- cmpm*/
|
||||
/* format 27 -- addx, subx */
|
||||
opf4()
|
||||
{
|
||||
if(get2ops())
|
||||
return;
|
||||
if (format==27) { /*addx,subx add in size bits*/
|
||||
ins[0] =| f1mode[modelen];
|
||||
}
|
||||
else if(format==10) { /*cmpm*/
|
||||
if((opnd[0].ea&070)!=INDINC || (opnd[1].ea&070)!=INDINC)
|
||||
uerr(20);
|
||||
ins[0] =| f1mode[modelen] | ((opnd[0].ea&7)|((opnd[1].ea&7)<<9));
|
||||
return;
|
||||
}
|
||||
if(ckdreg(&opnd[0]) && ckdreg(&opnd[1])) {
|
||||
ins[0] =| ((opnd[0].ea&7)|((opnd[1].ea&7)<<9));
|
||||
return;
|
||||
}
|
||||
if((opnd[0].ea&070)==DECIND && (opnd[1].ea&070)==DECIND) {
|
||||
ins[0] =| 010 | ((opnd[0].ea&7)|((opnd[1].ea&7)<<9));
|
||||
return;
|
||||
}
|
||||
uerr(20);
|
||||
}
|
||||
|
||||
/*format 5 -- div, mul*/
|
||||
/*format 26 -- cmp, chk */
|
||||
opf5()
|
||||
{
|
||||
if(get2ops())
|
||||
return;
|
||||
if(!ckdreg(&opnd[1])) {
|
||||
if(opcpt==cmpptr) {
|
||||
if(!dataea(&opnd[1])) /* [vlh] made define */
|
||||
ins[0] =| f5amode[modelen]; /* was pumode */
|
||||
else if(makeimm())
|
||||
return;
|
||||
else
|
||||
uerr(20);
|
||||
}
|
||||
else
|
||||
uerr(20);
|
||||
}
|
||||
if(opcpt==cmpptr) {
|
||||
ins[0] =| f5mode[modelen]; /* was pumode */
|
||||
ckbytea();
|
||||
}
|
||||
else if(!dataea(&opnd[0]))
|
||||
uerr(20);
|
||||
ins[0] =| (opnd[1].ea&7)<<9 | opnd[0].ea;
|
||||
doea(&opnd[0]);
|
||||
}
|
||||
|
||||
#define BTST 0000
|
||||
/* format 7 -- bit instrs -- btst, bclr, bset, etc*/
|
||||
opf7()
|
||||
{
|
||||
if(get2ops())
|
||||
return;
|
||||
if(opnd[1].ea==IMM||(ins[0]!=BTST&&pcea(&opnd[1]))||ckareg(&opnd[1]))
|
||||
uerr(20);
|
||||
if(ckdreg(&opnd[0])) {
|
||||
ins[0] =| (opnd[0].ea<<9)|0400;
|
||||
}
|
||||
else { /*static bit #*/
|
||||
if(opnd[0].con<0L || opnd[0].con>31 ||
|
||||
(opnd[1].ea&INDIRECT&&opnd[0].con>7)) /* [vlh] */
|
||||
uerr(23);
|
||||
if(opnd[0].ea != IMM)
|
||||
uerr(17);
|
||||
ins[0] =| 04000;
|
||||
dodisp(&opnd[0]);
|
||||
}
|
||||
if (modelen==1 && !(memea(&opnd[1]))) /*[vlh]*/
|
||||
uerr(20);
|
||||
else if (!(ckdreg(&opnd[1])) && modelen==4)
|
||||
uerr(20);
|
||||
ins[0] =| opnd[1].ea;
|
||||
doea(&opnd[1]);
|
||||
}
|
||||
|
||||
/* format 8 -- shifts and rotates*/
|
||||
opf8()
|
||||
{
|
||||
register i;
|
||||
|
||||
getea(0); /*get first operand*/
|
||||
if(pitw >= pnite) { /*end of all ops*/
|
||||
if(ckdreg(&opnd[0])) { /*shift dreg one bit*/
|
||||
cpop01(); /*copy opnd 0 to 1*/
|
||||
opnd[0].ea = IMM;
|
||||
opnd[0].con = 1L;
|
||||
if (!ckdreg(&opnd[1])) uerr(20);
|
||||
opf8l1:
|
||||
if(opnd[0].con<1 || opnd[0].con>8) /*[vlh legal range 1..8*/
|
||||
uerr(37);
|
||||
ins[0] =| ((opnd[0].con.wd2&7)<<9)|f1mode[modelen]|opnd[1].ea;
|
||||
return;
|
||||
}
|
||||
i = (ins[0]&077)<<6;
|
||||
ins[0] =& 0177700;
|
||||
ins[0] =| 0300|i|opnd[0].ea;
|
||||
if(!memalt(&opnd[0]) || pcea(&opnd[0]) || modelen != 2)
|
||||
uerr(20);
|
||||
doea(&opnd[0]);
|
||||
return;
|
||||
}
|
||||
if(!ckcomma()) {
|
||||
uerr(10);
|
||||
return;
|
||||
}
|
||||
getea(1); /*get second operand*/
|
||||
if(!ckdreg(&opnd[1])) /* [vlh] second operand must be dreg */
|
||||
uerr(20);
|
||||
if(ckdreg(&opnd[0])) { /*first op is D reg*/
|
||||
ins[0] =| (opnd[0].ea<<9)|040; /*reg # and reg bit*/
|
||||
}
|
||||
else {
|
||||
if(opnd[0].ea != IMM)
|
||||
uerr(20);
|
||||
goto opf8l1;
|
||||
}
|
||||
ins[0] =| f1mode[modelen] | opnd[1].ea; /*put in size and reg #*/
|
||||
}
|
||||
|
||||
/* format 9 -- jmp, jsr */
|
||||
/* format 14 -- stop */
|
||||
/* format 24 -- clr, neg, negx, not */
|
||||
/* format 25 -- s?? */
|
||||
/* format 29 -- pea */
|
||||
/* one operand instructions -- jmp, clr, neg, not, sge, etc.*/
|
||||
opf9()
|
||||
{
|
||||
getea(0);
|
||||
if(format==24) { /*clr, not, etc*/
|
||||
ins[0] =| f1mode[modelen]; /*add size bits*/
|
||||
if(!dataalt(&opnd[0]) || pcea(&opnd[0]))
|
||||
uerr(20);
|
||||
}
|
||||
else if(format==25) { /*tas,scc, etc*/
|
||||
if(ckareg(&opnd[0]) || pcea(&opnd[0]) || opnd[0].ea==IMM)
|
||||
uerr(20);
|
||||
}
|
||||
else if(format==14) { /*stop*/
|
||||
if(modelen!=2 || opnd[0].ea!=IMM)
|
||||
uerr(20);
|
||||
doea(&opnd[0]);
|
||||
return;
|
||||
}
|
||||
else if(!controlea(&opnd[0])) /*jmp, jsr, etc*/
|
||||
uerr(20);
|
||||
ins[0] =| opnd[0].ea;
|
||||
doea(&opnd[0]);
|
||||
}
|
||||
|
||||
/* format 11 -- dbcc*/
|
||||
/* format 19 -- link*/
|
||||
opf11()
|
||||
{
|
||||
if(get2ops())
|
||||
return;
|
||||
if(format==19) { /*link*/
|
||||
if(!ckareg(&opnd[0]))
|
||||
uerr(33);
|
||||
if(opnd[1].ea != IMM)
|
||||
uerr(17);
|
||||
}
|
||||
else {
|
||||
if(!ckdreg(&opnd[0]))
|
||||
uerr(33);
|
||||
if(opnd[1].drlc!=rlflg) /*[vlh]don't chk opnd[1].ea!=LADDR||SADDR*/
|
||||
uerr(22);
|
||||
opnd[1].con =- (loctr+2L);
|
||||
cksize(&opnd[1]);
|
||||
opnd[1].drlc = ABS; /*not relocatable*/
|
||||
}
|
||||
ins[0] =| opnd[0].ea&7; /*put in reg #*/
|
||||
dodisp(&opnd[1]);
|
||||
}
|
||||
|
||||
/* format 12 -- exg*/
|
||||
opf12()
|
||||
{
|
||||
register i;
|
||||
|
||||
if(get2ops())
|
||||
return;
|
||||
if(ckdreg(&opnd[0])) {
|
||||
if(ckdreg(&opnd[1])) { /*exchange D regs*/
|
||||
ins[0] =| 0100 | ((opnd[0].ea&7)<<9) | (opnd[1].ea&7);
|
||||
return;
|
||||
}
|
||||
if(ckareg(&opnd[1])) { /*ins[0] <- A and D flag*/
|
||||
ins[0] =| 0210 | ((opnd[0].ea&7)<<9) | (opnd[1].ea&7);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(ckareg(&opnd[0])) {
|
||||
if(ckareg(&opnd[1])) { /*both a regs*/
|
||||
ins[0] =| 0110 | ((opnd[0].ea&7)<<9) | (opnd[1].ea&7);
|
||||
return;
|
||||
}
|
||||
if(ckdreg(&opnd[1])) { /*A and D regs*/
|
||||
i = opnd[0].ea; /*exchg ea's*/
|
||||
opnd[0].ea = opnd[1].ea;
|
||||
opnd[1].ea = i;
|
||||
ins[0] =| 0210 | ((opnd[0].ea&7)<<9) | (opnd[1].ea&7);
|
||||
return;
|
||||
}
|
||||
}
|
||||
uerr(20);
|
||||
}
|
||||
|
||||
/* format 13 -- ext, unlk*/
|
||||
/* format 18 -- trap*/
|
||||
/* format 28 -- swap */
|
||||
#define UNLK 047130
|
||||
|
||||
opf13()
|
||||
{
|
||||
getea(0);
|
||||
if(format==18) { /*trap*/
|
||||
if(opnd[0].con<0 || opnd[0].con>15)
|
||||
uerr(15);
|
||||
ins[0] =| opnd[0].con.wd2;
|
||||
return;
|
||||
}
|
||||
if(ins[0]==UNLK) { /*unlk instr*/
|
||||
if(!ckareg(&opnd[0]))
|
||||
uerr(20);
|
||||
}
|
||||
else {
|
||||
if(!ckdreg(&opnd[0]))
|
||||
uerr(20);
|
||||
if (format==13) /* ext */
|
||||
ins[0] =| f13mode[modelen];
|
||||
}
|
||||
ins[0] =| opnd[0].ea&7;
|
||||
}
|
||||
|
||||
/* format 15 -- adda, cmpa, suba*/
|
||||
/* format 30 -- lea */
|
||||
opf15()
|
||||
{
|
||||
register i;
|
||||
|
||||
if(get2ops())
|
||||
return;
|
||||
if(!ckareg(&opnd[1]))
|
||||
uerr(33);
|
||||
if(format==30) {
|
||||
i = 0700;
|
||||
if(!controlea(&opnd[0]))
|
||||
uerr(20);
|
||||
}
|
||||
else
|
||||
i = f15mode[modelen];
|
||||
makef1(opnd[1].ea&7,i,&opnd[0]);
|
||||
if (format==15 && opnd[0].ea != 071) cksize(&opnd[0]);
|
||||
}
|
||||
|
||||
/*formats 16 and 17 -- addq, inc, subq, dec*/
|
||||
opf17()
|
||||
{
|
||||
if(format==16) { /*inc or dec*/
|
||||
clrea(&opnd[0]);
|
||||
opnd[0].ea = IMM;
|
||||
opnd[0].con = 1L;
|
||||
opnd[0].drlc = ABS;
|
||||
getea(1);
|
||||
}
|
||||
else {
|
||||
if(get2ops())
|
||||
return;
|
||||
}
|
||||
if(opnd[0].ea != IMM || !altea(&opnd[1]) || pcea(&opnd[1]))
|
||||
uerr(20);
|
||||
if(opnd[0].con<=0 || opnd[0].con>8)
|
||||
uerr(15);
|
||||
if(modelen==1 && !dataea(&opnd[1]))
|
||||
uerr(34);
|
||||
ins[0] =| f1mode[modelen]|((opnd[0].con.wd2&7)<<9)|opnd[1].ea;
|
||||
doea(&opnd[1]);
|
||||
}
|
||||
|
||||
/* format 20 -- movem */
|
||||
int regmsk0[] {0100000,040000,020000,010000,04000,02000,01000,0400,0200,
|
||||
0100,040,020,010,4,2,1};
|
||||
int regmsk1[] {1,2,4,010,020,040,0100,0200,0400,01000,02000,04000,010000,
|
||||
020000,040000,0100000};
|
||||
opf20()
|
||||
{
|
||||
register dr;
|
||||
register i,j;
|
||||
|
||||
dr = 0;
|
||||
if(getreg() != -1 || pitw->itty == ITRM) { /*regs to memory*/
|
||||
if (pitw->itty != ITRM) { /* [vlh] */
|
||||
pitw--;
|
||||
j = getrlist(regmsk0);
|
||||
}
|
||||
else {
|
||||
j = pitw->itop;
|
||||
pitw++;
|
||||
}
|
||||
if(!ckcomma())
|
||||
uerr(10);
|
||||
}
|
||||
else
|
||||
dr = 02000;
|
||||
getea(0);
|
||||
if(dr) {
|
||||
if(!ckcomma())
|
||||
uerr(10);
|
||||
if (pitw->itty != ITRM) /* [vlh] */
|
||||
j = getrlist(regmsk1); /*mem to regs*/
|
||||
else {
|
||||
j = pitw->itop;
|
||||
j = fixmask(j);
|
||||
pitw++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(controlea(&opnd[0]))
|
||||
j = fixmask(j);
|
||||
}
|
||||
i = opnd[0].ea&070;
|
||||
if(!controlea(&opnd[0]) && i!=INDINC && i!=DECIND)
|
||||
uerr(20);
|
||||
if(modelen==4) /*long*/
|
||||
ins[0] =| 0100;
|
||||
ins[0] =| opnd[0].ea|dr;
|
||||
*pins++ = j; /*reg mask*/
|
||||
*prlb++ = DABS;
|
||||
instrlen =+ 2;
|
||||
doea(&opnd[0]);
|
||||
if (!dr) { /* 1st argument (2nd is reg list) */
|
||||
if (pcea(&opnd[0]) || (opnd[0].ea&070)==INDINC)
|
||||
uerr(20); /* xx(pc), xx(pc,dx), -(ax) */
|
||||
}
|
||||
else /* 2nd argument (1st is reg list) */
|
||||
if ((opnd[0].ea&070)==DECIND)
|
||||
uerr(20); /* (ax)+ */
|
||||
}
|
||||
|
||||
/*
|
||||
* get a list of registers for the movem instr
|
||||
* call with:
|
||||
* ptr to reg-to-mem or mem-to-reg array of bits
|
||||
*/
|
||||
getrlist(ap)
|
||||
int *ap;
|
||||
{
|
||||
register int *p,i,j;
|
||||
register int mask;
|
||||
|
||||
p = ap;
|
||||
mask = 0;
|
||||
while((i=getreg()) != -1) {
|
||||
if(ckitc(pitw,'-')) {
|
||||
pitw++;
|
||||
if((j=getreg()) == -1) {
|
||||
uerr(40);
|
||||
break;
|
||||
}
|
||||
while(i<=j)
|
||||
mask =| p[i++];
|
||||
}
|
||||
else
|
||||
mask =| p[i];
|
||||
if(ckitc(pitw,'/'))
|
||||
pitw++;
|
||||
else
|
||||
break;
|
||||
}
|
||||
if(!mask)
|
||||
uerr(40);
|
||||
return(mask);
|
||||
}
|
||||
|
||||
/*reverse a movem register mask for control ea to memory*/
|
||||
fixmask(msk)
|
||||
{
|
||||
register i,j,k;
|
||||
|
||||
k = (msk&1) ? 0100000 : 0;
|
||||
i = 2;
|
||||
j = 040000;
|
||||
while(i) {
|
||||
if(msk&i)
|
||||
k =| j;
|
||||
i =<< 1;
|
||||
j =>> 1;
|
||||
}
|
||||
return(k);
|
||||
}
|
||||
|
||||
/* format 21 -- movep*/
|
||||
opf21()
|
||||
{
|
||||
register m,d;
|
||||
register char *p;
|
||||
|
||||
if(get2ops())
|
||||
return;
|
||||
if(ckdreg(&opnd[0])) { /*d reg source*/
|
||||
m = 0600;
|
||||
d = opnd[0].ea;
|
||||
p = &opnd[1];
|
||||
}
|
||||
else if(ckdreg(&opnd[1])) { /*d reg dest*/
|
||||
m = 0400;
|
||||
d = opnd[1].ea;
|
||||
p = &opnd[0];
|
||||
}
|
||||
else {
|
||||
uerr(20);
|
||||
}
|
||||
if((p->ea&070) != INDDISP)
|
||||
uerr(20);
|
||||
if(modelen == 4)
|
||||
m =| 0100;
|
||||
ins[0] =| (d<<9)|m|(p->ea&7);
|
||||
*pins++ = p->con.wd2;
|
||||
*prlb++ = p->drlc;
|
||||
instrlen =+ 2;
|
||||
}
|
||||
|
||||
/* format 22 -- moveq*/
|
||||
opf22()
|
||||
{
|
||||
if(get2ops())
|
||||
return;
|
||||
if(opnd[0].ea != IMM)
|
||||
uerr(17);
|
||||
if(opnd[0].con>255L || opnd[0].con<-256L)
|
||||
uerr(15);
|
||||
if(!ckdreg(&opnd[1]))
|
||||
uerr(33);
|
||||
ins[0] =| (opnd[1].ea<<9) | (opnd[0].con.wd2&0377);
|
||||
}
|
||||
|
||||
/* format 23 -- eor*/
|
||||
opf23()
|
||||
{
|
||||
if(get2ops())
|
||||
return;
|
||||
if (cksprg(&opnd[1],CCR) || cksprg(&opnd[1],SR)) {
|
||||
opcpt = eoriptr;
|
||||
ins[0] = opcpt->vl1.wd2;
|
||||
format = (opcpt->flags)&OPFF;
|
||||
ccr_or_sr();
|
||||
return;
|
||||
}
|
||||
if(!ckdreg(&opnd[0])) {
|
||||
if(makeimm()) /*must be immediate*/
|
||||
return;
|
||||
uerr(20); /*or error*/
|
||||
}
|
||||
if(!dataalt(&opnd[1]) || pcea(&opnd[1]))
|
||||
uerr(20);
|
||||
ins[0] =| (opnd[0].ea<<9)|f23mode[modelen]|opnd[1].ea;
|
||||
doea(&opnd[1]);
|
||||
}
|
||||
|
||||
856
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/as68/pass2.lis
Normal file
856
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/as68/pass2.lis
Normal file
@@ -0,0 +1,856 @@
|
||||
1File: PASS2.C Page 1
|
||||
1 /*
|
||||
2 Copyright 1981
|
||||
3 Alcyon Corporation
|
||||
4 8716 Production Ave.
|
||||
5 San Diego, Ca. 92121
|
||||
6 */
|
||||
7
|
||||
8 /*
|
||||
9 * pass two for the 68000 assembler
|
||||
10 * Bill Allen
|
||||
11 * March 1980
|
||||
12 */
|
||||
13
|
||||
14 #include "as68.h"
|
||||
15 #include "cout.h" /*c.out header definition & MAGIC*/
|
||||
16
|
||||
17 #define MOVEA 0100
|
||||
18
|
||||
19 int p2gi();
|
||||
20
|
||||
21 extern char tfilname[]; /*name of it file*/
|
||||
22 extern char initfnam[]; /*name of the initilization file*/
|
||||
23 int (*p2direct[])();
|
||||
24
|
||||
25 int opf1(), opf2(), opf3(), opf4(), opf5(), relbr(), opf7(), opf8();
|
||||
26 int opf9(), opf11(), opf12(), opf13(), opf15(), opf17(), opf20();
|
||||
27 int opf21(), opf22(), opf23();
|
||||
28
|
||||
29 int (*opfary[])() {
|
||||
30 0, /*0*/
|
||||
31 opf1, /*1*/
|
||||
32 opf2, /*2*/
|
||||
33 opf3, /*3*/
|
||||
34 opf4, /*4*/
|
||||
35 opf5, /*5*/
|
||||
36 relbr, /*6*/
|
||||
37 opf7, /*7*/
|
||||
38 opf8, /*8*/
|
||||
39 opf9, /*9*/
|
||||
40 opf4, /*10*/
|
||||
41 opf11, /*11*/
|
||||
42 opf12, /*12*/
|
||||
43 opf13, /*13*/
|
||||
44 opf9, /*14*/
|
||||
45 opf15, /*15*/
|
||||
46 opf17, /*16*/
|
||||
47 opf17, /*17*/
|
||||
48 opf13, /*18*/
|
||||
49 opf11, /*19*/
|
||||
50 opf20, /*20*/
|
||||
51 opf21, /*21*/
|
||||
52 opf22, /*22*/
|
||||
53 opf23, /*23*/
|
||||
54 opf9, /*24*/
|
||||
55 opf9, /*25*/
|
||||
56 opf5, /*26*/ /* [vlh] cmp, chk, extention verification */
|
||||
57 opf4, /*27*/ /* [vlh] addx, subx, extension verification */
|
||||
58 opf13, /*28*/ /* [vlh] swap, extension verification */
|
||||
59 opf9, /*29*/ /* [vlh] pea, extention verification */
|
||||
1File: PASS2.C Page 2
|
||||
60 opf15 /*30*/ /* [vlh] lea, extension verification */
|
||||
61 };
|
||||
62
|
||||
63 #define LSTFRMT 30
|
||||
64
|
||||
65 int f1mode[] {0,0,0100,0,0200};
|
||||
66 int f2mode[] {0,0,0100,0,0200};
|
||||
67 int f3mode[] {0,010000,030000,0,020000};
|
||||
68 int f15mode[] {0,0,0300,0,0700};
|
||||
69 int f5mode[] {0,0,0100,0,0200};
|
||||
70 int f5amode[] {0,0,0300,0,0700};
|
||||
71 int f13mode[] {0,0,0200,0,0300};
|
||||
72 int f23mode[] {0,0400,0500,0,0600};
|
||||
73 int rlbits[5]; /*holds relocation bits for instr*/
|
||||
74 int pline; /*number of last printed line*/
|
||||
75 int brkln2 077777; /*pass 2 break line number for debugging*/
|
||||
76 int prsp; /*special print alignment flag*/
|
||||
77 int amode; /*addressing mode*/
|
||||
78 int nitleft;
|
||||
79 /*pass two driver*/
|
||||
80 pass2()
|
||||
81 {
|
||||
82 register short *p;
|
||||
83 register i;
|
||||
84 register (*dirop)();
|
||||
85
|
||||
86 pitix = itbuf; /* This is init for doitrd*/
|
||||
87 xline = LPP;
|
||||
88 nitleft = 0;
|
||||
89 lbuf.nunused = tbuf.nunused = dabuf.nunused = drbuf.nunused = 512;
|
||||
90 lbuf.fildes = lfn; /*set buffered io for binary file*/
|
||||
91 lbuf.xfree = &lbuf.buff[0];
|
||||
92 tbuf.fildes = trbfn; /*set buffered io for text reloc bits file*/
|
||||
93 tbuf.xfree = &tbuf.buff[0];
|
||||
94 dabuf.fildes = dafn; /*set buffered io for data bytes*/
|
||||
95 dabuf.xfree = &dabuf.buff[0];
|
||||
96 drbuf.fildes = drbfn; /*set buffered io for data reloc bits*/
|
||||
97 drbuf.xfree = &drbuf.buff[0];
|
||||
98 couthd.ch_magic = MAGIC;/*c.out magic number*/
|
||||
99 if(savelc[TEXT]&1)
|
||||
100 savelc[TEXT]++; /*make it even*/
|
||||
101 couthd.ch_tsize = savelc[TEXT]; /*text size*/
|
||||
102 if(savelc[DATA]&1)
|
||||
103 savelc[DATA]++; /*make it even*/
|
||||
104 couthd.ch_dsize = savelc[DATA]; /*data size*/
|
||||
105 couthd.ch_bsize = savelc[BSS]; /*bss size*/
|
||||
106 /*symbol table size is not known now -- it is set at end of pass 2*/
|
||||
107 /* entry point and stack size are zero for now*/
|
||||
108 p = &couthd;
|
||||
109 for(i=0; i<HDSIZE/2; i++) {
|
||||
110 putw(*p++,&lbuf); /*write the file header words*/
|
||||
111 }
|
||||
112 savelc[0] = 0; savelc[1] = 0; savelc[2] = 0; savelc[3] = 0;
|
||||
113 loctr = 0; /*location counter*/
|
||||
114 rlflg = TEXT; /*TEXT relocatable*/
|
||||
115 p2flg = 1; /*pass two*/
|
||||
116 #ifdef UNIX
|
||||
117 if (lseek(ifn,0L,0) == -1) { /*beginning of source*/
|
||||
118 rpterr("seek error on source file\n");
|
||||
1File: PASS2.C Page 3
|
||||
119 abort();
|
||||
120 }
|
||||
121 #else
|
||||
122 close(ifn); /* This way for goddamn Whitesmith's */
|
||||
123 ifn=open(sfname,0,0); /* Re-open the fucking source file */
|
||||
124 if(ifn < 0) /* Couldn't */
|
||||
125 {
|
||||
126 printf("Unable to open file %s\n",sfname);
|
||||
127 abort();
|
||||
128 }
|
||||
129 #endif
|
||||
130 close(itfn);
|
||||
131 LASTCHTFN = itfnc;
|
||||
132 itfn = openfi(tfilname,0); /*open it for reading*/
|
||||
133 pline = 1; /*no lines printed*/
|
||||
134 fchr=gchr(); /*get first char*/
|
||||
135 while(ristb()) { /*pass 2 main loop*/
|
||||
136 p2absln = stbuf[0].itop; /*line number*/
|
||||
137 if(p2absln>=brkln2) /*for debugging the assembler*/
|
||||
138 i=0;
|
||||
139 opcpt = stbuf[2].itop.ptrw2; /*ptr to opcode entry in main tab*/
|
||||
140 nite = stbuf[0].itrl & 0377; /*number of it entries*/
|
||||
141 pnite = &stbuf[nite]; /*ptr to end of stmt*/
|
||||
142 modelen = stbuf[2].itrl; /*instr mode length*/
|
||||
143 p1inlen = stbuf[1].itrl; /*pass 1 instr length guess*/
|
||||
144 opdix = ITOP1; /*first operand*/
|
||||
145 pitw = &stbuf[ITOP1]; /*ptr to first operand*/
|
||||
146 prsp = 0; /*special print flag off*/
|
||||
147 instrlen = 2; /*default for print*/
|
||||
148 if(opcpt->flags&OPDR) { /*opcode is a directive*/
|
||||
149 i = opcpt->vl1; /*directive number*/
|
||||
150 dirop = p2direct[i];
|
||||
151 (*dirop)(); /*handle directive*/
|
||||
152 }
|
||||
153 else {
|
||||
154 gcist(); /*generate code for one statement*/
|
||||
155 }
|
||||
156 }
|
||||
157 }
|
||||
158
|
||||
159 /* generate code for an instruction*/
|
||||
160 /* call with*/
|
||||
161 /* intermediate text for instruction in stbuf*/
|
||||
162 gcist()
|
||||
163 {
|
||||
164 register i,j;
|
||||
165
|
||||
166 if(stbuf[0].itty != ITBS) /*beginning of statement*/
|
||||
167 abort();
|
||||
168 format = (opcpt->flags)&OPFF;
|
||||
169 in_err = 0; /*[vlh] no error this instruction, yet*/
|
||||
170 ival = 0; /*initial value for possible operand*/
|
||||
171 reloc = ABS;
|
||||
172 instrlen = 2; /*at least 2 bytes*/
|
||||
173 ins[0] = opcpt->vl1; /*opcode value*/
|
||||
174 rlbits[0] = INSABS; /*instruction absolute*/
|
||||
175 pins = &ins[1];
|
||||
176 prlb = &rlbits[1];
|
||||
177 if(nite>ITOP1) { /*operands*/
|
||||
1File: PASS2.C Page 4
|
||||
178 if(!format) {
|
||||
179 uerr(9);
|
||||
180 }
|
||||
181 else if(format>LSTFRMT) /* [vlh] was a magic number... */
|
||||
182 abort();
|
||||
183 else {
|
||||
184 (*opfary[format])();
|
||||
185 }
|
||||
186 }
|
||||
187 if (!ckein() && !in_err) /* at end of statement ?? */
|
||||
188 uerr(6);
|
||||
189 print(1); /*print source*/
|
||||
190
|
||||
191 loctr =+ p1inlen;
|
||||
192 if (!in_err && p1inlen != instrlen) /* [vlh] 2nd pass error recovery */
|
||||
193 uerr(38);
|
||||
194 outinstr(); /*write out instr binary*/
|
||||
195 }
|
||||
196
|
||||
197 /* relative branches*/
|
||||
198 relbr()
|
||||
199 {
|
||||
200 expr(&p2gi);
|
||||
201 if(extflg) { /*external reference*/
|
||||
202 instrlen =+ 2; /*long relative*/
|
||||
203 *pins++ = ival; /*pass constant part*/
|
||||
204 *prlb++ = (extref<<3)|EXTREL; /*ext ref*/
|
||||
205 return;
|
||||
206 }
|
||||
207 ival =- (loctr+2); /*calc relative offset*/
|
||||
208 if(itype!=ITCN || reloc != rlflg) {
|
||||
209 uerr(22); /*invalid relative branch*/
|
||||
210 ival = 0;
|
||||
211 }
|
||||
212 reloc = ABS;
|
||||
213 if(p1inlen==4) { /*long displacement*/
|
||||
214 if(ival< (-32768L) || ival > (32767L))
|
||||
215 uerr(22);
|
||||
216 instrlen =+ 2;
|
||||
217 *pins++ = ival;
|
||||
218 *prlb++ = DABS; /*data absolute*/
|
||||
219 }
|
||||
220 else { /*short displacement*/
|
||||
221 if (ival>127 || ival<-128)
|
||||
222 uerr(22);
|
||||
223 ins[0] =| (ival.wd2&0377);
|
||||
224 }
|
||||
225 if (!ival) { /* make it a nop */
|
||||
226 opcpt = nopptr;
|
||||
227 ins[0] = opcpt->vl1.wd2;
|
||||
228 pins = &ins[1];
|
||||
229 if (modelen==4) {
|
||||
230 *pins++ = opcpt->vl1.wd2;
|
||||
231 rlbits[1] = INSABS;
|
||||
232 }
|
||||
233 }
|
||||
234 in_err++; /* ignore extra eg. bra *+$d04(pc) vs. bra *+d04 */
|
||||
235 }
|
||||
236
|
||||
1File: PASS2.C Page 5
|
||||
237 /* format one -- add, sub, and, or, cmp, etc.*/
|
||||
238 /* one operand must be a D reg (or A reg dest for add, sub, or cmp)*/
|
||||
239 opf1()
|
||||
240 {
|
||||
241 register int *p;
|
||||
242
|
||||
243 if(get2ops())
|
||||
244 return;
|
||||
245 if (ins[0]==AND || ins[0]==OR)
|
||||
246 if (cksprg(&opnd[1],CCR) || cksprg(&opnd[1],SR)) {
|
||||
247 if (ins[0]==AND) opcpt = andiptr;
|
||||
248 else opcpt = oriptr;
|
||||
249 ins[0] = opcpt->vl1.wd2;
|
||||
250 format = (opcpt->flags)&OPFF;
|
||||
251 ccr_or_sr();
|
||||
252 return;
|
||||
253 }
|
||||
254 p = f1mode;
|
||||
255 if(ckdreg(&opnd[1])) { /*destn is D reg*/
|
||||
256 if((opcpt==andptr||opcpt==orptr)&&ckareg(&opnd[0])) /*A source*/
|
||||
257 uerr(20);
|
||||
258 makef1(opnd[1].ea,p[modelen],&opnd[0]); /*make instr*/
|
||||
259 return;
|
||||
260 }
|
||||
261 else if(ckdreg(&opnd[0]) && memalt(&opnd[1])) { /*source is D reg*/
|
||||
262 if (pcea(&opnd[1])) uerr(10);
|
||||
263 makef1(opnd[0].ea,p[modelen]+0400,&opnd[1]);
|
||||
264 return;
|
||||
265 }
|
||||
266 else if(ckareg(&opnd[1])) { /*A reg is dstn*/
|
||||
267 if(opcpt==addptr)
|
||||
268 opcpt = addaptr;
|
||||
269 else if(opcpt==cmpptr)
|
||||
270 opcpt = cmpaptr;
|
||||
271 else if(opcpt==subptr)
|
||||
272 opcpt = subaptr;
|
||||
273 else {
|
||||
274 uerr(20);
|
||||
275 return;
|
||||
276 }
|
||||
277 format = (opcpt->flags)&OPFF;
|
||||
278 opnd[1].ea =& 07;
|
||||
279 p = f15mode;
|
||||
280 makef1(opnd[1].ea,p[modelen],&opnd[0]); /*make instr*/
|
||||
281 return;
|
||||
282 }
|
||||
283 else if(!makeimm()) /*make an immediate instr*/
|
||||
284 uerr(20);
|
||||
285 }
|
||||
286
|
||||
287 /* format 2 -- addi, andi, subi, etc*/
|
||||
288 opf2()
|
||||
289 {
|
||||
290 if(get2ops())
|
||||
291 return;
|
||||
292 if(ins[0]==ANDI || ins[0]==ORI || ins[0]==EORI) {
|
||||
293 if(cksprg(&opnd[1],CCR) || cksprg(&opnd[1],SR)) {
|
||||
294 ccr_or_sr();
|
||||
295 return;
|
||||
1File: PASS2.C Page 6
|
||||
296 }
|
||||
297 }
|
||||
298 if(opnd[0].ea != IMM) {
|
||||
299 uerr(9);
|
||||
300 return;
|
||||
301 }
|
||||
302 if(!dataalt(&opnd[1]) || pcea(&opnd[1])) {
|
||||
303 uerr(20);
|
||||
304 return;
|
||||
305 }
|
||||
306 genimm();
|
||||
307 }
|
||||
308
|
||||
309 /*format #3 -- move and movea*/
|
||||
310 opf3()
|
||||
311 {
|
||||
312 register i,j,k;
|
||||
313
|
||||
314 if(get2ops())
|
||||
315 return;
|
||||
316 if(cksprg(&opnd[1],CCR)) {
|
||||
317 ins[0] = MOVECCR;
|
||||
318 opf3l1:
|
||||
319 if (modelen==1 || modelen==4) uerr(34);
|
||||
320 if(anysprg(&opnd[0]))
|
||||
321 uerr(20);
|
||||
322 ins[0] =| opnd[0].ea;
|
||||
323 if(!dataea(&opnd[0]))
|
||||
324 uerr(9);
|
||||
325 doea(&opnd[0]);
|
||||
326 return;
|
||||
327 }
|
||||
328 if(cksprg(&opnd[1],SR)) {
|
||||
329 ins[0] = MOVESR;
|
||||
330 goto opf3l1;
|
||||
331 }
|
||||
332 if(cksprg(&opnd[0],SR)) {
|
||||
333 if (modelen==1 || modelen==4)
|
||||
334 uerr(34);
|
||||
335 if(anysprg(&opnd[1]))
|
||||
336 uerr(20);
|
||||
337 ins[0] = SRMOVE | opnd[1].ea;
|
||||
338 if(!dataalt(&opnd[1]) || pcea(&opnd[1]))
|
||||
339 uerr(10);
|
||||
340 doea(&opnd[1]);
|
||||
341 return;
|
||||
342 }
|
||||
343 if(cksprg(&opnd[0],USP)) {
|
||||
344 if (modelen == 1)
|
||||
345 uerr(34); /* default is word, can't test */
|
||||
346 if (!ckareg(&opnd[1]))
|
||||
347 uerr(33);
|
||||
348 ins[0] = MOVEUSP|8|(opnd[1].ea&7);
|
||||
349 return;
|
||||
350 }
|
||||
351 if(cksprg(&opnd[1],USP)) {
|
||||
352 if (modelen == 1)
|
||||
353 uerr(34); /* default is word, can't test */
|
||||
354 if (!ckareg(&opnd[0]))
|
||||
1File: PASS2.C Page 7
|
||||
355 uerr(33);
|
||||
356 ins[0] = MOVEUSP|(opnd[0].ea&7);
|
||||
357 return;
|
||||
358 }
|
||||
359 k = ins[0];
|
||||
360 ins[0] =| f3mode[modelen];
|
||||
361 ckbytea();
|
||||
362 ins[0] =| opnd[0].ea; /*source ea*/
|
||||
363 doea(&opnd[0]);
|
||||
364 ins[0] =| (opnd[1].ea&7)<<9; /*dest register*/
|
||||
365 ins[0] =| (opnd[1].ea&070)<<3; /*dest mode*/
|
||||
366 doea(&opnd[1]);
|
||||
367 if(k==MOVEA) {
|
||||
368 if(dataea(&opnd[1]))
|
||||
369 uerr(20);
|
||||
370 }
|
||||
371 else if((pcea(&opnd[1]) && dataea(&opnd[1])) || opnd[1].ea==IMM)
|
||||
372 uerr(20);
|
||||
373 }
|
||||
374
|
||||
375 /* format 4 -- abcd, sbcd */
|
||||
376 /* format 10 -- cmpm*/
|
||||
377 /* format 27 -- addx, subx */
|
||||
378 opf4()
|
||||
379 {
|
||||
380 if(get2ops())
|
||||
381 return;
|
||||
382 if (format==27) { /*addx,subx add in size bits*/
|
||||
383 ins[0] =| f1mode[modelen];
|
||||
384 }
|
||||
385 else if(format==10) { /*cmpm*/
|
||||
386 if((opnd[0].ea&070)!=INDINC || (opnd[1].ea&070)!=INDINC)
|
||||
387 uerr(20);
|
||||
388 ins[0] =| f1mode[modelen] | ((opnd[0].ea&7)|((opnd[1].ea&7)<<9));
|
||||
389 return;
|
||||
390 }
|
||||
391 if(ckdreg(&opnd[0]) && ckdreg(&opnd[1])) {
|
||||
392 ins[0] =| ((opnd[0].ea&7)|((opnd[1].ea&7)<<9));
|
||||
393 return;
|
||||
394 }
|
||||
395 if((opnd[0].ea&070)==DECIND && (opnd[1].ea&070)==DECIND) {
|
||||
396 ins[0] =| 010 | ((opnd[0].ea&7)|((opnd[1].ea&7)<<9));
|
||||
397 return;
|
||||
398 }
|
||||
399 uerr(20);
|
||||
400 }
|
||||
401
|
||||
402 /*format 5 -- div, mul*/
|
||||
403 /*format 26 -- cmp, chk */
|
||||
404 opf5()
|
||||
405 {
|
||||
406 if(get2ops())
|
||||
407 return;
|
||||
408 if(!ckdreg(&opnd[1])) {
|
||||
409 if(opcpt==cmpptr) {
|
||||
410 if(!dataea(&opnd[1])) /* [vlh] made define */
|
||||
411 ins[0] =| f5amode[modelen]; /* was pumode */
|
||||
412 else if(makeimm())
|
||||
413 return;
|
||||
1File: PASS2.C Page 8
|
||||
414 else
|
||||
415 uerr(20);
|
||||
416 }
|
||||
417 else
|
||||
418 uerr(20);
|
||||
419 }
|
||||
420 if(opcpt==cmpptr) {
|
||||
421 ins[0] =| f5mode[modelen]; /* was pumode */
|
||||
422 ckbytea();
|
||||
423 }
|
||||
424 else if(!dataea(&opnd[0]))
|
||||
425 uerr(20);
|
||||
426 ins[0] =| (opnd[1].ea&7)<<9 | opnd[0].ea;
|
||||
427 doea(&opnd[0]);
|
||||
428 }
|
||||
429
|
||||
430 #define BTST 0000
|
||||
431 /* format 7 -- bit instrs -- btst, bclr, bset, etc*/
|
||||
432 opf7()
|
||||
433 {
|
||||
434 if(get2ops())
|
||||
435 return;
|
||||
436 if(opnd[1].ea==IMM||(ins[0]!=BTST&&pcea(&opnd[1]))||ckareg(&opnd[1]))
|
||||
437 uerr(20);
|
||||
438 if(ckdreg(&opnd[0])) {
|
||||
439 ins[0] =| (opnd[0].ea<<9)|0400;
|
||||
440 }
|
||||
441 else { /*static bit #*/
|
||||
442 if(opnd[0].con<0L || opnd[0].con>31 ||
|
||||
443 (opnd[1].ea&INDIRECT&&opnd[0].con>7)) /* [vlh] */
|
||||
444 uerr(23);
|
||||
445 if(opnd[0].ea != IMM)
|
||||
446 uerr(17);
|
||||
447 ins[0] =| 04000;
|
||||
448 dodisp(&opnd[0]);
|
||||
449 }
|
||||
450 if (modelen==1 && !(memea(&opnd[1]))) /*[vlh]*/
|
||||
451 uerr(20);
|
||||
452 else if (!(ckdreg(&opnd[1])) && modelen==4)
|
||||
453 uerr(20);
|
||||
454 ins[0] =| opnd[1].ea;
|
||||
455 doea(&opnd[1]);
|
||||
456 }
|
||||
457
|
||||
458 /* format 8 -- shifts and rotates*/
|
||||
459 opf8()
|
||||
460 {
|
||||
461 register i;
|
||||
462
|
||||
463 getea(0); /*get first operand*/
|
||||
464 if(pitw >= pnite) { /*end of all ops*/
|
||||
465 if(ckdreg(&opnd[0])) { /*shift dreg one bit*/
|
||||
466 cpop01(); /*copy opnd 0 to 1*/
|
||||
467 opnd[0].ea = IMM;
|
||||
468 opnd[0].con = 1L;
|
||||
469 if (!ckdreg(&opnd[1])) uerr(20);
|
||||
470 opf8l1:
|
||||
471 if(opnd[0].con<1 || opnd[0].con>8) /*[vlh legal range 1..8*/
|
||||
472 uerr(37);
|
||||
1File: PASS2.C Page 9
|
||||
473 ins[0] =| ((opnd[0].con.wd2&7)<<9)|f1mode[modelen]|opnd[1].ea;
|
||||
474 return;
|
||||
475 }
|
||||
476 i = (ins[0]&077)<<6;
|
||||
477 ins[0] =& 0177700;
|
||||
478 ins[0] =| 0300|i|opnd[0].ea;
|
||||
479 if(!memalt(&opnd[0]) || pcea(&opnd[0]) || modelen != 2)
|
||||
480 uerr(20);
|
||||
481 doea(&opnd[0]);
|
||||
482 return;
|
||||
483 }
|
||||
484 if(!ckcomma()) {
|
||||
485 uerr(10);
|
||||
486 return;
|
||||
487 }
|
||||
488 getea(1); /*get second operand*/
|
||||
489 if(!ckdreg(&opnd[1])) /* [vlh] second operand must be dreg */
|
||||
490 uerr(20);
|
||||
491 if(ckdreg(&opnd[0])) { /*first op is D reg*/
|
||||
492 ins[0] =| (opnd[0].ea<<9)|040; /*reg # and reg bit*/
|
||||
493 }
|
||||
494 else {
|
||||
495 if(opnd[0].ea != IMM)
|
||||
496 uerr(20);
|
||||
497 goto opf8l1;
|
||||
498 }
|
||||
499 ins[0] =| f1mode[modelen] | opnd[1].ea; /*put in size and reg #*/
|
||||
500 }
|
||||
501
|
||||
502 /* format 9 -- jmp, jsr */
|
||||
503 /* format 14 -- stop */
|
||||
504 /* format 24 -- clr, neg, negx, not */
|
||||
505 /* format 25 -- s?? */
|
||||
506 /* format 29 -- pea */
|
||||
507 /* one operand instructions -- jmp, clr, neg, not, sge, etc.*/
|
||||
508 opf9()
|
||||
509 {
|
||||
510 getea(0);
|
||||
511 if(format==24) { /*clr, not, etc*/
|
||||
512 ins[0] =| f1mode[modelen]; /*add size bits*/
|
||||
513 if(!dataalt(&opnd[0]) || pcea(&opnd[0]))
|
||||
514 uerr(20);
|
||||
515 }
|
||||
516 else if(format==25) { /*tas,scc, etc*/
|
||||
517 if(ckareg(&opnd[0]) || pcea(&opnd[0]) || opnd[0].ea==IMM)
|
||||
518 uerr(20);
|
||||
519 }
|
||||
520 else if(format==14) { /*stop*/
|
||||
521 if(modelen!=2 || opnd[0].ea!=IMM)
|
||||
522 uerr(20);
|
||||
523 doea(&opnd[0]);
|
||||
524 return;
|
||||
525 }
|
||||
526 else if(!controlea(&opnd[0])) /*jmp, jsr, etc*/
|
||||
527 uerr(20);
|
||||
528 ins[0] =| opnd[0].ea;
|
||||
529 doea(&opnd[0]);
|
||||
530 }
|
||||
531
|
||||
1File: PASS2.C Page 10
|
||||
532 /* format 11 -- dbcc*/
|
||||
533 /* format 19 -- link*/
|
||||
534 opf11()
|
||||
535 {
|
||||
536 if(get2ops())
|
||||
537 return;
|
||||
538 if(format==19) { /*link*/
|
||||
539 if(!ckareg(&opnd[0]))
|
||||
540 uerr(33);
|
||||
541 if(opnd[1].ea != IMM)
|
||||
542 uerr(17);
|
||||
543 }
|
||||
544 else {
|
||||
545 if(!ckdreg(&opnd[0]))
|
||||
546 uerr(33);
|
||||
547 if(opnd[1].drlc!=rlflg) /*[vlh]don't chk opnd[1].ea!=LADDR||SADDR*/
|
||||
548 uerr(22);
|
||||
549 opnd[1].con =- (loctr+2L);
|
||||
550 cksize(&opnd[1]);
|
||||
551 opnd[1].drlc = ABS; /*not relocatable*/
|
||||
552 }
|
||||
553 ins[0] =| opnd[0].ea&7; /*put in reg #*/
|
||||
554 dodisp(&opnd[1]);
|
||||
555 }
|
||||
556
|
||||
557 /* format 12 -- exg*/
|
||||
558 opf12()
|
||||
559 {
|
||||
560 register i;
|
||||
561
|
||||
562 if(get2ops())
|
||||
563 return;
|
||||
564 if(ckdreg(&opnd[0])) {
|
||||
565 if(ckdreg(&opnd[1])) { /*exchange D regs*/
|
||||
566 ins[0] =| 0100 | ((opnd[0].ea&7)<<9) | (opnd[1].ea&7);
|
||||
567 return;
|
||||
568 }
|
||||
569 if(ckareg(&opnd[1])) { /*ins[0] <- A and D flag*/
|
||||
570 ins[0] =| 0210 | ((opnd[0].ea&7)<<9) | (opnd[1].ea&7);
|
||||
571 return;
|
||||
572 }
|
||||
573 }
|
||||
574 if(ckareg(&opnd[0])) {
|
||||
575 if(ckareg(&opnd[1])) { /*both a regs*/
|
||||
576 ins[0] =| 0110 | ((opnd[0].ea&7)<<9) | (opnd[1].ea&7);
|
||||
577 return;
|
||||
578 }
|
||||
579 if(ckdreg(&opnd[1])) { /*A and D regs*/
|
||||
580 i = opnd[0].ea; /*exchg ea's*/
|
||||
581 opnd[0].ea = opnd[1].ea;
|
||||
582 opnd[1].ea = i;
|
||||
583 ins[0] =| 0210 | ((opnd[0].ea&7)<<9) | (opnd[1].ea&7);
|
||||
584 return;
|
||||
585 }
|
||||
586 }
|
||||
587 uerr(20);
|
||||
588 }
|
||||
589
|
||||
590 /* format 13 -- ext, unlk*/
|
||||
1File: PASS2.C Page 11
|
||||
591 /* format 18 -- trap*/
|
||||
592 /* format 28 -- swap */
|
||||
593 #define UNLK 047130
|
||||
594
|
||||
595 opf13()
|
||||
596 {
|
||||
597 getea(0);
|
||||
598 if(format==18) { /*trap*/
|
||||
599 if(opnd[0].con<0 || opnd[0].con>15)
|
||||
600 uerr(15);
|
||||
601 ins[0] =| opnd[0].con.wd2;
|
||||
602 return;
|
||||
603 }
|
||||
604 if(ins[0]==UNLK) { /*unlk instr*/
|
||||
605 if(!ckareg(&opnd[0]))
|
||||
606 uerr(20);
|
||||
607 }
|
||||
608 else {
|
||||
609 if(!ckdreg(&opnd[0]))
|
||||
610 uerr(20);
|
||||
611 if (format==13) /* ext */
|
||||
612 ins[0] =| f13mode[modelen];
|
||||
613 }
|
||||
614 ins[0] =| opnd[0].ea&7;
|
||||
615 }
|
||||
616
|
||||
617 /* format 15 -- adda, cmpa, suba*/
|
||||
618 /* format 30 -- lea */
|
||||
619 opf15()
|
||||
620 {
|
||||
621 register i;
|
||||
622
|
||||
623 if(get2ops())
|
||||
624 return;
|
||||
625 if(!ckareg(&opnd[1]))
|
||||
626 uerr(33);
|
||||
627 if(format==30) {
|
||||
628 i = 0700;
|
||||
629 if(!controlea(&opnd[0]))
|
||||
630 uerr(20);
|
||||
631 }
|
||||
632 else
|
||||
633 i = f15mode[modelen];
|
||||
634 makef1(opnd[1].ea&7,i,&opnd[0]);
|
||||
635 if (format==15 && opnd[0].ea != 071) cksize(&opnd[0]);
|
||||
636 }
|
||||
637
|
||||
638 /*formats 16 and 17 -- addq, inc, subq, dec*/
|
||||
639 opf17()
|
||||
640 {
|
||||
641 if(format==16) { /*inc or dec*/
|
||||
642 clrea(&opnd[0]);
|
||||
643 opnd[0].ea = IMM;
|
||||
644 opnd[0].con = 1L;
|
||||
645 opnd[0].drlc = ABS;
|
||||
646 getea(1);
|
||||
647 }
|
||||
648 else {
|
||||
649 if(get2ops())
|
||||
1File: PASS2.C Page 12
|
||||
650 return;
|
||||
651 }
|
||||
652 if(opnd[0].ea != IMM || !altea(&opnd[1]) || pcea(&opnd[1]))
|
||||
653 uerr(20);
|
||||
654 if(opnd[0].con<=0 || opnd[0].con>8)
|
||||
655 uerr(15);
|
||||
656 if(modelen==1 && !dataea(&opnd[1]))
|
||||
657 uerr(34);
|
||||
658 ins[0] =| f1mode[modelen]|((opnd[0].con.wd2&7)<<9)|opnd[1].ea;
|
||||
659 doea(&opnd[1]);
|
||||
660 }
|
||||
661
|
||||
662 /* format 20 -- movem */
|
||||
663 int regmsk0[] {0100000,040000,020000,010000,04000,02000,01000,0400,0200,
|
||||
664 0100,040,020,010,4,2,1};
|
||||
665 int regmsk1[] {1,2,4,010,020,040,0100,0200,0400,01000,02000,04000,010000,
|
||||
666 020000,040000,0100000};
|
||||
667 opf20()
|
||||
668 {
|
||||
669 register dr;
|
||||
670 register i,j;
|
||||
671
|
||||
672 dr = 0;
|
||||
673 if(getreg() != -1 || pitw->itty == ITRM) { /*regs to memory*/
|
||||
674 if (pitw->itty != ITRM) { /* [vlh] */
|
||||
675 pitw--;
|
||||
676 j = getrlist(regmsk0);
|
||||
677 }
|
||||
678 else {
|
||||
679 j = pitw->itop;
|
||||
680 pitw++;
|
||||
681 }
|
||||
682 if(!ckcomma())
|
||||
683 uerr(10);
|
||||
684 }
|
||||
685 else
|
||||
686 dr = 02000;
|
||||
687 getea(0);
|
||||
688 if(dr) {
|
||||
689 if(!ckcomma())
|
||||
690 uerr(10);
|
||||
691 if (pitw->itty != ITRM) /* [vlh] */
|
||||
692 j = getrlist(regmsk1); /*mem to regs*/
|
||||
693 else {
|
||||
694 j = pitw->itop;
|
||||
695 j = fixmask(j);
|
||||
696 pitw++;
|
||||
697 }
|
||||
698 }
|
||||
699 else {
|
||||
700 if(controlea(&opnd[0]))
|
||||
701 j = fixmask(j);
|
||||
702 }
|
||||
703 i = opnd[0].ea&070;
|
||||
704 if(!controlea(&opnd[0]) && i!=INDINC && i!=DECIND)
|
||||
705 uerr(20);
|
||||
706 if(modelen==4) /*long*/
|
||||
707 ins[0] =| 0100;
|
||||
708 ins[0] =| opnd[0].ea|dr;
|
||||
1File: PASS2.C Page 13
|
||||
709 *pins++ = j; /*reg mask*/
|
||||
710 *prlb++ = DABS;
|
||||
711 instrlen =+ 2;
|
||||
712 doea(&opnd[0]);
|
||||
713 if (!dr) { /* 1st argument (2nd is reg list) */
|
||||
714 if (pcea(&opnd[0]) || (opnd[0].ea&070)==INDINC)
|
||||
715 uerr(20); /* xx(pc), xx(pc,dx), -(ax) */
|
||||
716 }
|
||||
717 else /* 2nd argument (1st is reg list) */
|
||||
718 if ((opnd[0].ea&070)==DECIND)
|
||||
719 uerr(20); /* (ax)+ */
|
||||
720 }
|
||||
721
|
||||
722 /*
|
||||
723 * get a list of registers for the movem instr
|
||||
724 * call with:
|
||||
725 * ptr to reg-to-mem or mem-to-reg array of bits
|
||||
726 */
|
||||
727 getrlist(ap)
|
||||
728 int *ap;
|
||||
729 {
|
||||
730 register int *p,i,j;
|
||||
731 register int mask;
|
||||
732
|
||||
733 p = ap;
|
||||
734 mask = 0;
|
||||
735 while((i=getreg()) != -1) {
|
||||
736 if(ckitc(pitw,'-')) {
|
||||
737 pitw++;
|
||||
738 if((j=getreg()) == -1) {
|
||||
739 uerr(40);
|
||||
740 break;
|
||||
741 }
|
||||
742 while(i<=j)
|
||||
743 mask =| p[i++];
|
||||
744 }
|
||||
745 else
|
||||
746 mask =| p[i];
|
||||
747 if(ckitc(pitw,'/'))
|
||||
748 pitw++;
|
||||
749 else
|
||||
750 break;
|
||||
751 }
|
||||
752 if(!mask)
|
||||
753 uerr(40);
|
||||
754 return(mask);
|
||||
755 }
|
||||
756
|
||||
757 /*reverse a movem register mask for control ea to memory*/
|
||||
758 fixmask(msk)
|
||||
759 {
|
||||
760 register i,j,k;
|
||||
761
|
||||
762 k = (msk&1) ? 0100000 : 0;
|
||||
763 i = 2;
|
||||
764 j = 040000;
|
||||
765 while(i) {
|
||||
766 if(msk&i)
|
||||
767 k =| j;
|
||||
1File: PASS2.C Page 14
|
||||
768 i =<< 1;
|
||||
769 j =>> 1;
|
||||
770 }
|
||||
771 return(k);
|
||||
772 }
|
||||
773
|
||||
774 /* format 21 -- movep*/
|
||||
775 opf21()
|
||||
776 {
|
||||
777 register m,d;
|
||||
778 register char *p;
|
||||
779
|
||||
780 if(get2ops())
|
||||
781 return;
|
||||
782 if(ckdreg(&opnd[0])) { /*d reg source*/
|
||||
783 m = 0600;
|
||||
784 d = opnd[0].ea;
|
||||
785 p = &opnd[1];
|
||||
786 }
|
||||
787 else if(ckdreg(&opnd[1])) { /*d reg dest*/
|
||||
788 m = 0400;
|
||||
789 d = opnd[1].ea;
|
||||
790 p = &opnd[0];
|
||||
791 }
|
||||
792 else {
|
||||
793 uerr(20);
|
||||
794 }
|
||||
795 if((p->ea&070) != INDDISP)
|
||||
796 uerr(20);
|
||||
797 if(modelen == 4)
|
||||
798 m =| 0100;
|
||||
799 ins[0] =| (d<<9)|m|(p->ea&7);
|
||||
800 *pins++ = p->con.wd2;
|
||||
801 *prlb++ = p->drlc;
|
||||
802 instrlen =+ 2;
|
||||
803 }
|
||||
804
|
||||
805 /* format 22 -- moveq*/
|
||||
806 opf22()
|
||||
807 {
|
||||
808 if(get2ops())
|
||||
809 return;
|
||||
810 if(opnd[0].ea != IMM)
|
||||
811 uerr(17);
|
||||
812 if(opnd[0].con>255L || opnd[0].con<-256L)
|
||||
813 uerr(15);
|
||||
814 if(!ckdreg(&opnd[1]))
|
||||
815 uerr(33);
|
||||
816 ins[0] =| (opnd[1].ea<<9) | (opnd[0].con.wd2&0377);
|
||||
817 }
|
||||
818
|
||||
819 /* format 23 -- eor*/
|
||||
820 opf23()
|
||||
821 {
|
||||
822 if(get2ops())
|
||||
823 return;
|
||||
824 if (cksprg(&opnd[1],CCR) || cksprg(&opnd[1],SR)) {
|
||||
825 opcpt = eoriptr;
|
||||
826 ins[0] = opcpt->vl1.wd2;
|
||||
1File: PASS2.C Page 15
|
||||
827 format = (opcpt->flags)&OPFF;
|
||||
828 ccr_or_sr();
|
||||
829 return;
|
||||
830 }
|
||||
831 if(!ckdreg(&opnd[0])) {
|
||||
832 if(makeimm()) /*must be immediate*/
|
||||
833 return;
|
||||
834 uerr(20); /*or error*/
|
||||
835 }
|
||||
836 if(!dataalt(&opnd[1]) || pcea(&opnd[1]))
|
||||
837 uerr(20);
|
||||
838 ins[0] =| (opnd[0].ea<<9)|f23mode[modelen]|opnd[1].ea;
|
||||
839 doea(&opnd[1]);
|
||||
840 }
|
||||
841
|
||||
@@ -0,0 +1,4 @@
|
||||
$1lo68 -r -o as68.rel -f $1 -unofloat 0$1s.o dir.o expr.o main.o misc.o pass1a.o pass2.o strncmp.o symt.o 0$1lib6.a 0$1clib
|
||||
era *.o
|
||||
|
||||
user 10!make $1
|
||||
@@ -0,0 +1,30 @@
|
||||
/*********************************************************************
|
||||
* STRNCMP - compares strings up to n chars
|
||||
*
|
||||
* WORD strncmp(s1,s2,n)
|
||||
* BYTE *s1, *s2;
|
||||
* UWORD n;
|
||||
*
|
||||
* 'strncmp' compares null terminated strings s1 and s2, and examines
|
||||
* at most n chars.
|
||||
* Always compares at least 1 char.
|
||||
* n < 0 compares many, many characters.
|
||||
* Returns:
|
||||
* strncmp < 0 if s1<s2 (within n chars)
|
||||
* strncmp = 0 if s1=s2 " " "
|
||||
* strncmp > 0 if s1>s2 " " "
|
||||
*********************************************************************/
|
||||
|
||||
#include <portab.h>
|
||||
|
||||
WORD strncmp(s1,s2,n)
|
||||
REG BYTE *s1, *s2;
|
||||
REG WORD n;
|
||||
{
|
||||
for( ; --n > 0 && (*s1 == *s2); s1++, s2++ )
|
||||
{
|
||||
if( *s1 == NULL )
|
||||
return(0);
|
||||
}
|
||||
return(*s1 - *s2);
|
||||
}
|
||||
850
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/as68/symt.c
Normal file
850
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/as68/symt.c
Normal file
@@ -0,0 +1,850 @@
|
||||
/*
|
||||
Copyright 1981
|
||||
Alcyon Corporation
|
||||
8716 Production Ave.
|
||||
San Diego, Ca. 92121
|
||||
*/
|
||||
|
||||
#include "as68.h"
|
||||
|
||||
/* symbol table and misc routines*/
|
||||
|
||||
int errno;
|
||||
char *ermsg[];
|
||||
char tfilname[];
|
||||
char initfnam[];
|
||||
char ldfn[];
|
||||
char tlab1[];
|
||||
int stdofd;
|
||||
int ftudp;
|
||||
int poslab;
|
||||
|
||||
/*output it for beginning of statement*/
|
||||
opitb()
|
||||
{
|
||||
stbuf[0].itty = ITBS; /*beginning of statement*/
|
||||
stbuf[0].itop = (fchr!=EOLC) ? absln : absln-1;
|
||||
stbuf[1].itty = ITSY; /*label entry*/
|
||||
stbuf[1].itop.ptrw2 = lblpt; /*pointer to symbol or 0*/
|
||||
|
||||
/*put opcode in it buffer*/
|
||||
stbuf[2].itty = ITSY;
|
||||
stbuf[2].itrl = modelen; /*mode of instr(byte, word, long)*/
|
||||
stbuf[2].itop.ptrw2 = opcpt; /*pointer to opcode in main table*/
|
||||
stbuf[3].itty = ITCN;
|
||||
stbuf[3].itrl = rlflg; /*relocation base*/
|
||||
stbuf[3].itop = loctr; /*pass1 location counter*/
|
||||
itwc = ITOP1; /*next available slot-currently 4*/
|
||||
pitw = &stbuf[ITOP1].itty; /*init the pointer*/
|
||||
}
|
||||
|
||||
/*
|
||||
* get an input term (symbol, constant, or special character)
|
||||
* call with:
|
||||
* the first character in fchr
|
||||
* returns:
|
||||
* item type in itype
|
||||
* item value in ival if item is a constant or special character
|
||||
* if it is a symbol it is placed at the end of the main table
|
||||
|
||||
* meaning of state table:
|
||||
|
||||
* currently getting: symbol(0) constant(1) beginning(2)
|
||||
|
||||
* next char:
|
||||
* digit(0) 0 1 1
|
||||
|
||||
* letter(3) 0 3 0
|
||||
|
||||
* special char(6) 3 3 3
|
||||
|
||||
* contents of the state table is the next state. processing stops when
|
||||
* state 3 is encountered. state 2 is the beginning state.
|
||||
*/
|
||||
int sttbl[] {0,1,1,0,3,0,3,3,3}; /*state table for parser*/
|
||||
|
||||
gterm(constpc)
|
||||
int constpc;
|
||||
{
|
||||
register smode, i;
|
||||
register char *p;
|
||||
register int tmode;
|
||||
register char *j;
|
||||
long num;
|
||||
char istr[80];
|
||||
|
||||
/* if(fchr == '\'' || fchr == '"') */ /* Fucking Whitesmith's */
|
||||
if(fchr == 047 || fchr == 042)
|
||||
if(astring()) /*maybe ascii string*/
|
||||
return;
|
||||
smode = 2; /*beginning state*/
|
||||
i = 0;
|
||||
p = istr;
|
||||
|
||||
/*loop to put item on istr*/
|
||||
while(fchr>=' ') { /*until a control char*/
|
||||
if(smode==2 && fchr=='.')
|
||||
tmode = 3;
|
||||
else if(isalpha(fchr) || fchr=='~' || fchr=='_' || (fchr=='$'&&i))
|
||||
tmode=3;
|
||||
else if(isdigit(fchr))
|
||||
tmode=0;
|
||||
else
|
||||
tmode = 6;
|
||||
tmode = sttbl[tmode+smode]; /*new state*/
|
||||
if(tmode==3) break; /*end of item*/
|
||||
smode = tmode;
|
||||
*p++ = fchr; /*save character*/
|
||||
i++;
|
||||
fchr=gchr();
|
||||
}
|
||||
|
||||
/* end of item*/
|
||||
switch(smode) {
|
||||
|
||||
case 0: /*symbol*/
|
||||
*p = '\0'; /*end of symbol*/
|
||||
itype = ITSY; /*symbol*/
|
||||
pack(istr,lmte); /*put symbol at end of main table*/
|
||||
j = lemt(sirt,FALSE);
|
||||
if(istr[0]!='~' && !poslab && (j->flags&(SYEQ|SYER))==SYEQ) {
|
||||
itype = (j->flags&SYRM) ? ITRM : ITCN; /* [vlh] */
|
||||
ival = j->vl1;
|
||||
reloc = ((j->flags)&SYRO) ? TEXT : ((j->flags)&SYRA) ? DATA :
|
||||
((j->flags)&SYBS) ? BSS : ABS;
|
||||
}
|
||||
return;
|
||||
|
||||
case 1: /*constant*/
|
||||
if(!constant(&num,istr,i)) {
|
||||
uerr(17); /*illegal constant*/
|
||||
num = 0;
|
||||
}
|
||||
ival = num;
|
||||
itype = ITCN;
|
||||
reloc = ABS;
|
||||
return;
|
||||
|
||||
case 2: /*just a special char*/
|
||||
switch(fchr) {
|
||||
|
||||
case '*': /*location counter*/
|
||||
if(starmul) { /*multiply*/
|
||||
starmul = 0;
|
||||
goto specsy;
|
||||
}
|
||||
refpc++; /*referenced pgm ctr*/
|
||||
reloc = rlflg; /*relocation of location counter*/
|
||||
ival = loctr;
|
||||
itype = (constpc) ? ITCN : ITPC;
|
||||
break;
|
||||
|
||||
|
||||
case '$': /*hex constant*/
|
||||
oconst(16);
|
||||
return;
|
||||
|
||||
case '@': /*octal const*/
|
||||
oconst(8);
|
||||
return;
|
||||
|
||||
case '%': /*binary const*/
|
||||
oconst(2);
|
||||
return;
|
||||
|
||||
case '#':
|
||||
immed[opdix]++;
|
||||
goto specsy;
|
||||
|
||||
case '(':
|
||||
indir[opdix]++;
|
||||
plevel++;
|
||||
goto specsy;
|
||||
|
||||
case ')':
|
||||
plevel--;
|
||||
goto specsy;
|
||||
|
||||
default:
|
||||
specsy:
|
||||
itype = ITSP; /*return special char*/
|
||||
ival = fchr;
|
||||
}
|
||||
if(fchr != EOLC)
|
||||
fchr=gchr(); /*get next char*/
|
||||
if((ival=='>' && fchr=='>') || (ival=='<' && fchr=='<'))
|
||||
fchr=gchr(); /*shift op, ignore second char*/
|
||||
return;
|
||||
|
||||
default:
|
||||
abort(); /*not possible*/
|
||||
}
|
||||
}
|
||||
|
||||
/*check for an ascii string enclosed in single quotes*/
|
||||
|
||||
astring()
|
||||
{
|
||||
register char delim;
|
||||
|
||||
/* if(fchr != '\'' && fchr != '"') *//*valid delimiter*/
|
||||
if(fchr != 047 && fchr != 042)
|
||||
return;
|
||||
delim = fchr;
|
||||
if(equflg || (itype==ITSP && ival.wd2=='#')) { /*immediate operand*/
|
||||
if(astr1(delim)) {
|
||||
fchr = gchr();
|
||||
if(fchr!=delim)
|
||||
xerr(19);
|
||||
fchr=gchr();
|
||||
}
|
||||
return((equflg) ? 1 : 0);
|
||||
}
|
||||
while(astr1(delim)) {
|
||||
itype = ITSP;
|
||||
ival = ','; /*separate by commas*/
|
||||
reloc = ABS;
|
||||
opitoo();
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
astr1(adelim)
|
||||
{
|
||||
register delim,i,retv;
|
||||
register long l;
|
||||
|
||||
delim = adelim;
|
||||
i = 0; l = 0;
|
||||
retv = 1;
|
||||
while((fchr=gchr()) != EOF) {
|
||||
if(fchr==delim) {
|
||||
fchr = gchr();
|
||||
if(fchr != delim) {
|
||||
retv = 0; /*end of string*/
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(fchr == EOLC) {
|
||||
xerr(19);
|
||||
retv = 0; /*end of string*/
|
||||
break;
|
||||
}
|
||||
l = (l<<8) | fchr;
|
||||
if(++i >= modelen) {
|
||||
if((fchr=gchr()) == delim) {
|
||||
fchr = gchr();
|
||||
retv = 0; /*end of string*/
|
||||
}
|
||||
else
|
||||
peekc = fchr; /*next char in string*/
|
||||
break; /*filled one bucket*/
|
||||
}
|
||||
}
|
||||
while(i < modelen) {
|
||||
l =<< 8;
|
||||
i++;
|
||||
}
|
||||
itype = ITCN;
|
||||
ival = l;
|
||||
reloc = ABS;
|
||||
if(!equflg)
|
||||
opitoo(); /*output one operand*/
|
||||
return(retv);
|
||||
}
|
||||
|
||||
/*get constant given radix*/
|
||||
oconst(ardx)
|
||||
{
|
||||
register trdx,j;
|
||||
register long i;
|
||||
|
||||
switch (ardx) { /* radix as power of 2 */
|
||||
case 16 : trdx = 4; break;
|
||||
case 8 : trdx = 3; break;
|
||||
case 2 : trdx = 1; break;
|
||||
default :
|
||||
rpterr("invalid radix in oconst");
|
||||
abort();
|
||||
}
|
||||
i=0;
|
||||
while(1) {
|
||||
fchr=gchr();
|
||||
j=fchr;
|
||||
if(isdigit(j))
|
||||
j =- '0';
|
||||
else if((j=tolower(j))>='a' && j<='f')
|
||||
j = j-'a'+10;
|
||||
else
|
||||
break; /*not valid numeric char*/
|
||||
if(j>=0 && j<ardx)
|
||||
i = (i<<trdx)+j;
|
||||
else
|
||||
break;
|
||||
}
|
||||
ival = i;
|
||||
itype = ITCN;
|
||||
reloc = ABS;
|
||||
}
|
||||
|
||||
|
||||
/*convert ascii constant to binary*/
|
||||
constant(pnum,pstr,idx)
|
||||
long *pnum;
|
||||
char *pstr;
|
||||
{
|
||||
register i,j;
|
||||
register char *p;
|
||||
register long l;
|
||||
|
||||
p = pstr;
|
||||
l = 0;
|
||||
for(i=0; i<idx; i++) {
|
||||
j = *pstr++;
|
||||
if(isdigit(j))
|
||||
j =- '0';
|
||||
if(j<0 || j>=10)
|
||||
return(0);
|
||||
l = (l<<3) + (l<<1) + j; /* l = l*10 + j*/
|
||||
}
|
||||
*pnum = l;
|
||||
return(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* method for looking up entries in the main table
|
||||
*
|
||||
* Note: The entry to be looked up must be placed at the end
|
||||
* of the main table. The global cell 'lmte'(last main
|
||||
* entry) points to the next available entry in the main
|
||||
* table. The address of an initial reference table must
|
||||
* also be provided.
|
||||
*
|
||||
* 1) Compute the hash code for the symbol and add it to the base address
|
||||
* of the initial reference table given as input. Thus, two words are
|
||||
* accessed which define the chain on which the symbol must be if it
|
||||
* is in the table at all.
|
||||
*
|
||||
* 2) Alter the table link of the last symbol in the chain so that it
|
||||
* points to the symbol being looked up. Note that the symbol to be
|
||||
* looked up is always placed at the end of the main table before
|
||||
* calling the lookup routine. This essentially adds one more element
|
||||
* to the end of the chain, namely the symbol to be looked up.
|
||||
*
|
||||
* 3) Now start at the first symbol in the chain and follow the chain
|
||||
* looking for a symbol equal to the smbol being looked up. It is
|
||||
* guaranteed that such a symbol will be found because it is always
|
||||
* the last symbol on the chain.
|
||||
*
|
||||
* 4) When the symbol is found, check to see if it is the last symbol
|
||||
* on the chain. If not, the symbol being looked for is in the table
|
||||
* and has been found. If it is the last symbol, the symbol being
|
||||
* looked up is not in the table.
|
||||
*
|
||||
* 5) In the case the looked up symbol is not found, it is usually added
|
||||
* to the end of the table. This is done simply b changing the
|
||||
* initial reference table entry which points to the previous
|
||||
* last symbol on the chain so that is now points to the symbol at the
|
||||
* end of the main table. In case the symbol just looked up is not to
|
||||
* be added to the main table then no action is needed . This means
|
||||
* that the table link of the last symbol on a chain may point any-
|
||||
* where.
|
||||
*
|
||||
* look up entry in the main table
|
||||
* call with:
|
||||
* address of initial reference table
|
||||
* entry to be looked up at the end of the main table
|
||||
* returns:
|
||||
* a pointer to the entry. if this pointer is equal to
|
||||
* lmte then the symbol was not previously in the table.
|
||||
*/
|
||||
|
||||
char *lemt(airt,oplook)
|
||||
char **airt;
|
||||
int oplook; /* if true then looking in opcode table */
|
||||
{
|
||||
register char *mtpt;
|
||||
register int *p1, *p2;
|
||||
register int i, j;
|
||||
|
||||
if (oplook) { /* [vlh] get rid of preceding '.', to lowercase */
|
||||
if (lmte->name[0]=='.') {
|
||||
lmte->name[NAMELEN-1] = NULL; /* in case of '.' */
|
||||
j = 1;
|
||||
}
|
||||
else j = 0;
|
||||
for (i=0; j<NAMELEN; i++, j++)
|
||||
lmte->name[i] = tolower(lmte->name[j]);
|
||||
}
|
||||
|
||||
pirt = airt + hash(); /*hashed ptr to irt*/
|
||||
mtpt = pirt->irfe; /*pointer to first entry in chain*/
|
||||
if(!mtpt) /*empty chain*/
|
||||
mtpt = lmte; /*start at end of main table*/
|
||||
else
|
||||
(pirt->irle)->tlnk = lmte; /*last entry in chain is new symbol*/
|
||||
|
||||
/*loop to locate entry in main table*/
|
||||
lemtl:
|
||||
p1 = &mtpt->name[0];
|
||||
p2 = &lmte->name[0];
|
||||
i = NAMELEN/(sizeof i);
|
||||
while(i) {
|
||||
if(*p1++ != *p2++) {
|
||||
mtpt = mtpt->tlnk; /*go to next entry in chain*/
|
||||
goto lemtl;
|
||||
}
|
||||
i--;
|
||||
}
|
||||
return(mtpt);
|
||||
}
|
||||
|
||||
/* compute a hash code for the last entry in the main table*/
|
||||
/* returns the hash code*/
|
||||
hash()
|
||||
{
|
||||
register int i;
|
||||
register ht1;
|
||||
register char *p;
|
||||
|
||||
ht1 = 0;
|
||||
p = &lmte->name[0];
|
||||
for(i=0; i<NAMELEN; i++)
|
||||
ht1 =+ *p++;
|
||||
return(ht1&(SZIRT-2)); /*make hash code even and between 0 & SZIRT-2*/
|
||||
}
|
||||
|
||||
/*
|
||||
* Make an entry in the main table
|
||||
* assumes :
|
||||
* entry to be made is pointed at by lmte
|
||||
* pirt points to the correct initial reference table entry.
|
||||
*/
|
||||
mmte()
|
||||
{
|
||||
pirt->irle = lmte; /*pointer to last entry in chain*/
|
||||
if(pirt->irfe == 0) /*first entry in chain*/
|
||||
pirt->irfe = lmte;
|
||||
lmte =+ STESIZE; /*bump last main table entry pointer*/
|
||||
if(lmte>=emte) { /*main table overflow*/
|
||||
if(sbrk(STESIZE*ICRSZMT) == -1){ /*get more memory*/
|
||||
rpterr("symbol table overflow\n");
|
||||
endit();
|
||||
}
|
||||
else {
|
||||
emte =+ STESIZE*ICRSZMT; /*move end of main table*/
|
||||
cszmt =+ ICRSZMT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* make an entry in the main table for a directive
|
||||
* call with:
|
||||
* pointer to string containing directive name
|
||||
* address of routine to handle directive in pass one
|
||||
* address of routine to handle directive in pass two
|
||||
*/
|
||||
mdemt(mdstr,dirnum)
|
||||
char *mdstr;
|
||||
{
|
||||
register char *mdept;
|
||||
|
||||
pack(mdstr,lmte); /*pack name at end of main table*/
|
||||
mdept=lemt(oirt,TRUE); /*look up in opcode table*/
|
||||
if(mdept != lmte) { /*best not be there already*/
|
||||
uerr(5);
|
||||
abort();
|
||||
return;
|
||||
}
|
||||
mmte(); /*make main table entry*/
|
||||
mdept->flags =| OPDR|SYIN; /*directive*/
|
||||
mdept->vl1 = dirnum; /*directive #*/
|
||||
}
|
||||
|
||||
/*
|
||||
* pack a string into an entry in the main table
|
||||
* call with:
|
||||
* pointer to the string
|
||||
* pointer to desired entry in the main table
|
||||
*/
|
||||
pack(apkstr,apkptr)
|
||||
char *apkstr, *apkptr;
|
||||
{
|
||||
register i;
|
||||
register char *pkstr, *pkptr;
|
||||
|
||||
pkstr = apkstr;
|
||||
pkptr = apkptr;
|
||||
i = NAMELEN;
|
||||
while(*pkstr && i) {
|
||||
*pkptr++ = *pkstr++;
|
||||
i--;
|
||||
}
|
||||
while(i--)
|
||||
*pkptr++ = '\0'; /*pad with nulls*/
|
||||
}
|
||||
|
||||
/* function to get characters for source file*/
|
||||
int xcol = 0; /* Column Counter */
|
||||
int spcnt = 0; /* Space count for tab expansion */
|
||||
gchr()
|
||||
{
|
||||
register chr1;
|
||||
|
||||
if(peekc) {
|
||||
chr1 = peekc;
|
||||
peekc = 0;
|
||||
if(chr1 != SOH)
|
||||
xcol--;
|
||||
}
|
||||
else if (spcnt)
|
||||
{
|
||||
spcnt--;
|
||||
return(' ');
|
||||
}
|
||||
else
|
||||
{
|
||||
gchr1:
|
||||
if(sbuflen<=0){ /*nothing on input buffer*/
|
||||
sbuflen=read(ifn,sbuf,512); /*read in source*/
|
||||
if(sbuflen<=0)
|
||||
return(EOF); /*end of file*/
|
||||
psbuf = sbuf;
|
||||
}
|
||||
chr1 = *psbuf++;
|
||||
sbuflen--;
|
||||
}
|
||||
if (chr1 == SOH) /*preprocessor flag*/
|
||||
goto gchr1; /*ignore it*/
|
||||
if(chr1 == EOLC) { /*end of line*/
|
||||
xcol = -1; /* Clear column counter */
|
||||
if(!p2flg) /*pass 1 only*/
|
||||
absln++;
|
||||
}
|
||||
if(chr1=='\t') /*convert tabs to spaces*/
|
||||
{
|
||||
spcnt += 7 - (xcol&7); /* This many spaces */
|
||||
xcol += spcnt; /* New column number */
|
||||
chr1 = ' ';
|
||||
}
|
||||
xcol++;
|
||||
return(chr1);
|
||||
}
|
||||
|
||||
/*
|
||||
* write out intermediate text for one statement
|
||||
* call with
|
||||
* the it for the statement in stbuf
|
||||
*/
|
||||
wostb()
|
||||
{
|
||||
register int woix;
|
||||
register short *itwo;
|
||||
register int i;
|
||||
|
||||
if(stbuf[0].itty != ITBS) abort(); /*not beginning of stmt*/
|
||||
itwo = &stbuf;
|
||||
woix = stbuf[0].itrl & 0377; /*unsigned byte*/
|
||||
while(woix--) {
|
||||
for(i=0; i<(sizeof stbuf[0])/(sizeof *itwo); i++) {
|
||||
doitwr(*itwo++);
|
||||
}
|
||||
}
|
||||
/* debug(); //call debug package*/
|
||||
}
|
||||
|
||||
doitwr(word)
|
||||
short word;
|
||||
{
|
||||
short i;
|
||||
|
||||
if( pitix < itbuf || pitix > &itbuf[ITBSZ] ) {
|
||||
printf("doitwr: it buffer botch\n");
|
||||
endit();
|
||||
}
|
||||
if( pitix >= &itbuf[ITBSZ]) {
|
||||
if(write(itfn,itbuf,ITBSZ*(sizeof i)) != ITBSZ*(sizeof i)) {
|
||||
rpterr("it write error errno=%o\n",errno);
|
||||
endit();
|
||||
}
|
||||
pitix = itbuf;
|
||||
}
|
||||
*pitix++ = word;
|
||||
}
|
||||
|
||||
/*
|
||||
* user source error
|
||||
* call with:
|
||||
* number to indicate reason for error
|
||||
* types the error number and the line number on which
|
||||
* the error occured.
|
||||
*/
|
||||
uerr(errn)
|
||||
{
|
||||
if(p2flg) { /*pass 2 gets two ampersands*/
|
||||
in_err++; /* [vlh] instrlen <- pass1 estimation */
|
||||
printf("&& %d: %s\n",p2absln,ermsg[errn-1]);
|
||||
}
|
||||
else
|
||||
printf("& %d: %s\n",(fchr==EOLC)?absln-1:absln,ermsg[errn-1]);
|
||||
nerror++;
|
||||
}
|
||||
/*
|
||||
* user error that causes the statement to be abandoned
|
||||
* call with:
|
||||
* error number
|
||||
*/
|
||||
xerr(xern)
|
||||
{
|
||||
uerr(xern); /*type error message*/
|
||||
if(!p2flg) /*pass one*/
|
||||
igrst(); /*pass rest of source*/
|
||||
}
|
||||
|
||||
/* abort the assembly*/
|
||||
abort()
|
||||
{
|
||||
rpterr("as68 abort\n");
|
||||
nerror++;
|
||||
endit();
|
||||
}
|
||||
|
||||
/*ignore rest of statement*/
|
||||
igrst()
|
||||
{
|
||||
while(fchr!=EOLC && fchr!=EOF) /*until end of line*/
|
||||
fchr=gchr();
|
||||
while((fchr=gchr())==EOLC) ; /*ignore null lines*/
|
||||
}
|
||||
|
||||
/*ignore blanks after a label*/
|
||||
ligblk()
|
||||
{
|
||||
if(fchr == EOF) return;
|
||||
igblk();
|
||||
if(fchr==EOLC) {
|
||||
fchr=gchr();
|
||||
ligblk();
|
||||
}
|
||||
}
|
||||
|
||||
rubout()
|
||||
{
|
||||
nerror = -1;
|
||||
endit();
|
||||
}
|
||||
|
||||
/* exit from the assembler*/
|
||||
endit()
|
||||
{
|
||||
LASTCHTFN = itfnc;
|
||||
unlink(tfilname); /*delete temporary files*/
|
||||
LASTCHTFN = trbfnc;
|
||||
unlink(tfilname);
|
||||
LASTCHTFN = dafnc;
|
||||
unlink(tfilname);
|
||||
LASTCHTFN = drbfnc;
|
||||
unlink(tfilname);
|
||||
if(nerror != -1) { /*not rubout*/
|
||||
if(ftudp)
|
||||
putchar('\n');
|
||||
}
|
||||
if(nerror > 0) {
|
||||
fprintf(stderr,"& %d errors\n",nerror);
|
||||
}
|
||||
if (initflg)
|
||||
unlink(ldfn); /* [vlh] get rid of empty .o file */
|
||||
exit(nerror!=0);
|
||||
}
|
||||
|
||||
/*
|
||||
* open files
|
||||
* call with:
|
||||
* pointer to name of file to open
|
||||
* flag for how to open
|
||||
* 0 => read
|
||||
* 1 => write
|
||||
*/
|
||||
openfi(pname,hflag)
|
||||
char *pname;
|
||||
{
|
||||
register fd;
|
||||
|
||||
fd = (hflag==1) ? creat(pname,0666,1) : open(pname,hflag,1);
|
||||
if(fd < 0) { /*open failed*/
|
||||
rpterr("can't open %s errno=%o\n",pname,errno);
|
||||
endit();
|
||||
}
|
||||
return(fd);
|
||||
}
|
||||
|
||||
/* get a temp file for the intermediate text*/
|
||||
char lastfile = 'A';
|
||||
gettempf()
|
||||
{
|
||||
register i,j;
|
||||
register char *p;
|
||||
|
||||
LASTCHTFN = lastfile++; /* Creat temp name */
|
||||
if((j=creat(tfilname,0600,1)) >= 0)
|
||||
return(j); /* File created OK */
|
||||
rpterr("Unable to open temporary file\n");
|
||||
endit();
|
||||
}
|
||||
|
||||
/* move label name from lbt to main table entry pointed to by lmte*/
|
||||
setname()
|
||||
{
|
||||
register i;
|
||||
register int *p1, *p2;
|
||||
|
||||
p1 = &lmte->name[0];
|
||||
for(p2 = &lbt[0]; p2 < &lbt[NAMELEN]; ) {
|
||||
*p1++ = *p2;
|
||||
*p2++ = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* get the initialized main table and initial reference tables from*/
|
||||
/* the initialize file*/
|
||||
getsymtab()
|
||||
{
|
||||
long j; /* length for read / write */
|
||||
register char **p;
|
||||
register struct symtab *p1;
|
||||
register char *p2;
|
||||
register fd,i;
|
||||
|
||||
if((fd=open(initfnam,0,1)) < 0) {
|
||||
rerr:
|
||||
printf("& Unable to read init file: %s\n", initfnam);
|
||||
endit();
|
||||
}
|
||||
if(read(fd,sirt,SZIRT*(sizeof sirt[0])) != SZIRT*(sizeof sirt[0])) {
|
||||
goto rerr;
|
||||
}
|
||||
|
||||
if(read(fd,oirt,SZIRT*(sizeof sirt[0])) != SZIRT*(sizeof sirt[0]))
|
||||
goto rerr;
|
||||
|
||||
if(read(fd,&j,(sizeof j)) != (sizeof j)) /* Read Count */
|
||||
goto rerr; /* Y-U-K!!! */
|
||||
|
||||
if((i=read(fd,bmte,(int)j)) != j) /* Read table */
|
||||
goto rerr;
|
||||
|
||||
if((i%STESIZE) != 0)
|
||||
goto rerr;
|
||||
|
||||
lmte = bmte + i;
|
||||
p2 = bmte-1;
|
||||
for(p=sirt; p<&sirt[SZIRT]; p++) {
|
||||
if(*p)
|
||||
*p =+ (long)p2;
|
||||
}
|
||||
for(p=oirt; p<&oirt[SZIRT]; p++) {
|
||||
if(*p)
|
||||
*p =+ (long)p2;
|
||||
}
|
||||
for(p1=bmte; p1<lmte; p1++) {
|
||||
if(p1->tlnk)
|
||||
p1->tlnk =+ (long)p2;
|
||||
}
|
||||
close(fd);
|
||||
}
|
||||
|
||||
/* write the initialization file*/
|
||||
putsymtab()
|
||||
{
|
||||
long j;
|
||||
register char **p;
|
||||
register struct symtab *p1;
|
||||
register char *p2;
|
||||
register fd,i;
|
||||
|
||||
if((fd=creat(initfnam,0644,1))<0) {
|
||||
printf("& Cannot create init: %s\n", initfnam);
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* change all pointers so that they are relative to the beginning
|
||||
* of the symbol table
|
||||
*/
|
||||
p2 = bmte-1;
|
||||
for(p=sirt; p<&sirt[SZIRT]; p++) {
|
||||
if(*p)
|
||||
*p =- (long)p2;
|
||||
}
|
||||
for(p=oirt; p<&oirt[SZIRT]; p++) {
|
||||
if(*p)
|
||||
*p =- (long)p2;
|
||||
}
|
||||
for(p1=bmte; p1<lmte; p1++) {
|
||||
if(p1->tlnk)
|
||||
p1->tlnk =- (long)p2;
|
||||
}
|
||||
|
||||
if(write(fd,sirt,SZIRT*(sizeof sirt[0])) != SZIRT*(sizeof sirt[0])) {
|
||||
goto werr;
|
||||
}
|
||||
|
||||
if(write(fd,oirt,SZIRT*(sizeof oirt[0])) != SZIRT*(sizeof oirt[0]))
|
||||
goto werr;
|
||||
|
||||
i = lmte - bmte; /*length of current main table*/
|
||||
if((i % STESIZE) != 0) {
|
||||
goto werr;
|
||||
}
|
||||
j = i;
|
||||
if(write(fd,&j,(sizeof j)) != (sizeof j)) /* Y-U-K!! */
|
||||
goto werr;
|
||||
|
||||
if(write(fd,bmte,i) != i) {
|
||||
werr:
|
||||
printf("& Write error on init file: %s\n",initfnam);
|
||||
return;
|
||||
}
|
||||
close(fd);
|
||||
}
|
||||
|
||||
/* print an error on file descriptor 2*/
|
||||
/* used for errors with disasterous consequences*/
|
||||
rpterr(ptch,x1,x2,x3,x4,x5,x6)
|
||||
char *ptch;
|
||||
{
|
||||
if(prtflg==0) /* Check for paging output */
|
||||
page(); /* Perform page checks */
|
||||
fprintf(stderr,"& %d: ",absln);
|
||||
fprintf(stderr,ptch,x1,x2,x3,x4,x5,x6);
|
||||
}
|
||||
|
||||
/* set the file name for the relocatable object file (sourcefile.o)*/
|
||||
setldfn(ap)
|
||||
char *ap;
|
||||
{
|
||||
register char *p1,*p2;
|
||||
|
||||
p1 = ap;
|
||||
p2 = ldfn;
|
||||
while(*p1) {
|
||||
*p2++ = *p1++;
|
||||
}
|
||||
if(*(p2-2) != '.') { /*not name.?*/
|
||||
*p2++ = '.';
|
||||
*p2++ = 'o';
|
||||
}
|
||||
else { /* is name.? */
|
||||
*(p2-1) = 'o';
|
||||
}
|
||||
*p2 = '\0';
|
||||
}
|
||||
|
||||
savelab()
|
||||
{
|
||||
register int *p1, *p2;
|
||||
|
||||
p2 = &lmte->name[0];
|
||||
for(p1= &tlab1[0]; p1 < &tlab1[NAMELEN]; )
|
||||
*p1++ = *p2++;
|
||||
}
|
||||
865
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/as68/symt.lis
Normal file
865
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/as68/symt.lis
Normal file
@@ -0,0 +1,865 @@
|
||||
1File: SYMT.C Page 1
|
||||
1 /*
|
||||
2 Copyright 1981
|
||||
3 Alcyon Corporation
|
||||
4 8716 Production Ave.
|
||||
5 San Diego, Ca. 92121
|
||||
6 */
|
||||
7
|
||||
8 #include "as68.h"
|
||||
9
|
||||
10 /* symbol table and misc routines*/
|
||||
11
|
||||
12 int errno;
|
||||
13 char *ermsg[];
|
||||
14 char tfilname[];
|
||||
15 char initfnam[];
|
||||
16 char ldfn[];
|
||||
17 char tlab1[];
|
||||
18 int stdofd;
|
||||
19 int ftudp;
|
||||
20 int poslab;
|
||||
21
|
||||
22 /*output it for beginning of statement*/
|
||||
23 opitb()
|
||||
24 {
|
||||
25 stbuf[0].itty = ITBS; /*beginning of statement*/
|
||||
26 stbuf[0].itop = (fchr!=EOLC) ? absln : absln-1;
|
||||
27 stbuf[1].itty = ITSY; /*label entry*/
|
||||
28 stbuf[1].itop.ptrw2 = lblpt; /*pointer to symbol or 0*/
|
||||
29
|
||||
30 /*put opcode in it buffer*/
|
||||
31 stbuf[2].itty = ITSY;
|
||||
32 stbuf[2].itrl = modelen; /*mode of instr(byte, word, long)*/
|
||||
33 stbuf[2].itop.ptrw2 = opcpt; /*pointer to opcode in main table*/
|
||||
34 stbuf[3].itty = ITCN;
|
||||
35 stbuf[3].itrl = rlflg; /*relocation base*/
|
||||
36 stbuf[3].itop = loctr; /*pass1 location counter*/
|
||||
37 itwc = ITOP1; /*next available slot-currently 4*/
|
||||
38 pitw = &stbuf[ITOP1].itty; /*init the pointer*/
|
||||
39 }
|
||||
40
|
||||
41 /*
|
||||
42 * get an input term (symbol, constant, or special character)
|
||||
43 * call with:
|
||||
44 * the first character in fchr
|
||||
45 * returns:
|
||||
46 * item type in itype
|
||||
47 * item value in ival if item is a constant or special character
|
||||
48 * if it is a symbol it is placed at the end of the main table
|
||||
49
|
||||
50 * meaning of state table:
|
||||
51
|
||||
52 * currently getting: symbol(0) constant(1) beginning(2)
|
||||
53
|
||||
54 * next char:
|
||||
55 * digit(0) 0 1 1
|
||||
56
|
||||
57 * letter(3) 0 3 0
|
||||
58
|
||||
59 * special char(6) 3 3 3
|
||||
1File: SYMT.C Page 2
|
||||
60
|
||||
61 * contents of the state table is the next state. processing stops when
|
||||
62 * state 3 is encountered. state 2 is the beginning state.
|
||||
63 */
|
||||
64 int sttbl[] {0,1,1,0,3,0,3,3,3}; /*state table for parser*/
|
||||
65
|
||||
66 gterm(constpc)
|
||||
67 int constpc;
|
||||
68 {
|
||||
69 register smode, i;
|
||||
70 register char *p;
|
||||
71 register int tmode;
|
||||
72 register char *j;
|
||||
73 long num;
|
||||
74 char istr[80];
|
||||
75
|
||||
76 /* if(fchr == '\'' || fchr == '"') */ /* Fucking Whitesmith's */
|
||||
77 if(fchr == 047 || fchr == 042)
|
||||
78 if(astring()) /*maybe ascii string*/
|
||||
79 return;
|
||||
80 smode = 2; /*beginning state*/
|
||||
81 i = 0;
|
||||
82 p = istr;
|
||||
83
|
||||
84 /*loop to put item on istr*/
|
||||
85 while(fchr>=' ') { /*until a control char*/
|
||||
86 if(smode==2 && fchr=='.')
|
||||
87 tmode = 3;
|
||||
88 else if(isalpha(fchr) || fchr=='~' || fchr=='_' || (fchr=='$'&&i))
|
||||
89 tmode=3;
|
||||
90 else if(isdigit(fchr))
|
||||
91 tmode=0;
|
||||
92 else
|
||||
93 tmode = 6;
|
||||
94 tmode = sttbl[tmode+smode]; /*new state*/
|
||||
95 if(tmode==3) break; /*end of item*/
|
||||
96 smode = tmode;
|
||||
97 *p++ = fchr; /*save character*/
|
||||
98 i++;
|
||||
99 fchr=gchr();
|
||||
100 }
|
||||
101
|
||||
102 /* end of item*/
|
||||
103 switch(smode) {
|
||||
104
|
||||
105 case 0: /*symbol*/
|
||||
106 *p = '\0'; /*end of symbol*/
|
||||
107 itype = ITSY; /*symbol*/
|
||||
108 pack(istr,lmte); /*put symbol at end of main table*/
|
||||
109 j = lemt(sirt,FALSE);
|
||||
110 if(istr[0]!='~' && !poslab && (j->flags&(SYEQ|SYER))==SYEQ) {
|
||||
111 itype = (j->flags&SYRM) ? ITRM : ITCN; /* [vlh] */
|
||||
112 ival = j->vl1;
|
||||
113 reloc = ((j->flags)&SYRO) ? TEXT : ((j->flags)&SYRA) ? DATA :
|
||||
114 ((j->flags)&SYBS) ? BSS : ABS;
|
||||
115 }
|
||||
116 return;
|
||||
117
|
||||
118 case 1: /*constant*/
|
||||
1File: SYMT.C Page 3
|
||||
119 if(!constant(&num,istr,i)) {
|
||||
120 uerr(17); /*illegal constant*/
|
||||
121 num = 0;
|
||||
122 }
|
||||
123 ival = num;
|
||||
124 itype = ITCN;
|
||||
125 reloc = ABS;
|
||||
126 return;
|
||||
127
|
||||
128 case 2: /*just a special char*/
|
||||
129 switch(fchr) {
|
||||
130
|
||||
131 case '*': /*location counter*/
|
||||
132 if(starmul) { /*multiply*/
|
||||
133 starmul = 0;
|
||||
134 goto specsy;
|
||||
135 }
|
||||
136 refpc++; /*referenced pgm ctr*/
|
||||
137 reloc = rlflg; /*relocation of location counter*/
|
||||
138 ival = loctr;
|
||||
139 itype = (constpc) ? ITCN : ITPC;
|
||||
140 break;
|
||||
141
|
||||
142
|
||||
143 case '$': /*hex constant*/
|
||||
144 oconst(16);
|
||||
145 return;
|
||||
146
|
||||
147 case '@': /*octal const*/
|
||||
148 oconst(8);
|
||||
149 return;
|
||||
150
|
||||
151 case '%': /*binary const*/
|
||||
152 oconst(2);
|
||||
153 return;
|
||||
154
|
||||
155 case '#':
|
||||
156 immed[opdix]++;
|
||||
157 goto specsy;
|
||||
158
|
||||
159 case '(':
|
||||
160 indir[opdix]++;
|
||||
161 plevel++;
|
||||
162 goto specsy;
|
||||
163
|
||||
164 case ')':
|
||||
165 plevel--;
|
||||
166 goto specsy;
|
||||
167
|
||||
168 default:
|
||||
169 specsy:
|
||||
170 itype = ITSP; /*return special char*/
|
||||
171 ival = fchr;
|
||||
172 }
|
||||
173 if(fchr != EOLC)
|
||||
174 fchr=gchr(); /*get next char*/
|
||||
175 if((ival=='>' && fchr=='>') || (ival=='<' && fchr=='<'))
|
||||
176 fchr=gchr(); /*shift op, ignore second char*/
|
||||
177 return;
|
||||
1File: SYMT.C Page 4
|
||||
178
|
||||
179 default:
|
||||
180 abort(); /*not possible*/
|
||||
181 }
|
||||
182 }
|
||||
183
|
||||
184 /*check for an ascii string enclosed in single quotes*/
|
||||
185
|
||||
186 astring()
|
||||
187 {
|
||||
188 register char delim;
|
||||
189
|
||||
190 /* if(fchr != '\'' && fchr != '"') *//*valid delimiter*/
|
||||
191 if(fchr != 047 && fchr != 042)
|
||||
192 return;
|
||||
193 delim = fchr;
|
||||
194 if(equflg || (itype==ITSP && ival.wd2=='#')) { /*immediate operand*/
|
||||
195 if(astr1(delim)) {
|
||||
196 fchr = gchr();
|
||||
197 if(fchr!=delim)
|
||||
198 xerr(19);
|
||||
199 fchr=gchr();
|
||||
200 }
|
||||
201 return((equflg) ? 1 : 0);
|
||||
202 }
|
||||
203 while(astr1(delim)) {
|
||||
204 itype = ITSP;
|
||||
205 ival = ','; /*separate by commas*/
|
||||
206 reloc = ABS;
|
||||
207 opitoo();
|
||||
208 }
|
||||
209 return(0);
|
||||
210 }
|
||||
211
|
||||
212 astr1(adelim)
|
||||
213 {
|
||||
214 register delim,i,retv;
|
||||
215 register long l;
|
||||
216
|
||||
217 delim = adelim;
|
||||
218 i = 0; l = 0;
|
||||
219 retv = 1;
|
||||
220 while((fchr=gchr()) != EOF) {
|
||||
221 if(fchr==delim) {
|
||||
222 fchr = gchr();
|
||||
223 if(fchr != delim) {
|
||||
224 retv = 0; /*end of string*/
|
||||
225 break;
|
||||
226 }
|
||||
227 }
|
||||
228 if(fchr == EOLC) {
|
||||
229 xerr(19);
|
||||
230 retv = 0; /*end of string*/
|
||||
231 break;
|
||||
232 }
|
||||
233 l = (l<<8) | fchr;
|
||||
234 if(++i >= modelen) {
|
||||
235 if((fchr=gchr()) == delim) {
|
||||
236 fchr = gchr();
|
||||
1File: SYMT.C Page 5
|
||||
237 retv = 0; /*end of string*/
|
||||
238 }
|
||||
239 else
|
||||
240 peekc = fchr; /*next char in string*/
|
||||
241 break; /*filled one bucket*/
|
||||
242 }
|
||||
243 }
|
||||
244 while(i < modelen) {
|
||||
245 l =<< 8;
|
||||
246 i++;
|
||||
247 }
|
||||
248 itype = ITCN;
|
||||
249 ival = l;
|
||||
250 reloc = ABS;
|
||||
251 if(!equflg)
|
||||
252 opitoo(); /*output one operand*/
|
||||
253 return(retv);
|
||||
254 }
|
||||
255
|
||||
256 /*get constant given radix*/
|
||||
257 oconst(ardx)
|
||||
258 {
|
||||
259 register trdx,j;
|
||||
260 register long i;
|
||||
261
|
||||
262 switch (ardx) { /* radix as power of 2 */
|
||||
263 case 16 : trdx = 4; break;
|
||||
264 case 8 : trdx = 3; break;
|
||||
265 case 2 : trdx = 1; break;
|
||||
266 default :
|
||||
267 rpterr("invalid radix in oconst");
|
||||
268 abort();
|
||||
269 }
|
||||
270 i=0;
|
||||
271 while(1) {
|
||||
272 fchr=gchr();
|
||||
273 j=fchr;
|
||||
274 if(isdigit(j))
|
||||
275 j =- '0';
|
||||
276 else if((j=tolower(j))>='a' && j<='f')
|
||||
277 j = j-'a'+10;
|
||||
278 else
|
||||
279 break; /*not valid numeric char*/
|
||||
280 if(j>=0 && j<ardx)
|
||||
281 i = (i<<trdx)+j;
|
||||
282 else
|
||||
283 break;
|
||||
284 }
|
||||
285 ival = i;
|
||||
286 itype = ITCN;
|
||||
287 reloc = ABS;
|
||||
288 }
|
||||
289
|
||||
290
|
||||
291 /*convert ascii constant to binary*/
|
||||
292 constant(pnum,pstr,idx)
|
||||
293 long *pnum;
|
||||
294 char *pstr;
|
||||
295 {
|
||||
1File: SYMT.C Page 6
|
||||
296 register i,j;
|
||||
297 register char *p;
|
||||
298 register long l;
|
||||
299
|
||||
300 p = pstr;
|
||||
301 l = 0;
|
||||
302 for(i=0; i<idx; i++) {
|
||||
303 j = *pstr++;
|
||||
304 if(isdigit(j))
|
||||
305 j =- '0';
|
||||
306 if(j<0 || j>=10)
|
||||
307 return(0);
|
||||
308 l = (l<<3) + (l<<1) + j; /* l = l*10 + j*/
|
||||
309 }
|
||||
310 *pnum = l;
|
||||
311 return(1);
|
||||
312 }
|
||||
313
|
||||
314 /*
|
||||
315 * method for looking up entries in the main table
|
||||
316 *
|
||||
317 * Note: The entry to be looked up must be placed at the end
|
||||
318 * of the main table. The global cell 'lmte'(last main
|
||||
319 * entry) points to the next available entry in the main
|
||||
320 * table. The address of an initial reference table must
|
||||
321 * also be provided.
|
||||
322 *
|
||||
323 * 1) Compute the hash code for the symbol and add it to the base address
|
||||
324 * of the initial reference table given as input. Thus, two words are
|
||||
325 * accessed which define the chain on which the symbol must be if it
|
||||
326 * is in the table at all.
|
||||
327 *
|
||||
328 * 2) Alter the table link of the last symbol in the chain so that it
|
||||
329 * points to the symbol being looked up. Note that the symbol to be
|
||||
330 * looked up is always placed at the end of the main table before
|
||||
331 * calling the lookup routine. This essentially adds one more element
|
||||
332 * to the end of the chain, namely the symbol to be looked up.
|
||||
333 *
|
||||
334 * 3) Now start at the first symbol in the chain and follow the chain
|
||||
335 * looking for a symbol equal to the smbol being looked up. It is
|
||||
336 * guaranteed that such a symbol will be found because it is always
|
||||
337 * the last symbol on the chain.
|
||||
338 *
|
||||
339 * 4) When the symbol is found, check to see if it is the last symbol
|
||||
340 * on the chain. If not, the symbol being looked for is in the table
|
||||
341 * and has been found. If it is the last symbol, the symbol being
|
||||
342 * looked up is not in the table.
|
||||
343 *
|
||||
344 * 5) In the case the looked up symbol is not found, it is usually added
|
||||
345 * to the end of the table. This is done simply b changing the
|
||||
346 * initial reference table entry which points to the previous
|
||||
347 * last symbol on the chain so that is now points to the symbol at the
|
||||
348 * end of the main table. In case the symbol just looked up is not to
|
||||
349 * be added to the main table then no action is needed . This means
|
||||
350 * that the table link of the last symbol on a chain may point any-
|
||||
351 * where.
|
||||
352 *
|
||||
353 * look up entry in the main table
|
||||
354 * call with:
|
||||
1File: SYMT.C Page 7
|
||||
355 * address of initial reference table
|
||||
356 * entry to be looked up at the end of the main table
|
||||
357 * returns:
|
||||
358 * a pointer to the entry. if this pointer is equal to
|
||||
359 * lmte then the symbol was not previously in the table.
|
||||
360 */
|
||||
361
|
||||
362 char *lemt(airt,oplook)
|
||||
363 char **airt;
|
||||
364 int oplook; /* if true then looking in opcode table */
|
||||
365 {
|
||||
366 register char *mtpt;
|
||||
367 register int *p1, *p2;
|
||||
368 register int i, j;
|
||||
369
|
||||
370 if (oplook) { /* [vlh] get rid of preceding '.', to lowercase */
|
||||
371 if (lmte->name[0]=='.') {
|
||||
372 lmte->name[NAMELEN-1] = NULL; /* in case of '.' */
|
||||
373 j = 1;
|
||||
374 }
|
||||
375 else j = 0;
|
||||
376 for (i=0; j<NAMELEN; i++, j++)
|
||||
377 lmte->name[i] = tolower(lmte->name[j]);
|
||||
378 }
|
||||
379
|
||||
380 pirt = airt + hash(); /*hashed ptr to irt*/
|
||||
381 mtpt = pirt->irfe; /*pointer to first entry in chain*/
|
||||
382 if(!mtpt) /*empty chain*/
|
||||
383 mtpt = lmte; /*start at end of main table*/
|
||||
384 else
|
||||
385 (pirt->irle)->tlnk = lmte; /*last entry in chain is new symbol*/
|
||||
386
|
||||
387 /*loop to locate entry in main table*/
|
||||
388 lemtl:
|
||||
389 p1 = &mtpt->name[0];
|
||||
390 p2 = &lmte->name[0];
|
||||
391 i = NAMELEN/(sizeof i);
|
||||
392 while(i) {
|
||||
393 if(*p1++ != *p2++) {
|
||||
394 mtpt = mtpt->tlnk; /*go to next entry in chain*/
|
||||
395 goto lemtl;
|
||||
396 }
|
||||
397 i--;
|
||||
398 }
|
||||
399 return(mtpt);
|
||||
400 }
|
||||
401
|
||||
402 /* compute a hash code for the last entry in the main table*/
|
||||
403 /* returns the hash code*/
|
||||
404 hash()
|
||||
405 {
|
||||
406 register int i;
|
||||
407 register ht1;
|
||||
408 register char *p;
|
||||
409
|
||||
410 ht1 = 0;
|
||||
411 p = &lmte->name[0];
|
||||
412 for(i=0; i<NAMELEN; i++)
|
||||
413 ht1 =+ *p++;
|
||||
1File: SYMT.C Page 8
|
||||
414 return(ht1&(SZIRT-2)); /*make hash code even and between 0 & SZIRT-2*/
|
||||
415 }
|
||||
416
|
||||
417 /*
|
||||
418 * Make an entry in the main table
|
||||
419 * assumes :
|
||||
420 * entry to be made is pointed at by lmte
|
||||
421 * pirt points to the correct initial reference table entry.
|
||||
422 */
|
||||
423 mmte()
|
||||
424 {
|
||||
425 pirt->irle = lmte; /*pointer to last entry in chain*/
|
||||
426 if(pirt->irfe == 0) /*first entry in chain*/
|
||||
427 pirt->irfe = lmte;
|
||||
428 lmte =+ STESIZE; /*bump last main table entry pointer*/
|
||||
429 if(lmte>=emte) { /*main table overflow*/
|
||||
430 if(sbrk(STESIZE*ICRSZMT) == -1){ /*get more memory*/
|
||||
431 rpterr("symbol table overflow\n");
|
||||
432 endit();
|
||||
433 }
|
||||
434 else {
|
||||
435 emte =+ STESIZE*ICRSZMT; /*move end of main table*/
|
||||
436 cszmt =+ ICRSZMT;
|
||||
437 }
|
||||
438 }
|
||||
439 }
|
||||
440
|
||||
441 /*
|
||||
442 * make an entry in the main table for a directive
|
||||
443 * call with:
|
||||
444 * pointer to string containing directive name
|
||||
445 * address of routine to handle directive in pass one
|
||||
446 * address of routine to handle directive in pass two
|
||||
447 */
|
||||
448 mdemt(mdstr,dirnum)
|
||||
449 char *mdstr;
|
||||
450 {
|
||||
451 register char *mdept;
|
||||
452
|
||||
453 pack(mdstr,lmte); /*pack name at end of main table*/
|
||||
454 mdept=lemt(oirt,TRUE); /*look up in opcode table*/
|
||||
455 if(mdept != lmte) { /*best not be there already*/
|
||||
456 uerr(5);
|
||||
457 abort();
|
||||
458 return;
|
||||
459 }
|
||||
460 mmte(); /*make main table entry*/
|
||||
461 mdept->flags =| OPDR|SYIN; /*directive*/
|
||||
462 mdept->vl1 = dirnum; /*directive #*/
|
||||
463 }
|
||||
464
|
||||
465 /*
|
||||
466 * pack a string into an entry in the main table
|
||||
467 * call with:
|
||||
468 * pointer to the string
|
||||
469 * pointer to desired entry in the main table
|
||||
470 */
|
||||
471 pack(apkstr,apkptr)
|
||||
472 char *apkstr, *apkptr;
|
||||
1File: SYMT.C Page 9
|
||||
473 {
|
||||
474 register i;
|
||||
475 register char *pkstr, *pkptr;
|
||||
476
|
||||
477 pkstr = apkstr;
|
||||
478 pkptr = apkptr;
|
||||
479 i = NAMELEN;
|
||||
480 while(*pkstr && i) {
|
||||
481 *pkptr++ = *pkstr++;
|
||||
482 i--;
|
||||
483 }
|
||||
484 while(i--)
|
||||
485 *pkptr++ = '\0'; /*pad with nulls*/
|
||||
486 }
|
||||
487
|
||||
488 /* function to get characters for source file*/
|
||||
489 int xcol = 0; /* Column Counter */
|
||||
490 int spcnt = 0; /* Space count for tab expansion */
|
||||
491 gchr()
|
||||
492 {
|
||||
493 register chr1;
|
||||
494
|
||||
495 if(peekc) {
|
||||
496 chr1 = peekc;
|
||||
497 peekc = 0;
|
||||
498 if(chr1 != SOH)
|
||||
499 xcol--;
|
||||
500 }
|
||||
501 else if (spcnt)
|
||||
502 {
|
||||
503 spcnt--;
|
||||
504 return(' ');
|
||||
505 }
|
||||
506 else
|
||||
507 {
|
||||
508 gchr1:
|
||||
509 if(sbuflen<=0){ /*nothing on input buffer*/
|
||||
510 sbuflen=read(ifn,sbuf,512); /*read in source*/
|
||||
511 if(sbuflen<=0)
|
||||
512 return(EOF); /*end of file*/
|
||||
513 psbuf = sbuf;
|
||||
514 }
|
||||
515 chr1 = *psbuf++;
|
||||
516 sbuflen--;
|
||||
517 }
|
||||
518 if (chr1 == SOH) /*preprocessor flag*/
|
||||
519 goto gchr1; /*ignore it*/
|
||||
520 if(chr1 == EOLC) { /*end of line*/
|
||||
521 xcol = -1; /* Clear column counter */
|
||||
522 if(!p2flg) /*pass 1 only*/
|
||||
523 absln++;
|
||||
524 }
|
||||
525 if(chr1=='\t') /*convert tabs to spaces*/
|
||||
526 {
|
||||
527 spcnt += 7 - (xcol&7); /* This many spaces */
|
||||
528 xcol += spcnt; /* New column number */
|
||||
529 chr1 = ' ';
|
||||
530 }
|
||||
531 xcol++;
|
||||
1File: SYMT.C Page 10
|
||||
532 return(chr1);
|
||||
533 }
|
||||
534
|
||||
535 /*
|
||||
536 * write out intermediate text for one statement
|
||||
537 * call with
|
||||
538 * the it for the statement in stbuf
|
||||
539 */
|
||||
540 wostb()
|
||||
541 {
|
||||
542 register int woix;
|
||||
543 register short *itwo;
|
||||
544 register int i;
|
||||
545
|
||||
546 if(stbuf[0].itty != ITBS) abort(); /*not beginning of stmt*/
|
||||
547 itwo = &stbuf;
|
||||
548 woix = stbuf[0].itrl & 0377; /*unsigned byte*/
|
||||
549 while(woix--) {
|
||||
550 for(i=0; i<(sizeof stbuf[0])/(sizeof *itwo); i++) {
|
||||
551 doitwr(*itwo++);
|
||||
552 }
|
||||
553 }
|
||||
554 /* debug(); //call debug package*/
|
||||
555 }
|
||||
556
|
||||
557 doitwr(word)
|
||||
558 short word;
|
||||
559 {
|
||||
560 short i;
|
||||
561
|
||||
562 if( pitix < itbuf || pitix > &itbuf[ITBSZ] ) {
|
||||
563 printf("doitwr: it buffer botch\n");
|
||||
564 endit();
|
||||
565 }
|
||||
566 if( pitix >= &itbuf[ITBSZ]) {
|
||||
567 if(write(itfn,itbuf,ITBSZ*(sizeof i)) != ITBSZ*(sizeof i)) {
|
||||
568 rpterr("it write error errno=%o\n",errno);
|
||||
569 endit();
|
||||
570 }
|
||||
571 pitix = itbuf;
|
||||
572 }
|
||||
573 *pitix++ = word;
|
||||
574 }
|
||||
575
|
||||
576 /*
|
||||
577 * user source error
|
||||
578 * call with:
|
||||
579 * number to indicate reason for error
|
||||
580 * types the error number and the line number on which
|
||||
581 * the error occured.
|
||||
582 */
|
||||
583 uerr(errn)
|
||||
584 {
|
||||
585 if(p2flg) { /*pass 2 gets two ampersands*/
|
||||
586 in_err++; /* [vlh] instrlen <- pass1 estimation */
|
||||
587 printf("&& %d: %s\n",p2absln,ermsg[errn-1]);
|
||||
588 }
|
||||
589 else
|
||||
590 printf("& %d: %s\n",(fchr==EOLC)?absln-1:absln,ermsg[errn-1]);
|
||||
1File: SYMT.C Page 11
|
||||
591 nerror++;
|
||||
592 }
|
||||
593 /*
|
||||
594 * user error that causes the statement to be abandoned
|
||||
595 * call with:
|
||||
596 * error number
|
||||
597 */
|
||||
598 xerr(xern)
|
||||
599 {
|
||||
600 uerr(xern); /*type error message*/
|
||||
601 if(!p2flg) /*pass one*/
|
||||
602 igrst(); /*pass rest of source*/
|
||||
603 }
|
||||
604
|
||||
605 /* abort the assembly*/
|
||||
606 abort()
|
||||
607 {
|
||||
608 rpterr("as68 abort\n");
|
||||
609 nerror++;
|
||||
610 endit();
|
||||
611 }
|
||||
612
|
||||
613 /*ignore rest of statement*/
|
||||
614 igrst()
|
||||
615 {
|
||||
616 while(fchr!=EOLC && fchr!=EOF) /*until end of line*/
|
||||
617 fchr=gchr();
|
||||
618 while((fchr=gchr())==EOLC) ; /*ignore null lines*/
|
||||
619 }
|
||||
620
|
||||
621 /*ignore blanks after a label*/
|
||||
622 ligblk()
|
||||
623 {
|
||||
624 if(fchr == EOF) return;
|
||||
625 igblk();
|
||||
626 if(fchr==EOLC) {
|
||||
627 fchr=gchr();
|
||||
628 ligblk();
|
||||
629 }
|
||||
630 }
|
||||
631
|
||||
632 rubout()
|
||||
633 {
|
||||
634 nerror = -1;
|
||||
635 endit();
|
||||
636 }
|
||||
637
|
||||
638 /* exit from the assembler*/
|
||||
639 endit()
|
||||
640 {
|
||||
641 LASTCHTFN = itfnc;
|
||||
642 unlink(tfilname); /*delete temporary files*/
|
||||
643 LASTCHTFN = trbfnc;
|
||||
644 unlink(tfilname);
|
||||
645 LASTCHTFN = dafnc;
|
||||
646 unlink(tfilname);
|
||||
647 LASTCHTFN = drbfnc;
|
||||
648 unlink(tfilname);
|
||||
649 if(nerror != -1) { /*not rubout*/
|
||||
1File: SYMT.C Page 12
|
||||
650 if(ftudp)
|
||||
651 putchar('\n');
|
||||
652 }
|
||||
653 if(nerror > 0) {
|
||||
654 fprintf(stderr,"& %d errors\n",nerror);
|
||||
655 }
|
||||
656 if (initflg)
|
||||
657 unlink(ldfn); /* [vlh] get rid of empty .o file */
|
||||
658 exit(nerror!=0);
|
||||
659 }
|
||||
660
|
||||
661 /*
|
||||
662 * open files
|
||||
663 * call with:
|
||||
664 * pointer to name of file to open
|
||||
665 * flag for how to open
|
||||
666 * 0 => read
|
||||
667 * 1 => write
|
||||
668 */
|
||||
669 openfi(pname,hflag)
|
||||
670 char *pname;
|
||||
671 {
|
||||
672 register fd;
|
||||
673
|
||||
674 fd = (hflag==1) ? creat(pname,0666,1) : open(pname,hflag,1);
|
||||
675 if(fd < 0) { /*open failed*/
|
||||
676 rpterr("can't open %s errno=%o\n",pname,errno);
|
||||
677 endit();
|
||||
678 }
|
||||
679 return(fd);
|
||||
680 }
|
||||
681
|
||||
682 /* get a temp file for the intermediate text*/
|
||||
683 char lastfile = 'A';
|
||||
684 gettempf()
|
||||
685 {
|
||||
686 register i,j;
|
||||
687 register char *p;
|
||||
688
|
||||
689 LASTCHTFN = lastfile++; /* Creat temp name */
|
||||
690 if((j=creat(tfilname,0600,1)) >= 0)
|
||||
691 return(j); /* File created OK */
|
||||
692 rpterr("Unable to open temporary file\n");
|
||||
693 endit();
|
||||
694 }
|
||||
695
|
||||
696 /* move label name from lbt to main table entry pointed to by lmte*/
|
||||
697 setname()
|
||||
698 {
|
||||
699 register i;
|
||||
700 register int *p1, *p2;
|
||||
701
|
||||
702 p1 = &lmte->name[0];
|
||||
703 for(p2 = &lbt[0]; p2 < &lbt[NAMELEN]; ) {
|
||||
704 *p1++ = *p2;
|
||||
705 *p2++ = 0;
|
||||
706 }
|
||||
707 }
|
||||
708
|
||||
1File: SYMT.C Page 13
|
||||
709 /* get the initialized main table and initial reference tables from*/
|
||||
710 /* the initialize file*/
|
||||
711 getsymtab()
|
||||
712 {
|
||||
713 long j; /* length for read / write */
|
||||
714 register char **p;
|
||||
715 register struct symtab *p1;
|
||||
716 register char *p2;
|
||||
717 register fd,i;
|
||||
718
|
||||
719 if((fd=open(initfnam,0,1)) < 0) {
|
||||
720 rerr:
|
||||
721 printf("& Unable to read init file: %s\n", initfnam);
|
||||
722 endit();
|
||||
723 }
|
||||
724 if(read(fd,sirt,SZIRT*(sizeof sirt[0])) != SZIRT*(sizeof sirt[0])) {
|
||||
725 goto rerr;
|
||||
726 }
|
||||
727
|
||||
728 if(read(fd,oirt,SZIRT*(sizeof sirt[0])) != SZIRT*(sizeof sirt[0]))
|
||||
729 goto rerr;
|
||||
730
|
||||
731 if(read(fd,&j,(sizeof j)) != (sizeof j)) /* Read Count */
|
||||
732 goto rerr; /* Y-U-K!!! */
|
||||
733
|
||||
734 if((i=read(fd,bmte,(int)j)) != j) /* Read table */
|
||||
735 goto rerr;
|
||||
736
|
||||
737 if((i%STESIZE) != 0)
|
||||
738 goto rerr;
|
||||
739
|
||||
740 lmte = bmte + i;
|
||||
741 p2 = bmte-1;
|
||||
742 for(p=sirt; p<&sirt[SZIRT]; p++) {
|
||||
743 if(*p)
|
||||
744 *p =+ (long)p2;
|
||||
745 }
|
||||
746 for(p=oirt; p<&oirt[SZIRT]; p++) {
|
||||
747 if(*p)
|
||||
748 *p =+ (long)p2;
|
||||
749 }
|
||||
750 for(p1=bmte; p1<lmte; p1++) {
|
||||
751 if(p1->tlnk)
|
||||
752 p1->tlnk =+ (long)p2;
|
||||
753 }
|
||||
754 close(fd);
|
||||
755 }
|
||||
756
|
||||
757 /* write the initialization file*/
|
||||
758 putsymtab()
|
||||
759 {
|
||||
760 long j;
|
||||
761 register char **p;
|
||||
762 register struct symtab *p1;
|
||||
763 register char *p2;
|
||||
764 register fd,i;
|
||||
765
|
||||
766 if((fd=creat(initfnam,0644,1))<0) {
|
||||
767 printf("& Cannot create init: %s\n", initfnam);
|
||||
1File: SYMT.C Page 14
|
||||
768 return;
|
||||
769 }
|
||||
770 /*
|
||||
771 * change all pointers so that they are relative to the beginning
|
||||
772 * of the symbol table
|
||||
773 */
|
||||
774 p2 = bmte-1;
|
||||
775 for(p=sirt; p<&sirt[SZIRT]; p++) {
|
||||
776 if(*p)
|
||||
777 *p =- (long)p2;
|
||||
778 }
|
||||
779 for(p=oirt; p<&oirt[SZIRT]; p++) {
|
||||
780 if(*p)
|
||||
781 *p =- (long)p2;
|
||||
782 }
|
||||
783 for(p1=bmte; p1<lmte; p1++) {
|
||||
784 if(p1->tlnk)
|
||||
785 p1->tlnk =- (long)p2;
|
||||
786 }
|
||||
787
|
||||
788 if(write(fd,sirt,SZIRT*(sizeof sirt[0])) != SZIRT*(sizeof sirt[0])) {
|
||||
789 goto werr;
|
||||
790 }
|
||||
791
|
||||
792 if(write(fd,oirt,SZIRT*(sizeof oirt[0])) != SZIRT*(sizeof oirt[0]))
|
||||
793 goto werr;
|
||||
794
|
||||
795 i = lmte - bmte; /*length of current main table*/
|
||||
796 if((i % STESIZE) != 0) {
|
||||
797 goto werr;
|
||||
798 }
|
||||
799 j = i;
|
||||
800 if(write(fd,&j,(sizeof j)) != (sizeof j)) /* Y-U-K!! */
|
||||
801 goto werr;
|
||||
802
|
||||
803 if(write(fd,bmte,i) != i) {
|
||||
804 werr:
|
||||
805 printf("& Write error on init file: %s\n",initfnam);
|
||||
806 return;
|
||||
807 }
|
||||
808 close(fd);
|
||||
809 }
|
||||
810
|
||||
811 /* print an error on file descriptor 2*/
|
||||
812 /* used for errors with disasterous consequences*/
|
||||
813 rpterr(ptch,x1,x2,x3,x4,x5,x6)
|
||||
814 char *ptch;
|
||||
815 {
|
||||
816 if(prtflg==0) /* Check for paging output */
|
||||
817 page(); /* Perform page checks */
|
||||
818 fprintf(stderr,"& %d: ",absln);
|
||||
819 fprintf(stderr,ptch,x1,x2,x3,x4,x5,x6);
|
||||
820 }
|
||||
821
|
||||
822 /* set the file name for the relocatable object file (sourcefile.o)*/
|
||||
823 setldfn(ap)
|
||||
824 char *ap;
|
||||
825 {
|
||||
826 register char *p1,*p2;
|
||||
1File: SYMT.C Page 15
|
||||
827
|
||||
828 p1 = ap;
|
||||
829 p2 = ldfn;
|
||||
830 while(*p1) {
|
||||
831 *p2++ = *p1++;
|
||||
832 }
|
||||
833 if(*(p2-2) != '.') { /*not name.?*/
|
||||
834 *p2++ = '.';
|
||||
835 *p2++ = 'o';
|
||||
836 }
|
||||
837 else { /* is name.? */
|
||||
838 *(p2-1) = 'o';
|
||||
839 }
|
||||
840 *p2 = '\0';
|
||||
841 }
|
||||
842
|
||||
843 savelab()
|
||||
844 {
|
||||
845 register int *p1, *p2;
|
||||
846
|
||||
847 p2 = &lmte->name[0];
|
||||
848 for(p1= &tlab1[0]; p1 < &tlab1[NAMELEN]; )
|
||||
849 *p1++ = *p2++;
|
||||
850 }
|
||||
19
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/as68/up9.sub
Normal file
19
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/as68/up9.sub
Normal file
@@ -0,0 +1,19 @@
|
||||
e:vax DIR.C s
|
||||
e:vax EXPR.C s
|
||||
e:vax MAIN.C s
|
||||
e:vax MISC.C s
|
||||
e:vax PASS1A.C s
|
||||
e:vax PASS2.C s
|
||||
e:vax MAKE.SUB s
|
||||
e:vax STRNCMP.C s
|
||||
e:vax SYMT.C s
|
||||
e:vax VERSION.C s
|
||||
e:vax AS68.H s
|
||||
e:vax COUT.H s
|
||||
e:vax CTYPE.H s
|
||||
e:vax MACHINE.H s
|
||||
e:vax RELINK.SUB s
|
||||
e:vax MACHINE.11 s
|
||||
e:vax MACHINE.68K s
|
||||
e:vax MACHINE.VAX s
|
||||
e:vax AS68INIT. s
|
||||
@@ -0,0 +1 @@
|
||||
char *version "@(#) Tue Nov 23 14:31";
|
||||
@@ -0,0 +1,2 @@
|
||||
1File: VERSION.C Page 1
|
||||
1 char *version "@(#) Tue Nov 23 14:31";
|
||||
@@ -0,0 +1,15 @@
|
||||
$ asm
|
||||
$ !
|
||||
$ ! as68 Version 2.3 make file for VMS
|
||||
$ !
|
||||
$ set noon
|
||||
$ copy machine.vax machine.h
|
||||
$ cx AS68INIT
|
||||
$ cx DIR
|
||||
$ cx EXPR
|
||||
$ cx MAIN
|
||||
$ cx MISC
|
||||
$ cx PASS1A
|
||||
$ cx PASS2
|
||||
$ cx SYMT
|
||||
$ @vrelink
|
||||
@@ -0,0 +1 @@
|
||||
$ clink AS68INIT,DIR,EXPR,MAIN,PASS1A,PASS2,SYMT,MISC,lib:klib/lib as68
|
||||
@@ -0,0 +1,26 @@
|
||||
$ set noon
|
||||
$ vsend AS68.H
|
||||
$ vsend AS68INIT.
|
||||
$ vsend AS68INIT.C
|
||||
$ vsend COUT.H
|
||||
$ vsend CTYPE.H
|
||||
$ vsend DIR.C
|
||||
$ vsend EXPR.C
|
||||
$ vsend LIST.COM
|
||||
$ vsend MACHINE.11
|
||||
$ vsend MACHINE.68K
|
||||
$ vsend MACHINE.H
|
||||
$ vsend MACHINE.VAX
|
||||
$ vsend MAIN.C
|
||||
$ vsend MAKE.SUB
|
||||
$ vsend MISC.C
|
||||
$ vsend PASS1A.C
|
||||
$ vsend PASS2.C
|
||||
$ vsend RELINK.SUB
|
||||
$ vsend STRNCMP.C
|
||||
$ vsend SYMT.C
|
||||
$ vsend UP9.SUB
|
||||
$ vsend VERSION.C
|
||||
$ vsend VMAKE.COM
|
||||
$ vsend VRELINK.COM
|
||||
$ vsend done
|
||||
13
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/as68/xer.com
Normal file
13
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/as68/xer.com
Normal file
@@ -0,0 +1,13 @@
|
||||
$ xer AS68INIT.LIS
|
||||
$ xer DIR.LIS
|
||||
$ xer EXPR.LIS
|
||||
$ xer MAIN.LIS
|
||||
$ xer MISC.LIS
|
||||
$ xer PASS1A.LIS
|
||||
$ xer PASS2.LIS
|
||||
$ xer SYMT.LIS
|
||||
$ xer VERSION.LIS
|
||||
$ xer AS68.LST
|
||||
$ xer COUT.LST
|
||||
$ xer CTYPE.LST
|
||||
$ xer MACHINE.LST
|
||||
@@ -0,0 +1,18 @@
|
||||
|
||||
Directory DRB0:[STEVE.CPM68K.V102.AS68]
|
||||
|
||||
AS68INIT.LIS;1
|
||||
DIR.LIS;1
|
||||
EXPR.LIS;1
|
||||
MAIN.LIS;1
|
||||
MISC.LIS;1
|
||||
PASS1A.LIS;1
|
||||
PASS2.LIS;1
|
||||
SYMT.LIS;1
|
||||
VERSION.LIS;1
|
||||
AS68.LST;1
|
||||
COUT.LST;1
|
||||
CTYPE.LST;1
|
||||
MACHINE.LST;1
|
||||
|
||||
Total of 13 files.
|
||||
180
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/bdos/bdosdef.h
Normal file
180
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/bdos/bdosdef.h
Normal file
@@ -0,0 +1,180 @@
|
||||
|
||||
/********************************************************
|
||||
* *
|
||||
* CP/M-68K header file *
|
||||
* Copyright (c) 1982 by Digital Research, Inc. *
|
||||
* Structure definitions for BDOS globals *
|
||||
* and BDOS data structures *
|
||||
* *
|
||||
* Desecrated 6-Aug-83 (sw) for type-ahead *
|
||||
* *
|
||||
********************************************************/
|
||||
|
||||
/**************************************************************************
|
||||
The BDOS data structures, especially those relating to global variables,
|
||||
are structured in a way that hopefully will enable this BDOS, in the future,
|
||||
to easily become a re-entrant multi-tasking file system. Consequently,
|
||||
the BDOS global variables are divided into two classes. Those that are
|
||||
truly global, even in the case of multiple tasks using the file system
|
||||
concurrently, are simply declared as global variables in bdosmain.c.
|
||||
Only a few "globals" are really global in this sense.
|
||||
|
||||
The majority of the "global" variables are actually state variables that
|
||||
relate to the state of the task using the file system. In CP/M-68K, these
|
||||
are "global", since there's only one task, but in a multi-thread model they're
|
||||
not. This type of variables is put into a data structure, with the
|
||||
intention that in the multi-task environment this structure will be based.
|
||||
|
||||
The following declarations take this philosophy into account, and define
|
||||
a simple structure for the single thread environment while leaving the
|
||||
possibilities open for the multi-thread environment.
|
||||
****************************************************************************/
|
||||
|
||||
#define snglthrd TRUE
|
||||
/* TRUE for single-thread environment
|
||||
FALSE to create based structure for re-entrant model */
|
||||
#if snglthrd
|
||||
#define GBL gbls
|
||||
/* In single thread case, GBL just names
|
||||
the structure */
|
||||
#define BSETUP EXTERN struct stvars gbls;
|
||||
/* and BSETUP defines the extern structure */
|
||||
#endif
|
||||
|
||||
#if ! snglthrd
|
||||
#define GBL (*statep)
|
||||
/* If multi-task, state vars are based */
|
||||
#define BSETUP REG struct stvars *statep; \
|
||||
statep = &gbls;
|
||||
/* set up pointer to state variables */
|
||||
/* This is intended as an example to show the intent */
|
||||
#endif
|
||||
|
||||
|
||||
/* Note that there are a few critical regions in the file system that must
|
||||
execute without interruption. They pertain mostly to the manipulation of
|
||||
the allocation vector. This isn't a problem in a single-thread model, but
|
||||
must be provided for in a multi-tasking file system. Consequently, the
|
||||
primitives LOCK and UNLOCK are defined and used where necessary in the
|
||||
file system. For the single thread model, they are null routines */
|
||||
|
||||
#define LOCK /**/
|
||||
#define UNLOCK /**/
|
||||
/* Be sure LOCK and UNLOCK are implemented to allow recursive calls to LOCK.
|
||||
That is, if a process that calls LOCK already owns the lock, let it proceed,
|
||||
but remember that only the outer-most call to UNLOCK really releases the
|
||||
file system. */
|
||||
|
||||
|
||||
#define VERSION 0x2022 /* Version number for CP/M-68K */
|
||||
#define robit 0 /* read-only bit in file type field of fcb */
|
||||
#define arbit 2 /* archive bit in file type field of fcb */
|
||||
#define SECLEN 128 /* length of a CP/M sector */
|
||||
|
||||
|
||||
/* File Control Block definition */
|
||||
struct fcb
|
||||
{
|
||||
UBYTE drvcode; /* 0 = default drive, 1..16 are drives A..P */
|
||||
UBYTE fname[8]; /* File name (ASCII) */
|
||||
UBYTE ftype[3]; /* File type (ASCII) */
|
||||
UBYTE extent; /* Extent number (bits 0..4 used) */
|
||||
UBYTE s1; /* Reserved */
|
||||
UBYTE s2; /* Module field (bits 0..5), write flag (7) */
|
||||
UBYTE rcdcnt; /* Nmbr rcrds in last block, 0..128 */
|
||||
union
|
||||
{
|
||||
UBYTE small[16]; /* 16 block numbers of 1 byte */
|
||||
WORD big[8]; /* or 8 block numbers of 1 word */
|
||||
} dskmap;
|
||||
UBYTE cur_rec; /* current record field */
|
||||
UBYTE ran0; /* random record field (3 bytes) */
|
||||
UBYTE ran1;
|
||||
UBYTE ran2;
|
||||
};
|
||||
|
||||
|
||||
/* Declaration of directory entry */
|
||||
struct dirent
|
||||
{
|
||||
UBYTE entry; /* 0 - 15 for user numbers, E5 for empty */
|
||||
/* the rest are reserved */
|
||||
UBYTE fname[8]; /* File name (ASCII) */
|
||||
UBYTE ftype[3]; /* File type (ASCII) */
|
||||
UBYTE extent; /* Extent number (bits 0..4 used) */
|
||||
UBYTE s1; /* Reserved */
|
||||
UBYTE s2; /* Module field (bits 0..5), write flag (7) */
|
||||
UBYTE rcdcnt; /* Nmbr rcrds in last block, 0..128 */
|
||||
union
|
||||
{
|
||||
UBYTE small[16]; /* 16 block numbers of 1 byte */
|
||||
WORD big[8]; /* or 8 block numbers of 1 word */
|
||||
} dskmap;
|
||||
};
|
||||
|
||||
|
||||
/* Declaration of disk parameter tables */
|
||||
struct dpb /* disk parameter table */
|
||||
{
|
||||
UWORD spt; /* sectors per track */
|
||||
UBYTE bsh; /* block shift factor */
|
||||
UBYTE blm; /* block mask */
|
||||
UBYTE exm; /* extent mask */
|
||||
UBYTE dpbdum; /* dummy byte for fill */
|
||||
UWORD dsm; /* max disk size in blocks */
|
||||
UWORD drm; /* max directory entries */
|
||||
UWORD dir_al; /* initial allocation for dir */
|
||||
UWORD cks; /* number dir sectors to checksum */
|
||||
UWORD trk_off; /* track offset */
|
||||
};
|
||||
|
||||
struct dph /* disk parameter header */
|
||||
{
|
||||
UBYTE *xlt; /* pointer to sector translate table */
|
||||
UWORD hiwater; /* high water mark for this disk */
|
||||
UWORD dum1; /* dummy (unused) */
|
||||
UWORD dum2;
|
||||
UBYTE *dbufp; /* pointer to 128 byte directory buffer */
|
||||
struct dpb *dpbp; /* pointer to disk parameter block */
|
||||
UBYTE *csv; /* pointer to check vector */
|
||||
UBYTE *alv; /* pointer to allocation vector */
|
||||
};
|
||||
|
||||
|
||||
/* Declaration of structure containing "global" state variables */
|
||||
#define TBUFSIZ 126 /*sw # typed-ahead characters */
|
||||
struct stvars
|
||||
{
|
||||
UBYTE kbchar; /* keyboard type-ahead buffer count */
|
||||
UBYTE delim; /* Delimiter for function 9 */
|
||||
BOOLEAN lstecho; /* True if echoing console output to lst: */
|
||||
BOOLEAN echodel; /* Echo char when getting <del> ? */
|
||||
UWORD column; /* CRT column number for expanding tabs */
|
||||
UBYTE *chainp; /* Used for chain to program call */
|
||||
UBYTE curdsk; /* Currently selected disk */
|
||||
UBYTE dfltdsk; /* Default disk (last selected by fcn 14) */
|
||||
UBYTE user; /* Current user number */
|
||||
struct dph *dphp; /* pointer to disk parm hdr for cur disk */
|
||||
struct dirent *dirbufp; /* pointer for directory buff for process */
|
||||
/* stored here so that each process can */
|
||||
/* have a separate dirbuf. */
|
||||
struct dpb *parmp; /* pointer to disk parameter block for cur */
|
||||
/* disk. Stored here to save ref calc */
|
||||
UWORD srchpos; /* position in directory for search next */
|
||||
UBYTE *dmaadr; /* Disk dma address */
|
||||
struct fcb *srchp; /* Pointer to search FCB for function 17 */
|
||||
UBYTE *excvec[18]; /* Array of exception vectors */
|
||||
UBYTE *insptr; /*sw Insertion pointer for typeahead */
|
||||
UBYTE *remptr; /*sw Removal pointer for typeahead */
|
||||
UBYTE t_buff[TBUFSIZ]; /*sw Type-ahead buffer itself */
|
||||
};
|
||||
|
||||
|
||||
/* Console buffer structure declaration */
|
||||
struct conbuf
|
||||
{
|
||||
UBYTE maxlen; /* Maximum length from calling routine */
|
||||
UBYTE retlen; /* Length actually found by BDOS */
|
||||
UBYTE cbuf[]; /* Console data */
|
||||
};
|
||||
|
||||
154
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/bdos/bdosif.s
Normal file
154
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/bdos/bdosif.s
Normal file
@@ -0,0 +1,154 @@
|
||||
|
||||
*****************************************************************
|
||||
* *
|
||||
* CP/M-68K Basic Disk Operating System interface module *
|
||||
* For "C" version of CP/M-68K *
|
||||
* *
|
||||
* Copyright (c) 1982 Digital Research, Inc. *
|
||||
* *
|
||||
* Version 0.2 -- September 22, 1982 *
|
||||
* *
|
||||
*****************************************************************
|
||||
|
||||
* Declare Public Routines
|
||||
|
||||
.globl _bios1 * 6 BIOS entry points from BDOS
|
||||
.globl _bios2
|
||||
.globl _bios3
|
||||
.globl _bios4
|
||||
.globl _bios5
|
||||
.globl _bios6
|
||||
.globl _traphnd * trap #2 handler
|
||||
.globl _swap * byte swapper
|
||||
.globl _udiv * unsigned divide routine
|
||||
|
||||
* Declare external routines
|
||||
.globl __bdos * BDOS entry point in bdosmain
|
||||
|
||||
* The following external references were put in just to make sure that all
|
||||
* the BDOS modules were referenced, so we could put them in a library
|
||||
.globl _constat * references conbdos.o
|
||||
.globl _dirscan * references dskutil.o
|
||||
.globl _create * references fileio.o
|
||||
.globl _bdosrw * references bdosrw.o
|
||||
|
||||
biosf = 50
|
||||
setsupf = 62
|
||||
|
||||
_traphnd:
|
||||
*
|
||||
* first save the registers and
|
||||
* check for functions handled by assembly language routines
|
||||
*
|
||||
cmpi #setsupf,d0
|
||||
beq setsup
|
||||
movem.l d1-d7/a0-a6,-(sp)
|
||||
cmpi #biosf,d0
|
||||
beq bioscall
|
||||
*
|
||||
* function number is passed in D0
|
||||
* byte and word pararmeters are passed in D1.W
|
||||
* address parameters are passed in D1.L
|
||||
*
|
||||
move.l d1,-(a7)
|
||||
move.w d1,-(a7)
|
||||
move.w d0,-(a7)
|
||||
jsr __bdos * call BDOS
|
||||
*
|
||||
* now restore the regs
|
||||
*
|
||||
ext.l d0
|
||||
addq #8,sp * fix up the stack
|
||||
bdone:
|
||||
movem.l (sp)+,a0-a6/d1-d7
|
||||
rte * return from trap call
|
||||
|
||||
*
|
||||
* direct BIOS call function
|
||||
*
|
||||
bioscall:
|
||||
move.l d1,a0 * get address of CPB
|
||||
move.w (a0)+,d0
|
||||
movem.l (a0)+,d1-d2
|
||||
trap #3
|
||||
bra bdone
|
||||
|
||||
*
|
||||
* Set supervisor mode procedure
|
||||
*
|
||||
setsup:
|
||||
ori #$2000,(sp) * turn on supervisor bit in SR
|
||||
rte
|
||||
|
||||
*
|
||||
* BIOS Interface Routines
|
||||
*
|
||||
*
|
||||
* Note - there are 6 BIOS entry points from the BDOS, labelled BIOS1 -
|
||||
* BIOS6, depending on the parameters passed.
|
||||
|
||||
_bios5:
|
||||
* For BIOS functions sectran and set exception vector
|
||||
* Has function number and 2 parameters, a word followed by a long word
|
||||
move.l 8(sp),d2 * get 2nd parameter (long word)
|
||||
bra _bios2 * join common routine
|
||||
|
||||
_bios4:
|
||||
* For BIOS function seldsk
|
||||
* Has function number followed by 2 word parameters
|
||||
move.w 8(sp),d2 * get 2nd parameter (word)
|
||||
bra _bios2 * join common routine
|
||||
|
||||
_bios3:
|
||||
* For BIOS function set dma
|
||||
* Has function number followed by 1 long parameter
|
||||
move.l 6(sp),d1 * get long word parameter
|
||||
bra _bios1 * join common routine
|
||||
|
||||
_bios2:
|
||||
* For all BIOS functions with a word parameter
|
||||
* Word parameter follows function number
|
||||
move.w 6(sp),d1 * get 1st parameter (word)
|
||||
|
||||
_bios6:
|
||||
_bios1:
|
||||
* For all BIOS functions that have no parameter other than function number
|
||||
move.w 4(sp),d0 * get function number
|
||||
movem.l d3-d7/a3-a6,-(sp)
|
||||
* * save C register variables
|
||||
trap #3 * do BIOS call
|
||||
* * returns value in d0
|
||||
movem.l (sp)+,d3-d7/a3-a6
|
||||
rts
|
||||
|
||||
*
|
||||
* Utility Subroutines
|
||||
*
|
||||
|
||||
_swap:
|
||||
* Swap bytes of a word, return swapped value in d0
|
||||
move.b 5(sp),d0
|
||||
lsl #8,d0
|
||||
move.b 4(sp),d0
|
||||
rts
|
||||
|
||||
_udiv:
|
||||
* Unsigned divide routine
|
||||
* returns unsigned quotient in D0.W
|
||||
|
||||
* UWORD udiv( divisor, dividend, remp )
|
||||
*
|
||||
* REG LONG divisor;
|
||||
* UWORD dividend;
|
||||
* UWORD *remp /* pointer to remainder (returned) */
|
||||
|
||||
move.l 4(sp), d0 * get dividend
|
||||
divu 8(sp), d0 * do the divide
|
||||
movea.l 10(sp),a0
|
||||
swap d0
|
||||
move.w d0, (a0) * store remainder
|
||||
clr.w d0
|
||||
swap d0 * word quotient in d0
|
||||
rts
|
||||
|
||||
.end
|
||||
@@ -0,0 +1,68 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* C P / M C H E A D E R F I L E
|
||||
* -----------------------------------
|
||||
* Copyright 1982 by Digital Research Inc. All rights reserved.
|
||||
*
|
||||
* This is an include file for assisting the user to write portable
|
||||
* programs for C.
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define ALCYON 1 /* using Alcyon compiler */
|
||||
/*
|
||||
* Standard type definitions
|
||||
*/
|
||||
/***************************/
|
||||
#define BYTE char /* Signed byte */
|
||||
#define BOOLEAN char /* 2 valued (true/false) */
|
||||
#define WORD short /* Signed word (16 bits) */
|
||||
#define UWORD unsigned int /* unsigned word */
|
||||
#define LONG long /* signed long (32 bits) */
|
||||
#define ULONG unsigned long /* Unsigned long */
|
||||
#define REG register /* register variable */
|
||||
#define LOCAL auto /* Local var on 68000 */
|
||||
#define EXTERN extern /* External variable */
|
||||
#define MLOCAL static /* Local to module */
|
||||
#define GLOBAL /**/ /* Global variable */
|
||||
#define VOID /**/ /* Void function return */
|
||||
/***************************/
|
||||
#ifdef ALCYON
|
||||
#define UBYTE char
|
||||
#define UBWORD(a) ((UWORD)a & 0xff)
|
||||
/* Unsigned byte to word cast */
|
||||
#else
|
||||
#define UBYTE unsigned char /* Unsigned byte */
|
||||
#define UBWORD(a) (UWORD)a
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/* 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 (BYTE *)0 /* Null pointer value */
|
||||
#define EOF (-1) /* EOF Value */
|
||||
#define TRUE (1) /* Function TRUE value */
|
||||
#define FALSE (0) /* Function FALSE value */
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/* */
|
||||
/* M A C R O S */
|
||||
/* ----------- */
|
||||
/* */
|
||||
/* Define some stuff as macros .... */
|
||||
/* */
|
||||
/****************************************************************************/
|
||||
|
||||
#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 */
|
||||
|
||||
/*************************** end of stdio.h *********************************/
|
||||
304
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/bdos/bdosmain.c
Normal file
304
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/bdos/bdosmain.c
Normal file
@@ -0,0 +1,304 @@
|
||||
|
||||
/****************************************************************
|
||||
* *
|
||||
* CP/M-68K BDOS Main Routine *
|
||||
* *
|
||||
* This is the main routine for the BDOS for CP/M-68K *
|
||||
* It has one entry point, _bdos, which is called from *
|
||||
* the assembly language trap handler found in bdosif.s. *
|
||||
* The parameters are a function number (integer) and an *
|
||||
* information parameter (which is passed from bdosif as *
|
||||
* both an integer and a pointer).
|
||||
* The BDOS can potentially return a pointer, long word, *
|
||||
* or word *
|
||||
* *
|
||||
* Configured for Alcyon C on the VAX *
|
||||
* *
|
||||
****************************************************************/
|
||||
|
||||
#include "bdosinc.h" /* Standard I/O declarations */
|
||||
|
||||
#include "bdosdef.h" /* Type and structure declarations for BDOS */
|
||||
|
||||
#include "biosdef.h" /* Declarations of BIOS functions */
|
||||
|
||||
/* Declare EXTERN functions */
|
||||
|
||||
EXTERN warmboot(); /* Warm Boot function */
|
||||
EXTERN BOOLEAN constat(); /* Console status */
|
||||
EXTERN UBYTE conin(); /* Console Input function */
|
||||
EXTERN tabout(); /* Console output with tab expansion */
|
||||
EXTERN UBYTE rawconio(); /* Raw console I/O */
|
||||
EXTERN prt_line(); /* Print line until delimiter */
|
||||
EXTERN readline(); /* Buffered console read */
|
||||
EXTERN seldsk(); /* Select disk */
|
||||
EXTERN BOOLEAN openfile(); /* Open File */
|
||||
EXTERN UWORD close_fi(); /* Close File */
|
||||
EXTERN UWORD search(); /* Search first and next fcns */
|
||||
EXTERN UWORD dirscan(); /* General directory scanning routine */
|
||||
EXTERN UWORD bdosrw(); /* Sequential and Random disk read/write */
|
||||
EXTERN BOOLEAN create(); /* Create file */
|
||||
EXTERN BOOLEAN delete(); /* Delete file */
|
||||
EXTERN BOOLEAN rename(); /* Rename file */
|
||||
EXTERN BOOLEAN set_attr(); /* Set file attributes */
|
||||
EXTERN getsize(); /* Get File Size */
|
||||
EXTERN setran(); /* Set Random Record */
|
||||
EXTERN free_sp(); /* Get Disk Free Space */
|
||||
EXTERN UWORD flushit(); /* Flush Buffers */
|
||||
EXTERN UWORD pgmld(); /* Program Load */
|
||||
EXTERN UWORD setexc(); /* Set Exception Vector */
|
||||
EXTERN set_tpa(); /* Get/Set TPA Limits */
|
||||
EXTERN move(); /* general purpose byte mover */
|
||||
|
||||
|
||||
/* Declare "true" global variables; i.e., those which will pertain to the
|
||||
entire file system and thus will remain global even when this becomes
|
||||
a multi-tasking file system */
|
||||
|
||||
GLOBAL UWORD log_dsk; /* 16-bit vector of logged in drives */
|
||||
GLOBAL UWORD ro_dsk; /* 16-bit vector of read-only drives */
|
||||
GLOBAL UWORD crit_dsk; /* 16-bit vector of drives in "critical"
|
||||
state. Used to control dir checksums */
|
||||
GLOBAL BYTE *tpa_lp; /* TPA lower boundary (permanent) */
|
||||
GLOBAL BYTE *tpa_lt; /* TPA lower boundary (temporary) */
|
||||
GLOBAL BYTE *tpa_hp; /* TPA upper boundary (permanent) */
|
||||
GLOBAL BYTE *tpa_ht; /* TPA upper boundary (temporary) */
|
||||
|
||||
|
||||
/* Declare the "state variables". These are globals for the single-thread
|
||||
version of the file system, but are put in a structure so they can be
|
||||
based, with a pointer coming from the calling process */
|
||||
|
||||
GLOBAL struct stvars gbls;
|
||||
|
||||
struct tempstr
|
||||
{
|
||||
UBYTE tempdisk;
|
||||
BOOLEAN reselect;
|
||||
struct fcb *fptr;
|
||||
};
|
||||
|
||||
/****************************************************************
|
||||
* *
|
||||
* _bdos MAIN ROUTINE *
|
||||
* *
|
||||
* Called with _bdos(func, info, infop) *
|
||||
* *
|
||||
* Where: *
|
||||
* func is the BDOS function number (d0.w) *
|
||||
* info is the word parameter (d1.w) *
|
||||
* infop is the pointer parameter (d1.l) *
|
||||
* note that info is the word form of infop*
|
||||
* *
|
||||
****************************************************************/
|
||||
|
||||
|
||||
UWORD _bdos(func,info,infop)
|
||||
REG WORD func; /* BDOS function number */
|
||||
REG UWORD info; /* d1.w word parameter */
|
||||
REG UBYTE *infop; /* d1.l pointer parameter */
|
||||
{
|
||||
REG UWORD rtnval;
|
||||
LOCAL struct tempstr temp;
|
||||
BSETUP
|
||||
|
||||
temp.reselect = FALSE;
|
||||
temp.fptr = infop;
|
||||
rtnval = 0;
|
||||
|
||||
switch (func) /* switch on function number */
|
||||
{
|
||||
case 0: warmboot(0); /* warm boot function */
|
||||
/* break; */
|
||||
|
||||
case 1: return((UWORD)conin()); /* console input function */
|
||||
/* break; */
|
||||
|
||||
case 2: tabout((UBYTE)info); /* console output with */
|
||||
break; /* tab expansion */
|
||||
|
||||
case 3: return((UWORD)brdr()); /* get reader from bios */
|
||||
/* break; */
|
||||
|
||||
case 4: bpun((UBYTE)info); /* punch output to bios */
|
||||
break;
|
||||
|
||||
case 5: blstout((UBYTE)info); /* list output from bios */
|
||||
break;
|
||||
|
||||
case 6: return((UWORD)rawconio(info)); /* raw console I/O */
|
||||
/* break; */
|
||||
|
||||
case 7: return(bgetiob()); /* get i/o byte */
|
||||
/* break; */
|
||||
|
||||
case 8: bsetiob(info); /* set i/o byte function */
|
||||
break;
|
||||
|
||||
case 9: prt_line(infop); /* print line function */
|
||||
break;
|
||||
|
||||
case 10: readline(infop); /* read buffered con input */
|
||||
break;
|
||||
|
||||
case 11: return((UWORD)constat()); /* console status */
|
||||
/* break; */
|
||||
|
||||
case 12: return(VERSION); /* return version number */
|
||||
/* break; */
|
||||
|
||||
case 13: log_dsk = 0; /* reset disk system */
|
||||
ro_dsk = 0;
|
||||
crit_dsk= 0;
|
||||
GBL.curdsk = 0xff;
|
||||
GBL.dfltdsk = 0;
|
||||
break;
|
||||
|
||||
case 14: seldsk((UBYTE)info); /* select disk */
|
||||
GBL.dfltdsk = (UBYTE)info;
|
||||
break;
|
||||
|
||||
case 15: tmp_sel(&temp); /* open file */
|
||||
infop->extent = 0;
|
||||
infop->s2 = 0;
|
||||
rtnval = dirscan(openfile, infop, 0);
|
||||
break;
|
||||
|
||||
case 16: tmp_sel(&temp); /* close file */
|
||||
rtnval = close_fi(infop);
|
||||
break;
|
||||
|
||||
case 17: GBL.srchp = infop; /* search first */
|
||||
rtnval = search(infop, 0, &temp);
|
||||
break;
|
||||
|
||||
case 18: infop = GBL.srchp; /* search next */
|
||||
temp.fptr = infop;
|
||||
rtnval = search(infop, 1, &temp);
|
||||
break;
|
||||
|
||||
case 19: tmp_sel(&temp); /* delete file */
|
||||
rtnval = dirscan(delete, infop, 2);
|
||||
break;
|
||||
|
||||
case 20: tmp_sel(&temp); /* read sequential */
|
||||
rtnval = bdosrw(infop, TRUE, 0);
|
||||
break;
|
||||
|
||||
case 21: tmp_sel(&temp); /* write sequential */
|
||||
rtnval = bdosrw(infop, FALSE, 0);
|
||||
break;
|
||||
|
||||
case 22: tmp_sel(&temp); /* create file */
|
||||
infop->extent = 0;
|
||||
infop->s1 = 0;
|
||||
infop->s2 = 0;
|
||||
infop->rcdcnt = 0;
|
||||
/* Zero extent, S1, S2, rcrdcnt. create zeros rest */
|
||||
rtnval = dirscan(create, infop, 8);
|
||||
break;
|
||||
|
||||
case 23: tmp_sel(&temp); /* rename file */
|
||||
rtnval = dirscan(rename, infop, 2);
|
||||
break;
|
||||
|
||||
case 24: return(log_dsk); /* return login vector */
|
||||
/* break; */
|
||||
|
||||
case 25: return(UBWORD(GBL.dfltdsk)); /* return current disk */
|
||||
/* break; */
|
||||
|
||||
case 26: GBL.dmaadr = infop; /* set dma address */
|
||||
break;
|
||||
|
||||
/* No function 27 -- Get Allocation Vector */
|
||||
|
||||
case 28: ro_dsk |= 1<<GBL.dfltdsk; /* set disk read-only */
|
||||
break;
|
||||
|
||||
case 29: return(ro_dsk); /* get read-only vector */
|
||||
/* break; */
|
||||
|
||||
case 30: tmp_sel(&temp); /* set file attributes */
|
||||
rtnval = dirscan(set_attr, infop, 2);
|
||||
break;
|
||||
|
||||
case 31: if (GBL.curdsk != GBL.dfltdsk) seldsk(GBL.dfltdsk);
|
||||
move( (GBL.parmp), infop, sizeof *(GBL.parmp) );
|
||||
break; /* return disk parameters */
|
||||
|
||||
case 32: if ( (info & 0xff) <= 15 ) /* get/set user number */
|
||||
GBL.user = (UBYTE)info;
|
||||
return(UBWORD(GBL.user));
|
||||
/* break; */
|
||||
|
||||
case 33: tmp_sel(&temp); /* random read */
|
||||
rtnval = bdosrw(infop, TRUE, 1);
|
||||
break;
|
||||
|
||||
case 34: tmp_sel(&temp); /* random write */
|
||||
rtnval = bdosrw(infop, FALSE, 1);
|
||||
break;
|
||||
|
||||
case 35: tmp_sel(&temp); /* get file size */
|
||||
getsize(infop);
|
||||
break;
|
||||
|
||||
case 36: tmp_sel(&temp); /* set random record */
|
||||
setran(infop);
|
||||
break;
|
||||
|
||||
case 37: info = ~info; /* reset drive */
|
||||
log_dsk &= info;
|
||||
ro_dsk &= info;
|
||||
crit_dsk &= info;
|
||||
break;
|
||||
|
||||
case 40: tmp_sel(&temp); /* write random with 0 fill */
|
||||
rtnval = bdosrw(infop, FALSE, 2);
|
||||
break;
|
||||
|
||||
case 46: free_sp(info); /* get disk free space */
|
||||
break;
|
||||
|
||||
case 47: GBL.chainp = GBL.dmaadr; /* chain to program */
|
||||
warmboot(0); /* terminate calling program */
|
||||
/* break; */
|
||||
|
||||
case 48: return( flushit() ); /* flush buffers */
|
||||
/* break; */
|
||||
|
||||
case 59: return(pgmld(infop,GBL.dmaadr)); /* program load */
|
||||
/* break; */
|
||||
|
||||
case 61: return(setexc(infop)); /* set exception vector */
|
||||
/* break; */
|
||||
|
||||
case 63: set_tpa(infop); /* get/set TPA limits */
|
||||
break;
|
||||
|
||||
default: return(-1); /* bad function number */
|
||||
/* break; */
|
||||
|
||||
}; /* end of switch statement */
|
||||
if (temp.reselect) infop->drvcode = temp.tempdisk;
|
||||
/* if reselected disk, restore it now */
|
||||
|
||||
return(rtnval); /* return the BDOS return value */
|
||||
} /* end _bdos */
|
||||
|
||||
|
||||
tmp_sel(temptr) /* temporarily select disk pointed to by fcb */
|
||||
REG struct tempstr *temptr;
|
||||
{
|
||||
REG struct fcb *fcbp;
|
||||
REG UBYTE tmp_dsk;
|
||||
BSETUP
|
||||
|
||||
fcbp = temptr->fptr; /* get local copy of fcb pointer */
|
||||
tmp_dsk = (temptr->tempdisk = fcbp->drvcode);
|
||||
seldsk( tmp_dsk ? tmp_dsk - 1 : GBL.dfltdsk );
|
||||
|
||||
fcbp->drvcode = GBL.user;
|
||||
temptr->reselect = TRUE;
|
||||
}
|
||||
308
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/bdos/bdosmisc.c
Normal file
308
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/bdos/bdosmisc.c
Normal file
@@ -0,0 +1,308 @@
|
||||
|
||||
/****************************************************************
|
||||
* *
|
||||
* CP/M-68K BDOS Miscellaneous Module *
|
||||
* *
|
||||
* This module contains miscellaneous loose ends for *
|
||||
* CP/M-68K. Included are: *
|
||||
* *
|
||||
* bdosinit() - BDOS initialization routine *
|
||||
* called from CCP for system init *
|
||||
* warmboot() - BDOS warm boot exit routine *
|
||||
* error() - BDOS error printing routine *
|
||||
* ro_err() - BDOS read-only file error routine *
|
||||
* setexc() - BDOS set exception vector *
|
||||
* set_tpa() - BDOS get/set TPA limits *
|
||||
* serial # and copyright notice, machine readable *
|
||||
* *
|
||||
* *
|
||||
* Configured for Alcyon C on the VAX *
|
||||
* *
|
||||
****************************************************************/
|
||||
|
||||
#include "bdosinc.h" /* Standard I/O declarations */
|
||||
|
||||
#include "bdosdef.h" /* Type and structure declarations for BDOS */
|
||||
|
||||
#include "biosdef.h" /* BIOS definitions, needed for bios wboot */
|
||||
|
||||
|
||||
/* serial # and copyright notice */
|
||||
|
||||
char *copyrt="CP/M-68K(tm), Version 1.1, Copyright (c) 1983, Digital Research";
|
||||
char *serial="XXXX-0000-654321";
|
||||
|
||||
|
||||
|
||||
/* Declare external functions */
|
||||
EXTERN conout(); /* Console Output function */
|
||||
EXTERN UBYTE conin(); /* Console Input function */
|
||||
EXTERN prt_line(); /* Print String function */
|
||||
EXTERN UWORD _bdos(); /* BDOS main routine */
|
||||
EXTERN UBYTE *traphndl(); /* assembly language trap handler */
|
||||
EXTERN initexc(); /* init the exception handler in */
|
||||
/* exceptn.s */
|
||||
EXTERN UWORD dirscan(); /* Directory scanning routine */
|
||||
EXTERN BOOLEAN set_attr(); /* Set File attributes function */
|
||||
EXTERN UWORD dir_rd(); /* Read directory sector routine */
|
||||
|
||||
/* Declare external variables */
|
||||
EXTERN UWORD log_dsk; /* logged-on disk vector */
|
||||
EXTERN UWORD ro_dsk; /* read-only disk vector */
|
||||
EXTERN UWORD crit_dsk; /* vector of critical disks */
|
||||
EXTERN BYTE *tpa_lt; /* TPA lower limit (temporary) */
|
||||
EXTERN BYTE *tpa_lp; /* TPA lower limit (permanent) */
|
||||
EXTERN BYTE *tpa_ht; /* TPA upper limit (temporary) */
|
||||
EXTERN BYTE *tpa_hp; /* TPA upper limit (permanent) */
|
||||
EXTERN BOOLEAN submit; /* external variables from CCP */
|
||||
EXTERN BOOLEAN morecmds;
|
||||
|
||||
|
||||
#define trap2v 34 /* trap 2 vector number */
|
||||
#define ctrlc 3 /* control-c */
|
||||
|
||||
|
||||
/********************************
|
||||
* bdos initialization routine *
|
||||
********************************/
|
||||
|
||||
bdosinit()
|
||||
/* Initialize the File System */
|
||||
{
|
||||
REG struct
|
||||
{
|
||||
WORD nmbr;
|
||||
BYTE *low;
|
||||
LONG length;
|
||||
} *segp;
|
||||
BSETUP
|
||||
|
||||
bsetvec(trap2v, &traphndl); /* set up trap vector */
|
||||
GBL.kbchar = 0; /* initialize the "global" variables */
|
||||
GBL.insptr = GBL.remptr = &(GBL.t_buff[0]);
|
||||
GBL.delim = '$';
|
||||
GBL.lstecho = FALSE;
|
||||
GBL.echodel = TRUE;
|
||||
GBL.chainp = NULL;
|
||||
_bdos(13); /* reset disk system function */
|
||||
segp = bgetseg(); /* get pointer to memory segment table */
|
||||
tpa_lt = tpa_lp = segp->low;
|
||||
tpa_ht = tpa_hp = tpa_lp + segp->length;
|
||||
initexc( &(GBL.excvec[0]) );
|
||||
}
|
||||
|
||||
|
||||
/************************
|
||||
* warmboot entry point *
|
||||
************************/
|
||||
|
||||
warmboot(parm)
|
||||
/* Warm Boot the system */
|
||||
WORD parm; /* 1 to reset submit flag */
|
||||
{
|
||||
BSETUP
|
||||
|
||||
log_dsk &= ~ro_dsk; /* log off any disk marked read-only */
|
||||
/* note that this code is specifically for a single-
|
||||
thread system. It won't work in a multi-task sys */
|
||||
ro_dsk = 0;
|
||||
crit_dsk = 0;
|
||||
if (parm)
|
||||
submit = morecmds = FALSE;
|
||||
GBL.curdsk = 0xff; /* set current disk to "unknown" */
|
||||
tpa_lt = tpa_lp;
|
||||
tpa_ht = tpa_hp;
|
||||
initexc( &(GBL.excvec[0]) );
|
||||
bwboot();
|
||||
}
|
||||
|
||||
|
||||
/*************************/
|
||||
/* disk error handlers */
|
||||
/*************************/
|
||||
|
||||
prt_err(p)
|
||||
/* print the error message */
|
||||
|
||||
BYTE *p;
|
||||
{
|
||||
BSETUP
|
||||
|
||||
prt_line(p);
|
||||
prt_line(" error on drive $");
|
||||
conout(GBL.curdsk + 'A');
|
||||
}
|
||||
|
||||
|
||||
abrt_err(p)
|
||||
/* print the error message and always abort */
|
||||
|
||||
BYTE *p;
|
||||
{
|
||||
prt_err(p);
|
||||
warmboot(1);
|
||||
}
|
||||
|
||||
|
||||
ext_err(cont,p)
|
||||
/* print the error message, and allow for retry, abort, or ignore */
|
||||
|
||||
REG BOOLEAN cont; /* Boolean for whether continuing is allowed */
|
||||
BYTE *p; /* pointer to error message */
|
||||
{
|
||||
REG UBYTE ch;
|
||||
|
||||
prt_err(p);
|
||||
do
|
||||
{
|
||||
prt_line("\n\rDo you want to: Abort (A), Retry (R)$");
|
||||
if (cont) prt_line(", or Continue with bad data (C)$");
|
||||
prt_line("? $");
|
||||
ch = conin() & 0x5f;
|
||||
prt_line("\r\n$");
|
||||
|
||||
switch ( ch )
|
||||
{
|
||||
case ctrlc: warmboot(1);
|
||||
case 'A': warmboot(1);
|
||||
case 'C': if (cont) return(1);
|
||||
break;
|
||||
case 'R': return(0);
|
||||
}
|
||||
} while (TRUE);
|
||||
}
|
||||
|
||||
|
||||
/********************************/
|
||||
/* Read-only File Error Routine */
|
||||
/********************************/
|
||||
|
||||
ro_err(fcbp,dirindx)
|
||||
/* File R/O error */
|
||||
|
||||
REG struct fcb *fcbp;
|
||||
WORD dirindx;
|
||||
{
|
||||
REG BYTE *p;
|
||||
REG UWORD i;
|
||||
REG UBYTE ch;
|
||||
|
||||
p = (BYTE *)fcbp;
|
||||
prt_line("CP/M Disk file error: $");
|
||||
i = 8;
|
||||
do conout(*++p & 0x7f); while (--i);
|
||||
conout('.');
|
||||
i = 3;
|
||||
do conout(*++p & 0x7f); while (--i);
|
||||
prt_line(" is read-only.$");
|
||||
do
|
||||
{
|
||||
prt_line("\r\nDo you want to: Change it to read/write (C), or Abort (A)? $");
|
||||
ch = conin() & 0x5f;
|
||||
prt_line("\r\n$");
|
||||
|
||||
switch ( ch )
|
||||
{
|
||||
case ctrlc: warmboot(1);
|
||||
case 'A': warmboot(1);
|
||||
case 'C': fcbp->ftype[robit] &= 0x7f;
|
||||
dirscan(set_attr, fcbp, 2);
|
||||
return(dir_rd(dirindx >> 2));
|
||||
} /* Reset the directory buffer !!!! */
|
||||
} while (TRUE);
|
||||
}
|
||||
|
||||
|
||||
/************************
|
||||
* error entry point *
|
||||
************************/
|
||||
|
||||
error(errnum)
|
||||
/* Print error message, do appropriate response */
|
||||
|
||||
UWORD errnum; /* error number */
|
||||
{
|
||||
BSETUP
|
||||
|
||||
prt_line("\r\nCP/M Disk $");
|
||||
switch (errnum)
|
||||
{
|
||||
case 0: return( ext_err(TRUE,"read$") );
|
||||
/* break; */
|
||||
|
||||
case 1: return( ext_err(TRUE,"write$") );
|
||||
/* break; */
|
||||
|
||||
case 2: abrt_err("select$");
|
||||
/* break; */
|
||||
|
||||
case 3: return( ext_err(FALSE,"select$") );
|
||||
/* break; */
|
||||
|
||||
case 4: abrt_err("change$");
|
||||
/* break; */
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*****************************
|
||||
* set exception entry point *
|
||||
*****************************/
|
||||
|
||||
setexc(epbp)
|
||||
/* Set Exception Vector */
|
||||
REG struct
|
||||
{
|
||||
WORD vecnum;
|
||||
BYTE *newvec;
|
||||
BYTE *oldvec;
|
||||
} *epbp;
|
||||
|
||||
{
|
||||
REG WORD i;
|
||||
BSETUP
|
||||
|
||||
i = epbp->vecnum-2;
|
||||
if ( i==32 || i==33) return(-1);
|
||||
if ( (30 <= i) && (i <= 37) ) i -= 20;
|
||||
else if ( (i < 0) || (i > 9) ) return(255);
|
||||
epbp->oldvec = GBL.excvec[i];
|
||||
GBL.excvec[i] = epbp->newvec;
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
/*****************************
|
||||
* get/set TPA entry point *
|
||||
*****************************/
|
||||
|
||||
set_tpa(p)
|
||||
/* Get/Set TPA Limits */
|
||||
REG struct
|
||||
{
|
||||
UWORD parms;
|
||||
BYTE *low;
|
||||
BYTE *high;
|
||||
} *p;
|
||||
|
||||
#define set 1
|
||||
#define sticky 2
|
||||
|
||||
{
|
||||
if (p->parms & set)
|
||||
{
|
||||
tpa_lt = p->low;
|
||||
tpa_ht = p->high;
|
||||
if (p->parms & sticky)
|
||||
{
|
||||
tpa_lp = tpa_lt;
|
||||
tpa_hp = tpa_ht;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
p->low = tpa_lt;
|
||||
p->high = tpa_ht;
|
||||
}
|
||||
}
|
||||
314
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/bdos/bdosrw.c
Normal file
314
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/bdos/bdosrw.c
Normal file
@@ -0,0 +1,314 @@
|
||||
|
||||
/****************************************************************
|
||||
* *
|
||||
* CP/M-68K BDOS Disk Read/Write Module *
|
||||
* *
|
||||
* This module contains functions to perform sequential *
|
||||
* or random access read or write to the disk for CP/M-68K *
|
||||
* *
|
||||
* It includes the following external functions: *
|
||||
* *
|
||||
* bdosrw() - sequential and random disk I/O *
|
||||
* *
|
||||
* *
|
||||
* Compiled with Alcyon C on the VAX *
|
||||
* *
|
||||
****************************************************************/
|
||||
|
||||
#include "bdosinc.h" /* Standard I/O declarations */
|
||||
|
||||
#include "bdosdef.h" /* Type and structure declarations for BDOS */
|
||||
|
||||
|
||||
/* External function definitions */
|
||||
EXTERN UWORD rdwrt(); /* disk read/write routine */
|
||||
EXTERN WORD getaloc(); /* allocate a block of disk space */
|
||||
EXTERN WORD swap(); /* assembly language byte swapper */
|
||||
EXTERN UWORD dirscan(); /* directory scanning routine */
|
||||
EXTERN BOOLEAN openfile(); /* open file function passed to dirscan */
|
||||
EXTERN UWORD close_fi(); /* close file function */
|
||||
EXTERN BOOLEAN create(); /* create file function passed to dirscan */
|
||||
EXTERN UWORD ro_err(); /* read-only file error handler */
|
||||
|
||||
/* External variable definitions */
|
||||
EXTERN UWORD ro_dsk; /* read-only disk vector */
|
||||
|
||||
|
||||
/**********************************************************/
|
||||
/* First, some utility functions used by seqio and ranio */
|
||||
/**********************************************************/
|
||||
|
||||
/******************************
|
||||
* FCB block number routines *
|
||||
******************************/
|
||||
|
||||
WORD blkindx(fcbp)
|
||||
/* return index into fcb disk map */
|
||||
|
||||
REG struct fcb *fcbp; /* pointer to fcb */
|
||||
{
|
||||
REG struct dpb *dparmp; /* pointer to disk parameter block */
|
||||
REG WORD i;
|
||||
REG WORD blkshf;
|
||||
BSETUP
|
||||
|
||||
dparmp = GBL.parmp;
|
||||
blkshf = dparmp->bsh;
|
||||
i = ((fcbp->extent) & dparmp->exm) << (7 - blkshf);
|
||||
return (i + (UBWORD(fcbp->cur_rec) >> blkshf) );
|
||||
}
|
||||
|
||||
|
||||
UWORD blknum(fcbp, index, wrdfcb)
|
||||
/* return block number in fcb indicated by index */
|
||||
|
||||
REG struct fcb *fcbp; /* pointer to fcb */
|
||||
REG WORD index; /* index into disk map of fcb */
|
||||
WORD wrdfcb; /* boolean, fcb disk map of words */
|
||||
{
|
||||
if (wrdfcb)
|
||||
return( swap(fcbp->dskmap.big[index]) );
|
||||
else return( UBWORD(fcbp->dskmap.small[index]) );
|
||||
}
|
||||
|
||||
|
||||
setblk(fcbp, index, wrdfcb, block)
|
||||
/* put block number into fcb */
|
||||
|
||||
REG struct fcb *fcbp; /* pointer to fcb */
|
||||
REG WORD index; /* index into disk map of fcb */
|
||||
WORD wrdfcb; /* boolean, fcb disk map of words */
|
||||
REG UWORD block; /* block number */
|
||||
{
|
||||
fcbp->s2 &= 0x7f; /* set file write flag */
|
||||
if (wrdfcb)
|
||||
fcbp->dskmap.big[index] = swap(block);
|
||||
else fcbp->dskmap.small[index] = (UBYTE)block;
|
||||
}
|
||||
|
||||
|
||||
/***************************
|
||||
* disk read/write routine *
|
||||
***************************/
|
||||
|
||||
UWORD do_io(block, rcrd, parm)
|
||||
|
||||
UWORD block; /* block number */
|
||||
UBYTE rcrd; /* record number */
|
||||
REG WORD parm; /* write parameter */
|
||||
{
|
||||
REG LONG lsec;
|
||||
REG struct dpb *dparmp;
|
||||
BSETUP
|
||||
|
||||
dparmp = GBL.parmp; /* init dpb pointer */
|
||||
lsec = ((LONG)block << (dparmp->bsh)) +
|
||||
(LONG)(rcrd & (dparmp->blm));
|
||||
return( rdwrt(lsec, GBL.dmaadr, parm) );
|
||||
}
|
||||
|
||||
|
||||
/*******************************************
|
||||
* routine for crossing extent boundaries *
|
||||
*******************************************/
|
||||
|
||||
WORD new_ext(fcbp, reading, ran)
|
||||
/* If sequential I/O, open the next extent */
|
||||
/* If random I/O, compute new extent from random record field */
|
||||
|
||||
REG struct fcb *fcbp; /* pointer to fcb */
|
||||
BOOLEAN reading; /* read/write flag */
|
||||
WORD ran; /* random I/O flag */
|
||||
{
|
||||
REG UBYTE mod; /* module number */
|
||||
REG UBYTE ext; /* extent number */
|
||||
REG UBYTE t_mod; /* temp mod number */
|
||||
REG UBYTE t_ext; /* temp extent */
|
||||
BSETUP
|
||||
|
||||
if (ran)
|
||||
{
|
||||
mod = ( (fcbp->ran0) << 4) | ( (fcbp->ran1) >> 4);
|
||||
ext = ( ((fcbp->ran1) & 0x0f) << 1);
|
||||
if ((fcbp->ran2) & 0x80) ext |= 1;
|
||||
/* the calculation of ext was coded this way because of a */
|
||||
/* compiler bug from Alcyon */
|
||||
}
|
||||
else
|
||||
{
|
||||
mod = (fcbp->s2) & 0x3f;
|
||||
ext = (fcbp->extent) + 1; /* for sequential, incr extent */
|
||||
}
|
||||
if (ext >= 32)
|
||||
{
|
||||
ext = 0;
|
||||
mod += 1;
|
||||
}
|
||||
if (mod >= 64) return(6); /* past maximum file size */
|
||||
if ( mod == ((fcbp->s2) & 0x3f) )
|
||||
if ( ! ((ext ^ (fcbp->extent)) & ~((GBL.parmp)->exm) & 0x1f) )
|
||||
{ /* we're in same logical extent */
|
||||
fcbp->extent = ext;
|
||||
return(0);
|
||||
}
|
||||
/* Extent or Module numbers don't match */
|
||||
/* Close the old extent and open a one */
|
||||
if ( close_fi(fcbp) >= 255 ) return(3);
|
||||
/* can't close old extent */
|
||||
t_mod = fcbp->s2;
|
||||
t_ext = fcbp->extent;
|
||||
fcbp->s2 = mod;
|
||||
fcbp->extent = ext;
|
||||
if ( dirscan(openfile, fcbp, 0) >= 255 ) /* open extent */
|
||||
{
|
||||
if (reading)
|
||||
{ /* reading unwritten extent */
|
||||
fcbp->s2 = t_mod;
|
||||
fcbp->extent = t_ext;
|
||||
return(4);
|
||||
}
|
||||
if ( dirscan(create, fcbp, 8) >= 255 )
|
||||
return(5); /* can't create new extent */
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
/************************************
|
||||
* Routine to calculate the maximum *
|
||||
* extent number of an FCB in a *
|
||||
* extent-folded environment *
|
||||
************************************/
|
||||
|
||||
UWORD calcext(fcbp)
|
||||
|
||||
REG struct fcb *fcbp;
|
||||
|
||||
{
|
||||
REG UWORD i;
|
||||
REG BYTE *p;
|
||||
BSETUP
|
||||
|
||||
i = 15;
|
||||
p = &(fcbp->dskmap.small[16]);
|
||||
do
|
||||
{
|
||||
if (*--p) break;
|
||||
i -= 1;
|
||||
} while (i);
|
||||
/* Now i contains the index of the last non-zero block in the FCB */
|
||||
if ((GBL.parmp)->dsm > 255) i >>= 1;
|
||||
i >>= 7 - ((GBL.parmp)->bsh);
|
||||
return ( (fcbp->extent) & ~((GBL.parmp)->exm) & 0x1f | i );
|
||||
}
|
||||
|
||||
|
||||
/*********************************
|
||||
* Routine to get the actual *
|
||||
* record count of the currently *
|
||||
* active logical extent of a FCB *
|
||||
*********************************/
|
||||
|
||||
UWORD get_rc(fcbp)
|
||||
|
||||
REG struct fcb *fcbp;
|
||||
|
||||
{
|
||||
REG UWORD ext;
|
||||
|
||||
ext = calcext(fcbp); /* find last active extent in fcb */
|
||||
if (ext == fcbp->extent) return(UBWORD(fcbp->rcdcnt));
|
||||
/* if this is the last active fcb, return fcb's rc */
|
||||
else if (ext > fcbp->extent) return(128);
|
||||
/* if the fcb has more extents past this one, then */
|
||||
/* the current one is logically full */
|
||||
else return (0);
|
||||
/* if we seeked past the last active extent, rc = 0 */
|
||||
}
|
||||
|
||||
|
||||
/************************
|
||||
* bdosrw entry point *
|
||||
************************/
|
||||
|
||||
UWORD bdosrw(fcbp, reading, random)
|
||||
|
||||
REG struct fcb *fcbp; /* fcbp is a pointer to a fcb */
|
||||
REG BOOLEAN reading; /* boolean to tell whether to read or write */
|
||||
WORD random; /* 0 = sequential, 1 = random (normal), */
|
||||
/* 2 = random with zero fill */
|
||||
{
|
||||
REG UWORD block; /* block number from fcb */
|
||||
REG WORD index; /* index into disk map of fcb */
|
||||
REG BYTE *old_dma; /* temp holding spot for dmaadr */
|
||||
REG WORD parm; /* parameter to do-io */
|
||||
REG WORD bigfile; /* file system is in word mode */
|
||||
REG UWORD rtn; /* return parameter */
|
||||
REG UBYTE rc; /* temp storage for rcdcnt */
|
||||
BSETUP
|
||||
|
||||
bigfile = ((GBL.parmp)->dsm) & ~0xff;
|
||||
if ( ( ! reading) && (fcbp->ftype[robit] & 0x80) )
|
||||
ro_err(fcbp,((GBL.dpbp)->dpbp)->drm);
|
||||
/* check for read-only file */
|
||||
if (random)
|
||||
{
|
||||
if ( rtn = new_ext(fcbp, reading, TRUE) ) return(rtn);
|
||||
/* open new extent if necessary, return if error */
|
||||
fcbp->cur_rec = (fcbp->ran2) & 0x7f;
|
||||
}
|
||||
else /* sequential */
|
||||
if (fcbp->cur_rec == 128)
|
||||
{ /* time to try next extent */
|
||||
if ( new_ext(fcbp, reading, FALSE) )
|
||||
return(1); /* if can't open new extent, error */
|
||||
fcbp->cur_rec = 0; /* opened new extent, zero cur_rec */
|
||||
}
|
||||
|
||||
/* record is now in active fcb */
|
||||
rc = fcbp->rcdcnt;
|
||||
if ( UBWORD(fcbp->cur_rec) >= get_rc(fcbp) )
|
||||
{
|
||||
if (reading) return(1); /* reading unwritten data */
|
||||
fcbp->s2 &= 0x7f; /* set file write flag */
|
||||
rc = fcbp->cur_rec + 1;
|
||||
}
|
||||
index = blkindx(fcbp); /* get index into fcb disk map */
|
||||
block = blknum(fcbp, index, bigfile);
|
||||
if (block) parm = (reading ? 0 : 1);
|
||||
else /* if allocated block, parm is just read or write */
|
||||
{ /* unallocated block */
|
||||
if (reading) return(1); /* reading unwritten data */
|
||||
|
||||
/* Writing to new block */
|
||||
/* The parm passed to getaloc is the previously allocated block */
|
||||
/* or 0, if the previous block is not allocated */
|
||||
|
||||
block = getaloc(blknum(fcbp, (index ? (index - 1) : 0), bigfile));
|
||||
if (block == ~0) return(2); /* out of space */
|
||||
setblk(fcbp, index, bigfile, block);
|
||||
parm = 3;
|
||||
if (random == 2)
|
||||
{ /* Write random with zero fill */
|
||||
old_dma = GBL.dmaadr;
|
||||
GBL.dmaadr = GBL.dirbufp; /* Do DMA from dir_buf */
|
||||
index = SECLEN;
|
||||
do GBL.dmaadr[--index] = 0;
|
||||
while (index); /* zero the dma buffer */
|
||||
for (index = 0; index <= ((GBL.parmp)->blm); index++)
|
||||
{
|
||||
do_io(block, (UBYTE)index, parm);
|
||||
/* write zeros to the block */
|
||||
parm = 1; /* next write is not to new block */
|
||||
}
|
||||
GBL.dmaadr = old_dma; /* restore dma address */
|
||||
}
|
||||
}
|
||||
rtn = do_io(block, fcbp->cur_rec, parm);
|
||||
if ( rtn == 0 )
|
||||
{
|
||||
fcbp->rcdcnt = rc;
|
||||
if ( ! random ) fcbp->cur_rec += 1;
|
||||
}
|
||||
return(rtn);
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
|
||||
/********************************************************
|
||||
* *
|
||||
* BIOS definitions for CP/M-68K *
|
||||
* *
|
||||
* Copyright (c) 1982 Digital Research, Inc. *
|
||||
* *
|
||||
* This include file simply defines the BIOS calls *
|
||||
* *
|
||||
********************************************************/
|
||||
|
||||
EXTERN UBYTE bios1(); /* used for character I/O functions */
|
||||
EXTERN bios2(); /* parm1 is word, no return value */
|
||||
EXTERN bios3(); /* used for set dma only */
|
||||
/* parm1 is a pointer, no return */
|
||||
EXTERN UBYTE *bios4(); /* seldsk only, parm1 and parm2 are */
|
||||
/* words, returns a pointer to dph */
|
||||
EXTERN UWORD bios5(); /* for sectran and set exception */
|
||||
EXTERN BYTE *bios6(); /* for get memory segment table */
|
||||
|
||||
|
||||
#define bwboot() bios1(1) /* warm boot */
|
||||
#define bconstat() bios1(2) /* console status */
|
||||
#define bconin() bios1(3) /* console input */
|
||||
#define bconout(parm) bios2(4,parm) /* console output parm */
|
||||
#define blstout(parm) bios2(5,parm) /* list device output */
|
||||
#define bpun(parm) bios2(6,parm) /* punch char output */
|
||||
#define brdr() bios1(7) /* reader input */
|
||||
#define bhome() bios1(8) /* recalibrate drive */
|
||||
#define bseldsk(parm1,parm2) bios4(9,parm1,parm2)
|
||||
/* select disk and return info */
|
||||
#define bsettrk(parm) bios2(10,parm) /* set track on disk */
|
||||
#define bsetsec(parm) bios2(11,parm) /* set sector for disk */
|
||||
#define bsetdma(parm) bios3(12,parm) /* set dma address */
|
||||
#define bread() bios1(13) /* read sector from disk */
|
||||
#define bwrite(parm) bios2(14,parm) /* write sector to disk */
|
||||
#define blistst() bios1(15) /* list device status */
|
||||
#define bsectrn(parm1,parm2) bios5(16,parm1,parm2)
|
||||
/* sector translate */
|
||||
#define bgetseg() bios6(18) /* get memory segment tbl */
|
||||
#define bgetiob() bios1(19) /* get I/O byte */
|
||||
#define bsetiob(parm) bios2(20,parm) /* set I/O byte */
|
||||
#define bflush() bios1(21) /* flush buffers */
|
||||
#define bsetvec(parm1,parm2) bios5(22,parm1,parm2)
|
||||
/* set exception vector */
|
||||
|
||||
1476
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/bdos/ccp.c
Normal file
1476
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/bdos/ccp.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,18 @@
|
||||
*************************************************************************
|
||||
* *
|
||||
* INTERFACE MODULE BETWEEN *
|
||||
* CCP and THE BDOS *
|
||||
* *
|
||||
* *
|
||||
* THIS IS THE DUAL PROCESSOR,ROMABLE CP/M-68K SYSTEM *
|
||||
* ================================================== *
|
||||
* *
|
||||
* (C) Copyright Digital Research 1983 all rights reserved *
|
||||
* *
|
||||
*************************************************************************
|
||||
|
||||
.globl _bdos
|
||||
_bdos: move.w 4(sp),d0
|
||||
move.l 6(sp),d1
|
||||
trap #2
|
||||
rts
|
||||
158
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/bdos/ccpdef.h
Normal file
158
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/bdos/ccpdef.h
Normal file
@@ -0,0 +1,158 @@
|
||||
/*--------------------------------------------------------------*\
|
||||
| ccp_def.c DEFINES v1.0 |
|
||||
| ======= |
|
||||
| |
|
||||
| CP/M 68k: A CP/M derived operating system |
|
||||
| |
|
||||
| File contents: |
|
||||
| ------------- |
|
||||
| This file contains all of the #defines |
|
||||
| used by the console command processor. |
|
||||
| |
|
||||
| created by : Tom Saulpaugh Date: 7/13/82 |
|
||||
| ---------- |
|
||||
| last modified: 10/29/82 |
|
||||
| ------------- |
|
||||
| |
|
||||
| (c) COPYRIGHT Digital Research 1982 |
|
||||
| all rights reserved |
|
||||
| |
|
||||
\*--------------------------------------------------------------*/
|
||||
|
||||
|
||||
/*-------------------------------------------*\
|
||||
| CP/M Transient Commands |
|
||||
\*-------------------------------------------*/
|
||||
|
||||
#define DIRCMD 0
|
||||
#define TYPECMD 1
|
||||
#define RENCMD 2
|
||||
#define ERACMD 3
|
||||
#define UCMD 4
|
||||
#define CH_DISK 5
|
||||
#define SUBCMD 6
|
||||
#define SUB_FILE 7
|
||||
#define FILE 8
|
||||
#define DIRSCMD 9
|
||||
#define SEARCH 10
|
||||
|
||||
/*-------------------------------------------*\
|
||||
| Modes and Flags |
|
||||
\*-------------------------------------------*/
|
||||
|
||||
#define ON 1
|
||||
#define OFF 0
|
||||
#define MATCH 0
|
||||
#define GOOD 1
|
||||
#define BAD 0
|
||||
#define FILL 1
|
||||
#define NOFILL 0
|
||||
#define VOID /*no return value*/
|
||||
#define NO_FILE 98
|
||||
#define STOP 99
|
||||
#define USER_ZERO 0
|
||||
#define DISK_A 1
|
||||
#define SOURCEDRIVE 88
|
||||
#define DESTDRIVE 99
|
||||
#define BYTE char
|
||||
#define REG register
|
||||
#define WORD signed short
|
||||
#define UWORD unsigned int
|
||||
#define LONG signed long
|
||||
#define ULONG unsigned long
|
||||
#define GET_MEM_REG 18
|
||||
#define ZERO 0
|
||||
#define NULL '\0'
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
#define NO_READ 255
|
||||
#define BLANK ' '
|
||||
#define BACKSLH '\\'
|
||||
#define EXLIMPT '!'
|
||||
#define CMASK 0177
|
||||
#define ONE (long)49
|
||||
#define TAB 9
|
||||
#define Cr 13
|
||||
#define Lf 10
|
||||
#define CR (long)13
|
||||
#define LF (long)10
|
||||
#define EOF 26
|
||||
#define BLANKS (long)32
|
||||
#define PERIOD (long)46
|
||||
#define COLON (long)58
|
||||
#define ARROW (long)62
|
||||
|
||||
/*-------------------------------------------*\
|
||||
| Data Structure Size Constants |
|
||||
\*-------------------------------------------*/
|
||||
|
||||
#define CMD_LEN 128
|
||||
#define BIG_CMD_LEN 255
|
||||
#define MAX_ARGS 4
|
||||
#define ARG_LEN 26
|
||||
#define NO_OF_DRIVES 16
|
||||
#define NUMDELS 16
|
||||
#define FCB_LEN 36
|
||||
#define DMA_LEN 128
|
||||
#define FILES_PER_LINE 5
|
||||
#define SCR_HEIGHT 23
|
||||
#define BIG_WIDTH 80
|
||||
#define SMALL_WIDTH 40
|
||||
|
||||
/*-------------------------------------------*\
|
||||
| BDOS Function Calls |
|
||||
\*-------------------------------------------*/
|
||||
|
||||
#define WARMBOOT 0
|
||||
#define CONIN 1
|
||||
#define CONSOLE_OUTPUT 2
|
||||
#define READER_INPUT 3
|
||||
#define PUNCH_OUTPUT 4
|
||||
#define LIST_OUTPUT 5
|
||||
#define DIR_CONS_I/O 6
|
||||
#define GET_I/O_BYTE 7
|
||||
#define SET_I/O_BYTE 8
|
||||
#define PRINT_STRING 9
|
||||
#define READ_CONS_BUF 10
|
||||
#define GET_CONS_STAT 11
|
||||
#define RET_VERSION_NO 12
|
||||
#define RESET_DISK_SYS 13
|
||||
#define SELECT_DISK 14
|
||||
#define OPEN_FILE 15
|
||||
#define CLOSE_FILE 16
|
||||
#define SEARCH_FIRST 17
|
||||
#define SEARCH_NEXT 18
|
||||
#define DELETE_FILE 19
|
||||
#define READ_SEQ 20
|
||||
#define WRITE_SEQ 21
|
||||
#define MAKE_FILE 22
|
||||
#define RENAME_FILE 23
|
||||
#define RET_LOGIN_VEC 24
|
||||
#define RET_CUR_DISK 25
|
||||
#define SET_DMA_ADDR 26
|
||||
#define GET_ADDR(ALLOC) 27
|
||||
#define WRITE_PROT_DISK 28
|
||||
#define GET_READ/O_VEC 29
|
||||
#define SET_FILE_ATTRIB 30
|
||||
#define GET_ADDR_D_PARM 31
|
||||
#define GET_USER_NO 32
|
||||
#define READ_RANDOM 33
|
||||
#define WRITE_RANDOM 34
|
||||
#define COMP_FILE-SIZE 35
|
||||
#define SET_RANDOM_REC 36
|
||||
#define RESET_DRIVE 37
|
||||
#define WRITE_RAN_ZERO 40
|
||||
#define BIOS_CALL 50
|
||||
#define LOAD_PROGRAM 59
|
||||
|
||||
/*----------------------------------------------*\
|
||||
| MACROS |
|
||||
\*----------------------------------------------*/
|
||||
|
||||
#define isalpha(c) (islower(c) || isupper(c))
|
||||
#define islower(c) ('a' <= (c) && (c) <= 'z')
|
||||
#define isupper(c) ('A' <= (c) && (c) <= 'Z')
|
||||
#define tolower(c) (isupper(c) ? ((c)+040):(c))
|
||||
#define toupper(c) (islower(c) ? ((c)-040):(c))
|
||||
#define isdigit(c) ('0' <= (c) && (c) <= '9')
|
||||
|
||||
113
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/bdos/ccpif.s
Normal file
113
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/bdos/ccpif.s
Normal file
@@ -0,0 +1,113 @@
|
||||
*************************************************************************
|
||||
* *
|
||||
* CPM68K INTERFACE MODULE FOR *
|
||||
* THE CONSOLE COMMAND PROCESSOR *
|
||||
* *
|
||||
* THIS IS THE DUAL-PROCESSOR,ROMABLE CP/M-68K SYSTEM *
|
||||
* ================================================== *
|
||||
* *
|
||||
* (C) Copyright Digital Research 1983 all rights reserved *
|
||||
* *
|
||||
*************************************************************************
|
||||
|
||||
|
||||
.globl _bios1
|
||||
.globl _bdos
|
||||
.globl _load68k
|
||||
.globl _load_tbl
|
||||
.globl init_tbl
|
||||
.globl _load_try
|
||||
.globl _autorom
|
||||
.globl flags
|
||||
.globl TPAB
|
||||
.globl stack
|
||||
.globl _bdosini
|
||||
.globl _main
|
||||
.globl _submit
|
||||
.globl _morecmds
|
||||
.globl _autost
|
||||
.globl _usercmd
|
||||
.globl _init
|
||||
.globl _ccp
|
||||
.globl _patch
|
||||
.globl cpm
|
||||
|
||||
.text
|
||||
cpm:
|
||||
jmp.l ccpstart * start ccp with possible initial command
|
||||
jmp.l ccpclear * clear auto start flag
|
||||
|
||||
|
||||
|
||||
.bss
|
||||
_autost: .ds.b 1 * autostart command flag
|
||||
_usercmd: .ds.b 130 * user command buffer
|
||||
|
||||
.text
|
||||
copy: .dc.b 'COPYRIGHT (C) 1982, Digital Research '
|
||||
|
||||
|
||||
.text
|
||||
ccpclear:
|
||||
clr.b _autost * clear the autostart flag
|
||||
|
||||
ccpstart:
|
||||
lea stack,sp * set up the stack pointer
|
||||
clr.b _autost * clear the auto start flag
|
||||
jsr _init * call bios init
|
||||
move.w d0,dskuser * save user # & disk
|
||||
*
|
||||
*
|
||||
* ROM SYSTEM INITIALIZATION
|
||||
* OF BSS VARIABLES
|
||||
*
|
||||
*
|
||||
|
||||
clr.b _load_try
|
||||
clr.b _submit
|
||||
clr.b _morecmds
|
||||
move.b #$1,_autorom
|
||||
clr.w flags
|
||||
clr.w TPAB
|
||||
jsr init_tbl
|
||||
|
||||
|
||||
|
||||
jsr _bdosini * do bdos init
|
||||
move.w #32,d0 * get user bdos func #
|
||||
clr.l d1 * clear out d1
|
||||
move.b dskuser,d1 * get the user #
|
||||
trap #2 * set the user number
|
||||
clr.l d0 * clear d0
|
||||
move.w #14,d0 * select function
|
||||
clr.l d1 * clear d1
|
||||
move.w dskuser,d1 * get disk to be selected
|
||||
andi #$0ff,d1 * mask off the user #
|
||||
trap #2 * select the disk
|
||||
|
||||
_ccp:
|
||||
lea stack,sp * set up the stack pointer
|
||||
jsr _main * call the CCP
|
||||
bra _ccp
|
||||
|
||||
.bss
|
||||
.even
|
||||
|
||||
dskuser: .ds.w 1
|
||||
.even
|
||||
_submit: .ds.b 1
|
||||
.even
|
||||
_morecmds: .ds.b 1
|
||||
.even
|
||||
_patch .ds.l 25
|
||||
.end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
188
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/bdos/ccpload.s
Normal file
188
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/bdos/ccpload.s
Normal file
@@ -0,0 +1,188 @@
|
||||
*****************************************************************
|
||||
* *
|
||||
* COMMAND FILE LOADER FOR CPM68K *
|
||||
* ============================== *
|
||||
* *
|
||||
* (c) COPYRIGHT Digital Research 1983 *
|
||||
* all rights reserved *
|
||||
* *
|
||||
* THIS IS THE DUAL PROCESSOR,ROMABLE CP/M-68K SYSTEM *
|
||||
* ================================================== *
|
||||
* *
|
||||
* Description: *
|
||||
* ----------- The command file loader is envoked by *
|
||||
* the CCP after the CCP has successfully *
|
||||
* opened that file. The loader must *
|
||||
* call the BDOS to obtain the boundries *
|
||||
* of the TPA. The load parameter block *
|
||||
* defined in this loader holds all the *
|
||||
* memory size and location details. *
|
||||
* Next the loader returns the system to *
|
||||
* its original user #. The CCP might *
|
||||
* have switched to user zero during its *
|
||||
* search for the file. Next the default *
|
||||
* dma address is set for the loaded *
|
||||
* program. Next the command tail is *
|
||||
* placed,along with the first two parsed *
|
||||
* fcb's,into the user basepage. *
|
||||
* Lastly the user stack pointer is set up *
|
||||
* and the return address is put on the *
|
||||
* user stack. An RTE transferes control. *
|
||||
* If a load was not successfull, the *
|
||||
* appropriate error message is printed. *
|
||||
* *
|
||||
* Created by: Tom Saulpaugh *
|
||||
* *
|
||||
* Last Modified: 3/02/83 *
|
||||
* *
|
||||
*****************************************************************
|
||||
|
||||
|
||||
|
||||
.globl _load68k * make this procedure public
|
||||
.globl _user * global user # before load occured
|
||||
.globl _cmdfcb * parsed fcb
|
||||
.globl _tail * global pointer to command tail
|
||||
.globl _fill_fcb * procedure to fill fcb's
|
||||
.globl flags * ROM SYSTEM INITIALIZATION
|
||||
.globl TPAB * ROM SYSTEM INITIALIZATION
|
||||
|
||||
|
||||
reboot = 0
|
||||
printstr = 9
|
||||
setdma = 26
|
||||
chuser = 32
|
||||
pgmldf = 59
|
||||
gettpa = 63
|
||||
|
||||
_load68k:
|
||||
*
|
||||
* Load the 68k file into the TPA
|
||||
* ------------------------------
|
||||
*
|
||||
.text
|
||||
|
||||
move.l #TPAB,d1 * move in address of tpa parameter block
|
||||
move.w #gettpa,d0 * get function number
|
||||
trap #2 * get the tpa limits
|
||||
move.l low,lowadr * put it in the lpb
|
||||
move.l high,hiadr * put high tpa addr in lpb
|
||||
move.l #_cmdfcb,LPB * get address of opened fcb
|
||||
move.l #pgmldf,d0 * move in bdos function no
|
||||
move.l #LPB,d1 * d1 points to load block
|
||||
trap #2 * do the program load
|
||||
tst d0 * was the load successful?
|
||||
bne lderr * if not print error message and return
|
||||
*
|
||||
* return to original user #
|
||||
* -------------------------
|
||||
move.w _user,d1 * put user # to switch to in d1
|
||||
move.l #chuser,d0 * put bdos func # in d0
|
||||
trap #2 * do the user # change
|
||||
*
|
||||
* set the default dma address
|
||||
* ---------------------------
|
||||
clr.l d1 * clear d1 register
|
||||
move.l baspag,d1 * d1 points to user base page
|
||||
add #$80,d1 * d1 points to default dma in base page
|
||||
movea.l d1,a1 * save it for later use
|
||||
move #setdma,d0 * move in bdos function no
|
||||
trap #2 * set the default dma address
|
||||
*
|
||||
* move in the command tail
|
||||
* ------------------------
|
||||
move.l a1,a2 * save a pointer to the count field
|
||||
add.l #$01,a1 * point past count field
|
||||
move.l _tail,a0 * point to command tail
|
||||
clr.l d0 * clear out d0
|
||||
mvtail: cmpi.b #$00,(a0) * check for a NULL ending byte
|
||||
beq done * NULL byte terminates command
|
||||
cmpi.b #$21,(a0) * check for an '!'
|
||||
beq done * '!' ends the command
|
||||
move.b (a0)+,(a1)+ * move a byte of the command tail
|
||||
addq #1,d0 * bump up the character count
|
||||
bra mvtail * continue byte move
|
||||
done: move.b d0,(a2) * put in the character count
|
||||
move.b #$00,(a1) * terminate cmd tail with a NULL byte
|
||||
*
|
||||
* fill fcb1 & fcb2
|
||||
* ----------------
|
||||
move.l #_cmdfcb,-(sp) * put address of fcb buffer onto stack
|
||||
move.w #1,-(sp) * put 1 on stack(parm1)
|
||||
jsr _fill_fcb * jump to 'C' code & fill cmdfcb with parm1
|
||||
add.l #6,sp * clean off the stack
|
||||
clr.l d0 * clear register d0
|
||||
moveq #$5c,d0 * put basepage address of fcb1 in d0
|
||||
bsr movfcb * put fcb1 in the basepage
|
||||
move.l #_cmdfcb,-(sp) * put address of fcb buffer onto stack
|
||||
move.w #2,-(sp) * put 2 on stack(parm2)
|
||||
jsr _fill_fcb * jump to 'C' code & fill cmdfcb with parm2
|
||||
add.l #6,sp * clean off the stack
|
||||
clr.l d0 * clear register d0
|
||||
moveq #$38,d0 * put basepage address of fcb1 in d0
|
||||
bsr movfcb * put fcb2 in the basepage
|
||||
*
|
||||
* now push rte stuff on stack
|
||||
* ---------------------------
|
||||
movea.l usrstk,a0 * get user stack pointer
|
||||
move.l baspag,a1 * get basepage address
|
||||
move.l 8(a1),-(sp) * push address we want to jump to
|
||||
move sr,d0 * get the status register in d0
|
||||
andi #$5f00,d0 * mask trace,system bits,user flags
|
||||
move.w d0,-(sp) * push it on stack
|
||||
move.l a1,-(a0) * push addr of basepage onto user stack
|
||||
move.l #cmdrtn,-(a0) * push return address onto user stack
|
||||
move.l a0,usp * set up user stack pointer
|
||||
rte
|
||||
*
|
||||
* load error
|
||||
* ----------
|
||||
lderr:
|
||||
rts * return with error code in d0
|
||||
cmdrtn:
|
||||
move #reboot,d0 * reboot CPM
|
||||
trap #2
|
||||
movfcb:
|
||||
add.l baspag,d0 * get offset into basepage
|
||||
move.l d0,a0 * move address into a0
|
||||
move.l #_cmdfcb,a1 * a1 points to fcb to be moved
|
||||
clr.l d0 * clear register d0
|
||||
moveq #35,d0 * get length of fcb
|
||||
mov1:
|
||||
move.b (a1)+,(a0)+ * move a byte into the basepage
|
||||
dbf d0,mov1 * if not done branch to mov1
|
||||
rts
|
||||
|
||||
|
||||
.bss
|
||||
|
||||
.even
|
||||
*
|
||||
* LOAD PARAMETER BLOCK
|
||||
*
|
||||
LPB: .ds.l 1
|
||||
lowadr: .ds.l 1
|
||||
hiadr: .ds.l 1
|
||||
baspag: .ds.l 1
|
||||
usrstk: .ds.l 1
|
||||
flags: .ds.w 1
|
||||
|
||||
*
|
||||
* TPA Parameter Block
|
||||
*
|
||||
.even
|
||||
TPAB: .ds.w 1
|
||||
low: .ds.l 1
|
||||
high: .ds.l 1
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
.end
|
||||
346
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/bdos/conbdos.c
Normal file
346
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/bdos/conbdos.c
Normal file
@@ -0,0 +1,346 @@
|
||||
|
||||
/********************************************************
|
||||
* *
|
||||
* CP/M-68K BDOS Character I/O Routines *
|
||||
* *
|
||||
* This module does BDOS functions 1 thru 11 *
|
||||
* *
|
||||
* It contains the following functions which *
|
||||
* are called from the BDOS main routine: *
|
||||
* constat(); *
|
||||
* conin(); *
|
||||
* tabout(); *
|
||||
* rawconio(); *
|
||||
* prt_line(); *
|
||||
* readline(); *
|
||||
* *
|
||||
* Copyright (c) 1982 Digital Research, Inc. *
|
||||
* *
|
||||
********************************************************/
|
||||
|
||||
#include "bdosinc.h"
|
||||
|
||||
#include "bdosdef.h"
|
||||
|
||||
#include "biosdef.h"
|
||||
|
||||
|
||||
#define ctrlc 0x03
|
||||
#define ctrle 0x05
|
||||
#define ctrlp 0x10
|
||||
#define ctrlq 0x11
|
||||
#define ctrlr 0x12
|
||||
#define ctrls 0x13
|
||||
#define ctrlu 0x15
|
||||
#define ctrlx 0x18
|
||||
|
||||
#define cr 0x0d
|
||||
#define lf 0x0a
|
||||
#define tab 0x09
|
||||
#define rub 0x7f
|
||||
#define bs 0x08
|
||||
#define space 0x20
|
||||
|
||||
|
||||
EXTERN warmboot(); /* External function definition */
|
||||
|
||||
|
||||
/******************/
|
||||
/* console status */
|
||||
/******************/
|
||||
|
||||
BOOLEAN constat()
|
||||
{
|
||||
BSETUP
|
||||
|
||||
return( GBL.kbchar ? TRUE : bconstat() );
|
||||
}
|
||||
|
||||
/********************/
|
||||
/* check for ctrl/s */
|
||||
/* used internally */
|
||||
/********************/
|
||||
conbrk()
|
||||
{
|
||||
REG UBYTE ch;
|
||||
REG BOOLEAN stop;
|
||||
BSETUP
|
||||
|
||||
stop = FALSE;
|
||||
if ( bconstat() ) do
|
||||
{
|
||||
if ( (ch = bconin()) == ctrlc ) warmboot(1);
|
||||
if ( ch == ctrls ) stop = TRUE;
|
||||
else if (ch == ctrlq) stop = FALSE;
|
||||
else if (ch == ctrlp) GBL.lstecho = !GBL.lstecho;
|
||||
else /* Insert character in ring buffer */
|
||||
{ /* */
|
||||
if(GBL.kbchar < TBUFSIZ) /* Room? */
|
||||
{ /************************************/
|
||||
*GBL.insptr++ = ch; /* Yes, insert the character in buff*/
|
||||
GBL.kbchar++; /* Up count */
|
||||
} /************************************/
|
||||
} /* Note if no room, character is */
|
||||
/* Ignomiously discarded (!) */
|
||||
/************************************/
|
||||
} while (stop);
|
||||
}
|
||||
|
||||
|
||||
/******************/
|
||||
/* console output */
|
||||
/* used internally*/
|
||||
/******************/
|
||||
|
||||
conout(ch)
|
||||
REG UBYTE ch;
|
||||
{
|
||||
BSETUP
|
||||
|
||||
conbrk(); /* check for control-s break */
|
||||
bconout(ch); /* output character to console */
|
||||
if (GBL.lstecho) blstout(ch); /* if ctrl-p on, echo to list dev */
|
||||
if (ch >= ' ') GBL.column++; /* keep track of screen column */
|
||||
else if (ch == cr) GBL.column = 0;
|
||||
else if (ch == bs) GBL.column--;
|
||||
}
|
||||
|
||||
|
||||
/*************************************/
|
||||
/* console output with tab expansion */
|
||||
/*************************************/
|
||||
|
||||
tabout(ch)
|
||||
REG UBYTE ch; /* character to output to console */
|
||||
{
|
||||
BSETUP
|
||||
|
||||
if (ch == tab) do
|
||||
conout(' ');
|
||||
while (GBL.column & 7);
|
||||
else conout(ch);
|
||||
}
|
||||
|
||||
/*******************************/
|
||||
/* console output with tab and */
|
||||
/* control character expansion */
|
||||
/*******************************/
|
||||
|
||||
cookdout(ch)
|
||||
REG UBYTE ch; /* character to output to console */
|
||||
{
|
||||
if (ch == tab) tabout(ch); /* if tab, expand it */
|
||||
else
|
||||
{
|
||||
if ( (UWORD)ch < (UWORD)' ' )
|
||||
{
|
||||
conout( '^' );
|
||||
ch |= 0x40;
|
||||
}
|
||||
conout(ch); /* output the character */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*****************/
|
||||
/* console input */
|
||||
/*****************/
|
||||
|
||||
UBYTE getch() /* Get char from buffer or bios */
|
||||
/* For internal use only */
|
||||
{
|
||||
REG UBYTE temp;
|
||||
BSETUP
|
||||
|
||||
if(GBL.kbchar)
|
||||
{
|
||||
temp = *GBL.remptr++; /* Fetch the character */
|
||||
GBL.kbchar--; /* Decrement the count */
|
||||
if(!GBL.kbchar) /* Gone to zero? */
|
||||
GBL.remptr = GBL.insptr = &(GBL.t_buff[0]);
|
||||
return(temp);
|
||||
}
|
||||
return( bconin() ); /* else get char from bios */
|
||||
}
|
||||
|
||||
UBYTE conin() /* BDOS console input function */
|
||||
{
|
||||
REG UBYTE ch;
|
||||
BSETUP
|
||||
|
||||
conout( ch = getch() );
|
||||
if (ch == ctrlp) GBL.lstecho = !GBL.lstecho;
|
||||
return(ch);
|
||||
}
|
||||
|
||||
/******************
|
||||
* raw console i/o *
|
||||
******************/
|
||||
|
||||
UBYTE rawconio(parm) /* BDOS raw console I/O function */
|
||||
|
||||
REG UWORD parm;
|
||||
{
|
||||
BSETUP
|
||||
|
||||
if (parm == 0xff) return(getch());
|
||||
else if (parm == 0xfe) return(constat());
|
||||
else bconout(parm & 0xff);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************/
|
||||
/* print line up to delimiter($) with tab expansion */
|
||||
/****************************************************/
|
||||
|
||||
prt_line(p)
|
||||
REG UBYTE *p;
|
||||
{
|
||||
BSETUP
|
||||
|
||||
while( *p != GBL.delim ) tabout( *p++ );
|
||||
}
|
||||
|
||||
|
||||
/**********************************************/
|
||||
/* read line with editing and bounds checking */
|
||||
/**********************************************/
|
||||
|
||||
/* Two subroutines first */
|
||||
|
||||
newline(startcol)
|
||||
REG UWORD startcol;
|
||||
{
|
||||
BSETUP
|
||||
|
||||
conout(cr); /* go to new line */
|
||||
conout(lf);
|
||||
while(startcol)
|
||||
{
|
||||
conout(' ');
|
||||
startcol -= 1; /* start output at starting column */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
backsp(bufp, col)
|
||||
/* backspace one character position */
|
||||
REG struct conbuf *bufp; /* pointer to console buffer */
|
||||
REG WORD col; /* starting console column */
|
||||
{
|
||||
REG UBYTE ch; /* current character */
|
||||
REG WORD i;
|
||||
REG UBYTE *p; /* character pointer */
|
||||
BSETUP
|
||||
|
||||
if (bufp->retlen) --(bufp->retlen);
|
||||
/* if buffer non-empty, decrease it by 1 */
|
||||
i = UBWORD(bufp->retlen); /* get new character count */
|
||||
p = &(bufp->cbuf[0]); /* point to character buffer */
|
||||
while (i--) /* calculate column position */
|
||||
{ /* across entire char buffer */
|
||||
ch = *p++; /* get next char */
|
||||
if ( ch == tab )
|
||||
{
|
||||
col += 8;
|
||||
col &= ~7; /* for tab, go to multiple of 8 */
|
||||
}
|
||||
else if ( (UWORD)ch < (UWORD)' ' ) col += 2;
|
||||
/* control chars put out 2 printable chars */
|
||||
else col += 1;
|
||||
}
|
||||
while (GBL.column > col)
|
||||
{
|
||||
conout(bs); /* backspace until we get to proper column */
|
||||
conout(' ');
|
||||
conout(bs);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
readline(p) /* BDOS function 10 */
|
||||
REG struct conbuf *p;
|
||||
|
||||
{
|
||||
REG UBYTE ch;
|
||||
REG UWORD i;
|
||||
REG UWORD j;
|
||||
REG UBYTE *q;
|
||||
UWORD stcol;
|
||||
|
||||
BSETUP
|
||||
|
||||
stcol = GBL.column; /* set up starting column */
|
||||
if (GBL.chainp != NULL) /* chain to program code */
|
||||
{
|
||||
i = UBWORD(*(GBL.chainp++));
|
||||
j = UBWORD(p->maxlen);
|
||||
if (j < i) i = j; /* don't overflow console buffer! */
|
||||
p->retlen = (UBYTE)i;
|
||||
q = p->cbuf;
|
||||
while (i)
|
||||
{
|
||||
cookdout( *q++ = *(GBL.chainp++) );
|
||||
i -= 1;
|
||||
}
|
||||
GBL.chainp = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
p->retlen = 0; /* start out with empty buffer */
|
||||
while ( UBWORD(p->retlen) < UBWORD(p->maxlen) )
|
||||
{ /* main loop for read console buffer */
|
||||
|
||||
if ( ((ch=getch()) == ctrlc) && !(p->retlen) )
|
||||
{
|
||||
cookdout(ctrlc);
|
||||
warmboot(1);
|
||||
}
|
||||
|
||||
else if ( (ch == cr) || (ch == lf) )
|
||||
{ /* if cr or lf, exit */
|
||||
conout(cr);
|
||||
break;
|
||||
}
|
||||
|
||||
else if (ch == bs) backsp(p, stcol); /* backspace */
|
||||
|
||||
else if (ch == rub) /* delete character */
|
||||
{
|
||||
if (GBL.echodel)
|
||||
{
|
||||
if (p->retlen)
|
||||
{
|
||||
i = UBWORD(--(p->retlen));
|
||||
conout( p->cbuf[i] );
|
||||
}
|
||||
}
|
||||
else backsp(p, stcol);
|
||||
}
|
||||
|
||||
else if (ch == ctrlp) GBL.lstecho = !GBL.lstecho;
|
||||
/* control-p */
|
||||
else if (ch == ctrlx) /* control-x */
|
||||
do backsp(p,stcol); while (p->retlen);
|
||||
|
||||
else if (ch == ctrle) newline(stcol); /* control-e */
|
||||
|
||||
else if (ch == ctrlu) /* control-u */
|
||||
{
|
||||
conout('#');
|
||||
newline(stcol);
|
||||
p->retlen = 0;
|
||||
}
|
||||
|
||||
else if (ch == ctrlr) /* control-r */
|
||||
{
|
||||
conout('#');
|
||||
newline(stcol);
|
||||
for (i=0; i < UBWORD(p->retlen); i++)
|
||||
cookdout( p->cbuf[i] );
|
||||
}
|
||||
|
||||
else /* normal character */
|
||||
cookdout( p->cbuf[UBWORD((p->retlen)++)] = ch );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
|
||||
The following is a list of the modules that form the BDOS for the
|
||||
C language version of CP/M-68K:
|
||||
|
||||
SOURCE FILES
|
||||
|
||||
bdosif.s - assembly language interface, trap handler,
|
||||
BIOS caller, function 62 (set supervisor)
|
||||
|
||||
conbdos.c - BDOS functions 1 thru 11 (console functions)
|
||||
|
||||
bdosmisc.c - BDOS initialization, warmboot, error handler, set exception,
|
||||
(used for miscellaneous BDOS routines)
|
||||
|
||||
dskutil.c - bit map handlers, directory read & write, dirscan
|
||||
(miscellaneous disk handling utilities)
|
||||
|
||||
fileio.c - all file handling calls except read & write
|
||||
includes open, close, delete, rename, etc.
|
||||
|
||||
bdosrw.c - sequential and random read & write
|
||||
|
||||
bdosmain.c - the BDOS case statement, global variable declarations
|
||||
|
||||
iosys.c - packet I/O to BIOS interface
|
||||
|
||||
pgmld.s - program load (function 59)
|
||||
|
||||
exceptn.s - exception handler
|
||||
|
||||
|
||||
INCLUDE FILES
|
||||
|
||||
bdosinc.h - standard i/o stuff, universal declarations
|
||||
|
||||
bdosdef.h - BDOS data structure declarations
|
||||
|
||||
biosdef.h - procedure declarations to interface to BIOS
|
||||
|
||||
pktio.h - definition of data structure for packet I/O
|
||||
|
||||
BIN
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/bdos/cpmlib
Normal file
BIN
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/bdos/cpmlib
Normal file
Binary file not shown.
@@ -0,0 +1,31 @@
|
||||
e:vax BDOSDEF.H r
|
||||
e:vax BDOSIF.S r
|
||||
e:vax BDOSINC.H r
|
||||
e:vax BDOSMAIN.C r
|
||||
e:vax BDOSMISC.C r
|
||||
e:vax BDOSRW.C r
|
||||
e:vax BIOSDEF.H r
|
||||
e:vax CCP.C r
|
||||
e:vax CCPBDOS.S r
|
||||
e:vax CCPDEF.H r
|
||||
e:vax CCPIF.S r
|
||||
e:vax CCPLOAD.S r
|
||||
e:vax CONBDOS.C r
|
||||
e:vax CPMC.DOC r
|
||||
e:vax CPMLIB. r
|
||||
e:vax DOWN.SUB r
|
||||
e:vax DOWN2.SUB r
|
||||
e:vax DSKUTIL.C r
|
||||
e:vax EXCEPTN.S r
|
||||
e:vax FILEIO.C r
|
||||
e:vax FILETYPS.S r
|
||||
e:vax IOSYS.C r
|
||||
e:vax MAKE.SUB r
|
||||
e:vax PGMLD.S r
|
||||
e:vax PKTIO.H r
|
||||
e:vax REAR.SUB r
|
||||
e:vax SEND2.SUB r
|
||||
e:vax STACK.S r
|
||||
e:vax UP2.SUB r
|
||||
e:vax VMAKE.COM r
|
||||
e:vax VSEND.COM r
|
||||
@@ -0,0 +1,36 @@
|
||||
|
||||
Directory _DRB0:[STEVE.CPM68K.V102.BDOS]
|
||||
|
||||
BDOSDEF.H;3
|
||||
BDOSIF.S;1
|
||||
BDOSINC.H;1
|
||||
BDOSMAIN.C;1
|
||||
BDOSMISC.C;2
|
||||
BDOSRW.C;1
|
||||
BIOSDEF.H;1
|
||||
CCP.C;2
|
||||
CCPBDOS.S;1
|
||||
CCPDEF.H;1
|
||||
CCPIF.S;1
|
||||
CCPLOAD.S;1
|
||||
CONBDOS.C;3
|
||||
CPMC.DOC;1
|
||||
CPMLIB.;1
|
||||
DOWN.SUB;1
|
||||
DOWN2.SUB;2
|
||||
DSKUTIL.C;1
|
||||
EXCEPTN.S;1
|
||||
FILEIO.C;1
|
||||
FILETYPS.S;1
|
||||
IOSYS.C;1
|
||||
MAKE.SUB;5
|
||||
PGMLD.S;1
|
||||
PKTIO.H;1
|
||||
REAR.SUB;4
|
||||
SEND2.SUB;1
|
||||
STACK.S;1
|
||||
UP2.SUB;1
|
||||
VMAKE.COM;3
|
||||
VSEND.COM;3
|
||||
|
||||
Total of 31 files.
|
||||
@@ -0,0 +1,26 @@
|
||||
vax REAR.SUB r
|
||||
vax MAKE.SUB r
|
||||
vax BDOSDEF.H r
|
||||
vax BDOSIF.S r
|
||||
vax BDOSINC.H r
|
||||
vax BDOSMAIN.C r
|
||||
vax BDOSMISC.C r
|
||||
vax BDOSRW.C r
|
||||
vax BIOSDEF.H r
|
||||
vax CONBDOS.C r
|
||||
vax CPMC.DOC r
|
||||
vax DSKUTIL.C r
|
||||
vax EXCEPTN.S r
|
||||
vax FILEIO.C r
|
||||
vax IOSYS.C r
|
||||
vax PGMLD.S r
|
||||
vax PKTIO.H r
|
||||
vax CCP.C r
|
||||
vax CCPBDOS.S r
|
||||
vax CCPDEF.H r
|
||||
vax CCPIF.S r
|
||||
vax CCPLOAD.S r
|
||||
vax FILETYPS.S r
|
||||
vax STACK.S r
|
||||
vax SEND2.SUB r
|
||||
vax up2.sub r
|
||||
297
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/bdos/dskutil.c
Normal file
297
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/bdos/dskutil.c
Normal file
@@ -0,0 +1,297 @@
|
||||
|
||||
/****************************************************************
|
||||
* *
|
||||
* CP/M-68K BDOS Disk Utilities Module *
|
||||
* *
|
||||
* This module contains the miscellaneous utilities *
|
||||
* for manipulating the disk in CP/M-68K. Included are: *
|
||||
* *
|
||||
* dirscan() - general purpose dir scanning *
|
||||
* setaloc() - set bit in allocation vector *
|
||||
* clraloc() - clear bit in allocation vector *
|
||||
* getaloc() - get free allocation block *
|
||||
* dchksum() - directory checksum calculator *
|
||||
* dir_rd() - read directory sector *
|
||||
* dir_wr() - write directory sector *
|
||||
* rdwrt() - read/write disk sector *
|
||||
* *
|
||||
* *
|
||||
* Configured for Alcyon C on the VAX *
|
||||
* *
|
||||
****************************************************************/
|
||||
|
||||
#include "bdosinc.h" /* Standard I/O declarations */
|
||||
|
||||
#include "bdosdef.h" /* Type and structure declarations for BDOS */
|
||||
|
||||
#include "pktio.h" /* Packet I/O definitions */
|
||||
|
||||
|
||||
/* declare external functions and variables */
|
||||
EXTERN UWORD do_phio(); /* external physical disk I/O routine */
|
||||
EXTERN UWORD error(); /* external error routine */
|
||||
|
||||
EXTERN UWORD log_dsk; /* logged-on disk vector */
|
||||
EXTERN UWORD ro_dsk; /* read-only disk vector */
|
||||
EXTERN UWORD crit_dsk; /* critical disk vector */
|
||||
|
||||
|
||||
/**********************
|
||||
* read/write routine *
|
||||
**********************/
|
||||
|
||||
UWORD rdwrt(secnum, dma, parm)
|
||||
/* General disk sector read/write routine */
|
||||
/* It simply sets up a I/O packet and sends it to do_phio */
|
||||
|
||||
LONG secnum; /* logical sector number to read/write */
|
||||
UBYTE *dma; /* dma address */
|
||||
REG WORD parm; /* 0 for read, write parm + 1 for write */
|
||||
|
||||
{
|
||||
struct iopb rwpkt;
|
||||
BSETUP
|
||||
|
||||
rwpkt.devnum = GBL.curdsk; /* disk to read/write */
|
||||
if (parm)
|
||||
{
|
||||
rwpkt.iofcn = (BYTE)write; /* if parm non-zero, we're doing a write */
|
||||
rwpkt.ioflags = (BYTE)(parm-1); /* pass write parm */
|
||||
if ( ro_dsk & (1 << (rwpkt.devnum)) ) error(4);
|
||||
/* don't write on read-only disk */
|
||||
}
|
||||
else
|
||||
{
|
||||
rwpkt.iofcn = (BYTE)read;
|
||||
rwpkt.ioflags = (BYTE)0;
|
||||
}
|
||||
rwpkt.devadr = secnum; /* sector number */
|
||||
rwpkt.xferadr = dma; /* dma address */
|
||||
|
||||
/* parameters that are currently not used by do_phio
|
||||
rwpkt.devtype = disk;
|
||||
rwpkt.xferlen = 1;
|
||||
*/
|
||||
rwpkt.infop = GBL.dphp; /* pass ptr to dph */
|
||||
while ( do_phio(&rwpkt) )
|
||||
if ( error( parm ? 1 : 0 ) ) break;
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
/***************************
|
||||
* directory read routine *
|
||||
***************************/
|
||||
|
||||
UWORD dir_rd(secnum)
|
||||
|
||||
WORD secnum;
|
||||
{
|
||||
BSETUP
|
||||
|
||||
return( rdwrt((LONG)secnum, GBL.dirbufp, 0) );
|
||||
}
|
||||
|
||||
|
||||
/****************************
|
||||
* directory write routine *
|
||||
****************************/
|
||||
|
||||
UWORD dir_wr(secnum)
|
||||
|
||||
REG WORD secnum;
|
||||
{
|
||||
REG UWORD rtn;
|
||||
BSETUP
|
||||
|
||||
rtn = rdwrt( (LONG)secnum, GBL.dirbufp, 2);
|
||||
if ( secnum < (GBL.parmp)->cks )
|
||||
*((GBL.dphp)->csv + secnum) = dchksum();
|
||||
return(rtn);
|
||||
}
|
||||
|
||||
|
||||
/*******************************
|
||||
* directory checksum routine *
|
||||
*******************************/
|
||||
|
||||
UBYTE dchksum()
|
||||
/* Compute checksum over one directory sector */
|
||||
/* Note that this implementation is dependant on the representation */
|
||||
/* of a LONG and is therefore not very portable. But it's fast */
|
||||
{
|
||||
REG LONG *p; /* local temp variables */
|
||||
REG LONG lsum;
|
||||
REG WORD i;
|
||||
|
||||
BSETUP
|
||||
|
||||
p = GBL.dirbufp; /* point to directory buffer */
|
||||
lsum = 0;
|
||||
i = SECLEN / (sizeof lsum);
|
||||
do
|
||||
{
|
||||
lsum += *p++; /* add next 4 bytes of directory */
|
||||
i -= 1;
|
||||
} while (i);
|
||||
lsum += (lsum >> 16);
|
||||
lsum += (lsum >> 8);
|
||||
return( (UBYTE)(lsum & 0xff) );
|
||||
}
|
||||
|
||||
|
||||
/************************
|
||||
* dirscan entry point *
|
||||
************************/
|
||||
|
||||
UWORD dirscan(funcp, fcbp, parms)
|
||||
|
||||
BOOLEAN (*funcp)(); /* funcp is a pointer to a Boolean function */
|
||||
REG struct fcb *fcbp; /* fcbp is a pointer to a fcb */
|
||||
REG UWORD parms; /* parms is 16 bit set of bit parameters */
|
||||
|
||||
/* Parms & 1 = 0 to start at beginning of dir, 1 to continue from last */
|
||||
/* Parms & 2 = 0 to stop when *funcp is true, 1 to go until end */
|
||||
/* Parms & 4 = 0 to check the dir checksum, 1 to store new checksum */
|
||||
/* Parms & 8 = 0 to stop at hiwater, 1 to go until end of directory */
|
||||
|
||||
#define continue 1
|
||||
#define full 2
|
||||
#define initckv 4
|
||||
#define pasthw 8
|
||||
|
||||
{
|
||||
REG UWORD i; /* loop counter */
|
||||
REG struct dpb *dparmp; /* pointer to disk parm block */
|
||||
REG UWORD dirsec; /* sector number we're working on */
|
||||
REG UWORD rtn; /* return value */
|
||||
REG UBYTE *p; /* scratch pointer */
|
||||
REG UWORD bitvec; /* disk nmbr represented as a vector */
|
||||
|
||||
BSETUP
|
||||
|
||||
dparmp = GBL.parmp; /* init ptr to dpb */
|
||||
rtn = 255; /* assume it doesn't work */
|
||||
|
||||
i = ( (parms & continue) ? GBL.srchpos + 1 : 0 );
|
||||
while ( (parms & pasthw) || (i <= ((GBL.dphp)->hiwater + 1)) )
|
||||
{ /* main directory scanning loop */
|
||||
if ( i > dparmp->drm ) break;
|
||||
if ( ! (i & 3) )
|
||||
{ /* inside loop happens when we need to
|
||||
read another directory sector */
|
||||
retry: dirsec = i >> 2;
|
||||
dir_rd(dirsec); /* read the directory sector */
|
||||
if ( dirsec < (dparmp->cks) ) /* checksumming on this sector? */
|
||||
{
|
||||
p = ((GBL.dphp)->csv) + dirsec;
|
||||
/* point to checksum vector byte */
|
||||
if (parms & initckv) *p = dchksum();
|
||||
else if (*p != dchksum())
|
||||
{ /* checksum error! */
|
||||
(GBL.dphp)->hiwater = dparmp->drm; /* reset hi water */
|
||||
bitvec = 1 << (GBL.curdsk);
|
||||
if (crit_dsk & bitvec) /* if disk in critical mode */
|
||||
ro_dsk |= bitvec; /* then set it to r/o */
|
||||
else
|
||||
{
|
||||
log_dsk &= ~bitvec; /* else log it off */
|
||||
seldsk(GBL.curdsk); /* and re-select it */
|
||||
goto retry; /* and re-do current op */
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GBL.srchpos = i;
|
||||
if ( (*funcp)(fcbp, (GBL.dirbufp) + (i&3), i) )
|
||||
/* call function with parms of (1) fcb ptr,
|
||||
(2) pointer to directory entry, and
|
||||
(3) directory index */
|
||||
{
|
||||
if (parms & full) rtn = 0; /* found a match, but keep going */
|
||||
else return(i & 3); /* return directory code */
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
return(rtn);
|
||||
}
|
||||
|
||||
|
||||
/****************************************
|
||||
* Routines to manage allocation vector *
|
||||
* setaloc() *
|
||||
* clraloc() *
|
||||
* getaloc() *
|
||||
****************************************/
|
||||
|
||||
setaloc(bitnum)
|
||||
/* Set bit in allocation vector */
|
||||
REG UWORD bitnum;
|
||||
{
|
||||
BSETUP
|
||||
|
||||
if (bitnum >= 0 && bitnum <= (GBL.parmp)->dsm)
|
||||
*((GBL.dphp)->alv + (bitnum>>3)) |= 0x80 >> (bitnum & 7);
|
||||
}
|
||||
|
||||
|
||||
clraloc(bitnum)
|
||||
/* Clear bit in allocation vector */
|
||||
REG UWORD bitnum;
|
||||
{
|
||||
BSETUP
|
||||
|
||||
if (bitnum > 0 && bitnum <= (GBL.parmp)->dsm)
|
||||
*((GBL.dphp)->alv + (bitnum>>3)) &= ~(0x80 >> (bitnum & 7));
|
||||
}
|
||||
|
||||
|
||||
UWORD chkaloc(i)
|
||||
/* Check bit i in allocation vector */
|
||||
/* Return non-zero if block free, else return zero */
|
||||
REG UWORD i;
|
||||
{
|
||||
BSETUP
|
||||
|
||||
return( ~(*( (GBL.dphp)->alv + (i >> 3) )) & (0x80 >> (i&7)) );
|
||||
}
|
||||
|
||||
|
||||
UWORD getaloc(leftblk)
|
||||
/* Get a free block in the file system and set the bit in allocation vector */
|
||||
/* It is passed the block number of the last block allocated to the file */
|
||||
/* It tries to allocate the block closest to the block that was passed */
|
||||
REG UWORD leftblk;
|
||||
{
|
||||
REG UWORD blk; /* block number to allocate */
|
||||
REG UWORD rtblk; /* high block number to try */
|
||||
REG UWORD diskmax; /* # bits in alv - 1 */
|
||||
|
||||
BSETUP
|
||||
LOCK /* need to lock the file system while messing
|
||||
with the allocation vector */
|
||||
|
||||
diskmax = (GBL.parmp)->dsm;
|
||||
/* get disk max field from dpb */
|
||||
rtblk = leftblk;
|
||||
blk = ~0; /* -1 returned if no free block found */
|
||||
while (leftblk || rtblk < diskmax)
|
||||
{
|
||||
if (leftblk)
|
||||
if (chkaloc(--leftblk))
|
||||
{
|
||||
blk = leftblk;
|
||||
break;
|
||||
}
|
||||
if (rtblk < diskmax)
|
||||
if (chkaloc(++rtblk))
|
||||
{
|
||||
blk = rtblk;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (blk != ~0) setaloc(blk);
|
||||
UNLOCK
|
||||
return(blk);
|
||||
}
|
||||
291
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/bdos/exceptn.s
Normal file
291
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/bdos/exceptn.s
Normal file
@@ -0,0 +1,291 @@
|
||||
|
||||
*************************************************
|
||||
* *
|
||||
* CP/M-68k Basic Disk Operating System *
|
||||
* Exception Handling Module *
|
||||
* *
|
||||
* Version 0.0 -- July 21, 1982 *
|
||||
* Version 0.1 -- July 25, 1982 *
|
||||
* Version 0.2 -- October 6, 1982 *
|
||||
* Version 0.3 -- December 21, 1982 *
|
||||
* *
|
||||
*************************************************
|
||||
|
||||
|
||||
.globl _initexc
|
||||
.globl _tpa_lp
|
||||
.globl _tpa_hp
|
||||
|
||||
bgetseg = 18
|
||||
bsetexc = 22
|
||||
buserr = 2
|
||||
spurious = 24
|
||||
trap0 = 32
|
||||
trap2 = 34
|
||||
trap3 = 35
|
||||
endvec = 48
|
||||
|
||||
_initexc:
|
||||
* Initialize Exception Vector Handlers
|
||||
* It has 1 passed parameter: the address of the exception vector array
|
||||
move #bsetexc,d0
|
||||
moveq #2,d1
|
||||
move.l #exchndl,d2
|
||||
init1:
|
||||
movem.l d0-d2,-(sp)
|
||||
trap #3 * BIOS call to set exception vector
|
||||
movem.l (sp)+,d0-d2
|
||||
init2: addq #1,d1
|
||||
add.l #4,d2
|
||||
cmpi #spurious,d1
|
||||
bne init3
|
||||
move #trap0,d1
|
||||
init3: cmpi #trap2,d1
|
||||
beq init2 * don't init trap 2 or trap 3
|
||||
cmpi #trap3,d1
|
||||
beq init2
|
||||
cmpi #endvec,d1
|
||||
blt init1
|
||||
* initialize the exception vector array
|
||||
|
||||
moveq #bgetseg,d0
|
||||
trap #3 * get the original TPA limits
|
||||
movea.l d0,a0
|
||||
tst.w (a0)+
|
||||
move.l (a0)+,d1 * d1 = original low TPA limit
|
||||
move.l d1,d2
|
||||
add.l (a0),d2 * d2 = original high TPA limit
|
||||
move.l _tpa_lp,d3 * d3 = new low TPA limit
|
||||
move.l _tpa_hp,d4 * d4 = new high TPA limit
|
||||
move #17,d0
|
||||
movea.l 4(sp),a0
|
||||
move.l a0,evec_adr * save exception vector address
|
||||
init4:
|
||||
cmp.l (a0),d1
|
||||
bhi do_init * if old exception outside orig TPA, clear it
|
||||
cmp.l (a0),d2
|
||||
bls do_init
|
||||
* current exception array entry is in original TPA
|
||||
cmp.l (a0),d3
|
||||
bhi dontinit * if old exception in old TPA but outside new
|
||||
cmp.l (a0),d4 * TPA, don't clear it
|
||||
bls dontinit
|
||||
do_init:
|
||||
clr.l (a0)
|
||||
dontinit:
|
||||
tst.l (a0)+
|
||||
dbf d0,init4
|
||||
rts
|
||||
|
||||
exchndl:
|
||||
bsr.w except
|
||||
excrtn0:
|
||||
bsr.w except
|
||||
bsr.w except
|
||||
bsr.w except
|
||||
bsr.w except
|
||||
bsr.w except
|
||||
bsr.w except
|
||||
bsr.w except
|
||||
bsr.w except
|
||||
bsr.w except
|
||||
bsr.w except
|
||||
bsr.w except
|
||||
bsr.w except
|
||||
bsr.w except
|
||||
bsr.w except
|
||||
bsr.w except
|
||||
bsr.w except
|
||||
bsr.w except
|
||||
bsr.w except
|
||||
bsr.w except
|
||||
bsr.w except
|
||||
bsr.w except
|
||||
bsr.w except
|
||||
bsr.w except
|
||||
bsr.w except
|
||||
bsr.w except
|
||||
bsr.w except
|
||||
bsr.w except
|
||||
bsr.w except
|
||||
bsr.w except
|
||||
bsr.w except
|
||||
bsr.w except
|
||||
bsr.w except
|
||||
bsr.w except
|
||||
bsr.w except
|
||||
bsr.w except
|
||||
bsr.w except
|
||||
bsr.w except
|
||||
|
||||
|
||||
except:
|
||||
clr.w -(sp)
|
||||
movem.l a0/d0,-(sp) * 10 words now on stack in following order:
|
||||
* _______________________________
|
||||
* |____________D0.L_______________|
|
||||
* |____________A0.L_______________|
|
||||
* |____0000______|________________
|
||||
* |_______Handler Return__________|
|
||||
* If bus error, extra 2 longs are here
|
||||
* ______________
|
||||
* |__Status Reg__|________________
|
||||
* |_____Exception Return__________|
|
||||
|
||||
move.l 10(sp),d0 * get return address from above array
|
||||
sub.l #excrtn0,d0 * d0 now has 4 * (encoded excptn nmbr), where
|
||||
* encoded excptn nmbr is in [0..21,22..37]
|
||||
* representing [2..23,32..47]
|
||||
cmpi #36,d0 * if d0/4 is in [0..9,22..29] then
|
||||
ble chkredir * the exception may be redirected
|
||||
cmpi #88,d0
|
||||
blt dfltexc
|
||||
cmpi #116,d0
|
||||
bgt dfltexc
|
||||
* in range of redirected exceptions
|
||||
subi #48,d0 * subtract 4*12 to normalize [0..9,22..29]
|
||||
* into [0..9,10..17]
|
||||
chkredir:
|
||||
movea.l evec_adr,a0
|
||||
adda d0,a0 * index into exception vector array
|
||||
tst.l (a0) * if 00000000, then not redirected
|
||||
bne usrexc
|
||||
* not redirected, do default handler
|
||||
cmpi #40,d0
|
||||
blt dfltexc
|
||||
addi #48,d0 * add 4*12 that was sub'd above
|
||||
dfltexc:
|
||||
adda #14,sp * throw away 7 words that we added to stack
|
||||
asr #2,d0 * divide d0 by 4
|
||||
* now d0 is in [0..21,22..37]
|
||||
* to represent [2..23,32..47]
|
||||
cmpi #2,d0 * bus or address error?
|
||||
bge nobusexc
|
||||
movem.l (sp)+,a0-a1 * if yes, throw away 4 words from stack
|
||||
nobusexc:
|
||||
tst.w (sp)+ * throw away stacked SR
|
||||
addi #2,d0
|
||||
cmpi #23,d0 * get back real excptn nmbr in [2..23,32..47]
|
||||
ble lowexc
|
||||
addi #8,d0
|
||||
lowexc: move d0,-(sp) * save excptn nmbr
|
||||
lea excmsg1,a0
|
||||
bsr print * print default exception message
|
||||
move (sp)+,d0
|
||||
bsr prtbyte
|
||||
lea excmsg2, a0
|
||||
bsr print
|
||||
move.l (sp)+,d0
|
||||
bsr prtlong
|
||||
lea excmsg3, a0
|
||||
bsr print
|
||||
clr.l d0
|
||||
trap #2 * warm boot
|
||||
rte
|
||||
|
||||
usrexc:
|
||||
* Call user exception handler
|
||||
* make sure exception information is on his stack
|
||||
move.l (a0),10(sp) * put user handler address on our stack
|
||||
move.l usp,a0 * user stack pointer to a0
|
||||
cmpi #8,d0 * address or bus error?
|
||||
blt addrexc * if yes, skip
|
||||
btst #13,14(sp) * exception occured in user state?
|
||||
bne supstat1 * if no, go to supervisor handler
|
||||
move.l 16(sp),-(a0) * put exception return on user stack
|
||||
move.w 14(sp),-(a0) * put SR on user stack
|
||||
move.l a0,usp * update user stack pointer
|
||||
movem.l (sp)+,a0/d0 * restore regs
|
||||
move.l 2(sp),8(sp) * move address of user handler to excptn rtn
|
||||
addq #6,sp * clear junk from stack
|
||||
andi #$7fff,(sp) * clear trace bit
|
||||
rte * go to user handler
|
||||
addrexc:
|
||||
btst #13,22(sp) * exception occured in user state?
|
||||
bne supstat2 * if no, go to supervisor handler
|
||||
move.l 24(sp),-(a0) * put exception return on user stack
|
||||
move.w 22(sp),-(a0) * put SR on user stack
|
||||
move.l 18(sp),-(a0) * put extra 2 longs on user stack
|
||||
move.l 14(sp),-(a0)
|
||||
move.l a0,usp * update user stack pointer
|
||||
movem.l (sp)+,a0/d0 * restore regs
|
||||
move.l 2(sp),16(sp) * move address of user handler to excptn rtn
|
||||
adda #14,sp * clear junk from stack
|
||||
andi #$7fff,(sp) * clear trace bit
|
||||
rte * go to user handler
|
||||
|
||||
supstat1:
|
||||
move.w 14(sp),8(sp) * move SR to our exception return
|
||||
bra supstat3
|
||||
supstat2:
|
||||
move.w 22(sp),8(sp)
|
||||
supstat3:
|
||||
movem.l (sp)+,a0/d0
|
||||
rte
|
||||
|
||||
*
|
||||
* Subroutines
|
||||
*
|
||||
|
||||
print:
|
||||
clr.l d1
|
||||
move.b (a0)+, d1
|
||||
beq prtdone
|
||||
move #2, d0
|
||||
trap #2
|
||||
bra print
|
||||
prtdone:
|
||||
rts
|
||||
|
||||
prtlong:
|
||||
* Print d0.l in hex format
|
||||
move d0,-(sp)
|
||||
swap d0
|
||||
bsr prtword
|
||||
move (sp)+,d0
|
||||
|
||||
prtword:
|
||||
* Print d0.w in hex format
|
||||
move d0,-(sp)
|
||||
lsr #8,d0
|
||||
bsr prtbyte
|
||||
move (sp)+,d0
|
||||
|
||||
prtbyte:
|
||||
* Print d0.b in hex format
|
||||
move d0,-(sp)
|
||||
lsr #4,d0
|
||||
bsr prtnib
|
||||
move (sp)+,d0
|
||||
|
||||
prtnib:
|
||||
andi #$f,d0
|
||||
cmpi #10,d0
|
||||
blt lt10
|
||||
addi.b #'A'-'9'-1,d0
|
||||
lt10:
|
||||
addi.b #'0',d0
|
||||
move d0,d1
|
||||
move #2,d0
|
||||
trap #2
|
||||
rts
|
||||
|
||||
|
||||
.data
|
||||
|
||||
excmsg1:
|
||||
.dc.b 13,10,10,'Exception $',0
|
||||
|
||||
excmsg2:
|
||||
.dc.b ' at user address $',0
|
||||
|
||||
excmsg3:
|
||||
.dc.b '. Aborted.',0
|
||||
|
||||
|
||||
.bss
|
||||
|
||||
evec_adr:
|
||||
.ds.l 1
|
||||
|
||||
.end
|
||||
659
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/bdos/fileio.c
Normal file
659
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/bdos/fileio.c
Normal file
@@ -0,0 +1,659 @@
|
||||
|
||||
/****************************************************************
|
||||
* *
|
||||
* CP/M-68K BDOS File I/O Module *
|
||||
* *
|
||||
* This module contains all file handling BDOS functions *
|
||||
* except for read and write for CP/M-68K. Included are: *
|
||||
* *
|
||||
* seldsk() - select disk *
|
||||
* openfile() - open file *
|
||||
* close_fi() - close file *
|
||||
* search() - search for first/next file match *
|
||||
* create() - create file *
|
||||
* delete() - delete file *
|
||||
* rename() - rename file *
|
||||
* set_attr() - set file attributes *
|
||||
* getsize() - get file size *
|
||||
* setran() - set random record field *
|
||||
* free_sp() - get disk free space *
|
||||
* move() - general purpose byte mover *
|
||||
* *
|
||||
* *
|
||||
* Compiled with Alcyon C on the VAX *
|
||||
* *
|
||||
****************************************************************/
|
||||
|
||||
#include "bdosinc.h" /* Standard I/O declarations */
|
||||
|
||||
#include "bdosdef.h" /* Type and structure declarations for BDOS */
|
||||
|
||||
#include "pktio.h" /* Packet I/O definitions */
|
||||
|
||||
/* declare external fucntions */
|
||||
EXTERN UWORD dirscan(); /* directory scanning routine */
|
||||
EXTERN UWORD error(); /* disk error routine */
|
||||
EXTERN UWORD ro_err(); /* read-only file error routine */
|
||||
EXTERN UWORD do_phio(); /* packet disk i/o handler */
|
||||
EXTERN clraloc(); /* clear bit in allocation vector */
|
||||
EXTERN setaloc(); /* set bit in allocation vector */
|
||||
EXTERN UWORD swap(); /* assembly language byte swapper */
|
||||
EXTERN UWORD dir_wr(); /* directory write routine */
|
||||
EXTERN tmp_sel(); /* temporary select disk routine */
|
||||
EXTERN UWORD calcext(); /* calc max extent allocated for fcb */
|
||||
EXTERN UWORD udiv(); /* unsigned divide routine */
|
||||
|
||||
|
||||
/* declare external variables */
|
||||
EXTERN UWORD log_dsk; /* logged-on disk vector */
|
||||
EXTERN UWORD ro_dsk; /* read-only disk vector */
|
||||
EXTERN UWORD crit_dsk; /* vector of disks in critical state */
|
||||
|
||||
|
||||
/************************************
|
||||
* This function passed to dirscan *
|
||||
* from seldsk (below) *
|
||||
************************************/
|
||||
|
||||
BOOLEAN alloc(fcbp, dirp, dirindx)
|
||||
/* Set up allocation vector for directory entry pointed to by dirp */
|
||||
|
||||
struct fcb *fcbp; /* not used in this function */
|
||||
REG struct dirent *dirp; /* pointer to directory entry */
|
||||
WORD dirindx; /* index into directory for *dirp */
|
||||
{
|
||||
REG WORD i; /* loop counter */
|
||||
BSETUP
|
||||
|
||||
if ( UBWORD(dirp->entry) < 0x10 ) /* skip MP/M 2.x and CP/M 3.x XFCBs */
|
||||
{
|
||||
(GBL.dphp)->hiwater = dirindx; /* set up high water mark for disk */
|
||||
i = 0;
|
||||
if ((GBL.parmp)->dsm < 256)
|
||||
{
|
||||
do setaloc( UBWORD(dirp->dskmap.small[i++]) );
|
||||
while (i <= 15);
|
||||
}
|
||||
else
|
||||
{
|
||||
do setaloc(swap(dirp->dskmap.big[i++]));
|
||||
while (i <= 7);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/************************
|
||||
* seldsk entry point *
|
||||
************************/
|
||||
|
||||
seldsk(dsknum)
|
||||
|
||||
REG UBYTE dsknum; /* disk number to select */
|
||||
|
||||
{
|
||||
struct iopb selpkt;
|
||||
REG WORD i;
|
||||
UWORD j;
|
||||
REG UBYTE logflag;
|
||||
BSETUP
|
||||
|
||||
logflag = ~(log_dsk >> dsknum) & 1;
|
||||
if ((GBL.curdsk != dsknum) || logflag)
|
||||
{ /* if not last used disk or not logged on */
|
||||
selpkt.iofcn = sel_info;
|
||||
GBL.curdsk = (selpkt.devnum = dsknum);
|
||||
if (UBWORD(dsknum) > 15) error(2);
|
||||
selpkt.ioflags = logflag ^ 1;
|
||||
do
|
||||
{
|
||||
do_phio(&selpkt); /* actually do the disk select */
|
||||
if ( (GBL.dphp = selpkt.infop) != NULL ) break;
|
||||
} while ( ! error(3) );
|
||||
|
||||
GBL.dirbufp = (GBL.dphp)->dbufp;
|
||||
/* set up GBL copies of dir_buf and dpb ptrs */
|
||||
GBL.parmp = (GBL.dphp)->dpbp;
|
||||
}
|
||||
if (logflag)
|
||||
{ /* if disk not previously logged on, do it now */
|
||||
LOCK /* must lock the file system while messing with alloc vec */
|
||||
i = (GBL.parmp)->dsm;
|
||||
do clraloc(i); while (i--); /* clear the allocation vector */
|
||||
i = udiv( (LONG)(((GBL.parmp)->drm) + 1),
|
||||
4 * (((GBL.parmp)->blm) + 1), &j);
|
||||
/* calculate nmbr of directory blks */
|
||||
if (j) i++; /* round up */
|
||||
do setaloc(--i); while (i); /* alloc directory blocks */
|
||||
dirscan(alloc, NULL, 0x0e); /* do directory scan & alloc blocks */
|
||||
log_dsk |= 1 << dsknum; /* mark disk as logged in */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*******************************
|
||||
* General purpose byte mover *
|
||||
*******************************/
|
||||
|
||||
move(p1, p2, i)
|
||||
|
||||
REG BYTE *p1;
|
||||
REG BYTE *p2;
|
||||
REG WORD i;
|
||||
{
|
||||
while (i--)
|
||||
*p2++ = *p1++;
|
||||
}
|
||||
|
||||
|
||||
/*************************************
|
||||
* General purpose filename matcher *
|
||||
*************************************/
|
||||
|
||||
BOOLEAN match(p1, p2, chk_ext)
|
||||
|
||||
REG UBYTE *p1;
|
||||
REG UBYTE *p2;
|
||||
BOOLEAN chk_ext;
|
||||
{
|
||||
REG WORD i;
|
||||
REG UBYTE temp;
|
||||
BSETUP
|
||||
|
||||
i = 12;
|
||||
do
|
||||
{
|
||||
temp = (*p1 ^ '?');
|
||||
if ( ((*p1++ ^ *p2++) & 0x7f) && temp )
|
||||
return(FALSE);
|
||||
i -= 1;
|
||||
} while (i);
|
||||
if (chk_ext)
|
||||
{
|
||||
if ( (*p1 != '?') && ((*p1 ^ *p2) & ~((GBL.parmp)->exm)) )
|
||||
return(FALSE);
|
||||
p1 += 2;
|
||||
p2 += 2;
|
||||
if ((*p1 ^ *p2) & 0x3f) return(FALSE);
|
||||
}
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
|
||||
/************************
|
||||
* openfile entry point *
|
||||
************************/
|
||||
|
||||
BOOLEAN openfile(fcbp, dirp, dirindx)
|
||||
|
||||
REG struct fcb *fcbp; /* pointer to fcb for file to open */
|
||||
struct dirent *dirp; /* pointer to directory entry */
|
||||
WORD dirindx;
|
||||
|
||||
{
|
||||
REG UBYTE fcb_ext; /* extent field from fcb */
|
||||
REG BOOLEAN rtn;
|
||||
BSETUP
|
||||
|
||||
if ( rtn = match(fcbp, dirp, TRUE) )
|
||||
{
|
||||
fcb_ext = fcbp->extent; /* save extent number from user's fcb */
|
||||
move(dirp, fcbp, sizeof *dirp);
|
||||
/* copy dir entry into user's fcb */
|
||||
fcbp->extent = fcb_ext;
|
||||
fcbp->s2 |= 0x80; /* set hi bit of S2 (write flag) */
|
||||
crit_dsk |= 1 << (GBL.curdsk);
|
||||
}
|
||||
return(rtn);
|
||||
}
|
||||
|
||||
|
||||
/*************************/
|
||||
/* flush buffers routine */
|
||||
/*************************/
|
||||
|
||||
UWORD flushit()
|
||||
{
|
||||
REG UWORD rtn; /* return code from flush buffers call */
|
||||
struct iopb flushpkt; /* I/O packet for flush buffers call */
|
||||
|
||||
flushpkt.iofcn = flush;
|
||||
while ( rtn = do_phio(&flushpkt) )
|
||||
if ( error(1) ) break;
|
||||
return(rtn);
|
||||
}
|
||||
|
||||
|
||||
/*********************************
|
||||
* file close routine for dirscan *
|
||||
*********************************/
|
||||
|
||||
BOOLEAN close(fcbp, dirp, dirindx)
|
||||
|
||||
REG struct fcb *fcbp; /* pointer to fcb */
|
||||
REG struct dirent *dirp; /* pointer to directory entry */
|
||||
WORD dirindx; /* index into directory */
|
||||
|
||||
{
|
||||
REG WORD i;
|
||||
REG UBYTE *fp;
|
||||
REG UBYTE *dp;
|
||||
REG UWORD fcb_ext;
|
||||
REG UWORD dir_ext;
|
||||
BSETUP
|
||||
|
||||
if ( match(fcbp, dirp, TRUE) )
|
||||
{ /* Note that FCB merging is done here as a final
|
||||
confirmation that disks haven't been swapped */
|
||||
LOCK
|
||||
fp = &(fcbp->dskmap.small[0]);
|
||||
dp = &(dirp->dskmap.small[0]);
|
||||
if ((GBL.parmp)->dsm < 256)
|
||||
{ /* Small disk map merge routine */
|
||||
i = 16;
|
||||
do
|
||||
{
|
||||
if (*dp)
|
||||
{
|
||||
if (*fp)
|
||||
{
|
||||
if (*dp != *fp) goto badmerge;
|
||||
}
|
||||
else *fp = *dp;
|
||||
}
|
||||
else *dp = *fp;
|
||||
fp += 1;
|
||||
dp += 1;
|
||||
i -= 1;
|
||||
} while (i);
|
||||
}
|
||||
else
|
||||
{ /* Large disk map merge routine */
|
||||
i = 8;
|
||||
do
|
||||
{
|
||||
if (*(UWORD *)dp)
|
||||
{
|
||||
if (*(UWORD *)fp)
|
||||
{
|
||||
if (*(UWORD *)dp != *(UWORD *)fp) goto badmerge;
|
||||
}
|
||||
else *(UWORD *)fp = *(UWORD *)dp;
|
||||
}
|
||||
else *(UWORD *)dp = *(UWORD *)fp;
|
||||
(UWORD *)fp += 1;
|
||||
(UWORD *)dp += 1;
|
||||
i -= 1;
|
||||
} while (i);
|
||||
}
|
||||
/* Disk map merging complete */
|
||||
fcb_ext = calcext(fcbp); /* calc max extent for fcb */
|
||||
dir_ext = (UWORD)(dirp->extent) & 0x1f;
|
||||
if ( (fcb_ext > dir_ext) ||
|
||||
((fcb_ext == dir_ext) &&
|
||||
(UBWORD(fcbp->rcdcnt) > UBWORD(dirp->rcdcnt))) )
|
||||
/* if fcb points to larger file than dirp */
|
||||
{
|
||||
dirp->rcdcnt = fcbp->rcdcnt; /* set up rc, ext from fcb */
|
||||
dirp->extent = (BYTE)fcb_ext;
|
||||
}
|
||||
dirp->s1 = fcbp->s1;
|
||||
if ( (dirp->ftype[robit]) & 0x80) ro_err(fcbp,dirindx);
|
||||
/* read-only file error */
|
||||
dirp->ftype[arbit] &= 0x7f; /* clear archive bit */
|
||||
dir_wr(dirindx >> 2);
|
||||
UNLOCK
|
||||
return(TRUE);
|
||||
|
||||
badmerge:
|
||||
UNLOCK
|
||||
ro_dsk |= (1 << GBL.curdsk);
|
||||
return(FALSE);
|
||||
}
|
||||
else return(FALSE);
|
||||
}
|
||||
|
||||
|
||||
/************************
|
||||
* close_fi entry point *
|
||||
************************/
|
||||
|
||||
UWORD close_fi(fcbp)
|
||||
|
||||
struct fcb *fcbp; /* pointer to fcb for file to close */
|
||||
{
|
||||
flushit(); /* first, flush the buffers */
|
||||
if ((fcbp->s2) & 0x80) return(0); /* if file write flag not on,
|
||||
don't need to do physical close */
|
||||
return( dirscan(close, fcbp, 0)); /* call dirscan with close function */
|
||||
}
|
||||
|
||||
|
||||
/************************
|
||||
* search entry point *
|
||||
************************/
|
||||
|
||||
/* First two functions for dirscan */
|
||||
|
||||
BOOLEAN alltrue(p1, p2, i)
|
||||
UBYTE *p1;
|
||||
UBYTE *p2;
|
||||
WORD i;
|
||||
{
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
BOOLEAN matchit(p1, p2, i)
|
||||
UBYTE *p1;
|
||||
UBYTE *p2;
|
||||
WORD i;
|
||||
{
|
||||
return(match(p1, p2, TRUE));
|
||||
}
|
||||
|
||||
|
||||
/* search entry point */
|
||||
UWORD search(fcbp, dsparm, p)
|
||||
|
||||
REG struct fcb *fcbp; /* pointer to fcb for file to search */
|
||||
REG UWORD dsparm; /* parameter to pass through to dirscan */
|
||||
UBYTE *p; /* pointer to pass through to tmp_sel */
|
||||
|
||||
{
|
||||
REG UWORD rtn; /* return value */
|
||||
BSETUP
|
||||
|
||||
if (fcbp->drvcode == '?')
|
||||
{
|
||||
seldsk(GBL.dfltdsk);
|
||||
rtn = dirscan(alltrue, fcbp, dsparm);
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp_sel(p); /* temporarily select disk */
|
||||
if (fcbp->extent != '?') fcbp->extent = 0;
|
||||
fcbp->s2 = 0;
|
||||
rtn = dirscan(matchit, fcbp, dsparm);
|
||||
}
|
||||
move( GBL.dirbufp, GBL.dmaadr, SECLEN);
|
||||
return(rtn);
|
||||
}
|
||||
|
||||
|
||||
/************************
|
||||
* create entry point *
|
||||
************************/
|
||||
|
||||
BOOLEAN create(fcbp, dirp, dirindx)
|
||||
|
||||
REG struct fcb *fcbp; /* pointer to fcb for file to create */
|
||||
REG struct dirent *dirp; /* pointer to directory entry */
|
||||
REG WORD dirindx; /* index into directory */
|
||||
|
||||
{
|
||||
REG BYTE *p;
|
||||
REG WORD i;
|
||||
REG BOOLEAN rtn;
|
||||
BSETUP
|
||||
|
||||
if ( rtn = ((dirp->entry) == 0xe5) )
|
||||
{
|
||||
p = &(fcbp->rcdcnt);
|
||||
i = 17;
|
||||
do
|
||||
{ /* clear fcb rcdcnt and disk map */
|
||||
*p++ = 0;
|
||||
i -= 1;
|
||||
} while (i);
|
||||
move(fcbp, dirp, sizeof *dirp); /* move the fcb to the directory */
|
||||
dir_wr(dirindx >> 2); /* write the directory sector */
|
||||
if ( dirindx > (GBL.dphp)->hiwater )
|
||||
(GBL.dphp)->hiwater = dirindx;
|
||||
crit_dsk |= 1 << (GBL.curdsk);
|
||||
}
|
||||
return(rtn);
|
||||
}
|
||||
|
||||
|
||||
/************************
|
||||
* delete entry point *
|
||||
************************/
|
||||
|
||||
BOOLEAN delete(fcbp, dirp, dirindx)
|
||||
|
||||
REG struct fcb *fcbp; /* pointer to fcb for file to delete */
|
||||
REG struct dirent *dirp; /* pointer to directory entry */
|
||||
REG WORD dirindx; /* index into directory */
|
||||
|
||||
{
|
||||
REG WORD i;
|
||||
REG BOOLEAN rtn;
|
||||
BSETUP
|
||||
|
||||
if ( rtn = match(fcbp, dirp, FALSE) )
|
||||
{
|
||||
if ( (dirp->ftype[robit]) & 0x80 ) ro_err(fcbp,dirindx);
|
||||
/* check for read-only file */
|
||||
dirp->entry = 0xe5;
|
||||
LOCK
|
||||
dir_wr(dirindx >> 2);
|
||||
/* Now free up the space in the allocation vector */
|
||||
if ((GBL.parmp)->dsm < 256)
|
||||
{
|
||||
i = 16;
|
||||
do clraloc(UBWORD(dirp->dskmap.small[--i]));
|
||||
while (i);
|
||||
}
|
||||
else
|
||||
{
|
||||
i = 8;
|
||||
do clraloc(swap(dirp->dskmap.big[--i]));
|
||||
while (i);
|
||||
}
|
||||
UNLOCK
|
||||
}
|
||||
return(rtn);
|
||||
}
|
||||
|
||||
|
||||
/************************
|
||||
* rename entry point *
|
||||
************************/
|
||||
|
||||
BOOLEAN rename(fcbp, dirp, dirindx)
|
||||
|
||||
REG struct fcb *fcbp; /* pointer to fcb for file to delete */
|
||||
REG struct dirent *dirp; /* pointer to directory entry */
|
||||
REG WORD dirindx; /* index into directory */
|
||||
|
||||
{
|
||||
REG UWORD i;
|
||||
REG BYTE *p; /* general purpose pointers */
|
||||
REG BYTE *q;
|
||||
REG BOOLEAN rtn;
|
||||
BSETUP
|
||||
|
||||
if ( rtn = match(fcbp, dirp, FALSE) )
|
||||
{
|
||||
if ( (dirp->ftype[robit]) & 0x80 ) ro_err(fcbp,dirindx);
|
||||
/* check for read-only file */
|
||||
p = &(fcbp->dskmap.small[1]);
|
||||
q = &(dirp->fname[0]);
|
||||
i = 11;
|
||||
do
|
||||
{
|
||||
*q++ = *p++ & 0x7f;
|
||||
i -= 1;
|
||||
} while (i);
|
||||
dir_wr(dirindx >> 2);
|
||||
}
|
||||
return(rtn);
|
||||
}
|
||||
|
||||
|
||||
/************************
|
||||
* set_attr entry point *
|
||||
************************/
|
||||
|
||||
BOOLEAN set_attr(fcbp, dirp, dirindx)
|
||||
|
||||
REG struct fcb *fcbp; /* pointer to fcb for file to delete */
|
||||
REG struct dirent *dirp; /* pointer to directory entry */
|
||||
REG WORD dirindx; /* index into directory */
|
||||
|
||||
{
|
||||
REG BOOLEAN rtn;
|
||||
BSETUP
|
||||
|
||||
if ( rtn = match(fcbp, dirp, FALSE) )
|
||||
{
|
||||
move(&fcbp->fname[0], &dirp->fname[0], 11);
|
||||
dir_wr(dirindx >> 2);
|
||||
}
|
||||
return(rtn);
|
||||
}
|
||||
|
||||
|
||||
/****************************
|
||||
* utility routine used by *
|
||||
* setran and getsize *
|
||||
****************************/
|
||||
|
||||
LONG extsize(fcbp)
|
||||
/* Return size of extent pointed to by fcbp */
|
||||
REG struct fcb *fcbp;
|
||||
|
||||
{
|
||||
return( ((LONG)(fcbp->extent & 0x1f) << 7)
|
||||
| ((LONG)(fcbp->s2 & 0x3f) << 12) );
|
||||
}
|
||||
|
||||
|
||||
/************************
|
||||
* setran entry point *
|
||||
************************/
|
||||
|
||||
setran(fcbp)
|
||||
|
||||
REG struct fcb *fcbp; /* pointer to fcb for file to set ran rec */
|
||||
|
||||
{
|
||||
struct
|
||||
{
|
||||
BYTE b3;
|
||||
BYTE b2;
|
||||
BYTE b1;
|
||||
BYTE b0;
|
||||
};
|
||||
LONG random;
|
||||
|
||||
random = (LONG)UBWORD(fcbp->cur_rec) + extsize(fcbp);
|
||||
/* compute random record field */
|
||||
fcbp->ran0 = random.b2;
|
||||
fcbp->ran1 = random.b1;
|
||||
fcbp->ran2 = random.b0;
|
||||
}
|
||||
|
||||
|
||||
/**********************************/
|
||||
/* fsize is a funtion for dirscan */
|
||||
/* passed from getsize */
|
||||
/**********************************/
|
||||
|
||||
BOOLEAN fsize(fcbp, dirp, dirindx)
|
||||
|
||||
REG struct fcb *fcbp; /* pointer to fcb for file to delete */
|
||||
REG struct dirent *dirp; /* pointer to directory entry */
|
||||
WORD dirindx; /* index into directory */
|
||||
|
||||
{
|
||||
REG BOOLEAN rtn;
|
||||
struct
|
||||
{
|
||||
BYTE b3;
|
||||
BYTE b2;
|
||||
BYTE b1;
|
||||
BYTE b0;
|
||||
};
|
||||
LONG temp;
|
||||
|
||||
if ( rtn = match(fcbp, dirp, FALSE) )
|
||||
{
|
||||
temp = (LONG)UBWORD(dirp->rcdcnt) + extsize(dirp);
|
||||
/* compute file size */
|
||||
fcbp->ran0 = temp.b2;
|
||||
fcbp->ran1 = temp.b1;
|
||||
fcbp->ran2 = temp.b0;
|
||||
}
|
||||
return(rtn);
|
||||
}
|
||||
|
||||
/************************
|
||||
* getsize entry point *
|
||||
************************/
|
||||
|
||||
getsize(fcbp)
|
||||
/* get file size */
|
||||
REG struct fcb *fcbp; /* pointer to fcb to get file size for */
|
||||
|
||||
{
|
||||
LONG maxrcd;
|
||||
LONG temp;
|
||||
REG WORD dsparm;
|
||||
struct
|
||||
{
|
||||
BYTE b3;
|
||||
BYTE b2;
|
||||
BYTE b1;
|
||||
BYTE b0;
|
||||
};
|
||||
|
||||
maxrcd = 0;
|
||||
dsparm = 0;
|
||||
temp = 0;
|
||||
while ( dirscan(fsize, fcbp, dsparm) < 255 )
|
||||
{ /* loop until no more matches */
|
||||
temp.b2 = fcbp->ran0;
|
||||
temp.b1 = fcbp->ran1;
|
||||
temp.b0 = fcbp->ran2;
|
||||
if (temp > maxrcd) maxrcd = temp;
|
||||
dsparm = 1;
|
||||
}
|
||||
fcbp->ran0 = maxrcd.b2;
|
||||
fcbp->ran1 = maxrcd.b1;
|
||||
fcbp->ran2 = maxrcd.b0;
|
||||
}
|
||||
|
||||
|
||||
/************************
|
||||
* free_sp entry point *
|
||||
************************/
|
||||
|
||||
free_sp(dsknum)
|
||||
|
||||
UBYTE dsknum; /* disk number to get free space of */
|
||||
{
|
||||
REG LONG records;
|
||||
REG UWORD *alvec;
|
||||
REG UWORD bitmask;
|
||||
REG UWORD alvword;
|
||||
REG WORD i;
|
||||
BSETUP
|
||||
|
||||
seldsk(dsknum); /* select the disk */
|
||||
records = (LONG)0; /* initialize the variables */
|
||||
alvec = (GBL.dphp)->alv;
|
||||
bitmask = 0;
|
||||
for (i = 0; i <= (GBL.parmp)->dsm; i++) /* for loop to compute */
|
||||
{
|
||||
if ( ! bitmask)
|
||||
{
|
||||
bitmask = 0x8000;
|
||||
alvword = ~(*alvec++);
|
||||
}
|
||||
if ( alvword & bitmask)
|
||||
records += (LONG)( ((GBL.parmp)->blm) + 1 );
|
||||
bitmask >>= 1;
|
||||
}
|
||||
*(LONG *)GBL.dmaadr = records; /* move # records to DMA address */
|
||||
}
|
||||
106
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/bdos/filetyps.s
Normal file
106
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/bdos/filetyps.s
Normal file
@@ -0,0 +1,106 @@
|
||||
|
||||
*
|
||||
* CP/M-68K table driven file search module
|
||||
* ========================================
|
||||
*
|
||||
|
||||
* GLOBALS
|
||||
|
||||
|
||||
.globl _load_tbl * loader table
|
||||
.globl _load68k * default load program
|
||||
.globl init_tbl * initializes table on COLD BOOT
|
||||
|
||||
.text
|
||||
*************************************************************************
|
||||
* *
|
||||
* This is the DUAL PROCESSOR,ROMABLE version of CP/M-68K *
|
||||
* ====================================================== *
|
||||
* *
|
||||
* (c) Copyright Digital Research 1983 *
|
||||
* all rights reserved *
|
||||
* *
|
||||
*************************************************************************
|
||||
|
||||
*
|
||||
* The following code allows CP/M-68K to be ROM-able.
|
||||
* -------------------------------------------------
|
||||
*
|
||||
|
||||
init_tbl:
|
||||
move.l #typ1,typ1p
|
||||
move.l #typ2,typ2p * init the pointers to the filetypes
|
||||
move.l #typ3,typ3p
|
||||
move.l #null,typ4p
|
||||
|
||||
move.l #_load68k,pgld1
|
||||
move.l #_load68k,pgld2 * init the pointers to the loaders
|
||||
move.l #_load68k,pgld3
|
||||
move.l #_load68k,pgld4
|
||||
|
||||
rts
|
||||
.bss
|
||||
.even
|
||||
*************************************************************************
|
||||
* *
|
||||
* CP/M-68K LOADER TABLE *
|
||||
* ===================== *
|
||||
* *
|
||||
*-----------------------------------------------------------------------*
|
||||
* *
|
||||
* STRUCTURE OF A LOADER TABLE ENTRY: *
|
||||
* ================================= *
|
||||
* *
|
||||
* (1) LONG WORD pointer to a filetype *
|
||||
* (2) LONG WORD address of the program loader for the above type *
|
||||
* (3) BYTE flag #1 *
|
||||
* (4) BYTE flag #2 *
|
||||
* *
|
||||
*************************************************************************
|
||||
|
||||
|
||||
_load_tbl:
|
||||
typ1p: .ds.l 1
|
||||
pgld1: .ds.l 1
|
||||
.ds.b 1
|
||||
.ds.b 1
|
||||
typ2p: .ds.l 1
|
||||
pgld2: .ds.l 1
|
||||
.ds.b 1
|
||||
.ds.b 1
|
||||
typ3p: .ds.l 1
|
||||
pgld3: .ds.l 1
|
||||
.ds.b 1
|
||||
.ds.b 1
|
||||
typ4p: .ds.l 1
|
||||
pgld4: .ds.l 1
|
||||
.ds.b 1
|
||||
.ds.b 1
|
||||
|
||||
|
||||
*****************************************
|
||||
* *
|
||||
* FILETYPE TABLE *
|
||||
* ============== *
|
||||
* *
|
||||
*****************************************
|
||||
|
||||
|
||||
.data
|
||||
.even
|
||||
typ1: .dc.b '68K',0
|
||||
.even
|
||||
typ2: .dc.b ' ',0
|
||||
.even
|
||||
typ3: .dc.b 'SUB',0
|
||||
.even
|
||||
null: .dc.l 0
|
||||
.end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
77
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/bdos/iosys.c
Normal file
77
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/bdos/iosys.c
Normal file
@@ -0,0 +1,77 @@
|
||||
/****************************************************************
|
||||
* *
|
||||
* CP/M-68K BDOS Disk I/O System Module *
|
||||
* *
|
||||
* This module translates from the packet oriented I/O *
|
||||
* passed from the other BDOS modules into BIOS calls. *
|
||||
* *
|
||||
* It includes only one external entry point:
|
||||
* do_phio() - do physical i/o *
|
||||
* *
|
||||
* *
|
||||
* Configured for Alcyon C on the VAX *
|
||||
* *
|
||||
****************************************************************/
|
||||
|
||||
#include "bdosinc.h" /* Standard I/O declarations */
|
||||
|
||||
#include "bdosdef.h" /* Type and structure declarations for BDOS */
|
||||
|
||||
#include "pktio.h" /* Packet I/O definitions */
|
||||
|
||||
#include "biosdef.h" /* Declarations for BIOS entry points */
|
||||
|
||||
EXTERN udiv(); /* Assembly language unsigned divide routine */
|
||||
/* in bdosif.s. It's used because Alcyon C */
|
||||
/* can't do / or % without an external */
|
||||
|
||||
/************************
|
||||
* do_phio entry point *
|
||||
************************/
|
||||
|
||||
UWORD do_phio(iop)
|
||||
|
||||
REG struct iopb *iop; /* iop is a pointer to a i/o parameter block */
|
||||
|
||||
{
|
||||
MLOCAL UBYTE last_dsk; /* static variable to tell which disk
|
||||
was last used, to avoid disk selects */
|
||||
REG struct dph *hdrp; /* pointer to disk parameter header */
|
||||
REG struct dpb *dparmp; /* pointer to disk parameter block */
|
||||
REG UWORD rtn; /* return parameter */
|
||||
UWORD iosect; /* sector number returned from divide rtn */
|
||||
|
||||
LOCK /* lock the disk system while doing physical i/o */
|
||||
|
||||
rtn = 0;
|
||||
switch (iop->iofcn)
|
||||
{
|
||||
case sel_info:
|
||||
last_dsk = iop->devnum;
|
||||
iop->infop = bseldsk(last_dsk, iop->ioflags);
|
||||
break;
|
||||
|
||||
case read:
|
||||
case write:
|
||||
if (last_dsk != iop->devnum)
|
||||
bseldsk((last_dsk = iop->devnum), 0);
|
||||
/* guaranteed disk is logged on, because temp_sel in
|
||||
BDOSMAIN does it */
|
||||
hdrp = iop->infop;
|
||||
dparmp = hdrp->dpbp;
|
||||
|
||||
bsettrk( udiv( iop->devadr, dparmp->spt, &iosect )
|
||||
+ dparmp->trk_off );
|
||||
bsetsec( bsectrn( iosect, hdrp->xlt ) );
|
||||
bsetdma(iop->xferadr);
|
||||
if ((iop->iofcn) == read) rtn = bread();
|
||||
else rtn = bwrite(iop->ioflags);
|
||||
break;
|
||||
|
||||
case flush:
|
||||
rtn = bflush();
|
||||
}
|
||||
|
||||
UNLOCK
|
||||
return(rtn);
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
$1cp68 bdosmain.c $1x.i
|
||||
$1c068 $1x.i $1x.ic $1x.st
|
||||
era $1x.i
|
||||
era $1x.st
|
||||
$1c168 $1x.ic bdosmain.s -ld
|
||||
era $1x.ic
|
||||
$1as68 -s 0$1 -l -u -f $1 bdosmain.s
|
||||
era bdosmain.s
|
||||
|
||||
$1cp68 bdosmisc.c $1x.i
|
||||
$1c068 $1x.i $1x.ic $1x.st
|
||||
era $1x.i
|
||||
era $1x.st
|
||||
$1c168 $1x.ic bdosmisc.s -ld
|
||||
era $1x.ic
|
||||
$1as68 -s 0$1 -l -u -f $1 bdosmisc.s
|
||||
era bdosmisc.s
|
||||
|
||||
$1cp68 bdosrw.c $1x.i
|
||||
$1c068 $1x.i $1x.ic $1x.st
|
||||
era $1x.i
|
||||
era $1x.st
|
||||
$1c168 $1x.ic bdosrw.s -ld
|
||||
era $1x.ic
|
||||
$1as68 -s 0$1 -l -u -f $1 bdosrw.s
|
||||
era bdosrw.s
|
||||
|
||||
$1cp68 conbdos.c $1x.i
|
||||
$1c068 $1x.i $1x.ic $1x.st
|
||||
era $1x.i
|
||||
era $1x.st
|
||||
$1c168 $1x.ic conbdos.s -ld
|
||||
era $1x.ic
|
||||
$1as68 -s 0$1 -l -u -f $1 conbdos.s
|
||||
era conbdos.s
|
||||
|
||||
$1cp68 dskutil.c $1x.i
|
||||
$1c068 $1x.i $1x.ic $1x.st
|
||||
era $1x.i
|
||||
era $1x.st
|
||||
$1c168 $1x.ic dskutil.s -ld
|
||||
era $1x.ic
|
||||
$1as68 -s 0$1 -l -u -f $1 dskutil.s
|
||||
era dskutil.s
|
||||
|
||||
$1cp68 fileio.c $1x.i
|
||||
$1c068 $1x.i $1x.ic $1x.st
|
||||
era $1x.i
|
||||
era $1x.st
|
||||
$1c168 $1x.ic fileio.s -ld
|
||||
era $1x.ic
|
||||
$1as68 -s 0$1 -l -u -f $1 fileio.s
|
||||
era fileio.s
|
||||
|
||||
$1cp68 iosys.c $1x.i
|
||||
$1c068 $1x.i $1x.ic $1x.st
|
||||
era $1x.i
|
||||
era $1x.st
|
||||
$1c168 $1x.ic iosys.s -ld
|
||||
era $1x.ic
|
||||
$1as68 -s 0$1 -l -u -f $1 iosys.s
|
||||
era iosys.s
|
||||
|
||||
$1cp68 ccp.c $1x.i
|
||||
$1c068 $1x.i $1x.ic $1x.st
|
||||
era $1x.i
|
||||
era $1x.st
|
||||
$1c168 $1x.ic ccp.s -ld
|
||||
era $1x.ic
|
||||
$1as68 -s 0$1 -l -u -f $1 ccp.s
|
||||
era ccp.s
|
||||
|
||||
|
||||
$1as68 -s 0$1 -l -u -f $1 bdosif.s
|
||||
$1as68 -s 0$1 -l -u -f $1 -n exceptn.s
|
||||
$1as68 -s 0$1 -l -u -f $1 pgmld.s
|
||||
$1as68 -s 0$1 -l -u -f $1 ccpbdos.s
|
||||
$1as68 -s 0$1 -l -u -f $1 ccpif.s
|
||||
$1as68 -s 0$1 -l -u -f $1 ccpload.s
|
||||
$1as68 -s 0$1 -l -u -f $1 filetyps.s
|
||||
$1as68 -s 0$1 -l -u -f $1 stack.s
|
||||
|
||||
rear $1
|
||||
537
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/bdos/pgmld.s
Normal file
537
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/bdos/pgmld.s
Normal file
@@ -0,0 +1,537 @@
|
||||
|
||||
*********************************
|
||||
* *
|
||||
* Function 59 -- Program Load *
|
||||
* Assembly language version *
|
||||
* *
|
||||
* June 8, 1982 *
|
||||
* *
|
||||
*********************************
|
||||
|
||||
.globl _pgmld * this routine is public
|
||||
|
||||
secsize = 128 * CP/M sector size
|
||||
|
||||
* d0 always contains the return parameter from pgmld
|
||||
* d1 is the return register from local subroutines
|
||||
* a0 contains the pointer to the Load Parm Block passed to pgmld
|
||||
|
||||
* Return parameters in d0 are:
|
||||
* 00 - function successful
|
||||
* 01 - insufficient memory or bad header in file
|
||||
* 02 - read error on file
|
||||
* 03 - bad relocation information in file
|
||||
|
||||
|
||||
* Entry point for Program Load routine
|
||||
_pgmld:
|
||||
movem.l d1-d7/a0-a6, -(sp) * save everything, just to be safe
|
||||
move.l 60(sp),a0 * get pointer to LPB
|
||||
clr.l d0 * start with return parm cleared
|
||||
bsr gethdr * get header
|
||||
tst d0
|
||||
bne lddone * if unsuccessful, return
|
||||
bsr setaddr * set up load addresses
|
||||
tst d0
|
||||
bne lddone * if unsuccessful, return
|
||||
bsr rdtxt * read code and data text segments into mem
|
||||
tst d0
|
||||
bne lddone * if unsuccessful, return
|
||||
move.l tstart,d7
|
||||
cmp.l cseg,d7
|
||||
beq noreloc
|
||||
bsr reloc * do relocation if necessary
|
||||
noreloc:
|
||||
tst d0
|
||||
bne lddone
|
||||
bsr setrtn * set up return parameters
|
||||
lddone:
|
||||
move.l 64(sp), d1
|
||||
bsr setdma * restore dma address
|
||||
movem.l (sp)+,d1-d7/a0-a6
|
||||
rts
|
||||
|
||||
* Subroutines
|
||||
|
||||
readseq:
|
||||
* CP/M read sequential function
|
||||
move.l d0,-(sp) * save return parm
|
||||
move.l FCBPtr(a0),d1
|
||||
moveq #20,d0 * read seq function
|
||||
trap #2 * call bdos
|
||||
move.l d0,d1 * return parm in d1
|
||||
move.l (sp)+,d0
|
||||
rts
|
||||
|
||||
|
||||
setdma:
|
||||
* CP/M set dma function
|
||||
move.l d0,-(sp) * save return parm
|
||||
moveq #26,d0 * set dma function
|
||||
trap #2 * call bdos
|
||||
move.l (sp)+,d0 * restore d0
|
||||
rts
|
||||
|
||||
|
||||
gethdr:
|
||||
* Get header into buffer in data segment
|
||||
move.l LoAdr(a0),d1
|
||||
bsr setdma
|
||||
bsr readseq
|
||||
tst d1 * read ok?
|
||||
bne badhdr * if no, return bad
|
||||
moveq #18,d7
|
||||
movea.l LoAdr(a0),a5
|
||||
movea.l #hdr,a6
|
||||
geth1: move.w (a5)+,(a6)+ * move header into hdr
|
||||
dbf d7,geth1
|
||||
rts
|
||||
badhdr: moveq #2,d0
|
||||
rts
|
||||
|
||||
|
||||
conflict:
|
||||
* input parms: d2, d3 = 4 * segment nmbr
|
||||
* if segment d2/4 overlaps segment d3/4, then return 1 in d1
|
||||
* else return 0 in d1
|
||||
* uses d7, a2, a3
|
||||
clr.l d1 * assume it will work
|
||||
movea.l #cseg,a2 * a2 points to start of segment addresses
|
||||
movea.l #csize,a3 * a3 points to start of segment lengths
|
||||
move.l 0(a2,d2),d7 * get 1st seg start
|
||||
cmp.l 0(a2,d3),d7 * is 1st seg above 2nd seg?
|
||||
bge conf1
|
||||
add.l 0(a3,d2),d7 * yes, find top of 1st seg
|
||||
cmp.l 0(a2,d3),d7 * above start of 2nd seg?
|
||||
bgt confbd * if yes, we have a conflict
|
||||
rts * else, return good
|
||||
conf1:
|
||||
move.l 0(a2,d3),d7
|
||||
add.l 0(a3,d3),d7 * find top of 2nd seg
|
||||
cmp.l 0(a2,d2),d7 * above start of 1st seg?
|
||||
ble confgd * if no, we're ok
|
||||
confbd: moveq.l #1,d1
|
||||
confgd: rts
|
||||
|
||||
|
||||
trymemtp:
|
||||
* entry: d2 is a segment nmbr [0..4]
|
||||
* try to fit it at top of memory
|
||||
* uses d3, d6, d7, a5, a6
|
||||
* returns 0 in d1 if ok
|
||||
move.l d2,d6 * d6 is loop counter for chksegs
|
||||
subq #1,d6
|
||||
lsl #2,d2 * multiply d2 by 4
|
||||
move.l HiAdr(a0),d7 * top of mem to d7
|
||||
|
||||
chksegs:
|
||||
* entry: d2 = 4 * (segment nmbr to try)
|
||||
* d6 = (d2/4) - 1 (loop counter)
|
||||
* d7 = address below which to try it
|
||||
* check for conflicts with segments [0..d6] and low memory boundary
|
||||
* return 0 in d1 if no conflicts, else d1 = 1
|
||||
* uses d3, a5, a6
|
||||
movea.l #cseg,a5
|
||||
movea.l #csize,a6
|
||||
sub.l 0(a6,d2),d7 * subtract size of segment to try
|
||||
bclr #0,d7 * make it even address
|
||||
move.l d7,0(a5,d2) * insert address in segment table
|
||||
cmp.l LoAdr(a0),d7 * check for conflict with low memory
|
||||
blt confbd
|
||||
clr.l d3 * check for conflicts with 0..d6
|
||||
chk1:
|
||||
bsr conflict
|
||||
addq.l #4,d3
|
||||
tst.l d1 * conflict with this seg?
|
||||
dbne d6,chk1 * if no, try next
|
||||
rts
|
||||
|
||||
|
||||
fndseg:
|
||||
* entry: d2 is a segment nmbr [0..4]
|
||||
* try to fit segment d2 directly below segments 0..(d2-1)
|
||||
* uses d3-d7, a5, a6
|
||||
move.l d2,d5 * d5 is loop counter to find fit
|
||||
subq.l #1,d5
|
||||
move.l d5,temp
|
||||
lsl.l #2,d2 * multiply segment by 4
|
||||
clr.l d4 * d4 is segment to try to fit below
|
||||
fnd1:
|
||||
move.l temp,d6 * d6 is loop counter for chksegs
|
||||
movea.l #cseg,a5
|
||||
move.l 0(a5,d4),d7 * segment address to d7
|
||||
bsr chksegs * check for conflicts
|
||||
addq.l #4,d4
|
||||
tst.l d1
|
||||
dbeq d5,fnd1 * if conflict, try next
|
||||
rts
|
||||
|
||||
|
||||
setaddr:
|
||||
* Set up load addresses for cseg, dseg, bss, basepg, and stack
|
||||
move.w magic,d6
|
||||
andi.w #$fffe,d6
|
||||
cmpi.w #$601a,d6
|
||||
bne badadr * if magic nmbr <> 601a or 601b, skip
|
||||
move.l bpsize,symsize
|
||||
move.l #256,d7
|
||||
move.l d7,bpsize * base page is 256 bytes
|
||||
lea stksize,a2
|
||||
cmp (a2),d7
|
||||
blt set0 * if stack size < 256, set to 256
|
||||
move.l d7,(a2)
|
||||
set0: cmpi.w #$601b,magic
|
||||
beq seta
|
||||
tst.w rlbflg
|
||||
beq set1
|
||||
seta: move.l tstart,cseg * if not relocatable or hdr = $601b,
|
||||
bra set2 * cseg starts at tstart
|
||||
set1: btst #0,Flags(a0)
|
||||
bne sldhi
|
||||
* relocatable, load low
|
||||
move.l LoAdr(a0),d7
|
||||
add.l #$101,d7 * leave room for base page
|
||||
bclr #0,d7
|
||||
move.l d7,cseg * cseg is bottom of mem + $100 (even boundary)
|
||||
bra set2
|
||||
sldhi:
|
||||
* relocatable, load high
|
||||
move.l HiAdr(a0),d7
|
||||
sub.l csize,d7
|
||||
sub.l dsize,d7
|
||||
sub.l bsize,d7
|
||||
subq.l #4,d7
|
||||
bclr #0,d7 * put cseg at next even address below
|
||||
move.l d7,cseg * high memory - (sum of sizes)
|
||||
set2:
|
||||
* Cseg has been set up. Now do dseg, bseg
|
||||
cmpi.w #$601b,magic
|
||||
bne set3
|
||||
* if magic # = 601b, take addr from hdr
|
||||
move.l dstart,dseg
|
||||
move.l bstart,bseg
|
||||
bra set4
|
||||
set3:
|
||||
* if short header, dseg and bseg follow cseg
|
||||
move.l cseg,d7
|
||||
add.l csize,d7
|
||||
addq.l #1,d7
|
||||
bclr #0,d7
|
||||
move.l d7,dseg
|
||||
add.l dsize,d7
|
||||
addq.l #1,d7
|
||||
bclr #0,d7
|
||||
move.l d7,bseg
|
||||
set4:
|
||||
* cseg, dseg, bseg set up
|
||||
* now find a place for the base page and stack
|
||||
moveq.l #3,d2
|
||||
bsr fndseg * try to fit base page below cseg, dseg, bseg
|
||||
tst.l d1
|
||||
beq set5 * if found, skip
|
||||
moveq.l #3,d2
|
||||
bsr trymemtp * else, try top of memory
|
||||
tst.l d1
|
||||
bne badadr * if fail, exit
|
||||
set5: moveq.l #4,d2
|
||||
bsr trymemtp * try to fit stack at top of memory
|
||||
tst.l d1
|
||||
beq set6 * if ok, skip
|
||||
moveq.l #4,d2
|
||||
bsr fndseg * else, try to fit below other segs
|
||||
tst.l d1
|
||||
bne badadr
|
||||
set6:
|
||||
* now check all segments for conflicts with low and high memory boundaries
|
||||
movea.l #cseg,a5
|
||||
movea.l #csize,a6
|
||||
clr.l d2
|
||||
moveq #4,d3 * loop counter
|
||||
set7: move.l 0(a5,d2),d7 * get segment base
|
||||
cmp.l LoAdr(a0),d7 * above bottom of memory?
|
||||
blt badadr
|
||||
add.l 0(a6,d2),d7 * find top of segment
|
||||
cmp.l HiAdr(a0),d7 * below top of memory?
|
||||
bgt badadr
|
||||
addq.l #4,d2 * point to next segment
|
||||
dbf d3,set7
|
||||
rts
|
||||
badadr: moveq.l #1,d0
|
||||
rts
|
||||
|
||||
|
||||
movebuf:
|
||||
* move (d3) bytes from the base page buffer to (a2)
|
||||
* uses d6
|
||||
movea.l basepg,a1
|
||||
move.l #secsize,d6
|
||||
sub.w bufbyts,d6 * address to move from =
|
||||
adda.w d6,a1 * (basepg) + secsize - (bufbyts)
|
||||
sub.w d3,bufbyts * update # bytes buffered
|
||||
bra moveb2
|
||||
moveb1: move.b (a1)+,(a2)+ * do the move
|
||||
moveb2: dbf d3,moveb1
|
||||
rts
|
||||
|
||||
|
||||
rdtxt:
|
||||
* Read code and data text into memory
|
||||
* during this routine, a2 is always the load address,
|
||||
* d2 is number of bytes left to load
|
||||
moveq #63,d7
|
||||
movea.l LoAdr(a0),a5
|
||||
movea.l basepg,a6
|
||||
rdtxt1: move.w (a5)+,(a6)+ * move header sector to base page
|
||||
dbf d7,rdtxt1
|
||||
move.w #secsize-28,d7
|
||||
cmpi.w #$601a,magic * short header?
|
||||
beq rdtxt2
|
||||
subq.w #8,d7
|
||||
rdtxt2: move.w d7,bufbyts * indicate # bytes of text in buffer
|
||||
move.w #2,loop * do for code, data segments
|
||||
move.l cseg,a2 * start at cseg
|
||||
move.l csize,d2 * for csize bytes
|
||||
rdtxt3:
|
||||
clr.l d3
|
||||
move.w bufbyts,d3
|
||||
cmp.l d2,d3 * # bytes in buffer >= # bytes to load?
|
||||
blt rdtxt4
|
||||
move.l d2,d3
|
||||
bsr movebuf * if yes, move # bytes to load
|
||||
bra finrd
|
||||
rdtxt4:
|
||||
sub.l d3,d2 * if no, update # bytes to load
|
||||
bsr movebuf * move remainder of buffer
|
||||
move.l #secsize,d3 * d3 = secsize fo following loop
|
||||
rdtxt5:
|
||||
cmp.l d3,d2 * have at least one more full sector?
|
||||
blt rdtxt6
|
||||
move.l a2,d1
|
||||
bsr setdma * if yes, set up dma address
|
||||
bsr readseq * read next sector
|
||||
tst.w d1
|
||||
bne rdbad * if no good, exit
|
||||
sub.l d3,d2 * decrement # bytes to load
|
||||
adda.l #secsize,a2 * increment dma address
|
||||
bra rdtxt5
|
||||
rdtxt6:
|
||||
tst.l d2 * any more bytes to read?
|
||||
beq finrd
|
||||
move.l basepg,d1
|
||||
bsr setdma
|
||||
bsr readseq * if yes, read into base page
|
||||
tst.w d1
|
||||
bne rdbad
|
||||
move.w d3,bufbyts * indicate that we've buffered a sector
|
||||
move.l d2,d3
|
||||
bsr movebuf * move remainder of segment
|
||||
finrd:
|
||||
move.l dseg,a2 * set up to load data segment
|
||||
move.l dsize,d2
|
||||
sub.w #1,loop
|
||||
bne rdtxt3
|
||||
move.l bseg,a2 * clear the bss segment
|
||||
move.l bsize,d2
|
||||
beq rdtxt8
|
||||
rdtxt7: clr.b (a2)+
|
||||
subq.l #1,d2
|
||||
bne rdtxt7
|
||||
rdtxt8: rts
|
||||
|
||||
rdbad: moveq.l #2,d0
|
||||
rts
|
||||
|
||||
|
||||
relocword:
|
||||
* relocate word at (a2) based on reloc bits at (a3)
|
||||
* lsb of d2 indicates whether previous word was 1st half of long-word
|
||||
move.w (a3)+,d7 * get relocation info
|
||||
andi.w #7,d7 * strip off symbol table bits
|
||||
lsl #1,d7 * multiply by 2
|
||||
jmp 2(pc,d7)
|
||||
|
||||
bra relabs
|
||||
bra reldata
|
||||
bra relcode
|
||||
bra relbss
|
||||
bra relbad
|
||||
bra rellong
|
||||
bra relbad
|
||||
bra relop
|
||||
|
||||
relbad: move.l (sp)+,d0 * pop return address
|
||||
moveq #3,d0 * return bad relocation to main routine
|
||||
rts
|
||||
|
||||
relabs:
|
||||
relop: bclr #0,d2 * reset long word flag
|
||||
tst.w (a2)+ * point to next word of segment
|
||||
rts
|
||||
|
||||
rellong:
|
||||
bset #0,d2 * set long word flag
|
||||
tst.w (a2)+ * point to next word of segment
|
||||
rts
|
||||
|
||||
reldata:
|
||||
relbss:
|
||||
relcode:
|
||||
bclr #0,d2 * long word flag set?
|
||||
bne relc1 * if yes, skip
|
||||
move.w (a2),d6
|
||||
add.w d5,d6
|
||||
move.w d6,(a2)+
|
||||
rts
|
||||
|
||||
relc1: tst.w -(a2) * point to first word of long
|
||||
move.l (a2),d6
|
||||
add.l d5,d6
|
||||
move.l d6,(a2)+ * note that a2 points past long word
|
||||
rts
|
||||
|
||||
|
||||
reloc:
|
||||
* Modify address references of code and data segments based on relocation bits
|
||||
* During this routine,
|
||||
* a2 points to text file to relocate
|
||||
* a3 points to relocation word in basepg
|
||||
* lsb of d2 is long word flag (set on reloc type 5, reset on next word)
|
||||
* d3 is # words in relocation buffer
|
||||
* d4 is nmbr of words left to relocate
|
||||
* d5 is relocation offset
|
||||
|
||||
move.l basepg,d1
|
||||
bsr setdma * we will always read into base page
|
||||
* skip past the symbol table
|
||||
move.l symsize,d7
|
||||
divu #secsize,d7 * calculate how many sectors to skip
|
||||
* note that max # symbols is 8k, which is 896 sectors of 128 bytes
|
||||
move.w d7,d6 * d6 is nmbr sectors to skip
|
||||
swap d7 * d7 is nmbr bytes to skip
|
||||
move.w bufbyts,d3
|
||||
sub.w d7,d3 * subtract bytes to skip from buffer
|
||||
bge skip1
|
||||
addi #secsize,d3 *if amt in buffer < # bytes to skip,
|
||||
addq #1,d6 * read in 1 extra sector
|
||||
skip1: move.l basepg,a3
|
||||
adda #secsize,a3
|
||||
suba.w d3,a3 * set up a3 to point to buffer
|
||||
lsr #1,d3 * d3 is nmbr words in buffer
|
||||
bra skip3
|
||||
skip2:
|
||||
bsr readseq * read next symbol table sector
|
||||
tst.w d1
|
||||
bne rdbad
|
||||
skip3: dbf d6,skip2
|
||||
* we got past symbol table
|
||||
* a3, d3 are set up
|
||||
move.l cseg,d5
|
||||
move.l d5,a2 * relocate cseg first
|
||||
sub.l tstart,d5 * d5 contains the relocation offset
|
||||
move.l csize,d4 * nmbr of bytes to relocate
|
||||
move.w #2,loop * we're going to relocate 2 segments
|
||||
reloc1:
|
||||
* relocate one segment
|
||||
clr.l d2 * clear long word flag
|
||||
lsr.l #1,d4 * make d4 indicate # words
|
||||
bra reloc4
|
||||
reloc2:
|
||||
subq.w #1,d3
|
||||
bpl reloc3
|
||||
bsr readseq * if no more words in buffer, refill it
|
||||
tst.w d1
|
||||
bne rdbad
|
||||
move.l basepg,a3
|
||||
move.w #(secsize/2)-1,d3
|
||||
reloc3:
|
||||
bsr relocword * relocate one word
|
||||
subq.l #1,d4
|
||||
reloc4:
|
||||
tst.l d4 * any more to relocate in this segment?
|
||||
bne reloc2 * if yes, do it
|
||||
move.l dseg,a2 * else, set up for dseg
|
||||
move.l dsize,d4
|
||||
sub.w #1,loop
|
||||
bne reloc1
|
||||
rts
|
||||
|
||||
|
||||
setrtn:
|
||||
* Set up the return parameters in Ld Parm Blk and Base Page
|
||||
move.l basepg,BasPage(a0)
|
||||
move.l stk,d7
|
||||
add.l stksize,d7
|
||||
bclr #0,d7
|
||||
move.l d7,Stack(a0)
|
||||
move.l basepg,a1
|
||||
move.l LoAdr(a0),(a1)+
|
||||
move.l HiAdr(a0),(a1)+
|
||||
move.l cseg,(a1)+
|
||||
move.l csize,(a1)+
|
||||
move.l dseg,(a1)+
|
||||
move.l dsize,(a1)+
|
||||
move.l bseg,(a1)+
|
||||
move.l bsize,(a1)
|
||||
* find size of free memory after bss segment
|
||||
move.l HiAdr(a0),d7 * d7 contains next segment above bss
|
||||
move.l -4(a1),d6
|
||||
add.l (a1)+,d6 * d6 points to start of free mem after bss
|
||||
movea.l #cseg,a6 * a6 points to segment to try
|
||||
moveq #4,d5 * try for all segments
|
||||
clr.l bseg * but force bss not to appear
|
||||
setb1: cmp.l (a6),d6 * segment above bss?
|
||||
bhi setb2
|
||||
cmp.l (a6),d7 * segment is above bss. Is it below previous?
|
||||
bls setb2
|
||||
move.l (a6),d7
|
||||
setb2: tst.l (a6)+ * point to next segment
|
||||
dbf d5,setb1
|
||||
sub.l d6,d7 * diff between bss top and next segment abv
|
||||
move.l d7,(a1)+
|
||||
* now put disk number that we loaded from into base page
|
||||
movea.l FCBPtr(a0),a2
|
||||
move.b (a2),d0 * get disk select byte
|
||||
bne setb3 * if not auto-select, skip
|
||||
move #25,d0
|
||||
trap #2 * get default disk
|
||||
addq #1,d0 * we want it in range of 1..16
|
||||
setb3: move.b d0,(a1)+ * move disk number into base page
|
||||
clr.l d0 * function OK
|
||||
rts
|
||||
|
||||
|
||||
.bss
|
||||
|
||||
* offsets from start of parameter block
|
||||
FCBPtr = 0
|
||||
LoAdr = 4
|
||||
HiAdr = 8
|
||||
BasPage = 12 * return parameters
|
||||
Stack = 16
|
||||
Flags = 21
|
||||
|
||||
hdr:
|
||||
* load file header is read into here
|
||||
magic: .ds.w 1
|
||||
csize: .ds.l 1
|
||||
dsize: .ds.l 1
|
||||
bsize: .ds.l 1
|
||||
bpsize: .ds.l 1 * symb tbl size is swapped with base page size
|
||||
stksize: .ds.l 1
|
||||
tstart: .ds.l 1
|
||||
rlbflg: .ds.w 1
|
||||
dstart: .ds.l 1
|
||||
bstart: .ds.l 1
|
||||
|
||||
cseg: .ds.l 1
|
||||
dseg: .ds.l 1
|
||||
bseg: .ds.l 1
|
||||
basepg: .ds.l 1
|
||||
stk: .ds.l 1
|
||||
|
||||
symsize: .ds.l 1
|
||||
temp: .ds.l 1
|
||||
loop: .ds.w 1
|
||||
bufbyts: .ds.w 1
|
||||
|
||||
.end
|
||||
57
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/bdos/pktio.h
Normal file
57
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/bdos/pktio.h
Normal file
@@ -0,0 +1,57 @@
|
||||
/********************************************************
|
||||
* *
|
||||
* CP/M-68K header file *
|
||||
* Copyright (c) 1982 by Digital Research, Inc. *
|
||||
* Structure definitions for doing I/O in packets *
|
||||
* *
|
||||
********************************************************/
|
||||
|
||||
/* May use this information structure instead of disk parameter header and
|
||||
disk parameter block in future, but for now it's unused
|
||||
struct dskinfo
|
||||
{
|
||||
UBYTE *dbuffp;
|
||||
UBYTE *csv;
|
||||
UBYTE *alv;
|
||||
UBYTE blksize;
|
||||
UBYTE didummy;
|
||||
UWORD dskmax;
|
||||
UWORD dirmax;
|
||||
UWORD chksize;
|
||||
};
|
||||
*/
|
||||
|
||||
struct iopb
|
||||
{
|
||||
UBYTE iofcn; /* function number, see defines below */
|
||||
UBYTE ioflags; /* used for login flag and write flag */
|
||||
UBYTE devtype; /* device type, see defines below */
|
||||
/* currently unused */
|
||||
UBYTE devnum; /* device number, or, devtype and devnum
|
||||
taken together form int device number */
|
||||
LONG devadr; /* item nmbr on device to start xfer at */
|
||||
/* note -- item is sector for disks, byte for char devs */
|
||||
UWORD xferlen; /* number items to transfer */
|
||||
UBYTE *xferadr; /* memory address to xfer to/from */
|
||||
struct dph *infop; /* pointer to disk parameter header */
|
||||
/* return parm for fcn 0, input for rest */
|
||||
};
|
||||
|
||||
|
||||
/* Definitions for iofcn, the function number */
|
||||
#define sel_info 0 /* select and return info on device */
|
||||
#define read 1
|
||||
#define write 2
|
||||
#define flush 3
|
||||
#define status 4 /* not currently used */
|
||||
|
||||
|
||||
/* Definitions for devtype, the device type */
|
||||
/* This field not currently used */
|
||||
#define console 0
|
||||
#define printer 1
|
||||
#define disk 2
|
||||
#define memory 3 /* gets TPA boundaries */
|
||||
#define redir 4 /* read/write IOByte */
|
||||
#define exc_vec 5 /* set exception vector */
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
$1ar68 rvf $1 cpmlib ccpif.o ccpbdos.o ccpload.o ccp.o bdosif.o conbdos.o
|
||||
$1ar68 rvf $1 cpmlib bdosmisc.o dskutil.o fileio.o bdosrw.o bdosmain.o
|
||||
$1ar68 rvf $1 cpmlib iosys.o pgmld.o exceptn.o filetyps.o stack.o
|
||||
era *.o
|
||||
@@ -0,0 +1,25 @@
|
||||
E:SEND REAR.SUB
|
||||
E:SEND MAKE.SUB
|
||||
E:SEND BDOSDEF.H
|
||||
E:SEND BDOSIF.S
|
||||
E:SEND BDOSINC.H
|
||||
E:SEND BDOSMAIN.C
|
||||
E:SEND BDOSMISC.C
|
||||
E:SEND BDOSRW.C
|
||||
E:SEND BIOSDEF.H
|
||||
E:SEND CONBDOS.C
|
||||
E:SEND CPMC.DOC
|
||||
E:SEND DSKUTIL.C
|
||||
E:SEND EXCEPTN.S
|
||||
E:SEND FILEIO.C
|
||||
E:SEND IOSYS.C
|
||||
E:SEND PGMLD.S
|
||||
E:SEND PKTIO.H
|
||||
E:SEND CCP.C
|
||||
E:SEND CCPBDOS.S
|
||||
E:SEND CCPDEF.H
|
||||
E:SEND CCPIF.S
|
||||
E:SEND CCPLOAD.S
|
||||
E:SEND FILETYPS.S
|
||||
E:SEND STACK.S
|
||||
E:SEND SEND2.SUB
|
||||
15
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/bdos/stack.s
Normal file
15
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/bdos/stack.s
Normal file
@@ -0,0 +1,15 @@
|
||||
*************************************************************************
|
||||
* *
|
||||
* THIS IS THE SYSTEM STACK AREA *
|
||||
* *
|
||||
* *
|
||||
* THIS IS THE DUAL PROCESSOR,ROMABLE CP/M-68K SYSTEM *
|
||||
* ================================================== *
|
||||
*************************************************************************
|
||||
|
||||
.globl stack
|
||||
.bss
|
||||
.ds.l 400
|
||||
stack:
|
||||
.ds.w 1
|
||||
.end
|
||||
26
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/bdos/up2.sub
Normal file
26
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/bdos/up2.sub
Normal file
@@ -0,0 +1,26 @@
|
||||
vax REAR.SUB s
|
||||
vax MAKE.SUB s
|
||||
vax BDOSDEF.H s
|
||||
vax BDOSIF.S s
|
||||
vax BDOSINC.H s
|
||||
vax BDOSMAIN.C s
|
||||
vax BDOSMISC.C s
|
||||
vax BDOSRW.C s
|
||||
vax BIOSDEF.H s
|
||||
vax CONBDOS.C s
|
||||
vax CPMC.DOC s
|
||||
vax DSKUTIL.C s
|
||||
vax EXCEPTN.S s
|
||||
vax FILEIO.C s
|
||||
vax IOSYS.C s
|
||||
vax PGMLD.S s
|
||||
vax PKTIO.H s
|
||||
vax CCP.C s
|
||||
vax CCPBDOS.S s
|
||||
vax CCPDEF.H s
|
||||
vax CCPIF.S s
|
||||
vax CCPLOAD.S s
|
||||
vax FILETYPS.S s
|
||||
vax STACK.S s
|
||||
vax SEND2.SUB s
|
||||
vax up2.sub s
|
||||
@@ -0,0 +1,25 @@
|
||||
$ bdos
|
||||
$ !
|
||||
$ ! VMS command file to build CPMLIB using cross tools
|
||||
$ !
|
||||
$ set noon
|
||||
$ cc68 bdosmain
|
||||
$ cc68 bdosmisc
|
||||
$ cc68 bdosrw
|
||||
$ cc68 conbdos
|
||||
$ cc68 dskutil
|
||||
$ cc68 fileio
|
||||
$ cc68 iosys
|
||||
$ cc68 ccp
|
||||
$ as68 -l -u bdosif.s
|
||||
$ as68 -l -u -n exceptn.s
|
||||
$ as68 -l -u pgmld.s
|
||||
$ as68 -l -u ccpbdos.s
|
||||
$ as68 -l -u ccpif.s
|
||||
$ as68 -l -u ccpload.s
|
||||
$ as68 -l -u filetyps.s
|
||||
$ as68 -l -u stack.s
|
||||
$ ar68 r cpmlib ccpif.o ccpbdos.o ccpload.o ccp.o bdosif.o conbdos.o
|
||||
$ ar68 r cpmlib bdosmisc.o dskutil.o fileio.o bdosrw.o bdosmain.o
|
||||
$ ar68 r cpmlib iosys.o pgmld.o exceptn.o filetyps.o stack.o
|
||||
$ del *.o;*
|
||||
@@ -0,0 +1,30 @@
|
||||
$ set noon
|
||||
$ vsend BDOSDEF.H
|
||||
$ vsend BDOSIF.S
|
||||
$ vsend BDOSINC.H
|
||||
$ vsend BDOSMAIN.C
|
||||
$ vsend BDOSMISC.C
|
||||
$ vsend BDOSRW.C
|
||||
$ vsend BIOSDEF.H
|
||||
$ vsend CCP.C
|
||||
$ vsend CCPBDOS.S
|
||||
$ vsend CCPDEF.H
|
||||
$ vsend CCPIF.S
|
||||
$ vsend CCPLOAD.S
|
||||
$ vsend CONBDOS.C
|
||||
$ vsend CPMC.DOC
|
||||
$ vsend DOWN2.SUB
|
||||
$ vsend DSKUTIL.C
|
||||
$ vsend EXCEPTN.S
|
||||
$ vsend FILEIO.C
|
||||
$ vsend FILETYPS.S
|
||||
$ vsend IOSYS.C
|
||||
$ vsend MAKE.SUB
|
||||
$ vsend PGMLD.S
|
||||
$ vsend PKTIO.H
|
||||
$ vsend REAR.SUB
|
||||
$ vsend SEND2.SUB
|
||||
$ vsend STACK.S
|
||||
$ vsend UP2.SUB
|
||||
$ vsend VMAKE.COM
|
||||
$ vsend done
|
||||
1
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/bin/blah
Normal file
1
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/bin/blah
Normal file
@@ -0,0 +1 @@
|
||||
hello
|
||||
1342
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/bios/bios.c
Normal file
1342
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/bios/bios.c
Normal file
File diff suppressed because it is too large
Load Diff
94
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/bios/biosa.s
Normal file
94
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/bios/biosa.s
Normal file
@@ -0,0 +1,94 @@
|
||||
.text
|
||||
*
|
||||
* Global Code addresses
|
||||
*
|
||||
.globl _init
|
||||
.globl _biosinit
|
||||
.globl _flush
|
||||
.globl _wboot
|
||||
.globl _cbios
|
||||
.globl _dskia
|
||||
.globl _dskic
|
||||
.globl _setimask
|
||||
.globl _ccp
|
||||
.globl cpm * Lowest addr of CP/M
|
||||
.globl _end * Highest addr of CP/M
|
||||
*
|
||||
* Global data addresses
|
||||
*
|
||||
.globl _memtab * memory region table
|
||||
.globl _dpb3 * RAM disk dpb address
|
||||
.globl _memdsk * -> First memory disk location
|
||||
*
|
||||
* Vector Addresses
|
||||
*
|
||||
dskint: .equ $3fc * UDC Interrupt vector
|
||||
trap3: .equ $8c * Trap 3 vector
|
||||
buserr: .equ $8 * Bus error vector
|
||||
*
|
||||
*
|
||||
_init: lea entry,a0
|
||||
move.l a0,trap3
|
||||
lea _dskia,a0
|
||||
move.l a0,dskint
|
||||
*
|
||||
* Auto-Size TPA
|
||||
*
|
||||
lea _memtab,a0 * a0 -> Memory region table
|
||||
move.w #1,(a0)+ * 1 region
|
||||
move.l #$400,(a0)+ * TPA starts at 400
|
||||
move.l #cpm-$408,(a0)+ * Ends where CP/M begins
|
||||
*
|
||||
* Auto-Size RAM disk
|
||||
*
|
||||
move.l buserr,-(sp) * Push bus err vector
|
||||
lea _end,a0 * a0 -> Last location in CP/M
|
||||
add.l #cpm,a0 * Linker doesn't reloc this!!
|
||||
move.l a0,_memdsk * -> first location in RAM disk
|
||||
move.l #quit,buserr * set up vector -> ourselves
|
||||
loop:
|
||||
tst.w (a0)+ * Find
|
||||
bra loop * End of memory
|
||||
quit:
|
||||
add.l #14,a7 * Clear buserr gorp
|
||||
move.l (a7)+,buserr * Pop buserr vector
|
||||
sub.l #_end,a0 * a0 = # bytes in RAM disk
|
||||
sub.l #cpm,a0 * Relocation bug
|
||||
move.l a0,d0 * Into D reg for shift
|
||||
move.l #11,d1 * Load shift count
|
||||
lsr.l d1,d0 * Divide by 2048
|
||||
move.w d0,_dpb3+6 * Load DRM field of dpb
|
||||
|
||||
move #$2000,sr
|
||||
jsr _biosinit
|
||||
clr.l d0
|
||||
rts
|
||||
*
|
||||
_wboot: clr.l d0
|
||||
jmp _ccp
|
||||
*
|
||||
entry: move.l d2,-(a7)
|
||||
move.l d1,-(a7)
|
||||
move.w d0,-(a7)
|
||||
jsr _cbios
|
||||
add #10,a7
|
||||
rte
|
||||
*
|
||||
_dskia: link a6,#0
|
||||
movem.l d0-d7/a0-a5,-(a7)
|
||||
jsr _dskic
|
||||
movem.l (a7)+,d0-d7/a0-a5
|
||||
unlk a6
|
||||
rte
|
||||
*
|
||||
_setimask: move sr,d0
|
||||
lsr #8,d0
|
||||
and.l #7,d0
|
||||
move sr,d1
|
||||
ror.w #8,d1
|
||||
and.w #$fff8,d1
|
||||
add.w 4(a7),d1
|
||||
ror.w #8,d1
|
||||
move d1,sr
|
||||
rts
|
||||
.end
|
||||
@@ -0,0 +1,3 @@
|
||||
#define LOADER 0
|
||||
#define CTLTYPE 0
|
||||
#define MEMDSK 4
|
||||
@@ -0,0 +1,23 @@
|
||||
/************************************************/
|
||||
/* */
|
||||
/* Portable type definitions for use */
|
||||
/* with the C BIOS according to */
|
||||
/* CP/M-68K (tm) standard usage. */
|
||||
/* */
|
||||
/************************************************/
|
||||
|
||||
#define LONG long
|
||||
#define ULONG unsigned long
|
||||
#define WORD short int
|
||||
#define UWORD unsigned short
|
||||
#define BYTE char
|
||||
#define UBYTE unsigned char
|
||||
#define VOID
|
||||
|
||||
#define REG register
|
||||
#define LOCAL auto
|
||||
#define MLOCAL static
|
||||
#define GLOBAL extern
|
||||
#define EXTERN extern
|
||||
|
||||
/************************************************/
|
||||
@@ -0,0 +1,59 @@
|
||||
***************************************
|
||||
* Information to go on the 256 byte *
|
||||
* boot sector of an ExorMacs *
|
||||
***************************************
|
||||
|
||||
.text
|
||||
.dc.l $4000 * starting stack pointer
|
||||
.dc.l start * starting program counter
|
||||
.dc.w 1 * garbage
|
||||
.dc.w 1 * length of SAT
|
||||
.dc.l 2 * secondary directory start
|
||||
.dc.l 0 * primary directory PSN list start
|
||||
.dc.l 0 * start of boot loader
|
||||
.dc.w 26 * length of boot loader
|
||||
.dc.l $0 * boot execution address
|
||||
.dc.l $0 * boot load address
|
||||
.dc.b '9/30' * generation date
|
||||
.dc.b 'CP/M-68K of 9/30/82 ' * volume descriptor
|
||||
.dc.b '0020' * version/revision
|
||||
.dc.w $0a484 * checksum (god help us)
|
||||
.dc.l $0f1e2d3c * diagnostic test pattern
|
||||
.dc.l $4b5a6978
|
||||
.dc.l $8796a5b4
|
||||
.dc.l $c3d2e1f0
|
||||
.dc.l $0f1e2d3c * diagnostic test pattern
|
||||
.dc.l $4b5a6978
|
||||
.dc.l $8796a5b4
|
||||
.dc.l $c3d2e1f0
|
||||
.dc.l $4f8f0f07 * diagnostic test pattern
|
||||
.dc.l $0b0d0e06
|
||||
.dc.l $0a0c0408
|
||||
.dc.l $04020100
|
||||
.dc.l 00, 00, 00, 00 * diagnostic test pattern
|
||||
.dc.l 0 * diagnostic test area directory
|
||||
.dc.l 0 * start of dump area
|
||||
.dc.w 0 * length of dump area
|
||||
.dc.l 0 * start of sector lockout table
|
||||
.dc.w 0 * length of sector lockout table
|
||||
.dc.l 0,0,0,0,0,0,0 * unused, reserved
|
||||
.dc.l 0,0,0,0,0,0
|
||||
.dc.l 0,0,0,0,0,0,0
|
||||
.dc.l 0,0,0,0,0,0
|
||||
.dc.b 'EXORMACS' * let's hear it for Motorola
|
||||
*
|
||||
* end of volume id
|
||||
*
|
||||
* begin boot info proper
|
||||
*
|
||||
.ds.b $300 * skip over exception vectors
|
||||
.even
|
||||
start: move #$2700,sr
|
||||
move.l #$8,a0
|
||||
move.w #253,d0
|
||||
exlp: move.l #expdef,(a0)+
|
||||
dbf d0,exlp
|
||||
jmp grunt
|
||||
expdef: rte
|
||||
grunt: move #$2000,sr
|
||||
.end
|
||||
168
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/bios/cpm.map
Normal file
168
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/bios/cpm.map
Normal file
@@ -0,0 +1,168 @@
|
||||
_submit 4EA2 global bss
|
||||
_morecmd 4EA4 global bss
|
||||
_autost 4E1C global bss
|
||||
_usercmd 4E1D global bss
|
||||
_ccp A4 global text
|
||||
_patch 4EA6 global bss
|
||||
cpm 0 global text
|
||||
_bdos B2 global text
|
||||
_load68k BE global text
|
||||
flags 4F1E global bss
|
||||
TPAB 4F20 global bss
|
||||
_cmd_tbl 4922 global data
|
||||
_msg 4952 global data
|
||||
_msg2 496C global data
|
||||
_msg3 497E global data
|
||||
_msg4 4990 global data
|
||||
_msg5 49A2 global data
|
||||
_msg6 49B8 global data
|
||||
_msg7 49C2 global data
|
||||
_msg8 49DA global data
|
||||
_msg9 49F8 global data
|
||||
_msg10 4A08 global data
|
||||
_msg11 4A1A global data
|
||||
_msg12 4A30 global data
|
||||
_msg13 4A48 global data
|
||||
_lderr1 4A5E global data
|
||||
_lderr2 4A86 global data
|
||||
_lderr3 4AA2 global data
|
||||
_lderror 4AC4 global data
|
||||
_del 4AD8 global data
|
||||
_cr_lf 1AC global text
|
||||
_cpy 1D8 global text
|
||||
_strcmp 1F8 global text
|
||||
_copy_cm 240 global text
|
||||
_prompt 28C global text
|
||||
_echo_cm 334 global text
|
||||
_decode 3A4 global text
|
||||
_fill_fc 7B6 global text
|
||||
_delim 73A global text
|
||||
_check_c 4EA global text
|
||||
_get_cmd 56C global text
|
||||
_scan_cm 64C global text
|
||||
_get_par 68A global text
|
||||
_true_ch 77E global text
|
||||
_too_man 9DA global text
|
||||
_find_co A12 global text
|
||||
_chk_col A4A global text
|
||||
_dir_cmd A9A global text
|
||||
_type_cm CA6 global text
|
||||
_ren_cmd DD8 global text
|
||||
_era_cmd 1124 global text
|
||||
_user_cm 1272 global text
|
||||
_cmd_fil 133E global text
|
||||
_sub_rea 1858 global text
|
||||
_dollar 1886 global text
|
||||
_comment 19CC global text
|
||||
_transla 1AB0 global text
|
||||
_submit_ 1C72 global text
|
||||
_execute 1D8C global text
|
||||
_main 1EDE global text
|
||||
_bios1 2124 global text
|
||||
_bios2 2120 global text
|
||||
_bios3 211A global text
|
||||
_bios4 2114 global text
|
||||
_bios5 210E global text
|
||||
_bios6 2124 global text
|
||||
_traphnd 20D6 global text
|
||||
_swap 2134 global text
|
||||
_udiv 2140 global text
|
||||
_constat 2156 global text
|
||||
_conbrk 2176 global text
|
||||
_conout 220A global text
|
||||
_tabout 2278 global text
|
||||
_cookdou 22B4 global text
|
||||
_getch 22F6 global text
|
||||
_conin 2350 global text
|
||||
_rawconi 238C global text
|
||||
_prt_lin 23D0 global text
|
||||
_newline 23FE global text
|
||||
_backsp 2434 global text
|
||||
_readlin 24AE global text
|
||||
_copyrt 4B6E global data
|
||||
_serial 4B72 global data
|
||||
_bdosini 26AA global text
|
||||
_warmboo 274E global text
|
||||
_prt_err 27B6 global text
|
||||
_abrt_er 27E8 global text
|
||||
_ext_err 27FE global text
|
||||
_ro_err 289E global text
|
||||
_error 2984 global text
|
||||
_setexc 29FC global text
|
||||
_set_tpa 2A70 global text
|
||||
_rdwrt 2ACC global text
|
||||
_dir_rd 2B66 global text
|
||||
_dir_wr 2B84 global text
|
||||
_dchksum 2BD6 global text
|
||||
_dirscan 2C12 global text
|
||||
_setaloc 2D40 global text
|
||||
_clraloc 2D8C global text
|
||||
_chkaloc 2DDE global text
|
||||
_getaloc 2E1C global text
|
||||
_alloc 2E7E global text
|
||||
_seldsk 2EF8 global text
|
||||
_move 3036 global text
|
||||
_match 3060 global text
|
||||
_openfil 30E8 global text
|
||||
_flushit 3148 global text
|
||||
_close 3186 global text
|
||||
_close_f 32CC global text
|
||||
_alltrue 32FE global text
|
||||
_matchit 330A global text
|
||||
_search 3326 global text
|
||||
_create 33B2 global text
|
||||
_delete 3436 global text
|
||||
_rename 34D6 global text
|
||||
_set_att 3550 global text
|
||||
_extsize 35A2 global text
|
||||
_setran 35DA global text
|
||||
_fsize 3618 global text
|
||||
_getsize 3672 global text
|
||||
_free_sp 36E2 global text
|
||||
_blkindx 3750 global text
|
||||
_blknum 379C global text
|
||||
_setblk 37DA global text
|
||||
_do_io 3826 global text
|
||||
_new_ext 3878 global text
|
||||
_calcext 3990 global text
|
||||
_get_rc 39FA global text
|
||||
_bdosrw 3A44 global text
|
||||
__bdos 3C1E global text
|
||||
_tmp_sel 4034 global text
|
||||
_do_phio 4080 global text
|
||||
_pgmld 41B2 global text
|
||||
_initexc 4660 global text
|
||||
_load_tb 4F74 global bss
|
||||
init_tbl 48D0 global text
|
||||
stack 55DC global bss
|
||||
_sub_ind 55DE global bss
|
||||
_log_dsk 55E0 global bss
|
||||
_load_tr 55E2 global bss
|
||||
_gbls 55E4 global bss
|
||||
_crit_ds 56D6 global bss
|
||||
_tail 56D8 global bss
|
||||
_cur_dis 56DC global bss
|
||||
_parm 56DE global bss
|
||||
_dma 5746 global bss
|
||||
_init 57CA global bss
|
||||
_sub_use 57D0 global bss
|
||||
_save_su 57D2 global bss
|
||||
_subfcb 5854 global bss
|
||||
_first_s 5878 global bss
|
||||
_subdma 587A global bss
|
||||
_tpa_hp 58FA global bss
|
||||
_user 58FE global bss
|
||||
_tpa_lp 5900 global bss
|
||||
_tpa_ht 5904 global bss
|
||||
_user_pt 5908 global bss
|
||||
_ro_dsk 590C global bss
|
||||
_tpa_lt 590E global bss
|
||||
_autorom 5912 global bss
|
||||
_subprom 5914 global bss
|
||||
_end_of_ 5916 global bss
|
||||
_subcom 5918 global bss
|
||||
_glb_ind 599A global bss
|
||||
_chain_s 599E global bss
|
||||
_index 59A0 global bss
|
||||
_dirflag 59A2 global bss
|
||||
_cmdfcb 59A4 global bss
|
||||
288
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/bios/eldbios.s
Normal file
288
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/bios/eldbios.s
Normal file
@@ -0,0 +1,288 @@
|
||||
*****************************************************************
|
||||
* *
|
||||
* CP/M-68K Loader BIOS *
|
||||
* Basic Input/Output Subsystem *
|
||||
* For ERG 68000 with Tarbell floppy disk controller *
|
||||
* *
|
||||
*****************************************************************
|
||||
|
||||
|
||||
.globl _bios * declare external entry point
|
||||
|
||||
|
||||
_bios:
|
||||
cmpi #nfuncs,d0
|
||||
bge nogood
|
||||
lsl #2,d0 * multiply bios function by 4
|
||||
movea.l 6(pc,d0),a0 * get handler address
|
||||
jsr (a0) * call handler
|
||||
nogood:
|
||||
rts
|
||||
|
||||
biosbase:
|
||||
.dc.l nogood
|
||||
.dc.l nogood
|
||||
.dc.l constat
|
||||
.dc.l conin
|
||||
.dc.l conout
|
||||
.dc.l nogood
|
||||
.dc.l nogood
|
||||
.dc.l nogood
|
||||
.dc.l home
|
||||
.dc.l seldsk
|
||||
.dc.l settrk
|
||||
.dc.l setsec
|
||||
.dc.l setdma
|
||||
.dc.l read
|
||||
.dc.l nogood
|
||||
.dc.l nogood
|
||||
.dc.l sectran
|
||||
.dc.l setdma
|
||||
.dc.l getseg
|
||||
.dc.l nogood
|
||||
.dc.l nogood
|
||||
.dc.l nogood
|
||||
.dc.l setexc
|
||||
|
||||
nfuncs=(*-biosbase)/4
|
||||
|
||||
|
||||
constat: move.b $ffff01,d0 * get status byte
|
||||
andi.w #2,d0 * data available bit on?
|
||||
beq noton * branch if not
|
||||
moveq.l #$1,d0 * set result to true
|
||||
rts
|
||||
|
||||
noton: clr.l d0 * set result to false
|
||||
rts
|
||||
|
||||
conin: bsr constat * see if key pressed
|
||||
tst d0
|
||||
beq conin * wait until key pressed
|
||||
move.b $ffff00,d0 * get key
|
||||
and.l #$7f,d0 * clear all but low 7 bits
|
||||
rts
|
||||
|
||||
conout: move.b $ffff01,d0 * get status
|
||||
and.b #$1,d0 * check for transmitter buffer empty
|
||||
beq conout * wait until our port has aged...
|
||||
move.b d1,$ffff00 * and output it
|
||||
rts * and exit
|
||||
|
||||
|
||||
*
|
||||
* Disk Handlers for Tarbell 1793 floppy disk controller
|
||||
*
|
||||
maxdsk = 2 * this BIOS supports 2 floppy drives
|
||||
dphlen = 26 * length of disk parameter header
|
||||
|
||||
iobase = $00fffff8 * Tarbell floppy disk port base address
|
||||
dcmd = iobase * output port for command
|
||||
dstat = iobase * input status port
|
||||
dtrk = iobase+1 * disk track port
|
||||
dsect = iobase+2 * disk sector port
|
||||
ddata = iobase+3 * disk data port
|
||||
dwait = iobase+4 * input port to wait for op finished
|
||||
dcntrl = iobase+4 * output control port for drive selection
|
||||
|
||||
|
||||
home: clr.b track
|
||||
rts
|
||||
|
||||
seldsk:
|
||||
* select disk A
|
||||
clr.b seldrv * select drive A
|
||||
clr.b selcode * select code is 00 for drv 0, $10 for drv 1
|
||||
move.l #dph0,d0
|
||||
selrtn: rts
|
||||
|
||||
settrk: move.b d1,track
|
||||
rts
|
||||
|
||||
setsec: move.b d1,sector
|
||||
rts
|
||||
|
||||
sectran:
|
||||
* translate sector in d1 with translate table pointed to by d2
|
||||
* result in d0
|
||||
movea.l d2,a0
|
||||
ext.l d1
|
||||
move.b #0(a0,d1),d0
|
||||
ext.l d0
|
||||
rts
|
||||
|
||||
setdma:
|
||||
move.l d1,dma
|
||||
rts
|
||||
|
||||
read:
|
||||
* Read one sector from requested disk, track, sector to dma address
|
||||
* Retry if necessary, return in d0 00 if ok, else non-zero
|
||||
move.b #10,errcnt * set up retry counter
|
||||
rretry:
|
||||
bsr setup
|
||||
ori #$88,d3 * OR read command with head load bit
|
||||
move.b d3,dcmd * output it to FDC
|
||||
rloop: btst #7,dwait
|
||||
beq rdone * if end of read, exit
|
||||
move.b ddata,(a0)+ * else, move next byte of data
|
||||
bra rloop
|
||||
rdone:
|
||||
bsr rstatus * get FDC status
|
||||
bne rerror
|
||||
clr.l d0
|
||||
rts
|
||||
rerror: bsr errchk * go to error handler
|
||||
subq.b #1,errcnt
|
||||
bne rretry
|
||||
move.l #$ffffffff,d0
|
||||
rts
|
||||
|
||||
|
||||
setup:
|
||||
* common read and write setup code
|
||||
* select disk, set track, set sector were all deferred until now
|
||||
move.b #$d0,dcmd * clear controller, get status
|
||||
move.b curdrv,d3
|
||||
cmp.b seldrv,d3
|
||||
bne newdrive * if drive not selected, do it
|
||||
move.b track,d3
|
||||
cmp.b oldtrk,d3
|
||||
bne newtrk * if not on right track, do it
|
||||
clr.l d3 * if head already loaded, no head load delay
|
||||
btst #5,dstat * if head unloaded, treat as new disk
|
||||
bne sexit
|
||||
newdrive:
|
||||
move.b selcode,dcntrl * select the drive
|
||||
move.b seldrv,curdrv
|
||||
newtrk:
|
||||
bsr chkseek * seek to correct track if required
|
||||
moveq #4,d3 * force head load delay
|
||||
sexit:
|
||||
move.b sector,dsect * set up sector number
|
||||
move.b track,dtrk * set up track number
|
||||
move.l dma,a0 * dma address to a0
|
||||
rts
|
||||
|
||||
errchk:
|
||||
btst.b #4,d7
|
||||
bne chkseek * if record not found error, reseek
|
||||
rts
|
||||
|
||||
chkseek:
|
||||
* check for correct track, seek if necessary
|
||||
bsr readid * find out what track we're on
|
||||
beq chks1 * if read id ok, skip restore code
|
||||
restore:
|
||||
* home the drive and reseek to correct track
|
||||
move.b #$0B,dcmd * restore command to command port
|
||||
rstwait:
|
||||
btst #7,dwait
|
||||
bne rstwait * loop until restore completed
|
||||
btst #2,dstat
|
||||
beq restore * if not at track 0, try again
|
||||
clr.l d3 * track number returned in d3 from readid
|
||||
chks1:
|
||||
move.b d3,dtrk * update track register in FDC
|
||||
move.b track,oldtrk * update oldtrk
|
||||
cmp.b track,d3 * are we at right track?
|
||||
beq chkdone * if yes, exit
|
||||
move.b track,ddata * else, put desired track in data reg of FDC
|
||||
move.b #$18,dcmd * and issue a seek command
|
||||
chks2: btst #7,dwait
|
||||
bne chks2 * loop until seek complete
|
||||
move.b dstat,d3 * read status to clear FDC
|
||||
chkdone:
|
||||
rts
|
||||
|
||||
readid:
|
||||
* read track id, return track number in d3
|
||||
move.b #$c4,dcmd * issue read id command
|
||||
move.b dwait,d7 * wait for intrq
|
||||
move.b ddata,d3 * track byte to d3
|
||||
rid2:
|
||||
btst #7,dwait
|
||||
beq rstatus * wait for intrq
|
||||
move.b ddata,d7 * read another byte
|
||||
bra rid2 * and loop
|
||||
rstatus:
|
||||
move.b dstat,d7
|
||||
andi.b #$9d,d7 * set condition codes
|
||||
rts
|
||||
|
||||
|
||||
getseg:
|
||||
move.l #memrgn,d0 * return address of mem region table
|
||||
rts
|
||||
|
||||
|
||||
setexc:
|
||||
andi.l #$ff,d1 * do only for exceptions 0 - 255
|
||||
lsl #2,d1 * multiply exception number by 4
|
||||
movea.l d1,a0
|
||||
move.l (a0),d0 * return old vector value
|
||||
move.l d2,(a0) * insert new vector
|
||||
rts
|
||||
|
||||
|
||||
.data
|
||||
|
||||
seldrv: .dc.b $ff * drive requested by seldsk
|
||||
curdrv: .dc.b $ff * currently selected drive
|
||||
|
||||
track: .dc.b 0 * track requested by settrk
|
||||
oldtrk: .dc.b 0 * track we were on
|
||||
|
||||
sector: .dc.w 0
|
||||
dma: .dc.l 0
|
||||
selcode: .dc.b 0 * drive select code
|
||||
|
||||
errcnt: .dc.b 10 * retry counter
|
||||
|
||||
memrgn: .dc.w 1 * 1 memory region
|
||||
.dc.l $18000 * load the system at 18000 hex
|
||||
.dc.l $8000
|
||||
|
||||
|
||||
* disk parameter headers
|
||||
|
||||
dph0: .dc.l xlt
|
||||
.dc.w 0 * dummy
|
||||
.dc.w 0
|
||||
.dc.w 0
|
||||
.dc.l dirbuf * ptr to directory buffer
|
||||
.dc.l dpb * ptr to disk parameter block
|
||||
.dc.l 0 * ptr to check vector
|
||||
.dc.l 0 * ptr to allocation vector
|
||||
|
||||
|
||||
* disk parameter block
|
||||
|
||||
dpb: .dc.w 26 * sectors per track
|
||||
.dc.b 3 * block shift
|
||||
.dc.b 7 * block mask
|
||||
.dc.b 0 * extent mask
|
||||
.dc.b 0 * dummy fill
|
||||
.dc.w 242 * disk size
|
||||
.dc.w 63 * 64 directory entries
|
||||
.dc.w $c000 * directory mask
|
||||
.dc.w 16 * directory check size
|
||||
.dc.w 2 * track offset
|
||||
|
||||
* sector translate table
|
||||
|
||||
xlt: .dc.b 1, 7,13,19
|
||||
.dc.b 25, 5,11,17
|
||||
.dc.b 23, 3, 9,15
|
||||
.dc.b 21, 2, 8,14
|
||||
.dc.b 20,26, 6,12
|
||||
.dc.b 18,24, 4,10
|
||||
.dc.b 16,22
|
||||
|
||||
|
||||
.bss
|
||||
|
||||
dirbuf: .ds.b 128 * directory buffer
|
||||
|
||||
|
||||
.end
|
||||
360
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/bios/ergbios.s
Normal file
360
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/bios/ergbios.s
Normal file
@@ -0,0 +1,360 @@
|
||||
*****************************************************************
|
||||
* *
|
||||
* CP/M-68K BIOS *
|
||||
* Basic Input/Output Subsystem *
|
||||
* For ERG 68000 with Tarbell floppy disk controller *
|
||||
* *
|
||||
*****************************************************************
|
||||
|
||||
.globl _init * bios initialization entry point
|
||||
.globl _ccp * ccp entry point
|
||||
|
||||
_init: move.l #traphndl,$8c * set up trap #3 handler
|
||||
clr.l d0 * log on disk A, user 0
|
||||
rts
|
||||
|
||||
traphndl:
|
||||
cmpi #nfuncs,d0
|
||||
bcc trapng
|
||||
lsl #2,d0 * multiply bios function by 4
|
||||
movea.l 6(pc,d0),a0 * get handler address
|
||||
jsr (a0) * call handler
|
||||
trapng:
|
||||
rte
|
||||
|
||||
biosbase:
|
||||
.dc.l _init
|
||||
.dc.l wboot
|
||||
.dc.l constat
|
||||
.dc.l conin
|
||||
.dc.l conout
|
||||
.dc.l lstout
|
||||
.dc.l pun
|
||||
.dc.l rdr
|
||||
.dc.l home
|
||||
.dc.l seldsk
|
||||
.dc.l settrk
|
||||
.dc.l setsec
|
||||
.dc.l setdma
|
||||
.dc.l read
|
||||
.dc.l write
|
||||
.dc.l listst
|
||||
.dc.l sectran
|
||||
.dc.l setdma
|
||||
.dc.l getseg
|
||||
.dc.l getiob
|
||||
.dc.l setiob
|
||||
.dc.l flush
|
||||
.dc.l setexc
|
||||
|
||||
nfuncs=(*-biosbase)/4
|
||||
|
||||
wboot: jmp _ccp
|
||||
|
||||
constat: move.b $ffff01,d0 * get status byte
|
||||
andi.w #2,d0 * data available bit on?
|
||||
beq noton * branch if not
|
||||
moveq.l #$1,d0 * set result to true
|
||||
rts
|
||||
|
||||
noton: clr.l d0 * set result to false
|
||||
rts
|
||||
|
||||
conin: bsr constat * see if key pressed
|
||||
tst d0
|
||||
beq conin * wait until key pressed
|
||||
move.b $ffff00,d0 * get key
|
||||
and.l #$7f,d0 * clear all but low 7 bits
|
||||
cmpi.b #1,d0
|
||||
beq break
|
||||
rts
|
||||
break:
|
||||
trap $f
|
||||
.dc.w 0 * return to MACSBUG
|
||||
rts
|
||||
|
||||
conout: move.b $ffff01,d0 * get status
|
||||
and.b #$1,d0 * check for transmitter buffer empty
|
||||
beq conout * wait until our port has aged...
|
||||
move.b d1,$ffff00 * and output it
|
||||
rts * and exit
|
||||
|
||||
lstout: rts
|
||||
|
||||
pun: rts
|
||||
|
||||
rdr: rts
|
||||
|
||||
listst: move.b #$ff,d0
|
||||
rts
|
||||
|
||||
*
|
||||
* Disk Handlers for Tarbell 1793 floppy disk controller
|
||||
*
|
||||
maxdsk = 2 * this BIOS supports 2 floppy drives
|
||||
dphlen = 26 * length of disk parameter header
|
||||
|
||||
iobase = $00fffff8 * Tarbell floppy disk port base address
|
||||
dcmd = iobase * output port for command
|
||||
dstat = iobase * input status port
|
||||
dtrk = iobase+1 * disk track port
|
||||
dsect = iobase+2 * disk sector port
|
||||
ddata = iobase+3 * disk data port
|
||||
dwait = iobase+4 * input port to wait for op finished
|
||||
dcntrl = iobase+4 * output control port for drive selection
|
||||
|
||||
|
||||
home: clr.b track
|
||||
rts
|
||||
|
||||
seldsk:
|
||||
* select disk given by register d1.b
|
||||
moveq #0,d0
|
||||
cmp.b #maxdsk,d1 * valid drive number?
|
||||
bpl selrtn * if no, return 0 in d0
|
||||
move.b d1,seldrv * else, save drive number
|
||||
lsl.b #4,d1
|
||||
move.b d1,selcode * select code is 00 for drv 0, $10 for drv 1
|
||||
move.b seldrv,d0
|
||||
mulu #dphlen,d0
|
||||
add.l #dph0,d0 * point d0 at correct dph
|
||||
selrtn: rts
|
||||
|
||||
settrk: move.b d1,track
|
||||
rts
|
||||
|
||||
setsec: move.b d1,sector
|
||||
rts
|
||||
|
||||
sectran:
|
||||
* translate sector in d1 with translate table pointed to by d2
|
||||
* result in d0
|
||||
movea.l d2,a0
|
||||
ext.l d1
|
||||
move.b #0(a0,d1),d0
|
||||
ext.l d0
|
||||
rts
|
||||
|
||||
setdma:
|
||||
move.l d1,dma
|
||||
rts
|
||||
|
||||
read:
|
||||
* Read one sector from requested disk, track, sector to dma address
|
||||
* Retry if necessary, return in d0 00 if ok, else non-zero
|
||||
move.b #10,errcnt * set up retry counter
|
||||
rretry:
|
||||
bsr setup
|
||||
ori #$88,d3 * OR read command with head load bit
|
||||
move.b d3,dcmd * output it to FDC
|
||||
rloop: btst #7,dwait
|
||||
beq rdone * if end of read, exit
|
||||
move.b ddata,(a0)+ * else, move next byte of data
|
||||
bra rloop
|
||||
rdone:
|
||||
bsr rstatus * get FDC status
|
||||
bne rerror
|
||||
clr.l d0
|
||||
rts
|
||||
rerror: bsr errchk * go to error handler
|
||||
subq.b #1,errcnt
|
||||
bne rretry
|
||||
move.l #$ffffffff,d0
|
||||
rts
|
||||
|
||||
write:
|
||||
* Write one sector to requested disk, track, sector from dma address
|
||||
* Retry if necessary, return in d0 00 if ok, else non-zero
|
||||
move.b #10,errcnt * set up retry counter
|
||||
wretry:
|
||||
bsr setup
|
||||
ori #$a8,d3 * OR write command with head load bit
|
||||
move.b d3,dcmd * output it to FDC
|
||||
wloop: btst #7,dwait
|
||||
beq wdone * if end of read, exit
|
||||
move.b (a0)+,ddata * else, move next byte of data
|
||||
bra wloop
|
||||
wdone:
|
||||
bsr rstatus * get FDC status
|
||||
bne werror
|
||||
clr.l d0
|
||||
rts
|
||||
werror: bsr errchk * go to error handler
|
||||
subq.b #1,errcnt
|
||||
bne wretry
|
||||
move.l #$ffffffff,d0
|
||||
rts
|
||||
|
||||
setup:
|
||||
* common read and write setup code
|
||||
* select disk, set track, set sector were all deferred until now
|
||||
move.b #$d0,dcmd * clear controller, get status
|
||||
move.b curdrv,d3
|
||||
cmp.b seldrv,d3
|
||||
bne newdrive * if drive not selected, do it
|
||||
move.b track,d3
|
||||
cmp.b oldtrk,d3
|
||||
bne newtrk * if not on right track, do it
|
||||
clr.l d3 * if head already loaded, no head load delay
|
||||
btst #5,dstat * if head unloaded, treat as new disk
|
||||
bne sexit
|
||||
newdrive:
|
||||
move.b selcode,dcntrl * select the drive
|
||||
move.b seldrv,curdrv
|
||||
newtrk:
|
||||
bsr chkseek * seek to correct track if required
|
||||
moveq #4,d3 * force head load delay
|
||||
sexit:
|
||||
move.b sector,dsect * set up sector number
|
||||
move.b track,dtrk * set up track number
|
||||
move.l dma,a0 * dma address to a0
|
||||
rts
|
||||
|
||||
errchk:
|
||||
btst.b #4,d7
|
||||
bne chkseek * if record not found error, reseek
|
||||
rts
|
||||
|
||||
chkseek:
|
||||
* check for correct track, seek if necessary
|
||||
bsr readid * find out what track we're on
|
||||
beq chks1 * if read id ok, skip restore code
|
||||
restore:
|
||||
* home the drive and reseek to correct track
|
||||
move.b #$0B,dcmd * restore command to command port
|
||||
rstwait:
|
||||
btst #7,dwait
|
||||
bne rstwait * loop until restore completed
|
||||
btst #2,dstat
|
||||
beq restore * if not at track 0, try again
|
||||
clr.l d3 * track number returned in d3 from readid
|
||||
chks1:
|
||||
move.b d3,dtrk * update track register in FDC
|
||||
move.b track,oldtrk * update oldtrk
|
||||
cmp.b track,d3 * are we at right track?
|
||||
beq chkdone * if yes, exit
|
||||
move.b track,ddata * else, put desired track in data reg of FDC
|
||||
move.b #$18,dcmd * and issue a seek command
|
||||
chks2: btst #7,dwait
|
||||
bne chks2 * loop until seek complete
|
||||
move.b dstat,d3 * read status to clear FDC
|
||||
chkdone:
|
||||
rts
|
||||
|
||||
readid:
|
||||
* read track id, return track number in d3
|
||||
move.b #$c4,dcmd * issue read id command
|
||||
move.b dwait,d7 * wait for intrq
|
||||
move.b ddata,d3 * track byte to d3
|
||||
rid2:
|
||||
btst #7,dwait
|
||||
beq rstatus * wait for intrq
|
||||
move.b ddata,d7 * read another byte
|
||||
bra rid2 * and loop
|
||||
rstatus:
|
||||
move.b dstat,d7
|
||||
andi.b #$9d,d7 * set condition codes
|
||||
rts
|
||||
|
||||
|
||||
flush:
|
||||
clr.l d0 * return successful
|
||||
rts
|
||||
|
||||
getseg:
|
||||
move.l #memrgn,d0 * return address of mem region table
|
||||
rts
|
||||
|
||||
getiob:
|
||||
rts
|
||||
|
||||
setiob:
|
||||
rts
|
||||
|
||||
setexc:
|
||||
andi.l #$ff,d1 * do only for exceptions 0 - 255
|
||||
cmpi #47,d1
|
||||
beq noset * this BIOS doesn't set Trap 15
|
||||
cmpi #9,d1 * or Trace
|
||||
beq noset
|
||||
lsl #2,d1 * multiply exception nmbr by 4
|
||||
movea.l d1,a0
|
||||
move.l (a0),d0 * return old vector value
|
||||
move.l d2,(a0) * insert new vector
|
||||
noset: rts
|
||||
|
||||
|
||||
.data
|
||||
|
||||
seldrv: .dc.b $ff * drive requested by seldsk
|
||||
curdrv: .dc.b $ff * currently selected drive
|
||||
|
||||
track: .dc.b 0 * track requested by settrk
|
||||
oldtrk: .dc.b 0 * track we were on
|
||||
|
||||
sector: .dc.w 0
|
||||
dma: .dc.l 0
|
||||
selcode: .dc.b 0 * drive select code
|
||||
|
||||
errcnt: .dc.b 10 * retry counter
|
||||
|
||||
memrgn: .dc.w 1 * 1 memory region
|
||||
.dc.l $800 * starts at 800 hex
|
||||
.dc.l $17800 * goes until 18000 hex
|
||||
|
||||
|
||||
* disk parameter headers
|
||||
|
||||
dph0: .dc.l xlt
|
||||
.dc.w 0 * dummy
|
||||
.dc.w 0
|
||||
.dc.w 0
|
||||
.dc.l dirbuf * ptr to directory buffer
|
||||
.dc.l dpb * ptr to disk parameter block
|
||||
.dc.l ckv0 * ptr to check vector
|
||||
.dc.l alv0 * ptr to allocation vector
|
||||
|
||||
dph1: .dc.l xlt
|
||||
.dc.w 0 * dummy
|
||||
.dc.w 0
|
||||
.dc.w 0
|
||||
.dc.l dirbuf * ptr to directory buffer
|
||||
.dc.l dpb * ptr to disk parameter block
|
||||
.dc.l ckv1 * ptr to check vector
|
||||
.dc.l alv1 * ptr to allocation vector
|
||||
|
||||
* disk parameter block
|
||||
|
||||
dpb: .dc.w 26 * sectors per track
|
||||
.dc.b 3 * block shift
|
||||
.dc.b 7 * block mask
|
||||
.dc.b 0 * extent mask
|
||||
.dc.b 0 * dummy fill
|
||||
.dc.w 242 * disk size
|
||||
.dc.w 63 * 64 directory entries
|
||||
.dc.w $c000 * directory mask
|
||||
.dc.w 16 * directory check size
|
||||
.dc.w 2 * track offset
|
||||
|
||||
* sector translate table
|
||||
|
||||
xlt: .dc.b 1, 7,13,19
|
||||
.dc.b 25, 5,11,17
|
||||
.dc.b 23, 3, 9,15
|
||||
.dc.b 21, 2, 8,14
|
||||
.dc.b 20,26, 6,12
|
||||
.dc.b 18,24, 4,10
|
||||
.dc.b 16,22
|
||||
|
||||
|
||||
.bss
|
||||
|
||||
dirbuf: .ds.b 128 * directory buffer
|
||||
|
||||
ckv0: .ds.b 16 * check vector
|
||||
ckv1: .ds.b 16
|
||||
|
||||
alv0: .ds.b 32 * allocation vector
|
||||
alv1: .ds.b 32
|
||||
|
||||
.end
|
||||
@@ -0,0 +1 @@
|
||||
lo68 -r -o cpm.rel -ucpm cpmlib biosa.o bios.o
|
||||
@@ -0,0 +1,41 @@
|
||||
.text
|
||||
.globl _bios
|
||||
.globl _biosinit
|
||||
.globl _cbios
|
||||
.globl _dskia
|
||||
.globl _dskic
|
||||
.globl _setimask
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
_bios: link a6,#0
|
||||
move.l d2,-(a7)
|
||||
move.l d1,-(a7)
|
||||
move.w d0,-(a7)
|
||||
move #$2000,sr
|
||||
lea _dskia,a0
|
||||
move.l a0,$3fc
|
||||
jsr _cbios
|
||||
unlk a6
|
||||
rts
|
||||
*
|
||||
_dskia: link a6,#0
|
||||
movem.l d0-d7/a0-a5,-(a7)
|
||||
jsr _dskic
|
||||
movem.l (a7)+,d0-d7/a0-a5
|
||||
unlk a6
|
||||
rte
|
||||
*
|
||||
_setimask: move sr,d0
|
||||
lsr #8,d0
|
||||
and.l #7,d0
|
||||
move sr,d1
|
||||
ror.w #8,d1
|
||||
and.w #$fff8,d1
|
||||
add.w 4(a7),d1
|
||||
ror.w #8,d1
|
||||
move d1,sr
|
||||
rts
|
||||
*
|
||||
.end
|
||||
@@ -0,0 +1,3 @@
|
||||
#define LOADER 1
|
||||
#define CTLTYPE 0
|
||||
#define MEMDSK 0
|
||||
@@ -0,0 +1,9 @@
|
||||
pip biostype.h=loadbios.h
|
||||
cp68 bios.c bios.i
|
||||
c068 bios.i bios.ic bios.st
|
||||
era bios.i
|
||||
era bios.st
|
||||
c168 bios.ic bios.s -l
|
||||
as68 -u -l bios.s
|
||||
as68 -u -l ldbiosa.s
|
||||
pip ldbios.o=bios.o
|
||||
@@ -0,0 +1 @@
|
||||
lo68 -s -t0 -uldr -o cpmldr.sys booter.o ldrlib ldbiosa.o ldbios.o
|
||||
@@ -0,0 +1,3 @@
|
||||
#define LOADER 0
|
||||
#define CTLTYPE 0
|
||||
#define MEMDSK 4
|
||||
@@ -0,0 +1,8 @@
|
||||
pip biostype.h=normbios.h
|
||||
cp68 bios.c bios.i
|
||||
c068 bios.i bios.ic bios.st
|
||||
era bios.i
|
||||
era bios.st
|
||||
c168 bios.ic bios.s -l
|
||||
as68 -u -l bios.s
|
||||
as68 -u -l biosa.s
|
||||
194
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/bios/putboot.s
Normal file
194
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/bios/putboot.s
Normal file
@@ -0,0 +1,194 @@
|
||||
*********************************************************
|
||||
* *
|
||||
* Program to Write Boot Tracks for CP/M-68K (tm) *
|
||||
* *
|
||||
* Copyright Digital Research 1982 *
|
||||
* *
|
||||
*********************************************************
|
||||
*
|
||||
*
|
||||
*
|
||||
prntstr = 9 BDOS Functions
|
||||
dseldsk = 14
|
||||
open = 15
|
||||
readseq = 20
|
||||
dsetdma = 26
|
||||
*
|
||||
seldsk = 9 BIOS Functions
|
||||
settrk = 10
|
||||
setsec = 11
|
||||
isetdma = 12
|
||||
write = 14
|
||||
sectran = 16
|
||||
flush = 21
|
||||
*
|
||||
bufcnt = $80
|
||||
bufsize = $80*bufcnt
|
||||
*
|
||||
.text
|
||||
*
|
||||
start: link a6,#0
|
||||
move.l 8(a6),a0 base page address
|
||||
lea $5c(a0),a1
|
||||
move.l a1,fcb
|
||||
clr.b hflag
|
||||
add #$81,a0 first character of command tail
|
||||
scan: cmpi.b #$20,(a0)+ skip over blanks
|
||||
beq scan
|
||||
sub.l #1,a0
|
||||
scan1: tst.b (a0)
|
||||
beq erxit
|
||||
cmpi.b #$2d,(a0)+ check for -H flag
|
||||
bne nohyph
|
||||
cmpi.b #$48,(a0)+
|
||||
bne erxit
|
||||
tst.b hflag
|
||||
bne erxit
|
||||
move.b #$ff,hflag
|
||||
sub.l #$24,fcb change to 2nd default fcb
|
||||
bra scan
|
||||
nohyph: cmpi.b #$20,(a0)
|
||||
bne scan1
|
||||
scan2: cmpi.b #$20,(a0)+
|
||||
beq scan2
|
||||
cmpi.b #$61,-(a0) get disk letter
|
||||
blt upper upshift
|
||||
sub #$20,(a0)
|
||||
upper: cmpi.b #$41,(a0) compare with range A - P
|
||||
blt erxit
|
||||
cmpi.b #$50,(a0)
|
||||
bgt erxit
|
||||
move.b (a0),d0
|
||||
ext.w d0 put disk letter into range 0 - 15
|
||||
sub.w #$41,d0
|
||||
move.w d0,dsk
|
||||
*
|
||||
* open file to copy
|
||||
*
|
||||
move.w #open,d0
|
||||
move.l fcb,d1
|
||||
trap #2
|
||||
cmpi.w #$00ff,d0
|
||||
bne openok
|
||||
move.l #opnfl,d1
|
||||
jmp erx
|
||||
openok: move.l fcb,a0
|
||||
clr.b 32(a0)
|
||||
*
|
||||
* read
|
||||
*
|
||||
move.l #buf,d2
|
||||
clr.w count
|
||||
rloop: move.w #dsetdma,d0
|
||||
move.l d2,d1
|
||||
trap #2
|
||||
move.w #readseq,d0
|
||||
move.l fcb,d1
|
||||
trap #2
|
||||
tst.w d0
|
||||
bne wrtout
|
||||
add.l #128,d2
|
||||
add.w #1,count
|
||||
cmpi.w #bufcnt,count
|
||||
bgt bufoflx
|
||||
bra rloop
|
||||
*
|
||||
* write
|
||||
*
|
||||
wrtout: move.w #seldsk,d0 select the disk
|
||||
move.w dsk,d1
|
||||
clr.b d2
|
||||
trap #3
|
||||
tst.l d0 check for select error
|
||||
beq selerx
|
||||
move.l d0,a0
|
||||
move.l 14(a0),a0 get DPB address
|
||||
move.w (a0),spt get sectors per track
|
||||
move.w 14(a0),off get offset
|
||||
clr.w trk start at trk 0
|
||||
move.w #1,sect start at sector 1
|
||||
lea buf,a0
|
||||
tst.b hflag
|
||||
bne wrt1
|
||||
cmpi.w #$601a,(a0)
|
||||
bne wrt1
|
||||
add.l #28,a0
|
||||
wrt1: move.l a0,bufp
|
||||
*
|
||||
wloop: tst.w count
|
||||
beq exit
|
||||
move.w sect,d1 check for end-of-track
|
||||
cmp.w spt,d1
|
||||
ble sok
|
||||
move.w #1,sect advance to new track
|
||||
move.w trk,d0
|
||||
add.w #1,d0
|
||||
move.w d0,trk
|
||||
cmp.w off,d0
|
||||
bge oflex
|
||||
sok: move.w #settrk,d0 set the track
|
||||
move.w trk,d1
|
||||
trap #3
|
||||
move.w sect,d1 set sector
|
||||
move.w #setsec,d0
|
||||
trap #3
|
||||
move.w #isetdma,d0 set up dma address for write
|
||||
move.l bufp,d1
|
||||
trap #3
|
||||
move.w #write,d0 and write
|
||||
clr.w d1
|
||||
trap #3
|
||||
tst.w d0 check for write error
|
||||
bne wrterx
|
||||
add #1,sect increment sector number
|
||||
sub #1,count
|
||||
add.l #128,bufp
|
||||
bra wloop
|
||||
*
|
||||
exit: move.w #flush,d0 exit location - flush bios buffers
|
||||
trap #3
|
||||
unlk a6
|
||||
rts and exit to CCP
|
||||
*
|
||||
erxit: move.l #erstr,d1 miscellaneous errors
|
||||
erx: move.w #prntstr,d0 print error message and exit
|
||||
trap #2
|
||||
bra exit
|
||||
*
|
||||
selerx: move.l #selstr,d1 disk select error
|
||||
bra erx
|
||||
wrterx: move.l #wrtstr,d1 disk write error
|
||||
bra erx
|
||||
bufoflx: move.l #bufofl,d1 buffer overflow
|
||||
bra erx
|
||||
oflex: move.l #trkofl,d1
|
||||
bra erx
|
||||
*
|
||||
*
|
||||
.bss
|
||||
*
|
||||
.even
|
||||
*
|
||||
buf: .ds.b bufsize+128
|
||||
*
|
||||
fcb: .ds.l 1 fcb address
|
||||
spt: .ds.w 1 sectors per track
|
||||
sect: .ds.w 1 current sector
|
||||
trk: .ds.w 1 current track
|
||||
dsk: .ds.w 1 selected disk
|
||||
off: .ds.w 1 1st track of non-boot area
|
||||
count: .ds.w 1
|
||||
bufp: .ds.l 1
|
||||
hflag: .ds.b 1
|
||||
*
|
||||
.data
|
||||
*
|
||||
erstr: .dc.b 'Invalid Command Line',13,10,'$'
|
||||
selstr: .dc.b 'Select Error',13,10,'$'
|
||||
wrtstr: .dc.b 'Write Error',13,10,'$'
|
||||
opnfl: .dc.b 'Cannot Open Source File',13,10,'$'
|
||||
bufofl: .dc.b 'Buffer Overflow',13,10,'$'
|
||||
trkofl: .dc.b 'Too Much Data for System Tracks',13,10,'$'
|
||||
*
|
||||
*
|
||||
.end
|
||||
@@ -0,0 +1 @@
|
||||
reloc -b$1 cpm.rel cpm.sys
|
||||
17
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/bios/up1.sub
Normal file
17
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/bios/up1.sub
Normal file
@@ -0,0 +1,17 @@
|
||||
vax biosa.s s
|
||||
vax biostyps.h s
|
||||
vax booter.s s
|
||||
vax bios.c s
|
||||
vax eldbios.s s
|
||||
vax ergbios.s s
|
||||
vax lcpm.sub s
|
||||
vax biostype.h s
|
||||
vax ldbiosa.s s
|
||||
vax loadbios.sub s
|
||||
vax makeldr.sub s
|
||||
vax normbios.h s
|
||||
vax normbios.sub s
|
||||
vax putboot.s s
|
||||
vax relcpm.sub s
|
||||
vax loadbios.h s
|
||||
vax up1.sub s
|
||||
@@ -0,0 +1,14 @@
|
||||
$ bios
|
||||
$ set noon
|
||||
$ !
|
||||
$ ! VMS build file for EXORmacs bios using cross tools
|
||||
$ !
|
||||
$ copy loadbios.h biostype.h
|
||||
$ cc68 bios
|
||||
$ rename bios.o ldbios.o
|
||||
$ as68 -u -l ldbiosa.s
|
||||
$ as68 -u -l booter.s
|
||||
$ copy normbios.h biostype.h
|
||||
$ cc68 bios
|
||||
$ as68 -u -l biosa.s
|
||||
$ pur biostype.h
|
||||
@@ -0,0 +1,20 @@
|
||||
$ set noon
|
||||
$ vsend BIOS.C
|
||||
$ vsend BIOSA.S
|
||||
$ vsend BIOSTYPE.H
|
||||
$ vsend BIOSTYPS.H
|
||||
$ vsend BOOTER.S
|
||||
$ vsend ELDBIOS.S
|
||||
$ vsend ERGBIOS.S
|
||||
$ vsend LCPM.SUB
|
||||
$ vsend LDBIOSA.S
|
||||
$ vsend LOADBIOS.H
|
||||
$ vsend LOADBIOS.SUB
|
||||
$ vsend MAKELDR.SUB
|
||||
$ vsend NORMBIOS.H
|
||||
$ vsend NORMBIOS.SUB
|
||||
$ vsend PUTBOOT.S
|
||||
$ vsend RELCPM.SUB
|
||||
$ vsend UP1.SUB
|
||||
$ vsend VMAKE.COM
|
||||
$ vsend done
|
||||
152
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/boot/bdosdef.h
Normal file
152
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/boot/bdosdef.h
Normal file
@@ -0,0 +1,152 @@
|
||||
|
||||
/********************************************************
|
||||
* *
|
||||
* CP/M-68K header file *
|
||||
* Copyright (c) 1982 by Digital Research, Inc. *
|
||||
* Structure definitions for BDOS globals *
|
||||
* and BDOS data structures *
|
||||
* *
|
||||
********************************************************/
|
||||
|
||||
/**************************************************************************
|
||||
The BDOS data structures, especially those relating to global variables,
|
||||
are structured in a way that hopefully will enable this BDOS, in the future,
|
||||
to easily become a re-entrant multi-tasking file system. Consequently,
|
||||
the BDOS global variables are divided into two classes. Those that are
|
||||
truly global, even in the case of multiple tasks using the file system
|
||||
concurrently, are simply declared as global variables in bdosmain.c.
|
||||
Only a few "globals" are really global in this sense.
|
||||
|
||||
The majority of the "global" variables are actually state variables that
|
||||
relate to the state of the task using the file system. In CP/M-68K, these
|
||||
are "global", since there's only one task, but in a multi-thread model they're
|
||||
not. These type of variables are put into a data structure, with the
|
||||
intention that in the multi-task environment this structure will be based.
|
||||
|
||||
The following declarations take this philosophy into account, and define
|
||||
a simple structure for the single thread environment while leaving the
|
||||
possibilities open for the multi-thread environment.
|
||||
****************************************************************************/
|
||||
|
||||
#define snglthrd TRUE
|
||||
/* TRUE for single-thread environment
|
||||
FALSE to create based structure for re-entrant model */
|
||||
#if snglthrd
|
||||
#define GBL gbls
|
||||
/* In single thread case, GBL just names
|
||||
the structure */
|
||||
#define BSETUP EXTERN struct stvars gbls;
|
||||
/* and BSETUP defines the extern structure */
|
||||
#endif
|
||||
|
||||
#if ! snglthrd
|
||||
#define GBL (*statep)
|
||||
/* If multi-task, state vars are based */
|
||||
#define BSETUP REG struct stvars *statep; \
|
||||
statep = &gbls;
|
||||
/* set up pointer to state variables */
|
||||
/* This is intended as an example to show the intent */
|
||||
#endif
|
||||
|
||||
|
||||
/* Note that there are a few critical regions in the file system that must
|
||||
execute without interruption. They pertain mostly to the manipulation of
|
||||
the allocation vector. This isn't a problem in a single-thread model, but
|
||||
must be provided for in a multi-tasking file system. Consequently, the
|
||||
primitives LOCK and UNLOCK are defined and used where necessary in the
|
||||
file system. For the single thread model, they are null routines */
|
||||
|
||||
#define LOCK /**/
|
||||
#define UNLOCK /**/
|
||||
/* Be sure LOCK and UNLOCK are implemented to allow recursive calls to LOCK.
|
||||
That is, if a process that calls LOCK already owns the lock, let it proceed,
|
||||
but remember that only the outer-most call to UNLOCK really releases the
|
||||
file system. */
|
||||
|
||||
|
||||
#define VERSION 0x2022 /* Version number for CP/M-68K */
|
||||
#define robit 0 /* read-only bit in file type field of fcb */
|
||||
#define SECLEN 128 /* length of a CP/M sector */
|
||||
|
||||
|
||||
/* File Control Block definition */
|
||||
struct fcb
|
||||
{
|
||||
UBYTE drvcode; /* 0 = default drive, 1..16 are drives A..P */
|
||||
UBYTE fname[8]; /* File name (ASCII) */
|
||||
UBYTE ftype[3]; /* File type (ASCII) */
|
||||
UBYTE extent; /* Extent number (bits 0..4 used) */
|
||||
UBYTE s1; /* Reserved */
|
||||
UBYTE s2; /* Module field (bits 0..5), write flag (7) */
|
||||
UBYTE rcdcnt; /* Nmbr rcrds in last block, 0..128 */
|
||||
union
|
||||
{
|
||||
UBYTE small[16]; /* 16 block numbers of 1 byte */
|
||||
WORD big[8]; /* or 8 block numbers of 1 word */
|
||||
} dskmap;
|
||||
UBYTE cur_rec; /* current record field */
|
||||
UBYTE ran0; /* random record field (3 bytes) */
|
||||
UBYTE ran1;
|
||||
UBYTE ran2;
|
||||
};
|
||||
|
||||
|
||||
/* Declaration of directory entry */
|
||||
struct dirent
|
||||
{
|
||||
UBYTE entry; /* 0 - 15 for user numbers, E5 for empty */
|
||||
/* the rest are reserved */
|
||||
UBYTE fname[8]; /* File name (ASCII) */
|
||||
UBYTE ftype[3]; /* File type (ASCII) */
|
||||
UBYTE extent; /* Extent number (bits 0..4 used) */
|
||||
UBYTE s1; /* Reserved */
|
||||
UBYTE s2; /* Module field (bits 0..5), write flag (7) */
|
||||
UBYTE rcdcnt; /* Nmbr rcrds in last block, 0..128 */
|
||||
union
|
||||
{
|
||||
UBYTE small[16]; /* 16 block numbers of 1 byte */
|
||||
WORD big[8]; /* or 8 block numbers of 1 word */
|
||||
} dskmap;
|
||||
};
|
||||
|
||||
|
||||
/* Declaration of disk parameter tables */
|
||||
struct dpb /* disk parameter table */
|
||||
{
|
||||
UWORD spt; /* sectors per track */
|
||||
UBYTE bsh; /* block shift factor */
|
||||
UBYTE blm; /* block mask */
|
||||
UBYTE exm; /* extent mask */
|
||||
UBYTE dpbdum; /* dummy byte for fill */
|
||||
UWORD dsm; /* max disk size in blocks */
|
||||
UWORD drm; /* max directory entries */
|
||||
UWORD dir_al; /* initial allocation for dir */
|
||||
UWORD cks; /* number dir sectors to checksum */
|
||||
UWORD trk_off; /* track offset */
|
||||
};
|
||||
|
||||
struct dph /* disk parameter header */
|
||||
{
|
||||
UBYTE *xlt; /* pointer to sector translate table */
|
||||
UWORD hiwater; /* high water mark for this disk */
|
||||
UWORD dum1; /* dummy (unused) */
|
||||
UWORD dum2;
|
||||
UBYTE *dbufp; /* pointer to 128 byte directory buffer */
|
||||
struct dpb *dpbp; /* pointer to disk parameter block */
|
||||
UBYTE *csv; /* pointer to check vector */
|
||||
UBYTE *alv; /* pointer to allocation vector */
|
||||
};
|
||||
|
||||
|
||||
/* Declaration of structure containing "global" state variables */
|
||||
struct stvars
|
||||
{
|
||||
struct dph *dphp; /* pointer to disk parm hdr for cur disk */
|
||||
struct dirent *dirbufp; /* pointer for directory buff for process */
|
||||
/* stored here so that each process can */
|
||||
/* have a separate dirbuf. */
|
||||
struct dpb *parmp; /* pointer to disk parameter block for cur */
|
||||
/* disk. Stored here to save ref calc */
|
||||
UBYTE *dmaadr; /* Disk dma address */
|
||||
};
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
|
||||
*****************************************************************
|
||||
* *
|
||||
* CP/M-68K Interface Module for the Loader BDOS *
|
||||
* For "C" version of CP/M-68K *
|
||||
* *
|
||||
* Copyright (c) 1982 Digital Research, Inc. *
|
||||
* *
|
||||
* Version 0.1 -- September 22, 1982 *
|
||||
* *
|
||||
*****************************************************************
|
||||
|
||||
* Declare Public Routines
|
||||
|
||||
.globl _bios1 * 5 BIOS entry points from BDOS
|
||||
.globl _bios2
|
||||
.globl _bios3
|
||||
.globl _bios4
|
||||
.globl _bios5
|
||||
.globl _swap * byte swapper
|
||||
.globl _udiv * unsigned divide routine
|
||||
|
||||
* External Routine
|
||||
|
||||
.globl _bios
|
||||
|
||||
*
|
||||
* BIOS Interface Routines
|
||||
*
|
||||
*
|
||||
* Note - there are 5 BIOS entry points from the BDOS, labelled BIOS1 -
|
||||
* BIOS5, depending on the parameters passed.
|
||||
|
||||
_bios5:
|
||||
* For BIOS functions sectran and set exception vector
|
||||
* Has function number and 2 parameters, a word followed by a long word
|
||||
move.l 8(sp),d2 * get 2nd parameter (long word)
|
||||
bra _bios2 * join common routine
|
||||
|
||||
_bios4:
|
||||
* For BIOS function seldsk
|
||||
* Has function number followed by 2 word parameters
|
||||
move.w 8(sp),d2 * get 2nd parameter (word)
|
||||
bra _bios2 * join common routine
|
||||
|
||||
_bios3:
|
||||
* For BIOS function set dma
|
||||
* Has function number followed by 1 long parameter
|
||||
move.l 6(sp),d1 * get long word parameter
|
||||
bra _bios1 * join common routine
|
||||
|
||||
_bios2:
|
||||
* For all BIOS functions with a word parameter
|
||||
* Word parameter follows function number
|
||||
move.w 6(sp),d1 * get 1st parameter (word)
|
||||
|
||||
_bios1:
|
||||
* For all BIOS functions that have no parameter other than function number
|
||||
move.w 4(sp),d0 * get function number
|
||||
movem.l d3-d7/a3-a6,-(sp)
|
||||
jsr _bios * do BIOS call
|
||||
movem.l (sp)+,d3-d7/a3-a6
|
||||
* * returns value in d0
|
||||
rts
|
||||
|
||||
*
|
||||
* Utility Subroutines
|
||||
*
|
||||
|
||||
_swap:
|
||||
* Swap bytes of a word, return swapped value in d0
|
||||
move.b 5(sp),d0
|
||||
lsl #8,d0
|
||||
move.b 4(sp),d0
|
||||
rts
|
||||
|
||||
_udiv:
|
||||
* Unsigned divide.
|
||||
* Inputs: Long dividend, unsigned word divisor, address of return structure
|
||||
* Return: In structure passed, unsigned word quotient, unsigned word remainder
|
||||
move.l a0, -(sp) * save a0
|
||||
move.l 14(sp), a0 * get address of return structure
|
||||
move.l 8(sp), d0 * get dividend
|
||||
divu 12(sp), d0 * do the divide
|
||||
move.w d0, (a0)+ * store quotient
|
||||
swap d0
|
||||
move.w d0, (a0) * store remainder
|
||||
move.l (sp)+, a0 * restore a0
|
||||
rts
|
||||
|
||||
.end
|
||||
@@ -0,0 +1,93 @@
|
||||
|
||||
/****************************************************************
|
||||
* *
|
||||
* CP/M-68K Loader BDOS Main Routine *
|
||||
* *
|
||||
* This is the main routine for the Loader BDOS for *
|
||||
* CP/M-68K. It has one entry point, _bdos. *
|
||||
* the assembly language trap handler found in bdosif.s. *
|
||||
* There are two parameters: a function number (integer) *
|
||||
* and an information parameter, potentially a long word *
|
||||
* The BDOS can potentially return a pointer, long word, *
|
||||
* or word *
|
||||
* *
|
||||
* Configured for Alcyon C on the VAX *
|
||||
* *
|
||||
****************************************************************/
|
||||
|
||||
#include "stdio.h" /* Standard I/O declarations */
|
||||
|
||||
#include "bdosdef.h" /* Type and structure declarations for BDOS */
|
||||
|
||||
#include "biosdef.h" /* Declarations of BIOS functions */
|
||||
|
||||
/* Serial Number and Copyright Notice */
|
||||
|
||||
char *copyrt="CP/M-68K(tm), Version 1.1, Copyright (c) 1983, Digital Research";
|
||||
char *serial = "XXXX-0000-654321";
|
||||
|
||||
|
||||
/* Declare EXTERN functions */
|
||||
|
||||
EXTERN WORD seldisk(); /* Select disk */
|
||||
EXTERN BOOLEAN openfile(); /* Open File */
|
||||
EXTERN UWORD dirscan(); /* General directory scanning routine */
|
||||
EXTERN UWORD seqread(); /* Sequential disk read */
|
||||
|
||||
|
||||
/* Declare the "state variables". These are globals for the single-thread
|
||||
version of the file system, but are put in a structure so they can be
|
||||
based, with a pointer coming from the calling process */
|
||||
|
||||
GLOBAL struct stvars gbls;
|
||||
|
||||
|
||||
/****************************************************************
|
||||
* *
|
||||
* _bdos MAIN ROUTINE *
|
||||
* *
|
||||
* Called with _bdos(func, info, infop) *
|
||||
* *
|
||||
* Where: *
|
||||
* func is the BDOS function number (d0.w) *
|
||||
* info is the word parameter (d1.w) *
|
||||
* infop is the pointer parameter (d1.l) *
|
||||
* note that info is the word form of infop*
|
||||
* *
|
||||
****************************************************************/
|
||||
|
||||
|
||||
UWORD _bdos(func,info,infop)
|
||||
REG WORD func; /* BDOS function number */
|
||||
REG UWORD info; /* d1.w word parameter */
|
||||
REG UBYTE *infop; /* d1.l pointer parameter */
|
||||
{
|
||||
|
||||
switch (func) /* switch on function number */
|
||||
{
|
||||
|
||||
case 2: bconout((UBYTE)info); /* console output */
|
||||
break;
|
||||
|
||||
case 14: return(seldisk(info)); /* select disk */
|
||||
|
||||
case 15: infop->drvcode = 0; /* open file */
|
||||
infop->extent = 0;
|
||||
infop->s2 = 0;
|
||||
return(dirscan(openfile, infop));
|
||||
|
||||
case 20: infop->drvcode = 0; /* read sequential */
|
||||
return(seqread(infop));
|
||||
|
||||
case 26: GBL.dmaadr = infop; /* set dma address */
|
||||
break;
|
||||
|
||||
default: return(0xffff); /* bad function number */
|
||||
/* break; */
|
||||
|
||||
}; /* end of switch statement */
|
||||
|
||||
return(0); /* return the BDOS return value */
|
||||
} /* end _bdos */
|
||||
|
||||
|
||||
208
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/boot/bdosread.c
Normal file
208
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/boot/bdosread.c
Normal file
@@ -0,0 +1,208 @@
|
||||
|
||||
/****************************************************************
|
||||
* *
|
||||
* CP/M-68K BDOS Disk Read/Write Module *
|
||||
* *
|
||||
* This module contains functions to perform sequential *
|
||||
* or random access read or write to the disk for CP/M-68K *
|
||||
* *
|
||||
* It includes the following external functions: *
|
||||
* *
|
||||
* seqread() - sequential disk read *
|
||||
* *
|
||||
* *
|
||||
* Compiled with Alcyon C on the VAX *
|
||||
* *
|
||||
****************************************************************/
|
||||
|
||||
#include "stdio.h" /* Standard I/O declarations */
|
||||
|
||||
#include "bdosdef.h" /* Type and structure declarations for BDOS */
|
||||
|
||||
|
||||
/* External function definitions */
|
||||
EXTERN UWORD rdsec(); /* disk read routine */
|
||||
EXTERN WORD swap(); /* assembly language byte swapper */
|
||||
EXTERN UWORD dirscan(); /* directory scanning routine */
|
||||
EXTERN BOOLEAN openfile(); /* open file function passed to dirscan */
|
||||
|
||||
|
||||
/**********************************************************/
|
||||
/* First, some utility functions used by seqio and ranio */
|
||||
/**********************************************************/
|
||||
|
||||
/******************************
|
||||
* FCB block number routines *
|
||||
******************************/
|
||||
|
||||
WORD blkindx(fcbp)
|
||||
/* return index into fcb disk map */
|
||||
|
||||
REG struct fcb *fcbp; /* pointer to fcb */
|
||||
{
|
||||
REG struct dpb *dparmp; /* pointer to disk parameter block */
|
||||
REG WORD i;
|
||||
REG WORD blkshf;
|
||||
BSETUP
|
||||
|
||||
dparmp = GBL.parmp;
|
||||
blkshf = dparmp->bsh;
|
||||
i = ((fcbp->extent) & dparmp->exm) << (7 - blkshf);
|
||||
return (i + (UBWORD(fcbp->cur_rec) >> blkshf) );
|
||||
}
|
||||
|
||||
|
||||
UWORD blknum(fcbp, index, wrdfcb)
|
||||
/* return block number in fcb indicated by index */
|
||||
|
||||
REG struct fcb *fcbp; /* pointer to fcb */
|
||||
REG WORD index; /* index into disk map of fcb */
|
||||
WORD wrdfcb; /* boolean, fcb disk map of words? */
|
||||
{
|
||||
if (wrdfcb)
|
||||
return( swap(fcbp->dskmap.big[index]) );
|
||||
else return( UBWORD(fcbp->dskmap.small[index]) );
|
||||
}
|
||||
|
||||
|
||||
/*********************
|
||||
* disk read routine *
|
||||
*********************/
|
||||
|
||||
UWORD do_io(block, rcrd)
|
||||
|
||||
UWORD block; /* block number */
|
||||
UBYTE rcrd; /* record number */
|
||||
{
|
||||
LONG lsec;
|
||||
REG struct dpb *dparmp;
|
||||
BSETUP
|
||||
|
||||
dparmp = GBL.parmp; /* init dpb pointer */
|
||||
lsec = ((LONG)block << (dparmp->bsh)) +
|
||||
(LONG)(rcrd & (dparmp->blm));
|
||||
return( rdsec(lsec, GBL.dmaadr) );
|
||||
}
|
||||
|
||||
|
||||
/*******************************************
|
||||
* routine for crossing extent boundaries *
|
||||
*******************************************/
|
||||
|
||||
WORD new_ext(fcbp)
|
||||
/* If sequential I/O, open the next extent */
|
||||
|
||||
REG struct fcb *fcbp; /* pointer to fcb */
|
||||
{
|
||||
REG UBYTE mod; /* module number */
|
||||
REG UBYTE ext; /* extent number */
|
||||
BSETUP
|
||||
|
||||
mod = (fcbp->s2) & 0x3f;
|
||||
ext = (fcbp->extent) + 1; /* for sequential, incr extent */
|
||||
if (ext >= 32)
|
||||
{
|
||||
ext = 0;
|
||||
mod += 1;
|
||||
}
|
||||
if (mod >= 64) return(6); /* past maximum file size */
|
||||
if ( mod == ((fcbp->s2) & 0x3f) )
|
||||
if ( ! ((ext ^ (fcbp->extent)) & ~((GBL.parmp)->exm) & 0x1f) )
|
||||
{ /* we're in same logical extent */
|
||||
fcbp->extent = ext;
|
||||
return(0);
|
||||
}
|
||||
/* Extent or Module numbers don't match */
|
||||
/* Close the old extent and open a new one */
|
||||
fcbp->s2 = mod;
|
||||
fcbp->extent = ext;
|
||||
if ( dirscan(openfile, fcbp) >= 255 ) /* open new extent */
|
||||
return(4); /* reading unwritten extent */
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
/************************************
|
||||
* Routine to calculate the maximum *
|
||||
* extent number of an FCB in a *
|
||||
* extent-folded environment *
|
||||
************************************/
|
||||
|
||||
UWORD calcext(fcbp)
|
||||
|
||||
REG struct fcb *fcbp;
|
||||
|
||||
{
|
||||
REG UWORD i;
|
||||
REG BYTE *p;
|
||||
BSETUP
|
||||
|
||||
i = 15;
|
||||
p = &(fcbp->dskmap.small[16]);
|
||||
do
|
||||
{
|
||||
if (*--p) break;
|
||||
i -= 1;
|
||||
} while (i);
|
||||
/* Now i contains the index of the last non-zero block in the FCB */
|
||||
if ((GBL.parmp)->dsm > 255) i >>= 1;
|
||||
i >>= 7 - ((GBL.parmp)->bsh);
|
||||
return ( (fcbp->extent) & ~((GBL.parmp)->exm) & 0x1f | i );
|
||||
}
|
||||
|
||||
|
||||
/*********************************
|
||||
* Routine to get the actual *
|
||||
* record count of the currently *
|
||||
* active logical extent of a FCB *
|
||||
*********************************/
|
||||
|
||||
UWORD get_rc(fcbp)
|
||||
|
||||
REG struct fcb *fcbp;
|
||||
|
||||
{
|
||||
REG UWORD ext;
|
||||
|
||||
ext = calcext(fcbp); /* find last active extent in fcb */
|
||||
if (ext == fcbp->extent) return(UBWORD(fcbp->rcdcnt));
|
||||
/* if this is the last active fcb, return fcb's rc */
|
||||
else if (ext > fcbp->extent) return(128);
|
||||
/* if the fcb has more extents past this one, then */
|
||||
/* the current one is logically full */
|
||||
else return (0);
|
||||
/* if we seeked past the last active extent, rc = 0 */
|
||||
}
|
||||
|
||||
|
||||
/************************
|
||||
* seqread entry point *
|
||||
************************/
|
||||
|
||||
UWORD seqread(fcbp)
|
||||
|
||||
REG struct fcb *fcbp; /* fcbp is a pointer to a fcb */
|
||||
|
||||
{
|
||||
REG UWORD block; /* block number from fcb */
|
||||
REG WORD index; /* index into disk map of fcb */
|
||||
REG WORD parm; /* parameter to do-io */
|
||||
REG WORD bigfile; /* file system is in word mode */
|
||||
BSETUP
|
||||
|
||||
bigfile = ((GBL.parmp)->dsm) & ~0xff;
|
||||
if (fcbp->cur_rec == 128)
|
||||
{ /* time to try next extent */
|
||||
if ( new_ext(fcbp) )
|
||||
return(1); /* if can't open new extent, error */
|
||||
fcbp->cur_rec = 0; /* opened new extent, zero cur_rec */
|
||||
}
|
||||
if ( UBWORD(fcbp->cur_rec) >= get_rc(fcbp) )
|
||||
return(1); /* this is end of file */
|
||||
index = blkindx(fcbp); /* get index into fcb disk map */
|
||||
block = blknum(fcbp, index, bigfile);
|
||||
if ( ! block) /* no data allocated at that position */
|
||||
return(1); /* reading unwritten data */
|
||||
return( do_io(block, (fcbp->cur_rec)++) );
|
||||
}
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
|
||||
/********************************************************
|
||||
* *
|
||||
* BIOS definitions for CP/M-68K *
|
||||
* *
|
||||
* Copyright (c) 1982 Digital Research, Inc. *
|
||||
* *
|
||||
* This include file simply defines the BIOS calls *
|
||||
* *
|
||||
********************************************************/
|
||||
|
||||
EXTERN UBYTE bios1(); /* used for character I/O functions */
|
||||
EXTERN bios2(); /* parm1 is word, no return value */
|
||||
EXTERN bios3(); /* used for set dma only */
|
||||
/* parm1 is a pointer, no return */
|
||||
EXTERN UBYTE *bios4(); /* seldsk only, parm1 and parm2 are */
|
||||
/* words, returns a pointer to dph */
|
||||
EXTERN UWORD bios5(); /* for sectran and set exception */
|
||||
|
||||
|
||||
#define bwboot() bios1(1) /* warm boot */
|
||||
#define bconstat() bios1(2) /* console status */
|
||||
#define bconin() bios1(3) /* console input */
|
||||
#define bconout(parm) bios2(4,parm) /* console output parm */
|
||||
#define blstout(parm) bios2(5,parm) /* list device output */
|
||||
#define bpun(parm) bios2(6,parm) /* punch char output */
|
||||
#define brdr() bios1(7) /* reader input */
|
||||
#define bhome() bios1(8) /* recalibrate drive */
|
||||
#define bseldsk(parm1,parm2) bios4(9,parm1,parm2)
|
||||
/* select disk and return info */
|
||||
#define bsettrk(parm) bios2(10,parm) /* set track on disk */
|
||||
#define bsetsec(parm) bios2(11,parm) /* set sector for disk */
|
||||
#define bsetdma(parm) bios3(12,parm) /* set dma address */
|
||||
#define bread() bios1(13) /* read sector from disk */
|
||||
#define bwrite(parm) bios2(14,parm) /* write sector to disk */
|
||||
#define blistst() bios1(15) /* list device status */
|
||||
#define bsectrn(parm1,parm2) bios5(16,parm1,parm2)
|
||||
/* sector translate */
|
||||
#define bgetseg() bios1(18) /* get memory segment tbl */
|
||||
#define bgetiob() bios1(19) /* get I/O byte */
|
||||
#define bsetiob(parm) bios2(20,parm) /* set I/O byte */
|
||||
#define bflush() bios1(21) /* flush buffers */
|
||||
#define bsetvec(parm1,parm2) bios5(22,parm1,parm2)
|
||||
/* set exception vector */
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
***************************************
|
||||
* Information to go on the 256 byte *
|
||||
* boot sector of an ExorMacs *
|
||||
***************************************
|
||||
|
||||
.text
|
||||
.dc.l $4000 * starting stack pointer
|
||||
.dc.l start * starting program counter
|
||||
.dc.w 1 * garbage
|
||||
.dc.w 1 * length of SAT
|
||||
.dc.l 2 * secondary directory start
|
||||
.dc.l 0 * primary directory PSN list start
|
||||
.dc.l 0 * start of boot loader
|
||||
.dc.w 26 * length of boot loader
|
||||
.dc.l $0 * boot execution address
|
||||
.dc.l $0 * boot load address
|
||||
.dc.b '9/30' * generation date
|
||||
.dc.b 'CP/M-68K of 9/30/82 ' * volume descriptor
|
||||
.dc.b '0020' * version/revision
|
||||
.dc.w $0a484 * checksum (god help us)
|
||||
.dc.l $0f1e2d3c * diagnostic test pattern
|
||||
.dc.l $4b5a6978
|
||||
.dc.l $8796a5b4
|
||||
.dc.l $c3d2e1f0
|
||||
.dc.l $0f1e2d3c * diagnostic test pattern
|
||||
.dc.l $4b5a6978
|
||||
.dc.l $8796a5b4
|
||||
.dc.l $c3d2e1f0
|
||||
.dc.l $4f8f0f07 * diagnostic test pattern
|
||||
.dc.l $0b0d0e06
|
||||
.dc.l $0a0c0408
|
||||
.dc.l $04020100
|
||||
.dc.l 00, 00, 00, 00 * diagnostic test pattern
|
||||
.dc.l 0 * diagnostic test area directory
|
||||
.dc.l 0 * start of dump area
|
||||
.dc.w 0 * length of dump area
|
||||
.dc.l 0 * start of sector lockout table
|
||||
.dc.w 0 * length of sector lockout table
|
||||
.dc.l 0,0,0,0,0,0,0 * unused, reserved
|
||||
.dc.l 0,0,0,0,0,0
|
||||
.dc.l 0,0,0,0,0,0,0
|
||||
.dc.l 0,0,0,0,0,0
|
||||
.dc.b 'EXORMACS' * let's hear it for Motorola
|
||||
*
|
||||
* end of volume id
|
||||
*
|
||||
* begin boot info proper
|
||||
*
|
||||
.ds.b $300 * skip over exception vectors
|
||||
.even
|
||||
start: move #$2700,sr
|
||||
move.l #$8,a0
|
||||
move.w #253,d0
|
||||
exlp: move.l #expdef,(a0)+
|
||||
dbf d0,exlp
|
||||
jmp grunt
|
||||
expdef: rte
|
||||
grunt: move #$2000,sr
|
||||
.end
|
||||
174
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/boot/cpmldr.c
Normal file
174
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/boot/cpmldr.c
Normal file
@@ -0,0 +1,174 @@
|
||||
/****************************************************************
|
||||
* *
|
||||
* CP/M-68K Loader *
|
||||
* *
|
||||
* This is the main routine for the CP/M-68K Loader. *
|
||||
* It has one entry point, ldcpm, which is called from *
|
||||
* the assembly language routine called startld found in *
|
||||
* ldrif.s. startld just sets up the stack. *
|
||||
* *
|
||||
* Configured for Alcyon C on the VAX *
|
||||
* *
|
||||
****************************************************************/
|
||||
|
||||
#include "stdio.h" /* Standard I/O declarations */
|
||||
|
||||
#define ALCYON TRUE /* TRUE if compiling with the ALCYON 68K C compiler */
|
||||
#define SECLEN 128 /* CP/M sector length */
|
||||
|
||||
|
||||
/* Declare EXTERN functions */
|
||||
|
||||
EXTERN WORD _bdos(); /* Loader BDOS entry point */
|
||||
EXTERN startld(); /* Assembly routine to set up stack & retry */
|
||||
EXTERN BYTE *bios1(); /* bios entry point for get segment table */
|
||||
EXTERN move(); /* general purpose byte mover */
|
||||
|
||||
|
||||
#define conout(ch) _bdos(2,ch)
|
||||
#define seldsk(dsk) _bdos(14,dsk)
|
||||
#define open(fcbp) _bdos(15,0,fcbp)
|
||||
#define read(fcbp) _bdos(20,0,fcbp)
|
||||
#define setdma(p) _bdos(26,0,p)
|
||||
|
||||
|
||||
/* Define the data structures used in ldcpm */
|
||||
struct fcb
|
||||
{
|
||||
UBYTE drvcode; /* drive code, must be 0 for loader BDOS */
|
||||
/* (auto disk select not supported) */
|
||||
UBYTE fname[11]; /* includes file name and type fields */
|
||||
UBYTE sys_info[4]; /* ex, s1, s2, rc. These are don't cares */
|
||||
UBYTE dskmap[16]; /* disk map, also a don't care */
|
||||
UBYTE cur_rec; /* current record field */
|
||||
};
|
||||
|
||||
struct hdr
|
||||
{
|
||||
WORD magic; /* magic number. We only recognize 0x601a */
|
||||
LONG size[5]; /* sizes of code, data, bss, sym tbl, stack */
|
||||
BYTE *tstart; /* start address of text segment */
|
||||
WORD rlbflg; /* relocation bits suppressed flag */
|
||||
};
|
||||
|
||||
struct segtbl
|
||||
{ /* memory segment table from LDRBIOS */
|
||||
WORD entrys; /* number of segments, must be 1 */
|
||||
BYTE *start; /* low memory address */
|
||||
LONG length; /* length of segment */
|
||||
};
|
||||
|
||||
|
||||
/**********************/
|
||||
/* Global Variables */
|
||||
/**********************/
|
||||
|
||||
BYTE buffer[SECLEN]; /* 128 byte dma buffer to read program headers */
|
||||
|
||||
/* We need 2 FCB's: one to read CPM.SYS and one to read BIOS.SYS */
|
||||
/* Unfortunately, due to a bug in the Alcyon compiler, we can't initialize */
|
||||
/* them in a straightforward way. So: */
|
||||
|
||||
#if ALCYON
|
||||
|
||||
struct fcb cpmfcb =
|
||||
{ 0x0043, 0x504d, 0x2020, 0x2020, 0x2053, 0x5953, /* drive, name, and type */
|
||||
0,0,0,0,0,0,0,0,0,0,0 /* the rest of the fcb */
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
struct fcb cpmfcb =
|
||||
{ (BYTE)0 /* drive code */
|
||||
'CPM SYS', /* file name */
|
||||
0,0,0,0,0,0,0,0,0,0 /* the rest of the fcb */
|
||||
0,0,0,0,0,0,0,0,0,0,0
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/**************************/
|
||||
/* Utility Routines */
|
||||
/**************************/
|
||||
|
||||
pstring(p)
|
||||
/* print string */
|
||||
REG BYTE *p;
|
||||
{
|
||||
while (*p) conout(*p++);
|
||||
}
|
||||
|
||||
|
||||
badload(errtype)
|
||||
/* Load failed. Print message and try again */
|
||||
REG WORD errtype;
|
||||
{
|
||||
REG WORD i;
|
||||
|
||||
switch (errtype)
|
||||
{
|
||||
case 0: pstring("\r\nBoot error.");
|
||||
startld();
|
||||
|
||||
case 1: pstring("\n\rOpen or Read error on ");
|
||||
break;
|
||||
|
||||
case 2: pstring("\n\rBad file format on ");
|
||||
}
|
||||
pstring("CPM.SYS");
|
||||
startld();
|
||||
}
|
||||
|
||||
|
||||
/********************
|
||||
* load subroutine *
|
||||
********************/
|
||||
|
||||
BYTE *load(fcbp)
|
||||
/* load the file pointed to by fcbp and return pointer to load point */
|
||||
REG struct fcb *fcbp;
|
||||
{
|
||||
REG BYTE *p;
|
||||
REG struct hdr *hp;
|
||||
REG LONG length;
|
||||
|
||||
setdma( buffer );
|
||||
if ( open(fcbp) >= 255 ) badload(1);
|
||||
fcbp->cur_rec = 0;
|
||||
if ( read(fcbp) ) badload(1);
|
||||
hp = buffer;
|
||||
if ( (hp->magic != 0x601a) || ! (hp->rlbflg) )
|
||||
badload(2);
|
||||
p = hp->tstart;
|
||||
length = hp->size[0] + hp->size[1];
|
||||
move(&buffer[sizeof *hp], p, SECLEN - (sizeof *hp));
|
||||
/* move the first record minus header to load point */
|
||||
p += SECLEN - (sizeof *hp);
|
||||
length -= SECLEN - (sizeof *hp);
|
||||
while (length > 0L)
|
||||
{
|
||||
setdma(p);
|
||||
if ( read(fcbp) ) badload(1);
|
||||
p += SECLEN;
|
||||
length -= SECLEN;
|
||||
}
|
||||
return(hp->tstart);
|
||||
}
|
||||
|
||||
|
||||
/***************************
|
||||
* ldcpm main routine *
|
||||
***************************/
|
||||
|
||||
ldcpm()
|
||||
|
||||
{
|
||||
WORD (*gocpm)();
|
||||
|
||||
if (seldsk(0)) badload(0);
|
||||
gocpm = load(&cpmfcb); /* load the CP/M system */
|
||||
pstring("\r\n\nCP/M-68K(tm) Version 1.2 Alpha 8/21/83 ");
|
||||
pstring("\n\rCopyright (c) 1982 Digital Research, Inc.\r\n\n");
|
||||
(*gocpm)(); /* jump to the CCP */
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user