mirror of
https://github.com/SEPPDROID/Digital-Research-Source-Code.git
synced 2025-10-24 08:54:17 +00:00
487 lines
10 KiB
NASM
487 lines
10 KiB
NASM
$title('GETF - CP/M 3.0 Input Redirection - August 1982')
|
|
name getf
|
|
;******************************************************************
|
|
;
|
|
; get 'Input Redirection Initializer' version 3.0
|
|
;
|
|
; 11/30/82 - Doug Huskey
|
|
;******************************************************************
|
|
;
|
|
;
|
|
; Copyright (c) 1982
|
|
; Digital Research
|
|
; P.O. Box 579
|
|
; Pacific Grove, Ca.
|
|
; 93950
|
|
;
|
|
;
|
|
; generation procedure
|
|
;
|
|
; seteof get.plm
|
|
; seteof getscan.dcl
|
|
; seteof getf.asm
|
|
; seteof getscan.plm
|
|
; seteof parse.asm
|
|
; is14
|
|
; asm80 getf.asm debug
|
|
; asm80 mcd80a.asm debug
|
|
; asm80 parse.asm debug
|
|
; plm80 get.plm pagewidth(100) debug optimize
|
|
; link mcd80a.obj,get.obj,parse.obj,getf.obj,plm80.lib to get.mod
|
|
; locate get.mod code(0100H) stacksize(100)
|
|
; era get.mod
|
|
; cpm
|
|
; objcpm get
|
|
; rmac getrsx
|
|
; link getrsx[op]
|
|
; era get.rsx
|
|
; ren get.rsx=getrsx.prl
|
|
; gencom get.com
|
|
; gencom get.com get.rsx
|
|
;
|
|
;
|
|
;
|
|
; This module is called as an external routine by the
|
|
; PL/M routines GET and SUBMIT. It is passed a structure
|
|
; with the following format:
|
|
;
|
|
;
|
|
; declare getpb structure
|
|
; (input$type byte,
|
|
; echo$flag byte,
|
|
; filtered$flag byte,
|
|
; program$flag byte);
|
|
;
|
|
; input$type = 0 > console input (default)
|
|
; = 1 > auxiliary output
|
|
;
|
|
; echo = true > echo input to real device
|
|
; (default)
|
|
; = false > don't echo input (output is
|
|
; still echoed)
|
|
; filtered = true > convert control characters
|
|
; to a printable form
|
|
; preceeded by an ^ in echo
|
|
; (default)
|
|
; = false > no character conversions
|
|
; program = false > continue until EOF or
|
|
; GET INPUT FROM CONSOLE
|
|
; command
|
|
; = true > active only until program
|
|
; termination
|
|
;
|
|
public getf
|
|
extrn mon1,fcb,memsiz
|
|
;
|
|
;
|
|
true equ 0ffffh
|
|
false equ 00000h
|
|
;
|
|
biosfunctions equ true ;intercept BIOS conin & constat
|
|
;
|
|
;
|
|
; low memory locations
|
|
;
|
|
wboot equ 0000h
|
|
wboota equ wboot+1
|
|
;
|
|
; equates for non graphic characters
|
|
;
|
|
cr equ 0dh ; carriage return
|
|
lf equ 0ah ; line feed
|
|
;
|
|
; BDOS function equates
|
|
;
|
|
cinf equ 1 ;read character
|
|
coutf equ 2 ;output character
|
|
crawf equ 6 ;raw console I/O
|
|
creadf equ 10 ;read buffer
|
|
cstatf equ 11 ;status
|
|
pchrf equ 5 ;print character
|
|
pbuff equ 9 ;print buffer
|
|
openf equ 15 ;open file
|
|
closef equ 16 ;close file
|
|
delf equ 19 ;delete file
|
|
dreadf equ 20 ;disk read
|
|
dmaf equ 26 ;set dma function
|
|
curdrv equ 25
|
|
userf equ 32 ;set/get user number
|
|
scbf equ 49 ;set/get system control block word
|
|
rsxf equ 60 ;RSX function call
|
|
initf equ 128 ;GET initialization sub-function no.
|
|
killf equ 129 ;GET delete sub-function no.
|
|
jkillf equ 141 ;JOURNAL delete sub-function no.
|
|
;
|
|
; System Control Block definitions
|
|
;
|
|
scba equ 03ah ;offset of scbadr from SCB base
|
|
ccpflg2 equ 0b4h ;offset of 2nd ccp flag byte from pg bound
|
|
errflg equ 0aah ;offset of error flag from page boundary
|
|
conmode equ 0cfh ;offset of console mode from page boundary
|
|
listcp equ 0d4h ;offset of ^P flag from page boundary
|
|
common equ 0f9h ;offset of common memory base from pg. bound
|
|
wbootfx equ 068h ;offset of warm boot jmp from page. bound
|
|
constfx equ 06eh ;offset of constat jmp from page. bound
|
|
coninfx equ 074h ;offset of conin jmp from page. bound
|
|
conoufx equ 07ah ;offset of conout jmp from page. bound
|
|
listfx equ 080h ;offset of list jmp from page. bound
|
|
realdos equ 098h ;offset of real BDOS entry from pg. bound
|
|
;
|
|
; Restore mode equates (used with inr a, rz, rm, rpe, ret)
|
|
;
|
|
norestore equ 0ffh ;no BIOS interception
|
|
biosonly equ 07fh ;restore BIOS jump table only
|
|
stfix equ 080h ;restore BIOS jump table and
|
|
;restore JMP in RESBDOS for constat
|
|
everything equ 0 ;restore BIOS jump table and jmps in
|
|
;RESBDOS (default mode)
|
|
;
|
|
; Instructions
|
|
;
|
|
lxih equ 21h ;LXI H, instruction
|
|
jmpi equ 0c3h ;JMP instruction
|
|
shldi equ 22h ;SHLD instruction
|
|
;
|
|
;******************************************************************
|
|
; START OF INITIALIZATION CODE
|
|
;******************************************************************
|
|
|
|
cseg
|
|
|
|
getf:
|
|
;get parameters
|
|
mov h,b
|
|
mov l,c ;HL = .(parameter block)
|
|
mov a,m ;input type 0=con:,1=aux:
|
|
cpi 1 ;is it aux?
|
|
jz notimp ;error if so
|
|
inx h
|
|
mov a,m ;echo/noecho mode
|
|
sta echo
|
|
inx h
|
|
mov a,m ;cooked/raw mode
|
|
sta cooked
|
|
inx h
|
|
mov a,m
|
|
sta program
|
|
;
|
|
;check if enough memory
|
|
;
|
|
lhld memsiz
|
|
mov a,h
|
|
cpi 20h
|
|
jc nomem
|
|
;
|
|
;close to get those blocks in the directory
|
|
;
|
|
lxi d,fcb
|
|
mvi c,closef
|
|
call mon1
|
|
;
|
|
;check if drive specified
|
|
lxi h,fcb
|
|
mov a,m ;drive code
|
|
ora a ;default?
|
|
jnz movfcb
|
|
;
|
|
;set to current drive, if not
|
|
;
|
|
push h ;save .fcb
|
|
mvi c,curdrv
|
|
call mon1
|
|
pop h ;a=current drive, hl=.fcb
|
|
inr a
|
|
mov m,a ;set fcb to force drive select
|
|
;
|
|
movfcb: ;copy default fcb up into data area for move to RSX
|
|
;
|
|
lxi d,subfcb
|
|
lxi b,32 ;length of fcb
|
|
call ldir ;move it to subfcb
|
|
;
|
|
;initialize other variables to be moved to RSX
|
|
;
|
|
call getusr ;get current user number
|
|
sta subusr ;save for redirection file I/O
|
|
call getscbadr
|
|
shld scbadr ;System Control Block address
|
|
;
|
|
;get real BDOS address (bypass chain to check for user break)
|
|
;
|
|
mvi l,realdos
|
|
mov e,m
|
|
inx h
|
|
mov d,m
|
|
xchg
|
|
shld realbdos+1
|
|
;
|
|
;check for user abort
|
|
;
|
|
xchg
|
|
mvi l,conmode
|
|
mov a,m
|
|
ori 1 ;set ^C status mode
|
|
mov m,a
|
|
mvi c,cstatf
|
|
call realbdos ;check for user abort
|
|
ora a
|
|
jnz error1 ;abort if so
|
|
;
|
|
;get address of initialization table in RSX
|
|
;
|
|
mvi c,rsxf
|
|
lxi d,journkill
|
|
call mon1 ;terminate any PUT INPUT commands
|
|
mvi c,rsxf
|
|
lxi d,rsxinit
|
|
call mon1 ;call GET.RSX initialization routine
|
|
push h ;save for move at end of setup
|
|
mov e,m
|
|
inx h
|
|
mov d,m ;DE = .RSXKILL flag
|
|
push d ;set flag to zero if successfull
|
|
inx h ;HL = .(real bios status routine)
|
|
push h
|
|
;
|
|
if biosfunctions
|
|
;
|
|
;check if BIOS jump table looks valid (jmp in right places)
|
|
lhld wboota
|
|
lxi d,3
|
|
dad d ;HL = .(jmp constat address)
|
|
mov a,m
|
|
cpi jmpi ;should be a jump
|
|
jnz bioserr ;skip bios redirection if not
|
|
dad d ;HL = .(jmp conin address)
|
|
mov a,m
|
|
cpi jmpi
|
|
jnz bioserr ;skip bios redirection if not
|
|
;
|
|
;fix up RESBDOS to do BIOS calls to intercepted functions
|
|
;
|
|
lhld scbadr
|
|
mvi l,common+1
|
|
mov a,m ;get high byte of common base
|
|
ora a
|
|
jnz fix0 ;high byte = zero if non-banked
|
|
mvi a,biosonly
|
|
sta biosmode
|
|
jmp trap ;skip code that fixes resbdos
|
|
;fix BIOS constat
|
|
fix0: mvi l,constfx ;hl = .constfx in SCB
|
|
mov a,m
|
|
cpi jmpi ;is it a jump instruction?
|
|
jz fix1 ;jump if so
|
|
mvi a,biosonly ;whoops already changed
|
|
sta biosmode ;restore jump table only
|
|
fix1: mvi m,lxih
|
|
;fix BIOS conin
|
|
mvi l,coninfx ;hl = .coninfx in SCB
|
|
mov a,m
|
|
cpi jmpi ;is it a jump instruction?
|
|
lda biosmode
|
|
jz fix2 ;jump if so
|
|
cpi biosonly
|
|
jnz bioserr ;error if conin is LXI but not constat
|
|
xra a ;zero accumulator to jnz below
|
|
fix2: cpi biosonly ;was const already an LXI h?
|
|
jnz fix3 ;jmp if not
|
|
mvi a,stfix ;restore constat jmp but not conin
|
|
sta biosmode
|
|
fix3: mvi m,lxih
|
|
;get addresses of RSX const and conin traps
|
|
trap: pop h
|
|
mov c,m ;HL = .(.bios constat trap)
|
|
inx h
|
|
mov b,m ;BC = .bios constat trap in RSX
|
|
inx h
|
|
push h ;save for CONIN setup
|
|
;
|
|
;patch RSX constat entry into BIOS jump table
|
|
;save real constat address in RSX exit table
|
|
;
|
|
lhld wboota
|
|
lxi d,4
|
|
dad d ;HL = .(jmp constat address)
|
|
shld constjmp ;save for RSX restore at end
|
|
mov e,m
|
|
mov m,c
|
|
inx h
|
|
mov d,m ;DE = constat address
|
|
mov m,b ;BIOS constat jumps to RSX
|
|
xchg
|
|
shld biosta ;save real constat address
|
|
;
|
|
;get address of RSX bios conin entry point
|
|
;
|
|
pop h ;HL = .(RSX BIOS conin trap)
|
|
mov c,m
|
|
inx h
|
|
mov b,m
|
|
;
|
|
;patch RSX conin entry into BIOS jump table
|
|
;save real conin address in RSX exit table
|
|
;
|
|
xchg
|
|
inx h ;past jmp instruction
|
|
inx h ;HL = .(conin address)
|
|
shld coninjmp
|
|
mov e,m
|
|
mov m,c
|
|
inx h
|
|
mov d,m ;DE = conin address
|
|
mov m,b ;BIOS conin jumps to RSX
|
|
xchg
|
|
shld biosin ;save real conin address
|
|
endif
|
|
;
|
|
;move data area to RSX
|
|
;
|
|
rsxmov:
|
|
pop h ;HL = .Kill flag in RSX
|
|
inr m ;switch from FF to 0
|
|
lxi h,movstart
|
|
pop d ;RSX data area address
|
|
lxi b,movend-movstart
|
|
call ldir
|
|
mvi c,crawf
|
|
mvi e,0fdh ;raw console input
|
|
call mon1 ;prime RSX by reading a char
|
|
jmp wboot
|
|
|
|
if biosfunctions
|
|
;
|
|
; can't do BIOS redirection
|
|
;
|
|
bioserr:
|
|
lxi d,nobios
|
|
mvi c,pbuff
|
|
call mon1
|
|
lxi h,biosmode
|
|
mvi m,norestore ;no bios redirection
|
|
pop h ;throw away bios constat trap adr
|
|
jmp rsxmov
|
|
endif
|
|
;
|
|
; auxiliary redirection
|
|
;
|
|
notimp:
|
|
lxi d,notdone
|
|
error:
|
|
mvi c,pbuff
|
|
call mon1
|
|
error1: mvi c,closef
|
|
lxi d,fcb
|
|
call mon1
|
|
mvi c,delf
|
|
lxi d,fcb
|
|
call mon1
|
|
jmp wboot
|
|
;
|
|
; insufficient memory
|
|
;
|
|
nomem: lxi d,memerr
|
|
jmp error
|
|
|
|
;
|
|
; get/set user number
|
|
;
|
|
getusr: mvi a,0ffh ;get current user number
|
|
setusr: mov e,a ;set current user number (in A)
|
|
mvi c,userf
|
|
jmp mon1
|
|
;
|
|
; get system control block address
|
|
; (BDOS function #49)
|
|
;
|
|
; exit: hl = system control block address
|
|
;
|
|
getscbadr:
|
|
mvi c,scbf
|
|
lxi d,data49
|
|
jmp mon1
|
|
;
|
|
data49: db scba,0 ;data structure for getscbadd
|
|
;
|
|
; copy memory bytes (emulates z80 ldir instruction)
|
|
;
|
|
ldir: mov a,m ;get byte
|
|
stax d ;store it at destination
|
|
inx h ;advance pointers
|
|
inx d
|
|
dcx b ;decrement byte count
|
|
mov a,c ;loop if non-zero
|
|
ora b
|
|
jnz ldir
|
|
ret
|
|
;
|
|
;******************************************************************
|
|
; DATA AREA
|
|
;******************************************************************
|
|
|
|
;
|
|
journkill: db jkillf
|
|
rsxinit: db initf
|
|
nobios: db 'WARNING: Cannot redirect from BIOS',cr,lf,'$'
|
|
notdone:
|
|
db 'ERROR: Auxiliary device redirection not implemented',cr,lf,'$'
|
|
memerr:
|
|
db 'ERROR: Insufficient Memory',cr,lf,'$'
|
|
;
|
|
;******************************************************************
|
|
; Following variables are initialized by GET.COM
|
|
; and moved to the GET RSX - Their order must not be changed
|
|
;******************************************************************
|
|
;
|
|
;
|
|
;
|
|
movstart:
|
|
inittable: ;addresses used by GET.COM for
|
|
scbadr: dw 0 ;address of System Control Block
|
|
;
|
|
if biosfunctions ;GET.RSX initialization
|
|
;
|
|
biosta: dw 0 ;set to real BIOS routine
|
|
biosin: dw 0 ;set to real BIOS routine
|
|
;
|
|
;restore only if changed when removed.
|
|
biosmode:
|
|
db 0 ;if non-zero change LXI @jmpadr to JMP
|
|
;when removed.
|
|
restorebios:
|
|
;hl = real constat routine
|
|
;de = real conin routine
|
|
db shldi
|
|
constjmp:
|
|
dw 0 ;address of const jmp initialized by COM
|
|
xchg
|
|
db shldi
|
|
coninjmp:
|
|
dw 0 ;address of conin jmp initialized by COM
|
|
ret
|
|
endif
|
|
;
|
|
realbdos:
|
|
jmp 0 ;address filled in by COM
|
|
;
|
|
echo: db 1
|
|
cooked: db 0
|
|
;
|
|
program:
|
|
db 0 ;true if only program input
|
|
subusr: db 0 ;user number for redirection file
|
|
subfcb: db 1 ;a:
|
|
db 'SYSIN '
|
|
db 'SUB'
|
|
db 0,0
|
|
submod: db 0
|
|
subrc: db 0
|
|
ds 16 ;map
|
|
subcr: db 0
|
|
;
|
|
movend:
|
|
;*******************************************************************
|
|
end
|
|
EOF
|
|
|