Unpack disk3.tgz
This commit is contained in:
parent
3a12151067
commit
777c904054
|
@ -0,0 +1,16 @@
|
|||
/**
|
||||
*
|
||||
* This header file defines an equivalence between several of the
|
||||
* standard level 2 I/O functions and their console I/O counterparts.
|
||||
* Use this header file for programs which perform all of these functions
|
||||
* to the console only, and need an unbuffered, direct interface to the
|
||||
* user's console. See Section 3.2.3 of the manual for more information.
|
||||
*
|
||||
**/
|
||||
#define getchar getch
|
||||
#define putchar putch
|
||||
#define gets cgets
|
||||
#define puts cputs
|
||||
#define printf cprintf
|
||||
#define scanf cscanf
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
/**
|
||||
*
|
||||
* This header file defines various ASCII character manipulation macros,
|
||||
* as follows:
|
||||
*
|
||||
* isalpha(c) non-zero if c is alpha
|
||||
* isupper(c) non-zero if c is upper case
|
||||
* islower(c) non-zero if c is lower case
|
||||
* isdigit(c) non-zero if c is a digit (0 to 9)
|
||||
* isxdigit(c) non-zero if c is a hexadecimal digit (0 to 9, A to F,
|
||||
* a to f)
|
||||
* isspace(c) non-zero if c is white space
|
||||
* ispunct(c) non-zero if c is punctuation
|
||||
* isalnum(c) non-zero if c is alpha or digit
|
||||
* isprint(c) non-zero if c is printable (including blank)
|
||||
* isgraph(c) non-zero if c is graphic (excluding blank)
|
||||
* iscntrl(c) non-zero if c is control character
|
||||
* isascii(c) non-zero if c is ASCII
|
||||
* iscsym(c) non-zero if valid character for C symbols
|
||||
* iscsymf(c) non-zero if valid first character for C symbols
|
||||
*
|
||||
**/
|
||||
|
||||
#define _U 1 /* upper case flag */
|
||||
#define _L 2 /* lower case flag */
|
||||
#define _N 4 /* number flag */
|
||||
#define _S 8 /* space flag */
|
||||
#define _P 16 /* punctuation flag */
|
||||
#define _C 32 /* control character flag */
|
||||
#define _B 64 /* blank flag */
|
||||
#define _X 128 /* hexadecimal flag */
|
||||
|
||||
extern char _ctype[]; /* character type table */
|
||||
|
||||
#define isalpha(c) (_ctype[(c)+1]&(_U|_L))
|
||||
#define isupper(c) (_ctype[(c)+1]&_U)
|
||||
#define islower(c) (_ctype[(c)+1]&_L)
|
||||
#define isdigit(c) (_ctype[(c)+1]&_N)
|
||||
#define isxdigit(c) (_ctype[(c)+1]&_X)
|
||||
#define isspace(c) (_ctype[(c)+1]&_S)
|
||||
#define ispunct(c) (_ctype[(c)+1]&_P)
|
||||
#define isalnum(c) (_ctype[(c)+1]&(_U|_L|_N))
|
||||
#define isprint(c) (_ctype[(c)+1]&(_P|_U|_L|_N|_B))
|
||||
#define isgraph(c) (_ctype[(c)+1]&(_P|_U|_L|_N))
|
||||
#define iscntrl(c) (_ctype[(c)+1]&_C)
|
||||
#define isascii(c) ((unsigned)(c)<=127)
|
||||
#define iscsym(c) (isalnum(c)||(((c)&127)==0x5f))
|
||||
#define iscsymf(c) (isalpha(c)||(((c)&127)==0x5f))
|
||||
|
||||
#define toupper(c) (islower(c)?((c)-('a'-'A')):(c))
|
||||
#define tolower(c) (isupper(c)?((c)+('a'-'A')):(c))
|
||||
#define toascii(c) ((c)&127)
|
||||
|
||||
/**
|
||||
*
|
||||
* Define NULL if it's not already defined
|
||||
*
|
||||
*/
|
||||
#ifndef NULL
|
||||
#if SPTR
|
||||
#define NULL 0 /* null pointer value */
|
||||
#else
|
||||
#define NULL 0L
|
||||
#endif
|
||||
#endif
|
||||
|
|
@ -0,0 +1,476 @@
|
|||
/**
|
||||
*
|
||||
* This header file supplies information needed to interface with the
|
||||
* particular operating system and C compiler being used.
|
||||
*
|
||||
**/
|
||||
|
||||
/**
|
||||
*
|
||||
* Define NULL if it's not already defined
|
||||
*
|
||||
*/
|
||||
#ifndef NULL
|
||||
#if SPTR
|
||||
#define NULL 0 /* null pointer value */
|
||||
#else
|
||||
#define NULL 0L
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
*
|
||||
* The following symbols specify which operating system is being used.
|
||||
*
|
||||
* CPM Any CP/M OS
|
||||
* CPM80 CP/M for Intel 8080 or Zilog Z80
|
||||
* CPM86 CP/M for Intel 8086
|
||||
* CPM68 CP/M for Motorola 68000
|
||||
* MSDOS Microsoft's MSDOS
|
||||
*
|
||||
* Note: CPM will be set to 1 for any of the above.
|
||||
*
|
||||
* UNIX "Standard" UNIX
|
||||
* MIBS General Automation's MIBS OS
|
||||
*
|
||||
*/
|
||||
|
||||
#if CPM80
|
||||
#define CPM 1
|
||||
#endif
|
||||
#if CPM86
|
||||
#define CPM 1
|
||||
#endif
|
||||
#if CPM68
|
||||
#define CPM 1
|
||||
#endif
|
||||
#if MSDOS
|
||||
#define CPM 1
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* The following definitions specify the particular C compiler being used.
|
||||
*
|
||||
* LATTICE Lattice C compiler
|
||||
*
|
||||
*/
|
||||
#define LATTICE 1
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* The following type definitions take care of the particularly nasty
|
||||
* machine dependency caused by the unspecified handling of sign extension
|
||||
* in the C language. When converting "char" to "int" some compilers
|
||||
* will extend the sign, while others will not. Both are correct, and
|
||||
* the unsuspecting programmer is the loser. For situations where it
|
||||
* matters, the new type "byte" is equivalent to "unsigned char".
|
||||
*
|
||||
*/
|
||||
#if LATTICE
|
||||
typedef unsigned char byte;
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* Miscellaneous definitions
|
||||
*
|
||||
*/
|
||||
#define SECSIZ 128 /* disk sector size */
|
||||
#if CPM
|
||||
#define DMA (char *)0x80 /* disk buffer address */
|
||||
#endif
|
||||
|
||||
/**
|
||||
*
|
||||
* The following structure is a File Control Block. Operating systems
|
||||
* with CPM-like characteristics use the FCB to store information about
|
||||
* a file while it is open.
|
||||
*
|
||||
*/
|
||||
#if CPM
|
||||
struct FCB
|
||||
{
|
||||
char fcbdrv; /* drive code */
|
||||
char fcbnam[8]; /* file name */
|
||||
char fcbext[3]; /* file name extension */
|
||||
#if MSDOS
|
||||
short fcbcb; /* current block number */
|
||||
short fcblrs; /* logical record size */
|
||||
long fcblfs; /* logical file size */
|
||||
short fcbdat; /* create/change date */
|
||||
char fcbsys[10]; /* reserved */
|
||||
char fcbcr; /* current record number */
|
||||
long fcbrec; /* random record number */
|
||||
#else
|
||||
char fcbexn; /* extent number */
|
||||
char fcbs1; /* reserved */
|
||||
char fcbs2; /* reserved */
|
||||
char fcbrc; /* record count */
|
||||
char fcbsys[16]; /* reserved */
|
||||
char fcbcr; /* current record number */
|
||||
short fcbrec; /* random record number */
|
||||
char fcbovf; /* random record overflow */
|
||||
#endif
|
||||
};
|
||||
|
||||
#define FCBSIZ sizeof(struct FCB)
|
||||
#endif
|
||||
|
||||
/**
|
||||
*
|
||||
* The following symbols define the sizes of file names and node names.
|
||||
*
|
||||
*/
|
||||
#if CPM
|
||||
#define FNSIZE 13 /* maximum file node size */
|
||||
#define FMSIZE 64 /* maximum file name size */
|
||||
#define FESIZE 4 /* maximum file extension size */
|
||||
#else
|
||||
#define FNSIZE 16 /* maximum file node size */
|
||||
#define FMSIZE 64 /* maximum file name size */
|
||||
#define FESIZE 4 /* maximum file extension size */
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* The following structures define the 8086 registers that are passed to
|
||||
* various low-level operating system service functions.
|
||||
*
|
||||
*/
|
||||
#if I8086
|
||||
struct XREG
|
||||
{
|
||||
short ax,bx,cx,dx,si,di;
|
||||
};
|
||||
|
||||
struct HREG
|
||||
{
|
||||
byte al,ah,bl,bh,cl,ch,dl,dh;
|
||||
};
|
||||
|
||||
union REGS
|
||||
{
|
||||
struct XREG x;
|
||||
struct HREG h;
|
||||
};
|
||||
|
||||
struct SREGS
|
||||
{
|
||||
short es,cs,ss,ds;
|
||||
};
|
||||
|
||||
struct XREGS
|
||||
{
|
||||
short ax,bx,cx,dx,si,di,ds,es;
|
||||
};
|
||||
|
||||
union REGSS
|
||||
{
|
||||
struct XREGS x;
|
||||
struct HREG h;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* The following codes are returned by the low-level operating system service
|
||||
* calls. They are usually placed into _OSERR by the OS interface functions.
|
||||
*
|
||||
*/
|
||||
#if MSDOS
|
||||
#define E_FUNC 1 /* invalid function code */
|
||||
#define E_FNF 2 /* file not found */
|
||||
#define E_PNF 3 /* path not found */
|
||||
#define E_NMH 4 /* no more file handles */
|
||||
#define E_ACC 5 /* access denied */
|
||||
#define E_IFH 6 /* invalid file handle */
|
||||
#define E_MCB 7 /* memory control block problem */
|
||||
#define E_MEM 8 /* insufficient memory */
|
||||
#define E_MBA 9 /* invalid memory block address */
|
||||
#define E_ENV 10 /* invalid environment */
|
||||
#define E_FMT 11 /* invalid format */
|
||||
#define E_IAC 12 /* invalid access code */
|
||||
#define E_DATA 13 /* invalid data */
|
||||
#define E_DRV 15 /* invalid drive code */
|
||||
#define E_RMV 16 /* remove denied */
|
||||
#define E_DEV 17 /* invalid device */
|
||||
#define E_NMF 18 /* no more files */
|
||||
#endif
|
||||
|
||||
/**
|
||||
*
|
||||
* This structure contains disk size information returned by the getdfs
|
||||
* function.
|
||||
*/
|
||||
struct DISKINFO
|
||||
{
|
||||
unsigned short free; /* number of free clusters */
|
||||
unsigned short cpd; /* clusters per drive */
|
||||
unsigned short spc; /* sectors per cluster */
|
||||
unsigned short bps; /* bytes per sector */
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* The following structure is used by the dfind and dnext functions to
|
||||
* hold file information.
|
||||
*
|
||||
*/
|
||||
struct FILEINFO
|
||||
{
|
||||
char resv[21]; /* reserved */
|
||||
char attr; /* actual file attribute */
|
||||
long time; /* file time and date */
|
||||
long size; /* file size in bytes */
|
||||
char name[13]; /* file name */
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* The following structure appears at the beginning (low address) of
|
||||
* each free memory block.
|
||||
*
|
||||
*/
|
||||
struct MELT
|
||||
{
|
||||
struct MELT *fwd; /* points to next free block */
|
||||
#if SPTR
|
||||
unsigned size; /* number of MELTs in this block */
|
||||
#else
|
||||
long size; /* number of MELTs in this block */
|
||||
#endif
|
||||
};
|
||||
#define MELTSIZE sizeof(struct MELT)
|
||||
|
||||
/**
|
||||
*
|
||||
* The following structure is a device header. It is copied to _OSCED
|
||||
* when a critical error occurs.
|
||||
*
|
||||
*/
|
||||
struct DEV
|
||||
{
|
||||
long nextdev; /* long pointer to next device */
|
||||
short attr; /* device attributes */
|
||||
short sfunc; /* short pointer to strategy function */
|
||||
short ifunc; /* short pointer to interrupt function */
|
||||
char name[8]; /* device name */
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* The following structure contains country-dependent information returned
|
||||
* by the getcdi function.
|
||||
*
|
||||
*/
|
||||
struct CDI2 /* DOS Version 2 format */
|
||||
{
|
||||
short fdate; /* date/time format */
|
||||
/* 0 => USA (h:m:s m/d/y) */
|
||||
/* 1 => Europe (h:m:s d/m/y) */
|
||||
/* 2 => Japan (h:m:s d:m:y) */
|
||||
char curr[2]; /* currency symbol and null */
|
||||
char sthou[2]; /* thousands separator and null */
|
||||
char sdec[2]; /* decimal separator and null */
|
||||
char resv[24]; /* reserved */
|
||||
};
|
||||
|
||||
struct CDI3 /* DOS Version 3 format */
|
||||
{
|
||||
short fdate; /* date format */
|
||||
/* 0 => USA (m d y) */
|
||||
/* 1 => Europe (d m y) */
|
||||
/* 2 => Japan (d m y) */
|
||||
char curr[5]; /* currency symbol, null-terminated */
|
||||
char sthou[2]; /* thousands separator and null */
|
||||
char sdec[2]; /* decimal separator and null */
|
||||
char sdate[2]; /* date separator and null */
|
||||
char stime[2]; /* time separator and null */
|
||||
char fcurr; /* currency format */
|
||||
/* Bit 0 => 0 if symbol precedes value */
|
||||
/* => 1 if symbol follows value */
|
||||
/* Bit 1 => number of spaces between value */
|
||||
/* and symbol */
|
||||
char dcurr; /* number of decimals in currency */
|
||||
char ftime; /* time format */
|
||||
/* Bit 0 => 0 if 12-hour clock */
|
||||
/* => 1 if 24-hour clock */
|
||||
long pcase; /* far pointer to case map function */
|
||||
char sdata[2]; /* data list separator and null */
|
||||
short resv[5]; /* reserved */
|
||||
};
|
||||
|
||||
union CDI
|
||||
{
|
||||
struct CDI2 v2;
|
||||
struct CDI3 v3;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* Level 0 I/O services
|
||||
*
|
||||
**/
|
||||
#ifndef NARGS
|
||||
extern void chgdta(char *);
|
||||
extern int chgfa(char *, int);
|
||||
extern int chgft(int, long);
|
||||
extern int dclose(int);
|
||||
extern int dcreat(char *, int);
|
||||
extern int dcreatx(char *, int);
|
||||
extern int dfind(struct FILEINFO *, char *, int);
|
||||
extern int dnext(struct FILEINFO *);
|
||||
extern int dopen(char *, int);
|
||||
extern unsigned dread(int, char *, unsigned);
|
||||
extern long dseek(int, long, int);
|
||||
extern int dunique(char *, int);
|
||||
extern unsigned dwrite(int, char *, unsigned);
|
||||
extern int getcd(int,char *);
|
||||
extern int getch(void);
|
||||
extern int getche(void);
|
||||
extern int getdfs(int, struct DISKINFO *);
|
||||
extern char *getdta(void);
|
||||
extern int getfa(char *);
|
||||
extern int getfc(int, int *);
|
||||
extern long getft(int);
|
||||
extern int getvfy(void);
|
||||
extern int kbhit(void);
|
||||
extern int putch(int);
|
||||
extern int rlock(int, long, long);
|
||||
extern void rstdta(void);
|
||||
extern void rstvfy(void);
|
||||
extern int runlk(int, long, long);
|
||||
extern void setvfy(void);
|
||||
extern int ungetch(int);
|
||||
#else
|
||||
extern void chgdta();
|
||||
extern int chgfa();
|
||||
extern int chgft();
|
||||
extern int dclose();
|
||||
extern int dcreat();
|
||||
extern int dcreatx();
|
||||
extern int dfind();
|
||||
extern int dnext();
|
||||
extern int dopen();
|
||||
extern unsigned dread();
|
||||
extern long dseek();
|
||||
extern int dunique();
|
||||
extern unsigned dwrite();
|
||||
extern int getcd();
|
||||
extern int getch();
|
||||
extern int getche();
|
||||
extern int getdfs();
|
||||
extern char *getdta();
|
||||
extern int getfa();
|
||||
extern int getfc();
|
||||
extern long getft();
|
||||
extern int getvfy();
|
||||
extern int kbhit();
|
||||
extern int putch();
|
||||
extern int rlock();
|
||||
extern void rstdta();
|
||||
extern void rstvfy();
|
||||
extern int runlk();
|
||||
extern void setvfy();
|
||||
extern int ungetch();
|
||||
#endif
|
||||
|
||||
/**
|
||||
*
|
||||
* Miscellaneous external definitions
|
||||
*
|
||||
*/
|
||||
#ifndef NARGS
|
||||
extern int chgclk(unsigned char *);
|
||||
extern int chgdsk(int);
|
||||
extern char *envpack(char **, char **);
|
||||
extern int envunpk(char *);
|
||||
#if SPTR
|
||||
extern unsigned FP_OFF(long);
|
||||
extern unsigned FP_SEG(long);
|
||||
#else
|
||||
extern unsigned FP_OFF(char *);
|
||||
extern unsigned FP_SEG(char *);
|
||||
#endif
|
||||
extern long ftpack(char *);
|
||||
extern void ftunpk(long, char *);
|
||||
extern int getbrk(void);
|
||||
extern int getcdi(int, struct CDI3 *);
|
||||
extern void getclk(unsigned char *);
|
||||
extern int getdsk(void);
|
||||
extern int getpf(char *, char *);
|
||||
extern int getpfe(char *, char *);
|
||||
extern unsigned inp(unsigned);
|
||||
extern int int86(int, union REGS *, union REGS *);
|
||||
extern int int86s(int, union REGSS *, union REGSS *);
|
||||
extern int int86x(int, union REGS *, union REGS *, struct SREGS *);
|
||||
extern int intdos(union REGS *, union REGS *);
|
||||
extern int intdoss(union REGSS *, union REGSS *);
|
||||
extern int intdosx(union REGS *, union REGS *, struct SREGS *);
|
||||
extern int isnet(void);
|
||||
extern int isnetdc(int);
|
||||
extern int isnetfh(int);
|
||||
extern int isneton(void);
|
||||
extern void makedv(char *, unsigned *, unsigned *);
|
||||
extern void makepv(int(*)(), unsigned *, unsigned *);
|
||||
extern void movedata(unsigned, unsigned, unsigned, unsigned, unsigned);
|
||||
extern int onbreak(int(*)());
|
||||
extern void onerror(int);
|
||||
extern void outp(unsigned, unsigned);
|
||||
extern void peek(unsigned, unsigned, char *, unsigned);
|
||||
extern void poke(unsigned, unsigned, char *, unsigned);
|
||||
extern int poserr(char *);
|
||||
extern void rstbrk(void);
|
||||
extern void rstdsk(void);
|
||||
extern int setcdi(int);
|
||||
extern void setbrk(void);
|
||||
#else
|
||||
extern int chgclk();
|
||||
extern int chgdsk();
|
||||
extern char *envpack();
|
||||
extern int envunpk();
|
||||
extern unsigned FP_OFF();
|
||||
extern unsigned FP_SEG();
|
||||
extern long ftpack();
|
||||
extern void ftunpk();
|
||||
extern int getbrk();
|
||||
extern int getcdi();
|
||||
extern void getclk();
|
||||
extern int getdsk();
|
||||
extern int getpf();
|
||||
extern int getpfe();
|
||||
extern unsigned inp();
|
||||
extern int int86();
|
||||
extern int int86s();
|
||||
extern int int86x();
|
||||
extern int intdos();
|
||||
extern int intdoss();
|
||||
extern int intdosx();
|
||||
extern int isnet();
|
||||
extern int isnetdc();
|
||||
extern int isnetfh();
|
||||
extern int isneton();
|
||||
extern void makedv();
|
||||
extern void makepv();
|
||||
extern void movedata();
|
||||
extern int onbreak();
|
||||
extern void onerror();
|
||||
extern void outp();
|
||||
extern void peek();
|
||||
extern void poke();
|
||||
extern int poserr();
|
||||
extern void rstbrk();
|
||||
extern void rstdsk();
|
||||
extern int setcdi();
|
||||
extern void setbrk();
|
||||
#endif
|
||||
|
|
@ -0,0 +1,193 @@
|
|||
.XLIST
|
||||
PAGE 58,132
|
||||
;**
|
||||
;
|
||||
; This macro library defines the operating environment for the 8086 S
|
||||
; memory model, which allows 64Kbytes of data and 64Kbytes of program.
|
||||
;
|
||||
;**
|
||||
MSDOS EQU 2
|
||||
|
||||
;**
|
||||
;
|
||||
; The following symbols define the 8086 memory mode being used. Set LPROG
|
||||
; to 1 for a large program segment (greater than 64K-bytes), and set LDATA
|
||||
; to 1 for a large data segment. Set COM to 1 to generate .COM files
|
||||
; instead of .EXE files. Note that if COM is not zero, then LPROG and
|
||||
; LDATA must be 0.
|
||||
;
|
||||
;**
|
||||
COM EQU 0
|
||||
LPROG EQU 0
|
||||
LDATA EQU 0
|
||||
|
||||
;**
|
||||
;
|
||||
; The following symbols are established via LPROG and LDATA as follows:
|
||||
;
|
||||
; S8086 set for small model (small prog, small data)
|
||||
; D8086 set for model with large data, small prog
|
||||
; P8086 set for model with large prog, small data
|
||||
; L8086 set for large model
|
||||
;
|
||||
;**
|
||||
IF (LPROG EQ 0) AND (LDATA EQ 0)
|
||||
S8086 EQU 1
|
||||
D8086 EQU 0
|
||||
P8086 EQU 0
|
||||
L8086 EQU 0
|
||||
ENDIF
|
||||
|
||||
IF (LPROG EQ 0) AND (LDATA NE 0)
|
||||
S8086 EQU 0
|
||||
D8086 EQU 1
|
||||
P8086 EQU 0
|
||||
L8086 EQU 0
|
||||
ENDIF
|
||||
|
||||
IF (LPROG NE 0) AND (LDATA EQ 0)
|
||||
S8086 EQU 0
|
||||
D8086 EQU 0
|
||||
P8086 EQU 1
|
||||
L8086 EQU 0
|
||||
ENDIF
|
||||
|
||||
IF (LPROG NE 0) AND (LDATA NE 0)
|
||||
S8086 EQU 0
|
||||
D8086 EQU 0
|
||||
P8086 EQU 0
|
||||
L8086 EQU 1
|
||||
ENDIF
|
||||
|
||||
|
||||
;**
|
||||
;
|
||||
; The DSEG and PSEG macros are defined to generate the appropriate GROUP
|
||||
; and SEGMENT statements for the memory model being used. The ENDDS and
|
||||
; ENDPS macros are then used to end the segments.
|
||||
;
|
||||
;**
|
||||
DSEG MACRO
|
||||
DGROUP GROUP DATA
|
||||
DATA SEGMENT WORD PUBLIC 'DATA'
|
||||
ASSUME DS:DGROUP
|
||||
ENDM
|
||||
ENDDS MACRO
|
||||
DATA ENDS
|
||||
ENDM
|
||||
|
||||
IF S8086
|
||||
PSEG MACRO
|
||||
PGROUP GROUP PROG
|
||||
PROG SEGMENT BYTE PUBLIC 'PROG'
|
||||
ASSUME CS:PGROUP
|
||||
ENDM
|
||||
ENDPS MACRO
|
||||
PROG ENDS
|
||||
ENDM
|
||||
ENDIF
|
||||
|
||||
IF D8086
|
||||
PSEG MACRO
|
||||
CGROUP GROUP CODE
|
||||
CODE SEGMENT BYTE PUBLIC 'CODE'
|
||||
ASSUME CS:CGROUP
|
||||
ENDM
|
||||
ENDPS MACRO
|
||||
CODE ENDS
|
||||
ENDM
|
||||
ENDIF
|
||||
|
||||
IF P8086
|
||||
PSEG MACRO
|
||||
_CODE SEGMENT BYTE PUBLIC 'CODE'
|
||||
ASSUME CS:_CODE
|
||||
ENDM
|
||||
ENDPS MACRO
|
||||
_CODE ENDS
|
||||
ENDM
|
||||
ENDIF
|
||||
|
||||
IF L8086
|
||||
PSEG MACRO
|
||||
_PROG SEGMENT BYTE PUBLIC 'PROG'
|
||||
ASSUME CS:_PROG
|
||||
ENDM
|
||||
ENDPS MACRO
|
||||
_PROG ENDS
|
||||
ENDM
|
||||
ENDIF
|
||||
|
||||
;**
|
||||
;
|
||||
; The BEGIN and ENTRY macros establish appropriate function entry points
|
||||
; depending on whether NEAR or FAR program addressing is being used. The
|
||||
; only difference between the two is that BEGIN generates a PROC operation
|
||||
; to start a segment.
|
||||
;
|
||||
BEGIN MACRO NAME ; begin a function
|
||||
PUBLIC NAME
|
||||
IF LPROG
|
||||
NAME PROC FAR
|
||||
ELSE
|
||||
NAME PROC NEAR
|
||||
ENDIF
|
||||
ENDM
|
||||
|
||||
ENTRY MACRO NAME
|
||||
PUBLIC NAME
|
||||
IF LPROG
|
||||
NAME LABEL FAR
|
||||
ELSE
|
||||
NAME LABEL NEAR
|
||||
ENDIF
|
||||
ENDM
|
||||
|
||||
;**
|
||||
;
|
||||
; The following symbols are defined to help set up a STRUC defining the
|
||||
; stack frame:
|
||||
;
|
||||
; CPSIZE -> code pointer size (2 or 4)
|
||||
; DPSIZE -> data pointer size (2 or 4)
|
||||
;
|
||||
; These wouldn't be necessary if it were possible to use macros or even
|
||||
; conditionals within a STRUC.
|
||||
;
|
||||
IF LPROG
|
||||
CPSIZE EQU 4
|
||||
ELSE
|
||||
CPSIZE EQU 2
|
||||
ENDIF
|
||||
IF LDATA
|
||||
DPSIZE EQU 4
|
||||
ELSE
|
||||
DPSIZE EQU 2
|
||||
ENDIF
|
||||
|
||||
;
|
||||
; The SETX macro sets the symbol X to 4 if LPROG is 0 or to 6 otherwise.
|
||||
; X can then be used to skip past the BP and return address save area
|
||||
; in the stack frame when accessing the function arguments.
|
||||
;
|
||||
SETX MACRO
|
||||
IF LPROG
|
||||
X EQU 6
|
||||
ELSE
|
||||
X EQU 4
|
||||
ENDIF
|
||||
ENDM
|
||||
|
||||
;
|
||||
; The PEXTRN macro defines an external pointer in the data segment.
|
||||
;
|
||||
PEXTRN MACRO NAME
|
||||
IF LDATA
|
||||
EXTRN NAME:DWORD
|
||||
ELSE
|
||||
EXTRN NAME:WORD
|
||||
ENDIF
|
||||
ENDM
|
||||
|
||||
.LIST
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
dog equ 1
|
||||
|
|
@ -0,0 +1,167 @@
|
|||
/**
|
||||
*
|
||||
* Structure to hold information about math exceptions
|
||||
*
|
||||
*/
|
||||
struct exception
|
||||
{
|
||||
int type; /* error type */
|
||||
char *name; /* math function name */
|
||||
double arg1, arg2; /* function arguments */
|
||||
double retval; /* proposed return value */
|
||||
};
|
||||
|
||||
/*
|
||||
*
|
||||
* Exception type codes, found in exception.type
|
||||
*
|
||||
*/
|
||||
#define DOMAIN 1 /* domain error */
|
||||
#define SING 2 /* singularity */
|
||||
#define OVERFLOW 3 /* overflow */
|
||||
#define UNDERFLOW 4 /* underflow */
|
||||
#define TLOSS 5 /* total loss of significance */
|
||||
#define PLOSS 6 /* partial loss of significance */
|
||||
|
||||
/**
|
||||
*
|
||||
* Error codes generated by basic arithmetic operations (+ - * /)
|
||||
*
|
||||
*/
|
||||
#define FPEUND 1 /* underflow */
|
||||
#define FPEOVF 2 /* overflow */
|
||||
#define FPEZDV 3 /* zero divisor */
|
||||
#define FPENAN 4 /* not a number (invalid operation) */
|
||||
#define FPECOM 5 /* not comparable */
|
||||
|
||||
/**
|
||||
*
|
||||
* Constants
|
||||
*
|
||||
*/
|
||||
#define PI 3.14159265358979323846
|
||||
#define PID2 1.57079632679489661923 /* PI divided by 2 */
|
||||
#define PID4 0.78539816339744830962 /* PI divided by 4 */
|
||||
#define I_PI 0.31830988618379067154 /* Inverse of PI */
|
||||
#define I_PID2 0.63661977236758134308 /* Inverse of PID2 */
|
||||
|
||||
#define HUGE 1.797693e308 /* huge value */
|
||||
#define TINY 2.2e-308 /* tiny value */
|
||||
#define LOGHUGE 709.778 /* natural log of huge value */
|
||||
#define LOGTINY -708.396 /* natural log of tiny value */
|
||||
|
||||
/**
|
||||
*
|
||||
* External declarations
|
||||
*
|
||||
*/
|
||||
extern int _FPERR; /* floating point arithmetic error */
|
||||
extern int errno; /* UNIX error code */
|
||||
|
||||
#ifndef NARGS
|
||||
extern double acos(double);
|
||||
extern double asin(double);
|
||||
extern double atan(double);
|
||||
extern double atan2(double, double);
|
||||
extern double atof(char *);
|
||||
extern double ceil(double);
|
||||
extern double cos(double);
|
||||
extern double cosh(double);
|
||||
extern void CXFERR(int);
|
||||
extern double drand48(void);
|
||||
extern char *ecvt(double, int, int *, int *);
|
||||
extern double erand48(short *);
|
||||
extern double except(int, char *, double, double, double);
|
||||
extern double exp(double);
|
||||
extern double fabs(double);
|
||||
extern char *fcvt(double, int, int *, int *);
|
||||
extern double floor(double);
|
||||
extern double fmod(double, double);
|
||||
extern double frexp(double, int *);
|
||||
extern char *gcvt(double, int, char *);
|
||||
extern long jrand48(short *);
|
||||
extern double ldexp(double, int);
|
||||
extern void lcong48(short *);
|
||||
extern double log(double);
|
||||
extern double log10(double);
|
||||
extern long lrand48(void);
|
||||
extern int matherr(struct exception *);
|
||||
extern double modf(double, double *);
|
||||
extern long mrand48(void);
|
||||
extern long nrand48(short *);
|
||||
extern double pow(double, double);
|
||||
extern int rand(void);
|
||||
extern short *seed48(short *);
|
||||
extern double sin(double);
|
||||
extern double sinh(double);
|
||||
extern double sqrt(double);
|
||||
extern void srand(unsigned);
|
||||
extern void srand48(long);
|
||||
extern double tan(double);
|
||||
extern double tanh(double);
|
||||
|
||||
#else
|
||||
extern double acos();
|
||||
extern double asin();
|
||||
extern double atan();
|
||||
extern double atan2();
|
||||
extern double atof();
|
||||
extern double ceil();
|
||||
extern double cos();
|
||||
extern double cosh();
|
||||
extern void CXFERR();
|
||||
extern double drand48();
|
||||
extern char *ecvt();
|
||||
extern double erand48();
|
||||
extern double except();
|
||||
extern double exp();
|
||||
extern double fabs();
|
||||
extern char *fcvt();
|
||||
extern double floor();
|
||||
extern double fmod();
|
||||
extern double frexp();
|
||||
extern char *gcvt();
|
||||
extern long jrand48();
|
||||
extern void lcong48();
|
||||
extern double ldexp();
|
||||
extern double log();
|
||||
extern double log10();
|
||||
extern long lrand48();
|
||||
extern int matherr();
|
||||
extern double modf();
|
||||
extern long mrand48();
|
||||
extern long nrand48();
|
||||
extern double pow();
|
||||
extern int rand();
|
||||
extern short *seed48();
|
||||
extern double sin();
|
||||
extern double sinh();
|
||||
extern double sqrt();
|
||||
extern void srand();
|
||||
extern void srand48();
|
||||
extern double tan();
|
||||
extern double tanh();
|
||||
#endif
|
||||
|
||||
/**
|
||||
*
|
||||
* Macros
|
||||
*
|
||||
*/
|
||||
#define abs(x) ((x)<0?-(x):(x))
|
||||
#define max(a,b) ((a)>(b)?(a):(b))
|
||||
#define min(a,b) ((a)<=(b)?(a):(b))
|
||||
|
||||
/**
|
||||
*
|
||||
* Define NULL if it's not already defined
|
||||
*
|
||||
*/
|
||||
#ifndef NULL
|
||||
#if SPTR
|
||||
#define NULL 0 /* null pointer value */
|
||||
#else
|
||||
#define NULL 0L
|
||||
#endif
|
||||
#endif
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
IFDEF REGMEM
|
||||
MIN_PAGESIZE EQU 0C00H ; Minimum page size for conventional memory
|
||||
ENDIF
|
||||
|
||||
IFDEF EXPMEM
|
||||
MIN_PAGESIZE EQU 04000h ; Minimum page size for expanded memory
|
||||
ENDIF
|
||||
|
||||
IFDEF EXTMEM
|
||||
MIN_PAGESIZE EQU 04000h ; Minimum page size for extended memory
|
||||
ENDIF
|
||||
|
||||
IFDEF PROMEM
|
||||
MIN_PAGESIZE EQU 0C00h ; Minimum page size for protected memory
|
||||
MAX_PAGESIZE EQU 07FF0h ; Maximum page size for protected memory
|
||||
ENDIF
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
#ifdef REGMEM
|
||||
#define MIN_PAGESIZE 0x0C00
|
||||
#endif
|
||||
|
||||
#ifdef EXPMEM
|
||||
#define MIN_PAGESIZE 0x4000
|
||||
#endif
|
||||
|
||||
#ifdef EXTMEM
|
||||
#define MIN_PAGESIZE 0x4000
|
||||
#endif
|
||||
|
||||
#ifdef PROMEM
|
||||
#define MIN_PAGESIZE 0x0C00
|
||||
#define MAX_PAGESIZE 0x7FF0
|
||||
#endif
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
;
|
||||
; A list of EQU's for the various types of PCs
|
||||
;
|
||||
UNKNOWN equ 0
|
||||
TIPC equ 1
|
||||
IBMPC equ 0ffh
|
||||
IBMXT equ 0feh
|
||||
IBMJR equ 0fdh
|
||||
IBMAT equ 0fch ;IBM PC-AT
|
||||
IBM80 equ 0f8h ;IBM PS/2 Model 80
|
||||
IBMTYPE equ 0f0h ;IBM machine types >= this value
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
/* A list of DEFINES's for the various types of PCs */
|
||||
#define UNKNOWN 0
|
||||
#define TIPC 1
|
||||
#define IBMPC 0x0ff
|
||||
#define IBMXT 0x0fe
|
||||
#define IBMJR 0x0fd
|
||||
#define IBMAT 0x0fc
|
||||
#define IBM80 0xf8h ;IBM PS/2 Model 80
|
||||
#define IBMTYPE 0xf0h ;IBM machine types >= this value
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,888 @@
|
|||
; =====> PROSREAD.ASM
|
||||
;***************************************
|
||||
;* TIPC Scheme Runtime Support *
|
||||
;* S-Expression reading *
|
||||
;* *
|
||||
;* (C) Copyright 1985 by Texas *
|
||||
;* Instruments Incorporated. *
|
||||
;* All rights reserved. *
|
||||
;* *
|
||||
;* Date Written: 24 March 1986 *
|
||||
;* Last Modification: 10 Feb 1987 *
|
||||
;* *
|
||||
;* tc 2/10/87 fix to convert first *
|
||||
;* char after # to upper case *
|
||||
;* tc 2/10/87 added support to do *
|
||||
;* readline *
|
||||
;***************************************
|
||||
page 60,132
|
||||
include scheme.equ
|
||||
include sinterp.arg
|
||||
|
||||
SPACE equ 20h
|
||||
CTRL_Z equ 1Ah
|
||||
LINEFEED equ 0Ah
|
||||
RETURN equ 0Dh
|
||||
COM equ 3Bh
|
||||
BK_SLASH equ 5Ch
|
||||
BUFSIZE equ 256
|
||||
TEST_NUM equ 8
|
||||
EOFERR equ 1
|
||||
SHARPERR equ 7
|
||||
PORTERR equ -2
|
||||
HEAPERR equ -3
|
||||
|
||||
DGROUP group data
|
||||
data segment word public 'DATA'
|
||||
assume DS:DGROUP
|
||||
public test_ch, t_array
|
||||
extrn locases:word
|
||||
extrn hicases:word
|
||||
extrn CXFERR_s:word
|
||||
extrn port_r:word
|
||||
srd_str db "READ-ATOM",0
|
||||
sln_str db "READ-LINE",0
|
||||
inv_char db "Invalid character constant",0
|
||||
limit dw ? ; current size of atom buffer
|
||||
main_reg dw ? ; main register
|
||||
flg_eof dw ? ; whether to flag end-of-file
|
||||
atomb dw ? ; atom buffer
|
||||
test_ch db 0Ah,20h,7Fh,0Ch,09h,08h,0Dh,1Bh ; special characters
|
||||
char db 20h ; most recently received char
|
||||
t_str1 db "NEWLINE",0
|
||||
t_str2 db "SPACE",0
|
||||
t_str3 db "RUBOUT",0
|
||||
t_str4 db "PAGE",0
|
||||
t_str5 db "TAB",0
|
||||
t_str6 db "BACKSPACE",0
|
||||
t_str7 db "RETURN",0
|
||||
t_str8 db "ESCAPE",0
|
||||
t_array dw t_str1
|
||||
dw t_str2
|
||||
dw t_str3
|
||||
dw t_str4
|
||||
dw t_str5
|
||||
dw t_str6
|
||||
dw t_str7
|
||||
dw t_str8
|
||||
data ends
|
||||
|
||||
PGROUP group prog
|
||||
prog segment byte public 'PROG'
|
||||
assume CS:PGROUP
|
||||
|
||||
;;;***************************************************************************
|
||||
;;; Support for read-line
|
||||
;;;***************************************************************************
|
||||
rln_proc proc
|
||||
extrn next_SP:near
|
||||
extrn src_err:near
|
||||
|
||||
public srd_line
|
||||
srd_line: lods byte ptr ES:[SI]
|
||||
save <SI>
|
||||
add AX,offset reg0 ; compute register address
|
||||
mov main_reg,AX
|
||||
xor BX,BX
|
||||
push BX
|
||||
push AX
|
||||
C_call get_port,,Load_ES ; get the port object
|
||||
mov SP,BP ; get the return status
|
||||
test AX,AX ; error returned?
|
||||
jnz srd_lerr
|
||||
pushm <tmp_disp,tmp_page,main_reg>
|
||||
call sread_ln ; get a line
|
||||
mov SP,BP
|
||||
jmp next_SP ; return to interpreter
|
||||
;
|
||||
srd_lerr: lea BX,sln_str
|
||||
jmp src_err ; link to error handler
|
||||
rln_proc endp
|
||||
|
||||
;;;***************************************************************************
|
||||
;;; Set up for the operation of reading a single line from the given port.
|
||||
;;;***************************************************************************
|
||||
extrn setabort:near
|
||||
extrn abort:near
|
||||
extrn ssetadr:near
|
||||
srdlnarg struc
|
||||
temp_r dw ? ; temporary storage
|
||||
srdln_BP dw ? ; caller's BP
|
||||
dw ? ; caller's return address
|
||||
rp_reg dw ? ; port register
|
||||
rpg dw ? ; adjusted page number
|
||||
rdisp dw ? ; displacement
|
||||
srdlnarg ends
|
||||
;
|
||||
public sread_at
|
||||
sread_ln proc near
|
||||
push BP
|
||||
sub SP, offset srdln_BP ; allocate local storage
|
||||
mov BP,SP
|
||||
call setabort ; save stack pointer
|
||||
pushm <[BP].rdisp,[BP].rpg>
|
||||
call ssetadr ; set port address
|
||||
mov SP,BP
|
||||
test AX,AX ; check return status
|
||||
jz srdl_010
|
||||
mov AX,PORTERR ; port error
|
||||
push AX
|
||||
call abort
|
||||
;
|
||||
mov flg_eof,1 ; flag eof
|
||||
srdl_010:
|
||||
call rcvchar ; get char, eof won't return here
|
||||
cmp AL,LINEFEED ; is char linefeed?
|
||||
je srdl_010 ; if so, ignore
|
||||
|
||||
mov [BP].temp_r,AX ; save character read
|
||||
|
||||
mov AX,BUFSIZE ; Get buffer size
|
||||
mov limit,AX
|
||||
push AX
|
||||
C_call getmem ; allocate buffer
|
||||
mov SP,BP
|
||||
cmp AX,0 ; memory available?
|
||||
jne srdl_020
|
||||
;error allocate C heap space
|
||||
mov AX,HEAPERR ; no, error
|
||||
push AX
|
||||
call abortrea
|
||||
mov SP,BP
|
||||
jmp srdln_ret
|
||||
|
||||
srdl_020: mov SI,AX
|
||||
mov atomb,AX ; address of buffer
|
||||
mov flg_eof,0 ; don't flag error on EOF
|
||||
xor BX,BX ; index into buffer
|
||||
mov AX,[BP].temp_r ; restore saved character
|
||||
; read characters
|
||||
srdln_cha:
|
||||
cmp AL,RETURN ; Return character?
|
||||
je srdln_ret ; yes, return
|
||||
cmp AL,CTRL_Z ; EOF character?
|
||||
je srdln_ret ; yes, return
|
||||
cmp AL,LINEFEED ; Linefeed character?
|
||||
je srdln_ret ; yes, don't put in atomb
|
||||
|
||||
pushm <AX,BX>
|
||||
call addchar ; Add character to buffer
|
||||
mov SP,BP
|
||||
inc BX
|
||||
srdln_nxt:
|
||||
call rcvchar ; Get next character
|
||||
jmp srdln_cha ; Go get next character
|
||||
|
||||
srdln_ret:
|
||||
mov CX,STRTYPE ; Allocate string data type
|
||||
mov [BP].temp_r,BX
|
||||
pushm <BX,CX,main_reg>
|
||||
c_call alloc_bl,,Load_ES
|
||||
mov SP,BP
|
||||
mov CX,3 ; Copy buffer to Scheme string
|
||||
mov SI,atomb
|
||||
pushm <[BP].temp_r,SI,CX,main_reg>
|
||||
call toblock
|
||||
mov AX,limit ; Release buffer
|
||||
pushm <AX,atomb>
|
||||
C_call rlsmem
|
||||
mov SP,BP
|
||||
mov flg_eof,1 ; Reset flags
|
||||
mov limit,0
|
||||
add SP,offset srdln_BP ; Deallocate local storage
|
||||
pop BP
|
||||
ret ; Return
|
||||
sread_ln endp
|
||||
|
||||
;;;***************************************************************************
|
||||
;;; Support for read-atom
|
||||
;;;***************************************************************************
|
||||
rds_proc proc
|
||||
extrn next_SP:near
|
||||
extrn src_err:near
|
||||
|
||||
public srd_atom
|
||||
srd_atom: lods byte ptr ES:[SI]
|
||||
save <SI>
|
||||
add AX,offset reg0 ; compute register address
|
||||
mov main_reg,AX
|
||||
xor BX,BX
|
||||
push BX
|
||||
push AX
|
||||
C_call get_port,,Load_ES ; get the port object
|
||||
mov SP,BP ; get the return status
|
||||
test AX,AX ; error returned?
|
||||
jnz srd_err
|
||||
pushm <tmp_disp,tmp_page,main_reg>
|
||||
call sread_at ; sread_atom()
|
||||
mov SP,BP
|
||||
jmp next_SP ; return to interpreter
|
||||
;
|
||||
srd_err: lea BX,srd_str
|
||||
jmp src_err ; link to error handler
|
||||
rds_proc endp
|
||||
|
||||
;;;***************************************************************************
|
||||
;;; Set up for the operation of reading a single atom from the given port.
|
||||
;;; Special characters such as ')' are parsed as lists(!) to tell them from
|
||||
;;; ordianry atoms.
|
||||
;;;***************************************************************************
|
||||
extrn setabort:near
|
||||
extrn abort:near
|
||||
extrn ssetadr:near
|
||||
sreadarg struc
|
||||
dw ? ; caller's BP
|
||||
dw ? ; caller's return address
|
||||
p_reg dw ? ; port register
|
||||
pg dw ? ; adjusted page number
|
||||
disp dw ? ; displacement
|
||||
sreadarg ends
|
||||
;
|
||||
public sread_at
|
||||
sread_at proc near
|
||||
push BP
|
||||
mov BP,SP
|
||||
call setabort ; save stack pointer
|
||||
mov BX,[BP].p_reg ;be certain main_reg gets set if
|
||||
;sread_at gets called directly from C
|
||||
mov main_reg,BX
|
||||
pushm <[BP].disp,[BP].pg>
|
||||
call ssetadr ; set port address
|
||||
mov SP,BP
|
||||
test AX,AX ; check return status
|
||||
jz srd_010
|
||||
mov AX,PORTERR ; port error
|
||||
push AX
|
||||
call abort
|
||||
;
|
||||
srd_010: mov flg_eof,1 ; initialization
|
||||
mov limit,0
|
||||
; skip spaces
|
||||
srd_spa: call rcvchar
|
||||
call ck_space ; check for space
|
||||
test CX,CX
|
||||
jz srd_spa ; yes, skip
|
||||
; skip comments
|
||||
srd_com: cmp AL,COM ; check for comment
|
||||
jne srd_at
|
||||
srd_c10: call rcvchar
|
||||
cmp AL,RETURN
|
||||
jne srd_c10 ; yes, ignore the whole line
|
||||
jmp srd_spa
|
||||
;
|
||||
srd_at: test AL,AL ; null character?
|
||||
jz srd_spa
|
||||
call read_ato
|
||||
pop BP
|
||||
ret
|
||||
sread_at endp
|
||||
|
||||
;;;***************************************************************************
|
||||
;;; Fetch one character from the input stream
|
||||
;;;***************************************************************************
|
||||
extrn take_ch:near
|
||||
rcvchar proc near
|
||||
pop DX ; fetch return address
|
||||
;
|
||||
push DX ; save registers
|
||||
push SI
|
||||
push DI
|
||||
push CX
|
||||
push BX
|
||||
call take_ch ; takechar()
|
||||
pop BX ; restore registers
|
||||
pop CX
|
||||
pop DI
|
||||
pop SI
|
||||
pop DX
|
||||
; Check the character
|
||||
cmp AX,256
|
||||
jge rcv_10
|
||||
cmp AL,CTRL_Z ; EOF character?
|
||||
je rcv_10 ; yes, jump
|
||||
mov char,AL
|
||||
jmp DX ; return to caller
|
||||
; EOF character is fetched
|
||||
rcv_10: cmp flg_eof,0 ; EOF flag set?
|
||||
jne rcv_20 ; yes, error
|
||||
mov AX,CTRL_Z
|
||||
mov char,AL
|
||||
jmp DX ; return to caller
|
||||
;
|
||||
rcv_20: mov AX,EOFERR
|
||||
push AX
|
||||
call abortrea ; abortread(EOFERR)
|
||||
rcvchar endp
|
||||
|
||||
;;;***************************************************************************
|
||||
;;; Read in an atom (symbol, string, number)
|
||||
;;; Store the pointer to the atom in REG.
|
||||
;;; Special characters such as ')' or ',' are read as atoms themselves.
|
||||
;;; Normal atoms will end in a whitespace or a terminating macro character;
|
||||
;;; strings end with the closing '"'.
|
||||
;;; Numbers in the requested base are interpreted as such.
|
||||
;;; On exit, the next character in the buffer is the one following the last
|
||||
;;; character of the atom.
|
||||
;;;***************************************************************************
|
||||
extrn toblock:near
|
||||
extrn cons:near
|
||||
extrn buildint:near
|
||||
extrn alloc_st:near
|
||||
extrn scannum:near
|
||||
extrn pushchar:near
|
||||
|
||||
readarg struc
|
||||
num_base dw ? ; base of number
|
||||
tmpreg dw ?
|
||||
inputch dw ? ; whether the #\ macro is in effect
|
||||
escaped dw ? ; whether an escape char is used
|
||||
inflo dq ? ; for floating point value
|
||||
bignum dw ?
|
||||
biglimit dw ?
|
||||
read_BP dw ? ; caller's BP
|
||||
dw ? ; caller's ES
|
||||
dw ? ; caller's return address
|
||||
readarg ends
|
||||
;
|
||||
read_ato proc near
|
||||
push ES
|
||||
push BP
|
||||
sub SP,offset read_BP ; allocate local storage
|
||||
mov BP,SP
|
||||
xor CX,CX
|
||||
mov [BP].tmpreg,AX
|
||||
;;; cmp AL,SPACE ; check for space?
|
||||
;;; jne read_at
|
||||
;;; mov [DI].C_page,CX ; yes, form NIL and return
|
||||
;;; mov [DI].C_disp,CX
|
||||
;;; jmp read_end
|
||||
read_at: mov flg_eof,CX ; initialization
|
||||
mov [BP].inputch,CX
|
||||
mov [BP].escaped,CX
|
||||
mov CXFERR_s,CX
|
||||
mov AX,BUFSIZE
|
||||
mov limit,AX
|
||||
mov [BP].num_base,10
|
||||
push AX
|
||||
C_call getmem ; allocate memory
|
||||
mov SP,BP
|
||||
cmp AX,0 ; memory available?
|
||||
jne read_01
|
||||
memerr: mov AX,HEAPERR ; no, error
|
||||
push AX
|
||||
call abortrea
|
||||
mov SP,BP
|
||||
jmp read_ret
|
||||
read_01: mov SI,AX
|
||||
mov atomb,AX ; save the address of atom buffer
|
||||
mov DI,main_reg
|
||||
xor BX,BX
|
||||
mov AX,[BP].tmpreg
|
||||
; check for the special character first
|
||||
cmp AL,5Bh ; [
|
||||
je read_10
|
||||
cmp AL,5Dh ; ]
|
||||
je read_10
|
||||
cmp AL,7Bh ; {
|
||||
je read_10
|
||||
cmp AL,7Dh ; }
|
||||
je read_10
|
||||
cmp AL,28h ; (
|
||||
je read_10
|
||||
cmp AL,29h ; )
|
||||
je read_10
|
||||
cmp AL,27h ; '
|
||||
je read_10
|
||||
cmp AL,60h ; `
|
||||
jne read_st
|
||||
; special character case
|
||||
read_10: mov [SI],AL ; *atomb = ch
|
||||
inc BX
|
||||
jmp read_sp
|
||||
;
|
||||
read_st: cmp AL,22h ; "
|
||||
jne read_co
|
||||
; string case
|
||||
push AX
|
||||
call delimby ; get the string
|
||||
mov SP,BP
|
||||
mov [BP].tmpreg,BX ; save BX register
|
||||
mov CX,STRTYPE
|
||||
pushm <BX,CX,main_reg>
|
||||
C_call alloc_bl,,Load_ES ; allocate string object
|
||||
mov SP,BP
|
||||
mov CX,3
|
||||
mov SI,atomb
|
||||
pushm <[BP].tmpreg,SI,CX,main_reg>
|
||||
call toblock ; copy string to string object
|
||||
jmp read_bye
|
||||
;
|
||||
read_co: cmp AL,2Ch ; ,
|
||||
jne read_mac
|
||||
; comma case
|
||||
mov [SI],AL
|
||||
inc BX
|
||||
call rcvchar ; get the next character
|
||||
cmp AL,40h ; check for @
|
||||
je read_20
|
||||
cmp AL,2Eh ; check for .
|
||||
je read_20
|
||||
jmp read_nor
|
||||
read_20: mov [SI+BX],AL
|
||||
inc BX
|
||||
jmp read_sp
|
||||
;
|
||||
read_mac: cmp AL,23h ; #
|
||||
je read_25
|
||||
jmp read_sym
|
||||
; macro case
|
||||
read_25: mov flg_eof,1
|
||||
read_30: test BX,BX ; first character?
|
||||
jz read_34
|
||||
read_32: jmp read_200 ; no, jump
|
||||
;
|
||||
read_34: cmp AL,23h ; #
|
||||
jne read_32 ; no, jump
|
||||
call rcvchar ; get the next character
|
||||
call ck_space ; check for space
|
||||
test CX,CX
|
||||
jnz read_40
|
||||
read_35: mov AX,SHARPERR ; yes, error
|
||||
push AX
|
||||
call abortrea
|
||||
;
|
||||
read_40: mov byte ptr [SI+1],AL ; save the character
|
||||
push BX
|
||||
mov BX,offset locases ; address of lower-case characters
|
||||
xlat
|
||||
pop BX ; restore registers
|
||||
cmp AL,62h ; b?
|
||||
jne read_d
|
||||
mov [BP].num_base,2
|
||||
jmp read_100
|
||||
;
|
||||
read_d: cmp AL,64h ; d?
|
||||
jne read_x
|
||||
mov [BP].num_base,10
|
||||
jmp read_100
|
||||
;
|
||||
read_x: cmp AL,78h ; x?
|
||||
je read_50
|
||||
cmp AL,68h ; h?
|
||||
jne read_o
|
||||
read_50: mov [BP].num_base,16
|
||||
jmp read_100
|
||||
;
|
||||
read_o: cmp AL,6Fh ; o?
|
||||
jne read_ba
|
||||
mov [BP].num_base,8
|
||||
jmp read_100
|
||||
;
|
||||
read_ba: cmp AL,BK_SLASH ; \?
|
||||
jne read_i
|
||||
call rcvchar
|
||||
pushm <AX,BX>
|
||||
call addchar
|
||||
mov SP,BP
|
||||
inc BX
|
||||
mov [BP].inputch,1
|
||||
mov [BP].escaped,1
|
||||
jmp read_100
|
||||
;
|
||||
read_i: cmp AL,69h ; i?
|
||||
je read_100
|
||||
cmp AL,65h ; e?
|
||||
je read_100
|
||||
cmp AL,73h ; s?
|
||||
je read_100
|
||||
cmp AL,6Ch ; l?
|
||||
je read_100
|
||||
cmp AL,3Ch ; <?
|
||||
je read_60 ; yes, error
|
||||
cmp AL,29h ; )?
|
||||
jne read_70
|
||||
read_60: jmp read_35 ; yes, error
|
||||
;
|
||||
read_70: mov byte ptr [SI],23h ; default
|
||||
mov BX,offset hicases ; address of higher-case characters
|
||||
xlat
|
||||
mov byte ptr [SI+1],AL ; Change letter past # to upper case
|
||||
mov BX,2
|
||||
cmp AL,28h ; check for (
|
||||
jne read_100
|
||||
jmp read_sp ; yes, special case
|
||||
;
|
||||
read_100: call rcvchar ; get the next character
|
||||
jmp read_30
|
||||
;
|
||||
read_200: mov flg_eof,0
|
||||
; handle for symbol
|
||||
read_sym: ; default
|
||||
call ck_space ; check for space
|
||||
test CX,CX
|
||||
jz read_en ; yes, jump
|
||||
cmp AL,CTRL_Z ; eof character?
|
||||
je read_en
|
||||
cmp AL,28h ; (
|
||||
je read_en
|
||||
cmp AL,29h ; )
|
||||
je read_en
|
||||
cmp AL,27h ; '
|
||||
je read_en
|
||||
cmp AL,60h ; `
|
||||
je read_en
|
||||
cmp AL,COM ; comment?
|
||||
je read_en
|
||||
cmp AL,2Ch ; ,
|
||||
je read_en
|
||||
cmp AL,22h ; "
|
||||
je read_en
|
||||
cmp AL,5Bh ; [
|
||||
je read_en
|
||||
cmp AL,5Dh ; ]
|
||||
je read_en
|
||||
cmp AL,7Bh ; {
|
||||
je read_en
|
||||
cmp AL,7Dh ; }
|
||||
je read_en
|
||||
push BX
|
||||
mov BX,offset hicases ; address of higher-case characters
|
||||
xlat
|
||||
pop BX
|
||||
cmp AL,7Ch ; |?
|
||||
jne read_210
|
||||
mov [BP].escaped,1
|
||||
push AX
|
||||
call delimby ; read the whole symbol
|
||||
mov SP,BP
|
||||
jmp read_250
|
||||
;
|
||||
read_210: cmp AL,BK_SLASH ; \?
|
||||
jne read_220
|
||||
mov [BP].escaped,1
|
||||
mov flg_eof,1
|
||||
call rcvchar
|
||||
mov flg_eof,0
|
||||
read_220: pushm <AX,BX>
|
||||
call addchar
|
||||
mov SP,BP
|
||||
inc BX
|
||||
read_250: call rcvchar ; get the next character
|
||||
jmp read_sym
|
||||
;
|
||||
read_en: xor AL,AL ; put null at end of token
|
||||
pushm <AX,BX>
|
||||
call addchar
|
||||
mov SP,BP
|
||||
; Check for single, unescaped dot
|
||||
cmp BX,1
|
||||
jne read_num
|
||||
cmp byte ptr [SI],2Eh ; check for .
|
||||
jne read_num
|
||||
cmp [BP].escaped,1
|
||||
je read_num
|
||||
jmp read_nor
|
||||
; At this point a token has been accumulated, check for number
|
||||
read_num: mov [BP].tmpreg,BX ; save BX register
|
||||
push [BP].num_base
|
||||
push SI
|
||||
call scannum ; scan number
|
||||
mov SP,BP
|
||||
mov SI,atomb ; restore SI register
|
||||
mov BX,[BP].tmpreg ; restore BX register
|
||||
test AX,AX ; number or not?
|
||||
jnz read_n05
|
||||
jmp read_500
|
||||
read_n05: cmp [BP].escaped,1
|
||||
jne read_n07
|
||||
jmp read_500
|
||||
read_n07: cmp AX,0
|
||||
jle read_300 ; negative for floating point number
|
||||
; integer of some size
|
||||
add AX,9 ; (AX + 9) / 2
|
||||
shr AX,1 ; AX = bytes needed for integer
|
||||
mov [BP].biglimit,AX ; save for later
|
||||
push AX
|
||||
C_call getmem ; allocate memory for bignum
|
||||
mov SP,BP
|
||||
cmp AX,0 ; memory available?
|
||||
jne read_n10
|
||||
jmp memerr ; no, error
|
||||
read_n10: mov BX,AX
|
||||
mov [BP].bignum,AX
|
||||
mov byte ptr [BX+3],0
|
||||
mov byte ptr [BX+4],0
|
||||
pushm <[BP].num_base, atomb, BX>
|
||||
call buildint ; form integer
|
||||
mov SP,BP
|
||||
mov DI,main_reg
|
||||