home *** CD-ROM | disk | FTP | other *** search
- ;*
- ;* NewChain - Herbert Oppmann 1/93
- ;*
-
- AV EQU 0 ;TP3.00 = 0, TP3.01 = 1
-
- NCCmdLine EXT
- NCStart EXT
- NCLib EXT
- NCSecBuf EXT
-
- InitCharIO EQU 0364h+AV
- ParseAFN EQU 03EEh+AV
- ToUpper EQU 04A6h+AV
- OutOfMem EQU 20A8h+AV
-
- LF EQU 10
- CR EQU 13
- EOF EQU 26
- FCBSize EQU 33
- SecSize EQU 80h
-
- ConString EQU 9
- OpenFile EQU 15
- SetDMA EQU 26
- GetSetUsr EQU 32
- ReadRand EQU 33
-
- WBoot EQU 000h
- CurrDU EQU 004h
- BDOS EQU 005h
- DefaultFCB EQU 05Ch
- CmdLine EQU 080h
- DefaultDMA EQU 080h
- IORes EQU 0D0h
- StandAlone EQU 0D8h
- TPA EQU 0100h
-
- ;E: FilePointer in HL
- NewCh: DEFB 3Eh ;LD A,0AFh - Execute
- XOR A ;- Chain
- LD (Flag),A
- ;allowed?
- LD A,(HL)
- AND 0Fh ;File?
- LD A,20h ;not allowed on a logical device
- JR NZ,NewChEr1
- LD A,(StandAlone)
- AND A
- LD A,21h ;not allowed in direct mode
- JR Z,NewChEr1
- ;calculate address of FCB, s1-Byte
- LD DE,12
- ADD HL,DE ;point to FCB in FIB
- LD (FCBAddress),HL
- LD E,13 ;D=0
- ADD HL,DE ;point to s1 byte
- PUSH HL
- ;look if there is enough space for the overlay
- LD HL,(BDOS+1)
- LD DE,-200
- ADD HL,DE
- LD (ChainFCB),HL
- LD DE,NewChEnd
- AND A
- SBC HL,DE
- JP C,OutOfMem
- ;get current user and save it
- LD A,0FFh
- CALL XUser ;get current user
- LD (OldUser),A
- LD (DefaultA+13),A
- LD (DefaultB+13),A
- ;save s1 byte
- POP HL
- LD A,(HL)
- LD (MyUser),A
- PUSH HL ;save it for case of error
- ;if bit 7 is not set then set user
- BIT 7,A
- CALL Z,XUser
- ;if NCLib =0 then open the file
- LD HL,(NCLib)
- LD A,H ;library option?
- OR L
- JR NZ,NewCh1 ;yes -> don't open file
- FCBAddress DEFL $+1 ;InTheCode variable
- LD DE,0
- LD C,OpenFile
- CALL BDOS
- INC A ;ok?
- JR NZ,NewCh1
- LD A,01h ;file does not exist
-
- NewChEr: ;restore user in s1 byte (for next try) and restore old user
- POP HL ;HL= pointer to s1 byte in FCB
- PUSH AF ;save error code
- MyUser DEFL $+1
- LD (HL),0 ;restore s1 byte
- LD A,(OldUser)
- CALL XUser
- POP AF
- NewChEr1: LD (IORes),A
- RET
-
- ;E: User or 0FFh in A
- ;V: AF, BC, DE, HL
- ;R: - or current user in A
- XUser: LD E,A
- LD C,GetSetUsr
- JP BDOS
-
- NewCh1: ;pointer to s1 byte on stack Stack for case of error
- ;read in first sector and check
- LD DE,NCSecBuf
- LD C,SetDMA
- CALL BDOS
- LD DE,(FCBAddress)
- LD C,ReadRand
- CALL BDOS
- OR A ;ok?
- LD A,99h ;Unexpected end-of-file
- JR NZ,NewChEr
- Flag DEFL $+1 ;InTheCode
- LD A,0
- AND A ;Zero = Chain, NZero = Execute
- JR NZ,NewCh2
- ;Chain: plausibility check, version control
- LD A,0CEh ;Chain/Execute error
- LD HL,(NCSecBuf+0)
- LD DE,0031h ;LD SP,TPA
- SBC HL,DE
- JR NZ,NewChEr
- LD HL,(NCSecBuf+2)
- LD DE,2101h ;LD HL,buffer_address
- SBC HL,DE
- JR NZ,NewChEr
- LD HL,(NCSecBuf+10) ;address of InitCharIO
- LD DE,InitCharIO
- SBC HL,DE ;still NCarry from AND A above
- JR NZ,NewChEr
- JR NewCh3
-
- CheckZ3: LD DE,Z3txt
- LD B,5
- CheckZ4: LD A,(DE)
- CP (HL)
- RET NZ
- INC HL
- INC DE
- DJNZ CheckZ4
- RET
- Z3txt: DEFB 'Z3ENV'
-
- NewCh2: ;Execute: if (my program is a Z3 program and) the called program
- ;is a Z3 program, and we are running ZCPR, then see that the
- ;overlay sets EnvPtr
- LD HL,TPA+3
- CALL CheckZ3
- JR NZ,NewCh3
- ;supply address of Z3Env as a parameter to the program.
- ;ZCPR does this, and some programs expect this!
- LD HL,(TPA+9)
- LD (Z3Adr),HL
- LD HL,NCSecBuf+3
- CALL CheckZ3
- JR NZ,NewCh3
- LD HL,(TPA+9)
- LD A,H
- OR L
- JR Z,NewCh3
- LD A,H
- LD (EnvPtrH),A
- LD A,L
- LD (EnvPtrL),A
- LD A,1
- LD (SetEP+Over),A
- NewCh3: ;!! from now on, there is no way back, because vital parts of the
- ;!! Turbo Pascal program are overwritten now
- ;build commando line
- XOR A
- LD (CmdLine),A ;empty
- LD HL,NCCmdLine
- LD A,7Eh ;max. length
- CP (HL)
- JR C,NewCh4
- LD A,(HL)
- NewCh4: ;length in A
- INC HL ;to first char
- EX DE,HL ;save pointer in DE
- LD L,A ;point to end
- LD H,0
- ADD HL,DE
- LD (HL),EOF ;terminate string
- ;build (copy) command line
- CALL SkipBlanks ;empty string?
- JR Z,NewCh7 ;yes -> finish parsing
- PUSH DE
- LD HL,CmdLine+1
- LD (HL),' '
- INC HL
- LD B,1
- NewCh5: LD A,(DE)
- CP EOF
- JR Z,NewCh6
- CALL ToUpper ;convert to uppercase
- LD (HL),A
- INC DE
- INC HL
- INC B
- JR NewCh5
-
- NewCh6: LD (HL),H ;=0 terminate
- LD A,B ;length
- LD (CmdLine),A
- POP DE
- ;set DefaultFCB
- CALL MyParseAFN
- PUSH DE
- LD DE,DefaultA
- LDIR
- POP DE
- CALL SkipBlanks ;now empty?
- JR Z,NewCh7 ;yes -> finish parsing
- CALL MyParseAFN
- LD DE,DefaultB
- LDIR
- NewCh7: LD DE,DefaultFCB
- LD HL,DefaultA
- LD BC,32
- LDIR
- ;prepare overlay (OldUser is already set)
- LD HL,(ChainFCB)
- LD SP,HL
- EX DE,HL ;save pointer to FCB
- LD HL,0-SecSize ;InLass can't handle -SecSize properly..
- ADD HL,DE
- LD (MaxMem),HL
- LD HL,33 ;random record position
- ADD HL,DE
- LD (RRPos),HL
- LD HL,(FCBAddress)
- LD BC,36 ;copy FCB
- LDIR
- PUSH DE ;start address overlay
- LD HL,Msg
- ADD HL,DE
- LD (Message),HL
- LD HL,SetEP
- ADD HL,DE
- LD (SetEnvPtr),HL
- LD HL,Fill
- ADD HL,DE
- LD (FillEnd),HL
- LD A,(Flag)
- AND A
- LD HL,TPA ;Chain is always startet at TPA
- JR Z,NewCh8
- LD HL,(NCStart) ;Execute may be started elsewhere
- NewCh8: LD (StartAdr),HL
- LD HL,Over
- LD BC,OverLen
- LDIR
- ;now we have Zero if Chain/NZero else
- ;own address to HL, load address to DE, length to BC,
- ;(all other data are constants while the overlay is running
- ;and are thus stored in the code).
- LD BC,(NCLib) ;length in sectors
- LD DE,(TPA+1) ;Chain is always loaded there
- RET Z
- LD DE,(NCStart) ;Execute may get loaded elsewhere.
- RET ;Via this mechanism CIMs can be run too
-
- SkipBlanks: LD A,(DE)
- CP EOF
- RET Z
- CP ' '
- RET NZ
- INC DE
- JR SkipBlanks
-
- DefaultA: DEFB 0,' ',0,0,0,0
- DefaultB: DEFB 0,' ',0,0,0,0
-
- MyParseAFN: CALL ParseAFN
- LD HL,DefaultFCB
- LD BC,16
- LD A,(DefaultFCB+13)
- INC A
- RET NZ
- LD C,12 ;User lassen
- RET
-
- ;E: NCarry, load address in DE, length in sectors in BC (0 means whole file)
- Over: ;load
- MaxMem DEFL $+1
- LD HL,0
- SBC HL,DE
- JR NC,Over05
- Message DEFL $+1
- LD DE,0
- LD C,ConString
- CALL BDOS
- JP WBoot
- Msg EQU $-Over
- DEFB 'Out of memory',CR,LF,'$'
- Over05: PUSH BC
- PUSH DE
- LD C,SetDMA
- CALL BDOS
- ChainFCB DEFL $+1
- LD DE,0
- LD C,ReadRand
- CALL BDOS
- POP DE
- POP BC
- OR A ;ok?
- JR NZ,Over15
- SetEP EQU $+1-Over
- LD A,0
- AND A
- JR Z,Over08
- XOR A
- SetEnvPtr DEFL $+1
- LD (0),A
- LD HL,9
- ADD HL,DE
- EnvPtrL DEFL $+1
- LD (HL),0
- INC HL
- EnvPtrH DEFL $+1
- LD (HL),0
- ;Bump random record count, DMA, length
- RRPos DEFL $+1
- Over08: LD HL,0
- INC (HL)
- JR NZ,Over10
- INC HL
- INC (HL)
- Over10: LD HL,SecSize
- ADD HL,DE
- EX DE,HL
- DEC BC
- LD A,B ;at end?
- OR C
- JR NZ,Over ;no -> continue
- Over15: ;set DMA and user
- PUSH DE ;points behind loaded code
- LD DE,DefaultDMA
- LD C,SetDMA
- CALL BDOS
- OldUser DEFL $+1
- LD E,0
- LD C,GetSetUsr
- CALL BDOS
- POP DE
- ;clear and start program
- FillEnd DEFL $+1
- LD HL,0
- AND A
- SBC HL,DE
- EX DE,HL
- LD B,0FFh
- Fill EQU $-Over
- Over20: LD (HL),B
- INC HL
- DEC DE
- LD A,D
- OR E
- JR NZ,Over20
- Z3Adr DEFL $+1
- LD HL,0
- StartAdr DEFL $+1
- JP 0
- OverLen EQU $-Over
-
- NewChEnd:
- END