home *** CD-ROM | disk | FTP | other *** search
Text File | 1984-04-29 | 27.4 KB | 1,031 lines |
-
- ; =======================================================
- ; REC module containing RAM storage, I/O programs, main
- ; program, and the directory. The complete set of modules
- ; comprises REC80.MAC, PDL80.MAC, MKV80.MAC, RECLIB.MAC, and
- ; FXT80.MAC. RECLIB.MAC may be omitted if the operator X
- ; isn't used, and must be substituted by another module
- ; if the collection of subroutines to be called by X is
- ; to be changed.
- ;
- ; FXT80.MAC contains the following REC operators and
- ; predicates:
- ;
- ; C compile a REC expression
- ; i input from designated port
- ; k call CP/M without residue
- ; K call CP/M, preserve FCB, return value
- ; o output from designated port
- ; R read one character from console
- ; t type message given header
- ; T type argument on PDL
- ; W write argument on LST:
- ; x execute REC subroutine
- ; ` test if a character waits at keyboard
- ;
- ; REC version released during the 1980 Summer School of
- ; the Microcomputer Applications Group of the I.C.U.A.P.
- ;
- ; FXT80 - Copyright (C) 1980
- ; Universidad Autonoma de Puebla
- ; 49 Poniente 1102 - Puebla, Puebla, Mexico
- ; All Rights Reserved
- ;
- ; [Harold V. McIntosh, 28 August 1980]
- ;
- ; 1 January 1981 - get address of BIOS vector from rst0
- ; 1 January 1981 - protect T with pushes, pops of DE, HL
- ; 1 January 1981 - memory reorganization
- ; 24 May 1981 - 0000 at bottom of PDL to restrain L
- ; 3 March 1982 - rewrite extension as REC - (FGZ)
- ; 25 March 1982 - Y is now a predicate
- ; 25 April 1982 - C is also a predicate, modified for {}'s
- ; 20 May 1983 - N is numerical comparison predicate
- ; 20 May 1983 - h has been withdrawn
- ; 28 May 1983 - ~ has been redefined
- ; 30 May 1983 - cpin: return to CP/M if file won't open
- ; 8 July 1983 - C has object program origin as argument
- ; 8 July 1983 - C is an operator
- ; 8 July 1983 - c0 defined as lower limit compile area
- ; 8 July 1983 - x has been moved from RECLIB.MAC
- ; 8 July 1983 - x predicate - to call REC subroutines
- ; 9 July 1983 - Buffered CP/M input if no disk file given
- ; 14 July 1983 - exchange arguments of W
- ; 21 July 1983 - partition available memory on entry
- ; =======================================================
-
- ; Absolute program locations used by CP/M.
-
- rst0 equ 0000H
- boot equ rst0 ;CP/M bootstrap entry point
- bios equ rst0+1 ;CP/M BIOS reference point
- bdos equ rst0+5 ;CP/M I-O communication point
- emem equ rst0+6 ;where effective end of memory is stored
-
- tfcb equ 005CH ;CP/M file control block
- talt equ 006CH ;CP/M alternate file name
- fsiz equ 0010H ;CP/M file name size
- tbuf equ 0080H ;CP/M disk buffer location
- tsiz equ 0080H ;CP/M disk buffer size
-
- ; Useful constant.
-
- ze equ 00H
-
- ; Equivalences to other REC subroutines.
-
- ext noop
- ext ucl,cucl,narg,oarg
- ext miuc,mduc,putw,bcld,deld
- ext skp,req,seq,rer,rr2
- ext psiz,siz,sng,sing
- ext left,recrr,onel
-
- ext recre,emce,emcu,emcv,emcx,ar,nar,inre
-
- ext twol
-
- ; =======================================================
- ; Programs related to input-output and disk usage.
- ; =======================================================
-
- ; Buffer read routine.
-
- pty: push h ;conserve HL
- lhld rx ;pointer to read buffer
- mov a,m ;fetch byte
- inx h ;advance pointer to next byte
- shld rx ;update buffer pointer
- pop h ;restore HL - preserve all reg pairs
- ret
-
- ; Console character read routine. Strict CP/M compatible
- ; version, which has characteristics undesirable for some
- ; applications, such as an automatic echo or preemption
- ; of some of the control characters for editing purposes.
- ; When it is used, programs must forego their own echo,
- ; and do their own editing when required.
-
- ;chin: push h
- ; push d
- ; push b
- ; mvi c,1 ;read from console
- ; call bdos
- ; pop b
- ; pop d
- ; pop h
- ; ret
-
- ; Version with direct access to CONIN.
-
- chin equ conin
-
- ; Buffered console character read routine, which is more
- ; practical for use with CP/M.
-
- buin: push h ;save 3 register pairs
- push d ;
- push b ;
- lhld ry ;buffer limit
- xchg ;
- lhld rx ;buffer pointer
- mov a,l ;check for exhausted buffer
- cmp e ;
- jnz bi5 ;buffer remnant available
- mov a,h ;
- cmp d ;
- jnz bi5 ;buffer remnant available
- mvi c,9 ;(09) write message
- lxi d,bume ;REC80 prompt
- call bdos ;
- mvi c,10 ;(0A) buffered read
- lxi d,tbuf ;
- call bdos ;
- mvi c,9 ;(09) write message
- lxi d,crlf ;CR,LF
- call bdos ;
- lxi h,tbuf+2 ;where the text begins
- shld rx ;buffer pointer
- dcx h ;
- mov e,m ;get occupancy
- mvi d,0 ;insert leading zero
- dad d ;calculate final address
- inx h ;plus one more - that's REC style
- shld ry ;buffer limit
- lhld rx ;buffer pointer
- bi5: mov a,m ;pick up the next character
- inx h ;ready for another
- shld rx ;buffer pointer
- pop b ;restore 3 registers
- pop d ;
- pop h ;
- ret
-
- logo: db 0DH,0AH,' REC(8080)/ICUAP',0DH,0AH
- db 'Universidad Autonoma de Puebla',0DH,0AH
- db ' November 20, 1983',0DH,0AH,'$'
- bume: db 0DH,0AH,'REC80> $'
- crlf: db 0DH,0AH,'$'
-
- ; Define the console buffer as the source code reader.
-
- bure: lxi h,tbuf ;the disk won't be using its buffer
- mvi m,tsiz-2 ;define its maximum length
- inx h ;text origin is two bytes on
- inx h ;
- shld rx ;buffer pointer
- shld ry ;buffer limit
- lxi h,buin ;buffered source from console
- shld re ;REC compiler's I-O linkage
- ret
-
- ; Console character out routine. Strict CP/M compatible
- ; version, which unfortunately makes so many tests and
- ; jumps that it is unsuitable for programs such as the
- ; cursor editor which frequently write a full screen.
-
- ;chou: push h
- ; push d
- ; push b
- ; mvi c,2 ;write character at console
- ; mov e,a
- ; call bdos
- ; pop b
- ; pop d
- ; pop h
- ; ret
-
- ; Version with fast access to conout.
-
- chou: push b
- mov c,a
- call conou
- pop b
- ret
-
- ; (`) Test for preesence of waiting character (FALSE if
- ; none waiting).
- ;
- ;chaw: mvi c,11 ;<test for waiting character>
- ; call bdos ;
- ; rrc ;bit 0 holds the relevant information
- ; rnc ;FALSE return if the bit is zero
- ; jmp skp ;TRUE return if it is set
-
- ; Version with fast access to const. It is required when
- ; the fast chin is used, because CP/M has some internal
- ; buffers which will otherwise distort the results.
-
- chaw: call const
- rrc
- rnc
- jmp skp
-
- ; Printer output routine.
-
- prou: push h
- push d
- push b
- mvi c,5 ;output through LST:
- mov e,a
- call bdos
- pop b
- pop d
- pop h
- ret
-
- ; (R) REC read operator.
-
- ucr: lxi b,1 ;one byte to be inserted
- call narg ;close last arg, verify space
- call tyin ;get byte from console input
- mov m,a ;store on PDL
- inx h ;advance pointer
- shld py ;save as terminator
- ret
-
- ; (t) Write indirect operator. <org,siz,t> prints the
- ; indicated message, leaves no residue.
-
- lct: lhld px ;fetch argument pointer
- call twol ;move two args to 8080 stack
- pop d ;second arg (org) into DE
- pop h ;top arg (siz) into HL
- dad d ;org+siz=end
- xchg ;DE=end, HL=org
- jmp ut1 ;use write cycle in UCT
-
- ; (T) REC write operator. <'XXX' T> will write XXX on
- ; the console, leaving it on the PDL.
-
- uct: lhld py ;fetch terminal address
- xchg ;put it in DE
- lhld px ;beginning address to HL
- ut1: mov a,e ;compare low bytes
- cmp l ;
- jnz ut2 ;don't match, keep writing
- mov a,d ;compare high bytes
- cmp h ;
- rz ;they match, we're done
- ut2: mov a,m ;get byte out of memory
- push h ;the registers DE and HL
- push d ;are essential for the loop
- call tyou ;send it to typeout
- pop d ;recover the saved registers
- pop h ;
- inx h ;advance pointer
- jmp ut1 ;repeat
-
- ; (W) REC print operator. <org, siz, W> will print the
- ; indicated text on the list device, and then erase its
- ; arguments.
-
- ucw: lhld px ;pointer to arguments
- call twol ;2 args from PDL to 8080 stack
- pop h ;place text origin in HL
- pop d ;place length in DE
- uww: mov a,e ;check for zero length
- ora d ;by superposing length bytes
- rz ;no more to print
- mov a,m ;fetch a byte
- push h ;we need to be sure that DE and HL are
- push d ;preserved whatever the print routine
- call prou ;send it to printer
- pop d ;recover HL
- pop h ;and DE
- dcx d ;diminish count
- inx h ;advance pointer
- jmp uww ;repeat
-
- ; (i) Input from designated port. <port, i> leaves
- ; <port, byte> so that after disposing of <byte>, <port>
- ; can be reused.
-
- lci: lhld px ;get pointer to top argument on PDL
- mov a,m ;only the low order byte matters
- sta qi ;place it in teme IN instruction
- lxi b,1 ;we're only going to read one byte
- call narg ;prepare a place for it on the PDL
- call qin ;execute the captive IN instruction
- mov m,a ;storing the incoming byte on the PDL
- inx h ;always ready for the next byte
- shld py ;close off the argument
- ret ;and we're through
-
- ; (o) Output from designated port - <port, byte, o>
- ; leaves <port>, facilitating multiple OUTs through the
- ; same port.
-
- lco: lhld px ;pointer to last argument - output byte
- mov b,m ;tuck it into register b
- call ucl ;erase the top argument
- mov a,m ;HL points to next argument - get it
- sta qo ;store in tame OUT instruction
- mov a,b ;output must be from accumulator
- jmp qou ;execute the prepared OUT instruction
-
- ; =======================================================
- ;
- ; Communication with CP/M takes two forms: <FCB, n, K>
- ; which leaves <FCB, coDe> on the pushdown list, or else
- ; <FCB, n, k> which leaves nothing on the pushdown list.
- ; In either case - FCB is a two-byte parameter, usually
- ; the address of the file control block - but it could
- ; also be a DMA address or sometimes even null for the
- ; sake of uniformity. Approximately thirty options are
- ; available which are numbered serially, indicated by the
- ; argument n. The difference between K and k is that the
- ; former conserves the parameter FCB for possible use by
- ; a subsequent CP/M call, and reports a result in the
- ; one-byte result <code>. This could be the character
- ; read by an input routine or an error code for the disk
- ; routines.
- ;
- ; The options are:
- ;
- ; num function "FCB" "code"
- ; --- -------- ----- ------
- ;
- ; 0 system reset - -
- ; 1 read console - char
- ; 2 write console char -
- ; 3 read reader - char
- ; 4 write punch char -
- ; 5 write list char -
- ; 6 - - -
- ; 7 read i/o stat - stat
- ; 8 write i/ stat stat -
- ; 9 print buffer buffer -
- ; 10 read buffer buffer -
- ; 11 console status - stat
- ;
- ; 12 lift disk head - -
- ; 13 init disk only - -
- ; 14 select disk disk -
- ; 15 open file fcb code
- ; 16 close file fcb code
- ; 17 search once fcb code
- ; 18 search again fcb code
- ; 19 delete file fcb code
- ; 20 read 1 record fcb code
- ; 21 write 1 record fcb code
- ; 22 create file fcb code
- ; 23 rename file fcb code
- ; 24 read login - logv
- ; 25 read disklog - disk
- ; 26 set DMA address dma -
- ; 27 read bitmap - -
- ;
- ; Fuller details of all the CP/M options and the way they
- ; function can be obtained through consulting Digital
- ; Research's manuals for CP/M, especially their "CP/M
- ; Interface Guide."
- ;
- ; =======================================================
-
- ; (K) Set up communication with CP/M - top into BC,
- ; next into DE. Preserve next, call BDOS, (Aze) into
- ; top.
-
- cpm: lhld px ;fetch pointer to top argument
- mov c,m ;load C from low byte
- inx h ;next byte
- mov b,m ;load B from high byte
- lhld px ;pointer to top argument again
- dcx h ;high byte, pointer to prev arg
- mov d,m ;load up DE with high byte
- dcx h ;low byte, pointer to prev arg
- mov e,m ;finish loading DE
- xchg ;pointer into HL
- mov e,m ;low byte of under argument
- inx h ;advance pointer
- mov d,m ;high byte of under argument
- call bdos ;call BDOS with args in BC, DE
- lhld px ;pointer to top argument again
- mov m,a ;save low byte from A
- inx h ;on to high byte
- mvi m,ze ;make high byte a zero
- ret
-
- ; (k) Call to CP/M without any value returned.
-
- cpml: call bcld ;load top arg into BC, lift it
- call deld ;load next arg into DE, lift it too
- jmp bdos ;execute indicated operation
-
- ; -------------------------------------------------------
- ; Disk input-output routine working through CP/M.
- ; -------------------------------------------------------
-
- ; Set up a file control block with a given file name and
- ; the default extension REC. The pushdown list contains
- ; the disk unit designation, then by the filename without
- ; any extension. No protection is afforded against an
- ; overly long file name, a nonexistent disk, or the like.
- ; Some errors of this type must be caught by CP/M since
- ; REC cannot know such things as the exact number of disk
- ; drives that there will be.
-
- diin: mvi b,21H ;FCB requires 33 bytes
- lxi h,tfcb ;use CP/M's transient FCB
- mvi a,00H ;fill it with zeroes
- di1: mov m,a ;loop for block zero
- inx h ;advance pointer
- dcr b ;reduce count
- jnz di1 ;repeat until count vanishes
- mvi b,8 ;filename field is 8 bytes long
- lxi h,tfcb+1 ;field begins at second byte
- mvi a,' ' ;fill it with blanks
- di2: mov m,a ;loop for block of blanks
- inx h ;advance pointer
- dcr b ;reduce count
- jnz di2 ;repeat until count vanishes
- mvi m,'R' ;place 'REC' in extension field
- inx h ;
- mvi m,'E' ;
- inx h ;
- mvi m,'C' ;
- lhld px ;fetch pointer to top argument
- mov a,m ;load disk unit designator
- sui '@' ;normalize to uppercase letters
- sta tfcb ;store it in file control block
- call ucl ;pop top argument
- lhld px ;fetch pointer to file name
- xchg ;place it in DE for source
- lhld py ;end of file name
- call siz ;place py - px in BC
- lxi h,tfcb+1 ;destination origin
- call miuc ;move by increment until count
- cpin: lda tfcb+1
- cpi ' '
- jz boot ;no file given, so quit
- mvi c,15 ;<open file>
- lxi d,tfcb ;file control block
- call bdos ;
- cpi 0FFH ;check for error
- jz boot ;don't hang system; so quit instead
- lxi h,tbuf ;origin of CP/M's sector buffer
- shld rx ;initial address of pseudotty
- shld ry ;provoke disk read
- ret
-
- ; Read from disk buffer, replenish buffer when empty.
-
- dire: push h ;save 3 8080 register pairs
- push d ;
- push b ;
- lhld ry ;pointer to end of buffer
- xchg ;place in DE
- lhld rx ;pointer to current byte
- call seq ;skip if equal
- jmp di5 ;still have bytes in the buffer
- mvi c,20 ;<read next record>
- lxi d,tfcb ;file control block
- call bdos ;
- lxi h,tbuf+tsiz ;end of buffer
- shld ry ;store it in ry
- lxi h,tbuf ;beginning of buffer
- shld rx ;store it in rx
- di5: mov a,m ;common continuation
- inx h ;byte in acc, advance pointer
- shld rx ;store position of next byte
- pop b ;replace 3 register pairs
- pop d ;
- pop h ;
- ret
-
- ; Stack the secondary file name on the 8080's PDL.
-
- pualt: mvi b,fsiz ;load size of file name
- lxi d,talt ;load origin of secondary name
- pop h ;put the return address in HL
- pual: ldax d ;load acc from FCB
- push psw ;transfer to 8080 stack
- inx d ;advance pointer
- dcr b ;reduce count
- jnz pual ;repeat until count vanishes
- pchl ;return to addr stored in HL
-
- ; ================
- ; = main program =
- ; ================
-
- main:: lhld emem ;BDOS entry point is end of memory
- sphl ;define stack (end of memory)
- lxi d,-800H ;reserve space for stack
- dad d ;
- mvi m,0 ;0000 as barrier for '>'
- dcx h ;
- mvi m,0 ;
- dcx h ;
- shld p4 ;end of workspace
- xchg ;
- lxi h,bmem ;beginning of free memory
- shld c0 ;compile area lower limit
- shld c1 ;compile area pointer
- mov a,e ;calculate amount of available memory
- sub l ;
- mov e,a ;
- mov a,d ;
- sbb h ;
- mov d,a ;
- mvi b,3 ;right shift 3 = divide by 8
- majn: mov a,d ;shift loop
- ora a ;
- rar ;
- mov d,a ;
- mov a,e ;
- rar ;
- mov e,a ;
- dcr b ;
- jnz majn ;
- dad d ;assign 1/2 memory to compile area
- dad d ;
- dad d ;
- dad d ;
- shld c2 ;compile area upper limit
- mvi m,0 ;store 0000 as barrier to 'L'
- inx h ;
- mvi m,0 ;
- inx h ;
- shld px ;beginning of PDL
- shld py ;with null argument
- dad d ;assign 3/8 of memory to PDL
- dad d ;
- dad d ;
- shld pz ;upper limit of PDL
- shld p0 ;lower limit of workspace
- shld p1 ;initially filled with null text
- shld p2 ;workspace gets 1/8+roundoff of memory
- shld p3 ;
-
- ; Up to this point the memory has been partitioned between the
- ; compile area, pushdown list, workspace, and 8080 stack. By
- ; changing the distribution, it might be possible to accomodate
- ; the memory balance of a specific application better.
-
- lxi d,0003H ;length of one jump instruction
- lhld bios ;BIOS vector reference point
- dad d ;
- shld cnst ;jump to const = bios(1)
- dad d ;
- shld cnin ;jump to conin = bios(2)
- dad d ;
- shld cnou ;jmp to conout = bios(3)
- lda tfcb+1 ;if no disk, source from console
- cpi ' ' ;
- jz tylo ;type logo - including version date
- call pualt ;save secondary file name
- call cpin ;open disk file for REC program
- lxi h,dire ;REC input through disk
- shld re ;REC compiler's I-O linkage
- call inre ;initialize REC compiler RAM
- call emcx ;compile the program file
- mvi b,fsiz ;length of filename
- lxi d,tfcb+fsiz ;end of secondary filename
- pop h ;emcx leaves execution addr on stack
- poal: dcx d ;restoration loop runs backward
- pop psw ;
- stax d ;
- dcr b ;
- jnz poal ;
- push h ;put execution address back on stack
- call emcu ;execute the program file
- jmp boot ;return to CP/M if false
- jmp boot ;or even if it was true
-
- tylo: mvi c,9 ;(09) write message
- lxi d,logo ;'UAP ...' logo, version date
- call bdos ;
- nodi: call bure ;initialize for console buffer
- call inre ;initialize REC's RAM area
- call emcx ;compile a program
- call emcu ;execute it
- jmp nodi ;no-disk loop
- jmp nodi ;no-disk loop
-
- ; (C) REC compiling operator, which obtains the object code
- ; origin and the source code address from the pushdown list,
- ; in the form <'object', 'source', C>.
- ;
- ; <'', 'source', C> will use the current value of c1 for the
- ; object code origin, and would be the alternative normally
- ; selected by someone who did not want to do his own memory
- ; management. If c0 .LE. 'object' .LE. c2, c1 will be set to
- ; 'object', very likely disrupting the compile area; thus any
- ; origin must be specified with care. However, if the origin
- ; is taken from a value returned by C, all will work smoothly,
- ; allowing for the automatic erasure of a subroutine once it
- ; has been executed and is no longer needed. Likewise there
- ; will be no conflict if a compile area is taken from the
- ; pushdown list using the operator c.
- ;
- ; Ignoring 'object' for the moment, the various options for
- ; just <'source', C> are:
- ;
- ; ''C input program from console
- ; 'file' 'D' C take <file.rec> from disk D
- ; pC pushdown list
- ; qC workspace
- ; <org,siz,C> memory from address org onward
- ;
- ; In general, if the 'source' argument is of length zero, then
- ; the console is the source, while if it is of length one the
- ; named disk is the source [@=current disk, A, B, ... up to the
- ; system's limit], and finally if the argument has length 2, the
- ; combination of <org, siz> from the memory applies. It is the
- ; programmer's responsibility to avoid nonexistent memory, disk
- ; units, and the like.
- ;
- ; Two values are returned to the pushdown list by C, namely
- ; <'end', 'origin'>, which define the memory occupied by the
- ; subroutine just compiled, and which will be needed for the
- ; subsequent usage of the subroutine. For example, a series
- ; of subroutines can be compiled by using the 'end' of one as
- ; 'object' for the next: <'org' 'S1' Cm 'S2' Cm ...> leaving
- ; their execution addresses on the complementary pushdown list,
- ; where they may be recovered by the operator n. In practice,
- ; they would probably be defined as they were compiled using
- ; <... C 'X'$S ... @X>, or perhaps they would be executed and
- ; discarded using <... CxL>. Housekeeping is important when
- ; subroutines are to be discarded during program execution.
- ; If the origin of a subroutine is saved, it may be reused
- ; which implies that the space which it and any following
- ; subroutines occupied may also be reused.
-
- ucc: call psiz ;fetch size of top argument
- mov a,c ;test for zero bytes
- ora b ;by jamming BC into accumulator
- jz uc2 ;zero means console
- dcx b ;test for one byte
- mov a,c ;by jamming BC into accumulator
- ora b ;
- jz uc1 ;one means disk designation
- dcx b ;verify that we've got two bytes
- mov a,c ;again jamming BC into A
- ora b ;
- jnz rer ;no provision for other than 1, 2 bytes
- lxi h,pty ;setup readin from pseudoteletype
- shld re ;REC compiler's I-O linkage
- call bcld ;size into BC
- mov e,m ;HL is uncovered px
- inx h ;
- mov d,m ;
- xchg ;
- shld rx ;origin of REC source code
- dad b ;length of source code
- shld ry ;end of source code
- jmp uc4
- uc1: call diin ;setup the CP/M FCB for given file
- lxi h,dire ;setup input from disk reader
- jmp uc3
- uc2: lxi h,chin ;input from the console
- uc3: shld re ;REC compiler's I-O linkage
- uc4: call ucl ;expose 'object program origin'
- call psiz ;zero or two bytes
- mov a,c ;check which
- ora b ;
- jnz uc5 ;not zero may be two
- lhld c1 ;compile area pointer
- xchg ;
- jmp uc6 ;use compile pointer - no checks needed
- uc5: dcx b ;verify two
- dcx b ;
- mov a,c ;
- ora b ;
- jnz rer ;reject anything else
- call deld ;fetch origin into DE
- lhld c0 ;compile area lower limit
- mov a,e ;does it lie in compile area?
- sub l ;
- mov a,d ;
- sbb h ;
- jc uc6 ;no, it's below c0
- lhld c2 ;compile area upper limit
- mov a,l ;
- sub e ;
- mov a,h ;
- sbb d ;
- jc uc6 ;no, it's above c2
- xchg ;
- shld c1 ;readjust compile area pointer
- xchg ;
- uc6: push d ;execution address
- call left ;move up to source code
- call recrr ;compile the source code
- push d ;byte following compiled subroutine
- call putw ;word from 8080 stack to PDL
- call putw ;word from 8080 stack to PDL
- ret ;must be <call, ret>, not <jmp>
-
- ; (x) Call a subroutine. <'XXXX'Hx> calls the subroutine at
- ; the absolute location XXXX, which will be assumed to be a
- ; REC predicate. If it is not, it will act as though it were
- ; a FALSE predicate, so write ('XXXX'Hx;;) instead, or use (x).
-
- go: lhld px ;pointer to top argument
- call onel ;move from PDL to 8080 stack
- ret ;must be <call, ret>, not <jmp>
-
- ; -------------------------------------------------------
- ; Equivalences to subroutines in the REC nucleus.
- ; -------------------------------------------------------
-
- ext reclp,recrp,recco,recsc
- ext recop,recpr,reco1,recp1
- ext recdd,recms,recsq,recdq,reccm
-
- ; -------------------------------------------------------
- ; Equivalences to subroutines outside this overlay.
- ; -------------------------------------------------------
-
- ext qu,nu,ns,hs
- ext eql,pe
- ext ga,gb,gbi,gwi
- ext sa,sai
- ext gxs,lcq,ind
- ext uco,he,hx
- ext blok,conc
- ext sum,dif,mpy,dvd
- ext decr,incr
- ext exch,comp
- ext lca,uca,lcb,ucb,ucd,lce,uce,lcf,ucf
- ext uci,lcj,ucj,lcl,lcm,ucm,ucn,lcn,ucp
- ext lcq,ucq,lcs,ucu,ucv,lcw,ucy,lcz,ucz
- ext qm,bra,ket,ip
- ext vble,libr
- ext lbr
-
- ft: dw noop ;blank
- dw noop
- dw recop ; ! binary to hex string
- dw hx
- dw recdq ; " quoted expression
- dw qu
- dw recop ; # binary to decimal string
- dw ns
- dw recop ; $ fetch a variable cell
- dw vble
- dw recop ; % restrict to one byte
- dw pe
- dw recop ; & exchange top numeric pair
- dw exch
- dw recsq ; ' quoted expression
- dw qu
- dw reclp ; (
- dw noop
- dw recrp ; )
- dw noop
- dw recop ; * multiply
- dw mpy
- dw recop ; + add
- dw sum
- dw noop ; , separator like space
- dw noop
- dw recms ; - subtract
- dw dif
- dw recop ; .
- dw noop
- dw recop ; / divide [remainder, quotient]
- dw dvd
- dw recdd ; 0 number
- dw nu
- dw recdd ; 1 number
- dw nu
- dw recdd ; 2 number
- dw nu
- dw recdd ; 3 number
- dw nu
- dw recdd ; 4 number
- dw nu
- dw recdd ; 5 number
- dw nu
- dw recdd ; 6 number
- dw nu
- dw recdd ; 7 number
- dw nu
- dw recdd ; 8 number
- dw nu
- dw recdd ; 9 number
- dw nu
- dw recco ; :
- dw noop
- dw recsc ; ;
- dw noop
- dw recop ; < restrict workspace
- dw bra
- dw recpr ; = test equality of top pair
- dw eql
- dw recop ; > open workspace
- dw ket
- dw recpr ; ? test for error report
- dw qm
- dw recp1 ; @ execute subroutine
- dw ar
- dw recpr ; A advance pointer 1
- dw uca
- dw recpr ; B retract pointer 1
- dw ucb
- dw recop ; C compile
- dw ucc
- dw recop ; D delete text
- dw ucd
- dw recpr ; E equality between WS and PD
- dw uce
- dw recpr ; F find specified text
- dw ucf
- dw recop ; G fetch a block from memory
- dw ga
- dw recpr ; H ASCII hex to binary
- dw he
- dw recop ; I insert
- dw uci
- dw recop ; J jump to front
- dw ucj
- dw recop ; K call CP/M, keep DE, put value
- dw cpm
- dw recop ; L erase top of PDL
- dw ucl
- dw recpr ; M compare PDL and workspace
- dw ucm
- dw recpr ; N ;numerical comparison on PDL
- dw ucn
- dw recpr ; O decimal ASCII string to binary
- dw uco
- dw recop ; P put block into buffered memory
- dw ucp
- dw recop ; Q put workspace segment on PD
- dw ucq
- dw recop ; R read from keyboard
- dw ucr
- dw recop ; S store block in memory
- dw sa
- dw recop ; T write on screen
- dw uct
- dw recpr ; U search, yielding interval
- dw ucu
- dw recpr ; V U, including endpoints
- dw ucv
- dw recop ; W write on printer
- dw ucw
- dw recop ; X call library subroutine
- dw libr
- dw recpr ; Y recover previous position of p1
- dw ucy
- dw recop ; Z pointer 2 to end of text
- dw ucz
- dw reccm ; [ comment
- dw noop
- dw recop ; \ insert single byte in pair
- dw ip
- dw recop ; ]
- dw noop
- dw recop ; ^ increment top argument
- dw incr
- dw recop ; _ exit to monitor
- dw boot
- dw recpr ; ` true for waiting character
- dw chaw
- dw recpr ; a segment forward from p1
- dw lca
- dw recpr ; b segment backward from p2
- dw lcb
- dw recop ; c create block on PDL
- dw blok
- dw recpr ; d decrement but skip on zero
- dw decr
- dw recpr ; e extend workspace
- dw lce
- dw recpr ; f block fill
- dw lcf
- dw recop ; g non-incrementing byte fetch
- dw gb
- dw recop ; h
- dw noop
- dw recop ; i input from designated port
- dw lci
- dw recop ; j null interval at p1
- dw lcj
- dw recop ; k call CP/M: no returned values
- dw cpml
- dw recop ; l put pz on PDL
- dw lcl
- dw recop ; m set aside top argument
- dw lcm
- dw recop ; n recover set-aside argument
- dw lcn
- dw recop ; o output from designated port
- dw lco
- dw recop ; p put px, py-px on PDL
- dw gxs
- dw recop ; q put p1, p2-p1 on PDL
- dw lcq
- dw recop ; r indirect replacement of address
- dw ind
- dw recop ; s store block in memory wrt limit
- dw lcs
- dw recop ; t type out indicated interval
- dw lct
- dw recop ; u incrementing byte fetch
- dw gbi
- dw recop ; v incrementing byte store
- dw sai
- dw recop ; w store workspace header
- dw lcw
- dw recpr ; x subroutine call - no arguments
- dw go
- dw recop ; y fetch byte pair to PDL incr org
- dw gwi
- dw recop ; z null interval at p2
- dw lcz
- dw lbr ; { ;start a definition string
- dw noop
- dw recop ; | concatinate top two arguments
- dw conc
- dw noop ; } end of definition set
- dw noop
- dw recop ; ~ complement or negate top arg
- dw comp
- dw recop ; del
- dw noop
-
- ; -----------------------------------------------------
- ; RAM memory which is required for the operation of REC
- ; -----------------------------------------------------
-
- ; Relay area for input and output subroutines.
-
- const: db (jmp)
- cnst: dw 0000H
- conin: db (jmp)
- cnin: dw 0000H
- conou: db (jmp)
- cnou: dw 0000H
- read:: db (jmp) ;character input for REC compiler
- re:: dw chin
- tyin:: db (jmp) ;single character input for R
- ti:: dw chin
- tyou:: db (jmp) ;single character output for T
- to:: dw chou
-
- ; Temporary storage used by the REC compiler.
-
- xpd:: dw 0000 ;colon jump back to left parenthesis
- ypd:: dw 0000 ;false predicate jump chain
- zpd:: dw 0000 ;semicolon exit chain
-
- ; Pointers to the directories.
-
- fxt:: dw ft ;pointer to fixed operator directory
- vrt:: dw vt ;pointer to subroutine directory
-
- ; Pointers to the area of compiled subroutines.
-
- c0:: dw 0000H ;beginning of compiling area
- c1:: dw 0000H ;beginning of present compilation
- c2:: dw 0000H ;final location of present compilation
-
- ; Pointers to REC/MARKOV pushdown list.
-
- px:: dw 0000H ;beginning of pushdown text
- py:: dw 0000H ;end of pushdown text
- pz:: dw 0000H ;end of available pushdown space
-
- ; Workspace pointers.
-
- p0:: dw 0000H ;beginning of workspace
- p1:: dw 0000H ;beginning of marked segment
- p2:: dw 0000H ;end of marked segment
- p3:: dw 0000H ;end of text
- p4:: dw 0000H ;end of workspace
-
- ; I-O pointers.
-
- rx:: dw 0000
- ry:: dw 0000
-
- ; Linkage to input-output through ports.
-
- qin:: db (in)
- qi:: db 00H
- ret
-
- qou:: db (out)
- qo:: db 00H
- ret
-
- ; Temporary storage.
-
- pt:: dw 0000
-
- ; Error flag.
-
- er:: dw 0000
-
- vt: ds 100H ;directory for programs compiled by REC
-
- bmem: ds 0 ;end of REC, begin free memory.
-
- end main
-
-