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
/
CPM
/
PROGRAMS
/
WSTAR
/
WSLOAD.LBR
/
WSLOAD.AQM
/
WSLOAD.ASM
Wrap
Assembly Source File
|
2000-06-30
|
13KB
|
625 lines
; WSLOAD ------------------------ A WordStar Utility
;
; This utility is described fully in WSLOAD.DOC within the library.
; The source code here is included in the event that you need to reset
; the OFFSET variable to a higher address. The code below will
; assemble correctly with either MicroSoft's M80 or with the fine
; public domain assmebler Z80MR. If you have problems or need special
; assistance, I will be glad to do what I can. Please send a SAS
; envelope and/or disk.
;
; Lindsay Haisley
; 14206 Spreading Oaks
; Leander, TX 78641
;
;
; **** THE OFFSET VARIABLE:
; --------------------------
;
; The offset variable below is the address of the end of your current
; version of WordStar. The is usually 4600 hex but if the area beyond
; this address is already in use for an initialization routine, you must
; find an area of free memory above this routine for WSLOAD to use.
;
; WSLOAD will give you a "MORPAT OVERLAY" error if an init routine
; already occupies the area above the current value of the offset. You
; must use DDT, Z8E, ZSID or some similar utility to find a string of
; null or unused bytes above the offset address and reset "offset" to
; the address of this string. You may need to load WordStar and SAVE a
; page or two more than the usual 70. Make sure you have 200 bytes of
; free space available for WSLOAD to occupy.
offset equ 4600h
; -----------------------------------------------------------------------
aseg
.z80 ; IGNORE THIS ERROR WITH Z80MR
; WordStar user patch area equates
inisub equ 0287h
morpat equ 02CBh
fnwscm equ 0400h
loadpt equ 1100h ; Address of WordStar in memory for this prog.
loadref equ loadpt-100h
; CODE STARTS HERE
org 100h
jp ustart
fcb1: defb 0,20h,20h,20h,20h,20h,20h,20h,20h,20h,20h,20h,0,0,0,0
defb 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
fcb2: defb 0,20h,20h,20h,20h,20h,20h,20h,20h,20h,20h,20h,0,0,0,0
defb 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
fcb3: defb 0,20h,20h,20h,20h,20h,20h,20h,20h,20h,20h,20h,0,0,0,0
defb 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
cflag: defb '+'
defb 0
fnbuf: defb 0,0,0,0,0,0,0,0,0,0,0,0,0,0
endbuf: defb 0
getmsg: defb 0dh,0ah,'Enter the filename of your version of WordStar => ',0
outmsg: defb 0dh,0ah,'Enter the name you want for WordStar with WSLOAD'
defb ' installed => ',0
csmsg1: defb 0dh,0ah,'Enter the character you want to preceed overlay '
defb 'filenames => ',0
csmsg2: defb 0dh,0ah,0ah,'All configuration overlays (except '
defb 'the default) must start with '''
defb 0
csmsg3: defb '''',0dh,0ah,0
e1msg: defb 0dh,0ah,'File ',0
e2msg: defb ' not found',0dh,0ah,0
dnmsg: defb 0dh,0ah,'Modified WordStar written to disk as ',0
mpemsg: defb 0dh,0ah,'MORPAT ERROR - Reset patch location',0dh,0ah,0
cremsg: defb 0dh,0ah,'Out of directory space. Can''t create output file.'
defb 0dh,0ah,0
wremsg: defb 0dh,0ah,'Disk full. Operation aborted.',0dh,0ah,0
defmsg: defb 0dh,0ah,'Enter the default configuration filename => ',0
bktxt: defb 08h,20h,08h,0
nline: defb 0dh,0ah,0
; PROGRAM STARTS HERE
ustart: ld de,getmsg ; Ask for filename
call zprt
call getname
cp 03h
jp z,0000
ld a,(fnbuf)
or a
ret z ; Return to system if none given
ld hl,fcb1
call xfer
ld c,0fh ; Now open the file, if possible
ld de,fcb1
call 5
inc a
jr nz,ffound
ld de,e1msg ; If no find, report and quit
call zprt
ld de,fcb1
call fnshow
ld de,e2msg
call zprt
ret ; No Wordstar, no work !! (I quit!)
ffound: ld hl,fcb1 ; Save open fcb for output if necessary
ld de,fcb3
ld bc,24h
ldir
ld de,loadpt ; Read the input file to memory
call readfile
push hl ; Save size of file
ld de,outmsg ; Get name of output file
call zprt
call getname
cp 03h
jp z,0000
ld hl,fcb2
call xfer
ld de,fcb1 ; Is input same as output
ld hl,fcb2
call namecmp
jr z,same
ld a,(fcb2+1) ; Or is no filename specified
cp 20h
jr nz,notsme
same: ld hl,fcb3 ; Restore FCB opened for input to output FCB
ld de,fcb2
ld bc,24h
ldir
jr creok
notsme: ld c,13h ; Erase any file of similar name
ld de,fcb2
call 5
ld c,16h ; Create the file
ld de,fcb2
call 5
inc a
jr nz,creok ; If directory full, say so and quit
pop de
ld de,cremsg
call zprt
ret
creok: ld de,defmsg ; Get the default config. filename
call zprt
call getname
cp 03h
jp z,0000
ld hl,dnme
call xfer
getflg: ld de,csmsg1 ; Get the flag character
call zprt
ld c,01
call 5
call upcase
cp 0dh
jr z,ffdef ; If none given, use default
cp 21h ; Don't accept control characters
jr nc,ffok
call bell
jp getflg
ffok: ld (cflag),a ; Tell about the flag
ffdef: ld de,csmsg2
call zprt
ld de,cflag
call zprt
ld de,csmsg3
call zprt
; ACTUAL MODS TO WORDSTAR START HERE
ld a,(inisub+loadref)
cp 0c3h ; See if JP instruction in INISUB
jr nz,okini
ld hl,(inisub+loadref+1) ; If so, see where it JP's to
and a
ld de,offset
sbc hl,de
jp c,morpok
ld de,mpemsg
call zprt
pop de
ret ; If inisub too hi, quit
okini: ld a,0c3h ; Put a JP in inisub
ld (inisub+loadref),a
ld a,0c9h ; RETurn instruction instead of a JP to MORPAT
ld (retins),a ;
morpok: add hl,de
ld de,offset
ld (inisub+loadref+1),de ; Set up a patch and return situation
ld (retad),hl
ld a,(cflag) ; Enter the flag character into the overlay
ld (f1+1),a
ld (f2+1),a
ld hl,fcb2 ; Save the filename for later use by WordStar
ld de,nme
ld bc,12
ldir
; Now move the working code into WordStar image
ld hl,patstrt
ld de,loadref+offset
ld bc,patend-patstrt
ldir
; Now write the image back to a file
ld de,loadpt
pop bc
call writfile ; Write the file
jr z,alldn
ld de,fcb2
ld c,13h
call 5
ld de,wremsg ; If error, say so
call zprt
ret
; All done, so say so and quit
alldn: ld de,dnmsg
call zprt
ld de,fcb2
call fnshow
ld de,nline
call zprt
ret
; ++++++++++++++++++++++++ SUBROUTINES ++++++++++++++++++++++++++
getname: ; Get a valid CP/M filename to fnbuf
xor a ; Zero fnbuf
ld hl,fnbuf
ld de,fnbuf+1
ld (hl),a
ld bc,11
ldir
ld hl,fnbuf
fnloop: ld de,06 ; Use BIOS to fetch character
call ubios
cp 03h
ret z
cp 0dh ; Check for CR to mark end of string
jr nz,morget
ld (hl),0
ld de,nline ; If end, go on
call zprt
ret
morget: call upcase ; Convert to Upper case, if approp.
jr c,okchar ; If conversion done, character must be OK
cp 7fh ; Is it a DEL
jr z,bsordl
cp 08h ; Or is it a BS
jr nz,notbs
bsordl: ld de,fnbuf ; Ignore if start of buffer
and a
push hl
sbc hl,de
pop hl
jr z,fnloop
dec hl
ld de,bktxt
push hl
call zprt
pop hl
jr fnloop
notbs: cp 21h ; Don't accept other control characters
jr c,fnloop
okchar: ld de,endbuf ; Check to see if end of buffer reached
and a
push hl
sbc hl,de
pop hl
jr c,sizok
call bell
jr fnloop
sizok: ld (hl),a
inc hl
ld c,a
ld de,09h
call ubios
jr fnloop
; --------------------------------------------------------------
xfer: ; Transfer filename in FNBUF to (hl) in FCB format
push hl
xor a ; Clean and prep area to recieve transfer
ld (dotflg),a
ld (hl),a ; 0 for disk
inc hl
ld (hl),20h
push hl
pop de
inc de
ld bc,10
ldir
pop hl
ld de,fnbuf ; Do disk desig, if there is one
ld a,(fnbuf+1)
cp ':'
jr nz,nodisk
ld a,(de)
sub 40h
ld (hl),a
inc de
inc de
nodisk: inc hl
ld b,8
xlup: ld a,(de) ; Then copy characters
or a
ret z
cp '.' ; Check for a dot
jr nz,nodot
ld a,(dotflg) ; Make sure only one dot
or a
ret nz
dec a
ld (dotflg),a
inc de
ld c,b ; Set to copy extent, if any
ld b,0
add hl,bc
ld b,3
nodot: ld a,b
or a
jr z,lulu
ld a,(de)
ld (hl),a
dec b
inc hl
lulu: inc de
jr xlup
dotflg: defb 00 ; Flag to prevent multiple dots in name
; ---------------------------------------------------------------
readfile: ; Load file spec in FCB1 to mem starting at (de)
; Return number of sectors loaded in hl
ld bc,00
rloop: push de
push bc ; Save sector counter
ld c,1ah
call 5 ; Set DMA as per reg de
ld c,14h
ld de,fcb1
call 5 ; Read a Sector
pop bc
pop de
or a
jr nz,lfdone
ld hl,80h ; Bump the DMA pointer
add hl,de
ex de,hl
inc bc ; Bump the sector counter
jr rloop ; Go back for more
lfdone: ld h,b
ld l,c
ret
; --------------------------------------------------------------------
writfile: ; Writes (bc) sectors from memory, starting at (de) to
; the file spec in FCB2. Closes the file when done.
ld a,c
or b
jr z,wfdone ; Check up on the sector count
push de
push bc ; Set the DMA
ld c,1ah
call 5
ld c,15h ; Write a record
ld de,fcb2
call 5
pop bc
pop de
and a
ret nz
ld hl,80h ; Bump the DMA pointer
add hl,de
ex de,hl
dec bc
jr writfile
wfdone: ld c,10h ; Close the file
ld de,fcb2
call 5
xor a
ret
; --------------------------------------------------------------------
namecmp: ; Compares two names in FCB (12) bytes. Returns zflg
; according to results of compare
ld b,12
cmplup: ld a,(de)
cp (hl)
ret nz
inc de
inc hl
dec b
jr nz,cmplup
ret
; --------------------------------------------------------------------
ubios: push hl ; Use a BIOS direct call. Save hl reg.
ld hl,(001) ; de contains offset from BIOS start
add hl,de
ld (bi1),hl
bi1 equ $+1
call 0000 ; Self mod code
pop hl
ret
; ---------------------------------------------------------------------
zprt: ld a,(de) ; print null term string
or a
ret z
push de
ld c,2
ld e,a
call 5
pop de
inc de
jr zprt
; ---------------------------------------------------------------------
fnshow: ; Show a file name in *.* format from FCB format (in de)
ex de,hl
ld a,(hl)
cp 0
jp z,nfndsk
add a,40h
push hl
ld e,a
ld c,2
call 5
ld e,':'
ld c,2
call 5
pop hl
nfndsk: inc hl
ld b,8
call nfnlup
doext: ld c,b
ld b,0
add hl,bc
ld a,(hl)
cp 20h
ret z
ld e,'.'
ld c,2
push hl
call 5
pop hl
ld b,3
call nfnlup
ret
nfnlup: ld e,(hl)
ld a,20h
cp e
ret z
push bc
push hl
ld c,2
call 5
pop hl
pop bc
inc hl
dec b
jr nz,nfnlup
ret
; ---------------------------------------------------------------------
upcase: cp 61h ; Convert to upper case
jr c,notlo
cp 7bh
ret nc
and 01011111b ; If it is, uppercase it
and a
notlo: ccf
ret
; ---------------------------------------------------------------------
bell: push hl ; Ring the bell !!
ld c,02
ld e,07
call 5
pop hl
ret
; ----------------------------------------------------
; THE FOLLOWING IS THE PATCH TO THE END OF WORDSTAR
; ----------------------------------------------------
patstrt equ $
ld hl,05dh ; find an argument, if any
ld a,(hl)
f1: cp 0
jr z,isarg-offset+patstrt
ld hl,06dh
ld a,(hl)
f2: cp 0
jr z,isarg-offset+patstrt
jr godef-offset+patstrt ; if none, try for the default fnme
isarg equ $+offset-patstrt
dec hl
push hl
ld de,fcb ; move the filename to the fcb
ld bc,12
ldir
pop de
ld a,e
cp 05ch ; If first arg, substitute second arg
jr nz,nomove-offset+patstrt
ld hl,06ch
ld bc,12
ldir
nomove equ $+offset-patstrt
call open ; open the file
jr nz,pgodef-offset+patstrt
godef equ $+offset-patstrt ; If not found, try the default fnme
ld hl,defnme
ld de,fcb
ld bc,12
ldir
call open
jr z,jrret-offset+patstrt ; Can't find anything, so just do WS
pgodef equ $+offset-patstrt
ld de,80h ; Get set to loop
push de
lloop equ $+offset-patstrt
pop hl
ld de,80h
add hl,de
ex de,hl
push de
ld c,1ah
call 5 ; Advance DMA by 80h bytes
ld c,14h
ld de,fcb
call 5 ; Read a Sector
or a
jr z,lloop-offset+patstrt ; Until no more to read
pop de
ld de,80h ; Restore DMA
ld c,1ah
call 5
ld de,fnwscm ; Move the filename into WordStar
ld hl,wsname
ld bc,12
ldir
retins equ $
jrret equ $+offset-patstrt
jp 0000
retad equ $-2
open equ $+offset-patstrt
ld c,0fh
ld de,fcb
call 5
inc a
ret
fcb equ $+offset-patstrt
defb 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
defb 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
wsname equ $+offset-patstrt
nme: defb 0,0,0,0,0,0,0,0,0,0,0,0
defb 0
defnme equ $+offset-patstrt
dnme: defb 0,' '
defb 0
patend equ $
end