home *** CD-ROM | disk | FTP | other *** search
- ;INTEL 8080 STOIC KERNEL
- ;J. SACHS 3/24/77
- ;
- ;***************************************************************************
- ;** COPYRIGHT (C) MASSACHUSETTS INSTITUTE OF TECHNOLOGY AND HARVARD **
- ;** UNIVERSITY, BIOMEDICAL ENGINEERING CENTER 1977. ALL RIGHTS RESERVED. **
- ;***************************************************************************
- ;
-
- ;ASSY TIME PARAMETERS
- BCKSP EQU 0 ;TTY = -1 FOR A TERMINAL WITH BACKSPACE
- ;TTY = 0 FOR A TERMINAL WITHOUT BACKSPACE
-
- TABS EQU 0 ;TABS = -1 FOR A TERMINAL WITH HARDWARE TABS
- ;TABS = 0 FOR A TERMINAL WITHOUT HARDWARE TABS
-
- DISK EQU -1 ;DISK = 0 FOR TAPE
- ;DISK = -1 FOR DISK
-
- DEBUG EQU -1 ;DEBUG = 0 FOR NO ERROR CHECKING
- ;DEBUG = -1 FOR ERROR CHECKING
-
- CPM EQU -1 ;CPM = -1 FOR A CPM COMPATABLE KERNEL
- ;CPM = 0 FOR ORGINAL KERNEL
- ;LOCATIONS OF I/O ROUTINES IN BOOT ROM
- ;
-
- IF (DISK) AND (NOT CPM)
-
- Q$TTYI EQU 01F4H ;TTY INPUT ROUTINE
- Q$TTYO EQU Q$TTYI+3 ;TTY OUTPUT ROUTINE
- DSKIN EQU Q$TTYO+3 ;DISK INPUT ROUTINE
- DSKOU EQU DSKIN+3 ;DISK OUTPUT ROUTINE
-
- BSIZE EQU 1000Q ;DISK BLOCK SIZE (BYTES)
- NBLKS EQU 1000Q ;NUMBER OF DISK BLOCKS
-
- ENDIF
-
- IF (NOT DISK) AND (NOT CPM)
-
- DSKIN EQU 201DH
- DSKOU EQU 2018H
-
- BSIZE EQU 2000Q
- NBLKS EQU 1000Q
-
- ENDIF
-
- ;PARAMETER DEFINITIONS
- ;
- IF NOT CPM
-
- SSIZE EQU 256 ;MAIN STACK SIZE
- RSIZE EQU 64 ;RETURN STACK SIZE
- LSIZE EQU 64 ;LOOP STACK SIZE
- VSIZE EQU 8 ;VOCABULARY STACK SIZE
- KSIZE EQU 82 ;KEYBOARD BUFFER SIZE
- CSIZE EQU 256 ;COMPILE BUFFER SIZE
-
- ;RESTART JUMPS
- ORG 2000H
- JMP ABORT ;RESTART 0
- JMP 0 ;RESTART 1
- JMP 0 ;RESTART 2
- JMP 0 ;RESTART 3
- JMP 0 ;RESTART 4
- JMP 0 ;RESTART 5
- JMP 0 ;RESTART 6
- JMP 0 ;RESTART 7
-
- ENDIF
- ;
- IF (NOT DISK) AND (NOT CPM)
-
- ORG 2400H
-
- ;DEFINE TTY ADDRESSES
- TTYISR EQU 0E001H ;TTY INPUT STATUS REGISTER
- TTYOSR EQU 0E002H ;TTY OUTPUT STATUS REGISTER
- TTYIDR EQU 0E003H ;TTY INPUT DATA REGISTER
- TTYODR EQU 0E004H ;TTY OUTPUT DATA REGISTER
-
- ;GET CHAR FROM TTY
- Q$TTYI: LDA TTYISR
- ORA A
- JP Q$TTYI
- LDA TTYIDR
- ANI 177Q
- RET
-
- ;TYPE A CHARACTER ON TTY
- Q$TTYO: PUSH PSW
- TTYO1: LDA TTYOSR
- ORA A
- JP TTYO1
- POP PSW
- STA TTYODR
- RET
-
- ENDIF
- ;
- ;/////////////////////////////////////////////////////////////////////
- ;
- ;DATE 2/21/78
- ;
- ;
- ;ROUTINE: CPMKER
- ;PURP: ALTERNATIONS TO STOIC KERNEL TO RUN UNDER CPM
- ;ENTRY: SET CPM ASSEMBLY TIME PARAMETER TO -1=TRUE
- ;EXIT: ADDITIONAL ROUTINES ARE INSERTED INTO THE KERNEL TO
- ; INTERFACE TO CPM
- ; 1) TTYIN
- ; 2) TTYOUT
- ; 3) DISKIN
- ; 4) DISKOUT IS NOT IMPLEMENTED AT THIS TIME
- ; 5) RD15 MODIFIED TO IGNORE LINE FEED CHARACTERS
- ; 6) CPMLD COMMAND IMPLEMENTED TO READ IN STOIC SOURCE
- ; FILES FROM A CPM DISK
- ; TO USE TYPE
- ; 'NAME CPMLD
- ; NOTE THE NAME IS ONLY THE FIRST NAME AND NOT THE EXTENSION
- ; WHICH IS ASSUMED TO BE "STC"
- ; 7) RETCPM COMMAND WHICH WILL REBOOT CPM
- ; 8) ALSO THE MEMORY WILL BE SET EACH TIME STOIC IS BROUGHT UP
- ; TO THE VALUE @ LOCATION 6 = ADDRESS OF THE BASE OF BDOS
- ; 9) SZSTOIC COMPUTES THE # OF 256 BYTE PAGES USED BY STOIC
- ; USED FOR SAVING STOIC
- ; 10)CHANGES TO THE ORGINAL KERNEL SO THE KERNEL WILL
- ; ASSEMBLE USING "ASM"
- ; A) ALL ? CHANGED TO Q$
- ; B) ALL MVI A,-1 CHANGED TO MVI A,0FFH
- ; C) ALL MVI M,-1 CHANGED TO MVI M,OFFH
- ;
- ;
- ;/////////////////////////////////////////////////////////////////
- ;
- ;
- IF CPM
- ;
- ;BLOCK DEFINITIONS
- ;
- BSIZE EQU 400H ;SIZE OF DISK BLOCK
- NBLKS EQU 77*26*128/BSIZE ;77 TRACKS
- ;26 SECTORS PER TRACK
- ;128 BYTES PER SECTOR
- ;NUMBER OF BLOCKS
- ;
- ;
- ;PARAMETER DEFINITIONS
-
- SSIZE EQU 256 ;MAIN STACK SIZE
- RSIZE EQU 64 ;RETURN STACK SIZE
- LSIZE EQU 64 ;LOOP STACK SIZE
- VSIZE EQU 8 ;VOCABULARY STACK SIZE
- KSIZE EQU 82 ;KEYBOARD BUFFER SIZE
- CSIZE EQU 256 ;COMPILE BUFFER SIZE
-
- ORG 100H
- ;
- ;ENTER STOIC
- TPA: LXI SP,SSTACK ;SET NEW STACK POINTER
- ;
- ; PICK UP SIZE OF AVAIL MEMORY
- LHLD BDOS+1 ;GET BEGINING OF BDOS
- SHLD Q$MEMO ;STORE IN MEMORY LOCATION
- JMP ABORT ;ENTER STOIC
- ;
- ;
- ; BDOS AND IO EQUATES
- ;
- BDOS EQU 5 ;ADDRESS OF JMP TO BDOS
- CONO EQU 9 ;DISPLACEMENT TO CONOUT ROUTINE
- CONI EQU 6 ;INDEX INTO CONSOLE CBIOS ROUTINE
- BASEIOS EQU 1 ;LOCATION 1 HAS BASE OF IOS
- SELDSK EQU 14 ;SELECT THE DISK
- OPENCPM EQU 15 ;OPEN A CPM FILE
- RDNXTREC EQU 20 ;READ NEXT SECTOR
- CPMFCB EQU 5CH ;DEFUALT FILE CONTROL BLOCK
- SETDMA EQU 26 ;SET DMA ADDRESS
- ;
- ;
- ;
- ;TTYIN
- Q$TTYI: LHLD BASEIOS ;GET ADDRESS OF IOS
- LXI D,CONI
- DAD D
- PCHL ;JMP TO ROUTINE
- ;
- ;
- ;TTY OUT
- Q$TTYO: ANI 7FH ;CLEAR MSB
- MOV C,A ;PLACE IN REG C
- LHLD BASEIOS ;GET BASE OF IOS TABLE
- LXI D,CONO
- DAD D ;HL=ADDRESS OF CONSOLE OUT ROUTINE
- PCHL ;JMP TO CONO
- ;
- ;
- ;DISK OUTPUT ROUTINE PRESENTLY CAUSES A ERROR
-
- DSKOU: MVI A,1
- RET
- ;
- ;DISK INPUT ROUTINE
- ;PURP: INPUT A BLOCK OF DATA [8 SECTORS ] FROM A CPM FILE
- ;ENTRY: HL=BLOCK# IN LOWER 9 BITS [DISCARDED]
- ; THE 10,AND 11 BITS [BIT 1,2 OF HL] = THE UNIT
- ;EXIT: A=0 IF GOOD READ ELSE A=1
- ;
- ;PROCEDURE
- ;
- ;
- ;SET THE DMA ADDRESS TO POINT TO THE BUFFER
- ; AND READ 8 SECTORS
- DSKIN: MVI B,BSIZE/128
- NXTSEC: PUSH B ;SAVE COUNT
- PUSH D ;SAVE DMA ADDRESS
- MVI C,SETDMA
- CALL BDOS ;SET THE DMA ADDRESS
- LXI D,CPMFCB
- MVI C,RDNXTREC ;READ THE NEXT RECORD
- CALL BDOS ;READ THE SECTOR
- POP D
- POP B ;RETRIEVE POINTERS
- ORA A ;SET FLAGS RETURNED FROM THE READ OPERATION
- JZ NXTSECCONT
- DCR A ;IF ERROR WAS END OF FILE IGNORE
- RET ;IF ERROR WAS A 2 RET WITH ERROR 1
- ;
- NXTSECCONT:
- LXI H,128 ;
- DAD D
- XCHG ;DE=NEXT DMA LOCATION
- DCR B
- JNZ NXTSEC
- RET
- ;
- ;
- ;/////////////////////////////////////////////////
- ;
- ;
- ;ROUTINE: RET TO CPM
- ;PRUP: RETURN TO CPM
- ;ENTRY: NONE
- ;EXIT: NONE
- ;PROCEDURE
- ;
- DB 6,'RETCP'
- DW 0
- DW $+2
- Q$RETCPM: LHLD BASEIOS
- PCHL ;DO A WARM BOOT
- ;
- ;
- ;//////////////////////////////////////////////////
- ;
- ;
- ;
- ;ADDITIONAL WORDS TO IMPLEMENT FILE READING
- ;
- ;
- ;//////////////////////////////////////////////////
- ;
- ;ROUTINE: 0FCB
- ;PURP: FILL A CPM FCB WITH ZERO'S
- ;ENTRY: TOS=FCB ADDRESS
- ;EXIT: TOS=DELETED
- ;PROCEDURE
- ;
- DB 4,'0FCB'
- DW Q$RETCPM
- DW $+2
- Q$0FCB: POP H ;FETCH FCB ADDRESS
- MVI B,33
-
- Q$0FCB1:
- MVI M,0
- INX H
- DCR B
- JNZ Q$0FCB1 ;JIF NOT DONE
- JMP Q$NEXT
- ;
- ;///////////////////////////////////////////////////////////
- ;
- ;
- ;
- ;OPFILE
- ;PURP: OPEN A CPM FILE
- ;ENTRY: TOS=FCB ADDRESS
- ;EXIT: TOS=0 IF OK
- ; TOS=-1 IF ERROR
- ;PROCEDURE
- DB 6,'OPFIL'
- DW Q$0FCB
- DW $+2
- Q$OPFILE: LDA Q$UNIT ;GET THE UNIT
- MOV E,A
- MVI C,SELDSK
- CALL BDOS
- POP D ;GET FCB ADDRESS
- MVI C,OPENCPM
- CALL BDOS ;OPEN FILE
- INR A
- JNZ Q$NEXT ;JIF NO ERRORS
- LXI H,OPENERR
- JMP ERROR
- ;
- ;OPEN ERROR MESSAGE
- OPENERR: DB 15,'OPEN FILE ERROR',0
- ;
- ;
- ;
- ;////////////////////////////////////////
- ;
- ;ROUTINE DFTFCB
- ;PURP: PUSH THE ADDRESS OF THE DEFUALT ON TO THE TOS
- ;ENTRY: NONE
- ;EXIT: TOS=DEFUALT FCB
- ;PROCEDURE
- ;
- DB 6,'DFTFC' ;DEFUALT FCB
- DW Q$OPFILE
- DW Q$CONS
- Q$DFTFCB: DW CPMFCB
- ;
- ;//////////////////////////////////////////////
- ;
- ;ROUTINE: STORE A FILE NAME IN THE FCB
- ;PURP:
- ;ENTRY: TOS=FCB,NAME
- ;EXIT: TOS=DELETED
- ;PROCEDURE
- ;
- DB 6,'STNAM' ;STORENAME
- DW Q$DFTFCB
- DW $+2
- Q$STNAME: POP D ;GET DESTINATION
- POP H ;GET SOURCE
- MOV A,M ;GET LENGTH OF SOURCE
- MOV B,A ;PLACE IN B
- CPI 9 ;TEST FOR PROPER LENGTH
- JC STN1 ;JIF OK
- LXI H,BADNAME ;ELSE ERROR EXIT
- JMP ERROR
- ;
- ;FIRST MOVE THE DEFUALT EXTENSION ".STC" AND CLEAR THE NAME
- ; THE MOVE IN THE NAME
- STN1: PUSH H
- PUSH D
- MVI C,2 ;C=COUNTER TO DETERMINE WHEN THE NAME IS MOVED
- LXI H,DFEXT ;HL=DEFUALT CLEARED NAME AND .EXT
- STN2: MOV B,M ;FETCH COUNT
- STN3: INX D ;NEXT FCB
- INX H ;NEXT SOURCE
- MOV A,M
- STAX D
- DCR B ;DEC COUNT
- JNZ STN3 ;JIF NOT DONE
- DCR C ;DEC C TO CHECK IF WE HAVE MOVED THE NAME
- JZ Q$NEXT ;JIF WE HAVE
- POP D
- POP H
- JMP STN2 ;ELSE MOVE THE NAME NOW
- ;SINCE THE EXTENION IS IN
- ;
- ;
- ;BADNAME MESSAGE
- BADNAME: DB 19,'FILENAME LENGTH > 8',0
- ;DEFUALT EXTENSION WITH BLANK FILE NAME
- DFEXT: DB 11,' STC',0
- ;
- ;
- ;/////////////////////////////////////////////////////
- ;
- ;ROUTINE: CPMLD
- ;PRUP: LOAD A CPM FILE
- ;ENTRY: TOS=NAME
- ;EXIT: TOS=DELETED
- ;PROCEDURE
- ;
- DB 5,'CPMLD'
- DW Q$STNAME
- DW Q$COLN
- Q$CPMLD: DW Q$DFTFCB
- DW Q$0FCB ;0 THE FILE CONTROL BLOCK
- DW Q$DFTFCB
- DW Q$STNAME ;STORE NAME IN DFTFCB
- DW Q$DFTFCB ;GET ADDRESS OF DEFUALT FCB
- DW Q$OPFILE ;OPEN THE FILE
- DW EBUF ;EMPTY THE BUFFERS
- DW LIT
- DW 1 ;DUMMY BLOCK 1
- DW LOAD ;LOAD THE FILE
- DW Q$SEMI ;RETURN
- ;
- ;
- ENDIF
- ;
- ;
- ;/////////////////////////////////////////////////////////////
- ;
- ;
- ;INTERPRETER
- ;
- DW $+2
- PUSH0: LXI H,0 ;0PUSH
- JMP Q$Q$PUSH
-
- DW $+2
- PUSH1: LXI H,-1 ;-1PUSH
- JMP Q$Q$PUSH
-
- Q$DPUSH: PUSH D ;DPUSH
- Q$Q$PUSH: PUSH H ;PUSH
- Q$NEXT:
- IF DEBUG
- LXI H,-(SSTACK+1)
- DAD SP
- JC STKE1
- LXI H,-SSTKE
- DAD SP
- JNC STKE2
- ENDIF
- LHLD Q$I ;NEXT
- INX H
- INX H
- SHLD Q$I
- MOV E,M
- INX H
- MOV D,M
- NEXT1: MOV H,D
- MOV L,E
- DCX H
- MOV A,M
- DCX H
- MOV L,M
- MOV H,A
- PCHL
-
- IF DEBUG
- STKE1: LXI H,SERM1
- JMP ERROR
- STKE2: LXI H,SERM2
- JMP ERROR
- SERM1: DB 11,'STACK EMPTY'
- SERM2: DB 10,'STACK FULL'
- ENDIF
- ;
- ;
- ;TTY INPUT ROUTINE (JUMPS TO ADDRESS IN Q$TYI)
- ;
- ; CALL TTYIN
- ; CHARACTER RETURNED IN A
-
- TTYIN: LHLD Q$TYI
- PCHL
-
- ;TTY OUTPUT ROUTINE (JUMPS TO ADDRESS IN Q$TYO)
- ;
- ; CHARACTER IN A
- ; CALL TTYOU
-
- TTYOU: LHLD Q$TYO
- PCHL
-
- DW $+2
- Q$SEMI: LHLD Q$R ;RETURN STACK PTR
- MOV E,M ;GET TOP OR STACK INTO DE
- INX H
- MOV D,M
- DCX H
- DCX H ;DECREMENT RETURN STACK PTR BY 2
- DCX H
- SHLD Q$R
- XCHG ;MOVE RESULT TO HL
- SHLD Q$I ;SET .I
- JMP Q$NEXT
-
- DW $+2
- Q$SCOD: LHLD Q$CURR ;(;CODE<)
- MOV E,M
- INX H
- MOV D,M
- DCX D
- DCX D
- LHLD Q$I
- INX H
- INX H
- XCHG
- MOV M,E
- INX H
- MOV M,D
- JMP Q$SEMI
-
- DB 2,'()',0,0,0 ;()
- ;LINK TO CPM WORDS IF CPM=-1
- IF CPM
- DW Q$CPMLD
- ENDIF
- ;
- ;ELSE THIS WILL BE THE END OF THE DICTIONARY
- IF NOT CPM
- DW 0
- ENDIF
- ;
- DW $+2
- LIT: LHLD Q$I ;INCREMENT .I BY 2
- INX H
- INX H
- SHLD Q$I
- ATPUS: MOV E,M ;@PUSH
- INX H
- MOV D,M
- PUSHD: PUSH D ;PUSHD
- JMP Q$NEXT
-
- DB 3,'S()',0,0 ;S()
- DW LIT
- DW $+2
- SLIT: LHLD Q$I
- INX H
- INX H
- MVI D,0
- MOV E,M
- PUSH H
- DAD D
- SHLD Q$I
- JMP Q$NEXT
-
- DB 5,'ABORT' ;ABORT
- DW SLIT
- DW $+2
- ABORT: LXI SP,SSTACK ;RESET STACK PTR
- LXI H,RSTACK ;RESET RETURN STACK PTR
- SHLD Q$R
- LXI H,LSTACK ;RESET LOOP STACK PTR
- SHLD Q$Q$L
- LXI H,-1 ;SET INBLK TO -1 (READ FROM KEYBOARD)
- SHLD Q$INBLK
- CALL Q$Q$AB ;CALL USER ABORT ROUTINE
- LXI H,GO-2 ;SET .I TO GO-2
- SHLD Q$I
- JMP Q$NEXT ;START IT UP
-
- Q$Q$AB: LHLD Q$ABORT ;JMP TO ABORT ROUTINE ADDRESS
- PCHL
-
- IF DEBUG
- ;TEST FOR DICTIONARY FULL
- DICTF: LHLD Q$MEMO ;END OF MEMORY
- LXI D,-100 ;-100 FOR SAFETY
- DAD D
- CALL Q$MHL
- XCHG
- LHLD Q$Q$D ;DICTIONARY POINTER
- DAD D
- RNC
- LXI H,DER2 ;DICTIONARY FULL
- JMP ERROR
-
- DER2: DB 15,'DICTIONARY FULL'
-
- ;TEST FOR COMPILE BUFFER FULL
- CBF: LHLD Q$C ;COMPILE BUFFER PTR
- LXI D,-KBUF ;START OF LINE BUFFER
- DAD D
- RNC
- LXI H,CER2 ;COMPILE BUFFER FULL
- JMP ERROR
-
- CER2: DB 19,'COMPILE BUFFER FULL'
-
- ENDIF
- ;
- ;
- ;
- Q$MHL: DCX H ;-HL
- Q$NHL: MOV A,H ;NOTHL
- CMA
- MOV H,A
- MOV A,L
- CMA
- MOV L,A
- Q$AB: RET ;DEFAULT ABORT ROUTINE
-
- ;MULTIPLY ROUTINE
- ;MULTIPLIES (HL) BY (DE)
- ;RESULT RETURNED IN (HLDE)
-
- Q$MUL: PUSH H ;MUL
- MOV A,L
- LXI H,0
- LXI B,8
- MULT1: DAD H
- RAL
- JNC MULT2
- DAD D
- ADC B
- MULT2: DCR C
- JNZ MULT1
- XTHL
- MOV L,A
- MOV A,H
- MOV H,B
- MVI C,8
- MULT3: DAD H
- RAL
- JNC MULT4
- DAD D
- ADC B
- MULT4: DCR C
- JNZ MULT3
- MOV D,A
- MOV E,H
- MOV H,L
- MOV L,B
- POP B
- DAD B
- JNC MULT5
- INX D
- MULT5: XCHG
- RET
- ;
- ;
- DB 6,'(ELSE' ;(ELSE)
- DW ABORT
- DW $+2
- Q$ELSE: LHLD Q$I
- INX H
- INX H
- MOV E,M
- INX H
- MOV D,M
- DCX H
- DAD D
- SHLD Q$I
- JMP Q$NEXT
-
- DB 4,'(IF)',0 ;(IF)
- DW Q$ELSE
- DW $+2
- Q$IF: POP H
- MOV A,H
- ORA L
- JZ Q$ELSE
- LHLD Q$I
- INX H
- INX H
- SHLD Q$I
- JMP Q$NEXT
-
- DB 1,'.',0,0,0,0 ;.
- DW Q$IF
- DW $+2
- PERIO: LHLD Q$Q$D
- JMP Q$Q$PUSH
-
- DB 5,'STATE' ;STATE
- DW PERIO
- DW Q$CONS
- STATE: DW Q$STATE
- ;
- ;
- ;OUTPUT A CHARACTER TO TTY
- ;
- ; A ASCII CHARACTER CODE
- ; CALL Q$TTO
- ;
- ;OUTPUT A CR TO TTY
- ;
- ; CALL Q$CR
- ;
- ;OUTPUT A CR IF COLUMN NON-ZERO
- ;
- ; CALL Q$IFCR
-
- Q$IFCR: LDA Q$COLU
- ORA A
- RZ
- Q$CR: MVI A,15Q
- Q$TTO: LXI H,Q$COLU ;INCREMENT COLUMN
- INR M
-
- IF NOT TABS
- CPI 11Q ;TAB Q$
- JZ TTO2
- ENDIF
-
- TTO1: PUSH PSW ;SAVE CHARACTER
- CALL TTYOU ;OUTPUT IT
- POP PSW ;RESTORE CHARACTER
- CPI 15Q ;RETURN Q$
- RNZ ;NO, DONE
- SUB A ;RESET COLUMN TO 0
- STA Q$COLU
- MVI A,12Q ;OUTPUT A LINE FEED
- JMP TTO1
-
- IF NOT TABS
- TTO2: MVI A,40Q ;OUTPUT A SPACE
- CALL TTYOU
- LDA Q$COLU ;GET COLUMN #
- ANI 7 ;0 MOD 8 Q$
- RZ ;YES, DONE
- MVI A,11Q ;NO, INCREMENT COLUMN AND DO ANOTHER SPACE
- JMP Q$TTO
- ENDIF
-
- ;TYPE A MESSAGE ON TTY
- ;
- ; H PTR TO STRING
- ; CALL Q$MSG
-
- Q$MSG: MOV A,M ;GET BYTE COUNT IN A REGISTER
- MSG1: ORA A ;LENGTH = 0 Q$
- RZ ;YES, RETURN
- DCR A ;DECREMENT COUNT
- PUSH PSW ;SAVE IT
- INX H ;INCREMENT PTR
- PUSH H ;SAVE IT
- MOV A,M ;GET NEXT BYTE
- CALL Q$TTO ;TYPE IT
- POP H ;RESTORE PTR AND COUNT
- POP PSW
- JMP MSG1 ;CONTINUE
- ;
- ;
- ;DICTIONARY LOOKUP
- DB 6,'LOOKU' ;LOOKUP
- DW STATE
- DW $+2
- LOOKU: POP H ;PTR TO STRING
- SHLD Q$T1
- LHLD Q$V ;VOCABULARY STACK PTR
- LOOK0: SHLD Q$T3
- LXI D,-(VSTACK)
- DAD D
- MOV A,H
- ORA L
- JZ Q$Q$PUSH ;YES, LOSE
- LHLD Q$T3
- MOV E,M
- INX H
- MOV D,M
- XCHG
- MOV E,M
- INX H
- MOV D,M
- XCHG
- MOV A,H
- ORA L
- JZ LOOK4 ;EMPTY BRANCH
- LOOK1: LXI D,-10 ;BACK UP TO FIRST BYTE OF NAME
- DAD D
- SHLD Q$T2
- XCHG
-
- LHLD Q$T1 ;CHECK LENGTH BYTE
- LDAX D
- ANI 177Q ;AND OFF PRECEDENCE
- CMP M
- JNZ LOOK3 ;LENGTH BYTE DIFFERENT
-
- MVI C,5 ;CHECK NEXT 5 CHARACTERS
- LOOK5: INX D ;INCREMENT POINTERS
- INX H
- LDAX D ;COMPARE BYTES
- CMP M
- JNZ LOOK3 ;NO MATCH
- ORA A
- JZ LOOK2 ;BYTES EQUAL AND ZERO
- DCR C
- JNZ LOOK5
-
- LOOK2: LHLD Q$T2 ;MATCH
- LXI D,10
- DAD D
- PUSH H ;PUSH PTR TO ENTRY
- JMP PUSH1 ;PUSH -1
-
- LOOK3: LHLD Q$T2 ;LINK TO NEXT ENTRY
- LXI D,6
- DAD D
- MOV E,M
- INX H
- MOV D,M
- XCHG
- MOV A,H
- ORA L
- JNZ LOOK1
- LOOK4: LHLD Q$T3 ;LINK IS ZERO
- DCX H ;GO TO NEXT BRANCH
- DCX H
- JMP LOOK0
- ;
- ;
- DB 2,'B,',0,0,0 ;B,
- DW LOOKU
- DW $+2
- BCOMA: POP H
- MOV A,L
- CALL Q$BCOM
- JMP Q$NEXT
-
- DB 1,',',0,0,0,0 ;,
- DW BCOMA
- DW $+2
- COMMA: POP H
- CALL Q$COMM
- JMP Q$NEXT
-
- DB 2,'C,',0,0,0 ;C,
- DW COMMA
- DW $+2
- CCOMM: POP H
- CALL Q$CCOM
- JMP Q$NEXT
-
- Q$COMM: PUSH H
- MOV A,L
- CALL Q$BCOM
- POP H
- MOV A,H
- CALL Q$BCOM
- RET
-
- Q$BCOM: LHLD Q$Q$D
- MOV M,A
- INX H
- SHLD Q$Q$D
- IF DEBUG
- CALL DICTF
- ENDIF
- RET
-
- Q$CCOM: PUSH H
- MOV A,L
- CALL Q$CBCO
- POP H
- MOV A,H
- CALL Q$CBCO
- RET
-
- Q$CBCO: LHLD Q$C
- MOV M,A
- INX H
- SHLD Q$C
- IF DEBUG
- CALL CBF
- ENDIF
- RET
- ;
- ;
- DB 6,'RDLIN' ;RDLINE
- DW CCOMM
- DW $+2
- RDLIN: LXI H,KBUF+1 ;KEYBOARD BUFFER ADDRESS + 1
- SHLD Q$T2 ;CURRENT OUTPUT PTR
- SHLD Q$INP ;SET INP
-
- SUB A ;ZERO EOL,BUFFER MODIFIED FLAG
- STA Q$EOL
- STA Q$T1
- CMA ;SET EOC TO -1
- STA Q$EOC
-
- LHLD Q$INBLK ;READING FROM FILE Q$
- INX H
- MOV A,H
- ORA L
- JNZ RDL9 ;YES
-
- ;READING FROM TTY
- RDL1: CALL TTYIN ;GET NEXT CHAR
- CPI 12Q ;LINE FEED
- JZ RDL8
- CPI 177Q
- JZ RDL2 ;RUBOUT
- ORA A
- JZ RDL3 ;NULL
- CPI 15Q ;CR
- JZ RDL10
- CPI 14Q ;FF
- JZ RDL10
- RDL4: PUSH PSW ;ECHO CHARACTER
- CALL Q$TTO
- MVI A,0FFH ;SET BUFFER MODIFIED FLAG TO -1
- STA Q$T1
- POP PSW
- CALL OCH ;STORE CHAR IN BUFFER
- LXI D,-(KBUF+KSIZE)
- DAD D
- JNC RDL1
- RDL5: LXI H,RDL6 ;BUFFER FULL
- JMP ERROR
- RDL6: DB 13,'LINE TOO LONG'
-
- ;PROCESS RUBOUT
- RDL2: LHLD Q$T2 ;OUTPUT PTR
- LXI D,-(KBUF+1) ;START OF BUFFER
- DAD D
- MOV A,H
- ORA L
- JZ RDL1 ;BUFFER EMPTY, IGNORE RUBOUT
- LHLD Q$T2 ;BACK UP OUTPUT PTR
- DCX H
- SHLD Q$T2
-
- IF BCKSP
- MVI A,10Q ;ECHO BACKSPACE, SPACE, BACKSPACE
- CALL Q$TTO
- MVI A,40Q
- CALL Q$TTO
- MVI A,10Q
- CALL Q$TTO
- ENDIF
-
- IF NOT BCKSP
- MVI A,137Q ;ECHO _
- CALL Q$TTO
- ENDIF
-
- JMP RDL1
-
- ;PROCESS NULL
- RDL3: LXI H,KBUF+1 ;RESET OUTPUT PTR
- SHLD Q$T2
- ;PROCESS CR OR FF
- RDL10: CALL Q$CR ;ECHO A CR
- RDL11: SUB A ;OUTPUT A NULL TO LINE BUFFER
- LHLD Q$T2
- MOV M,A
- LXI D,-(KBUF+1) ;COMPUTE BYTE COUNT
- DAD D
- MOV A,L
- STA KBUF ;STORE IN 1ST BYTE OF LINE BUFFER
- JMP Q$NEXT
-
- ;PROCESS LINE FEED
- RDL8: LDA Q$T1 ;BUFFER MODIFIED Q$
- ORA A
- JNZ RDL1 ;YES, IGNORE LINE FEED
- CALL Q$CR ;ECHO A CR
- JMP Q$NEXT ;AND RE-EXECUTE LINE
-
- RDL9: LHLD Q$INBLK ;GET INBLK
- XCHG
- CALL RBLK ;GET ADDR OF BUFFER CONTAINING BLOCK
- PUSH D ;SAVE IT
- LHLD Q$INBYT ;GET INBYTE
- PUSH H ;SAVE IT
- INX H ;INCREMENT IT
- SHLD Q$INBYT
- LXI D,-BSIZE
- DAD D
- MOV A,H
- ORA L
- JNZ RDL15
- LHLD Q$INBLK ;INCREMENT INBLK
- INX H
- SHLD Q$INBLK
- LXI H,0 ;RESET INBYTE
- SHLD Q$INBYT
- RDL15: POP D
- POP H
- DAD D
- MOV A,M ;GET CHAR FROM FILE
- ;
- ;**********************************
- ;
- ; THIS CHECK FOR LF IS ADDED BY WINK SAVILLE SO
- ; FILES MADE UNDER CPM WHICH WILL HAVE LF IN THEM WILL WORK
- ;
- ;
- IF CPM
- ;
- CPI 0AH ;CHECK FOR A LINE FEED
- JZ RDL9 ;JIF LF
- ;IGNORE LINE FEED
- ENDIF
- ;
- ;
- ;***********************************
- ;
- CPI 15Q ;CR
- JZ RDL11
- CPI 14Q ;FF
- JZ RDL11
- CPI 4 ;EOF Q$
- JZ RDL12 ;YES, ERROR
- CALL OCH ;STORE CHAR IN BUFFER
- LXI D,-(KBUF+KSIZE)
- DAD D
- JNC RDL9
- JMP RDL5 ;LINE TOO LONG
-
- RDL12: LXI H,RDL13 ;END OF FILE
- JMP ERROR
- RDL13: DB 3,'EOF'
-
- ;OUTPUT A CHARACTER TO LINE BUFFER
- OCH: LHLD Q$T2
- MOV M,A
- INX H
- SHLD Q$T2
- RET
-
- ;
- ;
- DW $+2
- UNDEF: POP H ;WAS IF A LITERAL Q$
- MOV A,H
- ORA L
- JNZ Q$NEXT ;YES, OK
- LXI H,UND1
- ERROR: LXI SP,SSTACK ;RESET PARAMETER STACK POINTER
- PUSH H ;PUSH PTR TO STRING
- LXI H,RSTACK ;RESET RETURN STACK POINTER
- SHLD Q$R
- LXI H,LSTACK ;RESET LOOP STACK POINTER
- SHLD Q$Q$L
- JMP ERR ;EXECUTE ERROR HANDLER
-
- UND1: DB 9,'UNDEFINED'
-
- DB 3,'ERR',0,0 ;ERR
- DW RDLIN
- DW $+2
- ERR: LHLD Q$ERRM ;ERRMSG @ EXEC
- EXEC: XCHG
- JMP NEXT1
-
- DB 7,'ERRMS' ;ERRMSG0
- DW ERR
- DW $+2
- ERRM0: CALL Q$IFCR ;TYPE A CR IF COLUMN NON-ZERO
- POP H ;TYPE THE MESSAGE
- CALL Q$MSG
- CALL Q$CR ;TYPE A CR
- LHLD Q$Q$D ;TYPE THE LAST TOKEN
- CALL Q$MSG
- CALL Q$IFCR ;TYPE A CR IF COLUMN NON-ZERO
- LHLD Q$INBLK ;INBLK = -1 Q$
- INX H
- MOV A,H
- ORA L
- JZ ABORT ;YES, EXECUTING FROM KEYBD
- LXI H,KBUF ;NO, TYPE LINE BUFFER
- CALL Q$MSG
- CALL Q$CR ;TYPE A CR
- JMP ABORT ;ABORT
- ;
- ;
- DB 4,'UNIT',0 ;UNIT
- DW ERRM0
- DW Q$CONS
- UNIT: DW Q$UNIT
-
- IF DISK
- SETUP:
- ; MOV A,L ;TEST FOR ILLEGAL BLOCK #
- ; SUI NBLKS AND 0FFH
- ; MOV A,H
- ; SBI NBLKS/100H
- ; JNC IBN ;ILLEGAL BLOCK #
- LXI B,1 ;SET BLOCK COUNT TO 1
- RET
-
- ;IBN: LXI H,IBNM
- ; JMP ERROR
-
- WRERC: CALL SETUP
- Q$WRERC: CALL DSKOU
- RZ ;NO ERRORS
- CPI 4 ;WRITE PROTECTED Q$
- JNZ RDER1 ;NO, CHECK FOR OTHER ERRORS
- LXI H,WRER1 ;WRITE PROTECTED
- JMP ERROR
-
- RDERC: CALL SETUP
- Q$RDERC: CALL DSKIN
- RZ ;NO ERRORS
- RDER1: LXI H,RDER2 ;CRC ERROR
- JMP ERROR
-
- WRER1: DB 20,'DISK WRITE PROTECTED'
- RDER2: DB 10,'DISK ERROR'
- IBNM: DB 15,'ILLEGAL BLOCK #'
- ENDIF
-
- IF NOT DISK
- WRERC: LXI B,1 ;WRITE 1 BLOCK
- Q$WRERC: CALL DSKOU ;WRITE WITH ERROR CHECKING
- RZ
- JMP RDER1
-
- RDERC: LXI B,1 ;READ 1 BLOCK
- Q$RDERC: CALL DSKIN ;READ WITH ERROR CHECKING
- RZ ;IF 0, NO ERROR
- RDER1: DCR A
- MOV E,A
- MVI D,0
- LXI H,TERRT
- DAD D
- DAD D
- MOV E,M
- INX H
- MOV D,M
- XCHG
- JMP ERROR
-
- TERRT: DW TERR1
- DW TERR2
- DW TERR3
- DW TERR4
- DW TERR5
- DW TERR6
- DW TERR7
- DW TERR8
- DW TERR9
- DW TERRA
- DW TERRB
-
- TERR1: DB 14,'TAPE NOT READY'
- TERR2: DB 20,'TAPE WRITE PROTECTED'
- TERR3: DB 22,'READ AFTER WRITE ERROR'
- TERR4: DB 13,'READ OVERFLOW'
- TERR5: DB 15,'POSTAMBLE ERROR'
- TERR6: DB 11,'SHORT BLOCK'
- TERR7: DB 10,'LONG BLOCK'
- TERR8: DB 3,'EOT'
- TERR9: DB 3,'BOT'
- TERRA: DB 14,'CHECKSUM ERROR'
- TERRB: DB 12,'NO SUCH TAPE'
- ENDIF
- ;
- ;
- DB 6,'NEWES' ;NEWEST
- DW UNIT
- DW Q$CONS
- NEWQ$: DW NEWEST
-
- ; (D,E) BLOCK #
- ; CALL RBLK (WBLK)
- ; (D,E) BUFFER ADDRESS
-
- WBLK: MVI A,0FFH ;WBLK
- JMP BLK
- RBLK: SUB A ;RBLK
- BLK: STA FLAG
- LHLD NEWEST ;IS BLOCK THE MOST RECENTLY ACCESSED BLOCK Q$
- MOV A,E
- CMP M
- JNZ BLK1 ;NO
- INX H
- MOV A,D
- CMP M
- JNZ BLK1 ;NO
- INX H ;YES, RETURN BUFFER ADDR
- MOV E,M
- INX H
- MOV D,M
- RET
-
- BLK1: LHLD NEWEST ;SEARCH BUFFER LIST
- SHLD BUFP
- XCHG
- SHLD BLKN
-
- BLK2: LHLD BUFP ;GET LINK TO NEXT BCT
- LXI D,4
- CALL LDX
- MOV A,D
- ORA E
- JZ BLK3 ;END OF LIST, MUST READ IN BLOCK
- LHLD BUFP
- SHLD PREV
- XCHG
- SHLD BUFP
- MOV E,M ;GET BLOCK #
- INX H
- MOV D,M
- LHLD BLKN ;COMPARE WITH REQUESTED BLOCK #
- MOV A,H
- CMP D
- JNZ BLK2 ;NO
- MOV A,L
- CMP E
- JNZ BLK2 ;NO
- BLK6: LHLD BUFP ;RELINK BCT'S
- LXI D,4
- CALL LDX
- PUSH D ;SAVE LINK OF CURRENT BCT
- LHLD NEWEST ;RESET LINK OF CURRENT BCT TO NEWEST
- XCHG
- LHLD BUFP
- LXI B,4
- CALL STX
- LHLD BUFP ;SET NEWEST TO CURRENT BCT
- SHLD NEWEST
- LHLD PREV ;STORE SAVED LINK IN LINK OF PREVIOUS BCT
- POP D
- LXI B,4
- CALL STX
- LHLD BUFP ;RETURN BUFFER ADDRESS
- LXI D,2
- CALL LDX
- RET
-
- BLK3: CALL FBUF ;FREE A BUFFER
- LDA FLAG ;RBLOCK Q$
- ORA A
- JNZ BLK7 ;NO
- LHLD BUFP ;READ IN BLOCK
- LXI D,2
- CALL LDX
- LHLD BLKN
- CALL RDERC
- BLK7: LHLD BLKN ;STORE BLOCK # IN BCT
- XCHG
- LHLD BUFP
- MOV M,E
- INX H
- MOV M,D
- JMP BLK6 ;RELINK BCT'S
-
- FBUF: LHLD BUFP ;REEE A BUFFER
- LXI D,6 ;GET MODIFIED FLAG
- CALL LDX
- MOV A,D
- ORA E
- RZ ;NOT MODIFIED, RETURN
- LHLD BUFP ;GET BLOCK #
- MOV E,M
- INX H
- MOV D,M
- PUSH D
- LHLD BUFP ;GET BUFFER ADDR
- LXI D,2
- CALL LDX
- POP H
- CALL WRERC ;WRITE IT BACK OUT
- LHLD BUFP ;CLEAR THE MODIFIED FLAG
- LXI D,0
- LXI B,6
- CALL STX
- RET ;RETURN
-
- DB 6,'RBLOC' ;RBLOCK
- DW NEWQ$
- DW $+2
- RBLOC: POP D ;GET BLOCK #
- LDA Q$UNIT ;ADD IN UNIT NUMBER
- ORA A
- RAL
- ORA D
- MOV D,A
- CALL RBLK
- JMP PUSHD
-
- DB 6,'WBLOC' ;WBLOCK
- DW RBLOC
- DW $+2
- WBLOC: POP D
- LDA Q$UNIT ;ADD IN UNIT NUMBER
- ORA A
- RAL
- ORA D
- MOV D,A
- CALL WBLK
- PUSH D
- JMP UPDAT
-
- DB 6,'UPDAT' ;UPDATE
- DW WBLOC
- DW $+2
- UPDAT: LHLD NEWEST ;SET MODIFIED FLAG ON CURRENT BCT
- LXI D,-1
- LXI B,6
- CALL STX
- JMP Q$NEXT
-
- DB 5,'FLUSH' ;FLUSH
- DW UPDAT
- DW $+2
- FLUSH: LHLD NEWEST ;FREE ALL BUFFERS
- FLSH1: SHLD BUFP
- CALL FBUF ;FREE A BUFFER
- LHLD BUFP ;LINK TO NEXT BCT
- LXI D,4
- CALL LDX
- MOV A,D
- ORA E
- JZ Q$NEXT ;DONE
- XCHG ;DO ANOTHER ONE
- JMP FLSH1
-
- DB 4,'EBUF',0 ;EBUF
- DW FLUSH
- DW $+2
- EBUF: LHLD NEWEST ;SET ALL BLOCK NUMBERS TO -1
- EBUF1: SHLD BUFP
- MVI M,0FFH
- INX H
- MVI M,0FFH
- DCX H
- LXI D,0
- LXI B,6
- CALL STX
- LHLD BUFP ;LINK TO NEXT BCT
- LXI D,4
- CALL LDX
- MOV A,D
- ORA E
- JZ Q$NEXT ;DONE
- XCHG ;DO ANOTHER ONE
- JMP EBUF1
-
- ;INDEXED LOAD
- ; (DE) OFFSET
- ; (HL) BASE ADDRESS
- ; CALL LDX
- ; (DE) DATA
-
- LDX: DAD D
- MOV E,M
- INX H
- MOV D,M
- RET
-
- ;INDEXED STORE
- ; (BC) OFFSET
- ; (DE) DATA
- ; (HL) BASE ADDRESS
- ; CALL STX
-
- STX: DAD B
- MOV M,E
- INX H
- MOV M,D
- RET
- ;
- ;
- ;GET NEXT WORD FROM INPUT STREAM
- ;
- ;ON ENTRY,
- ;Q$INP CONTAINS INPUT POINTER
- ;
- ;ON EXIT,
- ;Q$INP IS UPDATED
- ;TOKEN IS AT END OF DICTIONARY (NULL TERMINATED)
- ;END-OF-LINE FLAG IS ON STACK
- ;
- ;DELIMITER IS SPACE OR TAB UNLESS FIRST CHARACTER IS " OR \
- ;IN WHICH CASE SCANNING CONTINUES UNTIL NEXT " OR \
- ;
- ;IF END-OF-LINE FLAG IS SET ON ENTRY, WORD RETURNS IMMEDIATELY
- ;SCANNING STOPS UNCONDITIONALLY ON A NULL IN THE INPUT STREAM
- ;AND THE END-OF-LINE FLAG IS SET IF THE NULL OCCURED INBETWEEN WORDS;
- ;OTHERWISE IT IS SET ON THE NEXT CALL TO WORD.
-
- DB 4,'WORD',0 ;WORD
- DW EBUF
- DW $+2
- WORD: LDA Q$EOL ;ALREADY AT END OF LINE Q$
- ORA A
- JNZ PUSH1 ;YES, RETURN -1
- LXI B,0920H ;SET TAB,SPACE AS DELIMITERS (IN (B,C))
- LHLD Q$Q$D ;(D,E) IS OUTPUT PTR
- INX H ;SKIP LENGTH BYTE
- XCHG
- LHLD Q$INP ;(H,L) IS INPUT PTR
- WORD3: MOV A,M ;GET NEXT INPUT CHAR
- INX H
- ORA A
- JZ WORD6 ;NULL, END OF LINE
- CMP B ;DELIMITER Q$
- JZ WORD3 ;YES, IGNORE
- CMP C
- JZ WORD3 ;YES, IGNORE
- CPI 42Q ;" Q$
- JZ WORD9
- CPI 134Q ;\ Q$
- JNZ WORD4
- WORD9: MOV B,A ;RESET DELIMITERS
- MOV C,A
- WORD4: STAX D ;OUTPUT CHARACTER
- INX D
- MOV A,M ;GET NEXT INPUT CHARACTER
- INX H
- ORA A ;NULL Q$
- JZ WORD7 ;YES, END OF LINE
- CMP B ;DELIMITER Q$
- JZ WORD8 ;YES, STOP
- CMP C ;DELIMITER Q$
- JNZ WORD4 ;NO, GET MORE CHARACTERS
- WORD8: SHLD Q$INP ;UPDATE INPUT PTR
- SUB A ;OUTPUT A NULL AT END OF STRING
- STAX D
- LHLD Q$Q$D ;COMPUTE LENGTH OF WORD
- CALL Q$MHL
- DAD D
- MOV A,L
- DCR A
- LHLD Q$Q$D ;STORE IN LENGTH BYTE
- MOV M,A
- LDA Q$EOL ;PUSH END OF LINE FLAG
- MOV L,A
- MOV H,A
- JMP Q$Q$PUSH
-
- WORD6: MVI A,0FFH ;SET EOL TO -1
- STA Q$EOL
- WORD7: DCX H ;DECREMENT INPUT PTR
- JMP WORD8
- ;
- ;
- ;LITERAL PROCESSOR
-
- DB 7,'LITER' ;LITERAL
- DW WORD
- DW Q$COLN
- LITER: DW PERIO
- DW ILITE
- DW Q$IF
- DW LIT1-2-$
- DW LIT
- DW LIT
- DW CCOMM
- DW CCOMM
- DW PUSH1
- DW Q$SEMI
-
- LIT1: DW PERIO
- DW SLITE
- DW Q$SEMI
-
- DB 8,'ILITE' ;ILITERAL
- DW LITER
- DW $+2
- ILITE: POP H ;POP INPUT POINTER
- INX H
- SHLD Q$T3 ;SET INPUT PTR
- LXI H,0 ;ZERO SIGN,VALUE
- SHLD Q$T4
- SHLD Q$T5
-
- CALL LITG ;GET NEXT CHAR
- CPI 53Q ;"+" Q$
- JZ ILIT1 ;IGNORE
- CPI 55Q ;"-" Q$
- JNZ ILIT2 ;NO
- LXI H,-1 ;SET SIGN FLAG
- SHLD Q$T4
- ILIT1: CALL LITG ;GET NEXT CHAR
- ILIT2: ORA A ;END OF LITERAL Q$
- JZ ILIT4 ;YES, DONE
- CPI 60Q ;TEST FOR LEGAL DIGIT
- JC PUSH0 ;ILLEGAL
- CPI 72Q
- JC ILIT3
- CPI 101Q
- JC PUSH0 ;ILLEGAL
- SUI 7
- ILIT3: SUI 60Q
- LHLD Q$RADIX
- CMP L
- JNC PUSH0 ;ILLEGAL
- STA Q$T1
- LHLD Q$RADIX ;MULTIPLY VALUE BY RADIX AND ADD DIGIT
- XCHG
- LHLD Q$T5
- CALL Q$MUL
- MOV A,H
- ORA L
- JNZ PUSH0 ;OVERFLOW
- LDA Q$T1
- MOV L,A
- MVI H,0
- DAD D
- SHLD Q$T5 ;SET NEW VALUE
- JMP ILIT1
-
- ILIT4: LHLD Q$T4 ;GET SIGN
- MOV A,H
- ORA L
- LHLD Q$T5 ;GET VALUE
- CM Q$MHL ;NEGATE IF SIGN NON-ZERO
- PUSH H ;PUSH RESULT
- JMP PUSH1 ;PUSH -1
-
- DB 8,'SLITE' ;SLITERAL
- DW ILITE
- DW $+2
- SLITE: POP H ;POP INPUT POINTER
- INX H
- SHLD Q$T3 ;SET INPUT PTR
- CALL LITG ;GET 1ST CHAR
- CPI 47Q ;'
- JZ SLIT1 ;STRING LITERAL
- CPI 42Q ;"
- JZ SLIT1 ;STRING LITERAL
- CPI 134Q ;\
- JNZ PUSH0 ;ILLEGAL STRING LITERAL
- SLIT1: LXI H,SLIT ;OUTPUT S()
- CALL Q$CCOM
- LHLD Q$C ;SAVE PTR TO START OF LITERAL
- SHLD Q$T1
- SUB A ;ZERO LENGTH BYTE
- CALL Q$CBCO
- SLIT2: CALL LITG ;GET NEXT CHAR
- ORA A
- JZ SLIT7 ;END OF STRING LITERAL
- CPI 46Q ;&
- JZ SLIT4 ;START OF OCTAL INSERT
- SLIT3: CALL Q$CBCO ;OUTPUT CHARACTER
- LHLD Q$T1 ;INCREMENT LENGTH
- INR M
- JMP SLIT2
-
- SLIT4: SUB A ;INITIALIZE VALUE TO 0
- SLIT5: STA Q$T2
- CALL LITG ;GET NEXT CHAR
- CPI 46Q ;&
- JZ SLIT6 ;END OF OCTAL NUMBER
- CPI 60Q ;0
- JM PUSH0 ;ILLEGAL DIGIT
- CPI 70Q ;8
- JP PUSH0 ;ILLEGAL DIGIT
- SUI 60Q ;CONVERT TO VALUE
- MOV B,A
- LDA Q$T2 ;MULTIPLY VALUE BY 8 AND ADD DIGIT
- RLC
- RLC
- RLC
- ADD B
- JMP SLIT5
-
- SLIT6: LDA Q$T2 ;RETURN OCTAL VALUE
- JMP SLIT3
-
- SLIT7: CALL Q$CBCO ;OUTPUT FINAL NULL
- JMP PUSH1 ;EXIT
-
- LITG: LHLD Q$T3 ;GET NEXT INPUT CHAR
- MOV A,M
- INX H
- SHLD Q$T3
- RET
-
- ;
- IF DEBUG
- DB 6,'ERRCH' ;ERRCHK
- DW SLITE
- DW $+2
- ERRCH: CALL DICTF
- CALL CBF
-
- LHLD Q$V ;VOCABULARY STACK PTR
- XCHG
- LXI H,-VSTACK-2 ;START OF VOCABULARY STACK + 2
- DAD D
- JNC ERRC1
- LXI H,-LSTACK
- DAD D
- JC ERRC2
-
- LHLD Q$Q$L ;LOOP STACK PTR
- XCHG
- LXI H,-LSTACK ;START OF LOOP STACK
- DAD D
- JNC ERRC3
- LXI H,-RSTACK ;START OF RETURN STACK
- DAD D
- JC ERRC4
- JMP Q$NEXT
-
- ERRC1: LXI H,VSTACK+2 ;RESET VOCABULARY STACK PTR
- SHLD Q$V
- LXI H,VER1 ;VOCABULARY STACK EMPTY
- JMP ERROR
- ERRC2: LXI H,VER2 ;VOCABULARY STACK FULL
- JMP ERROR
- ERRC3: LXI H,LER1 ;LOOP STACK EMPTY
- JMP ERROR
- ERRC4: LXI H,LER2 ;LOOP STACK FULL
- JMP ERROR
-
- VER1: DB 22,'VOCABULARY STACK EMPTY'
- VER2: DB 21,'VOCABULARY STACK FULL'
- LER1: DB 16,'LOOP STACK EMPTY'
- LER2: DB 15,'LOOP STACK FULL'
- ENDIF
-
- DW Q$COLN
- COMPI: DW WORD ;GET NEXT WORD FROM INPUT STREAM
- DW Q$IF
- DW COMP1-2-$
- DW Q$SEMI ;END OF LINE, RETURN
-
- COMP1: DW PERIO ;DO A DICTIONARY LOOKUP
- DW LOOKU
- DW Q$IF
- DW COMP2-2-$
- DW Q$COMP ;FOUND, COMPILE OR EXECUTE IT
- DW Q$ELSE
- DW COMPI-2-$
-
- COMP2: DW EXLIT ;NOT FOUND, MAYBE A LITERAL
- DW UNDEF
- DW Q$ELSE
- DW COMPI-2-$
-
- DW $+2
- EXLIT: LHLD Q$LIT
- JMP EXEC
-
- DW $+2
- Q$COMP: POP D ;PTR TO PARAMETER FIELD OF WORD
- LXI H,-10 ;BACK UP TO PRECEDENCE FIELD
- DAD D
- MOV A,M ;GET 1ST BYTE OF ENTRY
- ORA A
- JM NEXT1 ;PRECEDENCE BIT SET, EXECUTE IT
- LDA Q$STATE ;PRECEDENCE BIT ZERO, CHECK STATE
- ORA A
- JP NEXT1 ;STATE ZERO, EXECUTE IT
- XCHG ;STORE ADDR OF PARAMETER FIELD IN COMPLILE BUFFER
- CALL Q$CCOM
- JMP Q$NEXT
-
- DB 7,'PROMP' ;PROMPT0
- IF DEBUG
- DW ERRCH
- ENDIF
- IF NOT DEBUG
- SLITE
- ENDIF
- DW $+2
- PROM0: LHLD Q$INBLK ;EXECUTING A FILE Q$
- INX H
- MOV A,H
- ORA L
- JNZ Q$NEXT ;YES, NO PROMPT
- CALL Q$IFCR ;TYPE A CR IF COLUMN NON-ZERO
- LDA Q$CHECK ;TYPE CHECK
- CALL Q$TTO
- MVI A,76Q ;TYPE >
- CALL Q$TTO
- MVI A,40Q ;TYPE SPACE
- CALL Q$TTO
- JMP Q$NEXT ;RETURN
-
- DW Q$COLN
- GO: DW Q$GO1
- GO1: DW EXPRO
- GO8: DW RDLIN
- DW COMPI
- DW Q$GO2
- DW Q$IF
- DW GO1-2-$
- DW LIT
- DW Q$SEMI
- DW CCOMM
- DW EXCBUF
- IF DEBUG
- DW ERRCH
- ENDIF
- DW Q$ELSE
- DW GO-2-$
-
- DW $+2
- EXPRO: LHLD Q$PROM ;EXECUTE @ PROMPT
- JMP EXEC
-
- DW $+2
- EXCBUF: LXI D,CBUF+2 ;EXECUTE COMPILE BUFFER
- JMP NEXT1
-
- DW $+2
- Q$GO1: MVI A,80H ;SET STATE TO 80 HEX
- STA Q$STATE
- MVI A,60Q ;SET CHECK TO "0"
- STA Q$CHECK
- LXI H,CBUF ;RESET .C TO START OF COMPILE BUFFER
- SHLD Q$C
- LXI H,Q$COLN ;OUTPUT (:) TO COMPILE BUFFER
- CALL Q$CCOM
- JMP Q$NEXT
-
- DW $+2
- Q$GO2: LDA Q$EOC ;END OF COMMAND Q$
- ORA A
- JZ PUSH0 ;NO, RETURN 0
- LDA Q$CHECK ;CHECK = "0" Q$
- CPI 60Q
- JNZ PUSH0 ;NO, RETURN 0
- JMP PUSH1 ;YES, RETURN -1
- ;
- ;
- DB 5,'ENTER' ;ENTER
- DW PROM0
- DW $+2
- ENTER: LHLD Q$ENT
- JMP EXEC
-
- DB 4,'ENT0',0 ;ENT0
- DW ENTER
- DW $+2
- ENT0: LHLD Q$Q$D ;ZERO 6 BYTES AT END OF DICTIONARY
- MVI A,6
- ENT1: MVI M,0
- INX H
- DCR A
- JNZ ENT1
-
- POP B ;COPY NAME ONTO END OF DICTIONARY
- MVI A,6 ;6 BYTES
- STA Q$T1
- ENT2: LDAX B ;MOVE NAME AND LENGTH
- ORA A
- JZ ENT3 ;FILL WITH NULLS
- INX B
- ENT3: CALL Q$BCOM
- LXI H,Q$T1 ;DONE Q$
- DCR M
- JNZ ENT2 ;NO
-
- ;LINK NEW ENTRY INTO DICTIONARY
- LHLD Q$CURR ;GET PTR TO PREVIOUS ENTRY
- MOV E,M
- INX H
- MOV D,M
- XCHG
- CALL Q$COMM ;STORE IT IN LINK FIELD
-
- LHLD Q$Q$D ;STORE $+2 IN CODE ADDRESS FIELD
- INX H
- INX H
- CALL Q$COMM
-
- LHLD Q$Q$D ;RESET CURRENT TO .
- XCHG
- LHLD Q$CURR
- MOV M,E
- INX H
- MOV M,D
- JMP Q$NEXT ;RETURN
- ;
- ;
- Q$BRAN: XCHG ;PUSH @(DE) ON VOCABULARY STACK
- MOV E,M
- INX H
- MOV D,M
- BRAN1: LHLD Q$V
- INX H
- INX H
- SHLD Q$V
- MOV M,E
- INX H
- MOV M,D
- JMP Q$NEXT
-
- DB 10,'ASSEM' ;ASSEMBLER<
- DW ENT0
- DW Q$BRAN
- ASSEM: DW Q$ASSE
-
- DB 6,'STOIC' ;STOIC<
- DW ASSEM
- DW Q$BRAN
- STOIC: DW Q$STOI
-
- DB 2,'<L',0,0,0 ;<L
- DW STOIC
- DW $+2
- LPUSH: POP H
- CALL Q$LPUSH
- JMP Q$NEXT
-
- DB 2,'L>',0,0,0 ;L>
- DW LPUSH
- DW $+2
- LPOP: CALL Q$LPOP
- JMP Q$Q$PUSH
-
- DB 4,'LOAD',0 ;LOAD
- DW LPOP
- DW $+2
- LOAD: LHLD Q$INBLK
- CALL Q$LPUSH
- LHLD Q$INBYT
- CALL Q$LPUSH
- POP H
- SHLD Q$INBLK
- LXI H,0
- SHLD Q$INBYT
- JMP Q$NEXT
-
- DB 2,';F',0,0,0 ;;F
- DW LOAD
- DW $+2
- Q$SCLF: CALL Q$LPOP
- SHLD Q$INBYT
- CALL Q$LPOP
- SHLD Q$INBLK
- JMP Q$NEXT
-
- ;POP A NUMBER OFF THE LOOP STACK
- ;
- ; CALL Q$LPOP
- ; HL CONTAINS NUMBER
-
- Q$LPOP: LHLD Q$Q$L ;LOOP STACK PTR
- MOV E,M ;GET TOP OR STACK INTO DE
- INX H
- MOV D,M
- DCX H
- DCX H ;DECREMENT LOOP STACK PTR BY 2
- DCX H
- SHLD Q$Q$L
- XCHG ;MOVE RESULT TO HL
- RET ;RETURN
-
- ;PUSH A NUMBER ON THE LOOP STACK
- ;
- ; HL CONTAINS NUMBER
- ; CALL Q$LPUSH
-
- Q$LPUSH: XCHG ;MOVE NUMBER TO DE
- LHLD Q$Q$L ;INCREMENT LOOP STACK PTR BY 2
- INX H
- INX H
- SHLD Q$Q$L
- MOV M,E ;STORE NUMBER ON END OF RETURN STACK
- INX H
- MOV M,D
- RET ;RETURN
-
- DB 11,'DEFIN' ;DEFINTIONS
- DW Q$SCLF
- DW $+2
- DEFIN: LHLD Q$V
- MOV E,M
- INX H
- MOV D,M
- XCHG
- SHLD Q$CURR
- JMP Q$NEXT
-
- DB 1,'>',0,0,0,0 ;>
- DW DEFIN
- DW $+2
- REVER: LHLD Q$V
- DCX H
- DCX H
- SHLD Q$V
- JMP Q$NEXT
-
- DB 201Q,'^',0,0,0,0 ;^
- DW REVER
- DW $+2
- UPARR: SUB A
- STA Q$EOC
- JMP Q$NEXT
-
- DB 201Q,'%',0,0,0,0 ;%
- DW UPARR
- DW $+2
- PERC: MVI A,0FFH
- STA Q$EOL
- JMP Q$NEXT
- ;
- ;
- DB 201Q,':',0,0,0,0 ;:
- DW PERC
- DW $+2
- COLON: LDA Q$CHECK
- CPI 60Q
- JNZ CHERR
- INR A
- STA Q$CHECK
- LXI H,ENTER
- CALL Q$CCOM
- LXI H,COLN1
- CALL Q$CCOM
- LHLD Q$C
- PUSH H
- LXI H,0
- CALL Q$CCOM
- JMP Q$NEXT
-
- CHERR: LXI H,CHERM
- JMP ERROR
- CHERM: DB 12,'SYNTAX ERROR'
-
- Q$COLN: LHLD Q$I ;(;)
- XCHG
- DCX H ;SET .I TO W-2
- DCX H
- SHLD Q$I
- LHLD Q$R ;INCREMENT RETURN STACK PTR BY 2
- INX H
- INX H
- SHLD Q$R
- MOV M,E ;STORE .I ON END OF RETURN STACK
- INX H
- MOV M,D
- JMP Q$NEXT
-
- DW $+2
- COLN1: LHLD Q$I
- INX H
- INX H
- MOV E,M
- INX H
- MOV D,M
- INX H
- COLN2: PUSH H
- PUSH D
- MOV A,M
- CALL Q$BCOM
- POP D
- POP H
- INX H
- DCX D
- MOV A,D
- ORA E
- JNZ COLN2
- DCX H
- DCX H
- SHLD Q$I
- LHLD Q$CURR
- MOV E,M
- INX H
- MOV D,M
- DCX D
- DCX D
- LXI H,Q$COLN
- XCHG
- MOV M,E
- INX H
- MOV M,D
- JMP Q$NEXT
-
- DB 205Q,'CODE<' ;CODE<
- DW COLON
- DW Q$COLN
- CODE: DW LIT
- DW ENTER
- DW CCOMM
- DW ASSEM
- DW Q$SEMI
-
- DB 201Q,';',0,0,0,0 ;;
- DW CODE
- DW $+2
- SCOL: CALL Q$SCOL ;TERMINATE COLON DEFINITION
- LXI H,Q$SEMI ;OUTPUT (;) TO COMPILE BUFFER
- CALL Q$CCOM
- JMP Q$NEXT
-
- DB 206Q,';CODE' ;;CODE<
- DW SCOL
- DW $+2
- SCLCD: CALL Q$SCOL ;TERMINATE COLON DEFINITION
- LXI H,Q$SCOD ;OUTPUT (;CODE) TO COMPILE BUFFER
- CALL Q$CCOM
- LXI D,Q$ASSE ;ASSEMBLER<
- JMP BRAN1
-
- Q$SCOL: LDA Q$CHECK ;DECREMENT CHECK
- DCR A
- CPI 60Q
- JNZ CHERR ;ERROR IF NOT ZERO
- STA Q$CHECK
- POP H ;OLD C.
- XTHL
- PUSH H
- CALL Q$MHL ;COMPUTE DIFFERENCE
- XCHG
- LHLD Q$C ;C.
- DAD D
- XCHG
- POP H ;OLD C.
- MOV M,E ;STORE DIFFERENCE AT OLD C.
- INX H
- MOV M,D
- RET
-
- DB 8,'CONST' ;CONSTANT
- DW SCLCD
- DW Q$COLN
- CONST: DW ENTER
- DW COMMA
- DW Q$SCOD
- Q$CONS: XCHG ;(CONSTANT)
- JMP ATPUS
- ;
- ;
- DB 4,'PUSH',0 ;PUSH
- DW 0
- DW Q$CONS
- PUSHQ$: DW Q$Q$PUSH
-
- DB 4,'NEXT',0 ;NEXT
- DW PUSHQ$
- DW Q$CONS
- NEXTQ$: DW Q$NEXT
-
- DB 5,'DPUSH' ;DPUSH
- DW NEXTQ$
- DW Q$CONS
- DPSHQ$: DW Q$DPUSH
-
- DB 5,'@PUSH' ;@PUSH
- DW DPSHQ$
- DW Q$CONS
- ATPSQ$: DW ATPUS
-
- DB 5,'PUSHD' ;PUSHD
- DW ATPSQ$
- DW Q$CONS
- PUSDQ$: DW PUSHD
-
- DB 5,'0PUSH' ;0PUSH
- DW PUSDQ$
- DW Q$CONS
- PUS0Q$: DW PUSH0
-
- DB 6,'-1PUS' ;-1PUSH
- DW PUS0Q$
- DW Q$CONS
- PUS1Q$: DW PUSH1
-
- DB 3,'MUL',0,0 ;MUL
- DW PUS1Q$
- DW Q$CONS
- MULQ$: DW Q$MUL
-
- DB 3,'-HL',0,0 ;-HL
- DW MULQ$
- DW Q$CONS
- MHLQ$: DW Q$MHL
-
- DB 5,'(MSG)' ;(MSG)
- DW MHLQ$
- DW Q$CONS
- MSGQ$: DW Q$MSG
-
- DB 3,'(,)',0,0 ;(,)
- DW MSGQ$
- DW Q$CONS
- COMMQ$: DW Q$COMM
-
- DB 4,'(B,)',0 ;(B,)
- DW COMMQ$
- DW Q$CONS
- BCOMQ$: DW Q$BCOM
-
- DB 8,'(BRAN' ;(BRANCH)
- DW BCOMQ$
- DW Q$CONS
- BRANQ$: DW Q$BRAN
-
- DB 5,'ERROR' ;ERROR
- DW BRANQ$
- DW Q$CONS
- ERRQ$: DW ERROR
-
- DB 5,'(TTI)' ;(TTI)
- DW ERRQ$
- DW Q$CONS
- TTIQ$: DW TTYIN
-
- DB 5,'(TTO)' ;(TTO)
- DW TTIQ$
- DW Q$CONS
- TTOQ$: DW Q$TTO
-
- DB 6,'(READ' ;(READ)
- DW TTOQ$
- DW Q$CONS
- READQ$: DW Q$RDERC
-
- DB 7,'(WRIT' ;(WRITE)
- DW READQ$
- DW Q$CONS
- WRITQ$: DW Q$WRERC
-
- DB 8,'(RBLO' ;(RBLOCK)
- DW WRITQ$
- DW Q$CONS
- RBLKQ$: DW RBLK
-
- DB 8,'(WBLO' ;(WBLOCK)
- DW RBLKQ$
- DW Q$CONS
- WBLKQ$: DW WBLK
-
- DB 2,'T1',0,0,0 ;T1
- DW WBLKQ$
- DW Q$CONS
- T1Q$: DW Q$T1
-
- ;8080 INSTRUCTION CLASSES
- DB 2,'R0',0,0,0 ;R0
- DW T1Q$
- DW Q$COLN
- XR0: DW CONST
- DW Q$SCOD
- LDAX D
- CALL Q$BCOM
- JMP Q$NEXT
-
- DB 2,'R1',0,0,0 ;R1
- DW XR0
- DW Q$COLN
- R1: DW CONST
- DW Q$SCOD
- CALL SH3
- R11: CALL Q$BCOM
- JMP Q$NEXT
-
- DB 2,'R2',0,0,0 ;R2
- DW R1
- DW Q$COLN
- R2: DW CONST
- DW Q$SCOD
- CALL SH3
- R21: POP H
- ADD L
- JMP R11
-
- DB 2,'R3',0,0,0 ;R3
- DW R2
- DW Q$COLN
- R3: DW CONST
- DW Q$SCOD
- LDAX D
- JMP R21
-
- DB 2,'R4',0,0,0 ;R4
- DW R3
- DW Q$COLN
- R4: DW CONST
- DW Q$SCOD
- LDAX D
- R41: CALL Q$BCOM
- POP H
- MOV A,L
- CALL Q$BCOM
- JMP Q$NEXT
-
- DB 2,'R5',0,0,0 ;R5
- DW R4
- DW Q$COLN
- R5: DW CONST
- DW Q$SCOD
- CALL SH3
- JMP R41
-
- DB 2,'R6',0,0,0 ;R6
- DW R5
- DW Q$COLN
- R6: DW CONST
- DW Q$SCOD
- CALL SH3
- R61: CALL Q$BCOM
- POP H
- R62: CALL Q$COMM
- JMP Q$NEXT
-
- DB 2,'R7',0,0,0 ;R7
- DW R6
- DW Q$COLN
- R7: DW CONST
- DW Q$SCOD
- LDAX D
- JMP R61
-
- DB 2,'R8',0,0,0 ;R8
- DW R7
- DW Q$COLN
- R8: DW CONST
- DW Q$SCOD
- LDAX D
- CALL Q$BCOM
- LHLD Q$Q$D
- PUSH H
- LXI H,0
- JMP R62
-
- ;SHIFT TOP OF STACK 3 LEFT AND ADD BYTE ADDRESSED BY DE
- ;LEAVING RESULT IN A
-
- SH3: POP H
- XTHL
- DAD H
- DAD H
- DAD H
- LDAX D
- ADD L
- RET
-
- ;
- ;UNIT NUMBER
- Q$UNIT: DW 0
-
- ;BUFFER CONTROL TABLES
- BCT1: DW -1 ;BLOCK #
- DW BUF1 ;BUFFER ADDR
- DW BCT2 ;LINK
- DW 0 ;MODIFIED FLAG
-
- BCT2: DW -1
- DW BUF2
- DW 0
- DW 0
-
- ;I/O BUFFERS
- BUF1: DS BSIZE
- BUF2: DS BSIZE
-
- ;BUFFER HANDLER VARIABLES
- NEWEST: DW BCT1 ;HEAD OF BCT LIST
- PREV: DW 0 ;BUFFER STRATEGY TEMPORARIES
- BUFP: DW 0
- BLKN: DW 0
- FLAG: DB 0
-
- ;START OF USER MEMORY
-
- ;VARIABLES
- ;
- ;***************
- ;*** WARNING ***
- ;***************
- ;
- ;DO NOT ADD, DELETE, OR REARRANGE THE FOLLOWING
- ;VARIABLES WITHOUT MAKING CORRESPONDING CHANGES
- ;TO THE BASIC DEFINITIONS FILE WHICH DEFINES THE
- ;ADDRESSES OF THESE VARIABLES.
-
- ;BYTE VARIABLES
- Q$STATE: DB 0 ;STATE
- Q$CHECK: DB 0 ;CHECK
- Q$COLU: DB 0 ;COLUMN
-
- ;WORD VARIABLES
- Q$I: DW 0 ;.I
- Q$R: DW 0 ;.R
- Q$Q$L: DW 0 ;.L
- Q$V: DW VSTACK+2 ;.V
- Q$Q$D: DW LASTW ;.D
- Q$C: DW 0 ;.C
- Q$CURR: DW Q$STOI ;CURRENT
- Q$RADIX: DW 8 ;RADIX
- Q$PROM: DW PROM0 ;PROMPT
- Q$ERRM: DW ERRM0 ;ERRMSG
- Q$ENT: DW ENT0 ;ENT
- Q$MEMO: DW 0 ;MEMORY
- Q$LIT: DW LITER ;LIT
- Q$TYI: DW Q$TTYI ;(TTYIN)
- Q$TYO: DW Q$TTYO ;(TTYOU)
- Q$ABORT: DW Q$AB ;(ABORT)
-
- ;INTERNAL VARIABLES
- Q$EOC: DB 0 ;EOC
- Q$EOL: DB 0 ;EOL
- Q$ASSE: DW R8 ;ASSEMBLER<
- Q$STOI: DW CONST ;STOIC<
- Q$INP: DW 0 ;INP
- Q$INBYT: DW 0 ;INBYTE
- Q$INBLK: DW 0 ;INBLK
-
- Q$T1: DW 0 ;TEMPORARIES
- Q$T2: DW 0
- Q$T3: DW 0
- Q$T4: DW 0
- Q$T5: DW 0
- Q$T6: DW 0
- Q$T7: DW 0
- Q$T8: DW 0
- Q$T9: DW 0
- Q$T10: DW 0
-
- ;PARAMETER STACK
- SSTKE: DS SSIZE
- SSTACK: DS 8 ;PROTECTION AGAINST STACK UNDERFLOW
-
- ;VOCABULARY STACK
- VSTACK: DW 0
- DW Q$STOI
- DS VSIZE
-
- ;LOOP STACK
- LSTACK: DS LSIZE
-
- ;RETURN STACK
- RSTACK: DS RSIZE
-
- ;COMPILE BUFFER
- CBUF: DS CSIZE
-
- ;KEYBOARD BUFFER
- KBUF: DS KSIZE
-
- ;END OF KERNEL
- LASTW EQU $
- IF NOT CPM
- ;
- ;INITIALIZATION CODE, OVERWRITTER BY DICTIONARY
- ;SIZE MEMORY, SET Q$MEMO, JMP TO ABORT
- SIZE: LXI H,0C000H ;FIRST DEVICE ADDRESS
- MVI A,55H ;ALTERNATING 1'S AND 0'S
- SIZE1: DCX H ;DECREMENT TO NEXT LOC
- MOV M,A ;STORE BYTE IN MEMORY
- CMP M ;CAN READ IT BACK Q$
- JNZ SIZE1 ;NO, CONTINUE
- INX H ;BACK UP
- SHLD Q$MEMO ;SET MEMORY LIMIT
- JMP ABORT ;START UP STOIC
- ;
- ENDIF
- ;
- ;
- ;SET UP START ADDRESS
- ;
- IF NOT CPM
- START SET SIZE
- ENDIF
- ;
- IF CPM
- START SET TPA
- ENDIF
- ;
- ;
- END START
-
-
- ***EOF***
-