home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.barnyard.co.uk
/
2015.02.ftp.barnyard.co.uk.tar
/
ftp.barnyard.co.uk
/
cpm
/
walnut-creek-CDROM
/
OSBORNE
/
OXSDUMP.LBR
/
DUMPRSX.AQM
/
DUMPRSX.ASM
Wrap
Assembly Source File
|
2000-06-30
|
6KB
|
235 lines
; OSBORNE EXECUTIVE - Screen Dump Utility
;
; - written Dec'84 by Mark Steinbrecher
; (with help from Dave Mabry)
;
; This is an RSX to print the screen on an Osborne Executive
rsx equ 60 ; BDOS RSX function call
cr equ 0dh ; ASCII carriage return character
lf equ 0ah ; ASCII line feed character
freeram equ 0fb20h ; Address of unused common memory
; for new conin
serial:
ds 6 ; Initialized by loader
start:
jmp begin ; Start of RSX code
next:
db 0c3h ; Jump instruction
ds 2 ; Initialized by loader
prev:
ds 2 ; Initialized by loader
remove:
db 0 ; Don't remove
nonbank:
db 0 ; Load in all systems
db 'dump ' ; Name field
loader:
ds 1 ; Loader flag
ds 2 ; Reserved
; Here starts the code that is executed by a call to BDOS with
; RSX function number in C.
begin:
mov a,c ; Get BDOS function number
cpi rsx ; Is it for an RSX ?
jnz next ; No, pass it on
ldax d ; Get RSX function number
cpi 53 ; Is it for this RSX ?
jnz next ; No, pass it on
; Must save calling program's stack and use our owm
lxi h,0
dad sp
shld stack
lxi sp,stack
; Does calling program want us to remove ourself ?
mov h,d
mov l,e ;HL point to rsxpb
inx h
inx h ;Point to param1
mov a,m ;Fetch it
ora a ;Nonzero means remove
jz beg05 ;Zero means initialize
call next ;In case there is another DUMP RSX
jmp die ;Suicide
; Check to see if we are the only DUMP RSX in memory
beg05:
call next ;As if we are calling DUMP
ora a ;Returns zero if there is another
jz die05 ;Suicide if another exists
xchg ;HL point to RSX parameter block
inx h
inx h ;Point to parameter 1
mov a,m ;Get low byte
ora a ;Check for zero
jnz die ;If not binary 0, then suicide
inx h ;Point to trigger passed in
mov a,m
sta trigger
; At this point, we have to initialize the RSX code to intercept
; all console input calls.
; But only if we haven't done it before.
lda modified
ora a
jnz return ;Bypass vector modification if done
lhld 1 ;Get warm boot vector
lxi d,7
dad d ;Point to console in vector address
shld conin$adr ;Save for die also
push h ;save temporarily
mov a,m ;get low byte of conin vector address
inx h ;point to high byte
mov h,m ;get high byte of conin vector address
mov l,a ;hl reg now has conin address
shld old$conin ;store locally
call patch ;move patch code into unused BIOS ram
lxi d,freeram ;new console address to DE
pop h ;again point to conin vector in BIOS
mov m,e ;move low byte of unused BIOS ram address
inx h ;point to high byte of vector
mov m,d ;conin in vector is now patched !
; Now get the list out routine address in case application program
; modifies location 1 (warm boot vector). SuperCalc does this
; and maybe others.
lhld 1 ;Address of BIOS jump table
lxi d,13 ;Offset to address of list output
dad d
mov a,m ;Low byte of list out address
inx h
mov h,m ;High byte
mov l,a
shld l$out ;save address
; Indicate that the console in has been modified.
mvi a,0ffh ;Set modified flag
sta modified
return:
lhld stack ;get old stack address
sphl ;restore
mvi a,0 ;Indicate success
ret ;rsx initialization complete
die:
lda modified ;Have we modified the BIOS jump table ?
ora a
jz die05 ;No, then just die
lhld old$conin ;Get original address of CONIN
xchg ; to DE
lhld conin$adr ;Point to address field in jump table
mov m,e ;Restore original jump address
inx h
mov m,d
die05:
mvi a,0ffh ;True flag
sta remove ;Flag removal at next warm boot
jmp return
patch:
mvi b,length ;setup loop counter
lxi h,freeram ;setup address pointer for relocated code
lxi d,st$code ;setup address pointer for local code
loop: ldax d
mov m,a
inx h
inx d
dcr b
jnz loop
ret
;
; The code that follows is relocated to address <freeram> in common
; memory by <patch:>. Address <freeram> is patched into the conin
; vector in the BIOS jump table so that all further console inputs
; pass through this routine.
st$code:
in 0 ;get current bank
push psw ;save temporarily
mvi a,41h ;setup bank 1 (TPA bank)
out 0 ;enable TPA
call new$conin ;vector to console input patch
mov b,a ;move console char. to B temporarily
pop psw ;get old bank back
out 0 ;enable old bank
mov a,b ;put console char. back in A
ret ;ret with console character in A
;
length equ $-st$code
;
old:
lhld old$conin
pchl
;
new$conin:
push h
lxi h,0 ;Use a local stack
dad sp
shld stack
lxi sp,stack
call old ;Go get character
push psw ;Save status
lxi h,trigger ;Compare with the trigger character
cmp m ;Is it the same ?
cz doit ;Go dump screen if yes
pop psw ;Else pass it by
lhld stack
sphl
pop h
ret
doit:
lxi h,0c000h ;point to start of screen ram
lxi b,5018h ;set up row and column counters
next$row:
push b ;save row and column counts
next$col:
mov a,m ;get next char. from screen
ani 7fh ;strip attribute bit
cpi 20h ;check for valid ASCII character
cm bad
mov c,a
push h ;save pointer
push b
call list$out ;print character
pop b
pop h
inx h ;point to next character
dcr b ;decrement column counter
jnz next$col ;if not zero continue
mvi c,lf ;row finished so print a crlf
push h
call list$out
mvi c,cr
call list$out
pop h ;recall screen ram pointer
pop b ;recall row count & reset col. counter
dcr c ;decrement row counter
rz ;if row count=0, we're done
lxi d,30h ;row to row address offset
dad d ;not done so point to next row
jmp next$row
;
bad:
mvi a,20h ;replace nonprintable char. with space
ret
;
list$out:
lhld l$out ;Get address of list out routine
pchl ;Go do it
modified:
db 0 ;True -> BIOS jump table modified
trigger:
ds 1 ;Place to store trigger character
l$out:
ds 2 ;Place to store address of list out
old$conin:
ds 2 ;Place to store address of old conin
conin$adr:
ds 2 ;Place to store address of jump vector
; of CONIN in BIOS jump table
ds 30
stack:
ds 2 ;Place to save original stack
end