home *** CD-ROM | disk | FTP | other *** search
- TITLE 'UNSPOOL Disk to device background process'
- ;
- VERSION EQU 3$3 ;Version number
- ;
- ;Author:
- ; Gary P. Novosielski
- ;
- ;NOTE: This source file requires MAC for assembly.
- ; Due to the complexity of operations performed by
- ; the macros which generate the relocation table, the
- ; assembly process will be significantly longer than
- ; normal for a program of this size. Be prepared for
- ; a long period of no disk activity on each pass before
- ; pressing the panic button.
- ;
- ;Revisions: (in LIFO order)
- ;3.3 82-01-22
- ; Optional Formfeed simulation for printers
- ; which do not recognize the formfeed character.
- ; Set SIMFF to TRUE for this option. LPPP
- ; (lines per physical page - normally 66)
- ; added for calculation of # of linefeeds.
- ; PAGDEF can be set to TRUE to default PAG.
- ; In that case the PAG command parameter will
- ; turn paging OFF. END can be used instead of
- ; OFF, because I can never remember OFF. (Jon Tara)
- ;
- ;3.2 81-12-29
- ; Optional printer paging added. Feature is
- ; invoked by typing "UNSPOOL FN.FT PAG".
- ; In both cases formfeeds in the file will
- ; be passed to the output device.
- ; Note that paging is available only
- ; under default conditions (C. Strom)
- ;
- ;3.1 81-12-06
- ; Disable DIRECT BIOS call for DISK writes.
- ; Too many application programs which use
- ; direct BIOS calls to access the disk assume
- ; that they have sole control of drive/track/
- ; sector selection. This could be a potential
- ; disaster. See documentation.
- ;
- ;3.0 81-11-12
- ; New release. Relpaces 2.3.
- ;Version 3
- ; Now continues to run during direct BIOS input.
- ; The device name "off" has been implemented as
- ; a method of cancelling an already running
- ; UNSPOOL. It causes a BDOS function 0 reset.
- ; Function 0 reset now trapped. Prompts operator
- ; with option to cancel. Optional tab expansion
- ; support at assembly time. Disk reset (login)
- ; occurs during simulated warm-boot. Various
- ; cosmetic and source revisions.
- ;Version 2
- ; Copy BIOS table so application programs will
- ; still have BIOS access by using word at BOOT+1.
- ; Preserve USER and IOBYTE values as of startup.
- ;
-
- FALSE EQU 0
- TRUE EQU NOT FALSE
- ? EQU -1
-
- ;
- ; User-settable assembly options
- ;
- EXPAND SET TRUE ;True to expand tabs
- IF EXPAND
- PHYSBS SET TRUE ;True to recognize backspace
- ENDIF
- SIMFF SET TRUE ; Simulate formfeeds with multiple linefeeds.
- PAGDEF SET TRUE ; Default PAGing to on.
- LPP SET 60 ; Lines per PRINTED page.
- LPPP SET 66 ; Lines per PHYSICAL page.
-
- ;
- ; BDOS Functions:
- ;
- @SYS SET 0
- @KEY SET 1
- @CON SET 2
- @RDR SET 3
- @PUN SET 4
- @LST SET 5
- @DIO SET 6
- @RIO SET 7
- @SIO SET 8
- @MSG SET 9
- @INP SET 10
- @RDY SET 11
- @VER SET 12
- @LOG SET 13
- @DSK SET 14
- @OPN SET 15
- @CLS SET 16
- @DIR SET 17
- @NXT SET 18
- @DEL SET 19
- @FRD SET 20
- @FWR SET 21
- @MAK SET 22
- @REN SET 23
- @CUR SET 25
- @DMA SET 26
- @CHG SET 30
- @USR SET 32
- @RRD SET 33
- @RWR SET 34
- @SIZ SET 35
- @REC SET 36
- ;
- ;System equates:
- CPMBASE EQU 0
- BOOT SET CPMBASE
- BDOS SET BOOT+5
- TFCB EQU BOOT+5CH
- TFCB1 EQU TFCB
- TFCB2 EQU TFCB+16
- TBUFF EQU BOOT+80H
- TPA EQU BOOT+100H
- CTRL EQU ' '-1 ;CTRL CHAR MASK
- CR SET CTRL AND 'M'
- LF SET CTRL AND 'J'
- TAB SET CTRL AND 'I'
- FF SET CTRL AND 'L'
- BS SET CTRL AND 'H'
- EOF SET CTRL AND 'Z'
- NVECTS EQU 16; ;Number of BIOS vectors
- FCBLEN EQU 33 ;Length of input FCB
- ;
- ;The flag SAVECCP should be made true if
- ;the program segment should load below the CCP.
- ;If false the segment will load in the extreme
- ;top of the Transient Program Area, overlaying
- ;the Console Command Processor.
- ;
- SAVECCP SET TRUE ;MUST remain true for UNSPOOL
- OVERLAY SET FALSE ;(initially)
- ; Macro Definitions
- ;
- ; Perform a standard BIOS function:
- CPM MACRO FUNC,OPERAND
- IF NOT NUL OPERAND
- LXI D,OPERAND
- ENDIF ;not nul operand
- IF NOT NUL FUNC
- MVI C,@&FUNC
- ENDIF ;not nul func
- CALL BDOS
- ENDM
- ;
- ; Generate a label of the form ??Rnn to tag an
- ; address requiring relocation:
- RTAG MACRO LBL,VAL
- ??R&LBL EQU VAL
- ENDM
- ;
- ; Flag <INST> as a relocatable instruction
- ; <INST> is of the form: <MNE OP1[,OP2]>
- R MACRO INST
- @RLBL SET @RLBL+1
- RTAG %@RLBL,%2+$-@BASE
- INST-@BASE
- ENDM
- ;
- ; During bit map construction, get the next R-tagged
- ; address value:
- NXTRLD MACRO NN
- @RLD SET ??R&NN
- @NXTRLD SET @NXTRLD + 1
- ENDM
- ;
- ;
- ; Enter here from Console Command Processor (CCP)
- ;
- CCPIN ORG TPA
- JMP INTRO
- ;
- SIGNON:
- DB 'UNSPOOL',TAB,TAB,TAB
- DB 'Ver '
- DB (VERSION/10)+'0'
- DB '.'
- DB (VERSION MOD 10)+'0'
- IF EXPAND
- DB '/T'
- ENDIF ;expand
- IF PAGDEF
- DB '/P'
- ENDIF
- IF NOT SIMFF
- DB '/F'
- ENDIF
- DB '$'
- ;
- INTRO:
- CPM MSG,SIGNON
- CALL SETUP ;initialize.
- LXI H,BDOS+2 ;find top of memory
- MOV A,M ;page address
- ;Form destination...
- SUI PAGES ;...address in
- MOV D,A ;DE pair.
- MVI E,0
- PUSH D ;save on stack
- LXI H,@BASE ;source address
- LXI B,SEGLEN
- ;
- MOVLOOP:
- ;Move (HL) to (DE) for (BC) bytes
- MOV A,B
- ORA C ;test for (BC) = 0
- JZ MOVDONE
- DCX B ;count down
- MOV A,M ;move a byte
- STAX D
- INX D ;bump the pointers
- INX H
- JMP MOVLOOP
- ;
- MOVDONE:
- ;The segment is now moved to high memory, but not
- ;properly relocated. The bit table which specifies
- ;which addresses need to be adjusted is located
- ;just after the last byte of the source segment,
- ;so (HL) is now pointing at it.
- POP D ;beginning of newly moved code.
- LXI B,SEGLEN;length of segment
- PUSH H ;save pointer to reloc info
- MOV H,D ;offset page address
- ;
- FIXLOOP:
- ;Scan through the newly moved code, and adjust any
- ;page addresses by adding (H) to them. The word on
- ;top of the stack points to the next byte of the
- ;relocation bit table. Each bit in the table
- ;corresponds to one byte in the destination code.
- ;A value of 1 indicates the byte is to be adjusted.
- ;A value of 0 indicates the byte is to be unchanged.
- ;
- ;Thus one byte of relocation information serves to
- ;mark 8 bytes of object code. The bits which have
- ;not been used yet are saved in L until all 8
- ;are used.
- ;
- MOV A,B
- ORA C ;test if finished
- JZ FIXDONE
- DCX B ;count down
- MOV A,E
- ANI 07H ;on 8-byte boundry?
- JNZ NEXTBIT
- ;
- NEXTBYT:
- ;Get another byte of relocation bits
- XTHL
- MOV A,M
- INX H
- XTHL
- MOV L,A ;save in register L
- ;
- NEXTBIT MOV A,L ;remaining bits from L
- RAL ;next bit to CARRY
- MOV L,A ;save the rest
- JNC NEXTADR
- ;
- ;CARRY was = 1. Fix this byte.
- LDAX D
- ADD H ;(H) is the page offset
- STAX D
- ;
- NEXTADR INX D
- JMP FIXLOOP
- ;
- FIXDONE:
- ;Finished. Jump to the first address in the new
- ;segment in high memory.
- ;
- ;First adjust the stack. One garbage word was
- ;left by fixloop.
- INX SP
- INX SP
- ;
- ;(HL) still has the page address
- MOV L,A ;move zero to l
- PCHL ;Top-of-stack is CCP return
- SETUP:
- ;First, check environment to see if BIOS vectors
- ;are accessible.
- LDA BOOT ;Location BOOT should
- CPI ( JMP ) ;have a JMP instruction
- JNZ VECTERR
- LHLD BOOT+1 ;Location one points
- MVI C,NVECTS ;to the table of jumps
- ;which we move into
- ;the code.
- LXI D,BIOSV
- XCHG
- VLOOP:
- LDAX D
- CMP M ;another JMP?
- JNZ VECTERR
- INX D
- INX H
- LDAX D
- MOV M,A
- INX D
- INX H
- LDAX D
- MOV M,A
- INX H
- INX D
- DCR C
- JNZ VLOOP
- ; Save old vectors and CCP return address
- ;Patch up new vectors as required.
- LHLD BOOT+1
- SHLD OLDBOOT; Save the BOOT vector
- ;
- LXI H,2; Retrieve the CCP
- DAD SP; return address from
- MOV A,M; down the stack a ways.
- INX H
- MOV H,M
- MOV L,A
- SHLD CCPRET+1; Save the CCP re-entry
- ; point.
- ;
- LHLD BDOS+1
- SHLD GOBDOS+1; Save the BDOS entry
- ; point.
- ;
- LHLD CONIN+1; Save the direct call
- SHLD REALCON+1; to console input.
- SETUPDEV:
- LXI D,TFCB2+1
- LDAX D
- CPI ' '
- JZ SETUPFIL
- ;
- LXI H,LSTLIT
- MVI B,4
- CALL SCOMP
- JZ SETUPFIL; Use default
- ;
- LXI D,TFCB2+1
- LXI H,PUNLIT
- MVI B,4
- CALL SCOMP
- JNZ CKPAG
- MVI A,@PUN
- STA DEVICE
- JMP SETUPFIL
- ;
- CKPAG:
- LXI D,TFCB2+1
- LXI H,PAGLIT
- MVI B,4
- CALL SCOMP
- JNZ CKSYS
- LDA PAGFLG ; Get initial default value.
- XRI 0FFH ; Flip it.
- STA PAGFLG ; Store new value.
- JMP SETUPFIL
- ;
- CKSYS:
- LXI D,TFCB2+1
- LXI H,OFFLIT
- MVI B,4
- CALL SCOMP
- JZ RESET
- LXI D,TFCB2+1 ; Also check END cause I can never
- LXI H,ENDLIT ; remember ... uh ... uh ..
- MVI B,4 ; oh yea - OFF. (JT)
- CALL SCOMP
- JNZ DEVERR ; Didn't match anything - error.
- RESET:
- CPM SYS ;Request system reset
- SETUPFIL:
- LDA TFCB1
- ORA A
- JNZ OPENIT
- ;The drive has been defaulted. Make it explicit
- ;in case the default drive is changed while the
- ;file is being unspooled.
- CPM CUR; Returns A: as 00
- INR A; Open needs A: as 01
- STA TFCB1
- OPENIT:
- CPM OPN,TFCB1
- INR A
- JNZ COPYFCB
- ;Error. Can't open input file.
- LXI H,TBUFF
- MOV A,M
- ADD L
- MOV L,A
- ADC H
- SUB L
- MOV H,A
- INX H
- MVI M,'?'
- INX H
- MVI M,'$'
- CPM CON,CR
- CPM CON,LF
- CPM MSG,TBUFF+1
- POP H; Adjust stack
- RET; Exit to CCP
- ;
- COPYFCB:
- LXI H,TFCB1
- LXI D,FCB
- MVI C,FCBLEN
- COPY1 MOV A,M
- STAX D
- INX H
- INX D
- DCR C
- JNZ COPY1
- ;
- SETUPUSR:
- ; Save user number in effect at time of entry
- CPM USR,?
- STA ENTUSR
- ;
- SETUPIOB:
- ; Save IOBYTE in effect at time of entry
- CPM RIO
- STA ENTIOB
- ;
- RET
- ;
- SCOMP:
- LDAX D
- CMP M
- RNZ
- INX D
- INX H
- DCR B
- JNZ SCOMP
- RET
- ;
- DEVERR:
- CPM MSG,DEVERRMSG
- POP H; Adjust stack
- RET; Exit to CCP
- VECTERR:
- CPM MSG,VCTERRMSG
- JMP BOOT ;try re-booting.
- ;
- LSTLIT:
- DB 'LST ' ;Note trailing blank
- ENDLIT:
- DB 'END '
- PUNLIT:
- DB 'PUN ' ;Note trailing blank
- OFFLIT:
- DB 'OFF ' ;Note trailing blank
- PAGLIT:
- DB 'PAG ' ;Note trailing blank
- DEVERRMSG:
- DB CR,LF,'Invalid device.$'
- VCTERRMSG:
- DB CR,LF,'Error in system table. '
- DB 'Attempting re-boot.$'
- PAGE
- ;Align location counter to next page boundry
- @BASE ORG ($ + 0FFH) AND 0FF00H
- @RLBL SET 0
- ;
- ; The segment to be relocated goes here.
- ; Any position dependent (3-byte) instructions
- ; are handled by the "R" macro.
- ; For readability, the macro name "R" is placed in
- ; column 2. The preceding blank must be present to
- ; distinguish it from a label.
- ;*************************************************
- BDOSV:
- ;During operation, this location will point
- ;to INTERCEPT and will be jumped to by BDOS.
- ;It must be at the lowest location
- ;in the protected segment of code.
- R <JMP ONESHOT> ;complete installation
- BIOSV:
- REPT NVECTS
- JMP ?
- ENDM
- CONSTAT EQU BIOSV+(1*3)
- CONIN EQU BIOSV+(2*3)
- WRITE EQU BIOSV+(13*3)
- LSTSTAT EQU BIOSV+(14*3)
- ;
- INTERCEPT:
- ;This routine intercepts all BDOS calls.
- MOV A,C; Get function
- CPI @SYS; Is it a system reset?
- R <JZ SYSREQ>
- CPI @KEY; Is it single key input?
- R <JZ WAITING>
- CPI @INP; or buffered input?
- R <JNZ CKDMA>
- WAITING:
- ;Wait for actual keypress before honoring input
- ;request. Unspool characters in the meantime.
- R <LDA ACTIVE>
- ORA A; See if finished.
- R <CNZ PROCESS>; Note that A <> 0
- R <JMP GOBDOS>; Honor the input request
- ;
- CKDMA CPI @DMA; If the DMA address is being
- ; changed, we have to know.
- R <JNZ GOBDOS>
- XCHG
- R <SHLD DMAHOLD>
- XCHG
- ;
- GOBDOS JMP ?; Patched on entry
- ; points to "real" BDOS routine.
- ;
- TRAPCON:
- ; The application has done a direct BIOS call for
- ;console input. We can be confident that this was not
- ;as a result of a BDOS operation, since BDOS knows
- ;nothing about our local jump table. Thus we will not
- ;need to be concerned with the non-reentrancy of BDOS.
- ;
- R <LDA ACTIVE>
- ORA A; See if active.
- MVI A,0; Flag BIOS-type request.
- R <CNZ PROCESS>; Unspool a while if so.
- REALCON:
- JMP ?; Patched during setup.
- ;
- TRAPWRT:
- ; The application has attempted a direct BIOS
- ; disk write. This is too dangerous to be
- ; allowed, since the programmer may have made
- ; rash assumptions about the track or sector
- ; which are currently selected.
- R <LXI D,OPEXCPT>
- MVI C,@MSG
- R <CALL GOBDOS>; Give the bad news.
- JMP BOOT; Abort the application
- OPEXCPT:
- DB CR,LF
- DB 'Invalid operation attempted under'
- DB ' UNSPOOL.',CR,LF,'Program aborted.'
- DB '$'
- PROCESS:
- ;The application program is now waiting for a key
- ;to be input. We will use this opportunity to print
- ;some characters to the device until a key is
- ;actually pressed.
- R <STA ITYPE> ;The A register tells type
- ; of input request.
- LXI H,0
- DAD SP
- R <LXI SP,LCLSTACK>
- PUSH H; Save old SP
- PUSH B
- PUSH D; Save entry parameters
- MVI C,@RIO; Save old IOBYTE
- R <CALL GOBDOS>
- R <STA IOBHOLD>
- PROC1:
- R <CALL CKKEY>; Check for keypress.
- R <JNZ PROCEXIT>
- R <LDA DEVICE> ;Check device being used
- CPI @LST
- R <JNZ PROC2> ;If it is LST:
- R <CALL LSTSTAT>
- ORA A
- R <JZ PROC1> ;Loop if not ready
- ;
- PROC2:
- IF EXPAND
- R <LDA TABFLAG>; In a tab sequence?
- ORA A
- R <JZ NITAB>
- R <LXI H,LINEPOS>
- MVI A,7
- ANA M; Check if more blanks needed
- R <JNZ SPCOUT>
- R <STA TABFLAG>; Clear the flag
- R <JMP PROC1>
- NITAB: ; "Not in Tab"
- ENDIF ;EXPAND
-
- IF SIMFF ; Simulating form-feeds.
- R <LDA FFFLG> ; In a form-feed sequence?
- ORA A
- R <JZ NIFF> ; Skip if no.
- R <LXI H,NBLINS>
- DCR M ; Decrement # of linefeeds remaining.
- MVI A,LF ; (Preload LF char)
- R <JNZ OUTCHR> ; Output another line-feed.
- XRA A
- R <STA FFFLG> ; Clear the flag.
- R <JMP PROC1>
- NIFF: ; "Not in form feed"
- ENDIF ; SIMFF
-
- R <LXI H,BUFFER>
- MOV A,M
- ORA A
- R <CM FILLBUFF>
- R <JC ENDFILE>
- INR A
- MOV M,A
- MOV C,A
- MVI B,0
- DAD B; Point to the buffered char.
- MOV A,M
- CPI EOF
- R <JZ ENDFILE>
-
- IF EXPAND
- R <LXI H,LINEPOS>; Print head position.
- CPI TAB; Is this a tab?
- R <JNZ NOTTAB> ; Skip if not.
- R <STA TABFLAG>; Set the flag
- SPCOUT:
- MVI A,' '
- R <JMP PROC5>
- ;
- NOTTAB:
- IF PHYSBS
- CPI BS; Backspace?
- R <JNZ PROC3>
- DCR M; Back up 1 column
- R <JMP PROC9>
- PROC3:
- ENDIF ;PHYSBS
-
- CPI CR; End of line?
- R <JNZ PROC4>
- MVI M,0; Reset column count.
- R <JMP PROC9>
- PROC4:
- CPI ' '; Other ctrl char?
- R <JC PROC9> ; Dont increase column count.
- PROC5:
- INR M ; Increase column count.
- ENDIF ;EXPAND
- PROC9:
- ;
- PUSH PSW
- R <LDA PAGFLG>; Paging enabled?
- ORA A
- R <JZ OUTCHR1>; No, so jump
- POP PSW; Yes, so process
- CPI FF; Char a formfeed?
- R <JZ PG>; Yes, so process it
- CPI LF; Char a lineFEED?
- R <JZ LFPROC>; Yes, so process it
- R <JMP OUTCHR>; Else just output char
- LFPROC:
- R <LDA LINCNT>; Get line counter
- INR A; Bump it
- CPI LPP; Reached limit?
- R <JZ PG>; Yup, so issue formfeed
- R <STA LINCNT>; Nope, so...
- MVI A,LF; ...increment the counter and...
- R <JMP OUTCHR>; ...output the linefeed
- ;
- PG:
- IF SIMFF
- R <LDA LINCNT> ; Get # of lines already printed.
- ORA A ; If we're already at the top of a page,
- R <JZ PROC1> ; forget it.
- MOV B,A
- MVI A,LPPP ; Lines per physical page.
- SUB B ; Compute # of LFs to output.
- R <STA NBLINS> ; Store # of LFs.
- XRA A ; Zero the counter.
- R <STA LINCNT>
- DCR A ; Make an "FF"
- R <STA FFFLG> ; Set the formfeed flag.
- MVI A,LF ; Output the first linefeed.
- R <JMP OUTCHR>
- ELSE
- XRA A
- R <STA LINCNT>; zero the counter
- MVI A,FF; issue a formfeed
- R <JMP OUTCHR>
- ENDIF
- OUTCHR1:
- POP PSW
- OUTCHR:
- ;
- MOV E,A
- PUSH D ;SAVE CHARACTER
- ;Set the IOBYTE as it was when UNSPOOL was
- ;started.
- R <LDA ENTIOB>
- MOV E,A
- MVI C,@SIO
- R <CALL GOBDOS>
- POP D ;RESTORE CHARACTER
- MVI C,@LST; Default
- DEVICE EQU $-1; Device code patch
- R <CALL GOBDOS>
- R <LDA IOBHOLD>; Restore active IOBYTE
- MOV E,A
- MVI C,@SIO
- R <CALL GOBDOS>
- R <JMP PROC1>
- ;
-
- ENDFILE:
- ; An EOF has been reached on the input file.
- ;Mark this program as inactive, and de-install on
- ;the next warm boot.
- XRA A
- R <STA ACTIVE>
- ;
- PROCEXIT:
- POP D
- POP B
- POP H; Restore SP
- SPHL
- RET
- ;
- ;
- FILLBUFF:
- ;Fill the buffer from the file
- PUSH H
- INX H
- XCHG; Buffer address to DE
- MVI C,@DMA; Set DMA address
- R <CALL GOBDOS>
- MVI E,?
- MVI C,@USR
- R <CALL GOBDOS>; Get current user
- R <STA USRHOLD>; Save it
- R <LDA ENTUSR>; Change to user at entry
- MOV E,A
- MVI C,@USR
- R <CALL GOBDOS>
- R <LXI D,FCB>
- MVI C,@FRD; Read a sector
- R <CALL GOBDOS>
- PUSH PSW; Save read return code
- R <LHLD DMAHOLD>
- XCHG; Restore DMA address
- MVI C,@DMA; to old value.
- R <CALL GOBDOS>
- R <LDA USRHOLD>
- MOV E,A; Restore User number
- MVI C,@USR; to old value
- R <CALL GOBDOS>
- POP PSW; Read return code
- POP H; Buffer pointer
- ORA A; How went the read?
- RZ; Fine
- STC; No good. Set CARRY for EOF
- RET
- ;
- CKKEY:
- ; Return zero flag if key not pressed
- ;Two types of status checking are done, depending
- ;on the way in which console input was requested. If
- ;via BDOS, a BDOS call is used. If via direct BIOS, a
- ;direct BIOS call is used. This distinction in made
- ;necessary by the one-character input buffer which
- ;BDOS may fill during console output. (Yes output.)
- ;
- R <LDA ITYPE>; Type of input which
- ORA A; was requested.
- R <JZ CKKEY0>
- MVI C,@RDY; Use BDOS if non-zero
- R <CALL GOBDOS>
- ORA A
- RET
- CKKEY0:
- R <CALL CONSTAT>; Use BIOS otherwise
- ORA A
- RET
- ;
- SYSREQ:
- ;The application process has requested a warm-boot
- ;by invoking BDOS function 0. Inquire whether the
- ;spool writer should be terminated. If not, treat
- ;as a normal warm-boot request.
- ;
- LXI SP,CCPIN; Set up a valid stack
- R <LDA ACTIVE>; If not active
- ORA A; then don't ask.
- R <LXI D,DONEMSG>
- R <JZ SYSRQ9>
- R <LXI D,CNCL?>
- MVI C,@MSG
- R <CALL GOBDOS>
- ;
- CPM KEY ;Get reply
- ORI 'a'-'A' ;Force lower case
- CPI 'n' ;Note lower case n.
- JZ BOOT
- CPI 'y' ;Note lower case y.
- JNZ BOOT ;Default = No
- ;
- ; Do a real BDOS function 0 which will terminate
- ; the spool writer.
- R <LXI D,CNCLMSG>
- SYSRQ9:
- MVI C,@MSG ;Inform the operator
- R <CALL GOBDOS>
- ;
- MVI C,@SYS
- R <JMP GOBDOS> ;Reset system
- BOOTREQ:
- ;The application process has requested a reboot
- ;by jumping to location 0. If we are no longer
- ;active, we will honor the request by executing
- ;the address found in the BOOT vector at entry.
- ;Otherwise return to CCP without rebooting.
- LXI SP,CCPIN ;set up a valid stack
- R <LDA ACTIVE>
- ORA A
- R <JNZ NOTYET>
- ;Jump to old boot address as read from memory
- ;word 1 before we changed it.
- R <LXI D,DONEMSG>
- MVI C,@MSG
- R <CALL GOBDOS>
- R <LHLD OLDBOOT>
- PCHL
- ;
- NOTYET LXI H,TBUFF
- R <SHLD DMAHOLD>
- MVI C,@LOG
- R <CALL GOBDOS>
- R <LXI D,ACTMSG>
- MVI C,@MSG
- R <CALL GOBDOS>
- R <LXI H,INTERCEPT>
- R <SHLD BDOSV+1>
- R <LXI H,BDOSV>
- SHLD BDOS+1
- R <LXI H,BOOTREQ>
- R <SHLD BIOSV+1>
- R <LXI H,BIOSV>
- SHLD BOOT+1
- CCPRET:
- JMP ?; Patched on startup
- ;
- ACTMSG: DB CR,LF
- DB 'Unspooling in progress.'
- DB '$'
- DONEMSG:
- DB CR,LF,'UNSPOOL Completed.'
- DB '$'
- CNCL?:
- DB CR,LF,'Do you want to cancel UNSPOOL?'
- DB CR,LF,'{Y|N} ?>'
- DB '$'
- CNCLMSG:
- DB CR,LF,'UNSPOOL Cancelled.'
- DB '$'
- OLDBOOT DW ?
- DMAHOLD DW TBUFF
- ACTIVE DB TRUE
- IF EXPAND
- TABFLAG DB FALSE
- LINEPOS DB 0
- ENDIF ;EXPAND
- IF SIMFF
- FFFLG DB FALSE
- NBLINS DB 0
- ENDIF
- LINCNT DB 0; Linefeed counter
- PAGFLG DB PAGDEF; Paging flag (defaulted to PAGDEF)
- USRHOLD DB ?
- ENTUSR DB ?
- IOBHOLD DB ?
- ENTIOB DB ?
- ITYPE DB ?
- FCB DS FCBLEN
- BUFFER DB ?
- ;
- ONESHOT:
- ; This one-shot code patches the local jump table.
- ;It is then overlayed by the file buffer on the first
- ;read, so it takes up no extra memory.
- R <LXI H,TRAPCON>
- R <SHLD CONIN+1>
- R <LXI H,TRAPWRT>
- R <SHLD WRITE+1>
- R <JMP BOOTREQ>; Start the program.
- ;
- OVERLAY SET $ ;Bit table may start here
- ; Nothing past here but DS's.
- DS 128-$+BUFFER
- DS 32; LOCAL STACK AT LEAST 16 WORDS
- ; PLUS WHATEVER'S LEFT OVER
- ORG ($+0FFH) AND 0FF00H ; Org to next page boundry.
- LCLSTACK:
- ;*************************************************
- ;End of segment to be relocated.
- IF SAVECCP
- PAGES EQU ($-@BASE)/256+8; CCP = 8 pages.
- ELSE
- PAGES EQU ($-@BASE)/256
- ENDIF ;saveccp
- ;
- IF OVERLAY NE FALSE
- ;cause relocation map to slide down into
- ;unused DS area:
- SEGLEN EQU OVERLAY-@BASE
- ORG @BASE+SEGLEN
- ELSE
- ;relocation bit map starts here:
- SEGLEN EQU $-@BASE
- ENDIF ;overlay
- PAGE
- ; Build the relocation information into a
- ; bit map following the code.
- ;
- @X SET 0
- @BITCNT SET 0
- @RLD SET ??R1
- @NXTRLD SET 2
- RTAG %@RLBL+1,0FFFFH ;define one more symbol
- ;
- REPT SEGLEN+8
- IF @BITCNT>@RLD
- NXTRLD %@NXTRLD ;;next value
- ENDIF
- IF @BITCNT=@RLD
- @X SET @X OR 1 ;;set low bit
- ENDIF
- @BITCNT SET @BITCNT + 1
- IF @BITCNT MOD 8 = 0
- DB @X ;;DEFINE THE BYTE
- @X SET 0 ;;clear hold variable for more
- ELSE
- @X SET @X SHL 1 ;;not 8 yet. move over.
- ENDIF
- ENDM
- ;
- END CCPIN
-