home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CP/M
/
CPM_CDROM.iso
/
cpm
/
languags
/
prolog
/
epro23.ark
/
OUTPUT.MAC
< prev
next >
Wrap
Text File
|
1986-11-02
|
6KB
|
461 lines
; ===========================================================
;OUTPUT.Z80
; output routines for E-Prolog
; May 24, 1985
.Z80
FALSE EQU 0
TRUE EQU 1
EMPTY EQU -1
UNDEF EQU -2
HT EQU 9
LF EQU 10
CR EQU 13
CTLZ EQU 26
CPM EQU 0000H
BDOS EQU CPM+0005H
CDMA EQU CPM+0080H
TPA EQU CPM+0100H
; compare with given value
;
?CPHL MACRO ?VALUE
PUSH DE
LD DE,?VALUE
CALL CPHL##
POP DE
ENDM
DSEG
; output file: 0 = console, 1 = disk, -1 = null
OUTF:: DB 0
; file control block for output file
OUTFCB::
DB 0
DB ' '
DB ' '
DB 0,0,0,0
DS 20
; buffer for output file
OUTDMA::
DS 128
OUTE::
; pointer for output file
OUTP:: DW OUTDMA
CSEG
; fill with one character
;
; all registers destroyed
?FILL MACRO ?ADDR,?COUNT,?VAL
LD HL,?ADDR
PUSH HL
POP DE
INC DE
LD BC,?COUNT-1
LD (HL),?VAL
LDIR
ENDM
; copy string
;
; input:
; HL -> source
; all registers destroyed
?COPY MACRO ?ADDR
LD DE,?ADDR
CALL COPY
ENDM
; copy string
;
; input:
; HL -> source (string terminated by 0, which is
; not copied)
; DE -> destination
; all registers destroyed
DSEG
DEST: DW 0
CSEG
COPY::
LD (DEST),DE
CALL LISTP##
RET NZ
CALL NUMBP##
RET NZ
CALL @STR##
LD DE,(DEST)
COPY1: LD A,(HL)
OR A
RET Z
LD (DE),A
INC HL
INC DE
JR COPY1
; create FCB for output file.
;
; input:
; HL = list (rest of atom)
; DE = lsub (substitutions for HL)
DSEG
PEXP: DW 0
PLSUB: DW 0
CSEG
DOOUT::
LD (PEXP),HL
LD (PLSUB),DE
XOR A
LD (OUTF),A
?FILL OUTFCB,36,0
?FILL OUTFCB+1,11,' '
DOOUT1: LD HL,PEXP
LD DE,PLSUB
CALL VNEXT##
CALL SYMBP##
JR Z,DOOUT3
?CPHL ACON##
JR Z,DOOUT3
LD A,-1
LD (OUTF),A
?CPHL ANULL##
JP Z,DOOUT3
LD A,1
LD (OUTF),A
?COPY OUTFCB+1
LD HL,PEXP
LD DE,PLSUB
CALL VNEXT##
CALL SYMBP##
JR Z,DOOUT3
?CPHL ACOLON##
JR NZ,DOOUT2
LD A,(OUTFCB+1)
SUB 'A'-1
LD (OUTFCB),A
?FILL OUTFCB+1,11,' '
JR DOOUT1
DOOUT2: ?CPHL ADOT##
JR NZ,DOOUT3
LD HL,PEXP
LD DE,PLSUB
CALL VNEXT##
CALL SYMBP##
JR Z,DOOUT3
?COPY OUTFCB+9
DOOUT3:
RET
CRLF:: LD HL,CRLFX
CALL MSG
RET
DSEG
CRLFX: DB CR,LF,0
CSEG
; character out
;
; input:
; character in A
; saves registers, except AF
CHROUT::
PUSH BC
PUSH DE
PUSH HL
LD E,A
LD A,(OUTF) ; output device
OR A
JR Z,CHRO1 ; console
DEC A
JR NZ,CHROE ; null
LD HL,(OUTP) ; disk file
PUSH DE
LD DE,OUTE
CALL CPHL##
POP DE
JR NZ,CHRO2
PUSH DE ; E = character
CALL FLUSH ; flush buffer
POP DE ; E = character
LD HL,OUTDMA
CHRO2: LD (HL),E
INC HL
LD (OUTP),HL
JR CHROE
CHRO1: LD C,2 ; console write
CALL BDOS
CHROE: POP HL
POP DE
POP BC
RET
; flush output file buffer
FLUSH::
LD DE,OUTDMA
LD C,26 ; set DMA
CALL BDOS
LD DE,OUTFCB
LD C,21 ; write sequential
CALL BDOS
OR A
RET Z
LD HL,DSKERR
JP FATAL##
DSEG
DSKERR: DB CR,LF,'DISK WRITE ERROR.',0
CSEG
;msg(s)
; char * s;
; {
; register char c;
; while(c = *s++)
; chrout(c);
; }
MSG::
LD A,(HL)
INC HL
OR A
RET Z
CALL CHROUT
JR MSG
; close existing output device
CLOSE::
LD A,(OUTF) ; output device
DEC A
LD A,0
LD (OUTF),A ; revert to console
RET NZ
LD HL,(OUTP)
CLOSE0: ?CPHL OUTE
JR Z,CLOSE1
LD (HL),CTLZ ; fill with ^Z
INC HL
JR CLOSE0
CLOSE1: CALL FLUSH
LD DE,OUTFCB
LD C,16 ; close file
CALL BDOS
RET
;eprint(ex,ls) /* recursive */
; EXPR ex;
; LSUBST ls;
DSEG
EXP: DW 0
LSU: DW 0
; {
; EXPR e;
; SUBVAL sv;
SV: DW 0
CSEG
EPRINT::
;
LD (EXP),HL
LD (LSU),DE
; e.list = ex; /* synonym */
; if (varp(ex) && ls != (LSUBST)empty)
CALL VARP
JP Z,EP1
LD HL,(LSU)
?CPHL EMPTY
JR Z,EP1
; {
; sv.val = value(vf(ex,ls));
LD HL,(EXP)
LD DE,(LSU)
CALL VF##
CALL VALUE##
LD (SV),HL
; if (substp(sv.val))
CALL SUBSTP##
JR NZ,EP1
; ;
; else
; {
; ex = e.list = sv.assgn->sexp.list;
CALL @EXPR##
LD (EXP),HL
; ls = sv.assgn->slist;
LD HL,(SV)
CALL @SLIST##
LD (LSU),HL
; }
; }
EP1:
; if (numbp(ex))
; return prdec(ex);
LD HL,(EXP)
CALL NUMBP##
JP NZ,PRDEC
; if (symbp(ex))
; return msg(e.symbol->string);
CALL SYMBP##
JR Z,EP2
CALL @STR##
JP MSG
EP2:
; chrout('(');
LD A,'('
CALL CHROUT
; while (ex != (PAIR)empty)
EP3:
LD HL,(EXP)
?CPHL EMPTY
JP Z,EP4
; {
; eprint(ex->left.list,ls);
LD HL,(SV)
PUSH HL
LD HL,(EXP)
PUSH HL
CALL @LEFT##
LD DE,(LSU)
PUSH DE
CALL EPRINT ; recursion
POP HL
LD (LSU),HL
POP HL
POP DE
LD (SV),DE
; ex = e.list = ex->right.list;
CALL @RIGHT##
LD (EXP),HL
; if (varp(ex) && ls != (LSUBST)empty)
CALL VARP##
JR Z,EP5
LD HL,(LSU)
?CPHL EMPTY
JR Z,EP5
; {
; sv.val = value(vf(ex,ls));
LD HL,(EXP)
LD DE,(LSU)
CALL VF##
CALL VALUE##
LD (SV),HL
; if (substp(sv.val))
; ;
CALL SUBSTP
JR NZ,EP5
; else
; {
; ex = e.list = sv.assgn->sexp.list;
LD HL,(SV)
CALL @EXPR##
LD (EXP),HL
; ls = sv.assgn->slist;
LD HL,(SV)
CALL @SLIST
LD (LSU),HL
; }
; }
EP5:
; if (! listp(ex))
; {
LD HL,(EXP)
CALL LISTP
JR NZ,EP6
; msg(" | ");
LD HL,EPM
DSEG
EPM: DB ' | ',0
CSEG
CALL MSG
; eprint(ex,ls);
LD HL,(SV)
PUSH HL
LD HL,(EXP)
PUSH HL
LD DE,(LSU)
PUSH DE
CALL EPRINT ; recursion
POP HL
LD (LSU),HL
POP HL
LD (EXP),HL
POP HL
LD (SV),HL
; break;
JR EP4
; }
EP6:
; if (ex != (PAIR)empty)
; chrout(' ');
LD HL,(EXP)
?CPHL EMPTY
JR Z,EP8
LD A,' '
CALL CHROUT
; }
EP8:
JP EP3
EP4:
; return chrout(')');
LD A,')'
JP CHROUT
; }
; print decimal
;
; input:
; HL = number
; side effect:
; print out in decimal
; all registers destroyed
PRDEC::
LD A,H
OR L
JR NZ,PRD1
LD A,'0'
JP CHROUT
PRD1: LD BC,DD1
PRD2: LD A,(BC)
LD E,A
INC BC
LD A,(BC)
LD D,A
INC BC
PUSH HL
XOR A
SBC HL,DE
POP HL
JR C,PRD2
PRDL: XOR A
PRD3: SBC HL,DE
JR C,PRD4
INC A
JR PRD3
PRD4: ADD HL,DE
ADD A,'0'
CALL CHROUT
LD A,1
CP E
RET Z
LD A,(BC)
LD E,A
INC BC
LD A,(BC)
LD D,A
INC BC
JR PRDL
DSEG
DD1: DW 10000
DW 1000
DW 100
DW 10
DW 1
CSEG
END